diff --git a/product/src/common.pri b/product/src/common.pri index ab4e48d0..b946fe8d 100644 --- a/product/src/common.pri +++ b/product/src/common.pri @@ -63,3 +63,6 @@ LIBS += -L$$SRC_ROOT_PATH/../$$ISCS6000_OS$$DIR_DEBUG_RELEASE/ QMAKE_RPATHLINKDIR += $$PWD/../../platform/$$ISCS6000_OS$$DIR_DEBUG_RELEASE/ QMAKE_RPATHLINKDIR += $$SRC_ROOT_PATH/../$$ISCS6000_OS$$DIR_DEBUG_RELEASE/ +TR_EXCLUDE += $$SRC_ROOT_PATH/3rd/* \ + $$PWD/../../platform/src/3rd/* + diff --git a/product/src/fes/KBD511SInfo/KBD511SInfo.cpp b/product/src/fes/KBD511SInfo/KBD511SInfo.cpp new file mode 100644 index 00000000..729f1ebc --- /dev/null +++ b/product/src/fes/KBD511SInfo/KBD511SInfo.cpp @@ -0,0 +1,324 @@ +/* + @file KBD511SInfo.cpp + @brief R80 信息读取主程序 + APP加入WIFI连接后,发送组播报文请求管理机基本信息,本程序响应基本信息。 + 内容包括HOSTNAME,IP,MASK,MAC, + + @author thxiao + @history + +*/ +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "common/Common.h" +#include "boost/program_options.hpp" +#include "pub_utility_api/SingleProcInstance.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "pub_logger_api/logger.h" +#include "pub_utility_api/I18N.h" +#include "boost/dll/shared_library.hpp" +#include "pub_utility_api/FileUtil.h" +#include "KBD511SInfoRedundantManage.h" +#include "KBD511SInfo.h" + +#define OPT_DESC_APP "app" +#define OPT_DESC_HELP "help" +#define PROCESS_NAME_CMD_PROCESS "KBD511SInfo" + +using namespace std; +using namespace iot_sys; +using namespace iot_public; + +bool g_IsMainKBD511SInfo =false; +bool g_IsMainKBD511SInfoOld=false; + +CKBD511SInfo::CKBD511SInfo() +{ + //iot_public::initI18N("/fes/translate", "fes"); + m_ptrProcManage = NULL; + m_ptrReduSwitchManage = NULL; + m_ptrRedundantMng = NULL; +} + +CKBD511SInfo::~CKBD511SInfo() +{ + stop(); +} + +/* +@brief boost 命令参数解析 +@return 成功返回true,失败返回false +*/ +bool CKBD511SInfo::parseCommandLine(int argc, char *argv[]) +{ + for (int i = 1; i < argc; ++i) + { + if (i != 1) + { + m_strStartArgs += " "; + } + + m_strStartArgs += argv[i]; + } + + namespace po = boost::program_options; + po::options_description desc("usage"); + po::variables_map vm; + try + { + desc.add_options() + (OPT_DESC_APP",a", po::value()->required(), "app name") + (OPT_DESC_HELP",h", "\t""帮助"); + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if(vm.count(OPT_DESC_HELP)) + { + std::cout << desc << std::endl; + return false; + } + + m_strAppLabel = vm[OPT_DESC_APP].as(); + + } + catch (std::exception &ex) + { + std::cerr << ex.what() << std::endl; + std::cout << desc << endl; + return false; + } + catch (...) + { + std::cerr << "未知错误" << std::endl; + std::cout << desc << std::endl; + return false; + } + + return true; +} + +bool CKBD511SInfo::isAlreadyRunning() +{ + m_strInstName = PROCESS_NAME_CMD_PROCESS; + m_strInstName += " -s " + m_strAppLabel; + return iot_public::CSingleProcInstance::hasInstanceRunning(m_strInstName); +} + +/* +@brief 服务启动函数,一般需要继承,程序入口函数 +@return 成功返回true,失败返回false +*/ +bool CKBD511SInfo::start(int argc, char *argv[], int &/*nStatus*/) +{ + string strProcessName = "KBD511SInfo";//进程名,固定为"KBD511SInfo" + + //1、解析系统启动进程传入的参数,具体为"应用名" + //================================================================================ + if(!parseCommandLine(argc, argv))//获取应用名 + { + LOGERROR("CKBD511SInfo::start(), Get application name fail!\n"); + return false; + } + + //2、日志系统初始 + //================================================================================ + StartLogSystem(m_strAppLabel.c_str(),strProcessName.c_str() ); + + LOGDEBUG("CKBD511SInfo::start(), Get application name ok!\n"); + if(isAlreadyRunning()) + { + LOGERROR("ICKBD511SInfo::start(), Inst isAlreadyRunning, fail!\n"); + return false; + } + LOGDEBUG("ICKBD511SInfo::start(), Inst isAlreadyRunning, ok!\n"); + + //3、获取进程相关参数,包括应用名,进程名,节点信息等 + //================================================================================ + //SRunAppInfo stRunAppInfo; + CSysInfoInterfacePtr sysInfoPtr; + if(createSysInfoInstance(sysInfoPtr) == false) + { + LOGERROR("InstName=%s ,CKBD511SInfo::start(), createSysInfoInstance fail!\n", m_strInstName.c_str()); + return false; + } + if(sysInfoPtr == NULL) + { + LOGERROR("InstName=%s ,CKBD511SInfo::start(), Get System Info fail!\n", m_strInstName.c_str()); + return false; + } + sysInfoPtr->getLocalRunAppInfoByName(m_strAppLabel,m_stRunAppInfo); + + m_ProcessInfo.nAppId = m_stRunAppInfo.nAppId; + m_ProcessInfo.nDomainId = m_stRunAppInfo.nDomainId; + m_ProcessInfo.strNodeName = m_stRunAppInfo.strLocalNodeName; + m_ProcessInfo.strProcName = strProcessName; + m_ProcessInfo.strProcParam = m_strStartArgs; + + + //4、进程注册,消息总线注册,实时库注册等 + //================================================================================ + m_ptrProcManage = getProcMngInstance(m_ProcessInfo);//进程注册 + if(m_ptrProcManage== NULL) + { + LOGERROR("InstName=%s ,CKBD511SInfo::start(), getProcMngInstance fail!\n", m_strInstName.c_str()); + return false; + } + m_ptrProcManage->setCallback(this); + + + //5、WINSOCK注册 + //================================================================================ + InitWinsock(); + + //读取系统配置文件 + ReadConfigParam(); + + //8、业务线程初始化 + //================================================================================ + InitThread(); + + //9、创建主备用管理实例 + //================================================================================ + + m_ptrReduSwitchManage = boost::make_shared(m_ptrProcManage);// + if (m_ptrReduSwitchManage == NULL) + { + LOGERROR("InstName=%s ,CKBD511SInfo::start(), Start digital data process thread fail!\n", m_strInstName.c_str()); + return false; + } + //初始化冗余切换管理模块的数据 + SRedundantManageThreadParam Param; + + Param.ptrKBD511SInfoDataThread = m_ptrKBD511SInfoDataThread; + + /******转发相关线程*************************************************/ + m_ptrReduSwitchManage->Init(Param); + + + m_ptrRedundantMng = getRedundantMngInstance(m_ProcessInfo.nDomainId,m_ProcessInfo.nAppId,m_ProcessInfo.strNodeName); + if(m_ptrRedundantMng == NULL) + { + LOGERROR("InstName=%s ,CKBD511SInfo::start(), get RedundantMngInstance fail!\n", m_strInstName.c_str()); + return false; + } + m_ptrRedundantMng->setCallback(m_ptrReduSwitchManage); + + m_ptrProcManage->updateProcessInfo(true,false,false); + + + return true; +} + +/* + * @brief stop() + * @return + */ +bool CKBD511SInfo::stop() +{ + /* @brief 进行进程退出前的资源清理 */ + if (m_ptrRedundantMng != NULL) + { + m_ptrRedundantMng->unsetCallback(); + m_ptrRedundantMng.reset(); + } + + m_ptrReduSwitchManage.reset(); + + //8、业务线程停止 + //================================================================================ + LOGDEBUG("StopThread().......... start."); + StopThread(); + LOGDEBUG("StopThread().......... end."); + + + //5、WINSOCK注消 + //================================================================================ + + + //4、关闭日志系统 + //================================================================================ + LOGDEBUG("StopLogSystem().......... start."); + StopLogSystem(); + + + return true; +} + +/* + @brief 用来通知进程退出,一般应用继承后调用service::shutdown() + @return +*/ +int CKBD511SInfo::toQuit() +{ + shutdown(); + return iotSuccess; +} + +/** + * @brief CKBD511SInfo::InitThread + * 只创建线程,不唤醒线程。在冗余管理程序中唤醒线程。 + */ +bool CKBD511SInfo::InitThread() +{ + + m_ptrKBD511SInfoDataThread = boost::make_shared(); + if (m_ptrKBD511SInfoDataThread == NULL) + { + LOGERROR("m_ptrKBD511SInfoDataThread 创建失败"); + return false; + } + m_ptrKBD511SInfoDataThread->resume(); + + LOGINFO("InitThread() 创建成功!"); + + return true; +} + +/** + * @brief CKBD511SInfo::StopThread + */ +void CKBD511SInfo::StopThread() +{ + + if (m_ptrKBD511SInfoDataThread != NULL) + { + m_ptrKBD511SInfoDataThread->quit(); + m_ptrKBD511SInfoDataThread.reset(); + LOGDEBUG("CKBD511SInfo::StopThread m_ptrKBD511SInfoDataThread"); + } + +} + + +/** + * @brief CKBD511SInfo::InitWinsock + * + * Windows系统下网络库初始化 + * @return + */ +bool CKBD511SInfo::InitWinsock() +{ +#ifdef WIN32 + WSADATA wsdata; + WORD wVersion = MAKEWORD(2, 2); + if ((WSAStartup(wVersion, &wsdata)) != 0) + { + LOGERROR("WSAStartup() ERROR, errno:%d ", WSAGetLastError()); + return false; + } + return true; +#else + return true; +#endif +} + +/** + * @brief CKBD511SInfo::ReadConfigParam + * 读取FESSYS配置文件 + * @return 成功返回iotSuccess,失败返回iotFailed + */ +int CKBD511SInfo::ReadConfigParam() +{ + return iotSuccess; +} + diff --git a/product/src/fes/KBD511SInfo/KBD511SInfo.h b/product/src/fes/KBD511SInfo/KBD511SInfo.h new file mode 100644 index 00000000..26665557 --- /dev/null +++ b/product/src/fes/KBD511SInfo/KBD511SInfo.h @@ -0,0 +1,71 @@ +#pragma once + +#include "pub_utility_api/BaseService.h" +#include "sys_proc_mng_api/ProcMngInterface.h" +#include "sys_node_mng_api/NodeMngInterface.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "KBD511SInfoRedundantManage.h" +#include "FesDef.h" +#include "KBD511SInfoDataThread.h" + + +class CKBD511SInfo:public iot_public::CBaseService,iot_sys::CProcessQuitInterface +{ +public: + CKBD511SInfo(); + ~CKBD511SInfo(); + + + /* + @brief 解析命令行参数 CMsgQueueBuffer; + @return + */ + bool parseCommandLine(int argc, char* argv[]); + /* + @brief 判断进程是否单利模式运行 + @return + */ + bool isAlreadyRunning(); + + virtual bool start(int argc, char *argv[], int &nStatus); + /* + @brief 服务停止清理函数,决定了main()的返回值,缺省返回true,一般需要继承,进行一些必要的资源清理 + @return 成功返回true,失败返回false + */ + virtual bool stop(); + + /* + @brief 用来通知进程退出,一般应用继承后调用service::shutdown() + @return + */ + virtual int toQuit(); + + +private: + std::string m_strAppLabel; //应用名: pscada\bus.... + std::string m_strInstName; //实例名: 进程名+"-s"+应用名。进程名固定为"fes" + std::string m_strStartArgs; + iot_sys::SProcessInfoKey m_ProcessInfo;//进程信息 + iot_public::SRunAppInfo m_stRunAppInfo; + + iot_sys::CProcMngInterfacePtr m_ptrProcManage; + iot_sys::CRedundantMngInterfacePtr m_ptrRedundantMng; + CKBD511SInfoRedundantManagePtr m_ptrReduSwitchManage; + CKBD511SInfoDataThreadPtr m_ptrKBD511SInfoDataThread; + + bool InitWinsock(); + + /** + * @brief CKBD511SInfo::InitThread + * 只创建线程,不唤醒线程。在冗余管理程序中唤醒线程。 + */ + bool InitThread(); + + void StopThread(); + void Restart(); + + + int ReadConfigParam(); +}; + + diff --git a/product/src/fes/KBD511SInfo/KBD511SInfo.pro b/product/src/fes/KBD511SInfo/KBD511SInfo.pro new file mode 100644 index 00000000..7047cc0d --- /dev/null +++ b/product/src/fes/KBD511SInfo/KBD511SInfo.pro @@ -0,0 +1,40 @@ +QT -= core gui +CONFIG -= qt + +TEMPLATE = app +TARGET = KBD511SInfo +CONFIG += console c++11 +CONFIG -= app_bundle +CONFIG -= qt + +SOURCES += main.cpp \ + KBD511SInfo.cpp \ + KBD511SInfoRedundantManage.cpp \ + KBD511SInfoDataThread.cpp + +HEADERS += \ + KBD511SInfo.h \ + KBD511SInfoRedundantManage.h \ + KBD511SInfoDataThread.h + +INCLUDEPATH += ../include/ + +LIBS += -lboost_system -lboost_thread -lboost_chrono -lboost_program_options -lboost_date_time -lboost_filesystem -lboost_locale -lboost_regex +LIBS += -lpub_utility_api -lpub_logger_api -lnet_msg_bus_api -lpub_sysinfo_api -llog4cplus +LIBS += -lrdb_api +LIBS += -lprotobuf +LIBS += -lsys_node_mng_api +LIBS += -lsys_proc_mng_api + + +DEFINES += PROTOCOLBASE_API_EXPORTS + +include($$PWD/../../idl_files/idl_files.pri) + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/fes/KBD511SInfo/KBD511SInfoDataThread.cpp b/product/src/fes/KBD511SInfo/KBD511SInfoDataThread.cpp new file mode 100644 index 00000000..894fa229 --- /dev/null +++ b/product/src/fes/KBD511SInfo/KBD511SInfoDataThread.cpp @@ -0,0 +1,519 @@ +/* + @file KBD511SInfoDataThread.cpp + @brief APP加入WIFI连接后,发送组播报文请求管理机基本信息,本程序响应基本信息。 + WIN10上调试,发送组播报文测试时,只能保留实际的网络连接,其他的需要禁用才能正确收到报文。 + + @author thxiao + +*/ +#ifdef OS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +using namespace std; +#pragma comment(lib,"ws2_32.lib") +#pragma comment(lib,"Iphlpapi.lib") //需要添加Iphlpapi.lib库 +#else +#include +#endif + +#include "KBD511SInfoDataThread.h" + +using namespace iot_public; + +char g_KBD511SInfoMultIpAddr[] = "239.0.0.11"; //组播地址 +const int g_KBD511SInfoSendPort = 6664; //组播信息发送的端口号 +const int g_KBD511SInfoRcvPort = 6662; //组播信息接收的端口号 + + +CKBD511SInfoDataThread::CKBD511SInfoDataThread(): +CTimerThreadBase("KBD511SInfoDataThread",100) +{ + memset(m_HostName, 0, CN_KBD511SInfoEthDescMaxSize); + memset(&m_LocalEthInfo[0], 0, CN_KBD511SInfoEthMaxNum * sizeof(SKBD511SInfoETH)); + memset(&m_defaultGW, 0, CN_KBD511SInfoEthDescMaxSize); + m_LocalEthNum = 0; + m_Socket = INVALID_SOCKET; +} + +CKBD511SInfoDataThread::~CKBD511SInfoDataThread() +{ + +} + +/** + * @brief CKBD511SInfoDataThread::beforeExecute + * 检查消息总线上是否有消息前的一些初始化工作 + */ + +int CKBD511SInfoDataThread::beforeExecute() +{ + ReadInfo(); + SocketInit(); + return iotSuccess; +} + +/* + @brief CKBD511SInfoDataThread::execute + 检查消息总线上是否有消息,如果有把消息分类发送到不同的消息队列 + */ +void CKBD511SInfoDataThread::execute() +{ + RecvNetData(); + return; +} + +/* + @brief 执行execute函数后的处理 + */ +void CKBD511SInfoDataThread::afterExecute() +{ + +} + +/* +@brief 读取管理机信息 +*/ +void CKBD511SInfoDataThread::ReadInfo() +{ +#ifdef OS_WINDOWS + winGetHostname(m_HostName); //读出本机的机器名 + winGeEthParam(); //获取本机网口参数信息:ip地址、掩码、MAC +#else + gethostname(m_HostName, sizeof(m_HostName)); //读出本机配置的机器名 + //获取本机网卡信息 + memset(&m_LocalEthInfo[0], 0, CN_KBD511SInfoEthMaxNum * sizeof(SKBD511SInfoETH)); + m_LocalEthNum = 0; + KBD511S_GetEthParam("eth", 2); //获取有线网口参数 + KBD511S_GetEthParam("wlan", 1); //获取WIFI参数 +#endif + LOGDEBUG("HostName=%s", m_HostName); +} + + +/* +* @brief CKBD511SInfoDataThread::ExeCmmdScript +* 得到执行脚本命令返回信息 +*/ + +bool CKBD511SInfoDataThread::ExeCmmdScript(char *cmdStr, char *retCmdInfo, int infoLen) +{ + bool ret = false; + + if ((cmdStr == NULL) || (retCmdInfo == NULL)) + return ret; + + retCmdInfo[0] = '\0'; + +#ifndef OS_WINDOWS + FILE *fp; + + LOGDEBUG("%s ",cmdStr); + if ((fp = popen(cmdStr, "r")) == NULL) + { + LOGDEBUG("%s exe error!", cmdStr); + exit(1);//退出当前shell + return ret; + } + + ret = fread(retCmdInfo, sizeof(char), infoLen, fp); + LOGDEBUG("%s",retCmdInfo); + pclose(fp); +#endif + + return ret; +} + +//获取网口参数 +void CKBD511SInfoDataThread::KBD511S_GetEthParam(char* ethName, int ethNum) +{ + int i, ethFlag; + char buf[4096], cmd[128]; + char *spli_1; + + for (i = 0; i\n", errno, strerror(errno)); +#endif + return iotFailed; + } + + // struct sockaddr_in local; + memset(&localSin, 0, sizeof(localSin)); + localSin.sin_family = AF_INET; + localSin.sin_port = htons(g_KBD511SInfoRcvPort); + localSin.sin_addr.s_addr = htonl(INADDR_ANY); + //inet_pton(AF_INET, "0.0.0.0", &localSin.sin_addr.s_addr); + + ret = ::bind(m_Socket, (struct sockaddr *)&localSin, sizeof(localSin)); + if (ret == SOCKET_ERROR) + { +#ifdef OS_WINDOWS + LOGERROR("UDP bind(%d) failed, errno:%d ", m_Socket, WSAGetLastError()); +#else + LOGERROR("UDP bind(%d) failed, errno:%d <%s>", m_Socket, errno, strerror(errno)); +#endif + SocketClose(); + return iotFailed; + + } +/* //设置组播 +#ifdef OS_WINDOWS + n1.imr_multiaddr.s_addr = inet_addr(g_KBD511SInfoMultIpAddr); + n1.imr_interface.s_addr = htonl(INADDR_ANY); + //inet_pton(AF_INET, g_KBD511SInfoMultIpAddr, &n1.imr_multiaddr.s_addr); + //inet_pton(AF_INET, "0.0.0.0", &n1.imr_interface.s_addr); + if(setsockopt(m_Socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&n1, sizeof(n1))<0) +#else + n1.imr_multiaddr.s_addr = inet_addr(g_KBD511SInfoMultIpAddr); + n1.imr_interface.s_addr = htonl(INADDR_ANY); + //inet_pton(AF_INET, g_KBD511SInfoMultIpAddr, &n1.imr_multiaddr.s_addr); + //inet_pton(AF_INET, "0.0.0.0", &n1.imr_address.s_addr); + //n1.imr_ifindex = if_nametoindex("eth0"); + if(setsockopt(m_Socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &n1, sizeof(n1))<0) +#endif + { + LOGERROR("Usetsockopt m_Socket IP_ADD_MEMBERSHIP\n"); + //return iotFailed; + }*/ + + //设置套接字为非阻塞模式 +#ifdef OS_WINDOWS + u_long argp = 1; + if (ioctlsocket(m_Socket, FIONBIO, &argp) == SOCKET_ERROR) +#else + int flags; + flags = fcntl(m_Socket, F_GETFL, 0); + if (fcntl(m_Socket, F_SETFL, flags | O_NONBLOCK) < 0) //O_NDELAY + +#endif + { +#ifdef OS_WINDOWS + LOGERROR("ioctlsocket(sock:%d) set FIONBIO error, errno:%d \n", m_Socket, WSAGetLastError()); +#else + LOGERROR("fcntl(sock:%d) set O_NONBLOCK error, errno:%d <%s>\n", m_Socket, errno, strerror(errno)); +#endif + return iotFailed; + } + return iotSuccess; +} + +void CKBD511SInfoDataThread::SocketClose() +{ + if (m_Socket != INVALID_SOCKET) + { + closesocket(m_Socket); + m_Socket = INVALID_SOCKET; + LOGDEBUG("closesocket m_Socket =%d", m_Socket); + } +} + +int CKBD511SInfoDataThread::RxData(char *retData, int MaxDataLen) +{ + int len, fromlen; + fd_set fdSet; + sockaddr_in fromaddr; + struct timeval tv; + char fromIP[64]; + + if (m_Socket == SOCKET_ERROR) + return -1; + + //add 判断soket是否可读 + FD_ZERO(&fdSet); + FD_SET(m_Socket, &fdSet); + tv.tv_sec = 0; + tv.tv_usec = 20 * 1000; + + len = select((int)(m_Socket + 1), &fdSet, 0, 0, &tv); + if (len < 0) + { +#ifdef OS_WINDOWS + LOGWARN("select(sock+1:%d) error, errno:%d ", m_Socket + 1, WSAGetLastError()); +#else + LOGWARN("select(sock+1:%d) error, errno:%d <%s>", m_Socket, errno, strerror(errno)); +#endif + } + else + if (len > 0) + { + fromlen = sizeof(fromaddr); +#ifdef OS_WINDOWS + len = ::recvfrom(m_Socket, retData, MaxDataLen, 0, (struct sockaddr *)&fromaddr, &fromlen); +#else + len = ::recvfrom(m_Socket, retData, MaxDataLen, 0, (struct sockaddr *)&fromaddr, (socklen_t*)&fromlen); +#endif + if (len > 0) + { + memset(fromIP, 0, sizeof(fromIP)); + strcpy(fromIP, inet_ntoa(fromaddr.sin_addr)); + LOGDEBUG("Recv from %s len=%d", fromIP, len); + strcpy(g_KBD511SInfoMultIpAddr, fromIP); + } + } + + return len; +} + +int CKBD511SInfoDataThread::TxData(char *Data, int DataLen) +{ + struct sockaddr_in client; + int ret; + + ret = -1; + if (m_Socket == SOCKET_ERROR) + return ret; + + memset(&client, 0, sizeof(client)); + client.sin_family = AF_INET; + client.sin_port = htons(g_KBD511SInfoSendPort); + client.sin_addr.s_addr = inet_addr(g_KBD511SInfoMultIpAddr); + //inet_pton(AF_INET, g_KBD511SInfoMultIpAddr, &client.sin_addr.s_addr); + + ret = sendto(m_Socket, Data, DataLen, 0, (struct sockaddr *)&client, sizeof(client)); + if (ret < 0) + { +#ifdef OS_WINDOWS + LOGDEBUG("sendto(sock:%d) error, errno:%d ", m_Socket, WSAGetLastError()); +#else + LOGDEBUG("sendto(sock:%d) error, errno:%d <%s>", m_Socket, errno, strerror(errno)); +#endif + } + else + LOGDEBUG("sendto(%s:%d) len=%d ", g_KBD511SInfoMultIpAddr,g_KBD511SInfoSendPort,ret); + return ret; +} + +//windows获取主机名 +void CKBD511SInfoDataThread::winGetHostname(char* hostname) +{ +#ifdef OS_WINDOWS + WCHAR PCname[255]; + DWORD bufSizeP = 255; + memset(PCname, 0, 255); + + GetComputerName(PCname, &bufSizeP); + bufSizeP = WideCharToMultiByte(CP_ACP,0, PCname,-1,NULL,0,NULL,NULL); + WideCharToMultiByte(CP_ACP, 0, PCname, -1, hostname, bufSizeP, NULL, NULL); +#endif +} + +//windows获取网卡信息 +void CKBD511SInfoDataThread::winGeEthParam() +{ +#ifdef OS_WINDOWS + //PIP_ADAPTER_INFO结构体指针存储本机网卡信息 + PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO(); + //得到结构体大小,用于GetAdaptersInfo参数 + unsigned long stSize = sizeof(IP_ADAPTER_INFO); + //调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量 + int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize); + //记录网卡数量 + int netCardNum = 0; + //记录每张网卡上的IP地址数量 + //int IPnumPerNetCard = 0; + + memset(&m_LocalEthInfo[0], 0, CN_KBD511SInfoEthMaxNum * sizeof(SKBD511SInfoETH)); + m_LocalEthNum = 0; + if (ERROR_BUFFER_OVERFLOW == nRel) + { + //如果函数返回的是ERROR_BUFFER_OVERFLOW + //则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小 + //这也是说明为什么stSize既是一个输入量也是一个输出量 + //释放原来的内存空间 + delete pIpAdapterInfo; + //重新申请内存空间用来存储所有网卡信息 + pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize]; + //再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量 + nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize); + } + if (ERROR_SUCCESS == nRel) + { + //输出网卡信息 + //可能有多网卡,因此通过循环去判断 + while (pIpAdapterInfo) + { + //网卡名称 + strcpy(m_LocalEthInfo[netCardNum].EthName, pIpAdapterInfo->Description); + //网卡描述 + //strcpy(m_LocalEthInfo[netCardNum].EthName, pIpAdapterInfo->Description); + //网卡类型 + m_LocalEthInfo[netCardNum].Type = pIpAdapterInfo->Type; + /*switch (pIpAdapterInfo->Type) + { + case MIB_IF_TYPE_OTHER: + cout << "网卡类型:" << "OTHER" << endl; + break; + case MIB_IF_TYPE_ETHERNET: + cout << "网卡类型:" << "ETHERNET" << endl; + break; + case MIB_IF_TYPE_TOKENRING: + cout << "网卡类型:" << "TOKENRING" << endl; + break; + case MIB_IF_TYPE_FDDI: + cout << "网卡类型:" << "FDDI" << endl; + break; + case MIB_IF_TYPE_PPP: + cout << "网卡类型:" << "PPP" << endl; + break; + case MIB_IF_TYPE_LOOPBACK: + cout << "网卡类型:" << "LOOPBACK" << endl; + break; + case MIB_IF_TYPE_SLIP: + cout << "网卡类型:" << "SLIP" << endl; + break; + default: + break; + }*/ + //网卡MAC地址 + for (unsigned int i = 0; i < pIpAdapterInfo->AddressLength; i++) + { + if (i < pIpAdapterInfo->AddressLength - 1) + sprintf(&m_LocalEthInfo[netCardNum].Mac[i*3],"%02X-", pIpAdapterInfo->Address[i]); + else + sprintf(&m_LocalEthInfo[netCardNum].Mac[i * 3],"%02X", pIpAdapterInfo->Address[i]); + } + //可能网卡有多IP,因此通过循环去判断 + IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfo->IpAddressList); + /*do { + cout << "该网卡上的IP数量:" << ++IPnumPerNetCard << endl; + cout << "IP 地址:" << pIpAddrString->IpAddress.String << endl; + cout << "子网地址:" << pIpAddrString->IpMask.String << endl; + cout << "网关地址:" << pIpAdapterInfo->GatewayList.IpAddress.String << endl; + pIpAddrString = pIpAddrString->Next; + } while (pIpAddrString);*/ + + //网卡第一个IP地址 + strcpy(m_LocalEthInfo[netCardNum].IpAddr, pIpAddrString->IpAddress.String); + //掩码 + strcpy(m_LocalEthInfo[netCardNum].Mask, pIpAddrString->IpMask.String); + //网关 + strcpy(m_LocalEthInfo[netCardNum].Gateway, pIpAdapterInfo->GatewayList.IpAddress.String); + pIpAdapterInfo = pIpAdapterInfo->Next; + netCardNum++; + } + m_LocalEthNum = netCardNum; + } + //释放内存空间 + if (pIpAdapterInfo) + delete pIpAdapterInfo; +#endif +} + +void CKBD511SInfoDataThread::RecvNetData() +{ + char recvBuf[100]; + int maxRecvSize; + int retLen; + + memset(recvBuf,0,100); + maxRecvSize = sizeof(recvBuf); + retLen = RxData(recvBuf, maxRecvSize); + if (retLen > 0) + { + LOGDEBUG("recv(%s:%d) %s ", g_KBD511SInfoMultIpAddr,g_KBD511SInfoSendPort,recvBuf); + if (strcmp(recvBuf, "APP") == 0) + RecvDataProcess(); + } +} + +int CKBD511SInfoDataThread::RecvDataProcess() +{ + char sendData[1024]; + char temStr[500]; + int sendLen,ret; + + LOGDEBUG("recv(%s:%d) APP sendInfo ", g_KBD511SInfoMultIpAddr,g_KBD511SInfoSendPort); + sprintf(sendData, "hostname:%s,\n", m_HostName); + for (int i = 0; i < m_LocalEthNum; i++) + { + memset(temStr, 0, 500); + sprintf(temStr, "%s IP:%s\nMAC:%s\nMask:%s,\n", m_LocalEthInfo[i].EthName, m_LocalEthInfo[i].IpAddr, m_LocalEthInfo[i].Mac, m_LocalEthInfo[i].Mask); + strcat(sendData, temStr); + } + sendLen = (int)strlen(sendData); + ret = TxData(sendData, sendLen); + + return ret; +} + + diff --git a/product/src/fes/KBD511SInfo/KBD511SInfoDataThread.h b/product/src/fes/KBD511SInfo/KBD511SInfoDataThread.h new file mode 100644 index 00000000..312d8ea2 --- /dev/null +++ b/product/src/fes/KBD511SInfo/KBD511SInfoDataThread.h @@ -0,0 +1,73 @@ +#pragma once +#include "FesDef.h" + +//本机网口信息 +const int CN_KBD511SInfoEthMaxNum = 8; +const int CN_KBD511SInfoEthDescMaxSize = 100; + +typedef struct _SKBD511SInfoETH{ + char EthName[CN_KBD511SInfoEthDescMaxSize]; //ETH名 + char IpAddr[CN_KBD511SInfoEthDescMaxSize]; //IP + char Mask[CN_KBD511SInfoEthDescMaxSize]; //掩码 + char Mac[CN_KBD511SInfoEthDescMaxSize]; //MAC + char Bcast[CN_KBD511SInfoEthDescMaxSize]; + char Gateway[CN_KBD511SInfoEthDescMaxSize]; //网关 + unsigned int Type; //网卡类型 + _SKBD511SInfoETH() { + memset(EthName, 0, CN_KBD511SInfoEthDescMaxSize); + memset(IpAddr, 0, CN_KBD511SInfoEthDescMaxSize); + memset(Mask, 0, CN_KBD511SInfoEthDescMaxSize); + memset(Mac, 0, CN_KBD511SInfoEthDescMaxSize); + memset(Bcast, 0, CN_KBD511SInfoEthDescMaxSize); + memset(Gateway, 0, CN_KBD511SInfoEthDescMaxSize); + Type = 0; + } +}SKBD511SInfoETH; + + +class CKBD511SInfoDataThread : public iot_public::CTimerThreadBase +{ +public: + CKBD511SInfoDataThread(); + + virtual ~CKBD511SInfoDataThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + /* + @brief 执行execute函数后的处理 + */ + virtual void afterExecute(); + + +private: + char m_HostName[CN_KBD511SInfoEthDescMaxSize]; + SKBD511SInfoETH m_LocalEthInfo[CN_KBD511SInfoEthMaxNum]; + int m_LocalEthNum; + char m_defaultGW[CN_KBD511SInfoEthDescMaxSize]; + int m_Socket; + + bool ExeCmmdScript(char *cmdStr, char *retCmdInfo, int infoLen); + void ReadInfo(); + void SocketClose(); + int RxData(char *retData, int MaxDataLen); + int TxData(char *Data, int DataLen); + void RecvNetData(); + int RecvDataProcess(); + int SocketInit(); + + void winGetHostname(char* hostname); + void winGeEthParam(); + + void KBD511S_GetEthParam(char* ethName, int ethNum); + +}; + +typedef boost::shared_ptr CKBD511SInfoDataThreadPtr; + diff --git a/product/src/fes/KBD511SInfo/KBD511SInfoRedundantManage.cpp b/product/src/fes/KBD511SInfo/KBD511SInfoRedundantManage.cpp new file mode 100644 index 00000000..a777653d --- /dev/null +++ b/product/src/fes/KBD511SInfo/KBD511SInfoRedundantManage.cpp @@ -0,0 +1,115 @@ +/* + @file KBD511SInfoRedundantManage.c + @brief 程序冗余调度的实现,冗余调度在接口redundantSwitch实现; + @author thxiao + @history + +*/ +#include "KBD511SInfoRedundantManage.h" +#include "KBD511SInfo.h" + +using namespace iot_sys; + +extern bool g_IsMainKBD511SInfo; +extern bool g_IsMainKBD511SInfoOld; + +CKBD511SInfoRedundantManage::CKBD511SInfoRedundantManage(iot_sys::CProcMngInterfacePtr ptrProc) +{ + m_ptrProcManage = ptrProc; + m_bMaster = false; + m_bSlave = false; + m_startThreadFlag = false; +} + +CKBD511SInfoRedundantManage::~CKBD511SInfoRedundantManage(void) +{ +} + +/* +@brief 冗余切换,应用需要继承并重写,实现自身的冗余切换逻辑 +@param bool bMaster 是否为主 +@param bool bSlave 是否为备 +@return +@retval +*/ +int CKBD511SInfoRedundantManage::redundantSwitch(bool bMaster, bool bSlave) +{ + + if (m_startThreadFlag == false) + { + m_startThreadFlag = true; + LOGINFO("bMaster = [%d] bSlave = [%d] 启动永不挂起线程", bMaster, bSlave); + //StartThread();//部分线程需要一直开启 + } + + if((true == bMaster) && (false == bSlave) ) //主状态,启动部分线程 + { + g_IsMainKBD511SInfo = true; + LOGINFO(" bMaster=[%d] bSlave=[%d] g_IsMainKBD511SInfo = true", bMaster, bSlave); + //ResumeThread(); + } + else if((false == bMaster) && (true == bSlave)) //备用状态,停止部分线程 + { + g_IsMainKBD511SInfo = false; + LOGINFO(" bMaster=[%d] bSlave=[%d] g_IsMainKBD511SInfo = false", bMaster, bSlave); + //SuspendThread(); + } + else + { + //在非主非备的情况下(开门狗叫),按备机方式处理 + g_IsMainKBD511SInfo = false; + LOGINFO("非主非备不确定状态 bMaster=[%d] bSlave=[%d] g_IsMainKBD511SInfo = false", bMaster, bSlave); + //SuspendThread(); + } + + m_bMaster = bMaster; + m_bSlave = bSlave; + m_ptrProcManage->updateProcessInfo(true,m_bMaster,m_bSlave); + + return iotSuccess; +} + +/* +@brief 初始化冗余切换管理模块的数据 +@param SRedundantManageThreadParam &Param 线程参数 +@return +@retval +*/ +void CKBD511SInfoRedundantManage::Init(SRedundantManageThreadParam &Param ) +{ + m_ptrKBD511SInfoDataThread =Param.ptrKBD511SInfoDataThread; + +} + +/* +@brief 在主FES状态下,resume thread +@param +@return +@retval +*/ +void CKBD511SInfoRedundantManage::ResumeThread() +{ + +} + +/* +@brief 一直需要启动的thread +@param +@return +@retval +*/ +void CKBD511SInfoRedundantManage::StartThread() +{ + +} + +/* +@brief 在备FES状态下,suspend thread +@param CKBD511SInfoApp *pApp 数据 +@return +@retval +*/ +void CKBD511SInfoRedundantManage::SuspendThread() +{ + +} diff --git a/product/src/fes/KBD511SInfo/KBD511SInfoRedundantManage.h b/product/src/fes/KBD511SInfo/KBD511SInfoRedundantManage.h new file mode 100644 index 00000000..eb9201be --- /dev/null +++ b/product/src/fes/KBD511SInfo/KBD511SInfoRedundantManage.h @@ -0,0 +1,73 @@ +/* + @file KBD511SInfoRedundantManage.h + @brief 程序冗余调度的实现,冗余调度在接口redundantSwitch实现; + @author thxiao +*/ +#pragma once + +#include "sys_node_mng_api/NodeMngInterface.h" +#include "sys_proc_mng_api/ProcMngInterface.h" +#include "KBD511SInfoDataThread.h" + +typedef struct{ + CKBD511SInfoDataThreadPtr ptrKBD511SInfoDataThread; + }SRedundantManageThreadParam; + +class CKBD511SInfoRedundantManage : + public ::iot_sys::CRedundantSwitchInterface +{ +public: + CKBD511SInfoRedundantManage(iot_sys::CProcMngInterfacePtr ptrProc); + ~CKBD511SInfoRedundantManage(void); + + /* + @brief 冗余切换,应用需要继承并重写,实现自身的冗余切换逻辑 + @param bool bMaster 是否为主 + @param bool bSlave 是否为备 + @return + @retval + */ + virtual int redundantSwitch(bool bMaster, bool bSlave); + + /* + @brief 初始化冗余切换管理模块的数据 + @param SRedundantManageThreadParam &Param 线程参数 + @return + @retval + */ + void Init(SRedundantManageThreadParam &Param); + + /* + @brief 在主FES状态下,resume thread + @param CKBD511SInfoApp *pApp 数据 + @return + @retval + */ + void ResumeThread(); + + /* + @brief 在备FES状态下,suspend thread + @param CKBD511SInfoApp *pApp 数据 + @return + @retval + */ + void SuspendThread(); + + + /* + @brief 一直需要启动的thread + @param + @return + @retval + */ + void StartThread(); + +private: + bool m_bMaster; + bool m_bSlave; + bool m_startThreadFlag; + iot_sys::CProcMngInterfacePtr m_ptrProcManage; + + CKBD511SInfoDataThreadPtr m_ptrKBD511SInfoDataThread; +}; +typedef boost::shared_ptr CKBD511SInfoRedundantManagePtr; diff --git a/product/src/fes/KBD511SInfo/main.cpp b/product/src/fes/KBD511SInfo/main.cpp new file mode 100644 index 00000000..5bde6e97 --- /dev/null +++ b/product/src/fes/KBD511SInfo/main.cpp @@ -0,0 +1,12 @@ +#include +#include "KBD511SInfo.h" + +using namespace std; + +int main(int argc, char *argv[]) +{ + + CKBD511SInfo objApp; + return objApp.main(argc, argv); + +} diff --git a/product/src/fes/fes.pro b/product/src/fes/fes.pro index 574482b7..a084a294 100644 --- a/product/src/fes/fes.pro +++ b/product/src/fes/fes.pro @@ -3,6 +3,10 @@ TEMPLATE = subdirs CONFIG += ordered -SUBDIRS += iec61850 protocol fes fesSim - +SUBDIRS += \ + fes_pub \ +# iec61850 \ + protocol \ + fes \ +# fesSim diff --git a/product/src/fes/fesSim/FesSim/fes_sim.ico b/product/src/fes/fesSim/FesSim/fes_sim.ico index dd80e08c..0afbc451 100644 Binary files a/product/src/fes/fesSim/FesSim/fes_sim.ico and b/product/src/fes/fesSim/FesSim/fes_sim.ico differ diff --git a/product/src/fes/fesSim/FesSim/fwaccmondlg.cpp b/product/src/fes/fesSim/FesSim/fwaccmondlg.cpp index 0f39926d..1f741462 100644 --- a/product/src/fes/fesSim/FesSim/fwaccmondlg.cpp +++ b/product/src/fes/fesSim/FesSim/fwaccmondlg.cpp @@ -591,10 +591,11 @@ void FwAccMonDlg::OnRecvPiDataResp(int CmdCode,QByteArray Data,int DataLen) return; int readx,count; float fvalue; + double dvalue; unsigned char* pTemp; count = 0; readx = 16; - pTemp = (unsigned char*)&fvalue; + pTemp = (unsigned char*)&dvalue; while(readxValueEdit->text(); - m_PiValue = str.toLong(&ok,10); + //m_PiValue = str.toLong(&ok,10); + m_PiValue = str.toDouble(&ok); str = ui->StatusEdit->text(); m_PiStatus = str.toInt(&ok,10); @@ -781,14 +793,24 @@ void SimPiDlg::OnSetValue() data[writex++] = m_PiFlag; data[writex++] = 0x00; data[writex++] = 0x00; - data[writex++] = m_PiValue&0xff; - data[writex++] = (m_PiValue>>8)&0xff; - data[writex++] = (m_PiValue>>16)&0xff; - data[writex++] = (m_PiValue>>24)&0xff; - data[writex++] = (m_PiValue>>32)&0xff; - data[writex++] = (m_PiValue>>40)&0xff; - data[writex++] = (m_PiValue>>48)&0xff; - data[writex++] = (m_PiValue>>56)&0xff; + // data[writex++] = m_PiValue&0xff; + // data[writex++] = (m_PiValue>>8)&0xff; + // data[writex++] = (m_PiValue>>16)&0xff; + // data[writex++] = (m_PiValue>>24)&0xff; + // data[writex++] = (m_PiValue>>32)&0xff; + // data[writex++] = (m_PiValue>>40)&0xff; + // data[writex++] = (m_PiValue>>48)&0xff; + // data[writex++] = (m_PiValue>>56)&0xff; + pTemp = (unsigned char*)&m_PiValue; + data[writex++] = *pTemp; + data[writex++] = *(pTemp+1); + data[writex++] = *(pTemp+2); + data[writex++] = *(pTemp+3); + data[writex++] = *(pTemp+4); + data[writex++] = *(pTemp+5); + data[writex++] = *(pTemp+6); + data[writex++] = *(pTemp+7); + data[writex++] = m_PiStatus&0xff; data[writex++] = (m_PiStatus>>8)&0xff; data[writex++] = (m_PiStatus>>16)&0xff; @@ -838,6 +860,7 @@ void SimPiDlg::OnLineSet() { unsigned char data[50]; int SetMode,writex; + unsigned char *pTemp; //if(!this->isActiveWindow())//只有激活的窗口才可发送数据,避免发送数据冲突。 // return; @@ -877,11 +900,14 @@ void SimPiDlg::OnLineSet() */ str = ui->MinValueEdit->text(); - m_MinValue = str.toInt(&ok,10); + //m_MinValue = str.toInt(&ok,10); + m_MinValue = str.toDouble(&ok); str = ui->MaxValueEdit->text(); - m_MaxValue = str.toInt(&ok,10); + //m_MaxValue = str.toInt(&ok,10); + m_MaxValue = str.toDouble(&ok); str = ui->StepValueEdit->text(); - m_StepValue = str.toInt(&ok,10); + // m_StepValue = str.toInt(&ok,10); + m_StepValue = str.toDouble(&ok); str = ui->ChangeTimeEdit->text(); m_ChangeTime = str.toInt(&ok,10); @@ -905,18 +931,34 @@ void SimPiDlg::OnLineSet() data[writex++] = (m_ChangeTime>>8)&0xff; memset(&data[writex],0,12); writex+=12; - data[writex++] = m_MinValue&0xff; - data[writex++] = (m_MinValue>>8)&0xff; - data[writex++] = (m_MinValue>>16)&0xff; - data[writex++] = (m_MinValue>>24)&0xff; - data[writex++] = m_MaxValue&0xff; - data[writex++] = (m_MaxValue>>8)&0xff; - data[writex++] = (m_MaxValue>>16)&0xff; - data[writex++] = (m_MaxValue>>24)&0xff; - data[writex++] = m_StepValue&0xff; - data[writex++] = (m_StepValue>>8)&0xff; - data[writex++] = (m_StepValue>>16)&0xff; - data[writex++] = (m_StepValue>>24)&0xff; + // data[writex++] = m_MinValue&0xff; + // data[writex++] = (m_MinValue>>8)&0xff; + // data[writex++] = (m_MinValue>>16)&0xff; + // data[writex++] = (m_MinValue>>24)&0xff; + // data[writex++] = m_MaxValue&0xff; + // data[writex++] = (m_MaxValue>>8)&0xff; + // data[writex++] = (m_MaxValue>>16)&0xff; + // data[writex++] = (m_MaxValue>>24)&0xff; + // data[writex++] = m_StepValue&0xff; + // data[writex++] = (m_StepValue>>8)&0xff; + // data[writex++] = (m_StepValue>>16)&0xff; + // data[writex++] = (m_StepValue>>24)&0xff; + pTemp = (unsigned char*)&m_MinValue; + data[writex++] = *pTemp; + data[writex++] = *(pTemp+1); + data[writex++] = *(pTemp+2); + data[writex++] = *(pTemp+3); + pTemp = (unsigned char*)&m_MaxValue; + data[writex++] = *pTemp; + data[writex++] = *(pTemp+1); + data[writex++] = *(pTemp+2); + data[writex++] = *(pTemp+3); + pTemp = (unsigned char*)&m_StepValue; + data[writex++] = *pTemp; + data[writex++] = *(pTemp+1); + data[writex++] = *(pTemp+2); + data[writex++] = *(pTemp+3); + data[writex++] = m_CurrentRtuNo&0xff; data[writex++] = (m_CurrentRtuNo>>8)&0xff; data[writex++] = (m_CurrentRtuNo>>16)&0xff; diff --git a/product/src/fes/fesSim/FesSim/simpidlg.h b/product/src/fes/fesSim/FesSim/simpidlg.h index 44aba304..33f8d286 100644 --- a/product/src/fes/fesSim/FesSim/simpidlg.h +++ b/product/src/fes/fesSim/FesSim/simpidlg.h @@ -73,12 +73,16 @@ private: bool m_AllPiFlag; int m_PiFlag; - long m_MaxValue; - long m_MinValue; - long m_StepValue; + // long m_MaxValue; + // long m_MinValue; + // long m_StepValue; + float m_MaxValue; + float m_MinValue; + float m_StepValue; + int m_ChangeTime; //unit:1s - uint64 m_PiValue; + double m_PiValue; int m_PiStatus; }; diff --git a/product/src/fes/fes_idl_files/FesDebugTool.pb.cc b/product/src/fes/fes_idl_files/FesDebugTool.pb.cc new file mode 100644 index 00000000..75f1247f --- /dev/null +++ b/product/src/fes/fes_idl_files/FesDebugTool.pb.cc @@ -0,0 +1,15508 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: FesDebugTool.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "FesDebugTool.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace iot_idl { + +namespace { + +const ::google::protobuf::Descriptor* FesDebugToolReqMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolReqMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolNetRoute_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolNetRoute_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolChanParam_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolChanParam_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolChanParamRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolChanParamRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolRtuParam_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolRtuParam_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolRtuParamRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolRtuParamRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolRtuInfo_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolRtuInfo_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolRtuInfoRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolRtuInfoRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolPntParamReqMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolPntParamReqMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolPntParam_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolPntParam_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolPntParamRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolPntParamRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolPntValueReqMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolPntValueReqMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolIntPntValue_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolIntPntValue_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolFloatPntValue_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolFloatPntValue_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolDoublePntValue_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolDoublePntValue_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolPntValueRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolPntValueRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolValueVariant_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolValueVariant_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolValueSetSimParam_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolValueSetSimParam_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolLineSetSimParam_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolLineSetSimParam_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolRandSetSimParam_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolRandSetSimParam_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolValueSimSetReqMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolValueSimSetReqMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolValueSimSetRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolValueSimSetRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolSimEventRtuSoe_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolSimEventRtuSoe_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolSimEventCreateReqMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolSimEventCreateReqMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolSimEventCreateRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolSimEventCreateRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolSimControlReqMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolSimControlReqMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolSimControlRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolSimControlRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolSimDefCmdReqMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolSimDefCmdReqMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolFwPntParam_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolFwPntParam_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolFwPntParamRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolFwPntParamRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolSoeEvent_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolSoeEvent_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolSoeEventRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolSoeEventRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolChanEvent_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolChanEvent_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolChanEventRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolChanEventRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolChanMonCmdReqMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolChanMonCmdReqMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolChanMonCmdRepMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolChanMonCmdRepMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolChanMonFrame_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolChanMonFrame_reflection_ = NULL; +const ::google::protobuf::Descriptor* FesDebugToolChanMonInfoMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FesDebugToolChanMonInfoMsg_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* enFesDebugMsgType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* enFesDebugSimMode_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* enFesDebugSimRangeType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* enFesDebugEventSimType_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_FesDebugTool_2eproto() { + protobuf_AddDesc_FesDebugTool_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "FesDebugTool.proto"); + GOOGLE_CHECK(file != NULL); + FesDebugToolReqMsg_descriptor_ = file->message_type(0); + static const int FesDebugToolReqMsg_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolReqMsg, type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolReqMsg, body_), + }; + FesDebugToolReqMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolReqMsg_descriptor_, + FesDebugToolReqMsg::default_instance_, + FesDebugToolReqMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolReqMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolReqMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolReqMsg)); + FesDebugToolRepMsg_descriptor_ = file->message_type(1); + static const int FesDebugToolRepMsg_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRepMsg, success_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRepMsg, err_msg_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRepMsg, type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRepMsg, body_), + }; + FesDebugToolRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolRepMsg_descriptor_, + FesDebugToolRepMsg::default_instance_, + FesDebugToolRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolRepMsg)); + FesDebugToolNetRoute_descriptor_ = file->message_type(2); + static const int FesDebugToolNetRoute_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolNetRoute, desc_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolNetRoute, port_no_), + }; + FesDebugToolNetRoute_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolNetRoute_descriptor_, + FesDebugToolNetRoute::default_instance_, + FesDebugToolNetRoute_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolNetRoute, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolNetRoute, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolNetRoute)); + FesDebugToolChanParam_descriptor_ = file->message_type(3); + static const int FesDebugToolChanParam_offsets_[18] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, chan_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, tag_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, chan_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, used_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, chan_status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, comm_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, chan_mode_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, protocol_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, net_route_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, connect_wait_sec_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, connect_timeout_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, retry_times_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, recv_timeout_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, resp_timeout_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, max_rx_size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, max_tx_size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, err_rate_limit_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, backup_chan_no_), + }; + FesDebugToolChanParam_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolChanParam_descriptor_, + FesDebugToolChanParam::default_instance_, + FesDebugToolChanParam_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParam, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolChanParam)); + FesDebugToolChanParamRepMsg_descriptor_ = file->message_type(4); + static const int FesDebugToolChanParamRepMsg_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParamRepMsg, chan_param_), + }; + FesDebugToolChanParamRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolChanParamRepMsg_descriptor_, + FesDebugToolChanParamRepMsg::default_instance_, + FesDebugToolChanParamRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParamRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanParamRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolChanParamRepMsg)); + FesDebugToolRtuParam_descriptor_ = file->message_type(5); + static const int FesDebugToolRtuParam_offsets_[11] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, rtu_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, rtu_desc_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, rtu_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, used_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, rtu_status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, rtu_addr_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, chan_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, max_ai_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, max_di_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, max_acc_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, recv_fail_limit_), + }; + FesDebugToolRtuParam_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolRtuParam_descriptor_, + FesDebugToolRtuParam::default_instance_, + FesDebugToolRtuParam_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParam, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolRtuParam)); + FesDebugToolRtuParamRepMsg_descriptor_ = file->message_type(6); + static const int FesDebugToolRtuParamRepMsg_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParamRepMsg, rtu_param_), + }; + FesDebugToolRtuParamRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolRtuParamRepMsg_descriptor_, + FesDebugToolRtuParamRepMsg::default_instance_, + FesDebugToolRtuParamRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParamRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuParamRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolRtuParamRepMsg)); + FesDebugToolRtuInfo_descriptor_ = file->message_type(7); + static const int FesDebugToolRtuInfo_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuInfo, rtu_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuInfo, used_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuInfo, rtu_desc_), + }; + FesDebugToolRtuInfo_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolRtuInfo_descriptor_, + FesDebugToolRtuInfo::default_instance_, + FesDebugToolRtuInfo_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuInfo, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuInfo, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolRtuInfo)); + FesDebugToolRtuInfoRepMsg_descriptor_ = file->message_type(8); + static const int FesDebugToolRtuInfoRepMsg_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuInfoRepMsg, rtu_info_), + }; + FesDebugToolRtuInfoRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolRtuInfoRepMsg_descriptor_, + FesDebugToolRtuInfoRepMsg::default_instance_, + FesDebugToolRtuInfoRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuInfoRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRtuInfoRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolRtuInfoRepMsg)); + FesDebugToolPntParamReqMsg_descriptor_ = file->message_type(9); + static const int FesDebugToolPntParamReqMsg_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParamReqMsg, rtu_no_), + }; + FesDebugToolPntParamReqMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolPntParamReqMsg_descriptor_, + FesDebugToolPntParamReqMsg::default_instance_, + FesDebugToolPntParamReqMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParamReqMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParamReqMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolPntParamReqMsg)); + FesDebugToolPntParam_descriptor_ = file->message_type(10); + static const int FesDebugToolPntParam_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParam, pnt_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParam, used_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParam, pnt_desc_), + }; + FesDebugToolPntParam_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolPntParam_descriptor_, + FesDebugToolPntParam::default_instance_, + FesDebugToolPntParam_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParam, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParam, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolPntParam)); + FesDebugToolPntParamRepMsg_descriptor_ = file->message_type(11); + static const int FesDebugToolPntParamRepMsg_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParamRepMsg, rtu_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParamRepMsg, max_pnt_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParamRepMsg, pnt_param_), + }; + FesDebugToolPntParamRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolPntParamRepMsg_descriptor_, + FesDebugToolPntParamRepMsg::default_instance_, + FesDebugToolPntParamRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParamRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntParamRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolPntParamRepMsg)); + FesDebugToolPntValueReqMsg_descriptor_ = file->message_type(12); + static const int FesDebugToolPntValueReqMsg_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntValueReqMsg, rtu_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntValueReqMsg, start_index_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntValueReqMsg, end_index_), + }; + FesDebugToolPntValueReqMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolPntValueReqMsg_descriptor_, + FesDebugToolPntValueReqMsg::default_instance_, + FesDebugToolPntValueReqMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntValueReqMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntValueReqMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolPntValueReqMsg)); + FesDebugToolIntPntValue_descriptor_ = file->message_type(13); + static const int FesDebugToolIntPntValue_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolIntPntValue, pnt_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolIntPntValue, value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolIntPntValue, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolIntPntValue, time_), + }; + FesDebugToolIntPntValue_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolIntPntValue_descriptor_, + FesDebugToolIntPntValue::default_instance_, + FesDebugToolIntPntValue_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolIntPntValue, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolIntPntValue, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolIntPntValue)); + FesDebugToolFloatPntValue_descriptor_ = file->message_type(14); + static const int FesDebugToolFloatPntValue_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFloatPntValue, pnt_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFloatPntValue, value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFloatPntValue, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFloatPntValue, time_), + }; + FesDebugToolFloatPntValue_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolFloatPntValue_descriptor_, + FesDebugToolFloatPntValue::default_instance_, + FesDebugToolFloatPntValue_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFloatPntValue, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFloatPntValue, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolFloatPntValue)); + FesDebugToolDoublePntValue_descriptor_ = file->message_type(15); + static const int FesDebugToolDoublePntValue_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolDoublePntValue, pnt_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolDoublePntValue, value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolDoublePntValue, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolDoublePntValue, time_), + }; + FesDebugToolDoublePntValue_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolDoublePntValue_descriptor_, + FesDebugToolDoublePntValue::default_instance_, + FesDebugToolDoublePntValue_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolDoublePntValue, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolDoublePntValue, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolDoublePntValue)); + FesDebugToolPntValueRepMsg_descriptor_ = file->message_type(16); + static const int FesDebugToolPntValueRepMsg_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntValueRepMsg, rtu_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntValueRepMsg, int_values_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntValueRepMsg, float_values_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntValueRepMsg, double_values_), + }; + FesDebugToolPntValueRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolPntValueRepMsg_descriptor_, + FesDebugToolPntValueRepMsg::default_instance_, + FesDebugToolPntValueRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntValueRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolPntValueRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolPntValueRepMsg)); + FesDebugToolValueVariant_descriptor_ = file->message_type(17); + static const int FesDebugToolValueVariant_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueVariant, int_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueVariant, float_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueVariant, double_value_), + }; + FesDebugToolValueVariant_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolValueVariant_descriptor_, + FesDebugToolValueVariant::default_instance_, + FesDebugToolValueVariant_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueVariant, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueVariant, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolValueVariant)); + FesDebugToolValueSetSimParam_descriptor_ = file->message_type(18); + static const int FesDebugToolValueSetSimParam_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSetSimParam, value_), + }; + FesDebugToolValueSetSimParam_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolValueSetSimParam_descriptor_, + FesDebugToolValueSetSimParam::default_instance_, + FesDebugToolValueSetSimParam_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSetSimParam, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSetSimParam, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolValueSetSimParam)); + FesDebugToolLineSetSimParam_descriptor_ = file->message_type(19); + static const int FesDebugToolLineSetSimParam_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolLineSetSimParam, min_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolLineSetSimParam, max_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolLineSetSimParam, step_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolLineSetSimParam, period_), + }; + FesDebugToolLineSetSimParam_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolLineSetSimParam_descriptor_, + FesDebugToolLineSetSimParam::default_instance_, + FesDebugToolLineSetSimParam_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolLineSetSimParam, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolLineSetSimParam, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolLineSetSimParam)); + FesDebugToolRandSetSimParam_descriptor_ = file->message_type(20); + static const int FesDebugToolRandSetSimParam_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRandSetSimParam, min_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRandSetSimParam, max_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRandSetSimParam, period_), + }; + FesDebugToolRandSetSimParam_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolRandSetSimParam_descriptor_, + FesDebugToolRandSetSimParam::default_instance_, + FesDebugToolRandSetSimParam_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRandSetSimParam, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolRandSetSimParam, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolRandSetSimParam)); + FesDebugToolValueSimSetReqMsg_descriptor_ = file->message_type(21); + static const int FesDebugToolValueSimSetReqMsg_offsets_[8] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetReqMsg, sim_mode_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetReqMsg, sim_range_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetReqMsg, rtu_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetReqMsg, pnt_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetReqMsg, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetReqMsg, value_set_param_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetReqMsg, line_set_param_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetReqMsg, rand_set_param_), + }; + FesDebugToolValueSimSetReqMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolValueSimSetReqMsg_descriptor_, + FesDebugToolValueSimSetReqMsg::default_instance_, + FesDebugToolValueSimSetReqMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetReqMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetReqMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolValueSimSetReqMsg)); + FesDebugToolValueSimSetRepMsg_descriptor_ = file->message_type(22); + static const int FesDebugToolValueSimSetRepMsg_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetRepMsg, sim_mode_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetRepMsg, body_), + }; + FesDebugToolValueSimSetRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolValueSimSetRepMsg_descriptor_, + FesDebugToolValueSimSetRepMsg::default_instance_, + FesDebugToolValueSimSetRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolValueSimSetRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolValueSimSetRepMsg)); + FesDebugToolSimEventRtuSoe_descriptor_ = file->message_type(23); + static const int FesDebugToolSimEventRtuSoe_offsets_[8] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventRtuSoe, event_source_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventRtuSoe, rtu_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventRtuSoe, pnt_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventRtuSoe, value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventRtuSoe, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventRtuSoe, fault_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventRtuSoe, fault_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventRtuSoe, fault_value_), + }; + FesDebugToolSimEventRtuSoe_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolSimEventRtuSoe_descriptor_, + FesDebugToolSimEventRtuSoe::default_instance_, + FesDebugToolSimEventRtuSoe_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventRtuSoe, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventRtuSoe, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolSimEventRtuSoe)); + FesDebugToolSimEventCreateReqMsg_descriptor_ = file->message_type(24); + static const int FesDebugToolSimEventCreateReqMsg_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventCreateReqMsg, event_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventCreateReqMsg, event_), + }; + FesDebugToolSimEventCreateReqMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolSimEventCreateReqMsg_descriptor_, + FesDebugToolSimEventCreateReqMsg::default_instance_, + FesDebugToolSimEventCreateReqMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventCreateReqMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventCreateReqMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolSimEventCreateReqMsg)); + FesDebugToolSimEventCreateRepMsg_descriptor_ = file->message_type(25); + static const int FesDebugToolSimEventCreateRepMsg_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventCreateRepMsg, event_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventCreateRepMsg, body_), + }; + FesDebugToolSimEventCreateRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolSimEventCreateRepMsg_descriptor_, + FesDebugToolSimEventCreateRepMsg::default_instance_, + FesDebugToolSimEventCreateRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventCreateRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimEventCreateRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolSimEventCreateRepMsg)); + FesDebugToolSimControlReqMsg_descriptor_ = file->message_type(26); + static const int FesDebugToolSimControlReqMsg_offsets_[6] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlReqMsg, ctrl_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlReqMsg, seq_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlReqMsg, rtu_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlReqMsg, pnt_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlReqMsg, float_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlReqMsg, int_value_), + }; + FesDebugToolSimControlReqMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolSimControlReqMsg_descriptor_, + FesDebugToolSimControlReqMsg::default_instance_, + FesDebugToolSimControlReqMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlReqMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlReqMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolSimControlReqMsg)); + FesDebugToolSimControlRepMsg_descriptor_ = file->message_type(27); + static const int FesDebugToolSimControlRepMsg_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlRepMsg, ctrl_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlRepMsg, seq_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlRepMsg, success_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlRepMsg, err_msg_), + }; + FesDebugToolSimControlRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolSimControlRepMsg_descriptor_, + FesDebugToolSimControlRepMsg::default_instance_, + FesDebugToolSimControlRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimControlRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolSimControlRepMsg)); + FesDebugToolSimDefCmdReqMsg_descriptor_ = file->message_type(28); + static const int FesDebugToolSimDefCmdReqMsg_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimDefCmdReqMsg, rtu_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimDefCmdReqMsg, dev_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimDefCmdReqMsg, keys_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimDefCmdReqMsg, values_), + }; + FesDebugToolSimDefCmdReqMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolSimDefCmdReqMsg_descriptor_, + FesDebugToolSimDefCmdReqMsg::default_instance_, + FesDebugToolSimDefCmdReqMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimDefCmdReqMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSimDefCmdReqMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolSimDefCmdReqMsg)); + FesDebugToolFwPntParam_descriptor_ = file->message_type(29); + static const int FesDebugToolFwPntParam_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFwPntParam, pnt_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFwPntParam, used_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFwPntParam, fes_rtu_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFwPntParam, fes_pnt_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFwPntParam, pnt_desc_), + }; + FesDebugToolFwPntParam_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolFwPntParam_descriptor_, + FesDebugToolFwPntParam::default_instance_, + FesDebugToolFwPntParam_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFwPntParam, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFwPntParam, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolFwPntParam)); + FesDebugToolFwPntParamRepMsg_descriptor_ = file->message_type(30); + static const int FesDebugToolFwPntParamRepMsg_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFwPntParamRepMsg, rtu_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFwPntParamRepMsg, max_pnt_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFwPntParamRepMsg, pnt_param_), + }; + FesDebugToolFwPntParamRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolFwPntParamRepMsg_descriptor_, + FesDebugToolFwPntParamRepMsg::default_instance_, + FesDebugToolFwPntParamRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFwPntParamRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolFwPntParamRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolFwPntParamRepMsg)); + FesDebugToolSoeEvent_descriptor_ = file->message_type(31); + static const int FesDebugToolSoeEvent_offsets_[9] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEvent, table_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEvent, col_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEvent, tag_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEvent, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEvent, value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEvent, time_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEvent, fault_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEvent, fault_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEvent, fault_value_), + }; + FesDebugToolSoeEvent_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolSoeEvent_descriptor_, + FesDebugToolSoeEvent::default_instance_, + FesDebugToolSoeEvent_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEvent, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEvent, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolSoeEvent)); + FesDebugToolSoeEventRepMsg_descriptor_ = file->message_type(32); + static const int FesDebugToolSoeEventRepMsg_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEventRepMsg, over_flow_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEventRepMsg, event_), + }; + FesDebugToolSoeEventRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolSoeEventRepMsg_descriptor_, + FesDebugToolSoeEventRepMsg::default_instance_, + FesDebugToolSoeEventRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEventRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolSoeEventRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolSoeEventRepMsg)); + FesDebugToolChanEvent_descriptor_ = file->message_type(33); + static const int FesDebugToolChanEvent_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanEvent, tag_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanEvent, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanEvent, err_rate_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanEvent, time_), + }; + FesDebugToolChanEvent_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolChanEvent_descriptor_, + FesDebugToolChanEvent::default_instance_, + FesDebugToolChanEvent_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanEvent, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanEvent, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolChanEvent)); + FesDebugToolChanEventRepMsg_descriptor_ = file->message_type(34); + static const int FesDebugToolChanEventRepMsg_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanEventRepMsg, over_flow_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanEventRepMsg, event_), + }; + FesDebugToolChanEventRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolChanEventRepMsg_descriptor_, + FesDebugToolChanEventRepMsg::default_instance_, + FesDebugToolChanEventRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanEventRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanEventRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolChanEventRepMsg)); + FesDebugToolChanMonCmdReqMsg_descriptor_ = file->message_type(35); + static const int FesDebugToolChanMonCmdReqMsg_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonCmdReqMsg, chan_no_), + }; + FesDebugToolChanMonCmdReqMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolChanMonCmdReqMsg_descriptor_, + FesDebugToolChanMonCmdReqMsg::default_instance_, + FesDebugToolChanMonCmdReqMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonCmdReqMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonCmdReqMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolChanMonCmdReqMsg)); + FesDebugToolChanMonCmdRepMsg_descriptor_ = file->message_type(36); + static const int FesDebugToolChanMonCmdRepMsg_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonCmdRepMsg, chan_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonCmdRepMsg, rx_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonCmdRepMsg, tx_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonCmdRepMsg, err_num_), + }; + FesDebugToolChanMonCmdRepMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolChanMonCmdRepMsg_descriptor_, + FesDebugToolChanMonCmdRepMsg::default_instance_, + FesDebugToolChanMonCmdRepMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonCmdRepMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonCmdRepMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolChanMonCmdRepMsg)); + FesDebugToolChanMonFrame_descriptor_ = file->message_type(37); + static const int FesDebugToolChanMonFrame_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonFrame, frame_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonFrame, data_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonFrame, time_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonFrame, data_), + }; + FesDebugToolChanMonFrame_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolChanMonFrame_descriptor_, + FesDebugToolChanMonFrame::default_instance_, + FesDebugToolChanMonFrame_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonFrame, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonFrame, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolChanMonFrame)); + FesDebugToolChanMonInfoMsg_descriptor_ = file->message_type(38); + static const int FesDebugToolChanMonInfoMsg_offsets_[6] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonInfoMsg, chan_no_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonInfoMsg, rx_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonInfoMsg, tx_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonInfoMsg, err_num_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonInfoMsg, over_flow_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonInfoMsg, frame_), + }; + FesDebugToolChanMonInfoMsg_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FesDebugToolChanMonInfoMsg_descriptor_, + FesDebugToolChanMonInfoMsg::default_instance_, + FesDebugToolChanMonInfoMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonInfoMsg, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FesDebugToolChanMonInfoMsg, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FesDebugToolChanMonInfoMsg)); + enFesDebugMsgType_descriptor_ = file->enum_type(0); + enFesDebugSimMode_descriptor_ = file->enum_type(1); + enFesDebugSimRangeType_descriptor_ = file->enum_type(2); + enFesDebugEventSimType_descriptor_ = file->enum_type(3); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_FesDebugTool_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolReqMsg_descriptor_, &FesDebugToolReqMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolRepMsg_descriptor_, &FesDebugToolRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolNetRoute_descriptor_, &FesDebugToolNetRoute::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolChanParam_descriptor_, &FesDebugToolChanParam::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolChanParamRepMsg_descriptor_, &FesDebugToolChanParamRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolRtuParam_descriptor_, &FesDebugToolRtuParam::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolRtuParamRepMsg_descriptor_, &FesDebugToolRtuParamRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolRtuInfo_descriptor_, &FesDebugToolRtuInfo::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolRtuInfoRepMsg_descriptor_, &FesDebugToolRtuInfoRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolPntParamReqMsg_descriptor_, &FesDebugToolPntParamReqMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolPntParam_descriptor_, &FesDebugToolPntParam::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolPntParamRepMsg_descriptor_, &FesDebugToolPntParamRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolPntValueReqMsg_descriptor_, &FesDebugToolPntValueReqMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolIntPntValue_descriptor_, &FesDebugToolIntPntValue::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolFloatPntValue_descriptor_, &FesDebugToolFloatPntValue::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolDoublePntValue_descriptor_, &FesDebugToolDoublePntValue::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolPntValueRepMsg_descriptor_, &FesDebugToolPntValueRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolValueVariant_descriptor_, &FesDebugToolValueVariant::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolValueSetSimParam_descriptor_, &FesDebugToolValueSetSimParam::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolLineSetSimParam_descriptor_, &FesDebugToolLineSetSimParam::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolRandSetSimParam_descriptor_, &FesDebugToolRandSetSimParam::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolValueSimSetReqMsg_descriptor_, &FesDebugToolValueSimSetReqMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolValueSimSetRepMsg_descriptor_, &FesDebugToolValueSimSetRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolSimEventRtuSoe_descriptor_, &FesDebugToolSimEventRtuSoe::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolSimEventCreateReqMsg_descriptor_, &FesDebugToolSimEventCreateReqMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolSimEventCreateRepMsg_descriptor_, &FesDebugToolSimEventCreateRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolSimControlReqMsg_descriptor_, &FesDebugToolSimControlReqMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolSimControlRepMsg_descriptor_, &FesDebugToolSimControlRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolSimDefCmdReqMsg_descriptor_, &FesDebugToolSimDefCmdReqMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolFwPntParam_descriptor_, &FesDebugToolFwPntParam::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolFwPntParamRepMsg_descriptor_, &FesDebugToolFwPntParamRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolSoeEvent_descriptor_, &FesDebugToolSoeEvent::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolSoeEventRepMsg_descriptor_, &FesDebugToolSoeEventRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolChanEvent_descriptor_, &FesDebugToolChanEvent::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolChanEventRepMsg_descriptor_, &FesDebugToolChanEventRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolChanMonCmdReqMsg_descriptor_, &FesDebugToolChanMonCmdReqMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolChanMonCmdRepMsg_descriptor_, &FesDebugToolChanMonCmdRepMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolChanMonFrame_descriptor_, &FesDebugToolChanMonFrame::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FesDebugToolChanMonInfoMsg_descriptor_, &FesDebugToolChanMonInfoMsg::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_FesDebugTool_2eproto() { + delete FesDebugToolReqMsg::default_instance_; + delete FesDebugToolReqMsg_reflection_; + delete FesDebugToolRepMsg::default_instance_; + delete FesDebugToolRepMsg_reflection_; + delete FesDebugToolNetRoute::default_instance_; + delete FesDebugToolNetRoute_reflection_; + delete FesDebugToolChanParam::default_instance_; + delete FesDebugToolChanParam_reflection_; + delete FesDebugToolChanParamRepMsg::default_instance_; + delete FesDebugToolChanParamRepMsg_reflection_; + delete FesDebugToolRtuParam::default_instance_; + delete FesDebugToolRtuParam_reflection_; + delete FesDebugToolRtuParamRepMsg::default_instance_; + delete FesDebugToolRtuParamRepMsg_reflection_; + delete FesDebugToolRtuInfo::default_instance_; + delete FesDebugToolRtuInfo_reflection_; + delete FesDebugToolRtuInfoRepMsg::default_instance_; + delete FesDebugToolRtuInfoRepMsg_reflection_; + delete FesDebugToolPntParamReqMsg::default_instance_; + delete FesDebugToolPntParamReqMsg_reflection_; + delete FesDebugToolPntParam::default_instance_; + delete FesDebugToolPntParam_reflection_; + delete FesDebugToolPntParamRepMsg::default_instance_; + delete FesDebugToolPntParamRepMsg_reflection_; + delete FesDebugToolPntValueReqMsg::default_instance_; + delete FesDebugToolPntValueReqMsg_reflection_; + delete FesDebugToolIntPntValue::default_instance_; + delete FesDebugToolIntPntValue_reflection_; + delete FesDebugToolFloatPntValue::default_instance_; + delete FesDebugToolFloatPntValue_reflection_; + delete FesDebugToolDoublePntValue::default_instance_; + delete FesDebugToolDoublePntValue_reflection_; + delete FesDebugToolPntValueRepMsg::default_instance_; + delete FesDebugToolPntValueRepMsg_reflection_; + delete FesDebugToolValueVariant::default_instance_; + delete FesDebugToolValueVariant_reflection_; + delete FesDebugToolValueSetSimParam::default_instance_; + delete FesDebugToolValueSetSimParam_reflection_; + delete FesDebugToolLineSetSimParam::default_instance_; + delete FesDebugToolLineSetSimParam_reflection_; + delete FesDebugToolRandSetSimParam::default_instance_; + delete FesDebugToolRandSetSimParam_reflection_; + delete FesDebugToolValueSimSetReqMsg::default_instance_; + delete FesDebugToolValueSimSetReqMsg_reflection_; + delete FesDebugToolValueSimSetRepMsg::default_instance_; + delete FesDebugToolValueSimSetRepMsg_reflection_; + delete FesDebugToolSimEventRtuSoe::default_instance_; + delete FesDebugToolSimEventRtuSoe_reflection_; + delete FesDebugToolSimEventCreateReqMsg::default_instance_; + delete FesDebugToolSimEventCreateReqMsg_reflection_; + delete FesDebugToolSimEventCreateRepMsg::default_instance_; + delete FesDebugToolSimEventCreateRepMsg_reflection_; + delete FesDebugToolSimControlReqMsg::default_instance_; + delete FesDebugToolSimControlReqMsg_reflection_; + delete FesDebugToolSimControlRepMsg::default_instance_; + delete FesDebugToolSimControlRepMsg_reflection_; + delete FesDebugToolSimDefCmdReqMsg::default_instance_; + delete FesDebugToolSimDefCmdReqMsg_reflection_; + delete FesDebugToolFwPntParam::default_instance_; + delete FesDebugToolFwPntParam_reflection_; + delete FesDebugToolFwPntParamRepMsg::default_instance_; + delete FesDebugToolFwPntParamRepMsg_reflection_; + delete FesDebugToolSoeEvent::default_instance_; + delete FesDebugToolSoeEvent_reflection_; + delete FesDebugToolSoeEventRepMsg::default_instance_; + delete FesDebugToolSoeEventRepMsg_reflection_; + delete FesDebugToolChanEvent::default_instance_; + delete FesDebugToolChanEvent_reflection_; + delete FesDebugToolChanEventRepMsg::default_instance_; + delete FesDebugToolChanEventRepMsg_reflection_; + delete FesDebugToolChanMonCmdReqMsg::default_instance_; + delete FesDebugToolChanMonCmdReqMsg_reflection_; + delete FesDebugToolChanMonCmdRepMsg::default_instance_; + delete FesDebugToolChanMonCmdRepMsg_reflection_; + delete FesDebugToolChanMonFrame::default_instance_; + delete FesDebugToolChanMonFrame_reflection_; + delete FesDebugToolChanMonInfoMsg::default_instance_; + delete FesDebugToolChanMonInfoMsg_reflection_; +} + +void protobuf_AddDesc_FesDebugTool_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\022FesDebugTool.proto\022\007iot_idl\"L\n\022FesDebu" + "gToolReqMsg\022(\n\004type\030\001 \002(\0162\032.iot_idl.enFe" + "sDebugMsgType\022\014\n\004body\030\002 \001(\t\"n\n\022FesDebugT" + "oolRepMsg\022\017\n\007success\030\001 \002(\010\022\017\n\007err_msg\030\002 " + "\001(\t\022(\n\004type\030\003 \002(\0162\032.iot_idl.enFesDebugMs" + "gType\022\014\n\004body\030\004 \001(\t\"5\n\024FesDebugToolNetRo" + "ute\022\014\n\004desc\030\001 \002(\t\022\017\n\007port_no\030\002 \002(\005\"\253\003\n\025F" + "esDebugToolChanParam\022\017\n\007chan_no\030\001 \002(\005\022\020\n" + "\010tag_name\030\002 \002(\t\022\021\n\tchan_name\030\003 \002(\t\022\014\n\004us" + "ed\030\004 \002(\005\022\023\n\013chan_status\030\005 \002(\005\022\021\n\tcomm_ty" + "pe\030\006 \002(\005\022\021\n\tchan_mode\030\007 \002(\005\022\023\n\013protocol_" + "id\030\010 \002(\005\0220\n\tnet_route\030\t \003(\0132\035.iot_idl.Fe" + "sDebugToolNetRoute\022\030\n\020connect_wait_sec\030\n" + " \002(\005\022\027\n\017connect_timeout\030\013 \002(\005\022\023\n\013retry_t" + "imes\030\014 \002(\005\022\024\n\014recv_timeout\030\r \002(\005\022\024\n\014resp" + "_timeout\030\016 \002(\005\022\023\n\013max_rx_size\030\017 \002(\005\022\023\n\013m" + "ax_tx_size\030\020 \002(\005\022\026\n\016err_rate_limit\030\021 \002(\002" + "\022\026\n\016backup_chan_no\030\022 \003(\005\"Q\n\033FesDebugTool" + "ChanParamRepMsg\0222\n\nchan_param\030\001 \003(\0132\036.io" + "t_idl.FesDebugToolChanParam\"\345\001\n\024FesDebug" + "ToolRtuParam\022\016\n\006rtu_no\030\001 \002(\005\022\020\n\010rtu_desc" + "\030\002 \002(\t\022\020\n\010rtu_name\030\003 \002(\t\022\014\n\004used\030\004 \002(\005\022\022" + "\n\nrtu_status\030\005 \002(\005\022\020\n\010rtu_addr\030\006 \002(\005\022\017\n\007" + "chan_no\030\007 \002(\005\022\022\n\nmax_ai_num\030\010 \002(\005\022\022\n\nmax" + "_di_num\030\t \002(\005\022\023\n\013max_acc_num\030\n \002(\005\022\027\n\017re" + "cv_fail_limit\030\013 \002(\005\"N\n\032FesDebugToolRtuPa" + "ramRepMsg\0220\n\trtu_param\030\001 \003(\0132\035.iot_idl.F" + "esDebugToolRtuParam\"E\n\023FesDebugToolRtuIn" + "fo\022\016\n\006rtu_no\030\001 \002(\005\022\014\n\004used\030\002 \002(\005\022\020\n\010rtu_" + "desc\030\003 \002(\t\"K\n\031FesDebugToolRtuInfoRepMsg\022" + ".\n\010rtu_info\030\001 \003(\0132\034.iot_idl.FesDebugTool" + "RtuInfo\",\n\032FesDebugToolPntParamReqMsg\022\016\n" + "\006rtu_no\030\001 \002(\005\"F\n\024FesDebugToolPntParam\022\016\n" + "\006pnt_no\030\001 \002(\005\022\014\n\004used\030\002 \002(\005\022\020\n\010pnt_desc\030" + "\003 \002(\t\"s\n\032FesDebugToolPntParamRepMsg\022\016\n\006r" + "tu_no\030\001 \002(\005\022\023\n\013max_pnt_num\030\002 \002(\005\0220\n\tpnt_" + "param\030\003 \003(\0132\035.iot_idl.FesDebugToolPntPar" + "am\"T\n\032FesDebugToolPntValueReqMsg\022\016\n\006rtu_" + "no\030\001 \002(\005\022\023\n\013start_index\030\002 \002(\005\022\021\n\tend_ind" + "ex\030\003 \002(\005\"V\n\027FesDebugToolIntPntValue\022\016\n\006p" + "nt_no\030\001 \002(\005\022\r\n\005value\030\002 \002(\021\022\016\n\006status\030\003 \002" + "(\r\022\014\n\004time\030\004 \002(\004\"X\n\031FesDebugToolFloatPnt" + "Value\022\016\n\006pnt_no\030\001 \002(\005\022\r\n\005value\030\002 \002(\002\022\016\n\006" + "status\030\003 \002(\r\022\014\n\004time\030\004 \002(\004\"Y\n\032FesDebugTo" + "olDoublePntValue\022\016\n\006pnt_no\030\001 \002(\005\022\r\n\005valu" + "e\030\002 \002(\001\022\016\n\006status\030\003 \002(\r\022\014\n\004time\030\004 \002(\004\"\330\001" + "\n\032FesDebugToolPntValueRepMsg\022\016\n\006rtu_no\030\001" + " \002(\005\0224\n\nint_values\030\002 \003(\0132 .iot_idl.FesDe" + "bugToolIntPntValue\0228\n\014float_values\030\003 \003(\013" + "2\".iot_idl.FesDebugToolFloatPntValue\022:\n\r" + "double_values\030\004 \003(\0132#.iot_idl.FesDebugTo" + "olDoublePntValue\"X\n\030FesDebugToolValueVar" + "iant\022\021\n\tint_value\030\001 \001(\005\022\023\n\013float_value\030\002" + " \001(\002\022\024\n\014double_value\030\003 \001(\001\"-\n\034FesDebugTo" + "olValueSetSimParam\022\r\n\005value\030\001 \002(\001\"g\n\033Fes" + "DebugToolLineSetSimParam\022\021\n\tmin_value\030\001 " + "\002(\001\022\021\n\tmax_value\030\002 \002(\001\022\022\n\nstep_value\030\003 \002" + "(\001\022\016\n\006period\030\004 \002(\005\"S\n\033FesDebugToolRandSe" + "tSimParam\022\021\n\tmin_value\030\001 \001(\001\022\021\n\tmax_valu" + "e\030\002 \001(\001\022\016\n\006period\030\003 \002(\005\"\355\002\n\035FesDebugTool" + "ValueSimSetReqMsg\022,\n\010sim_mode\030\001 \002(\0162\032.io" + "t_idl.enFesDebugSimMode\0222\n\tsim_range\030\002 \002" + "(\0162\037.iot_idl.enFesDebugSimRangeType\022\016\n\006r" + "tu_no\030\003 \001(\005\022\016\n\006pnt_no\030\004 \001(\005\022\016\n\006status\030\005 " + "\001(\r\022>\n\017value_set_param\030\006 \001(\0132%.iot_idl.F" + "esDebugToolValueSetSimParam\022<\n\016line_set_" + "param\030\007 \001(\0132$.iot_idl.FesDebugToolLineSe" + "tSimParam\022<\n\016rand_set_param\030\010 \001(\0132$.iot_" + "idl.FesDebugToolRandSetSimParam\"[\n\035FesDe" + "bugToolValueSimSetRepMsg\022,\n\010sim_mode\030\001 \002" + "(\0162\032.iot_idl.enFesDebugSimMode\022\014\n\004body\030\002" + " \001(\t\"\255\001\n\032FesDebugToolSimEventRtuSoe\022\024\n\014e" + "vent_source\030\001 \002(\005\022\016\n\006rtu_no\030\002 \002(\005\022\016\n\006pnt" + "_no\030\003 \002(\005\022\r\n\005value\030\004 \002(\005\022\016\n\006status\030\005 \002(\r" + "\022\021\n\tfault_num\030\006 \002(\005\022\022\n\nfault_type\030\007 \003(\005\022" + "\023\n\013fault_value\030\010 \003(\002\"\213\001\n FesDebugToolSim" + "EventCreateReqMsg\0223\n\nevent_type\030\001 \002(\0162\037." + "iot_idl.enFesDebugEventSimType\0222\n\005event\030" + "\002 \001(\0132#.iot_idl.FesDebugToolSimEventRtuS" + "oe\"e\n FesDebugToolSimEventCreateRepMsg\0223" + "\n\nevent_type\030\001 \002(\0162\037.iot_idl.enFesDebugE" + "ventSimType\022\014\n\004body\030\002 \001(\t\"\211\001\n\034FesDebugTo" + "olSimControlReqMsg\022\021\n\tctrl_type\030\001 \002(\005\022\016\n" + "\006seq_no\030\002 \002(\003\022\016\n\006rtu_no\030\003 \002(\005\022\016\n\006pnt_no\030" + "\004 \002(\005\022\023\n\013float_value\030\005 \001(\002\022\021\n\tint_value\030" + "\006 \001(\005\"c\n\034FesDebugToolSimControlRepMsg\022\021\n" + "\tctrl_type\030\001 \002(\005\022\016\n\006seq_no\030\002 \002(\003\022\017\n\007succ" + "ess\030\003 \002(\010\022\017\n\007err_msg\030\004 \001(\t\"[\n\033FesDebugTo" + "olSimDefCmdReqMsg\022\016\n\006rtu_no\030\001 \002(\005\022\016\n\006dev" + "_id\030\002 \002(\005\022\014\n\004keys\030\003 \003(\t\022\016\n\006values\030\004 \003(\t\"" + "p\n\026FesDebugToolFwPntParam\022\016\n\006pnt_no\030\001 \002(" + "\005\022\014\n\004used\030\002 \002(\005\022\022\n\nfes_rtu_no\030\003 \002(\005\022\022\n\nf" + "es_pnt_no\030\004 \002(\005\022\020\n\010pnt_desc\030\005 \002(\t\"w\n\034Fes" + "DebugToolFwPntParamRepMsg\022\016\n\006rtu_no\030\001 \002(" + "\005\022\023\n\013max_pnt_num\030\002 \002(\005\0222\n\tpnt_param\030\003 \003(" + "\0132\037.iot_idl.FesDebugToolFwPntParam\"\267\001\n\024F" + "esDebugToolSoeEvent\022\022\n\ntable_name\030\001 \002(\t\022" + "\020\n\010col_name\030\002 \002(\t\022\020\n\010tag_name\030\003 \002(\t\022\016\n\006s" + "tatus\030\004 \002(\r\022\r\n\005value\030\005 \002(\005\022\014\n\004time\030\006 \002(\004" + "\022\021\n\tfault_num\030\007 \002(\005\022\022\n\nfault_type\030\010 \003(\005\022" + "\023\n\013fault_value\030\t \003(\002\"]\n\032FesDebugToolSoeE" + "ventRepMsg\022\021\n\tover_flow\030\001 \002(\005\022,\n\005event\030\002" + " \003(\0132\035.iot_idl.FesDebugToolSoeEvent\"Y\n\025F" + "esDebugToolChanEvent\022\020\n\010tag_name\030\001 \002(\t\022\016" + "\n\006status\030\002 \002(\r\022\020\n\010err_rate\030\003 \002(\002\022\014\n\004time" + "\030\004 \002(\004\"_\n\033FesDebugToolChanEventRepMsg\022\021\n" + "\tover_flow\030\001 \002(\005\022-\n\005event\030\002 \003(\0132\036.iot_id" + "l.FesDebugToolChanEvent\"/\n\034FesDebugToolC" + "hanMonCmdReqMsg\022\017\n\007chan_no\030\001 \002(\005\"`\n\034FesD" + "ebugToolChanMonCmdRepMsg\022\017\n\007chan_no\030\001 \002(" + "\005\022\016\n\006rx_num\030\002 \001(\005\022\016\n\006tx_num\030\003 \001(\005\022\017\n\007err" + "_num\030\004 \001(\005\"]\n\030FesDebugToolChanMonFrame\022\022" + "\n\nframe_type\030\001 \002(\005\022\021\n\tdata_type\030\002 \002(\005\022\014\n" + "\004time\030\003 \002(\004\022\014\n\004data\030\004 \002(\014\"\243\001\n\032FesDebugTo" + "olChanMonInfoMsg\022\017\n\007chan_no\030\001 \002(\005\022\016\n\006rx_" + "num\030\002 \002(\005\022\016\n\006tx_num\030\003 \002(\005\022\017\n\007err_num\030\004 \002" + "(\005\022\021\n\tover_flow\030\005 \002(\005\0220\n\005frame\030\006 \003(\0132!.i" + "ot_idl.FesDebugToolChanMonFrame*\213\020\n\021enFe" + "sDebugMsgType\022\027\n\023MT_FESDBG_HeartBeat\020\000\022\025" + "\n\021MT_FESDBG_CONNECT\020\001\022\030\n\024MT_FESDBG_DISCO" + "NNECT\020\002\022\027\n\023MT_FESDBG_ChanParam\020\005\022\026\n\022MT_F" + "ESDBG_RtuParam\020\006\022\030\n\024MT_FESDBG_AI_RtuInfo" + "\020\n\022\026\n\022MT_FESDBG_AI_Param\020\013\022\026\n\022MT_FESDBG_" + "AI_Value\020\014\022\030\n\024MT_FESDBG_DI_RtuInfo\020\024\022\026\n\022" + "MT_FESDBG_DI_Param\020\025\022\026\n\022MT_FESDBG_DI_Val" + "ue\020\026\022\031\n\025MT_FESDBG_ACC_RtuInfo\020\036\022\027\n\023MT_FE" + "SDBG_ACC_Param\020\037\022\027\n\023MT_FESDBG_ACC_Value\020" + " \022\030\n\024MT_FESDBG_MI_RtuInfo\020(\022\026\n\022MT_FESDBG" + "_MI_Param\020)\022\026\n\022MT_FESDBG_MI_Value\020*\022\033\n\027M" + "T_FESDBG_SimAI_RtuInfo\0202\022\031\n\025MT_FESDBG_Si" + "mAI_Param\0203\022\031\n\025MT_FESDBG_SimAI_Value\0204\022\034" + "\n\030MT_FESDBG_SimAI_StartSim\0205\022\033\n\027MT_FESDB" + "G_SimAI_StopSim\0206\022\033\n\027MT_FESDBG_SimDI_Rtu" + "Info\020<\022\031\n\025MT_FESDBG_SimDI_Param\020=\022\031\n\025MT_" + "FESDBG_SimDI_Value\020>\022\034\n\030MT_FESDBG_SimDI_" + "StartSim\020\?\022\033\n\027MT_FESDBG_SimDI_StopSim\020@\022" + "\033\n\027MT_FESDBG_SimMI_RtuInfo\020F\022\031\n\025MT_FESDB" + "G_SimMI_Param\020G\022\031\n\025MT_FESDBG_SimMI_Value" + "\020H\022\034\n\030MT_FESDBG_SimMI_StartSim\020I\022\033\n\027MT_F" + "ESDBG_SimMI_StopSim\020J\022\034\n\030MT_FESDBG_SimAC" + "C_RtuInfo\020P\022\032\n\026MT_FESDBG_SimACC_Param\020Q\022" + "\032\n\026MT_FESDBG_SimACC_Value\020R\022\035\n\031MT_FESDBG" + "_SimACC_StartSim\020S\022\034\n\030MT_FESDBG_SimACC_S" + "topSim\020T\022\036\n\032MT_FESDBG_SimEvent_RtuInfo\020Z" + "\022\036\n\032MT_FESDBG_SimEvent_DiParam\020[\022\035\n\031MT_F" + "ESDBG_SimEvent_Create\020\\\022\033\n\027MT_FESDBG_Sim" + "AO_RtuInfo\020d\022\031\n\025MT_FESDBG_SimAO_Param\020e\022" + "\033\n\027MT_FESDBG_SimAO_Control\020f\022\033\n\027MT_FESDB" + "G_SimDO_RtuInfo\020n\022\031\n\025MT_FESDBG_SimDO_Par" + "am\020o\022\033\n\027MT_FESDBG_SimDO_Control\020p\022\033\n\027MT_" + "FESDBG_SimMO_RtuInfo\020x\022\031\n\025MT_FESDBG_SimM" + "O_Param\020y\022\033\n\027MT_FESDBG_SimMO_Control\020z\022 " + "\n\033MT_FESDBG_SimDefCmd_RtuInfo\020\202\001\022 \n\033MT_F" + "ESDBG_SimDefCmd_Control\020\203\001\022\033\n\026MT_FESDBG_" + "FWAI_RtuInfo\020\214\001\022\031\n\024MT_FESDBG_FWAI_Param\020" + "\215\001\022\031\n\024MT_FESDBG_FWAI_Value\020\216\001\022\033\n\026MT_FESD" + "BG_FWDI_RtuInfo\020\226\001\022\031\n\024MT_FESDBG_FWDI_Par" + "am\020\227\001\022\031\n\024MT_FESDBG_FWDI_Value\020\230\001\022\034\n\027MT_F" + "ESDBG_FWDDI_RtuInfo\020\240\001\022\032\n\025MT_FESDBG_FWDD" + "I_Param\020\241\001\022\032\n\025MT_FESDBG_FWDDI_Value\020\242\001\022\033" + "\n\026MT_FESDBG_FWMI_RtuInfo\020\252\001\022\031\n\024MT_FESDBG" + "_FWMI_Param\020\253\001\022\031\n\024MT_FESDBG_FWMI_Value\020\254" + "\001\022\034\n\027MT_FESDBG_FWACC_RtuInfo\020\264\001\022\032\n\025MT_FE" + "SDBG_FWACC_Param\020\265\001\022\032\n\025MT_FESDBG_FWACC_V" + "alue\020\266\001\022\030\n\023MT_FESDBG_Event_SOE\020\276\001\022\034\n\027MT_" + "FESDBG_Event_Channel\020\277\001\022\036\n\031MT_FESDBG_Eve" + "nt_SOEMemory\020\300\001\022\034\n\027MT_FESDBG_Mon_ChanSta" + "rt\020\310\001\022\033\n\026MT_FESDBG_Mon_ChanStop\020\311\001\022\034\n\027MT" + "_FESDBG_Mon_ChanClear\020\312\001\022\033\n\026MT_FESDBG_Mo" + "n_ChanInfo\020\313\001*b\n\021enFesDebugSimMode\022\031\n\025MT" + "_FESDBG_SM_ValueSet\020\001\022\030\n\024MT_FESDBG_SM_Li" + "neSet\020\002\022\030\n\024MT_FESDBG_SM_RandSet\020\003*l\n\026enF" + "esDebugSimRangeType\022\034\n\030MT_FESDBG_RT_Sing" + "lePoint\020\001\022\031\n\025MT_FESDBG_RT_RtuPoint\020\002\022\031\n\025" + "MT_FESDBG_RT_AllPoint\020\003*L\n\026enFesDebugEve" + "ntSimType\022\030\n\024MT_FESDBG_EST_RtuSoe\020\001\022\030\n\024M" + "T_FESDBG_EST_FepSoe\020\002", 7061); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "FesDebugTool.proto", &protobuf_RegisterTypes); + FesDebugToolReqMsg::default_instance_ = new FesDebugToolReqMsg(); + FesDebugToolRepMsg::default_instance_ = new FesDebugToolRepMsg(); + FesDebugToolNetRoute::default_instance_ = new FesDebugToolNetRoute(); + FesDebugToolChanParam::default_instance_ = new FesDebugToolChanParam(); + FesDebugToolChanParamRepMsg::default_instance_ = new FesDebugToolChanParamRepMsg(); + FesDebugToolRtuParam::default_instance_ = new FesDebugToolRtuParam(); + FesDebugToolRtuParamRepMsg::default_instance_ = new FesDebugToolRtuParamRepMsg(); + FesDebugToolRtuInfo::default_instance_ = new FesDebugToolRtuInfo(); + FesDebugToolRtuInfoRepMsg::default_instance_ = new FesDebugToolRtuInfoRepMsg(); + FesDebugToolPntParamReqMsg::default_instance_ = new FesDebugToolPntParamReqMsg(); + FesDebugToolPntParam::default_instance_ = new FesDebugToolPntParam(); + FesDebugToolPntParamRepMsg::default_instance_ = new FesDebugToolPntParamRepMsg(); + FesDebugToolPntValueReqMsg::default_instance_ = new FesDebugToolPntValueReqMsg(); + FesDebugToolIntPntValue::default_instance_ = new FesDebugToolIntPntValue(); + FesDebugToolFloatPntValue::default_instance_ = new FesDebugToolFloatPntValue(); + FesDebugToolDoublePntValue::default_instance_ = new FesDebugToolDoublePntValue(); + FesDebugToolPntValueRepMsg::default_instance_ = new FesDebugToolPntValueRepMsg(); + FesDebugToolValueVariant::default_instance_ = new FesDebugToolValueVariant(); + FesDebugToolValueSetSimParam::default_instance_ = new FesDebugToolValueSetSimParam(); + FesDebugToolLineSetSimParam::default_instance_ = new FesDebugToolLineSetSimParam(); + FesDebugToolRandSetSimParam::default_instance_ = new FesDebugToolRandSetSimParam(); + FesDebugToolValueSimSetReqMsg::default_instance_ = new FesDebugToolValueSimSetReqMsg(); + FesDebugToolValueSimSetRepMsg::default_instance_ = new FesDebugToolValueSimSetRepMsg(); + FesDebugToolSimEventRtuSoe::default_instance_ = new FesDebugToolSimEventRtuSoe(); + FesDebugToolSimEventCreateReqMsg::default_instance_ = new FesDebugToolSimEventCreateReqMsg(); + FesDebugToolSimEventCreateRepMsg::default_instance_ = new FesDebugToolSimEventCreateRepMsg(); + FesDebugToolSimControlReqMsg::default_instance_ = new FesDebugToolSimControlReqMsg(); + FesDebugToolSimControlRepMsg::default_instance_ = new FesDebugToolSimControlRepMsg(); + FesDebugToolSimDefCmdReqMsg::default_instance_ = new FesDebugToolSimDefCmdReqMsg(); + FesDebugToolFwPntParam::default_instance_ = new FesDebugToolFwPntParam(); + FesDebugToolFwPntParamRepMsg::default_instance_ = new FesDebugToolFwPntParamRepMsg(); + FesDebugToolSoeEvent::default_instance_ = new FesDebugToolSoeEvent(); + FesDebugToolSoeEventRepMsg::default_instance_ = new FesDebugToolSoeEventRepMsg(); + FesDebugToolChanEvent::default_instance_ = new FesDebugToolChanEvent(); + FesDebugToolChanEventRepMsg::default_instance_ = new FesDebugToolChanEventRepMsg(); + FesDebugToolChanMonCmdReqMsg::default_instance_ = new FesDebugToolChanMonCmdReqMsg(); + FesDebugToolChanMonCmdRepMsg::default_instance_ = new FesDebugToolChanMonCmdRepMsg(); + FesDebugToolChanMonFrame::default_instance_ = new FesDebugToolChanMonFrame(); + FesDebugToolChanMonInfoMsg::default_instance_ = new FesDebugToolChanMonInfoMsg(); + FesDebugToolReqMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolNetRoute::default_instance_->InitAsDefaultInstance(); + FesDebugToolChanParam::default_instance_->InitAsDefaultInstance(); + FesDebugToolChanParamRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolRtuParam::default_instance_->InitAsDefaultInstance(); + FesDebugToolRtuParamRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolRtuInfo::default_instance_->InitAsDefaultInstance(); + FesDebugToolRtuInfoRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolPntParamReqMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolPntParam::default_instance_->InitAsDefaultInstance(); + FesDebugToolPntParamRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolPntValueReqMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolIntPntValue::default_instance_->InitAsDefaultInstance(); + FesDebugToolFloatPntValue::default_instance_->InitAsDefaultInstance(); + FesDebugToolDoublePntValue::default_instance_->InitAsDefaultInstance(); + FesDebugToolPntValueRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolValueVariant::default_instance_->InitAsDefaultInstance(); + FesDebugToolValueSetSimParam::default_instance_->InitAsDefaultInstance(); + FesDebugToolLineSetSimParam::default_instance_->InitAsDefaultInstance(); + FesDebugToolRandSetSimParam::default_instance_->InitAsDefaultInstance(); + FesDebugToolValueSimSetReqMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolValueSimSetRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolSimEventRtuSoe::default_instance_->InitAsDefaultInstance(); + FesDebugToolSimEventCreateReqMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolSimEventCreateRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolSimControlReqMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolSimControlRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolSimDefCmdReqMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolFwPntParam::default_instance_->InitAsDefaultInstance(); + FesDebugToolFwPntParamRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolSoeEvent::default_instance_->InitAsDefaultInstance(); + FesDebugToolSoeEventRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolChanEvent::default_instance_->InitAsDefaultInstance(); + FesDebugToolChanEventRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolChanMonCmdReqMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolChanMonCmdRepMsg::default_instance_->InitAsDefaultInstance(); + FesDebugToolChanMonFrame::default_instance_->InitAsDefaultInstance(); + FesDebugToolChanMonInfoMsg::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_FesDebugTool_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_FesDebugTool_2eproto { + StaticDescriptorInitializer_FesDebugTool_2eproto() { + protobuf_AddDesc_FesDebugTool_2eproto(); + } +} static_descriptor_initializer_FesDebugTool_2eproto_; +const ::google::protobuf::EnumDescriptor* enFesDebugMsgType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return enFesDebugMsgType_descriptor_; +} +bool enFesDebugMsgType_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 5: + case 6: + case 10: + case 11: + case 12: + case 20: + case 21: + case 22: + case 30: + case 31: + case 32: + case 40: + case 41: + case 42: + case 50: + case 51: + case 52: + case 53: + case 54: + case 60: + case 61: + case 62: + case 63: + case 64: + case 70: + case 71: + case 72: + case 73: + case 74: + case 80: + case 81: + case 82: + case 83: + case 84: + case 90: + case 91: + case 92: + case 100: + case 101: + case 102: + case 110: + case 111: + case 112: + case 120: + case 121: + case 122: + case 130: + case 131: + case 140: + case 141: + case 142: + case 150: + case 151: + case 152: + case 160: + case 161: + case 162: + case 170: + case 171: + case 172: + case 180: + case 181: + case 182: + case 190: + case 191: + case 192: + case 200: + case 201: + case 202: + case 203: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* enFesDebugSimMode_descriptor() { + protobuf_AssignDescriptorsOnce(); + return enFesDebugSimMode_descriptor_; +} +bool enFesDebugSimMode_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* enFesDebugSimRangeType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return enFesDebugSimRangeType_descriptor_; +} +bool enFesDebugSimRangeType_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* enFesDebugEventSimType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return enFesDebugEventSimType_descriptor_; +} +bool enFesDebugEventSimType_IsValid(int value) { + switch(value) { + case 1: + case 2: + return true; + default: + return false; + } +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolReqMsg::kTypeFieldNumber; +const int FesDebugToolReqMsg::kBodyFieldNumber; +#endif // !_MSC_VER + +FesDebugToolReqMsg::FesDebugToolReqMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolReqMsg) +} + +void FesDebugToolReqMsg::InitAsDefaultInstance() { +} + +FesDebugToolReqMsg::FesDebugToolReqMsg(const FesDebugToolReqMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolReqMsg) +} + +void FesDebugToolReqMsg::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + type_ = 0; + body_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolReqMsg::~FesDebugToolReqMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolReqMsg) + SharedDtor(); +} + +void FesDebugToolReqMsg::SharedDtor() { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete body_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolReqMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolReqMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolReqMsg_descriptor_; +} + +const FesDebugToolReqMsg& FesDebugToolReqMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolReqMsg* FesDebugToolReqMsg::default_instance_ = NULL; + +FesDebugToolReqMsg* FesDebugToolReqMsg::New() const { + return new FesDebugToolReqMsg; +} + +void FesDebugToolReqMsg::Clear() { + if (_has_bits_[0 / 32] & 3) { + type_ = 0; + if (has_body()) { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolReqMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolReqMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .iot_idl.enFesDebugMsgType type = 1; + case 1: { + if (tag == 8) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::iot_idl::enFesDebugMsgType_IsValid(value)) { + set_type(static_cast< ::iot_idl::enFesDebugMsgType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_body; + break; + } + + // optional string body = 2; + case 2: { + if (tag == 18) { + parse_body: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_body())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->body().data(), this->body().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "body"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolReqMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolReqMsg) + return false; +#undef DO_ +} + +void FesDebugToolReqMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolReqMsg) + // required .iot_idl.enFesDebugMsgType type = 1; + if (has_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->type(), output); + } + + // optional string body = 2; + if (has_body()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->body().data(), this->body().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "body"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->body(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolReqMsg) +} + +::google::protobuf::uint8* FesDebugToolReqMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolReqMsg) + // required .iot_idl.enFesDebugMsgType type = 1; + if (has_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->type(), target); + } + + // optional string body = 2; + if (has_body()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->body().data(), this->body().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "body"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->body(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolReqMsg) + return target; +} + +int FesDebugToolReqMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .iot_idl.enFesDebugMsgType type = 1; + if (has_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); + } + + // optional string body = 2; + if (has_body()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->body()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolReqMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolReqMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolReqMsg::MergeFrom(const FesDebugToolReqMsg& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_type()) { + set_type(from.type()); + } + if (from.has_body()) { + set_body(from.body()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolReqMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolReqMsg::CopyFrom(const FesDebugToolReqMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolReqMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void FesDebugToolReqMsg::Swap(FesDebugToolReqMsg* other) { + if (other != this) { + std::swap(type_, other->type_); + std::swap(body_, other->body_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolReqMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolReqMsg_descriptor_; + metadata.reflection = FesDebugToolReqMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolRepMsg::kSuccessFieldNumber; +const int FesDebugToolRepMsg::kErrMsgFieldNumber; +const int FesDebugToolRepMsg::kTypeFieldNumber; +const int FesDebugToolRepMsg::kBodyFieldNumber; +#endif // !_MSC_VER + +FesDebugToolRepMsg::FesDebugToolRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolRepMsg) +} + +void FesDebugToolRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolRepMsg::FesDebugToolRepMsg(const FesDebugToolRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolRepMsg) +} + +void FesDebugToolRepMsg::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + success_ = false; + err_msg_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + type_ = 0; + body_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolRepMsg::~FesDebugToolRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolRepMsg) + SharedDtor(); +} + +void FesDebugToolRepMsg::SharedDtor() { + if (err_msg_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete err_msg_; + } + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete body_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolRepMsg_descriptor_; +} + +const FesDebugToolRepMsg& FesDebugToolRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolRepMsg* FesDebugToolRepMsg::default_instance_ = NULL; + +FesDebugToolRepMsg* FesDebugToolRepMsg::New() const { + return new FesDebugToolRepMsg; +} + +void FesDebugToolRepMsg::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 15) { + ZR_(success_, type_); + if (has_err_msg()) { + if (err_msg_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + err_msg_->clear(); + } + } + if (has_body()) { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required bool success = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &success_))); + set_has_success(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_err_msg; + break; + } + + // optional string err_msg = 2; + case 2: { + if (tag == 18) { + parse_err_msg: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_err_msg())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->err_msg().data(), this->err_msg().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "err_msg"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_type; + break; + } + + // required .iot_idl.enFesDebugMsgType type = 3; + case 3: { + if (tag == 24) { + parse_type: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::iot_idl::enFesDebugMsgType_IsValid(value)) { + set_type(static_cast< ::iot_idl::enFesDebugMsgType >(value)); + } else { + mutable_unknown_fields()->AddVarint(3, value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_body; + break; + } + + // optional string body = 4; + case 4: { + if (tag == 34) { + parse_body: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_body())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->body().data(), this->body().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "body"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolRepMsg) + // required bool success = 1; + if (has_success()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->success(), output); + } + + // optional string err_msg = 2; + if (has_err_msg()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->err_msg().data(), this->err_msg().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "err_msg"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->err_msg(), output); + } + + // required .iot_idl.enFesDebugMsgType type = 3; + if (has_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 3, this->type(), output); + } + + // optional string body = 4; + if (has_body()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->body().data(), this->body().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "body"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 4, this->body(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolRepMsg) +} + +::google::protobuf::uint8* FesDebugToolRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolRepMsg) + // required bool success = 1; + if (has_success()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->success(), target); + } + + // optional string err_msg = 2; + if (has_err_msg()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->err_msg().data(), this->err_msg().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "err_msg"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->err_msg(), target); + } + + // required .iot_idl.enFesDebugMsgType type = 3; + if (has_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 3, this->type(), target); + } + + // optional string body = 4; + if (has_body()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->body().data(), this->body().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "body"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->body(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolRepMsg) + return target; +} + +int FesDebugToolRepMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required bool success = 1; + if (has_success()) { + total_size += 1 + 1; + } + + // optional string err_msg = 2; + if (has_err_msg()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->err_msg()); + } + + // required .iot_idl.enFesDebugMsgType type = 3; + if (has_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); + } + + // optional string body = 4; + if (has_body()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->body()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolRepMsg::MergeFrom(const FesDebugToolRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_success()) { + set_success(from.success()); + } + if (from.has_err_msg()) { + set_err_msg(from.err_msg()); + } + if (from.has_type()) { + set_type(from.type()); + } + if (from.has_body()) { + set_body(from.body()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolRepMsg::CopyFrom(const FesDebugToolRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolRepMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000005) != 0x00000005) return false; + + return true; +} + +void FesDebugToolRepMsg::Swap(FesDebugToolRepMsg* other) { + if (other != this) { + std::swap(success_, other->success_); + std::swap(err_msg_, other->err_msg_); + std::swap(type_, other->type_); + std::swap(body_, other->body_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolRepMsg_descriptor_; + metadata.reflection = FesDebugToolRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolNetRoute::kDescFieldNumber; +const int FesDebugToolNetRoute::kPortNoFieldNumber; +#endif // !_MSC_VER + +FesDebugToolNetRoute::FesDebugToolNetRoute() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolNetRoute) +} + +void FesDebugToolNetRoute::InitAsDefaultInstance() { +} + +FesDebugToolNetRoute::FesDebugToolNetRoute(const FesDebugToolNetRoute& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolNetRoute) +} + +void FesDebugToolNetRoute::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + port_no_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolNetRoute::~FesDebugToolNetRoute() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolNetRoute) + SharedDtor(); +} + +void FesDebugToolNetRoute::SharedDtor() { + if (desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete desc_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolNetRoute::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolNetRoute::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolNetRoute_descriptor_; +} + +const FesDebugToolNetRoute& FesDebugToolNetRoute::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolNetRoute* FesDebugToolNetRoute::default_instance_ = NULL; + +FesDebugToolNetRoute* FesDebugToolNetRoute::New() const { + return new FesDebugToolNetRoute; +} + +void FesDebugToolNetRoute::Clear() { + if (_has_bits_[0 / 32] & 3) { + if (has_desc()) { + if (desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + desc_->clear(); + } + } + port_no_ = 0; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolNetRoute::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolNetRoute) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string desc = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_desc())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->desc().data(), this->desc().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "desc"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_port_no; + break; + } + + // required int32 port_no = 2; + case 2: { + if (tag == 16) { + parse_port_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &port_no_))); + set_has_port_no(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolNetRoute) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolNetRoute) + return false; +#undef DO_ +} + +void FesDebugToolNetRoute::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolNetRoute) + // required string desc = 1; + if (has_desc()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->desc().data(), this->desc().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "desc"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->desc(), output); + } + + // required int32 port_no = 2; + if (has_port_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->port_no(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolNetRoute) +} + +::google::protobuf::uint8* FesDebugToolNetRoute::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolNetRoute) + // required string desc = 1; + if (has_desc()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->desc().data(), this->desc().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "desc"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->desc(), target); + } + + // required int32 port_no = 2; + if (has_port_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->port_no(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolNetRoute) + return target; +} + +int FesDebugToolNetRoute::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string desc = 1; + if (has_desc()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->desc()); + } + + // required int32 port_no = 2; + if (has_port_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->port_no()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolNetRoute::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolNetRoute* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolNetRoute::MergeFrom(const FesDebugToolNetRoute& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_desc()) { + set_desc(from.desc()); + } + if (from.has_port_no()) { + set_port_no(from.port_no()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolNetRoute::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolNetRoute::CopyFrom(const FesDebugToolNetRoute& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolNetRoute::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void FesDebugToolNetRoute::Swap(FesDebugToolNetRoute* other) { + if (other != this) { + std::swap(desc_, other->desc_); + std::swap(port_no_, other->port_no_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolNetRoute::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolNetRoute_descriptor_; + metadata.reflection = FesDebugToolNetRoute_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolChanParam::kChanNoFieldNumber; +const int FesDebugToolChanParam::kTagNameFieldNumber; +const int FesDebugToolChanParam::kChanNameFieldNumber; +const int FesDebugToolChanParam::kUsedFieldNumber; +const int FesDebugToolChanParam::kChanStatusFieldNumber; +const int FesDebugToolChanParam::kCommTypeFieldNumber; +const int FesDebugToolChanParam::kChanModeFieldNumber; +const int FesDebugToolChanParam::kProtocolIdFieldNumber; +const int FesDebugToolChanParam::kNetRouteFieldNumber; +const int FesDebugToolChanParam::kConnectWaitSecFieldNumber; +const int FesDebugToolChanParam::kConnectTimeoutFieldNumber; +const int FesDebugToolChanParam::kRetryTimesFieldNumber; +const int FesDebugToolChanParam::kRecvTimeoutFieldNumber; +const int FesDebugToolChanParam::kRespTimeoutFieldNumber; +const int FesDebugToolChanParam::kMaxRxSizeFieldNumber; +const int FesDebugToolChanParam::kMaxTxSizeFieldNumber; +const int FesDebugToolChanParam::kErrRateLimitFieldNumber; +const int FesDebugToolChanParam::kBackupChanNoFieldNumber; +#endif // !_MSC_VER + +FesDebugToolChanParam::FesDebugToolChanParam() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolChanParam) +} + +void FesDebugToolChanParam::InitAsDefaultInstance() { +} + +FesDebugToolChanParam::FesDebugToolChanParam(const FesDebugToolChanParam& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolChanParam) +} + +void FesDebugToolChanParam::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + chan_no_ = 0; + tag_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + chan_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + used_ = 0; + chan_status_ = 0; + comm_type_ = 0; + chan_mode_ = 0; + protocol_id_ = 0; + connect_wait_sec_ = 0; + connect_timeout_ = 0; + retry_times_ = 0; + recv_timeout_ = 0; + resp_timeout_ = 0; + max_rx_size_ = 0; + max_tx_size_ = 0; + err_rate_limit_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolChanParam::~FesDebugToolChanParam() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolChanParam) + SharedDtor(); +} + +void FesDebugToolChanParam::SharedDtor() { + if (tag_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete tag_name_; + } + if (chan_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete chan_name_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolChanParam::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolChanParam::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolChanParam_descriptor_; +} + +const FesDebugToolChanParam& FesDebugToolChanParam::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolChanParam* FesDebugToolChanParam::default_instance_ = NULL; + +FesDebugToolChanParam* FesDebugToolChanParam::New() const { + return new FesDebugToolChanParam; +} + +void FesDebugToolChanParam::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 255) { + ZR_(chan_no_, used_); + ZR_(chan_status_, protocol_id_); + if (has_tag_name()) { + if (tag_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_->clear(); + } + } + if (has_chan_name()) { + if (chan_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + chan_name_->clear(); + } + } + } + if (_has_bits_[8 / 32] & 65024) { + ZR_(connect_wait_sec_, max_tx_size_); + } + err_rate_limit_ = 0; + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + net_route_.Clear(); + backup_chan_no_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolChanParam::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolChanParam) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 chan_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &chan_no_))); + set_has_chan_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_tag_name; + break; + } + + // required string tag_name = 2; + case 2: { + if (tag == 18) { + parse_tag_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_tag_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->tag_name().data(), this->tag_name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "tag_name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_chan_name; + break; + } + + // required string chan_name = 3; + case 3: { + if (tag == 26) { + parse_chan_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_chan_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->chan_name().data(), this->chan_name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "chan_name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_used; + break; + } + + // required int32 used = 4; + case 4: { + if (tag == 32) { + parse_used: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &used_))); + set_has_used(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_chan_status; + break; + } + + // required int32 chan_status = 5; + case 5: { + if (tag == 40) { + parse_chan_status: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &chan_status_))); + set_has_chan_status(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(48)) goto parse_comm_type; + break; + } + + // required int32 comm_type = 6; + case 6: { + if (tag == 48) { + parse_comm_type: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &comm_type_))); + set_has_comm_type(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(56)) goto parse_chan_mode; + break; + } + + // required int32 chan_mode = 7; + case 7: { + if (tag == 56) { + parse_chan_mode: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &chan_mode_))); + set_has_chan_mode(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(64)) goto parse_protocol_id; + break; + } + + // required int32 protocol_id = 8; + case 8: { + if (tag == 64) { + parse_protocol_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &protocol_id_))); + set_has_protocol_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(74)) goto parse_net_route; + break; + } + + // repeated .iot_idl.FesDebugToolNetRoute net_route = 9; + case 9: { + if (tag == 74) { + parse_net_route: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_net_route())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(74)) goto parse_net_route; + if (input->ExpectTag(80)) goto parse_connect_wait_sec; + break; + } + + // required int32 connect_wait_sec = 10; + case 10: { + if (tag == 80) { + parse_connect_wait_sec: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &connect_wait_sec_))); + set_has_connect_wait_sec(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(88)) goto parse_connect_timeout; + break; + } + + // required int32 connect_timeout = 11; + case 11: { + if (tag == 88) { + parse_connect_timeout: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &connect_timeout_))); + set_has_connect_timeout(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(96)) goto parse_retry_times; + break; + } + + // required int32 retry_times = 12; + case 12: { + if (tag == 96) { + parse_retry_times: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &retry_times_))); + set_has_retry_times(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(104)) goto parse_recv_timeout; + break; + } + + // required int32 recv_timeout = 13; + case 13: { + if (tag == 104) { + parse_recv_timeout: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &recv_timeout_))); + set_has_recv_timeout(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(112)) goto parse_resp_timeout; + break; + } + + // required int32 resp_timeout = 14; + case 14: { + if (tag == 112) { + parse_resp_timeout: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &resp_timeout_))); + set_has_resp_timeout(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(120)) goto parse_max_rx_size; + break; + } + + // required int32 max_rx_size = 15; + case 15: { + if (tag == 120) { + parse_max_rx_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &max_rx_size_))); + set_has_max_rx_size(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(128)) goto parse_max_tx_size; + break; + } + + // required int32 max_tx_size = 16; + case 16: { + if (tag == 128) { + parse_max_tx_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &max_tx_size_))); + set_has_max_tx_size(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(141)) goto parse_err_rate_limit; + break; + } + + // required float err_rate_limit = 17; + case 17: { + if (tag == 141) { + parse_err_rate_limit: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &err_rate_limit_))); + set_has_err_rate_limit(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(144)) goto parse_backup_chan_no; + break; + } + + // repeated int32 backup_chan_no = 18; + case 18: { + if (tag == 144) { + parse_backup_chan_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + 2, 144, input, this->mutable_backup_chan_no()))); + } else if (tag == 146) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, this->mutable_backup_chan_no()))); + } else { + goto handle_unusual; + } + if (input->ExpectTag(144)) goto parse_backup_chan_no; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolChanParam) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolChanParam) + return false; +#undef DO_ +} + +void FesDebugToolChanParam::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolChanParam) + // required int32 chan_no = 1; + if (has_chan_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->chan_no(), output); + } + + // required string tag_name = 2; + if (has_tag_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->tag_name().data(), this->tag_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "tag_name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->tag_name(), output); + } + + // required string chan_name = 3; + if (has_chan_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->chan_name().data(), this->chan_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "chan_name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 3, this->chan_name(), output); + } + + // required int32 used = 4; + if (has_used()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->used(), output); + } + + // required int32 chan_status = 5; + if (has_chan_status()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(5, this->chan_status(), output); + } + + // required int32 comm_type = 6; + if (has_comm_type()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(6, this->comm_type(), output); + } + + // required int32 chan_mode = 7; + if (has_chan_mode()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(7, this->chan_mode(), output); + } + + // required int32 protocol_id = 8; + if (has_protocol_id()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(8, this->protocol_id(), output); + } + + // repeated .iot_idl.FesDebugToolNetRoute net_route = 9; + for (int i = 0; i < this->net_route_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 9, this->net_route(i), output); + } + + // required int32 connect_wait_sec = 10; + if (has_connect_wait_sec()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(10, this->connect_wait_sec(), output); + } + + // required int32 connect_timeout = 11; + if (has_connect_timeout()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(11, this->connect_timeout(), output); + } + + // required int32 retry_times = 12; + if (has_retry_times()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(12, this->retry_times(), output); + } + + // required int32 recv_timeout = 13; + if (has_recv_timeout()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(13, this->recv_timeout(), output); + } + + // required int32 resp_timeout = 14; + if (has_resp_timeout()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(14, this->resp_timeout(), output); + } + + // required int32 max_rx_size = 15; + if (has_max_rx_size()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(15, this->max_rx_size(), output); + } + + // required int32 max_tx_size = 16; + if (has_max_tx_size()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(16, this->max_tx_size(), output); + } + + // required float err_rate_limit = 17; + if (has_err_rate_limit()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(17, this->err_rate_limit(), output); + } + + // repeated int32 backup_chan_no = 18; + for (int i = 0; i < this->backup_chan_no_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteInt32( + 18, this->backup_chan_no(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolChanParam) +} + +::google::protobuf::uint8* FesDebugToolChanParam::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolChanParam) + // required int32 chan_no = 1; + if (has_chan_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->chan_no(), target); + } + + // required string tag_name = 2; + if (has_tag_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->tag_name().data(), this->tag_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "tag_name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->tag_name(), target); + } + + // required string chan_name = 3; + if (has_chan_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->chan_name().data(), this->chan_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "chan_name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->chan_name(), target); + } + + // required int32 used = 4; + if (has_used()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->used(), target); + } + + // required int32 chan_status = 5; + if (has_chan_status()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(5, this->chan_status(), target); + } + + // required int32 comm_type = 6; + if (has_comm_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(6, this->comm_type(), target); + } + + // required int32 chan_mode = 7; + if (has_chan_mode()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(7, this->chan_mode(), target); + } + + // required int32 protocol_id = 8; + if (has_protocol_id()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(8, this->protocol_id(), target); + } + + // repeated .iot_idl.FesDebugToolNetRoute net_route = 9; + for (int i = 0; i < this->net_route_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 9, this->net_route(i), target); + } + + // required int32 connect_wait_sec = 10; + if (has_connect_wait_sec()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(10, this->connect_wait_sec(), target); + } + + // required int32 connect_timeout = 11; + if (has_connect_timeout()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(11, this->connect_timeout(), target); + } + + // required int32 retry_times = 12; + if (has_retry_times()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(12, this->retry_times(), target); + } + + // required int32 recv_timeout = 13; + if (has_recv_timeout()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(13, this->recv_timeout(), target); + } + + // required int32 resp_timeout = 14; + if (has_resp_timeout()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(14, this->resp_timeout(), target); + } + + // required int32 max_rx_size = 15; + if (has_max_rx_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(15, this->max_rx_size(), target); + } + + // required int32 max_tx_size = 16; + if (has_max_tx_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(16, this->max_tx_size(), target); + } + + // required float err_rate_limit = 17; + if (has_err_rate_limit()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(17, this->err_rate_limit(), target); + } + + // repeated int32 backup_chan_no = 18; + for (int i = 0; i < this->backup_chan_no_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32ToArray(18, this->backup_chan_no(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolChanParam) + return target; +} + +int FesDebugToolChanParam::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 chan_no = 1; + if (has_chan_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->chan_no()); + } + + // required string tag_name = 2; + if (has_tag_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->tag_name()); + } + + // required string chan_name = 3; + if (has_chan_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->chan_name()); + } + + // required int32 used = 4; + if (has_used()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->used()); + } + + // required int32 chan_status = 5; + if (has_chan_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->chan_status()); + } + + // required int32 comm_type = 6; + if (has_comm_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->comm_type()); + } + + // required int32 chan_mode = 7; + if (has_chan_mode()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->chan_mode()); + } + + // required int32 protocol_id = 8; + if (has_protocol_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->protocol_id()); + } + + } + if (_has_bits_[9 / 32] & (0xffu << (9 % 32))) { + // required int32 connect_wait_sec = 10; + if (has_connect_wait_sec()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->connect_wait_sec()); + } + + // required int32 connect_timeout = 11; + if (has_connect_timeout()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->connect_timeout()); + } + + // required int32 retry_times = 12; + if (has_retry_times()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->retry_times()); + } + + // required int32 recv_timeout = 13; + if (has_recv_timeout()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->recv_timeout()); + } + + // required int32 resp_timeout = 14; + if (has_resp_timeout()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->resp_timeout()); + } + + // required int32 max_rx_size = 15; + if (has_max_rx_size()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->max_rx_size()); + } + + // required int32 max_tx_size = 16; + if (has_max_tx_size()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->max_tx_size()); + } + + } + if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) { + // required float err_rate_limit = 17; + if (has_err_rate_limit()) { + total_size += 2 + 4; + } + + } + // repeated .iot_idl.FesDebugToolNetRoute net_route = 9; + total_size += 1 * this->net_route_size(); + for (int i = 0; i < this->net_route_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->net_route(i)); + } + + // repeated int32 backup_chan_no = 18; + { + int data_size = 0; + for (int i = 0; i < this->backup_chan_no_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + Int32Size(this->backup_chan_no(i)); + } + total_size += 2 * this->backup_chan_no_size() + data_size; + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolChanParam::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolChanParam* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolChanParam::MergeFrom(const FesDebugToolChanParam& from) { + GOOGLE_CHECK_NE(&from, this); + net_route_.MergeFrom(from.net_route_); + backup_chan_no_.MergeFrom(from.backup_chan_no_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_chan_no()) { + set_chan_no(from.chan_no()); + } + if (from.has_tag_name()) { + set_tag_name(from.tag_name()); + } + if (from.has_chan_name()) { + set_chan_name(from.chan_name()); + } + if (from.has_used()) { + set_used(from.used()); + } + if (from.has_chan_status()) { + set_chan_status(from.chan_status()); + } + if (from.has_comm_type()) { + set_comm_type(from.comm_type()); + } + if (from.has_chan_mode()) { + set_chan_mode(from.chan_mode()); + } + if (from.has_protocol_id()) { + set_protocol_id(from.protocol_id()); + } + } + if (from._has_bits_[9 / 32] & (0xffu << (9 % 32))) { + if (from.has_connect_wait_sec()) { + set_connect_wait_sec(from.connect_wait_sec()); + } + if (from.has_connect_timeout()) { + set_connect_timeout(from.connect_timeout()); + } + if (from.has_retry_times()) { + set_retry_times(from.retry_times()); + } + if (from.has_recv_timeout()) { + set_recv_timeout(from.recv_timeout()); + } + if (from.has_resp_timeout()) { + set_resp_timeout(from.resp_timeout()); + } + if (from.has_max_rx_size()) { + set_max_rx_size(from.max_rx_size()); + } + if (from.has_max_tx_size()) { + set_max_tx_size(from.max_tx_size()); + } + } + if (from._has_bits_[16 / 32] & (0xffu << (16 % 32))) { + if (from.has_err_rate_limit()) { + set_err_rate_limit(from.err_rate_limit()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolChanParam::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolChanParam::CopyFrom(const FesDebugToolChanParam& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolChanParam::IsInitialized() const { + if ((_has_bits_[0] & 0x0001feff) != 0x0001feff) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->net_route())) return false; + return true; +} + +void FesDebugToolChanParam::Swap(FesDebugToolChanParam* other) { + if (other != this) { + std::swap(chan_no_, other->chan_no_); + std::swap(tag_name_, other->tag_name_); + std::swap(chan_name_, other->chan_name_); + std::swap(used_, other->used_); + std::swap(chan_status_, other->chan_status_); + std::swap(comm_type_, other->comm_type_); + std::swap(chan_mode_, other->chan_mode_); + std::swap(protocol_id_, other->protocol_id_); + net_route_.Swap(&other->net_route_); + std::swap(connect_wait_sec_, other->connect_wait_sec_); + std::swap(connect_timeout_, other->connect_timeout_); + std::swap(retry_times_, other->retry_times_); + std::swap(recv_timeout_, other->recv_timeout_); + std::swap(resp_timeout_, other->resp_timeout_); + std::swap(max_rx_size_, other->max_rx_size_); + std::swap(max_tx_size_, other->max_tx_size_); + std::swap(err_rate_limit_, other->err_rate_limit_); + backup_chan_no_.Swap(&other->backup_chan_no_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolChanParam::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolChanParam_descriptor_; + metadata.reflection = FesDebugToolChanParam_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolChanParamRepMsg::kChanParamFieldNumber; +#endif // !_MSC_VER + +FesDebugToolChanParamRepMsg::FesDebugToolChanParamRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolChanParamRepMsg) +} + +void FesDebugToolChanParamRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolChanParamRepMsg::FesDebugToolChanParamRepMsg(const FesDebugToolChanParamRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolChanParamRepMsg) +} + +void FesDebugToolChanParamRepMsg::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolChanParamRepMsg::~FesDebugToolChanParamRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolChanParamRepMsg) + SharedDtor(); +} + +void FesDebugToolChanParamRepMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolChanParamRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolChanParamRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolChanParamRepMsg_descriptor_; +} + +const FesDebugToolChanParamRepMsg& FesDebugToolChanParamRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolChanParamRepMsg* FesDebugToolChanParamRepMsg::default_instance_ = NULL; + +FesDebugToolChanParamRepMsg* FesDebugToolChanParamRepMsg::New() const { + return new FesDebugToolChanParamRepMsg; +} + +void FesDebugToolChanParamRepMsg::Clear() { + chan_param_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolChanParamRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolChanParamRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .iot_idl.FesDebugToolChanParam chan_param = 1; + case 1: { + if (tag == 10) { + parse_chan_param: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_chan_param())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(10)) goto parse_chan_param; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolChanParamRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolChanParamRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolChanParamRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolChanParamRepMsg) + // repeated .iot_idl.FesDebugToolChanParam chan_param = 1; + for (int i = 0; i < this->chan_param_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->chan_param(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolChanParamRepMsg) +} + +::google::protobuf::uint8* FesDebugToolChanParamRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolChanParamRepMsg) + // repeated .iot_idl.FesDebugToolChanParam chan_param = 1; + for (int i = 0; i < this->chan_param_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->chan_param(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolChanParamRepMsg) + return target; +} + +int FesDebugToolChanParamRepMsg::ByteSize() const { + int total_size = 0; + + // repeated .iot_idl.FesDebugToolChanParam chan_param = 1; + total_size += 1 * this->chan_param_size(); + for (int i = 0; i < this->chan_param_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->chan_param(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolChanParamRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolChanParamRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolChanParamRepMsg::MergeFrom(const FesDebugToolChanParamRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + chan_param_.MergeFrom(from.chan_param_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolChanParamRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolChanParamRepMsg::CopyFrom(const FesDebugToolChanParamRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolChanParamRepMsg::IsInitialized() const { + + if (!::google::protobuf::internal::AllAreInitialized(this->chan_param())) return false; + return true; +} + +void FesDebugToolChanParamRepMsg::Swap(FesDebugToolChanParamRepMsg* other) { + if (other != this) { + chan_param_.Swap(&other->chan_param_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolChanParamRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolChanParamRepMsg_descriptor_; + metadata.reflection = FesDebugToolChanParamRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolRtuParam::kRtuNoFieldNumber; +const int FesDebugToolRtuParam::kRtuDescFieldNumber; +const int FesDebugToolRtuParam::kRtuNameFieldNumber; +const int FesDebugToolRtuParam::kUsedFieldNumber; +const int FesDebugToolRtuParam::kRtuStatusFieldNumber; +const int FesDebugToolRtuParam::kRtuAddrFieldNumber; +const int FesDebugToolRtuParam::kChanNoFieldNumber; +const int FesDebugToolRtuParam::kMaxAiNumFieldNumber; +const int FesDebugToolRtuParam::kMaxDiNumFieldNumber; +const int FesDebugToolRtuParam::kMaxAccNumFieldNumber; +const int FesDebugToolRtuParam::kRecvFailLimitFieldNumber; +#endif // !_MSC_VER + +FesDebugToolRtuParam::FesDebugToolRtuParam() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolRtuParam) +} + +void FesDebugToolRtuParam::InitAsDefaultInstance() { +} + +FesDebugToolRtuParam::FesDebugToolRtuParam(const FesDebugToolRtuParam& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolRtuParam) +} + +void FesDebugToolRtuParam::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + rtu_no_ = 0; + rtu_desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + rtu_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + used_ = 0; + rtu_status_ = 0; + rtu_addr_ = 0; + chan_no_ = 0; + max_ai_num_ = 0; + max_di_num_ = 0; + max_acc_num_ = 0; + recv_fail_limit_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolRtuParam::~FesDebugToolRtuParam() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolRtuParam) + SharedDtor(); +} + +void FesDebugToolRtuParam::SharedDtor() { + if (rtu_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete rtu_desc_; + } + if (rtu_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete rtu_name_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolRtuParam::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolRtuParam::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolRtuParam_descriptor_; +} + +const FesDebugToolRtuParam& FesDebugToolRtuParam::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolRtuParam* FesDebugToolRtuParam::default_instance_ = NULL; + +FesDebugToolRtuParam* FesDebugToolRtuParam::New() const { + return new FesDebugToolRtuParam; +} + +void FesDebugToolRtuParam::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 255) { + ZR_(rtu_no_, used_); + ZR_(rtu_status_, max_ai_num_); + if (has_rtu_desc()) { + if (rtu_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_desc_->clear(); + } + } + if (has_rtu_name()) { + if (rtu_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_name_->clear(); + } + } + } + ZR_(max_di_num_, recv_fail_limit_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolRtuParam::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolRtuParam) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 rtu_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_no_))); + set_has_rtu_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_rtu_desc; + break; + } + + // required string rtu_desc = 2; + case 2: { + if (tag == 18) { + parse_rtu_desc: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_rtu_desc())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->rtu_desc().data(), this->rtu_desc().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "rtu_desc"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_rtu_name; + break; + } + + // required string rtu_name = 3; + case 3: { + if (tag == 26) { + parse_rtu_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_rtu_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->rtu_name().data(), this->rtu_name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "rtu_name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_used; + break; + } + + // required int32 used = 4; + case 4: { + if (tag == 32) { + parse_used: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &used_))); + set_has_used(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_rtu_status; + break; + } + + // required int32 rtu_status = 5; + case 5: { + if (tag == 40) { + parse_rtu_status: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_status_))); + set_has_rtu_status(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(48)) goto parse_rtu_addr; + break; + } + + // required int32 rtu_addr = 6; + case 6: { + if (tag == 48) { + parse_rtu_addr: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_addr_))); + set_has_rtu_addr(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(56)) goto parse_chan_no; + break; + } + + // required int32 chan_no = 7; + case 7: { + if (tag == 56) { + parse_chan_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &chan_no_))); + set_has_chan_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(64)) goto parse_max_ai_num; + break; + } + + // required int32 max_ai_num = 8; + case 8: { + if (tag == 64) { + parse_max_ai_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &max_ai_num_))); + set_has_max_ai_num(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(72)) goto parse_max_di_num; + break; + } + + // required int32 max_di_num = 9; + case 9: { + if (tag == 72) { + parse_max_di_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &max_di_num_))); + set_has_max_di_num(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(80)) goto parse_max_acc_num; + break; + } + + // required int32 max_acc_num = 10; + case 10: { + if (tag == 80) { + parse_max_acc_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &max_acc_num_))); + set_has_max_acc_num(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(88)) goto parse_recv_fail_limit; + break; + } + + // required int32 recv_fail_limit = 11; + case 11: { + if (tag == 88) { + parse_recv_fail_limit: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &recv_fail_limit_))); + set_has_recv_fail_limit(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolRtuParam) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolRtuParam) + return false; +#undef DO_ +} + +void FesDebugToolRtuParam::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolRtuParam) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->rtu_no(), output); + } + + // required string rtu_desc = 2; + if (has_rtu_desc()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->rtu_desc().data(), this->rtu_desc().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "rtu_desc"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->rtu_desc(), output); + } + + // required string rtu_name = 3; + if (has_rtu_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->rtu_name().data(), this->rtu_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "rtu_name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 3, this->rtu_name(), output); + } + + // required int32 used = 4; + if (has_used()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->used(), output); + } + + // required int32 rtu_status = 5; + if (has_rtu_status()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(5, this->rtu_status(), output); + } + + // required int32 rtu_addr = 6; + if (has_rtu_addr()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(6, this->rtu_addr(), output); + } + + // required int32 chan_no = 7; + if (has_chan_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(7, this->chan_no(), output); + } + + // required int32 max_ai_num = 8; + if (has_max_ai_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(8, this->max_ai_num(), output); + } + + // required int32 max_di_num = 9; + if (has_max_di_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(9, this->max_di_num(), output); + } + + // required int32 max_acc_num = 10; + if (has_max_acc_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(10, this->max_acc_num(), output); + } + + // required int32 recv_fail_limit = 11; + if (has_recv_fail_limit()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(11, this->recv_fail_limit(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolRtuParam) +} + +::google::protobuf::uint8* FesDebugToolRtuParam::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolRtuParam) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->rtu_no(), target); + } + + // required string rtu_desc = 2; + if (has_rtu_desc()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->rtu_desc().data(), this->rtu_desc().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "rtu_desc"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->rtu_desc(), target); + } + + // required string rtu_name = 3; + if (has_rtu_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->rtu_name().data(), this->rtu_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "rtu_name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->rtu_name(), target); + } + + // required int32 used = 4; + if (has_used()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->used(), target); + } + + // required int32 rtu_status = 5; + if (has_rtu_status()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(5, this->rtu_status(), target); + } + + // required int32 rtu_addr = 6; + if (has_rtu_addr()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(6, this->rtu_addr(), target); + } + + // required int32 chan_no = 7; + if (has_chan_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(7, this->chan_no(), target); + } + + // required int32 max_ai_num = 8; + if (has_max_ai_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(8, this->max_ai_num(), target); + } + + // required int32 max_di_num = 9; + if (has_max_di_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(9, this->max_di_num(), target); + } + + // required int32 max_acc_num = 10; + if (has_max_acc_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(10, this->max_acc_num(), target); + } + + // required int32 recv_fail_limit = 11; + if (has_recv_fail_limit()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(11, this->recv_fail_limit(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolRtuParam) + return target; +} + +int FesDebugToolRtuParam::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 rtu_no = 1; + if (has_rtu_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_no()); + } + + // required string rtu_desc = 2; + if (has_rtu_desc()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->rtu_desc()); + } + + // required string rtu_name = 3; + if (has_rtu_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->rtu_name()); + } + + // required int32 used = 4; + if (has_used()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->used()); + } + + // required int32 rtu_status = 5; + if (has_rtu_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_status()); + } + + // required int32 rtu_addr = 6; + if (has_rtu_addr()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_addr()); + } + + // required int32 chan_no = 7; + if (has_chan_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->chan_no()); + } + + // required int32 max_ai_num = 8; + if (has_max_ai_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->max_ai_num()); + } + + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // required int32 max_di_num = 9; + if (has_max_di_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->max_di_num()); + } + + // required int32 max_acc_num = 10; + if (has_max_acc_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->max_acc_num()); + } + + // required int32 recv_fail_limit = 11; + if (has_recv_fail_limit()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->recv_fail_limit()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolRtuParam::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolRtuParam* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolRtuParam::MergeFrom(const FesDebugToolRtuParam& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_rtu_no()) { + set_rtu_no(from.rtu_no()); + } + if (from.has_rtu_desc()) { + set_rtu_desc(from.rtu_desc()); + } + if (from.has_rtu_name()) { + set_rtu_name(from.rtu_name()); + } + if (from.has_used()) { + set_used(from.used()); + } + if (from.has_rtu_status()) { + set_rtu_status(from.rtu_status()); + } + if (from.has_rtu_addr()) { + set_rtu_addr(from.rtu_addr()); + } + if (from.has_chan_no()) { + set_chan_no(from.chan_no()); + } + if (from.has_max_ai_num()) { + set_max_ai_num(from.max_ai_num()); + } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_max_di_num()) { + set_max_di_num(from.max_di_num()); + } + if (from.has_max_acc_num()) { + set_max_acc_num(from.max_acc_num()); + } + if (from.has_recv_fail_limit()) { + set_recv_fail_limit(from.recv_fail_limit()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolRtuParam::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolRtuParam::CopyFrom(const FesDebugToolRtuParam& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolRtuParam::IsInitialized() const { + if ((_has_bits_[0] & 0x000007ff) != 0x000007ff) return false; + + return true; +} + +void FesDebugToolRtuParam::Swap(FesDebugToolRtuParam* other) { + if (other != this) { + std::swap(rtu_no_, other->rtu_no_); + std::swap(rtu_desc_, other->rtu_desc_); + std::swap(rtu_name_, other->rtu_name_); + std::swap(used_, other->used_); + std::swap(rtu_status_, other->rtu_status_); + std::swap(rtu_addr_, other->rtu_addr_); + std::swap(chan_no_, other->chan_no_); + std::swap(max_ai_num_, other->max_ai_num_); + std::swap(max_di_num_, other->max_di_num_); + std::swap(max_acc_num_, other->max_acc_num_); + std::swap(recv_fail_limit_, other->recv_fail_limit_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolRtuParam::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolRtuParam_descriptor_; + metadata.reflection = FesDebugToolRtuParam_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolRtuParamRepMsg::kRtuParamFieldNumber; +#endif // !_MSC_VER + +FesDebugToolRtuParamRepMsg::FesDebugToolRtuParamRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolRtuParamRepMsg) +} + +void FesDebugToolRtuParamRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolRtuParamRepMsg::FesDebugToolRtuParamRepMsg(const FesDebugToolRtuParamRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolRtuParamRepMsg) +} + +void FesDebugToolRtuParamRepMsg::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolRtuParamRepMsg::~FesDebugToolRtuParamRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolRtuParamRepMsg) + SharedDtor(); +} + +void FesDebugToolRtuParamRepMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolRtuParamRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolRtuParamRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolRtuParamRepMsg_descriptor_; +} + +const FesDebugToolRtuParamRepMsg& FesDebugToolRtuParamRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolRtuParamRepMsg* FesDebugToolRtuParamRepMsg::default_instance_ = NULL; + +FesDebugToolRtuParamRepMsg* FesDebugToolRtuParamRepMsg::New() const { + return new FesDebugToolRtuParamRepMsg; +} + +void FesDebugToolRtuParamRepMsg::Clear() { + rtu_param_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolRtuParamRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolRtuParamRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .iot_idl.FesDebugToolRtuParam rtu_param = 1; + case 1: { + if (tag == 10) { + parse_rtu_param: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_rtu_param())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(10)) goto parse_rtu_param; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolRtuParamRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolRtuParamRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolRtuParamRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolRtuParamRepMsg) + // repeated .iot_idl.FesDebugToolRtuParam rtu_param = 1; + for (int i = 0; i < this->rtu_param_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->rtu_param(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolRtuParamRepMsg) +} + +::google::protobuf::uint8* FesDebugToolRtuParamRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolRtuParamRepMsg) + // repeated .iot_idl.FesDebugToolRtuParam rtu_param = 1; + for (int i = 0; i < this->rtu_param_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->rtu_param(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolRtuParamRepMsg) + return target; +} + +int FesDebugToolRtuParamRepMsg::ByteSize() const { + int total_size = 0; + + // repeated .iot_idl.FesDebugToolRtuParam rtu_param = 1; + total_size += 1 * this->rtu_param_size(); + for (int i = 0; i < this->rtu_param_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->rtu_param(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolRtuParamRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolRtuParamRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolRtuParamRepMsg::MergeFrom(const FesDebugToolRtuParamRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + rtu_param_.MergeFrom(from.rtu_param_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolRtuParamRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolRtuParamRepMsg::CopyFrom(const FesDebugToolRtuParamRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolRtuParamRepMsg::IsInitialized() const { + + if (!::google::protobuf::internal::AllAreInitialized(this->rtu_param())) return false; + return true; +} + +void FesDebugToolRtuParamRepMsg::Swap(FesDebugToolRtuParamRepMsg* other) { + if (other != this) { + rtu_param_.Swap(&other->rtu_param_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolRtuParamRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolRtuParamRepMsg_descriptor_; + metadata.reflection = FesDebugToolRtuParamRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolRtuInfo::kRtuNoFieldNumber; +const int FesDebugToolRtuInfo::kUsedFieldNumber; +const int FesDebugToolRtuInfo::kRtuDescFieldNumber; +#endif // !_MSC_VER + +FesDebugToolRtuInfo::FesDebugToolRtuInfo() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolRtuInfo) +} + +void FesDebugToolRtuInfo::InitAsDefaultInstance() { +} + +FesDebugToolRtuInfo::FesDebugToolRtuInfo(const FesDebugToolRtuInfo& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolRtuInfo) +} + +void FesDebugToolRtuInfo::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + rtu_no_ = 0; + used_ = 0; + rtu_desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolRtuInfo::~FesDebugToolRtuInfo() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolRtuInfo) + SharedDtor(); +} + +void FesDebugToolRtuInfo::SharedDtor() { + if (rtu_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete rtu_desc_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolRtuInfo::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolRtuInfo::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolRtuInfo_descriptor_; +} + +const FesDebugToolRtuInfo& FesDebugToolRtuInfo::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolRtuInfo* FesDebugToolRtuInfo::default_instance_ = NULL; + +FesDebugToolRtuInfo* FesDebugToolRtuInfo::New() const { + return new FesDebugToolRtuInfo; +} + +void FesDebugToolRtuInfo::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 7) { + ZR_(rtu_no_, used_); + if (has_rtu_desc()) { + if (rtu_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_desc_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolRtuInfo::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolRtuInfo) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 rtu_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_no_))); + set_has_rtu_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_used; + break; + } + + // required int32 used = 2; + case 2: { + if (tag == 16) { + parse_used: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &used_))); + set_has_used(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_rtu_desc; + break; + } + + // required string rtu_desc = 3; + case 3: { + if (tag == 26) { + parse_rtu_desc: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_rtu_desc())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->rtu_desc().data(), this->rtu_desc().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "rtu_desc"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolRtuInfo) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolRtuInfo) + return false; +#undef DO_ +} + +void FesDebugToolRtuInfo::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolRtuInfo) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->rtu_no(), output); + } + + // required int32 used = 2; + if (has_used()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->used(), output); + } + + // required string rtu_desc = 3; + if (has_rtu_desc()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->rtu_desc().data(), this->rtu_desc().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "rtu_desc"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 3, this->rtu_desc(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolRtuInfo) +} + +::google::protobuf::uint8* FesDebugToolRtuInfo::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolRtuInfo) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->rtu_no(), target); + } + + // required int32 used = 2; + if (has_used()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->used(), target); + } + + // required string rtu_desc = 3; + if (has_rtu_desc()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->rtu_desc().data(), this->rtu_desc().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "rtu_desc"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->rtu_desc(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolRtuInfo) + return target; +} + +int FesDebugToolRtuInfo::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 rtu_no = 1; + if (has_rtu_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_no()); + } + + // required int32 used = 2; + if (has_used()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->used()); + } + + // required string rtu_desc = 3; + if (has_rtu_desc()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->rtu_desc()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolRtuInfo::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolRtuInfo* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolRtuInfo::MergeFrom(const FesDebugToolRtuInfo& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_rtu_no()) { + set_rtu_no(from.rtu_no()); + } + if (from.has_used()) { + set_used(from.used()); + } + if (from.has_rtu_desc()) { + set_rtu_desc(from.rtu_desc()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolRtuInfo::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolRtuInfo::CopyFrom(const FesDebugToolRtuInfo& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolRtuInfo::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void FesDebugToolRtuInfo::Swap(FesDebugToolRtuInfo* other) { + if (other != this) { + std::swap(rtu_no_, other->rtu_no_); + std::swap(used_, other->used_); + std::swap(rtu_desc_, other->rtu_desc_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolRtuInfo::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolRtuInfo_descriptor_; + metadata.reflection = FesDebugToolRtuInfo_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolRtuInfoRepMsg::kRtuInfoFieldNumber; +#endif // !_MSC_VER + +FesDebugToolRtuInfoRepMsg::FesDebugToolRtuInfoRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolRtuInfoRepMsg) +} + +void FesDebugToolRtuInfoRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolRtuInfoRepMsg::FesDebugToolRtuInfoRepMsg(const FesDebugToolRtuInfoRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolRtuInfoRepMsg) +} + +void FesDebugToolRtuInfoRepMsg::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolRtuInfoRepMsg::~FesDebugToolRtuInfoRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolRtuInfoRepMsg) + SharedDtor(); +} + +void FesDebugToolRtuInfoRepMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolRtuInfoRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolRtuInfoRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolRtuInfoRepMsg_descriptor_; +} + +const FesDebugToolRtuInfoRepMsg& FesDebugToolRtuInfoRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolRtuInfoRepMsg* FesDebugToolRtuInfoRepMsg::default_instance_ = NULL; + +FesDebugToolRtuInfoRepMsg* FesDebugToolRtuInfoRepMsg::New() const { + return new FesDebugToolRtuInfoRepMsg; +} + +void FesDebugToolRtuInfoRepMsg::Clear() { + rtu_info_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolRtuInfoRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolRtuInfoRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .iot_idl.FesDebugToolRtuInfo rtu_info = 1; + case 1: { + if (tag == 10) { + parse_rtu_info: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_rtu_info())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(10)) goto parse_rtu_info; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolRtuInfoRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolRtuInfoRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolRtuInfoRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolRtuInfoRepMsg) + // repeated .iot_idl.FesDebugToolRtuInfo rtu_info = 1; + for (int i = 0; i < this->rtu_info_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->rtu_info(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolRtuInfoRepMsg) +} + +::google::protobuf::uint8* FesDebugToolRtuInfoRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolRtuInfoRepMsg) + // repeated .iot_idl.FesDebugToolRtuInfo rtu_info = 1; + for (int i = 0; i < this->rtu_info_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->rtu_info(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolRtuInfoRepMsg) + return target; +} + +int FesDebugToolRtuInfoRepMsg::ByteSize() const { + int total_size = 0; + + // repeated .iot_idl.FesDebugToolRtuInfo rtu_info = 1; + total_size += 1 * this->rtu_info_size(); + for (int i = 0; i < this->rtu_info_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->rtu_info(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolRtuInfoRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolRtuInfoRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolRtuInfoRepMsg::MergeFrom(const FesDebugToolRtuInfoRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + rtu_info_.MergeFrom(from.rtu_info_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolRtuInfoRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolRtuInfoRepMsg::CopyFrom(const FesDebugToolRtuInfoRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolRtuInfoRepMsg::IsInitialized() const { + + if (!::google::protobuf::internal::AllAreInitialized(this->rtu_info())) return false; + return true; +} + +void FesDebugToolRtuInfoRepMsg::Swap(FesDebugToolRtuInfoRepMsg* other) { + if (other != this) { + rtu_info_.Swap(&other->rtu_info_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolRtuInfoRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolRtuInfoRepMsg_descriptor_; + metadata.reflection = FesDebugToolRtuInfoRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolPntParamReqMsg::kRtuNoFieldNumber; +#endif // !_MSC_VER + +FesDebugToolPntParamReqMsg::FesDebugToolPntParamReqMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolPntParamReqMsg) +} + +void FesDebugToolPntParamReqMsg::InitAsDefaultInstance() { +} + +FesDebugToolPntParamReqMsg::FesDebugToolPntParamReqMsg(const FesDebugToolPntParamReqMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolPntParamReqMsg) +} + +void FesDebugToolPntParamReqMsg::SharedCtor() { + _cached_size_ = 0; + rtu_no_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolPntParamReqMsg::~FesDebugToolPntParamReqMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolPntParamReqMsg) + SharedDtor(); +} + +void FesDebugToolPntParamReqMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolPntParamReqMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolPntParamReqMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolPntParamReqMsg_descriptor_; +} + +const FesDebugToolPntParamReqMsg& FesDebugToolPntParamReqMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolPntParamReqMsg* FesDebugToolPntParamReqMsg::default_instance_ = NULL; + +FesDebugToolPntParamReqMsg* FesDebugToolPntParamReqMsg::New() const { + return new FesDebugToolPntParamReqMsg; +} + +void FesDebugToolPntParamReqMsg::Clear() { + rtu_no_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolPntParamReqMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolPntParamReqMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 rtu_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_no_))); + set_has_rtu_no(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolPntParamReqMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolPntParamReqMsg) + return false; +#undef DO_ +} + +void FesDebugToolPntParamReqMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolPntParamReqMsg) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->rtu_no(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolPntParamReqMsg) +} + +::google::protobuf::uint8* FesDebugToolPntParamReqMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolPntParamReqMsg) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->rtu_no(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolPntParamReqMsg) + return target; +} + +int FesDebugToolPntParamReqMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 rtu_no = 1; + if (has_rtu_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_no()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolPntParamReqMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolPntParamReqMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolPntParamReqMsg::MergeFrom(const FesDebugToolPntParamReqMsg& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_rtu_no()) { + set_rtu_no(from.rtu_no()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolPntParamReqMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolPntParamReqMsg::CopyFrom(const FesDebugToolPntParamReqMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolPntParamReqMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void FesDebugToolPntParamReqMsg::Swap(FesDebugToolPntParamReqMsg* other) { + if (other != this) { + std::swap(rtu_no_, other->rtu_no_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolPntParamReqMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolPntParamReqMsg_descriptor_; + metadata.reflection = FesDebugToolPntParamReqMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolPntParam::kPntNoFieldNumber; +const int FesDebugToolPntParam::kUsedFieldNumber; +const int FesDebugToolPntParam::kPntDescFieldNumber; +#endif // !_MSC_VER + +FesDebugToolPntParam::FesDebugToolPntParam() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolPntParam) +} + +void FesDebugToolPntParam::InitAsDefaultInstance() { +} + +FesDebugToolPntParam::FesDebugToolPntParam(const FesDebugToolPntParam& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolPntParam) +} + +void FesDebugToolPntParam::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + pnt_no_ = 0; + used_ = 0; + pnt_desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolPntParam::~FesDebugToolPntParam() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolPntParam) + SharedDtor(); +} + +void FesDebugToolPntParam::SharedDtor() { + if (pnt_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete pnt_desc_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolPntParam::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolPntParam::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolPntParam_descriptor_; +} + +const FesDebugToolPntParam& FesDebugToolPntParam::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolPntParam* FesDebugToolPntParam::default_instance_ = NULL; + +FesDebugToolPntParam* FesDebugToolPntParam::New() const { + return new FesDebugToolPntParam; +} + +void FesDebugToolPntParam::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 7) { + ZR_(pnt_no_, used_); + if (has_pnt_desc()) { + if (pnt_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + pnt_desc_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolPntParam::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolPntParam) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 pnt_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &pnt_no_))); + set_has_pnt_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_used; + break; + } + + // required int32 used = 2; + case 2: { + if (tag == 16) { + parse_used: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &used_))); + set_has_used(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_pnt_desc; + break; + } + + // required string pnt_desc = 3; + case 3: { + if (tag == 26) { + parse_pnt_desc: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_pnt_desc())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->pnt_desc().data(), this->pnt_desc().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "pnt_desc"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolPntParam) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolPntParam) + return false; +#undef DO_ +} + +void FesDebugToolPntParam::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolPntParam) + // required int32 pnt_no = 1; + if (has_pnt_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->pnt_no(), output); + } + + // required int32 used = 2; + if (has_used()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->used(), output); + } + + // required string pnt_desc = 3; + if (has_pnt_desc()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->pnt_desc().data(), this->pnt_desc().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "pnt_desc"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 3, this->pnt_desc(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolPntParam) +} + +::google::protobuf::uint8* FesDebugToolPntParam::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolPntParam) + // required int32 pnt_no = 1; + if (has_pnt_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->pnt_no(), target); + } + + // required int32 used = 2; + if (has_used()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->used(), target); + } + + // required string pnt_desc = 3; + if (has_pnt_desc()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->pnt_desc().data(), this->pnt_desc().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "pnt_desc"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->pnt_desc(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolPntParam) + return target; +} + +int FesDebugToolPntParam::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 pnt_no = 1; + if (has_pnt_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->pnt_no()); + } + + // required int32 used = 2; + if (has_used()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->used()); + } + + // required string pnt_desc = 3; + if (has_pnt_desc()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->pnt_desc()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolPntParam::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolPntParam* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolPntParam::MergeFrom(const FesDebugToolPntParam& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_pnt_no()) { + set_pnt_no(from.pnt_no()); + } + if (from.has_used()) { + set_used(from.used()); + } + if (from.has_pnt_desc()) { + set_pnt_desc(from.pnt_desc()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolPntParam::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolPntParam::CopyFrom(const FesDebugToolPntParam& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolPntParam::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void FesDebugToolPntParam::Swap(FesDebugToolPntParam* other) { + if (other != this) { + std::swap(pnt_no_, other->pnt_no_); + std::swap(used_, other->used_); + std::swap(pnt_desc_, other->pnt_desc_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolPntParam::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolPntParam_descriptor_; + metadata.reflection = FesDebugToolPntParam_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolPntParamRepMsg::kRtuNoFieldNumber; +const int FesDebugToolPntParamRepMsg::kMaxPntNumFieldNumber; +const int FesDebugToolPntParamRepMsg::kPntParamFieldNumber; +#endif // !_MSC_VER + +FesDebugToolPntParamRepMsg::FesDebugToolPntParamRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolPntParamRepMsg) +} + +void FesDebugToolPntParamRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolPntParamRepMsg::FesDebugToolPntParamRepMsg(const FesDebugToolPntParamRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolPntParamRepMsg) +} + +void FesDebugToolPntParamRepMsg::SharedCtor() { + _cached_size_ = 0; + rtu_no_ = 0; + max_pnt_num_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolPntParamRepMsg::~FesDebugToolPntParamRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolPntParamRepMsg) + SharedDtor(); +} + +void FesDebugToolPntParamRepMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolPntParamRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolPntParamRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolPntParamRepMsg_descriptor_; +} + +const FesDebugToolPntParamRepMsg& FesDebugToolPntParamRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolPntParamRepMsg* FesDebugToolPntParamRepMsg::default_instance_ = NULL; + +FesDebugToolPntParamRepMsg* FesDebugToolPntParamRepMsg::New() const { + return new FesDebugToolPntParamRepMsg; +} + +void FesDebugToolPntParamRepMsg::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(rtu_no_, max_pnt_num_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + pnt_param_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolPntParamRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolPntParamRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 rtu_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_no_))); + set_has_rtu_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_max_pnt_num; + break; + } + + // required int32 max_pnt_num = 2; + case 2: { + if (tag == 16) { + parse_max_pnt_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &max_pnt_num_))); + set_has_max_pnt_num(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_pnt_param; + break; + } + + // repeated .iot_idl.FesDebugToolPntParam pnt_param = 3; + case 3: { + if (tag == 26) { + parse_pnt_param: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_pnt_param())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_pnt_param; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolPntParamRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolPntParamRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolPntParamRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolPntParamRepMsg) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->rtu_no(), output); + } + + // required int32 max_pnt_num = 2; + if (has_max_pnt_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->max_pnt_num(), output); + } + + // repeated .iot_idl.FesDebugToolPntParam pnt_param = 3; + for (int i = 0; i < this->pnt_param_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->pnt_param(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolPntParamRepMsg) +} + +::google::protobuf::uint8* FesDebugToolPntParamRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolPntParamRepMsg) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->rtu_no(), target); + } + + // required int32 max_pnt_num = 2; + if (has_max_pnt_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->max_pnt_num(), target); + } + + // repeated .iot_idl.FesDebugToolPntParam pnt_param = 3; + for (int i = 0; i < this->pnt_param_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->pnt_param(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolPntParamRepMsg) + return target; +} + +int FesDebugToolPntParamRepMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 rtu_no = 1; + if (has_rtu_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_no()); + } + + // required int32 max_pnt_num = 2; + if (has_max_pnt_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->max_pnt_num()); + } + + } + // repeated .iot_idl.FesDebugToolPntParam pnt_param = 3; + total_size += 1 * this->pnt_param_size(); + for (int i = 0; i < this->pnt_param_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->pnt_param(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolPntParamRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolPntParamRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolPntParamRepMsg::MergeFrom(const FesDebugToolPntParamRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + pnt_param_.MergeFrom(from.pnt_param_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_rtu_no()) { + set_rtu_no(from.rtu_no()); + } + if (from.has_max_pnt_num()) { + set_max_pnt_num(from.max_pnt_num()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolPntParamRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolPntParamRepMsg::CopyFrom(const FesDebugToolPntParamRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolPntParamRepMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->pnt_param())) return false; + return true; +} + +void FesDebugToolPntParamRepMsg::Swap(FesDebugToolPntParamRepMsg* other) { + if (other != this) { + std::swap(rtu_no_, other->rtu_no_); + std::swap(max_pnt_num_, other->max_pnt_num_); + pnt_param_.Swap(&other->pnt_param_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolPntParamRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolPntParamRepMsg_descriptor_; + metadata.reflection = FesDebugToolPntParamRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolPntValueReqMsg::kRtuNoFieldNumber; +const int FesDebugToolPntValueReqMsg::kStartIndexFieldNumber; +const int FesDebugToolPntValueReqMsg::kEndIndexFieldNumber; +#endif // !_MSC_VER + +FesDebugToolPntValueReqMsg::FesDebugToolPntValueReqMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolPntValueReqMsg) +} + +void FesDebugToolPntValueReqMsg::InitAsDefaultInstance() { +} + +FesDebugToolPntValueReqMsg::FesDebugToolPntValueReqMsg(const FesDebugToolPntValueReqMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolPntValueReqMsg) +} + +void FesDebugToolPntValueReqMsg::SharedCtor() { + _cached_size_ = 0; + rtu_no_ = 0; + start_index_ = 0; + end_index_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolPntValueReqMsg::~FesDebugToolPntValueReqMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolPntValueReqMsg) + SharedDtor(); +} + +void FesDebugToolPntValueReqMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolPntValueReqMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolPntValueReqMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolPntValueReqMsg_descriptor_; +} + +const FesDebugToolPntValueReqMsg& FesDebugToolPntValueReqMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolPntValueReqMsg* FesDebugToolPntValueReqMsg::default_instance_ = NULL; + +FesDebugToolPntValueReqMsg* FesDebugToolPntValueReqMsg::New() const { + return new FesDebugToolPntValueReqMsg; +} + +void FesDebugToolPntValueReqMsg::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(rtu_no_, end_index_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolPntValueReqMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolPntValueReqMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 rtu_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_no_))); + set_has_rtu_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_start_index; + break; + } + + // required int32 start_index = 2; + case 2: { + if (tag == 16) { + parse_start_index: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &start_index_))); + set_has_start_index(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_end_index; + break; + } + + // required int32 end_index = 3; + case 3: { + if (tag == 24) { + parse_end_index: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &end_index_))); + set_has_end_index(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolPntValueReqMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolPntValueReqMsg) + return false; +#undef DO_ +} + +void FesDebugToolPntValueReqMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolPntValueReqMsg) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->rtu_no(), output); + } + + // required int32 start_index = 2; + if (has_start_index()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->start_index(), output); + } + + // required int32 end_index = 3; + if (has_end_index()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->end_index(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolPntValueReqMsg) +} + +::google::protobuf::uint8* FesDebugToolPntValueReqMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolPntValueReqMsg) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->rtu_no(), target); + } + + // required int32 start_index = 2; + if (has_start_index()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->start_index(), target); + } + + // required int32 end_index = 3; + if (has_end_index()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->end_index(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolPntValueReqMsg) + return target; +} + +int FesDebugToolPntValueReqMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 rtu_no = 1; + if (has_rtu_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_no()); + } + + // required int32 start_index = 2; + if (has_start_index()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->start_index()); + } + + // required int32 end_index = 3; + if (has_end_index()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->end_index()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolPntValueReqMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolPntValueReqMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolPntValueReqMsg::MergeFrom(const FesDebugToolPntValueReqMsg& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_rtu_no()) { + set_rtu_no(from.rtu_no()); + } + if (from.has_start_index()) { + set_start_index(from.start_index()); + } + if (from.has_end_index()) { + set_end_index(from.end_index()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolPntValueReqMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolPntValueReqMsg::CopyFrom(const FesDebugToolPntValueReqMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolPntValueReqMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void FesDebugToolPntValueReqMsg::Swap(FesDebugToolPntValueReqMsg* other) { + if (other != this) { + std::swap(rtu_no_, other->rtu_no_); + std::swap(start_index_, other->start_index_); + std::swap(end_index_, other->end_index_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolPntValueReqMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolPntValueReqMsg_descriptor_; + metadata.reflection = FesDebugToolPntValueReqMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolIntPntValue::kPntNoFieldNumber; +const int FesDebugToolIntPntValue::kValueFieldNumber; +const int FesDebugToolIntPntValue::kStatusFieldNumber; +const int FesDebugToolIntPntValue::kTimeFieldNumber; +#endif // !_MSC_VER + +FesDebugToolIntPntValue::FesDebugToolIntPntValue() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolIntPntValue) +} + +void FesDebugToolIntPntValue::InitAsDefaultInstance() { +} + +FesDebugToolIntPntValue::FesDebugToolIntPntValue(const FesDebugToolIntPntValue& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolIntPntValue) +} + +void FesDebugToolIntPntValue::SharedCtor() { + _cached_size_ = 0; + pnt_no_ = 0; + value_ = 0; + status_ = 0u; + time_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolIntPntValue::~FesDebugToolIntPntValue() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolIntPntValue) + SharedDtor(); +} + +void FesDebugToolIntPntValue::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolIntPntValue::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolIntPntValue::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolIntPntValue_descriptor_; +} + +const FesDebugToolIntPntValue& FesDebugToolIntPntValue::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolIntPntValue* FesDebugToolIntPntValue::default_instance_ = NULL; + +FesDebugToolIntPntValue* FesDebugToolIntPntValue::New() const { + return new FesDebugToolIntPntValue; +} + +void FesDebugToolIntPntValue::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(pnt_no_, status_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolIntPntValue::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolIntPntValue) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 pnt_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &pnt_no_))); + set_has_pnt_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_value; + break; + } + + // required sint32 value = 2; + case 2: { + if (tag == 16) { + parse_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_SINT32>( + input, &value_))); + set_has_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_status; + break; + } + + // required uint32 status = 3; + case 3: { + if (tag == 24) { + parse_status: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &status_))); + set_has_status(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_time; + break; + } + + // required uint64 time = 4; + case 4: { + if (tag == 32) { + parse_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &time_))); + set_has_time(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolIntPntValue) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolIntPntValue) + return false; +#undef DO_ +} + +void FesDebugToolIntPntValue::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolIntPntValue) + // required int32 pnt_no = 1; + if (has_pnt_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->pnt_no(), output); + } + + // required sint32 value = 2; + if (has_value()) { + ::google::protobuf::internal::WireFormatLite::WriteSInt32(2, this->value(), output); + } + + // required uint32 status = 3; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->status(), output); + } + + // required uint64 time = 4; + if (has_time()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->time(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolIntPntValue) +} + +::google::protobuf::uint8* FesDebugToolIntPntValue::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolIntPntValue) + // required int32 pnt_no = 1; + if (has_pnt_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->pnt_no(), target); + } + + // required sint32 value = 2; + if (has_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteSInt32ToArray(2, this->value(), target); + } + + // required uint32 status = 3; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->status(), target); + } + + // required uint64 time = 4; + if (has_time()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->time(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolIntPntValue) + return target; +} + +int FesDebugToolIntPntValue::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 pnt_no = 1; + if (has_pnt_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->pnt_no()); + } + + // required sint32 value = 2; + if (has_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::SInt32Size( + this->value()); + } + + // required uint32 status = 3; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->status()); + } + + // required uint64 time = 4; + if (has_time()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->time()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolIntPntValue::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolIntPntValue* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolIntPntValue::MergeFrom(const FesDebugToolIntPntValue& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_pnt_no()) { + set_pnt_no(from.pnt_no()); + } + if (from.has_value()) { + set_value(from.value()); + } + if (from.has_status()) { + set_status(from.status()); + } + if (from.has_time()) { + set_time(from.time()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolIntPntValue::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolIntPntValue::CopyFrom(const FesDebugToolIntPntValue& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolIntPntValue::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + return true; +} + +void FesDebugToolIntPntValue::Swap(FesDebugToolIntPntValue* other) { + if (other != this) { + std::swap(pnt_no_, other->pnt_no_); + std::swap(value_, other->value_); + std::swap(status_, other->status_); + std::swap(time_, other->time_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolIntPntValue::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolIntPntValue_descriptor_; + metadata.reflection = FesDebugToolIntPntValue_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolFloatPntValue::kPntNoFieldNumber; +const int FesDebugToolFloatPntValue::kValueFieldNumber; +const int FesDebugToolFloatPntValue::kStatusFieldNumber; +const int FesDebugToolFloatPntValue::kTimeFieldNumber; +#endif // !_MSC_VER + +FesDebugToolFloatPntValue::FesDebugToolFloatPntValue() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolFloatPntValue) +} + +void FesDebugToolFloatPntValue::InitAsDefaultInstance() { +} + +FesDebugToolFloatPntValue::FesDebugToolFloatPntValue(const FesDebugToolFloatPntValue& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolFloatPntValue) +} + +void FesDebugToolFloatPntValue::SharedCtor() { + _cached_size_ = 0; + pnt_no_ = 0; + value_ = 0; + status_ = 0u; + time_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolFloatPntValue::~FesDebugToolFloatPntValue() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolFloatPntValue) + SharedDtor(); +} + +void FesDebugToolFloatPntValue::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolFloatPntValue::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolFloatPntValue::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolFloatPntValue_descriptor_; +} + +const FesDebugToolFloatPntValue& FesDebugToolFloatPntValue::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolFloatPntValue* FesDebugToolFloatPntValue::default_instance_ = NULL; + +FesDebugToolFloatPntValue* FesDebugToolFloatPntValue::New() const { + return new FesDebugToolFloatPntValue; +} + +void FesDebugToolFloatPntValue::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(pnt_no_, status_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolFloatPntValue::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolFloatPntValue) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 pnt_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &pnt_no_))); + set_has_pnt_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(21)) goto parse_value; + break; + } + + // required float value = 2; + case 2: { + if (tag == 21) { + parse_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &value_))); + set_has_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_status; + break; + } + + // required uint32 status = 3; + case 3: { + if (tag == 24) { + parse_status: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &status_))); + set_has_status(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_time; + break; + } + + // required uint64 time = 4; + case 4: { + if (tag == 32) { + parse_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &time_))); + set_has_time(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolFloatPntValue) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolFloatPntValue) + return false; +#undef DO_ +} + +void FesDebugToolFloatPntValue::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolFloatPntValue) + // required int32 pnt_no = 1; + if (has_pnt_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->pnt_no(), output); + } + + // required float value = 2; + if (has_value()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(2, this->value(), output); + } + + // required uint32 status = 3; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->status(), output); + } + + // required uint64 time = 4; + if (has_time()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->time(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolFloatPntValue) +} + +::google::protobuf::uint8* FesDebugToolFloatPntValue::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolFloatPntValue) + // required int32 pnt_no = 1; + if (has_pnt_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->pnt_no(), target); + } + + // required float value = 2; + if (has_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(2, this->value(), target); + } + + // required uint32 status = 3; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->status(), target); + } + + // required uint64 time = 4; + if (has_time()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->time(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolFloatPntValue) + return target; +} + +int FesDebugToolFloatPntValue::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 pnt_no = 1; + if (has_pnt_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->pnt_no()); + } + + // required float value = 2; + if (has_value()) { + total_size += 1 + 4; + } + + // required uint32 status = 3; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->status()); + } + + // required uint64 time = 4; + if (has_time()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->time()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolFloatPntValue::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolFloatPntValue* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolFloatPntValue::MergeFrom(const FesDebugToolFloatPntValue& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_pnt_no()) { + set_pnt_no(from.pnt_no()); + } + if (from.has_value()) { + set_value(from.value()); + } + if (from.has_status()) { + set_status(from.status()); + } + if (from.has_time()) { + set_time(from.time()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolFloatPntValue::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolFloatPntValue::CopyFrom(const FesDebugToolFloatPntValue& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolFloatPntValue::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + return true; +} + +void FesDebugToolFloatPntValue::Swap(FesDebugToolFloatPntValue* other) { + if (other != this) { + std::swap(pnt_no_, other->pnt_no_); + std::swap(value_, other->value_); + std::swap(status_, other->status_); + std::swap(time_, other->time_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolFloatPntValue::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolFloatPntValue_descriptor_; + metadata.reflection = FesDebugToolFloatPntValue_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolDoublePntValue::kPntNoFieldNumber; +const int FesDebugToolDoublePntValue::kValueFieldNumber; +const int FesDebugToolDoublePntValue::kStatusFieldNumber; +const int FesDebugToolDoublePntValue::kTimeFieldNumber; +#endif // !_MSC_VER + +FesDebugToolDoublePntValue::FesDebugToolDoublePntValue() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolDoublePntValue) +} + +void FesDebugToolDoublePntValue::InitAsDefaultInstance() { +} + +FesDebugToolDoublePntValue::FesDebugToolDoublePntValue(const FesDebugToolDoublePntValue& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolDoublePntValue) +} + +void FesDebugToolDoublePntValue::SharedCtor() { + _cached_size_ = 0; + pnt_no_ = 0; + value_ = 0; + status_ = 0u; + time_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolDoublePntValue::~FesDebugToolDoublePntValue() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolDoublePntValue) + SharedDtor(); +} + +void FesDebugToolDoublePntValue::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolDoublePntValue::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolDoublePntValue::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolDoublePntValue_descriptor_; +} + +const FesDebugToolDoublePntValue& FesDebugToolDoublePntValue::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolDoublePntValue* FesDebugToolDoublePntValue::default_instance_ = NULL; + +FesDebugToolDoublePntValue* FesDebugToolDoublePntValue::New() const { + return new FesDebugToolDoublePntValue; +} + +void FesDebugToolDoublePntValue::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(value_, time_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolDoublePntValue::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolDoublePntValue) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 pnt_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &pnt_no_))); + set_has_pnt_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(17)) goto parse_value; + break; + } + + // required double value = 2; + case 2: { + if (tag == 17) { + parse_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &value_))); + set_has_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_status; + break; + } + + // required uint32 status = 3; + case 3: { + if (tag == 24) { + parse_status: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &status_))); + set_has_status(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_time; + break; + } + + // required uint64 time = 4; + case 4: { + if (tag == 32) { + parse_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &time_))); + set_has_time(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolDoublePntValue) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolDoublePntValue) + return false; +#undef DO_ +} + +void FesDebugToolDoublePntValue::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolDoublePntValue) + // required int32 pnt_no = 1; + if (has_pnt_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->pnt_no(), output); + } + + // required double value = 2; + if (has_value()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->value(), output); + } + + // required uint32 status = 3; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->status(), output); + } + + // required uint64 time = 4; + if (has_time()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->time(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolDoublePntValue) +} + +::google::protobuf::uint8* FesDebugToolDoublePntValue::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolDoublePntValue) + // required int32 pnt_no = 1; + if (has_pnt_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->pnt_no(), target); + } + + // required double value = 2; + if (has_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->value(), target); + } + + // required uint32 status = 3; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->status(), target); + } + + // required uint64 time = 4; + if (has_time()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->time(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolDoublePntValue) + return target; +} + +int FesDebugToolDoublePntValue::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 pnt_no = 1; + if (has_pnt_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->pnt_no()); + } + + // required double value = 2; + if (has_value()) { + total_size += 1 + 8; + } + + // required uint32 status = 3; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->status()); + } + + // required uint64 time = 4; + if (has_time()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->time()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolDoublePntValue::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolDoublePntValue* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolDoublePntValue::MergeFrom(const FesDebugToolDoublePntValue& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_pnt_no()) { + set_pnt_no(from.pnt_no()); + } + if (from.has_value()) { + set_value(from.value()); + } + if (from.has_status()) { + set_status(from.status()); + } + if (from.has_time()) { + set_time(from.time()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolDoublePntValue::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolDoublePntValue::CopyFrom(const FesDebugToolDoublePntValue& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolDoublePntValue::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + return true; +} + +void FesDebugToolDoublePntValue::Swap(FesDebugToolDoublePntValue* other) { + if (other != this) { + std::swap(pnt_no_, other->pnt_no_); + std::swap(value_, other->value_); + std::swap(status_, other->status_); + std::swap(time_, other->time_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolDoublePntValue::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolDoublePntValue_descriptor_; + metadata.reflection = FesDebugToolDoublePntValue_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolPntValueRepMsg::kRtuNoFieldNumber; +const int FesDebugToolPntValueRepMsg::kIntValuesFieldNumber; +const int FesDebugToolPntValueRepMsg::kFloatValuesFieldNumber; +const int FesDebugToolPntValueRepMsg::kDoubleValuesFieldNumber; +#endif // !_MSC_VER + +FesDebugToolPntValueRepMsg::FesDebugToolPntValueRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolPntValueRepMsg) +} + +void FesDebugToolPntValueRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolPntValueRepMsg::FesDebugToolPntValueRepMsg(const FesDebugToolPntValueRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolPntValueRepMsg) +} + +void FesDebugToolPntValueRepMsg::SharedCtor() { + _cached_size_ = 0; + rtu_no_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolPntValueRepMsg::~FesDebugToolPntValueRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolPntValueRepMsg) + SharedDtor(); +} + +void FesDebugToolPntValueRepMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolPntValueRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolPntValueRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolPntValueRepMsg_descriptor_; +} + +const FesDebugToolPntValueRepMsg& FesDebugToolPntValueRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolPntValueRepMsg* FesDebugToolPntValueRepMsg::default_instance_ = NULL; + +FesDebugToolPntValueRepMsg* FesDebugToolPntValueRepMsg::New() const { + return new FesDebugToolPntValueRepMsg; +} + +void FesDebugToolPntValueRepMsg::Clear() { + rtu_no_ = 0; + int_values_.Clear(); + float_values_.Clear(); + double_values_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolPntValueRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolPntValueRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 rtu_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_no_))); + set_has_rtu_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_int_values; + break; + } + + // repeated .iot_idl.FesDebugToolIntPntValue int_values = 2; + case 2: { + if (tag == 18) { + parse_int_values: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_int_values())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_int_values; + if (input->ExpectTag(26)) goto parse_float_values; + break; + } + + // repeated .iot_idl.FesDebugToolFloatPntValue float_values = 3; + case 3: { + if (tag == 26) { + parse_float_values: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_float_values())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_float_values; + if (input->ExpectTag(34)) goto parse_double_values; + break; + } + + // repeated .iot_idl.FesDebugToolDoublePntValue double_values = 4; + case 4: { + if (tag == 34) { + parse_double_values: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_double_values())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_double_values; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolPntValueRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolPntValueRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolPntValueRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolPntValueRepMsg) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->rtu_no(), output); + } + + // repeated .iot_idl.FesDebugToolIntPntValue int_values = 2; + for (int i = 0; i < this->int_values_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->int_values(i), output); + } + + // repeated .iot_idl.FesDebugToolFloatPntValue float_values = 3; + for (int i = 0; i < this->float_values_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->float_values(i), output); + } + + // repeated .iot_idl.FesDebugToolDoublePntValue double_values = 4; + for (int i = 0; i < this->double_values_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 4, this->double_values(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolPntValueRepMsg) +} + +::google::protobuf::uint8* FesDebugToolPntValueRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolPntValueRepMsg) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->rtu_no(), target); + } + + // repeated .iot_idl.FesDebugToolIntPntValue int_values = 2; + for (int i = 0; i < this->int_values_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->int_values(i), target); + } + + // repeated .iot_idl.FesDebugToolFloatPntValue float_values = 3; + for (int i = 0; i < this->float_values_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->float_values(i), target); + } + + // repeated .iot_idl.FesDebugToolDoublePntValue double_values = 4; + for (int i = 0; i < this->double_values_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->double_values(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolPntValueRepMsg) + return target; +} + +int FesDebugToolPntValueRepMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 rtu_no = 1; + if (has_rtu_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_no()); + } + + } + // repeated .iot_idl.FesDebugToolIntPntValue int_values = 2; + total_size += 1 * this->int_values_size(); + for (int i = 0; i < this->int_values_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->int_values(i)); + } + + // repeated .iot_idl.FesDebugToolFloatPntValue float_values = 3; + total_size += 1 * this->float_values_size(); + for (int i = 0; i < this->float_values_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->float_values(i)); + } + + // repeated .iot_idl.FesDebugToolDoublePntValue double_values = 4; + total_size += 1 * this->double_values_size(); + for (int i = 0; i < this->double_values_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->double_values(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolPntValueRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolPntValueRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolPntValueRepMsg::MergeFrom(const FesDebugToolPntValueRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + int_values_.MergeFrom(from.int_values_); + float_values_.MergeFrom(from.float_values_); + double_values_.MergeFrom(from.double_values_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_rtu_no()) { + set_rtu_no(from.rtu_no()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolPntValueRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolPntValueRepMsg::CopyFrom(const FesDebugToolPntValueRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolPntValueRepMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->int_values())) return false; + if (!::google::protobuf::internal::AllAreInitialized(this->float_values())) return false; + if (!::google::protobuf::internal::AllAreInitialized(this->double_values())) return false; + return true; +} + +void FesDebugToolPntValueRepMsg::Swap(FesDebugToolPntValueRepMsg* other) { + if (other != this) { + std::swap(rtu_no_, other->rtu_no_); + int_values_.Swap(&other->int_values_); + float_values_.Swap(&other->float_values_); + double_values_.Swap(&other->double_values_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolPntValueRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolPntValueRepMsg_descriptor_; + metadata.reflection = FesDebugToolPntValueRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolValueVariant::kIntValueFieldNumber; +const int FesDebugToolValueVariant::kFloatValueFieldNumber; +const int FesDebugToolValueVariant::kDoubleValueFieldNumber; +#endif // !_MSC_VER + +FesDebugToolValueVariant::FesDebugToolValueVariant() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolValueVariant) +} + +void FesDebugToolValueVariant::InitAsDefaultInstance() { +} + +FesDebugToolValueVariant::FesDebugToolValueVariant(const FesDebugToolValueVariant& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolValueVariant) +} + +void FesDebugToolValueVariant::SharedCtor() { + _cached_size_ = 0; + int_value_ = 0; + float_value_ = 0; + double_value_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolValueVariant::~FesDebugToolValueVariant() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolValueVariant) + SharedDtor(); +} + +void FesDebugToolValueVariant::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolValueVariant::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolValueVariant::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolValueVariant_descriptor_; +} + +const FesDebugToolValueVariant& FesDebugToolValueVariant::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolValueVariant* FesDebugToolValueVariant::default_instance_ = NULL; + +FesDebugToolValueVariant* FesDebugToolValueVariant::New() const { + return new FesDebugToolValueVariant; +} + +void FesDebugToolValueVariant::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(int_value_, double_value_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolValueVariant::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolValueVariant) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional int32 int_value = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &int_value_))); + set_has_int_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(21)) goto parse_float_value; + break; + } + + // optional float float_value = 2; + case 2: { + if (tag == 21) { + parse_float_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &float_value_))); + set_has_float_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(25)) goto parse_double_value; + break; + } + + // optional double double_value = 3; + case 3: { + if (tag == 25) { + parse_double_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &double_value_))); + set_has_double_value(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolValueVariant) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolValueVariant) + return false; +#undef DO_ +} + +void FesDebugToolValueVariant::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolValueVariant) + // optional int32 int_value = 1; + if (has_int_value()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->int_value(), output); + } + + // optional float float_value = 2; + if (has_float_value()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(2, this->float_value(), output); + } + + // optional double double_value = 3; + if (has_double_value()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(3, this->double_value(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolValueVariant) +} + +::google::protobuf::uint8* FesDebugToolValueVariant::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolValueVariant) + // optional int32 int_value = 1; + if (has_int_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->int_value(), target); + } + + // optional float float_value = 2; + if (has_float_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(2, this->float_value(), target); + } + + // optional double double_value = 3; + if (has_double_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(3, this->double_value(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolValueVariant) + return target; +} + +int FesDebugToolValueVariant::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional int32 int_value = 1; + if (has_int_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->int_value()); + } + + // optional float float_value = 2; + if (has_float_value()) { + total_size += 1 + 4; + } + + // optional double double_value = 3; + if (has_double_value()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolValueVariant::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolValueVariant* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolValueVariant::MergeFrom(const FesDebugToolValueVariant& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_int_value()) { + set_int_value(from.int_value()); + } + if (from.has_float_value()) { + set_float_value(from.float_value()); + } + if (from.has_double_value()) { + set_double_value(from.double_value()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolValueVariant::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolValueVariant::CopyFrom(const FesDebugToolValueVariant& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolValueVariant::IsInitialized() const { + + return true; +} + +void FesDebugToolValueVariant::Swap(FesDebugToolValueVariant* other) { + if (other != this) { + std::swap(int_value_, other->int_value_); + std::swap(float_value_, other->float_value_); + std::swap(double_value_, other->double_value_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolValueVariant::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolValueVariant_descriptor_; + metadata.reflection = FesDebugToolValueVariant_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolValueSetSimParam::kValueFieldNumber; +#endif // !_MSC_VER + +FesDebugToolValueSetSimParam::FesDebugToolValueSetSimParam() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolValueSetSimParam) +} + +void FesDebugToolValueSetSimParam::InitAsDefaultInstance() { +} + +FesDebugToolValueSetSimParam::FesDebugToolValueSetSimParam(const FesDebugToolValueSetSimParam& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolValueSetSimParam) +} + +void FesDebugToolValueSetSimParam::SharedCtor() { + _cached_size_ = 0; + value_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolValueSetSimParam::~FesDebugToolValueSetSimParam() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolValueSetSimParam) + SharedDtor(); +} + +void FesDebugToolValueSetSimParam::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolValueSetSimParam::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolValueSetSimParam::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolValueSetSimParam_descriptor_; +} + +const FesDebugToolValueSetSimParam& FesDebugToolValueSetSimParam::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolValueSetSimParam* FesDebugToolValueSetSimParam::default_instance_ = NULL; + +FesDebugToolValueSetSimParam* FesDebugToolValueSetSimParam::New() const { + return new FesDebugToolValueSetSimParam; +} + +void FesDebugToolValueSetSimParam::Clear() { + value_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolValueSetSimParam::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolValueSetSimParam) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required double value = 1; + case 1: { + if (tag == 9) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &value_))); + set_has_value(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolValueSetSimParam) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolValueSetSimParam) + return false; +#undef DO_ +} + +void FesDebugToolValueSetSimParam::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolValueSetSimParam) + // required double value = 1; + if (has_value()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->value(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolValueSetSimParam) +} + +::google::protobuf::uint8* FesDebugToolValueSetSimParam::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolValueSetSimParam) + // required double value = 1; + if (has_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->value(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolValueSetSimParam) + return target; +} + +int FesDebugToolValueSetSimParam::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required double value = 1; + if (has_value()) { + total_size += 1 + 8; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolValueSetSimParam::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolValueSetSimParam* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolValueSetSimParam::MergeFrom(const FesDebugToolValueSetSimParam& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_value()) { + set_value(from.value()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolValueSetSimParam::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolValueSetSimParam::CopyFrom(const FesDebugToolValueSetSimParam& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolValueSetSimParam::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void FesDebugToolValueSetSimParam::Swap(FesDebugToolValueSetSimParam* other) { + if (other != this) { + std::swap(value_, other->value_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolValueSetSimParam::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolValueSetSimParam_descriptor_; + metadata.reflection = FesDebugToolValueSetSimParam_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolLineSetSimParam::kMinValueFieldNumber; +const int FesDebugToolLineSetSimParam::kMaxValueFieldNumber; +const int FesDebugToolLineSetSimParam::kStepValueFieldNumber; +const int FesDebugToolLineSetSimParam::kPeriodFieldNumber; +#endif // !_MSC_VER + +FesDebugToolLineSetSimParam::FesDebugToolLineSetSimParam() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolLineSetSimParam) +} + +void FesDebugToolLineSetSimParam::InitAsDefaultInstance() { +} + +FesDebugToolLineSetSimParam::FesDebugToolLineSetSimParam(const FesDebugToolLineSetSimParam& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolLineSetSimParam) +} + +void FesDebugToolLineSetSimParam::SharedCtor() { + _cached_size_ = 0; + min_value_ = 0; + max_value_ = 0; + step_value_ = 0; + period_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolLineSetSimParam::~FesDebugToolLineSetSimParam() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolLineSetSimParam) + SharedDtor(); +} + +void FesDebugToolLineSetSimParam::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolLineSetSimParam::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolLineSetSimParam::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolLineSetSimParam_descriptor_; +} + +const FesDebugToolLineSetSimParam& FesDebugToolLineSetSimParam::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolLineSetSimParam* FesDebugToolLineSetSimParam::default_instance_ = NULL; + +FesDebugToolLineSetSimParam* FesDebugToolLineSetSimParam::New() const { + return new FesDebugToolLineSetSimParam; +} + +void FesDebugToolLineSetSimParam::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(min_value_, period_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolLineSetSimParam::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolLineSetSimParam) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required double min_value = 1; + case 1: { + if (tag == 9) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &min_value_))); + set_has_min_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(17)) goto parse_max_value; + break; + } + + // required double max_value = 2; + case 2: { + if (tag == 17) { + parse_max_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &max_value_))); + set_has_max_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(25)) goto parse_step_value; + break; + } + + // required double step_value = 3; + case 3: { + if (tag == 25) { + parse_step_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &step_value_))); + set_has_step_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_period; + break; + } + + // required int32 period = 4; + case 4: { + if (tag == 32) { + parse_period: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &period_))); + set_has_period(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolLineSetSimParam) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolLineSetSimParam) + return false; +#undef DO_ +} + +void FesDebugToolLineSetSimParam::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolLineSetSimParam) + // required double min_value = 1; + if (has_min_value()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->min_value(), output); + } + + // required double max_value = 2; + if (has_max_value()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->max_value(), output); + } + + // required double step_value = 3; + if (has_step_value()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(3, this->step_value(), output); + } + + // required int32 period = 4; + if (has_period()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->period(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolLineSetSimParam) +} + +::google::protobuf::uint8* FesDebugToolLineSetSimParam::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolLineSetSimParam) + // required double min_value = 1; + if (has_min_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->min_value(), target); + } + + // required double max_value = 2; + if (has_max_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->max_value(), target); + } + + // required double step_value = 3; + if (has_step_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(3, this->step_value(), target); + } + + // required int32 period = 4; + if (has_period()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->period(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolLineSetSimParam) + return target; +} + +int FesDebugToolLineSetSimParam::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required double min_value = 1; + if (has_min_value()) { + total_size += 1 + 8; + } + + // required double max_value = 2; + if (has_max_value()) { + total_size += 1 + 8; + } + + // required double step_value = 3; + if (has_step_value()) { + total_size += 1 + 8; + } + + // required int32 period = 4; + if (has_period()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->period()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolLineSetSimParam::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolLineSetSimParam* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolLineSetSimParam::MergeFrom(const FesDebugToolLineSetSimParam& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_min_value()) { + set_min_value(from.min_value()); + } + if (from.has_max_value()) { + set_max_value(from.max_value()); + } + if (from.has_step_value()) { + set_step_value(from.step_value()); + } + if (from.has_period()) { + set_period(from.period()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolLineSetSimParam::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolLineSetSimParam::CopyFrom(const FesDebugToolLineSetSimParam& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolLineSetSimParam::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + return true; +} + +void FesDebugToolLineSetSimParam::Swap(FesDebugToolLineSetSimParam* other) { + if (other != this) { + std::swap(min_value_, other->min_value_); + std::swap(max_value_, other->max_value_); + std::swap(step_value_, other->step_value_); + std::swap(period_, other->period_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolLineSetSimParam::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolLineSetSimParam_descriptor_; + metadata.reflection = FesDebugToolLineSetSimParam_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolRandSetSimParam::kMinValueFieldNumber; +const int FesDebugToolRandSetSimParam::kMaxValueFieldNumber; +const int FesDebugToolRandSetSimParam::kPeriodFieldNumber; +#endif // !_MSC_VER + +FesDebugToolRandSetSimParam::FesDebugToolRandSetSimParam() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolRandSetSimParam) +} + +void FesDebugToolRandSetSimParam::InitAsDefaultInstance() { +} + +FesDebugToolRandSetSimParam::FesDebugToolRandSetSimParam(const FesDebugToolRandSetSimParam& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolRandSetSimParam) +} + +void FesDebugToolRandSetSimParam::SharedCtor() { + _cached_size_ = 0; + min_value_ = 0; + max_value_ = 0; + period_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolRandSetSimParam::~FesDebugToolRandSetSimParam() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolRandSetSimParam) + SharedDtor(); +} + +void FesDebugToolRandSetSimParam::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolRandSetSimParam::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolRandSetSimParam::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolRandSetSimParam_descriptor_; +} + +const FesDebugToolRandSetSimParam& FesDebugToolRandSetSimParam::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolRandSetSimParam* FesDebugToolRandSetSimParam::default_instance_ = NULL; + +FesDebugToolRandSetSimParam* FesDebugToolRandSetSimParam::New() const { + return new FesDebugToolRandSetSimParam; +} + +void FesDebugToolRandSetSimParam::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(min_value_, period_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolRandSetSimParam::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolRandSetSimParam) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional double min_value = 1; + case 1: { + if (tag == 9) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &min_value_))); + set_has_min_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(17)) goto parse_max_value; + break; + } + + // optional double max_value = 2; + case 2: { + if (tag == 17) { + parse_max_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &max_value_))); + set_has_max_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_period; + break; + } + + // required int32 period = 3; + case 3: { + if (tag == 24) { + parse_period: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &period_))); + set_has_period(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolRandSetSimParam) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolRandSetSimParam) + return false; +#undef DO_ +} + +void FesDebugToolRandSetSimParam::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolRandSetSimParam) + // optional double min_value = 1; + if (has_min_value()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->min_value(), output); + } + + // optional double max_value = 2; + if (has_max_value()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->max_value(), output); + } + + // required int32 period = 3; + if (has_period()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->period(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolRandSetSimParam) +} + +::google::protobuf::uint8* FesDebugToolRandSetSimParam::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolRandSetSimParam) + // optional double min_value = 1; + if (has_min_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->min_value(), target); + } + + // optional double max_value = 2; + if (has_max_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->max_value(), target); + } + + // required int32 period = 3; + if (has_period()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->period(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolRandSetSimParam) + return target; +} + +int FesDebugToolRandSetSimParam::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional double min_value = 1; + if (has_min_value()) { + total_size += 1 + 8; + } + + // optional double max_value = 2; + if (has_max_value()) { + total_size += 1 + 8; + } + + // required int32 period = 3; + if (has_period()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->period()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolRandSetSimParam::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolRandSetSimParam* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolRandSetSimParam::MergeFrom(const FesDebugToolRandSetSimParam& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_min_value()) { + set_min_value(from.min_value()); + } + if (from.has_max_value()) { + set_max_value(from.max_value()); + } + if (from.has_period()) { + set_period(from.period()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolRandSetSimParam::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolRandSetSimParam::CopyFrom(const FesDebugToolRandSetSimParam& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolRandSetSimParam::IsInitialized() const { + if ((_has_bits_[0] & 0x00000004) != 0x00000004) return false; + + return true; +} + +void FesDebugToolRandSetSimParam::Swap(FesDebugToolRandSetSimParam* other) { + if (other != this) { + std::swap(min_value_, other->min_value_); + std::swap(max_value_, other->max_value_); + std::swap(period_, other->period_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolRandSetSimParam::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolRandSetSimParam_descriptor_; + metadata.reflection = FesDebugToolRandSetSimParam_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolValueSimSetReqMsg::kSimModeFieldNumber; +const int FesDebugToolValueSimSetReqMsg::kSimRangeFieldNumber; +const int FesDebugToolValueSimSetReqMsg::kRtuNoFieldNumber; +const int FesDebugToolValueSimSetReqMsg::kPntNoFieldNumber; +const int FesDebugToolValueSimSetReqMsg::kStatusFieldNumber; +const int FesDebugToolValueSimSetReqMsg::kValueSetParamFieldNumber; +const int FesDebugToolValueSimSetReqMsg::kLineSetParamFieldNumber; +const int FesDebugToolValueSimSetReqMsg::kRandSetParamFieldNumber; +#endif // !_MSC_VER + +FesDebugToolValueSimSetReqMsg::FesDebugToolValueSimSetReqMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolValueSimSetReqMsg) +} + +void FesDebugToolValueSimSetReqMsg::InitAsDefaultInstance() { + value_set_param_ = const_cast< ::iot_idl::FesDebugToolValueSetSimParam*>(&::iot_idl::FesDebugToolValueSetSimParam::default_instance()); + line_set_param_ = const_cast< ::iot_idl::FesDebugToolLineSetSimParam*>(&::iot_idl::FesDebugToolLineSetSimParam::default_instance()); + rand_set_param_ = const_cast< ::iot_idl::FesDebugToolRandSetSimParam*>(&::iot_idl::FesDebugToolRandSetSimParam::default_instance()); +} + +FesDebugToolValueSimSetReqMsg::FesDebugToolValueSimSetReqMsg(const FesDebugToolValueSimSetReqMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolValueSimSetReqMsg) +} + +void FesDebugToolValueSimSetReqMsg::SharedCtor() { + _cached_size_ = 0; + sim_mode_ = 1; + sim_range_ = 1; + rtu_no_ = 0; + pnt_no_ = 0; + status_ = 0u; + value_set_param_ = NULL; + line_set_param_ = NULL; + rand_set_param_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolValueSimSetReqMsg::~FesDebugToolValueSimSetReqMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolValueSimSetReqMsg) + SharedDtor(); +} + +void FesDebugToolValueSimSetReqMsg::SharedDtor() { + if (this != default_instance_) { + delete value_set_param_; + delete line_set_param_; + delete rand_set_param_; + } +} + +void FesDebugToolValueSimSetReqMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolValueSimSetReqMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolValueSimSetReqMsg_descriptor_; +} + +const FesDebugToolValueSimSetReqMsg& FesDebugToolValueSimSetReqMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolValueSimSetReqMsg* FesDebugToolValueSimSetReqMsg::default_instance_ = NULL; + +FesDebugToolValueSimSetReqMsg* FesDebugToolValueSimSetReqMsg::New() const { + return new FesDebugToolValueSimSetReqMsg; +} + +void FesDebugToolValueSimSetReqMsg::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 255) { + ZR_(rtu_no_, pnt_no_); + sim_mode_ = 1; + sim_range_ = 1; + status_ = 0u; + if (has_value_set_param()) { + if (value_set_param_ != NULL) value_set_param_->::iot_idl::FesDebugToolValueSetSimParam::Clear(); + } + if (has_line_set_param()) { + if (line_set_param_ != NULL) line_set_param_->::iot_idl::FesDebugToolLineSetSimParam::Clear(); + } + if (has_rand_set_param()) { + if (rand_set_param_ != NULL) rand_set_param_->::iot_idl::FesDebugToolRandSetSimParam::Clear(); + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolValueSimSetReqMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolValueSimSetReqMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .iot_idl.enFesDebugSimMode sim_mode = 1; + case 1: { + if (tag == 8) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::iot_idl::enFesDebugSimMode_IsValid(value)) { + set_sim_mode(static_cast< ::iot_idl::enFesDebugSimMode >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_sim_range; + break; + } + + // required .iot_idl.enFesDebugSimRangeType sim_range = 2; + case 2: { + if (tag == 16) { + parse_sim_range: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::iot_idl::enFesDebugSimRangeType_IsValid(value)) { + set_sim_range(static_cast< ::iot_idl::enFesDebugSimRangeType >(value)); + } else { + mutable_unknown_fields()->AddVarint(2, value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_rtu_no; + break; + } + + // optional int32 rtu_no = 3; + case 3: { + if (tag == 24) { + parse_rtu_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_no_))); + set_has_rtu_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_pnt_no; + break; + } + + // optional int32 pnt_no = 4; + case 4: { + if (tag == 32) { + parse_pnt_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &pnt_no_))); + set_has_pnt_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_status; + break; + } + + // optional uint32 status = 5; + case 5: { + if (tag == 40) { + parse_status: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &status_))); + set_has_status(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(50)) goto parse_value_set_param; + break; + } + + // optional .iot_idl.FesDebugToolValueSetSimParam value_set_param = 6; + case 6: { + if (tag == 50) { + parse_value_set_param: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_value_set_param())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(58)) goto parse_line_set_param; + break; + } + + // optional .iot_idl.FesDebugToolLineSetSimParam line_set_param = 7; + case 7: { + if (tag == 58) { + parse_line_set_param: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_line_set_param())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(66)) goto parse_rand_set_param; + break; + } + + // optional .iot_idl.FesDebugToolRandSetSimParam rand_set_param = 8; + case 8: { + if (tag == 66) { + parse_rand_set_param: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_rand_set_param())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolValueSimSetReqMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolValueSimSetReqMsg) + return false; +#undef DO_ +} + +void FesDebugToolValueSimSetReqMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolValueSimSetReqMsg) + // required .iot_idl.enFesDebugSimMode sim_mode = 1; + if (has_sim_mode()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->sim_mode(), output); + } + + // required .iot_idl.enFesDebugSimRangeType sim_range = 2; + if (has_sim_range()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 2, this->sim_range(), output); + } + + // optional int32 rtu_no = 3; + if (has_rtu_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->rtu_no(), output); + } + + // optional int32 pnt_no = 4; + if (has_pnt_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->pnt_no(), output); + } + + // optional uint32 status = 5; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->status(), output); + } + + // optional .iot_idl.FesDebugToolValueSetSimParam value_set_param = 6; + if (has_value_set_param()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 6, this->value_set_param(), output); + } + + // optional .iot_idl.FesDebugToolLineSetSimParam line_set_param = 7; + if (has_line_set_param()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 7, this->line_set_param(), output); + } + + // optional .iot_idl.FesDebugToolRandSetSimParam rand_set_param = 8; + if (has_rand_set_param()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 8, this->rand_set_param(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolValueSimSetReqMsg) +} + +::google::protobuf::uint8* FesDebugToolValueSimSetReqMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolValueSimSetReqMsg) + // required .iot_idl.enFesDebugSimMode sim_mode = 1; + if (has_sim_mode()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->sim_mode(), target); + } + + // required .iot_idl.enFesDebugSimRangeType sim_range = 2; + if (has_sim_range()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 2, this->sim_range(), target); + } + + // optional int32 rtu_no = 3; + if (has_rtu_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->rtu_no(), target); + } + + // optional int32 pnt_no = 4; + if (has_pnt_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->pnt_no(), target); + } + + // optional uint32 status = 5; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->status(), target); + } + + // optional .iot_idl.FesDebugToolValueSetSimParam value_set_param = 6; + if (has_value_set_param()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 6, this->value_set_param(), target); + } + + // optional .iot_idl.FesDebugToolLineSetSimParam line_set_param = 7; + if (has_line_set_param()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 7, this->line_set_param(), target); + } + + // optional .iot_idl.FesDebugToolRandSetSimParam rand_set_param = 8; + if (has_rand_set_param()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 8, this->rand_set_param(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolValueSimSetReqMsg) + return target; +} + +int FesDebugToolValueSimSetReqMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .iot_idl.enFesDebugSimMode sim_mode = 1; + if (has_sim_mode()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->sim_mode()); + } + + // required .iot_idl.enFesDebugSimRangeType sim_range = 2; + if (has_sim_range()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->sim_range()); + } + + // optional int32 rtu_no = 3; + if (has_rtu_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_no()); + } + + // optional int32 pnt_no = 4; + if (has_pnt_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->pnt_no()); + } + + // optional uint32 status = 5; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->status()); + } + + // optional .iot_idl.FesDebugToolValueSetSimParam value_set_param = 6; + if (has_value_set_param()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->value_set_param()); + } + + // optional .iot_idl.FesDebugToolLineSetSimParam line_set_param = 7; + if (has_line_set_param()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->line_set_param()); + } + + // optional .iot_idl.FesDebugToolRandSetSimParam rand_set_param = 8; + if (has_rand_set_param()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->rand_set_param()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolValueSimSetReqMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolValueSimSetReqMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolValueSimSetReqMsg::MergeFrom(const FesDebugToolValueSimSetReqMsg& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_sim_mode()) { + set_sim_mode(from.sim_mode()); + } + if (from.has_sim_range()) { + set_sim_range(from.sim_range()); + } + if (from.has_rtu_no()) { + set_rtu_no(from.rtu_no()); + } + if (from.has_pnt_no()) { + set_pnt_no(from.pnt_no()); + } + if (from.has_status()) { + set_status(from.status()); + } + if (from.has_value_set_param()) { + mutable_value_set_param()->::iot_idl::FesDebugToolValueSetSimParam::MergeFrom(from.value_set_param()); + } + if (from.has_line_set_param()) { + mutable_line_set_param()->::iot_idl::FesDebugToolLineSetSimParam::MergeFrom(from.line_set_param()); + } + if (from.has_rand_set_param()) { + mutable_rand_set_param()->::iot_idl::FesDebugToolRandSetSimParam::MergeFrom(from.rand_set_param()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolValueSimSetReqMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolValueSimSetReqMsg::CopyFrom(const FesDebugToolValueSimSetReqMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolValueSimSetReqMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_value_set_param()) { + if (!this->value_set_param().IsInitialized()) return false; + } + if (has_line_set_param()) { + if (!this->line_set_param().IsInitialized()) return false; + } + if (has_rand_set_param()) { + if (!this->rand_set_param().IsInitialized()) return false; + } + return true; +} + +void FesDebugToolValueSimSetReqMsg::Swap(FesDebugToolValueSimSetReqMsg* other) { + if (other != this) { + std::swap(sim_mode_, other->sim_mode_); + std::swap(sim_range_, other->sim_range_); + std::swap(rtu_no_, other->rtu_no_); + std::swap(pnt_no_, other->pnt_no_); + std::swap(status_, other->status_); + std::swap(value_set_param_, other->value_set_param_); + std::swap(line_set_param_, other->line_set_param_); + std::swap(rand_set_param_, other->rand_set_param_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolValueSimSetReqMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolValueSimSetReqMsg_descriptor_; + metadata.reflection = FesDebugToolValueSimSetReqMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolValueSimSetRepMsg::kSimModeFieldNumber; +const int FesDebugToolValueSimSetRepMsg::kBodyFieldNumber; +#endif // !_MSC_VER + +FesDebugToolValueSimSetRepMsg::FesDebugToolValueSimSetRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolValueSimSetRepMsg) +} + +void FesDebugToolValueSimSetRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolValueSimSetRepMsg::FesDebugToolValueSimSetRepMsg(const FesDebugToolValueSimSetRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolValueSimSetRepMsg) +} + +void FesDebugToolValueSimSetRepMsg::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + sim_mode_ = 1; + body_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolValueSimSetRepMsg::~FesDebugToolValueSimSetRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolValueSimSetRepMsg) + SharedDtor(); +} + +void FesDebugToolValueSimSetRepMsg::SharedDtor() { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete body_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolValueSimSetRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolValueSimSetRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolValueSimSetRepMsg_descriptor_; +} + +const FesDebugToolValueSimSetRepMsg& FesDebugToolValueSimSetRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolValueSimSetRepMsg* FesDebugToolValueSimSetRepMsg::default_instance_ = NULL; + +FesDebugToolValueSimSetRepMsg* FesDebugToolValueSimSetRepMsg::New() const { + return new FesDebugToolValueSimSetRepMsg; +} + +void FesDebugToolValueSimSetRepMsg::Clear() { + if (_has_bits_[0 / 32] & 3) { + sim_mode_ = 1; + if (has_body()) { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolValueSimSetRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolValueSimSetRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .iot_idl.enFesDebugSimMode sim_mode = 1; + case 1: { + if (tag == 8) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::iot_idl::enFesDebugSimMode_IsValid(value)) { + set_sim_mode(static_cast< ::iot_idl::enFesDebugSimMode >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_body; + break; + } + + // optional string body = 2; + case 2: { + if (tag == 18) { + parse_body: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_body())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->body().data(), this->body().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "body"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolValueSimSetRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolValueSimSetRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolValueSimSetRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolValueSimSetRepMsg) + // required .iot_idl.enFesDebugSimMode sim_mode = 1; + if (has_sim_mode()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->sim_mode(), output); + } + + // optional string body = 2; + if (has_body()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->body().data(), this->body().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "body"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->body(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolValueSimSetRepMsg) +} + +::google::protobuf::uint8* FesDebugToolValueSimSetRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolValueSimSetRepMsg) + // required .iot_idl.enFesDebugSimMode sim_mode = 1; + if (has_sim_mode()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->sim_mode(), target); + } + + // optional string body = 2; + if (has_body()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->body().data(), this->body().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "body"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->body(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolValueSimSetRepMsg) + return target; +} + +int FesDebugToolValueSimSetRepMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .iot_idl.enFesDebugSimMode sim_mode = 1; + if (has_sim_mode()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->sim_mode()); + } + + // optional string body = 2; + if (has_body()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->body()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolValueSimSetRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolValueSimSetRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolValueSimSetRepMsg::MergeFrom(const FesDebugToolValueSimSetRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_sim_mode()) { + set_sim_mode(from.sim_mode()); + } + if (from.has_body()) { + set_body(from.body()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolValueSimSetRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolValueSimSetRepMsg::CopyFrom(const FesDebugToolValueSimSetRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolValueSimSetRepMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void FesDebugToolValueSimSetRepMsg::Swap(FesDebugToolValueSimSetRepMsg* other) { + if (other != this) { + std::swap(sim_mode_, other->sim_mode_); + std::swap(body_, other->body_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolValueSimSetRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolValueSimSetRepMsg_descriptor_; + metadata.reflection = FesDebugToolValueSimSetRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolSimEventRtuSoe::kEventSourceFieldNumber; +const int FesDebugToolSimEventRtuSoe::kRtuNoFieldNumber; +const int FesDebugToolSimEventRtuSoe::kPntNoFieldNumber; +const int FesDebugToolSimEventRtuSoe::kValueFieldNumber; +const int FesDebugToolSimEventRtuSoe::kStatusFieldNumber; +const int FesDebugToolSimEventRtuSoe::kFaultNumFieldNumber; +const int FesDebugToolSimEventRtuSoe::kFaultTypeFieldNumber; +const int FesDebugToolSimEventRtuSoe::kFaultValueFieldNumber; +#endif // !_MSC_VER + +FesDebugToolSimEventRtuSoe::FesDebugToolSimEventRtuSoe() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolSimEventRtuSoe) +} + +void FesDebugToolSimEventRtuSoe::InitAsDefaultInstance() { +} + +FesDebugToolSimEventRtuSoe::FesDebugToolSimEventRtuSoe(const FesDebugToolSimEventRtuSoe& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolSimEventRtuSoe) +} + +void FesDebugToolSimEventRtuSoe::SharedCtor() { + _cached_size_ = 0; + event_source_ = 0; + rtu_no_ = 0; + pnt_no_ = 0; + value_ = 0; + status_ = 0u; + fault_num_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolSimEventRtuSoe::~FesDebugToolSimEventRtuSoe() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolSimEventRtuSoe) + SharedDtor(); +} + +void FesDebugToolSimEventRtuSoe::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolSimEventRtuSoe::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolSimEventRtuSoe::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolSimEventRtuSoe_descriptor_; +} + +const FesDebugToolSimEventRtuSoe& FesDebugToolSimEventRtuSoe::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolSimEventRtuSoe* FesDebugToolSimEventRtuSoe::default_instance_ = NULL; + +FesDebugToolSimEventRtuSoe* FesDebugToolSimEventRtuSoe::New() const { + return new FesDebugToolSimEventRtuSoe; +} + +void FesDebugToolSimEventRtuSoe::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 63) { + ZR_(event_source_, fault_num_); + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + fault_type_.Clear(); + fault_value_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolSimEventRtuSoe::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolSimEventRtuSoe) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 event_source = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &event_source_))); + set_has_event_source(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_rtu_no; + break; + } + + // required int32 rtu_no = 2; + case 2: { + if (tag == 16) { + parse_rtu_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_no_))); + set_has_rtu_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_pnt_no; + break; + } + + // required int32 pnt_no = 3; + case 3: { + if (tag == 24) { + parse_pnt_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &pnt_no_))); + set_has_pnt_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_value; + break; + } + + // required int32 value = 4; + case 4: { + if (tag == 32) { + parse_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &value_))); + set_has_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_status; + break; + } + + // required uint32 status = 5; + case 5: { + if (tag == 40) { + parse_status: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &status_))); + set_has_status(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(48)) goto parse_fault_num; + break; + } + + // required int32 fault_num = 6; + case 6: { + if (tag == 48) { + parse_fault_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &fault_num_))); + set_has_fault_num(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(56)) goto parse_fault_type; + break; + } + + // repeated int32 fault_type = 7; + case 7: { + if (tag == 56) { + parse_fault_type: + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + 1, 56, input, this->mutable_fault_type()))); + } else if (tag == 58) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, this->mutable_fault_type()))); + } else { + goto handle_unusual; + } + if (input->ExpectTag(56)) goto parse_fault_type; + if (input->ExpectTag(69)) goto parse_fault_value; + break; + } + + // repeated float fault_value = 8; + case 8: { + if (tag == 69) { + parse_fault_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + 1, 69, input, this->mutable_fault_value()))); + } else if (tag == 66) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, this->mutable_fault_value()))); + } else { + goto handle_unusual; + } + if (input->ExpectTag(69)) goto parse_fault_value; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolSimEventRtuSoe) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolSimEventRtuSoe) + return false; +#undef DO_ +} + +void FesDebugToolSimEventRtuSoe::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolSimEventRtuSoe) + // required int32 event_source = 1; + if (has_event_source()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->event_source(), output); + } + + // required int32 rtu_no = 2; + if (has_rtu_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->rtu_no(), output); + } + + // required int32 pnt_no = 3; + if (has_pnt_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->pnt_no(), output); + } + + // required int32 value = 4; + if (has_value()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->value(), output); + } + + // required uint32 status = 5; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->status(), output); + } + + // required int32 fault_num = 6; + if (has_fault_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(6, this->fault_num(), output); + } + + // repeated int32 fault_type = 7; + for (int i = 0; i < this->fault_type_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteInt32( + 7, this->fault_type(i), output); + } + + // repeated float fault_value = 8; + for (int i = 0; i < this->fault_value_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteFloat( + 8, this->fault_value(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolSimEventRtuSoe) +} + +::google::protobuf::uint8* FesDebugToolSimEventRtuSoe::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolSimEventRtuSoe) + // required int32 event_source = 1; + if (has_event_source()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->event_source(), target); + } + + // required int32 rtu_no = 2; + if (has_rtu_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->rtu_no(), target); + } + + // required int32 pnt_no = 3; + if (has_pnt_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->pnt_no(), target); + } + + // required int32 value = 4; + if (has_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->value(), target); + } + + // required uint32 status = 5; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->status(), target); + } + + // required int32 fault_num = 6; + if (has_fault_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(6, this->fault_num(), target); + } + + // repeated int32 fault_type = 7; + for (int i = 0; i < this->fault_type_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32ToArray(7, this->fault_type(i), target); + } + + // repeated float fault_value = 8; + for (int i = 0; i < this->fault_value_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteFloatToArray(8, this->fault_value(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolSimEventRtuSoe) + return target; +} + +int FesDebugToolSimEventRtuSoe::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 event_source = 1; + if (has_event_source()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->event_source()); + } + + // required int32 rtu_no = 2; + if (has_rtu_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_no()); + } + + // required int32 pnt_no = 3; + if (has_pnt_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->pnt_no()); + } + + // required int32 value = 4; + if (has_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->value()); + } + + // required uint32 status = 5; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->status()); + } + + // required int32 fault_num = 6; + if (has_fault_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->fault_num()); + } + + } + // repeated int32 fault_type = 7; + { + int data_size = 0; + for (int i = 0; i < this->fault_type_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + Int32Size(this->fault_type(i)); + } + total_size += 1 * this->fault_type_size() + data_size; + } + + // repeated float fault_value = 8; + { + int data_size = 0; + data_size = 4 * this->fault_value_size(); + total_size += 1 * this->fault_value_size() + data_size; + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolSimEventRtuSoe::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolSimEventRtuSoe* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolSimEventRtuSoe::MergeFrom(const FesDebugToolSimEventRtuSoe& from) { + GOOGLE_CHECK_NE(&from, this); + fault_type_.MergeFrom(from.fault_type_); + fault_value_.MergeFrom(from.fault_value_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_event_source()) { + set_event_source(from.event_source()); + } + if (from.has_rtu_no()) { + set_rtu_no(from.rtu_no()); + } + if (from.has_pnt_no()) { + set_pnt_no(from.pnt_no()); + } + if (from.has_value()) { + set_value(from.value()); + } + if (from.has_status()) { + set_status(from.status()); + } + if (from.has_fault_num()) { + set_fault_num(from.fault_num()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolSimEventRtuSoe::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolSimEventRtuSoe::CopyFrom(const FesDebugToolSimEventRtuSoe& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolSimEventRtuSoe::IsInitialized() const { + if ((_has_bits_[0] & 0x0000003f) != 0x0000003f) return false; + + return true; +} + +void FesDebugToolSimEventRtuSoe::Swap(FesDebugToolSimEventRtuSoe* other) { + if (other != this) { + std::swap(event_source_, other->event_source_); + std::swap(rtu_no_, other->rtu_no_); + std::swap(pnt_no_, other->pnt_no_); + std::swap(value_, other->value_); + std::swap(status_, other->status_); + std::swap(fault_num_, other->fault_num_); + fault_type_.Swap(&other->fault_type_); + fault_value_.Swap(&other->fault_value_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolSimEventRtuSoe::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolSimEventRtuSoe_descriptor_; + metadata.reflection = FesDebugToolSimEventRtuSoe_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolSimEventCreateReqMsg::kEventTypeFieldNumber; +const int FesDebugToolSimEventCreateReqMsg::kEventFieldNumber; +#endif // !_MSC_VER + +FesDebugToolSimEventCreateReqMsg::FesDebugToolSimEventCreateReqMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolSimEventCreateReqMsg) +} + +void FesDebugToolSimEventCreateReqMsg::InitAsDefaultInstance() { + event_ = const_cast< ::iot_idl::FesDebugToolSimEventRtuSoe*>(&::iot_idl::FesDebugToolSimEventRtuSoe::default_instance()); +} + +FesDebugToolSimEventCreateReqMsg::FesDebugToolSimEventCreateReqMsg(const FesDebugToolSimEventCreateReqMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolSimEventCreateReqMsg) +} + +void FesDebugToolSimEventCreateReqMsg::SharedCtor() { + _cached_size_ = 0; + event_type_ = 1; + event_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolSimEventCreateReqMsg::~FesDebugToolSimEventCreateReqMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolSimEventCreateReqMsg) + SharedDtor(); +} + +void FesDebugToolSimEventCreateReqMsg::SharedDtor() { + if (this != default_instance_) { + delete event_; + } +} + +void FesDebugToolSimEventCreateReqMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolSimEventCreateReqMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolSimEventCreateReqMsg_descriptor_; +} + +const FesDebugToolSimEventCreateReqMsg& FesDebugToolSimEventCreateReqMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolSimEventCreateReqMsg* FesDebugToolSimEventCreateReqMsg::default_instance_ = NULL; + +FesDebugToolSimEventCreateReqMsg* FesDebugToolSimEventCreateReqMsg::New() const { + return new FesDebugToolSimEventCreateReqMsg; +} + +void FesDebugToolSimEventCreateReqMsg::Clear() { + if (_has_bits_[0 / 32] & 3) { + event_type_ = 1; + if (has_event()) { + if (event_ != NULL) event_->::iot_idl::FesDebugToolSimEventRtuSoe::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolSimEventCreateReqMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolSimEventCreateReqMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .iot_idl.enFesDebugEventSimType event_type = 1; + case 1: { + if (tag == 8) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::iot_idl::enFesDebugEventSimType_IsValid(value)) { + set_event_type(static_cast< ::iot_idl::enFesDebugEventSimType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_event; + break; + } + + // optional .iot_idl.FesDebugToolSimEventRtuSoe event = 2; + case 2: { + if (tag == 18) { + parse_event: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_event())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolSimEventCreateReqMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolSimEventCreateReqMsg) + return false; +#undef DO_ +} + +void FesDebugToolSimEventCreateReqMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolSimEventCreateReqMsg) + // required .iot_idl.enFesDebugEventSimType event_type = 1; + if (has_event_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->event_type(), output); + } + + // optional .iot_idl.FesDebugToolSimEventRtuSoe event = 2; + if (has_event()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->event(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolSimEventCreateReqMsg) +} + +::google::protobuf::uint8* FesDebugToolSimEventCreateReqMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolSimEventCreateReqMsg) + // required .iot_idl.enFesDebugEventSimType event_type = 1; + if (has_event_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->event_type(), target); + } + + // optional .iot_idl.FesDebugToolSimEventRtuSoe event = 2; + if (has_event()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->event(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolSimEventCreateReqMsg) + return target; +} + +int FesDebugToolSimEventCreateReqMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .iot_idl.enFesDebugEventSimType event_type = 1; + if (has_event_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->event_type()); + } + + // optional .iot_idl.FesDebugToolSimEventRtuSoe event = 2; + if (has_event()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->event()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolSimEventCreateReqMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolSimEventCreateReqMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolSimEventCreateReqMsg::MergeFrom(const FesDebugToolSimEventCreateReqMsg& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_event_type()) { + set_event_type(from.event_type()); + } + if (from.has_event()) { + mutable_event()->::iot_idl::FesDebugToolSimEventRtuSoe::MergeFrom(from.event()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolSimEventCreateReqMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolSimEventCreateReqMsg::CopyFrom(const FesDebugToolSimEventCreateReqMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolSimEventCreateReqMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_event()) { + if (!this->event().IsInitialized()) return false; + } + return true; +} + +void FesDebugToolSimEventCreateReqMsg::Swap(FesDebugToolSimEventCreateReqMsg* other) { + if (other != this) { + std::swap(event_type_, other->event_type_); + std::swap(event_, other->event_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolSimEventCreateReqMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolSimEventCreateReqMsg_descriptor_; + metadata.reflection = FesDebugToolSimEventCreateReqMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolSimEventCreateRepMsg::kEventTypeFieldNumber; +const int FesDebugToolSimEventCreateRepMsg::kBodyFieldNumber; +#endif // !_MSC_VER + +FesDebugToolSimEventCreateRepMsg::FesDebugToolSimEventCreateRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolSimEventCreateRepMsg) +} + +void FesDebugToolSimEventCreateRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolSimEventCreateRepMsg::FesDebugToolSimEventCreateRepMsg(const FesDebugToolSimEventCreateRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolSimEventCreateRepMsg) +} + +void FesDebugToolSimEventCreateRepMsg::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + event_type_ = 1; + body_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolSimEventCreateRepMsg::~FesDebugToolSimEventCreateRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolSimEventCreateRepMsg) + SharedDtor(); +} + +void FesDebugToolSimEventCreateRepMsg::SharedDtor() { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete body_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolSimEventCreateRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolSimEventCreateRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolSimEventCreateRepMsg_descriptor_; +} + +const FesDebugToolSimEventCreateRepMsg& FesDebugToolSimEventCreateRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolSimEventCreateRepMsg* FesDebugToolSimEventCreateRepMsg::default_instance_ = NULL; + +FesDebugToolSimEventCreateRepMsg* FesDebugToolSimEventCreateRepMsg::New() const { + return new FesDebugToolSimEventCreateRepMsg; +} + +void FesDebugToolSimEventCreateRepMsg::Clear() { + if (_has_bits_[0 / 32] & 3) { + event_type_ = 1; + if (has_body()) { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolSimEventCreateRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolSimEventCreateRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .iot_idl.enFesDebugEventSimType event_type = 1; + case 1: { + if (tag == 8) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::iot_idl::enFesDebugEventSimType_IsValid(value)) { + set_event_type(static_cast< ::iot_idl::enFesDebugEventSimType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_body; + break; + } + + // optional string body = 2; + case 2: { + if (tag == 18) { + parse_body: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_body())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->body().data(), this->body().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "body"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolSimEventCreateRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolSimEventCreateRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolSimEventCreateRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolSimEventCreateRepMsg) + // required .iot_idl.enFesDebugEventSimType event_type = 1; + if (has_event_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->event_type(), output); + } + + // optional string body = 2; + if (has_body()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->body().data(), this->body().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "body"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->body(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolSimEventCreateRepMsg) +} + +::google::protobuf::uint8* FesDebugToolSimEventCreateRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolSimEventCreateRepMsg) + // required .iot_idl.enFesDebugEventSimType event_type = 1; + if (has_event_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->event_type(), target); + } + + // optional string body = 2; + if (has_body()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->body().data(), this->body().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "body"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->body(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolSimEventCreateRepMsg) + return target; +} + +int FesDebugToolSimEventCreateRepMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .iot_idl.enFesDebugEventSimType event_type = 1; + if (has_event_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->event_type()); + } + + // optional string body = 2; + if (has_body()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->body()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolSimEventCreateRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolSimEventCreateRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolSimEventCreateRepMsg::MergeFrom(const FesDebugToolSimEventCreateRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_event_type()) { + set_event_type(from.event_type()); + } + if (from.has_body()) { + set_body(from.body()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolSimEventCreateRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolSimEventCreateRepMsg::CopyFrom(const FesDebugToolSimEventCreateRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolSimEventCreateRepMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void FesDebugToolSimEventCreateRepMsg::Swap(FesDebugToolSimEventCreateRepMsg* other) { + if (other != this) { + std::swap(event_type_, other->event_type_); + std::swap(body_, other->body_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolSimEventCreateRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolSimEventCreateRepMsg_descriptor_; + metadata.reflection = FesDebugToolSimEventCreateRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolSimControlReqMsg::kCtrlTypeFieldNumber; +const int FesDebugToolSimControlReqMsg::kSeqNoFieldNumber; +const int FesDebugToolSimControlReqMsg::kRtuNoFieldNumber; +const int FesDebugToolSimControlReqMsg::kPntNoFieldNumber; +const int FesDebugToolSimControlReqMsg::kFloatValueFieldNumber; +const int FesDebugToolSimControlReqMsg::kIntValueFieldNumber; +#endif // !_MSC_VER + +FesDebugToolSimControlReqMsg::FesDebugToolSimControlReqMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolSimControlReqMsg) +} + +void FesDebugToolSimControlReqMsg::InitAsDefaultInstance() { +} + +FesDebugToolSimControlReqMsg::FesDebugToolSimControlReqMsg(const FesDebugToolSimControlReqMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolSimControlReqMsg) +} + +void FesDebugToolSimControlReqMsg::SharedCtor() { + _cached_size_ = 0; + ctrl_type_ = 0; + seq_no_ = GOOGLE_LONGLONG(0); + rtu_no_ = 0; + pnt_no_ = 0; + float_value_ = 0; + int_value_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolSimControlReqMsg::~FesDebugToolSimControlReqMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolSimControlReqMsg) + SharedDtor(); +} + +void FesDebugToolSimControlReqMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolSimControlReqMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolSimControlReqMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolSimControlReqMsg_descriptor_; +} + +const FesDebugToolSimControlReqMsg& FesDebugToolSimControlReqMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolSimControlReqMsg* FesDebugToolSimControlReqMsg::default_instance_ = NULL; + +FesDebugToolSimControlReqMsg* FesDebugToolSimControlReqMsg::New() const { + return new FesDebugToolSimControlReqMsg; +} + +void FesDebugToolSimControlReqMsg::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 63) { + ZR_(seq_no_, int_value_); + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolSimControlReqMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolSimControlReqMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 ctrl_type = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &ctrl_type_))); + set_has_ctrl_type(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_seq_no; + break; + } + + // required int64 seq_no = 2; + case 2: { + if (tag == 16) { + parse_seq_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &seq_no_))); + set_has_seq_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_rtu_no; + break; + } + + // required int32 rtu_no = 3; + case 3: { + if (tag == 24) { + parse_rtu_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_no_))); + set_has_rtu_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_pnt_no; + break; + } + + // required int32 pnt_no = 4; + case 4: { + if (tag == 32) { + parse_pnt_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &pnt_no_))); + set_has_pnt_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(45)) goto parse_float_value; + break; + } + + // optional float float_value = 5; + case 5: { + if (tag == 45) { + parse_float_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &float_value_))); + set_has_float_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(48)) goto parse_int_value; + break; + } + + // optional int32 int_value = 6; + case 6: { + if (tag == 48) { + parse_int_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &int_value_))); + set_has_int_value(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolSimControlReqMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolSimControlReqMsg) + return false; +#undef DO_ +} + +void FesDebugToolSimControlReqMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolSimControlReqMsg) + // required int32 ctrl_type = 1; + if (has_ctrl_type()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->ctrl_type(), output); + } + + // required int64 seq_no = 2; + if (has_seq_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(2, this->seq_no(), output); + } + + // required int32 rtu_no = 3; + if (has_rtu_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->rtu_no(), output); + } + + // required int32 pnt_no = 4; + if (has_pnt_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->pnt_no(), output); + } + + // optional float float_value = 5; + if (has_float_value()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(5, this->float_value(), output); + } + + // optional int32 int_value = 6; + if (has_int_value()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(6, this->int_value(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolSimControlReqMsg) +} + +::google::protobuf::uint8* FesDebugToolSimControlReqMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolSimControlReqMsg) + // required int32 ctrl_type = 1; + if (has_ctrl_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->ctrl_type(), target); + } + + // required int64 seq_no = 2; + if (has_seq_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(2, this->seq_no(), target); + } + + // required int32 rtu_no = 3; + if (has_rtu_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->rtu_no(), target); + } + + // required int32 pnt_no = 4; + if (has_pnt_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->pnt_no(), target); + } + + // optional float float_value = 5; + if (has_float_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(5, this->float_value(), target); + } + + // optional int32 int_value = 6; + if (has_int_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(6, this->int_value(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolSimControlReqMsg) + return target; +} + +int FesDebugToolSimControlReqMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 ctrl_type = 1; + if (has_ctrl_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->ctrl_type()); + } + + // required int64 seq_no = 2; + if (has_seq_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->seq_no()); + } + + // required int32 rtu_no = 3; + if (has_rtu_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_no()); + } + + // required int32 pnt_no = 4; + if (has_pnt_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->pnt_no()); + } + + // optional float float_value = 5; + if (has_float_value()) { + total_size += 1 + 4; + } + + // optional int32 int_value = 6; + if (has_int_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->int_value()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolSimControlReqMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolSimControlReqMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolSimControlReqMsg::MergeFrom(const FesDebugToolSimControlReqMsg& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_ctrl_type()) { + set_ctrl_type(from.ctrl_type()); + } + if (from.has_seq_no()) { + set_seq_no(from.seq_no()); + } + if (from.has_rtu_no()) { + set_rtu_no(from.rtu_no()); + } + if (from.has_pnt_no()) { + set_pnt_no(from.pnt_no()); + } + if (from.has_float_value()) { + set_float_value(from.float_value()); + } + if (from.has_int_value()) { + set_int_value(from.int_value()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolSimControlReqMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolSimControlReqMsg::CopyFrom(const FesDebugToolSimControlReqMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolSimControlReqMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + return true; +} + +void FesDebugToolSimControlReqMsg::Swap(FesDebugToolSimControlReqMsg* other) { + if (other != this) { + std::swap(ctrl_type_, other->ctrl_type_); + std::swap(seq_no_, other->seq_no_); + std::swap(rtu_no_, other->rtu_no_); + std::swap(pnt_no_, other->pnt_no_); + std::swap(float_value_, other->float_value_); + std::swap(int_value_, other->int_value_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolSimControlReqMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolSimControlReqMsg_descriptor_; + metadata.reflection = FesDebugToolSimControlReqMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolSimControlRepMsg::kCtrlTypeFieldNumber; +const int FesDebugToolSimControlRepMsg::kSeqNoFieldNumber; +const int FesDebugToolSimControlRepMsg::kSuccessFieldNumber; +const int FesDebugToolSimControlRepMsg::kErrMsgFieldNumber; +#endif // !_MSC_VER + +FesDebugToolSimControlRepMsg::FesDebugToolSimControlRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolSimControlRepMsg) +} + +void FesDebugToolSimControlRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolSimControlRepMsg::FesDebugToolSimControlRepMsg(const FesDebugToolSimControlRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolSimControlRepMsg) +} + +void FesDebugToolSimControlRepMsg::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + ctrl_type_ = 0; + seq_no_ = GOOGLE_LONGLONG(0); + success_ = false; + err_msg_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolSimControlRepMsg::~FesDebugToolSimControlRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolSimControlRepMsg) + SharedDtor(); +} + +void FesDebugToolSimControlRepMsg::SharedDtor() { + if (err_msg_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete err_msg_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolSimControlRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolSimControlRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolSimControlRepMsg_descriptor_; +} + +const FesDebugToolSimControlRepMsg& FesDebugToolSimControlRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolSimControlRepMsg* FesDebugToolSimControlRepMsg::default_instance_ = NULL; + +FesDebugToolSimControlRepMsg* FesDebugToolSimControlRepMsg::New() const { + return new FesDebugToolSimControlRepMsg; +} + +void FesDebugToolSimControlRepMsg::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 15) { + ZR_(seq_no_, success_); + if (has_err_msg()) { + if (err_msg_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + err_msg_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolSimControlRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolSimControlRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 ctrl_type = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &ctrl_type_))); + set_has_ctrl_type(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_seq_no; + break; + } + + // required int64 seq_no = 2; + case 2: { + if (tag == 16) { + parse_seq_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &seq_no_))); + set_has_seq_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_success; + break; + } + + // required bool success = 3; + case 3: { + if (tag == 24) { + parse_success: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &success_))); + set_has_success(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_err_msg; + break; + } + + // optional string err_msg = 4; + case 4: { + if (tag == 34) { + parse_err_msg: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_err_msg())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->err_msg().data(), this->err_msg().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "err_msg"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolSimControlRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolSimControlRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolSimControlRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolSimControlRepMsg) + // required int32 ctrl_type = 1; + if (has_ctrl_type()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->ctrl_type(), output); + } + + // required int64 seq_no = 2; + if (has_seq_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(2, this->seq_no(), output); + } + + // required bool success = 3; + if (has_success()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->success(), output); + } + + // optional string err_msg = 4; + if (has_err_msg()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->err_msg().data(), this->err_msg().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "err_msg"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 4, this->err_msg(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolSimControlRepMsg) +} + +::google::protobuf::uint8* FesDebugToolSimControlRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolSimControlRepMsg) + // required int32 ctrl_type = 1; + if (has_ctrl_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->ctrl_type(), target); + } + + // required int64 seq_no = 2; + if (has_seq_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(2, this->seq_no(), target); + } + + // required bool success = 3; + if (has_success()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->success(), target); + } + + // optional string err_msg = 4; + if (has_err_msg()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->err_msg().data(), this->err_msg().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "err_msg"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->err_msg(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolSimControlRepMsg) + return target; +} + +int FesDebugToolSimControlRepMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 ctrl_type = 1; + if (has_ctrl_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->ctrl_type()); + } + + // required int64 seq_no = 2; + if (has_seq_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->seq_no()); + } + + // required bool success = 3; + if (has_success()) { + total_size += 1 + 1; + } + + // optional string err_msg = 4; + if (has_err_msg()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->err_msg()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolSimControlRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolSimControlRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolSimControlRepMsg::MergeFrom(const FesDebugToolSimControlRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_ctrl_type()) { + set_ctrl_type(from.ctrl_type()); + } + if (from.has_seq_no()) { + set_seq_no(from.seq_no()); + } + if (from.has_success()) { + set_success(from.success()); + } + if (from.has_err_msg()) { + set_err_msg(from.err_msg()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolSimControlRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolSimControlRepMsg::CopyFrom(const FesDebugToolSimControlRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolSimControlRepMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void FesDebugToolSimControlRepMsg::Swap(FesDebugToolSimControlRepMsg* other) { + if (other != this) { + std::swap(ctrl_type_, other->ctrl_type_); + std::swap(seq_no_, other->seq_no_); + std::swap(success_, other->success_); + std::swap(err_msg_, other->err_msg_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolSimControlRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolSimControlRepMsg_descriptor_; + metadata.reflection = FesDebugToolSimControlRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolSimDefCmdReqMsg::kRtuNoFieldNumber; +const int FesDebugToolSimDefCmdReqMsg::kDevIdFieldNumber; +const int FesDebugToolSimDefCmdReqMsg::kKeysFieldNumber; +const int FesDebugToolSimDefCmdReqMsg::kValuesFieldNumber; +#endif // !_MSC_VER + +FesDebugToolSimDefCmdReqMsg::FesDebugToolSimDefCmdReqMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolSimDefCmdReqMsg) +} + +void FesDebugToolSimDefCmdReqMsg::InitAsDefaultInstance() { +} + +FesDebugToolSimDefCmdReqMsg::FesDebugToolSimDefCmdReqMsg(const FesDebugToolSimDefCmdReqMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolSimDefCmdReqMsg) +} + +void FesDebugToolSimDefCmdReqMsg::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + rtu_no_ = 0; + dev_id_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolSimDefCmdReqMsg::~FesDebugToolSimDefCmdReqMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolSimDefCmdReqMsg) + SharedDtor(); +} + +void FesDebugToolSimDefCmdReqMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolSimDefCmdReqMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolSimDefCmdReqMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolSimDefCmdReqMsg_descriptor_; +} + +const FesDebugToolSimDefCmdReqMsg& FesDebugToolSimDefCmdReqMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolSimDefCmdReqMsg* FesDebugToolSimDefCmdReqMsg::default_instance_ = NULL; + +FesDebugToolSimDefCmdReqMsg* FesDebugToolSimDefCmdReqMsg::New() const { + return new FesDebugToolSimDefCmdReqMsg; +} + +void FesDebugToolSimDefCmdReqMsg::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(rtu_no_, dev_id_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + keys_.Clear(); + values_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolSimDefCmdReqMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolSimDefCmdReqMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 rtu_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_no_))); + set_has_rtu_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_dev_id; + break; + } + + // required int32 dev_id = 2; + case 2: { + if (tag == 16) { + parse_dev_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &dev_id_))); + set_has_dev_id(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_keys; + break; + } + + // repeated string keys = 3; + case 3: { + if (tag == 26) { + parse_keys: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_keys())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->keys(this->keys_size() - 1).data(), + this->keys(this->keys_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE, + "keys"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_keys; + if (input->ExpectTag(34)) goto parse_values; + break; + } + + // repeated string values = 4; + case 4: { + if (tag == 34) { + parse_values: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_values())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->values(this->values_size() - 1).data(), + this->values(this->values_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE, + "values"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_values; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolSimDefCmdReqMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolSimDefCmdReqMsg) + return false; +#undef DO_ +} + +void FesDebugToolSimDefCmdReqMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolSimDefCmdReqMsg) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->rtu_no(), output); + } + + // required int32 dev_id = 2; + if (has_dev_id()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->dev_id(), output); + } + + // repeated string keys = 3; + for (int i = 0; i < this->keys_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->keys(i).data(), this->keys(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "keys"); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->keys(i), output); + } + + // repeated string values = 4; + for (int i = 0; i < this->values_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->values(i).data(), this->values(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "values"); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->values(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolSimDefCmdReqMsg) +} + +::google::protobuf::uint8* FesDebugToolSimDefCmdReqMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolSimDefCmdReqMsg) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->rtu_no(), target); + } + + // required int32 dev_id = 2; + if (has_dev_id()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->dev_id(), target); + } + + // repeated string keys = 3; + for (int i = 0; i < this->keys_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->keys(i).data(), this->keys(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "keys"); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(3, this->keys(i), target); + } + + // repeated string values = 4; + for (int i = 0; i < this->values_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->values(i).data(), this->values(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "values"); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(4, this->values(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolSimDefCmdReqMsg) + return target; +} + +int FesDebugToolSimDefCmdReqMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 rtu_no = 1; + if (has_rtu_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_no()); + } + + // required int32 dev_id = 2; + if (has_dev_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->dev_id()); + } + + } + // repeated string keys = 3; + total_size += 1 * this->keys_size(); + for (int i = 0; i < this->keys_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->keys(i)); + } + + // repeated string values = 4; + total_size += 1 * this->values_size(); + for (int i = 0; i < this->values_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->values(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolSimDefCmdReqMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolSimDefCmdReqMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolSimDefCmdReqMsg::MergeFrom(const FesDebugToolSimDefCmdReqMsg& from) { + GOOGLE_CHECK_NE(&from, this); + keys_.MergeFrom(from.keys_); + values_.MergeFrom(from.values_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_rtu_no()) { + set_rtu_no(from.rtu_no()); + } + if (from.has_dev_id()) { + set_dev_id(from.dev_id()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolSimDefCmdReqMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolSimDefCmdReqMsg::CopyFrom(const FesDebugToolSimDefCmdReqMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolSimDefCmdReqMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void FesDebugToolSimDefCmdReqMsg::Swap(FesDebugToolSimDefCmdReqMsg* other) { + if (other != this) { + std::swap(rtu_no_, other->rtu_no_); + std::swap(dev_id_, other->dev_id_); + keys_.Swap(&other->keys_); + values_.Swap(&other->values_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolSimDefCmdReqMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolSimDefCmdReqMsg_descriptor_; + metadata.reflection = FesDebugToolSimDefCmdReqMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolFwPntParam::kPntNoFieldNumber; +const int FesDebugToolFwPntParam::kUsedFieldNumber; +const int FesDebugToolFwPntParam::kFesRtuNoFieldNumber; +const int FesDebugToolFwPntParam::kFesPntNoFieldNumber; +const int FesDebugToolFwPntParam::kPntDescFieldNumber; +#endif // !_MSC_VER + +FesDebugToolFwPntParam::FesDebugToolFwPntParam() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolFwPntParam) +} + +void FesDebugToolFwPntParam::InitAsDefaultInstance() { +} + +FesDebugToolFwPntParam::FesDebugToolFwPntParam(const FesDebugToolFwPntParam& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolFwPntParam) +} + +void FesDebugToolFwPntParam::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + pnt_no_ = 0; + used_ = 0; + fes_rtu_no_ = 0; + fes_pnt_no_ = 0; + pnt_desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolFwPntParam::~FesDebugToolFwPntParam() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolFwPntParam) + SharedDtor(); +} + +void FesDebugToolFwPntParam::SharedDtor() { + if (pnt_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete pnt_desc_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolFwPntParam::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolFwPntParam::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolFwPntParam_descriptor_; +} + +const FesDebugToolFwPntParam& FesDebugToolFwPntParam::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolFwPntParam* FesDebugToolFwPntParam::default_instance_ = NULL; + +FesDebugToolFwPntParam* FesDebugToolFwPntParam::New() const { + return new FesDebugToolFwPntParam; +} + +void FesDebugToolFwPntParam::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 31) { + ZR_(pnt_no_, fes_pnt_no_); + if (has_pnt_desc()) { + if (pnt_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + pnt_desc_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolFwPntParam::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolFwPntParam) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 pnt_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &pnt_no_))); + set_has_pnt_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_used; + break; + } + + // required int32 used = 2; + case 2: { + if (tag == 16) { + parse_used: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &used_))); + set_has_used(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_fes_rtu_no; + break; + } + + // required int32 fes_rtu_no = 3; + case 3: { + if (tag == 24) { + parse_fes_rtu_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &fes_rtu_no_))); + set_has_fes_rtu_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_fes_pnt_no; + break; + } + + // required int32 fes_pnt_no = 4; + case 4: { + if (tag == 32) { + parse_fes_pnt_no: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &fes_pnt_no_))); + set_has_fes_pnt_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(42)) goto parse_pnt_desc; + break; + } + + // required string pnt_desc = 5; + case 5: { + if (tag == 42) { + parse_pnt_desc: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_pnt_desc())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->pnt_desc().data(), this->pnt_desc().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "pnt_desc"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolFwPntParam) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolFwPntParam) + return false; +#undef DO_ +} + +void FesDebugToolFwPntParam::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolFwPntParam) + // required int32 pnt_no = 1; + if (has_pnt_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->pnt_no(), output); + } + + // required int32 used = 2; + if (has_used()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->used(), output); + } + + // required int32 fes_rtu_no = 3; + if (has_fes_rtu_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->fes_rtu_no(), output); + } + + // required int32 fes_pnt_no = 4; + if (has_fes_pnt_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->fes_pnt_no(), output); + } + + // required string pnt_desc = 5; + if (has_pnt_desc()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->pnt_desc().data(), this->pnt_desc().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "pnt_desc"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 5, this->pnt_desc(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolFwPntParam) +} + +::google::protobuf::uint8* FesDebugToolFwPntParam::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolFwPntParam) + // required int32 pnt_no = 1; + if (has_pnt_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->pnt_no(), target); + } + + // required int32 used = 2; + if (has_used()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->used(), target); + } + + // required int32 fes_rtu_no = 3; + if (has_fes_rtu_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->fes_rtu_no(), target); + } + + // required int32 fes_pnt_no = 4; + if (has_fes_pnt_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->fes_pnt_no(), target); + } + + // required string pnt_desc = 5; + if (has_pnt_desc()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->pnt_desc().data(), this->pnt_desc().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "pnt_desc"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 5, this->pnt_desc(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolFwPntParam) + return target; +} + +int FesDebugToolFwPntParam::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 pnt_no = 1; + if (has_pnt_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->pnt_no()); + } + + // required int32 used = 2; + if (has_used()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->used()); + } + + // required int32 fes_rtu_no = 3; + if (has_fes_rtu_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->fes_rtu_no()); + } + + // required int32 fes_pnt_no = 4; + if (has_fes_pnt_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->fes_pnt_no()); + } + + // required string pnt_desc = 5; + if (has_pnt_desc()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->pnt_desc()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolFwPntParam::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolFwPntParam* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolFwPntParam::MergeFrom(const FesDebugToolFwPntParam& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_pnt_no()) { + set_pnt_no(from.pnt_no()); + } + if (from.has_used()) { + set_used(from.used()); + } + if (from.has_fes_rtu_no()) { + set_fes_rtu_no(from.fes_rtu_no()); + } + if (from.has_fes_pnt_no()) { + set_fes_pnt_no(from.fes_pnt_no()); + } + if (from.has_pnt_desc()) { + set_pnt_desc(from.pnt_desc()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolFwPntParam::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolFwPntParam::CopyFrom(const FesDebugToolFwPntParam& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolFwPntParam::IsInitialized() const { + if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false; + + return true; +} + +void FesDebugToolFwPntParam::Swap(FesDebugToolFwPntParam* other) { + if (other != this) { + std::swap(pnt_no_, other->pnt_no_); + std::swap(used_, other->used_); + std::swap(fes_rtu_no_, other->fes_rtu_no_); + std::swap(fes_pnt_no_, other->fes_pnt_no_); + std::swap(pnt_desc_, other->pnt_desc_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolFwPntParam::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolFwPntParam_descriptor_; + metadata.reflection = FesDebugToolFwPntParam_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolFwPntParamRepMsg::kRtuNoFieldNumber; +const int FesDebugToolFwPntParamRepMsg::kMaxPntNumFieldNumber; +const int FesDebugToolFwPntParamRepMsg::kPntParamFieldNumber; +#endif // !_MSC_VER + +FesDebugToolFwPntParamRepMsg::FesDebugToolFwPntParamRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolFwPntParamRepMsg) +} + +void FesDebugToolFwPntParamRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolFwPntParamRepMsg::FesDebugToolFwPntParamRepMsg(const FesDebugToolFwPntParamRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolFwPntParamRepMsg) +} + +void FesDebugToolFwPntParamRepMsg::SharedCtor() { + _cached_size_ = 0; + rtu_no_ = 0; + max_pnt_num_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolFwPntParamRepMsg::~FesDebugToolFwPntParamRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolFwPntParamRepMsg) + SharedDtor(); +} + +void FesDebugToolFwPntParamRepMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolFwPntParamRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolFwPntParamRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolFwPntParamRepMsg_descriptor_; +} + +const FesDebugToolFwPntParamRepMsg& FesDebugToolFwPntParamRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolFwPntParamRepMsg* FesDebugToolFwPntParamRepMsg::default_instance_ = NULL; + +FesDebugToolFwPntParamRepMsg* FesDebugToolFwPntParamRepMsg::New() const { + return new FesDebugToolFwPntParamRepMsg; +} + +void FesDebugToolFwPntParamRepMsg::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(rtu_no_, max_pnt_num_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + pnt_param_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolFwPntParamRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolFwPntParamRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 rtu_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rtu_no_))); + set_has_rtu_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_max_pnt_num; + break; + } + + // required int32 max_pnt_num = 2; + case 2: { + if (tag == 16) { + parse_max_pnt_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &max_pnt_num_))); + set_has_max_pnt_num(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_pnt_param; + break; + } + + // repeated .iot_idl.FesDebugToolFwPntParam pnt_param = 3; + case 3: { + if (tag == 26) { + parse_pnt_param: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_pnt_param())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_pnt_param; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolFwPntParamRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolFwPntParamRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolFwPntParamRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolFwPntParamRepMsg) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->rtu_no(), output); + } + + // required int32 max_pnt_num = 2; + if (has_max_pnt_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->max_pnt_num(), output); + } + + // repeated .iot_idl.FesDebugToolFwPntParam pnt_param = 3; + for (int i = 0; i < this->pnt_param_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->pnt_param(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolFwPntParamRepMsg) +} + +::google::protobuf::uint8* FesDebugToolFwPntParamRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolFwPntParamRepMsg) + // required int32 rtu_no = 1; + if (has_rtu_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->rtu_no(), target); + } + + // required int32 max_pnt_num = 2; + if (has_max_pnt_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->max_pnt_num(), target); + } + + // repeated .iot_idl.FesDebugToolFwPntParam pnt_param = 3; + for (int i = 0; i < this->pnt_param_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->pnt_param(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolFwPntParamRepMsg) + return target; +} + +int FesDebugToolFwPntParamRepMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 rtu_no = 1; + if (has_rtu_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rtu_no()); + } + + // required int32 max_pnt_num = 2; + if (has_max_pnt_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->max_pnt_num()); + } + + } + // repeated .iot_idl.FesDebugToolFwPntParam pnt_param = 3; + total_size += 1 * this->pnt_param_size(); + for (int i = 0; i < this->pnt_param_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->pnt_param(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolFwPntParamRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolFwPntParamRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolFwPntParamRepMsg::MergeFrom(const FesDebugToolFwPntParamRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + pnt_param_.MergeFrom(from.pnt_param_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_rtu_no()) { + set_rtu_no(from.rtu_no()); + } + if (from.has_max_pnt_num()) { + set_max_pnt_num(from.max_pnt_num()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolFwPntParamRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolFwPntParamRepMsg::CopyFrom(const FesDebugToolFwPntParamRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolFwPntParamRepMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->pnt_param())) return false; + return true; +} + +void FesDebugToolFwPntParamRepMsg::Swap(FesDebugToolFwPntParamRepMsg* other) { + if (other != this) { + std::swap(rtu_no_, other->rtu_no_); + std::swap(max_pnt_num_, other->max_pnt_num_); + pnt_param_.Swap(&other->pnt_param_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolFwPntParamRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolFwPntParamRepMsg_descriptor_; + metadata.reflection = FesDebugToolFwPntParamRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolSoeEvent::kTableNameFieldNumber; +const int FesDebugToolSoeEvent::kColNameFieldNumber; +const int FesDebugToolSoeEvent::kTagNameFieldNumber; +const int FesDebugToolSoeEvent::kStatusFieldNumber; +const int FesDebugToolSoeEvent::kValueFieldNumber; +const int FesDebugToolSoeEvent::kTimeFieldNumber; +const int FesDebugToolSoeEvent::kFaultNumFieldNumber; +const int FesDebugToolSoeEvent::kFaultTypeFieldNumber; +const int FesDebugToolSoeEvent::kFaultValueFieldNumber; +#endif // !_MSC_VER + +FesDebugToolSoeEvent::FesDebugToolSoeEvent() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolSoeEvent) +} + +void FesDebugToolSoeEvent::InitAsDefaultInstance() { +} + +FesDebugToolSoeEvent::FesDebugToolSoeEvent(const FesDebugToolSoeEvent& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolSoeEvent) +} + +void FesDebugToolSoeEvent::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + table_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + col_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + tag_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + status_ = 0u; + value_ = 0; + time_ = GOOGLE_ULONGLONG(0); + fault_num_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolSoeEvent::~FesDebugToolSoeEvent() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolSoeEvent) + SharedDtor(); +} + +void FesDebugToolSoeEvent::SharedDtor() { + if (table_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete table_name_; + } + if (col_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete col_name_; + } + if (tag_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete tag_name_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolSoeEvent::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolSoeEvent::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolSoeEvent_descriptor_; +} + +const FesDebugToolSoeEvent& FesDebugToolSoeEvent::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolSoeEvent* FesDebugToolSoeEvent::default_instance_ = NULL; + +FesDebugToolSoeEvent* FesDebugToolSoeEvent::New() const { + return new FesDebugToolSoeEvent; +} + +void FesDebugToolSoeEvent::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 127) { + ZR_(status_, time_); + if (has_table_name()) { + if (table_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + table_name_->clear(); + } + } + if (has_col_name()) { + if (col_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + col_name_->clear(); + } + } + if (has_tag_name()) { + if (tag_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_->clear(); + } + } + fault_num_ = 0; + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + fault_type_.Clear(); + fault_value_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolSoeEvent::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolSoeEvent) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string table_name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_table_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->table_name().data(), this->table_name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "table_name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_col_name; + break; + } + + // required string col_name = 2; + case 2: { + if (tag == 18) { + parse_col_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_col_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->col_name().data(), this->col_name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "col_name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_tag_name; + break; + } + + // required string tag_name = 3; + case 3: { + if (tag == 26) { + parse_tag_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_tag_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->tag_name().data(), this->tag_name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "tag_name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_status; + break; + } + + // required uint32 status = 4; + case 4: { + if (tag == 32) { + parse_status: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &status_))); + set_has_status(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_value; + break; + } + + // required int32 value = 5; + case 5: { + if (tag == 40) { + parse_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &value_))); + set_has_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(48)) goto parse_time; + break; + } + + // required uint64 time = 6; + case 6: { + if (tag == 48) { + parse_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &time_))); + set_has_time(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(56)) goto parse_fault_num; + break; + } + + // required int32 fault_num = 7; + case 7: { + if (tag == 56) { + parse_fault_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &fault_num_))); + set_has_fault_num(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(64)) goto parse_fault_type; + break; + } + + // repeated int32 fault_type = 8; + case 8: { + if (tag == 64) { + parse_fault_type: + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + 1, 64, input, this->mutable_fault_type()))); + } else if (tag == 66) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, this->mutable_fault_type()))); + } else { + goto handle_unusual; + } + if (input->ExpectTag(64)) goto parse_fault_type; + if (input->ExpectTag(77)) goto parse_fault_value; + break; + } + + // repeated float fault_value = 9; + case 9: { + if (tag == 77) { + parse_fault_value: + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + 1, 77, input, this->mutable_fault_value()))); + } else if (tag == 74) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, this->mutable_fault_value()))); + } else { + goto handle_unusual; + } + if (input->ExpectTag(77)) goto parse_fault_value; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolSoeEvent) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolSoeEvent) + return false; +#undef DO_ +} + +void FesDebugToolSoeEvent::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolSoeEvent) + // required string table_name = 1; + if (has_table_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->table_name().data(), this->table_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "table_name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->table_name(), output); + } + + // required string col_name = 2; + if (has_col_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->col_name().data(), this->col_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "col_name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->col_name(), output); + } + + // required string tag_name = 3; + if (has_tag_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->tag_name().data(), this->tag_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "tag_name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 3, this->tag_name(), output); + } + + // required uint32 status = 4; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->status(), output); + } + + // required int32 value = 5; + if (has_value()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(5, this->value(), output); + } + + // required uint64 time = 6; + if (has_time()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(6, this->time(), output); + } + + // required int32 fault_num = 7; + if (has_fault_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(7, this->fault_num(), output); + } + + // repeated int32 fault_type = 8; + for (int i = 0; i < this->fault_type_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteInt32( + 8, this->fault_type(i), output); + } + + // repeated float fault_value = 9; + for (int i = 0; i < this->fault_value_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteFloat( + 9, this->fault_value(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolSoeEvent) +} + +::google::protobuf::uint8* FesDebugToolSoeEvent::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolSoeEvent) + // required string table_name = 1; + if (has_table_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->table_name().data(), this->table_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "table_name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->table_name(), target); + } + + // required string col_name = 2; + if (has_col_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->col_name().data(), this->col_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "col_name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->col_name(), target); + } + + // required string tag_name = 3; + if (has_tag_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->tag_name().data(), this->tag_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "tag_name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->tag_name(), target); + } + + // required uint32 status = 4; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->status(), target); + } + + // required int32 value = 5; + if (has_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(5, this->value(), target); + } + + // required uint64 time = 6; + if (has_time()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(6, this->time(), target); + } + + // required int32 fault_num = 7; + if (has_fault_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(7, this->fault_num(), target); + } + + // repeated int32 fault_type = 8; + for (int i = 0; i < this->fault_type_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32ToArray(8, this->fault_type(i), target); + } + + // repeated float fault_value = 9; + for (int i = 0; i < this->fault_value_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteFloatToArray(9, this->fault_value(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolSoeEvent) + return target; +} + +int FesDebugToolSoeEvent::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string table_name = 1; + if (has_table_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->table_name()); + } + + // required string col_name = 2; + if (has_col_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->col_name()); + } + + // required string tag_name = 3; + if (has_tag_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->tag_name()); + } + + // required uint32 status = 4; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->status()); + } + + // required int32 value = 5; + if (has_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->value()); + } + + // required uint64 time = 6; + if (has_time()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->time()); + } + + // required int32 fault_num = 7; + if (has_fault_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->fault_num()); + } + + } + // repeated int32 fault_type = 8; + { + int data_size = 0; + for (int i = 0; i < this->fault_type_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + Int32Size(this->fault_type(i)); + } + total_size += 1 * this->fault_type_size() + data_size; + } + + // repeated float fault_value = 9; + { + int data_size = 0; + data_size = 4 * this->fault_value_size(); + total_size += 1 * this->fault_value_size() + data_size; + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolSoeEvent::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolSoeEvent* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolSoeEvent::MergeFrom(const FesDebugToolSoeEvent& from) { + GOOGLE_CHECK_NE(&from, this); + fault_type_.MergeFrom(from.fault_type_); + fault_value_.MergeFrom(from.fault_value_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_table_name()) { + set_table_name(from.table_name()); + } + if (from.has_col_name()) { + set_col_name(from.col_name()); + } + if (from.has_tag_name()) { + set_tag_name(from.tag_name()); + } + if (from.has_status()) { + set_status(from.status()); + } + if (from.has_value()) { + set_value(from.value()); + } + if (from.has_time()) { + set_time(from.time()); + } + if (from.has_fault_num()) { + set_fault_num(from.fault_num()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolSoeEvent::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolSoeEvent::CopyFrom(const FesDebugToolSoeEvent& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolSoeEvent::IsInitialized() const { + if ((_has_bits_[0] & 0x0000007f) != 0x0000007f) return false; + + return true; +} + +void FesDebugToolSoeEvent::Swap(FesDebugToolSoeEvent* other) { + if (other != this) { + std::swap(table_name_, other->table_name_); + std::swap(col_name_, other->col_name_); + std::swap(tag_name_, other->tag_name_); + std::swap(status_, other->status_); + std::swap(value_, other->value_); + std::swap(time_, other->time_); + std::swap(fault_num_, other->fault_num_); + fault_type_.Swap(&other->fault_type_); + fault_value_.Swap(&other->fault_value_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolSoeEvent::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolSoeEvent_descriptor_; + metadata.reflection = FesDebugToolSoeEvent_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolSoeEventRepMsg::kOverFlowFieldNumber; +const int FesDebugToolSoeEventRepMsg::kEventFieldNumber; +#endif // !_MSC_VER + +FesDebugToolSoeEventRepMsg::FesDebugToolSoeEventRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolSoeEventRepMsg) +} + +void FesDebugToolSoeEventRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolSoeEventRepMsg::FesDebugToolSoeEventRepMsg(const FesDebugToolSoeEventRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolSoeEventRepMsg) +} + +void FesDebugToolSoeEventRepMsg::SharedCtor() { + _cached_size_ = 0; + over_flow_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolSoeEventRepMsg::~FesDebugToolSoeEventRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolSoeEventRepMsg) + SharedDtor(); +} + +void FesDebugToolSoeEventRepMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolSoeEventRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolSoeEventRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolSoeEventRepMsg_descriptor_; +} + +const FesDebugToolSoeEventRepMsg& FesDebugToolSoeEventRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolSoeEventRepMsg* FesDebugToolSoeEventRepMsg::default_instance_ = NULL; + +FesDebugToolSoeEventRepMsg* FesDebugToolSoeEventRepMsg::New() const { + return new FesDebugToolSoeEventRepMsg; +} + +void FesDebugToolSoeEventRepMsg::Clear() { + over_flow_ = 0; + event_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolSoeEventRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolSoeEventRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 over_flow = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &over_flow_))); + set_has_over_flow(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_event; + break; + } + + // repeated .iot_idl.FesDebugToolSoeEvent event = 2; + case 2: { + if (tag == 18) { + parse_event: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_event())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_event; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolSoeEventRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolSoeEventRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolSoeEventRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolSoeEventRepMsg) + // required int32 over_flow = 1; + if (has_over_flow()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->over_flow(), output); + } + + // repeated .iot_idl.FesDebugToolSoeEvent event = 2; + for (int i = 0; i < this->event_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->event(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolSoeEventRepMsg) +} + +::google::protobuf::uint8* FesDebugToolSoeEventRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolSoeEventRepMsg) + // required int32 over_flow = 1; + if (has_over_flow()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->over_flow(), target); + } + + // repeated .iot_idl.FesDebugToolSoeEvent event = 2; + for (int i = 0; i < this->event_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->event(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolSoeEventRepMsg) + return target; +} + +int FesDebugToolSoeEventRepMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 over_flow = 1; + if (has_over_flow()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->over_flow()); + } + + } + // repeated .iot_idl.FesDebugToolSoeEvent event = 2; + total_size += 1 * this->event_size(); + for (int i = 0; i < this->event_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->event(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolSoeEventRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolSoeEventRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolSoeEventRepMsg::MergeFrom(const FesDebugToolSoeEventRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + event_.MergeFrom(from.event_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_over_flow()) { + set_over_flow(from.over_flow()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolSoeEventRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolSoeEventRepMsg::CopyFrom(const FesDebugToolSoeEventRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolSoeEventRepMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->event())) return false; + return true; +} + +void FesDebugToolSoeEventRepMsg::Swap(FesDebugToolSoeEventRepMsg* other) { + if (other != this) { + std::swap(over_flow_, other->over_flow_); + event_.Swap(&other->event_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolSoeEventRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolSoeEventRepMsg_descriptor_; + metadata.reflection = FesDebugToolSoeEventRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolChanEvent::kTagNameFieldNumber; +const int FesDebugToolChanEvent::kStatusFieldNumber; +const int FesDebugToolChanEvent::kErrRateFieldNumber; +const int FesDebugToolChanEvent::kTimeFieldNumber; +#endif // !_MSC_VER + +FesDebugToolChanEvent::FesDebugToolChanEvent() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolChanEvent) +} + +void FesDebugToolChanEvent::InitAsDefaultInstance() { +} + +FesDebugToolChanEvent::FesDebugToolChanEvent(const FesDebugToolChanEvent& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolChanEvent) +} + +void FesDebugToolChanEvent::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + tag_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + status_ = 0u; + err_rate_ = 0; + time_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolChanEvent::~FesDebugToolChanEvent() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolChanEvent) + SharedDtor(); +} + +void FesDebugToolChanEvent::SharedDtor() { + if (tag_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete tag_name_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolChanEvent::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolChanEvent::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolChanEvent_descriptor_; +} + +const FesDebugToolChanEvent& FesDebugToolChanEvent::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolChanEvent* FesDebugToolChanEvent::default_instance_ = NULL; + +FesDebugToolChanEvent* FesDebugToolChanEvent::New() const { + return new FesDebugToolChanEvent; +} + +void FesDebugToolChanEvent::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 15) { + ZR_(status_, time_); + if (has_tag_name()) { + if (tag_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolChanEvent::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolChanEvent) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string tag_name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_tag_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->tag_name().data(), this->tag_name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "tag_name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_status; + break; + } + + // required uint32 status = 2; + case 2: { + if (tag == 16) { + parse_status: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &status_))); + set_has_status(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(29)) goto parse_err_rate; + break; + } + + // required float err_rate = 3; + case 3: { + if (tag == 29) { + parse_err_rate: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &err_rate_))); + set_has_err_rate(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_time; + break; + } + + // required uint64 time = 4; + case 4: { + if (tag == 32) { + parse_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &time_))); + set_has_time(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolChanEvent) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolChanEvent) + return false; +#undef DO_ +} + +void FesDebugToolChanEvent::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolChanEvent) + // required string tag_name = 1; + if (has_tag_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->tag_name().data(), this->tag_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "tag_name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->tag_name(), output); + } + + // required uint32 status = 2; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->status(), output); + } + + // required float err_rate = 3; + if (has_err_rate()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(3, this->err_rate(), output); + } + + // required uint64 time = 4; + if (has_time()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->time(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolChanEvent) +} + +::google::protobuf::uint8* FesDebugToolChanEvent::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolChanEvent) + // required string tag_name = 1; + if (has_tag_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->tag_name().data(), this->tag_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "tag_name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->tag_name(), target); + } + + // required uint32 status = 2; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->status(), target); + } + + // required float err_rate = 3; + if (has_err_rate()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(3, this->err_rate(), target); + } + + // required uint64 time = 4; + if (has_time()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->time(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolChanEvent) + return target; +} + +int FesDebugToolChanEvent::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string tag_name = 1; + if (has_tag_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->tag_name()); + } + + // required uint32 status = 2; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->status()); + } + + // required float err_rate = 3; + if (has_err_rate()) { + total_size += 1 + 4; + } + + // required uint64 time = 4; + if (has_time()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->time()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolChanEvent::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolChanEvent* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolChanEvent::MergeFrom(const FesDebugToolChanEvent& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_tag_name()) { + set_tag_name(from.tag_name()); + } + if (from.has_status()) { + set_status(from.status()); + } + if (from.has_err_rate()) { + set_err_rate(from.err_rate()); + } + if (from.has_time()) { + set_time(from.time()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolChanEvent::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolChanEvent::CopyFrom(const FesDebugToolChanEvent& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolChanEvent::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + return true; +} + +void FesDebugToolChanEvent::Swap(FesDebugToolChanEvent* other) { + if (other != this) { + std::swap(tag_name_, other->tag_name_); + std::swap(status_, other->status_); + std::swap(err_rate_, other->err_rate_); + std::swap(time_, other->time_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolChanEvent::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolChanEvent_descriptor_; + metadata.reflection = FesDebugToolChanEvent_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolChanEventRepMsg::kOverFlowFieldNumber; +const int FesDebugToolChanEventRepMsg::kEventFieldNumber; +#endif // !_MSC_VER + +FesDebugToolChanEventRepMsg::FesDebugToolChanEventRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolChanEventRepMsg) +} + +void FesDebugToolChanEventRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolChanEventRepMsg::FesDebugToolChanEventRepMsg(const FesDebugToolChanEventRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolChanEventRepMsg) +} + +void FesDebugToolChanEventRepMsg::SharedCtor() { + _cached_size_ = 0; + over_flow_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolChanEventRepMsg::~FesDebugToolChanEventRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolChanEventRepMsg) + SharedDtor(); +} + +void FesDebugToolChanEventRepMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolChanEventRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolChanEventRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolChanEventRepMsg_descriptor_; +} + +const FesDebugToolChanEventRepMsg& FesDebugToolChanEventRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolChanEventRepMsg* FesDebugToolChanEventRepMsg::default_instance_ = NULL; + +FesDebugToolChanEventRepMsg* FesDebugToolChanEventRepMsg::New() const { + return new FesDebugToolChanEventRepMsg; +} + +void FesDebugToolChanEventRepMsg::Clear() { + over_flow_ = 0; + event_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolChanEventRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolChanEventRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 over_flow = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &over_flow_))); + set_has_over_flow(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_event; + break; + } + + // repeated .iot_idl.FesDebugToolChanEvent event = 2; + case 2: { + if (tag == 18) { + parse_event: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_event())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_event; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolChanEventRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolChanEventRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolChanEventRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolChanEventRepMsg) + // required int32 over_flow = 1; + if (has_over_flow()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->over_flow(), output); + } + + // repeated .iot_idl.FesDebugToolChanEvent event = 2; + for (int i = 0; i < this->event_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->event(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolChanEventRepMsg) +} + +::google::protobuf::uint8* FesDebugToolChanEventRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolChanEventRepMsg) + // required int32 over_flow = 1; + if (has_over_flow()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->over_flow(), target); + } + + // repeated .iot_idl.FesDebugToolChanEvent event = 2; + for (int i = 0; i < this->event_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->event(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolChanEventRepMsg) + return target; +} + +int FesDebugToolChanEventRepMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 over_flow = 1; + if (has_over_flow()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->over_flow()); + } + + } + // repeated .iot_idl.FesDebugToolChanEvent event = 2; + total_size += 1 * this->event_size(); + for (int i = 0; i < this->event_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->event(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolChanEventRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolChanEventRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolChanEventRepMsg::MergeFrom(const FesDebugToolChanEventRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + event_.MergeFrom(from.event_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_over_flow()) { + set_over_flow(from.over_flow()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolChanEventRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolChanEventRepMsg::CopyFrom(const FesDebugToolChanEventRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolChanEventRepMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->event())) return false; + return true; +} + +void FesDebugToolChanEventRepMsg::Swap(FesDebugToolChanEventRepMsg* other) { + if (other != this) { + std::swap(over_flow_, other->over_flow_); + event_.Swap(&other->event_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolChanEventRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolChanEventRepMsg_descriptor_; + metadata.reflection = FesDebugToolChanEventRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolChanMonCmdReqMsg::kChanNoFieldNumber; +#endif // !_MSC_VER + +FesDebugToolChanMonCmdReqMsg::FesDebugToolChanMonCmdReqMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolChanMonCmdReqMsg) +} + +void FesDebugToolChanMonCmdReqMsg::InitAsDefaultInstance() { +} + +FesDebugToolChanMonCmdReqMsg::FesDebugToolChanMonCmdReqMsg(const FesDebugToolChanMonCmdReqMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolChanMonCmdReqMsg) +} + +void FesDebugToolChanMonCmdReqMsg::SharedCtor() { + _cached_size_ = 0; + chan_no_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolChanMonCmdReqMsg::~FesDebugToolChanMonCmdReqMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolChanMonCmdReqMsg) + SharedDtor(); +} + +void FesDebugToolChanMonCmdReqMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolChanMonCmdReqMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolChanMonCmdReqMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolChanMonCmdReqMsg_descriptor_; +} + +const FesDebugToolChanMonCmdReqMsg& FesDebugToolChanMonCmdReqMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolChanMonCmdReqMsg* FesDebugToolChanMonCmdReqMsg::default_instance_ = NULL; + +FesDebugToolChanMonCmdReqMsg* FesDebugToolChanMonCmdReqMsg::New() const { + return new FesDebugToolChanMonCmdReqMsg; +} + +void FesDebugToolChanMonCmdReqMsg::Clear() { + chan_no_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolChanMonCmdReqMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolChanMonCmdReqMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 chan_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &chan_no_))); + set_has_chan_no(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolChanMonCmdReqMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolChanMonCmdReqMsg) + return false; +#undef DO_ +} + +void FesDebugToolChanMonCmdReqMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolChanMonCmdReqMsg) + // required int32 chan_no = 1; + if (has_chan_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->chan_no(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolChanMonCmdReqMsg) +} + +::google::protobuf::uint8* FesDebugToolChanMonCmdReqMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolChanMonCmdReqMsg) + // required int32 chan_no = 1; + if (has_chan_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->chan_no(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolChanMonCmdReqMsg) + return target; +} + +int FesDebugToolChanMonCmdReqMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 chan_no = 1; + if (has_chan_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->chan_no()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolChanMonCmdReqMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolChanMonCmdReqMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolChanMonCmdReqMsg::MergeFrom(const FesDebugToolChanMonCmdReqMsg& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_chan_no()) { + set_chan_no(from.chan_no()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolChanMonCmdReqMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolChanMonCmdReqMsg::CopyFrom(const FesDebugToolChanMonCmdReqMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolChanMonCmdReqMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void FesDebugToolChanMonCmdReqMsg::Swap(FesDebugToolChanMonCmdReqMsg* other) { + if (other != this) { + std::swap(chan_no_, other->chan_no_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolChanMonCmdReqMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolChanMonCmdReqMsg_descriptor_; + metadata.reflection = FesDebugToolChanMonCmdReqMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolChanMonCmdRepMsg::kChanNoFieldNumber; +const int FesDebugToolChanMonCmdRepMsg::kRxNumFieldNumber; +const int FesDebugToolChanMonCmdRepMsg::kTxNumFieldNumber; +const int FesDebugToolChanMonCmdRepMsg::kErrNumFieldNumber; +#endif // !_MSC_VER + +FesDebugToolChanMonCmdRepMsg::FesDebugToolChanMonCmdRepMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolChanMonCmdRepMsg) +} + +void FesDebugToolChanMonCmdRepMsg::InitAsDefaultInstance() { +} + +FesDebugToolChanMonCmdRepMsg::FesDebugToolChanMonCmdRepMsg(const FesDebugToolChanMonCmdRepMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolChanMonCmdRepMsg) +} + +void FesDebugToolChanMonCmdRepMsg::SharedCtor() { + _cached_size_ = 0; + chan_no_ = 0; + rx_num_ = 0; + tx_num_ = 0; + err_num_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolChanMonCmdRepMsg::~FesDebugToolChanMonCmdRepMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolChanMonCmdRepMsg) + SharedDtor(); +} + +void FesDebugToolChanMonCmdRepMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolChanMonCmdRepMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolChanMonCmdRepMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolChanMonCmdRepMsg_descriptor_; +} + +const FesDebugToolChanMonCmdRepMsg& FesDebugToolChanMonCmdRepMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolChanMonCmdRepMsg* FesDebugToolChanMonCmdRepMsg::default_instance_ = NULL; + +FesDebugToolChanMonCmdRepMsg* FesDebugToolChanMonCmdRepMsg::New() const { + return new FesDebugToolChanMonCmdRepMsg; +} + +void FesDebugToolChanMonCmdRepMsg::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(chan_no_, err_num_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolChanMonCmdRepMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolChanMonCmdRepMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 chan_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &chan_no_))); + set_has_chan_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_rx_num; + break; + } + + // optional int32 rx_num = 2; + case 2: { + if (tag == 16) { + parse_rx_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rx_num_))); + set_has_rx_num(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_tx_num; + break; + } + + // optional int32 tx_num = 3; + case 3: { + if (tag == 24) { + parse_tx_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &tx_num_))); + set_has_tx_num(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_err_num; + break; + } + + // optional int32 err_num = 4; + case 4: { + if (tag == 32) { + parse_err_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &err_num_))); + set_has_err_num(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolChanMonCmdRepMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolChanMonCmdRepMsg) + return false; +#undef DO_ +} + +void FesDebugToolChanMonCmdRepMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolChanMonCmdRepMsg) + // required int32 chan_no = 1; + if (has_chan_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->chan_no(), output); + } + + // optional int32 rx_num = 2; + if (has_rx_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->rx_num(), output); + } + + // optional int32 tx_num = 3; + if (has_tx_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->tx_num(), output); + } + + // optional int32 err_num = 4; + if (has_err_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->err_num(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolChanMonCmdRepMsg) +} + +::google::protobuf::uint8* FesDebugToolChanMonCmdRepMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolChanMonCmdRepMsg) + // required int32 chan_no = 1; + if (has_chan_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->chan_no(), target); + } + + // optional int32 rx_num = 2; + if (has_rx_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->rx_num(), target); + } + + // optional int32 tx_num = 3; + if (has_tx_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->tx_num(), target); + } + + // optional int32 err_num = 4; + if (has_err_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->err_num(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolChanMonCmdRepMsg) + return target; +} + +int FesDebugToolChanMonCmdRepMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 chan_no = 1; + if (has_chan_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->chan_no()); + } + + // optional int32 rx_num = 2; + if (has_rx_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rx_num()); + } + + // optional int32 tx_num = 3; + if (has_tx_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->tx_num()); + } + + // optional int32 err_num = 4; + if (has_err_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->err_num()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolChanMonCmdRepMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolChanMonCmdRepMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolChanMonCmdRepMsg::MergeFrom(const FesDebugToolChanMonCmdRepMsg& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_chan_no()) { + set_chan_no(from.chan_no()); + } + if (from.has_rx_num()) { + set_rx_num(from.rx_num()); + } + if (from.has_tx_num()) { + set_tx_num(from.tx_num()); + } + if (from.has_err_num()) { + set_err_num(from.err_num()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolChanMonCmdRepMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolChanMonCmdRepMsg::CopyFrom(const FesDebugToolChanMonCmdRepMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolChanMonCmdRepMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void FesDebugToolChanMonCmdRepMsg::Swap(FesDebugToolChanMonCmdRepMsg* other) { + if (other != this) { + std::swap(chan_no_, other->chan_no_); + std::swap(rx_num_, other->rx_num_); + std::swap(tx_num_, other->tx_num_); + std::swap(err_num_, other->err_num_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolChanMonCmdRepMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolChanMonCmdRepMsg_descriptor_; + metadata.reflection = FesDebugToolChanMonCmdRepMsg_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolChanMonFrame::kFrameTypeFieldNumber; +const int FesDebugToolChanMonFrame::kDataTypeFieldNumber; +const int FesDebugToolChanMonFrame::kTimeFieldNumber; +const int FesDebugToolChanMonFrame::kDataFieldNumber; +#endif // !_MSC_VER + +FesDebugToolChanMonFrame::FesDebugToolChanMonFrame() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolChanMonFrame) +} + +void FesDebugToolChanMonFrame::InitAsDefaultInstance() { +} + +FesDebugToolChanMonFrame::FesDebugToolChanMonFrame(const FesDebugToolChanMonFrame& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolChanMonFrame) +} + +void FesDebugToolChanMonFrame::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + frame_type_ = 0; + data_type_ = 0; + time_ = GOOGLE_ULONGLONG(0); + data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolChanMonFrame::~FesDebugToolChanMonFrame() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolChanMonFrame) + SharedDtor(); +} + +void FesDebugToolChanMonFrame::SharedDtor() { + if (data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete data_; + } + if (this != default_instance_) { + } +} + +void FesDebugToolChanMonFrame::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolChanMonFrame::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolChanMonFrame_descriptor_; +} + +const FesDebugToolChanMonFrame& FesDebugToolChanMonFrame::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolChanMonFrame* FesDebugToolChanMonFrame::default_instance_ = NULL; + +FesDebugToolChanMonFrame* FesDebugToolChanMonFrame::New() const { + return new FesDebugToolChanMonFrame; +} + +void FesDebugToolChanMonFrame::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 15) { + ZR_(frame_type_, time_); + if (has_data()) { + if (data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + data_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolChanMonFrame::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolChanMonFrame) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 frame_type = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &frame_type_))); + set_has_frame_type(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_data_type; + break; + } + + // required int32 data_type = 2; + case 2: { + if (tag == 16) { + parse_data_type: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &data_type_))); + set_has_data_type(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_time; + break; + } + + // required uint64 time = 3; + case 3: { + if (tag == 24) { + parse_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &time_))); + set_has_time(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_data; + break; + } + + // required bytes data = 4; + case 4: { + if (tag == 34) { + parse_data: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_data())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolChanMonFrame) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolChanMonFrame) + return false; +#undef DO_ +} + +void FesDebugToolChanMonFrame::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolChanMonFrame) + // required int32 frame_type = 1; + if (has_frame_type()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->frame_type(), output); + } + + // required int32 data_type = 2; + if (has_data_type()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->data_type(), output); + } + + // required uint64 time = 3; + if (has_time()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->time(), output); + } + + // required bytes data = 4; + if (has_data()) { + ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( + 4, this->data(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolChanMonFrame) +} + +::google::protobuf::uint8* FesDebugToolChanMonFrame::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolChanMonFrame) + // required int32 frame_type = 1; + if (has_frame_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->frame_type(), target); + } + + // required int32 data_type = 2; + if (has_data_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->data_type(), target); + } + + // required uint64 time = 3; + if (has_time()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->time(), target); + } + + // required bytes data = 4; + if (has_data()) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 4, this->data(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolChanMonFrame) + return target; +} + +int FesDebugToolChanMonFrame::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 frame_type = 1; + if (has_frame_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->frame_type()); + } + + // required int32 data_type = 2; + if (has_data_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->data_type()); + } + + // required uint64 time = 3; + if (has_time()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->time()); + } + + // required bytes data = 4; + if (has_data()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->data()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolChanMonFrame::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolChanMonFrame* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolChanMonFrame::MergeFrom(const FesDebugToolChanMonFrame& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_frame_type()) { + set_frame_type(from.frame_type()); + } + if (from.has_data_type()) { + set_data_type(from.data_type()); + } + if (from.has_time()) { + set_time(from.time()); + } + if (from.has_data()) { + set_data(from.data()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolChanMonFrame::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolChanMonFrame::CopyFrom(const FesDebugToolChanMonFrame& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolChanMonFrame::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + return true; +} + +void FesDebugToolChanMonFrame::Swap(FesDebugToolChanMonFrame* other) { + if (other != this) { + std::swap(frame_type_, other->frame_type_); + std::swap(data_type_, other->data_type_); + std::swap(time_, other->time_); + std::swap(data_, other->data_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolChanMonFrame::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolChanMonFrame_descriptor_; + metadata.reflection = FesDebugToolChanMonFrame_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FesDebugToolChanMonInfoMsg::kChanNoFieldNumber; +const int FesDebugToolChanMonInfoMsg::kRxNumFieldNumber; +const int FesDebugToolChanMonInfoMsg::kTxNumFieldNumber; +const int FesDebugToolChanMonInfoMsg::kErrNumFieldNumber; +const int FesDebugToolChanMonInfoMsg::kOverFlowFieldNumber; +const int FesDebugToolChanMonInfoMsg::kFrameFieldNumber; +#endif // !_MSC_VER + +FesDebugToolChanMonInfoMsg::FesDebugToolChanMonInfoMsg() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:iot_idl.FesDebugToolChanMonInfoMsg) +} + +void FesDebugToolChanMonInfoMsg::InitAsDefaultInstance() { +} + +FesDebugToolChanMonInfoMsg::FesDebugToolChanMonInfoMsg(const FesDebugToolChanMonInfoMsg& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:iot_idl.FesDebugToolChanMonInfoMsg) +} + +void FesDebugToolChanMonInfoMsg::SharedCtor() { + _cached_size_ = 0; + chan_no_ = 0; + rx_num_ = 0; + tx_num_ = 0; + err_num_ = 0; + over_flow_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FesDebugToolChanMonInfoMsg::~FesDebugToolChanMonInfoMsg() { + // @@protoc_insertion_point(destructor:iot_idl.FesDebugToolChanMonInfoMsg) + SharedDtor(); +} + +void FesDebugToolChanMonInfoMsg::SharedDtor() { + if (this != default_instance_) { + } +} + +void FesDebugToolChanMonInfoMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FesDebugToolChanMonInfoMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FesDebugToolChanMonInfoMsg_descriptor_; +} + +const FesDebugToolChanMonInfoMsg& FesDebugToolChanMonInfoMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_FesDebugTool_2eproto(); + return *default_instance_; +} + +FesDebugToolChanMonInfoMsg* FesDebugToolChanMonInfoMsg::default_instance_ = NULL; + +FesDebugToolChanMonInfoMsg* FesDebugToolChanMonInfoMsg::New() const { + return new FesDebugToolChanMonInfoMsg; +} + +void FesDebugToolChanMonInfoMsg::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 31) { + ZR_(chan_no_, err_num_); + over_flow_ = 0; + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + frame_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FesDebugToolChanMonInfoMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:iot_idl.FesDebugToolChanMonInfoMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 chan_no = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &chan_no_))); + set_has_chan_no(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_rx_num; + break; + } + + // required int32 rx_num = 2; + case 2: { + if (tag == 16) { + parse_rx_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &rx_num_))); + set_has_rx_num(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_tx_num; + break; + } + + // required int32 tx_num = 3; + case 3: { + if (tag == 24) { + parse_tx_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &tx_num_))); + set_has_tx_num(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_err_num; + break; + } + + // required int32 err_num = 4; + case 4: { + if (tag == 32) { + parse_err_num: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &err_num_))); + set_has_err_num(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_over_flow; + break; + } + + // required int32 over_flow = 5; + case 5: { + if (tag == 40) { + parse_over_flow: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &over_flow_))); + set_has_over_flow(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(50)) goto parse_frame; + break; + } + + // repeated .iot_idl.FesDebugToolChanMonFrame frame = 6; + case 6: { + if (tag == 50) { + parse_frame: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_frame())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(50)) goto parse_frame; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:iot_idl.FesDebugToolChanMonInfoMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:iot_idl.FesDebugToolChanMonInfoMsg) + return false; +#undef DO_ +} + +void FesDebugToolChanMonInfoMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:iot_idl.FesDebugToolChanMonInfoMsg) + // required int32 chan_no = 1; + if (has_chan_no()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->chan_no(), output); + } + + // required int32 rx_num = 2; + if (has_rx_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->rx_num(), output); + } + + // required int32 tx_num = 3; + if (has_tx_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->tx_num(), output); + } + + // required int32 err_num = 4; + if (has_err_num()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->err_num(), output); + } + + // required int32 over_flow = 5; + if (has_over_flow()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(5, this->over_flow(), output); + } + + // repeated .iot_idl.FesDebugToolChanMonFrame frame = 6; + for (int i = 0; i < this->frame_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 6, this->frame(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:iot_idl.FesDebugToolChanMonInfoMsg) +} + +::google::protobuf::uint8* FesDebugToolChanMonInfoMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:iot_idl.FesDebugToolChanMonInfoMsg) + // required int32 chan_no = 1; + if (has_chan_no()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->chan_no(), target); + } + + // required int32 rx_num = 2; + if (has_rx_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->rx_num(), target); + } + + // required int32 tx_num = 3; + if (has_tx_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->tx_num(), target); + } + + // required int32 err_num = 4; + if (has_err_num()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->err_num(), target); + } + + // required int32 over_flow = 5; + if (has_over_flow()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(5, this->over_flow(), target); + } + + // repeated .iot_idl.FesDebugToolChanMonFrame frame = 6; + for (int i = 0; i < this->frame_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 6, this->frame(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:iot_idl.FesDebugToolChanMonInfoMsg) + return target; +} + +int FesDebugToolChanMonInfoMsg::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required int32 chan_no = 1; + if (has_chan_no()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->chan_no()); + } + + // required int32 rx_num = 2; + if (has_rx_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->rx_num()); + } + + // required int32 tx_num = 3; + if (has_tx_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->tx_num()); + } + + // required int32 err_num = 4; + if (has_err_num()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->err_num()); + } + + // required int32 over_flow = 5; + if (has_over_flow()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->over_flow()); + } + + } + // repeated .iot_idl.FesDebugToolChanMonFrame frame = 6; + total_size += 1 * this->frame_size(); + for (int i = 0; i < this->frame_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->frame(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FesDebugToolChanMonInfoMsg::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FesDebugToolChanMonInfoMsg* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FesDebugToolChanMonInfoMsg::MergeFrom(const FesDebugToolChanMonInfoMsg& from) { + GOOGLE_CHECK_NE(&from, this); + frame_.MergeFrom(from.frame_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_chan_no()) { + set_chan_no(from.chan_no()); + } + if (from.has_rx_num()) { + set_rx_num(from.rx_num()); + } + if (from.has_tx_num()) { + set_tx_num(from.tx_num()); + } + if (from.has_err_num()) { + set_err_num(from.err_num()); + } + if (from.has_over_flow()) { + set_over_flow(from.over_flow()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FesDebugToolChanMonInfoMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FesDebugToolChanMonInfoMsg::CopyFrom(const FesDebugToolChanMonInfoMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FesDebugToolChanMonInfoMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->frame())) return false; + return true; +} + +void FesDebugToolChanMonInfoMsg::Swap(FesDebugToolChanMonInfoMsg* other) { + if (other != this) { + std::swap(chan_no_, other->chan_no_); + std::swap(rx_num_, other->rx_num_); + std::swap(tx_num_, other->tx_num_); + std::swap(err_num_, other->err_num_); + std::swap(over_flow_, other->over_flow_); + frame_.Swap(&other->frame_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FesDebugToolChanMonInfoMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FesDebugToolChanMonInfoMsg_descriptor_; + metadata.reflection = FesDebugToolChanMonInfoMsg_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace iot_idl + +// @@protoc_insertion_point(global_scope) diff --git a/product/src/fes/fes_idl_files/FesDebugTool.pb.h b/product/src/fes/fes_idl_files/FesDebugTool.pb.h new file mode 100644 index 00000000..a84b5277 --- /dev/null +++ b/product/src/fes/fes_idl_files/FesDebugTool.pb.h @@ -0,0 +1,9809 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: FesDebugTool.proto + +#ifndef PROTOBUF_FesDebugTool_2eproto__INCLUDED +#define PROTOBUF_FesDebugTool_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2006000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace iot_idl { + +// Internal implementation detail -- do not call these. +void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); +void protobuf_AssignDesc_FesDebugTool_2eproto(); +void protobuf_ShutdownFile_FesDebugTool_2eproto(); + +class FesDebugToolReqMsg; +class FesDebugToolRepMsg; +class FesDebugToolNetRoute; +class FesDebugToolChanParam; +class FesDebugToolChanParamRepMsg; +class FesDebugToolRtuParam; +class FesDebugToolRtuParamRepMsg; +class FesDebugToolRtuInfo; +class FesDebugToolRtuInfoRepMsg; +class FesDebugToolPntParamReqMsg; +class FesDebugToolPntParam; +class FesDebugToolPntParamRepMsg; +class FesDebugToolPntValueReqMsg; +class FesDebugToolIntPntValue; +class FesDebugToolFloatPntValue; +class FesDebugToolDoublePntValue; +class FesDebugToolPntValueRepMsg; +class FesDebugToolValueVariant; +class FesDebugToolValueSetSimParam; +class FesDebugToolLineSetSimParam; +class FesDebugToolRandSetSimParam; +class FesDebugToolValueSimSetReqMsg; +class FesDebugToolValueSimSetRepMsg; +class FesDebugToolSimEventRtuSoe; +class FesDebugToolSimEventCreateReqMsg; +class FesDebugToolSimEventCreateRepMsg; +class FesDebugToolSimControlReqMsg; +class FesDebugToolSimControlRepMsg; +class FesDebugToolSimDefCmdReqMsg; +class FesDebugToolFwPntParam; +class FesDebugToolFwPntParamRepMsg; +class FesDebugToolSoeEvent; +class FesDebugToolSoeEventRepMsg; +class FesDebugToolChanEvent; +class FesDebugToolChanEventRepMsg; +class FesDebugToolChanMonCmdReqMsg; +class FesDebugToolChanMonCmdRepMsg; +class FesDebugToolChanMonFrame; +class FesDebugToolChanMonInfoMsg; + +enum enFesDebugMsgType { + MT_FESDBG_HeartBeat = 0, + MT_FESDBG_CONNECT = 1, + MT_FESDBG_DISCONNECT = 2, + MT_FESDBG_ChanParam = 5, + MT_FESDBG_RtuParam = 6, + MT_FESDBG_AI_RtuInfo = 10, + MT_FESDBG_AI_Param = 11, + MT_FESDBG_AI_Value = 12, + MT_FESDBG_DI_RtuInfo = 20, + MT_FESDBG_DI_Param = 21, + MT_FESDBG_DI_Value = 22, + MT_FESDBG_ACC_RtuInfo = 30, + MT_FESDBG_ACC_Param = 31, + MT_FESDBG_ACC_Value = 32, + MT_FESDBG_MI_RtuInfo = 40, + MT_FESDBG_MI_Param = 41, + MT_FESDBG_MI_Value = 42, + MT_FESDBG_SimAI_RtuInfo = 50, + MT_FESDBG_SimAI_Param = 51, + MT_FESDBG_SimAI_Value = 52, + MT_FESDBG_SimAI_StartSim = 53, + MT_FESDBG_SimAI_StopSim = 54, + MT_FESDBG_SimDI_RtuInfo = 60, + MT_FESDBG_SimDI_Param = 61, + MT_FESDBG_SimDI_Value = 62, + MT_FESDBG_SimDI_StartSim = 63, + MT_FESDBG_SimDI_StopSim = 64, + MT_FESDBG_SimMI_RtuInfo = 70, + MT_FESDBG_SimMI_Param = 71, + MT_FESDBG_SimMI_Value = 72, + MT_FESDBG_SimMI_StartSim = 73, + MT_FESDBG_SimMI_StopSim = 74, + MT_FESDBG_SimACC_RtuInfo = 80, + MT_FESDBG_SimACC_Param = 81, + MT_FESDBG_SimACC_Value = 82, + MT_FESDBG_SimACC_StartSim = 83, + MT_FESDBG_SimACC_StopSim = 84, + MT_FESDBG_SimEvent_RtuInfo = 90, + MT_FESDBG_SimEvent_DiParam = 91, + MT_FESDBG_SimEvent_Create = 92, + MT_FESDBG_SimAO_RtuInfo = 100, + MT_FESDBG_SimAO_Param = 101, + MT_FESDBG_SimAO_Control = 102, + MT_FESDBG_SimDO_RtuInfo = 110, + MT_FESDBG_SimDO_Param = 111, + MT_FESDBG_SimDO_Control = 112, + MT_FESDBG_SimMO_RtuInfo = 120, + MT_FESDBG_SimMO_Param = 121, + MT_FESDBG_SimMO_Control = 122, + MT_FESDBG_SimDefCmd_RtuInfo = 130, + MT_FESDBG_SimDefCmd_Control = 131, + MT_FESDBG_FWAI_RtuInfo = 140, + MT_FESDBG_FWAI_Param = 141, + MT_FESDBG_FWAI_Value = 142, + MT_FESDBG_FWDI_RtuInfo = 150, + MT_FESDBG_FWDI_Param = 151, + MT_FESDBG_FWDI_Value = 152, + MT_FESDBG_FWDDI_RtuInfo = 160, + MT_FESDBG_FWDDI_Param = 161, + MT_FESDBG_FWDDI_Value = 162, + MT_FESDBG_FWMI_RtuInfo = 170, + MT_FESDBG_FWMI_Param = 171, + MT_FESDBG_FWMI_Value = 172, + MT_FESDBG_FWACC_RtuInfo = 180, + MT_FESDBG_FWACC_Param = 181, + MT_FESDBG_FWACC_Value = 182, + MT_FESDBG_Event_SOE = 190, + MT_FESDBG_Event_Channel = 191, + MT_FESDBG_Event_SOEMemory = 192, + MT_FESDBG_Mon_ChanStart = 200, + MT_FESDBG_Mon_ChanStop = 201, + MT_FESDBG_Mon_ChanClear = 202, + MT_FESDBG_Mon_ChanInfo = 203 +}; +IDL_FILES_EXPORT bool enFesDebugMsgType_IsValid(int value); +const enFesDebugMsgType enFesDebugMsgType_MIN = MT_FESDBG_HeartBeat; +const enFesDebugMsgType enFesDebugMsgType_MAX = MT_FESDBG_Mon_ChanInfo; +const int enFesDebugMsgType_ARRAYSIZE = enFesDebugMsgType_MAX + 1; + +IDL_FILES_EXPORT const ::google::protobuf::EnumDescriptor* enFesDebugMsgType_descriptor(); +inline const ::std::string& enFesDebugMsgType_Name(enFesDebugMsgType value) { + return ::google::protobuf::internal::NameOfEnum( + enFesDebugMsgType_descriptor(), value); +} +inline bool enFesDebugMsgType_Parse( + const ::std::string& name, enFesDebugMsgType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + enFesDebugMsgType_descriptor(), name, value); +} +enum enFesDebugSimMode { + MT_FESDBG_SM_ValueSet = 1, + MT_FESDBG_SM_LineSet = 2, + MT_FESDBG_SM_RandSet = 3 +}; +IDL_FILES_EXPORT bool enFesDebugSimMode_IsValid(int value); +const enFesDebugSimMode enFesDebugSimMode_MIN = MT_FESDBG_SM_ValueSet; +const enFesDebugSimMode enFesDebugSimMode_MAX = MT_FESDBG_SM_RandSet; +const int enFesDebugSimMode_ARRAYSIZE = enFesDebugSimMode_MAX + 1; + +IDL_FILES_EXPORT const ::google::protobuf::EnumDescriptor* enFesDebugSimMode_descriptor(); +inline const ::std::string& enFesDebugSimMode_Name(enFesDebugSimMode value) { + return ::google::protobuf::internal::NameOfEnum( + enFesDebugSimMode_descriptor(), value); +} +inline bool enFesDebugSimMode_Parse( + const ::std::string& name, enFesDebugSimMode* value) { + return ::google::protobuf::internal::ParseNamedEnum( + enFesDebugSimMode_descriptor(), name, value); +} +enum enFesDebugSimRangeType { + MT_FESDBG_RT_SinglePoint = 1, + MT_FESDBG_RT_RtuPoint = 2, + MT_FESDBG_RT_AllPoint = 3 +}; +IDL_FILES_EXPORT bool enFesDebugSimRangeType_IsValid(int value); +const enFesDebugSimRangeType enFesDebugSimRangeType_MIN = MT_FESDBG_RT_SinglePoint; +const enFesDebugSimRangeType enFesDebugSimRangeType_MAX = MT_FESDBG_RT_AllPoint; +const int enFesDebugSimRangeType_ARRAYSIZE = enFesDebugSimRangeType_MAX + 1; + +IDL_FILES_EXPORT const ::google::protobuf::EnumDescriptor* enFesDebugSimRangeType_descriptor(); +inline const ::std::string& enFesDebugSimRangeType_Name(enFesDebugSimRangeType value) { + return ::google::protobuf::internal::NameOfEnum( + enFesDebugSimRangeType_descriptor(), value); +} +inline bool enFesDebugSimRangeType_Parse( + const ::std::string& name, enFesDebugSimRangeType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + enFesDebugSimRangeType_descriptor(), name, value); +} +enum enFesDebugEventSimType { + MT_FESDBG_EST_RtuSoe = 1, + MT_FESDBG_EST_FepSoe = 2 +}; +IDL_FILES_EXPORT bool enFesDebugEventSimType_IsValid(int value); +const enFesDebugEventSimType enFesDebugEventSimType_MIN = MT_FESDBG_EST_RtuSoe; +const enFesDebugEventSimType enFesDebugEventSimType_MAX = MT_FESDBG_EST_FepSoe; +const int enFesDebugEventSimType_ARRAYSIZE = enFesDebugEventSimType_MAX + 1; + +IDL_FILES_EXPORT const ::google::protobuf::EnumDescriptor* enFesDebugEventSimType_descriptor(); +inline const ::std::string& enFesDebugEventSimType_Name(enFesDebugEventSimType value) { + return ::google::protobuf::internal::NameOfEnum( + enFesDebugEventSimType_descriptor(), value); +} +inline bool enFesDebugEventSimType_Parse( + const ::std::string& name, enFesDebugEventSimType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + enFesDebugEventSimType_descriptor(), name, value); +} +// =================================================================== + +class IDL_FILES_EXPORT FesDebugToolReqMsg : public ::google::protobuf::Message { + public: + FesDebugToolReqMsg(); + virtual ~FesDebugToolReqMsg(); + + FesDebugToolReqMsg(const FesDebugToolReqMsg& from); + + inline FesDebugToolReqMsg& operator=(const FesDebugToolReqMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolReqMsg& default_instance(); + + void Swap(FesDebugToolReqMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolReqMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolReqMsg& from); + void MergeFrom(const FesDebugToolReqMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .iot_idl.enFesDebugMsgType type = 1; + inline bool has_type() const; + inline void clear_type(); + static const int kTypeFieldNumber = 1; + inline ::iot_idl::enFesDebugMsgType type() const; + inline void set_type(::iot_idl::enFesDebugMsgType value); + + // optional string body = 2; + inline bool has_body() const; + inline void clear_body(); + static const int kBodyFieldNumber = 2; + inline const ::std::string& body() const; + inline void set_body(const ::std::string& value); + inline void set_body(const char* value); + inline void set_body(const char* value, size_t size); + inline ::std::string* mutable_body(); + inline ::std::string* release_body(); + inline void set_allocated_body(::std::string* body); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolReqMsg) + private: + inline void set_has_type(); + inline void clear_has_type(); + inline void set_has_body(); + inline void clear_has_body(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* body_; + int type_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolReqMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolRepMsg(); + virtual ~FesDebugToolRepMsg(); + + FesDebugToolRepMsg(const FesDebugToolRepMsg& from); + + inline FesDebugToolRepMsg& operator=(const FesDebugToolRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolRepMsg& default_instance(); + + void Swap(FesDebugToolRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolRepMsg& from); + void MergeFrom(const FesDebugToolRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required bool success = 1; + inline bool has_success() const; + inline void clear_success(); + static const int kSuccessFieldNumber = 1; + inline bool success() const; + inline void set_success(bool value); + + // optional string err_msg = 2; + inline bool has_err_msg() const; + inline void clear_err_msg(); + static const int kErrMsgFieldNumber = 2; + inline const ::std::string& err_msg() const; + inline void set_err_msg(const ::std::string& value); + inline void set_err_msg(const char* value); + inline void set_err_msg(const char* value, size_t size); + inline ::std::string* mutable_err_msg(); + inline ::std::string* release_err_msg(); + inline void set_allocated_err_msg(::std::string* err_msg); + + // required .iot_idl.enFesDebugMsgType type = 3; + inline bool has_type() const; + inline void clear_type(); + static const int kTypeFieldNumber = 3; + inline ::iot_idl::enFesDebugMsgType type() const; + inline void set_type(::iot_idl::enFesDebugMsgType value); + + // optional string body = 4; + inline bool has_body() const; + inline void clear_body(); + static const int kBodyFieldNumber = 4; + inline const ::std::string& body() const; + inline void set_body(const ::std::string& value); + inline void set_body(const char* value); + inline void set_body(const char* value, size_t size); + inline ::std::string* mutable_body(); + inline ::std::string* release_body(); + inline void set_allocated_body(::std::string* body); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolRepMsg) + private: + inline void set_has_success(); + inline void clear_has_success(); + inline void set_has_err_msg(); + inline void clear_has_err_msg(); + inline void set_has_type(); + inline void clear_has_type(); + inline void set_has_body(); + inline void clear_has_body(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* err_msg_; + bool success_; + int type_; + ::std::string* body_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolNetRoute : public ::google::protobuf::Message { + public: + FesDebugToolNetRoute(); + virtual ~FesDebugToolNetRoute(); + + FesDebugToolNetRoute(const FesDebugToolNetRoute& from); + + inline FesDebugToolNetRoute& operator=(const FesDebugToolNetRoute& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolNetRoute& default_instance(); + + void Swap(FesDebugToolNetRoute* other); + + // implements Message ---------------------------------------------- + + FesDebugToolNetRoute* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolNetRoute& from); + void MergeFrom(const FesDebugToolNetRoute& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string desc = 1; + inline bool has_desc() const; + inline void clear_desc(); + static const int kDescFieldNumber = 1; + inline const ::std::string& desc() const; + inline void set_desc(const ::std::string& value); + inline void set_desc(const char* value); + inline void set_desc(const char* value, size_t size); + inline ::std::string* mutable_desc(); + inline ::std::string* release_desc(); + inline void set_allocated_desc(::std::string* desc); + + // required int32 port_no = 2; + inline bool has_port_no() const; + inline void clear_port_no(); + static const int kPortNoFieldNumber = 2; + inline ::google::protobuf::int32 port_no() const; + inline void set_port_no(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolNetRoute) + private: + inline void set_has_desc(); + inline void clear_has_desc(); + inline void set_has_port_no(); + inline void clear_has_port_no(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* desc_; + ::google::protobuf::int32 port_no_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolNetRoute* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolChanParam : public ::google::protobuf::Message { + public: + FesDebugToolChanParam(); + virtual ~FesDebugToolChanParam(); + + FesDebugToolChanParam(const FesDebugToolChanParam& from); + + inline FesDebugToolChanParam& operator=(const FesDebugToolChanParam& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolChanParam& default_instance(); + + void Swap(FesDebugToolChanParam* other); + + // implements Message ---------------------------------------------- + + FesDebugToolChanParam* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolChanParam& from); + void MergeFrom(const FesDebugToolChanParam& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 chan_no = 1; + inline bool has_chan_no() const; + inline void clear_chan_no(); + static const int kChanNoFieldNumber = 1; + inline ::google::protobuf::int32 chan_no() const; + inline void set_chan_no(::google::protobuf::int32 value); + + // required string tag_name = 2; + inline bool has_tag_name() const; + inline void clear_tag_name(); + static const int kTagNameFieldNumber = 2; + inline const ::std::string& tag_name() const; + inline void set_tag_name(const ::std::string& value); + inline void set_tag_name(const char* value); + inline void set_tag_name(const char* value, size_t size); + inline ::std::string* mutable_tag_name(); + inline ::std::string* release_tag_name(); + inline void set_allocated_tag_name(::std::string* tag_name); + + // required string chan_name = 3; + inline bool has_chan_name() const; + inline void clear_chan_name(); + static const int kChanNameFieldNumber = 3; + inline const ::std::string& chan_name() const; + inline void set_chan_name(const ::std::string& value); + inline void set_chan_name(const char* value); + inline void set_chan_name(const char* value, size_t size); + inline ::std::string* mutable_chan_name(); + inline ::std::string* release_chan_name(); + inline void set_allocated_chan_name(::std::string* chan_name); + + // required int32 used = 4; + inline bool has_used() const; + inline void clear_used(); + static const int kUsedFieldNumber = 4; + inline ::google::protobuf::int32 used() const; + inline void set_used(::google::protobuf::int32 value); + + // required int32 chan_status = 5; + inline bool has_chan_status() const; + inline void clear_chan_status(); + static const int kChanStatusFieldNumber = 5; + inline ::google::protobuf::int32 chan_status() const; + inline void set_chan_status(::google::protobuf::int32 value); + + // required int32 comm_type = 6; + inline bool has_comm_type() const; + inline void clear_comm_type(); + static const int kCommTypeFieldNumber = 6; + inline ::google::protobuf::int32 comm_type() const; + inline void set_comm_type(::google::protobuf::int32 value); + + // required int32 chan_mode = 7; + inline bool has_chan_mode() const; + inline void clear_chan_mode(); + static const int kChanModeFieldNumber = 7; + inline ::google::protobuf::int32 chan_mode() const; + inline void set_chan_mode(::google::protobuf::int32 value); + + // required int32 protocol_id = 8; + inline bool has_protocol_id() const; + inline void clear_protocol_id(); + static const int kProtocolIdFieldNumber = 8; + inline ::google::protobuf::int32 protocol_id() const; + inline void set_protocol_id(::google::protobuf::int32 value); + + // repeated .iot_idl.FesDebugToolNetRoute net_route = 9; + inline int net_route_size() const; + inline void clear_net_route(); + static const int kNetRouteFieldNumber = 9; + inline const ::iot_idl::FesDebugToolNetRoute& net_route(int index) const; + inline ::iot_idl::FesDebugToolNetRoute* mutable_net_route(int index); + inline ::iot_idl::FesDebugToolNetRoute* add_net_route(); + inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolNetRoute >& + net_route() const; + inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolNetRoute >* + mutable_net_route(); + + // required int32 connect_wait_sec = 10; + inline bool has_connect_wait_sec() const; + inline void clear_connect_wait_sec(); + static const int kConnectWaitSecFieldNumber = 10; + inline ::google::protobuf::int32 connect_wait_sec() const; + inline void set_connect_wait_sec(::google::protobuf::int32 value); + + // required int32 connect_timeout = 11; + inline bool has_connect_timeout() const; + inline void clear_connect_timeout(); + static const int kConnectTimeoutFieldNumber = 11; + inline ::google::protobuf::int32 connect_timeout() const; + inline void set_connect_timeout(::google::protobuf::int32 value); + + // required int32 retry_times = 12; + inline bool has_retry_times() const; + inline void clear_retry_times(); + static const int kRetryTimesFieldNumber = 12; + inline ::google::protobuf::int32 retry_times() const; + inline void set_retry_times(::google::protobuf::int32 value); + + // required int32 recv_timeout = 13; + inline bool has_recv_timeout() const; + inline void clear_recv_timeout(); + static const int kRecvTimeoutFieldNumber = 13; + inline ::google::protobuf::int32 recv_timeout() const; + inline void set_recv_timeout(::google::protobuf::int32 value); + + // required int32 resp_timeout = 14; + inline bool has_resp_timeout() const; + inline void clear_resp_timeout(); + static const int kRespTimeoutFieldNumber = 14; + inline ::google::protobuf::int32 resp_timeout() const; + inline void set_resp_timeout(::google::protobuf::int32 value); + + // required int32 max_rx_size = 15; + inline bool has_max_rx_size() const; + inline void clear_max_rx_size(); + static const int kMaxRxSizeFieldNumber = 15; + inline ::google::protobuf::int32 max_rx_size() const; + inline void set_max_rx_size(::google::protobuf::int32 value); + + // required int32 max_tx_size = 16; + inline bool has_max_tx_size() const; + inline void clear_max_tx_size(); + static const int kMaxTxSizeFieldNumber = 16; + inline ::google::protobuf::int32 max_tx_size() const; + inline void set_max_tx_size(::google::protobuf::int32 value); + + // required float err_rate_limit = 17; + inline bool has_err_rate_limit() const; + inline void clear_err_rate_limit(); + static const int kErrRateLimitFieldNumber = 17; + inline float err_rate_limit() const; + inline void set_err_rate_limit(float value); + + // repeated int32 backup_chan_no = 18; + inline int backup_chan_no_size() const; + inline void clear_backup_chan_no(); + static const int kBackupChanNoFieldNumber = 18; + inline ::google::protobuf::int32 backup_chan_no(int index) const; + inline void set_backup_chan_no(int index, ::google::protobuf::int32 value); + inline void add_backup_chan_no(::google::protobuf::int32 value); + inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + backup_chan_no() const; + inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_backup_chan_no(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolChanParam) + private: + inline void set_has_chan_no(); + inline void clear_has_chan_no(); + inline void set_has_tag_name(); + inline void clear_has_tag_name(); + inline void set_has_chan_name(); + inline void clear_has_chan_name(); + inline void set_has_used(); + inline void clear_has_used(); + inline void set_has_chan_status(); + inline void clear_has_chan_status(); + inline void set_has_comm_type(); + inline void clear_has_comm_type(); + inline void set_has_chan_mode(); + inline void clear_has_chan_mode(); + inline void set_has_protocol_id(); + inline void clear_has_protocol_id(); + inline void set_has_connect_wait_sec(); + inline void clear_has_connect_wait_sec(); + inline void set_has_connect_timeout(); + inline void clear_has_connect_timeout(); + inline void set_has_retry_times(); + inline void clear_has_retry_times(); + inline void set_has_recv_timeout(); + inline void clear_has_recv_timeout(); + inline void set_has_resp_timeout(); + inline void clear_has_resp_timeout(); + inline void set_has_max_rx_size(); + inline void clear_has_max_rx_size(); + inline void set_has_max_tx_size(); + inline void clear_has_max_tx_size(); + inline void set_has_err_rate_limit(); + inline void clear_has_err_rate_limit(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* tag_name_; + ::google::protobuf::int32 chan_no_; + ::google::protobuf::int32 used_; + ::std::string* chan_name_; + ::google::protobuf::int32 chan_status_; + ::google::protobuf::int32 comm_type_; + ::google::protobuf::int32 chan_mode_; + ::google::protobuf::int32 protocol_id_; + ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolNetRoute > net_route_; + ::google::protobuf::int32 connect_wait_sec_; + ::google::protobuf::int32 connect_timeout_; + ::google::protobuf::int32 retry_times_; + ::google::protobuf::int32 recv_timeout_; + ::google::protobuf::int32 resp_timeout_; + ::google::protobuf::int32 max_rx_size_; + ::google::protobuf::int32 max_tx_size_; + float err_rate_limit_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > backup_chan_no_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolChanParam* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolChanParamRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolChanParamRepMsg(); + virtual ~FesDebugToolChanParamRepMsg(); + + FesDebugToolChanParamRepMsg(const FesDebugToolChanParamRepMsg& from); + + inline FesDebugToolChanParamRepMsg& operator=(const FesDebugToolChanParamRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolChanParamRepMsg& default_instance(); + + void Swap(FesDebugToolChanParamRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolChanParamRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolChanParamRepMsg& from); + void MergeFrom(const FesDebugToolChanParamRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .iot_idl.FesDebugToolChanParam chan_param = 1; + inline int chan_param_size() const; + inline void clear_chan_param(); + static const int kChanParamFieldNumber = 1; + inline const ::iot_idl::FesDebugToolChanParam& chan_param(int index) const; + inline ::iot_idl::FesDebugToolChanParam* mutable_chan_param(int index); + inline ::iot_idl::FesDebugToolChanParam* add_chan_param(); + inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanParam >& + chan_param() const; + inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanParam >* + mutable_chan_param(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolChanParamRepMsg) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanParam > chan_param_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolChanParamRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolRtuParam : public ::google::protobuf::Message { + public: + FesDebugToolRtuParam(); + virtual ~FesDebugToolRtuParam(); + + FesDebugToolRtuParam(const FesDebugToolRtuParam& from); + + inline FesDebugToolRtuParam& operator=(const FesDebugToolRtuParam& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolRtuParam& default_instance(); + + void Swap(FesDebugToolRtuParam* other); + + // implements Message ---------------------------------------------- + + FesDebugToolRtuParam* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolRtuParam& from); + void MergeFrom(const FesDebugToolRtuParam& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 rtu_no = 1; + inline bool has_rtu_no() const; + inline void clear_rtu_no(); + static const int kRtuNoFieldNumber = 1; + inline ::google::protobuf::int32 rtu_no() const; + inline void set_rtu_no(::google::protobuf::int32 value); + + // required string rtu_desc = 2; + inline bool has_rtu_desc() const; + inline void clear_rtu_desc(); + static const int kRtuDescFieldNumber = 2; + inline const ::std::string& rtu_desc() const; + inline void set_rtu_desc(const ::std::string& value); + inline void set_rtu_desc(const char* value); + inline void set_rtu_desc(const char* value, size_t size); + inline ::std::string* mutable_rtu_desc(); + inline ::std::string* release_rtu_desc(); + inline void set_allocated_rtu_desc(::std::string* rtu_desc); + + // required string rtu_name = 3; + inline bool has_rtu_name() const; + inline void clear_rtu_name(); + static const int kRtuNameFieldNumber = 3; + inline const ::std::string& rtu_name() const; + inline void set_rtu_name(const ::std::string& value); + inline void set_rtu_name(const char* value); + inline void set_rtu_name(const char* value, size_t size); + inline ::std::string* mutable_rtu_name(); + inline ::std::string* release_rtu_name(); + inline void set_allocated_rtu_name(::std::string* rtu_name); + + // required int32 used = 4; + inline bool has_used() const; + inline void clear_used(); + static const int kUsedFieldNumber = 4; + inline ::google::protobuf::int32 used() const; + inline void set_used(::google::protobuf::int32 value); + + // required int32 rtu_status = 5; + inline bool has_rtu_status() const; + inline void clear_rtu_status(); + static const int kRtuStatusFieldNumber = 5; + inline ::google::protobuf::int32 rtu_status() const; + inline void set_rtu_status(::google::protobuf::int32 value); + + // required int32 rtu_addr = 6; + inline bool has_rtu_addr() const; + inline void clear_rtu_addr(); + static const int kRtuAddrFieldNumber = 6; + inline ::google::protobuf::int32 rtu_addr() const; + inline void set_rtu_addr(::google::protobuf::int32 value); + + // required int32 chan_no = 7; + inline bool has_chan_no() const; + inline void clear_chan_no(); + static const int kChanNoFieldNumber = 7; + inline ::google::protobuf::int32 chan_no() const; + inline void set_chan_no(::google::protobuf::int32 value); + + // required int32 max_ai_num = 8; + inline bool has_max_ai_num() const; + inline void clear_max_ai_num(); + static const int kMaxAiNumFieldNumber = 8; + inline ::google::protobuf::int32 max_ai_num() const; + inline void set_max_ai_num(::google::protobuf::int32 value); + + // required int32 max_di_num = 9; + inline bool has_max_di_num() const; + inline void clear_max_di_num(); + static const int kMaxDiNumFieldNumber = 9; + inline ::google::protobuf::int32 max_di_num() const; + inline void set_max_di_num(::google::protobuf::int32 value); + + // required int32 max_acc_num = 10; + inline bool has_max_acc_num() const; + inline void clear_max_acc_num(); + static const int kMaxAccNumFieldNumber = 10; + inline ::google::protobuf::int32 max_acc_num() const; + inline void set_max_acc_num(::google::protobuf::int32 value); + + // required int32 recv_fail_limit = 11; + inline bool has_recv_fail_limit() const; + inline void clear_recv_fail_limit(); + static const int kRecvFailLimitFieldNumber = 11; + inline ::google::protobuf::int32 recv_fail_limit() const; + inline void set_recv_fail_limit(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolRtuParam) + private: + inline void set_has_rtu_no(); + inline void clear_has_rtu_no(); + inline void set_has_rtu_desc(); + inline void clear_has_rtu_desc(); + inline void set_has_rtu_name(); + inline void clear_has_rtu_name(); + inline void set_has_used(); + inline void clear_has_used(); + inline void set_has_rtu_status(); + inline void clear_has_rtu_status(); + inline void set_has_rtu_addr(); + inline void clear_has_rtu_addr(); + inline void set_has_chan_no(); + inline void clear_has_chan_no(); + inline void set_has_max_ai_num(); + inline void clear_has_max_ai_num(); + inline void set_has_max_di_num(); + inline void clear_has_max_di_num(); + inline void set_has_max_acc_num(); + inline void clear_has_max_acc_num(); + inline void set_has_recv_fail_limit(); + inline void clear_has_recv_fail_limit(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* rtu_desc_; + ::google::protobuf::int32 rtu_no_; + ::google::protobuf::int32 used_; + ::std::string* rtu_name_; + ::google::protobuf::int32 rtu_status_; + ::google::protobuf::int32 rtu_addr_; + ::google::protobuf::int32 chan_no_; + ::google::protobuf::int32 max_ai_num_; + ::google::protobuf::int32 max_di_num_; + ::google::protobuf::int32 max_acc_num_; + ::google::protobuf::int32 recv_fail_limit_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolRtuParam* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolRtuParamRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolRtuParamRepMsg(); + virtual ~FesDebugToolRtuParamRepMsg(); + + FesDebugToolRtuParamRepMsg(const FesDebugToolRtuParamRepMsg& from); + + inline FesDebugToolRtuParamRepMsg& operator=(const FesDebugToolRtuParamRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolRtuParamRepMsg& default_instance(); + + void Swap(FesDebugToolRtuParamRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolRtuParamRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolRtuParamRepMsg& from); + void MergeFrom(const FesDebugToolRtuParamRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .iot_idl.FesDebugToolRtuParam rtu_param = 1; + inline int rtu_param_size() const; + inline void clear_rtu_param(); + static const int kRtuParamFieldNumber = 1; + inline const ::iot_idl::FesDebugToolRtuParam& rtu_param(int index) const; + inline ::iot_idl::FesDebugToolRtuParam* mutable_rtu_param(int index); + inline ::iot_idl::FesDebugToolRtuParam* add_rtu_param(); + inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolRtuParam >& + rtu_param() const; + inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolRtuParam >* + mutable_rtu_param(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolRtuParamRepMsg) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolRtuParam > rtu_param_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolRtuParamRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolRtuInfo : public ::google::protobuf::Message { + public: + FesDebugToolRtuInfo(); + virtual ~FesDebugToolRtuInfo(); + + FesDebugToolRtuInfo(const FesDebugToolRtuInfo& from); + + inline FesDebugToolRtuInfo& operator=(const FesDebugToolRtuInfo& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolRtuInfo& default_instance(); + + void Swap(FesDebugToolRtuInfo* other); + + // implements Message ---------------------------------------------- + + FesDebugToolRtuInfo* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolRtuInfo& from); + void MergeFrom(const FesDebugToolRtuInfo& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 rtu_no = 1; + inline bool has_rtu_no() const; + inline void clear_rtu_no(); + static const int kRtuNoFieldNumber = 1; + inline ::google::protobuf::int32 rtu_no() const; + inline void set_rtu_no(::google::protobuf::int32 value); + + // required int32 used = 2; + inline bool has_used() const; + inline void clear_used(); + static const int kUsedFieldNumber = 2; + inline ::google::protobuf::int32 used() const; + inline void set_used(::google::protobuf::int32 value); + + // required string rtu_desc = 3; + inline bool has_rtu_desc() const; + inline void clear_rtu_desc(); + static const int kRtuDescFieldNumber = 3; + inline const ::std::string& rtu_desc() const; + inline void set_rtu_desc(const ::std::string& value); + inline void set_rtu_desc(const char* value); + inline void set_rtu_desc(const char* value, size_t size); + inline ::std::string* mutable_rtu_desc(); + inline ::std::string* release_rtu_desc(); + inline void set_allocated_rtu_desc(::std::string* rtu_desc); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolRtuInfo) + private: + inline void set_has_rtu_no(); + inline void clear_has_rtu_no(); + inline void set_has_used(); + inline void clear_has_used(); + inline void set_has_rtu_desc(); + inline void clear_has_rtu_desc(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 rtu_no_; + ::google::protobuf::int32 used_; + ::std::string* rtu_desc_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolRtuInfo* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolRtuInfoRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolRtuInfoRepMsg(); + virtual ~FesDebugToolRtuInfoRepMsg(); + + FesDebugToolRtuInfoRepMsg(const FesDebugToolRtuInfoRepMsg& from); + + inline FesDebugToolRtuInfoRepMsg& operator=(const FesDebugToolRtuInfoRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolRtuInfoRepMsg& default_instance(); + + void Swap(FesDebugToolRtuInfoRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolRtuInfoRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolRtuInfoRepMsg& from); + void MergeFrom(const FesDebugToolRtuInfoRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .iot_idl.FesDebugToolRtuInfo rtu_info = 1; + inline int rtu_info_size() const; + inline void clear_rtu_info(); + static const int kRtuInfoFieldNumber = 1; + inline const ::iot_idl::FesDebugToolRtuInfo& rtu_info(int index) const; + inline ::iot_idl::FesDebugToolRtuInfo* mutable_rtu_info(int index); + inline ::iot_idl::FesDebugToolRtuInfo* add_rtu_info(); + inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolRtuInfo >& + rtu_info() const; + inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolRtuInfo >* + mutable_rtu_info(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolRtuInfoRepMsg) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolRtuInfo > rtu_info_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolRtuInfoRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolPntParamReqMsg : public ::google::protobuf::Message { + public: + FesDebugToolPntParamReqMsg(); + virtual ~FesDebugToolPntParamReqMsg(); + + FesDebugToolPntParamReqMsg(const FesDebugToolPntParamReqMsg& from); + + inline FesDebugToolPntParamReqMsg& operator=(const FesDebugToolPntParamReqMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolPntParamReqMsg& default_instance(); + + void Swap(FesDebugToolPntParamReqMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolPntParamReqMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolPntParamReqMsg& from); + void MergeFrom(const FesDebugToolPntParamReqMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 rtu_no = 1; + inline bool has_rtu_no() const; + inline void clear_rtu_no(); + static const int kRtuNoFieldNumber = 1; + inline ::google::protobuf::int32 rtu_no() const; + inline void set_rtu_no(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolPntParamReqMsg) + private: + inline void set_has_rtu_no(); + inline void clear_has_rtu_no(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 rtu_no_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolPntParamReqMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolPntParam : public ::google::protobuf::Message { + public: + FesDebugToolPntParam(); + virtual ~FesDebugToolPntParam(); + + FesDebugToolPntParam(const FesDebugToolPntParam& from); + + inline FesDebugToolPntParam& operator=(const FesDebugToolPntParam& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolPntParam& default_instance(); + + void Swap(FesDebugToolPntParam* other); + + // implements Message ---------------------------------------------- + + FesDebugToolPntParam* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolPntParam& from); + void MergeFrom(const FesDebugToolPntParam& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 pnt_no = 1; + inline bool has_pnt_no() const; + inline void clear_pnt_no(); + static const int kPntNoFieldNumber = 1; + inline ::google::protobuf::int32 pnt_no() const; + inline void set_pnt_no(::google::protobuf::int32 value); + + // required int32 used = 2; + inline bool has_used() const; + inline void clear_used(); + static const int kUsedFieldNumber = 2; + inline ::google::protobuf::int32 used() const; + inline void set_used(::google::protobuf::int32 value); + + // required string pnt_desc = 3; + inline bool has_pnt_desc() const; + inline void clear_pnt_desc(); + static const int kPntDescFieldNumber = 3; + inline const ::std::string& pnt_desc() const; + inline void set_pnt_desc(const ::std::string& value); + inline void set_pnt_desc(const char* value); + inline void set_pnt_desc(const char* value, size_t size); + inline ::std::string* mutable_pnt_desc(); + inline ::std::string* release_pnt_desc(); + inline void set_allocated_pnt_desc(::std::string* pnt_desc); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolPntParam) + private: + inline void set_has_pnt_no(); + inline void clear_has_pnt_no(); + inline void set_has_used(); + inline void clear_has_used(); + inline void set_has_pnt_desc(); + inline void clear_has_pnt_desc(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 pnt_no_; + ::google::protobuf::int32 used_; + ::std::string* pnt_desc_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolPntParam* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolPntParamRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolPntParamRepMsg(); + virtual ~FesDebugToolPntParamRepMsg(); + + FesDebugToolPntParamRepMsg(const FesDebugToolPntParamRepMsg& from); + + inline FesDebugToolPntParamRepMsg& operator=(const FesDebugToolPntParamRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolPntParamRepMsg& default_instance(); + + void Swap(FesDebugToolPntParamRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolPntParamRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolPntParamRepMsg& from); + void MergeFrom(const FesDebugToolPntParamRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 rtu_no = 1; + inline bool has_rtu_no() const; + inline void clear_rtu_no(); + static const int kRtuNoFieldNumber = 1; + inline ::google::protobuf::int32 rtu_no() const; + inline void set_rtu_no(::google::protobuf::int32 value); + + // required int32 max_pnt_num = 2; + inline bool has_max_pnt_num() const; + inline void clear_max_pnt_num(); + static const int kMaxPntNumFieldNumber = 2; + inline ::google::protobuf::int32 max_pnt_num() const; + inline void set_max_pnt_num(::google::protobuf::int32 value); + + // repeated .iot_idl.FesDebugToolPntParam pnt_param = 3; + inline int pnt_param_size() const; + inline void clear_pnt_param(); + static const int kPntParamFieldNumber = 3; + inline const ::iot_idl::FesDebugToolPntParam& pnt_param(int index) const; + inline ::iot_idl::FesDebugToolPntParam* mutable_pnt_param(int index); + inline ::iot_idl::FesDebugToolPntParam* add_pnt_param(); + inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolPntParam >& + pnt_param() const; + inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolPntParam >* + mutable_pnt_param(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolPntParamRepMsg) + private: + inline void set_has_rtu_no(); + inline void clear_has_rtu_no(); + inline void set_has_max_pnt_num(); + inline void clear_has_max_pnt_num(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 rtu_no_; + ::google::protobuf::int32 max_pnt_num_; + ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolPntParam > pnt_param_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolPntParamRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolPntValueReqMsg : public ::google::protobuf::Message { + public: + FesDebugToolPntValueReqMsg(); + virtual ~FesDebugToolPntValueReqMsg(); + + FesDebugToolPntValueReqMsg(const FesDebugToolPntValueReqMsg& from); + + inline FesDebugToolPntValueReqMsg& operator=(const FesDebugToolPntValueReqMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolPntValueReqMsg& default_instance(); + + void Swap(FesDebugToolPntValueReqMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolPntValueReqMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolPntValueReqMsg& from); + void MergeFrom(const FesDebugToolPntValueReqMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 rtu_no = 1; + inline bool has_rtu_no() const; + inline void clear_rtu_no(); + static const int kRtuNoFieldNumber = 1; + inline ::google::protobuf::int32 rtu_no() const; + inline void set_rtu_no(::google::protobuf::int32 value); + + // required int32 start_index = 2; + inline bool has_start_index() const; + inline void clear_start_index(); + static const int kStartIndexFieldNumber = 2; + inline ::google::protobuf::int32 start_index() const; + inline void set_start_index(::google::protobuf::int32 value); + + // required int32 end_index = 3; + inline bool has_end_index() const; + inline void clear_end_index(); + static const int kEndIndexFieldNumber = 3; + inline ::google::protobuf::int32 end_index() const; + inline void set_end_index(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolPntValueReqMsg) + private: + inline void set_has_rtu_no(); + inline void clear_has_rtu_no(); + inline void set_has_start_index(); + inline void clear_has_start_index(); + inline void set_has_end_index(); + inline void clear_has_end_index(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 rtu_no_; + ::google::protobuf::int32 start_index_; + ::google::protobuf::int32 end_index_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolPntValueReqMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolIntPntValue : public ::google::protobuf::Message { + public: + FesDebugToolIntPntValue(); + virtual ~FesDebugToolIntPntValue(); + + FesDebugToolIntPntValue(const FesDebugToolIntPntValue& from); + + inline FesDebugToolIntPntValue& operator=(const FesDebugToolIntPntValue& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolIntPntValue& default_instance(); + + void Swap(FesDebugToolIntPntValue* other); + + // implements Message ---------------------------------------------- + + FesDebugToolIntPntValue* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolIntPntValue& from); + void MergeFrom(const FesDebugToolIntPntValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 pnt_no = 1; + inline bool has_pnt_no() const; + inline void clear_pnt_no(); + static const int kPntNoFieldNumber = 1; + inline ::google::protobuf::int32 pnt_no() const; + inline void set_pnt_no(::google::protobuf::int32 value); + + // required sint32 value = 2; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 2; + inline ::google::protobuf::int32 value() const; + inline void set_value(::google::protobuf::int32 value); + + // required uint32 status = 3; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 3; + inline ::google::protobuf::uint32 status() const; + inline void set_status(::google::protobuf::uint32 value); + + // required uint64 time = 4; + inline bool has_time() const; + inline void clear_time(); + static const int kTimeFieldNumber = 4; + inline ::google::protobuf::uint64 time() const; + inline void set_time(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolIntPntValue) + private: + inline void set_has_pnt_no(); + inline void clear_has_pnt_no(); + inline void set_has_value(); + inline void clear_has_value(); + inline void set_has_status(); + inline void clear_has_status(); + inline void set_has_time(); + inline void clear_has_time(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 pnt_no_; + ::google::protobuf::int32 value_; + ::google::protobuf::uint64 time_; + ::google::protobuf::uint32 status_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolIntPntValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolFloatPntValue : public ::google::protobuf::Message { + public: + FesDebugToolFloatPntValue(); + virtual ~FesDebugToolFloatPntValue(); + + FesDebugToolFloatPntValue(const FesDebugToolFloatPntValue& from); + + inline FesDebugToolFloatPntValue& operator=(const FesDebugToolFloatPntValue& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolFloatPntValue& default_instance(); + + void Swap(FesDebugToolFloatPntValue* other); + + // implements Message ---------------------------------------------- + + FesDebugToolFloatPntValue* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolFloatPntValue& from); + void MergeFrom(const FesDebugToolFloatPntValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 pnt_no = 1; + inline bool has_pnt_no() const; + inline void clear_pnt_no(); + static const int kPntNoFieldNumber = 1; + inline ::google::protobuf::int32 pnt_no() const; + inline void set_pnt_no(::google::protobuf::int32 value); + + // required float value = 2; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 2; + inline float value() const; + inline void set_value(float value); + + // required uint32 status = 3; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 3; + inline ::google::protobuf::uint32 status() const; + inline void set_status(::google::protobuf::uint32 value); + + // required uint64 time = 4; + inline bool has_time() const; + inline void clear_time(); + static const int kTimeFieldNumber = 4; + inline ::google::protobuf::uint64 time() const; + inline void set_time(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolFloatPntValue) + private: + inline void set_has_pnt_no(); + inline void clear_has_pnt_no(); + inline void set_has_value(); + inline void clear_has_value(); + inline void set_has_status(); + inline void clear_has_status(); + inline void set_has_time(); + inline void clear_has_time(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 pnt_no_; + float value_; + ::google::protobuf::uint64 time_; + ::google::protobuf::uint32 status_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolFloatPntValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolDoublePntValue : public ::google::protobuf::Message { + public: + FesDebugToolDoublePntValue(); + virtual ~FesDebugToolDoublePntValue(); + + FesDebugToolDoublePntValue(const FesDebugToolDoublePntValue& from); + + inline FesDebugToolDoublePntValue& operator=(const FesDebugToolDoublePntValue& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolDoublePntValue& default_instance(); + + void Swap(FesDebugToolDoublePntValue* other); + + // implements Message ---------------------------------------------- + + FesDebugToolDoublePntValue* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolDoublePntValue& from); + void MergeFrom(const FesDebugToolDoublePntValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 pnt_no = 1; + inline bool has_pnt_no() const; + inline void clear_pnt_no(); + static const int kPntNoFieldNumber = 1; + inline ::google::protobuf::int32 pnt_no() const; + inline void set_pnt_no(::google::protobuf::int32 value); + + // required double value = 2; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 2; + inline double value() const; + inline void set_value(double value); + + // required uint32 status = 3; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 3; + inline ::google::protobuf::uint32 status() const; + inline void set_status(::google::protobuf::uint32 value); + + // required uint64 time = 4; + inline bool has_time() const; + inline void clear_time(); + static const int kTimeFieldNumber = 4; + inline ::google::protobuf::uint64 time() const; + inline void set_time(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolDoublePntValue) + private: + inline void set_has_pnt_no(); + inline void clear_has_pnt_no(); + inline void set_has_value(); + inline void clear_has_value(); + inline void set_has_status(); + inline void clear_has_status(); + inline void set_has_time(); + inline void clear_has_time(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + double value_; + ::google::protobuf::int32 pnt_no_; + ::google::protobuf::uint32 status_; + ::google::protobuf::uint64 time_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolDoublePntValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolPntValueRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolPntValueRepMsg(); + virtual ~FesDebugToolPntValueRepMsg(); + + FesDebugToolPntValueRepMsg(const FesDebugToolPntValueRepMsg& from); + + inline FesDebugToolPntValueRepMsg& operator=(const FesDebugToolPntValueRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolPntValueRepMsg& default_instance(); + + void Swap(FesDebugToolPntValueRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolPntValueRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolPntValueRepMsg& from); + void MergeFrom(const FesDebugToolPntValueRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 rtu_no = 1; + inline bool has_rtu_no() const; + inline void clear_rtu_no(); + static const int kRtuNoFieldNumber = 1; + inline ::google::protobuf::int32 rtu_no() const; + inline void set_rtu_no(::google::protobuf::int32 value); + + // repeated .iot_idl.FesDebugToolIntPntValue int_values = 2; + inline int int_values_size() const; + inline void clear_int_values(); + static const int kIntValuesFieldNumber = 2; + inline const ::iot_idl::FesDebugToolIntPntValue& int_values(int index) const; + inline ::iot_idl::FesDebugToolIntPntValue* mutable_int_values(int index); + inline ::iot_idl::FesDebugToolIntPntValue* add_int_values(); + inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolIntPntValue >& + int_values() const; + inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolIntPntValue >* + mutable_int_values(); + + // repeated .iot_idl.FesDebugToolFloatPntValue float_values = 3; + inline int float_values_size() const; + inline void clear_float_values(); + static const int kFloatValuesFieldNumber = 3; + inline const ::iot_idl::FesDebugToolFloatPntValue& float_values(int index) const; + inline ::iot_idl::FesDebugToolFloatPntValue* mutable_float_values(int index); + inline ::iot_idl::FesDebugToolFloatPntValue* add_float_values(); + inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolFloatPntValue >& + float_values() const; + inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolFloatPntValue >* + mutable_float_values(); + + // repeated .iot_idl.FesDebugToolDoublePntValue double_values = 4; + inline int double_values_size() const; + inline void clear_double_values(); + static const int kDoubleValuesFieldNumber = 4; + inline const ::iot_idl::FesDebugToolDoublePntValue& double_values(int index) const; + inline ::iot_idl::FesDebugToolDoublePntValue* mutable_double_values(int index); + inline ::iot_idl::FesDebugToolDoublePntValue* add_double_values(); + inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolDoublePntValue >& + double_values() const; + inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolDoublePntValue >* + mutable_double_values(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolPntValueRepMsg) + private: + inline void set_has_rtu_no(); + inline void clear_has_rtu_no(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolIntPntValue > int_values_; + ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolFloatPntValue > float_values_; + ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolDoublePntValue > double_values_; + ::google::protobuf::int32 rtu_no_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolPntValueRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolValueVariant : public ::google::protobuf::Message { + public: + FesDebugToolValueVariant(); + virtual ~FesDebugToolValueVariant(); + + FesDebugToolValueVariant(const FesDebugToolValueVariant& from); + + inline FesDebugToolValueVariant& operator=(const FesDebugToolValueVariant& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolValueVariant& default_instance(); + + void Swap(FesDebugToolValueVariant* other); + + // implements Message ---------------------------------------------- + + FesDebugToolValueVariant* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolValueVariant& from); + void MergeFrom(const FesDebugToolValueVariant& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 int_value = 1; + inline bool has_int_value() const; + inline void clear_int_value(); + static const int kIntValueFieldNumber = 1; + inline ::google::protobuf::int32 int_value() const; + inline void set_int_value(::google::protobuf::int32 value); + + // optional float float_value = 2; + inline bool has_float_value() const; + inline void clear_float_value(); + static const int kFloatValueFieldNumber = 2; + inline float float_value() const; + inline void set_float_value(float value); + + // optional double double_value = 3; + inline bool has_double_value() const; + inline void clear_double_value(); + static const int kDoubleValueFieldNumber = 3; + inline double double_value() const; + inline void set_double_value(double value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolValueVariant) + private: + inline void set_has_int_value(); + inline void clear_has_int_value(); + inline void set_has_float_value(); + inline void clear_has_float_value(); + inline void set_has_double_value(); + inline void clear_has_double_value(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 int_value_; + float float_value_; + double double_value_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolValueVariant* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolValueSetSimParam : public ::google::protobuf::Message { + public: + FesDebugToolValueSetSimParam(); + virtual ~FesDebugToolValueSetSimParam(); + + FesDebugToolValueSetSimParam(const FesDebugToolValueSetSimParam& from); + + inline FesDebugToolValueSetSimParam& operator=(const FesDebugToolValueSetSimParam& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolValueSetSimParam& default_instance(); + + void Swap(FesDebugToolValueSetSimParam* other); + + // implements Message ---------------------------------------------- + + FesDebugToolValueSetSimParam* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolValueSetSimParam& from); + void MergeFrom(const FesDebugToolValueSetSimParam& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required double value = 1; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 1; + inline double value() const; + inline void set_value(double value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolValueSetSimParam) + private: + inline void set_has_value(); + inline void clear_has_value(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + double value_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolValueSetSimParam* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolLineSetSimParam : public ::google::protobuf::Message { + public: + FesDebugToolLineSetSimParam(); + virtual ~FesDebugToolLineSetSimParam(); + + FesDebugToolLineSetSimParam(const FesDebugToolLineSetSimParam& from); + + inline FesDebugToolLineSetSimParam& operator=(const FesDebugToolLineSetSimParam& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolLineSetSimParam& default_instance(); + + void Swap(FesDebugToolLineSetSimParam* other); + + // implements Message ---------------------------------------------- + + FesDebugToolLineSetSimParam* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolLineSetSimParam& from); + void MergeFrom(const FesDebugToolLineSetSimParam& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required double min_value = 1; + inline bool has_min_value() const; + inline void clear_min_value(); + static const int kMinValueFieldNumber = 1; + inline double min_value() const; + inline void set_min_value(double value); + + // required double max_value = 2; + inline bool has_max_value() const; + inline void clear_max_value(); + static const int kMaxValueFieldNumber = 2; + inline double max_value() const; + inline void set_max_value(double value); + + // required double step_value = 3; + inline bool has_step_value() const; + inline void clear_step_value(); + static const int kStepValueFieldNumber = 3; + inline double step_value() const; + inline void set_step_value(double value); + + // required int32 period = 4; + inline bool has_period() const; + inline void clear_period(); + static const int kPeriodFieldNumber = 4; + inline ::google::protobuf::int32 period() const; + inline void set_period(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolLineSetSimParam) + private: + inline void set_has_min_value(); + inline void clear_has_min_value(); + inline void set_has_max_value(); + inline void clear_has_max_value(); + inline void set_has_step_value(); + inline void clear_has_step_value(); + inline void set_has_period(); + inline void clear_has_period(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + double min_value_; + double max_value_; + double step_value_; + ::google::protobuf::int32 period_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolLineSetSimParam* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolRandSetSimParam : public ::google::protobuf::Message { + public: + FesDebugToolRandSetSimParam(); + virtual ~FesDebugToolRandSetSimParam(); + + FesDebugToolRandSetSimParam(const FesDebugToolRandSetSimParam& from); + + inline FesDebugToolRandSetSimParam& operator=(const FesDebugToolRandSetSimParam& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolRandSetSimParam& default_instance(); + + void Swap(FesDebugToolRandSetSimParam* other); + + // implements Message ---------------------------------------------- + + FesDebugToolRandSetSimParam* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolRandSetSimParam& from); + void MergeFrom(const FesDebugToolRandSetSimParam& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional double min_value = 1; + inline bool has_min_value() const; + inline void clear_min_value(); + static const int kMinValueFieldNumber = 1; + inline double min_value() const; + inline void set_min_value(double value); + + // optional double max_value = 2; + inline bool has_max_value() const; + inline void clear_max_value(); + static const int kMaxValueFieldNumber = 2; + inline double max_value() const; + inline void set_max_value(double value); + + // required int32 period = 3; + inline bool has_period() const; + inline void clear_period(); + static const int kPeriodFieldNumber = 3; + inline ::google::protobuf::int32 period() const; + inline void set_period(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolRandSetSimParam) + private: + inline void set_has_min_value(); + inline void clear_has_min_value(); + inline void set_has_max_value(); + inline void clear_has_max_value(); + inline void set_has_period(); + inline void clear_has_period(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + double min_value_; + double max_value_; + ::google::protobuf::int32 period_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolRandSetSimParam* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolValueSimSetReqMsg : public ::google::protobuf::Message { + public: + FesDebugToolValueSimSetReqMsg(); + virtual ~FesDebugToolValueSimSetReqMsg(); + + FesDebugToolValueSimSetReqMsg(const FesDebugToolValueSimSetReqMsg& from); + + inline FesDebugToolValueSimSetReqMsg& operator=(const FesDebugToolValueSimSetReqMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolValueSimSetReqMsg& default_instance(); + + void Swap(FesDebugToolValueSimSetReqMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolValueSimSetReqMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolValueSimSetReqMsg& from); + void MergeFrom(const FesDebugToolValueSimSetReqMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .iot_idl.enFesDebugSimMode sim_mode = 1; + inline bool has_sim_mode() const; + inline void clear_sim_mode(); + static const int kSimModeFieldNumber = 1; + inline ::iot_idl::enFesDebugSimMode sim_mode() const; + inline void set_sim_mode(::iot_idl::enFesDebugSimMode value); + + // required .iot_idl.enFesDebugSimRangeType sim_range = 2; + inline bool has_sim_range() const; + inline void clear_sim_range(); + static const int kSimRangeFieldNumber = 2; + inline ::iot_idl::enFesDebugSimRangeType sim_range() const; + inline void set_sim_range(::iot_idl::enFesDebugSimRangeType value); + + // optional int32 rtu_no = 3; + inline bool has_rtu_no() const; + inline void clear_rtu_no(); + static const int kRtuNoFieldNumber = 3; + inline ::google::protobuf::int32 rtu_no() const; + inline void set_rtu_no(::google::protobuf::int32 value); + + // optional int32 pnt_no = 4; + inline bool has_pnt_no() const; + inline void clear_pnt_no(); + static const int kPntNoFieldNumber = 4; + inline ::google::protobuf::int32 pnt_no() const; + inline void set_pnt_no(::google::protobuf::int32 value); + + // optional uint32 status = 5; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 5; + inline ::google::protobuf::uint32 status() const; + inline void set_status(::google::protobuf::uint32 value); + + // optional .iot_idl.FesDebugToolValueSetSimParam value_set_param = 6; + inline bool has_value_set_param() const; + inline void clear_value_set_param(); + static const int kValueSetParamFieldNumber = 6; + inline const ::iot_idl::FesDebugToolValueSetSimParam& value_set_param() const; + inline ::iot_idl::FesDebugToolValueSetSimParam* mutable_value_set_param(); + inline ::iot_idl::FesDebugToolValueSetSimParam* release_value_set_param(); + inline void set_allocated_value_set_param(::iot_idl::FesDebugToolValueSetSimParam* value_set_param); + + // optional .iot_idl.FesDebugToolLineSetSimParam line_set_param = 7; + inline bool has_line_set_param() const; + inline void clear_line_set_param(); + static const int kLineSetParamFieldNumber = 7; + inline const ::iot_idl::FesDebugToolLineSetSimParam& line_set_param() const; + inline ::iot_idl::FesDebugToolLineSetSimParam* mutable_line_set_param(); + inline ::iot_idl::FesDebugToolLineSetSimParam* release_line_set_param(); + inline void set_allocated_line_set_param(::iot_idl::FesDebugToolLineSetSimParam* line_set_param); + + // optional .iot_idl.FesDebugToolRandSetSimParam rand_set_param = 8; + inline bool has_rand_set_param() const; + inline void clear_rand_set_param(); + static const int kRandSetParamFieldNumber = 8; + inline const ::iot_idl::FesDebugToolRandSetSimParam& rand_set_param() const; + inline ::iot_idl::FesDebugToolRandSetSimParam* mutable_rand_set_param(); + inline ::iot_idl::FesDebugToolRandSetSimParam* release_rand_set_param(); + inline void set_allocated_rand_set_param(::iot_idl::FesDebugToolRandSetSimParam* rand_set_param); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolValueSimSetReqMsg) + private: + inline void set_has_sim_mode(); + inline void clear_has_sim_mode(); + inline void set_has_sim_range(); + inline void clear_has_sim_range(); + inline void set_has_rtu_no(); + inline void clear_has_rtu_no(); + inline void set_has_pnt_no(); + inline void clear_has_pnt_no(); + inline void set_has_status(); + inline void clear_has_status(); + inline void set_has_value_set_param(); + inline void clear_has_value_set_param(); + inline void set_has_line_set_param(); + inline void clear_has_line_set_param(); + inline void set_has_rand_set_param(); + inline void clear_has_rand_set_param(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + int sim_mode_; + int sim_range_; + ::google::protobuf::int32 rtu_no_; + ::google::protobuf::int32 pnt_no_; + ::iot_idl::FesDebugToolValueSetSimParam* value_set_param_; + ::iot_idl::FesDebugToolLineSetSimParam* line_set_param_; + ::iot_idl::FesDebugToolRandSetSimParam* rand_set_param_; + ::google::protobuf::uint32 status_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolValueSimSetReqMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolValueSimSetRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolValueSimSetRepMsg(); + virtual ~FesDebugToolValueSimSetRepMsg(); + + FesDebugToolValueSimSetRepMsg(const FesDebugToolValueSimSetRepMsg& from); + + inline FesDebugToolValueSimSetRepMsg& operator=(const FesDebugToolValueSimSetRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolValueSimSetRepMsg& default_instance(); + + void Swap(FesDebugToolValueSimSetRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolValueSimSetRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolValueSimSetRepMsg& from); + void MergeFrom(const FesDebugToolValueSimSetRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .iot_idl.enFesDebugSimMode sim_mode = 1; + inline bool has_sim_mode() const; + inline void clear_sim_mode(); + static const int kSimModeFieldNumber = 1; + inline ::iot_idl::enFesDebugSimMode sim_mode() const; + inline void set_sim_mode(::iot_idl::enFesDebugSimMode value); + + // optional string body = 2; + inline bool has_body() const; + inline void clear_body(); + static const int kBodyFieldNumber = 2; + inline const ::std::string& body() const; + inline void set_body(const ::std::string& value); + inline void set_body(const char* value); + inline void set_body(const char* value, size_t size); + inline ::std::string* mutable_body(); + inline ::std::string* release_body(); + inline void set_allocated_body(::std::string* body); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolValueSimSetRepMsg) + private: + inline void set_has_sim_mode(); + inline void clear_has_sim_mode(); + inline void set_has_body(); + inline void clear_has_body(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* body_; + int sim_mode_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolValueSimSetRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolSimEventRtuSoe : public ::google::protobuf::Message { + public: + FesDebugToolSimEventRtuSoe(); + virtual ~FesDebugToolSimEventRtuSoe(); + + FesDebugToolSimEventRtuSoe(const FesDebugToolSimEventRtuSoe& from); + + inline FesDebugToolSimEventRtuSoe& operator=(const FesDebugToolSimEventRtuSoe& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolSimEventRtuSoe& default_instance(); + + void Swap(FesDebugToolSimEventRtuSoe* other); + + // implements Message ---------------------------------------------- + + FesDebugToolSimEventRtuSoe* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolSimEventRtuSoe& from); + void MergeFrom(const FesDebugToolSimEventRtuSoe& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 event_source = 1; + inline bool has_event_source() const; + inline void clear_event_source(); + static const int kEventSourceFieldNumber = 1; + inline ::google::protobuf::int32 event_source() const; + inline void set_event_source(::google::protobuf::int32 value); + + // required int32 rtu_no = 2; + inline bool has_rtu_no() const; + inline void clear_rtu_no(); + static const int kRtuNoFieldNumber = 2; + inline ::google::protobuf::int32 rtu_no() const; + inline void set_rtu_no(::google::protobuf::int32 value); + + // required int32 pnt_no = 3; + inline bool has_pnt_no() const; + inline void clear_pnt_no(); + static const int kPntNoFieldNumber = 3; + inline ::google::protobuf::int32 pnt_no() const; + inline void set_pnt_no(::google::protobuf::int32 value); + + // required int32 value = 4; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 4; + inline ::google::protobuf::int32 value() const; + inline void set_value(::google::protobuf::int32 value); + + // required uint32 status = 5; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 5; + inline ::google::protobuf::uint32 status() const; + inline void set_status(::google::protobuf::uint32 value); + + // required int32 fault_num = 6; + inline bool has_fault_num() const; + inline void clear_fault_num(); + static const int kFaultNumFieldNumber = 6; + inline ::google::protobuf::int32 fault_num() const; + inline void set_fault_num(::google::protobuf::int32 value); + + // repeated int32 fault_type = 7; + inline int fault_type_size() const; + inline void clear_fault_type(); + static const int kFaultTypeFieldNumber = 7; + inline ::google::protobuf::int32 fault_type(int index) const; + inline void set_fault_type(int index, ::google::protobuf::int32 value); + inline void add_fault_type(::google::protobuf::int32 value); + inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + fault_type() const; + inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_fault_type(); + + // repeated float fault_value = 8; + inline int fault_value_size() const; + inline void clear_fault_value(); + static const int kFaultValueFieldNumber = 8; + inline float fault_value(int index) const; + inline void set_fault_value(int index, float value); + inline void add_fault_value(float value); + inline const ::google::protobuf::RepeatedField< float >& + fault_value() const; + inline ::google::protobuf::RepeatedField< float >* + mutable_fault_value(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolSimEventRtuSoe) + private: + inline void set_has_event_source(); + inline void clear_has_event_source(); + inline void set_has_rtu_no(); + inline void clear_has_rtu_no(); + inline void set_has_pnt_no(); + inline void clear_has_pnt_no(); + inline void set_has_value(); + inline void clear_has_value(); + inline void set_has_status(); + inline void clear_has_status(); + inline void set_has_fault_num(); + inline void clear_has_fault_num(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 event_source_; + ::google::protobuf::int32 rtu_no_; + ::google::protobuf::int32 pnt_no_; + ::google::protobuf::int32 value_; + ::google::protobuf::uint32 status_; + ::google::protobuf::int32 fault_num_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > fault_type_; + ::google::protobuf::RepeatedField< float > fault_value_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolSimEventRtuSoe* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolSimEventCreateReqMsg : public ::google::protobuf::Message { + public: + FesDebugToolSimEventCreateReqMsg(); + virtual ~FesDebugToolSimEventCreateReqMsg(); + + FesDebugToolSimEventCreateReqMsg(const FesDebugToolSimEventCreateReqMsg& from); + + inline FesDebugToolSimEventCreateReqMsg& operator=(const FesDebugToolSimEventCreateReqMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolSimEventCreateReqMsg& default_instance(); + + void Swap(FesDebugToolSimEventCreateReqMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolSimEventCreateReqMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolSimEventCreateReqMsg& from); + void MergeFrom(const FesDebugToolSimEventCreateReqMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .iot_idl.enFesDebugEventSimType event_type = 1; + inline bool has_event_type() const; + inline void clear_event_type(); + static const int kEventTypeFieldNumber = 1; + inline ::iot_idl::enFesDebugEventSimType event_type() const; + inline void set_event_type(::iot_idl::enFesDebugEventSimType value); + + // optional .iot_idl.FesDebugToolSimEventRtuSoe event = 2; + inline bool has_event() const; + inline void clear_event(); + static const int kEventFieldNumber = 2; + inline const ::iot_idl::FesDebugToolSimEventRtuSoe& event() const; + inline ::iot_idl::FesDebugToolSimEventRtuSoe* mutable_event(); + inline ::iot_idl::FesDebugToolSimEventRtuSoe* release_event(); + inline void set_allocated_event(::iot_idl::FesDebugToolSimEventRtuSoe* event); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolSimEventCreateReqMsg) + private: + inline void set_has_event_type(); + inline void clear_has_event_type(); + inline void set_has_event(); + inline void clear_has_event(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::iot_idl::FesDebugToolSimEventRtuSoe* event_; + int event_type_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolSimEventCreateReqMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolSimEventCreateRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolSimEventCreateRepMsg(); + virtual ~FesDebugToolSimEventCreateRepMsg(); + + FesDebugToolSimEventCreateRepMsg(const FesDebugToolSimEventCreateRepMsg& from); + + inline FesDebugToolSimEventCreateRepMsg& operator=(const FesDebugToolSimEventCreateRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolSimEventCreateRepMsg& default_instance(); + + void Swap(FesDebugToolSimEventCreateRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolSimEventCreateRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolSimEventCreateRepMsg& from); + void MergeFrom(const FesDebugToolSimEventCreateRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .iot_idl.enFesDebugEventSimType event_type = 1; + inline bool has_event_type() const; + inline void clear_event_type(); + static const int kEventTypeFieldNumber = 1; + inline ::iot_idl::enFesDebugEventSimType event_type() const; + inline void set_event_type(::iot_idl::enFesDebugEventSimType value); + + // optional string body = 2; + inline bool has_body() const; + inline void clear_body(); + static const int kBodyFieldNumber = 2; + inline const ::std::string& body() const; + inline void set_body(const ::std::string& value); + inline void set_body(const char* value); + inline void set_body(const char* value, size_t size); + inline ::std::string* mutable_body(); + inline ::std::string* release_body(); + inline void set_allocated_body(::std::string* body); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolSimEventCreateRepMsg) + private: + inline void set_has_event_type(); + inline void clear_has_event_type(); + inline void set_has_body(); + inline void clear_has_body(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* body_; + int event_type_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolSimEventCreateRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolSimControlReqMsg : public ::google::protobuf::Message { + public: + FesDebugToolSimControlReqMsg(); + virtual ~FesDebugToolSimControlReqMsg(); + + FesDebugToolSimControlReqMsg(const FesDebugToolSimControlReqMsg& from); + + inline FesDebugToolSimControlReqMsg& operator=(const FesDebugToolSimControlReqMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolSimControlReqMsg& default_instance(); + + void Swap(FesDebugToolSimControlReqMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolSimControlReqMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolSimControlReqMsg& from); + void MergeFrom(const FesDebugToolSimControlReqMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 ctrl_type = 1; + inline bool has_ctrl_type() const; + inline void clear_ctrl_type(); + static const int kCtrlTypeFieldNumber = 1; + inline ::google::protobuf::int32 ctrl_type() const; + inline void set_ctrl_type(::google::protobuf::int32 value); + + // required int64 seq_no = 2; + inline bool has_seq_no() const; + inline void clear_seq_no(); + static const int kSeqNoFieldNumber = 2; + inline ::google::protobuf::int64 seq_no() const; + inline void set_seq_no(::google::protobuf::int64 value); + + // required int32 rtu_no = 3; + inline bool has_rtu_no() const; + inline void clear_rtu_no(); + static const int kRtuNoFieldNumber = 3; + inline ::google::protobuf::int32 rtu_no() const; + inline void set_rtu_no(::google::protobuf::int32 value); + + // required int32 pnt_no = 4; + inline bool has_pnt_no() const; + inline void clear_pnt_no(); + static const int kPntNoFieldNumber = 4; + inline ::google::protobuf::int32 pnt_no() const; + inline void set_pnt_no(::google::protobuf::int32 value); + + // optional float float_value = 5; + inline bool has_float_value() const; + inline void clear_float_value(); + static const int kFloatValueFieldNumber = 5; + inline float float_value() const; + inline void set_float_value(float value); + + // optional int32 int_value = 6; + inline bool has_int_value() const; + inline void clear_int_value(); + static const int kIntValueFieldNumber = 6; + inline ::google::protobuf::int32 int_value() const; + inline void set_int_value(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolSimControlReqMsg) + private: + inline void set_has_ctrl_type(); + inline void clear_has_ctrl_type(); + inline void set_has_seq_no(); + inline void clear_has_seq_no(); + inline void set_has_rtu_no(); + inline void clear_has_rtu_no(); + inline void set_has_pnt_no(); + inline void clear_has_pnt_no(); + inline void set_has_float_value(); + inline void clear_has_float_value(); + inline void set_has_int_value(); + inline void clear_has_int_value(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int64 seq_no_; + ::google::protobuf::int32 ctrl_type_; + ::google::protobuf::int32 rtu_no_; + ::google::protobuf::int32 pnt_no_; + float float_value_; + ::google::protobuf::int32 int_value_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolSimControlReqMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolSimControlRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolSimControlRepMsg(); + virtual ~FesDebugToolSimControlRepMsg(); + + FesDebugToolSimControlRepMsg(const FesDebugToolSimControlRepMsg& from); + + inline FesDebugToolSimControlRepMsg& operator=(const FesDebugToolSimControlRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolSimControlRepMsg& default_instance(); + + void Swap(FesDebugToolSimControlRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolSimControlRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolSimControlRepMsg& from); + void MergeFrom(const FesDebugToolSimControlRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 ctrl_type = 1; + inline bool has_ctrl_type() const; + inline void clear_ctrl_type(); + static const int kCtrlTypeFieldNumber = 1; + inline ::google::protobuf::int32 ctrl_type() const; + inline void set_ctrl_type(::google::protobuf::int32 value); + + // required int64 seq_no = 2; + inline bool has_seq_no() const; + inline void clear_seq_no(); + static const int kSeqNoFieldNumber = 2; + inline ::google::protobuf::int64 seq_no() const; + inline void set_seq_no(::google::protobuf::int64 value); + + // required bool success = 3; + inline bool has_success() const; + inline void clear_success(); + static const int kSuccessFieldNumber = 3; + inline bool success() const; + inline void set_success(bool value); + + // optional string err_msg = 4; + inline bool has_err_msg() const; + inline void clear_err_msg(); + static const int kErrMsgFieldNumber = 4; + inline const ::std::string& err_msg() const; + inline void set_err_msg(const ::std::string& value); + inline void set_err_msg(const char* value); + inline void set_err_msg(const char* value, size_t size); + inline ::std::string* mutable_err_msg(); + inline ::std::string* release_err_msg(); + inline void set_allocated_err_msg(::std::string* err_msg); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolSimControlRepMsg) + private: + inline void set_has_ctrl_type(); + inline void clear_has_ctrl_type(); + inline void set_has_seq_no(); + inline void clear_has_seq_no(); + inline void set_has_success(); + inline void clear_has_success(); + inline void set_has_err_msg(); + inline void clear_has_err_msg(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int64 seq_no_; + ::google::protobuf::int32 ctrl_type_; + bool success_; + ::std::string* err_msg_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolSimControlRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolSimDefCmdReqMsg : public ::google::protobuf::Message { + public: + FesDebugToolSimDefCmdReqMsg(); + virtual ~FesDebugToolSimDefCmdReqMsg(); + + FesDebugToolSimDefCmdReqMsg(const FesDebugToolSimDefCmdReqMsg& from); + + inline FesDebugToolSimDefCmdReqMsg& operator=(const FesDebugToolSimDefCmdReqMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolSimDefCmdReqMsg& default_instance(); + + void Swap(FesDebugToolSimDefCmdReqMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolSimDefCmdReqMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolSimDefCmdReqMsg& from); + void MergeFrom(const FesDebugToolSimDefCmdReqMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 rtu_no = 1; + inline bool has_rtu_no() const; + inline void clear_rtu_no(); + static const int kRtuNoFieldNumber = 1; + inline ::google::protobuf::int32 rtu_no() const; + inline void set_rtu_no(::google::protobuf::int32 value); + + // required int32 dev_id = 2; + inline bool has_dev_id() const; + inline void clear_dev_id(); + static const int kDevIdFieldNumber = 2; + inline ::google::protobuf::int32 dev_id() const; + inline void set_dev_id(::google::protobuf::int32 value); + + // repeated string keys = 3; + inline int keys_size() const; + inline void clear_keys(); + static const int kKeysFieldNumber = 3; + inline const ::std::string& keys(int index) const; + inline ::std::string* mutable_keys(int index); + inline void set_keys(int index, const ::std::string& value); + inline void set_keys(int index, const char* value); + inline void set_keys(int index, const char* value, size_t size); + inline ::std::string* add_keys(); + inline void add_keys(const ::std::string& value); + inline void add_keys(const char* value); + inline void add_keys(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& keys() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_keys(); + + // repeated string values = 4; + inline int values_size() const; + inline void clear_values(); + static const int kValuesFieldNumber = 4; + inline const ::std::string& values(int index) const; + inline ::std::string* mutable_values(int index); + inline void set_values(int index, const ::std::string& value); + inline void set_values(int index, const char* value); + inline void set_values(int index, const char* value, size_t size); + inline ::std::string* add_values(); + inline void add_values(const ::std::string& value); + inline void add_values(const char* value); + inline void add_values(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& values() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_values(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolSimDefCmdReqMsg) + private: + inline void set_has_rtu_no(); + inline void clear_has_rtu_no(); + inline void set_has_dev_id(); + inline void clear_has_dev_id(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 rtu_no_; + ::google::protobuf::int32 dev_id_; + ::google::protobuf::RepeatedPtrField< ::std::string> keys_; + ::google::protobuf::RepeatedPtrField< ::std::string> values_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolSimDefCmdReqMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolFwPntParam : public ::google::protobuf::Message { + public: + FesDebugToolFwPntParam(); + virtual ~FesDebugToolFwPntParam(); + + FesDebugToolFwPntParam(const FesDebugToolFwPntParam& from); + + inline FesDebugToolFwPntParam& operator=(const FesDebugToolFwPntParam& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolFwPntParam& default_instance(); + + void Swap(FesDebugToolFwPntParam* other); + + // implements Message ---------------------------------------------- + + FesDebugToolFwPntParam* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolFwPntParam& from); + void MergeFrom(const FesDebugToolFwPntParam& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 pnt_no = 1; + inline bool has_pnt_no() const; + inline void clear_pnt_no(); + static const int kPntNoFieldNumber = 1; + inline ::google::protobuf::int32 pnt_no() const; + inline void set_pnt_no(::google::protobuf::int32 value); + + // required int32 used = 2; + inline bool has_used() const; + inline void clear_used(); + static const int kUsedFieldNumber = 2; + inline ::google::protobuf::int32 used() const; + inline void set_used(::google::protobuf::int32 value); + + // required int32 fes_rtu_no = 3; + inline bool has_fes_rtu_no() const; + inline void clear_fes_rtu_no(); + static const int kFesRtuNoFieldNumber = 3; + inline ::google::protobuf::int32 fes_rtu_no() const; + inline void set_fes_rtu_no(::google::protobuf::int32 value); + + // required int32 fes_pnt_no = 4; + inline bool has_fes_pnt_no() const; + inline void clear_fes_pnt_no(); + static const int kFesPntNoFieldNumber = 4; + inline ::google::protobuf::int32 fes_pnt_no() const; + inline void set_fes_pnt_no(::google::protobuf::int32 value); + + // required string pnt_desc = 5; + inline bool has_pnt_desc() const; + inline void clear_pnt_desc(); + static const int kPntDescFieldNumber = 5; + inline const ::std::string& pnt_desc() const; + inline void set_pnt_desc(const ::std::string& value); + inline void set_pnt_desc(const char* value); + inline void set_pnt_desc(const char* value, size_t size); + inline ::std::string* mutable_pnt_desc(); + inline ::std::string* release_pnt_desc(); + inline void set_allocated_pnt_desc(::std::string* pnt_desc); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolFwPntParam) + private: + inline void set_has_pnt_no(); + inline void clear_has_pnt_no(); + inline void set_has_used(); + inline void clear_has_used(); + inline void set_has_fes_rtu_no(); + inline void clear_has_fes_rtu_no(); + inline void set_has_fes_pnt_no(); + inline void clear_has_fes_pnt_no(); + inline void set_has_pnt_desc(); + inline void clear_has_pnt_desc(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 pnt_no_; + ::google::protobuf::int32 used_; + ::google::protobuf::int32 fes_rtu_no_; + ::google::protobuf::int32 fes_pnt_no_; + ::std::string* pnt_desc_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolFwPntParam* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolFwPntParamRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolFwPntParamRepMsg(); + virtual ~FesDebugToolFwPntParamRepMsg(); + + FesDebugToolFwPntParamRepMsg(const FesDebugToolFwPntParamRepMsg& from); + + inline FesDebugToolFwPntParamRepMsg& operator=(const FesDebugToolFwPntParamRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolFwPntParamRepMsg& default_instance(); + + void Swap(FesDebugToolFwPntParamRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolFwPntParamRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolFwPntParamRepMsg& from); + void MergeFrom(const FesDebugToolFwPntParamRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 rtu_no = 1; + inline bool has_rtu_no() const; + inline void clear_rtu_no(); + static const int kRtuNoFieldNumber = 1; + inline ::google::protobuf::int32 rtu_no() const; + inline void set_rtu_no(::google::protobuf::int32 value); + + // required int32 max_pnt_num = 2; + inline bool has_max_pnt_num() const; + inline void clear_max_pnt_num(); + static const int kMaxPntNumFieldNumber = 2; + inline ::google::protobuf::int32 max_pnt_num() const; + inline void set_max_pnt_num(::google::protobuf::int32 value); + + // repeated .iot_idl.FesDebugToolFwPntParam pnt_param = 3; + inline int pnt_param_size() const; + inline void clear_pnt_param(); + static const int kPntParamFieldNumber = 3; + inline const ::iot_idl::FesDebugToolFwPntParam& pnt_param(int index) const; + inline ::iot_idl::FesDebugToolFwPntParam* mutable_pnt_param(int index); + inline ::iot_idl::FesDebugToolFwPntParam* add_pnt_param(); + inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolFwPntParam >& + pnt_param() const; + inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolFwPntParam >* + mutable_pnt_param(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolFwPntParamRepMsg) + private: + inline void set_has_rtu_no(); + inline void clear_has_rtu_no(); + inline void set_has_max_pnt_num(); + inline void clear_has_max_pnt_num(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 rtu_no_; + ::google::protobuf::int32 max_pnt_num_; + ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolFwPntParam > pnt_param_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolFwPntParamRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolSoeEvent : public ::google::protobuf::Message { + public: + FesDebugToolSoeEvent(); + virtual ~FesDebugToolSoeEvent(); + + FesDebugToolSoeEvent(const FesDebugToolSoeEvent& from); + + inline FesDebugToolSoeEvent& operator=(const FesDebugToolSoeEvent& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolSoeEvent& default_instance(); + + void Swap(FesDebugToolSoeEvent* other); + + // implements Message ---------------------------------------------- + + FesDebugToolSoeEvent* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolSoeEvent& from); + void MergeFrom(const FesDebugToolSoeEvent& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string table_name = 1; + inline bool has_table_name() const; + inline void clear_table_name(); + static const int kTableNameFieldNumber = 1; + inline const ::std::string& table_name() const; + inline void set_table_name(const ::std::string& value); + inline void set_table_name(const char* value); + inline void set_table_name(const char* value, size_t size); + inline ::std::string* mutable_table_name(); + inline ::std::string* release_table_name(); + inline void set_allocated_table_name(::std::string* table_name); + + // required string col_name = 2; + inline bool has_col_name() const; + inline void clear_col_name(); + static const int kColNameFieldNumber = 2; + inline const ::std::string& col_name() const; + inline void set_col_name(const ::std::string& value); + inline void set_col_name(const char* value); + inline void set_col_name(const char* value, size_t size); + inline ::std::string* mutable_col_name(); + inline ::std::string* release_col_name(); + inline void set_allocated_col_name(::std::string* col_name); + + // required string tag_name = 3; + inline bool has_tag_name() const; + inline void clear_tag_name(); + static const int kTagNameFieldNumber = 3; + inline const ::std::string& tag_name() const; + inline void set_tag_name(const ::std::string& value); + inline void set_tag_name(const char* value); + inline void set_tag_name(const char* value, size_t size); + inline ::std::string* mutable_tag_name(); + inline ::std::string* release_tag_name(); + inline void set_allocated_tag_name(::std::string* tag_name); + + // required uint32 status = 4; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 4; + inline ::google::protobuf::uint32 status() const; + inline void set_status(::google::protobuf::uint32 value); + + // required int32 value = 5; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 5; + inline ::google::protobuf::int32 value() const; + inline void set_value(::google::protobuf::int32 value); + + // required uint64 time = 6; + inline bool has_time() const; + inline void clear_time(); + static const int kTimeFieldNumber = 6; + inline ::google::protobuf::uint64 time() const; + inline void set_time(::google::protobuf::uint64 value); + + // required int32 fault_num = 7; + inline bool has_fault_num() const; + inline void clear_fault_num(); + static const int kFaultNumFieldNumber = 7; + inline ::google::protobuf::int32 fault_num() const; + inline void set_fault_num(::google::protobuf::int32 value); + + // repeated int32 fault_type = 8; + inline int fault_type_size() const; + inline void clear_fault_type(); + static const int kFaultTypeFieldNumber = 8; + inline ::google::protobuf::int32 fault_type(int index) const; + inline void set_fault_type(int index, ::google::protobuf::int32 value); + inline void add_fault_type(::google::protobuf::int32 value); + inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + fault_type() const; + inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_fault_type(); + + // repeated float fault_value = 9; + inline int fault_value_size() const; + inline void clear_fault_value(); + static const int kFaultValueFieldNumber = 9; + inline float fault_value(int index) const; + inline void set_fault_value(int index, float value); + inline void add_fault_value(float value); + inline const ::google::protobuf::RepeatedField< float >& + fault_value() const; + inline ::google::protobuf::RepeatedField< float >* + mutable_fault_value(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolSoeEvent) + private: + inline void set_has_table_name(); + inline void clear_has_table_name(); + inline void set_has_col_name(); + inline void clear_has_col_name(); + inline void set_has_tag_name(); + inline void clear_has_tag_name(); + inline void set_has_status(); + inline void clear_has_status(); + inline void set_has_value(); + inline void clear_has_value(); + inline void set_has_time(); + inline void clear_has_time(); + inline void set_has_fault_num(); + inline void clear_has_fault_num(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* table_name_; + ::std::string* col_name_; + ::std::string* tag_name_; + ::google::protobuf::uint32 status_; + ::google::protobuf::int32 value_; + ::google::protobuf::uint64 time_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > fault_type_; + ::google::protobuf::RepeatedField< float > fault_value_; + ::google::protobuf::int32 fault_num_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolSoeEvent* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolSoeEventRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolSoeEventRepMsg(); + virtual ~FesDebugToolSoeEventRepMsg(); + + FesDebugToolSoeEventRepMsg(const FesDebugToolSoeEventRepMsg& from); + + inline FesDebugToolSoeEventRepMsg& operator=(const FesDebugToolSoeEventRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolSoeEventRepMsg& default_instance(); + + void Swap(FesDebugToolSoeEventRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolSoeEventRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolSoeEventRepMsg& from); + void MergeFrom(const FesDebugToolSoeEventRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 over_flow = 1; + inline bool has_over_flow() const; + inline void clear_over_flow(); + static const int kOverFlowFieldNumber = 1; + inline ::google::protobuf::int32 over_flow() const; + inline void set_over_flow(::google::protobuf::int32 value); + + // repeated .iot_idl.FesDebugToolSoeEvent event = 2; + inline int event_size() const; + inline void clear_event(); + static const int kEventFieldNumber = 2; + inline const ::iot_idl::FesDebugToolSoeEvent& event(int index) const; + inline ::iot_idl::FesDebugToolSoeEvent* mutable_event(int index); + inline ::iot_idl::FesDebugToolSoeEvent* add_event(); + inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolSoeEvent >& + event() const; + inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolSoeEvent >* + mutable_event(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolSoeEventRepMsg) + private: + inline void set_has_over_flow(); + inline void clear_has_over_flow(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolSoeEvent > event_; + ::google::protobuf::int32 over_flow_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolSoeEventRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolChanEvent : public ::google::protobuf::Message { + public: + FesDebugToolChanEvent(); + virtual ~FesDebugToolChanEvent(); + + FesDebugToolChanEvent(const FesDebugToolChanEvent& from); + + inline FesDebugToolChanEvent& operator=(const FesDebugToolChanEvent& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolChanEvent& default_instance(); + + void Swap(FesDebugToolChanEvent* other); + + // implements Message ---------------------------------------------- + + FesDebugToolChanEvent* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolChanEvent& from); + void MergeFrom(const FesDebugToolChanEvent& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string tag_name = 1; + inline bool has_tag_name() const; + inline void clear_tag_name(); + static const int kTagNameFieldNumber = 1; + inline const ::std::string& tag_name() const; + inline void set_tag_name(const ::std::string& value); + inline void set_tag_name(const char* value); + inline void set_tag_name(const char* value, size_t size); + inline ::std::string* mutable_tag_name(); + inline ::std::string* release_tag_name(); + inline void set_allocated_tag_name(::std::string* tag_name); + + // required uint32 status = 2; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 2; + inline ::google::protobuf::uint32 status() const; + inline void set_status(::google::protobuf::uint32 value); + + // required float err_rate = 3; + inline bool has_err_rate() const; + inline void clear_err_rate(); + static const int kErrRateFieldNumber = 3; + inline float err_rate() const; + inline void set_err_rate(float value); + + // required uint64 time = 4; + inline bool has_time() const; + inline void clear_time(); + static const int kTimeFieldNumber = 4; + inline ::google::protobuf::uint64 time() const; + inline void set_time(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolChanEvent) + private: + inline void set_has_tag_name(); + inline void clear_has_tag_name(); + inline void set_has_status(); + inline void clear_has_status(); + inline void set_has_err_rate(); + inline void clear_has_err_rate(); + inline void set_has_time(); + inline void clear_has_time(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* tag_name_; + ::google::protobuf::uint32 status_; + float err_rate_; + ::google::protobuf::uint64 time_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolChanEvent* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolChanEventRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolChanEventRepMsg(); + virtual ~FesDebugToolChanEventRepMsg(); + + FesDebugToolChanEventRepMsg(const FesDebugToolChanEventRepMsg& from); + + inline FesDebugToolChanEventRepMsg& operator=(const FesDebugToolChanEventRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolChanEventRepMsg& default_instance(); + + void Swap(FesDebugToolChanEventRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolChanEventRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolChanEventRepMsg& from); + void MergeFrom(const FesDebugToolChanEventRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 over_flow = 1; + inline bool has_over_flow() const; + inline void clear_over_flow(); + static const int kOverFlowFieldNumber = 1; + inline ::google::protobuf::int32 over_flow() const; + inline void set_over_flow(::google::protobuf::int32 value); + + // repeated .iot_idl.FesDebugToolChanEvent event = 2; + inline int event_size() const; + inline void clear_event(); + static const int kEventFieldNumber = 2; + inline const ::iot_idl::FesDebugToolChanEvent& event(int index) const; + inline ::iot_idl::FesDebugToolChanEvent* mutable_event(int index); + inline ::iot_idl::FesDebugToolChanEvent* add_event(); + inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanEvent >& + event() const; + inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanEvent >* + mutable_event(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolChanEventRepMsg) + private: + inline void set_has_over_flow(); + inline void clear_has_over_flow(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanEvent > event_; + ::google::protobuf::int32 over_flow_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolChanEventRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolChanMonCmdReqMsg : public ::google::protobuf::Message { + public: + FesDebugToolChanMonCmdReqMsg(); + virtual ~FesDebugToolChanMonCmdReqMsg(); + + FesDebugToolChanMonCmdReqMsg(const FesDebugToolChanMonCmdReqMsg& from); + + inline FesDebugToolChanMonCmdReqMsg& operator=(const FesDebugToolChanMonCmdReqMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolChanMonCmdReqMsg& default_instance(); + + void Swap(FesDebugToolChanMonCmdReqMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolChanMonCmdReqMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolChanMonCmdReqMsg& from); + void MergeFrom(const FesDebugToolChanMonCmdReqMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 chan_no = 1; + inline bool has_chan_no() const; + inline void clear_chan_no(); + static const int kChanNoFieldNumber = 1; + inline ::google::protobuf::int32 chan_no() const; + inline void set_chan_no(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolChanMonCmdReqMsg) + private: + inline void set_has_chan_no(); + inline void clear_has_chan_no(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 chan_no_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolChanMonCmdReqMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolChanMonCmdRepMsg : public ::google::protobuf::Message { + public: + FesDebugToolChanMonCmdRepMsg(); + virtual ~FesDebugToolChanMonCmdRepMsg(); + + FesDebugToolChanMonCmdRepMsg(const FesDebugToolChanMonCmdRepMsg& from); + + inline FesDebugToolChanMonCmdRepMsg& operator=(const FesDebugToolChanMonCmdRepMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolChanMonCmdRepMsg& default_instance(); + + void Swap(FesDebugToolChanMonCmdRepMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolChanMonCmdRepMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolChanMonCmdRepMsg& from); + void MergeFrom(const FesDebugToolChanMonCmdRepMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 chan_no = 1; + inline bool has_chan_no() const; + inline void clear_chan_no(); + static const int kChanNoFieldNumber = 1; + inline ::google::protobuf::int32 chan_no() const; + inline void set_chan_no(::google::protobuf::int32 value); + + // optional int32 rx_num = 2; + inline bool has_rx_num() const; + inline void clear_rx_num(); + static const int kRxNumFieldNumber = 2; + inline ::google::protobuf::int32 rx_num() const; + inline void set_rx_num(::google::protobuf::int32 value); + + // optional int32 tx_num = 3; + inline bool has_tx_num() const; + inline void clear_tx_num(); + static const int kTxNumFieldNumber = 3; + inline ::google::protobuf::int32 tx_num() const; + inline void set_tx_num(::google::protobuf::int32 value); + + // optional int32 err_num = 4; + inline bool has_err_num() const; + inline void clear_err_num(); + static const int kErrNumFieldNumber = 4; + inline ::google::protobuf::int32 err_num() const; + inline void set_err_num(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolChanMonCmdRepMsg) + private: + inline void set_has_chan_no(); + inline void clear_has_chan_no(); + inline void set_has_rx_num(); + inline void clear_has_rx_num(); + inline void set_has_tx_num(); + inline void clear_has_tx_num(); + inline void set_has_err_num(); + inline void clear_has_err_num(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 chan_no_; + ::google::protobuf::int32 rx_num_; + ::google::protobuf::int32 tx_num_; + ::google::protobuf::int32 err_num_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolChanMonCmdRepMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolChanMonFrame : public ::google::protobuf::Message { + public: + FesDebugToolChanMonFrame(); + virtual ~FesDebugToolChanMonFrame(); + + FesDebugToolChanMonFrame(const FesDebugToolChanMonFrame& from); + + inline FesDebugToolChanMonFrame& operator=(const FesDebugToolChanMonFrame& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolChanMonFrame& default_instance(); + + void Swap(FesDebugToolChanMonFrame* other); + + // implements Message ---------------------------------------------- + + FesDebugToolChanMonFrame* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolChanMonFrame& from); + void MergeFrom(const FesDebugToolChanMonFrame& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 frame_type = 1; + inline bool has_frame_type() const; + inline void clear_frame_type(); + static const int kFrameTypeFieldNumber = 1; + inline ::google::protobuf::int32 frame_type() const; + inline void set_frame_type(::google::protobuf::int32 value); + + // required int32 data_type = 2; + inline bool has_data_type() const; + inline void clear_data_type(); + static const int kDataTypeFieldNumber = 2; + inline ::google::protobuf::int32 data_type() const; + inline void set_data_type(::google::protobuf::int32 value); + + // required uint64 time = 3; + inline bool has_time() const; + inline void clear_time(); + static const int kTimeFieldNumber = 3; + inline ::google::protobuf::uint64 time() const; + inline void set_time(::google::protobuf::uint64 value); + + // required bytes data = 4; + inline bool has_data() const; + inline void clear_data(); + static const int kDataFieldNumber = 4; + inline const ::std::string& data() const; + inline void set_data(const ::std::string& value); + inline void set_data(const char* value); + inline void set_data(const void* value, size_t size); + inline ::std::string* mutable_data(); + inline ::std::string* release_data(); + inline void set_allocated_data(::std::string* data); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolChanMonFrame) + private: + inline void set_has_frame_type(); + inline void clear_has_frame_type(); + inline void set_has_data_type(); + inline void clear_has_data_type(); + inline void set_has_time(); + inline void clear_has_time(); + inline void set_has_data(); + inline void clear_has_data(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 frame_type_; + ::google::protobuf::int32 data_type_; + ::google::protobuf::uint64 time_; + ::std::string* data_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolChanMonFrame* default_instance_; +}; +// ------------------------------------------------------------------- + +class IDL_FILES_EXPORT FesDebugToolChanMonInfoMsg : public ::google::protobuf::Message { + public: + FesDebugToolChanMonInfoMsg(); + virtual ~FesDebugToolChanMonInfoMsg(); + + FesDebugToolChanMonInfoMsg(const FesDebugToolChanMonInfoMsg& from); + + inline FesDebugToolChanMonInfoMsg& operator=(const FesDebugToolChanMonInfoMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FesDebugToolChanMonInfoMsg& default_instance(); + + void Swap(FesDebugToolChanMonInfoMsg* other); + + // implements Message ---------------------------------------------- + + FesDebugToolChanMonInfoMsg* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FesDebugToolChanMonInfoMsg& from); + void MergeFrom(const FesDebugToolChanMonInfoMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 chan_no = 1; + inline bool has_chan_no() const; + inline void clear_chan_no(); + static const int kChanNoFieldNumber = 1; + inline ::google::protobuf::int32 chan_no() const; + inline void set_chan_no(::google::protobuf::int32 value); + + // required int32 rx_num = 2; + inline bool has_rx_num() const; + inline void clear_rx_num(); + static const int kRxNumFieldNumber = 2; + inline ::google::protobuf::int32 rx_num() const; + inline void set_rx_num(::google::protobuf::int32 value); + + // required int32 tx_num = 3; + inline bool has_tx_num() const; + inline void clear_tx_num(); + static const int kTxNumFieldNumber = 3; + inline ::google::protobuf::int32 tx_num() const; + inline void set_tx_num(::google::protobuf::int32 value); + + // required int32 err_num = 4; + inline bool has_err_num() const; + inline void clear_err_num(); + static const int kErrNumFieldNumber = 4; + inline ::google::protobuf::int32 err_num() const; + inline void set_err_num(::google::protobuf::int32 value); + + // required int32 over_flow = 5; + inline bool has_over_flow() const; + inline void clear_over_flow(); + static const int kOverFlowFieldNumber = 5; + inline ::google::protobuf::int32 over_flow() const; + inline void set_over_flow(::google::protobuf::int32 value); + + // repeated .iot_idl.FesDebugToolChanMonFrame frame = 6; + inline int frame_size() const; + inline void clear_frame(); + static const int kFrameFieldNumber = 6; + inline const ::iot_idl::FesDebugToolChanMonFrame& frame(int index) const; + inline ::iot_idl::FesDebugToolChanMonFrame* mutable_frame(int index); + inline ::iot_idl::FesDebugToolChanMonFrame* add_frame(); + inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanMonFrame >& + frame() const; + inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanMonFrame >* + mutable_frame(); + + // @@protoc_insertion_point(class_scope:iot_idl.FesDebugToolChanMonInfoMsg) + private: + inline void set_has_chan_no(); + inline void clear_has_chan_no(); + inline void set_has_rx_num(); + inline void clear_has_rx_num(); + inline void set_has_tx_num(); + inline void clear_has_tx_num(); + inline void set_has_err_num(); + inline void clear_has_err_num(); + inline void set_has_over_flow(); + inline void clear_has_over_flow(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 chan_no_; + ::google::protobuf::int32 rx_num_; + ::google::protobuf::int32 tx_num_; + ::google::protobuf::int32 err_num_; + ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanMonFrame > frame_; + ::google::protobuf::int32 over_flow_; + friend void IDL_FILES_EXPORT protobuf_AddDesc_FesDebugTool_2eproto(); + friend void protobuf_AssignDesc_FesDebugTool_2eproto(); + friend void protobuf_ShutdownFile_FesDebugTool_2eproto(); + + void InitAsDefaultInstance(); + static FesDebugToolChanMonInfoMsg* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// FesDebugToolReqMsg + +// required .iot_idl.enFesDebugMsgType type = 1; +inline bool FesDebugToolReqMsg::has_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolReqMsg::set_has_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolReqMsg::clear_has_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolReqMsg::clear_type() { + type_ = 0; + clear_has_type(); +} +inline ::iot_idl::enFesDebugMsgType FesDebugToolReqMsg::type() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolReqMsg.type) + return static_cast< ::iot_idl::enFesDebugMsgType >(type_); +} +inline void FesDebugToolReqMsg::set_type(::iot_idl::enFesDebugMsgType value) { + assert(::iot_idl::enFesDebugMsgType_IsValid(value)); + set_has_type(); + type_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolReqMsg.type) +} + +// optional string body = 2; +inline bool FesDebugToolReqMsg::has_body() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolReqMsg::set_has_body() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolReqMsg::clear_has_body() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolReqMsg::clear_body() { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_->clear(); + } + clear_has_body(); +} +inline const ::std::string& FesDebugToolReqMsg::body() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolReqMsg.body) + return *body_; +} +inline void FesDebugToolReqMsg::set_body(const ::std::string& value) { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + body_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolReqMsg.body) +} +inline void FesDebugToolReqMsg::set_body(const char* value) { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + body_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolReqMsg.body) +} +inline void FesDebugToolReqMsg::set_body(const char* value, size_t size) { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + body_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolReqMsg.body) +} +inline ::std::string* FesDebugToolReqMsg::mutable_body() { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolReqMsg.body) + return body_; +} +inline ::std::string* FesDebugToolReqMsg::release_body() { + clear_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = body_; + body_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolReqMsg::set_allocated_body(::std::string* body) { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete body_; + } + if (body) { + set_has_body(); + body_ = body; + } else { + clear_has_body(); + body_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolReqMsg.body) +} + +// ------------------------------------------------------------------- + +// FesDebugToolRepMsg + +// required bool success = 1; +inline bool FesDebugToolRepMsg::has_success() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolRepMsg::set_has_success() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolRepMsg::clear_has_success() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolRepMsg::clear_success() { + success_ = false; + clear_has_success(); +} +inline bool FesDebugToolRepMsg::success() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRepMsg.success) + return success_; +} +inline void FesDebugToolRepMsg::set_success(bool value) { + set_has_success(); + success_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRepMsg.success) +} + +// optional string err_msg = 2; +inline bool FesDebugToolRepMsg::has_err_msg() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolRepMsg::set_has_err_msg() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolRepMsg::clear_has_err_msg() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolRepMsg::clear_err_msg() { + if (err_msg_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + err_msg_->clear(); + } + clear_has_err_msg(); +} +inline const ::std::string& FesDebugToolRepMsg::err_msg() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRepMsg.err_msg) + return *err_msg_; +} +inline void FesDebugToolRepMsg::set_err_msg(const ::std::string& value) { + set_has_err_msg(); + if (err_msg_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + err_msg_ = new ::std::string; + } + err_msg_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRepMsg.err_msg) +} +inline void FesDebugToolRepMsg::set_err_msg(const char* value) { + set_has_err_msg(); + if (err_msg_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + err_msg_ = new ::std::string; + } + err_msg_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolRepMsg.err_msg) +} +inline void FesDebugToolRepMsg::set_err_msg(const char* value, size_t size) { + set_has_err_msg(); + if (err_msg_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + err_msg_ = new ::std::string; + } + err_msg_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolRepMsg.err_msg) +} +inline ::std::string* FesDebugToolRepMsg::mutable_err_msg() { + set_has_err_msg(); + if (err_msg_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + err_msg_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolRepMsg.err_msg) + return err_msg_; +} +inline ::std::string* FesDebugToolRepMsg::release_err_msg() { + clear_has_err_msg(); + if (err_msg_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = err_msg_; + err_msg_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolRepMsg::set_allocated_err_msg(::std::string* err_msg) { + if (err_msg_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete err_msg_; + } + if (err_msg) { + set_has_err_msg(); + err_msg_ = err_msg; + } else { + clear_has_err_msg(); + err_msg_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolRepMsg.err_msg) +} + +// required .iot_idl.enFesDebugMsgType type = 3; +inline bool FesDebugToolRepMsg::has_type() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolRepMsg::set_has_type() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolRepMsg::clear_has_type() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolRepMsg::clear_type() { + type_ = 0; + clear_has_type(); +} +inline ::iot_idl::enFesDebugMsgType FesDebugToolRepMsg::type() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRepMsg.type) + return static_cast< ::iot_idl::enFesDebugMsgType >(type_); +} +inline void FesDebugToolRepMsg::set_type(::iot_idl::enFesDebugMsgType value) { + assert(::iot_idl::enFesDebugMsgType_IsValid(value)); + set_has_type(); + type_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRepMsg.type) +} + +// optional string body = 4; +inline bool FesDebugToolRepMsg::has_body() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolRepMsg::set_has_body() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolRepMsg::clear_has_body() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolRepMsg::clear_body() { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_->clear(); + } + clear_has_body(); +} +inline const ::std::string& FesDebugToolRepMsg::body() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRepMsg.body) + return *body_; +} +inline void FesDebugToolRepMsg::set_body(const ::std::string& value) { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + body_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRepMsg.body) +} +inline void FesDebugToolRepMsg::set_body(const char* value) { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + body_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolRepMsg.body) +} +inline void FesDebugToolRepMsg::set_body(const char* value, size_t size) { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + body_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolRepMsg.body) +} +inline ::std::string* FesDebugToolRepMsg::mutable_body() { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolRepMsg.body) + return body_; +} +inline ::std::string* FesDebugToolRepMsg::release_body() { + clear_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = body_; + body_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolRepMsg::set_allocated_body(::std::string* body) { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete body_; + } + if (body) { + set_has_body(); + body_ = body; + } else { + clear_has_body(); + body_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolRepMsg.body) +} + +// ------------------------------------------------------------------- + +// FesDebugToolNetRoute + +// required string desc = 1; +inline bool FesDebugToolNetRoute::has_desc() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolNetRoute::set_has_desc() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolNetRoute::clear_has_desc() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolNetRoute::clear_desc() { + if (desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + desc_->clear(); + } + clear_has_desc(); +} +inline const ::std::string& FesDebugToolNetRoute::desc() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolNetRoute.desc) + return *desc_; +} +inline void FesDebugToolNetRoute::set_desc(const ::std::string& value) { + set_has_desc(); + if (desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + desc_ = new ::std::string; + } + desc_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolNetRoute.desc) +} +inline void FesDebugToolNetRoute::set_desc(const char* value) { + set_has_desc(); + if (desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + desc_ = new ::std::string; + } + desc_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolNetRoute.desc) +} +inline void FesDebugToolNetRoute::set_desc(const char* value, size_t size) { + set_has_desc(); + if (desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + desc_ = new ::std::string; + } + desc_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolNetRoute.desc) +} +inline ::std::string* FesDebugToolNetRoute::mutable_desc() { + set_has_desc(); + if (desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + desc_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolNetRoute.desc) + return desc_; +} +inline ::std::string* FesDebugToolNetRoute::release_desc() { + clear_has_desc(); + if (desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = desc_; + desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolNetRoute::set_allocated_desc(::std::string* desc) { + if (desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete desc_; + } + if (desc) { + set_has_desc(); + desc_ = desc; + } else { + clear_has_desc(); + desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolNetRoute.desc) +} + +// required int32 port_no = 2; +inline bool FesDebugToolNetRoute::has_port_no() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolNetRoute::set_has_port_no() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolNetRoute::clear_has_port_no() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolNetRoute::clear_port_no() { + port_no_ = 0; + clear_has_port_no(); +} +inline ::google::protobuf::int32 FesDebugToolNetRoute::port_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolNetRoute.port_no) + return port_no_; +} +inline void FesDebugToolNetRoute::set_port_no(::google::protobuf::int32 value) { + set_has_port_no(); + port_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolNetRoute.port_no) +} + +// ------------------------------------------------------------------- + +// FesDebugToolChanParam + +// required int32 chan_no = 1; +inline bool FesDebugToolChanParam::has_chan_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolChanParam::set_has_chan_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolChanParam::clear_has_chan_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolChanParam::clear_chan_no() { + chan_no_ = 0; + clear_has_chan_no(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::chan_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.chan_no) + return chan_no_; +} +inline void FesDebugToolChanParam::set_chan_no(::google::protobuf::int32 value) { + set_has_chan_no(); + chan_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.chan_no) +} + +// required string tag_name = 2; +inline bool FesDebugToolChanParam::has_tag_name() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolChanParam::set_has_tag_name() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolChanParam::clear_has_tag_name() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolChanParam::clear_tag_name() { + if (tag_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_->clear(); + } + clear_has_tag_name(); +} +inline const ::std::string& FesDebugToolChanParam::tag_name() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.tag_name) + return *tag_name_; +} +inline void FesDebugToolChanParam::set_tag_name(const ::std::string& value) { + set_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_ = new ::std::string; + } + tag_name_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.tag_name) +} +inline void FesDebugToolChanParam::set_tag_name(const char* value) { + set_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_ = new ::std::string; + } + tag_name_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolChanParam.tag_name) +} +inline void FesDebugToolChanParam::set_tag_name(const char* value, size_t size) { + set_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_ = new ::std::string; + } + tag_name_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolChanParam.tag_name) +} +inline ::std::string* FesDebugToolChanParam::mutable_tag_name() { + set_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolChanParam.tag_name) + return tag_name_; +} +inline ::std::string* FesDebugToolChanParam::release_tag_name() { + clear_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = tag_name_; + tag_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolChanParam::set_allocated_tag_name(::std::string* tag_name) { + if (tag_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete tag_name_; + } + if (tag_name) { + set_has_tag_name(); + tag_name_ = tag_name; + } else { + clear_has_tag_name(); + tag_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolChanParam.tag_name) +} + +// required string chan_name = 3; +inline bool FesDebugToolChanParam::has_chan_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolChanParam::set_has_chan_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolChanParam::clear_has_chan_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolChanParam::clear_chan_name() { + if (chan_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + chan_name_->clear(); + } + clear_has_chan_name(); +} +inline const ::std::string& FesDebugToolChanParam::chan_name() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.chan_name) + return *chan_name_; +} +inline void FesDebugToolChanParam::set_chan_name(const ::std::string& value) { + set_has_chan_name(); + if (chan_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + chan_name_ = new ::std::string; + } + chan_name_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.chan_name) +} +inline void FesDebugToolChanParam::set_chan_name(const char* value) { + set_has_chan_name(); + if (chan_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + chan_name_ = new ::std::string; + } + chan_name_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolChanParam.chan_name) +} +inline void FesDebugToolChanParam::set_chan_name(const char* value, size_t size) { + set_has_chan_name(); + if (chan_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + chan_name_ = new ::std::string; + } + chan_name_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolChanParam.chan_name) +} +inline ::std::string* FesDebugToolChanParam::mutable_chan_name() { + set_has_chan_name(); + if (chan_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + chan_name_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolChanParam.chan_name) + return chan_name_; +} +inline ::std::string* FesDebugToolChanParam::release_chan_name() { + clear_has_chan_name(); + if (chan_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = chan_name_; + chan_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolChanParam::set_allocated_chan_name(::std::string* chan_name) { + if (chan_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete chan_name_; + } + if (chan_name) { + set_has_chan_name(); + chan_name_ = chan_name; + } else { + clear_has_chan_name(); + chan_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolChanParam.chan_name) +} + +// required int32 used = 4; +inline bool FesDebugToolChanParam::has_used() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolChanParam::set_has_used() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolChanParam::clear_has_used() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolChanParam::clear_used() { + used_ = 0; + clear_has_used(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::used() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.used) + return used_; +} +inline void FesDebugToolChanParam::set_used(::google::protobuf::int32 value) { + set_has_used(); + used_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.used) +} + +// required int32 chan_status = 5; +inline bool FesDebugToolChanParam::has_chan_status() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FesDebugToolChanParam::set_has_chan_status() { + _has_bits_[0] |= 0x00000010u; +} +inline void FesDebugToolChanParam::clear_has_chan_status() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FesDebugToolChanParam::clear_chan_status() { + chan_status_ = 0; + clear_has_chan_status(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::chan_status() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.chan_status) + return chan_status_; +} +inline void FesDebugToolChanParam::set_chan_status(::google::protobuf::int32 value) { + set_has_chan_status(); + chan_status_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.chan_status) +} + +// required int32 comm_type = 6; +inline bool FesDebugToolChanParam::has_comm_type() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FesDebugToolChanParam::set_has_comm_type() { + _has_bits_[0] |= 0x00000020u; +} +inline void FesDebugToolChanParam::clear_has_comm_type() { + _has_bits_[0] &= ~0x00000020u; +} +inline void FesDebugToolChanParam::clear_comm_type() { + comm_type_ = 0; + clear_has_comm_type(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::comm_type() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.comm_type) + return comm_type_; +} +inline void FesDebugToolChanParam::set_comm_type(::google::protobuf::int32 value) { + set_has_comm_type(); + comm_type_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.comm_type) +} + +// required int32 chan_mode = 7; +inline bool FesDebugToolChanParam::has_chan_mode() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void FesDebugToolChanParam::set_has_chan_mode() { + _has_bits_[0] |= 0x00000040u; +} +inline void FesDebugToolChanParam::clear_has_chan_mode() { + _has_bits_[0] &= ~0x00000040u; +} +inline void FesDebugToolChanParam::clear_chan_mode() { + chan_mode_ = 0; + clear_has_chan_mode(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::chan_mode() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.chan_mode) + return chan_mode_; +} +inline void FesDebugToolChanParam::set_chan_mode(::google::protobuf::int32 value) { + set_has_chan_mode(); + chan_mode_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.chan_mode) +} + +// required int32 protocol_id = 8; +inline bool FesDebugToolChanParam::has_protocol_id() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void FesDebugToolChanParam::set_has_protocol_id() { + _has_bits_[0] |= 0x00000080u; +} +inline void FesDebugToolChanParam::clear_has_protocol_id() { + _has_bits_[0] &= ~0x00000080u; +} +inline void FesDebugToolChanParam::clear_protocol_id() { + protocol_id_ = 0; + clear_has_protocol_id(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::protocol_id() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.protocol_id) + return protocol_id_; +} +inline void FesDebugToolChanParam::set_protocol_id(::google::protobuf::int32 value) { + set_has_protocol_id(); + protocol_id_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.protocol_id) +} + +// repeated .iot_idl.FesDebugToolNetRoute net_route = 9; +inline int FesDebugToolChanParam::net_route_size() const { + return net_route_.size(); +} +inline void FesDebugToolChanParam::clear_net_route() { + net_route_.Clear(); +} +inline const ::iot_idl::FesDebugToolNetRoute& FesDebugToolChanParam::net_route(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.net_route) + return net_route_.Get(index); +} +inline ::iot_idl::FesDebugToolNetRoute* FesDebugToolChanParam::mutable_net_route(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolChanParam.net_route) + return net_route_.Mutable(index); +} +inline ::iot_idl::FesDebugToolNetRoute* FesDebugToolChanParam::add_net_route() { + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolChanParam.net_route) + return net_route_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolNetRoute >& +FesDebugToolChanParam::net_route() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolChanParam.net_route) + return net_route_; +} +inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolNetRoute >* +FesDebugToolChanParam::mutable_net_route() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolChanParam.net_route) + return &net_route_; +} + +// required int32 connect_wait_sec = 10; +inline bool FesDebugToolChanParam::has_connect_wait_sec() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void FesDebugToolChanParam::set_has_connect_wait_sec() { + _has_bits_[0] |= 0x00000200u; +} +inline void FesDebugToolChanParam::clear_has_connect_wait_sec() { + _has_bits_[0] &= ~0x00000200u; +} +inline void FesDebugToolChanParam::clear_connect_wait_sec() { + connect_wait_sec_ = 0; + clear_has_connect_wait_sec(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::connect_wait_sec() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.connect_wait_sec) + return connect_wait_sec_; +} +inline void FesDebugToolChanParam::set_connect_wait_sec(::google::protobuf::int32 value) { + set_has_connect_wait_sec(); + connect_wait_sec_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.connect_wait_sec) +} + +// required int32 connect_timeout = 11; +inline bool FesDebugToolChanParam::has_connect_timeout() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void FesDebugToolChanParam::set_has_connect_timeout() { + _has_bits_[0] |= 0x00000400u; +} +inline void FesDebugToolChanParam::clear_has_connect_timeout() { + _has_bits_[0] &= ~0x00000400u; +} +inline void FesDebugToolChanParam::clear_connect_timeout() { + connect_timeout_ = 0; + clear_has_connect_timeout(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::connect_timeout() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.connect_timeout) + return connect_timeout_; +} +inline void FesDebugToolChanParam::set_connect_timeout(::google::protobuf::int32 value) { + set_has_connect_timeout(); + connect_timeout_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.connect_timeout) +} + +// required int32 retry_times = 12; +inline bool FesDebugToolChanParam::has_retry_times() const { + return (_has_bits_[0] & 0x00000800u) != 0; +} +inline void FesDebugToolChanParam::set_has_retry_times() { + _has_bits_[0] |= 0x00000800u; +} +inline void FesDebugToolChanParam::clear_has_retry_times() { + _has_bits_[0] &= ~0x00000800u; +} +inline void FesDebugToolChanParam::clear_retry_times() { + retry_times_ = 0; + clear_has_retry_times(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::retry_times() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.retry_times) + return retry_times_; +} +inline void FesDebugToolChanParam::set_retry_times(::google::protobuf::int32 value) { + set_has_retry_times(); + retry_times_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.retry_times) +} + +// required int32 recv_timeout = 13; +inline bool FesDebugToolChanParam::has_recv_timeout() const { + return (_has_bits_[0] & 0x00001000u) != 0; +} +inline void FesDebugToolChanParam::set_has_recv_timeout() { + _has_bits_[0] |= 0x00001000u; +} +inline void FesDebugToolChanParam::clear_has_recv_timeout() { + _has_bits_[0] &= ~0x00001000u; +} +inline void FesDebugToolChanParam::clear_recv_timeout() { + recv_timeout_ = 0; + clear_has_recv_timeout(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::recv_timeout() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.recv_timeout) + return recv_timeout_; +} +inline void FesDebugToolChanParam::set_recv_timeout(::google::protobuf::int32 value) { + set_has_recv_timeout(); + recv_timeout_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.recv_timeout) +} + +// required int32 resp_timeout = 14; +inline bool FesDebugToolChanParam::has_resp_timeout() const { + return (_has_bits_[0] & 0x00002000u) != 0; +} +inline void FesDebugToolChanParam::set_has_resp_timeout() { + _has_bits_[0] |= 0x00002000u; +} +inline void FesDebugToolChanParam::clear_has_resp_timeout() { + _has_bits_[0] &= ~0x00002000u; +} +inline void FesDebugToolChanParam::clear_resp_timeout() { + resp_timeout_ = 0; + clear_has_resp_timeout(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::resp_timeout() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.resp_timeout) + return resp_timeout_; +} +inline void FesDebugToolChanParam::set_resp_timeout(::google::protobuf::int32 value) { + set_has_resp_timeout(); + resp_timeout_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.resp_timeout) +} + +// required int32 max_rx_size = 15; +inline bool FesDebugToolChanParam::has_max_rx_size() const { + return (_has_bits_[0] & 0x00004000u) != 0; +} +inline void FesDebugToolChanParam::set_has_max_rx_size() { + _has_bits_[0] |= 0x00004000u; +} +inline void FesDebugToolChanParam::clear_has_max_rx_size() { + _has_bits_[0] &= ~0x00004000u; +} +inline void FesDebugToolChanParam::clear_max_rx_size() { + max_rx_size_ = 0; + clear_has_max_rx_size(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::max_rx_size() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.max_rx_size) + return max_rx_size_; +} +inline void FesDebugToolChanParam::set_max_rx_size(::google::protobuf::int32 value) { + set_has_max_rx_size(); + max_rx_size_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.max_rx_size) +} + +// required int32 max_tx_size = 16; +inline bool FesDebugToolChanParam::has_max_tx_size() const { + return (_has_bits_[0] & 0x00008000u) != 0; +} +inline void FesDebugToolChanParam::set_has_max_tx_size() { + _has_bits_[0] |= 0x00008000u; +} +inline void FesDebugToolChanParam::clear_has_max_tx_size() { + _has_bits_[0] &= ~0x00008000u; +} +inline void FesDebugToolChanParam::clear_max_tx_size() { + max_tx_size_ = 0; + clear_has_max_tx_size(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::max_tx_size() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.max_tx_size) + return max_tx_size_; +} +inline void FesDebugToolChanParam::set_max_tx_size(::google::protobuf::int32 value) { + set_has_max_tx_size(); + max_tx_size_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.max_tx_size) +} + +// required float err_rate_limit = 17; +inline bool FesDebugToolChanParam::has_err_rate_limit() const { + return (_has_bits_[0] & 0x00010000u) != 0; +} +inline void FesDebugToolChanParam::set_has_err_rate_limit() { + _has_bits_[0] |= 0x00010000u; +} +inline void FesDebugToolChanParam::clear_has_err_rate_limit() { + _has_bits_[0] &= ~0x00010000u; +} +inline void FesDebugToolChanParam::clear_err_rate_limit() { + err_rate_limit_ = 0; + clear_has_err_rate_limit(); +} +inline float FesDebugToolChanParam::err_rate_limit() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.err_rate_limit) + return err_rate_limit_; +} +inline void FesDebugToolChanParam::set_err_rate_limit(float value) { + set_has_err_rate_limit(); + err_rate_limit_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.err_rate_limit) +} + +// repeated int32 backup_chan_no = 18; +inline int FesDebugToolChanParam::backup_chan_no_size() const { + return backup_chan_no_.size(); +} +inline void FesDebugToolChanParam::clear_backup_chan_no() { + backup_chan_no_.Clear(); +} +inline ::google::protobuf::int32 FesDebugToolChanParam::backup_chan_no(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParam.backup_chan_no) + return backup_chan_no_.Get(index); +} +inline void FesDebugToolChanParam::set_backup_chan_no(int index, ::google::protobuf::int32 value) { + backup_chan_no_.Set(index, value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanParam.backup_chan_no) +} +inline void FesDebugToolChanParam::add_backup_chan_no(::google::protobuf::int32 value) { + backup_chan_no_.Add(value); + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolChanParam.backup_chan_no) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +FesDebugToolChanParam::backup_chan_no() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolChanParam.backup_chan_no) + return backup_chan_no_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +FesDebugToolChanParam::mutable_backup_chan_no() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolChanParam.backup_chan_no) + return &backup_chan_no_; +} + +// ------------------------------------------------------------------- + +// FesDebugToolChanParamRepMsg + +// repeated .iot_idl.FesDebugToolChanParam chan_param = 1; +inline int FesDebugToolChanParamRepMsg::chan_param_size() const { + return chan_param_.size(); +} +inline void FesDebugToolChanParamRepMsg::clear_chan_param() { + chan_param_.Clear(); +} +inline const ::iot_idl::FesDebugToolChanParam& FesDebugToolChanParamRepMsg::chan_param(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanParamRepMsg.chan_param) + return chan_param_.Get(index); +} +inline ::iot_idl::FesDebugToolChanParam* FesDebugToolChanParamRepMsg::mutable_chan_param(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolChanParamRepMsg.chan_param) + return chan_param_.Mutable(index); +} +inline ::iot_idl::FesDebugToolChanParam* FesDebugToolChanParamRepMsg::add_chan_param() { + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolChanParamRepMsg.chan_param) + return chan_param_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanParam >& +FesDebugToolChanParamRepMsg::chan_param() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolChanParamRepMsg.chan_param) + return chan_param_; +} +inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanParam >* +FesDebugToolChanParamRepMsg::mutable_chan_param() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolChanParamRepMsg.chan_param) + return &chan_param_; +} + +// ------------------------------------------------------------------- + +// FesDebugToolRtuParam + +// required int32 rtu_no = 1; +inline bool FesDebugToolRtuParam::has_rtu_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolRtuParam::set_has_rtu_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolRtuParam::clear_has_rtu_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolRtuParam::clear_rtu_no() { + rtu_no_ = 0; + clear_has_rtu_no(); +} +inline ::google::protobuf::int32 FesDebugToolRtuParam::rtu_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuParam.rtu_no) + return rtu_no_; +} +inline void FesDebugToolRtuParam::set_rtu_no(::google::protobuf::int32 value) { + set_has_rtu_no(); + rtu_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuParam.rtu_no) +} + +// required string rtu_desc = 2; +inline bool FesDebugToolRtuParam::has_rtu_desc() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolRtuParam::set_has_rtu_desc() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolRtuParam::clear_has_rtu_desc() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolRtuParam::clear_rtu_desc() { + if (rtu_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_desc_->clear(); + } + clear_has_rtu_desc(); +} +inline const ::std::string& FesDebugToolRtuParam::rtu_desc() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuParam.rtu_desc) + return *rtu_desc_; +} +inline void FesDebugToolRtuParam::set_rtu_desc(const ::std::string& value) { + set_has_rtu_desc(); + if (rtu_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_desc_ = new ::std::string; + } + rtu_desc_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuParam.rtu_desc) +} +inline void FesDebugToolRtuParam::set_rtu_desc(const char* value) { + set_has_rtu_desc(); + if (rtu_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_desc_ = new ::std::string; + } + rtu_desc_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolRtuParam.rtu_desc) +} +inline void FesDebugToolRtuParam::set_rtu_desc(const char* value, size_t size) { + set_has_rtu_desc(); + if (rtu_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_desc_ = new ::std::string; + } + rtu_desc_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolRtuParam.rtu_desc) +} +inline ::std::string* FesDebugToolRtuParam::mutable_rtu_desc() { + set_has_rtu_desc(); + if (rtu_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_desc_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolRtuParam.rtu_desc) + return rtu_desc_; +} +inline ::std::string* FesDebugToolRtuParam::release_rtu_desc() { + clear_has_rtu_desc(); + if (rtu_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = rtu_desc_; + rtu_desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolRtuParam::set_allocated_rtu_desc(::std::string* rtu_desc) { + if (rtu_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete rtu_desc_; + } + if (rtu_desc) { + set_has_rtu_desc(); + rtu_desc_ = rtu_desc; + } else { + clear_has_rtu_desc(); + rtu_desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolRtuParam.rtu_desc) +} + +// required string rtu_name = 3; +inline bool FesDebugToolRtuParam::has_rtu_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolRtuParam::set_has_rtu_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolRtuParam::clear_has_rtu_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolRtuParam::clear_rtu_name() { + if (rtu_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_name_->clear(); + } + clear_has_rtu_name(); +} +inline const ::std::string& FesDebugToolRtuParam::rtu_name() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuParam.rtu_name) + return *rtu_name_; +} +inline void FesDebugToolRtuParam::set_rtu_name(const ::std::string& value) { + set_has_rtu_name(); + if (rtu_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_name_ = new ::std::string; + } + rtu_name_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuParam.rtu_name) +} +inline void FesDebugToolRtuParam::set_rtu_name(const char* value) { + set_has_rtu_name(); + if (rtu_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_name_ = new ::std::string; + } + rtu_name_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolRtuParam.rtu_name) +} +inline void FesDebugToolRtuParam::set_rtu_name(const char* value, size_t size) { + set_has_rtu_name(); + if (rtu_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_name_ = new ::std::string; + } + rtu_name_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolRtuParam.rtu_name) +} +inline ::std::string* FesDebugToolRtuParam::mutable_rtu_name() { + set_has_rtu_name(); + if (rtu_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_name_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolRtuParam.rtu_name) + return rtu_name_; +} +inline ::std::string* FesDebugToolRtuParam::release_rtu_name() { + clear_has_rtu_name(); + if (rtu_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = rtu_name_; + rtu_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolRtuParam::set_allocated_rtu_name(::std::string* rtu_name) { + if (rtu_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete rtu_name_; + } + if (rtu_name) { + set_has_rtu_name(); + rtu_name_ = rtu_name; + } else { + clear_has_rtu_name(); + rtu_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolRtuParam.rtu_name) +} + +// required int32 used = 4; +inline bool FesDebugToolRtuParam::has_used() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolRtuParam::set_has_used() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolRtuParam::clear_has_used() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolRtuParam::clear_used() { + used_ = 0; + clear_has_used(); +} +inline ::google::protobuf::int32 FesDebugToolRtuParam::used() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuParam.used) + return used_; +} +inline void FesDebugToolRtuParam::set_used(::google::protobuf::int32 value) { + set_has_used(); + used_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuParam.used) +} + +// required int32 rtu_status = 5; +inline bool FesDebugToolRtuParam::has_rtu_status() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FesDebugToolRtuParam::set_has_rtu_status() { + _has_bits_[0] |= 0x00000010u; +} +inline void FesDebugToolRtuParam::clear_has_rtu_status() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FesDebugToolRtuParam::clear_rtu_status() { + rtu_status_ = 0; + clear_has_rtu_status(); +} +inline ::google::protobuf::int32 FesDebugToolRtuParam::rtu_status() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuParam.rtu_status) + return rtu_status_; +} +inline void FesDebugToolRtuParam::set_rtu_status(::google::protobuf::int32 value) { + set_has_rtu_status(); + rtu_status_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuParam.rtu_status) +} + +// required int32 rtu_addr = 6; +inline bool FesDebugToolRtuParam::has_rtu_addr() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FesDebugToolRtuParam::set_has_rtu_addr() { + _has_bits_[0] |= 0x00000020u; +} +inline void FesDebugToolRtuParam::clear_has_rtu_addr() { + _has_bits_[0] &= ~0x00000020u; +} +inline void FesDebugToolRtuParam::clear_rtu_addr() { + rtu_addr_ = 0; + clear_has_rtu_addr(); +} +inline ::google::protobuf::int32 FesDebugToolRtuParam::rtu_addr() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuParam.rtu_addr) + return rtu_addr_; +} +inline void FesDebugToolRtuParam::set_rtu_addr(::google::protobuf::int32 value) { + set_has_rtu_addr(); + rtu_addr_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuParam.rtu_addr) +} + +// required int32 chan_no = 7; +inline bool FesDebugToolRtuParam::has_chan_no() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void FesDebugToolRtuParam::set_has_chan_no() { + _has_bits_[0] |= 0x00000040u; +} +inline void FesDebugToolRtuParam::clear_has_chan_no() { + _has_bits_[0] &= ~0x00000040u; +} +inline void FesDebugToolRtuParam::clear_chan_no() { + chan_no_ = 0; + clear_has_chan_no(); +} +inline ::google::protobuf::int32 FesDebugToolRtuParam::chan_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuParam.chan_no) + return chan_no_; +} +inline void FesDebugToolRtuParam::set_chan_no(::google::protobuf::int32 value) { + set_has_chan_no(); + chan_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuParam.chan_no) +} + +// required int32 max_ai_num = 8; +inline bool FesDebugToolRtuParam::has_max_ai_num() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void FesDebugToolRtuParam::set_has_max_ai_num() { + _has_bits_[0] |= 0x00000080u; +} +inline void FesDebugToolRtuParam::clear_has_max_ai_num() { + _has_bits_[0] &= ~0x00000080u; +} +inline void FesDebugToolRtuParam::clear_max_ai_num() { + max_ai_num_ = 0; + clear_has_max_ai_num(); +} +inline ::google::protobuf::int32 FesDebugToolRtuParam::max_ai_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuParam.max_ai_num) + return max_ai_num_; +} +inline void FesDebugToolRtuParam::set_max_ai_num(::google::protobuf::int32 value) { + set_has_max_ai_num(); + max_ai_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuParam.max_ai_num) +} + +// required int32 max_di_num = 9; +inline bool FesDebugToolRtuParam::has_max_di_num() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void FesDebugToolRtuParam::set_has_max_di_num() { + _has_bits_[0] |= 0x00000100u; +} +inline void FesDebugToolRtuParam::clear_has_max_di_num() { + _has_bits_[0] &= ~0x00000100u; +} +inline void FesDebugToolRtuParam::clear_max_di_num() { + max_di_num_ = 0; + clear_has_max_di_num(); +} +inline ::google::protobuf::int32 FesDebugToolRtuParam::max_di_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuParam.max_di_num) + return max_di_num_; +} +inline void FesDebugToolRtuParam::set_max_di_num(::google::protobuf::int32 value) { + set_has_max_di_num(); + max_di_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuParam.max_di_num) +} + +// required int32 max_acc_num = 10; +inline bool FesDebugToolRtuParam::has_max_acc_num() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void FesDebugToolRtuParam::set_has_max_acc_num() { + _has_bits_[0] |= 0x00000200u; +} +inline void FesDebugToolRtuParam::clear_has_max_acc_num() { + _has_bits_[0] &= ~0x00000200u; +} +inline void FesDebugToolRtuParam::clear_max_acc_num() { + max_acc_num_ = 0; + clear_has_max_acc_num(); +} +inline ::google::protobuf::int32 FesDebugToolRtuParam::max_acc_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuParam.max_acc_num) + return max_acc_num_; +} +inline void FesDebugToolRtuParam::set_max_acc_num(::google::protobuf::int32 value) { + set_has_max_acc_num(); + max_acc_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuParam.max_acc_num) +} + +// required int32 recv_fail_limit = 11; +inline bool FesDebugToolRtuParam::has_recv_fail_limit() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void FesDebugToolRtuParam::set_has_recv_fail_limit() { + _has_bits_[0] |= 0x00000400u; +} +inline void FesDebugToolRtuParam::clear_has_recv_fail_limit() { + _has_bits_[0] &= ~0x00000400u; +} +inline void FesDebugToolRtuParam::clear_recv_fail_limit() { + recv_fail_limit_ = 0; + clear_has_recv_fail_limit(); +} +inline ::google::protobuf::int32 FesDebugToolRtuParam::recv_fail_limit() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuParam.recv_fail_limit) + return recv_fail_limit_; +} +inline void FesDebugToolRtuParam::set_recv_fail_limit(::google::protobuf::int32 value) { + set_has_recv_fail_limit(); + recv_fail_limit_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuParam.recv_fail_limit) +} + +// ------------------------------------------------------------------- + +// FesDebugToolRtuParamRepMsg + +// repeated .iot_idl.FesDebugToolRtuParam rtu_param = 1; +inline int FesDebugToolRtuParamRepMsg::rtu_param_size() const { + return rtu_param_.size(); +} +inline void FesDebugToolRtuParamRepMsg::clear_rtu_param() { + rtu_param_.Clear(); +} +inline const ::iot_idl::FesDebugToolRtuParam& FesDebugToolRtuParamRepMsg::rtu_param(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuParamRepMsg.rtu_param) + return rtu_param_.Get(index); +} +inline ::iot_idl::FesDebugToolRtuParam* FesDebugToolRtuParamRepMsg::mutable_rtu_param(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolRtuParamRepMsg.rtu_param) + return rtu_param_.Mutable(index); +} +inline ::iot_idl::FesDebugToolRtuParam* FesDebugToolRtuParamRepMsg::add_rtu_param() { + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolRtuParamRepMsg.rtu_param) + return rtu_param_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolRtuParam >& +FesDebugToolRtuParamRepMsg::rtu_param() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolRtuParamRepMsg.rtu_param) + return rtu_param_; +} +inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolRtuParam >* +FesDebugToolRtuParamRepMsg::mutable_rtu_param() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolRtuParamRepMsg.rtu_param) + return &rtu_param_; +} + +// ------------------------------------------------------------------- + +// FesDebugToolRtuInfo + +// required int32 rtu_no = 1; +inline bool FesDebugToolRtuInfo::has_rtu_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolRtuInfo::set_has_rtu_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolRtuInfo::clear_has_rtu_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolRtuInfo::clear_rtu_no() { + rtu_no_ = 0; + clear_has_rtu_no(); +} +inline ::google::protobuf::int32 FesDebugToolRtuInfo::rtu_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuInfo.rtu_no) + return rtu_no_; +} +inline void FesDebugToolRtuInfo::set_rtu_no(::google::protobuf::int32 value) { + set_has_rtu_no(); + rtu_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuInfo.rtu_no) +} + +// required int32 used = 2; +inline bool FesDebugToolRtuInfo::has_used() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolRtuInfo::set_has_used() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolRtuInfo::clear_has_used() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolRtuInfo::clear_used() { + used_ = 0; + clear_has_used(); +} +inline ::google::protobuf::int32 FesDebugToolRtuInfo::used() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuInfo.used) + return used_; +} +inline void FesDebugToolRtuInfo::set_used(::google::protobuf::int32 value) { + set_has_used(); + used_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuInfo.used) +} + +// required string rtu_desc = 3; +inline bool FesDebugToolRtuInfo::has_rtu_desc() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolRtuInfo::set_has_rtu_desc() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolRtuInfo::clear_has_rtu_desc() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolRtuInfo::clear_rtu_desc() { + if (rtu_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_desc_->clear(); + } + clear_has_rtu_desc(); +} +inline const ::std::string& FesDebugToolRtuInfo::rtu_desc() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuInfo.rtu_desc) + return *rtu_desc_; +} +inline void FesDebugToolRtuInfo::set_rtu_desc(const ::std::string& value) { + set_has_rtu_desc(); + if (rtu_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_desc_ = new ::std::string; + } + rtu_desc_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRtuInfo.rtu_desc) +} +inline void FesDebugToolRtuInfo::set_rtu_desc(const char* value) { + set_has_rtu_desc(); + if (rtu_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_desc_ = new ::std::string; + } + rtu_desc_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolRtuInfo.rtu_desc) +} +inline void FesDebugToolRtuInfo::set_rtu_desc(const char* value, size_t size) { + set_has_rtu_desc(); + if (rtu_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_desc_ = new ::std::string; + } + rtu_desc_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolRtuInfo.rtu_desc) +} +inline ::std::string* FesDebugToolRtuInfo::mutable_rtu_desc() { + set_has_rtu_desc(); + if (rtu_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + rtu_desc_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolRtuInfo.rtu_desc) + return rtu_desc_; +} +inline ::std::string* FesDebugToolRtuInfo::release_rtu_desc() { + clear_has_rtu_desc(); + if (rtu_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = rtu_desc_; + rtu_desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolRtuInfo::set_allocated_rtu_desc(::std::string* rtu_desc) { + if (rtu_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete rtu_desc_; + } + if (rtu_desc) { + set_has_rtu_desc(); + rtu_desc_ = rtu_desc; + } else { + clear_has_rtu_desc(); + rtu_desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolRtuInfo.rtu_desc) +} + +// ------------------------------------------------------------------- + +// FesDebugToolRtuInfoRepMsg + +// repeated .iot_idl.FesDebugToolRtuInfo rtu_info = 1; +inline int FesDebugToolRtuInfoRepMsg::rtu_info_size() const { + return rtu_info_.size(); +} +inline void FesDebugToolRtuInfoRepMsg::clear_rtu_info() { + rtu_info_.Clear(); +} +inline const ::iot_idl::FesDebugToolRtuInfo& FesDebugToolRtuInfoRepMsg::rtu_info(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRtuInfoRepMsg.rtu_info) + return rtu_info_.Get(index); +} +inline ::iot_idl::FesDebugToolRtuInfo* FesDebugToolRtuInfoRepMsg::mutable_rtu_info(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolRtuInfoRepMsg.rtu_info) + return rtu_info_.Mutable(index); +} +inline ::iot_idl::FesDebugToolRtuInfo* FesDebugToolRtuInfoRepMsg::add_rtu_info() { + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolRtuInfoRepMsg.rtu_info) + return rtu_info_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolRtuInfo >& +FesDebugToolRtuInfoRepMsg::rtu_info() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolRtuInfoRepMsg.rtu_info) + return rtu_info_; +} +inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolRtuInfo >* +FesDebugToolRtuInfoRepMsg::mutable_rtu_info() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolRtuInfoRepMsg.rtu_info) + return &rtu_info_; +} + +// ------------------------------------------------------------------- + +// FesDebugToolPntParamReqMsg + +// required int32 rtu_no = 1; +inline bool FesDebugToolPntParamReqMsg::has_rtu_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolPntParamReqMsg::set_has_rtu_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolPntParamReqMsg::clear_has_rtu_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolPntParamReqMsg::clear_rtu_no() { + rtu_no_ = 0; + clear_has_rtu_no(); +} +inline ::google::protobuf::int32 FesDebugToolPntParamReqMsg::rtu_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntParamReqMsg.rtu_no) + return rtu_no_; +} +inline void FesDebugToolPntParamReqMsg::set_rtu_no(::google::protobuf::int32 value) { + set_has_rtu_no(); + rtu_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolPntParamReqMsg.rtu_no) +} + +// ------------------------------------------------------------------- + +// FesDebugToolPntParam + +// required int32 pnt_no = 1; +inline bool FesDebugToolPntParam::has_pnt_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolPntParam::set_has_pnt_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolPntParam::clear_has_pnt_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolPntParam::clear_pnt_no() { + pnt_no_ = 0; + clear_has_pnt_no(); +} +inline ::google::protobuf::int32 FesDebugToolPntParam::pnt_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntParam.pnt_no) + return pnt_no_; +} +inline void FesDebugToolPntParam::set_pnt_no(::google::protobuf::int32 value) { + set_has_pnt_no(); + pnt_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolPntParam.pnt_no) +} + +// required int32 used = 2; +inline bool FesDebugToolPntParam::has_used() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolPntParam::set_has_used() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolPntParam::clear_has_used() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolPntParam::clear_used() { + used_ = 0; + clear_has_used(); +} +inline ::google::protobuf::int32 FesDebugToolPntParam::used() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntParam.used) + return used_; +} +inline void FesDebugToolPntParam::set_used(::google::protobuf::int32 value) { + set_has_used(); + used_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolPntParam.used) +} + +// required string pnt_desc = 3; +inline bool FesDebugToolPntParam::has_pnt_desc() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolPntParam::set_has_pnt_desc() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolPntParam::clear_has_pnt_desc() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolPntParam::clear_pnt_desc() { + if (pnt_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + pnt_desc_->clear(); + } + clear_has_pnt_desc(); +} +inline const ::std::string& FesDebugToolPntParam::pnt_desc() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntParam.pnt_desc) + return *pnt_desc_; +} +inline void FesDebugToolPntParam::set_pnt_desc(const ::std::string& value) { + set_has_pnt_desc(); + if (pnt_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + pnt_desc_ = new ::std::string; + } + pnt_desc_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolPntParam.pnt_desc) +} +inline void FesDebugToolPntParam::set_pnt_desc(const char* value) { + set_has_pnt_desc(); + if (pnt_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + pnt_desc_ = new ::std::string; + } + pnt_desc_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolPntParam.pnt_desc) +} +inline void FesDebugToolPntParam::set_pnt_desc(const char* value, size_t size) { + set_has_pnt_desc(); + if (pnt_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + pnt_desc_ = new ::std::string; + } + pnt_desc_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolPntParam.pnt_desc) +} +inline ::std::string* FesDebugToolPntParam::mutable_pnt_desc() { + set_has_pnt_desc(); + if (pnt_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + pnt_desc_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolPntParam.pnt_desc) + return pnt_desc_; +} +inline ::std::string* FesDebugToolPntParam::release_pnt_desc() { + clear_has_pnt_desc(); + if (pnt_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = pnt_desc_; + pnt_desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolPntParam::set_allocated_pnt_desc(::std::string* pnt_desc) { + if (pnt_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete pnt_desc_; + } + if (pnt_desc) { + set_has_pnt_desc(); + pnt_desc_ = pnt_desc; + } else { + clear_has_pnt_desc(); + pnt_desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolPntParam.pnt_desc) +} + +// ------------------------------------------------------------------- + +// FesDebugToolPntParamRepMsg + +// required int32 rtu_no = 1; +inline bool FesDebugToolPntParamRepMsg::has_rtu_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolPntParamRepMsg::set_has_rtu_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolPntParamRepMsg::clear_has_rtu_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolPntParamRepMsg::clear_rtu_no() { + rtu_no_ = 0; + clear_has_rtu_no(); +} +inline ::google::protobuf::int32 FesDebugToolPntParamRepMsg::rtu_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntParamRepMsg.rtu_no) + return rtu_no_; +} +inline void FesDebugToolPntParamRepMsg::set_rtu_no(::google::protobuf::int32 value) { + set_has_rtu_no(); + rtu_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolPntParamRepMsg.rtu_no) +} + +// required int32 max_pnt_num = 2; +inline bool FesDebugToolPntParamRepMsg::has_max_pnt_num() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolPntParamRepMsg::set_has_max_pnt_num() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolPntParamRepMsg::clear_has_max_pnt_num() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolPntParamRepMsg::clear_max_pnt_num() { + max_pnt_num_ = 0; + clear_has_max_pnt_num(); +} +inline ::google::protobuf::int32 FesDebugToolPntParamRepMsg::max_pnt_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntParamRepMsg.max_pnt_num) + return max_pnt_num_; +} +inline void FesDebugToolPntParamRepMsg::set_max_pnt_num(::google::protobuf::int32 value) { + set_has_max_pnt_num(); + max_pnt_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolPntParamRepMsg.max_pnt_num) +} + +// repeated .iot_idl.FesDebugToolPntParam pnt_param = 3; +inline int FesDebugToolPntParamRepMsg::pnt_param_size() const { + return pnt_param_.size(); +} +inline void FesDebugToolPntParamRepMsg::clear_pnt_param() { + pnt_param_.Clear(); +} +inline const ::iot_idl::FesDebugToolPntParam& FesDebugToolPntParamRepMsg::pnt_param(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntParamRepMsg.pnt_param) + return pnt_param_.Get(index); +} +inline ::iot_idl::FesDebugToolPntParam* FesDebugToolPntParamRepMsg::mutable_pnt_param(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolPntParamRepMsg.pnt_param) + return pnt_param_.Mutable(index); +} +inline ::iot_idl::FesDebugToolPntParam* FesDebugToolPntParamRepMsg::add_pnt_param() { + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolPntParamRepMsg.pnt_param) + return pnt_param_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolPntParam >& +FesDebugToolPntParamRepMsg::pnt_param() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolPntParamRepMsg.pnt_param) + return pnt_param_; +} +inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolPntParam >* +FesDebugToolPntParamRepMsg::mutable_pnt_param() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolPntParamRepMsg.pnt_param) + return &pnt_param_; +} + +// ------------------------------------------------------------------- + +// FesDebugToolPntValueReqMsg + +// required int32 rtu_no = 1; +inline bool FesDebugToolPntValueReqMsg::has_rtu_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolPntValueReqMsg::set_has_rtu_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolPntValueReqMsg::clear_has_rtu_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolPntValueReqMsg::clear_rtu_no() { + rtu_no_ = 0; + clear_has_rtu_no(); +} +inline ::google::protobuf::int32 FesDebugToolPntValueReqMsg::rtu_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntValueReqMsg.rtu_no) + return rtu_no_; +} +inline void FesDebugToolPntValueReqMsg::set_rtu_no(::google::protobuf::int32 value) { + set_has_rtu_no(); + rtu_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolPntValueReqMsg.rtu_no) +} + +// required int32 start_index = 2; +inline bool FesDebugToolPntValueReqMsg::has_start_index() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolPntValueReqMsg::set_has_start_index() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolPntValueReqMsg::clear_has_start_index() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolPntValueReqMsg::clear_start_index() { + start_index_ = 0; + clear_has_start_index(); +} +inline ::google::protobuf::int32 FesDebugToolPntValueReqMsg::start_index() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntValueReqMsg.start_index) + return start_index_; +} +inline void FesDebugToolPntValueReqMsg::set_start_index(::google::protobuf::int32 value) { + set_has_start_index(); + start_index_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolPntValueReqMsg.start_index) +} + +// required int32 end_index = 3; +inline bool FesDebugToolPntValueReqMsg::has_end_index() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolPntValueReqMsg::set_has_end_index() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolPntValueReqMsg::clear_has_end_index() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolPntValueReqMsg::clear_end_index() { + end_index_ = 0; + clear_has_end_index(); +} +inline ::google::protobuf::int32 FesDebugToolPntValueReqMsg::end_index() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntValueReqMsg.end_index) + return end_index_; +} +inline void FesDebugToolPntValueReqMsg::set_end_index(::google::protobuf::int32 value) { + set_has_end_index(); + end_index_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolPntValueReqMsg.end_index) +} + +// ------------------------------------------------------------------- + +// FesDebugToolIntPntValue + +// required int32 pnt_no = 1; +inline bool FesDebugToolIntPntValue::has_pnt_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolIntPntValue::set_has_pnt_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolIntPntValue::clear_has_pnt_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolIntPntValue::clear_pnt_no() { + pnt_no_ = 0; + clear_has_pnt_no(); +} +inline ::google::protobuf::int32 FesDebugToolIntPntValue::pnt_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolIntPntValue.pnt_no) + return pnt_no_; +} +inline void FesDebugToolIntPntValue::set_pnt_no(::google::protobuf::int32 value) { + set_has_pnt_no(); + pnt_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolIntPntValue.pnt_no) +} + +// required sint32 value = 2; +inline bool FesDebugToolIntPntValue::has_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolIntPntValue::set_has_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolIntPntValue::clear_has_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolIntPntValue::clear_value() { + value_ = 0; + clear_has_value(); +} +inline ::google::protobuf::int32 FesDebugToolIntPntValue::value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolIntPntValue.value) + return value_; +} +inline void FesDebugToolIntPntValue::set_value(::google::protobuf::int32 value) { + set_has_value(); + value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolIntPntValue.value) +} + +// required uint32 status = 3; +inline bool FesDebugToolIntPntValue::has_status() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolIntPntValue::set_has_status() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolIntPntValue::clear_has_status() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolIntPntValue::clear_status() { + status_ = 0u; + clear_has_status(); +} +inline ::google::protobuf::uint32 FesDebugToolIntPntValue::status() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolIntPntValue.status) + return status_; +} +inline void FesDebugToolIntPntValue::set_status(::google::protobuf::uint32 value) { + set_has_status(); + status_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolIntPntValue.status) +} + +// required uint64 time = 4; +inline bool FesDebugToolIntPntValue::has_time() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolIntPntValue::set_has_time() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolIntPntValue::clear_has_time() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolIntPntValue::clear_time() { + time_ = GOOGLE_ULONGLONG(0); + clear_has_time(); +} +inline ::google::protobuf::uint64 FesDebugToolIntPntValue::time() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolIntPntValue.time) + return time_; +} +inline void FesDebugToolIntPntValue::set_time(::google::protobuf::uint64 value) { + set_has_time(); + time_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolIntPntValue.time) +} + +// ------------------------------------------------------------------- + +// FesDebugToolFloatPntValue + +// required int32 pnt_no = 1; +inline bool FesDebugToolFloatPntValue::has_pnt_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolFloatPntValue::set_has_pnt_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolFloatPntValue::clear_has_pnt_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolFloatPntValue::clear_pnt_no() { + pnt_no_ = 0; + clear_has_pnt_no(); +} +inline ::google::protobuf::int32 FesDebugToolFloatPntValue::pnt_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolFloatPntValue.pnt_no) + return pnt_no_; +} +inline void FesDebugToolFloatPntValue::set_pnt_no(::google::protobuf::int32 value) { + set_has_pnt_no(); + pnt_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolFloatPntValue.pnt_no) +} + +// required float value = 2; +inline bool FesDebugToolFloatPntValue::has_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolFloatPntValue::set_has_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolFloatPntValue::clear_has_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolFloatPntValue::clear_value() { + value_ = 0; + clear_has_value(); +} +inline float FesDebugToolFloatPntValue::value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolFloatPntValue.value) + return value_; +} +inline void FesDebugToolFloatPntValue::set_value(float value) { + set_has_value(); + value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolFloatPntValue.value) +} + +// required uint32 status = 3; +inline bool FesDebugToolFloatPntValue::has_status() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolFloatPntValue::set_has_status() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolFloatPntValue::clear_has_status() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolFloatPntValue::clear_status() { + status_ = 0u; + clear_has_status(); +} +inline ::google::protobuf::uint32 FesDebugToolFloatPntValue::status() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolFloatPntValue.status) + return status_; +} +inline void FesDebugToolFloatPntValue::set_status(::google::protobuf::uint32 value) { + set_has_status(); + status_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolFloatPntValue.status) +} + +// required uint64 time = 4; +inline bool FesDebugToolFloatPntValue::has_time() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolFloatPntValue::set_has_time() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolFloatPntValue::clear_has_time() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolFloatPntValue::clear_time() { + time_ = GOOGLE_ULONGLONG(0); + clear_has_time(); +} +inline ::google::protobuf::uint64 FesDebugToolFloatPntValue::time() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolFloatPntValue.time) + return time_; +} +inline void FesDebugToolFloatPntValue::set_time(::google::protobuf::uint64 value) { + set_has_time(); + time_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolFloatPntValue.time) +} + +// ------------------------------------------------------------------- + +// FesDebugToolDoublePntValue + +// required int32 pnt_no = 1; +inline bool FesDebugToolDoublePntValue::has_pnt_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolDoublePntValue::set_has_pnt_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolDoublePntValue::clear_has_pnt_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolDoublePntValue::clear_pnt_no() { + pnt_no_ = 0; + clear_has_pnt_no(); +} +inline ::google::protobuf::int32 FesDebugToolDoublePntValue::pnt_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolDoublePntValue.pnt_no) + return pnt_no_; +} +inline void FesDebugToolDoublePntValue::set_pnt_no(::google::protobuf::int32 value) { + set_has_pnt_no(); + pnt_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolDoublePntValue.pnt_no) +} + +// required double value = 2; +inline bool FesDebugToolDoublePntValue::has_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolDoublePntValue::set_has_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolDoublePntValue::clear_has_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolDoublePntValue::clear_value() { + value_ = 0; + clear_has_value(); +} +inline double FesDebugToolDoublePntValue::value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolDoublePntValue.value) + return value_; +} +inline void FesDebugToolDoublePntValue::set_value(double value) { + set_has_value(); + value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolDoublePntValue.value) +} + +// required uint32 status = 3; +inline bool FesDebugToolDoublePntValue::has_status() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolDoublePntValue::set_has_status() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolDoublePntValue::clear_has_status() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolDoublePntValue::clear_status() { + status_ = 0u; + clear_has_status(); +} +inline ::google::protobuf::uint32 FesDebugToolDoublePntValue::status() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolDoublePntValue.status) + return status_; +} +inline void FesDebugToolDoublePntValue::set_status(::google::protobuf::uint32 value) { + set_has_status(); + status_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolDoublePntValue.status) +} + +// required uint64 time = 4; +inline bool FesDebugToolDoublePntValue::has_time() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolDoublePntValue::set_has_time() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolDoublePntValue::clear_has_time() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolDoublePntValue::clear_time() { + time_ = GOOGLE_ULONGLONG(0); + clear_has_time(); +} +inline ::google::protobuf::uint64 FesDebugToolDoublePntValue::time() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolDoublePntValue.time) + return time_; +} +inline void FesDebugToolDoublePntValue::set_time(::google::protobuf::uint64 value) { + set_has_time(); + time_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolDoublePntValue.time) +} + +// ------------------------------------------------------------------- + +// FesDebugToolPntValueRepMsg + +// required int32 rtu_no = 1; +inline bool FesDebugToolPntValueRepMsg::has_rtu_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolPntValueRepMsg::set_has_rtu_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolPntValueRepMsg::clear_has_rtu_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolPntValueRepMsg::clear_rtu_no() { + rtu_no_ = 0; + clear_has_rtu_no(); +} +inline ::google::protobuf::int32 FesDebugToolPntValueRepMsg::rtu_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntValueRepMsg.rtu_no) + return rtu_no_; +} +inline void FesDebugToolPntValueRepMsg::set_rtu_no(::google::protobuf::int32 value) { + set_has_rtu_no(); + rtu_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolPntValueRepMsg.rtu_no) +} + +// repeated .iot_idl.FesDebugToolIntPntValue int_values = 2; +inline int FesDebugToolPntValueRepMsg::int_values_size() const { + return int_values_.size(); +} +inline void FesDebugToolPntValueRepMsg::clear_int_values() { + int_values_.Clear(); +} +inline const ::iot_idl::FesDebugToolIntPntValue& FesDebugToolPntValueRepMsg::int_values(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntValueRepMsg.int_values) + return int_values_.Get(index); +} +inline ::iot_idl::FesDebugToolIntPntValue* FesDebugToolPntValueRepMsg::mutable_int_values(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolPntValueRepMsg.int_values) + return int_values_.Mutable(index); +} +inline ::iot_idl::FesDebugToolIntPntValue* FesDebugToolPntValueRepMsg::add_int_values() { + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolPntValueRepMsg.int_values) + return int_values_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolIntPntValue >& +FesDebugToolPntValueRepMsg::int_values() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolPntValueRepMsg.int_values) + return int_values_; +} +inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolIntPntValue >* +FesDebugToolPntValueRepMsg::mutable_int_values() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolPntValueRepMsg.int_values) + return &int_values_; +} + +// repeated .iot_idl.FesDebugToolFloatPntValue float_values = 3; +inline int FesDebugToolPntValueRepMsg::float_values_size() const { + return float_values_.size(); +} +inline void FesDebugToolPntValueRepMsg::clear_float_values() { + float_values_.Clear(); +} +inline const ::iot_idl::FesDebugToolFloatPntValue& FesDebugToolPntValueRepMsg::float_values(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntValueRepMsg.float_values) + return float_values_.Get(index); +} +inline ::iot_idl::FesDebugToolFloatPntValue* FesDebugToolPntValueRepMsg::mutable_float_values(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolPntValueRepMsg.float_values) + return float_values_.Mutable(index); +} +inline ::iot_idl::FesDebugToolFloatPntValue* FesDebugToolPntValueRepMsg::add_float_values() { + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolPntValueRepMsg.float_values) + return float_values_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolFloatPntValue >& +FesDebugToolPntValueRepMsg::float_values() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolPntValueRepMsg.float_values) + return float_values_; +} +inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolFloatPntValue >* +FesDebugToolPntValueRepMsg::mutable_float_values() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolPntValueRepMsg.float_values) + return &float_values_; +} + +// repeated .iot_idl.FesDebugToolDoublePntValue double_values = 4; +inline int FesDebugToolPntValueRepMsg::double_values_size() const { + return double_values_.size(); +} +inline void FesDebugToolPntValueRepMsg::clear_double_values() { + double_values_.Clear(); +} +inline const ::iot_idl::FesDebugToolDoublePntValue& FesDebugToolPntValueRepMsg::double_values(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolPntValueRepMsg.double_values) + return double_values_.Get(index); +} +inline ::iot_idl::FesDebugToolDoublePntValue* FesDebugToolPntValueRepMsg::mutable_double_values(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolPntValueRepMsg.double_values) + return double_values_.Mutable(index); +} +inline ::iot_idl::FesDebugToolDoublePntValue* FesDebugToolPntValueRepMsg::add_double_values() { + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolPntValueRepMsg.double_values) + return double_values_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolDoublePntValue >& +FesDebugToolPntValueRepMsg::double_values() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolPntValueRepMsg.double_values) + return double_values_; +} +inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolDoublePntValue >* +FesDebugToolPntValueRepMsg::mutable_double_values() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolPntValueRepMsg.double_values) + return &double_values_; +} + +// ------------------------------------------------------------------- + +// FesDebugToolValueVariant + +// optional int32 int_value = 1; +inline bool FesDebugToolValueVariant::has_int_value() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolValueVariant::set_has_int_value() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolValueVariant::clear_has_int_value() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolValueVariant::clear_int_value() { + int_value_ = 0; + clear_has_int_value(); +} +inline ::google::protobuf::int32 FesDebugToolValueVariant::int_value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueVariant.int_value) + return int_value_; +} +inline void FesDebugToolValueVariant::set_int_value(::google::protobuf::int32 value) { + set_has_int_value(); + int_value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolValueVariant.int_value) +} + +// optional float float_value = 2; +inline bool FesDebugToolValueVariant::has_float_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolValueVariant::set_has_float_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolValueVariant::clear_has_float_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolValueVariant::clear_float_value() { + float_value_ = 0; + clear_has_float_value(); +} +inline float FesDebugToolValueVariant::float_value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueVariant.float_value) + return float_value_; +} +inline void FesDebugToolValueVariant::set_float_value(float value) { + set_has_float_value(); + float_value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolValueVariant.float_value) +} + +// optional double double_value = 3; +inline bool FesDebugToolValueVariant::has_double_value() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolValueVariant::set_has_double_value() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolValueVariant::clear_has_double_value() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolValueVariant::clear_double_value() { + double_value_ = 0; + clear_has_double_value(); +} +inline double FesDebugToolValueVariant::double_value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueVariant.double_value) + return double_value_; +} +inline void FesDebugToolValueVariant::set_double_value(double value) { + set_has_double_value(); + double_value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolValueVariant.double_value) +} + +// ------------------------------------------------------------------- + +// FesDebugToolValueSetSimParam + +// required double value = 1; +inline bool FesDebugToolValueSetSimParam::has_value() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolValueSetSimParam::set_has_value() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolValueSetSimParam::clear_has_value() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolValueSetSimParam::clear_value() { + value_ = 0; + clear_has_value(); +} +inline double FesDebugToolValueSetSimParam::value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueSetSimParam.value) + return value_; +} +inline void FesDebugToolValueSetSimParam::set_value(double value) { + set_has_value(); + value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolValueSetSimParam.value) +} + +// ------------------------------------------------------------------- + +// FesDebugToolLineSetSimParam + +// required double min_value = 1; +inline bool FesDebugToolLineSetSimParam::has_min_value() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolLineSetSimParam::set_has_min_value() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolLineSetSimParam::clear_has_min_value() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolLineSetSimParam::clear_min_value() { + min_value_ = 0; + clear_has_min_value(); +} +inline double FesDebugToolLineSetSimParam::min_value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolLineSetSimParam.min_value) + return min_value_; +} +inline void FesDebugToolLineSetSimParam::set_min_value(double value) { + set_has_min_value(); + min_value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolLineSetSimParam.min_value) +} + +// required double max_value = 2; +inline bool FesDebugToolLineSetSimParam::has_max_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolLineSetSimParam::set_has_max_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolLineSetSimParam::clear_has_max_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolLineSetSimParam::clear_max_value() { + max_value_ = 0; + clear_has_max_value(); +} +inline double FesDebugToolLineSetSimParam::max_value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolLineSetSimParam.max_value) + return max_value_; +} +inline void FesDebugToolLineSetSimParam::set_max_value(double value) { + set_has_max_value(); + max_value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolLineSetSimParam.max_value) +} + +// required double step_value = 3; +inline bool FesDebugToolLineSetSimParam::has_step_value() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolLineSetSimParam::set_has_step_value() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolLineSetSimParam::clear_has_step_value() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolLineSetSimParam::clear_step_value() { + step_value_ = 0; + clear_has_step_value(); +} +inline double FesDebugToolLineSetSimParam::step_value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolLineSetSimParam.step_value) + return step_value_; +} +inline void FesDebugToolLineSetSimParam::set_step_value(double value) { + set_has_step_value(); + step_value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolLineSetSimParam.step_value) +} + +// required int32 period = 4; +inline bool FesDebugToolLineSetSimParam::has_period() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolLineSetSimParam::set_has_period() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolLineSetSimParam::clear_has_period() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolLineSetSimParam::clear_period() { + period_ = 0; + clear_has_period(); +} +inline ::google::protobuf::int32 FesDebugToolLineSetSimParam::period() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolLineSetSimParam.period) + return period_; +} +inline void FesDebugToolLineSetSimParam::set_period(::google::protobuf::int32 value) { + set_has_period(); + period_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolLineSetSimParam.period) +} + +// ------------------------------------------------------------------- + +// FesDebugToolRandSetSimParam + +// optional double min_value = 1; +inline bool FesDebugToolRandSetSimParam::has_min_value() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolRandSetSimParam::set_has_min_value() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolRandSetSimParam::clear_has_min_value() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolRandSetSimParam::clear_min_value() { + min_value_ = 0; + clear_has_min_value(); +} +inline double FesDebugToolRandSetSimParam::min_value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRandSetSimParam.min_value) + return min_value_; +} +inline void FesDebugToolRandSetSimParam::set_min_value(double value) { + set_has_min_value(); + min_value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRandSetSimParam.min_value) +} + +// optional double max_value = 2; +inline bool FesDebugToolRandSetSimParam::has_max_value() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolRandSetSimParam::set_has_max_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolRandSetSimParam::clear_has_max_value() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolRandSetSimParam::clear_max_value() { + max_value_ = 0; + clear_has_max_value(); +} +inline double FesDebugToolRandSetSimParam::max_value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRandSetSimParam.max_value) + return max_value_; +} +inline void FesDebugToolRandSetSimParam::set_max_value(double value) { + set_has_max_value(); + max_value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRandSetSimParam.max_value) +} + +// required int32 period = 3; +inline bool FesDebugToolRandSetSimParam::has_period() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolRandSetSimParam::set_has_period() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolRandSetSimParam::clear_has_period() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolRandSetSimParam::clear_period() { + period_ = 0; + clear_has_period(); +} +inline ::google::protobuf::int32 FesDebugToolRandSetSimParam::period() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolRandSetSimParam.period) + return period_; +} +inline void FesDebugToolRandSetSimParam::set_period(::google::protobuf::int32 value) { + set_has_period(); + period_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolRandSetSimParam.period) +} + +// ------------------------------------------------------------------- + +// FesDebugToolValueSimSetReqMsg + +// required .iot_idl.enFesDebugSimMode sim_mode = 1; +inline bool FesDebugToolValueSimSetReqMsg::has_sim_mode() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolValueSimSetReqMsg::set_has_sim_mode() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_has_sim_mode() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_sim_mode() { + sim_mode_ = 1; + clear_has_sim_mode(); +} +inline ::iot_idl::enFesDebugSimMode FesDebugToolValueSimSetReqMsg::sim_mode() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueSimSetReqMsg.sim_mode) + return static_cast< ::iot_idl::enFesDebugSimMode >(sim_mode_); +} +inline void FesDebugToolValueSimSetReqMsg::set_sim_mode(::iot_idl::enFesDebugSimMode value) { + assert(::iot_idl::enFesDebugSimMode_IsValid(value)); + set_has_sim_mode(); + sim_mode_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolValueSimSetReqMsg.sim_mode) +} + +// required .iot_idl.enFesDebugSimRangeType sim_range = 2; +inline bool FesDebugToolValueSimSetReqMsg::has_sim_range() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolValueSimSetReqMsg::set_has_sim_range() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_has_sim_range() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_sim_range() { + sim_range_ = 1; + clear_has_sim_range(); +} +inline ::iot_idl::enFesDebugSimRangeType FesDebugToolValueSimSetReqMsg::sim_range() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueSimSetReqMsg.sim_range) + return static_cast< ::iot_idl::enFesDebugSimRangeType >(sim_range_); +} +inline void FesDebugToolValueSimSetReqMsg::set_sim_range(::iot_idl::enFesDebugSimRangeType value) { + assert(::iot_idl::enFesDebugSimRangeType_IsValid(value)); + set_has_sim_range(); + sim_range_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolValueSimSetReqMsg.sim_range) +} + +// optional int32 rtu_no = 3; +inline bool FesDebugToolValueSimSetReqMsg::has_rtu_no() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolValueSimSetReqMsg::set_has_rtu_no() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_has_rtu_no() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_rtu_no() { + rtu_no_ = 0; + clear_has_rtu_no(); +} +inline ::google::protobuf::int32 FesDebugToolValueSimSetReqMsg::rtu_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueSimSetReqMsg.rtu_no) + return rtu_no_; +} +inline void FesDebugToolValueSimSetReqMsg::set_rtu_no(::google::protobuf::int32 value) { + set_has_rtu_no(); + rtu_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolValueSimSetReqMsg.rtu_no) +} + +// optional int32 pnt_no = 4; +inline bool FesDebugToolValueSimSetReqMsg::has_pnt_no() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolValueSimSetReqMsg::set_has_pnt_no() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_has_pnt_no() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_pnt_no() { + pnt_no_ = 0; + clear_has_pnt_no(); +} +inline ::google::protobuf::int32 FesDebugToolValueSimSetReqMsg::pnt_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueSimSetReqMsg.pnt_no) + return pnt_no_; +} +inline void FesDebugToolValueSimSetReqMsg::set_pnt_no(::google::protobuf::int32 value) { + set_has_pnt_no(); + pnt_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolValueSimSetReqMsg.pnt_no) +} + +// optional uint32 status = 5; +inline bool FesDebugToolValueSimSetReqMsg::has_status() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FesDebugToolValueSimSetReqMsg::set_has_status() { + _has_bits_[0] |= 0x00000010u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_has_status() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_status() { + status_ = 0u; + clear_has_status(); +} +inline ::google::protobuf::uint32 FesDebugToolValueSimSetReqMsg::status() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueSimSetReqMsg.status) + return status_; +} +inline void FesDebugToolValueSimSetReqMsg::set_status(::google::protobuf::uint32 value) { + set_has_status(); + status_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolValueSimSetReqMsg.status) +} + +// optional .iot_idl.FesDebugToolValueSetSimParam value_set_param = 6; +inline bool FesDebugToolValueSimSetReqMsg::has_value_set_param() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FesDebugToolValueSimSetReqMsg::set_has_value_set_param() { + _has_bits_[0] |= 0x00000020u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_has_value_set_param() { + _has_bits_[0] &= ~0x00000020u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_value_set_param() { + if (value_set_param_ != NULL) value_set_param_->::iot_idl::FesDebugToolValueSetSimParam::Clear(); + clear_has_value_set_param(); +} +inline const ::iot_idl::FesDebugToolValueSetSimParam& FesDebugToolValueSimSetReqMsg::value_set_param() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueSimSetReqMsg.value_set_param) + return value_set_param_ != NULL ? *value_set_param_ : *default_instance_->value_set_param_; +} +inline ::iot_idl::FesDebugToolValueSetSimParam* FesDebugToolValueSimSetReqMsg::mutable_value_set_param() { + set_has_value_set_param(); + if (value_set_param_ == NULL) value_set_param_ = new ::iot_idl::FesDebugToolValueSetSimParam; + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolValueSimSetReqMsg.value_set_param) + return value_set_param_; +} +inline ::iot_idl::FesDebugToolValueSetSimParam* FesDebugToolValueSimSetReqMsg::release_value_set_param() { + clear_has_value_set_param(); + ::iot_idl::FesDebugToolValueSetSimParam* temp = value_set_param_; + value_set_param_ = NULL; + return temp; +} +inline void FesDebugToolValueSimSetReqMsg::set_allocated_value_set_param(::iot_idl::FesDebugToolValueSetSimParam* value_set_param) { + delete value_set_param_; + value_set_param_ = value_set_param; + if (value_set_param) { + set_has_value_set_param(); + } else { + clear_has_value_set_param(); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolValueSimSetReqMsg.value_set_param) +} + +// optional .iot_idl.FesDebugToolLineSetSimParam line_set_param = 7; +inline bool FesDebugToolValueSimSetReqMsg::has_line_set_param() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void FesDebugToolValueSimSetReqMsg::set_has_line_set_param() { + _has_bits_[0] |= 0x00000040u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_has_line_set_param() { + _has_bits_[0] &= ~0x00000040u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_line_set_param() { + if (line_set_param_ != NULL) line_set_param_->::iot_idl::FesDebugToolLineSetSimParam::Clear(); + clear_has_line_set_param(); +} +inline const ::iot_idl::FesDebugToolLineSetSimParam& FesDebugToolValueSimSetReqMsg::line_set_param() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueSimSetReqMsg.line_set_param) + return line_set_param_ != NULL ? *line_set_param_ : *default_instance_->line_set_param_; +} +inline ::iot_idl::FesDebugToolLineSetSimParam* FesDebugToolValueSimSetReqMsg::mutable_line_set_param() { + set_has_line_set_param(); + if (line_set_param_ == NULL) line_set_param_ = new ::iot_idl::FesDebugToolLineSetSimParam; + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolValueSimSetReqMsg.line_set_param) + return line_set_param_; +} +inline ::iot_idl::FesDebugToolLineSetSimParam* FesDebugToolValueSimSetReqMsg::release_line_set_param() { + clear_has_line_set_param(); + ::iot_idl::FesDebugToolLineSetSimParam* temp = line_set_param_; + line_set_param_ = NULL; + return temp; +} +inline void FesDebugToolValueSimSetReqMsg::set_allocated_line_set_param(::iot_idl::FesDebugToolLineSetSimParam* line_set_param) { + delete line_set_param_; + line_set_param_ = line_set_param; + if (line_set_param) { + set_has_line_set_param(); + } else { + clear_has_line_set_param(); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolValueSimSetReqMsg.line_set_param) +} + +// optional .iot_idl.FesDebugToolRandSetSimParam rand_set_param = 8; +inline bool FesDebugToolValueSimSetReqMsg::has_rand_set_param() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void FesDebugToolValueSimSetReqMsg::set_has_rand_set_param() { + _has_bits_[0] |= 0x00000080u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_has_rand_set_param() { + _has_bits_[0] &= ~0x00000080u; +} +inline void FesDebugToolValueSimSetReqMsg::clear_rand_set_param() { + if (rand_set_param_ != NULL) rand_set_param_->::iot_idl::FesDebugToolRandSetSimParam::Clear(); + clear_has_rand_set_param(); +} +inline const ::iot_idl::FesDebugToolRandSetSimParam& FesDebugToolValueSimSetReqMsg::rand_set_param() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueSimSetReqMsg.rand_set_param) + return rand_set_param_ != NULL ? *rand_set_param_ : *default_instance_->rand_set_param_; +} +inline ::iot_idl::FesDebugToolRandSetSimParam* FesDebugToolValueSimSetReqMsg::mutable_rand_set_param() { + set_has_rand_set_param(); + if (rand_set_param_ == NULL) rand_set_param_ = new ::iot_idl::FesDebugToolRandSetSimParam; + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolValueSimSetReqMsg.rand_set_param) + return rand_set_param_; +} +inline ::iot_idl::FesDebugToolRandSetSimParam* FesDebugToolValueSimSetReqMsg::release_rand_set_param() { + clear_has_rand_set_param(); + ::iot_idl::FesDebugToolRandSetSimParam* temp = rand_set_param_; + rand_set_param_ = NULL; + return temp; +} +inline void FesDebugToolValueSimSetReqMsg::set_allocated_rand_set_param(::iot_idl::FesDebugToolRandSetSimParam* rand_set_param) { + delete rand_set_param_; + rand_set_param_ = rand_set_param; + if (rand_set_param) { + set_has_rand_set_param(); + } else { + clear_has_rand_set_param(); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolValueSimSetReqMsg.rand_set_param) +} + +// ------------------------------------------------------------------- + +// FesDebugToolValueSimSetRepMsg + +// required .iot_idl.enFesDebugSimMode sim_mode = 1; +inline bool FesDebugToolValueSimSetRepMsg::has_sim_mode() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolValueSimSetRepMsg::set_has_sim_mode() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolValueSimSetRepMsg::clear_has_sim_mode() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolValueSimSetRepMsg::clear_sim_mode() { + sim_mode_ = 1; + clear_has_sim_mode(); +} +inline ::iot_idl::enFesDebugSimMode FesDebugToolValueSimSetRepMsg::sim_mode() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueSimSetRepMsg.sim_mode) + return static_cast< ::iot_idl::enFesDebugSimMode >(sim_mode_); +} +inline void FesDebugToolValueSimSetRepMsg::set_sim_mode(::iot_idl::enFesDebugSimMode value) { + assert(::iot_idl::enFesDebugSimMode_IsValid(value)); + set_has_sim_mode(); + sim_mode_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolValueSimSetRepMsg.sim_mode) +} + +// optional string body = 2; +inline bool FesDebugToolValueSimSetRepMsg::has_body() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolValueSimSetRepMsg::set_has_body() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolValueSimSetRepMsg::clear_has_body() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolValueSimSetRepMsg::clear_body() { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_->clear(); + } + clear_has_body(); +} +inline const ::std::string& FesDebugToolValueSimSetRepMsg::body() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolValueSimSetRepMsg.body) + return *body_; +} +inline void FesDebugToolValueSimSetRepMsg::set_body(const ::std::string& value) { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + body_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolValueSimSetRepMsg.body) +} +inline void FesDebugToolValueSimSetRepMsg::set_body(const char* value) { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + body_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolValueSimSetRepMsg.body) +} +inline void FesDebugToolValueSimSetRepMsg::set_body(const char* value, size_t size) { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + body_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolValueSimSetRepMsg.body) +} +inline ::std::string* FesDebugToolValueSimSetRepMsg::mutable_body() { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolValueSimSetRepMsg.body) + return body_; +} +inline ::std::string* FesDebugToolValueSimSetRepMsg::release_body() { + clear_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = body_; + body_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolValueSimSetRepMsg::set_allocated_body(::std::string* body) { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete body_; + } + if (body) { + set_has_body(); + body_ = body; + } else { + clear_has_body(); + body_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolValueSimSetRepMsg.body) +} + +// ------------------------------------------------------------------- + +// FesDebugToolSimEventRtuSoe + +// required int32 event_source = 1; +inline bool FesDebugToolSimEventRtuSoe::has_event_source() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolSimEventRtuSoe::set_has_event_source() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolSimEventRtuSoe::clear_has_event_source() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolSimEventRtuSoe::clear_event_source() { + event_source_ = 0; + clear_has_event_source(); +} +inline ::google::protobuf::int32 FesDebugToolSimEventRtuSoe::event_source() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimEventRtuSoe.event_source) + return event_source_; +} +inline void FesDebugToolSimEventRtuSoe::set_event_source(::google::protobuf::int32 value) { + set_has_event_source(); + event_source_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimEventRtuSoe.event_source) +} + +// required int32 rtu_no = 2; +inline bool FesDebugToolSimEventRtuSoe::has_rtu_no() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolSimEventRtuSoe::set_has_rtu_no() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolSimEventRtuSoe::clear_has_rtu_no() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolSimEventRtuSoe::clear_rtu_no() { + rtu_no_ = 0; + clear_has_rtu_no(); +} +inline ::google::protobuf::int32 FesDebugToolSimEventRtuSoe::rtu_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimEventRtuSoe.rtu_no) + return rtu_no_; +} +inline void FesDebugToolSimEventRtuSoe::set_rtu_no(::google::protobuf::int32 value) { + set_has_rtu_no(); + rtu_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimEventRtuSoe.rtu_no) +} + +// required int32 pnt_no = 3; +inline bool FesDebugToolSimEventRtuSoe::has_pnt_no() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolSimEventRtuSoe::set_has_pnt_no() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolSimEventRtuSoe::clear_has_pnt_no() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolSimEventRtuSoe::clear_pnt_no() { + pnt_no_ = 0; + clear_has_pnt_no(); +} +inline ::google::protobuf::int32 FesDebugToolSimEventRtuSoe::pnt_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimEventRtuSoe.pnt_no) + return pnt_no_; +} +inline void FesDebugToolSimEventRtuSoe::set_pnt_no(::google::protobuf::int32 value) { + set_has_pnt_no(); + pnt_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimEventRtuSoe.pnt_no) +} + +// required int32 value = 4; +inline bool FesDebugToolSimEventRtuSoe::has_value() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolSimEventRtuSoe::set_has_value() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolSimEventRtuSoe::clear_has_value() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolSimEventRtuSoe::clear_value() { + value_ = 0; + clear_has_value(); +} +inline ::google::protobuf::int32 FesDebugToolSimEventRtuSoe::value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimEventRtuSoe.value) + return value_; +} +inline void FesDebugToolSimEventRtuSoe::set_value(::google::protobuf::int32 value) { + set_has_value(); + value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimEventRtuSoe.value) +} + +// required uint32 status = 5; +inline bool FesDebugToolSimEventRtuSoe::has_status() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FesDebugToolSimEventRtuSoe::set_has_status() { + _has_bits_[0] |= 0x00000010u; +} +inline void FesDebugToolSimEventRtuSoe::clear_has_status() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FesDebugToolSimEventRtuSoe::clear_status() { + status_ = 0u; + clear_has_status(); +} +inline ::google::protobuf::uint32 FesDebugToolSimEventRtuSoe::status() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimEventRtuSoe.status) + return status_; +} +inline void FesDebugToolSimEventRtuSoe::set_status(::google::protobuf::uint32 value) { + set_has_status(); + status_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimEventRtuSoe.status) +} + +// required int32 fault_num = 6; +inline bool FesDebugToolSimEventRtuSoe::has_fault_num() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FesDebugToolSimEventRtuSoe::set_has_fault_num() { + _has_bits_[0] |= 0x00000020u; +} +inline void FesDebugToolSimEventRtuSoe::clear_has_fault_num() { + _has_bits_[0] &= ~0x00000020u; +} +inline void FesDebugToolSimEventRtuSoe::clear_fault_num() { + fault_num_ = 0; + clear_has_fault_num(); +} +inline ::google::protobuf::int32 FesDebugToolSimEventRtuSoe::fault_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimEventRtuSoe.fault_num) + return fault_num_; +} +inline void FesDebugToolSimEventRtuSoe::set_fault_num(::google::protobuf::int32 value) { + set_has_fault_num(); + fault_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimEventRtuSoe.fault_num) +} + +// repeated int32 fault_type = 7; +inline int FesDebugToolSimEventRtuSoe::fault_type_size() const { + return fault_type_.size(); +} +inline void FesDebugToolSimEventRtuSoe::clear_fault_type() { + fault_type_.Clear(); +} +inline ::google::protobuf::int32 FesDebugToolSimEventRtuSoe::fault_type(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimEventRtuSoe.fault_type) + return fault_type_.Get(index); +} +inline void FesDebugToolSimEventRtuSoe::set_fault_type(int index, ::google::protobuf::int32 value) { + fault_type_.Set(index, value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimEventRtuSoe.fault_type) +} +inline void FesDebugToolSimEventRtuSoe::add_fault_type(::google::protobuf::int32 value) { + fault_type_.Add(value); + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolSimEventRtuSoe.fault_type) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +FesDebugToolSimEventRtuSoe::fault_type() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolSimEventRtuSoe.fault_type) + return fault_type_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +FesDebugToolSimEventRtuSoe::mutable_fault_type() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolSimEventRtuSoe.fault_type) + return &fault_type_; +} + +// repeated float fault_value = 8; +inline int FesDebugToolSimEventRtuSoe::fault_value_size() const { + return fault_value_.size(); +} +inline void FesDebugToolSimEventRtuSoe::clear_fault_value() { + fault_value_.Clear(); +} +inline float FesDebugToolSimEventRtuSoe::fault_value(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimEventRtuSoe.fault_value) + return fault_value_.Get(index); +} +inline void FesDebugToolSimEventRtuSoe::set_fault_value(int index, float value) { + fault_value_.Set(index, value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimEventRtuSoe.fault_value) +} +inline void FesDebugToolSimEventRtuSoe::add_fault_value(float value) { + fault_value_.Add(value); + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolSimEventRtuSoe.fault_value) +} +inline const ::google::protobuf::RepeatedField< float >& +FesDebugToolSimEventRtuSoe::fault_value() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolSimEventRtuSoe.fault_value) + return fault_value_; +} +inline ::google::protobuf::RepeatedField< float >* +FesDebugToolSimEventRtuSoe::mutable_fault_value() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolSimEventRtuSoe.fault_value) + return &fault_value_; +} + +// ------------------------------------------------------------------- + +// FesDebugToolSimEventCreateReqMsg + +// required .iot_idl.enFesDebugEventSimType event_type = 1; +inline bool FesDebugToolSimEventCreateReqMsg::has_event_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolSimEventCreateReqMsg::set_has_event_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolSimEventCreateReqMsg::clear_has_event_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolSimEventCreateReqMsg::clear_event_type() { + event_type_ = 1; + clear_has_event_type(); +} +inline ::iot_idl::enFesDebugEventSimType FesDebugToolSimEventCreateReqMsg::event_type() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimEventCreateReqMsg.event_type) + return static_cast< ::iot_idl::enFesDebugEventSimType >(event_type_); +} +inline void FesDebugToolSimEventCreateReqMsg::set_event_type(::iot_idl::enFesDebugEventSimType value) { + assert(::iot_idl::enFesDebugEventSimType_IsValid(value)); + set_has_event_type(); + event_type_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimEventCreateReqMsg.event_type) +} + +// optional .iot_idl.FesDebugToolSimEventRtuSoe event = 2; +inline bool FesDebugToolSimEventCreateReqMsg::has_event() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolSimEventCreateReqMsg::set_has_event() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolSimEventCreateReqMsg::clear_has_event() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolSimEventCreateReqMsg::clear_event() { + if (event_ != NULL) event_->::iot_idl::FesDebugToolSimEventRtuSoe::Clear(); + clear_has_event(); +} +inline const ::iot_idl::FesDebugToolSimEventRtuSoe& FesDebugToolSimEventCreateReqMsg::event() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimEventCreateReqMsg.event) + return event_ != NULL ? *event_ : *default_instance_->event_; +} +inline ::iot_idl::FesDebugToolSimEventRtuSoe* FesDebugToolSimEventCreateReqMsg::mutable_event() { + set_has_event(); + if (event_ == NULL) event_ = new ::iot_idl::FesDebugToolSimEventRtuSoe; + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolSimEventCreateReqMsg.event) + return event_; +} +inline ::iot_idl::FesDebugToolSimEventRtuSoe* FesDebugToolSimEventCreateReqMsg::release_event() { + clear_has_event(); + ::iot_idl::FesDebugToolSimEventRtuSoe* temp = event_; + event_ = NULL; + return temp; +} +inline void FesDebugToolSimEventCreateReqMsg::set_allocated_event(::iot_idl::FesDebugToolSimEventRtuSoe* event) { + delete event_; + event_ = event; + if (event) { + set_has_event(); + } else { + clear_has_event(); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolSimEventCreateReqMsg.event) +} + +// ------------------------------------------------------------------- + +// FesDebugToolSimEventCreateRepMsg + +// required .iot_idl.enFesDebugEventSimType event_type = 1; +inline bool FesDebugToolSimEventCreateRepMsg::has_event_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolSimEventCreateRepMsg::set_has_event_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolSimEventCreateRepMsg::clear_has_event_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolSimEventCreateRepMsg::clear_event_type() { + event_type_ = 1; + clear_has_event_type(); +} +inline ::iot_idl::enFesDebugEventSimType FesDebugToolSimEventCreateRepMsg::event_type() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimEventCreateRepMsg.event_type) + return static_cast< ::iot_idl::enFesDebugEventSimType >(event_type_); +} +inline void FesDebugToolSimEventCreateRepMsg::set_event_type(::iot_idl::enFesDebugEventSimType value) { + assert(::iot_idl::enFesDebugEventSimType_IsValid(value)); + set_has_event_type(); + event_type_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimEventCreateRepMsg.event_type) +} + +// optional string body = 2; +inline bool FesDebugToolSimEventCreateRepMsg::has_body() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolSimEventCreateRepMsg::set_has_body() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolSimEventCreateRepMsg::clear_has_body() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolSimEventCreateRepMsg::clear_body() { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_->clear(); + } + clear_has_body(); +} +inline const ::std::string& FesDebugToolSimEventCreateRepMsg::body() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimEventCreateRepMsg.body) + return *body_; +} +inline void FesDebugToolSimEventCreateRepMsg::set_body(const ::std::string& value) { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + body_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimEventCreateRepMsg.body) +} +inline void FesDebugToolSimEventCreateRepMsg::set_body(const char* value) { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + body_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolSimEventCreateRepMsg.body) +} +inline void FesDebugToolSimEventCreateRepMsg::set_body(const char* value, size_t size) { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + body_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolSimEventCreateRepMsg.body) +} +inline ::std::string* FesDebugToolSimEventCreateRepMsg::mutable_body() { + set_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + body_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolSimEventCreateRepMsg.body) + return body_; +} +inline ::std::string* FesDebugToolSimEventCreateRepMsg::release_body() { + clear_has_body(); + if (body_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = body_; + body_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolSimEventCreateRepMsg::set_allocated_body(::std::string* body) { + if (body_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete body_; + } + if (body) { + set_has_body(); + body_ = body; + } else { + clear_has_body(); + body_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolSimEventCreateRepMsg.body) +} + +// ------------------------------------------------------------------- + +// FesDebugToolSimControlReqMsg + +// required int32 ctrl_type = 1; +inline bool FesDebugToolSimControlReqMsg::has_ctrl_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolSimControlReqMsg::set_has_ctrl_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolSimControlReqMsg::clear_has_ctrl_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolSimControlReqMsg::clear_ctrl_type() { + ctrl_type_ = 0; + clear_has_ctrl_type(); +} +inline ::google::protobuf::int32 FesDebugToolSimControlReqMsg::ctrl_type() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimControlReqMsg.ctrl_type) + return ctrl_type_; +} +inline void FesDebugToolSimControlReqMsg::set_ctrl_type(::google::protobuf::int32 value) { + set_has_ctrl_type(); + ctrl_type_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimControlReqMsg.ctrl_type) +} + +// required int64 seq_no = 2; +inline bool FesDebugToolSimControlReqMsg::has_seq_no() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolSimControlReqMsg::set_has_seq_no() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolSimControlReqMsg::clear_has_seq_no() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolSimControlReqMsg::clear_seq_no() { + seq_no_ = GOOGLE_LONGLONG(0); + clear_has_seq_no(); +} +inline ::google::protobuf::int64 FesDebugToolSimControlReqMsg::seq_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimControlReqMsg.seq_no) + return seq_no_; +} +inline void FesDebugToolSimControlReqMsg::set_seq_no(::google::protobuf::int64 value) { + set_has_seq_no(); + seq_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimControlReqMsg.seq_no) +} + +// required int32 rtu_no = 3; +inline bool FesDebugToolSimControlReqMsg::has_rtu_no() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolSimControlReqMsg::set_has_rtu_no() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolSimControlReqMsg::clear_has_rtu_no() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolSimControlReqMsg::clear_rtu_no() { + rtu_no_ = 0; + clear_has_rtu_no(); +} +inline ::google::protobuf::int32 FesDebugToolSimControlReqMsg::rtu_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimControlReqMsg.rtu_no) + return rtu_no_; +} +inline void FesDebugToolSimControlReqMsg::set_rtu_no(::google::protobuf::int32 value) { + set_has_rtu_no(); + rtu_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimControlReqMsg.rtu_no) +} + +// required int32 pnt_no = 4; +inline bool FesDebugToolSimControlReqMsg::has_pnt_no() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolSimControlReqMsg::set_has_pnt_no() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolSimControlReqMsg::clear_has_pnt_no() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolSimControlReqMsg::clear_pnt_no() { + pnt_no_ = 0; + clear_has_pnt_no(); +} +inline ::google::protobuf::int32 FesDebugToolSimControlReqMsg::pnt_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimControlReqMsg.pnt_no) + return pnt_no_; +} +inline void FesDebugToolSimControlReqMsg::set_pnt_no(::google::protobuf::int32 value) { + set_has_pnt_no(); + pnt_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimControlReqMsg.pnt_no) +} + +// optional float float_value = 5; +inline bool FesDebugToolSimControlReqMsg::has_float_value() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FesDebugToolSimControlReqMsg::set_has_float_value() { + _has_bits_[0] |= 0x00000010u; +} +inline void FesDebugToolSimControlReqMsg::clear_has_float_value() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FesDebugToolSimControlReqMsg::clear_float_value() { + float_value_ = 0; + clear_has_float_value(); +} +inline float FesDebugToolSimControlReqMsg::float_value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimControlReqMsg.float_value) + return float_value_; +} +inline void FesDebugToolSimControlReqMsg::set_float_value(float value) { + set_has_float_value(); + float_value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimControlReqMsg.float_value) +} + +// optional int32 int_value = 6; +inline bool FesDebugToolSimControlReqMsg::has_int_value() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FesDebugToolSimControlReqMsg::set_has_int_value() { + _has_bits_[0] |= 0x00000020u; +} +inline void FesDebugToolSimControlReqMsg::clear_has_int_value() { + _has_bits_[0] &= ~0x00000020u; +} +inline void FesDebugToolSimControlReqMsg::clear_int_value() { + int_value_ = 0; + clear_has_int_value(); +} +inline ::google::protobuf::int32 FesDebugToolSimControlReqMsg::int_value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimControlReqMsg.int_value) + return int_value_; +} +inline void FesDebugToolSimControlReqMsg::set_int_value(::google::protobuf::int32 value) { + set_has_int_value(); + int_value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimControlReqMsg.int_value) +} + +// ------------------------------------------------------------------- + +// FesDebugToolSimControlRepMsg + +// required int32 ctrl_type = 1; +inline bool FesDebugToolSimControlRepMsg::has_ctrl_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolSimControlRepMsg::set_has_ctrl_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolSimControlRepMsg::clear_has_ctrl_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolSimControlRepMsg::clear_ctrl_type() { + ctrl_type_ = 0; + clear_has_ctrl_type(); +} +inline ::google::protobuf::int32 FesDebugToolSimControlRepMsg::ctrl_type() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimControlRepMsg.ctrl_type) + return ctrl_type_; +} +inline void FesDebugToolSimControlRepMsg::set_ctrl_type(::google::protobuf::int32 value) { + set_has_ctrl_type(); + ctrl_type_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimControlRepMsg.ctrl_type) +} + +// required int64 seq_no = 2; +inline bool FesDebugToolSimControlRepMsg::has_seq_no() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolSimControlRepMsg::set_has_seq_no() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolSimControlRepMsg::clear_has_seq_no() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolSimControlRepMsg::clear_seq_no() { + seq_no_ = GOOGLE_LONGLONG(0); + clear_has_seq_no(); +} +inline ::google::protobuf::int64 FesDebugToolSimControlRepMsg::seq_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimControlRepMsg.seq_no) + return seq_no_; +} +inline void FesDebugToolSimControlRepMsg::set_seq_no(::google::protobuf::int64 value) { + set_has_seq_no(); + seq_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimControlRepMsg.seq_no) +} + +// required bool success = 3; +inline bool FesDebugToolSimControlRepMsg::has_success() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolSimControlRepMsg::set_has_success() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolSimControlRepMsg::clear_has_success() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolSimControlRepMsg::clear_success() { + success_ = false; + clear_has_success(); +} +inline bool FesDebugToolSimControlRepMsg::success() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimControlRepMsg.success) + return success_; +} +inline void FesDebugToolSimControlRepMsg::set_success(bool value) { + set_has_success(); + success_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimControlRepMsg.success) +} + +// optional string err_msg = 4; +inline bool FesDebugToolSimControlRepMsg::has_err_msg() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolSimControlRepMsg::set_has_err_msg() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolSimControlRepMsg::clear_has_err_msg() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolSimControlRepMsg::clear_err_msg() { + if (err_msg_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + err_msg_->clear(); + } + clear_has_err_msg(); +} +inline const ::std::string& FesDebugToolSimControlRepMsg::err_msg() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimControlRepMsg.err_msg) + return *err_msg_; +} +inline void FesDebugToolSimControlRepMsg::set_err_msg(const ::std::string& value) { + set_has_err_msg(); + if (err_msg_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + err_msg_ = new ::std::string; + } + err_msg_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimControlRepMsg.err_msg) +} +inline void FesDebugToolSimControlRepMsg::set_err_msg(const char* value) { + set_has_err_msg(); + if (err_msg_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + err_msg_ = new ::std::string; + } + err_msg_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolSimControlRepMsg.err_msg) +} +inline void FesDebugToolSimControlRepMsg::set_err_msg(const char* value, size_t size) { + set_has_err_msg(); + if (err_msg_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + err_msg_ = new ::std::string; + } + err_msg_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolSimControlRepMsg.err_msg) +} +inline ::std::string* FesDebugToolSimControlRepMsg::mutable_err_msg() { + set_has_err_msg(); + if (err_msg_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + err_msg_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolSimControlRepMsg.err_msg) + return err_msg_; +} +inline ::std::string* FesDebugToolSimControlRepMsg::release_err_msg() { + clear_has_err_msg(); + if (err_msg_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = err_msg_; + err_msg_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolSimControlRepMsg::set_allocated_err_msg(::std::string* err_msg) { + if (err_msg_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete err_msg_; + } + if (err_msg) { + set_has_err_msg(); + err_msg_ = err_msg; + } else { + clear_has_err_msg(); + err_msg_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolSimControlRepMsg.err_msg) +} + +// ------------------------------------------------------------------- + +// FesDebugToolSimDefCmdReqMsg + +// required int32 rtu_no = 1; +inline bool FesDebugToolSimDefCmdReqMsg::has_rtu_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolSimDefCmdReqMsg::set_has_rtu_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolSimDefCmdReqMsg::clear_has_rtu_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolSimDefCmdReqMsg::clear_rtu_no() { + rtu_no_ = 0; + clear_has_rtu_no(); +} +inline ::google::protobuf::int32 FesDebugToolSimDefCmdReqMsg::rtu_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimDefCmdReqMsg.rtu_no) + return rtu_no_; +} +inline void FesDebugToolSimDefCmdReqMsg::set_rtu_no(::google::protobuf::int32 value) { + set_has_rtu_no(); + rtu_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimDefCmdReqMsg.rtu_no) +} + +// required int32 dev_id = 2; +inline bool FesDebugToolSimDefCmdReqMsg::has_dev_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolSimDefCmdReqMsg::set_has_dev_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolSimDefCmdReqMsg::clear_has_dev_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolSimDefCmdReqMsg::clear_dev_id() { + dev_id_ = 0; + clear_has_dev_id(); +} +inline ::google::protobuf::int32 FesDebugToolSimDefCmdReqMsg::dev_id() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimDefCmdReqMsg.dev_id) + return dev_id_; +} +inline void FesDebugToolSimDefCmdReqMsg::set_dev_id(::google::protobuf::int32 value) { + set_has_dev_id(); + dev_id_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimDefCmdReqMsg.dev_id) +} + +// repeated string keys = 3; +inline int FesDebugToolSimDefCmdReqMsg::keys_size() const { + return keys_.size(); +} +inline void FesDebugToolSimDefCmdReqMsg::clear_keys() { + keys_.Clear(); +} +inline const ::std::string& FesDebugToolSimDefCmdReqMsg::keys(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimDefCmdReqMsg.keys) + return keys_.Get(index); +} +inline ::std::string* FesDebugToolSimDefCmdReqMsg::mutable_keys(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolSimDefCmdReqMsg.keys) + return keys_.Mutable(index); +} +inline void FesDebugToolSimDefCmdReqMsg::set_keys(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimDefCmdReqMsg.keys) + keys_.Mutable(index)->assign(value); +} +inline void FesDebugToolSimDefCmdReqMsg::set_keys(int index, const char* value) { + keys_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolSimDefCmdReqMsg.keys) +} +inline void FesDebugToolSimDefCmdReqMsg::set_keys(int index, const char* value, size_t size) { + keys_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolSimDefCmdReqMsg.keys) +} +inline ::std::string* FesDebugToolSimDefCmdReqMsg::add_keys() { + return keys_.Add(); +} +inline void FesDebugToolSimDefCmdReqMsg::add_keys(const ::std::string& value) { + keys_.Add()->assign(value); + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolSimDefCmdReqMsg.keys) +} +inline void FesDebugToolSimDefCmdReqMsg::add_keys(const char* value) { + keys_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:iot_idl.FesDebugToolSimDefCmdReqMsg.keys) +} +inline void FesDebugToolSimDefCmdReqMsg::add_keys(const char* value, size_t size) { + keys_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:iot_idl.FesDebugToolSimDefCmdReqMsg.keys) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +FesDebugToolSimDefCmdReqMsg::keys() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolSimDefCmdReqMsg.keys) + return keys_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +FesDebugToolSimDefCmdReqMsg::mutable_keys() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolSimDefCmdReqMsg.keys) + return &keys_; +} + +// repeated string values = 4; +inline int FesDebugToolSimDefCmdReqMsg::values_size() const { + return values_.size(); +} +inline void FesDebugToolSimDefCmdReqMsg::clear_values() { + values_.Clear(); +} +inline const ::std::string& FesDebugToolSimDefCmdReqMsg::values(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSimDefCmdReqMsg.values) + return values_.Get(index); +} +inline ::std::string* FesDebugToolSimDefCmdReqMsg::mutable_values(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolSimDefCmdReqMsg.values) + return values_.Mutable(index); +} +inline void FesDebugToolSimDefCmdReqMsg::set_values(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSimDefCmdReqMsg.values) + values_.Mutable(index)->assign(value); +} +inline void FesDebugToolSimDefCmdReqMsg::set_values(int index, const char* value) { + values_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolSimDefCmdReqMsg.values) +} +inline void FesDebugToolSimDefCmdReqMsg::set_values(int index, const char* value, size_t size) { + values_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolSimDefCmdReqMsg.values) +} +inline ::std::string* FesDebugToolSimDefCmdReqMsg::add_values() { + return values_.Add(); +} +inline void FesDebugToolSimDefCmdReqMsg::add_values(const ::std::string& value) { + values_.Add()->assign(value); + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolSimDefCmdReqMsg.values) +} +inline void FesDebugToolSimDefCmdReqMsg::add_values(const char* value) { + values_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:iot_idl.FesDebugToolSimDefCmdReqMsg.values) +} +inline void FesDebugToolSimDefCmdReqMsg::add_values(const char* value, size_t size) { + values_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:iot_idl.FesDebugToolSimDefCmdReqMsg.values) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +FesDebugToolSimDefCmdReqMsg::values() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolSimDefCmdReqMsg.values) + return values_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +FesDebugToolSimDefCmdReqMsg::mutable_values() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolSimDefCmdReqMsg.values) + return &values_; +} + +// ------------------------------------------------------------------- + +// FesDebugToolFwPntParam + +// required int32 pnt_no = 1; +inline bool FesDebugToolFwPntParam::has_pnt_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolFwPntParam::set_has_pnt_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolFwPntParam::clear_has_pnt_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolFwPntParam::clear_pnt_no() { + pnt_no_ = 0; + clear_has_pnt_no(); +} +inline ::google::protobuf::int32 FesDebugToolFwPntParam::pnt_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolFwPntParam.pnt_no) + return pnt_no_; +} +inline void FesDebugToolFwPntParam::set_pnt_no(::google::protobuf::int32 value) { + set_has_pnt_no(); + pnt_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolFwPntParam.pnt_no) +} + +// required int32 used = 2; +inline bool FesDebugToolFwPntParam::has_used() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolFwPntParam::set_has_used() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolFwPntParam::clear_has_used() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolFwPntParam::clear_used() { + used_ = 0; + clear_has_used(); +} +inline ::google::protobuf::int32 FesDebugToolFwPntParam::used() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolFwPntParam.used) + return used_; +} +inline void FesDebugToolFwPntParam::set_used(::google::protobuf::int32 value) { + set_has_used(); + used_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolFwPntParam.used) +} + +// required int32 fes_rtu_no = 3; +inline bool FesDebugToolFwPntParam::has_fes_rtu_no() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolFwPntParam::set_has_fes_rtu_no() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolFwPntParam::clear_has_fes_rtu_no() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolFwPntParam::clear_fes_rtu_no() { + fes_rtu_no_ = 0; + clear_has_fes_rtu_no(); +} +inline ::google::protobuf::int32 FesDebugToolFwPntParam::fes_rtu_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolFwPntParam.fes_rtu_no) + return fes_rtu_no_; +} +inline void FesDebugToolFwPntParam::set_fes_rtu_no(::google::protobuf::int32 value) { + set_has_fes_rtu_no(); + fes_rtu_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolFwPntParam.fes_rtu_no) +} + +// required int32 fes_pnt_no = 4; +inline bool FesDebugToolFwPntParam::has_fes_pnt_no() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolFwPntParam::set_has_fes_pnt_no() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolFwPntParam::clear_has_fes_pnt_no() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolFwPntParam::clear_fes_pnt_no() { + fes_pnt_no_ = 0; + clear_has_fes_pnt_no(); +} +inline ::google::protobuf::int32 FesDebugToolFwPntParam::fes_pnt_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolFwPntParam.fes_pnt_no) + return fes_pnt_no_; +} +inline void FesDebugToolFwPntParam::set_fes_pnt_no(::google::protobuf::int32 value) { + set_has_fes_pnt_no(); + fes_pnt_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolFwPntParam.fes_pnt_no) +} + +// required string pnt_desc = 5; +inline bool FesDebugToolFwPntParam::has_pnt_desc() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FesDebugToolFwPntParam::set_has_pnt_desc() { + _has_bits_[0] |= 0x00000010u; +} +inline void FesDebugToolFwPntParam::clear_has_pnt_desc() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FesDebugToolFwPntParam::clear_pnt_desc() { + if (pnt_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + pnt_desc_->clear(); + } + clear_has_pnt_desc(); +} +inline const ::std::string& FesDebugToolFwPntParam::pnt_desc() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolFwPntParam.pnt_desc) + return *pnt_desc_; +} +inline void FesDebugToolFwPntParam::set_pnt_desc(const ::std::string& value) { + set_has_pnt_desc(); + if (pnt_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + pnt_desc_ = new ::std::string; + } + pnt_desc_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolFwPntParam.pnt_desc) +} +inline void FesDebugToolFwPntParam::set_pnt_desc(const char* value) { + set_has_pnt_desc(); + if (pnt_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + pnt_desc_ = new ::std::string; + } + pnt_desc_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolFwPntParam.pnt_desc) +} +inline void FesDebugToolFwPntParam::set_pnt_desc(const char* value, size_t size) { + set_has_pnt_desc(); + if (pnt_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + pnt_desc_ = new ::std::string; + } + pnt_desc_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolFwPntParam.pnt_desc) +} +inline ::std::string* FesDebugToolFwPntParam::mutable_pnt_desc() { + set_has_pnt_desc(); + if (pnt_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + pnt_desc_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolFwPntParam.pnt_desc) + return pnt_desc_; +} +inline ::std::string* FesDebugToolFwPntParam::release_pnt_desc() { + clear_has_pnt_desc(); + if (pnt_desc_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = pnt_desc_; + pnt_desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolFwPntParam::set_allocated_pnt_desc(::std::string* pnt_desc) { + if (pnt_desc_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete pnt_desc_; + } + if (pnt_desc) { + set_has_pnt_desc(); + pnt_desc_ = pnt_desc; + } else { + clear_has_pnt_desc(); + pnt_desc_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolFwPntParam.pnt_desc) +} + +// ------------------------------------------------------------------- + +// FesDebugToolFwPntParamRepMsg + +// required int32 rtu_no = 1; +inline bool FesDebugToolFwPntParamRepMsg::has_rtu_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolFwPntParamRepMsg::set_has_rtu_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolFwPntParamRepMsg::clear_has_rtu_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolFwPntParamRepMsg::clear_rtu_no() { + rtu_no_ = 0; + clear_has_rtu_no(); +} +inline ::google::protobuf::int32 FesDebugToolFwPntParamRepMsg::rtu_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolFwPntParamRepMsg.rtu_no) + return rtu_no_; +} +inline void FesDebugToolFwPntParamRepMsg::set_rtu_no(::google::protobuf::int32 value) { + set_has_rtu_no(); + rtu_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolFwPntParamRepMsg.rtu_no) +} + +// required int32 max_pnt_num = 2; +inline bool FesDebugToolFwPntParamRepMsg::has_max_pnt_num() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolFwPntParamRepMsg::set_has_max_pnt_num() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolFwPntParamRepMsg::clear_has_max_pnt_num() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolFwPntParamRepMsg::clear_max_pnt_num() { + max_pnt_num_ = 0; + clear_has_max_pnt_num(); +} +inline ::google::protobuf::int32 FesDebugToolFwPntParamRepMsg::max_pnt_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolFwPntParamRepMsg.max_pnt_num) + return max_pnt_num_; +} +inline void FesDebugToolFwPntParamRepMsg::set_max_pnt_num(::google::protobuf::int32 value) { + set_has_max_pnt_num(); + max_pnt_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolFwPntParamRepMsg.max_pnt_num) +} + +// repeated .iot_idl.FesDebugToolFwPntParam pnt_param = 3; +inline int FesDebugToolFwPntParamRepMsg::pnt_param_size() const { + return pnt_param_.size(); +} +inline void FesDebugToolFwPntParamRepMsg::clear_pnt_param() { + pnt_param_.Clear(); +} +inline const ::iot_idl::FesDebugToolFwPntParam& FesDebugToolFwPntParamRepMsg::pnt_param(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolFwPntParamRepMsg.pnt_param) + return pnt_param_.Get(index); +} +inline ::iot_idl::FesDebugToolFwPntParam* FesDebugToolFwPntParamRepMsg::mutable_pnt_param(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolFwPntParamRepMsg.pnt_param) + return pnt_param_.Mutable(index); +} +inline ::iot_idl::FesDebugToolFwPntParam* FesDebugToolFwPntParamRepMsg::add_pnt_param() { + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolFwPntParamRepMsg.pnt_param) + return pnt_param_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolFwPntParam >& +FesDebugToolFwPntParamRepMsg::pnt_param() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolFwPntParamRepMsg.pnt_param) + return pnt_param_; +} +inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolFwPntParam >* +FesDebugToolFwPntParamRepMsg::mutable_pnt_param() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolFwPntParamRepMsg.pnt_param) + return &pnt_param_; +} + +// ------------------------------------------------------------------- + +// FesDebugToolSoeEvent + +// required string table_name = 1; +inline bool FesDebugToolSoeEvent::has_table_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolSoeEvent::set_has_table_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolSoeEvent::clear_has_table_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolSoeEvent::clear_table_name() { + if (table_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + table_name_->clear(); + } + clear_has_table_name(); +} +inline const ::std::string& FesDebugToolSoeEvent::table_name() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSoeEvent.table_name) + return *table_name_; +} +inline void FesDebugToolSoeEvent::set_table_name(const ::std::string& value) { + set_has_table_name(); + if (table_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + table_name_ = new ::std::string; + } + table_name_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSoeEvent.table_name) +} +inline void FesDebugToolSoeEvent::set_table_name(const char* value) { + set_has_table_name(); + if (table_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + table_name_ = new ::std::string; + } + table_name_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolSoeEvent.table_name) +} +inline void FesDebugToolSoeEvent::set_table_name(const char* value, size_t size) { + set_has_table_name(); + if (table_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + table_name_ = new ::std::string; + } + table_name_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolSoeEvent.table_name) +} +inline ::std::string* FesDebugToolSoeEvent::mutable_table_name() { + set_has_table_name(); + if (table_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + table_name_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolSoeEvent.table_name) + return table_name_; +} +inline ::std::string* FesDebugToolSoeEvent::release_table_name() { + clear_has_table_name(); + if (table_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = table_name_; + table_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolSoeEvent::set_allocated_table_name(::std::string* table_name) { + if (table_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete table_name_; + } + if (table_name) { + set_has_table_name(); + table_name_ = table_name; + } else { + clear_has_table_name(); + table_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolSoeEvent.table_name) +} + +// required string col_name = 2; +inline bool FesDebugToolSoeEvent::has_col_name() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolSoeEvent::set_has_col_name() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolSoeEvent::clear_has_col_name() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolSoeEvent::clear_col_name() { + if (col_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + col_name_->clear(); + } + clear_has_col_name(); +} +inline const ::std::string& FesDebugToolSoeEvent::col_name() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSoeEvent.col_name) + return *col_name_; +} +inline void FesDebugToolSoeEvent::set_col_name(const ::std::string& value) { + set_has_col_name(); + if (col_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + col_name_ = new ::std::string; + } + col_name_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSoeEvent.col_name) +} +inline void FesDebugToolSoeEvent::set_col_name(const char* value) { + set_has_col_name(); + if (col_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + col_name_ = new ::std::string; + } + col_name_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolSoeEvent.col_name) +} +inline void FesDebugToolSoeEvent::set_col_name(const char* value, size_t size) { + set_has_col_name(); + if (col_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + col_name_ = new ::std::string; + } + col_name_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolSoeEvent.col_name) +} +inline ::std::string* FesDebugToolSoeEvent::mutable_col_name() { + set_has_col_name(); + if (col_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + col_name_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolSoeEvent.col_name) + return col_name_; +} +inline ::std::string* FesDebugToolSoeEvent::release_col_name() { + clear_has_col_name(); + if (col_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = col_name_; + col_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolSoeEvent::set_allocated_col_name(::std::string* col_name) { + if (col_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete col_name_; + } + if (col_name) { + set_has_col_name(); + col_name_ = col_name; + } else { + clear_has_col_name(); + col_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolSoeEvent.col_name) +} + +// required string tag_name = 3; +inline bool FesDebugToolSoeEvent::has_tag_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolSoeEvent::set_has_tag_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolSoeEvent::clear_has_tag_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolSoeEvent::clear_tag_name() { + if (tag_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_->clear(); + } + clear_has_tag_name(); +} +inline const ::std::string& FesDebugToolSoeEvent::tag_name() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSoeEvent.tag_name) + return *tag_name_; +} +inline void FesDebugToolSoeEvent::set_tag_name(const ::std::string& value) { + set_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_ = new ::std::string; + } + tag_name_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSoeEvent.tag_name) +} +inline void FesDebugToolSoeEvent::set_tag_name(const char* value) { + set_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_ = new ::std::string; + } + tag_name_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolSoeEvent.tag_name) +} +inline void FesDebugToolSoeEvent::set_tag_name(const char* value, size_t size) { + set_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_ = new ::std::string; + } + tag_name_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolSoeEvent.tag_name) +} +inline ::std::string* FesDebugToolSoeEvent::mutable_tag_name() { + set_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolSoeEvent.tag_name) + return tag_name_; +} +inline ::std::string* FesDebugToolSoeEvent::release_tag_name() { + clear_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = tag_name_; + tag_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolSoeEvent::set_allocated_tag_name(::std::string* tag_name) { + if (tag_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete tag_name_; + } + if (tag_name) { + set_has_tag_name(); + tag_name_ = tag_name; + } else { + clear_has_tag_name(); + tag_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolSoeEvent.tag_name) +} + +// required uint32 status = 4; +inline bool FesDebugToolSoeEvent::has_status() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolSoeEvent::set_has_status() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolSoeEvent::clear_has_status() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolSoeEvent::clear_status() { + status_ = 0u; + clear_has_status(); +} +inline ::google::protobuf::uint32 FesDebugToolSoeEvent::status() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSoeEvent.status) + return status_; +} +inline void FesDebugToolSoeEvent::set_status(::google::protobuf::uint32 value) { + set_has_status(); + status_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSoeEvent.status) +} + +// required int32 value = 5; +inline bool FesDebugToolSoeEvent::has_value() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FesDebugToolSoeEvent::set_has_value() { + _has_bits_[0] |= 0x00000010u; +} +inline void FesDebugToolSoeEvent::clear_has_value() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FesDebugToolSoeEvent::clear_value() { + value_ = 0; + clear_has_value(); +} +inline ::google::protobuf::int32 FesDebugToolSoeEvent::value() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSoeEvent.value) + return value_; +} +inline void FesDebugToolSoeEvent::set_value(::google::protobuf::int32 value) { + set_has_value(); + value_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSoeEvent.value) +} + +// required uint64 time = 6; +inline bool FesDebugToolSoeEvent::has_time() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FesDebugToolSoeEvent::set_has_time() { + _has_bits_[0] |= 0x00000020u; +} +inline void FesDebugToolSoeEvent::clear_has_time() { + _has_bits_[0] &= ~0x00000020u; +} +inline void FesDebugToolSoeEvent::clear_time() { + time_ = GOOGLE_ULONGLONG(0); + clear_has_time(); +} +inline ::google::protobuf::uint64 FesDebugToolSoeEvent::time() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSoeEvent.time) + return time_; +} +inline void FesDebugToolSoeEvent::set_time(::google::protobuf::uint64 value) { + set_has_time(); + time_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSoeEvent.time) +} + +// required int32 fault_num = 7; +inline bool FesDebugToolSoeEvent::has_fault_num() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void FesDebugToolSoeEvent::set_has_fault_num() { + _has_bits_[0] |= 0x00000040u; +} +inline void FesDebugToolSoeEvent::clear_has_fault_num() { + _has_bits_[0] &= ~0x00000040u; +} +inline void FesDebugToolSoeEvent::clear_fault_num() { + fault_num_ = 0; + clear_has_fault_num(); +} +inline ::google::protobuf::int32 FesDebugToolSoeEvent::fault_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSoeEvent.fault_num) + return fault_num_; +} +inline void FesDebugToolSoeEvent::set_fault_num(::google::protobuf::int32 value) { + set_has_fault_num(); + fault_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSoeEvent.fault_num) +} + +// repeated int32 fault_type = 8; +inline int FesDebugToolSoeEvent::fault_type_size() const { + return fault_type_.size(); +} +inline void FesDebugToolSoeEvent::clear_fault_type() { + fault_type_.Clear(); +} +inline ::google::protobuf::int32 FesDebugToolSoeEvent::fault_type(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSoeEvent.fault_type) + return fault_type_.Get(index); +} +inline void FesDebugToolSoeEvent::set_fault_type(int index, ::google::protobuf::int32 value) { + fault_type_.Set(index, value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSoeEvent.fault_type) +} +inline void FesDebugToolSoeEvent::add_fault_type(::google::protobuf::int32 value) { + fault_type_.Add(value); + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolSoeEvent.fault_type) +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +FesDebugToolSoeEvent::fault_type() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolSoeEvent.fault_type) + return fault_type_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +FesDebugToolSoeEvent::mutable_fault_type() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolSoeEvent.fault_type) + return &fault_type_; +} + +// repeated float fault_value = 9; +inline int FesDebugToolSoeEvent::fault_value_size() const { + return fault_value_.size(); +} +inline void FesDebugToolSoeEvent::clear_fault_value() { + fault_value_.Clear(); +} +inline float FesDebugToolSoeEvent::fault_value(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSoeEvent.fault_value) + return fault_value_.Get(index); +} +inline void FesDebugToolSoeEvent::set_fault_value(int index, float value) { + fault_value_.Set(index, value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSoeEvent.fault_value) +} +inline void FesDebugToolSoeEvent::add_fault_value(float value) { + fault_value_.Add(value); + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolSoeEvent.fault_value) +} +inline const ::google::protobuf::RepeatedField< float >& +FesDebugToolSoeEvent::fault_value() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolSoeEvent.fault_value) + return fault_value_; +} +inline ::google::protobuf::RepeatedField< float >* +FesDebugToolSoeEvent::mutable_fault_value() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolSoeEvent.fault_value) + return &fault_value_; +} + +// ------------------------------------------------------------------- + +// FesDebugToolSoeEventRepMsg + +// required int32 over_flow = 1; +inline bool FesDebugToolSoeEventRepMsg::has_over_flow() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolSoeEventRepMsg::set_has_over_flow() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolSoeEventRepMsg::clear_has_over_flow() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolSoeEventRepMsg::clear_over_flow() { + over_flow_ = 0; + clear_has_over_flow(); +} +inline ::google::protobuf::int32 FesDebugToolSoeEventRepMsg::over_flow() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSoeEventRepMsg.over_flow) + return over_flow_; +} +inline void FesDebugToolSoeEventRepMsg::set_over_flow(::google::protobuf::int32 value) { + set_has_over_flow(); + over_flow_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolSoeEventRepMsg.over_flow) +} + +// repeated .iot_idl.FesDebugToolSoeEvent event = 2; +inline int FesDebugToolSoeEventRepMsg::event_size() const { + return event_.size(); +} +inline void FesDebugToolSoeEventRepMsg::clear_event() { + event_.Clear(); +} +inline const ::iot_idl::FesDebugToolSoeEvent& FesDebugToolSoeEventRepMsg::event(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolSoeEventRepMsg.event) + return event_.Get(index); +} +inline ::iot_idl::FesDebugToolSoeEvent* FesDebugToolSoeEventRepMsg::mutable_event(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolSoeEventRepMsg.event) + return event_.Mutable(index); +} +inline ::iot_idl::FesDebugToolSoeEvent* FesDebugToolSoeEventRepMsg::add_event() { + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolSoeEventRepMsg.event) + return event_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolSoeEvent >& +FesDebugToolSoeEventRepMsg::event() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolSoeEventRepMsg.event) + return event_; +} +inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolSoeEvent >* +FesDebugToolSoeEventRepMsg::mutable_event() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolSoeEventRepMsg.event) + return &event_; +} + +// ------------------------------------------------------------------- + +// FesDebugToolChanEvent + +// required string tag_name = 1; +inline bool FesDebugToolChanEvent::has_tag_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolChanEvent::set_has_tag_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolChanEvent::clear_has_tag_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolChanEvent::clear_tag_name() { + if (tag_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_->clear(); + } + clear_has_tag_name(); +} +inline const ::std::string& FesDebugToolChanEvent::tag_name() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanEvent.tag_name) + return *tag_name_; +} +inline void FesDebugToolChanEvent::set_tag_name(const ::std::string& value) { + set_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_ = new ::std::string; + } + tag_name_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanEvent.tag_name) +} +inline void FesDebugToolChanEvent::set_tag_name(const char* value) { + set_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_ = new ::std::string; + } + tag_name_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolChanEvent.tag_name) +} +inline void FesDebugToolChanEvent::set_tag_name(const char* value, size_t size) { + set_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_ = new ::std::string; + } + tag_name_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolChanEvent.tag_name) +} +inline ::std::string* FesDebugToolChanEvent::mutable_tag_name() { + set_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tag_name_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolChanEvent.tag_name) + return tag_name_; +} +inline ::std::string* FesDebugToolChanEvent::release_tag_name() { + clear_has_tag_name(); + if (tag_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = tag_name_; + tag_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolChanEvent::set_allocated_tag_name(::std::string* tag_name) { + if (tag_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete tag_name_; + } + if (tag_name) { + set_has_tag_name(); + tag_name_ = tag_name; + } else { + clear_has_tag_name(); + tag_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolChanEvent.tag_name) +} + +// required uint32 status = 2; +inline bool FesDebugToolChanEvent::has_status() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolChanEvent::set_has_status() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolChanEvent::clear_has_status() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolChanEvent::clear_status() { + status_ = 0u; + clear_has_status(); +} +inline ::google::protobuf::uint32 FesDebugToolChanEvent::status() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanEvent.status) + return status_; +} +inline void FesDebugToolChanEvent::set_status(::google::protobuf::uint32 value) { + set_has_status(); + status_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanEvent.status) +} + +// required float err_rate = 3; +inline bool FesDebugToolChanEvent::has_err_rate() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolChanEvent::set_has_err_rate() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolChanEvent::clear_has_err_rate() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolChanEvent::clear_err_rate() { + err_rate_ = 0; + clear_has_err_rate(); +} +inline float FesDebugToolChanEvent::err_rate() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanEvent.err_rate) + return err_rate_; +} +inline void FesDebugToolChanEvent::set_err_rate(float value) { + set_has_err_rate(); + err_rate_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanEvent.err_rate) +} + +// required uint64 time = 4; +inline bool FesDebugToolChanEvent::has_time() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolChanEvent::set_has_time() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolChanEvent::clear_has_time() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolChanEvent::clear_time() { + time_ = GOOGLE_ULONGLONG(0); + clear_has_time(); +} +inline ::google::protobuf::uint64 FesDebugToolChanEvent::time() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanEvent.time) + return time_; +} +inline void FesDebugToolChanEvent::set_time(::google::protobuf::uint64 value) { + set_has_time(); + time_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanEvent.time) +} + +// ------------------------------------------------------------------- + +// FesDebugToolChanEventRepMsg + +// required int32 over_flow = 1; +inline bool FesDebugToolChanEventRepMsg::has_over_flow() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolChanEventRepMsg::set_has_over_flow() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolChanEventRepMsg::clear_has_over_flow() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolChanEventRepMsg::clear_over_flow() { + over_flow_ = 0; + clear_has_over_flow(); +} +inline ::google::protobuf::int32 FesDebugToolChanEventRepMsg::over_flow() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanEventRepMsg.over_flow) + return over_flow_; +} +inline void FesDebugToolChanEventRepMsg::set_over_flow(::google::protobuf::int32 value) { + set_has_over_flow(); + over_flow_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanEventRepMsg.over_flow) +} + +// repeated .iot_idl.FesDebugToolChanEvent event = 2; +inline int FesDebugToolChanEventRepMsg::event_size() const { + return event_.size(); +} +inline void FesDebugToolChanEventRepMsg::clear_event() { + event_.Clear(); +} +inline const ::iot_idl::FesDebugToolChanEvent& FesDebugToolChanEventRepMsg::event(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanEventRepMsg.event) + return event_.Get(index); +} +inline ::iot_idl::FesDebugToolChanEvent* FesDebugToolChanEventRepMsg::mutable_event(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolChanEventRepMsg.event) + return event_.Mutable(index); +} +inline ::iot_idl::FesDebugToolChanEvent* FesDebugToolChanEventRepMsg::add_event() { + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolChanEventRepMsg.event) + return event_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanEvent >& +FesDebugToolChanEventRepMsg::event() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolChanEventRepMsg.event) + return event_; +} +inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanEvent >* +FesDebugToolChanEventRepMsg::mutable_event() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolChanEventRepMsg.event) + return &event_; +} + +// ------------------------------------------------------------------- + +// FesDebugToolChanMonCmdReqMsg + +// required int32 chan_no = 1; +inline bool FesDebugToolChanMonCmdReqMsg::has_chan_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolChanMonCmdReqMsg::set_has_chan_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolChanMonCmdReqMsg::clear_has_chan_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolChanMonCmdReqMsg::clear_chan_no() { + chan_no_ = 0; + clear_has_chan_no(); +} +inline ::google::protobuf::int32 FesDebugToolChanMonCmdReqMsg::chan_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonCmdReqMsg.chan_no) + return chan_no_; +} +inline void FesDebugToolChanMonCmdReqMsg::set_chan_no(::google::protobuf::int32 value) { + set_has_chan_no(); + chan_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonCmdReqMsg.chan_no) +} + +// ------------------------------------------------------------------- + +// FesDebugToolChanMonCmdRepMsg + +// required int32 chan_no = 1; +inline bool FesDebugToolChanMonCmdRepMsg::has_chan_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolChanMonCmdRepMsg::set_has_chan_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolChanMonCmdRepMsg::clear_has_chan_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolChanMonCmdRepMsg::clear_chan_no() { + chan_no_ = 0; + clear_has_chan_no(); +} +inline ::google::protobuf::int32 FesDebugToolChanMonCmdRepMsg::chan_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonCmdRepMsg.chan_no) + return chan_no_; +} +inline void FesDebugToolChanMonCmdRepMsg::set_chan_no(::google::protobuf::int32 value) { + set_has_chan_no(); + chan_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonCmdRepMsg.chan_no) +} + +// optional int32 rx_num = 2; +inline bool FesDebugToolChanMonCmdRepMsg::has_rx_num() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolChanMonCmdRepMsg::set_has_rx_num() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolChanMonCmdRepMsg::clear_has_rx_num() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolChanMonCmdRepMsg::clear_rx_num() { + rx_num_ = 0; + clear_has_rx_num(); +} +inline ::google::protobuf::int32 FesDebugToolChanMonCmdRepMsg::rx_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonCmdRepMsg.rx_num) + return rx_num_; +} +inline void FesDebugToolChanMonCmdRepMsg::set_rx_num(::google::protobuf::int32 value) { + set_has_rx_num(); + rx_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonCmdRepMsg.rx_num) +} + +// optional int32 tx_num = 3; +inline bool FesDebugToolChanMonCmdRepMsg::has_tx_num() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolChanMonCmdRepMsg::set_has_tx_num() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolChanMonCmdRepMsg::clear_has_tx_num() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolChanMonCmdRepMsg::clear_tx_num() { + tx_num_ = 0; + clear_has_tx_num(); +} +inline ::google::protobuf::int32 FesDebugToolChanMonCmdRepMsg::tx_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonCmdRepMsg.tx_num) + return tx_num_; +} +inline void FesDebugToolChanMonCmdRepMsg::set_tx_num(::google::protobuf::int32 value) { + set_has_tx_num(); + tx_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonCmdRepMsg.tx_num) +} + +// optional int32 err_num = 4; +inline bool FesDebugToolChanMonCmdRepMsg::has_err_num() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolChanMonCmdRepMsg::set_has_err_num() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolChanMonCmdRepMsg::clear_has_err_num() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolChanMonCmdRepMsg::clear_err_num() { + err_num_ = 0; + clear_has_err_num(); +} +inline ::google::protobuf::int32 FesDebugToolChanMonCmdRepMsg::err_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonCmdRepMsg.err_num) + return err_num_; +} +inline void FesDebugToolChanMonCmdRepMsg::set_err_num(::google::protobuf::int32 value) { + set_has_err_num(); + err_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonCmdRepMsg.err_num) +} + +// ------------------------------------------------------------------- + +// FesDebugToolChanMonFrame + +// required int32 frame_type = 1; +inline bool FesDebugToolChanMonFrame::has_frame_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolChanMonFrame::set_has_frame_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolChanMonFrame::clear_has_frame_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolChanMonFrame::clear_frame_type() { + frame_type_ = 0; + clear_has_frame_type(); +} +inline ::google::protobuf::int32 FesDebugToolChanMonFrame::frame_type() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonFrame.frame_type) + return frame_type_; +} +inline void FesDebugToolChanMonFrame::set_frame_type(::google::protobuf::int32 value) { + set_has_frame_type(); + frame_type_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonFrame.frame_type) +} + +// required int32 data_type = 2; +inline bool FesDebugToolChanMonFrame::has_data_type() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolChanMonFrame::set_has_data_type() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolChanMonFrame::clear_has_data_type() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolChanMonFrame::clear_data_type() { + data_type_ = 0; + clear_has_data_type(); +} +inline ::google::protobuf::int32 FesDebugToolChanMonFrame::data_type() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonFrame.data_type) + return data_type_; +} +inline void FesDebugToolChanMonFrame::set_data_type(::google::protobuf::int32 value) { + set_has_data_type(); + data_type_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonFrame.data_type) +} + +// required uint64 time = 3; +inline bool FesDebugToolChanMonFrame::has_time() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolChanMonFrame::set_has_time() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolChanMonFrame::clear_has_time() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolChanMonFrame::clear_time() { + time_ = GOOGLE_ULONGLONG(0); + clear_has_time(); +} +inline ::google::protobuf::uint64 FesDebugToolChanMonFrame::time() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonFrame.time) + return time_; +} +inline void FesDebugToolChanMonFrame::set_time(::google::protobuf::uint64 value) { + set_has_time(); + time_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonFrame.time) +} + +// required bytes data = 4; +inline bool FesDebugToolChanMonFrame::has_data() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolChanMonFrame::set_has_data() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolChanMonFrame::clear_has_data() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolChanMonFrame::clear_data() { + if (data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + data_->clear(); + } + clear_has_data(); +} +inline const ::std::string& FesDebugToolChanMonFrame::data() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonFrame.data) + return *data_; +} +inline void FesDebugToolChanMonFrame::set_data(const ::std::string& value) { + set_has_data(); + if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + data_ = new ::std::string; + } + data_->assign(value); + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonFrame.data) +} +inline void FesDebugToolChanMonFrame::set_data(const char* value) { + set_has_data(); + if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + data_ = new ::std::string; + } + data_->assign(value); + // @@protoc_insertion_point(field_set_char:iot_idl.FesDebugToolChanMonFrame.data) +} +inline void FesDebugToolChanMonFrame::set_data(const void* value, size_t size) { + set_has_data(); + if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + data_ = new ::std::string; + } + data_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:iot_idl.FesDebugToolChanMonFrame.data) +} +inline ::std::string* FesDebugToolChanMonFrame::mutable_data() { + set_has_data(); + if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + data_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolChanMonFrame.data) + return data_; +} +inline ::std::string* FesDebugToolChanMonFrame::release_data() { + clear_has_data(); + if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = data_; + data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void FesDebugToolChanMonFrame::set_allocated_data(::std::string* data) { + if (data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete data_; + } + if (data) { + set_has_data(); + data_ = data; + } else { + clear_has_data(); + data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:iot_idl.FesDebugToolChanMonFrame.data) +} + +// ------------------------------------------------------------------- + +// FesDebugToolChanMonInfoMsg + +// required int32 chan_no = 1; +inline bool FesDebugToolChanMonInfoMsg::has_chan_no() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FesDebugToolChanMonInfoMsg::set_has_chan_no() { + _has_bits_[0] |= 0x00000001u; +} +inline void FesDebugToolChanMonInfoMsg::clear_has_chan_no() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FesDebugToolChanMonInfoMsg::clear_chan_no() { + chan_no_ = 0; + clear_has_chan_no(); +} +inline ::google::protobuf::int32 FesDebugToolChanMonInfoMsg::chan_no() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonInfoMsg.chan_no) + return chan_no_; +} +inline void FesDebugToolChanMonInfoMsg::set_chan_no(::google::protobuf::int32 value) { + set_has_chan_no(); + chan_no_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonInfoMsg.chan_no) +} + +// required int32 rx_num = 2; +inline bool FesDebugToolChanMonInfoMsg::has_rx_num() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FesDebugToolChanMonInfoMsg::set_has_rx_num() { + _has_bits_[0] |= 0x00000002u; +} +inline void FesDebugToolChanMonInfoMsg::clear_has_rx_num() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FesDebugToolChanMonInfoMsg::clear_rx_num() { + rx_num_ = 0; + clear_has_rx_num(); +} +inline ::google::protobuf::int32 FesDebugToolChanMonInfoMsg::rx_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonInfoMsg.rx_num) + return rx_num_; +} +inline void FesDebugToolChanMonInfoMsg::set_rx_num(::google::protobuf::int32 value) { + set_has_rx_num(); + rx_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonInfoMsg.rx_num) +} + +// required int32 tx_num = 3; +inline bool FesDebugToolChanMonInfoMsg::has_tx_num() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FesDebugToolChanMonInfoMsg::set_has_tx_num() { + _has_bits_[0] |= 0x00000004u; +} +inline void FesDebugToolChanMonInfoMsg::clear_has_tx_num() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FesDebugToolChanMonInfoMsg::clear_tx_num() { + tx_num_ = 0; + clear_has_tx_num(); +} +inline ::google::protobuf::int32 FesDebugToolChanMonInfoMsg::tx_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonInfoMsg.tx_num) + return tx_num_; +} +inline void FesDebugToolChanMonInfoMsg::set_tx_num(::google::protobuf::int32 value) { + set_has_tx_num(); + tx_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonInfoMsg.tx_num) +} + +// required int32 err_num = 4; +inline bool FesDebugToolChanMonInfoMsg::has_err_num() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FesDebugToolChanMonInfoMsg::set_has_err_num() { + _has_bits_[0] |= 0x00000008u; +} +inline void FesDebugToolChanMonInfoMsg::clear_has_err_num() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FesDebugToolChanMonInfoMsg::clear_err_num() { + err_num_ = 0; + clear_has_err_num(); +} +inline ::google::protobuf::int32 FesDebugToolChanMonInfoMsg::err_num() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonInfoMsg.err_num) + return err_num_; +} +inline void FesDebugToolChanMonInfoMsg::set_err_num(::google::protobuf::int32 value) { + set_has_err_num(); + err_num_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonInfoMsg.err_num) +} + +// required int32 over_flow = 5; +inline bool FesDebugToolChanMonInfoMsg::has_over_flow() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FesDebugToolChanMonInfoMsg::set_has_over_flow() { + _has_bits_[0] |= 0x00000010u; +} +inline void FesDebugToolChanMonInfoMsg::clear_has_over_flow() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FesDebugToolChanMonInfoMsg::clear_over_flow() { + over_flow_ = 0; + clear_has_over_flow(); +} +inline ::google::protobuf::int32 FesDebugToolChanMonInfoMsg::over_flow() const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonInfoMsg.over_flow) + return over_flow_; +} +inline void FesDebugToolChanMonInfoMsg::set_over_flow(::google::protobuf::int32 value) { + set_has_over_flow(); + over_flow_ = value; + // @@protoc_insertion_point(field_set:iot_idl.FesDebugToolChanMonInfoMsg.over_flow) +} + +// repeated .iot_idl.FesDebugToolChanMonFrame frame = 6; +inline int FesDebugToolChanMonInfoMsg::frame_size() const { + return frame_.size(); +} +inline void FesDebugToolChanMonInfoMsg::clear_frame() { + frame_.Clear(); +} +inline const ::iot_idl::FesDebugToolChanMonFrame& FesDebugToolChanMonInfoMsg::frame(int index) const { + // @@protoc_insertion_point(field_get:iot_idl.FesDebugToolChanMonInfoMsg.frame) + return frame_.Get(index); +} +inline ::iot_idl::FesDebugToolChanMonFrame* FesDebugToolChanMonInfoMsg::mutable_frame(int index) { + // @@protoc_insertion_point(field_mutable:iot_idl.FesDebugToolChanMonInfoMsg.frame) + return frame_.Mutable(index); +} +inline ::iot_idl::FesDebugToolChanMonFrame* FesDebugToolChanMonInfoMsg::add_frame() { + // @@protoc_insertion_point(field_add:iot_idl.FesDebugToolChanMonInfoMsg.frame) + return frame_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanMonFrame >& +FesDebugToolChanMonInfoMsg::frame() const { + // @@protoc_insertion_point(field_list:iot_idl.FesDebugToolChanMonInfoMsg.frame) + return frame_; +} +inline ::google::protobuf::RepeatedPtrField< ::iot_idl::FesDebugToolChanMonFrame >* +FesDebugToolChanMonInfoMsg::mutable_frame() { + // @@protoc_insertion_point(field_mutable_list:iot_idl.FesDebugToolChanMonInfoMsg.frame) + return &frame_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace iot_idl + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::iot_idl::enFesDebugMsgType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::iot_idl::enFesDebugMsgType>() { + return ::iot_idl::enFesDebugMsgType_descriptor(); +} +template <> struct is_proto_enum< ::iot_idl::enFesDebugSimMode> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::iot_idl::enFesDebugSimMode>() { + return ::iot_idl::enFesDebugSimMode_descriptor(); +} +template <> struct is_proto_enum< ::iot_idl::enFesDebugSimRangeType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::iot_idl::enFesDebugSimRangeType>() { + return ::iot_idl::enFesDebugSimRangeType_descriptor(); +} +template <> struct is_proto_enum< ::iot_idl::enFesDebugEventSimType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::iot_idl::enFesDebugEventSimType>() { + return ::iot_idl::enFesDebugEventSimType_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_FesDebugTool_2eproto__INCLUDED diff --git a/product/src/fes/fes_idl_files/FesDebugTool.proto b/product/src/fes/fes_idl_files/FesDebugTool.proto new file mode 100644 index 00000000..7faf2dd8 --- /dev/null +++ b/product/src/fes/fes_idl_files/FesDebugTool.proto @@ -0,0 +1,465 @@ +//====================================================================================== +// @file FesDebugTool.proto +// @brief 用于debug_tool与fes交互 +// @author caodingfa +//====================================================================================== + +syntax="proto2"; +package iot_idl; + +//======================================================================================== +// 调试命令消息类型枚举 +//======================================================================================== + +enum enFesDebugMsgType +{ + MT_FESDBG_HeartBeat = 0; + MT_FESDBG_CONNECT = 1; + MT_FESDBG_DISCONNECT = 2; + + MT_FESDBG_ChanParam = 5; + MT_FESDBG_RtuParam = 6; + + MT_FESDBG_AI_RtuInfo = 10; + MT_FESDBG_AI_Param = 11; + MT_FESDBG_AI_Value = 12; + + MT_FESDBG_DI_RtuInfo = 20; + MT_FESDBG_DI_Param = 21; + MT_FESDBG_DI_Value = 22; + + MT_FESDBG_ACC_RtuInfo = 30; + MT_FESDBG_ACC_Param = 31; + MT_FESDBG_ACC_Value = 32; + + MT_FESDBG_MI_RtuInfo = 40; + MT_FESDBG_MI_Param = 41; + MT_FESDBG_MI_Value = 42; + + MT_FESDBG_SimAI_RtuInfo = 50; + MT_FESDBG_SimAI_Param = 51; + MT_FESDBG_SimAI_Value = 52; + MT_FESDBG_SimAI_StartSim = 53; + MT_FESDBG_SimAI_StopSim = 54; + + MT_FESDBG_SimDI_RtuInfo = 60; + MT_FESDBG_SimDI_Param = 61; + MT_FESDBG_SimDI_Value = 62; + MT_FESDBG_SimDI_StartSim = 63; + MT_FESDBG_SimDI_StopSim = 64; + + MT_FESDBG_SimMI_RtuInfo = 70; + MT_FESDBG_SimMI_Param = 71; + MT_FESDBG_SimMI_Value = 72; + MT_FESDBG_SimMI_StartSim = 73; + MT_FESDBG_SimMI_StopSim = 74; + + MT_FESDBG_SimACC_RtuInfo = 80; + MT_FESDBG_SimACC_Param = 81; + MT_FESDBG_SimACC_Value = 82; + MT_FESDBG_SimACC_StartSim = 83; + MT_FESDBG_SimACC_StopSim = 84; + + MT_FESDBG_SimEvent_RtuInfo = 90; + MT_FESDBG_SimEvent_DiParam = 91; + MT_FESDBG_SimEvent_Create = 92; + + MT_FESDBG_SimAO_RtuInfo = 100; + MT_FESDBG_SimAO_Param = 101; + MT_FESDBG_SimAO_Control = 102; + + MT_FESDBG_SimDO_RtuInfo = 110; + MT_FESDBG_SimDO_Param = 111; + MT_FESDBG_SimDO_Control = 112; + + MT_FESDBG_SimMO_RtuInfo = 120; + MT_FESDBG_SimMO_Param = 121; + MT_FESDBG_SimMO_Control = 122; + + MT_FESDBG_SimDefCmd_RtuInfo = 130; + MT_FESDBG_SimDefCmd_Control = 131; + + MT_FESDBG_FWAI_RtuInfo = 140; + MT_FESDBG_FWAI_Param = 141; + MT_FESDBG_FWAI_Value = 142; + + MT_FESDBG_FWDI_RtuInfo = 150; + MT_FESDBG_FWDI_Param = 151; + MT_FESDBG_FWDI_Value = 152; + + MT_FESDBG_FWDDI_RtuInfo = 160; + MT_FESDBG_FWDDI_Param = 161; + MT_FESDBG_FWDDI_Value = 162; + + MT_FESDBG_FWMI_RtuInfo = 170; + MT_FESDBG_FWMI_Param = 171; + MT_FESDBG_FWMI_Value = 172; + + MT_FESDBG_FWACC_RtuInfo = 180; + MT_FESDBG_FWACC_Param = 181; + MT_FESDBG_FWACC_Value = 182; + + MT_FESDBG_Event_SOE = 190; + MT_FESDBG_Event_Channel = 191; + MT_FESDBG_Event_SOEMemory = 192; + + MT_FESDBG_Mon_ChanStart = 200; + MT_FESDBG_Mon_ChanStop = 201; + MT_FESDBG_Mon_ChanClear = 202; + MT_FESDBG_Mon_ChanInfo = 203; +} + + +message FesDebugToolReqMsg +{ + required enFesDebugMsgType type = 1; //消息类型 + optional string body = 2; //消息 +} + +message FesDebugToolRepMsg +{ + required bool success = 1; + optional string err_msg = 2; + required enFesDebugMsgType type = 3; //消息类型 + optional string body = 4; //消息 +} + +message FesDebugToolNetRoute +{ + required string desc = 1; + required int32 port_no = 2; +} + +message FesDebugToolChanParam +{ + required int32 chan_no = 1; + required string tag_name = 2; + required string chan_name = 3; + required int32 used = 4; + required int32 chan_status = 5; + required int32 comm_type = 6; + required int32 chan_mode = 7; + required int32 protocol_id = 8; + repeated FesDebugToolNetRoute net_route = 9; + required int32 connect_wait_sec = 10; + required int32 connect_timeout = 11; + required int32 retry_times = 12; + required int32 recv_timeout = 13; + required int32 resp_timeout = 14; + required int32 max_rx_size = 15; + required int32 max_tx_size = 16; + required float err_rate_limit = 17; + repeated int32 backup_chan_no = 18; +} + +message FesDebugToolChanParamRepMsg +{ + repeated FesDebugToolChanParam chan_param = 1; +} + +message FesDebugToolRtuParam +{ + required int32 rtu_no = 1; + required string rtu_desc = 2; + required string rtu_name = 3; + required int32 used = 4; + required int32 rtu_status = 5; + required int32 rtu_addr = 6; + required int32 chan_no = 7; + required int32 max_ai_num = 8; + required int32 max_di_num = 9; + required int32 max_acc_num = 10; + required int32 recv_fail_limit = 11; +} + +message FesDebugToolRtuParamRepMsg +{ + repeated FesDebugToolRtuParam rtu_param = 1; +} + +message FesDebugToolRtuInfo +{ + required int32 rtu_no = 1; + required int32 used = 2; +// required int32 max_pnt_num = 3; + required string rtu_desc = 3; +} + +message FesDebugToolRtuInfoRepMsg +{ + repeated FesDebugToolRtuInfo rtu_info = 1; +} + +//前置数据 - 测点参数 +message FesDebugToolPntParamReqMsg +{ + required int32 rtu_no = 1; +} + +message FesDebugToolPntParam +{ + required int32 pnt_no = 1; + required int32 used = 2; + required string pnt_desc = 3; +} + +message FesDebugToolPntParamRepMsg +{ + required int32 rtu_no = 1; + required int32 max_pnt_num = 2; + repeated FesDebugToolPntParam pnt_param = 3; +} + +//前置数据 - 测点数据 +message FesDebugToolPntValueReqMsg +{ + required int32 rtu_no = 1; + required int32 start_index = 2; + required int32 end_index = 3; +} + +//前置数据 - 测点数据 - 用于数字量和混合量 +message FesDebugToolIntPntValue +{ + required int32 pnt_no = 1; + required sint32 value = 2; + required uint32 status = 3; + required uint64 time = 4; +} + +//前置数据 - 测点数据 - 用于模拟量 +message FesDebugToolFloatPntValue +{ + required int32 pnt_no = 1; + required float value = 2; + required uint32 status = 3; + required uint64 time = 4; +} + +//前置数据 - 测点数据 - 用于累积量 +message FesDebugToolDoublePntValue +{ + required int32 pnt_no = 1; + required double value = 2; + required uint32 status = 3; + required uint64 time = 4; +} + +message FesDebugToolPntValueRepMsg +{ + required int32 rtu_no = 1; + repeated FesDebugToolIntPntValue int_values = 2; + repeated FesDebugToolFloatPntValue float_values = 3; + repeated FesDebugToolDoublePntValue double_values = 4; +} + +//数据仿真 +//数据仿真 - 测点仿真类型 +enum enFesDebugSimMode +{ + MT_FESDBG_SM_ValueSet = 1; //固定设置 + MT_FESDBG_SM_LineSet = 2; //线性设置 + MT_FESDBG_SM_RandSet = 3; //随机设置 +// MT_FESDBG_SM_PeriodSet = 4; //周期设置 +} + +//数据仿真 - 仿真的测点范围 +enum enFesDebugSimRangeType +{ + MT_FESDBG_RT_SinglePoint = 1; //单个测点 + MT_FESDBG_RT_RtuPoint = 2; //整个RTU测点 + MT_FESDBG_RT_AllPoint = 3; //所有测点 +} + +//数据仿真 - 事件类型 +enum enFesDebugEventSimType +{ + MT_FESDBG_EST_RtuSoe = 1; //接入设备(RTU)SOE事件 + MT_FESDBG_EST_FepSoe = 2; //前置终端(FEP)生成SOE事件 +} + +message FesDebugToolValueVariant +{ + optional int32 int_value = 1; + optional float float_value = 2; + optional double double_value = 3; +} + +//固定设置仿真配置参数 +message FesDebugToolValueSetSimParam +{ + required double value = 1; +} + +// 线性置数 +message FesDebugToolLineSetSimParam +{ + required double min_value = 1; + required double max_value = 2; + required double step_value = 3; + required int32 period = 4; //变化周期,单位秒 +} + +//周期置数 +message FesDebugToolRandSetSimParam +{ + optional double min_value = 1; + optional double max_value = 2; + required int32 period = 3; //变化周期,单位秒 +} + +//数据仿真请求报文 +message FesDebugToolValueSimSetReqMsg +{ + required enFesDebugSimMode sim_mode = 1; + required enFesDebugSimRangeType sim_range = 2; + optional int32 rtu_no = 3; + optional int32 pnt_no = 4; + optional uint32 status = 5; + optional FesDebugToolValueSetSimParam value_set_param = 6; + optional FesDebugToolLineSetSimParam line_set_param = 7; + optional FesDebugToolRandSetSimParam rand_set_param = 8; +} + +//数据仿真响应报文 +message FesDebugToolValueSimSetRepMsg +{ + required enFesDebugSimMode sim_mode = 1; + optional string body = 2; +} + +//数据仿真-事件仿真请求报文 +message FesDebugToolSimEventRtuSoe +{ + required int32 event_source = 1; + required int32 rtu_no = 2; + required int32 pnt_no = 3; + required int32 value = 4; + required uint32 status = 5; + required int32 fault_num = 6; + repeated int32 fault_type = 7; + repeated float fault_value = 8; +} + +message FesDebugToolSimEventCreateReqMsg +{ + required enFesDebugEventSimType event_type = 1; + optional FesDebugToolSimEventRtuSoe event = 2; +} + +message FesDebugToolSimEventCreateRepMsg +{ + required enFesDebugEventSimType event_type = 1; + optional string body = 2; +} + +//控制仿真 +message FesDebugToolSimControlReqMsg +{ + required int32 ctrl_type = 1; + required int64 seq_no = 2; + required int32 rtu_no = 3; + required int32 pnt_no = 4; + optional float float_value = 5; + optional int32 int_value = 6; +} + +message FesDebugToolSimControlRepMsg +{ + required int32 ctrl_type = 1; + required int64 seq_no = 2; + required bool success = 3; + optional string err_msg = 4; +} + +message FesDebugToolSimDefCmdReqMsg +{ + required int32 rtu_no = 1; + required int32 dev_id = 2; + repeated string keys = 3; + repeated string values = 4; +} + +//数据转发 +message FesDebugToolFwPntParam +{ + required int32 pnt_no = 1; + required int32 used = 2; + required int32 fes_rtu_no = 3; + required int32 fes_pnt_no = 4; + required string pnt_desc = 5; +} + +message FesDebugToolFwPntParamRepMsg +{ + required int32 rtu_no = 1; + required int32 max_pnt_num = 2; + repeated FesDebugToolFwPntParam pnt_param = 3; +} + +//事件监视 +message FesDebugToolSoeEvent +{ + required string table_name = 1; + required string col_name = 2; + required string tag_name = 3; + required uint32 status = 4; + required int32 value = 5; + required uint64 time = 6; + required int32 fault_num = 7; + repeated int32 fault_type = 8; + repeated float fault_value = 9; + //required int32 rtu_no = 10; + //required int32 pnt_no = 11; +} + +message FesDebugToolSoeEventRepMsg +{ + required int32 over_flow = 1; + repeated FesDebugToolSoeEvent event = 2; +} + +message FesDebugToolChanEvent +{ + required string tag_name = 1; + required uint32 status = 2; + required float err_rate = 3; + required uint64 time = 4; +} + +message FesDebugToolChanEventRepMsg +{ + required int32 over_flow = 1; + repeated FesDebugToolChanEvent event = 2; +} + +message FesDebugToolChanMonCmdReqMsg +{ + required int32 chan_no = 1; +} + +message FesDebugToolChanMonCmdRepMsg +{ + required int32 chan_no = 1; + optional int32 rx_num = 2; + optional int32 tx_num = 3; + optional int32 err_num = 4; +} + +message FesDebugToolChanMonFrame +{ + required int32 frame_type = 1; + required int32 data_type = 2; + required uint64 time = 3; + required bytes data = 4; +} + +message FesDebugToolChanMonInfoMsg +{ + required int32 chan_no = 1; + required int32 rx_num = 2; + required int32 tx_num = 3; + required int32 err_num = 4; + required int32 over_flow = 5; + repeated FesDebugToolChanMonFrame frame = 6; +} diff --git a/product/src/fes/fes_idl_files/build.bat b/product/src/fes/fes_idl_files/build.bat new file mode 100644 index 00000000..3f47eca8 --- /dev/null +++ b/product/src/fes/fes_idl_files/build.bat @@ -0,0 +1,25 @@ +@echo off + +::协议文件路径 +set SOURCE_FOLDER=. + + +::cpp编译器路径 +set CPP_COMPILER_PATH=.\protoc.exe + +::cpp文件生成路径 +set CPP_TARGET_PATH=. + +::删除之前创建的文件 +del %CPP_TARGET_PATH%\*.h /f /s /q +del %CPP_TARGET_PATH%\*.cc /f /s /q + +::遍历所有文件 +for /f "delims=" %%i in ('dir /b "%SOURCE_FOLDER%\*.proto"') do ( + ::生成 cpp 代码 + echo %CPP_COMPILER_PATH% --cpp_out=dllexport_decl=IDL_FILES_EXPORT:%CPP_TARGET_PATH% %%i + %CPP_COMPILER_PATH% --cpp_out=dllexport_decl=IDL_FILES_EXPORT:%CPP_TARGET_PATH% %%i +) +echo gen finish + +pause \ No newline at end of file diff --git a/product/src/fes/fes_idl_files/fes_idl_files.pri b/product/src/fes/fes_idl_files/fes_idl_files.pri new file mode 100644 index 00000000..160b8907 --- /dev/null +++ b/product/src/fes/fes_idl_files/fes_idl_files.pri @@ -0,0 +1,11 @@ +win32 { + DEFINES += IDL_FILES_EXPORT=__declspec(dllimport) + + #暂时禁用警告 + QMAKE_CXXFLAGS += /wd"4251" + QMAKE_CXXFLAGS += /wd"4275" +} else { + DEFINES += IDL_FILES_EXPORT= +} + +LIBS += -lfes_idl_files diff --git a/product/src/fes/fes_idl_files/fes_idl_files.pro b/product/src/fes/fes_idl_files/fes_idl_files.pro new file mode 100644 index 00000000..c8e1dbdb --- /dev/null +++ b/product/src/fes/fes_idl_files/fes_idl_files.pro @@ -0,0 +1,37 @@ +QT -= core gui + +#平台的库保持原名 +#产品的库名已改为 idl_files_product +TARGET = fes_idl_files +TEMPLATE = lib + +#暂时禁用警告 +win32{ + QMAKE_CXXFLAGS += /wd"4251" + QMAKE_CXXFLAGS += /wd"4275" + QMAKE_CXXFLAGS += /wd"4267" + QMAKE_CXXFLAGS += /wd"4100" + contains (QMAKE_CXXFLAGS_WARN_ON, -w34100) : QMAKE_CXXFLAGS_WARN_ON -= -w34100 +} + +HEADERS += \ + FesDebugTool.pb.h + +SOURCES += \ + FesDebugTool.pb.cc + +win32 { + DEFINES += IDL_FILES_EXPORT=__declspec(dllexport) +} else { + DEFINES += IDL_FILES_EXPORT=\'__attribute__((visibility(\"default\")))\' +} + +LIBS += -lprotobuf + +COMMON_PRI=$$PWD/../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/fes/fes_idl_files/protoc.exe b/product/src/fes/fes_idl_files/protoc.exe new file mode 100644 index 00000000..9b0ebdc9 Binary files /dev/null and b/product/src/fes/fes_idl_files/protoc.exe differ diff --git a/product/src/fes/fes_pub/fes_ping_api/Ping.cpp b/product/src/fes/fes_pub/fes_ping_api/Ping.cpp new file mode 100644 index 00000000..22f48f4b --- /dev/null +++ b/product/src/fes/fes_pub/fes_ping_api/Ping.cpp @@ -0,0 +1,295 @@ +/** + @file Ping.cpp + @brief ping操作类 + @author 曹顶法 +*/ +#include "Ping.h" +#include "common/Common.h" +#include "pub_logger_api/logger.h" + +using namespace std; +#ifdef OS_WINDOWS +using boost::asio::ip::icmp; +#endif +#ifdef OS_LINUX +using boost::asio::ip::icmp_nonroot; +#endif + +using boost::asio::deadline_timer; +namespace posix_time = boost::posix_time; + +using namespace iot_public; +using namespace iot_fes; + +iot_fes::CPinger::CPinger(boost::asio::io_service& ioService, + const std::string &strDstIP, + const int nChannelNo, + const int nIpIdx, + const size_t nInitSequenceNum, + const size_t nSequenceStep, + const CPingResultCachePtr &ptrPingCache) + : m_bIsExit(false), + m_strDstIP(strDstIP), + m_nChannelNo(nChannelNo), + m_nIpIdx(nIpIdx), + m_dwInitSequenceNum(static_cast(nInitSequenceNum)), + m_dwSequenceNum(static_cast(nInitSequenceNum)), + m_nSequenceStep(static_cast(nSequenceStep)), + m_nReplyNum(0), + m_nFailTime(0), + m_bLastNetworkState(false), + m_nTimeoutMsec(1000), + m_nCheckInterval(500), + m_nPingRetryTime(3), + m_ptrPingCache(ptrPingCache), + m_objResolver(ioService), + #ifdef OS_WINDOWS + m_objSocket(ioService, icmp::v4()), + #endif + #ifdef OS_LINUX + m_objSocket(ioService, icmp_nonroot::v4()), + #endif + m_objTimer(ioService) +{ + +} + +iot_fes::CPinger::~CPinger() +{ + m_bIsExit = true; + boost::system::error_code ec; + m_objTimer.cancel(ec); + //m_ptrNetworkTable.reset(); + m_objSocket.close(); +} + +/* @brief 初始化 */ +int iot_fes::CPinger::initialize() +{ + //m_nTimeoutMsec = CNetworkCfgParam::getPingTimeoutMsec(); //< ping超时时间 + //m_nCheckInterval = CNetworkCfgParam::getPingCheckIntervalMsec(); //< ping检查周期 + //m_nPingRetryTime = CNetworkCfgParam::getPingRetryTime(); //< ping失败重试次数,超过重试次数才认为失败 + + m_nTimeoutMsec = 2000; //< ping超时时间 + m_nCheckInterval = 1000; //< ping检查周期 + m_nPingRetryTime = 3; //< ping失败重试次数,超过重试次数才认为失败 + +#ifdef OS_WINDOWS + icmp::resolver::query objQuery(icmp::v4(), m_strDstIP, "", + icmp::resolver::query::resolver_query_base::all_matching); + + try + { + m_objEndpoint = *m_objResolver.resolve(objQuery); + } + catch (std::exception& ex) + { + LOGERROR("创建endpoint失败.IP=[%s].error=[%s]", m_strDstIP.c_str(), ex.what()); + return iotFailed; + } +#endif +#ifdef OS_LINUX + m_objEndpoint = icmp_nonroot::endpoint( boost::asio::ip::address::from_string( m_strDstIP ), 0 ); +#endif + + startSend(); + startReceive(); + + return iotSuccess; +} + +/* @brief 启动发送 */ +void iot_fes::CPinger::startSend() +{ + if (m_bIsExit) //< 退出 + { + LOGINFO("接收到退出命令,停止Ping"); + return; + } +#ifdef OS_WINDOWS + std::string strBody = "ping " + m_strDstIP; +#endif +#ifdef OS_LINUX + std::string strBody( "iscs_ping" ); +#endif + + // Create an ICMP header for an echo request. + icmp_header objRequest; + objRequest.type(icmp_header::echo_request); + objRequest.code(0); + +#ifdef OS_WINDOWS + objRequest.identifier(getIdentifier()); +#endif + + uint16_t lastSeqNum = m_dwSequenceNum; + m_dwSequenceNum += m_nSequenceStep; + if(m_dwSequenceNum < lastSeqNum) + { + m_dwSequenceNum = m_dwInitSequenceNum; + } + + objRequest.sequence_number(m_dwSequenceNum); + +#ifdef OS_WINDOWS + compute_checksum(objRequest, strBody.begin(), strBody.end()); +#endif + + // Encode the request packet. + boost::asio::streambuf request_buffer; + std::ostream os(&request_buffer); + os << objRequest << strBody; + + // Send the request. + m_sendTime = posix_time::microsec_clock::universal_time(); + + try + { + if(m_ptrPingCache->isEnablePing(m_nChannelNo)) + { + m_objSocket.send_to(request_buffer.data(), m_objEndpoint); + } + } + catch (const std::exception& ex) + { + if (m_bLastNetworkState && m_nFailTime <= m_nPingRetryTime) /* @brief 防止网络异常时频繁打印日志 */ + { + LOGERROR("消息发送失败.err=[%s]", ex.what()); + } + } + + // Wait up to five seconds for a reply. + m_nReplyNum = 0; + m_objTimer.expires_from_now(/*time_sent_ +*/ posix_time::millisec(m_nTimeoutMsec)); + m_objTimer.async_wait(boost::bind(&CPinger::handleTimeout, this)); +} + +/* @brief 超时处理 */ +void iot_fes::CPinger::handleTimeout() +{ + if (m_bIsExit) //< 退出 + { + LOGINFO("接收到退出命令,停止Ping"); + return; + } + + bool bNetworkNormal = false; + if (m_nReplyNum == 0) + { + /* @brief 超时 */ + ++m_nFailTime; + } + else + { + m_nFailTime = 0; + bNetworkNormal = true; //< 网络正常 + } + + //if (m_bLastNetworkState != bNetworkNormal) + { + bool bUpdateTable = false; + + if (bNetworkNormal) + { + bUpdateTable = true; + LOGTRACE("%s网络正常",m_strDstIP.c_str()); + } + else + { + if (m_nFailTime >= m_nPingRetryTime) //< 超过指定次数才认为失败 + { + bUpdateTable = true; + LOGTRACE("%s网络故障",m_strDstIP.c_str()); + } + } + + if (bUpdateTable) + { + m_bLastNetworkState = bNetworkNormal; + m_ptrPingCache->setPingResult(m_nChannelNo,m_nIpIdx,bNetworkNormal); + } + } + + if (m_nFailTime >= m_nPingRetryTime) //< 失败后复位计数 + { + m_nFailTime = 0; + } + + /* @brief 设置ping的周期,如果上一次失败,则不需要等待,直接再次ping */ + int nTimeoutMsec = m_nCheckInterval; + if (m_nFailTime > 0) + { + nTimeoutMsec = 0; + } + + // Requests must be sent no less than one second apart. + m_objTimer.expires_from_now(/*time_sent_ +*/ posix_time::millisec(nTimeoutMsec)); + m_objTimer.async_wait(boost::bind(&CPinger::startSend, this)); +} + +/* @brief 启动接收 */ +void iot_fes::CPinger::startReceive() +{ + // Discard any data already in the buffer. + m_objReplyBuf.consume(m_objReplyBuf.size()); + + // Wait for a reply. We prepare the buffer to receive up to 64KB. + m_objSocket.async_receive(m_objReplyBuf.prepare(65536), boost::bind(&CPinger::handleReceive, this, _2)); +} + +void iot_fes::CPinger::handleReceive(std::size_t ulLength) +{ + // The actual number of bytes received is committed to the buffer so that we + // can extract it using a std::istream object. + m_objReplyBuf.commit(ulLength); + + // Decode the reply packet. + std::istream is(&m_objReplyBuf); + ipv4_header ipv4_hdr; + icmp_header icmp_hdr; + +#if OS_WINDOWS + is >> ipv4_hdr >> icmp_hdr; +#endif +#ifdef OS_LINUX + is >> icmp_hdr; +#endif + + // We can receive all ICMP packets received by the host, so we need to + // filter out only the echo replies that match the our identifier and + // expected sequence number. + if (is && icmp_hdr.type() == icmp_header::echo_reply +#ifdef OS_WINDOWS + && icmp_hdr.identifier() == getIdentifier() +#endif + && icmp_hdr.sequence_number() == m_dwSequenceNum) + { + // If this is the first reply, interrupt the five second timeout. + if (m_nReplyNum++ == 0) + { + m_objTimer.cancel(); //< 调用后,会调用注册的handle + } + + // Print out some information about the reply packet. + posix_time::ptime now = posix_time::microsec_clock::universal_time(); + int64 lIntervalMsec = (now - m_sendTime).total_milliseconds(); + if (lIntervalMsec > 50) //< 大于100ms时记录一下 + { + LOGWARN("[%" PRIu64 "] bytes from [%s] : icmp_seq=[%u],ttl=[%u],time=[%" PRId64 "]ms", + ulLength, ipv4_hdr.source_address().to_string().c_str(), + icmp_hdr.sequence_number(), ipv4_hdr.time_to_live(), lIntervalMsec); + } + } + + startReceive(); +} + +/* @brief 用来生成唯一索引 */ +uint16 iot_fes::CPinger::getIdentifier() +{ +#if defined(BOOST_ASIO_WINDOWS) + return static_cast(::GetCurrentProcessId()); +#else + return static_cast(::getpid()); +#endif +} diff --git a/product/src/fes/fes_pub/fes_ping_api/Ping.h b/product/src/fes/fes_pub/fes_ping_api/Ping.h new file mode 100644 index 00000000..96c17415 --- /dev/null +++ b/product/src/fes/fes_pub/fes_ping_api/Ping.h @@ -0,0 +1,94 @@ +/** + @file Ping.h + @brief ping操作类 + @author 曹顶法 +*/ +#pragma once +#include "boost/asio.hpp" +#ifdef OS_LINUX +#include "asio_icmp_nonroot.hpp" +#endif +#include "boost/bind.hpp" +//#include "common/DataType.h" +#include "icmp_header.hpp" +#include "ipv4_header.hpp" +#include "fes_ping_api/PingResultCache.h" + +namespace iot_fes +{ + class CPinger + { + public: + /** + @brief 构造函数 + @param boost::asio::io_service & ioService asio服务 + @param const std::string & strDstIP 要ping的IP地址 + @param const int nChannelNo 通道号 + @param const int nIpIdx 本通道下第几个IP + @param const size_t nInitSequenceNum 初始序号 + @param const size_t nSequenceStep 序号的步长 + @param const CPingResultCachePtr & ptrPingCache Ping结果缓存 + */ + CPinger(boost::asio::io_service& ioService, + const std::string &strDstIP, + const int nChannelNo, + const int nIpIdx, + const size_t nInitSequenceNum, + const size_t nSequenceStep, + const CPingResultCachePtr &ptrPingCache); + virtual ~CPinger(); + /** + @brief 初始化 + @return 成功返回iotSuccess,失败返回iotFailed + */ + int initialize(); + + private: + /* @brief 启动发送 */ + void startSend(); + /* @brief 超时处理 */ + void handleTimeout(); + /* @brief 启动接收 */ + void startReceive(); + /* @brief 收到反馈时的处理 */ + void handleReceive(std::size_t length); + /** + @brief 用来生成唯一索引 + @return 返回索引 + */ + static uint16_t getIdentifier(); + + private: + bool m_bIsExit; //< 是否退出 + std::string m_strDstIP; //< 要ping的IP地址 + int m_nChannelNo; //< 通道号 + int m_nIpIdx; //< 本通道下第几个IP + uint16_t m_dwInitSequenceNum; //初始发送序号 + uint16_t m_dwSequenceNum; //< 发送序号 + int m_nSequenceStep; //< 序号增长步长 + std::size_t m_nReplyNum; //< 接收到的反馈数目 + int m_nFailTime; //< ping失败次数 + bool m_bLastNetworkState; //< 上一次网络状态 + int m_nTimeoutMsec; //< ping超时时间 + int m_nCheckInterval; //< ping检查周期 + int m_nPingRetryTime; //< ping失败重试次数,超过重试次数才认为失败 + CPingResultCachePtr m_ptrPingCache; //保存Ping结果 + +#ifdef OS_WINDOWS + boost::asio::ip::icmp::resolver m_objResolver; + boost::asio::ip::icmp::endpoint m_objEndpoint; + boost::asio::ip::icmp::socket m_objSocket; +#endif +#ifdef OS_LINUX + boost::asio::ip::icmp_nonroot::resolver m_objResolver; + boost::asio::ip::icmp_nonroot::endpoint m_objEndpoint; + boost::asio::ip::icmp_nonroot::socket m_objSocket; +#endif + boost::asio::deadline_timer m_objTimer; //< 定时器 + boost::posix_time::ptime m_sendTime; //< ping发送时间 + boost::asio::streambuf m_objReplyBuf; + }; + + typedef boost::shared_ptr CPingerPtr; + +} //namespace iot_fes diff --git a/product/src/fes/fes_pub/fes_ping_api/PingImpl.cpp b/product/src/fes/fes_pub/fes_ping_api/PingImpl.cpp new file mode 100644 index 00000000..b68f356b --- /dev/null +++ b/product/src/fes/fes_pub/fes_ping_api/PingImpl.cpp @@ -0,0 +1,158 @@ +/** + @file NetworkCheckImpl.cpp + @brief 网络检测访问库接口实现文件 + @author 曹顶法 +*/ +#include "common/Common.h" +#include "PingImpl.h" +#include "pub_logger_api/logger.h" + +using namespace iot_fes; +iot_fes::CPingImpl::CPingImpl() : m_pThread(nullptr),m_ptrPingCache(NULL) +{ + +} + +iot_fes::CPingImpl::~CPingImpl() +{ + stop(); +} + +/* @brief 获取当前网络是否正常 */ +int iot_fes::CPingImpl::start() +{ + if(m_vecPingInfo.empty()) + { + LOGINFO("没有配置需要Ping的地址"); + return iotSuccess; + } + + if(iotSuccess != initPinger()) + { + return iotFailed; + } + + m_pThread = new boost::thread( boost::bind(&iot_fes::CPingImpl::startListen,this)); + if ( nullptr == m_pThread ) + { + LOGERROR("创建Ping监听线程失败"); + return iotFailed; + } + + return iotSuccess; +} + +int iot_fes::CPingImpl::stop() +{ + m_objIOService.stop(); + if(m_pThread != nullptr) + { + if(m_pThread->joinable()) + { + LOGINFO("开始停止Ping线程"); + m_pThread->join(); + LOGINFO("Ping线程停止成功"); + } + + delete m_pThread; + m_pThread = nullptr; + } + + for (size_t i = 0; i < m_vecPingerPtr.size(); ++i) + { + m_vecPingerPtr[i].reset(); + } + m_vecPingerPtr.clear(); + + return iotSuccess; +} + +/* @brief 初始化本类资源,主要打开内存表 */ +int iot_fes::CPingImpl::initialize() +{ + m_ptrPingCache = boost::make_shared(); + if(m_ptrPingCache == NULL) + { + LOGERROR("创建PingCache失败,不启用Ping功能"); + return iotFailed; + } + + return iotSuccess; +} + +void iot_fes::CPingImpl::startListen() +{ + LOGINFO("运行Ping监听服务"); + m_objIOService.run(); + LOGINFO("停止Ping监听服务"); +} + +void iot_fes::CPingImpl::addAddress(const int nChannelNo, const int nIpIdx, const std::string &strIp) +{ + SPingAddrInfo stInfo(nChannelNo,nIpIdx,strIp); + m_vecPingInfo.push_back(stInfo); +} + +bool iot_fes::CPingImpl::getPingResult(const int nChannelNo) +{ + return m_ptrPingCache->getPingResult(nChannelNo); +} + +int CPingImpl::getPingOkIpIndex(const int nChannelNo) +{ + return m_ptrPingCache->getPingOkIpIndex(nChannelNo); +} + +void iot_fes::CPingImpl::enablePing(const int nChannelNo) +{ + m_ptrPingCache->enablePing(nChannelNo); +} + +void iot_fes::CPingImpl::disablePing(const int nChannelNo) +{ + m_ptrPingCache->disablePing(nChannelNo); +} + + +int iot_fes::CPingImpl::initPinger() +{ + try + { + /* @brief 每个网关IP创建一个CPinger,每个Pinger检测一个网关的网络状况 */ + for (size_t i = 0; i < m_vecPingInfo.size(); ++i) + { + CPingerPtr ptrPinger = boost::make_shared(m_objIOService, + m_vecPingInfo[i].strIp, + m_vecPingInfo[i].nChNo, + m_vecPingInfo[i].nIdx, + i, + m_vecPingInfo.size(), + m_ptrPingCache); + if (ptrPinger == NULL) + { + LOGERROR("创建pinger失败.ChNo=%d,ip=%s",m_vecPingInfo[i].nChNo,m_vecPingInfo[i].strIp.c_str()); + return iotFailed; + } + else + { + if (iotSuccess != ptrPinger->initialize()) + { + return iotFailed; + } + else + { + m_vecPingerPtr.push_back(ptrPinger); + //先默认认为网络正常 + m_ptrPingCache->setPingResult(m_vecPingInfo[i].nChNo,m_vecPingInfo[i].nIdx,true); + } + } + } + } + catch (std::exception& ex) + { + LOGERROR("创建Pinger失败.error=[%s]", ex.what()); + return iotFailed; + } + + return iotSuccess; +} diff --git a/product/src/fes/fes_pub/fes_ping_api/PingImpl.h b/product/src/fes/fes_pub/fes_ping_api/PingImpl.h new file mode 100644 index 00000000..2a1ad056 --- /dev/null +++ b/product/src/fes/fes_pub/fes_ping_api/PingImpl.h @@ -0,0 +1,83 @@ +/** + @file NetworkCheckImpl.h + @brief 网络检测访问库接口实现文件 + @author 曹顶法 +*/ +#pragma once +#include "boost/thread.hpp" +#include "fes_ping_api/PingInterface.h" +#include "Ping.h" + +namespace iot_fes +{ + typedef struct _SPingAddrInfo + { + _SPingAddrInfo(const int nChannelNo,const int nIpIdx,const std::string &strPingIp) + :nChNo(nChannelNo),nIdx(nIpIdx),strIp(strPingIp) + {} + + int nChNo; //通道号 + int nIdx; //本通道下第几个IP,从0开始 + std::string strIp; //Ip地址 + }SPingAddrInfo,*PSPingAddrInfo; + + typedef std::vector SPingAddrInfoSeq; + + class CPingImpl : public CPingInterface + { + public: + CPingImpl(); + ~CPingImpl(); + + /** + @brief 启动Ping + @return 正常返回iotSuccess + */ + virtual int start(); + + //停止Ping + virtual int stop(); + /** + @brief 初始化本类资源,主要创建Ping结果缓存 + @return 成功返回iotSuccess,失败返回错误码 + @retval + */ + int initialize(); + //启动网络监听服务 + void startListen(); + + /** + @brief 增加需要Ping的信息,要在start执行执行,可以多次执行 + @param const int nChannelNo 通道号 + @param const int nIpIdx 本通道下第几个IP + @param const std::string & strDstIP 要ping的IP地址 + */ + void addAddress(const int nChannelNo,const int nIpIdx,const std::string &strIp); + + //获取指定通道的Ping结果 + bool getPingResult(const int nChannelNo); + + //获取指定通道的Ping结果,返回是ping的ip的索引,找不到返回-1 + int getPingOkIpIndex(const int nChannelNo); + + //启用指定通道的Ping功能 + void enablePing(const int nChannelNo); + + //禁用指定通道的Ping功能 + void disablePing(const int nChannelNo); + + private: + //每个IP创建一个Ping实例 + int initPinger(); + + private: + boost::thread *m_pThread; //网络监听线程 + boost::asio::io_service m_objIOService; //< asio服务类 + SPingAddrInfoSeq m_vecPingInfo; //IP地址信息 + CPingResultCachePtr m_ptrPingCache; //存放ping结果 + std::vector m_vecPingerPtr; //< 需要ping的IP类列表 + }; + + typedef boost::shared_ptr CPingImplPtr; + +} //namespace iot_sys diff --git a/product/src/fes/fes_pub/fes_ping_api/PingInterface.cpp b/product/src/fes/fes_pub/fes_ping_api/PingInterface.cpp new file mode 100644 index 00000000..2700592b --- /dev/null +++ b/product/src/fes/fes_pub/fes_ping_api/PingInterface.cpp @@ -0,0 +1,24 @@ +/** + @file NetworkCheckInterface.cpp + @brief 网络检测接口创建 + @author 曹顶法 +*/ +#include "fes_ping_api/PingInterface.h" +#include "PingImpl.h" +#include "common/Common.h" + +using namespace iot_fes; + +FES_PING_API CPingInterfacePtr iot_fes::getPingInstance() +{ + CPingImplPtr ptrNetworkCheck = boost::make_shared(); + if (ptrNetworkCheck != NULL) + { + if (iotSuccess != ptrNetworkCheck->initialize()) + { + ptrNetworkCheck.reset(); + } + } + + return ptrNetworkCheck; +} diff --git a/product/src/fes/fes_pub/fes_ping_api/PingResultCache.cpp b/product/src/fes/fes_pub/fes_ping_api/PingResultCache.cpp new file mode 100644 index 00000000..bb0a5eea --- /dev/null +++ b/product/src/fes/fes_pub/fes_ping_api/PingResultCache.cpp @@ -0,0 +1,103 @@ +/** + @file NetworkCheckImpl.cpp + @brief 网络检测访问库接口实现文件 + @author 曹顶法 +*/ +#include "common/Common.h" +#include "fes_ping_api/PingResultCache.h" +#include "pub_logger_api/logger.h" + +using namespace iot_fes; + +iot_fes::CPingResultCache::CPingResultCache() +{ + +} + +iot_fes::CPingResultCache::~CPingResultCache() +{ + +} + +bool iot_fes::CPingResultCache::getPingResult(const int nChannelNo) +{ + boost::mutex::scoped_lock lock(m_objMutex); + Chan2ConnStatMAP::const_iterator pIter = m_mapChToPingResult.find(nChannelNo); + if(pIter == m_mapChToPingResult.end()) + { + return true; //找不到,走默认逻辑,认为需要重连 + } + return pIter->second.any(); +} + +int CPingResultCache::getPingOkIpIndex(const int nChannelNo) +{ + boost::mutex::scoped_lock lock(m_objMutex); + Chan2ConnStatMAP::const_iterator pIter = m_mapChToPingResult.find(nChannelNo); + if(pIter == m_mapChToPingResult.end()) + { + + return -1; //找不到,走默认逻辑,认为需要重连 + } + + if(pIter->second.test(0) && pIter->second.test(1)) + { + return -1; //如果2个都能ping通,返回-1,防止设备能ping通但是端口未开的情况 + } + + if(pIter->second.test(0)) + { + return 0; + } + else if(pIter->second.test(1)) + { + return 1; + } + + return -1; +} + +void iot_fes::CPingResultCache::setPingResult(const int nChNo, const int nIdx,const bool bRet) +{ + boost::mutex::scoped_lock lock(m_objMutex); + m_mapChToPingResult[nChNo].set(nIdx,bRet); +} + +bool iot_fes::CPingResultCache::isEnablePing(const int nChannelNo) +{ + boost::mutex::scoped_lock lock(m_objMutex); + Chan2ConnStatMAP::const_iterator pIter = m_mapChToPingResult.find(nChannelNo); + if(pIter == m_mapChToPingResult.end()) + { + return true; //找不到,走默认逻辑,认为需要Ping + } + + if(pIter->second.test(CONST_MAX_PING_NUM - 1)) //如果最高位设置为1,表示当前网络正常,可以暂停ping + { + return false; + } + + return true; +} + +void iot_fes::CPingResultCache::enablePing(const int nChannelNo) +{ + boost::mutex::scoped_lock lock(m_objMutex); + Chan2ConnStatMAP::iterator pIter = m_mapChToPingResult.find(nChannelNo); + if(pIter != m_mapChToPingResult.end()) + { + LOGINFO("启用通道Ping功能.ChannelNo=%d",nChannelNo); + pIter->second.reset(CONST_MAX_PING_NUM - 1); + } +} + +void CPingResultCache::disablePing(const int nChannelNo) +{ + boost::mutex::scoped_lock lock(m_objMutex); + Chan2ConnStatMAP::iterator pIter = m_mapChToPingResult.find(nChannelNo); + if(pIter != m_mapChToPingResult.end()) + { + LOGINFO("禁用通道Ping功能.ChannelNo=%d",nChannelNo); + pIter->second.set(CONST_MAX_PING_NUM - 1,true); + } +} diff --git a/product/src/fes/fes_pub/fes_ping_api/asio_icmp_nonroot.hpp b/product/src/fes/fes_pub/fes_ping_api/asio_icmp_nonroot.hpp new file mode 100644 index 00000000..7729a435 --- /dev/null +++ b/product/src/fes/fes_pub/fes_ping_api/asio_icmp_nonroot.hpp @@ -0,0 +1,106 @@ + +/** + * @brief 无需root权限发送icmp包,从boost/asio/ip/icmp.hpp修改而来 + * @author yikenan + */ + +# pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost +{ +namespace asio +{ +namespace ip +{ + +/** + * @brief 无需root权限发送icmp包,从boost/asio/ip/icmp.hpp修改而来 + */ +class icmp_nonroot +{ +public: + /// The type of a ICMP endpoint. + typedef basic_endpoint endpoint; + + /// Construct to represent the IPv4 ICMP protocol. + static icmp_nonroot v4() + { + return icmp_nonroot( BOOST_ASIO_OS_DEF( IPPROTO_ICMP ), + BOOST_ASIO_OS_DEF( AF_INET ) ); + } + + /// Construct to represent the IPv6 ICMP protocol. + static icmp_nonroot v6() + { + return icmp_nonroot( BOOST_ASIO_OS_DEF( IPPROTO_ICMPV6 ), + BOOST_ASIO_OS_DEF( AF_INET6 ) ); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + //< yikenan + // return BOOST_ASIO_OS_DEF(SOCK_RAW); + return BOOST_ASIO_OS_DEF( SOCK_DGRAM ); + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return protocol_; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// The ICMP socket type. + //< yikenan + //typedef basic_raw_socket socket; + typedef basic_datagram_socket socket; + + /// The ICMP resolver type. + typedef basic_resolver resolver; + + /// Compare two protocols for equality. + friend bool operator==( const icmp_nonroot &p1, const icmp_nonroot &p2 ) + { + return p1.protocol_ == p2.protocol_ && p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=( const icmp_nonroot &p1, const icmp_nonroot &p2 ) + { + return p1.protocol_ != p2.protocol_ || p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit icmp_nonroot( int protocol_id, int protocol_family ) + : protocol_( protocol_id ), + family_( protocol_family ) + { + } + + int protocol_; + int family_; +}; + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + diff --git a/product/src/fes/fes_pub/fes_ping_api/fes_ping_api.pro b/product/src/fes/fes_pub/fes_ping_api/fes_ping_api.pro new file mode 100644 index 00000000..20147cb2 --- /dev/null +++ b/product/src/fes/fes_pub/fes_ping_api/fes_ping_api.pro @@ -0,0 +1,43 @@ +QT -= core gui +CONFIG -= qt + +TEMPLATE = lib +TARGET = fes_ping_api + +DEFINES += FES_PING_EXPORTS + +# Input +HEADERS += \ + PingImpl.h \ + icmp_header.hpp \ + ipv4_header.hpp \ + Ping.h \ + ../../include/fes_ping_api/PingApiCommon.h \ + ../../include/fes_ping_api/PingInterface.h \ + ../../include/fes_ping_api/PingResultCache.h + +linux-g++* { + HEADERS += asio_icmp_nonroot.hpp +} + +SOURCES += \ + PingImpl.cpp \ + PingResultCache.cpp \ + PingInterface.cpp \ + Ping.cpp + +INCLUDEPATH += ../../include/ + +#LIBS += -lboost_filesystem -lboost_system -lboost_thread +LIBS += -lboost_date_time -lboost_thread +LIBS += -lboost_system -llog4cplus +LIBS += -lpub_utility_api -lpub_logger_api -lrdb_api + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/fes/fes_pub/fes_ping_api/icmp_header.hpp b/product/src/fes/fes_pub/fes_ping_api/icmp_header.hpp new file mode 100644 index 00000000..ba8bd744 --- /dev/null +++ b/product/src/fes/fes_pub/fes_ping_api/icmp_header.hpp @@ -0,0 +1,94 @@ +// +// icmp_header.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ICMP_HEADER_HPP +#define ICMP_HEADER_HPP + +#include +#include +#include + +// ICMP header for both IPv4 and IPv6. +// +// The wire format of an ICMP header is: +// +// 0 8 16 31 +// +---------------+---------------+------------------------------+ --- +// | | | | ^ +// | type | code | checksum | | +// | | | | | +// +---------------+---------------+------------------------------+ 8 bytes +// | | | | +// | identifier | sequence number | | +// | | | v +// +-------------------------------+------------------------------+ --- + +class icmp_header +{ +public: + enum { echo_reply = 0, destination_unreachable = 3, source_quench = 4, + redirect = 5, echo_request = 8, time_exceeded = 11, parameter_problem = 12, + timestamp_request = 13, timestamp_reply = 14, info_request = 15, + info_reply = 16, address_request = 17, address_reply = 18 }; + + icmp_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); } + + unsigned char type() const { return rep_[0]; } + unsigned char code() const { return rep_[1]; } + unsigned short checksum() const { return decode(2, 3); } + unsigned short identifier() const { return decode(4, 5); } + unsigned short sequence_number() const { return decode(6, 7); } + + void type(unsigned char n) { rep_[0] = n; } + void code(unsigned char n) { rep_[1] = n; } + void checksum(unsigned short n) { encode(2, 3, n); } + void identifier(unsigned short n) { encode(4, 5, n); } + void sequence_number(unsigned short n) { encode(6, 7, n); } + + friend std::istream& operator>>(std::istream& is, icmp_header& header) + { return is.read(reinterpret_cast(header.rep_), 8); } + + friend std::ostream& operator<<(std::ostream& os, const icmp_header& header) + { return os.write(reinterpret_cast(header.rep_), 8); } + +private: + unsigned short decode(int a, int b) const + { return (rep_[a] << 8) + rep_[b]; } + + void encode(int a, int b, unsigned short n) + { + rep_[a] = static_cast(n >> 8); + rep_[b] = static_cast(n & 0xFF); + } + + unsigned char rep_[8]; +}; + +template +void compute_checksum(icmp_header& header, + Iterator body_begin, Iterator body_end) +{ + unsigned int sum = (header.type() << 8) + header.code() + + header.identifier() + header.sequence_number(); + + Iterator body_iter = body_begin; + while (body_iter != body_end) + { + sum += (static_cast(*body_iter++) << 8); + if (body_iter != body_end) + sum += static_cast(*body_iter++); + } + + sum = (sum >> 16) + (sum & 0xFFFF); + sum += (sum >> 16); + header.checksum(static_cast(~sum)); +} + +#endif // ICMP_HEADER_HPP diff --git a/product/src/fes/fes_pub/fes_ping_api/ipv4_header.hpp b/product/src/fes/fes_pub/fes_ping_api/ipv4_header.hpp new file mode 100644 index 00000000..68c9ba11 --- /dev/null +++ b/product/src/fes/fes_pub/fes_ping_api/ipv4_header.hpp @@ -0,0 +1,102 @@ +// +// ipv4_header.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef IPV4_HEADER_HPP +#define IPV4_HEADER_HPP + +#include +#include + +// Packet header for IPv4. +// +// The wire format of an IPv4 header is: +// +// 0 8 16 31 +// +-------+-------+---------------+------------------------------+ --- +// | | | | | ^ +// |version|header | type of | total length in bytes | | +// | (4) | length| service | | | +// +-------+-------+---------------+-+-+-+------------------------+ | +// | | | | | | | +// | identification |0|D|M| fragment offset | | +// | | |F|F| | | +// +---------------+---------------+-+-+-+------------------------+ | +// | | | | | +// | time to live | protocol | header checksum | 20 bytes +// | | | | | +// +---------------+---------------+------------------------------+ | +// | | | +// | source IPv4 address | | +// | | | +// +--------------------------------------------------------------+ | +// | | | +// | destination IPv4 address | | +// | | v +// +--------------------------------------------------------------+ --- +// | | ^ +// | | | +// / options (if any) / 0 - 40 +// / / bytes +// | | | +// | | v +// +--------------------------------------------------------------+ --- + +class ipv4_header +{ +public: + ipv4_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); } + + unsigned char version() const { return (rep_[0] >> 4) & 0xF; } + unsigned short header_length() const { return (rep_[0] & 0xF) * 4; } + unsigned char type_of_service() const { return rep_[1]; } + unsigned short total_length() const { return decode(2, 3); } + unsigned short identification() const { return decode(4, 5); } + bool dont_fragment() const { return (rep_[6] & 0x40) != 0; } + bool more_fragments() const { return (rep_[6] & 0x20) != 0; } + unsigned short fragment_offset() const { return decode(6, 7) & 0x1FFF; } + unsigned int time_to_live() const { return rep_[8]; } + unsigned char protocol() const { return rep_[9]; } + unsigned short header_checksum() const { return decode(10, 11); } + + boost::asio::ip::address_v4 source_address() const + { + boost::asio::ip::address_v4::bytes_type bytes + = { { rep_[12], rep_[13], rep_[14], rep_[15] } }; + return boost::asio::ip::address_v4(bytes); + } + + boost::asio::ip::address_v4 destination_address() const + { + boost::asio::ip::address_v4::bytes_type bytes + = { { rep_[16], rep_[17], rep_[18], rep_[19] } }; + return boost::asio::ip::address_v4(bytes); + } + + friend std::istream& operator>>(std::istream& is, ipv4_header& header) + { + is.read(reinterpret_cast(header.rep_), 20); + if (header.version() != 4) + is.setstate(std::ios::failbit); + std::streamsize options_length = header.header_length() - 20; + if (options_length < 0 || options_length > 40) + is.setstate(std::ios::failbit); + else + is.read(reinterpret_cast(header.rep_) + 20, options_length); + return is; + } + +private: + unsigned short decode(int a, int b) const + { return (rep_[a] << 8) + rep_[b]; } + + unsigned char rep_[60]; +}; + +#endif // IPV4_HEADER_HPP diff --git a/product/src/fes/fes_pub/fes_pub.pro b/product/src/fes/fes_pub/fes_pub.pro new file mode 100644 index 00000000..430a8f18 --- /dev/null +++ b/product/src/fes/fes_pub/fes_pub.pro @@ -0,0 +1,9 @@ +#各子工程按书写顺序编译,清注意各子工程的依赖关系,被依赖的库应写在前面。 + +TEMPLATE = subdirs +CONFIG += ordered + +SUBDIRS += \ + #fes_ping_api + + diff --git a/product/src/fes/include/ComSerialPort.h b/product/src/fes/include/ComSerialPort.h new file mode 100644 index 00000000..80648f1d --- /dev/null +++ b/product/src/fes/include/ComSerialPort.h @@ -0,0 +1,72 @@ +/* + @file SerialPortThread.h + @brief SerialPortThread类 + @author thxiao +*/ +#pragma once + +#include "FesDef.h" +#include "FesBase.h" + +#ifdef WIN32 //无效句柄定义,返回类型定义 +#define HINVALID NULL +#define HVALID(x) (HANDLE)x +#define DEVTYPE HANDLE +#else +#define HINVALID -1 +#define HVALID(x) x +#define DEVTYPE int +#endif + +#define COM_NOPARITY 0 +#define COM_EVENPARITY 2 +#define COM_ODDPARITY 3 +#define COM_SPACEPARITY 4 +#define COM_MARKPARITY 5 + +#define COM_ONESTOPBIT 0 +#define COM_ONE5STOPBITS 1 +#define COM_TWOSTOPBITS 2 + +using namespace iot_public; + +class CComSerialPort +{ + +public: + CComSerialPort(CFesChanPtr ptrCFesChan); + virtual ~CComSerialPort(); + + void TxComData(CFesChanPtr ptrCFesChan,int dateLen, byte *pData); + void RxComData(CFesChanPtr ptrCFesChan); + int GetComStatus(); + + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + + int m_timerCount; + int m_timerCountReset; + + bool OpenChan(CFesChanPtr ptrCFesChan); + void CloseChan(CFesChanPtr ptrCFesChan); + void SetChan(CFesChanPtr ptrCFesChan); + +private: + DEVTYPE m_devId; + int m_comIndex;//1~24(P1,P2........) + int errSendCount; + int errRecvCount; + int openCount; +#ifdef WIN32 + BOOL cfgWrite(HANDLE hPortHandle, BYTE bReg, BYTE bValue); + BOOL cfgRead(HANDLE hPortHandle, BYTE bReg, BYTE *pbValue); + void ComModeSet(HANDLE hPortHandle, unsigned int Mode, unsigned int num); + void ComReset(HANDLE hPortHandle, unsigned int Mode, unsigned int num); +#else + int ComModeSet(int fd, unsigned int Mode,unsigned int num); +#endif + +}; + +typedef boost::shared_ptr CComSerialPortPtr; + diff --git a/product/src/fes/include/FesBase.h b/product/src/fes/include/FesBase.h index f8f9d642..3c19e82c 100644 --- a/product/src/fes/include/FesBase.h +++ b/product/src/fes/include/FesBase.h @@ -394,56 +394,56 @@ public: * 通过TagName,获取非本FES转发点SFesFwPubAi * @param TagName 点TagName */ - SFesFwPubAi* GetFesFwPubFesAi(std::string TagName); + SFesFwPubAi* GetFesFwPubFesAi(const std::string &TagName); /** * @brief CFesBase::GetFesFwDpAi * 通过TagName,获取非本DP转发点SFesFwDpAi * @param TagName 点TagName */ - SFesFwPubAi* GetFesFwPubDpAi(std::string TagName); + SFesFwPubAi* GetFesFwPubDpAi(const std::string &TagName); /** * @brief CFesBase::GetFesFwPubDi * 通过TagName,获取非本FES转发点SFesFwPubDi * @param TagName 点TagName */ - SFesFwPubDi* GetFesFwPubFesDi(std::string TagName); + SFesFwPubDi* GetFesFwPubFesDi(const std::string &TagName); /** * @brief CFesBase::GetFesFwPubDi * 通过TagName,获取DP转发点SFesFwPubDi * @param TagName 点TagName */ - SFesFwPubDi* GetFesFwPubDpDi(std::string TagName); + SFesFwPubDi* GetFesFwPubDpDi(const std::string &TagName); /** * @brief CFesBase::GetFesFwPubAcc * 通过TagName,获取非本FES转发点SFesFwPubAcc * @param TagName 点TagName */ - SFesFwPubAcc* GetFesFwPubFesAcc(std::string TagName); + SFesFwPubAcc* GetFesFwPubFesAcc(const std::string &TagName); /** * @brief CFesBase::GetFesFwPubDpAcc * 通过TagName,获取非本DP转发点SFesFwPubAcc * @param TagName 点TagName */ - SFesFwPubAcc* GetFesFwPubDpAcc(std::string TagName); + SFesFwPubAcc* GetFesFwPubDpAcc(const std::string &TagName); /** * @brief CFesBase::GetFesFwPubFesMi * 通过TagName,获取非本FES转发点SFesFwPubMi * @param TagName 点TagName */ - SFesFwPubMi* GetFesFwPubFesMi(std::string TagName); + SFesFwPubMi* GetFesFwPubFesMi(const std::string &TagName); /** * @brief CFesBase::GetFesFwPubDpMi * 通过TagName,获取非本DP转发点SFesFwPubMi * @param TagName 点TagName */ - SFesFwPubMi* GetFesFwPubDpMi(std::string TagName); + SFesFwPubMi* GetFesFwPubDpMi(const std::string &TagName); /** * @brief CFesBase::WriteSoeEventBuf diff --git a/product/src/fes/include/FesDef.h b/product/src/fes/include/FesDef.h index 88a50efb..d837eaec 100644 --- a/product/src/fes/include/FesDef.h +++ b/product/src/fes/include/FesDef.h @@ -1,2310 +1,2340 @@ -/* - @file FesDef.h - @brief 头文件 - @author thxiao - @history - 2019-02-20 thxiao 增加转发规约的接口结构;DI增加转发站标志,增加转发功能 - 2019-03-11 thxiao 增加规约映射表,数据按规约点的顺序排列.方便工程在完成的情况下,现场工程又修改了点顺序。 - 2019-03-18 thxiao 转发规约遥控指令需要RtuNo,SFesRxDoCmd\SFesRxAoCmd\SFesRxMoCmd增加定义 - 2019-06-05 thxiao SFesRtuParam 增加车站描述,方便保存录波按“车站\设备”保存 - 2019-06-10 thxiao SFesRtuDevParam 增加录波路径,方便保存录波按“车站\设备”保存 - 2019-06-11 thxiao CN_SFesSimComFrameMaxLen=300 监视帧最大长度由120变为300 - 2019-08-30 thxiao SFesAi 增加 float fPercentValue; 转换后的突变比较范围 - 2019-09-18 thxiao SFesChanParam,SFesRtuParam,增加报警使能 - 2019-10-21 thxiao 点结构增加字段 - 2020-01-16 thxiao 前置点增加点描述 - 2020-03-11 thxiao SFesRtuParam 增加设备类型、整数设备类型,一般为采集串口RTU使用,避免判断字符串,优化查找时间 - 2020-09-29 thxiao 控制命令返回状态增加部分操作成功 - 2020-10-15 thxiao 增加虚拟数据结构SFesVirtualValue - 2021-03-04 thxiao DO AO MO DZ增加DevId - 2021-05-25 thxiao 增加字符型的SOE - 2021-06-25 thxiao 增加MODBUS类型 - 2021-08-03 thxiao 增加数据清零方式定义,越限清零 - -*/ -#pragma once -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include -//#include -#include - -#ifdef WIN32 -/* -#pragma warning(disable: 4100)//未引用的形参 -#pragma warning(disable: 4101)//未引用的局部变量 -#pragma warning(disable: 4251)//需要有dll接口由class"xxxx"的客户端使用 -#pragma warning(disable: 4267)// “=”: 从“size_t”转换到“int”,可能丢失数据 -#pragma warning(disable: 4305)// “初始化”: 从“double”到“float”截断 -#pragma warning(disable: 4275)// 非 dll 接口 class“google::protobuf::Message”用作 dll 接口 class“iot_idl:: -#pragma warning(disable: 4819)//该文件包含不能在当前代码页(0)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 -#pragma warning(disable: 4474)// sprintf: 格式字符串中传递的参数太多 -#pragma warning(disable: 4313)//“sprintf”: 格式字符串中的“%d”与“char *”类型的参数 5 冲突 -*/ -#include -#include -#define in_addr_t unsigned long -#define SHUT_RDWR 2 -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN 16 -#endif -#define socklen_t int -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -typedef int SOCKET; -#define INVALID_SOCKET -1 -#define SOCKET_ERROR -1 -#define closesocket close -#define ioctlsocket ioctl -#endif - -#ifndef FESSIM -// 以下头文件FES仿真程序不需要使用,如有包含会编译出错 -#include -#include -#include -#include "pub_utility_api/TimerThreadBase.h" -#include "pub_utility_api/TimeUtil.h" -#include "pub_logger_api/logger.h" -#endif -#include "common/Common.h" -#include "common/DataType.h" -#include "FesRdbStruct.h" - - -#ifdef PROTOCOLBASE_API_EXPORTS -#define PROTOCOLBASE_API G_DECL_EXPORT -#else -#define PROTOCOLBASE_API G_DECL_IMPORT -#endif - -/* -#ifdef PROTOCOLBASE_API_EXPORTS -#ifdef WIN32 -#define PROTOCOLBASE_API G_DECL_EXPORT -#else -//LINUX下 默认情况下会使用C++ API函数命名规则(函数名会增加字符),使用extern "C"修饰后变为C的函数名,便于使用。 -#define PROTOCOLBASE_API extern "C" -#endif -#else -#define PROTOCOLBASE_API G_DECL_IMPORT -#endif -*/ - -using namespace std; - -const float CN_FesFloatCompare = 0.000001;//用于浮点型数据的比较 - -const int CN_FesMaxProtocolNum = 64; //系统可接入规约数 -const int CN_FesMaxRtuNumPerChan = 32; //每个通道可接设备数(只对通道为polling方式) -const int CN_FesMaxChangeMultiple = 5; //变化数据缓冲区为数据个数的倍数 -const int CN_FesMaxDzParamSize =800; //定值参数最大长度 -const int CN_FesMaxDzNum =40; //定值最大个数一帧的定值个数最大40个(KBD104中规定) -const int CN_FesMaxDefCmdSize =512; //自定义命令最大长度 -const int CN_FesMaxWaveFileNameSize =256; //录波文件名最大长度 -const int CN_FesMaxModbusTxCmdNum =200; //MODBUS命令发送缓冲区最大条数 -const int CN_FesMaxFaultNum =4; //事件中最大故障数据 -const int CN_FesFwMaxCollectRtuNum =256; //RTU转发表里的采集RTU最大个数 -const int CN_Fes_Fw_MaxMapping = 16; //转发协议最大转发站数目 - -//模拟量死区类型 -const int CN_FesDeadbandType_Percent = 0; //上下限百分比 -const int CN_FesDeadbandType_Abs = 1; //绝对值 -const int CN_FesDeadbandType_None = 2; //不判断死区 - -//点值状态 -const int CN_FesValueNotUpdate =0x00; //BIT0: 0:点值未更新 1:点已更新 -const int CN_FesValueUpdate =0x01; //BIT0: 0:点值未更新 1:点已更新 -const int CN_FesValueInvaild =0x02; //BIT1:0:点值无效 1:点值无效 设备报告无效 -const int CN_FesValueExceed =0x04; //BIT2:0:点值正常 1:点值超限 -const int CN_FesValueComDown =0x08; //BIT3:0:通信正常 1: 通信中断 -const int CN_FesDoUnBlocked =0x80; //BIT7:0:五防闭锁 1: 五防解锁 - -//RTU状态 -const int CN_FesRtuNotUsed = 0; //保留未用 -const int CN_FesRtuNormal = 1; //RTU正常 -const int CN_FesRtuComDown = 2; //RTU通信中断 - -//通道状态 -const int CN_FesChanNotUsed = 0; //保留未用 -const int CN_FesChanCheck = 1; //通道检测,使用但未正常通信 -const int CN_FesChanRun = 2; //通道运行 -const int CN_FesChanStop = 3; //通道停止 -const int CN_FesChanErrRate = 4; //接收帧错误率高 错误率可以设置 -const int CN_FesChanErrRateRecover = 5; //接收帧错误率恢复 - -//事件类型 -const int CN_FesRtuSoeEvent = 1; //接入设备(RTU)SOE事件 -const int CN_FesFepSoeEvent = 2; //前置终端(FEP)生成SOE事件 -const int CN_FesRtuEvent = 3; //RTU事件 -const int CN_FesChanEvent = 4; //通道事件 - -//通道性质 -const int CN_FesComProperty_Collect = 0; //采集通道 -const int CN_FesComProperty_Transmit = 1; //转发通道 - -//通道类型 -const int CN_FesComNone =0; -const int CN_FesTcpClient =1; -const int CN_FesTcpServer =2; -const int CN_FesUdpClient =3; -const int CN_FesUdpServer =4; -const int CN_FesSerialPort =5; - -//通道方式 -const int CN_FesDoubleChanMode = 0; //0:双通道通信方式 -const int CN_FesSingleChanMode = 1; //1:单通道方式 - - -//通道方式 -const int CN_FesRunFlag = 1; //运行标志 -const int CN_FesStopFlag = 0; //停运标志 - -//通道数据LinkStatus状态定义 -const int CN_FesChanDisconnect =0; //通道停运 -const int CN_FesChanConnecting =1; //正在连接 -const int CN_FesChanConnect =2; //链接成功,通道运行 - - -//控制命令定义:选择、取消、执行 -const int CN_ControlSelect =1; -const int CN_ControlAbort =2; -const int CN_ControlExecute =3; -const int CN_ControlPrevent = 4; - -//定值命令定义: 读取、切区、下装、确定 -const int CN_SettingRead =1; -const int CN_SettingAreaSwitch =2; -const int CN_SettingDownload =3; -const int CN_SettingAck =4; - -//控制命令返回状态 -const int CN_ControlFailed =0; -const int CN_ControlSuccess =1; -const int CN_ControlPointErr =2; -const int CN_ControlPartialSuccess =3; //部分操作成功 - -//AO命令数值类型 -const int CN_AoValueType_Float =0; -const int CN_AoValueType_Int =1; - -//FesSimServer -const int CN_FesSimSoeEventMaxBufSize =1024; -const int CN_FesSimRtuEventMaxBufSize =256; -const int CN_FesSimChanEventMaxBufSize =256; -const int CN_FesSimChanMonMaxBufSize =512; - -//通信监视数据 -const int CN_SFesSimComFrameMaxLen =300; //监视帧最大长度 -const int CN_SFesSimComFrameTypeRecv = 0; //监视帧类型:接收 -const int CN_SFesSimComFrameTypeSend = 1; //监视帧类型:发送 -const int CN_SFesSimComDataType_Data = 0; //监视帧数据类型:数据 -const int CN_SFesSimComDataType_Str = 1; //监视帧数据类型:字符数据 -const int CN_SFesSimComFrameMaxNum = 7; //每次发送监视帧最大个数 - -const int CN_FesControlStrParamSize = 256; - -//故障相定义 (SFesSoeEvent结构中FaultValTag定义) -const int CN_Fes_IA =1; -const int CN_Fes_IB =2; -const int CN_Fes_IC =3; -const int CN_Fes_I0 =4; -const int CN_Fes_I2 =5; -const int CN_Fes_UA =6; -const int CN_Fes_UB =7; -const int CN_Fes_UC =8; -const int CN_Fes_U0 =9; -const int CN_Fes_U2 =10; -const int CN_Fes_UAB =11; -const int CN_Fes_UBC =12; -const int CN_Fes_UCA =13; -const int CN_Fes_CLOSE_NUM =14; - -//控制方向 0:FES外部(HMI) 1:FES内部(转发规约) -const int CN_Fes_CtrlDir_OutSide=0; -const int CN_Fes_CtrlDir_InSide=1; - -//转发点数据来源 -const int CN_FesFw_FesSrc = 0; //来源于FES -const int CN_FesFw_DPSrc = 1; //来源于DP - -//遥信点类型 -const int CN_FesFw_SDI = 0; //单点 -const int CN_FesFw_DDI = 1; //双点 - -//点所属专业最多个数 -const int CN_FesSubSystem_Max_Num = 16; - -//点类型 -const int CN_Fes_AI = 1; -const int CN_Fes_DI = 2; -const int CN_Fes_ACC = 3; -const int CN_Fes_MI = 4; -const int CN_Fes_DO = 5; -const int CN_Fes_AO = 6; -const int CN_Fes_MO = 7; -const int CN_Fes_Setting = 8; - -const float CN_FesFwAIChangeScale = 0.0001; - -//RTU 类型 -const int CN_Fes_RTU_Collect = 0;//采集RTU -const int CN_Fes_RTU_Forward = 1;//转发RTU - -//2021-08-03 thxiao 数据清零方式定义 -const int CN_Fes_Comdown_Clear = 0x0001; //bit0 设备离线数据清零 1:清零 0:保持数据 -const int CN_Fes_Exceed_Clear = 0x0002; //bit1 数据越限数据清零 1:清零 0:保持数据 - -//Modbus Frame Type -#define DI_BYTE_LH 0 //数字量帧(单字节) -#define DI_UWord_HL 1 //数字量帧(16bit 高字节前) -#define DI_UWord_LH 2 //数字量帧(16bit 低字节前) -#define AI_Word_HL 3 //模拟量帧(16bit 有符号 高字节前) -#define AI_Word_LH 4 //模拟量帧(16bit 有符号 低字节前) -#define AI_UWord_HL 5 //模拟量帧(16bit 无符号 高字节前) -#define AI_UWord_LH 6 //模拟量帧(16bit 无符号 低字节前) -#define AI_DWord_HH 7 //模拟量帧(32bit 有符号 高字前 高字节前) -#define AI_DWord_LH 8 //模拟量帧(32bit 有符号 低字前 高字节前) -#define AI_DWord_LL 9 //模拟量帧(32bit 有符号 低字前 低字节前) -#define AI_UDWord_HH 10 //模拟量帧(32bit 无符号 高字前 高字节前) -#define AI_UDWord_LH 11 //模拟量帧(32bit 无符号 低字前 高字节前) -#define AI_UDWord_LL 12 //模拟量帧(32bit 无符号 低字前 低字节前) -#define AI_Float_HH 13 //模拟量帧(四字节浮点 高字前 高字节前) -#define AI_Float_LH 14 //模拟量帧(四字节浮点 低字前 高字节前) -#define AI_Float_LL 15 //模拟量帧(四字节浮点 低字前 低字节前) -#define ACC_Word_HL 16 //整形量帧(16bit 有符号 高字节前) -#define ACC_Word_LH 17 //整形量帧(16bit 有符号 低字节前) -#define ACC_UWord_HL 18 //整形量帧(16bit 无符号 高字节前) -#define ACC_UWord_LH 19 //整形量帧(16bit 无符号 低字节前) -#define ACC_DWord_HH 20 //整形量帧(32bit 有符号 高字前 高字节前) -#define ACC_DWord_LH 21 //整形量帧(32bit 有符号 低字前 高字节前) -#define ACC_DWord_LL 22 //整形量帧(32bit 有符号 低字前 低字节前) -#define ACC_UDWord_HH 23 //整形量帧(32bit 无符号 高字前 高字节前) -#define ACC_UDWord_LH 24 //整形量帧(32bit 无符号 低字前 高字节前) -#define ACC_UDWord_LL 25 //整形量帧(32bit 无符号 低字前 低字节前) -#define ACC_Float_HH 26 //整形量帧(四字节浮点 高字前 高字节前) -#define ACC_Float_LH 27 //整形量帧(四字节浮点 低字前 高字节前) -#define ACC_Float_LL 28 //整形量帧(四字节浮点 低字前 低字节前) -#define MI_Word_HL 29 //混合量帧(16bit 有符号 高字节前) -#define MI_Word_LH 30 //混合量帧(16bit 有符号 低字节前) -#define MI_UWord_HL 31 //混合量帧(16bit 无符号 高字节前) -#define MI_UWord_LH 32 //混合量帧(16bit 无符号 低字节前) -#define MI_DWord_HH 33 //混合量帧(32bit 有符号 高字前 高字节前) -#define MI_DWord_LH 34 //混合量帧(32bit 有符号 低字前 高字节前) -#define MI_DWord_LL 35 //混合量帧(32bit 有符号 低字前 低字节前) -#define MI_UDWord_HH 36 //混合量帧(32bit 无符号 高字前 高字节前) -#define MI_UDWord_LH 37 //混合量帧(32bit 无符号 低字前 高字节前) -#define MI_UDWord_LL 38 //混合量帧(32bit 无符号 低字前 低字节前) - -#define SPEAM_SOE 40 //施耐德SOE帧 -#define PLC_DZ 41 //PLC_DZ -#define PLC_SOE 42 //PLC_SOE -#define PLC_DZ_DWord_HH 43 //PLC_DZ(四字节定值,高字前、高字节前) - -#define AI_Hybrid_Type 44 //模拟量混合量帧 -#define ACC_Hybrid_Type 45 //累积量混合量帧 - -#define DZ_DI_BYTE_LH 46 //数字量帧(单字节) -#define DZ_DI_UWord_HL 47 //数字量帧(16bit 高字节前) -#define DZ_DI_UWord_LH 48 //数字量帧(16bit 低字节前) -#define DZ_AI_Word_HL 49 //模拟量帧(16bit 有符号 高字节前) -#define DZ_AI_Word_LH 50 //模拟量帧(16bit 有符号 低字节前) -#define DZ_AI_UWord_HL 51 //模拟量帧(16bit 无符号 高字节前) -#define DZ_AI_UWord_LH 52 //模拟量帧(16bit 无符号 低字节前) -#define DZ_AI_DWord_HH 53 //模拟量帧(32bit 有符号 高字前 高字节前) -#define DZ_AI_DWord_LH 54 //模拟量帧(32bit 有符号 低字前 高字节前) -#define DZ_AI_DWord_LL 55 //模拟量帧(32bit 有符号 低字前 低字节前) -#define DZ_AI_UDWord_HH 56 //模拟量帧(32bit 无符号 高字前 高字节前) -#define DZ_AI_UDWord_LH 57 //模拟量帧(32bit 无符号 低字前 高字节前) -#define DZ_AI_UDWord_LL 58 //模拟量帧(32bit 无符号 低字前 低字节前) -#define DZ_AI_Float_HH 59 //模拟量帧(四字节浮点 高字前 高字节前) -#define DZ_AI_Float_LH 60 //模拟量帧(四字节浮点 低字前 高字节前) -#define DZ_AI_Float_LL 61 //模拟量帧(四字节浮点 低字前 低字节前) -#define AI_SIGNEDFLAG16_HL 62 //模拟量帧(符号位(bit15)加数值 高字节前) -#define AI_SIGNEDFLAG32_HL 63 //模拟量帧(符号位(bit31)加数值 高字节前) - - -/********************************************************************************************************************/ -//以下内部结构 -//主备通道状态 -#define EN_MAIN_CHAN 0 -#define EN_BACKUP_CHAN 1 - -//线程运行状态 -#define EN_THREAD_STOP 0 -#define EN_THREAD_RUN 1 - - -//转发五防闭锁标志 -#define CN_FW_YK_UNBLOCK 0x8000 //五防解锁 -#define CN_FW_YK_BLOCK 0x0000 //五防闭锁 -#define CN_FW_YK_UNBLOCKCLEAR 0x7fff //五防解锁清除 - - -//MODBUS配置 -typedef struct _SModbusCmd{ - int Index; //序号 - int Rtuaddr; //设备站址 - int FunCode; //功能码(即MODBUS中的命令码) - int StartAddr; //数据起始地址 - int DataLen; //数据长度 - int PollTime; //命令下发周期(相对时间,一个周期=50ms) - int Type; //帧类别 - int PollTimeCount; //命令下发周期计数 - int IsCreateSoe; //对遥信帧有效,0:不产生SOE,1:产生SOE - int Param1; //保留参数1 - int Param2; //保留参数2 - int Param3; //保留参数3 - int Param4; //保留参数4 - int Used; //块使能 - bool CommandSendFlag; //数据块轮询时间到就开始发送 - int64 lastPollTime; - int SeqNo; //2022-09-06 thxiao 自动分配块序号,供MODBUSTCPV3内部使用 - int Res1; //2022-09-06 thxiao 增加2个保留参数 - int Res2; - _SModbusCmd() - { - Index=0; //序号 - Rtuaddr=0; //设备站址 - FunCode=0; //功能码(即MODBUS中的命令码) - StartAddr=0; //数据起始地址 - DataLen=0; //数据长度 - PollTime=0; //命令下发周期(相对时间,一个周期=50ms) - Type=0; //帧类别 - PollTimeCount=0; //命令下发周期计数 - IsCreateSoe=0; //对遥信帧有效,0:不产生SOE,1:产生SOE - Param1 = 0; //保留参数1 - Param2 = 0; //保留参数2 - Param3 = 0; //保留参数3 - Param4 = 0; //保留参数4 - Used = 1; - CommandSendFlag = true; //数据块轮询时间到就开始发送(数据块第一次都会发送) - lastPollTime = 0; - SeqNo = 0; - Res1 = 0; - Res2 = 0; - } -}SModbusCmd; - -typedef struct { - int num; - int readx; - int writex; - SModbusCmd *pCmd; -}SModbusCmdBuf; - -typedef struct { - int readx; - int writex; - SModbusCmd cmd[CN_FesMaxModbusTxCmdNum]; -}SModbuTxCmdBuf; - -typedef struct { - int MappingIndex; - int RemoteNo; -}SFesFwMapping; - -typedef struct { - int SrcSubSystem; //点所属专业 - int AiFlag; - int DiFlag; - int AccFlag; - int MiFlag; -}SFesSubSystem; - -//变化数据缓存区 -const int CN_SFesAiJudge_Deadband = 0x01; -const int CN_SFesAiJudge_Limit = 0x02; - -typedef struct _SFesAi{ - int PointNo; - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - short IsFilter; //是否过滤AI突变 - short IsZeroBand;//是否判断归零死区 - int Percent; //突变百分比 - float fPercentValue; //2019-08-30 thxiao 转换后的突变比较范围 - int DeadBandType;//死区类型 - float DeadBand; //死区值 - float ZeroBand; //归零死区 - float Base; //基值 - float Coeff; //系数; - float MaxRange; //度上限 - float MinRange; //度下限 - int Param1; //规约参数,每种协议含义相同。 - int Param2; //规约参数,每种协议含义相同。 如modbus FunNo - int Param3; //规约参数,每种协议含义相同。 如modbus DataAddress - int Param4; //规约参数,每种协议含义相同。 - int Param5; //规约参数,每种协议含义相同。 - int Param6; //规约参数,每种协议含义相同。 - int Param7; //规约参数,每种协议含义相同。 - int Param8; //规约参数,每种协议含义相同。 - int Used; - float DeadBandValue;//根据配置计算处理的死区 - int JudgeFlag; //判断标志,置位了,才做对应的判断 - float Value; - float LastFilterValue; //上次收到的值,用于过滤AI突变 - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 - int DevId; //2020-12-17 thxiao 增加DevId,方便录播调用 - int FwMapNum; //转发映射个数 - SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 - _SFesAi(){ - IsZeroBand = 0; - PointNo = 0; - memset(TableName, 0, CN_FesMaxTableNameSize); - memset(ColumnName, 0, CN_FesMaxColumnNameSize); - memset(TagName, 0, CN_FesMaxTagSize); - memset(PointTagName, 0, CN_FesMaxTagSize); - memset(PointDesc, 0, CN_FesMaxDescSize); - IsFilter = 0; - Percent = 0; - fPercentValue = 0; - DeadBandType = 0; - DeadBand = 0; - ZeroBand = 0; - Base = 0.0; - Coeff = 0.0; - MaxRange = 0.0; - MinRange = 0.0; - Param1 = 0; - Param2 = 0; - Param3 = 0; - Param4 = 0; - Param5 = 0; - Param6 = 0; - Param7 = 0; - Param8 = 0; - Used = 0; - DeadBandValue = 0; - JudgeFlag = 0; - Value = 0; - LastFilterValue = 0; - Status = 0; - time = 0; - DevId = 0; - FwMapNum = 0; - memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); - } - -}SFesAi; - -typedef struct _SFesDi { - int PointNo; - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - int IsFilterErr; //是否过滤错误DI - int IsFilterDisturb;//是否过滤DI抖动 - int DisturbTime; //抖动时限 - int Revers; //取反 - int Attribute; //点属性 - int RelateDI; //关联遥信 - int Param1; //规约参数,每种协议含义相同。 如modbus FunNo - int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress - int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo - int Param4; //规约参数,每种协议各不相同。 - int Param5; //规约参数,每种协议含义相同。 - int Param6; //规约参数,每种协议含义相同。 - int Param7; //规约参数,每种协议含义相同。 - int Param8; //规约参数,每种协议含义相同。 - int Used; - int Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 - int DevId; //2020-12-17 thxiao 增加DevId,方便录播调用 - int FwMapNum; //转发映射个数 - SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 - _SFesDi() { - PointNo = 0; - memset(TableName, 0, CN_FesMaxTableNameSize); - memset(ColumnName, 0, CN_FesMaxColumnNameSize); - memset(TagName, 0, CN_FesMaxTagSize); - memset(PointTagName, 0, CN_FesMaxTagSize); - memset(PointDesc, 0, CN_FesMaxDescSize); - IsFilterErr = 0; - IsFilterDisturb = 0; - DisturbTime = 0; - Revers = 0; - Attribute = 0; - RelateDI = 0; - Param1 = 0; - Param2 = 0; - Param3 = 0; - Param4 = 0; - Param5 = 0; - Param6 = 0; - Param7 = 0; - Param8 = 0; - Used = 0; - Value = 0; - Status = 0; - time = 0; - DevId = 0; - FwMapNum = 0; - memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); - } -}SFesDi; - -typedef struct _SFesAcc { - int PointNo; - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - float Base; //基值 - float Coeff; //系数; - int Param1; //规约参数,每种协议各不相同。 如modbus FunNo - int Param2; //规约参数,每种协议各不相同。 如modbus DataAddress - int Param3; //规约参数,每种协议各不相同。 如modbus InfoNo - int Param4; //规约参数,每种协议各不相同。 如modbus ValueType - int Param5; //规约参数,每种协议含义相同。 - int Param6; //规约参数,每种协议含义相同。 - int Param7; //规约参数,每种协议含义相同。 - int Param8; //规约参数,每种协议含义相同。 - int Used; - int64 Value; - uint32 Status; - int DevId; //2020-12-17 thxiao 增加DevId,方便录播调用 - uint64 time; //1970-01-01 00:00 至今的毫秒数 - int FwMapNum; //转发映射个数 - SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 - _SFesAcc() { - PointNo = 0; - memset(TableName, 0, CN_FesMaxTableNameSize); - memset(ColumnName, 0, CN_FesMaxColumnNameSize); - memset(TagName, 0, CN_FesMaxTagSize); - memset(PointTagName, 0, CN_FesMaxTagSize); - memset(PointDesc, 0, CN_FesMaxDescSize); - Base = 0; - Coeff = 0; - Param1 = 0; - Param2 = 0; - Param3 = 0; - Param4 = 0; - Param5 = 0; - Param6 = 0; - Param7 = 0; - Param8 = 0; - Used = 0; - Value = 0; - Status = 0; - DevId = 0; - time = 0; - FwMapNum = 0; - memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); - } -}SFesAcc; - - -typedef struct _SFesMi { - int PointNo; - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - int Base; //基值 - int Coeff; //系数; - int MaxRange; //度上限 - int MinRange; //度下限 - int Param1; //规约参数,每种协议各不相同。 如modbus FunNo - int Param2; //规约参数,每种协议各不相同。 如modbus DataAddress - int Param3; //规约参数,每种协议各不相同。 如modbus InfoNo - int Param4; //规约参数,每种协议各不相同。 如modbus ValueType - int Param5; //规约参数,每种协议含义相同。 - int Param6; //规约参数,每种协议含义相同。 - int Param7; //规约参数,每种协议含义相同。 - int Param8; //规约参数,每种协议含义相同。 - int Used; - int Value; - uint32 Status; - int DevId; //2020-12-17 thxiao 增加DevId,方便录播调用 - uint64 time; //1970-01-01 00:00 至今的毫秒数 - int FwMapNum; //转发映射个数 - SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 - _SFesMi() { - PointNo = 0; - memset(TableName, 0, CN_FesMaxTableNameSize); - memset(ColumnName, 0, CN_FesMaxColumnNameSize); - memset(TagName, 0, CN_FesMaxTagSize); - memset(PointTagName, 0, CN_FesMaxTagSize); - memset(PointDesc, 0, CN_FesMaxDescSize); - Base = 0; - Coeff = 0; - MaxRange = 0; - MinRange = 0; - Param1 = 0; - Param2 = 0; - Param3 = 0; - Param4 = 0; - Param5 = 0; - Param6 = 0; - Param7 = 0; - Param8 = 0; - Used = 0; - Value = 0; - Status = 0; - DevId = 0; - time = 0; - FwMapNum = 0; - memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); - } -}SFesMi; - -typedef struct { - char used; - char unBlockFlag; //1:解锁 0:闭锁 -}SFesWfParam; - - -//Attribute -//Bit0 遥控类型。0脉冲输出,1自保持输出(需要程序清零)。 -//Bit1 遥控复归。0:表示普通遥控,1:表示复归。 -//Bit2 特殊遥控点0:表示普通遥控,1:特殊遥控点。 -const int CN_FesDo_Normal = 0x00; -const int CN_FesDo_Pulse = 0x00; -const int CN_FesDo_Keep = 0x01; -const int CN_FesDo_Reset = 0x02; -const int CN_FesDo_Special = 0x04; - -typedef struct _SFesDo { - int PointNo; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - int Attribute; //点属性 - int ControlParam; //遥控参数 - int Param1; //规约参数,每种协议含义相同。 如modbus FunNo - int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress - int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo - int Param4; //规约参数,每种协议各不相同。 - int Param5; //规约参数,每种协议含义相同。 - int Param6; //规约参数,每种协议含义相同。 - int Param7; //规约参数,每种协议含义相同。 - int Param8; //规约参数,每种协议含义相同。 - int Used; - int Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 - SFesWfParam wfParam;//五防参数 - int DevId; //2021-03-03 thxiao 增加DevId - _SFesDo() { - PointNo = 0; - memset(PointTagName, 0, CN_FesMaxTagSize); - memset(PointDesc, 0, CN_FesMaxDescSize); - memset(&wfParam, 0, sizeof(wfParam)); - Attribute = 0; - ControlParam = 0; - Param1 = 0; - Param2 = 0; - Param3 = 0; - Param4 = 0; - Param5 = 0; - Param6 = 0; - Param7 = 0; - Param8 = 0; - Used = 0; - Value = 0; - Status = 0; - time = 0; - DevId = 0; - } -}SFesDo; - -typedef struct _SFesAo { - int PointNo; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - float Base; //基值 - float Coeff; //系数; - float MaxRange; //度上限 - float MinRange; //度下限 - int Param1; //规约参数,每种协议含义相同。 如modbus FunNo - int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress - int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo - int Param4; //规约参数,每种协议含义相同。 - int Param5; //规约参数,每种协议含义相同。 - int Param6; //规约参数,每种协议含义相同。 - int Param7; //规约参数,每种协议含义相同。 - int Param8; //规约参数,每种协议含义相同。 - int Used; - float Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 - int DevId; //2021-03-03 thxiao 增加DevId - _SFesAo() { - PointNo = 0; - memset(PointTagName, 0, CN_FesMaxTagSize); - memset(PointDesc, 0, CN_FesMaxDescSize); - Base = 0; - Coeff = 0; - MaxRange = 0; - MinRange = 0; - Param1 = 0; - Param2 = 0; - Param3 = 0; - Param4 = 0; - Param5 = 0; - Param6 = 0; - Param7 = 0; - Param8 = 0; - Used = 0; - Value = 0; - Status = 0; - time = 0; - DevId = 0; - } -}SFesAo; - -typedef struct _SFesMo{ - int PointNo; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - int Base; //基值 - int Coeff; //系数; - int MaxRange; //度上限 - int MinRange; //度下限 - int Param1; //规约参数,每种协议各不相同。 如modbus FunNo - int Param2; //规约参数,每种协议各不相同。 如modbus DataAddress - int Param3; //规约参数,每种协议各不相同。 如modbus InfoNo - int Param4; //规约参数,每种协议各不相同。 如modbus ValueType - int Param5; //规约参数,每种协议含义相同。 - int Param6; //规约参数,每种协议含义相同。 - int Param7; //规约参数,每种协议含义相同。 - int Param8; //规约参数,每种协议含义相同。 - int Used; - int Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 - int DevId; //2021-03-03 thxiao 增加DevId - _SFesMo() { - PointNo = 0; - memset(PointTagName, 0, CN_FesMaxTagSize); - memset(PointDesc, 0, CN_FesMaxDescSize); - Base = 0; - Coeff = 0; - MaxRange = 0; - MinRange = 0; - Param1 = 0; - Param2 = 0; - Param3 = 0; - Param4 = 0; - Param5 = 0; - Param6 = 0; - Param7 = 0; - Param8 = 0; - Used = 0; - Value = 0; - Status = 0; - time = 0; - DevId = 0; - } -}SFesMo; - - -typedef struct { - int PointNo; - // char TagName[CN_FesMaxTagSize]; - char PointTagName[CN_FesMaxTagSize]; - int GroupNo; //定值组号 - int CodeNo; //定值代号 - int SeqNo; //定值序号 - int DzType; //定值类型 - int Unit; //单位 - double Base; //基值 - double Coeff; //系数; - double MaxRange; //度上限 - double MinRange; //度下限 - int Param1; //规约参数 - int Param2; //规约参数 - int Param3; //规约参数 - int Param4; //规约参数 - int Param5; //规约参数,每种协议含义相同。 - int Param6; //规约参数,每种协议含义相同。 - int Param7; //规约参数,每种协议含义相同。 - int Param8; //规约参数,每种协议含义相同。 - int Used; - int ValueType; - union - { - int iVal; - float fVal; - - }Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 - int DevId; //2021-03-03 thxiao 增加DevId -}SFesDz; - -//转发表变化数据缓冲区 -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - char DPTagName[CN_FesMaxTagSize]; //后台标签名 - int FesRtuNo; //采集rtu号 - int FesPointNo; //采集点号 - int DpSeqNo; //组号 - double Coeff; //系数; - double Base; //修正值 - int DeadBandType; //死区类型 - double DeadBand; //死区值 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) - int Used; - float Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesFwAi; - -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - char DPTagName[CN_FesMaxTagSize]; //后台标签名 - int FesRtuNo; //采集rtu号 - int FesPointNo; //采集点号 - int DpSeqNo; //后台点序号 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) - short Used; - short InitFlag; //数值已更新,因为DP->FES数据要产生SOE,所以需要。 - int Value; - uint32 Status; //bit7:1 (五防解锁) 0(五防闭锁) - uint64 time; //1970-01-01 00:00 至今的毫秒数 - //五防信息 - int DORemoteNo; //对应的转发遥控号 -}SFesFwDi; - -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - char DPTagName[CN_FesMaxTagSize]; //后台标签名 - int FesRtuNo; //采集rtu号 - int FesPointNo; //采集点号 - int DpSeqNo; //后台点序号 - double Coeff; //系数; - double Base; //修正值 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) - int Used; - int64 Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesFwAcc; - -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - char DPTagName[CN_FesMaxTagSize]; //后台标签名 - int FesRtuNo; //采集rtu号 - int FesPointNo; //采集点号 - int DpSeqNo; //组号 - double Coeff; //系数; - double Base; //修正值 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) - int Used; - int Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesFwMi; - -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - int FesRtuNo; //采集rtu号 - int FesPointNo; //采集点号 - double MaxRange; //度上限 - double MinRange; //度下限 - double Coeff; //系数; - double Base; //修正值 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) - int Used; - float Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesFwAo; - -const int CN_FesFwDoPointNum=5; - -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - int FesRtuNo; //采集rtu号 - int FesPointNum;//分量数 - int FesPointNo[CN_FesFwDoPointNum]; //采集点号 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) - int Used; - int Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 - //五防信息 - int DIRemoteNo; //对应的转发遥信号 - uint64 WfBlockedTimeout; //五防闭锁时间 -}SFesFwDo; - -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - int FesRtuNo; //采集rtu号 - int FesPointNo; //采集点号 - double MaxRange; //度上限 - double MinRange; //度下限 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) - int Used; - float Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesFwMo; - - -//FES间的RTU数据交互 -typedef struct { - int PointNo; - float Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesRtuAiValue; - -typedef struct { - int PointNo; - int Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesRtuDiValue; - -typedef struct { - int PointNo; - int64 Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesRtuAccValue; - -typedef struct { - int PointNo; - int Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesRtuMiValue; - -//Fes间采集RTU与转发RTU数据交互 -typedef struct { - int PointNo; - float Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesFwRtuAiValue; - -typedef struct { - int PointNo; - int Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesFwRtuDiValue; - -typedef struct { - int PointNo; - int64 Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesFwRtuAccValue; - - -//SCADA 与FES间的数据交互 变化数据缓存区 -typedef struct { - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - uint32 Status; - float Value; - uint64 time; - int RtuNo; - int PointNo; -}SFesChgAi; - -typedef struct { - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - uint32 Status; - int Value; - uint64 time; - int RtuNo; - int PointNo; -}SFesChgDi; - -typedef struct { - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - uint32 Status; - int64 Value; - uint64 time; - int RtuNo; - int PointNo; -}SFesChgAcc; - -typedef struct { - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - uint32 Status; - int Value; - uint64 time; - int RtuNo; - int PointNo; -}SFesChgMi; - -//SCADA 与FES间的数据交互 全数据 -typedef struct { - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - uint32 Status; - float Value; -}SFesAllAi; - -typedef struct { - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - uint32 Status; - int Value; -}SFesAllDi; - -typedef struct { - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - uint32 Status; - int64 Value; -}SFesAllAcc; - -typedef struct { - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - uint32 Status; - int Value; -}SFesAllMi; - -typedef struct{ - int ChanNo; - int Status; - float ErrRate; - uint64 time; -}SFesChanStatus; - -typedef struct{ - int RtuNo; - int Status; - uint64 time; -}SFesRtuStatus; - -typedef struct{ - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - uint32 Status; //遥测信状态 - int Value; //点值 - uint64 time; //1970-01-01 00:00 至今的毫秒数 - int FaultNum; //故障值个数 - int FaultValTag [CN_FesMaxFaultNum];//表明以下数值的来源 - float FaultVal[CN_FesMaxFaultNum]; - int RtuNo; //RTU号 - int PointNo; -}SFesSoeEvent; - -typedef struct{ - char ChanTagName[CN_FesMaxTagSize];//通道标签 - int nChannelNo; //通道号 - char ChanName[CN_FesMaxNameSize];//通道名词 - char ChanDesc[CN_FesMaxDescSize];//通道描述 - int nLocationId; //车站 - int nSubSystem; //专业 - int nRegionId; //责任区ID - uint32 Status; //通道状态 - float ErrRate; //通道误码率 - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesChanEvent; - -typedef struct{ - char RtuTagName[CN_FesMaxTagSize];//RTU标签 - int nRtuNo; //RTU号 - char RtuName[CN_FesMaxNameSize];//rtu名词 - char RtuDesc[CN_FesMaxDescSize];//rtu描述 - int nLocationId; //车站 - int nSubSystem; //专业 - int nRegionId; //责任区ID - uint32 Status; //RTU状态 - int CurrentChanNo; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesRtuEvent; - - -typedef struct _SFesRxDoCmd{ - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char RtuName[CN_FesMaxNameSize]; - int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) - int FwSubSystem; //转发专业 - int FwRtuNo; //转发RTU号 - int FwPointNo; //转发点号 - int RtuNo; //源RTU号 - int PointID; //源点号 - int SubSystem; //源专业 - int iValue; //目标值(DO、MO) - int CtrlActType; //控制类型 选择、取消、执行, - int TagtState; - uint64 Param1; - uint64 Param2; - float fParam; - char strParam[CN_FesControlStrParamSize]; - _SFesRxDoCmd() - { - memset(TableName,0,sizeof(TableName)); - memset(ColumnName,0,sizeof(ColumnName)); - memset(TagName,0,sizeof(TagName)); - memset(RtuName,0,sizeof(RtuName)); - CtrlDir=0; - RtuNo = 0; - PointID = 0; - SubSystem = 0; - FwSubSystem = 0; - FwRtuNo = 0; - FwPointNo = 0; - iValue = 0; //目标值(DO、MO) - CtrlActType = 0; //控制类型 选择、取消、执行, - TagtState = 0; - Param1 = 0; - Param2 = 0; - fParam = 0; - memset(strParam,0,sizeof(strParam)); - } -}SFesRxDoCmd; - -typedef struct _SFesTxDoCmd{ - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char RtuName[CN_FesMaxNameSize]; - int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) - int FwSubSystem; //转发专业 - int FwRtuNo; //转发RTU号 - int FwPointNo; //转发点号 - int RtuNo; //源RTU号 - int PointID; //源点号 - int SubSystem; //源专业 - int retStatus; //返回状态 - uint64 Param1; - uint64 Param2; - float fParam; - char strParam[CN_FesControlStrParamSize]; - int CtrlActType; //控制类型 选择、取消、执行, - _SFesTxDoCmd() - { - memset(TableName,0,sizeof(TableName)); - memset(ColumnName,0,sizeof(ColumnName)); - memset(TagName,0,sizeof(TagName)); - memset(RtuName,0,sizeof(RtuName)); - CtrlDir=0; - RtuNo = 0; - PointID = 0; - SubSystem = 0; - FwSubSystem = 0; - FwRtuNo = 0; - FwPointNo = 0; - retStatus = 0; //返回状态 - CtrlActType = 0; //控制类型 选择、取消、执行, - Param1 = 0; - Param2 = 0; - fParam = 0; - memset(strParam,0,sizeof(strParam)); - } -}SFesTxDoCmd; - -typedef struct _SFesRxAoCmd{ - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char RtuName[CN_FesMaxNameSize]; - int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) - int FwSubSystem; //转发专业 - int FwRtuNo; //转发RTU号 - int FwPointNo; //转发点号 - int RtuNo; //源RTU号 - int PointID; //源点号 - int SubSystem; //源专业 - float fValue; //目标值(AO) - int CtrlActType; //控制类型 选择、取消、执行, - int TagtState; - uint64 Param1; - uint64 Param2; - float fParam; - char strParam[CN_FesControlStrParamSize]; - _SFesRxAoCmd() - { - memset(TableName,0,sizeof(TableName)); - memset(ColumnName,0,sizeof(ColumnName)); - memset(TagName,0,sizeof(TagName)); - memset(RtuName,0,sizeof(RtuName)); - CtrlDir=0; - RtuNo = 0; - PointID = 0; - SubSystem = 0; - FwSubSystem = 0; - FwRtuNo = 0; - FwPointNo = 0; - fValue = 0; //目标值(AO) - CtrlActType = 0; //控制类型 选择、取消、执行, - TagtState = 0; - Param1 = 0; - Param2 = 0; - fParam = 0; - memset(strParam,0,sizeof(strParam)); - } -}SFesRxAoCmd; - -typedef struct _SFesTxAoCmd{ - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char RtuName[CN_FesMaxNameSize]; - int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) - int FwSubSystem; //转发专业 - int FwRtuNo; //转发RTU号 - int FwPointNo; //转发点号 - int RtuNo; //源RTU号 - int PointID; //源点号 - int SubSystem; //源专业 - int retStatus; //返回状态 - uint64 Param1; - uint64 Param2; - float fParam; - char strParam[CN_FesControlStrParamSize]; - int CtrlActType; //控制类型 选择、取消、执行, - _SFesTxAoCmd() - { - memset(TableName,0,sizeof(TableName)); - memset(ColumnName,0,sizeof(ColumnName)); - memset(TagName,0,sizeof(TagName)); - memset(RtuName,0,sizeof(RtuName)); - CtrlDir=0; - RtuNo = 0; - PointID = 0; - SubSystem = 0; - FwSubSystem = 0; - FwRtuNo = 0; - FwPointNo = 0; - retStatus = 0; - CtrlActType = 0; //控制类型 选择、取消、执行, - Param1 = 0; - Param2 = 0; - fParam = 0; - memset(strParam,0,sizeof(strParam)); - } -}SFesTxAoCmd; - -typedef struct _SFesRxMoCmd{ - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char RtuName[CN_FesMaxNameSize]; - int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) - int FwSubSystem; //转发专业 - int FwRtuNo; //转发RTU号 - int FwPointNo; //转发点号 - int RtuNo; //源RTU号 - int PointID; //源点号 - int SubSystem; //源专业 - int iValue; //目标值(DO、MO) - int CtrlActType; //控制类型 选择、取消、执行, - int TagtState; - uint64 Param1; - uint64 Param2; - float fParam; - char strParam[CN_FesControlStrParamSize]; - _SFesRxMoCmd() - { - memset(TableName,0,sizeof(TableName)); - memset(ColumnName,0,sizeof(ColumnName)); - memset(TagName,0,sizeof(TagName)); - memset(RtuName,0,sizeof(RtuName)); - CtrlDir=0; - RtuNo = 0; - PointID = 0; - SubSystem = 0; - FwSubSystem = 0; - FwRtuNo = 0; - FwPointNo = 0; - iValue = 0; //目标值(DO、MO) - CtrlActType = 0; //控制类型 选择、取消、执行, - TagtState = 0; - Param1 = 0; - Param2 = 0; - fParam = 0; - memset(strParam,0,sizeof(strParam)); - } -}SFesRxMoCmd; - -typedef struct _SFesTxMoCmd{ - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char RtuName[CN_FesMaxNameSize]; - int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) - int FwSubSystem; //转发专业 - int FwRtuNo; //转发RTU号 - int FwPointNo; //转发点号 - int RtuNo; //源RTU号 - int PointID; //源点号 - int SubSystem; //源专业 - int retStatus; //返回状态 - uint64 Param1; - uint64 Param2; - float fParam; - char strParam[CN_FesControlStrParamSize]; - int CtrlActType; //控制类型 选择、取消、执行, - _SFesTxMoCmd() - { - memset(TableName,0,sizeof(TableName)); - memset(ColumnName,0,sizeof(ColumnName)); - memset(TagName,0,sizeof(TagName)); - memset(RtuName,0,sizeof(RtuName)); - CtrlDir=0; - RtuNo = 0; - PointID = 0; - SubSystem = 0; - FwSubSystem = 0; - FwRtuNo = 0; - FwPointNo = 0; - retStatus = 0; - CtrlActType = 0; //控制类型 选择、取消、执行, - Param1 = 0; - Param2 = 0; - fParam = 0; - memset(strParam,0,sizeof(strParam)); - } -}SFesTxMoCmd; - -typedef struct{ - char TagName[CN_FesMaxTagSize];//Point tag - int Index; //Point index - int iValue; //Point Value -}SFesRxSetting; - -typedef struct{ - int RtuNo; - int DevId; //PCS3000 下的DevId - int CtrlActType; //控制类型 读取,下装、确定 - int Num; //定值个数,下装定值和确定修改定值(Num=0), 读取保护定值(Num!=0),不超过100点 - SFesRxSetting Setting[CN_FesMaxDzNum];//定值 -}SFesRxSettingCmd; - -typedef struct{ - int RtuNo; - int DevId; //PCS3000 下的DevId - int CtrlActType; //控制类型 读取,下装、确定 - int retStatus; //返回状态 - int Num; //定值个数,下装定值和确定修改定值(Num=0), 读取保护定值(Num!=0),不超过100点 - SFesRxSetting Setting[CN_FesMaxDzNum];//定值 - char strParam[CN_FesControlStrParamSize]; -}SFesTxSettingCmd; - -/* -typedef struct{ - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char RtuName[CN_FesMaxNameSize]; - int DevId; //PCS3000 下的DevId - int ParamLen; - byte Param[CN_FesMaxDefCmdSize]; //自定义命令 -}SFesRxDefCmd; - -typedef struct{ - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char RtuName[CN_FesMaxNameSize]; - int DevId; //PCS3000 下的DevId - int retStatus; //返回状态 - int ParamLen; - byte Param[CN_FesMaxDefCmdSize]; //自定义命令 - char strParam[CN_FesControlStrParamSize]; -}SFesTxDefCmd; -*/ - -typedef struct{ - std::string name; - std::string value; -}FesDefCmd; - - -typedef struct _SFesRxDefCmd { - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char RtuName[CN_FesMaxNameSize]; - int DevId; //PCS3000 下的DevId - int CmdNum; - int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) - int SrcRtuNo; //转发规约源RTU号 - std::vector VecCmd; - _SFesRxDefCmd() - { - memset(TableName, 0, sizeof(TableName)); - memset(ColumnName, 0, sizeof(ColumnName)); - memset(TagName, 0, sizeof(TagName)); - memset(RtuName, 0, sizeof(RtuName)); - DevId = 0; - CmdNum = 0; - CtrlDir = 0; - SrcRtuNo = 0; - //VecCmd.clear(); - } -}SFesRxDefCmd; - -typedef struct _SFesTxDefCmd{ - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char RtuName[CN_FesMaxNameSize]; - int DevId; //PCS3000 下的DevId - int retStatus; //返回状态 - int CmdNum; - std::vector VecCmd; - char strParam[CN_FesControlStrParamSize]; - int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) - int SrcRtuNo; //转发规约源RTU号 - _SFesTxDefCmd() - { - CtrlDir = 0; - memset(TableName,0,sizeof(TableName)); - memset(ColumnName,0,sizeof(ColumnName)); - memset(TagName,0,sizeof(TagName)); - memset(RtuName,0,sizeof(RtuName)); - DevId = 0; - retStatus = 0; - CmdNum = 0; - SrcRtuNo = 0; - memset(strParam,0,sizeof(strParam)); - } -}SFesTxDefCmd; - -typedef struct{ - int RtuNo; - int DevId; - int fileSize; - char fileName[CN_FesMaxWaveFileNameSize]; -}SFesWaveForm; - -typedef struct -{ - int ProtocolId; - char Name[CN_FesMaxNameSize]; -}SFesProtocolName; - -typedef struct{ - char NetDesc[CN_FesMaxNetDescSize]; //通道IP - int PortNo;//通道网络端口 -}SFesNetRoute; - -typedef struct{ - int ChanNo; //通道号 - char TagName[CN_FesMaxTagSize]; //RTU - char ChanName[CN_FesMaxNameSize];//通道名 - char ChanDesc[CN_FesMaxDescSize];//通道描述 - int nLocationId; //车站 - int nSubSystem; //专业 - int nRegionId; //责任区ID - int Used; //通道使用标志 - float ErrRateLimit; //帧错误标准 - SFesNetRoute NetRoute[CN_FesMaxNetRouteNum]; - int CommProperty; //通道性质 0:接收通道 1:转发通道 - int CommType; //通信方式 - int ChanMode; //通道方式0:双通道通信方式 1:单通道方式 - int ProtocolId; //规约类型 - int ConnectWaitSec; - int RespTimeout; //响应超时 - int RetryTimes; //最大重连次数 - int RecvTimeout; //接收超时,单位ms - int ConnectTimeout; //链接超时 - int MaxRxSize; //接收缓存区长度 - int MaxTxSize; //发送缓存区长度 - int BackupChanNo[CN_FesMaxChangeChanNum-1];//实际配置的备用通道号 - //char ComPortName[CN_FesMaxNameSize];//串口端口名 - int BaudRate; //波特率设置 - int Parity; //校验位 - int DataBit; //数据位 - int StopBit; //停止位 - int ResParam1; - int ResParam2; - int SetTimeEnable; //通道对时使能 - int LocalPortNo; //本地端口号 - int AlarmEnable; //2019-09-18 thxiao 增加报警使能 -}SFesChanParam; - -//本结构是通道管理的内部结构,备用通道收发的统计数据(RxNum、TxNum、ErrCnt)在自己通道结构中, -//其他数据都在主通道结构中 -typedef struct{ - uint32 Writex;//写指针 - uint32 Readx; //读指针 - byte *pData; //数据内容 -}SFesChanRxBuf; - -typedef struct{ - uint32 Writex;//写指针 - uint32 Readx; //读指针 - byte *pData; //数据内容 -}SFesChanTxBuf; - -typedef struct{ - int RtuNo; //RTU号 - char TagName[CN_FesMaxTagSize]; //RTU - char RtuName[CN_FesMaxNameSize]; //RTU - char RtuDesc[CN_FesMaxDescSize];//rtu描述 - int nLocationId;//车站 - char LocationDesc[CN_FesMaxDescSize];//2019-06-05 thxiao 车站描述 - int nSubSystem; //专业 - int Used; //使用标志 - int RtuAddr; //RTU地址 - int ChanNo; //通道号 - int RecvFailLimit; //连续接收数据失败计数(>5代表停运) - int ProtocolId; //规约类型 2018-12-25 add by thxiao - int AlarmEnable; //报警使能 2019-09-18 add by thxiao - int ResParam1; - int ResParam2; - int ResParam3; - int ControlDisable; //遥控禁止 1:禁止 0:允许 - int ClearDataEnable; //2021-08-03 thxiao - //bit0 设备离线数据清零 1:清零 0:保持数据 - //bit1 数据越限数据清零 1:清零 0:保持数据 - - char DevType[CN_FesMaxTagSize]; //2020-03-09 thxiao 设备类型 - int iDevType; //2020-03-11 thxiao 整数设备类型,一般为采集串口RTU使用,避免判断字符串,优化查找时间 - int WaveEnable; //录波使能 1:是 0:否 - SModbusCmdBuf ModbusCmdBuf; -}SFesRtuParam; - -//FesSimServer -typedef struct -{ - int RefreshFlag; //数据刷新标志为1:事件写入缓冲区 0:不写入缓存区 - int Overflow; //事件溢出标志 1:溢出 0:正常 - int Readx; - int Writex; - SFesSoeEvent Event[CN_FesSimSoeEventMaxBufSize]; -}SFesSimServerSoeEventBuf; - -typedef struct -{ - int RefreshFlag; //数据刷新标志为1:事件写入缓冲区 0:不写入缓存区 - int Overflow; //事件溢出标志 1:溢出 0:正常 - int Readx; - int Writex; - SFesRtuEvent Event[CN_FesSimRtuEventMaxBufSize]; -}SFesSimServerRtuEventBuf; - -typedef struct -{ - int RefreshFlag; //数据刷新标志为1:事件写入缓冲区 0:不写入缓存区 - int Overflow; //事件溢出标志 1:溢出 0:正常 - int Readx; - int Writex; - SFesChanEvent Event[CN_FesSimChanEventMaxBufSize]; -}SFesSimServerChanEventBuf; - -typedef struct{ - int RxNum; // - int TxNum; // - int ErrNum; -}SFesChanStatistics; - -typedef struct{ - char FrameType; //0:data 1:string - char DataType; - short FrameLen; - uint64 Time; //1970-01-01 00:00 至今的毫秒数 - byte Data[CN_SFesSimComFrameMaxLen]; -}SFesChanFrame; - -typedef struct -{ - int RefreshFlag; //数据刷新标志为1:事件写入缓冲区 0:不写入缓存区 - int ChanNo; - int Overflow; //事件溢出标志 1:溢出 0:正常 - int RxNum; // - int TxNum; // - int ErrNum; - int Readx; - int Writex; - SFesChanFrame Frame[CN_FesSimChanMonMaxBufSize]; -}SFesSimServerChanMonBuf; - -//网络通信事件队列结构,通信层和应用层互相交互 -const int CN_FesNetEvent_Waitting_Connect = 1; -const int CN_FesNetEvent_Connect = 2; -const int CN_FesNetEvent_Disconnect = 3; - -typedef struct -{ - uint64 Time; - int EventType; -}SFesNetEvent; - -//应用层事件请求,应用层和通信层互相交互 -const int CN_FesAppNetEvent_CloseSock = 1; -const int CN_FesAppNetEvent_ReopenChan = 2; - -typedef struct -{ - uint64 Time; - int EventType; -}SFesAppNetEvent; - - -//设备信息表 -typedef struct{ - int CfgSize; - int DataSize; - int Year; - int Mon; - int Day; - int Hour; - int Min; - //int Sec; - int mSec; //sec*1000+msec; -}SFesRtuWareform; - -typedef struct{ - int DevId; - char TagName[CN_FesMaxTagSize]; //2020-12-17 thxiao 设备标签名 - char DevDesc[CN_FesMaxNameSize]; - int ChildDevId; - SFesRtuWareform Record; - char LuboPath[CN_FesMaxDescSize];//2019-06-10 thxiao 增加录波路径,方便保存录波按“车站\设备”保存 - char AlarmLuboPath[CN_FesMaxDescSize];//2019-06-10 thxiao 增加相对告警录波路径,“车站\设备” -}SFesRtuDevParam; - -typedef struct{ - int RtuNo; - int DevNum; - SFesRtuDevParam *pDev; - //int WfDataLen; //录波数据长度 - //byte *pWfData; //录波数据缓存区 - //int RecvDataIndex; //录波数据保存当前数据长度 -}SFesRtuDevInfo; -//增加一个数据初始化筛选转发表的采集RTU号 -typedef struct { - int CollectRtuNum; - int CollectRtuCount; - int CollectRtuNo[CN_FesFwMaxCollectRtuNum]; -}SFesCollectRtu; - -//转发规约的接口结构 -typedef struct { - int RemoteNo; //远动号 - int RtuNo; //RTU号 - int PointNo; - uint32 Status; - float Value; - uint64 time; -}SFesFwChgAi; - -typedef struct { - int RemoteNo; //远动号 - int RtuNo; //RTU号 - int PointNo; - uint32 Status; - int Value; - uint64 time; -}SFesFwChgDi; - -typedef struct{ - int RemoteNo; //远动号 - int RtuNo; //RTU号 - int PointNo; - uint32 Status; //遥测信状态 - int Value; //点值 - uint64 time; //1970-01-01 00:00 至今的毫秒数 - int FaultNum; //故障值个数 - int FaultValTag [CN_FesMaxFaultNum];//表明以下数值的来源 - float FaultVal[CN_FesMaxFaultNum]; -}SFesFwSoeEvent; - - -typedef struct { - int RemoteNo; //远动号 - int RtuNo; //RTU号 - int PointNo; - uint32 Status; - int64 Value; - uint64 time; -}SFesFwChgAcc; - -typedef struct { - int RemoteNo; //远动号 - int RtuNo; //RTU号 - int PointNo; - uint32 Status; - int Value; - uint64 time; -}SFesFwChgMi; - -typedef struct { - int SrcSubSystem; //所属专业 - int SrcRtuNo; //RTU号 - int SrcPointNo; - uint32 Status; -}SFesFwChgDo; - -typedef struct _SFesFwDoRespCmd{ - int FwRtuNo; //RTU号 - int FwPointNo; //遥控点号 - int retStatus; //返回状态 - int CtrlActType; //控制类型 选择、取消、执行, - uint64 Param1; - uint64 Param2; - float fParam; - _SFesFwDoRespCmd() - { - FwRtuNo=0; - FwPointNo = 0; //遥控点号 - retStatus = 0; //返回状态 - CtrlActType = 0; //控制类型 选择、取消、执行, - Param1 = 0; - Param2 = 0; - fParam = 0; - } -}SFesFwDoRespCmd; - -typedef struct _SFesFwAoRespCmd{ - int FwRtuNo; //RTU号 - int FwPointNo; //遥控点号 - int retStatus; //返回状态 - uint64 Param1; - uint64 Param2; - float fParam; - int CtrlActType; //控制类型 选择、取消、执行, - _SFesFwAoRespCmd() - { - FwRtuNo =0; - FwPointNo =0; - retStatus = 0; - CtrlActType = 0; //控制类型 选择、取消、执行, - Param1 = 0; - Param2 = 0; - fParam = 0; - } -}SFesFwAoRespCmd; - -typedef struct _SFesFwMoRespCmd { - int FwRtuNo; //RTU号 - int FwPointNo; //遥控点号 - int retStatus; //返回状态 - uint64 Param1; - uint64 Param2; - float fParam; - int CtrlActType; //控制类型 选择、取消、执行, - _SFesFwMoRespCmd() - { - FwRtuNo =0; - FwPointNo = 0; //遥控点号 - retStatus = 0; - CtrlActType = 0; //控制类型 选择、取消、执行, - Param1 = 0; - Param2 = 0; - fParam = 0; - } -}SFesFwMoRespCmd; - -//201-03-011 thxiao 增加规约映射表,数据按规约点的顺序排列.方便工程在完成的情况下,现场工程又修改了点顺序。 -typedef struct { - int Used; - int PIndex; //use param1. - int PointNo; - int DevId; //2021-03-03 thxiao 增加DevId - int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo - int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress - int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo - //2021-08-04 thxiao added - int Param5; //规约参数,每种协议含义不相同。 - int Param6; //规约参数,每种协议含义不相同。 -}SFesAiIndex; - -typedef struct { - int Used; - int PIndex; //use param1. - int PointNo; - int DevId; //2021-03-03 thxiao 增加DevId - int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo - int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress - int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo - //2021-08-04 thxiao added - int Param5; //规约参数,每种协议含义不相同。 - int Param6; //规约参数,每种协议含义不相同。 -}SFesDiIndex; - -typedef struct { - int Used; - int PIndex; //use param1. - int PointNo; - int DevId; //2021-03-03 thxiao 增加DevId - int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo - int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress - int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo - //2021-08-04 thxiao added - int Param5; //规约参数,每种协议含义不相同。 - int Param6; //规约参数,每种协议含义不相同。 -}SFesAccIndex; - -typedef struct { - int Used; - int PIndex; //use param1. - int PointNo; - int DevId; //2021-03-03 thxiao 增加DevId - int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo - int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress - int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo - //2021-08-04 thxiao added - int Param5; //规约参数,每种协议含义不相同。 - int Param6; //规约参数,每种协议含义不相同。 -}SFesMiIndex; - -typedef struct { - int Used; - int PIndex; //use param1. - int PointNo; - int DevId; //2021-03-03 thxiao 增加DevId - int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo - int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress - int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo - //2021-08-04 thxiao added - int Param5; //规约参数,每种协议含义不相同。 - int Param6; //规约参数,每种协议含义不相同。 -}SFesDoIndex; - -typedef struct { - int Used; - int PIndex; //use param1. - int PointNo; - int DevId; //2021-03-03 thxiao 增加DevId - int Param2; //规约参数,每种协议含义相同。 如modbus FunNo - int Param3; //规约参数,每种协议含义相同。 如modbus DataAddress - int Param4; //规约参数,每种协议含义相同。 如modbus InfoNo - //2021-08-04 thxiao added - int Param5; //规约参数,每种协议含义不相同。 - int Param6; //规约参数,每种协议含义不相同。 -}SFesAoIndex; - -typedef struct { - int Used; - int PIndex; //use param1. - int PointNo; - int DevId; //2021-03-03 thxiao 增加DevId - int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo - int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress - int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo - //2021-08-04 thxiao added - int Param5; //规约参数,每种协议含义不相同。 - int Param6; //规约参数,每种协议含义不相同。 -}SFesMoIndex; - -typedef struct { - int Used; - int PIndex; //use param1. - int PointNo; - int DevId; //2021-03-03 thxiao 增加DevId - int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo - int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress - int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo - //2021-08-04 thxiao added - int Param5; //规约参数,每种协议含义不相同。 - int Param6; //规约参数,每种协议含义不相同。 -}SFesDzIndex; - -//车站 -typedef struct { - int nLocationId;//车站 - char LocationDesc[CN_FesMaxDescSize];//2019-06-05 thxiao 车站描述 -}SFesLocation; - -/******************************************************************************** -//转发公共数据 -*********************************************************************************/ -typedef struct _SFesFwPubAi { - int SrcLocationID; //点所属厂站 - int SrcSubSystem; //点所属专业 - char DPTagName[CN_FesMaxTagSize]; //后台标签名 - int FesRtuNo; //采集rtu号 - int SrcPointNo; //采集点号 - float Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 - int FwMapNum; //转发映射个数 - SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 - _SFesFwPubAi() - { - SrcLocationID = 0; - SrcSubSystem = 0; - memset(DPTagName, 0, CN_FesMaxTagSize); - FesRtuNo = 0; - SrcPointNo = 0; - Value = 0; - Status = 0; - time = 0; - FwMapNum = 0; - memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); - } -}SFesFwPubAi; - -typedef struct _SFesFwPubDi { - int SrcLocationID; //点所属厂站 - int SrcSubSystem; //点所属专业 - char DPTagName[CN_FesMaxTagSize]; //后台标签名 - int FesRtuNo; //采集rtu号 - int SrcPointNo; //采集点号/DP点号 - int Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 - short PointType; //0:单点 1:双点 - short FwMapNum; //转发映射个数 - SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 - _SFesFwPubDi() - { - PointType = 0; - SrcLocationID = 0; - SrcSubSystem = 0; - memset(DPTagName, 0, CN_FesMaxTagSize); - FesRtuNo = 0; - SrcPointNo = 0; - Value = 0; - Status = 0; - time = 0; - FwMapNum = 0; - memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); - } -}SFesFwPubDi; - -typedef struct _SFesFwPubAcc { - int SrcLocationID; //点所属厂站 - int SrcSubSystem; //点所属专业 - char DPTagName[CN_FesMaxTagSize]; //后台标签名 - int FesRtuNo; //采集rtu号 - int SrcPointNo; //采集点号 - uint64 Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 - int FwMapNum; //转发映射个数 - SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 - _SFesFwPubAcc() - { - SrcLocationID = 0; - SrcSubSystem = 0; - memset(DPTagName, 0, CN_FesMaxTagSize); - FesRtuNo = 0; - SrcPointNo = 0; - Value = 0; - Status = 0; - time = 0; - FwMapNum = 0; - memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); - } -}SFesFwPubAcc; - -typedef struct _SFesFwPubMi { - int SrcLocationID; //点所属厂站 - int SrcSubSystem; //点所属专业 - char DPTagName[CN_FesMaxTagSize]; //后台标签名 - int FesRtuNo; //采集rtu号 - int SrcPointNo; //采集点号 - int Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 - int FwMapNum; //转发映射个数 - SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 - _SFesFwPubMi() - { - SrcLocationID = 0; - SrcSubSystem = 0; - memset(DPTagName, 0, CN_FesMaxTagSize); - FesRtuNo = 0; - SrcPointNo = 0; - Value = 0; - Status = 0; - time = 0; - FwMapNum = 0; - memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); - } -}SFesFwPubMi; - -typedef struct _SFesFwPubDo { - int SrcLocationID; //点所属厂站 - int SrcSubSystem; //点所属专业 - int FesRtuNo; //采集rtu号 - int SrcPointNo; //采集点号/DP点号 - uint32 Status; - _SFesFwPubDo() - { - SrcLocationID = 0; - SrcSubSystem = 0; - FesRtuNo = 0; - SrcPointNo = 0; - Status = 0; - } -}SFesFwPubDo; - - -typedef struct _SFesFwDoBusCmd { - int FwSubSystem; //转发专业 - int FwRtuNo; //转发RTU号 - int FwPointNo; //转发点号 - int SubSystem; //源专业 - int RtuNo; //源RTU号 - int PointID; //源点号 - int retStatus; //返回状态 - int CtrlActType; //控制类型 选择、取消、执行, - int iValue; //目标值(DO、MO) - uint64 Param1; - uint64 Param2; - float fParam; - _SFesFwDoBusCmd() - { - FwSubSystem = 0; - FwRtuNo = 0; - FwPointNo = 0; - RtuNo = 0; - PointID = 0; - SubSystem = 0; - retStatus = 0; //返回状态 - CtrlActType = 0; //控制类型 选择、取消、执行, - iValue = 0; - Param1 = 0; - Param2 = 0; - fParam = 0; - } -}SFesFwDoBusCmd; - -typedef struct _SFesFwAoBusCmd { - int FwSubSystem; //转发专业 - int FwRtuNo; //转发RTU号 - int FwPointNo; //转发点号 - int SubSystem; //源专业 - int RtuNo; //源RTU号 - int PointID; //源点号 - int retStatus; //返回状态 - int CtrlActType; //控制类型 选择、取消、执行, - float fValue; //目标值(AO) - uint64 Param1; - uint64 Param2; - float fParam; - _SFesFwAoBusCmd() - { - FwSubSystem = 0; - FwRtuNo = 0; - FwPointNo = 0; - RtuNo = 0; - PointID = 0; - SubSystem = 0; - retStatus = 0; - CtrlActType = 0; //控制类型 选择、取消、执行, - fValue = 0; - Param1 = 0; - Param2 = 0; - fParam = 0; - } -}SFesFwAoBusCmd; - -typedef struct _SFesFwMoBusCmd { - int FwSubSystem; //转发专业 - int FwRtuNo; //转发RTU号 - int FwPointNo; //转发点号 - int SubSystem; //源专业 - int RtuNo; //源RTU号 - int PointID; //源点号 - int retStatus; //返回状态 - int CtrlActType; //控制类型 选择、取消、执行, - int iValue; //目标值(DO、MO) - uint64 Param1; - uint64 Param2; - float fParam; - _SFesFwMoBusCmd() - { - FwSubSystem = 0; - FwRtuNo = 0; - FwPointNo = 0; - RtuNo = 0; - PointID = 0; - SubSystem = 0; - retStatus = 0; - CtrlActType = 0; //控制类型 选择、取消、执行, - iValue = 0; - Param1 = 0; - Param2 = 0; - fParam = 0; - } -}SFesFwMoBusCmd; - -typedef struct { - float Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesFwAiValue; - -typedef struct { - int Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesFwDiValue; - -typedef struct { - int64 Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesFwAccValue; - -typedef struct { - int Value; - uint32 Status; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesFwMiValue; - -//2020-10-15 thxiao 虚拟数据结构 -typedef struct { - char PointTag[CN_FesMaxTagSize]; //Point Tag - char RtuTag[CN_FesMaxTagSize]; //RTU Tag - int PointType; //DO:5 AO:6 - int PointNo; - float Value; - uint64 time; //1970-01-01 00:00 至今的毫秒数 -}SFesVirtualValue; - -//2021-05-25 thiao 增加字符型的SOE -const int CN_FesSoeStrEventDecsLen = 64; - -typedef struct { - int FaultValTag; - char FaultValueDecs[CN_FesSoeStrEventDecsLen]; -}SFesSoeStrEventDesc; - - -typedef struct _SFesSoeStrEvent { - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - uint32 Status; //遥测信状态 - int Value; //点值 - uint64 time; //1970-01-01 00:00 至今的毫秒数 - vector FaultStrVal; - int RtuNo; //RTU号 - int PointNo; - _SFesSoeStrEvent(){ - memset(TableName,0,CN_FesMaxTableNameSize); - memset(ColumnName, 0, CN_FesMaxColumnNameSize); - memset(TagName, 0, CN_FesMaxTagSize); - Status = 0; - Value = 0; - time = 0; - RtuNo = 0; - PointNo = 0; - } -}SFesSoeStrEvent; +/* + @file FesDef.h + @brief 头文件 + @author thxiao + @history + 2019-02-20 thxiao 增加转发规约的接口结构;DI增加转发站标志,增加转发功能 + 2019-03-11 thxiao 增加规约映射表,数据按规约点的顺序排列.方便工程在完成的情况下,现场工程又修改了点顺序。 + 2019-03-18 thxiao 转发规约遥控指令需要RtuNo,SFesRxDoCmd\SFesRxAoCmd\SFesRxMoCmd增加定义 + 2019-06-05 thxiao SFesRtuParam 增加车站描述,方便保存录波按“车站\设备”保存 + 2019-06-10 thxiao SFesRtuDevParam 增加录波路径,方便保存录波按“车站\设备”保存 + 2019-06-11 thxiao CN_SFesSimComFrameMaxLen=300 监视帧最大长度由120变为300 + 2019-08-30 thxiao SFesAi 增加 float fPercentValue; 转换后的突变比较范围 + 2019-09-18 thxiao SFesChanParam,SFesRtuParam,增加报警使能 + 2019-10-21 thxiao 点结构增加字段 + 2020-01-16 thxiao 前置点增加点描述 + 2020-03-11 thxiao SFesRtuParam 增加设备类型、整数设备类型,一般为采集串口RTU使用,避免判断字符串,优化查找时间 + 2020-09-29 thxiao 控制命令返回状态增加部分操作成功 + 2020-10-15 thxiao 增加虚拟数据结构SFesVirtualValue + 2021-03-04 thxiao DO AO MO DZ增加DevId + 2021-05-25 thxiao 增加字符型的SOE + 2021-06-25 thxiao 增加MODBUS类型 + 2021-08-03 thxiao 增加数据清零方式定义,越限清零 + +*/ +#pragma once +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +//#include +#include + +#ifdef WIN32 +/* +#pragma warning(disable: 4100)//未引用的形参 +#pragma warning(disable: 4101)//未引用的局部变量 +#pragma warning(disable: 4251)//需要有dll接口由class"xxxx"的客户端使用 +#pragma warning(disable: 4267)// “=”: 从“size_t”转换到“int”,可能丢失数据 +#pragma warning(disable: 4305)// “初始化”: 从“double”到“float”截断 +#pragma warning(disable: 4275)// 非 dll 接口 class“google::protobuf::Message”用作 dll 接口 class“iot_idl:: +#pragma warning(disable: 4819)//该文件包含不能在当前代码页(0)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 +#pragma warning(disable: 4474)// sprintf: 格式字符串中传递的参数太多 +#pragma warning(disable: 4313)//“sprintf”: 格式字符串中的“%d”与“char *”类型的参数 5 冲突 +*/ +#include +#include +#define in_addr_t unsigned long +#define SHUT_RDWR 2 +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif +#define socklen_t int +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +typedef int SOCKET; +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define closesocket close +#define ioctlsocket ioctl +#endif + +#ifndef FESSIM +// 以下头文件FES仿真程序不需要使用,如有包含会编译出错 +#include +#include +#include +#include "pub_utility_api/TimerThreadBase.h" +#include "pub_utility_api/TimeUtil.h" +#include "pub_logger_api/logger.h" +#endif +#include "common/Common.h" +#include "common/DataType.h" +#include "FesRdbStruct.h" + + +#ifdef PROTOCOLBASE_API_EXPORTS +#define PROTOCOLBASE_API G_DECL_EXPORT +#else +#define PROTOCOLBASE_API G_DECL_IMPORT +#endif + +/* +#ifdef PROTOCOLBASE_API_EXPORTS +#ifdef WIN32 +#define PROTOCOLBASE_API G_DECL_EXPORT +#else +//LINUX下 默认情况下会使用C++ API函数命名规则(函数名会增加字符),使用extern "C"修饰后变为C的函数名,便于使用。 +#define PROTOCOLBASE_API extern "C" +#endif +#else +#define PROTOCOLBASE_API G_DECL_IMPORT +#endif +*/ + +using namespace std; + +const float CN_FesFloatCompare = 0.000001f;//用于浮点型数据的比较 + +const int CN_FesMaxProtocolNum = 64; //系统可接入规约数 +const int CN_FesMaxRtuNumPerChan = 32; //每个通道可接设备数(只对通道为polling方式) +const int CN_FesMaxChangeMultiple = 5; //变化数据缓冲区为数据个数的倍数 +const int CN_FesMaxDzParamSize =800; //定值参数最大长度 +const int CN_FesMaxDzNum =40; //定值最大个数一帧的定值个数最大40个(KBD104中规定) +const int CN_FesMaxDefCmdSize =512; //自定义命令最大长度 +const int CN_FesMaxWaveFileNameSize =256; //录波文件名最大长度 +const int CN_FesMaxModbusTxCmdNum =200; //MODBUS命令发送缓冲区最大条数 +const int CN_FesMaxFaultNum =4; //事件中最大故障数据 +const int CN_FesFwMaxCollectRtuNum =256; //RTU转发表里的采集RTU最大个数 +const int CN_Fes_Fw_MaxMapping = 16; //转发协议最大转发站数目 +const int CN_Fes_MaxCmdBufSize = 100; //每个RTU每种命令类型最多缓存的命令数量 + +//模拟量死区类型 +const int CN_FesDeadbandType_Percent = 0; //上下限百分比 +const int CN_FesDeadbandType_Abs = 1; //绝对值 +const int CN_FesDeadbandType_None = 2; //不判断死区 + +//点值状态 +const int CN_FesValueNotUpdate =0x00; //BIT0: 0:点值未更新 1:点已更新 +const int CN_FesValueUpdate =0x01; //BIT0: 0:点值未更新 1:点已更新 +const int CN_FesValueInvaild =0x02; //BIT1:0:点值无效 1:点值无效 设备报告无效 +const int CN_FesValueExceed =0x04; //BIT2:0:点值正常 1:点值超限 +const int CN_FesValueComDown =0x08; //BIT3:0:通信正常 1: 通信中断 +const int CN_FesDoUnBlocked =0x80; //BIT7:0:五防闭锁 1: 五防解锁 + +//RTU状态 +const int CN_FesRtuNotUsed = 0; //保留未用 +const int CN_FesRtuNormal = 1; //RTU正常 +const int CN_FesRtuComDown = 2; //RTU通信中断 + +//通道状态 +const int CN_FesChanNotUsed = 0; //保留未用 +const int CN_FesChanCheck = 1; //通道检测,使用但未正常通信 +const int CN_FesChanRun = 2; //通道运行 +const int CN_FesChanStop = 3; //通道停止 +const int CN_FesChanErrRate = 4; //接收帧错误率高 错误率可以设置 +const int CN_FesChanErrRateRecover = 5; //接收帧错误率恢复 + +//事件类型 +const int CN_FesRtuSoeEvent = 1; //接入设备(RTU)SOE事件 +const int CN_FesFepSoeEvent = 2; //前置终端(FEP)生成SOE事件 +const int CN_FesRtuEvent = 3; //RTU事件 +const int CN_FesChanEvent = 4; //通道事件 + +//通道性质 +const int CN_FesComProperty_Collect = 0; //采集通道 +const int CN_FesComProperty_Transmit = 1; //转发通道 + +//通道类型 +const int CN_FesComNone =0; +const int CN_FesTcpClient =1; +const int CN_FesTcpServer =2; +const int CN_FesUdpClient =3; +const int CN_FesUdpServer =4; +const int CN_FesSerialPort =5; + +//通道方式 +const int CN_FesDoubleChanMode = 0; //0:双通道通信方式 +const int CN_FesSingleChanMode = 1; //1:单通道方式 + + +//通道方式 +const int CN_FesRunFlag = 1; //运行标志 +const int CN_FesStopFlag = 0; //停运标志 + +//通道数据LinkStatus状态定义 +const int CN_FesChanDisconnect =0; //通道停运 +const int CN_FesChanConnecting =1; //正在连接 +const int CN_FesChanConnect =2; //链接成功,通道运行 + + +//控制命令定义:选择、取消、执行 +const int CN_ControlSelect =1; +const int CN_ControlAbort =2; +const int CN_ControlExecute =3; +const int CN_ControlPrevent = 4; + +//定值命令定义: 读取、切区、下装、确定 +const int CN_SettingRead =1; +const int CN_SettingAreaSwitch =2; +const int CN_SettingDownload =3; +const int CN_SettingAck =4; + +//控制命令返回状态 +const int CN_ControlFailed =0; +const int CN_ControlSuccess =1; +const int CN_ControlPointErr =2; +const int CN_ControlPartialSuccess =3; //部分操作成功 + +//AO命令数值类型 +const int CN_AoValueType_Float =0; +const int CN_AoValueType_Int =1; + +//FesSimServer +const int CN_FesSimSoeEventMaxBufSize =1024; +const int CN_FesSimRtuEventMaxBufSize =256; +const int CN_FesSimChanEventMaxBufSize =256; +const int CN_FesSimChanMonMaxBufSize =512; + +//通信监视数据 +const int CN_SFesSimComFrameMaxLen =300; //监视帧最大长度 +const int CN_SFesSimComFrameTypeRecv = 0; //监视帧类型:接收 +const int CN_SFesSimComFrameTypeSend = 1; //监视帧类型:发送 +const int CN_SFesSimComDataType_Data = 0; //监视帧数据类型:数据 +const int CN_SFesSimComDataType_Str = 1; //监视帧数据类型:字符数据 +const int CN_SFesSimComFrameMaxNum = 7; //每次发送监视帧最大个数 + +const int CN_FesControlStrParamSize = 256; + +//故障相定义 (SFesSoeEvent结构中FaultValTag定义) +const int CN_Fes_IA =1; +const int CN_Fes_IB =2; +const int CN_Fes_IC =3; +const int CN_Fes_I0 =4; +const int CN_Fes_I2 =5; +const int CN_Fes_UA =6; +const int CN_Fes_UB =7; +const int CN_Fes_UC =8; +const int CN_Fes_U0 =9; +const int CN_Fes_U2 =10; +const int CN_Fes_UAB =11; +const int CN_Fes_UBC =12; +const int CN_Fes_UCA =13; +const int CN_Fes_CLOSE_NUM =14; + +//控制方向 0:FES外部(HMI) 1:FES内部(转发规约) +const int CN_Fes_CtrlDir_OutSide=0; +const int CN_Fes_CtrlDir_InSide=1; + +//转发点数据来源 +const int CN_FesFw_FesSrc = 0; //来源于FES +const int CN_FesFw_DPSrc = 1; //来源于DP + +//遥信点类型 +const int CN_FesFw_SDI = 0; //单点 +const int CN_FesFw_DDI = 1; //双点 + +//点所属专业最多个数 +const int CN_FesSubSystem_Max_Num = 16; + +//点类型 +const int CN_Fes_AI = 1; +const int CN_Fes_DI = 2; +const int CN_Fes_ACC = 3; +const int CN_Fes_MI = 4; +const int CN_Fes_DO = 5; +const int CN_Fes_AO = 6; +const int CN_Fes_MO = 7; +const int CN_Fes_Setting = 8; + +const float CN_FesFwAIChangeScale = 0.0001f; + +//RTU 类型 +const int CN_Fes_RTU_Collect = 0;//采集RTU +const int CN_Fes_RTU_Forward = 1;//转发RTU + +//2021-08-03 thxiao 数据清零方式定义 +const int CN_Fes_Comdown_Clear = 0x0001; //bit0 设备离线数据清零 1:清零 0:保持数据 +const int CN_Fes_Exceed_Clear = 0x0002; //bit1 数据越限数据清零 1:清零 0:保持数据 + +//Modbus Frame Type +#define DI_BYTE_LH 0 //数字量帧(单字节) +#define DI_UWord_HL 1 //数字量帧(16bit 高字节前) +#define DI_UWord_LH 2 //数字量帧(16bit 低字节前) +#define AI_Word_HL 3 //模拟量帧(16bit 有符号 高字节前) +#define AI_Word_LH 4 //模拟量帧(16bit 有符号 低字节前) +#define AI_UWord_HL 5 //模拟量帧(16bit 无符号 高字节前) +#define AI_UWord_LH 6 //模拟量帧(16bit 无符号 低字节前) +#define AI_DWord_HH 7 //模拟量帧(32bit 有符号 高字前 高字节前) +#define AI_DWord_LH 8 //模拟量帧(32bit 有符号 低字前 高字节前) +#define AI_DWord_LL 9 //模拟量帧(32bit 有符号 低字前 低字节前) +#define AI_UDWord_HH 10 //模拟量帧(32bit 无符号 高字前 高字节前) +#define AI_UDWord_LH 11 //模拟量帧(32bit 无符号 低字前 高字节前) +#define AI_UDWord_LL 12 //模拟量帧(32bit 无符号 低字前 低字节前) +#define AI_Float_HH 13 //模拟量帧(四字节浮点 高字前 高字节前) +#define AI_Float_LH 14 //模拟量帧(四字节浮点 低字前 高字节前) +#define AI_Float_LL 15 //模拟量帧(四字节浮点 低字前 低字节前) +#define ACC_Word_HL 16 //整形量帧(16bit 有符号 高字节前) +#define ACC_Word_LH 17 //整形量帧(16bit 有符号 低字节前) +#define ACC_UWord_HL 18 //整形量帧(16bit 无符号 高字节前) +#define ACC_UWord_LH 19 //整形量帧(16bit 无符号 低字节前) +#define ACC_DWord_HH 20 //整形量帧(32bit 有符号 高字前 高字节前) +#define ACC_DWord_LH 21 //整形量帧(32bit 有符号 低字前 高字节前) +#define ACC_DWord_LL 22 //整形量帧(32bit 有符号 低字前 低字节前) +#define ACC_UDWord_HH 23 //整形量帧(32bit 无符号 高字前 高字节前) +#define ACC_UDWord_LH 24 //整形量帧(32bit 无符号 低字前 高字节前) +#define ACC_UDWord_LL 25 //整形量帧(32bit 无符号 低字前 低字节前) +#define ACC_Float_HH 26 //整形量帧(四字节浮点 高字前 高字节前) +#define ACC_Float_LH 27 //整形量帧(四字节浮点 低字前 高字节前) +#define ACC_Float_LL 28 //整形量帧(四字节浮点 低字前 低字节前) +#define MI_Word_HL 29 //混合量帧(16bit 有符号 高字节前) +#define MI_Word_LH 30 //混合量帧(16bit 有符号 低字节前) +#define MI_UWord_HL 31 //混合量帧(16bit 无符号 高字节前) +#define MI_UWord_LH 32 //混合量帧(16bit 无符号 低字节前) +#define MI_DWord_HH 33 //混合量帧(32bit 有符号 高字前 高字节前) +#define MI_DWord_LH 34 //混合量帧(32bit 有符号 低字前 高字节前) +#define MI_DWord_LL 35 //混合量帧(32bit 有符号 低字前 低字节前) +#define MI_UDWord_HH 36 //混合量帧(32bit 无符号 高字前 高字节前) +#define MI_UDWord_LH 37 //混合量帧(32bit 无符号 低字前 高字节前) +#define MI_UDWord_LL 38 //混合量帧(32bit 无符号 低字前 低字节前) + +#define SPEAM_SOE 40 //施耐德SOE帧 +#define PLC_DZ 41 //PLC_DZ +#define PLC_SOE 42 //PLC_SOE +#define PLC_DZ_DWord_HH 43 //PLC_DZ(四字节定值,高字前、高字节前) + +#define AI_Hybrid_Type 44 //模拟量混合量帧 +#define ACC_Hybrid_Type 45 //累积量混合量帧 + +#define DZ_DI_BYTE_LH 46 //数字量帧(单字节) +#define DZ_DI_UWord_HL 47 //数字量帧(16bit 高字节前) +#define DZ_DI_UWord_LH 48 //数字量帧(16bit 低字节前) +#define DZ_AI_Word_HL 49 //模拟量帧(16bit 有符号 高字节前) +#define DZ_AI_Word_LH 50 //模拟量帧(16bit 有符号 低字节前) +#define DZ_AI_UWord_HL 51 //模拟量帧(16bit 无符号 高字节前) +#define DZ_AI_UWord_LH 52 //模拟量帧(16bit 无符号 低字节前) +#define DZ_AI_DWord_HH 53 //模拟量帧(32bit 有符号 高字前 高字节前) +#define DZ_AI_DWord_LH 54 //模拟量帧(32bit 有符号 低字前 高字节前) +#define DZ_AI_DWord_LL 55 //模拟量帧(32bit 有符号 低字前 低字节前) +#define DZ_AI_UDWord_HH 56 //模拟量帧(32bit 无符号 高字前 高字节前) +#define DZ_AI_UDWord_LH 57 //模拟量帧(32bit 无符号 低字前 高字节前) +#define DZ_AI_UDWord_LL 58 //模拟量帧(32bit 无符号 低字前 低字节前) +#define DZ_AI_Float_HH 59 //模拟量帧(四字节浮点 高字前 高字节前) +#define DZ_AI_Float_LH 60 //模拟量帧(四字节浮点 低字前 高字节前) +#define DZ_AI_Float_LL 61 //模拟量帧(四字节浮点 低字前 低字节前) +#define AI_SIGNEDFLAG16_HL 62 //模拟量帧(符号位(bit15)加数值 高字节前) +#define AI_SIGNEDFLAG32_HL 63 //模拟量帧(符号位(bit31)加数值 高字节前) +#define AI_16BIT_BYBITS 64 //模拟量帧(取16bit 按位组合取值) + + +/********************************************************************************************************************/ +//以下内部结构 +//主备通道状态 +#define EN_MAIN_CHAN 0 +#define EN_BACKUP_CHAN 1 + +//线程运行状态 +#define EN_THREAD_STOP 0 +#define EN_THREAD_RUN 1 + + +//转发五防闭锁标志 +#define CN_FW_YK_UNBLOCK 0x8000 //五防解锁 +#define CN_FW_YK_BLOCK 0x0000 //五防闭锁 +#define CN_FW_YK_UNBLOCKCLEAR 0x7fff //五防解锁清除 + +//< 更新转发缓冲区的模式 +enum EnumUpdateFwCacheMode +{ + eDirectUpdate = 0, //< 直接更新,不进行任何数据加工和处理 + eNormalUpdate = 1, //< 对数据进行基值和系数变换后,判断死区后更新 + eWithoutDeadbandUpdate = 2, //< 对数据进行基值和系数变换,不判断死区 +}; + +//MODBUS配置 +typedef struct _SModbusCmd{ + int Index; //序号 + int Rtuaddr; //设备站址 + int FunCode; //功能码(即MODBUS中的命令码) + int StartAddr; //数据起始地址 + int DataLen; //数据长度 + int PollTime; //命令下发周期(相对时间,一个周期=50ms) + int Type; //帧类别 + int PollTimeCount; //命令下发周期计数 + int IsCreateSoe; //对遥信帧有效,0:不产生SOE,1:产生SOE + int Param1; //保留参数1 + int Param2; //保留参数2 + int Param3; //保留参数3 + int Param4; //保留参数4 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int Used; //块使能 + bool CommandSendFlag; //数据块轮询时间到就开始发送 + int64 lastPollTime; + int SeqNo; //2022-09-06 thxiao 自动分配块序号,供MODBUSTCPV3内部使用 + int Res1; //2022-09-06 thxiao 增加2个保留参数 + int Res2; + _SModbusCmd() + { + memset(szResParam1,0,sizeof(szResParam1)); + Index=0; //序号 + Rtuaddr=0; //设备站址 + FunCode=0; //功能码(即MODBUS中的命令码) + StartAddr=0; //数据起始地址 + DataLen=0; //数据长度 + PollTime=0; //命令下发周期(相对时间,一个周期=50ms) + Type=0; //帧类别 + PollTimeCount=0; //命令下发周期计数 + IsCreateSoe=0; //对遥信帧有效,0:不产生SOE,1:产生SOE + Param1 = 0; //保留参数1 + Param2 = 0; //保留参数2 + Param3 = 0; //保留参数3 + Param4 = 0; //保留参数4 + Used = 1; + CommandSendFlag = true; //数据块轮询时间到就开始发送(数据块第一次都会发送) + lastPollTime = 0; + SeqNo = 0; + Res1 = 0; + Res2 = 0; + } +}SModbusCmd; + +typedef struct { + int num; + int readx; + int writex; + SModbusCmd *pCmd; +}SModbusCmdBuf; + +typedef struct { + int readx; + int writex; + SModbusCmd cmd[CN_FesMaxModbusTxCmdNum]; +}SModbuTxCmdBuf; + +typedef struct { + int MappingIndex; + int RemoteNo; +}SFesFwMapping; + +typedef struct { + int SrcSubSystem; //点所属专业 + int AiFlag; + int DiFlag; + int AccFlag; + int MiFlag; +}SFesSubSystem; + +//变化数据缓存区 +const int CN_SFesAiJudge_Deadband = 0x01; +const int CN_SFesAiJudge_Limit = 0x02; + +typedef struct _SFesAi{ + int PointNo; + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + short IsFilter; //是否过滤AI突变 + short IsZeroBand;//是否判断归零死区 + int Percent; //突变百分比 + float fPercentValue; //2019-08-30 thxiao 转换后的突变比较范围 + int DeadBandType;//死区类型 + float DeadBand; //死区值 + float ZeroBand; //归零死区 + float Base; //基值 + float Coeff; //系数; + float MaxRange; //度上限 + float MinRange; //度下限 + int Param1; //规约参数,每种协议含义相同。 + int Param2; //规约参数,每种协议含义相同。 如modbus FunNo + int Param3; //规约参数,每种协议含义相同。 如modbus DataAddress + int Param4; //规约参数,每种协议含义相同。 + int Param5; //规约参数,每种协议含义相同。 + int Param6; //规约参数,每种协议含义相同。 + int Param7; //规约参数,每种协议含义相同。 + int Param8; //规约参数,每种协议含义相同。 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int Used; + float DeadBandValue;//根据配置计算处理的死区 + int JudgeFlag; //判断标志,置位了,才做对应的判断 + float Value; + float LastFilterValue; //上次收到的值,用于过滤AI突变 + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 + int DevId; //2020-12-17 thxiao 增加DevId,方便录播调用 + int FwMapNum; //转发映射个数 + SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 + _SFesAi(){ + IsZeroBand = 0; + PointNo = 0; + memset(TableName, 0, CN_FesMaxTableNameSize); + memset(ColumnName, 0, CN_FesMaxColumnNameSize); + memset(TagName, 0, CN_FesMaxTagSize); + memset(PointTagName, 0, CN_FesMaxTagSize); + memset(PointDesc, 0, CN_FesMaxDescSize); + memset(szResParam1,0,sizeof(szResParam1)); + IsFilter = 0; + Percent = 0; + fPercentValue = 0; + DeadBandType = 0; + DeadBand = 0; + ZeroBand = 0; + Base = 0.0; + Coeff = 0.0; + MaxRange = 0.0; + MinRange = 0.0; + Param1 = 0; + Param2 = 0; + Param3 = 0; + Param4 = 0; + Param5 = 0; + Param6 = 0; + Param7 = 0; + Param8 = 0; + Used = 0; + DeadBandValue = 0; + JudgeFlag = 0; + Value = 0; + LastFilterValue = 0; + Status = 0; + time = 0; + DevId = 0; + FwMapNum = 0; + memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); + } + +}SFesAi; + +typedef struct _SFesDi { + int PointNo; + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + int IsFilterErr; //是否过滤错误DI + int IsFilterDisturb;//是否过滤DI抖动 + int DisturbTime; //抖动时限 + int Revers; //取反 + int Attribute; //点属性 + int RelateDI; //关联遥信 + int Param1; //规约参数,每种协议含义相同。 如modbus FunNo + int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress + int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo + int Param4; //规约参数,每种协议各不相同。 + int Param5; //规约参数,每种协议含义相同。 + int Param6; //规约参数,每种协议含义相同。 + int Param7; //规约参数,每种协议含义相同。 + int Param8; //规约参数,每种协议含义相同。 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int Used; + int Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 + int DevId; //2020-12-17 thxiao 增加DevId,方便录播调用 + int FwMapNum; //转发映射个数 + SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 + _SFesDi() { + PointNo = 0; + memset(TableName, 0, CN_FesMaxTableNameSize); + memset(ColumnName, 0, CN_FesMaxColumnNameSize); + memset(TagName, 0, CN_FesMaxTagSize); + memset(PointTagName, 0, CN_FesMaxTagSize); + memset(PointDesc, 0, CN_FesMaxDescSize); + memset(szResParam1,0,sizeof(szResParam1)); + IsFilterErr = 0; + IsFilterDisturb = 0; + DisturbTime = 0; + Revers = 0; + Attribute = 0; + RelateDI = 0; + Param1 = 0; + Param2 = 0; + Param3 = 0; + Param4 = 0; + Param5 = 0; + Param6 = 0; + Param7 = 0; + Param8 = 0; + Used = 0; + Value = 0; + Status = 0; + time = 0; + DevId = 0; + FwMapNum = 0; + memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); + } +}SFesDi; + +typedef struct _SFesAcc { + int PointNo; + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + float Base; //基值 + double Coeff; //系数; + int Param1; //规约参数,每种协议各不相同。 如modbus FunNo + int Param2; //规约参数,每种协议各不相同。 如modbus DataAddress + int Param3; //规约参数,每种协议各不相同。 如modbus InfoNo + int Param4; //规约参数,每种协议各不相同。 如modbus ValueType + int Param5; //规约参数,每种协议含义相同。 + int Param6; //规约参数,每种协议含义相同。 + int Param7; //规约参数,每种协议含义相同。 + int Param8; //规约参数,每种协议含义相同。 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int Used; + double Value; + uint32 Status; + int DevId; //2020-12-17 thxiao 增加DevId,方便录播调用 + uint64 time; //1970-01-01 00:00 至今的毫秒数 + int FwMapNum; //转发映射个数 + SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 + _SFesAcc() { + PointNo = 0; + memset(TableName, 0, CN_FesMaxTableNameSize); + memset(ColumnName, 0, CN_FesMaxColumnNameSize); + memset(TagName, 0, CN_FesMaxTagSize); + memset(PointTagName, 0, CN_FesMaxTagSize); + memset(PointDesc, 0, CN_FesMaxDescSize); + memset(szResParam1,0,sizeof(szResParam1)); + Base = 0; + Coeff = 0; + Param1 = 0; + Param2 = 0; + Param3 = 0; + Param4 = 0; + Param5 = 0; + Param6 = 0; + Param7 = 0; + Param8 = 0; + Used = 0; + Value = 0; + Status = 0; + DevId = 0; + time = 0; + FwMapNum = 0; + memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); + } +}SFesAcc; + + +typedef struct _SFesMi { + int PointNo; + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + int Base; //基值 + int Coeff; //系数; + int MaxRange; //度上限 + int MinRange; //度下限 + int Param1; //规约参数,每种协议各不相同。 如modbus FunNo + int Param2; //规约参数,每种协议各不相同。 如modbus DataAddress + int Param3; //规约参数,每种协议各不相同。 如modbus InfoNo + int Param4; //规约参数,每种协议各不相同。 如modbus ValueType + int Param5; //规约参数,每种协议含义相同。 + int Param6; //规约参数,每种协议含义相同。 + int Param7; //规约参数,每种协议含义相同。 + int Param8; //规约参数,每种协议含义相同。 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int Used; + int Value; + uint32 Status; + int DevId; //2020-12-17 thxiao 增加DevId,方便录播调用 + uint64 time; //1970-01-01 00:00 至今的毫秒数 + int FwMapNum; //转发映射个数 + SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 + _SFesMi() { + PointNo = 0; + memset(TableName, 0, CN_FesMaxTableNameSize); + memset(ColumnName, 0, CN_FesMaxColumnNameSize); + memset(TagName, 0, CN_FesMaxTagSize); + memset(PointTagName, 0, CN_FesMaxTagSize); + memset(PointDesc, 0, CN_FesMaxDescSize); + memset(szResParam1,0,sizeof(szResParam1)); + Base = 0; + Coeff = 0; + MaxRange = 0; + MinRange = 0; + Param1 = 0; + Param2 = 0; + Param3 = 0; + Param4 = 0; + Param5 = 0; + Param6 = 0; + Param7 = 0; + Param8 = 0; + Used = 0; + Value = 0; + Status = 0; + DevId = 0; + time = 0; + FwMapNum = 0; + memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); + } +}SFesMi; + +typedef struct { + char used; + char unBlockFlag; //1:解锁 0:闭锁 +}SFesWfParam; + + +//Attribute +//Bit0 遥控类型。0脉冲输出,1自保持输出(需要程序清零)。 +//Bit1 遥控复归。0:表示普通遥控,1:表示复归。 +//Bit2 特殊遥控点0:表示普通遥控,1:特殊遥控点。 +const int CN_FesDo_Normal = 0x00; +const int CN_FesDo_Pulse = 0x00; +const int CN_FesDo_Keep = 0x01; +const int CN_FesDo_Reset = 0x02; +const int CN_FesDo_Special = 0x04; + +typedef struct _SFesDo { + int PointNo; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + int Attribute; //点属性 + int ControlParam; //遥控参数 + int Param1; //规约参数,每种协议含义相同。 如modbus FunNo + int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress + int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo + int Param4; //规约参数,每种协议各不相同。 + int Param5; //规约参数,每种协议含义相同。 + int Param6; //规约参数,每种协议含义相同。 + int Param7; //规约参数,每种协议含义相同。 + int Param8; //规约参数,每种协议含义相同。 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int Used; + int Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 + SFesWfParam wfParam;//五防参数 + int DevId; //2021-03-03 thxiao 增加DevId + _SFesDo() { + PointNo = 0; + memset(PointTagName, 0, CN_FesMaxTagSize); + memset(PointDesc, 0, CN_FesMaxDescSize); + memset(&wfParam, 0, sizeof(wfParam)); + memset(szResParam1,0,sizeof(szResParam1)); + Attribute = 0; + ControlParam = 0; + Param1 = 0; + Param2 = 0; + Param3 = 0; + Param4 = 0; + Param5 = 0; + Param6 = 0; + Param7 = 0; + Param8 = 0; + Used = 0; + Value = 0; + Status = 0; + time = 0; + DevId = 0; + } +}SFesDo; + +typedef struct _SFesAo { + int PointNo; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + float Base; //基值 + float Coeff; //系数; + float MaxRange; //度上限 + float MinRange; //度下限 + int Param1; //规约参数,每种协议含义相同。 如modbus FunNo + int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress + int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo + int Param4; //规约参数,每种协议含义相同。 + int Param5; //规约参数,每种协议含义相同。 + int Param6; //规约参数,每种协议含义相同。 + int Param7; //规约参数,每种协议含义相同。 + int Param8; //规约参数,每种协议含义相同。 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int Used; + float Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 + int DevId; //2021-03-03 thxiao 增加DevId + _SFesAo() { + PointNo = 0; + memset(PointTagName, 0, CN_FesMaxTagSize); + memset(PointDesc, 0, CN_FesMaxDescSize); + memset(szResParam1,0,sizeof(szResParam1)); + Base = 0; + Coeff = 0; + MaxRange = 0; + MinRange = 0; + Param1 = 0; + Param2 = 0; + Param3 = 0; + Param4 = 0; + Param5 = 0; + Param6 = 0; + Param7 = 0; + Param8 = 0; + Used = 0; + Value = 0; + Status = 0; + time = 0; + DevId = 0; + } +}SFesAo; + +typedef struct _SFesMo{ + int PointNo; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + int Base; //基值 + int Coeff; //系数; + int MaxRange; //度上限 + int MinRange; //度下限 + int Param1; //规约参数,每种协议各不相同。 如modbus FunNo + int Param2; //规约参数,每种协议各不相同。 如modbus DataAddress + int Param3; //规约参数,每种协议各不相同。 如modbus InfoNo + int Param4; //规约参数,每种协议各不相同。 如modbus ValueType + int Param5; //规约参数,每种协议含义相同。 + int Param6; //规约参数,每种协议含义相同。 + int Param7; //规约参数,每种协议含义相同。 + int Param8; //规约参数,每种协议含义相同。 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int Used; + int Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 + int DevId; //2021-03-03 thxiao 增加DevId + _SFesMo() { + PointNo = 0; + memset(PointTagName, 0, CN_FesMaxTagSize); + memset(PointDesc, 0, CN_FesMaxDescSize); + memset(szResParam1,0,sizeof(szResParam1)); + Base = 0; + Coeff = 0; + MaxRange = 0; + MinRange = 0; + Param1 = 0; + Param2 = 0; + Param3 = 0; + Param4 = 0; + Param5 = 0; + Param6 = 0; + Param7 = 0; + Param8 = 0; + Used = 0; + Value = 0; + Status = 0; + time = 0; + DevId = 0; + } +}SFesMo; + + +typedef struct { + int PointNo; + // char TagName[CN_FesMaxTagSize]; + char PointTagName[CN_FesMaxTagSize]; + int GroupNo; //定值组号 + int CodeNo; //定值代号 + int SeqNo; //定值序号 + int DzType; //定值类型 + int Unit; //单位 + double Base; //基值 + double Coeff; //系数; + double MaxRange; //度上限 + double MinRange; //度下限 + int Param1; //规约参数 + int Param2; //规约参数 + int Param3; //规约参数 + int Param4; //规约参数 + int Param5; //规约参数,每种协议含义相同。 + int Param6; //规约参数,每种协议含义相同。 + int Param7; //规约参数,每种协议含义相同。 + int Param8; //规约参数,每种协议含义相同。 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int Used; + int ValueType; + union + { + int iVal; + float fVal; + + }Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 + int DevId; //2021-03-03 thxiao 增加DevId +}SFesDz; + +//转发表变化数据缓冲区 +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + char DPTagName[CN_FesMaxTagSize]; //后台标签名 + int FesRtuNo; //采集rtu号 + int FesPointNo; //采集点号 + int DpSeqNo; //组号 + double Coeff; //系数; + double Base; //修正值 + int DeadBandType; //死区类型 + double DeadBand; // 配置死区值 + float RealDeadBandValue; //< 根据死区类型计算后的实际死区,运行时不再需要进行死区类型的判断 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) + int Used; + float Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesFwAi; + +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + char DPTagName[CN_FesMaxTagSize]; //后台标签名 + int FesRtuNo; //采集rtu号 + int FesPointNo; //采集点号 + int DpSeqNo; //后台点序号 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) + short Used; + short InitFlag; //数值已更新,因为DP->FES数据要产生SOE,所以需要。 + int Value; + uint32 Status; //bit7:1 (五防解锁) 0(五防闭锁) + uint64 time; //1970-01-01 00:00 至今的毫秒数 + //五防信息 + int DORemoteNo; //对应的转发遥控号 +}SFesFwDi; + +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + char DPTagName[CN_FesMaxTagSize]; //后台标签名 + int FesRtuNo; //采集rtu号 + int FesPointNo; //采集点号 + int DpSeqNo; //后台点序号 + double Coeff; //系数; + double Base; //修正值 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) + int Used; + double Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesFwAcc; + +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + char DPTagName[CN_FesMaxTagSize]; //后台标签名 + int FesRtuNo; //采集rtu号 + int FesPointNo; //采集点号 + int DpSeqNo; //组号 + double Coeff; //系数; + double Base; //修正值 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) + int Used; + int Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesFwMi; + +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + int FesRtuNo; //采集rtu号 + int FesPointNo; //采集点号 + double MaxRange; //度上限 + double MinRange; //度下限 + double Coeff; //系数; + double Base; //修正值 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) + int Used; + float Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesFwAo; + +const int CN_FesFwDoPointNum=5; + +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + int FesRtuNo; //采集rtu号 + int FesPointNum;//分量数 + int FesPointNo[CN_FesFwDoPointNum]; //采集点号 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) + int Used; + int Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 + //五防信息 + int DIRemoteNo; //对应的转发遥信号 + uint64 WfBlockedTimeout; //五防闭锁时间 +}SFesFwDo; + +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + int FesRtuNo; //采集rtu号 + int FesPointNo; //采集点号 + double MaxRange; //度上限 + double MinRange; //度下限 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) + int Used; + float Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesFwMo; + + +//FES间的RTU数据交互 +typedef struct { + int PointNo; + float Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesRtuAiValue; + +typedef struct { + int PointNo; + int Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesRtuDiValue; + +typedef struct { + int PointNo; + double Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesRtuAccValue; + +typedef struct { + int PointNo; + int Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesRtuMiValue; + +//Fes间采集RTU与转发RTU数据交互 +typedef struct { + int PointNo; + float Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesFwRtuAiValue; + +typedef struct { + int PointNo; + int Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesFwRtuDiValue; + +typedef struct { + int PointNo; + int64 Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesFwRtuAccValue; + + +//SCADA 与FES间的数据交互 变化数据缓存区 +typedef struct { + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + uint32 Status; + float Value; + uint64 time; + int RtuNo; + int PointNo; +}SFesChgAi; + +typedef struct { + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + uint32 Status; + int Value; + uint64 time; + int RtuNo; + int PointNo; +}SFesChgDi; + +typedef struct { + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + uint32 Status; + double Value; + uint64 time; + int RtuNo; + int PointNo; +}SFesChgAcc; + +typedef struct { + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + uint32 Status; + int Value; + uint64 time; + int RtuNo; + int PointNo; +}SFesChgMi; + +//SCADA 与FES间的数据交互 全数据 +typedef struct { + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + uint32 Status; + float Value; +}SFesAllAi; + +typedef struct { + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + uint32 Status; + int Value; +}SFesAllDi; + +typedef struct { + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + uint32 Status; + double Value; +}SFesAllAcc; + +typedef struct { + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + uint32 Status; + int Value; +}SFesAllMi; + +typedef struct{ + int ChanNo; + int Status; + float ErrRate; + uint64 time; +}SFesChanStatus; + +typedef struct{ + int RtuNo; + int Status; + uint64 time; +}SFesRtuStatus; + +typedef struct{ + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + uint32 Status; //遥测信状态 + int Value; //点值 + uint64 time; //1970-01-01 00:00 至今的毫秒数 + int FaultNum; //故障值个数 + int FaultValTag [CN_FesMaxFaultNum];//表明以下数值的来源 + float FaultVal[CN_FesMaxFaultNum]; + int RtuNo; //RTU号 + int PointNo; +}SFesSoeEvent; + +typedef struct{ + char ChanTagName[CN_FesMaxTagSize];//通道标签 + int nChannelNo; //通道号 + char ChanName[CN_FesMaxNameSize];//通道名词 + char ChanDesc[CN_FesMaxDescSize];//通道描述 + int nLocationId; //车站 + int nSubSystem; //专业 + int nRegionId; //责任区ID + uint32 Status; //通道状态 + float ErrRate; //通道误码率 + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesChanEvent; + +typedef struct{ + char RtuTagName[CN_FesMaxTagSize];//RTU标签 + int nRtuNo; //RTU号 + char RtuName[CN_FesMaxNameSize];//rtu名词 + char RtuDesc[CN_FesMaxDescSize];//rtu描述 + int nLocationId; //车站 + int nSubSystem; //专业 + int nRegionId; //责任区ID + uint32 Status; //RTU状态 + int CurrentChanNo; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesRtuEvent; + + +typedef struct _SFesRxDoCmd{ + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char RtuName[CN_FesMaxNameSize]; + int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) + int FwSubSystem; //转发专业 + int FwRtuNo; //转发RTU号 + int FwPointNo; //转发点号 + int RtuNo; //源RTU号 + int PointID; //源点号 + int SubSystem; //源专业 + int iValue; //目标值(DO、MO) + int CtrlActType; //控制类型 选择、取消、执行, + int TagtState; + uint64 Param1; + uint64 Param2; + float fParam; + char strParam[CN_FesControlStrParamSize]; + _SFesRxDoCmd() + { + memset(TableName,0,sizeof(TableName)); + memset(ColumnName,0,sizeof(ColumnName)); + memset(TagName,0,sizeof(TagName)); + memset(RtuName,0,sizeof(RtuName)); + CtrlDir=0; + RtuNo = 0; + PointID = 0; + SubSystem = 0; + FwSubSystem = 0; + FwRtuNo = 0; + FwPointNo = 0; + iValue = 0; //目标值(DO、MO) + CtrlActType = 0; //控制类型 选择、取消、执行, + TagtState = 0; + Param1 = 0; + Param2 = 0; + fParam = 0; + memset(strParam,0,sizeof(strParam)); + } +}SFesRxDoCmd; + +typedef struct _SFesTxDoCmd{ + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char RtuName[CN_FesMaxNameSize]; + int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) + int FwSubSystem; //转发专业 + int FwRtuNo; //转发RTU号 + int FwPointNo; //转发点号 + int RtuNo; //源RTU号 + int PointID; //源点号 + int SubSystem; //源专业 + int retStatus; //返回状态 + uint64 Param1; + uint64 Param2; + float fParam; + char strParam[CN_FesControlStrParamSize]; + int CtrlActType; //控制类型 选择、取消、执行, + _SFesTxDoCmd() + { + memset(TableName,0,sizeof(TableName)); + memset(ColumnName,0,sizeof(ColumnName)); + memset(TagName,0,sizeof(TagName)); + memset(RtuName,0,sizeof(RtuName)); + CtrlDir=0; + RtuNo = 0; + PointID = 0; + SubSystem = 0; + FwSubSystem = 0; + FwRtuNo = 0; + FwPointNo = 0; + retStatus = 0; //返回状态 + CtrlActType = 0; //控制类型 选择、取消、执行, + Param1 = 0; + Param2 = 0; + fParam = 0; + memset(strParam,0,sizeof(strParam)); + } +}SFesTxDoCmd; + +typedef struct _SFesRxAoCmd{ + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char RtuName[CN_FesMaxNameSize]; + int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) + int FwSubSystem; //转发专业 + int FwRtuNo; //转发RTU号 + int FwPointNo; //转发点号 + int RtuNo; //源RTU号 + int PointID; //源点号 + int SubSystem; //源专业 + float fValue; //目标值(AO) + int CtrlActType; //控制类型 选择、取消、执行, + int TagtState; + uint64 Param1; + uint64 Param2; + float fParam; + char strParam[CN_FesControlStrParamSize]; + _SFesRxAoCmd() + { + memset(TableName,0,sizeof(TableName)); + memset(ColumnName,0,sizeof(ColumnName)); + memset(TagName,0,sizeof(TagName)); + memset(RtuName,0,sizeof(RtuName)); + CtrlDir=0; + RtuNo = 0; + PointID = 0; + SubSystem = 0; + FwSubSystem = 0; + FwRtuNo = 0; + FwPointNo = 0; + fValue = 0; //目标值(AO) + CtrlActType = 0; //控制类型 选择、取消、执行, + TagtState = 0; + Param1 = 0; + Param2 = 0; + fParam = 0; + memset(strParam,0,sizeof(strParam)); + } +}SFesRxAoCmd; + +typedef struct _SFesTxAoCmd{ + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char RtuName[CN_FesMaxNameSize]; + int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) + int FwSubSystem; //转发专业 + int FwRtuNo; //转发RTU号 + int FwPointNo; //转发点号 + int RtuNo; //源RTU号 + int PointID; //源点号 + int SubSystem; //源专业 + int retStatus; //返回状态 + uint64 Param1; + uint64 Param2; + float fParam; + char strParam[CN_FesControlStrParamSize]; + int CtrlActType; //控制类型 选择、取消、执行, + _SFesTxAoCmd() + { + memset(TableName,0,sizeof(TableName)); + memset(ColumnName,0,sizeof(ColumnName)); + memset(TagName,0,sizeof(TagName)); + memset(RtuName,0,sizeof(RtuName)); + CtrlDir=0; + RtuNo = 0; + PointID = 0; + SubSystem = 0; + FwSubSystem = 0; + FwRtuNo = 0; + FwPointNo = 0; + retStatus = 0; + CtrlActType = 0; //控制类型 选择、取消、执行, + Param1 = 0; + Param2 = 0; + fParam = 0; + memset(strParam,0,sizeof(strParam)); + } +}SFesTxAoCmd; + +typedef struct _SFesRxMoCmd{ + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char RtuName[CN_FesMaxNameSize]; + int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) + int FwSubSystem; //转发专业 + int FwRtuNo; //转发RTU号 + int FwPointNo; //转发点号 + int RtuNo; //源RTU号 + int PointID; //源点号 + int SubSystem; //源专业 + int iValue; //目标值(DO、MO) + int CtrlActType; //控制类型 选择、取消、执行, + int TagtState; + uint64 Param1; + uint64 Param2; + float fParam; + char strParam[CN_FesControlStrParamSize]; + _SFesRxMoCmd() + { + memset(TableName,0,sizeof(TableName)); + memset(ColumnName,0,sizeof(ColumnName)); + memset(TagName,0,sizeof(TagName)); + memset(RtuName,0,sizeof(RtuName)); + CtrlDir=0; + RtuNo = 0; + PointID = 0; + SubSystem = 0; + FwSubSystem = 0; + FwRtuNo = 0; + FwPointNo = 0; + iValue = 0; //目标值(DO、MO) + CtrlActType = 0; //控制类型 选择、取消、执行, + TagtState = 0; + Param1 = 0; + Param2 = 0; + fParam = 0; + memset(strParam,0,sizeof(strParam)); + } +}SFesRxMoCmd; + +typedef struct _SFesTxMoCmd{ + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char RtuName[CN_FesMaxNameSize]; + int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) + int FwSubSystem; //转发专业 + int FwRtuNo; //转发RTU号 + int FwPointNo; //转发点号 + int RtuNo; //源RTU号 + int PointID; //源点号 + int SubSystem; //源专业 + int retStatus; //返回状态 + uint64 Param1; + uint64 Param2; + float fParam; + char strParam[CN_FesControlStrParamSize]; + int CtrlActType; //控制类型 选择、取消、执行, + _SFesTxMoCmd() + { + memset(TableName,0,sizeof(TableName)); + memset(ColumnName,0,sizeof(ColumnName)); + memset(TagName,0,sizeof(TagName)); + memset(RtuName,0,sizeof(RtuName)); + CtrlDir=0; + RtuNo = 0; + PointID = 0; + SubSystem = 0; + FwSubSystem = 0; + FwRtuNo = 0; + FwPointNo = 0; + retStatus = 0; + CtrlActType = 0; //控制类型 选择、取消、执行, + Param1 = 0; + Param2 = 0; + fParam = 0; + memset(strParam,0,sizeof(strParam)); + } +}SFesTxMoCmd; + +typedef struct{ + char TagName[CN_FesMaxTagSize];//Point tag + int Index; //Point index + int iValue; //Point Value +}SFesRxSetting; + +typedef struct{ + int RtuNo; + int DevId; //PCS3000 下的DevId + int CtrlActType; //控制类型 读取,下装、确定 + int Num; //定值个数,下装定值和确定修改定值(Num=0), 读取保护定值(Num!=0),不超过100点 + SFesRxSetting Setting[CN_FesMaxDzNum];//定值 +}SFesRxSettingCmd; + +typedef struct{ + int RtuNo; + int DevId; //PCS3000 下的DevId + int CtrlActType; //控制类型 读取,下装、确定 + int retStatus; //返回状态 + int Num; //定值个数,下装定值和确定修改定值(Num=0), 读取保护定值(Num!=0),不超过100点 + SFesRxSetting Setting[CN_FesMaxDzNum];//定值 + char strParam[CN_FesControlStrParamSize]; +}SFesTxSettingCmd; + +/* +typedef struct{ + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char RtuName[CN_FesMaxNameSize]; + int DevId; //PCS3000 下的DevId + int ParamLen; + byte Param[CN_FesMaxDefCmdSize]; //自定义命令 +}SFesRxDefCmd; + +typedef struct{ + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char RtuName[CN_FesMaxNameSize]; + int DevId; //PCS3000 下的DevId + int retStatus; //返回状态 + int ParamLen; + byte Param[CN_FesMaxDefCmdSize]; //自定义命令 + char strParam[CN_FesControlStrParamSize]; +}SFesTxDefCmd; +*/ + +typedef struct{ + std::string name; + std::string value; +}FesDefCmd; + + +typedef struct _SFesRxDefCmd { + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char RtuName[CN_FesMaxNameSize]; + int DevId; //PCS3000 下的DevId + int CmdNum; + int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) + int SrcRtuNo; //转发规约源RTU号 + std::vector VecCmd; + _SFesRxDefCmd() + { + memset(TableName, 0, sizeof(TableName)); + memset(ColumnName, 0, sizeof(ColumnName)); + memset(TagName, 0, sizeof(TagName)); + memset(RtuName, 0, sizeof(RtuName)); + DevId = 0; + CmdNum = 0; + CtrlDir = 0; + SrcRtuNo = 0; + //VecCmd.clear(); + } +}SFesRxDefCmd; + +typedef struct _SFesTxDefCmd{ + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char RtuName[CN_FesMaxNameSize]; + int DevId; //PCS3000 下的DevId + int retStatus; //返回状态 + int CmdNum; + std::vector VecCmd; + char strParam[CN_FesControlStrParamSize]; + int CtrlDir; //控制方向 0:FES外部(HMI) 1:FES内部(转发规约) + int SrcRtuNo; //转发规约源RTU号 + _SFesTxDefCmd() + { + CtrlDir = 0; + memset(TableName,0,sizeof(TableName)); + memset(ColumnName,0,sizeof(ColumnName)); + memset(TagName,0,sizeof(TagName)); + memset(RtuName,0,sizeof(RtuName)); + DevId = 0; + retStatus = 0; + CmdNum = 0; + SrcRtuNo = 0; + memset(strParam,0,sizeof(strParam)); + } +}SFesTxDefCmd; + +typedef struct{ + int RtuNo; + int DevId; + int fileSize; + char fileName[CN_FesMaxWaveFileNameSize]; +}SFesWaveForm; + +typedef struct +{ + int ProtocolId; + char Name[CN_FesMaxNameSize]; +}SFesProtocolName; + +typedef struct{ + char NetDesc[CN_FesMaxNetDescSize]; //通道IP + int PortNo;//通道网络端口 +}SFesNetRoute; + +typedef struct{ + int ChanNo; //通道号 + char TagName[CN_FesMaxTagSize]; //RTU + char ChanName[CN_FesMaxNameSize];//通道名 + char ChanDesc[CN_FesMaxDescSize];//通道描述 + int nLocationId; //车站 + int nSubSystem; //专业 + int nRegionId; //责任区ID + int Used; //通道使用标志 + float ErrRateLimit; //帧错误标准 + SFesNetRoute NetRoute[CN_FesMaxNetRouteNum]; + int CommProperty; //通道性质 0:接收通道 1:转发通道 + int CommType; //通信方式 + int ChanMode; //通道方式0:双通道通信方式 1:单通道方式 + int ProtocolId; //规约类型 + int ConnectWaitSec; + int RespTimeout; //响应超时 + int RetryTimes; //最大重连次数 + int RecvTimeout; //接收超时,单位ms + int ConnectTimeout; //链接超时 + int MaxRxSize; //接收缓存区长度 + int MaxTxSize; //发送缓存区长度 + int BackupChanNo[CN_FesMaxChangeChanNum-1];//实际配置的备用通道号 + //char ComPortName[CN_FesMaxNameSize];//串口端口名 + int BaudRate; //波特率设置 + int Parity; //校验位 + int DataBit; //数据位 + int StopBit; //停止位 + int ResParam1; + int ResParam2; + int SetTimeEnable; //通道对时使能 + int LocalPortNo; //本地端口号 + int AlarmEnable; //2019-09-18 thxiao 增加报警使能 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 +}SFesChanParam; + +//本结构是通道管理的内部结构,备用通道收发的统计数据(RxNum、TxNum、ErrCnt)在自己通道结构中, +//其他数据都在主通道结构中 +typedef struct{ + uint32 Writex;//写指针 + uint32 Readx; //读指针 + byte *pData; //数据内容 +}SFesChanRxBuf; + +typedef struct{ + uint32 Writex;//写指针 + uint32 Readx; //读指针 + byte *pData; //数据内容 +}SFesChanTxBuf; + +typedef struct{ + int RtuNo; //RTU号 + char TagName[CN_FesMaxTagSize]; //RTU + char RtuName[CN_FesMaxNameSize]; //RTU + char RtuDesc[CN_FesMaxDescSize];//rtu描述 + int nLocationId;//车站 + char LocationDesc[CN_FesMaxDescSize];//2019-06-05 thxiao 车站描述 + int nSubSystem; //专业 + int Used; //使用标志 + int RtuAddr; //RTU地址 + int ChanNo; //通道号 + int RecvFailLimit; //连续接收数据失败计数(>5代表停运) + int ProtocolId; //规约类型 2018-12-25 add by thxiao + int AlarmEnable; //报警使能 2019-09-18 add by thxiao + int ResParam1; + int ResParam2; + int ResParam3; + int ControlDisable; //遥控禁止 1:禁止 0:允许 + int ClearDataEnable; //2021-08-03 thxiao + //bit0 设备离线数据清零 1:清零 0:保持数据 + //bit1 数据越限数据清零 1:清零 0:保持数据 + + char DevType[CN_FesMaxTagSize]; //2020-03-09 thxiao 设备类型 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int iDevType; //2020-03-11 thxiao 整数设备类型,一般为采集串口RTU使用,避免判断字符串,优化查找时间 + int WaveEnable; //录波使能 1:是 0:否 + SModbusCmdBuf ModbusCmdBuf; +}SFesRtuParam; + +//FesSimServer +typedef struct +{ + int RefreshFlag; //数据刷新标志为1:事件写入缓冲区 0:不写入缓存区 + int Overflow; //事件溢出标志 1:溢出 0:正常 + int Readx; + int Writex; + SFesSoeEvent Event[CN_FesSimSoeEventMaxBufSize]; +}SFesSimServerSoeEventBuf; + +typedef struct +{ + int RefreshFlag; //数据刷新标志为1:事件写入缓冲区 0:不写入缓存区 + int Overflow; //事件溢出标志 1:溢出 0:正常 + int Readx; + int Writex; + SFesRtuEvent Event[CN_FesSimRtuEventMaxBufSize]; +}SFesSimServerRtuEventBuf; + +typedef struct +{ + int RefreshFlag; //数据刷新标志为1:事件写入缓冲区 0:不写入缓存区 + int Overflow; //事件溢出标志 1:溢出 0:正常 + int Readx; + int Writex; + SFesChanEvent Event[CN_FesSimChanEventMaxBufSize]; +}SFesSimServerChanEventBuf; + +typedef struct{ + int RxNum; // + int TxNum; // + int ErrNum; +}SFesChanStatistics; + +typedef struct{ + char FrameType; //0:data 1:string + char DataType; + short FrameLen; + uint64 Time; //1970-01-01 00:00 至今的毫秒数 + byte Data[CN_SFesSimComFrameMaxLen]; +}SFesChanFrame; + +typedef struct +{ + int RefreshFlag; //数据刷新标志为1:事件写入缓冲区 0:不写入缓存区 + int ChanNo; + int Overflow; //事件溢出标志 1:溢出 0:正常 + int RxNum; // + int TxNum; // + int ErrNum; + int Readx; + int Writex; + SFesChanFrame Frame[CN_FesSimChanMonMaxBufSize]; +}SFesSimServerChanMonBuf; + +//网络通信事件队列结构,通信层和应用层互相交互 +const int CN_FesNetEvent_Waitting_Connect = 1; +const int CN_FesNetEvent_Connect = 2; +const int CN_FesNetEvent_Disconnect = 3; + +typedef struct +{ + uint64 Time; + int EventType; +}SFesNetEvent; + +//应用层事件请求,应用层和通信层互相交互 +const int CN_FesAppNetEvent_CloseSock = 1; +const int CN_FesAppNetEvent_ReopenChan = 2; + +typedef struct +{ + uint64 Time; + int EventType; +}SFesAppNetEvent; + + +//设备信息表 +typedef struct{ + int CfgSize; + int DataSize; + int Year; + int Mon; + int Day; + int Hour; + int Min; + //int Sec; + int mSec; //sec*1000+msec; +}SFesRtuWareform; + +typedef struct{ + int DevId; + char TagName[CN_FesMaxTagSize]; //2020-12-17 thxiao 设备标签名 + char DevDesc[CN_FesMaxNameSize]; + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int ChildDevId; + SFesRtuWareform Record; + char LuboPath[CN_FesMaxDescSize];//2019-06-10 thxiao 增加录波路径,方便保存录波按“车站\设备”保存 + char AlarmLuboPath[CN_FesMaxDescSize];//2019-06-10 thxiao 增加相对告警录波路径,“车站\设备” +}SFesRtuDevParam; + +typedef struct{ + int RtuNo; + int DevNum; + SFesRtuDevParam *pDev; + //int WfDataLen; //录波数据长度 + //byte *pWfData; //录波数据缓存区 + //int RecvDataIndex; //录波数据保存当前数据长度 +}SFesRtuDevInfo; +//增加一个数据初始化筛选转发表的采集RTU号 +typedef struct { + int CollectRtuNum; + int CollectRtuCount; + int CollectRtuNo[CN_FesFwMaxCollectRtuNum]; +}SFesCollectRtu; + +//转发规约的接口结构 +typedef struct { + int RemoteNo; //远动号 + int RtuNo; //RTU号 + int PointNo; + uint32 Status; + float Value; + uint64 time; +}SFesFwChgAi; + +typedef struct { + int RemoteNo; //远动号 + int RtuNo; //RTU号 + int PointNo; + uint32 Status; + int Value; + uint64 time; +}SFesFwChgDi; + +typedef struct{ + int RemoteNo; //远动号 + int RtuNo; //RTU号 + int PointNo; + uint32 Status; //遥测信状态 + int Value; //点值 + uint64 time; //1970-01-01 00:00 至今的毫秒数 + int FaultNum; //故障值个数 + int FaultValTag [CN_FesMaxFaultNum];//表明以下数值的来源 + float FaultVal[CN_FesMaxFaultNum]; +}SFesFwSoeEvent; + + +typedef struct { + int RemoteNo; //远动号 + int RtuNo; //RTU号 + int PointNo; + uint32 Status; + double Value; + uint64 time; +}SFesFwChgAcc; + +typedef struct { + int RemoteNo; //远动号 + int RtuNo; //RTU号 + int PointNo; + uint32 Status; + int Value; + uint64 time; +}SFesFwChgMi; + +typedef struct { + int SrcSubSystem; //所属专业 + int SrcRtuNo; //RTU号 + int SrcPointNo; + uint32 Status; +}SFesFwChgDo; + +typedef struct _SFesFwDoRespCmd{ + int FwRtuNo; //RTU号 + int FwPointNo; //遥控点号 + int retStatus; //返回状态 + int CtrlActType; //控制类型 选择、取消、执行, + uint64 Param1; + uint64 Param2; + float fParam; + _SFesFwDoRespCmd() + { + FwRtuNo=0; + FwPointNo = 0; //遥控点号 + retStatus = 0; //返回状态 + CtrlActType = 0; //控制类型 选择、取消、执行, + Param1 = 0; + Param2 = 0; + fParam = 0; + } +}SFesFwDoRespCmd; + +typedef struct _SFesFwAoRespCmd{ + int FwRtuNo; //RTU号 + int FwPointNo; //遥控点号 + int retStatus; //返回状态 + uint64 Param1; + uint64 Param2; + float fParam; + int CtrlActType; //控制类型 选择、取消、执行, + _SFesFwAoRespCmd() + { + FwRtuNo =0; + FwPointNo =0; + retStatus = 0; + CtrlActType = 0; //控制类型 选择、取消、执行, + Param1 = 0; + Param2 = 0; + fParam = 0; + } +}SFesFwAoRespCmd; + +typedef struct _SFesFwMoRespCmd { + int FwRtuNo; //RTU号 + int FwPointNo; //遥控点号 + int retStatus; //返回状态 + uint64 Param1; + uint64 Param2; + float fParam; + int CtrlActType; //控制类型 选择、取消、执行, + _SFesFwMoRespCmd() + { + FwRtuNo =0; + FwPointNo = 0; //遥控点号 + retStatus = 0; + CtrlActType = 0; //控制类型 选择、取消、执行, + Param1 = 0; + Param2 = 0; + fParam = 0; + } +}SFesFwMoRespCmd; + +//201-03-011 thxiao 增加规约映射表,数据按规约点的顺序排列.方便工程在完成的情况下,现场工程又修改了点顺序。 +typedef struct { + int Used; + int PIndex; //use param1. + int PointNo; + int DevId; //2021-03-03 thxiao 增加DevId + int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo + int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress + int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo + //2021-08-04 thxiao added + int Param5; //规约参数,每种协议含义不相同。 + int Param6; //规约参数,每种协议含义不相同。 +}SFesAiIndex; + +typedef struct { + int Used; + int PIndex; //use param1. + int PointNo; + int DevId; //2021-03-03 thxiao 增加DevId + int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo + int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress + int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo + //2021-08-04 thxiao added + int Param5; //规约参数,每种协议含义不相同。 + int Param6; //规约参数,每种协议含义不相同。 +}SFesDiIndex; + +typedef struct { + int Used; + int PIndex; //use param1. + int PointNo; + int DevId; //2021-03-03 thxiao 增加DevId + int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo + int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress + int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo + //2021-08-04 thxiao added + int Param5; //规约参数,每种协议含义不相同。 + int Param6; //规约参数,每种协议含义不相同。 +}SFesAccIndex; + +typedef struct { + int Used; + int PIndex; //use param1. + int PointNo; + int DevId; //2021-03-03 thxiao 增加DevId + int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo + int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress + int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo + //2021-08-04 thxiao added + int Param5; //规约参数,每种协议含义不相同。 + int Param6; //规约参数,每种协议含义不相同。 +}SFesMiIndex; + +typedef struct { + int Used; + int PIndex; //use param1. + int PointNo; + int DevId; //2021-03-03 thxiao 增加DevId + int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo + int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress + int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo + //2021-08-04 thxiao added + int Param5; //规约参数,每种协议含义不相同。 + int Param6; //规约参数,每种协议含义不相同。 +}SFesDoIndex; + +typedef struct { + int Used; + int PIndex; //use param1. + int PointNo; + int DevId; //2021-03-03 thxiao 增加DevId + int Param2; //规约参数,每种协议含义相同。 如modbus FunNo + int Param3; //规约参数,每种协议含义相同。 如modbus DataAddress + int Param4; //规约参数,每种协议含义相同。 如modbus InfoNo + //2021-08-04 thxiao added + int Param5; //规约参数,每种协议含义不相同。 + int Param6; //规约参数,每种协议含义不相同。 +}SFesAoIndex; + +typedef struct { + int Used; + int PIndex; //use param1. + int PointNo; + int DevId; //2021-03-03 thxiao 增加DevId + int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo + int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress + int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo + //2021-08-04 thxiao added + int Param5; //规约参数,每种协议含义不相同。 + int Param6; //规约参数,每种协议含义不相同。 +}SFesMoIndex; + +typedef struct { + int Used; + int PIndex; //use param1. + int PointNo; + int DevId; //2021-03-03 thxiao 增加DevId + int Param2; //规约参数,每种协议含义不相同。 如modbus FunNo + int Param3; //规约参数,每种协议含义不相同。 如modbus DataAddress + int Param4; //规约参数,每种协议含义不相同。 如modbus InfoNo + //2021-08-04 thxiao added + int Param5; //规约参数,每种协议含义不相同。 + int Param6; //规约参数,每种协议含义不相同。 +}SFesDzIndex; + +//车站 +typedef struct { + int nLocationId;//车站 + char LocationDesc[CN_FesMaxDescSize];//2019-06-05 thxiao 车站描述 +}SFesLocation; + +/******************************************************************************** +//转发公共数据 +*********************************************************************************/ +typedef struct _SFesFwPubAi { + int SrcLocationID; //点所属厂站 + int SrcSubSystem; //点所属专业 + char DPTagName[CN_FesMaxTagSize]; //后台标签名 + int FesRtuNo; //采集rtu号 + int SrcPointNo; //采集点号 + float Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 + int FwMapNum; //转发映射个数 + SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 + _SFesFwPubAi() + { + SrcLocationID = 0; + SrcSubSystem = 0; + memset(DPTagName, 0, CN_FesMaxTagSize); + FesRtuNo = 0; + SrcPointNo = 0; + Value = 0; + Status = 0; + time = 0; + FwMapNum = 0; + memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); + } +}SFesFwPubAi; + +typedef struct _SFesFwPubDi { + int SrcLocationID; //点所属厂站 + int SrcSubSystem; //点所属专业 + char DPTagName[CN_FesMaxTagSize]; //后台标签名 + int FesRtuNo; //采集rtu号 + int SrcPointNo; //采集点号/DP点号 + int Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 + short PointType; //0:单点 1:双点 + short FwMapNum; //转发映射个数 + SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 + _SFesFwPubDi() + { + PointType = 0; + SrcLocationID = 0; + SrcSubSystem = 0; + memset(DPTagName, 0, CN_FesMaxTagSize); + FesRtuNo = 0; + SrcPointNo = 0; + Value = 0; + Status = 0; + time = 0; + FwMapNum = 0; + memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); + } +}SFesFwPubDi; + +typedef struct _SFesFwPubAcc { + int SrcLocationID; //点所属厂站 + int SrcSubSystem; //点所属专业 + char DPTagName[CN_FesMaxTagSize]; //后台标签名 + int FesRtuNo; //采集rtu号 + int SrcPointNo; //采集点号 + double Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 + int FwMapNum; //转发映射个数 + SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 + _SFesFwPubAcc() + { + SrcLocationID = 0; + SrcSubSystem = 0; + memset(DPTagName, 0, CN_FesMaxTagSize); + FesRtuNo = 0; + SrcPointNo = 0; + Value = 0; + Status = 0; + time = 0; + FwMapNum = 0; + memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); + } +}SFesFwPubAcc; + +typedef struct _SFesFwPubMi { + int SrcLocationID; //点所属厂站 + int SrcSubSystem; //点所属专业 + char DPTagName[CN_FesMaxTagSize]; //后台标签名 + int FesRtuNo; //采集rtu号 + int SrcPointNo; //采集点号 + int Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 + int FwMapNum; //转发映射个数 + SFesFwMapping FwMapping[CN_Fes_Fw_MaxMapping];//对应的转发点号,快速找到转发点 + _SFesFwPubMi() + { + SrcLocationID = 0; + SrcSubSystem = 0; + memset(DPTagName, 0, CN_FesMaxTagSize); + FesRtuNo = 0; + SrcPointNo = 0; + Value = 0; + Status = 0; + time = 0; + FwMapNum = 0; + memset(&FwMapping[0], 0, sizeof(SFesFwMapping)*CN_Fes_Fw_MaxMapping); + } +}SFesFwPubMi; + +typedef struct _SFesFwPubDo { + int SrcLocationID; //点所属厂站 + int SrcSubSystem; //点所属专业 + int FesRtuNo; //采集rtu号 + int SrcPointNo; //采集点号/DP点号 + uint32 Status; + _SFesFwPubDo() + { + SrcLocationID = 0; + SrcSubSystem = 0; + FesRtuNo = 0; + SrcPointNo = 0; + Status = 0; + } +}SFesFwPubDo; + + +typedef struct _SFesFwDoBusCmd { + int FwSubSystem; //转发专业 + int FwRtuNo; //转发RTU号 + int FwPointNo; //转发点号 + int SubSystem; //源专业 + int RtuNo; //源RTU号 + int PointID; //源点号 + int retStatus; //返回状态 + int CtrlActType; //控制类型 选择、取消、执行, + int iValue; //目标值(DO、MO) + uint64 Param1; + uint64 Param2; + float fParam; + _SFesFwDoBusCmd() + { + FwSubSystem = 0; + FwRtuNo = 0; + FwPointNo = 0; + RtuNo = 0; + PointID = 0; + SubSystem = 0; + retStatus = 0; //返回状态 + CtrlActType = 0; //控制类型 选择、取消、执行, + iValue = 0; + Param1 = 0; + Param2 = 0; + fParam = 0; + } +}SFesFwDoBusCmd; + +typedef struct _SFesFwAoBusCmd { + int FwSubSystem; //转发专业 + int FwRtuNo; //转发RTU号 + int FwPointNo; //转发点号 + int SubSystem; //源专业 + int RtuNo; //源RTU号 + int PointID; //源点号 + int retStatus; //返回状态 + int CtrlActType; //控制类型 选择、取消、执行, + float fValue; //目标值(AO) + uint64 Param1; + uint64 Param2; + float fParam; + _SFesFwAoBusCmd() + { + FwSubSystem = 0; + FwRtuNo = 0; + FwPointNo = 0; + RtuNo = 0; + PointID = 0; + SubSystem = 0; + retStatus = 0; + CtrlActType = 0; //控制类型 选择、取消、执行, + fValue = 0; + Param1 = 0; + Param2 = 0; + fParam = 0; + } +}SFesFwAoBusCmd; + +typedef struct _SFesFwMoBusCmd { + int FwSubSystem; //转发专业 + int FwRtuNo; //转发RTU号 + int FwPointNo; //转发点号 + int SubSystem; //源专业 + int RtuNo; //源RTU号 + int PointID; //源点号 + int retStatus; //返回状态 + int CtrlActType; //控制类型 选择、取消、执行, + int iValue; //目标值(DO、MO) + uint64 Param1; + uint64 Param2; + float fParam; + _SFesFwMoBusCmd() + { + FwSubSystem = 0; + FwRtuNo = 0; + FwPointNo = 0; + RtuNo = 0; + PointID = 0; + SubSystem = 0; + retStatus = 0; + CtrlActType = 0; //控制类型 选择、取消、执行, + iValue = 0; + Param1 = 0; + Param2 = 0; + fParam = 0; + } +}SFesFwMoBusCmd; + +typedef struct { + float Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesFwAiValue; + +typedef struct { + int Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesFwDiValue; + +typedef struct { + double Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesFwAccValue; + +typedef struct { + int Value; + uint32 Status; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesFwMiValue; + +//2020-10-15 thxiao 虚拟数据结构 +typedef struct { + char PointTag[CN_FesMaxTagSize]; //Point Tag + char RtuTag[CN_FesMaxTagSize]; //RTU Tag + int PointType; //DO:5 AO:6 + int PointNo; + float Value; + uint64 time; //1970-01-01 00:00 至今的毫秒数 +}SFesVirtualValue; + +//2021-05-25 thiao 增加字符型的SOE +const int CN_FesSoeStrEventDecsLen = 64; + +typedef struct { + int FaultValTag; + char FaultValueDecs[CN_FesSoeStrEventDecsLen]; +}SFesSoeStrEventDesc; + + +typedef struct _SFesSoeStrEvent { + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + uint32 Status; //遥测信状态 + int Value; //点值 + uint64 time; //1970-01-01 00:00 至今的毫秒数 + vector FaultStrVal; + int RtuNo; //RTU号 + int PointNo; + _SFesSoeStrEvent(){ + memset(TableName,0,CN_FesMaxTableNameSize); + memset(ColumnName, 0, CN_FesMaxColumnNameSize); + memset(TagName, 0, CN_FesMaxTagSize); + Status = 0; + Value = 0; + time = 0; + RtuNo = 0; + PointNo = 0; + } +}SFesSoeStrEvent; diff --git a/product/src/fes/include/FesRdbStruct.h b/product/src/fes/include/FesRdbStruct.h index 3b0d4892..01cddc49 100644 --- a/product/src/fes/include/FesRdbStruct.h +++ b/product/src/fes/include/FesRdbStruct.h @@ -1,513 +1,526 @@ -/* - @file fesrdbstruct.h - @brief fes 实时库数据结构 - - @author thxiao - 2019-4-16 thxiao long的数据类型在WINDOWS系统下长度为4,LIUNX系统为8,所以改为int64,统一长度。 - 2019-06-05 thxiao 增加车站,方便保存录波按“车站\设备”保存 - 2019-09-18 thxiao 增加通道报警使能 - 2020-01-16 thxiao 前置点增加点描述 - 2021-03-04 thxiao DO AO MO DZ增加DevTagName - -*/ - -#pragma once - -const int CN_FesMaxTableNameSize =32; //TagName最大长度 -const int CN_FesMaxColumnNameSize =16; //TagName最大长度 -const int CN_FesMaxTagSize =64; //TagName最大长度 -const int CN_FesMaxDescSize =128; -const int CN_FesMaxNameSize =64; //Name最大长度 -const int CN_FesMaxNetDescSize =32; //"127.0.0.1" -const int CN_FesMaxChangeChanNum =4; //RTU允许切换的最大通道数 -const int CN_FesMaxNetRouteNum =4; //每个通道最大路由数 - -#define RT_DICT_TEXT_TBL "dict_text_define" -#define RT_FES_RTU_TBL "fes_rtu_para" -#define RT_FES_CHAN_TBL "fes_channel_para" -#define RT_FES_PROTOCOL_TBL "fes_protocol" -#define RT_FES_AI_TBL "fes_analog" -#define RT_FES_AO_TBL "fes_analog_ctrl" -#define RT_FES_DI_TBL "fes_digital" -#define RT_FES_DO_TBL "fes_digital_ctrl" -#define RT_FES_ACC_TBL "fes_accuml" -#define RT_FES_MI_TBL "fes_mix" -#define RT_FES_MO_TBL "fes_mix_ctrl" -#define RT_FES_SETTING_TBL "fes_const" -#define RT_FES_DATA_BLOCK_TBL "fes_data_block" -#define RT_FES_DEV_INFO_TBL "fes_dev_info" -#define RT_FES_LOCATION_TBL "sys_model_location_info" -//转发点表 -#define RT_FES_FW_AI_TBL "forward_analog" -#define RT_FES_FW_AO_TBL "forward_analog_ctrl" -#define RT_FES_FW_SDI_TBL "forward_digital_single" -#define RT_FES_FW_DDI_TBL "forward_digital_double" -#define RT_FES_FW_DO_TBL "forward_digital_ctrl" -#define RT_FES_FW_ACC_TBL "forward_accuml" -#define RT_FES_FW_MI_TBL "forward_mix" -#define RT_FES_FW_MO_TBL "forward_mix_ctrl" - -typedef struct{ - int nLocationId; //车站 - char LocationIDesc[CN_FesMaxDescSize];//描述 -}SFesRdbLocationParam; - -typedef struct{ - int RtuNo; //RTU号 - char TagName[CN_FesMaxTagSize]; //RTU - char RtuName[CN_FesMaxNameSize]; //RTU - char RtuDesc[CN_FesMaxDescSize];//rtu描述 - int nLocationId;//车站 - int nSubSystem; //专业 - int Used; //使用标志 - int RtuAddr; //RTU地址 - int ChanNo; //通道号 - int RecvFailLimit; //连续接收数据失败计数(>5代表停运) - int AlarmEnable; //报警使能 2019-09-18 add by thxiao - int ResParam1; - int ResParam2; - int ResParam3; - char DevType[CN_FesMaxTagSize]; - int WaveEnable; //录波使能 1:是 0:否 - int ControlDisable; - int ClearDataEnable; -}SFesRdbRtuParam; - -typedef struct{ - int ChanNo; //通道号 - char TagName[CN_FesMaxTagSize]; //RTU - char ChanName[CN_FesMaxNameSize];//通道名 - char ChanDesc[CN_FesMaxDescSize];//通道描述 - int nLocationId; //车站 - int nSubSystem; //专业 - int nRegionId; //责任区ID - int Used; //通道使用标志 - double ErrRateLimit; //帧错误标准 - char NetDesc1[CN_FesMaxNetDescSize]; //通道IP - int PortNo1; //通道网络端口 - char NetDesc2[CN_FesMaxNetDescSize]; //通道IP - int PortNo2; //通道网络端口 - char NetDesc3[CN_FesMaxNetDescSize]; //通道IP - int PortNo3; //通道网络端口 - char NetDesc4[CN_FesMaxNetDescSize]; //通道IP - int PortNo4; //通道网络端口 - int CommProperty; //通道性质 0:接收通道 1:转发通道 - int CommType; //通信方式 - int ChanMode; //通道方式0:双通道通信方式 1:单通道方式 - int ProtocolId; //规约类型 - int ConnectWaitSec; //连接等待重连时间,单位秒 - int ConnectTimeout; //链接超时,单位秒 - int RetryTimes; //最大重连次数 - int RespTimeout; //响应超时,单位毫秒 - int RecvTimeout; //接收超时,单位秒,判断是否需要端开连接重新连接 - int MaxRxSize; //接收缓存区长度 - int MaxTxSize; //发送缓存区长度 - int BackupChanNo1;//实际配置的备用通道号 - int BackupChanNo2;//实际配置的备用通道号 - int BackupChanNo3;//实际配置的备用通道号 - int ResParam1; - int ResParam2; - int ResParam3; - int ResParam4; - //char ComPortName[CN_FesMaxNameSize];//串口端口名 - int BaudRate; //波特率设置 - int Parity; //校验位 - int DataBit; //数据位 - int StopBit; //停止位 - int AlarmEnable; //2019-09-18 thxiao 通道报警使能 -}SFesRdbChanParam; - -typedef struct -{ - int ProtocolId; - char Name[CN_FesMaxNameSize]; -}SFesRdbProtocolParam; - -typedef struct { - int RtuNo; - int Index; //序号 - int FunCode; //功能码(即MODBUS中的命令码) - int StartAddr; //数据起始地址 - int DataLen; //数据长度 - int PollTime; //命令下发周期(相对时间,一个周期=50ms) - int FrameType; //帧类别 - int IsCreateSoe; //对遥信帧有效,0:不产生SOE,1:产生SOE - int Param1; //保留参数1 - int Param2; //保留参数2 - int Param3; - int Param4; - int Used; -}SFesRdbDataBlock; - -typedef struct { - int RtuNo; - int PointNo; - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - char DevTagName[CN_FesMaxTagSize];//2020-12-17 thxiao DEVTAG - int IsFilter; //是否过滤AI突变 - int Percent; //突变百分比 - int DeadBandType;//死区类型 - double DeadBand; //死区值 - double ZeroBand; //归零死区 - double Base; //基值 - double Coeff; //系数; - double MaxRange; //度上限 - double MinRange; //度下限 - int Param1; //规约参数,每种协议含义相同。 如modbus FunNo - int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress - int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo - int Param4; //规约参数,每种协议含义相同。 - int Param5; - int Param6; - int Param7; - int Param8; -}SFesRdbAiParam; - -typedef struct { - int RtuNo; - int PointNo; - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - char DevTagName[CN_FesMaxTagSize];//2020-12-17 thxiao DEVTAG - int IsFilterErr; //是否过滤错误DI - int IsFilterDisturb;//是否过滤DI抖动 - int DisturbTime; //抖动时限 - int Revers; //取反 - int Param1; //规约参数,每种协议含义相同。 如modbus FunNo - int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress - int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo - int Param4; //规约参数,每种协议各不相同。 - int Param5; - int Param6; - int Param7; - int Param8; - int Attribute; //点属性 - int RelateDI; //关联遥信 -}SFesRdbDiParam; - -typedef struct { - int RtuNo; - int PointNo; - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - char DevTagName[CN_FesMaxTagSize];//2020-12-17 thxiao DEVTAG - double Base; //基值 - double Coeff; //系数; - int Param1; //规约参数,每种协议各不相同。 如modbus FunNo - int Param2; //规约参数,每种协议各不相同。 如modbus DataAddress - int Param3; //规约参数,每种协议各不相同。 如modbus InfoNo - int Param4; //规约参数,每种协议各不相同。 如modbus ValueType - int Param5; - int Param6; - int Param7; - int Param8; -}SFesRdbAccParam; - - -typedef struct { - int RtuNo; - int PointNo; - char TableName[CN_FesMaxTableNameSize]; - char ColumnName[CN_FesMaxColumnNameSize]; - char TagName[CN_FesMaxTagSize]; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - char DevTagName[CN_FesMaxTagSize];//2020-12-17 thxiao DEVTAG - int Base; //基值 - int Coeff; //系数; - int MaxRange; //度上限 - int MinRange; //度下限 - int Param1; //规约参数,每种协议各不相同。 如modbus FunNo - int Param2; //规约参数,每种协议各不相同。 如modbus DataAddress - int Param3; //规约参数,每种协议各不相同。 如modbus InfoNo - int Param4; //规约参数,每种协议各不相同。 如modbus ValueType - int Param5; //规约参数,每种协议含义相同。 - int Param6; //规约参数,每种协议含义相同。 - int Param7; //规约参数,每种协议含义相同。 - int Param8; //规约参数,每种协议含义相同。 -}SFesRdbMiParam; - -typedef struct { - int RtuNo; - int PointNo; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - char DevTagName[CN_FesMaxTagSize];//2021-03-03 thxiao DEVTAG - int Revers; //取反 - int Param1; //规约参数,每种协议含义相同。 如modbus FunNo - int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress - int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo - int Param4; //规约参数,每种协议各不相同。 - int Param5; - int Param6; - int Param7; - int Param8; - int Attribute; //点属性 - int ControlParam; //遥控参数 -}SFesRdbDoParam; - -typedef struct { - int RtuNo; - int PointNo; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - char DevTagName[CN_FesMaxTagSize];//2021-03-03 thxiao DEVTAG - double Base; //基值 - double Coeff; //系数; - double MaxRange; //度上限 - double MinRange; //度下限 - int Param1; //规约参数,每种协议含义相同。 如modbus FunNo - int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress - int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo - int Param4; //规约参数,每种协议含义相同。 - int Param5; //规约参数,每种协议含义相同。 - int Param6; //规约参数,每种协议含义相同。 - int Param7; //规约参数,每种协议含义相同。 - int Param8; //规约参数,每种协议含义相同。 -}SFesRdbAoParam; - -typedef struct { - int RtuNo; - int PointNo; - char PointTagName[CN_FesMaxTagSize]; - char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 - char DevTagName[CN_FesMaxTagSize];//2021-03-03 thxiao DEVTAG - int Base; //基值 - int Coeff; //系数; - int MaxRange; //度上限 - int MinRange; //度下限 - int Param1; //规约参数,每种协议各不相同。 如modbus FunNo - int Param2; //规约参数,每种协议各不相同。 如modbus DataAddress - int Param3; //规约参数,每种协议各不相同。 如modbus InfoNo - int Param4; //规约参数,每种协议各不相同。 如modbus ValueType - int Param5; //规约参数,每种协议含义相同。 - int Param6; //规约参数,每种协议含义相同。 - int Param7; //规约参数,每种协议含义相同。 - int Param8; //规约参数,每种协议含义相同。 -}SFesRdbMoParam; - -typedef struct { - int RtuNo; - int PointNo; - char DevTagName[CN_FesMaxTagSize];//2021-03-03 thxiao DEVTAG - int GroupNo; //定值组号 - int CodeNo; //定值代号 - int SeqNo; //定值序号 - int DzType; //定值类型 - int Unit; //单位 - double Base; //基值 - double Coeff; //系数; - double MaxRange; //度上限 - double MinRange; //度下限 - int Param1; //规约参数 - int Param2; //规约参数 - int Param3; //规约参数 - int Param4; //规约参数 - int Param5; //规约参数,每种协议含义相同。 - int Param6; //规约参数,每种协议含义相同。 - int Param7; //规约参数,每种协议含义相同。 - int Param8; //规约参数,每种协议含义相同。 -}SFesRdbDzParam; - - -typedef struct { - int RtuNo; - int DevID; //FEP 的设备ID号 - char DevDesc[CN_FesMaxNameSize];//设备描述 - char TagName[CN_FesMaxTagSize]; //2020-12-17 thxiao 设备标签名 -}SFesRdbDevInfo; - -//转发表Rdb结构参数 -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - char DPTagName[CN_FesMaxTagSize]; //后台标签名 - int FesRtuNo; //采集rtu号 - int FesPointNo; //采集点号 - int DpSeqNo; //后台点序号 - double Coeff; //系数; - double Base; //修正值 - int DeadBandType; //死区类型 - double DeadBand; //死区值 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP)*/ -}SFesRdbFwAiParam; - -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - char DPTagName[CN_FesMaxTagSize]; //后台标签名 - int FesRtuNo; //采集rtu号 - int FesPointNo; //采集点号 - int DpSeqNo; //后台点序号 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) -}SFesRdbFwDiParam; - -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - char DPTagName[CN_FesMaxTagSize]; //后台标签名 - int FesRtuNo; //采集rtu号 - int FesPointNo; //采集点号 - int DpSeqNo; //后台点序号 - double Coeff; //系数; - double Base; //修正值 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) -}SFesRdbFwAccParam; - -//转发表Rdb结构参数 -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - char DPTagName[CN_FesMaxTagSize]; //后台标签名 - int FesRtuNo; //采集rtu号 - int FesPointNo; //采集点号 - int DpSeqNo; //后台点序号 - int Coeff; //系数; - int Base; //修正值 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) -}SFesRdbFwMiParam; - -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - int FesRtuNo; //采集rtu号 - int FesPointNo; //采集点号 - double MaxRange; //度上限 - double MinRange; //度下限 - double Coeff; //系数; - double Base; //修正值 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) -}SFesRdbFwAoParam; - -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - int FesRtuNo; //采集rtu号 - int FesPointNum;//分量数 - int FesPointNo1; //采集点号 - int FesPointNo2; //采集点号 - int FesPointNo3; //采集点号 - int FesPointNo4; //采集点号 - int FesPointNo5; //采集点号 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) -}SFesRdbFwDoParam; - -typedef struct { - int RemoteNo; //远动序号 - char TagName[CN_FesMaxTagSize]; //采集标签名 - char PointDesc[CN_FesMaxDescSize]; //点描述 - int FesRtuNo; //采集rtu号 - int FesPointNo; //采集点号 - int MaxRange; //度上限 - int MinRange; //度下限 - int Property; //属性 - int SrcLocationID; //所属厂站 - int SrcSubSystem; //所属专业 - int ResParam1; //规约参数1 - int ResParam2; //规约参数2 - int ResParam3; //规约参数3 - int ResParam4; //规约参数4 - int ResParam5; //规约参数5 - int ResParam6; //规约参数6 - int ResParam7; //规约参数7 - char StrParam[CN_FesMaxTagSize]; - int SrcType; //点来源(0:FES 1:DP) -}SFesRdbFwMoParam; - -typedef struct { - int nFaultCode; - char FaultName[CN_FesMaxNameSize]; //Fault Name -}SFesRdbFaultCode; - - -//201-03-011 thxiao 增加规约映射表 -typedef struct { - int RtuNo; - int PointNo; - int Param1; //Index - int Param2; //Index - int Param3; //Index - int Param4; //Index -}SFesRdbPPointMapping; //SFesRdbProtocolPointMapping +/* + @file fesrdbstruct.h + @brief fes 实时库数据结构 + + @author thxiao + 2019-4-16 thxiao long的数据类型在WINDOWS系统下长度为4,LIUNX系统为8,所以改为int64,统一长度。 + 2019-06-05 thxiao 增加车站,方便保存录波按“车站\设备”保存 + 2019-09-18 thxiao 增加通道报警使能 + 2020-01-16 thxiao 前置点增加点描述 + 2021-03-04 thxiao DO AO MO DZ增加DevTagName + +*/ + +#pragma once + +const int CN_FesMaxTableNameSize =32; //TagName最大长度 +const int CN_FesMaxColumnNameSize =16; //TagName最大长度 +const int CN_FesMaxTagSize =64; //TagName最大长度 +const int CN_FesMaxDescSize =128; +const int CN_FesMaxNameSize =64; //Name最大长度 +const int CN_FesMaxNetDescSize =32; //"127.0.0.1" +const int CN_FesMaxChangeChanNum =4; //RTU允许切换的最大通道数 +const int CN_FesMaxNetRouteNum =4; //每个通道最大路由数 +const int CN_FES_CharArray64 = 64; //< 64字节长度 + +#define RT_DICT_TEXT_TBL "dict_text_define" +#define RT_FES_RTU_TBL "fes_rtu_para" +#define RT_FES_CHAN_TBL "fes_channel_para" +#define RT_FES_PROTOCOL_TBL "fes_protocol" +#define RT_FES_AI_TBL "fes_analog" +#define RT_FES_AO_TBL "fes_analog_ctrl" +#define RT_FES_DI_TBL "fes_digital" +#define RT_FES_DO_TBL "fes_digital_ctrl" +#define RT_FES_ACC_TBL "fes_accuml" +#define RT_FES_MI_TBL "fes_mix" +#define RT_FES_MO_TBL "fes_mix_ctrl" +#define RT_FES_SETTING_TBL "fes_const" +#define RT_FES_DATA_BLOCK_TBL "fes_data_block" +#define RT_FES_DEV_INFO_TBL "fes_dev_info" +#define RT_FES_LOCATION_TBL "sys_model_location_info" +//转发点表 +#define RT_FES_FW_AI_TBL "forward_analog" +#define RT_FES_FW_AO_TBL "forward_analog_ctrl" +#define RT_FES_FW_SDI_TBL "forward_digital_single" +#define RT_FES_FW_DDI_TBL "forward_digital_double" +#define RT_FES_FW_DO_TBL "forward_digital_ctrl" +#define RT_FES_FW_ACC_TBL "forward_accuml" +#define RT_FES_FW_MI_TBL "forward_mix" +#define RT_FES_FW_MO_TBL "forward_mix_ctrl" + +typedef struct{ + int nLocationId; //车站 + char LocationIDesc[CN_FesMaxDescSize];//描述 +}SFesRdbLocationParam; + +typedef struct{ + int RtuNo; //RTU号 + char TagName[CN_FesMaxTagSize]; //RTU + char RtuName[CN_FesMaxNameSize]; //RTU + char RtuDesc[CN_FesMaxDescSize];//rtu描述 + int nLocationId;//车站 + int nSubSystem; //专业 + int Used; //使用标志 + int RtuAddr; //RTU地址 + int ChanNo; //通道号 + int RecvFailLimit; //连续接收数据失败计数(>5代表停运) + int AlarmEnable; //报警使能 2019-09-18 add by thxiao + int ResParam1; + int ResParam2; + int ResParam3; + char DevType[CN_FesMaxTagSize]; + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int WaveEnable; //录波使能 1:是 0:否 + int ControlDisable; + int ClearDataEnable; +}SFesRdbRtuParam; + +typedef struct{ + int ChanNo; //通道号 + char TagName[CN_FesMaxTagSize]; //RTU + char ChanName[CN_FesMaxNameSize];//通道名 + char ChanDesc[CN_FesMaxDescSize];//通道描述 + int nLocationId; //车站 + int nSubSystem; //专业 + int nRegionId; //责任区ID + int Used; //通道使用标志 + double ErrRateLimit; //帧错误标准 + char NetDesc1[CN_FesMaxNetDescSize]; //通道IP + int PortNo1; //通道网络端口 + char NetDesc2[CN_FesMaxNetDescSize]; //通道IP + int PortNo2; //通道网络端口 + char NetDesc3[CN_FesMaxNetDescSize]; //通道IP + int PortNo3; //通道网络端口 + char NetDesc4[CN_FesMaxNetDescSize]; //通道IP + int PortNo4; //通道网络端口 + int CommProperty; //通道性质 0:接收通道 1:转发通道 + int CommType; //通信方式 + int ChanMode; //通道方式0:双通道通信方式 1:单通道方式 + int ProtocolId; //规约类型 + int ConnectWaitSec; //连接等待重连时间,单位秒 + int ConnectTimeout; //链接超时,单位秒 + int RetryTimes; //最大重连次数 + int RespTimeout; //响应超时,单位毫秒 + int RecvTimeout; //接收超时,单位秒,判断是否需要端开连接重新连接 + int MaxRxSize; //接收缓存区长度 + int MaxTxSize; //发送缓存区长度 + int BackupChanNo1;//实际配置的备用通道号 + int BackupChanNo2;//实际配置的备用通道号 + int BackupChanNo3;//实际配置的备用通道号 + int ResParam1; + int ResParam2; + int ResParam3; + int ResParam4; + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + //char ComPortName[CN_FesMaxNameSize];//串口端口名 + int BaudRate; //波特率设置 + int Parity; //校验位 + int DataBit; //数据位 + int StopBit; //停止位 + int AlarmEnable; //2019-09-18 thxiao 通道报警使能 +}SFesRdbChanParam; + +typedef struct +{ + int ProtocolId; + char Name[CN_FesMaxNameSize]; +}SFesRdbProtocolParam; + +typedef struct { + int RtuNo; + int Index; //序号 + int FunCode; //功能码(即MODBUS中的命令码) + int StartAddr; //数据起始地址 + int DataLen; //数据长度 + int PollTime; //命令下发周期(相对时间,一个周期=50ms) + int FrameType; //帧类别 + int IsCreateSoe; //对遥信帧有效,0:不产生SOE,1:产生SOE + int Param1; //保留参数1 + int Param2; //保留参数2 + int Param3; + int Param4; + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int Used; +}SFesRdbDataBlock; + +typedef struct { + int RtuNo; + int PointNo; + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + char DevTagName[CN_FesMaxTagSize];//2020-12-17 thxiao DEVTAG + int IsFilter; //是否过滤AI突变 + int Percent; //突变百分比 + int DeadBandType;//死区类型 + double DeadBand; //死区值 + double ZeroBand; //归零死区 + double Base; //基值 + double Coeff; //系数; + double MaxRange; //度上限 + double MinRange; //度下限 + int Param1; //规约参数,每种协议含义相同。 如modbus FunNo + int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress + int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo + int Param4; //规约参数,每种协议含义相同。 + int Param5; + int Param6; + int Param7; + int Param8; + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 +}SFesRdbAiParam; + +typedef struct { + int RtuNo; + int PointNo; + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + char DevTagName[CN_FesMaxTagSize];//2020-12-17 thxiao DEVTAG + int IsFilterErr; //是否过滤错误DI + int IsFilterDisturb;//是否过滤DI抖动 + int DisturbTime; //抖动时限 + int Revers; //取反 + int Param1; //规约参数,每种协议含义相同。 如modbus FunNo + int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress + int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo + int Param4; //规约参数,每种协议各不相同。 + int Param5; + int Param6; + int Param7; + int Param8; + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int Attribute; //点属性 + int RelateDI; //关联遥信 +}SFesRdbDiParam; + +typedef struct { + int RtuNo; + int PointNo; + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + char DevTagName[CN_FesMaxTagSize];//2020-12-17 thxiao DEVTAG + double Base; //基值 + double Coeff; //系数; + int Param1; //规约参数,每种协议各不相同。 如modbus FunNo + int Param2; //规约参数,每种协议各不相同。 如modbus DataAddress + int Param3; //规约参数,每种协议各不相同。 如modbus InfoNo + int Param4; //规约参数,每种协议各不相同。 如modbus ValueType + int Param5; + int Param6; + int Param7; + int Param8; + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 +}SFesRdbAccParam; + + +typedef struct { + int RtuNo; + int PointNo; + char TableName[CN_FesMaxTableNameSize]; + char ColumnName[CN_FesMaxColumnNameSize]; + char TagName[CN_FesMaxTagSize]; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + char DevTagName[CN_FesMaxTagSize];//2020-12-17 thxiao DEVTAG + int Base; //基值 + int Coeff; //系数; + int MaxRange; //度上限 + int MinRange; //度下限 + int Param1; //规约参数,每种协议各不相同。 如modbus FunNo + int Param2; //规约参数,每种协议各不相同。 如modbus DataAddress + int Param3; //规约参数,每种协议各不相同。 如modbus InfoNo + int Param4; //规约参数,每种协议各不相同。 如modbus ValueType + int Param5; //规约参数,每种协议含义相同。 + int Param6; //规约参数,每种协议含义相同。 + int Param7; //规约参数,每种协议含义相同。 + int Param8; //规约参数,每种协议含义相同。 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 +}SFesRdbMiParam; + +typedef struct { + int RtuNo; + int PointNo; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + char DevTagName[CN_FesMaxTagSize];//2021-03-03 thxiao DEVTAG + int Revers; //取反 + int Param1; //规约参数,每种协议含义相同。 如modbus FunNo + int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress + int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo + int Param4; //规约参数,每种协议各不相同。 + int Param5; + int Param6; + int Param7; + int Param8; + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int Attribute; //点属性 + int ControlParam; //遥控参数 +}SFesRdbDoParam; + +typedef struct { + int RtuNo; + int PointNo; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + char DevTagName[CN_FesMaxTagSize];//2021-03-03 thxiao DEVTAG + double Base; //基值 + double Coeff; //系数; + double MaxRange; //度上限 + double MinRange; //度下限 + int Param1; //规约参数,每种协议含义相同。 如modbus FunNo + int Param2; //规约参数,每种协议含义相同。 如modbus DataAddress + int Param3; //规约参数,每种协议含义相同。 如modbus InfoNo + int Param4; //规约参数,每种协议含义相同。 + int Param5; //规约参数,每种协议含义相同。 + int Param6; //规约参数,每种协议含义相同。 + int Param7; //规约参数,每种协议含义相同。 + int Param8; //规约参数,每种协议含义相同。 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 +}SFesRdbAoParam; + +typedef struct { + int RtuNo; + int PointNo; + char PointTagName[CN_FesMaxTagSize]; + char PointDesc[CN_FesMaxDescSize];//2020-01-16 thxiao 增加点描述 + char DevTagName[CN_FesMaxTagSize];//2021-03-03 thxiao DEVTAG + int Base; //基值 + int Coeff; //系数; + int MaxRange; //度上限 + int MinRange; //度下限 + int Param1; //规约参数,每种协议各不相同。 如modbus FunNo + int Param2; //规约参数,每种协议各不相同。 如modbus DataAddress + int Param3; //规约参数,每种协议各不相同。 如modbus InfoNo + int Param4; //规约参数,每种协议各不相同。 如modbus ValueType + int Param5; //规约参数,每种协议含义相同。 + int Param6; //规约参数,每种协议含义相同。 + int Param7; //规约参数,每种协议含义相同。 + int Param8; //规约参数,每种协议含义相同。 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 +}SFesRdbMoParam; + +typedef struct { + int RtuNo; + int PointNo; + char DevTagName[CN_FesMaxTagSize];//2021-03-03 thxiao DEVTAG + int GroupNo; //定值组号 + int CodeNo; //定值代号 + int SeqNo; //定值序号 + int DzType; //定值类型 + int Unit; //单位 + double Base; //基值 + double Coeff; //系数; + double MaxRange; //度上限 + double MinRange; //度下限 + int Param1; //规约参数 + int Param2; //规约参数 + int Param3; //规约参数 + int Param4; //规约参数 + int Param5; //规约参数,每种协议含义相同。 + int Param6; //规约参数,每种协议含义相同。 + int Param7; //规约参数,每种协议含义相同。 + int Param8; //规约参数,每种协议含义相同。 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 +}SFesRdbDzParam; + + +typedef struct { + int RtuNo; + int DevID; //FEP 的设备ID号 + char DevDesc[CN_FesMaxNameSize];//设备描述 + char TagName[CN_FesMaxTagSize]; //2020-12-17 thxiao 设备标签名 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 +}SFesRdbDevInfo; + +//转发表Rdb结构参数 +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + char DPTagName[CN_FesMaxTagSize]; //后台标签名 + int FesRtuNo; //采集rtu号 + int FesPointNo; //采集点号 + int DpSeqNo; //后台点序号 + double Coeff; //系数; + double Base; //修正值 + int DeadBandType; //死区类型 + double DeadBand; //死区值 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP)*/ +}SFesRdbFwAiParam; + +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + char DPTagName[CN_FesMaxTagSize]; //后台标签名 + int FesRtuNo; //采集rtu号 + int FesPointNo; //采集点号 + int DpSeqNo; //后台点序号 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) +}SFesRdbFwDiParam; + +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + char DPTagName[CN_FesMaxTagSize]; //后台标签名 + int FesRtuNo; //采集rtu号 + int FesPointNo; //采集点号 + int DpSeqNo; //后台点序号 + double Coeff; //系数; + double Base; //修正值 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) +}SFesRdbFwAccParam; + +//转发表Rdb结构参数 +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + char DPTagName[CN_FesMaxTagSize]; //后台标签名 + int FesRtuNo; //采集rtu号 + int FesPointNo; //采集点号 + int DpSeqNo; //后台点序号 + int Coeff; //系数; + int Base; //修正值 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) +}SFesRdbFwMiParam; + +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + int FesRtuNo; //采集rtu号 + int FesPointNo; //采集点号 + double MaxRange; //度上限 + double MinRange; //度下限 + double Coeff; //系数; + double Base; //修正值 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) +}SFesRdbFwAoParam; + +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + int FesRtuNo; //采集rtu号 + int FesPointNum;//分量数 + int FesPointNo1; //采集点号 + int FesPointNo2; //采集点号 + int FesPointNo3; //采集点号 + int FesPointNo4; //采集点号 + int FesPointNo5; //采集点号 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) +}SFesRdbFwDoParam; + +typedef struct { + int RemoteNo; //远动序号 + char TagName[CN_FesMaxTagSize]; //采集标签名 + char PointDesc[CN_FesMaxDescSize]; //点描述 + int FesRtuNo; //采集rtu号 + int FesPointNo; //采集点号 + int MaxRange; //度上限 + int MinRange; //度下限 + int Property; //属性 + int SrcLocationID; //所属厂站 + int SrcSubSystem; //所属专业 + int ResParam1; //规约参数1 + int ResParam2; //规约参数2 + int ResParam3; //规约参数3 + int ResParam4; //规约参数4 + int ResParam5; //规约参数5 + int ResParam6; //规约参数6 + int ResParam7; //规约参数7 + char szResParam1[CN_FES_CharArray64]; //< 字符串类型预留参数 + int SrcType; //点来源(0:FES 1:DP) +}SFesRdbFwMoParam; + +typedef struct { + int nFaultCode; + char FaultName[CN_FesMaxNameSize]; //Fault Name +}SFesRdbFaultCode; + + +//201-03-011 thxiao 增加规约映射表 +typedef struct { + int RtuNo; + int PointNo; + int Param1; //Index + int Param2; //Index + int Param3; //Index + int Param4; //Index +}SFesRdbPPointMapping; //SFesRdbProtocolPointMapping diff --git a/product/src/fes/include/FesRtu.h b/product/src/fes/include/FesRtu.h index fcd33da2..d6830bf6 100644 --- a/product/src/fes/include/FesRtu.h +++ b/product/src/fes/include/FesRtu.h @@ -13,6 +13,19 @@ #include "FesDef.h" #include +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4003) +#endif + +#include "rapidjson/document.h" + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +typedef boost::shared_ptr RapidJsonDocPtr; + class PROTOCOLBASE_API CFesRtu { public: @@ -47,6 +60,7 @@ public: int m_MaxDiIndex; //实际数字量最大个数=最大PonitNo+1 int m_MaxAccIndex; //实际整形量最大个数=最大PonitNo+1 int m_MaxMiIndex; //实际混合量最大个数=最大PonitNo+1 + int m_MinMiIndex; //实际混合量最小索引,即规约参数1最小值,-1表示没有或者无效 int m_MaxAoIndex; //=最大PonitNo+1 int m_MaxDoIndex; //=最大PonitNo+1 int m_MaxMoIndex; //=最大PonitNo+1 @@ -77,11 +91,11 @@ public: int m_FwAoPointsNum; //实际转发遥调量个数 int m_FwDoPointsNum; int m_FwMoPointsNum; - SFesFwAi *m_pFwAi; //转发点值为源数据的原始值,转发时需要乘上系数。 + SFesFwAi *m_pFwAi; //转发点值为源数据的原始值,已经乘上系数。 SFesFwDi *m_pFwDi; SFesFwDi *m_pFwDDi; - SFesFwAcc *m_pFwAcc; //转发点值为源数据的原始值,转发时需要乘上系数。 - SFesFwMi *m_pFwMi; //转发点值为源数据的原始值,转发时需要乘上系数。 + SFesFwAcc *m_pFwAcc; //转发点值为源数据的原始值,已经乘上系数。 + SFesFwMi *m_pFwMi; //转发点值为源数据的原始值,已经乘上系数。 SFesFwAo *m_pFwAo; SFesFwDo *m_pFwDo; SFesFwMo *m_pFwMo; @@ -138,6 +152,7 @@ public: std::queue RxMoCmdBuf; std::queue RxSettingCmdBuf; std::queue RxDefCmdBuf; + std::queue m_jsonFormatReqCmdBuf; //< 自定义命令,用于存放json格式的自定义命令 //对于FES采集来说,控制响应消息分成:1、HMI(消息发送) 2、本FES转发协议(内部交互) 3、非本FES转发协议(消息发送) //FES外部(HMI)控制响应队列 @@ -146,6 +161,7 @@ public: std::queue TxMoCmdBuf; std::queue TxSettingCmdBuf; std::queue TxDefCmdBuf; + std::queue m_jsonFormatReplayCmdBuf; //< 自定义命令反馈,对应m_jsonFormatReqCmdBuf //对于FES转发,控制响应队列(内部交互)。 std::queue FwDoRespCmdBuf; @@ -906,35 +922,35 @@ public: * 写入转发SOE EVENT缓冲区内容 * @param buffer 写入数据 */ - void WriteFwSoeEventBuf(SFesFwSoeEvent buffer); + void WriteFwSoeEventBuf(const SFesFwSoeEvent &buffer); /** * @brief CFesRtu::WriteFwDiBuf * 写入转发DI变化缓冲区内容 * @param buffer 写入数据 */ - void WriteFwDiBuf(SFesFwChgDi buffer); + void WriteFwDiBuf(const SFesFwChgDi &buffer); /** * @brief CFesRtu::WriteFwAiBuf * 写入转发Ai变化缓冲区内容 * @param buffer 写入数据 */ - void WriteFwAiBuf(SFesFwChgAi buffer); + void WriteFwAiBuf(const SFesFwChgAi &buffer); /** * @brief CFesRtu::WriteFwAccBuf * 写入转发Acc变化缓冲区内容 * @param buffer 写入数据 */ - void WriteFwAccBuf(SFesFwChgAcc buffer); + void WriteFwAccBuf(const SFesFwChgAcc &buffer); /** * @brief CFesRtu::WriteFwMiBuf * 写入转发Mi变化缓冲区内容 * @param buffer 写入数据 */ - void WriteFwMiBuf(SFesFwChgMi buffer); + void WriteFwMiBuf(const SFesFwChgMi &buffer); /** * @brief CFesRtu::GetFwSOEEventNum @@ -1130,14 +1146,14 @@ public: * 写入转发DDI变化缓冲区内容 * @param buffer 写入数据 */ - void WriteFwDDiBuf(SFesFwChgDi buffer); + void WriteFwDDiBuf(const SFesFwChgDi &buffer); /** * @brief CFesRtu::WriteFwDSoeEventBuf * 写入转发DSOE EVENT缓冲区内容 * @param buffer 写入数据 */ - void WriteFwDSoeEventBuf(SFesFwSoeEvent buffer); + void WriteFwDSoeEventBuf(const SFesFwSoeEvent &buffer); /** * @brief CFesRtu::GetFwDSOEEventNum @@ -1162,7 +1178,7 @@ public: * @param updateMode 更新模式 1:判断后更新(DP to FES) 0:直接更新,不需要判断(默认)(FES to FES) * @return true:更新 false:没更新 */ - bool UpdataFwDiValue(SFesFwChgDi DiValue, int updateMode = 0); + bool UpdataFwDiValue(const SFesFwChgDi &DiValue, int updateMode = 0); /** * @brief CFesRtu::UpdataFwDiValue @@ -1171,16 +1187,16 @@ public: * @param updateMode 更新模式 1:判断后更新(DP to FES) 0:直接更新,不需要判断(默认)(FES to FES) * @return true:更新 false:没更新 */ - bool UpdataFwDDiValue(SFesFwChgDi DiValue, int updateMode = 0); + bool UpdataFwDDiValue(const SFesFwChgDi &DiValue, int updateMode = 0); /** * @brief CFesRtu::UpdataFwAiValue - * 更新转发RTU AI数据 + * 更新转发RTU AI数据,同时会返回更新后的值,比如:内部进行基值和K值变换 * @param SFesFwChgAi 新值 * @param updateMode 更新模式 1:判断后更新(DP to FES) 0:直接更新,不需要判断(默认)(FES to FES) * @return true:更新 false:没更新 */ - bool UpdataFwAiValue(SFesFwChgAi AiValue, int updateMode = 0); + bool UpdataFwAiValue(const SFesFwChgAi &AiValue, float &fNewValue,EnumUpdateFwCacheMode eUpdateMode); /** * @brief CFesRtu::UpdataFwAccValue @@ -1189,7 +1205,7 @@ public: * @param updateMode 更新模式 1:判断后更新(DP to FES) 0:直接更新,不需要判断(默认)(FES to FES) * @return true:更新 false:没更新 */ - bool UpdataFwAccValue(SFesFwChgAcc AccValue, int updateMode = 0); + bool UpdataFwAccValue(const SFesFwChgAcc &AccValue, double &dNewValue,EnumUpdateFwCacheMode eUpdateMode); /** * @brief CFesRtu::UpdataFwMiValue @@ -1198,7 +1214,7 @@ public: * @param updateMode 更新模式 1:判断后更新(DP to FES) 0:直接更新,不需要判断(默认)(FES to FES) * @return true:更新 false:没更新 */ - bool UpdataFwMiValue(SFesFwChgMi MiValue, int updateMode = 0); + bool UpdataFwMiValue(const SFesFwChgMi &MiValue,int &nNewValue, EnumUpdateFwCacheMode eUpdateMode); void ClearFwDiBuf(); void ClearFwDDiBuf(); @@ -1325,7 +1341,7 @@ public: void ClearComStatusInit(); - void WriteVirtualValue(SFesVirtualValue Value); + void WriteVirtualValue(const SFesVirtualValue &Value); int ReadVirtualValue(SFesVirtualValue *Value); @@ -1366,14 +1382,42 @@ public: */ int ReadSoeStrEvent(int num, SFesSoeStrEvent *buffer); - /** + /** * @brief CFesRtu::WriteRtuPointsComDown * 更新所有点的通信中断状态 * @param comStatus RTU通信状态 */ void WriteRtuPointsComDown(); + /** + * @brief CFesRtu::writeStringFormatReqCmd + * 写入FES自定义命令缓存区(字符串格式,一般用json) + * @param strCmd 自定义命令报文 + */ + void writeJsonFormatReqCmd(const rapidjson::Value &jsonCmd); + /** + * @brief CFesRtu::readStringFormatReqCmd + * 读取发送自定义命令缓冲区内容 + * @param dequeStrCmd 控制命令 + */ + void readJsonFormatReqCmd(std::queue &dequeJsonCmd); + + size_t getJsonFormatReqCmdSize(); + void clearJsonFormatReqCmdBuf(); + /** + * @brief CFesRtu::writeJsonFormatReplayCmd + * 写入FES自定义命令反馈缓存区(字符串格式,一般用json) + * @param strCmd 自定义命令反馈报文 + */ + void writeJsonFormatReplayCmd(const std::string &strCmd); + + /** + * @brief CFesRtu::readJsonFormatReplayCmd + * 读取发送自定义命令反馈缓冲区内容 + * @param dequeStrCmd 控制反馈命令 + */ + void readJsonFormatReplayCmd(std::queue &dequeStrCmd); }; #ifndef FESSIM diff --git a/product/src/fes/include/FesSimProtocol.h b/product/src/fes/include/FesSimProtocol.h index aa4857ac..33022b48 100644 --- a/product/src/fes/include/FesSimProtocol.h +++ b/product/src/fes/include/FesSimProtocol.h @@ -421,7 +421,7 @@ typedef struct{ //整形量数值响应 typedef struct { uint32 PointNo; - uint64 Value; + double Value; uint32 Status; uint64 time; //1970-01-01 00:00 至今的毫秒数 }SFesSimAccData; @@ -621,16 +621,16 @@ typedef struct{ }SFesSimDiStopResp; -//整形量仿真启动请求================================== +//累积量仿真启动请求================================== typedef struct{ char SetMode; //设置方式 1:固定设置 2:线性设置 3:随机设置 char Range; //设置范围 1:当前模拟量 2:当前RTU 3:所有RTU short Period; //变化周期,单位:秒 - int64 SetValue; //设置值 + double SetValue; //设置值 uint32 Status; //设值点状态 - int MinValue; //设置值最小值 - int MaxValue; //设置值最大值 - int StepValue; //设置值步长 + float MinValue; //设置值最小值 + float MaxValue; //设置值最大值 + float StepValue; //设置值步长 int RtuNo; // RTU号 -1: 所有RTU 其他:对应RTU号 int PointNo; //点号, -1:RTU所有点 其他:对应点号 }SFesSimAccStartReq; diff --git a/product/src/fes/include/fes_ping_api/PingApiCommon.h b/product/src/fes/include/fes_ping_api/PingApiCommon.h new file mode 100644 index 00000000..d5f63b4e --- /dev/null +++ b/product/src/fes/include/fes_ping_api/PingApiCommon.h @@ -0,0 +1,15 @@ +/** + @file PingApiCommon.h + @brief 网络检测库公共结构定义 + @author 曹顶法 +*/ +#pragma once +#include +#include "Export.h" + +#ifdef FES_PING_EXPORTS +#define FES_PING_API G_DECL_EXPORT +#else +#define FES_PING_API G_DECL_IMPORT +#endif + diff --git a/product/src/fes/include/fes_ping_api/PingInterface.h b/product/src/fes/include/fes_ping_api/PingInterface.h new file mode 100644 index 00000000..78a43ca2 --- /dev/null +++ b/product/src/fes/include/fes_ping_api/PingInterface.h @@ -0,0 +1,56 @@ +/** + @file NetworkCheckInterface.h + @brief 网络检测接口类 + @author 曹顶法 +*/ +#pragma once +#include +#include "boost/shared_ptr.hpp" +#include "boost/make_shared.hpp" +#include "PingApiCommon.h" +#include "PingResultCache.h" + +namespace iot_fes +{ + /** + @brief 网络检测接口类 + */ + class CPingInterface + { + public: + /** + @brief 启动Ping + @return 正常返回iotSuccess + */ + virtual int start() = 0; + //停止Ping + virtual int stop() = 0; + + /** + @brief 增加需要Ping的信息,要在start执行执行,可以多次执行 + @param const int nChannelNo 通道号 + @param const int nIpIdx 本通道下第几个IP + @param const std::string & strDstIP 要ping的IP地址 + */ + virtual void addAddress(const int nChannelNo,const int nIpIdx,const std::string &strIp) = 0; + + //获取指定通道的Ping结果 + virtual bool getPingResult(const int nChannelNo) = 0; + + //获取指定通道的Ping结果,返回是ping的ip的索引,找不到返回-1 + virtual int getPingOkIpIndex(const int nChannelNo) = 0; + + //启用指定通道的Ping功能 + virtual void enablePing(const int nChannelNo) = 0; + + //禁用指定通道的Ping功能 + virtual void disablePing(const int nChannelNo) = 0; + + }; + + typedef boost::shared_ptr CPingInterfacePtr; + + /* @brief 创建网络检测访问库实例 */ + FES_PING_API CPingInterfacePtr getPingInstance(); + +} //namespace iot_fes diff --git a/product/src/fes/include/fes_ping_api/PingResultCache.h b/product/src/fes/include/fes_ping_api/PingResultCache.h new file mode 100644 index 00000000..f3037a7a --- /dev/null +++ b/product/src/fes/include/fes_ping_api/PingResultCache.h @@ -0,0 +1,51 @@ +/** + @file SysRunNetworkInfoTable.h + @brief 表sys_network_info对应的结构 + @author 曹顶法 +*/ +#pragma once +#include +#include +#include +#include +#include "fes_ping_api/PingApiCommon.h" + +namespace iot_fes +{ +//每个通道最大Ip数量 +//最高位用来标记启用Ping功能,用于实现设备通信正常时关闭Ping功能,通信异常时重新启用Ping +const int CONST_MAX_PING_NUM = 3; +typedef std::map > Chan2ConnStatMAP; + class CPingResultCache + { + public: + CPingResultCache(); + ~CPingResultCache(); + + //查询指定通道的Ping结果,查询不到返回true,认为网络OK + bool getPingResult(const int nChannelNo); + + //获取指定通道的Ping结果,返回是ping的ip的索引,找不到返回-1 + int getPingOkIpIndex(const int nChannelNo); + + //设置通道Ip的Ping结果 + void setPingResult(const int nChNo,const int nIdx,const bool bRet); + + //查询指定通道是否启用,如果找不到,走默认逻辑,认为需要Ping + //如果最高位设置为1,表示当前网络正常,可以暂停ping,所以认为禁用,返回false + bool isEnablePing(const int nChannelNo); + + //启用Ping功能 + void enablePing(const int nChannelNo); + //禁用Ping功能 + void disablePing(const int nChannelNo); + + private: + Chan2ConnStatMAP m_mapChToPingResult; + boost::mutex m_objMutex; //< 互斥量 + }; + + typedef boost::shared_ptr CPingResultCachePtr; + +} //namespace iot_fes + diff --git a/product/src/fes/include/libdnp3/opendnp3/ConsoleLogger.h b/product/src/fes/include/libdnp3/opendnp3/ConsoleLogger.h new file mode 100644 index 00000000..5532b0d1 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/ConsoleLogger.h @@ -0,0 +1,60 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_CONSOLELOGGER_H +#define OPENDNP3_CONSOLELOGGER_H + +#include "opendnp3/logging/ILogHandler.h" +#include "opendnp3/util/Uncopyable.h" + +#include +#include + +namespace opendnp3 +{ + +/** + * LogHandler that prints all log messages to the console + */ +class ConsoleLogger final : public opendnp3::ILogHandler, private Uncopyable +{ + +public: + void log(opendnp3::ModuleId module, + const char* id, + opendnp3::LogLevel level, + char const* location, + char const* message) final; + + static std::shared_ptr Create(bool printLocation = false) + { + return std::make_shared(printLocation); + }; + + ConsoleLogger(bool printLocation) : printLocation(printLocation) {} + +private: + bool printLocation; + + std::mutex mutex; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/DNP3Manager.h b/product/src/fes/include/libdnp3/opendnp3/DNP3Manager.h new file mode 100644 index 00000000..a6d54150 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/DNP3Manager.h @@ -0,0 +1,217 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_DNP3MANAGER_H +#define OPENDNP3_DNP3MANAGER_H + +#include "opendnp3/ErrorCodes.h" +#include "opendnp3/channel/ChannelRetry.h" +#include "opendnp3/channel/IChannel.h" +#include "opendnp3/channel/IChannelListener.h" +#include "opendnp3/channel/IListener.h" +#include "opendnp3/channel/IPEndpoint.h" +#include "opendnp3/channel/SerialSettings.h" +#include "opendnp3/channel/TLSConfig.h" +#include "opendnp3/gen/ChannelState.h" +#include "opendnp3/gen/ServerAcceptMode.h" +#include "opendnp3/logging/ILogHandler.h" +#include "opendnp3/logging/LogLevels.h" +#include "opendnp3/master/IListenCallbacks.h" +#include "opendnp3/util/TimeDuration.h" + +#include +#include +#include + +namespace opendnp3 +{ + +class DNP3ManagerImpl; + +/** + * Root DNP3 object used to create channels and sessions. + */ +class DNP3Manager +{ + +public: + /** + * Construct a manager + * + * @param concurrencyHint How many threads to allocate in the thread pool + * @param handler Callback interface for log messages + * @param onThreadStart Action to run when a thread pool thread starts + * @param onThreadExit Action to run just before a thread pool thread exits + */ + DNP3Manager(uint32_t concurrencyHint, + std::shared_ptr handler = std::shared_ptr(), + std::function onThreadStart = [](uint32_t) {}, + std::function onThreadExit = [](uint32_t) {}); + + ~DNP3Manager(); + + /** + * Permanently shutdown the manager and all sub-objects that have been created. Stop + * the thead pool. + */ + void Shutdown(); + + /** + * Add a persistent TCP client channel. Automatically attempts to reconnect. + * + * @param id Alias that will be used for logging purposes with this channel + * @param levels Bitfield that describes the logging level for this channel and associated sessions + * @param retry Retry parameters for failed channels + * @param hosts List of host addresses to use to connect to the remote outstation (i.e. 127.0.0.1 or www.google.com) + * @param local adapter address on which to attempt the connection (use 0.0.0.0 for all adapters) + * @param listener optional callback interface (can be nullptr) for info about the running channel + * @return shared_ptr to a channel interface + */ + std::shared_ptr AddTCPClient(const std::string& id, + const opendnp3::LogLevels& levels, + const ChannelRetry& retry, + const std::vector& hosts, + const std::string& local, + std::shared_ptr listener); + + /** + * Add a persistent TCP server channel. Only accepts a single connection at a time. + * + * @param id Alias that will be used for logging purposes with this channel + * @param levels Bitfield that describes the logging level for this channel and associated sessions + * @param mode Describes how new connections are treated when another session already exists + * @param endpoint Network adapter to listen on (i.e. 127.0.0.1 or 0.0.0.0) and port + * @param listener optional callback interface (can be nullptr) for info about the running channel + * @throw DNP3Error if the manager was already shutdown or if the server could not be binded properly + * @return shared_ptr to a channel interface + */ + std::shared_ptr AddTCPServer(const std::string& id, + const opendnp3::LogLevels& levels, + ServerAcceptMode mode, + const IPEndpoint& endpoint, + std::shared_ptr listener); + + /** + * Add a persistent UDP channel. + * + * @param id Alias that will be used for logging purposes with this channel + * @param levels Bitfield that describes the logging level for this channel and associated sessions + * @param retry Retry parameters for failed channels + * @param localEndpoint Local endpoint from which datagrams will be received + * @param remoteEndpoint Remote endpoint where datagrams will be sent to + * @param listener optional callback interface (can be nullptr) for info about the running channel + * @throw DNP3Error if the manager was already shutdown + * @return shared_ptr to a channel interface + */ + std::shared_ptr AddUDPChannel(const std::string& id, + const opendnp3::LogLevels& levels, + const ChannelRetry& retry, + const IPEndpoint& localEndpoint, + const IPEndpoint& remoteEndpoint, + std::shared_ptr listener); + + /** + * Add a persistent serial channel + * + * @param id Alias that will be used for logging purposes with this channel + * @param levels Bitfield that describes the logging level for this channel and associated sessions + * @param retry Retry parameters for failed channels + * @param settings settings object that fully parameterizes the serial port + * @param listener optional callback interface (can be nullptr) for info about the running channel + * @throw DNP3Error if the manager was already shutdown + * @return shared_ptr to a channel interface + */ + std::shared_ptr AddSerial(const std::string& id, + const opendnp3::LogLevels& levels, + const ChannelRetry& retry, + SerialSettings settings, + std::shared_ptr listener); + + /** + * Add a TLS client channel + * + * @throw std::system_error Throws underlying ASIO exception of TLS configuration is invalid + * + * @param id Alias that will be used for logging purposes with this channel + * @param levels Bitfield that describes the logging level for this channel and associated sessions + * @param retry Retry parameters for failed channels + * @param hosts IP address of remote outstation (i.e. 127.0.0.1 or www.google.com) + * @param local adapter address on which to attempt the connection (use 0.0.0.0 for all adapters) + * @param config TLS configuration information + * @param listener optional callback interface (can be nullptr) for info about the running channel + * @throw DNP3Error if the manager was already shutdown or if the library was compiled without TLS support + * @return shared_ptr to a channel interface + */ + std::shared_ptr AddTLSClient(const std::string& id, + const opendnp3::LogLevels& levels, + const ChannelRetry& retry, + const std::vector& hosts, + const std::string& local, + const TLSConfig& config, + std::shared_ptr listener); + + /** + * Add a TLS server channel + * + * @throw std::system_error Throws underlying ASIO exception of TLS configuration is invalid + * + * @param id Alias that will be used for logging purposes with this channel + * @param levels Bitfield that describes the logging level for this channel and associated sessions + * @param mode Describes how new connections are treated when another session already exists + * @param endpoint Network adapter to listen on (i.e. 127.0.0.1 or 0.0.0.0) and port + * @param config TLS configuration information + * @param listener optional callback interface (can be nullptr) for info about the running channel + * @throw DNP3Error if the manager was already shutdown, if the library was compiled without TLS support + * or if the server could not be binded properly + * @return shared_ptr to a channel interface + */ + std::shared_ptr AddTLSServer(const std::string& id, + const opendnp3::LogLevels& levels, + ServerAcceptMode mode, + const IPEndpoint& endpoint, + const TLSConfig& config, + std::shared_ptr listener); + + /** + * Create a TCP listener that will be used to accept incoming connections + * @throw DNP3Error if the manager was already shutdown or if the server could not be binded properly + */ + std::shared_ptr CreateListener(std::string loggerid, + const opendnp3::LogLevels& loglevel, + const IPEndpoint& endpoint, + const std::shared_ptr& callbacks); + + /** + * Create a TLS listener that will be used to accept incoming connections + * @throw DNP3Error if the manager was already shutdown, if the library was compiled without TLS support + * or if the server could not be binded properly + */ + std::shared_ptr CreateListener(std::string loggerid, + const opendnp3::LogLevels& loglevel, + const IPEndpoint& endpoint, + const TLSConfig& config, + const std::shared_ptr& callbacks); + +private: + std::unique_ptr impl; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/ErrorCodes.h b/product/src/fes/include/libdnp3/opendnp3/ErrorCodes.h new file mode 100644 index 00000000..31911c6f --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/ErrorCodes.h @@ -0,0 +1,66 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OPENDNP3_ERRORCODES_H +#define OPENDNP3_ERRORCODES_H + +#include +#include +#include + +namespace opendnp3 +{ + +enum class Error : int +{ + SHUTTING_DOWN, + NO_TLS_SUPPORT, + UNABLE_TO_BIND_SERVER +}; + +struct ErrorSpec +{ + static std::string to_string(Error err) + { + switch (err) + { + case Error::SHUTTING_DOWN: + return "The operation was requested while the resource was shutting down"; + case Error::NO_TLS_SUPPORT: + return "Not built with TLS support"; + case Error::UNABLE_TO_BIND_SERVER: + return "Unable to bind server to the specified port"; + default: + return "unknown error"; + }; + } +}; + +class DNP3Error final : public std::runtime_error +{ +public: + explicit DNP3Error(Error err) : std::runtime_error(ErrorSpec::to_string(err)) {} + + DNP3Error(Error err, std::error_code& ec) : std::runtime_error(ErrorSpec::to_string(err) + ": " + ec.message()) {} +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/IResource.h b/product/src/fes/include/libdnp3/opendnp3/IResource.h new file mode 100644 index 00000000..b12c88a4 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/IResource.h @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IRESOURCE_H +#define OPENDNP3_IRESOURCE_H + +namespace opendnp3 +{ + +/** + * Anything that can be shutdown + */ +struct IResource +{ +public: + virtual ~IResource() = default; + + virtual void Shutdown() = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/IStack.h b/product/src/fes/include/libdnp3/opendnp3/IStack.h new file mode 100644 index 00000000..fd59f6a2 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/IStack.h @@ -0,0 +1,55 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ISTACK_H +#define OPENDNP3_ISTACK_H + +#include "opendnp3/IResource.h" +#include "opendnp3/StackStatistics.h" + +namespace opendnp3 +{ + +/** + * Base class for masters or outstations + */ +class IStack : public IResource +{ +public: + virtual ~IStack() {} + + /** + * Synchronously enable communications + */ + virtual bool Enable() = 0; + + /** + * Synchronously disable communications + */ + virtual bool Disable() = 0; + + /** + * @return stack statistics counters + */ + virtual StackStatistics GetStackStatistics() = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/StackStatistics.h b/product/src/fes/include/libdnp3/opendnp3/StackStatistics.h new file mode 100644 index 00000000..7f4f015a --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/StackStatistics.h @@ -0,0 +1,91 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_STACKSTATISTICS_H +#define OPENDNP3_STACKSTATISTICS_H + +#include + +namespace opendnp3 +{ + +/** + * Statistics related to both a master or outstation session + */ +struct StackStatistics +{ + struct Link + { + /// number of unexpected frames + uint64_t numUnexpectedFrame = 0; + + /// frames received w/ wrong master bit + uint64_t numBadMasterBit = 0; + + /// frames received for an unknown destination + uint64_t numUnknownDestination = 0; + + /// frames received for an unknown source + uint64_t numUnknownSource = 0; + }; + + struct Transport + { + struct Rx + { + /// Number of valid TPDU's received + uint64_t numTransportRx = 0; + + /// Number of TPDUs dropped due to malformed contents + uint64_t numTransportErrorRx = 0; + + /// Number of times received data was too big for reassembly buffer + uint64_t numTransportBufferOverflow = 0; + + /// number of times transport buffer is discard due to new FIR + uint64_t numTransportDiscard = 0; + + /// number of segments ignored due to bad FIR/FIN or SEQ + uint64_t numTransportIgnore = 0; + }; + + struct Tx + { + /// Number of TPDUs transmitted + uint64_t numTransportTx = 0; + }; + + Transport() = default; + Transport(const Rx& rx, const Tx& tx) : rx(rx), tx(tx) {} + + Rx rx; + Tx tx; + }; + + StackStatistics() = default; + + StackStatistics(const Link& link, const Transport& transport) : link(link), transport(transport) {} + + Link link; + Transport transport; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/AnalogCommandEvent.h b/product/src/fes/include/libdnp3/opendnp3/app/AnalogCommandEvent.h new file mode 100644 index 00000000..1bf41e84 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/AnalogCommandEvent.h @@ -0,0 +1,50 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ANALOGCOMMANDEVENT_H +#define OPENDNP3_ANALOGCOMMANDEVENT_H + +#include "opendnp3/app/DNPTime.h" +#include "opendnp3/gen/CommandStatus.h" + +namespace opendnp3 +{ + +/** + * Occurs when an outstation receives and analog command. Maps to Group43. + */ +class AnalogCommandEvent +{ +public: + AnalogCommandEvent(); + + AnalogCommandEvent(double value, CommandStatus status); + + AnalogCommandEvent(double value, CommandStatus status, DNPTime time); + + double value; + CommandStatus status; + DNPTime time; + + bool operator==(const AnalogCommandEvent& rhs) const; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/AnalogOutput.h b/product/src/fes/include/libdnp3/opendnp3/app/AnalogOutput.h new file mode 100644 index 00000000..560430b9 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/AnalogOutput.h @@ -0,0 +1,108 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ANALOGOUTPUT_H +#define OPENDNP3_ANALOGOUTPUT_H + +#include "opendnp3/gen/CommandStatus.h" + +namespace opendnp3 +{ + +/** + * The object to represent a setpoint request from the master. Think of + * this like turning a dial on the front of a machine to desired setting. + */ +template class AnalogOutput +{ +public: + AnalogOutput() : value(0), status(CommandStatus::SUCCESS) {} + + AnalogOutput(T value_) : value(value_), status(CommandStatus::SUCCESS) {} + + AnalogOutput(T value_, CommandStatus status_) : value(value_), status(status_) {} + + bool ValuesEqual(const AnalogOutput& lhs) const + { + return value == lhs.value; + } + + T value; + + /** + * The status value defaults to CS_SUCCESS for requests + */ + CommandStatus status; +}; + +/** + * 16-bit signed integer analog output. The underlying serialization is Group41, Variation 2 + */ +class AnalogOutputInt16 : public AnalogOutput +{ +public: + AnalogOutputInt16(); + AnalogOutputInt16(int16_t); + AnalogOutputInt16(int16_t, CommandStatus); + + bool operator==(const AnalogOutputInt16& arRHS) const; +}; + +/** + * 32-bit signed integer analog output. The underlying serialization is Group41, Variation 1 + */ +class AnalogOutputInt32 : public AnalogOutput +{ +public: + AnalogOutputInt32(); + AnalogOutputInt32(int32_t); + AnalogOutputInt32(int32_t, CommandStatus); + + bool operator==(const AnalogOutputInt32& arRHS) const; +}; + +/** + * Single precision analog output. The underlying serialization is Group41, Variation 3 + */ +class AnalogOutputFloat32 : public AnalogOutput +{ +public: + AnalogOutputFloat32(); + AnalogOutputFloat32(float); + AnalogOutputFloat32(float, CommandStatus); + + bool operator==(const AnalogOutputFloat32& arRHS) const; +}; + +/** + * Double precision analog output. The underlying serialization is Group41, Variation 3 + */ +class AnalogOutputDouble64 : public AnalogOutput +{ +public: + AnalogOutputDouble64(); + AnalogOutputDouble64(double); + AnalogOutputDouble64(double, CommandStatus); + + bool operator==(const AnalogOutputDouble64& arRHS) const; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/AppConstants.h b/product/src/fes/include/libdnp3/opendnp3/app/AppConstants.h new file mode 100644 index 00000000..34b6e70f --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/AppConstants.h @@ -0,0 +1,37 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OPENDNP3_APPCONSTANTS_H +#define OPENDNP3_APPCONSTANTS_H + +#include "opendnp3/util/TimeDuration.h" + +#include + +namespace opendnp3 +{ +// the default size for an APDU +const uint32_t DEFAULT_MAX_APDU_SIZE = 2048; + +// default timeout for the application layer +const TimeDuration DEFAULT_APP_TIMEOUT = TimeDuration::Seconds(5); +} // namespace opendnp3 + +#endif \ No newline at end of file diff --git a/product/src/fes/include/libdnp3/opendnp3/app/BaseMeasurementTypes.h b/product/src/fes/include/libdnp3/opendnp3/app/BaseMeasurementTypes.h new file mode 100644 index 00000000..c116b08b --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/BaseMeasurementTypes.h @@ -0,0 +1,65 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_BASEMEASUREMENTTYPES_H +#define OPENDNP3_BASEMEASUREMENTTYPES_H + +#include "opendnp3/app/DNPTime.h" +#include "opendnp3/app/Flags.h" + +#include + +namespace opendnp3 +{ + +/** + Base class shared by all of the DataPoint types. +*/ +class Measurement +{ +public: + Flags flags; // bitfield that stores type specific quality information + DNPTime time; // timestamp associated with the measurement + +protected: + Measurement() {} + + Measurement(Flags flags) : flags(flags) {} + + Measurement(Flags flags, DNPTime time) : flags(flags), time(time) {} +}; + +/// Common subclass to analogs and counters +template class TypedMeasurement : public Measurement +{ +public: + T value; + + typedef T Type; + +protected: + TypedMeasurement() : Measurement(), value(0) {} + TypedMeasurement(Flags flags) : Measurement(flags), value(0) {} + TypedMeasurement(T value, Flags flags) : Measurement(flags), value(value) {} + TypedMeasurement(T value, Flags flags, DNPTime time) : Measurement(flags, time), value(value) {} +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/BinaryCommandEvent.h b/product/src/fes/include/libdnp3/opendnp3/app/BinaryCommandEvent.h new file mode 100644 index 00000000..431ee7c9 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/BinaryCommandEvent.h @@ -0,0 +1,65 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OPENDNP3_BINARYCOMMANDEVENT_H +#define OPENDNP3_BINARYCOMMANDEVENT_H + +#include "opendnp3/app/DNPTime.h" +#include "opendnp3/app/Flags.h" +#include "opendnp3/gen/CommandStatus.h" + +namespace opendnp3 +{ + +/** +Maps to Group13Var1/2 +*/ +class BinaryCommandEvent +{ +public: + BinaryCommandEvent(); + + BinaryCommandEvent(Flags flags); + + BinaryCommandEvent(Flags flags, DNPTime time); + + BinaryCommandEvent(bool value, CommandStatus status); + + BinaryCommandEvent(bool value, CommandStatus status, DNPTime time); + + bool value; + CommandStatus status; + DNPTime time; + + Flags GetFlags() const; + + bool operator==(const BinaryCommandEvent& rhs) const; + +private: + static const uint8_t ValueMask = 0x80; + static const uint8_t StatusMask = 0x7F; + + static bool GetValueFromFlags(Flags flags); + static CommandStatus GetStatusFromFlags(Flags flags); +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/ClassField.h b/product/src/fes/include/libdnp3/opendnp3/app/ClassField.h new file mode 100644 index 00000000..4eca5f75 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/ClassField.h @@ -0,0 +1,91 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_CLASSFIELD_H +#define OPENDNP3_CLASSFIELD_H + +#include "opendnp3/app/EventType.h" +#include "opendnp3/gen/PointClass.h" + +#include + +namespace opendnp3 +{ + +/** + * Specifies a set of event classes e.g. some subset of {0, 1, 2, 3} + */ +class ClassField +{ +public: + ClassField(); + + explicit ClassField(PointClass pc); + + explicit ClassField(EventClass ec); + + explicit ClassField(uint8_t mask_); + + ClassField(bool class0, bool class1, bool class2, bool class3); + + bool IsEmpty() const; + + bool Intersects(const ClassField& other) const; + + uint8_t GetBitfield() const + { + return bitfield; + }; + + ClassField OnlyEventClasses() const; + + void Clear(const ClassField& field); + + void Set(const ClassField& field); + + void Set(PointClass pc); + + static const uint8_t CLASS_0 = static_cast(PointClass::Class0); + static const uint8_t CLASS_1 = static_cast(PointClass::Class1); + static const uint8_t CLASS_2 = static_cast(PointClass::Class2); + static const uint8_t CLASS_3 = static_cast(PointClass::Class3); + static const uint8_t EVENT_CLASSES = CLASS_1 | CLASS_2 | CLASS_3; + static const uint8_t ALL_CLASSES = EVENT_CLASSES | CLASS_0; + + bool HasEventType(EventClass ec) const; + + bool HasClass0() const; + bool HasClass1() const; + bool HasClass2() const; + bool HasClass3() const; + + bool HasEventClass() const; + bool HasAnyClass() const; + + static ClassField None(); + static ClassField AllClasses(); + static ClassField AllEventClasses(); + +private: + uint8_t bitfield; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/ControlRelayOutputBlock.h b/product/src/fes/include/libdnp3/opendnp3/app/ControlRelayOutputBlock.h new file mode 100644 index 00000000..b1889f06 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/ControlRelayOutputBlock.h @@ -0,0 +1,92 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_CONTROLRELAYOUTPUTBLOCK_H +#define OPENDNP3_CONTROLRELAYOUTPUTBLOCK_H + +#include "opendnp3/gen/CommandStatus.h" +#include "opendnp3/gen/OperationType.h" +#include "opendnp3/gen/TripCloseCode.h" + +namespace opendnp3 +{ + +/** + * Describes an incoming control request from the master. It is the + * applications responsibility to handle the request and return an + * approiate status code. The PULSE_CLOSE and PULSE_TRIP OperationType + * require setting the mOnTimeMS, mOffTimeMS and mCount variables, otherwise + * just use the defaults. + */ +class ControlRelayOutputBlock +{ +public: + // primary constructor where the control code is split by its components + ControlRelayOutputBlock(OperationType opType = OperationType::LATCH_ON, + TripCloseCode tcc = TripCloseCode::NUL, + bool clear = false, + uint8_t count = 1, + uint32_t onTime = 100, + uint32_t offTime = 100, + CommandStatus status = CommandStatus::SUCCESS); + + // overloaded constructor that allows the user to set a raw control code for non-standard codes + ControlRelayOutputBlock(uint8_t rawCode, + uint8_t count = 1, + uint32_t onTime = 100, + uint32_t offTime = 100, + CommandStatus status = CommandStatus::SUCCESS); + + /// operation type + OperationType opType; + // trip-close code + TripCloseCode tcc; + // clear bit + bool clear; + /// the number of times to repeat the operation + uint8_t count; + /// the 'on' time for the pulse train + uint32_t onTimeMS; + /// the 'off' time for the pulse train + uint32_t offTimeMS; + /// status of the resulting operation + CommandStatus status; + /// The raw code in bytes + uint8_t rawCode; + + bool IsQUFlagSet() const + { + return (rawCode & 0x10) != 0; + } + + bool ValuesEqual(const ControlRelayOutputBlock& lhs) const + { + return (opType == lhs.opType) && (tcc == lhs.tcc) && (clear == lhs.clear) && (count == lhs.count) + && (onTimeMS == lhs.onTimeMS) && (offTimeMS == lhs.offTimeMS); + } + + bool operator==(const ControlRelayOutputBlock& lhs) const + { + return this->ValuesEqual(lhs) && (this->status == lhs.status); + } +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/DNPTime.h b/product/src/fes/include/libdnp3/opendnp3/app/DNPTime.h new file mode 100644 index 00000000..414174bb --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/DNPTime.h @@ -0,0 +1,47 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_DNPTIME_H +#define OPENDNP3_DNPTIME_H + +#include "opendnp3/gen/TimestampQuality.h" + +#include + +namespace opendnp3 +{ + +struct DNPTime +{ + DNPTime() : value(0), quality(TimestampQuality::INVALID) {} + explicit DNPTime(uint64_t value) : value(value), quality(TimestampQuality::SYNCHRONIZED) {} + DNPTime(uint64_t value, TimestampQuality quality) : value(value), quality(quality) {} + + bool operator==(const DNPTime& rhs) const + { + return this->value == rhs.value && this->quality == rhs.quality; + } + + uint64_t value; + TimestampQuality quality; +}; + +} // namespace opendnp3 + +#endif // namespace opendnp3 diff --git a/product/src/fes/include/libdnp3/opendnp3/app/EventCells.h b/product/src/fes/include/libdnp3/opendnp3/app/EventCells.h new file mode 100644 index 00000000..7a8a6db8 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/EventCells.h @@ -0,0 +1,70 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_EVENTCELLS_H +#define OPENDNP3_EVENTCELLS_H + +#include "opendnp3/app/EventType.h" +#include "opendnp3/gen/PointClass.h" + +namespace opendnp3 +{ + +/// A null object for types that have no metadata +struct EmptyEventCell +{ +}; + +/// Base class for different types of event metadata +template struct EventCellBase +{ + PointClass clazz; + typename Spec::meas_t lastEvent; + typename Spec::event_variation_t evariation; + + void SetEventValue(const typename Spec::meas_t& value) + { + lastEvent = value; + } + +protected: + EventCellBase() : clazz(PointClass::Class1), lastEvent(), evariation(Spec::DefaultEventVariation) {} +}; + +/// Metatype w/o a deadband +template struct SimpleEventCell : EventCellBase +{ + bool IsEvent(const typename Spec::config_t& config, const typename Spec::meas_t& newValue) const + { + return Spec::IsEvent(this->lastEvent, newValue); + } +}; + +/// Structure for holding metadata information on points that have support deadbanding +template struct DeadbandEventCell : SimpleEventCell +{ + bool IsEvent(const typename Spec::config_t& config, const typename Spec::meas_t& newValue) const + { + return Spec::IsEvent(this->lastEvent, newValue, config.deadband); + } +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/EventTriggers.h b/product/src/fes/include/libdnp3/opendnp3/app/EventTriggers.h new file mode 100644 index 00000000..9d784059 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/EventTriggers.h @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_EVENTTRIGGERS_H +#define OPENDNP3_EVENTTRIGGERS_H + +#include "opendnp3/app/BaseMeasurementTypes.h" + +namespace opendnp3 +{ +namespace measurements +{ + template bool IsEvent(const T& val1, const T& val2, T deadband) + { + // T can be unsigned data type so std::abs won't work since it only directly supports signed data types + // If one uses std::abs and T is unsigned one will get an ambiguous override error. + + U diff = (val2 > val1) ? (static_cast(val2) - static_cast(val1)) + : (static_cast(val1) - static_cast(val2)); + + return diff > deadband; + } + + bool IsEvent(const TypedMeasurement& newMeas, const TypedMeasurement& oldMeas, double deadband); + +} // namespace measurements +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/EventType.h b/product/src/fes/include/libdnp3/opendnp3/app/EventType.h new file mode 100644 index 00000000..cd04afc9 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/EventType.h @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_EVENTTYPE_H +#define OPENDNP3_EVENTTYPE_H + +#include + +namespace opendnp3 +{ + +enum class EventType : uint16_t +{ + Binary = 0, + Analog = 1, + Counter = 2, + FrozenCounter = 3, + DoubleBitBinary = 4, + BinaryOutputStatus = 5, + AnalogOutputStatus = 6, + OctetString = 7 +}; + +enum class EventClass : uint8_t +{ + EC1 = 0, + EC2 = 1, + EC3 = 2 +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/Flags.h b/product/src/fes/include/libdnp3/opendnp3/app/Flags.h new file mode 100644 index 00000000..52336ad1 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/Flags.h @@ -0,0 +1,118 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_FLAGS_H +#define OPENDNP3_FLAGS_H + +#include "opendnp3/gen/AnalogOutputStatusQuality.h" +#include "opendnp3/gen/AnalogQuality.h" +#include "opendnp3/gen/BinaryOutputStatusQuality.h" +#include "opendnp3/gen/BinaryQuality.h" +#include "opendnp3/gen/CounterQuality.h" +#include "opendnp3/gen/DoubleBitBinaryQuality.h" +#include "opendnp3/gen/FrozenCounterQuality.h" + +namespace opendnp3 +{ + +/** + Measurement Flags +*/ +class Flags +{ +public: + Flags() : value(0) {} + + explicit Flags(uint8_t value) : value(value) {} + + inline bool IsSet(BinaryQuality flag) const + { + return IsSetAny(flag); + } + inline bool IsSet(DoubleBitBinaryQuality flag) const + { + return IsSetAny(flag); + } + inline bool IsSet(AnalogQuality flag) const + { + return IsSetAny(flag); + } + inline bool IsSet(CounterQuality flag) const + { + return IsSetAny(flag); + } + inline bool IsSet(FrozenCounterQuality flag) const + { + return IsSetAny(flag); + } + inline bool IsSet(BinaryOutputStatusQuality flag) const + { + return IsSetAny(flag); + } + inline bool IsSet(AnalogOutputStatusQuality flag) const + { + return IsSetAny(flag); + } + + inline void Set(BinaryQuality flag) + { + SetAny(flag); + } + inline void Set(DoubleBitBinaryQuality flag) + { + SetAny(flag); + } + inline void Set(AnalogQuality flag) + { + SetAny(flag); + } + inline void Set(CounterQuality flag) + { + SetAny(flag); + } + inline void Set(FrozenCounterQuality flag) + { + SetAny(flag); + } + inline void Set(BinaryOutputStatusQuality flag) + { + SetAny(flag); + } + inline void Set(AnalogOutputStatusQuality flag) + { + SetAny(flag); + } + + uint8_t value; + +protected: + template bool IsSetAny(T flag) const + { + return (value & static_cast(flag)) != 0; + } + + template void SetAny(T flag) + { + value |= static_cast(flag); + } +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/GroupVariationID.h b/product/src/fes/include/libdnp3/opendnp3/app/GroupVariationID.h new file mode 100644 index 00000000..1452a35d --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/GroupVariationID.h @@ -0,0 +1,41 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_GROUPVARIATIONID_H +#define OPENDNP3_GROUPVARIATIONID_H + +#include + +namespace opendnp3 +{ + +/// Simple uint8_t/uint8_t tuple for group and variation +struct GroupVariationID +{ + GroupVariationID() : group(0xFF), variation(0xFF) {} + + GroupVariationID(uint8_t aGroup, uint8_t aVariation) : group(aGroup), variation(aVariation) {} + + uint8_t group; + uint8_t variation; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/IINField.h b/product/src/fes/include/libdnp3/opendnp3/app/IINField.h new file mode 100644 index 00000000..f8e43897 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/IINField.h @@ -0,0 +1,191 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IINFIELD_H +#define OPENDNP3_IINFIELD_H + +#include + +namespace opendnp3 +{ + +enum class IINBit +{ + BROADCAST = 0, + CLASS1_EVENTS, + CLASS2_EVENTS, + CLASS3_EVENTS, + NEED_TIME, + LOCAL_CONTROL, + DEVICE_TROUBLE, + DEVICE_RESTART, + FUNC_NOT_SUPPORTED, + OBJECT_UNKNOWN, + PARAM_ERROR, + EVENT_BUFFER_OVERFLOW, + ALREADY_EXECUTING, + CONFIG_CORRUPT, + RESERVED1, + RESERVED2 = 15 +}; + +/** DNP3 two-byte IIN field. + */ +class IINField +{ + +private: + enum class LSBMask : uint8_t + { + BROADCAST = 0x01, + CLASS1_EVENTS = 0x02, + CLASS2_EVENTS = 0x04, + CLASS3_EVENTS = 0x08, + NEED_TIME = 0x10, + LOCAL_CONTROL = 0x20, + DEVICE_TROUBLE = 0x40, + DEVICE_RESTART = 0x80, + }; + + enum class MSBMask : uint8_t + { + FUNC_NOT_SUPPORTED = 0x01, + OBJECT_UNKNOWN = 0x02, + PARAM_ERROR = 0x04, + EVENT_BUFFER_OVERFLOW = 0x08, + ALREADY_EXECUTING = 0x10, + CONFIG_CORRUPT = 0x20, + RESERVED1 = 0x40, + RESERVED2 = 0x80, + + // special mask that indicates if there was any error processing a request + REQUEST_ERROR_MASK = FUNC_NOT_SUPPORTED | OBJECT_UNKNOWN | PARAM_ERROR + }; + +public: + static IINField Empty() + { + return IINField(0, 0); + } + + IINField(IINBit bit) : LSB(0), MSB(0) + { + this->SetBit(bit); + } + + IINField(uint8_t aLSB, uint8_t aMSB) : LSB(aLSB), MSB(aMSB) {} + + IINField() : LSB(0), MSB(0) {} + + bool IsSet(IINBit bit) const; + + bool IsClear(IINBit bit) const + { + return !IsSet(bit); + } + + void SetBit(IINBit bit); + void ClearBit(IINBit bit); + + void SetBitToValue(IINBit bit, bool value); + + bool operator==(const IINField& aRHS) const; + + bool Any() const + { + return (LSB | MSB) != 0; + } + + void Clear() + { + LSB = MSB = 0; + } + + bool HasRequestError() const + { + return Get(MSBMask::REQUEST_ERROR_MASK); + } + + IINField operator|(const IINField& aIIN) const + { + return IINField(LSB | aIIN.LSB, MSB | aIIN.MSB); + } + + IINField& operator|=(const IINField& aIIN) + { + MSB |= aIIN.MSB; + LSB |= aIIN.LSB; + return *this; + } + + IINField operator&(const IINField& aIIN) const + { + return IINField(LSB & aIIN.LSB, MSB & aIIN.MSB); + } + + IINField& operator&=(const IINField& aIIN) + { + MSB &= aIIN.MSB; + LSB &= aIIN.LSB; + return *this; + } + + IINField operator~() const + { + return IINField(~LSB, ~MSB); + } + + uint8_t LSB; + uint8_t MSB; + +private: + static const uint8_t REQUEST_ERROR_MASK; + + inline bool Get(LSBMask bit) const + { + return (LSB & static_cast(bit)) != 0; + } + + inline bool Get(MSBMask bit) const + { + return (MSB & static_cast(bit)) != 0; + } + + inline void Set(LSBMask bit) + { + LSB |= static_cast(bit); + } + inline void Set(MSBMask bit) + { + MSB |= static_cast(bit); + } + + inline void Clear(LSBMask bit) + { + LSB &= ~static_cast(bit); + } + inline void Clear(MSBMask bit) + { + MSB &= ~static_cast(bit); + } +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/Indexed.h b/product/src/fes/include/libdnp3/opendnp3/app/Indexed.h new file mode 100644 index 00000000..64438f74 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/Indexed.h @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_INDEXED_H +#define OPENDNP3_INDEXED_H + +#include + +namespace opendnp3 +{ + +/** + * A simple tuple for pairing Values with an index + */ +template class Indexed +{ +public: + Indexed(const T& value_, uint16_t index_) : value(value_), index(index_) {} + + Indexed() : value(), index(0) {} + + T value; + uint16_t index; +}; + +template Indexed WithIndex(const T& value, uint16_t index) +{ + return Indexed(value, index); +} + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/MeasurementInfo.h b/product/src/fes/include/libdnp3/opendnp3/app/MeasurementInfo.h new file mode 100644 index 00000000..70fc6e19 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/MeasurementInfo.h @@ -0,0 +1,166 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_MEASUREMENTINFO_H +#define OPENDNP3_MEASUREMENTINFO_H + +#include "opendnp3/app/EventType.h" +#include "opendnp3/app/MeasurementTypes.h" +#include "opendnp3/app/OctetString.h" +#include "opendnp3/gen/BinaryQuality.h" +#include "opendnp3/gen/EventAnalogOutputStatusVariation.h" +#include "opendnp3/gen/EventAnalogVariation.h" +#include "opendnp3/gen/EventBinaryOutputStatusVariation.h" +#include "opendnp3/gen/EventBinaryVariation.h" +#include "opendnp3/gen/EventCounterVariation.h" +#include "opendnp3/gen/EventDoubleBinaryVariation.h" +#include "opendnp3/gen/EventFrozenCounterVariation.h" +#include "opendnp3/gen/EventOctetStringVariation.h" +#include "opendnp3/gen/EventSecurityStatVariation.h" +#include "opendnp3/gen/StaticAnalogOutputStatusVariation.h" +#include "opendnp3/gen/StaticAnalogVariation.h" +#include "opendnp3/gen/StaticBinaryOutputStatusVariation.h" +#include "opendnp3/gen/StaticBinaryVariation.h" +#include "opendnp3/gen/StaticCounterVariation.h" +#include "opendnp3/gen/StaticDoubleBinaryVariation.h" +#include "opendnp3/gen/StaticFrozenCounterVariation.h" +#include "opendnp3/gen/StaticOctetStringVariation.h" +#include "opendnp3/gen/StaticSecurityStatVariation.h" +#include "opendnp3/gen/StaticTimeAndIntervalVariation.h" +#include "opendnp3/gen/StaticTypeBitmask.h" +#include "opendnp3/util/StaticOnly.h" + +namespace opendnp3 +{ + +struct BinaryInfo : private StaticOnly +{ + typedef Binary meas_t; + typedef bool value_t; + typedef EventBinaryVariation event_variation_t; + typedef StaticBinaryVariation static_variation_t; + + static const EventType EventTypeEnum; + static const StaticTypeBitmask StaticTypeEnum; + static const event_variation_t DefaultEventVariation; + static const static_variation_t DefaultStaticVariation; +}; + +struct DoubleBitBinaryInfo : private StaticOnly +{ + typedef DoubleBitBinary meas_t; + typedef DoubleBit value_t; + typedef EventDoubleBinaryVariation event_variation_t; + typedef StaticDoubleBinaryVariation static_variation_t; + + static const EventType EventTypeEnum; + static const StaticTypeBitmask StaticTypeEnum; + static const event_variation_t DefaultEventVariation; + static const static_variation_t DefaultStaticVariation; +}; + +struct BinaryOutputStatusInfo : private StaticOnly +{ + typedef BinaryOutputStatus meas_t; + typedef bool value_t; + typedef EventBinaryOutputStatusVariation event_variation_t; + typedef StaticBinaryOutputStatusVariation static_variation_t; + + static const EventType EventTypeEnum; + static const StaticTypeBitmask StaticTypeEnum; + static const event_variation_t DefaultEventVariation; + static const static_variation_t DefaultStaticVariation; +}; + +struct AnalogInfo : private StaticOnly +{ + typedef Analog meas_t; + typedef double value_t; + typedef EventAnalogVariation event_variation_t; + typedef StaticAnalogVariation static_variation_t; + + static const EventType EventTypeEnum; + static const StaticTypeBitmask StaticTypeEnum; + static const event_variation_t DefaultEventVariation; + static const static_variation_t DefaultStaticVariation; +}; + +struct CounterInfo : private StaticOnly +{ + typedef Counter meas_t; + typedef uint32_t value_t; + typedef EventCounterVariation event_variation_t; + typedef StaticCounterVariation static_variation_t; + + static const EventType EventTypeEnum; + static const StaticTypeBitmask StaticTypeEnum; + static const event_variation_t DefaultEventVariation; + static const static_variation_t DefaultStaticVariation; +}; + +struct FrozenCounterInfo : private StaticOnly +{ + typedef FrozenCounter meas_t; + typedef uint32_t value_t; + typedef EventFrozenCounterVariation event_variation_t; + typedef StaticFrozenCounterVariation static_variation_t; + + static const EventType EventTypeEnum; + static const StaticTypeBitmask StaticTypeEnum; + static const event_variation_t DefaultEventVariation; + static const static_variation_t DefaultStaticVariation; +}; + +struct AnalogOutputStatusInfo : private StaticOnly +{ + typedef AnalogOutputStatus meas_t; + typedef double value_t; + typedef EventAnalogOutputStatusVariation event_variation_t; + typedef StaticAnalogOutputStatusVariation static_variation_t; + + static const EventType EventTypeEnum; + static const StaticTypeBitmask StaticTypeEnum; + static const event_variation_t DefaultEventVariation; + static const static_variation_t DefaultStaticVariation; +}; + +struct OctetStringInfo : private StaticOnly +{ + typedef OctetString meas_t; + typedef EventOctetStringVariation event_variation_t; + typedef StaticOctetStringVariation static_variation_t; + + static const EventType EventTypeEnum; + static const StaticTypeBitmask StaticTypeEnum; + static const event_variation_t DefaultEventVariation; + static const static_variation_t DefaultStaticVariation; +}; + +struct TimeAndIntervalInfo : private StaticOnly +{ + typedef TimeAndInterval meas_t; + typedef StaticTimeAndIntervalVariation static_variation_t; + + static const StaticTypeBitmask StaticTypeEnum; + static const StaticTimeAndIntervalVariation DefaultStaticVariation; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/MeasurementTypes.h b/product/src/fes/include/libdnp3/opendnp3/app/MeasurementTypes.h new file mode 100644 index 00000000..ba065592 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/MeasurementTypes.h @@ -0,0 +1,186 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_MEASUREMENTTYPES_H +#define OPENDNP3_MEASUREMENTTYPES_H + +#include "opendnp3/app/BaseMeasurementTypes.h" +#include "opendnp3/gen/DoubleBit.h" +#include "opendnp3/gen/IntervalUnits.h" + +namespace opendnp3 +{ + +/** + The Binary data type is for describing on-off (boolean) type values. Good examples of + binaries are alarms, mode settings, enabled/disabled flags etc. Think of it as a status + LED on a piece of equipment. +*/ +class Binary : public TypedMeasurement +{ +public: + Binary(); + + explicit Binary(bool value); + + explicit Binary(Flags flags); + + Binary(Flags flags, DNPTime time); + + Binary(bool value, Flags flags); + + Binary(bool value, Flags flags, DNPTime time); +}; + +/** +The Double-bit Binary data type has two stable states, on and off, and an in transit state. Motor operated switches +or binary valves are good examples. +*/ +class DoubleBitBinary : public TypedMeasurement +{ +public: + DoubleBitBinary(); + + explicit DoubleBitBinary(DoubleBit value); + + explicit DoubleBitBinary(Flags flags); + + DoubleBitBinary(Flags flags, DNPTime time); + + DoubleBitBinary(DoubleBit value, Flags flags); + + DoubleBitBinary(DoubleBit value, Flags flags, DNPTime time); + +private: + static const uint8_t ValueMask = 0xC0; + static const uint8_t QualityMask = 0x3F; + + static DoubleBit GetValue(Flags flags); + + static Flags GetFlags(Flags flags, DoubleBit state); +}; + +/** + BinaryOutputStatus is used for describing the current state of a control. It is very infrequently + used and many masters don't provide any mechanisms for reading these values so their use is + strongly discouraged, a Binary should be used instead. +*/ +class BinaryOutputStatus : public TypedMeasurement +{ +public: + BinaryOutputStatus(); + + explicit BinaryOutputStatus(bool value); + + explicit BinaryOutputStatus(Flags flags); + + BinaryOutputStatus(Flags flags, DNPTime time); + + BinaryOutputStatus(bool value, Flags flags); + + BinaryOutputStatus(bool value, Flags flags, DNPTime time); +}; + +/** + Analogs are used for variable data points that usually reflect a real world value. + Good examples are current, voltage, sensor readouts, etc. Think of a speedometer guage. +*/ + +class Analog : public TypedMeasurement +{ +public: + Analog(); + + explicit Analog(double value); + + Analog(double value, Flags flags); + + Analog(double value, Flags flags, DNPTime time); +}; + +/** + Counters are used for describing generally increasing values (non-negative!). Good examples are + total power consumed, max voltage. Think odometer on a car. +*/ +class Counter : public TypedMeasurement +{ +public: + Counter(); + + explicit Counter(uint32_t value); + + Counter(uint32_t value, Flags flags); + + Counter(uint32_t value, Flags flags, DNPTime time); +}; + +/** + Frozen counters are used to report the value of a counter point captured at the instant when the count is frozen. +*/ +class FrozenCounter : public TypedMeasurement +{ +public: + FrozenCounter(); + + explicit FrozenCounter(uint32_t value); + + FrozenCounter(uint32_t value, Flags flags); + + FrozenCounter(uint32_t value, Flags flags, DNPTime time); +}; + +/** + Describes the last set value of the set-point. Like the BinaryOutputStatus data type it is not + well supported and its generally better practice to use an explicit analog. +*/ +class AnalogOutputStatus : public TypedMeasurement +{ +public: + AnalogOutputStatus(); + + explicit AnalogOutputStatus(double value); + + AnalogOutputStatus(double value, Flags flags); + + AnalogOutputStatus(double value, Flags flags, DNPTime time); +}; + +/** + Maps to Group50Var4 + This class is a bit of an outlier as an indexed type and is really only used in the DNP3 PV profile +*/ +class TimeAndInterval +{ +public: + TimeAndInterval(); + + TimeAndInterval(DNPTime time, uint32_t interval, uint8_t units); + + TimeAndInterval(DNPTime time, uint32_t interval, IntervalUnits units); + + IntervalUnits GetUnitsEnum() const; + + DNPTime time; + uint32_t interval; + uint8_t units; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/OctetData.h b/product/src/fes/include/libdnp3/opendnp3/app/OctetData.h new file mode 100644 index 00000000..05b15211 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/OctetData.h @@ -0,0 +1,110 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_OCTETDATA_H +#define OPENDNP3_OCTETDATA_H + +#include "opendnp3/util/Buffer.h" + +#include +#include + +namespace opendnp3 +{ + +/** + * A base-class for bitstrings containing up to 255 bytes + */ +class OctetData +{ +public: + const static uint8_t MAX_SIZE = 255; + + /** + * Construct with a default value of [0x00] (length == 1) + */ + OctetData(); + + /** + * Construct from a c-style string + * + * strlen() is used internally to determine the length + * + * If the length is 0, the default value of [0x00] is assigned + * If the length is > 255, only the first 255 bytes are copied. + * + * The null terminator is NOT copied as part of buffer + */ + OctetData(const char* input); + + /** + * Construct from read-only buffer slice + * + * + * If the length is 0, the default value of [0x00] is assigned + * If the length is > 255, only the first 255 bytes are copied. + * + * The null terminator is NOT copied as part of buffer + */ + OctetData(const Buffer& input); + + inline uint8_t Size() const + { + return size; + } + + /** + * Set the octet data to the input buffer + * + * If the length is 0, the default value of [0x00] is assigned + * If the length is > 255, only the first 255 bytes are copied + * + * @param input the input data to copy into this object + * + * @return true if the input meets the length requirements, false otherwise + */ + bool Set(const Buffer& input); + + /** + * Set the buffer equal to the supplied c-string + * + * If the length is 0, the default value of [0x00] is assigned + * If the length is > 255, only the first 255 bytes are copied + * + * @param input c-style string to copy into this object + * + * @return true if the input meets the length requirements, false otherwise + */ + bool Set(const char* input); + + /** + * @return a view of the current data + */ + const Buffer ToBuffer() const; + +private: + static const Buffer ToSlice(const char* input); + + std::array buffer = {{0x00}}; + uint8_t size; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/OctetString.h b/product/src/fes/include/libdnp3/opendnp3/app/OctetString.h new file mode 100644 index 00000000..f0d8628d --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/OctetString.h @@ -0,0 +1,62 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_OCTETSTRING_H +#define OPENDNP3_OCTETSTRING_H + +#include "opendnp3/app/OctetData.h" + +namespace opendnp3 +{ + +/** + * Respresents group 110/111 objects + */ +class OctetString : public OctetData +{ +public: + /** + * Construct with a default value of [0x00] (length == 1) + */ + OctetString() : OctetData() {} + + /** + * Construct from a c-style string + * + * strlen() is used internally to determine the length + * + * If the length is 0, the default value of [0x00] is assigned + * If the length is > 255, only the first 255 bytes are copied + * + * The null terminator is NOT copied as part of buffer + */ + OctetString(const char* input) : OctetData(input) {} + + /** + * Construct from read-only buffer slice + * + * If the length is 0, the default value of [0x00] is assigned + * If the length is > 255, only the first 255 bytes are copied + */ + OctetString(const Buffer& buffer) : OctetData(buffer) {} +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/app/parsing/ICollection.h b/product/src/fes/include/libdnp3/opendnp3/app/parsing/ICollection.h new file mode 100644 index 00000000..86287410 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/app/parsing/ICollection.h @@ -0,0 +1,104 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ICOLLECTION_H +#define OPENDNP3_ICOLLECTION_H + +#include + +namespace opendnp3 +{ + +/** + * Abstract way of visiting elements of a collection + * + */ +template class IVisitor +{ +public: + virtual void OnValue(const T& value) = 0; +}; + +/** + * A visitor implemented as an abstract functor + * + */ +template class FunctorVisitor : public IVisitor +{ + +public: + FunctorVisitor(const Fun& fun_) : fun(fun_) {} + + virtual void OnValue(const T& value) override final + { + fun(value); + } + +private: + Fun fun; +}; + +/** + * An interface representing an abstract immutable collection of things of type T. + * + * The user can only read these values via callback to receive each element. + */ +template class ICollection +{ +public: + /** + * The number of elements in the collection + */ + virtual size_t Count() const = 0; + + /** + * Visit all the elements of a collection + */ + virtual void Foreach(IVisitor& visitor) const = 0; + + /** + visit all of the elements of a collection + */ + template void ForeachItem(const Fun& fun) const + { + FunctorVisitor visitor(fun); + this->Foreach(visitor); + } + + /** + Retrieve the only value from the collection. + */ + bool ReadOnlyValue(T& value) const + { + if (this->Count() == 1) + { + auto assignValue = [&value](const T& item) { value = item; }; + this->ForeachItem(assignValue); + return true; + } + else + { + return false; + } + } +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/channel/ChannelRetry.h b/product/src/fes/include/libdnp3/opendnp3/channel/ChannelRetry.h new file mode 100644 index 00000000..6065d9dc --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/channel/ChannelRetry.h @@ -0,0 +1,67 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_CHANNEL_RETRY_H +#define OPENDNP3_CHANNEL_RETRY_H + +#include "opendnp3/channel/IOpenDelayStrategy.h" +#include "opendnp3/util/TimeDuration.h" + +namespace opendnp3 +{ + +/// Class used to configure how channel failures are retried +class ChannelRetry +{ + +public: + /* + * Construct a channel retry config class + * + * @param minOpenRetry minimum connection retry interval on failure + * @param maxOpenRetry maximum connection retry interval on failure + */ + ChannelRetry(TimeDuration minOpenRetry, + TimeDuration maxOpenRetry, + TimeDuration reconnectDelay = TimeDuration::Zero(), + IOpenDelayStrategy& strategy = ExponentialBackoffStrategy::Instance()); + + /// Return the default configuration of exponential backoff from 1 sec to 1 minute + static ChannelRetry Default(); + + /// minimum connection retry interval on failure + TimeDuration minOpenRetry; + /// maximum connection retry interval on failure + TimeDuration maxOpenRetry; + /// reconnect delay (defaults to zero) + TimeDuration reconnectDelay; + + TimeDuration NextDelay(const TimeDuration& current) const + { + return strategy.GetNextDelay(current, maxOpenRetry); + } + +private: + //// Strategy to use (default to exponential backoff) + IOpenDelayStrategy& strategy; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/channel/IChannel.h b/product/src/fes/include/libdnp3/opendnp3/channel/IChannel.h new file mode 100644 index 00000000..317672bf --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/channel/IChannel.h @@ -0,0 +1,98 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ICHANNEL_H +#define OPENDNP3_ICHANNEL_H + +#include "opendnp3/IResource.h" +#include "opendnp3/gen/ChannelState.h" +#include "opendnp3/link/LinkStatistics.h" +#include "opendnp3/logging/LogLevels.h" +#include "opendnp3/master/IMaster.h" +#include "opendnp3/master/IMasterApplication.h" +#include "opendnp3/master/ISOEHandler.h" +#include "opendnp3/master/MasterStackConfig.h" +#include "opendnp3/outstation/ICommandHandler.h" +#include "opendnp3/outstation/IOutstation.h" +#include "opendnp3/outstation/IOutstationApplication.h" +#include "opendnp3/outstation/OutstationStackConfig.h" + +#include + +namespace opendnp3 +{ + +/** + * Represents a communication channel upon which masters and outstations can be bound. + */ +class IChannel : public IResource +{ +public: + virtual ~IChannel() {} + + /** + * Synchronously read the channel statistics + */ + virtual LinkStatistics GetStatistics() = 0; + + /** + * @return The current logger settings for this channel + */ + virtual opendnp3::LogLevels GetLogFilters() const = 0; + + /** + * @param filters Adjust the filters to this value + */ + virtual void SetLogFilters(const opendnp3::LogLevels& filters) = 0; + + /** + * Add a master to the channel + * + * @param id An ID that gets used for logging + * @param SOEHandler Callback object for all received measurements + * @param application The master application bound to the master session + * @param config Configuration object that controls how the master behaves + * + * @return shared_ptr to the running master + */ + virtual std::shared_ptr AddMaster(const std::string& id, + std::shared_ptr SOEHandler, + std::shared_ptr application, + const MasterStackConfig& config) + = 0; + + /** + * Add an outstation to the channel + * + * @param id An ID that gets used for logging + * @param commandHandler Callback object for handling command requests + * @param application Callback object for user code + * @param config Configuration object that controls how the outstation behaves + * @return shared_ptr to the running outstation + */ + virtual std::shared_ptr AddOutstation(const std::string& id, + std::shared_ptr commandHandler, + std::shared_ptr application, + const OutstationStackConfig& config) + = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/channel/IChannelListener.h b/product/src/fes/include/libdnp3/opendnp3/channel/IChannelListener.h new file mode 100644 index 00000000..e75defc1 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/channel/IChannelListener.h @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ICHANNELLISTENER_H +#define OPENDNP3_ICHANNELLISTENER_H + +#include "opendnp3/gen/ChannelState.h" + +namespace opendnp3 +{ + +/** + * Callback interface for receiving information about a running channel + */ +class IChannelListener +{ +public: + virtual ~IChannelListener() {} + + /* + * Receive callbacks for state transitions on the channels executor + */ + virtual void OnStateChange(ChannelState state) = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/channel/IListener.h b/product/src/fes/include/libdnp3/opendnp3/channel/IListener.h new file mode 100644 index 00000000..6d9dad42 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/channel/IListener.h @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ILISTENER_H +#define OPENDNP3_ILISTENER_H + +#include "opendnp3/IResource.h" + +namespace opendnp3 +{ + +/** + * Represents a running TCP or TLS listener that can be shutdown + * so that no new connections are accepted. + */ +class IListener : public IResource +{ +public: + virtual ~IListener() {} +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/channel/IOpenDelayStrategy.h b/product/src/fes/include/libdnp3/opendnp3/channel/IOpenDelayStrategy.h new file mode 100644 index 00000000..e3979376 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/channel/IOpenDelayStrategy.h @@ -0,0 +1,59 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IOPENDELAYSTRATEGY_H +#define OPENDNP3_IOPENDELAYSTRATEGY_H + +#include "opendnp3/util/TimeDuration.h" +#include "opendnp3/util/Uncopyable.h" + +namespace opendnp3 +{ + +/** + * A strategy interface for controlling how connection are retried + */ +class IOpenDelayStrategy +{ + +public: + virtual ~IOpenDelayStrategy() {} + + /** + * The the next delay based on the current and the maximum. + */ + virtual TimeDuration GetNextDelay(const TimeDuration& current, const TimeDuration& max) const = 0; +}; + +/** + * Implements IOpenDelayStrategy using exponential-backoff. + */ +class ExponentialBackoffStrategy final : public IOpenDelayStrategy, private Uncopyable +{ + static ExponentialBackoffStrategy instance; + +public: + static IOpenDelayStrategy& Instance(); + + TimeDuration GetNextDelay(const TimeDuration& current, const TimeDuration& max) const final; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/channel/IPEndpoint.h b/product/src/fes/include/libdnp3/opendnp3/channel/IPEndpoint.h new file mode 100644 index 00000000..2cd551ca --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/channel/IPEndpoint.h @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IPENDPOINT_H +#define OPENDNP3_IPENDPOINT_H + +#include +#include + +namespace opendnp3 +{ + +struct IPEndpoint +{ + IPEndpoint(const std::string& address, uint16_t port) : address(address), port(port) {} + + static IPEndpoint AllAdapters(uint16_t port) + { + return IPEndpoint("0.0.0.0", port); + } + + static IPEndpoint Localhost(uint16_t port) + { + return IPEndpoint("127.0.0.1", port); + } + + std::string address; + uint16_t port; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/channel/PrintingChannelListener.h b/product/src/fes/include/libdnp3/opendnp3/channel/PrintingChannelListener.h new file mode 100644 index 00000000..154c175a --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/channel/PrintingChannelListener.h @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_PRINTINGCHANNELLISTENER_H +#define OPENDNP3_PRINTINGCHANNELLISTENER_H + +#include "opendnp3/channel/IChannelListener.h" +#include "opendnp3/util/Uncopyable.h" + +#include +#include + +namespace opendnp3 +{ + +/** + * Callback interface for receiving information about a running channel + */ +class PrintingChannelListener final : public IChannelListener, private Uncopyable +{ +public: + virtual void OnStateChange(ChannelState state) override + { + std::cout << "channel state change: " << ChannelStateSpec::to_human_string(state) << std::endl; + } + + static std::shared_ptr Create() + { + return std::make_shared(); + } + + PrintingChannelListener() {} +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/channel/SerialSettings.h b/product/src/fes/include/libdnp3/opendnp3/channel/SerialSettings.h new file mode 100644 index 00000000..cf395770 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/channel/SerialSettings.h @@ -0,0 +1,72 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_SERIALTYPES_H +#define OPENDNP3_SERIALTYPES_H + +#include "opendnp3/gen/FlowControl.h" +#include "opendnp3/gen/Parity.h" +#include "opendnp3/gen/StopBits.h" +#include "opendnp3/util/TimeDuration.h" + +#include + +namespace opendnp3 +{ + +/// Settings structure for the serial port +struct SerialSettings +{ + + /// Defaults to the familiar 9600 8/N/1, no flow control + SerialSettings() + : baud(9600), + dataBits(8), + stopBits(StopBits::One), + parity(Parity::None), + flowType(FlowControl::None), + asyncOpenDelay(TimeDuration::Milliseconds(500)) + { + } + + /// name of the port, i.e. "COM1" or "/dev/tty0" + std::string deviceName; + + /// Baud rate of the port, i.e. 9600 or 57600 + int baud; + + /// Data bits, usually 8 + int dataBits; + + /// Stop bits, usually set to 1 + StopBits stopBits; + + /// Parity setting for the port, usually PAR_NONE + Parity parity; + + /// Flow control setting, usually FLOW_NONE + FlowControl flowType; + + /// Some physical layers need time to "settle" so that the first tx isn't lost + TimeDuration asyncOpenDelay; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/channel/TLSConfig.h b/product/src/fes/include/libdnp3/opendnp3/channel/TLSConfig.h new file mode 100644 index 00000000..786fbec8 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/channel/TLSConfig.h @@ -0,0 +1,100 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OPENDNP3_TLS_CONFIG_H +#define OPENDNP3_TLS_CONFIG_H + +#include + +namespace opendnp3 +{ + +/** + * TLS configuration information + */ +struct TLSConfig +{ + /** + * Construct a TLS configuration + * + * @param peerCertFilePath Certificate file used to verify the peer or server. Can be CA file or a self-signed cert + * provided by other party. + * @param localCertFilePath File that contains the certificate (or certificate chain) that will be presented to the + * remote side of the connection + * @param privateKeyFilePath File that contains the private key corresponding to the local certificate + * @param allowTLSv10 Allow TLS version 1.0 (default false) + * @param allowTLSv11 Allow TLS version 1.1 (default false) + * @param allowTLSv12 Allow TLS version 1.2 (default true) + * @param allowTLSv13 Allow TLS version 1.3 (default true) + * @param cipherList The openssl cipher-list, defaults to "" which does not modify the default cipher list + * + * localCertFilePath and privateKeyFilePath can optionally be the same file, i.e. a PEM that contains both pieces of + * data. + * + */ + TLSConfig(const std::string& peerCertFilePath, + const std::string& localCertFilePath, + const std::string& privateKeyFilePath, + bool allowTLSv10 = false, + bool allowTLSv11 = false, + bool allowTLSv12 = true, + bool allowTLSv13 = true, + const std::string& cipherList = "") + : peerCertFilePath(peerCertFilePath), + localCertFilePath(localCertFilePath), + privateKeyFilePath(privateKeyFilePath), + allowTLSv10(allowTLSv10), + allowTLSv11(allowTLSv11), + allowTLSv12(allowTLSv12), + allowTLSv13(allowTLSv13), + cipherList(cipherList) + { + } + + /// Certificate file used to verify the peer or server. Can be CA file or a self-signed cert provided by other + /// party. + std::string peerCertFilePath; + + /// File that contains the certificate (or certificate chain) that will be presented to the remote side of the + /// connection + std::string localCertFilePath; + + /// File that contains the private key corresponding to the local certificate + std::string privateKeyFilePath; + + /// Allow TLS version 1.0 (default false) + bool allowTLSv10; + + /// Allow TLS version 1.1 (default false) + bool allowTLSv11; + + /// Allow TLS version 1.2 (default true) + bool allowTLSv12; + + /// Allow TLS version 1.3 (default true) + bool allowTLSv13; + + /// openssl format cipher list + std::string cipherList; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/decoder/Decoder.h b/product/src/fes/include/libdnp3/opendnp3/decoder/Decoder.h new file mode 100644 index 00000000..d5157423 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/decoder/Decoder.h @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_DECODER_H +#define OPENDNP3_DECODER_H + +#include "opendnp3/decoder/IDecoderCallbacks.h" +#include "opendnp3/logging/Logger.h" +#include "opendnp3/util/Buffer.h" + +namespace opendnp3 +{ + +class DecoderImpl; + +// stand-alone DNP3 decoder +class Decoder +{ +public: + Decoder(IDecoderCallbacks& callbacks, const Logger& logger); + ~Decoder(); + + void DecodeLPDU(const Buffer& data); + void DecodeTPDU(const Buffer& data); + void DecodeAPDU(const Buffer& data); + +private: + DecoderImpl* impl; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/decoder/IDecoderCallbacks.h b/product/src/fes/include/libdnp3/opendnp3/decoder/IDecoderCallbacks.h new file mode 100644 index 00000000..db7c5f35 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/decoder/IDecoderCallbacks.h @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IDECODERCALLBACKS_H +#define OPENDNP3_IDECODERCALLBACKS_H + +#include "opendnp3/util/Uncopyable.h" + +namespace opendnp3 +{ + +class IDecoderCallbacks : Uncopyable +{ + friend class Indent; + +protected: + virtual void PushIndent(){}; + virtual void PopIndent(){}; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/AnalogOutputStatusQuality.h b/product/src/fes/include/libdnp3/opendnp3/gen/AnalogOutputStatusQuality.h new file mode 100644 index 00000000..472843ba --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/AnalogOutputStatusQuality.h @@ -0,0 +1,76 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_ANALOGOUTPUTSTATUSQUALITY_H +#define OPENDNP3_ANALOGOUTPUTSTATUSQUALITY_H + +#include +#include + +namespace opendnp3 { + +/** + Quality field bitmask for analog output status values +*/ +enum class AnalogOutputStatusQuality : uint8_t +{ + /// set when the data is "good", meaning that rest of the system can trust the value + ONLINE = 0x1, + /// the quality all points get before we have established communication (or populated) the point + RESTART = 0x2, + /// set if communication has been lost with the source of the data (after establishing contact) + COMM_LOST = 0x4, + /// set if the value is being forced to a "fake" value somewhere in the system + REMOTE_FORCED = 0x8, + /// set if the value is being forced to a "fake" value on the original device + LOCAL_FORCED = 0x10, + /// set if a hardware input etc. is out of range and we are using a place holder value + OVERRANGE = 0x20, + /// set if calibration or reference voltage has been lost meaning readings are questionable + REFERENCE_ERR = 0x40, + /// reserved bit + RESERVED = 0x80 +}; + +struct AnalogOutputStatusQualitySpec +{ + using enum_type_t = AnalogOutputStatusQuality; + + static uint8_t to_type(AnalogOutputStatusQuality arg); + static AnalogOutputStatusQuality from_type(uint8_t arg); + static char const* to_string(AnalogOutputStatusQuality arg); + static char const* to_human_string(AnalogOutputStatusQuality arg); + static AnalogOutputStatusQuality from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/AnalogQuality.h b/product/src/fes/include/libdnp3/opendnp3/gen/AnalogQuality.h new file mode 100644 index 00000000..f4b7a2b9 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/AnalogQuality.h @@ -0,0 +1,76 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_ANALOGQUALITY_H +#define OPENDNP3_ANALOGQUALITY_H + +#include +#include + +namespace opendnp3 { + +/** + Quality field bitmask for analog values +*/ +enum class AnalogQuality : uint8_t +{ + /// set when the data is "good", meaning that rest of the system can trust the value + ONLINE = 0x1, + /// the quality all points get before we have established communication (or populated) the point + RESTART = 0x2, + /// set if communication has been lost with the source of the data (after establishing contact) + COMM_LOST = 0x4, + /// set if the value is being forced to a "fake" value somewhere in the system + REMOTE_FORCED = 0x8, + /// set if the value is being forced to a "fake" value on the original device + LOCAL_FORCED = 0x10, + /// set if a hardware input etc. is out of range and we are using a place holder value + OVERRANGE = 0x20, + /// set if calibration or reference voltage has been lost meaning readings are questionable + REFERENCE_ERR = 0x40, + /// reserved bit + RESERVED = 0x80 +}; + +struct AnalogQualitySpec +{ + using enum_type_t = AnalogQuality; + + static uint8_t to_type(AnalogQuality arg); + static AnalogQuality from_type(uint8_t arg); + static char const* to_string(AnalogQuality arg); + static char const* to_human_string(AnalogQuality arg); + static AnalogQuality from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/AssignClassType.h b/product/src/fes/include/libdnp3/opendnp3/gen/AssignClassType.h new file mode 100644 index 00000000..1566de97 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/AssignClassType.h @@ -0,0 +1,67 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_ASSIGNCLASSTYPE_H +#define OPENDNP3_ASSIGNCLASSTYPE_H + +#include +#include + +namespace opendnp3 { + +/** + groups that can be used inconjunction with the ASSIGN_CLASS function code +*/ +enum class AssignClassType : uint8_t +{ + BinaryInput = 0x0, + DoubleBinaryInput = 0x1, + Counter = 0x2, + FrozenCounter = 0x3, + AnalogInput = 0x4, + BinaryOutputStatus = 0x5, + AnalogOutputStatus = 0x6 +}; + +struct AssignClassTypeSpec +{ + using enum_type_t = AssignClassType; + + static uint8_t to_type(AssignClassType arg); + static AssignClassType from_type(uint8_t arg); + static char const* to_string(AssignClassType arg); + static char const* to_human_string(AssignClassType arg); + static AssignClassType from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/Attributes.h b/product/src/fes/include/libdnp3/opendnp3/gen/Attributes.h new file mode 100644 index 00000000..641903dd --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/Attributes.h @@ -0,0 +1,46 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_ATTRIBUTES_H +#define OPENDNP3_ATTRIBUTES_H + +#include "opendnp3/gen/GroupVariation.h" + +namespace opendnp3 { + +bool HasAbsoluteTime(GroupVariation gv); +bool HasRelativeTime(GroupVariation gv); +bool HasFlags(GroupVariation gv); +bool IsEvent(GroupVariation gv); + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/BinaryOutputStatusQuality.h b/product/src/fes/include/libdnp3/opendnp3/gen/BinaryOutputStatusQuality.h new file mode 100644 index 00000000..b9702572 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/BinaryOutputStatusQuality.h @@ -0,0 +1,76 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_BINARYOUTPUTSTATUSQUALITY_H +#define OPENDNP3_BINARYOUTPUTSTATUSQUALITY_H + +#include +#include + +namespace opendnp3 { + +/** + Quality field bitmask for binary output status values +*/ +enum class BinaryOutputStatusQuality : uint8_t +{ + /// set when the data is "good", meaning that rest of the system can trust the value + ONLINE = 0x1, + /// the quality all points get before we have established communication (or populated) the point + RESTART = 0x2, + /// set if communication has been lost with the source of the data (after establishing contact) + COMM_LOST = 0x4, + /// set if the value is being forced to a "fake" value somewhere in the system + REMOTE_FORCED = 0x8, + /// set if the value is being forced to a "fake" value on the original device + LOCAL_FORCED = 0x10, + /// reserved bit 1 + RESERVED1 = 0x20, + /// reserved bit 2 + RESERVED2 = 0x40, + /// state bit + STATE = 0x80 +}; + +struct BinaryOutputStatusQualitySpec +{ + using enum_type_t = BinaryOutputStatusQuality; + + static uint8_t to_type(BinaryOutputStatusQuality arg); + static BinaryOutputStatusQuality from_type(uint8_t arg); + static char const* to_string(BinaryOutputStatusQuality arg); + static char const* to_human_string(BinaryOutputStatusQuality arg); + static BinaryOutputStatusQuality from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/BinaryQuality.h b/product/src/fes/include/libdnp3/opendnp3/gen/BinaryQuality.h new file mode 100644 index 00000000..ef07a4d4 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/BinaryQuality.h @@ -0,0 +1,76 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_BINARYQUALITY_H +#define OPENDNP3_BINARYQUALITY_H + +#include +#include + +namespace opendnp3 { + +/** + Quality field bitmask for binary values +*/ +enum class BinaryQuality : uint8_t +{ + /// set when the data is "good", meaning that rest of the system can trust the value + ONLINE = 0x1, + /// the quality all points get before we have established communication (or populated) the point + RESTART = 0x2, + /// set if communication has been lost with the source of the data (after establishing contact) + COMM_LOST = 0x4, + /// set if the value is being forced to a "fake" value somewhere in the system + REMOTE_FORCED = 0x8, + /// set if the value is being forced to a "fake" value on the original device + LOCAL_FORCED = 0x10, + /// set if the value is oscillating very quickly and some events are being suppressed + CHATTER_FILTER = 0x20, + /// reserved bit + RESERVED = 0x40, + /// state bit + STATE = 0x80 +}; + +struct BinaryQualitySpec +{ + using enum_type_t = BinaryQuality; + + static uint8_t to_type(BinaryQuality arg); + static BinaryQuality from_type(uint8_t arg); + static char const* to_string(BinaryQuality arg); + static char const* to_human_string(BinaryQuality arg); + static BinaryQuality from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/ChannelState.h b/product/src/fes/include/libdnp3/opendnp3/gen/ChannelState.h new file mode 100644 index 00000000..ac2d09f1 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/ChannelState.h @@ -0,0 +1,68 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_CHANNELSTATE_H +#define OPENDNP3_CHANNELSTATE_H + +#include +#include + +namespace opendnp3 { + +/** + Enumeration for possible states of a channel +*/ +enum class ChannelState : uint8_t +{ + /// offline and idle + CLOSED = 0, + /// trying to open + OPENING = 1, + /// open + OPEN = 2, + /// stopped and will never do anything again + SHUTDOWN = 3 +}; + +struct ChannelStateSpec +{ + using enum_type_t = ChannelState; + + static uint8_t to_type(ChannelState arg); + static ChannelState from_type(uint8_t arg); + static char const* to_string(ChannelState arg); + static char const* to_human_string(ChannelState arg); + static ChannelState from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/CommandPointState.h b/product/src/fes/include/libdnp3/opendnp3/gen/CommandPointState.h new file mode 100644 index 00000000..2ccd15b2 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/CommandPointState.h @@ -0,0 +1,72 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_COMMANDPOINTSTATE_H +#define OPENDNP3_COMMANDPOINTSTATE_H + +#include +#include + +namespace opendnp3 { + +/** + List the various states that an individual command object can be in after an SBO or direct operate request +*/ +enum class CommandPointState : uint8_t +{ + /// No corresponding response was ever received for this command point + INIT = 0, + /// A response to a select request was received and matched, but the operate did not complete + SELECT_SUCCESS = 1, + /// A response to a select operation did not contain the same value that was sent + SELECT_MISMATCH = 2, + /// A response to a select operation contained a command status other than success + SELECT_FAIL = 3, + /// A response to an operate or direct operate did not match the request + OPERATE_FAIL = 4, + /// A matching response was received to the operate + SUCCESS = 5 +}; + +struct CommandPointStateSpec +{ + using enum_type_t = CommandPointState; + + static uint8_t to_type(CommandPointState arg); + static CommandPointState from_type(uint8_t arg); + static char const* to_string(CommandPointState arg); + static char const* to_human_string(CommandPointState arg); + static CommandPointState from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/CommandStatus.h b/product/src/fes/include/libdnp3/opendnp3/gen/CommandStatus.h new file mode 100644 index 00000000..a5e9375d --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/CommandStatus.h @@ -0,0 +1,103 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_COMMANDSTATUS_H +#define OPENDNP3_COMMANDSTATUS_H + +#include +#include + +namespace opendnp3 { + +/** + An enumeration of result codes received from an outstation in response to command request. + These correspond to those defined in the DNP3 standard +*/ +enum class CommandStatus : uint8_t +{ + /// command was accepted, initiated, or queued + SUCCESS = 0, + /// command timed out before completing + TIMEOUT = 1, + /// command requires being selected before operate, configuration issue + NO_SELECT = 2, + /// bad control code or timing values + FORMAT_ERROR = 3, + /// command is not implemented + NOT_SUPPORTED = 4, + /// command is all ready in progress or its all ready in that mode + ALREADY_ACTIVE = 5, + /// something is stopping the command, often a local/remote interlock + HARDWARE_ERROR = 6, + /// the function governed by the control is in local only control + LOCAL = 7, + /// the command has been done too often and has been throttled + TOO_MANY_OPS = 8, + /// the command was rejected because the device denied it or an RTU intercepted it + NOT_AUTHORIZED = 9, + /// command not accepted because it was prevented or inhibited by a local automation process, such as interlocking logic or synchrocheck + AUTOMATION_INHIBIT = 10, + /// command not accepted because the device cannot process any more activities than are presently in progress + PROCESSING_LIMITED = 11, + /// command not accepted because the value is outside the acceptable range permitted for this point + OUT_OF_RANGE = 12, + /// command not accepted because the outstation is forwarding the request to another downstream device which reported LOCAL + DOWNSTREAM_LOCAL = 13, + /// command not accepted because the outstation has already completed the requested operation + ALREADY_COMPLETE = 14, + /// command not accepted because the requested function is specifically blocked at the outstation + BLOCKED = 15, + /// command not accepted because the operation was cancelled + CANCELLED = 16, + /// command not accepted because another master is communicating with the outstation and has exclusive rights to operate this control point + BLOCKED_OTHER_MASTER = 17, + /// command not accepted because the outstation is forwarding the request to another downstream device which cannot be reached or is otherwise incapable of performing the request + DOWNSTREAM_FAIL = 18, + /// (deprecated) indicates the outstation shall not issue or perform the control operation + NON_PARTICIPATING = 126, + /// 10 to 126 are currently reserved + UNDEFINED = 127 +}; + +struct CommandStatusSpec +{ + using enum_type_t = CommandStatus; + + static uint8_t to_type(CommandStatus arg); + static CommandStatus from_type(uint8_t arg); + static char const* to_string(CommandStatus arg); + static char const* to_human_string(CommandStatus arg); + static CommandStatus from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/CounterQuality.h b/product/src/fes/include/libdnp3/opendnp3/gen/CounterQuality.h new file mode 100644 index 00000000..cff44ac1 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/CounterQuality.h @@ -0,0 +1,76 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_COUNTERQUALITY_H +#define OPENDNP3_COUNTERQUALITY_H + +#include +#include + +namespace opendnp3 { + +/** + Quality field bitmask for counter values +*/ +enum class CounterQuality : uint8_t +{ + /// set when the data is "good", meaning that rest of the system can trust the value + ONLINE = 0x1, + /// the quality all points get before we have established communication (or populated) the point + RESTART = 0x2, + /// set if communication has been lost with the source of the data (after establishing contact) + COMM_LOST = 0x4, + /// set if the value is being forced to a "fake" value somewhere in the system + REMOTE_FORCED = 0x8, + /// set if the value is being forced to a "fake" value on the original device + LOCAL_FORCED = 0x10, + /// Deprecated flag that indicates value has rolled over + ROLLOVER = 0x20, + /// indicates an unusual change in value + DISCONTINUITY = 0x40, + /// reserved bit + RESERVED = 0x80 +}; + +struct CounterQualitySpec +{ + using enum_type_t = CounterQuality; + + static uint8_t to_type(CounterQuality arg); + static CounterQuality from_type(uint8_t arg); + static char const* to_string(CounterQuality arg); + static char const* to_human_string(CounterQuality arg); + static CounterQuality from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/DoubleBit.h b/product/src/fes/include/libdnp3/opendnp3/gen/DoubleBit.h new file mode 100644 index 00000000..c1b31b04 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/DoubleBit.h @@ -0,0 +1,68 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_DOUBLEBIT_H +#define OPENDNP3_DOUBLEBIT_H + +#include +#include + +namespace opendnp3 { + +/** + Enumeration for possible states of a double bit value +*/ +enum class DoubleBit : uint8_t +{ + /// Transitioning between end conditions + INTERMEDIATE = 0x0, + /// End condition, determined to be OFF + DETERMINED_OFF = 0x1, + /// End condition, determined to be ON + DETERMINED_ON = 0x2, + /// Abnormal or custom condition + INDETERMINATE = 0x3 +}; + +struct DoubleBitSpec +{ + using enum_type_t = DoubleBit; + + static uint8_t to_type(DoubleBit arg); + static DoubleBit from_type(uint8_t arg); + static char const* to_string(DoubleBit arg); + static char const* to_human_string(DoubleBit arg); + static DoubleBit from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/DoubleBitBinaryQuality.h b/product/src/fes/include/libdnp3/opendnp3/gen/DoubleBitBinaryQuality.h new file mode 100644 index 00000000..5e74ae09 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/DoubleBitBinaryQuality.h @@ -0,0 +1,76 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_DOUBLEBITBINARYQUALITY_H +#define OPENDNP3_DOUBLEBITBINARYQUALITY_H + +#include +#include + +namespace opendnp3 { + +/** + Quality field bitmask for double bit binary values +*/ +enum class DoubleBitBinaryQuality : uint8_t +{ + /// set when the data is "good", meaning that rest of the system can trust the value + ONLINE = 0x1, + /// the quality all points get before we have established communication (or populated) the point + RESTART = 0x2, + /// set if communication has been lost with the source of the data (after establishing contact) + COMM_LOST = 0x4, + /// set if the value is being forced to a "fake" value somewhere in the system + REMOTE_FORCED = 0x8, + /// set if the value is being forced to a "fake" value on the original device + LOCAL_FORCED = 0x10, + /// set if the value is oscillating very quickly and some events are being suppressed + CHATTER_FILTER = 0x20, + /// state bit 1 + STATE1 = 0x40, + /// state bit 2 + STATE2 = 0x80 +}; + +struct DoubleBitBinaryQualitySpec +{ + using enum_type_t = DoubleBitBinaryQuality; + + static uint8_t to_type(DoubleBitBinaryQuality arg); + static DoubleBitBinaryQuality from_type(uint8_t arg); + static char const* to_string(DoubleBitBinaryQuality arg); + static char const* to_human_string(DoubleBitBinaryQuality arg); + static DoubleBitBinaryQuality from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/EventAnalogOutputStatusVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/EventAnalogOutputStatusVariation.h new file mode 100644 index 00000000..5dbb4176 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/EventAnalogOutputStatusVariation.h @@ -0,0 +1,65 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_EVENTANALOGOUTPUTSTATUSVARIATION_H +#define OPENDNP3_EVENTANALOGOUTPUTSTATUSVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class EventAnalogOutputStatusVariation : uint8_t +{ + Group42Var1 = 0, + Group42Var2 = 1, + Group42Var3 = 2, + Group42Var4 = 3, + Group42Var5 = 4, + Group42Var6 = 5, + Group42Var7 = 6, + Group42Var8 = 7 +}; + +struct EventAnalogOutputStatusVariationSpec +{ + using enum_type_t = EventAnalogOutputStatusVariation; + + static uint8_t to_type(EventAnalogOutputStatusVariation arg); + static EventAnalogOutputStatusVariation from_type(uint8_t arg); + static char const* to_string(EventAnalogOutputStatusVariation arg); + static char const* to_human_string(EventAnalogOutputStatusVariation arg); + static EventAnalogOutputStatusVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/EventAnalogVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/EventAnalogVariation.h new file mode 100644 index 00000000..ed95e4f6 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/EventAnalogVariation.h @@ -0,0 +1,65 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_EVENTANALOGVARIATION_H +#define OPENDNP3_EVENTANALOGVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class EventAnalogVariation : uint8_t +{ + Group32Var1 = 0, + Group32Var2 = 1, + Group32Var3 = 2, + Group32Var4 = 3, + Group32Var5 = 4, + Group32Var6 = 5, + Group32Var7 = 6, + Group32Var8 = 7 +}; + +struct EventAnalogVariationSpec +{ + using enum_type_t = EventAnalogVariation; + + static uint8_t to_type(EventAnalogVariation arg); + static EventAnalogVariation from_type(uint8_t arg); + static char const* to_string(EventAnalogVariation arg); + static char const* to_human_string(EventAnalogVariation arg); + static EventAnalogVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/EventBinaryOutputStatusVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/EventBinaryOutputStatusVariation.h new file mode 100644 index 00000000..9987e496 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/EventBinaryOutputStatusVariation.h @@ -0,0 +1,59 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_EVENTBINARYOUTPUTSTATUSVARIATION_H +#define OPENDNP3_EVENTBINARYOUTPUTSTATUSVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class EventBinaryOutputStatusVariation : uint8_t +{ + Group11Var1 = 0, + Group11Var2 = 1 +}; + +struct EventBinaryOutputStatusVariationSpec +{ + using enum_type_t = EventBinaryOutputStatusVariation; + + static uint8_t to_type(EventBinaryOutputStatusVariation arg); + static EventBinaryOutputStatusVariation from_type(uint8_t arg); + static char const* to_string(EventBinaryOutputStatusVariation arg); + static char const* to_human_string(EventBinaryOutputStatusVariation arg); + static EventBinaryOutputStatusVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/EventBinaryVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/EventBinaryVariation.h new file mode 100644 index 00000000..83ed1cc2 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/EventBinaryVariation.h @@ -0,0 +1,60 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_EVENTBINARYVARIATION_H +#define OPENDNP3_EVENTBINARYVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class EventBinaryVariation : uint8_t +{ + Group2Var1 = 0, + Group2Var2 = 1, + Group2Var3 = 2 +}; + +struct EventBinaryVariationSpec +{ + using enum_type_t = EventBinaryVariation; + + static uint8_t to_type(EventBinaryVariation arg); + static EventBinaryVariation from_type(uint8_t arg); + static char const* to_string(EventBinaryVariation arg); + static char const* to_human_string(EventBinaryVariation arg); + static EventBinaryVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/EventCounterVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/EventCounterVariation.h new file mode 100644 index 00000000..5b305cd7 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/EventCounterVariation.h @@ -0,0 +1,61 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_EVENTCOUNTERVARIATION_H +#define OPENDNP3_EVENTCOUNTERVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class EventCounterVariation : uint8_t +{ + Group22Var1 = 0, + Group22Var2 = 1, + Group22Var5 = 2, + Group22Var6 = 3 +}; + +struct EventCounterVariationSpec +{ + using enum_type_t = EventCounterVariation; + + static uint8_t to_type(EventCounterVariation arg); + static EventCounterVariation from_type(uint8_t arg); + static char const* to_string(EventCounterVariation arg); + static char const* to_human_string(EventCounterVariation arg); + static EventCounterVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/EventDoubleBinaryVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/EventDoubleBinaryVariation.h new file mode 100644 index 00000000..87ff74d1 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/EventDoubleBinaryVariation.h @@ -0,0 +1,60 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_EVENTDOUBLEBINARYVARIATION_H +#define OPENDNP3_EVENTDOUBLEBINARYVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class EventDoubleBinaryVariation : uint8_t +{ + Group4Var1 = 0, + Group4Var2 = 1, + Group4Var3 = 2 +}; + +struct EventDoubleBinaryVariationSpec +{ + using enum_type_t = EventDoubleBinaryVariation; + + static uint8_t to_type(EventDoubleBinaryVariation arg); + static EventDoubleBinaryVariation from_type(uint8_t arg); + static char const* to_string(EventDoubleBinaryVariation arg); + static char const* to_human_string(EventDoubleBinaryVariation arg); + static EventDoubleBinaryVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/EventFrozenCounterVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/EventFrozenCounterVariation.h new file mode 100644 index 00000000..f2359cdb --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/EventFrozenCounterVariation.h @@ -0,0 +1,61 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_EVENTFROZENCOUNTERVARIATION_H +#define OPENDNP3_EVENTFROZENCOUNTERVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class EventFrozenCounterVariation : uint8_t +{ + Group23Var1 = 0, + Group23Var2 = 1, + Group23Var5 = 2, + Group23Var6 = 3 +}; + +struct EventFrozenCounterVariationSpec +{ + using enum_type_t = EventFrozenCounterVariation; + + static uint8_t to_type(EventFrozenCounterVariation arg); + static EventFrozenCounterVariation from_type(uint8_t arg); + static char const* to_string(EventFrozenCounterVariation arg); + static char const* to_human_string(EventFrozenCounterVariation arg); + static EventFrozenCounterVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/EventMode.h b/product/src/fes/include/libdnp3/opendnp3/gen/EventMode.h new file mode 100644 index 00000000..c8ebe452 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/EventMode.h @@ -0,0 +1,68 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_EVENTMODE_H +#define OPENDNP3_EVENTMODE_H + +#include +#include + +namespace opendnp3 { + +/** + Describes how a transaction behaves with respect to event generation +*/ +enum class EventMode : uint8_t +{ + /// Detect events using the specific mechanism for that type + Detect = 0x0, + /// Force the creation of an event bypassing detection mechanism + Force = 0x1, + /// Never produce an event regardless of changes + Suppress = 0x2, + /// Force the creation of an event bypassing detection mechanism, but does not update the static value + EventOnly = 0x3 +}; + +struct EventModeSpec +{ + using enum_type_t = EventMode; + + static uint8_t to_type(EventMode arg); + static EventMode from_type(uint8_t arg); + static char const* to_string(EventMode arg); + static char const* to_human_string(EventMode arg); + static EventMode from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/EventOctetStringVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/EventOctetStringVariation.h new file mode 100644 index 00000000..621fb850 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/EventOctetStringVariation.h @@ -0,0 +1,58 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_EVENTOCTETSTRINGVARIATION_H +#define OPENDNP3_EVENTOCTETSTRINGVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class EventOctetStringVariation : uint8_t +{ + Group111Var0 = 0 +}; + +struct EventOctetStringVariationSpec +{ + using enum_type_t = EventOctetStringVariation; + + static uint8_t to_type(EventOctetStringVariation arg); + static EventOctetStringVariation from_type(uint8_t arg); + static char const* to_string(EventOctetStringVariation arg); + static char const* to_human_string(EventOctetStringVariation arg); + static EventOctetStringVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/EventSecurityStatVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/EventSecurityStatVariation.h new file mode 100644 index 00000000..120c034e --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/EventSecurityStatVariation.h @@ -0,0 +1,59 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_EVENTSECURITYSTATVARIATION_H +#define OPENDNP3_EVENTSECURITYSTATVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class EventSecurityStatVariation : uint8_t +{ + Group122Var1 = 0, + Group122Var2 = 1 +}; + +struct EventSecurityStatVariationSpec +{ + using enum_type_t = EventSecurityStatVariation; + + static uint8_t to_type(EventSecurityStatVariation arg); + static EventSecurityStatVariation from_type(uint8_t arg); + static char const* to_string(EventSecurityStatVariation arg); + static char const* to_human_string(EventSecurityStatVariation arg); + static EventSecurityStatVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/FlagsType.h b/product/src/fes/include/libdnp3/opendnp3/gen/FlagsType.h new file mode 100644 index 00000000..0895fb90 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/FlagsType.h @@ -0,0 +1,67 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_FLAGSTYPE_H +#define OPENDNP3_FLAGSTYPE_H + +#include +#include + +namespace opendnp3 { + +/** + enumerates all types that have flags +*/ +enum class FlagsType : uint8_t +{ + DoubleBinaryInput = 0x1, + Counter = 0x2, + FrozenCounter = 0x3, + AnalogInput = 0x4, + BinaryOutputStatus = 0x5, + AnalogOutputStatus = 0x6, + BinaryInput = 0x0 +}; + +struct FlagsTypeSpec +{ + using enum_type_t = FlagsType; + + static uint8_t to_type(FlagsType arg); + static FlagsType from_type(uint8_t arg); + static char const* to_string(FlagsType arg); + static char const* to_human_string(FlagsType arg); + static FlagsType from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/FlowControl.h b/product/src/fes/include/libdnp3/opendnp3/gen/FlowControl.h new file mode 100644 index 00000000..a3e03840 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/FlowControl.h @@ -0,0 +1,63 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_FLOWCONTROL_H +#define OPENDNP3_FLOWCONTROL_H + +#include +#include + +namespace opendnp3 { + +/** + Enumeration for setting serial port flow control +*/ +enum class FlowControl : uint8_t +{ + Hardware = 1, + XONXOFF = 2, + None = 0 +}; + +struct FlowControlSpec +{ + using enum_type_t = FlowControl; + + static uint8_t to_type(FlowControl arg); + static FlowControl from_type(uint8_t arg); + static char const* to_string(FlowControl arg); + static char const* to_human_string(FlowControl arg); + static FlowControl from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/FrozenCounterQuality.h b/product/src/fes/include/libdnp3/opendnp3/gen/FrozenCounterQuality.h new file mode 100644 index 00000000..1d767bb4 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/FrozenCounterQuality.h @@ -0,0 +1,76 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_FROZENCOUNTERQUALITY_H +#define OPENDNP3_FROZENCOUNTERQUALITY_H + +#include +#include + +namespace opendnp3 { + +/** + Quality field bitmask for frozen counter values +*/ +enum class FrozenCounterQuality : uint8_t +{ + /// set when the data is "good", meaning that rest of the system can trust the value + ONLINE = 0x1, + /// the quality all points get before we have established communication (or populated) the point + RESTART = 0x2, + /// set if communication has been lost with the source of the data (after establishing contact) + COMM_LOST = 0x4, + /// set if the value is being forced to a "fake" value somewhere in the system + REMOTE_FORCED = 0x8, + /// set if the value is being forced to a "fake" value on the original device + LOCAL_FORCED = 0x10, + /// Deprecated flag that indicates value has rolled over + ROLLOVER = 0x20, + /// indicates an unusual change in value + DISCONTINUITY = 0x40, + /// reserved bit + RESERVED = 0x80 +}; + +struct FrozenCounterQualitySpec +{ + using enum_type_t = FrozenCounterQuality; + + static uint8_t to_type(FrozenCounterQuality arg); + static FrozenCounterQuality from_type(uint8_t arg); + static char const* to_string(FrozenCounterQuality arg); + static char const* to_human_string(FrozenCounterQuality arg); + static FrozenCounterQuality from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/FunctionCode.h b/product/src/fes/include/libdnp3/opendnp3/gen/FunctionCode.h new file mode 100644 index 00000000..ca46a3dd --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/FunctionCode.h @@ -0,0 +1,134 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_FUNCTIONCODE_H +#define OPENDNP3_FUNCTIONCODE_H + +#include +#include + +namespace opendnp3 { + +/** + Application layer function code enumeration +*/ +enum class FunctionCode : uint8_t +{ + /// Master sends this to an outstation to confirm the receipt of an Application Layer fragment + CONFIRM = 0x0, + /// Outstation shall return the data specified by the objects in the request + READ = 0x1, + /// Outstation shall store the data specified by the objects in the request + WRITE = 0x2, + /// Outstation shall select (or arm) the output points specified by the objects in the request in preparation for a subsequent operate command + SELECT = 0x3, + /// Outstation shall activate the output points selected (or armed) by a previous select function code command + OPERATE = 0x4, + /// Outstation shall immediately actuate the output points specified by the objects in the request + DIRECT_OPERATE = 0x5, + /// Same as DIRECT_OPERATE but outstation shall not send a response + DIRECT_OPERATE_NR = 0x6, + /// Outstation shall copy the point data values specified by the objects in the request to a separate freeze buffer + IMMED_FREEZE = 0x7, + /// Same as IMMED_FREEZE but outstation shall not send a response + IMMED_FREEZE_NR = 0x8, + /// Outstation shall copy the point data values specified by the objects in the request into a separate freeze buffer and then clear the values + FREEZE_CLEAR = 0x9, + /// Same as FREEZE_CLEAR but outstation shall not send a response + FREEZE_CLEAR_NR = 0xA, + /// Outstation shall copy the point data values specified by the objects in the request to a separate freeze buffer at the time and/or time intervals specified in a special time data information object + FREEZE_AT_TIME = 0xB, + /// Same as FREEZE_AT_TIME but outstation shall not send a response + FREEZE_AT_TIME_NR = 0xC, + /// Outstation shall perform a complete reset of all hardware and software in the device + COLD_RESTART = 0xD, + /// Outstation shall reset only portions of the device + WARM_RESTART = 0xE, + /// Obsolete-Do not use for new designs + INITIALIZE_DATA = 0xF, + /// Outstation shall place the applications specified by the objects in the request into the ready to run state + INITIALIZE_APPLICATION = 0x10, + /// Outstation shall start running the applications specified by the objects in the request + START_APPLICATION = 0x11, + /// Outstation shall stop running the applications specified by the objects in the request + STOP_APPLICATION = 0x12, + /// This code is deprecated-Do not use for new designs + SAVE_CONFIGURATION = 0x13, + /// Enables outstation to initiate unsolicited responses from points specified by the objects in the request + ENABLE_UNSOLICITED = 0x14, + /// Prevents outstation from initiating unsolicited responses from points specified by the objects in the request + DISABLE_UNSOLICITED = 0x15, + /// Outstation shall assign the events generated by the points specified by the objects in the request to one of the classes + ASSIGN_CLASS = 0x16, + /// Outstation shall report the time it takes to process and initiate the transmission of its response + DELAY_MEASURE = 0x17, + /// Outstation shall save the time when the last octet of this message is received + RECORD_CURRENT_TIME = 0x18, + /// Outstation shall open a file + OPEN_FILE = 0x19, + /// Outstation shall close a file + CLOSE_FILE = 0x1A, + /// Outstation shall delete a file + DELETE_FILE = 0x1B, + /// Outstation shall retrieve information about a file + GET_FILE_INFO = 0x1C, + /// Outstation shall return a file authentication key + AUTHENTICATE_FILE = 0x1D, + /// Outstation shall abort a file transfer operation + ABORT_FILE = 0x1E, + /// The master uses this function code when sending authentication requests to the outstation + AUTH_REQUEST = 0x20, + /// The master uses this function code when sending authentication requests to the outstation that do no require acknowledgement + AUTH_REQUEST_NO_ACK = 0x21, + /// Master shall interpret this fragment as an Application Layer response to an ApplicationLayer request + RESPONSE = 0x81, + /// Master shall interpret this fragment as an unsolicited response that was not prompted by an explicit request + UNSOLICITED_RESPONSE = 0x82, + /// The outstation uses this function code to issue authentication messages to the master + AUTH_RESPONSE = 0x83, + /// Unknown function code. Used internally in opendnp3 to indicate the code didn't match anything known + UNKNOWN = 0xFF +}; + +struct FunctionCodeSpec +{ + using enum_type_t = FunctionCode; + + static uint8_t to_type(FunctionCode arg); + static FunctionCode from_type(uint8_t arg); + static char const* to_string(FunctionCode arg); + static char const* to_human_string(FunctionCode arg); + static FunctionCode from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/GroupVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/GroupVariation.h new file mode 100644 index 00000000..4eb1d36f --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/GroupVariation.h @@ -0,0 +1,174 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_GROUPVARIATION_H +#define OPENDNP3_GROUPVARIATION_H + +#include +#include + +namespace opendnp3 { + +/** + Comprehensive list of supported groups and variations +*/ +enum class GroupVariation : uint16_t +{ + Group1Var0 = 0x100, + Group1Var1 = 0x101, + Group1Var2 = 0x102, + Group2Var0 = 0x200, + Group2Var1 = 0x201, + Group2Var2 = 0x202, + Group2Var3 = 0x203, + Group3Var0 = 0x300, + Group3Var1 = 0x301, + Group3Var2 = 0x302, + Group4Var0 = 0x400, + Group4Var1 = 0x401, + Group4Var2 = 0x402, + Group4Var3 = 0x403, + Group10Var0 = 0xA00, + Group10Var1 = 0xA01, + Group10Var2 = 0xA02, + Group11Var0 = 0xB00, + Group11Var1 = 0xB01, + Group11Var2 = 0xB02, + Group12Var0 = 0xC00, + Group12Var1 = 0xC01, + Group13Var1 = 0xD01, + Group13Var2 = 0xD02, + Group20Var0 = 0x1400, + Group20Var1 = 0x1401, + Group20Var2 = 0x1402, + Group20Var5 = 0x1405, + Group20Var6 = 0x1406, + Group21Var0 = 0x1500, + Group21Var1 = 0x1501, + Group21Var2 = 0x1502, + Group21Var5 = 0x1505, + Group21Var6 = 0x1506, + Group21Var9 = 0x1509, + Group21Var10 = 0x150A, + Group22Var0 = 0x1600, + Group22Var1 = 0x1601, + Group22Var2 = 0x1602, + Group22Var5 = 0x1605, + Group22Var6 = 0x1606, + Group23Var0 = 0x1700, + Group23Var1 = 0x1701, + Group23Var2 = 0x1702, + Group23Var5 = 0x1705, + Group23Var6 = 0x1706, + Group30Var0 = 0x1E00, + Group30Var1 = 0x1E01, + Group30Var2 = 0x1E02, + Group30Var3 = 0x1E03, + Group30Var4 = 0x1E04, + Group30Var5 = 0x1E05, + Group30Var6 = 0x1E06, + Group32Var0 = 0x2000, + Group32Var1 = 0x2001, + Group32Var2 = 0x2002, + Group32Var3 = 0x2003, + Group32Var4 = 0x2004, + Group32Var5 = 0x2005, + Group32Var6 = 0x2006, + Group32Var7 = 0x2007, + Group32Var8 = 0x2008, + Group40Var0 = 0x2800, + Group40Var1 = 0x2801, + Group40Var2 = 0x2802, + Group40Var3 = 0x2803, + Group40Var4 = 0x2804, + Group41Var0 = 0x2900, + Group41Var1 = 0x2901, + Group41Var2 = 0x2902, + Group41Var3 = 0x2903, + Group41Var4 = 0x2904, + Group42Var0 = 0x2A00, + Group42Var1 = 0x2A01, + Group42Var2 = 0x2A02, + Group42Var3 = 0x2A03, + Group42Var4 = 0x2A04, + Group42Var5 = 0x2A05, + Group42Var6 = 0x2A06, + Group42Var7 = 0x2A07, + Group42Var8 = 0x2A08, + Group43Var1 = 0x2B01, + Group43Var2 = 0x2B02, + Group43Var3 = 0x2B03, + Group43Var4 = 0x2B04, + Group43Var5 = 0x2B05, + Group43Var6 = 0x2B06, + Group43Var7 = 0x2B07, + Group43Var8 = 0x2B08, + Group50Var1 = 0x3201, + Group50Var3 = 0x3203, + Group50Var4 = 0x3204, + Group51Var1 = 0x3301, + Group51Var2 = 0x3302, + Group52Var1 = 0x3401, + Group52Var2 = 0x3402, + Group60Var1 = 0x3C01, + Group60Var2 = 0x3C02, + Group60Var3 = 0x3C03, + Group60Var4 = 0x3C04, + Group70Var1 = 0x4601, + Group70Var2 = 0x4602, + Group70Var3 = 0x4603, + Group70Var4 = 0x4604, + Group70Var5 = 0x4605, + Group70Var6 = 0x4606, + Group70Var7 = 0x4607, + Group70Var8 = 0x4608, + Group80Var1 = 0x5001, + Group110Var0 = 0x6E00, + Group111Var0 = 0x6F00, + Group112Var0 = 0x7000, + Group113Var0 = 0x7100, + UNKNOWN = 0xFFFF +}; + +struct GroupVariationSpec +{ + using enum_type_t = GroupVariation; + + static uint16_t to_type(GroupVariation arg); + static GroupVariation from_type(uint16_t arg); + static char const* to_string(GroupVariation arg); + static char const* to_human_string(GroupVariation arg); + static GroupVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/IndexQualifierMode.h b/product/src/fes/include/libdnp3/opendnp3/gen/IndexQualifierMode.h new file mode 100644 index 00000000..2c9e352d --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/IndexQualifierMode.h @@ -0,0 +1,64 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_INDEXQUALIFIERMODE_H +#define OPENDNP3_INDEXQUALIFIERMODE_H + +#include +#include + +namespace opendnp3 { + +/** + Specifies whether opendnp3 optimizes for 1-byte indexes when making requests +*/ +enum class IndexQualifierMode : uint8_t +{ + /// Use a one byte qualifier if possible + allow_one_byte = 0x0, + /// Always use two byte qualifiers even if the index is less than or equal to 255 + always_two_bytes = 0x1 +}; + +struct IndexQualifierModeSpec +{ + using enum_type_t = IndexQualifierMode; + + static uint8_t to_type(IndexQualifierMode arg); + static IndexQualifierMode from_type(uint8_t arg); + static char const* to_string(IndexQualifierMode arg); + static char const* to_human_string(IndexQualifierMode arg); + static IndexQualifierMode from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/IntervalUnits.h b/product/src/fes/include/libdnp3/opendnp3/gen/IntervalUnits.h new file mode 100644 index 00000000..3f730b2c --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/IntervalUnits.h @@ -0,0 +1,84 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_INTERVALUNITS_H +#define OPENDNP3_INTERVALUNITS_H + +#include +#include + +namespace opendnp3 { + +/** + Time internal units +*/ +enum class IntervalUnits : uint8_t +{ + /// The outstation does not repeat the action regardless of the value in the interval count + NoRepeat = 0x0, + /// the interval is always counted relative to the start time and is constant regardless of the clock time set at the outstation + Milliseconds = 0x1, + /// At the same millisecond within the second that is specified in the start time + Seconds = 0x2, + /// At the same second and millisecond within the minute that is specified in the start time + Minutes = 0x3, + /// At the same minute, second and millisecond within the hour that is specified in the start time + Hours = 0x4, + /// At the same time of day that is specified in the start time + Days = 0x5, + /// On the same day of the week at the same time of day that is specified in the start time + Weeks = 0x6, + /// On the same day of each month at the same time of day that is specified in the start time + Months7 = 0x7, + /// At the same time of day on the same day of the week after the beginning of the month as the day specified in the start time + Months8 = 0x8, + /// Months on Same Day of Week from End of Month - The outstation shall interpret this setting as in Months8, but the day of the week shall be measured from the end of the month, + Months9 = 0x9, + /// The definition of a season is specific to the outstation + Seasons = 0xA, + /// 11-127 are reserved for future use + Undefined = 0x7F +}; + +struct IntervalUnitsSpec +{ + using enum_type_t = IntervalUnits; + + static uint8_t to_type(IntervalUnits arg); + static IntervalUnits from_type(uint8_t arg); + static char const* to_string(IntervalUnits arg); + static char const* to_human_string(IntervalUnits arg); + static IntervalUnits from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/LinkFunction.h b/product/src/fes/include/libdnp3/opendnp3/gen/LinkFunction.h new file mode 100644 index 00000000..10d9cca9 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/LinkFunction.h @@ -0,0 +1,70 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_LINKFUNCTION_H +#define OPENDNP3_LINKFUNCTION_H + +#include +#include + +namespace opendnp3 { + +/** + Link layer function code enumeration +*/ +enum class LinkFunction : uint8_t +{ + PRI_RESET_LINK_STATES = 0x40, + PRI_TEST_LINK_STATES = 0x42, + PRI_CONFIRMED_USER_DATA = 0x43, + PRI_UNCONFIRMED_USER_DATA = 0x44, + PRI_REQUEST_LINK_STATUS = 0x49, + SEC_ACK = 0x0, + SEC_NACK = 0x1, + SEC_LINK_STATUS = 0xB, + SEC_NOT_SUPPORTED = 0xF, + INVALID = 0xFF +}; + +struct LinkFunctionSpec +{ + using enum_type_t = LinkFunction; + + static uint8_t to_type(LinkFunction arg); + static LinkFunction from_type(uint8_t arg); + static char const* to_string(LinkFunction arg); + static char const* to_human_string(LinkFunction arg); + static LinkFunction from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/LinkStatus.h b/product/src/fes/include/libdnp3/opendnp3/gen/LinkStatus.h new file mode 100644 index 00000000..12b6bad9 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/LinkStatus.h @@ -0,0 +1,64 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_LINKSTATUS_H +#define OPENDNP3_LINKSTATUS_H + +#include +#include + +namespace opendnp3 { + +/** + Enumeration for reset/unreset states of a link layer +*/ +enum class LinkStatus : uint8_t +{ + /// DOWN + UNRESET = 0, + /// UP + RESET = 1 +}; + +struct LinkStatusSpec +{ + using enum_type_t = LinkStatus; + + static uint8_t to_type(LinkStatus arg); + static LinkStatus from_type(uint8_t arg); + static char const* to_string(LinkStatus arg); + static char const* to_human_string(LinkStatus arg); + static LinkStatus from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/MasterTaskType.h b/product/src/fes/include/libdnp3/opendnp3/gen/MasterTaskType.h new file mode 100644 index 00000000..d1d9cb67 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/MasterTaskType.h @@ -0,0 +1,69 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_MASTERTASKTYPE_H +#define OPENDNP3_MASTERTASKTYPE_H + +#include +#include + +namespace opendnp3 { + +/** + Enumeration of internal tasks +*/ +enum class MasterTaskType : uint8_t +{ + CLEAR_RESTART = 0, + DISABLE_UNSOLICITED = 1, + ASSIGN_CLASS = 2, + STARTUP_INTEGRITY_POLL = 3, + NON_LAN_TIME_SYNC = 4, + LAN_TIME_SYNC = 5, + ENABLE_UNSOLICITED = 6, + AUTO_EVENT_SCAN = 7, + USER_TASK = 8 +}; + +struct MasterTaskTypeSpec +{ + using enum_type_t = MasterTaskType; + + static uint8_t to_type(MasterTaskType arg); + static MasterTaskType from_type(uint8_t arg); + static char const* to_string(MasterTaskType arg); + static char const* to_human_string(MasterTaskType arg); + static MasterTaskType from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/OperateType.h b/product/src/fes/include/libdnp3/opendnp3/gen/OperateType.h new file mode 100644 index 00000000..5d16e6c1 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/OperateType.h @@ -0,0 +1,66 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_OPERATETYPE_H +#define OPENDNP3_OPERATETYPE_H + +#include +#include + +namespace opendnp3 { + +/** + Various ways that an outstation can receive a request to operate a BO or AO point +*/ +enum class OperateType : uint8_t +{ + /// The outstation received a valid prior SELECT followed by OPERATE + SelectBeforeOperate = 0x0, + /// The outstation received a direct operate request + DirectOperate = 0x1, + /// The outstation received a direct operate no ack request + DirectOperateNoAck = 0x2 +}; + +struct OperateTypeSpec +{ + using enum_type_t = OperateType; + + static uint8_t to_type(OperateType arg); + static OperateType from_type(uint8_t arg); + static char const* to_string(OperateType arg); + static char const* to_human_string(OperateType arg); + static OperateType from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/OperationType.h b/product/src/fes/include/libdnp3/opendnp3/gen/OperationType.h new file mode 100644 index 00000000..d35ffa9e --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/OperationType.h @@ -0,0 +1,73 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_OPERATIONTYPE_H +#define OPENDNP3_OPERATIONTYPE_H + +#include +#include + +namespace opendnp3 { + +/** + Used in conjunction with Trip Close Code in a CROB to describe what action to perform + Refer to section A.8.1 of IEEE 1815-2012 for a full description +*/ +enum class OperationType : uint8_t +{ + /// Do nothing. + NUL = 0x0, + /// Set output to active for the duration of the On-time. + PULSE_ON = 0x1, + /// Non-interoperable code. Do not use for new applications. + PULSE_OFF = 0x2, + /// Set output to active. + LATCH_ON = 0x3, + /// Set the output to inactive. + LATCH_OFF = 0x4, + /// Undefined. + Undefined = 0xFF +}; + +struct OperationTypeSpec +{ + using enum_type_t = OperationType; + + static uint8_t to_type(OperationType arg); + static OperationType from_type(uint8_t arg); + static char const* to_string(OperationType arg); + static char const* to_human_string(OperationType arg); + static OperationType from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/Parity.h b/product/src/fes/include/libdnp3/opendnp3/gen/Parity.h new file mode 100644 index 00000000..3f602f66 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/Parity.h @@ -0,0 +1,63 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_PARITY_H +#define OPENDNP3_PARITY_H + +#include +#include + +namespace opendnp3 { + +/** + Enumeration for setting serial port parity +*/ +enum class Parity : uint8_t +{ + Even = 1, + Odd = 2, + None = 0 +}; + +struct ParitySpec +{ + using enum_type_t = Parity; + + static uint8_t to_type(Parity arg); + static Parity from_type(uint8_t arg); + static char const* to_string(Parity arg); + static char const* to_human_string(Parity arg); + static Parity from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/PointClass.h b/product/src/fes/include/libdnp3/opendnp3/gen/PointClass.h new file mode 100644 index 00000000..4b86a8a9 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/PointClass.h @@ -0,0 +1,68 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_POINTCLASS_H +#define OPENDNP3_POINTCLASS_H + +#include +#include + +namespace opendnp3 { + +/** + Class assignment for a measurement point +*/ +enum class PointClass : uint8_t +{ + /// No event class assignment + Class0 = 0x1, + /// Assigned to event class 1 + Class1 = 0x2, + /// Assigned to event class 2 + Class2 = 0x4, + /// Assigned to event class 3 + Class3 = 0x8 +}; + +struct PointClassSpec +{ + using enum_type_t = PointClass; + + static uint8_t to_type(PointClass arg); + static PointClass from_type(uint8_t arg); + static char const* to_string(PointClass arg); + static char const* to_human_string(PointClass arg); + static PointClass from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/QualifierCode.h b/product/src/fes/include/libdnp3/opendnp3/gen/QualifierCode.h new file mode 100644 index 00000000..2aed09a8 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/QualifierCode.h @@ -0,0 +1,68 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_QUALIFIERCODE_H +#define OPENDNP3_QUALIFIERCODE_H + +#include +#include + +namespace opendnp3 { + +/** + Object header range/prefix as a single enumeration +*/ +enum class QualifierCode : uint8_t +{ + UINT8_START_STOP = 0x0, + UINT16_START_STOP = 0x1, + ALL_OBJECTS = 0x6, + UINT8_CNT = 0x7, + UINT16_CNT = 0x8, + UINT8_CNT_UINT8_INDEX = 0x17, + UINT16_CNT_UINT16_INDEX = 0x28, + UNDEFINED = 0xFF +}; + +struct QualifierCodeSpec +{ + using enum_type_t = QualifierCode; + + static uint8_t to_type(QualifierCode arg); + static QualifierCode from_type(uint8_t arg); + static char const* to_string(QualifierCode arg); + static char const* to_human_string(QualifierCode arg); + static QualifierCode from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/RestartMode.h b/product/src/fes/include/libdnp3/opendnp3/gen/RestartMode.h new file mode 100644 index 00000000..a1461c69 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/RestartMode.h @@ -0,0 +1,66 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_RESTARTMODE_H +#define OPENDNP3_RESTARTMODE_H + +#include +#include + +namespace opendnp3 { + +/** + Enumeration describing restart mode support of an outstation +*/ +enum class RestartMode : uint8_t +{ + /// Device does not support restart + UNSUPPORTED = 0, + /// Supports restart, and time returned is a fine time delay + SUPPORTED_DELAY_FINE = 1, + /// Supports restart, and time returned is a coarse time delay + SUPPORTED_DELAY_COARSE = 2 +}; + +struct RestartModeSpec +{ + using enum_type_t = RestartMode; + + static uint8_t to_type(RestartMode arg); + static RestartMode from_type(uint8_t arg); + static char const* to_string(RestartMode arg); + static char const* to_human_string(RestartMode arg); + static RestartMode from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/RestartType.h b/product/src/fes/include/libdnp3/opendnp3/gen/RestartType.h new file mode 100644 index 00000000..22c64959 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/RestartType.h @@ -0,0 +1,64 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_RESTARTTYPE_H +#define OPENDNP3_RESTARTTYPE_H + +#include +#include + +namespace opendnp3 { + +/** + Enumeration describing restart operation to perform on an outstation +*/ +enum class RestartType : uint8_t +{ + /// Full reboot + COLD = 0, + /// Warm reboot of process only + WARM = 1 +}; + +struct RestartTypeSpec +{ + using enum_type_t = RestartType; + + static uint8_t to_type(RestartType arg); + static RestartType from_type(uint8_t arg); + static char const* to_string(RestartType arg); + static char const* to_human_string(RestartType arg); + static RestartType from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/ServerAcceptMode.h b/product/src/fes/include/libdnp3/opendnp3/gen/ServerAcceptMode.h new file mode 100644 index 00000000..57b8c37d --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/ServerAcceptMode.h @@ -0,0 +1,62 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_SERVERACCEPTMODE_H +#define OPENDNP3_SERVERACCEPTMODE_H + +#include +#include + +namespace opendnp3 { + +/** + Describes how TCP/TLS server channels handle new connections when an existing connection is already active +*/ +enum class ServerAcceptMode : uint8_t +{ + CloseNew = 0, + CloseExisting = 1 +}; + +struct ServerAcceptModeSpec +{ + using enum_type_t = ServerAcceptMode; + + static uint8_t to_type(ServerAcceptMode arg); + static ServerAcceptMode from_type(uint8_t arg); + static char const* to_string(ServerAcceptMode arg); + static char const* to_human_string(ServerAcceptMode arg); + static ServerAcceptMode from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/StaticAnalogOutputStatusVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/StaticAnalogOutputStatusVariation.h new file mode 100644 index 00000000..10f87360 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/StaticAnalogOutputStatusVariation.h @@ -0,0 +1,61 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_STATICANALOGOUTPUTSTATUSVARIATION_H +#define OPENDNP3_STATICANALOGOUTPUTSTATUSVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class StaticAnalogOutputStatusVariation : uint8_t +{ + Group40Var1 = 0, + Group40Var2 = 1, + Group40Var3 = 2, + Group40Var4 = 3 +}; + +struct StaticAnalogOutputStatusVariationSpec +{ + using enum_type_t = StaticAnalogOutputStatusVariation; + + static uint8_t to_type(StaticAnalogOutputStatusVariation arg); + static StaticAnalogOutputStatusVariation from_type(uint8_t arg); + static char const* to_string(StaticAnalogOutputStatusVariation arg); + static char const* to_human_string(StaticAnalogOutputStatusVariation arg); + static StaticAnalogOutputStatusVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/StaticAnalogVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/StaticAnalogVariation.h new file mode 100644 index 00000000..fe9e2aa5 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/StaticAnalogVariation.h @@ -0,0 +1,63 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_STATICANALOGVARIATION_H +#define OPENDNP3_STATICANALOGVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class StaticAnalogVariation : uint8_t +{ + Group30Var1 = 0, + Group30Var2 = 1, + Group30Var3 = 2, + Group30Var4 = 3, + Group30Var5 = 4, + Group30Var6 = 5 +}; + +struct StaticAnalogVariationSpec +{ + using enum_type_t = StaticAnalogVariation; + + static uint8_t to_type(StaticAnalogVariation arg); + static StaticAnalogVariation from_type(uint8_t arg); + static char const* to_string(StaticAnalogVariation arg); + static char const* to_human_string(StaticAnalogVariation arg); + static StaticAnalogVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/StaticBinaryOutputStatusVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/StaticBinaryOutputStatusVariation.h new file mode 100644 index 00000000..e18b60df --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/StaticBinaryOutputStatusVariation.h @@ -0,0 +1,58 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_STATICBINARYOUTPUTSTATUSVARIATION_H +#define OPENDNP3_STATICBINARYOUTPUTSTATUSVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class StaticBinaryOutputStatusVariation : uint8_t +{ + Group10Var2 = 0 +}; + +struct StaticBinaryOutputStatusVariationSpec +{ + using enum_type_t = StaticBinaryOutputStatusVariation; + + static uint8_t to_type(StaticBinaryOutputStatusVariation arg); + static StaticBinaryOutputStatusVariation from_type(uint8_t arg); + static char const* to_string(StaticBinaryOutputStatusVariation arg); + static char const* to_human_string(StaticBinaryOutputStatusVariation arg); + static StaticBinaryOutputStatusVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/StaticBinaryVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/StaticBinaryVariation.h new file mode 100644 index 00000000..cb9d2f8b --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/StaticBinaryVariation.h @@ -0,0 +1,59 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_STATICBINARYVARIATION_H +#define OPENDNP3_STATICBINARYVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class StaticBinaryVariation : uint8_t +{ + Group1Var1 = 0, + Group1Var2 = 1 +}; + +struct StaticBinaryVariationSpec +{ + using enum_type_t = StaticBinaryVariation; + + static uint8_t to_type(StaticBinaryVariation arg); + static StaticBinaryVariation from_type(uint8_t arg); + static char const* to_string(StaticBinaryVariation arg); + static char const* to_human_string(StaticBinaryVariation arg); + static StaticBinaryVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/StaticCounterVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/StaticCounterVariation.h new file mode 100644 index 00000000..0d1306b5 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/StaticCounterVariation.h @@ -0,0 +1,61 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_STATICCOUNTERVARIATION_H +#define OPENDNP3_STATICCOUNTERVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class StaticCounterVariation : uint8_t +{ + Group20Var1 = 0, + Group20Var2 = 1, + Group20Var5 = 2, + Group20Var6 = 3 +}; + +struct StaticCounterVariationSpec +{ + using enum_type_t = StaticCounterVariation; + + static uint8_t to_type(StaticCounterVariation arg); + static StaticCounterVariation from_type(uint8_t arg); + static char const* to_string(StaticCounterVariation arg); + static char const* to_human_string(StaticCounterVariation arg); + static StaticCounterVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/StaticDoubleBinaryVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/StaticDoubleBinaryVariation.h new file mode 100644 index 00000000..f59cb905 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/StaticDoubleBinaryVariation.h @@ -0,0 +1,58 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_STATICDOUBLEBINARYVARIATION_H +#define OPENDNP3_STATICDOUBLEBINARYVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class StaticDoubleBinaryVariation : uint8_t +{ + Group3Var2 = 0 +}; + +struct StaticDoubleBinaryVariationSpec +{ + using enum_type_t = StaticDoubleBinaryVariation; + + static uint8_t to_type(StaticDoubleBinaryVariation arg); + static StaticDoubleBinaryVariation from_type(uint8_t arg); + static char const* to_string(StaticDoubleBinaryVariation arg); + static char const* to_human_string(StaticDoubleBinaryVariation arg); + static StaticDoubleBinaryVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/StaticFrozenCounterVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/StaticFrozenCounterVariation.h new file mode 100644 index 00000000..d7d5981a --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/StaticFrozenCounterVariation.h @@ -0,0 +1,63 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_STATICFROZENCOUNTERVARIATION_H +#define OPENDNP3_STATICFROZENCOUNTERVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class StaticFrozenCounterVariation : uint8_t +{ + Group21Var1 = 0, + Group21Var2 = 1, + Group21Var5 = 2, + Group21Var6 = 3, + Group21Var9 = 4, + Group21Var10 = 5 +}; + +struct StaticFrozenCounterVariationSpec +{ + using enum_type_t = StaticFrozenCounterVariation; + + static uint8_t to_type(StaticFrozenCounterVariation arg); + static StaticFrozenCounterVariation from_type(uint8_t arg); + static char const* to_string(StaticFrozenCounterVariation arg); + static char const* to_human_string(StaticFrozenCounterVariation arg); + static StaticFrozenCounterVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/StaticOctetStringVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/StaticOctetStringVariation.h new file mode 100644 index 00000000..8c3e0940 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/StaticOctetStringVariation.h @@ -0,0 +1,58 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_STATICOCTETSTRINGVARIATION_H +#define OPENDNP3_STATICOCTETSTRINGVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class StaticOctetStringVariation : uint8_t +{ + Group110Var0 = 0 +}; + +struct StaticOctetStringVariationSpec +{ + using enum_type_t = StaticOctetStringVariation; + + static uint8_t to_type(StaticOctetStringVariation arg); + static StaticOctetStringVariation from_type(uint8_t arg); + static char const* to_string(StaticOctetStringVariation arg); + static char const* to_human_string(StaticOctetStringVariation arg); + static StaticOctetStringVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/StaticSecurityStatVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/StaticSecurityStatVariation.h new file mode 100644 index 00000000..fd5514b6 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/StaticSecurityStatVariation.h @@ -0,0 +1,58 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_STATICSECURITYSTATVARIATION_H +#define OPENDNP3_STATICSECURITYSTATVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class StaticSecurityStatVariation : uint8_t +{ + Group121Var1 = 0 +}; + +struct StaticSecurityStatVariationSpec +{ + using enum_type_t = StaticSecurityStatVariation; + + static uint8_t to_type(StaticSecurityStatVariation arg); + static StaticSecurityStatVariation from_type(uint8_t arg); + static char const* to_string(StaticSecurityStatVariation arg); + static char const* to_human_string(StaticSecurityStatVariation arg); + static StaticSecurityStatVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/StaticTimeAndIntervalVariation.h b/product/src/fes/include/libdnp3/opendnp3/gen/StaticTimeAndIntervalVariation.h new file mode 100644 index 00000000..845e158b --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/StaticTimeAndIntervalVariation.h @@ -0,0 +1,58 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_STATICTIMEANDINTERVALVARIATION_H +#define OPENDNP3_STATICTIMEANDINTERVALVARIATION_H + +#include +#include + +namespace opendnp3 { + +enum class StaticTimeAndIntervalVariation : uint8_t +{ + Group50Var4 = 0 +}; + +struct StaticTimeAndIntervalVariationSpec +{ + using enum_type_t = StaticTimeAndIntervalVariation; + + static uint8_t to_type(StaticTimeAndIntervalVariation arg); + static StaticTimeAndIntervalVariation from_type(uint8_t arg); + static char const* to_string(StaticTimeAndIntervalVariation arg); + static char const* to_human_string(StaticTimeAndIntervalVariation arg); + static StaticTimeAndIntervalVariation from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/StaticTypeBitmask.h b/product/src/fes/include/libdnp3/opendnp3/gen/StaticTypeBitmask.h new file mode 100644 index 00000000..606ac2cd --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/StaticTypeBitmask.h @@ -0,0 +1,69 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_STATICTYPEBITMASK_H +#define OPENDNP3_STATICTYPEBITMASK_H + +#include +#include + +namespace opendnp3 { + +/** + Bitmask values for all the static types +*/ +enum class StaticTypeBitmask : uint16_t +{ + BinaryInput = 0x1, + DoubleBinaryInput = 0x2, + Counter = 0x4, + FrozenCounter = 0x8, + AnalogInput = 0x10, + BinaryOutputStatus = 0x20, + AnalogOutputStatus = 0x40, + TimeAndInterval = 0x80, + OctetString = 0x100 +}; + +struct StaticTypeBitmaskSpec +{ + using enum_type_t = StaticTypeBitmask; + + static uint16_t to_type(StaticTypeBitmask arg); + static StaticTypeBitmask from_type(uint16_t arg); + static char const* to_string(StaticTypeBitmask arg); + static char const* to_human_string(StaticTypeBitmask arg); + static StaticTypeBitmask from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/StopBits.h b/product/src/fes/include/libdnp3/opendnp3/gen/StopBits.h new file mode 100644 index 00000000..d1dd25f8 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/StopBits.h @@ -0,0 +1,64 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_STOPBITS_H +#define OPENDNP3_STOPBITS_H + +#include +#include + +namespace opendnp3 { + +/** + Enumeration for setting serial port stop bits +*/ +enum class StopBits : uint8_t +{ + One = 1, + OnePointFive = 2, + Two = 3, + None = 0 +}; + +struct StopBitsSpec +{ + using enum_type_t = StopBits; + + static uint8_t to_type(StopBits arg); + static StopBits from_type(uint8_t arg); + static char const* to_string(StopBits arg); + static char const* to_human_string(StopBits arg); + static StopBits from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/TaskCompletion.h b/product/src/fes/include/libdnp3/opendnp3/gen/TaskCompletion.h new file mode 100644 index 00000000..bbcd1e0b --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/TaskCompletion.h @@ -0,0 +1,72 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_TASKCOMPLETION_H +#define OPENDNP3_TASKCOMPLETION_H + +#include +#include + +namespace opendnp3 { + +/** + Enum that describes if a master task succeeded or failed +*/ +enum class TaskCompletion : uint8_t +{ + /// A valid response was received from the outstation + SUCCESS = 0, + /// A response was received from the outstation, but it was not valid + FAILURE_BAD_RESPONSE = 1, + /// The task request did not receive a response within the timeout + FAILURE_RESPONSE_TIMEOUT = 2, + /// The start timeout expired before the task could begin running + FAILURE_START_TIMEOUT = 3, + /// The task failed because the master was unable to format the request + FAILURE_MESSAGE_FORMAT_ERROR = 4, + /// There is no communication with the outstation, so the task was not attempted + FAILURE_NO_COMMS = 255 +}; + +struct TaskCompletionSpec +{ + using enum_type_t = TaskCompletion; + + static uint8_t to_type(TaskCompletion arg); + static TaskCompletion from_type(uint8_t arg); + static char const* to_string(TaskCompletion arg); + static char const* to_human_string(TaskCompletion arg); + static TaskCompletion from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/TimeSyncMode.h b/product/src/fes/include/libdnp3/opendnp3/gen/TimeSyncMode.h new file mode 100644 index 00000000..5f682377 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/TimeSyncMode.h @@ -0,0 +1,66 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_TIMESYNCMODE_H +#define OPENDNP3_TIMESYNCMODE_H + +#include +#include + +namespace opendnp3 { + +/** + Determines what the master station does when it sees the NEED_TIME iin bit +*/ +enum class TimeSyncMode : uint8_t +{ + /// synchronize the outstation's time using the non-LAN time sync procedure + NonLAN = 1, + /// synchronize the outstation's time using the LAN time sync procedure + LAN = 2, + /// don't perform a time-sync + None = 0 +}; + +struct TimeSyncModeSpec +{ + using enum_type_t = TimeSyncMode; + + static uint8_t to_type(TimeSyncMode arg); + static TimeSyncMode from_type(uint8_t arg); + static char const* to_string(TimeSyncMode arg); + static char const* to_human_string(TimeSyncMode arg); + static TimeSyncMode from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/TimestampQuality.h b/product/src/fes/include/libdnp3/opendnp3/gen/TimestampQuality.h new file mode 100644 index 00000000..cfd53d79 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/TimestampQuality.h @@ -0,0 +1,66 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_TIMESTAMPQUALITY_H +#define OPENDNP3_TIMESTAMPQUALITY_H + +#include +#include + +namespace opendnp3 { + +/** + Indicates the quality of timestamp values +*/ +enum class TimestampQuality : uint8_t +{ + /// The timestamp is UTC synchronized at the remote device + SYNCHRONIZED = 1, + /// The device indicate the timestamp may be unsynchronized + UNSYNCHRONIZED = 2, + /// Timestamp is not valid, ignore the value and use a local timestamp + INVALID = 0 +}; + +struct TimestampQualitySpec +{ + using enum_type_t = TimestampQuality; + + static uint8_t to_type(TimestampQuality arg); + static TimestampQuality from_type(uint8_t arg); + static char const* to_string(TimestampQuality arg); + static char const* to_human_string(TimestampQuality arg); + static TimestampQuality from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/gen/TripCloseCode.h b/product/src/fes/include/libdnp3/opendnp3/gen/TripCloseCode.h new file mode 100644 index 00000000..ac1bb4a1 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/gen/TripCloseCode.h @@ -0,0 +1,69 @@ +// +// _ _ ______ _ _ _ _ _ _ _ +// | \ | | | ____| | (_) | (_) | | | | +// | \| | ___ | |__ __| |_| |_ _ _ __ __ _| | | | +// | . ` |/ _ \ | __| / _` | | __| | '_ \ / _` | | | | +// | |\ | (_) | | |___| (_| | | |_| | | | | (_| |_|_|_| +// |_| \_|\___/ |______\__,_|_|\__|_|_| |_|\__, (_|_|_) +// __/ | +// |___/ +// +// This file is auto-generated. Do not edit manually +// +// Copyright 2013-2022 Step Function I/O, LLC +// +// Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O +// LLC (https://stepfunc.io) under one or more contributor license agreements. +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license +// this file to you under the Apache License, Version 2.0 (the "License"); you +// may not use this file except in compliance with the License. You may obtain +// a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OPENDNP3_TRIPCLOSECODE_H +#define OPENDNP3_TRIPCLOSECODE_H + +#include +#include + +namespace opendnp3 { + +/** + Used in conjunction with Operation Type in a CROB to describe which output to operate for complementary two-output model + Refer to section A.8.1 of IEEE 1815-2012 for a full description +*/ +enum class TripCloseCode : uint8_t +{ + /// Use the default output. + NUL = 0x0, + /// For complementary two-output model, operate the close output. + CLOSE = 0x1, + /// For complementary two-output model, operate the trip output. + TRIP = 0x2, + /// Reserved for future use. + RESERVED = 0x3 +}; + +struct TripCloseCodeSpec +{ + using enum_type_t = TripCloseCode; + + static uint8_t to_type(TripCloseCode arg); + static TripCloseCode from_type(uint8_t arg); + static char const* to_string(TripCloseCode arg); + static char const* to_human_string(TripCloseCode arg); + static TripCloseCode from_string(const std::string& arg); +}; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/link/Addresses.h b/product/src/fes/include/libdnp3/opendnp3/link/Addresses.h new file mode 100644 index 00000000..ea1a2c0d --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/link/Addresses.h @@ -0,0 +1,57 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ADDRESSES_H +#define OPENDNP3_ADDRESSES_H + +#include + +namespace opendnp3 +{ + +struct Addresses +{ + Addresses() = default; + + Addresses(uint16_t source, uint16_t destination) : source(source), destination(destination) {} + + Addresses Reverse() const + { + return Addresses(this->destination, this->source); + } + + inline bool operator==(const Addresses& other) const + { + return (this->source == other.source) && (this->destination == other.destination); + } + + inline bool operator!=(const Addresses& other) const + { + return !((*this) == other); + } + + bool IsBroadcast() const; + + uint16_t source = 0; + uint16_t destination = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/link/ILinkListener.h b/product/src/fes/include/libdnp3/opendnp3/link/ILinkListener.h new file mode 100644 index 00000000..75893b2c --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/link/ILinkListener.h @@ -0,0 +1,56 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OPENDNP3_ILINK_LISTENER_H +#define OPENDNP3_ILINK_LISTENER_H + +#include "opendnp3/gen/LinkStatus.h" + +namespace opendnp3 +{ + +/** + * Various optional callbacks that can be received for the link layer + */ +class ILinkListener +{ +public: + /// Called when a the reset/unreset status of the link layer changes + virtual void OnStateChange(LinkStatus value) {} + + /// Called when a link-layer frame is received from an unknown destination address + virtual void OnUnknownDestinationAddress(uint16_t destination) {} + + /// Called when a link-layer frame is received from an unknown source address + virtual void OnUnknownSourceAddress(uint16_t source) {} + + /// Called when the keep alive timer elapses. This doesn't denote a keep-alive failure, it's just a notification + virtual void OnKeepAliveInitiated() {} + + /// Called when a keep alive message (request link status) receives no response + virtual void OnKeepAliveFailure() {} + + /// Called when a keep alive message receives a valid response + virtual void OnKeepAliveSuccess() {} +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/link/LinkConfig.h b/product/src/fes/include/libdnp3/opendnp3/link/LinkConfig.h new file mode 100644 index 00000000..37c4ef3f --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/link/LinkConfig.h @@ -0,0 +1,92 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_LINKCONFIG_H +#define OPENDNP3_LINKCONFIG_H + +#include "opendnp3/link/Addresses.h" +#include "opendnp3/util/TimeDuration.h" + +namespace opendnp3 +{ + +/** + Configuration for the dnp3 link layer +*/ +struct LinkConfig +{ + LinkConfig() = delete; + + LinkConfig( + bool isMaster, uint16_t localAddr, uint16_t remoteAddr, TimeDuration timeout, TimeDuration keepAliveTimeout) + : + IsMaster(isMaster), + LocalAddr(localAddr), + RemoteAddr(remoteAddr), + Timeout(timeout), + KeepAliveTimeout(keepAliveTimeout) + { + } + + [[deprecated("Use LinkConfig(bool) instead.")]] + LinkConfig(bool isMaster, bool useConfirms) + : + IsMaster(isMaster), + LocalAddr(isMaster ? 1 : 1024), + RemoteAddr(isMaster ? 1024 : 1), + Timeout(TimeDuration::Seconds(1)), + KeepAliveTimeout(TimeDuration::Minutes(1)) + { + } + + LinkConfig(bool isMaster) + : + IsMaster(isMaster), + LocalAddr(isMaster ? 1 : 1024), + RemoteAddr(isMaster ? 1024 : 1), + Timeout(TimeDuration::Seconds(1)), + KeepAliveTimeout(TimeDuration::Minutes(1)) + { + } + + inline Addresses GetAddresses() const + { + return Addresses(this->LocalAddr, this->RemoteAddr); + } + + /// The master/outstation bit set on all messages + bool IsMaster; + + /// dnp3 address of the local device + uint16_t LocalAddr; + + /// dnp3 address of the remote device + uint16_t RemoteAddr; + + /// the response timeout in milliseconds for confirmed requests + TimeDuration Timeout; + + /// the interval for keep-alive messages (link status requests) + /// if set to TimeDuration::Max(), the keep-alive is disabled + TimeDuration KeepAliveTimeout; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/link/LinkHeaderFields.h b/product/src/fes/include/libdnp3/opendnp3/link/LinkHeaderFields.h new file mode 100644 index 00000000..43a8a47b --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/link/LinkHeaderFields.h @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_LINK_HEADER_FIELDS_H +#define OPENDNP3_LINK_HEADER_FIELDS_H + +#include "opendnp3/gen/LinkFunction.h" +#include "opendnp3/link/Addresses.h" + +namespace opendnp3 +{ + +struct LinkHeaderFields +{ + LinkHeaderFields(); + + LinkHeaderFields(LinkFunction func, bool isMaster, bool fcb, bool fcvdfc, Addresses addresses); + + LinkFunction func; + bool isFromMaster; + bool fcb; + bool fcvdfc; + Addresses addresses; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/link/LinkStatistics.h b/product/src/fes/include/libdnp3/opendnp3/link/LinkStatistics.h new file mode 100644 index 00000000..27f38090 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/link/LinkStatistics.h @@ -0,0 +1,91 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_LINKSTATISTICS_H +#define OPENDNP3_LINKSTATISTICS_H + +#include + +namespace opendnp3 +{ + +/** + * Counters for the channel and the DNP3 link layer + */ +struct LinkStatistics +{ + struct Parser + { + /// Number of frames discarded due to header CRC errors + size_t numHeaderCrcError = 0; + + /// Number of frames discarded due to body CRC errors + size_t numBodyCrcError = 0; + + /// Number of frames received + size_t numLinkFrameRx = 0; + + /// number of bad LEN fields received (malformed frame) + size_t numBadLength = 0; + + /// number of bad function codes (malformed frame) + size_t numBadFunctionCode = 0; + + /// number of FCV / function code mismatches (malformed frame) + size_t numBadFCV = 0; + + /// number of frames w/ unexpected FCB bit set (malformed frame) + size_t numBadFCB = 0; + }; + + struct Channel + { + /// The number of times the channel has successfully opened + size_t numOpen = 0; + + /// The number of times the channel has failed to open + size_t numOpenFail = 0; + + /// The number of times the channel has closed either due to user intervention or an error + size_t numClose = 0; + + /// The number of bytes received + size_t numBytesRx = 0; + + /// The number of bytes transmitted + size_t numBytesTx = 0; + + /// Number of frames transmitted + size_t numLinkFrameTx = 0; + }; + + LinkStatistics() = default; + + LinkStatistics(const Channel& channel, const Parser& parser) : channel(channel), parser(parser) {} + + /// statistics for the communicaiton channel + Channel channel; + + /// statistics for the link parser + Parser parser; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/logging/ILogHandler.h b/product/src/fes/include/libdnp3/opendnp3/logging/ILogHandler.h new file mode 100644 index 00000000..eaa6b232 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/logging/ILogHandler.h @@ -0,0 +1,50 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ILOGHANDLER_H +#define OPENDNP3_ILOGHANDLER_H + +#include "opendnp3/logging/LogLevels.h" + +namespace opendnp3 +{ + +/** + * Callback interface for log messages + */ +class ILogHandler +{ +public: + virtual ~ILogHandler() {} + + /** + * Callback method for log messages + * + * @param module ModuleId of the logger + * @param id string id of the logger + * @param level bitfield LogLevel of the logger + * @param location location in the source of the log call + * @param message message of the log call + */ + virtual void log(ModuleId module, const char* id, LogLevel level, char const* location, char const* message) = 0; +}; + +} // namespace opendnp3 + +#endif // OPENDNP3_ILOGHANDLER_H diff --git a/product/src/fes/include/libdnp3/opendnp3/logging/LogLevels.h b/product/src/fes/include/libdnp3/opendnp3/logging/LogLevels.h new file mode 100644 index 00000000..002c9937 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/logging/LogLevels.h @@ -0,0 +1,168 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_LOGLEVELS_H +#define OPENDNP3_LOGLEVELS_H + +#include + +namespace opendnp3 +{ + +struct ModuleId +{ +public: + ModuleId() = default; + + explicit ModuleId(int32_t level) : value(level) {} + + int32_t value = 0; +}; + +struct LogLevel +{ +public: + LogLevel() = default; + + explicit LogLevel(int32_t level) : value(level) {} + + LogLevel next() const + { + return LogLevel(value << 1); + } + + bool operator==(const LogLevel& other) const + { + return this->value == other.value; + } + + int32_t value = 0; +}; + +/** + * Strongly typed wrapper for flags bitfield + */ +class LogLevels +{ +public: + LogLevels() = default; + + explicit LogLevels(int32_t levels) : levels(levels) {} + + LogLevels(LogLevel level) : levels(level.value) {} + + static LogLevels none() + { + return LogLevels(0); + } + + static LogLevels everything() + { + return LogLevels(~0); + } + + inline bool is_set(const LogLevel& level) const + { + return (level.value & levels) != 0; + } + + LogLevels operator~() const + { + return LogLevels(~this->levels); + } + + LogLevels& operator|=(const LogLevel& other) + { + this->levels |= other.value; + return *this; + } + + LogLevels operator|(const LogLevel& other) const + { + return LogLevels(this->levels | other.value); + } + + LogLevels& operator|=(const LogLevels& other) + { + this->levels |= other.levels; + return *this; + } + + LogLevels operator|(const LogLevels& other) const + { + return LogLevels(this->levels | other.levels); + } + + inline int32_t get_value() const + { + return levels; + } + +private: + int32_t levels = 0; +}; + +namespace flags +{ + + // base filters + const LogLevel EVENT = LogLevel(1); + const LogLevel ERR = EVENT.next(); + const LogLevel WARN = ERR.next(); + const LogLevel INFO = WARN.next(); + const LogLevel DBG = INFO.next(); + + // up-shift the custom dnp3 filters + + const LogLevel LINK_RX = DBG.next(); + const LogLevel LINK_RX_HEX = LINK_RX.next(); + + const LogLevel LINK_TX = LINK_RX_HEX.next(); + const LogLevel LINK_TX_HEX = LINK_TX.next(); + + const LogLevel TRANSPORT_RX = LINK_TX_HEX.next(); + const LogLevel TRANSPORT_TX = TRANSPORT_RX.next(); + + const LogLevel APP_HEADER_RX = TRANSPORT_TX.next(); + const LogLevel APP_HEADER_TX = APP_HEADER_RX.next(); + + const LogLevel APP_OBJECT_RX = APP_HEADER_TX.next(); + const LogLevel APP_OBJECT_TX = APP_OBJECT_RX.next(); + + const LogLevel APP_HEX_RX = APP_OBJECT_TX.next(); + const LogLevel APP_HEX_TX = APP_HEX_RX.next(); + +} // namespace flags + +namespace levels +{ + const LogLevels NOTHING = LogLevels::none(); + const LogLevels ALL = LogLevels::everything(); + const LogLevels NORMAL = NOTHING | flags::EVENT | flags::ERR | flags::WARN | flags::INFO; + const LogLevels ALL_APP_COMMS = NOTHING | flags::APP_HEADER_RX | flags::APP_HEADER_TX | flags::APP_OBJECT_RX + | flags::APP_OBJECT_TX | flags::APP_HEX_RX | flags::APP_HEX_TX; + const LogLevels ALL_COMMS + = ALL_APP_COMMS | flags::LINK_RX | flags::LINK_TX | flags::TRANSPORT_RX | flags::TRANSPORT_TX; +} // namespace levels + +const char* LogFlagToString(const LogLevel& flag); + +} // namespace opendnp3 + +#endif // OPENDNP3_LOGLEVELS_H diff --git a/product/src/fes/include/libdnp3/opendnp3/logging/Logger.h b/product/src/fes/include/libdnp3/opendnp3/logging/Logger.h new file mode 100644 index 00000000..31451ecb --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/logging/Logger.h @@ -0,0 +1,116 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_LOGGER_H +#define OPENDNP3_LOGGER_H + +#include "opendnp3/logging/ILogHandler.h" + +#include +#include + +namespace opendnp3 +{ + +const uint32_t max_log_entry_size = 120; + +/** + * A copyable facade over a LogRoot class + */ +class Logger +{ +public: + struct Settings + { + Settings(ModuleId module, const std::string& id, LogLevels levels) : module(module), id(id), levels(levels) {} + + ModuleId module; + std::string id; + LogLevels levels; + }; + + Logger(const std::shared_ptr& backend, ModuleId moduleid, const std::string& id, LogLevels levels) + : backend(backend), settings(std::make_shared(moduleid, id, levels)) + { + } + + static Logger empty() + { + return Logger(nullptr, ModuleId(0), "", LogLevels(0)); + } + + void log(const LogLevel& level, const char* location, const char* message) + { + if (backend) + { + backend->log(this->settings->module, this->settings->id.c_str(), level, location, message); + } + } + + Logger detach(const std::string& id) const + { + return Logger(this->backend, std::make_shared(this->settings->module, id, this->settings->levels)); + } + + Logger detach(const std::string& id, LogLevels levels) const + { + return Logger(this->backend, std::make_shared(this->settings->module, id, levels)); + } + + Logger detach(LogLevels levels) const + { + return Logger(this->backend, std::make_shared(this->settings->module, this->settings->id, levels)); + } + + bool is_enabled(const LogLevel& level) const + { + return backend && settings->levels.is_set(level); + } + + LogLevels get_levels() const + { + return this->settings->levels; + } + + void set_levels(const LogLevels& filters) + { + this->settings->levels = filters; + } + + void rename(const std::string& id) + { + this->settings->id = id; + } + +private: + Logger(const std::shared_ptr& backend, const std::shared_ptr& settings) + : backend(backend), settings(settings) + { + } + + Logger() = delete; + Logger& operator=(const Logger&) = delete; + + const std::shared_ptr backend; + const std::shared_ptr settings; +}; + +} // namespace opendnp3 + +#endif // OPENDNP3_LOGGER_H diff --git a/product/src/fes/include/libdnp3/opendnp3/master/CommandPointResult.h b/product/src/fes/include/libdnp3/opendnp3/master/CommandPointResult.h new file mode 100644 index 00000000..ea7e9294 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/CommandPointResult.h @@ -0,0 +1,63 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OPENDNP3_COMMAND_POINT_RESULT_H +#define OPENDNP3_COMMAND_POINT_RESULT_H + +#include "opendnp3/gen/CommandPointState.h" +#include "opendnp3/gen/CommandStatus.h" + +namespace opendnp3 +{ + +/// Represents the result of a command operation on a particular point +class CommandPointResult +{ + +public: + /// Fully construct based on all members + CommandPointResult(uint32_t headerIndex_, uint16_t index_, CommandPointState state_, CommandStatus status_) + : headerIndex(headerIndex_), index(index_), state(state_), status(status_) + { + } + + /// Check the result for equality against another value + bool Equals(const CommandPointResult& other) const + { + return (headerIndex == other.headerIndex) && (index == other.index) && (state == other.state) + && (status == other.status); + } + + /// The index of the header when request was made (0-based) + uint32_t headerIndex; + + /// The index of the command that was requested + uint16_t index; + + /// The final state of the command operation on this point + CommandPointState state; + + /// The response value. This is only valid if state == SUCCESS or state == SELECT_FAIL + CommandStatus status; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/CommandResultCallbackT.h b/product/src/fes/include/libdnp3/opendnp3/master/CommandResultCallbackT.h new file mode 100644 index 00000000..079d2e57 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/CommandResultCallbackT.h @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_COMMANDRESULTCALLBACKT_H +#define OPENDNP3_COMMANDRESULTCALLBACKT_H + +#include "opendnp3/master/ICommandTaskResult.h" + +#include + +namespace opendnp3 +{ + +using CommandResultCallbackT = std::function; + +} + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/CommandSet.h b/product/src/fes/include/libdnp3/opendnp3/master/CommandSet.h new file mode 100644 index 00000000..0ead9bb2 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/CommandSet.h @@ -0,0 +1,144 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_COMMAND_SET_H +#define OPENDNP3_COMMAND_SET_H + +#include "opendnp3/app/AnalogOutput.h" +#include "opendnp3/app/ControlRelayOutputBlock.h" +#include "opendnp3/app/Indexed.h" +#include "opendnp3/master/ICommandCollection.h" + +#include +#include +#include + +namespace opendnp3 +{ + +// don't want this to be part of the public API +class ICommandHeader; + +/** + * Provides a mechanism for building a set of one or more command headers + */ +class CommandSet final +{ + // friend class used to hide some implementation details while keeping the headers private + friend class CommandSetOps; + +public: + typedef std::vector> HeaderVector; + + /// Contrsuct an empty command set + CommandSet() = default; + + // Put this in impl so we can hide details of ICommandHeader + ~CommandSet(); + + /// Construct a new command set and take ownership of the headers in argument + CommandSet(CommandSet&& other); + + /// Construct a command set from a list of CROB + CommandSet(std::initializer_list> items); + + /// Construct a command set from a list of AOInt16 + CommandSet(std::initializer_list> items); + + /// Construct a command set from a list of AOInt32 + CommandSet(std::initializer_list> items); + + /// Construct a command set from a list of AOFloat32 + CommandSet(std::initializer_list> items); + + /// Construct a command set from a list of AODouble64 + CommandSet(std::initializer_list> items); + + /// Convenience functions that can build an entire header in one call + template void Add(std::initializer_list> items) + { + if (items.size() != 0) + { + auto& header = this->StartHeader(); + for (auto& command : items) + { + header.Add(command.value, command.index); + } + } + } + + /// Convenience functions that can build an entire header in one call + template void Add(std::vector> items) + { + if (!items.empty()) + { + auto& header = this->StartHeader(); + for (auto& command : items) + { + header.Add(command.value, command.index); + } + } + } + + /// Begin a header of the parameterized type + template ICommandCollection& StartHeader(); + +private: + template void AddAny(std::initializer_list> items); + + ICommandCollection& StartHeaderCROB(); + ICommandCollection& StartHeaderAOInt32(); + ICommandCollection& StartHeaderAOInt16(); + ICommandCollection& StartHeaderAOFloat32(); + ICommandCollection& StartHeaderAODouble64(); + + CommandSet(const CommandSet&) = delete; + CommandSet& operator=(const CommandSet& other) = delete; + + HeaderVector m_headers; +}; + +template<> inline ICommandCollection& CommandSet::StartHeader() +{ + return this->StartHeaderCROB(); +} + +template<> inline ICommandCollection& CommandSet::StartHeader() +{ + return this->StartHeaderAOInt16(); +} + +template<> inline ICommandCollection& CommandSet::StartHeader() +{ + return this->StartHeaderAOInt32(); +} + +template<> inline ICommandCollection& CommandSet::StartHeader() +{ + return this->StartHeaderAOFloat32(); +} + +template<> inline ICommandCollection& CommandSet::StartHeader() +{ + return this->StartHeaderAODouble64(); +} + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/DefaultListenCallbacks.h b/product/src/fes/include/libdnp3/opendnp3/master/DefaultListenCallbacks.h new file mode 100644 index 00000000..3fa3260e --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/DefaultListenCallbacks.h @@ -0,0 +1,57 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_DEFAULTLISTENCALLBACKS_H +#define OPENDNP3_DEFAULTLISTENCALLBACKS_H + +#include "opendnp3/master/DefaultMasterApplication.h" +#include "opendnp3/master/IListenCallbacks.h" + +namespace opendnp3 +{ + +/** + * Callback interface invoked when a new connection is accepted + */ +class DefaultListenCallbacks final : public IListenCallbacks +{ +public: + DefaultListenCallbacks(); + + virtual ~DefaultListenCallbacks() {} + + virtual bool AcceptConnection(uint64_t sessionid, const std::string& ipaddress) override; + + virtual bool AcceptCertificate(uint64_t sessionid, const X509Info& info) override; + + virtual TimeDuration GetFirstFrameTimeout() override; + + virtual void OnFirstFrame(uint64_t sessionid, const LinkHeaderFields& header, ISessionAcceptor& acceptor) override; + + virtual void OnConnectionClose(uint64_t sessionid, const std::shared_ptr& session) override; + + virtual void OnCertificateError(uint64_t sessionid, const X509Info& info, int error) override; + +private: + std::string SessionIdToString(uint64_t id); +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/DefaultMasterApplication.h b/product/src/fes/include/libdnp3/opendnp3/master/DefaultMasterApplication.h new file mode 100644 index 00000000..24fa499d --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/DefaultMasterApplication.h @@ -0,0 +1,60 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_DEFAULTMASTERAPPLICATION_H +#define OPENDNP3_DEFAULTMASTERAPPLICATION_H + +#include "opendnp3/master/IMasterApplication.h" + +#include + +namespace opendnp3 +{ + +class DefaultMasterApplication final : public IMasterApplication +{ +public: + DefaultMasterApplication() {} + + static std::shared_ptr Create() + { + return std::make_shared(); + } + + virtual void OnReceiveIIN(const IINField& iin) final {} + + virtual void OnTaskStart(MasterTaskType type, TaskId id) final {} + + virtual void OnTaskComplete(const TaskInfo& info) final {} + + virtual bool AssignClassDuringStartup() final + { + return false; + } + + virtual void ConfigureAssignClassRequest(const WriteHeaderFunT& fun) final {} + + virtual UTCTimestamp Now() final; + + virtual void OnStateChange(LinkStatus value) final {} +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/HeaderInfo.h b/product/src/fes/include/libdnp3/opendnp3/master/HeaderInfo.h new file mode 100644 index 00000000..53bdf3de --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/HeaderInfo.h @@ -0,0 +1,74 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_HEADERINFO_H +#define OPENDNP3_HEADERINFO_H + +#include "opendnp3/gen/Attributes.h" +#include "opendnp3/gen/GroupVariation.h" +#include "opendnp3/gen/QualifierCode.h" +#include "opendnp3/gen/TimestampQuality.h" + +namespace opendnp3 +{ + +/** + * Simple structure used in the ISOEHandler callbacks to return information + * about the associated header. + */ +class HeaderInfo +{ +public: + HeaderInfo() + : gv(GroupVariation::UNKNOWN), + qualifier(QualifierCode::UNDEFINED), + tsquality(TimestampQuality::INVALID), + isEventVariation(false), + flagsValid(false), + headerIndex(0) + { + } + + HeaderInfo(GroupVariation gv_, QualifierCode qualifier_, TimestampQuality tsquality_, uint32_t headerIndex_) + : gv(gv_), + qualifier(qualifier_), + tsquality(tsquality_), + isEventVariation(IsEvent(gv_)), + flagsValid(HasFlags(gv_)), + headerIndex(headerIndex_) + { + } + + /// The group/variation enumeration for the header + GroupVariation gv; + /// The qualifier code enumeration for the header + QualifierCode qualifier; + /// Enumeration that provides information about the validity of timestamps on the associated objects + TimestampQuality tsquality; + /// True if the specfied variation is an event variation + bool isEventVariation; + /// True if the flags on the value were present on underlying type, false if online is just assumed + bool flagsValid; + /// The 0-based index of the header within the ASDU + uint32_t headerIndex; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/HeaderTypes.h b/product/src/fes/include/libdnp3/opendnp3/master/HeaderTypes.h new file mode 100644 index 00000000..75bab56e --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/HeaderTypes.h @@ -0,0 +1,132 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_HEADERTYPES_H +#define OPENDNP3_HEADERTYPES_H + +#include "opendnp3/app/GroupVariationID.h" +#include "opendnp3/gen/PointClass.h" +#include "opendnp3/gen/QualifierCode.h" + +#include + +namespace opendnp3 +{ + +class HeaderWriter; + +/** + * An enumeration that defines the type of object header + */ +enum class HeaderType : uint8_t +{ + AllObjects, + Ranged8, + Ranged16, + LimitedCount8, + LimitedCount16 +}; + +/** + * A template for a integer range + */ +template struct StartStopRange +{ + T start; + T stop; +}; + +/** + * A template for an integer count + */ +template struct Count +{ + T value; +}; + +/** + * Union type that holds information for a single header type + */ +union HeaderUnion +{ + StartStopRange range8; + StartStopRange range16; + Count count8; + Count count16; +}; + +/** + * Class used to specify a header type + */ +class Header +{ +public: + bool WriteTo(HeaderWriter& writer) const; + + /** + * Create an all objects (0x06) header + */ + static Header AllObjects(uint8_t group, uint8_t variation); + + /** + * Create an all objects (0x06) header + */ + static Header From(PointClass pc); + + /** + * Create a 8-bit start stop header (0x00) + */ + static Header Range8(uint8_t group, uint8_t variation, uint8_t start, uint8_t stop); + + /** + * Create a 16-bit start stop header (0x01) + */ + static Header Range16(uint8_t group, uint8_t variation, uint16_t start, uint16_t stop); + + /** + * Create a 8-bit count header (0x07) + */ + static Header Count8(uint8_t group, uint8_t variation, uint8_t count); + + /** + * Create a 16-bit count header (0x08) + */ + static Header Count16(uint8_t group, uint8_t variation, uint16_t count); + + Header() = default; + +private: + GroupVariationID id; + HeaderType type = HeaderType::AllObjects; + HeaderUnion value; + + Header(uint8_t group, uint8_t var); + + Header(uint8_t group, uint8_t var, uint8_t start, uint8_t stop); + + Header(uint8_t group, uint8_t var, uint16_t start, uint16_t stop); + + Header(uint8_t group, uint8_t var, uint8_t count); + + Header(uint8_t group, uint8_t var, uint16_t count); +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/ICommandCollection.h b/product/src/fes/include/libdnp3/opendnp3/master/ICommandCollection.h new file mode 100644 index 00000000..73452bea --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/ICommandCollection.h @@ -0,0 +1,37 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ICOMMAND_COLLECTION_H +#define OPENDNP3_ICOMMAND_COLLECTION_H + +#include + +namespace opendnp3 +{ + +/// A collection type for command to which the user can add by type and index +template class ICommandCollection +{ +public: + virtual ICommandCollection& Add(const T& command, uint16_t index) = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/ICommandProcessor.h b/product/src/fes/include/libdnp3/opendnp3/master/ICommandProcessor.h new file mode 100644 index 00000000..d2f7c3b8 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/ICommandProcessor.h @@ -0,0 +1,111 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ICOMMANDPROCESSOR_H +#define OPENDNP3_ICOMMANDPROCESSOR_H + +#include "opendnp3/master/CommandResultCallbackT.h" +#include "opendnp3/master/CommandSet.h" +#include "opendnp3/master/TaskConfig.h" + +namespace opendnp3 +{ + +/** + * Interface used to dispatch SELECT / OPERATE / DIRECT OPERATE from application code to a master + */ +class ICommandProcessor +{ +public: + /** + * Select and operate a set of commands + * + * @param commands Set of command headers + * @param callback callback that will be invoked upon completion or failure + * @param config optional configuration that controls normal callbacks and allows the user to be specified for SA + */ + virtual void SelectAndOperate(CommandSet&& commands, + const CommandResultCallbackT& callback, + const TaskConfig& config = TaskConfig::Default()) + = 0; + + /** + * Direct operate a set of commands + * + * @param commands Set of command headers + * @param callback callback that will be invoked upon completion or failure + * @param config optional configuration that controls normal callbacks and allows the user to be specified for SA + */ + virtual void DirectOperate(CommandSet&& commands, + const CommandResultCallbackT& callback, + const TaskConfig& config = TaskConfig::Default()) + = 0; + + /** + * Select/operate a single command + * + * @param command Command to operate + * @param index of the command + * @param callback callback that will be invoked upon completion or failure + * @param config optional configuration that controls normal callbacks and allows the user to be specified for SA + */ + template + void SelectAndOperate(const T& command, + uint16_t index, + const CommandResultCallbackT& callback, + const TaskConfig& config = TaskConfig::Default()); + + /** + * Direct operate a single command + * + * @param command Command to operate + * @param index of the command + * @param callback callback that will be invoked upon completion or failure + * @param config optional configuration that controls normal callbacks and allows the user to be specified for SA + */ + template + void DirectOperate(const T& command, + uint16_t index, + const CommandResultCallbackT& callback, + const TaskConfig& config = TaskConfig::Default()); +}; + +template +void ICommandProcessor::SelectAndOperate(const T& command, + uint16_t index, + const CommandResultCallbackT& callback, + const TaskConfig& config) +{ + CommandSet commands({WithIndex(command, index)}); + this->SelectAndOperate(std::move(commands), callback, config); +} + +template +void ICommandProcessor::DirectOperate(const T& command, + uint16_t index, + const CommandResultCallbackT& callback, + const TaskConfig& config) +{ + CommandSet commands({WithIndex(command, index)}); + this->DirectOperate(std::move(commands), callback, config); +} + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/ICommandTaskResult.h b/product/src/fes/include/libdnp3/opendnp3/master/ICommandTaskResult.h new file mode 100644 index 00000000..d431c74b --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/ICommandTaskResult.h @@ -0,0 +1,52 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OPENDNP3_ICOMMAND_TASK_RESULT_H +#define OPENDNP3_ICOMMAND_TASK_RESULT_H + +#include "opendnp3/app/parsing/ICollection.h" +#include "opendnp3/gen/TaskCompletion.h" +#include "opendnp3/master/CommandPointResult.h" + +namespace opendnp3 +{ + +/** + * Abstract result type returned via callback to a command operation. + * + * Provides the TaskCompleton summary value and access to a collection + * of flatten results. + * + * A result value is provided for every object in every header specified + * in the CommandSet used to start the operation. + * + */ +class ICommandTaskResult : public ICollection +{ +public: + ICommandTaskResult(TaskCompletion result_) : summary(result_) {} + + /// A summary result for the entire task + TaskCompletion summary; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/IListenCallbacks.h b/product/src/fes/include/libdnp3/opendnp3/master/IListenCallbacks.h new file mode 100644 index 00000000..4999b03a --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/IListenCallbacks.h @@ -0,0 +1,87 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ILISTENCALLBACKS_H +#define OPENDNP3_ILISTENCALLBACKS_H + +#include "opendnp3/link/LinkHeaderFields.h" +#include "opendnp3/master/ISessionAcceptor.h" +#include "opendnp3/master/X509Info.h" +#include "opendnp3/util/TimeDuration.h" + +namespace opendnp3 +{ + +/** + * Callback interface invoked when a new connection is accepted + */ +class IListenCallbacks +{ +public: + virtual ~IListenCallbacks() {} + + /** + * Ask user code if the following connection should be accepted + * + * @param sessionid Incrementing id used to uniquely identify the session + * @param ipaddress The IP address of the connecting host. Can optionally be used for connection filtering + * + * @return If true, the connection is accepted and a link frame parser is created to handle incoming frame data + */ + virtual bool AcceptConnection(uint64_t sessionid, const std::string& ipaddress) = 0; + + /** + * Ask user code if the following preverified certificate should be accepted + * + * @param sessionid Incrementing id used to uniquely identify the session + * @param info Information from the x509 certificate + * + * @return If true, if the certificate should be accepted, false otherwise. + */ + virtual bool AcceptCertificate(uint64_t sessionid, const X509Info& info) = 0; + + /// return the amount of time the session should wait for the first frame + virtual TimeDuration GetFirstFrameTimeout() = 0; + + /** + * Called when the first link-layer frame is received for a session + */ + virtual void OnFirstFrame(uint64_t sessionid, const LinkHeaderFields& header, ISessionAcceptor& acceptor) = 0; + + /** + * Called when a socket closes + * + * @param sessionid Incrementing id used to uniquely identify the session + * @param session Possibly NULL shared_ptr to the master session if it was created + */ + virtual void OnConnectionClose(uint64_t sessionid, const std::shared_ptr& session) = 0; + + /** + * Called when a certificate fails verification + * + * @param sessionid Incrementing id used to uniquely identify the session + * @param info Information from the x509 certificate + * @param error Error code with reason for failed verification + */ + virtual void OnCertificateError(uint64_t sessionid, const X509Info& info, int error) = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/IMaster.h b/product/src/fes/include/libdnp3/opendnp3/master/IMaster.h new file mode 100644 index 00000000..3922fd00 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/IMaster.h @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IMASTER_H +#define OPENDNP3_IMASTER_H + +#include "opendnp3/IStack.h" +#include "opendnp3/master/IMasterOperations.h" + +namespace opendnp3 +{ + +/** + * Interface that represents a running master session. + */ +class IMaster : public IMasterOperations, public IStack +{ +public: + virtual ~IMaster() = default; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/IMasterApplication.h b/product/src/fes/include/libdnp3/opendnp3/master/IMasterApplication.h new file mode 100644 index 00000000..82f51c97 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/IMasterApplication.h @@ -0,0 +1,75 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IMASTERAPPLICATION_H +#define OPENDNP3_IMASTERAPPLICATION_H + +#include "opendnp3/app/IINField.h" +#include "opendnp3/gen/MasterTaskType.h" +#include "opendnp3/gen/TaskCompletion.h" +#include "opendnp3/link/ILinkListener.h" +#include "opendnp3/master/HeaderTypes.h" +#include "opendnp3/master/IUTCTimeSource.h" +#include "opendnp3/master/TaskInfo.h" + +#include + +namespace opendnp3 +{ + +typedef std::function WriteHeaderFunT; + +/** + * Interface for all master application callback info except for measurement values. + */ +class IMasterApplication : public ILinkListener, public IUTCTimeSource +{ +public: + virtual ~IMasterApplication() {} + + /// Called when a response or unsolicited response is receive from the outstation + virtual void OnReceiveIIN(const IINField& iin) {} + + /// Task start notification + virtual void OnTaskStart(MasterTaskType type, TaskId id) {} + + /// Task completion notification + virtual void OnTaskComplete(const TaskInfo& info) {} + + /// Called when the application layer is opened + virtual void OnOpen() {} + + /// Called when the application layer is closed + virtual void OnClose() {} + + /// @return true if the master should do an assign class task during startup handshaking + virtual bool AssignClassDuringStartup() + { + return false; + } + + /// Configure the request headers for assign class. Only called if + /// "AssignClassDuringStartup" returns true + /// The user only needs to call the function for each header type to be written + virtual void ConfigureAssignClassRequest(const WriteHeaderFunT& fun) {} +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/IMasterOperations.h b/product/src/fes/include/libdnp3/opendnp3/master/IMasterOperations.h new file mode 100644 index 00000000..24c86b94 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/IMasterOperations.h @@ -0,0 +1,159 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IMASTEROPERATIONS_H +#define OPENDNP3_IMASTEROPERATIONS_H + +#include "opendnp3/StackStatistics.h" +#include "opendnp3/app/ClassField.h" +#include "opendnp3/app/MeasurementTypes.h" +#include "opendnp3/gen/FunctionCode.h" +#include "opendnp3/gen/RestartType.h" +#include "opendnp3/logging/LogLevels.h" +#include "opendnp3/master/HeaderTypes.h" +#include "opendnp3/master/ICommandProcessor.h" +#include "opendnp3/master/IMasterScan.h" +#include "opendnp3/master/ISOEHandler.h" +#include "opendnp3/master/RestartOperationResult.h" +#include "opendnp3/master/TaskConfig.h" +#include "opendnp3/util/TimeDuration.h" + +#include +#include +#include + +namespace opendnp3 +{ + +/** + * All the operations that the user can perform on a running master + */ +class IMasterOperations : public ICommandProcessor +{ +public: + virtual ~IMasterOperations() {} + + /** + * @param filters Adjust the filters to this value + */ + virtual void SetLogFilters(const opendnp3::LogLevels& filters) = 0; + + /** + * Add a recurring user-defined scan from a vector of headers + * @ return A proxy class used to manipulate the scan + */ + virtual std::shared_ptr AddScan(TimeDuration period, + const std::vector
& headers, + std::shared_ptr soe_handler, + const TaskConfig& config = TaskConfig::Default()) + = 0; + + /** + * Add a scan that requests all objects using qualifier code 0x06 + * @ return A proxy class used to manipulate the scan + */ + virtual std::shared_ptr AddAllObjectsScan(GroupVariationID gvId, + TimeDuration period, + std::shared_ptr soe_handler, + const TaskConfig& config = TaskConfig::Default()) + = 0; + + /** + * Add a class-based scan to the master + * @return A proxy class used to manipulate the scan + */ + virtual std::shared_ptr AddClassScan(const ClassField& field, + TimeDuration period, + std::shared_ptr soe_handler, + const TaskConfig& config = TaskConfig::Default()) + = 0; + + /** + * Add a start/stop (range) scan to the master + * @return A proxy class used to manipulate the scan + */ + virtual std::shared_ptr AddRangeScan(GroupVariationID gvId, + uint16_t start, + uint16_t stop, + TimeDuration period, + std::shared_ptr soe_handler, + const TaskConfig& config = TaskConfig::Default()) + = 0; + + /** + * Initiate a single user defined scan via a vector of headers + */ + virtual void Scan(const std::vector
& headers, + std::shared_ptr soe_handler, + const TaskConfig& config = TaskConfig::Default()) + = 0; + + /** + * Initiate a single scan that requests all objects (0x06 qualifier code) for a certain group and variation + */ + virtual void ScanAllObjects(GroupVariationID gvId, + std::shared_ptr soe_handler, + const TaskConfig& config = TaskConfig::Default()) + = 0; + + /** + * Initiate a single class-based scan + */ + virtual void ScanClasses(const ClassField& field, + std::shared_ptr soe_handler, + const TaskConfig& config = TaskConfig::Default()) + = 0; + + /** + * Initiate a single start/stop (range) scan + */ + virtual void ScanRange(GroupVariationID gvId, + uint16_t start, + uint16_t stop, + std::shared_ptr soe_handler, + const TaskConfig& config = TaskConfig::Default()) + = 0; + + /** + * Write a time and interval object to a specific index + */ + virtual void Write(const TimeAndInterval& value, uint16_t index, const TaskConfig& config = TaskConfig::Default()) + = 0; + + /** + * Perform a cold or warm restart and get back the time-to-complete value + */ + virtual void Restart(RestartType op, + const RestartOperationCallbackT& callback, + TaskConfig config = TaskConfig::Default()) + = 0; + + /** + * Perform any operation that requires just a function code + */ + virtual void PerformFunction(const std::string& name, + FunctionCode func, + const std::vector
& headers, + const TaskConfig& config = TaskConfig::Default()) + = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/IMasterScan.h b/product/src/fes/include/libdnp3/opendnp3/master/IMasterScan.h new file mode 100644 index 00000000..87d1a18d --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/IMasterScan.h @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IMASTERSCAN_H +#define OPENDNP3_IMASTERSCAN_H + +namespace opendnp3 +{ + +/** + * Interface for interacting w/ a permanently bound scan + */ +class IMasterScan +{ +public: + virtual ~IMasterScan() = default; + + // Request that the scan be performed as soon as possible + virtual void Demand() = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/IMasterSession.h b/product/src/fes/include/libdnp3/opendnp3/master/IMasterSession.h new file mode 100644 index 00000000..7a016172 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/IMasterSession.h @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IMASTERSESSION_H +#define OPENDNP3_IMASTERSESSION_H + +#include "opendnp3/master/IMasterOperations.h" + +namespace opendnp3 +{ + +/** + * Interface that represents an emphemeral master session + */ +class IMasterSession : public IMasterOperations +{ +public: + virtual ~IMasterSession() = default; + + virtual StackStatistics GetStackStatistics() = 0; + + virtual void BeginShutdown() = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/ISOEHandler.h b/product/src/fes/include/libdnp3/opendnp3/master/ISOEHandler.h new file mode 100644 index 00000000..f4b1168d --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/ISOEHandler.h @@ -0,0 +1,68 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ISOEHANDLER_H +#define OPENDNP3_ISOEHANDLER_H + +#include "opendnp3/app/AnalogCommandEvent.h" +#include "opendnp3/app/BinaryCommandEvent.h" +#include "opendnp3/app/Indexed.h" +#include "opendnp3/app/MeasurementTypes.h" +#include "opendnp3/app/OctetString.h" +#include "opendnp3/app/parsing/ICollection.h" +#include "opendnp3/master/HeaderInfo.h" +#include "opendnp3/master/ResponseInfo.h" + +namespace opendnp3 +{ + +/** + * An interface for Sequence-Of-Events (SOE) callbacks from a master stack to + * the application layer. + * + * A call is made to the appropriate member method for every measurement value in an ASDU. + * The HeaderInfo class provides information about the object header associated with the value. + * + */ +class ISOEHandler +{ + +public: + virtual ~ISOEHandler() = default; + + virtual void BeginFragment(const ResponseInfo& info) = 0; + virtual void EndFragment(const ResponseInfo& info) = 0; + + virtual void Process(const HeaderInfo& info, const ICollection>& values) = 0; + virtual void Process(const HeaderInfo& info, const ICollection>& values) = 0; + virtual void Process(const HeaderInfo& info, const ICollection>& values) = 0; + virtual void Process(const HeaderInfo& info, const ICollection>& values) = 0; + virtual void Process(const HeaderInfo& info, const ICollection>& values) = 0; + virtual void Process(const HeaderInfo& info, const ICollection>& values) = 0; + virtual void Process(const HeaderInfo& info, const ICollection>& values) = 0; + virtual void Process(const HeaderInfo& info, const ICollection>& values) = 0; + virtual void Process(const HeaderInfo& info, const ICollection>& values) = 0; + virtual void Process(const HeaderInfo& info, const ICollection>& values) = 0; + virtual void Process(const HeaderInfo& info, const ICollection>& values) = 0; + virtual void Process(const HeaderInfo& info, const ICollection& values) = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/ISessionAcceptor.h b/product/src/fes/include/libdnp3/opendnp3/master/ISessionAcceptor.h new file mode 100644 index 00000000..655f7bff --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/ISessionAcceptor.h @@ -0,0 +1,50 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ISESSION_ACCEPTOR_H +#define OPENDNP3_ISESSION_ACCEPTOR_H + +#include "opendnp3/master/IMasterApplication.h" +#include "opendnp3/master/IMasterSession.h" +#include "opendnp3/master/ISOEHandler.h" +#include "opendnp3/master/MasterStackConfig.h" + +#include + +namespace opendnp3 +{ + +/** + * Callback interface invoked when a new connection is accepted + */ +class ISessionAcceptor +{ +public: + virtual ~ISessionAcceptor() {} + + virtual std::shared_ptr AcceptSession(const std::string& sessionid, + std::shared_ptr SOEHandler, + std::shared_ptr application, + const MasterStackConfig& config) + = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/ITaskCallback.h b/product/src/fes/include/libdnp3/opendnp3/master/ITaskCallback.h new file mode 100644 index 00000000..69dc1bce --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/ITaskCallback.h @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ITASKCALLBACK_H +#define OPENDNP3_ITASKCALLBACK_H + +#include "opendnp3/gen/TaskCompletion.h" + +namespace opendnp3 +{ + +/** + * Callbacks for when a task starts and completes + */ +class ITaskCallback +{ +public: + // Called when the task starts running + virtual void OnStart() = 0; + + // Called when the task succeeds or fails + virtual void OnComplete(TaskCompletion result) = 0; + + // Called when the task no longer exists and no more calls will be made to OnStart/OnComplete + virtual void OnDestroyed() = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/IUTCTimeSource.h b/product/src/fes/include/libdnp3/opendnp3/master/IUTCTimeSource.h new file mode 100644 index 00000000..efc2a24a --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/IUTCTimeSource.h @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IUTCTIMESOURCE_H +#define OPENDNP3_IUTCTIMESOURCE_H + +#include "opendnp3/util/UTCTimestamp.h" + +namespace opendnp3 +{ + +/** + * Interface that defines a method to get UTC timestamps + */ +class IUTCTimeSource +{ + +public: + /** + * Returns a UTCTimestamp of the current time + */ + virtual UTCTimestamp Now() = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/MasterParams.h b/product/src/fes/include/libdnp3/opendnp3/master/MasterParams.h new file mode 100644 index 00000000..1c07cf69 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/MasterParams.h @@ -0,0 +1,88 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_MASTERPARAMS_H +#define OPENDNP3_MASTERPARAMS_H + +#include "opendnp3/app/AppConstants.h" +#include "opendnp3/app/ClassField.h" +#include "opendnp3/gen/IndexQualifierMode.h" +#include "opendnp3/gen/TimeSyncMode.h" +#include "opendnp3/util/TimeDuration.h" + +namespace opendnp3 +{ + +/** +Configuration information for the dnp3 master +*/ +struct MasterParams +{ + /// Default constructor + MasterParams() {} + + /// Application layer response timeout + TimeDuration responseTimeout = TimeDuration::Seconds(5); + + /// If true, the master will do time syncs when it sees the time IIN bit from the outstation + TimeSyncMode timeSyncMode = TimeSyncMode::None; + + /// If true, the master will disable unsol on startup for all 3 classes + bool disableUnsolOnStartup = true; + + /// If true, the master will not clear the restart IIN bit in response to detecting it set + bool ignoreRestartIIN = false; + + /// Bitwise mask used determine which classes are enabled for unsol, if 0 unsol is not enabled + ClassField unsolClassMask = ClassField::AllEventClasses(); + + /// Which classes should be requested in a startup integrity scan, defaults to 3/2/1/0 + /// A mask equal to 0 means no startup integrity scan will be performed + ClassField startupIntegrityClassMask = ClassField::AllClasses(); + + /// Defines whether an integrity scan will be performed when the EventBufferOverflow IIN is detected + bool integrityOnEventOverflowIIN = true; + + /// Which classes should be requested in an event scan when detecting corresponding events available IIN + ClassField eventScanOnEventsAvailableClassMask = ClassField::None(); + + /// Time delay before retrying a failed task + TimeDuration taskRetryPeriod = TimeDuration::Seconds(5); + + /// Maximum time delay before retrying a failed task. Backs off exponentially from taskRetryPeriod + TimeDuration maxTaskRetryPeriod = TimeDuration::Minutes(1); + + /// Time delay before failing a non-recurring task (e.g. commands) that cannot start + TimeDuration taskStartTimeout = TimeDuration::Seconds(10); + + /// maximum APDU tx size in bytes + uint32_t maxTxFragSize = DEFAULT_MAX_APDU_SIZE; + + /// maximum APDU rx size in bytes + uint32_t maxRxFragSize = DEFAULT_MAX_APDU_SIZE; + + /// Control how the master chooses what qualifier to send when making requests + /// The default behavior is to always use two bytes, but the one byte optimization + /// can be enabled + IndexQualifierMode controlQualifierMode = IndexQualifierMode::always_two_bytes; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/MasterStackConfig.h b/product/src/fes/include/libdnp3/opendnp3/master/MasterStackConfig.h new file mode 100644 index 00000000..49609b69 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/MasterStackConfig.h @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_MASTERSTACKCONFIG_H +#define OPENDNP3_MASTERSTACKCONFIG_H + +#include "opendnp3/link/LinkConfig.h" +#include "opendnp3/master/MasterParams.h" + +namespace opendnp3 +{ + +/** A composite configuration struct that contains all the config + information for a dnp3 master stack +*/ +struct MasterStackConfig +{ + MasterStackConfig() : link(true) {} + + /// Master config + MasterParams master; + + /// Link layer config + LinkConfig link; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/PrintingCommandResultCallback.h b/product/src/fes/include/libdnp3/opendnp3/master/PrintingCommandResultCallback.h new file mode 100644 index 00000000..e27cffd9 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/PrintingCommandResultCallback.h @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_PRINTINGCOMMANDRESULTCALLBACK_H +#define OPENDNP3_PRINTINGCOMMANDRESULTCALLBACK_H + +#include "opendnp3/util/StaticOnly.h" + +#include "opendnp3/master/CommandResultCallbackT.h" + +namespace opendnp3 +{ + +class PrintingCommandResultCallback : public StaticOnly +{ + +public: + static CommandResultCallbackT Get(); +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/PrintingSOEHandler.h b/product/src/fes/include/libdnp3/opendnp3/master/PrintingSOEHandler.h new file mode 100644 index 00000000..8e4f0e13 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/PrintingSOEHandler.h @@ -0,0 +1,109 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_PRINTINGSOEHANDLER_H +#define OPENDNP3_PRINTINGSOEHANDLER_H + +#include "opendnp3/master/ISOEHandler.h" + +#include +#include +#include + +namespace opendnp3 +{ + +/** + * ISOEHandler singleton that prints to the console. + */ +class PrintingSOEHandler final : public ISOEHandler +{ + +public: + PrintingSOEHandler() {} + + static std::shared_ptr Create() + { + return std::make_shared(); + } + + void BeginFragment(const ResponseInfo& info) override; + void EndFragment(const ResponseInfo& info) override; + + virtual void Process(const HeaderInfo& info, const ICollection>& values) override; + virtual void Process(const HeaderInfo& info, const ICollection>& values) override; + virtual void Process(const HeaderInfo& info, const ICollection>& values) override; + virtual void Process(const HeaderInfo& info, const ICollection>& values) override; + virtual void Process(const HeaderInfo& info, const ICollection>& values) override; + virtual void Process(const HeaderInfo& info, const ICollection>& values) override; + virtual void Process(const HeaderInfo& info, const ICollection>& values) override; + virtual void Process(const HeaderInfo& info, const ICollection>& values) override; + virtual void Process(const HeaderInfo& info, const ICollection>& values) override; + virtual void Process(const HeaderInfo& info, const ICollection>& values) override; + virtual void Process(const HeaderInfo& info, const ICollection>& values) override; + virtual void Process(const HeaderInfo& info, const ICollection& values) override; + +private: + template static void PrintAll(const HeaderInfo& info, const ICollection>& values) + { + auto print = [&](const Indexed& pair) { Print(info, pair.value, pair.index); }; + values.ForeachItem(print); + } + + template static void Print(const HeaderInfo& info, const T& value, uint16_t index) + { + std::cout << "[" << index << "] : " << ValueToString(value) << " : " << static_cast(value.flags.value) + << " : " << value.time.value << std::endl; + } + + template static std::string ValueToString(const T& meas) + { + std::ostringstream oss; + oss << meas.value; + return oss.str(); + } + + static std::string GetTimeString(TimestampQuality tsquality) + { + std::ostringstream oss; + switch (tsquality) + { + case (TimestampQuality::SYNCHRONIZED): + return "synchronized"; + break; + case (TimestampQuality::UNSYNCHRONIZED): + oss << "unsynchronized"; + break; + default: + oss << "no timestamp"; + break; + } + + return oss.str(); + } + + static std::string ValueToString(const DoubleBitBinary& meas) + { + return DoubleBitSpec::to_human_string(meas.value); + } +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/ResponseInfo.h b/product/src/fes/include/libdnp3/opendnp3/master/ResponseInfo.h new file mode 100644 index 00000000..381e4b57 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/ResponseInfo.h @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_RESPONSEINFO_H +#define OPENDNP3_RESPONSEINFO_H + +namespace opendnp3 +{ + +/** + * provides basic information about an APDU response + */ +struct ResponseInfo +{ + ResponseInfo(bool unsolicited, bool fir, bool fin) : unsolicited(unsolicited), fir(fir), fin(fin) {} + + // true if the response is unsolicited + bool unsolicited; + // true if this is the first fragment in a multi-fragment response + bool fir; + // true if this is the final fragment in a multi-fragment response + bool fin; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/RestartOperationResult.h b/product/src/fes/include/libdnp3/opendnp3/master/RestartOperationResult.h new file mode 100644 index 00000000..29d57fb0 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/RestartOperationResult.h @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_RESTART_OPERATION_RESULT_H +#define OPENDNP3_RESTART_OPERATION_RESULT_H + +#include "opendnp3/gen/TaskCompletion.h" +#include "opendnp3/util/TimeDuration.h" + +#include +#include + +namespace opendnp3 +{ + +class RestartOperationResult +{ +public: + RestartOperationResult() : summary(TaskCompletion::FAILURE_NO_COMMS) {} + + RestartOperationResult(TaskCompletion summary_, TimeDuration restartTime_) + : summary(summary_), restartTime(restartTime_) + { + } + + /// The result of the task as a whole. + TaskCompletion summary; + + /// Time delay until restart + TimeDuration restartTime; +}; + +typedef std::function RestartOperationCallbackT; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/TaskConfig.h b/product/src/fes/include/libdnp3/opendnp3/master/TaskConfig.h new file mode 100644 index 00000000..87180284 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/TaskConfig.h @@ -0,0 +1,60 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_TASKCONFIG_H +#define OPENDNP3_TASKCONFIG_H + +#include "opendnp3/master/ITaskCallback.h" +#include "opendnp3/master/TaskId.h" + +#include + +namespace opendnp3 +{ + +/** + * Object containing multiple fields for configuring tasks + */ +class TaskConfig +{ +public: + TaskConfig(TaskId taskId, std::shared_ptr pCallback) : taskId(taskId), pCallback(pCallback) {} + + static TaskConfig Default() + { + return TaskConfig(TaskId::Undefined(), nullptr); + } + + /// --- syntax sugar for building configs ----- + + static TaskConfig With(std::shared_ptr callback) + { + return TaskConfig(TaskId::Undefined(), callback); + } + + TaskConfig() = delete; + +public: + TaskId taskId; + std::shared_ptr pCallback; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/TaskId.h b/product/src/fes/include/libdnp3/opendnp3/master/TaskId.h new file mode 100644 index 00000000..d46f29be --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/TaskId.h @@ -0,0 +1,61 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_TASKID_H +#define OPENDNP3_TASKID_H + +namespace opendnp3 +{ + +/** + * Interface that represents a running master. + */ +class TaskId +{ +public: + static TaskId Defined(int id) + { + return TaskId(id, true); + } + static TaskId Undefined() + { + return TaskId(-1, false); + } + + int GetId() const + { + return id; + } + bool IsDefined() const + { + return isDefined; + } + +private: + TaskId() = delete; + + TaskId(int id_, bool isDefined_) : id(id_), isDefined(isDefined_) {} + + int id; + bool isDefined; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/TaskInfo.h b/product/src/fes/include/libdnp3/opendnp3/master/TaskInfo.h new file mode 100644 index 00000000..c6c0a455 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/TaskInfo.h @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_TASK_INFO_H +#define OPENDNP3_TASK_INFO_H + +#include "opendnp3/gen/MasterTaskType.h" +#include "opendnp3/gen/TaskCompletion.h" +#include "opendnp3/master/TaskId.h" + +namespace opendnp3 +{ + +/** + * Struct that provides information about a completed or failed task. + */ +class TaskInfo +{ + +public: + TaskInfo(MasterTaskType type_, TaskCompletion result_, TaskId id_) : type(type_), result(result_), id(id_) {} + + MasterTaskType type; + TaskCompletion result; + TaskId id; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/master/X509Info.h b/product/src/fes/include/libdnp3/opendnp3/master/X509Info.h new file mode 100644 index 00000000..65fe72c2 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/master/X509Info.h @@ -0,0 +1,58 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_X509_INFO_H +#define OPENDNP3_X509_INFO_H + +#include "opendnp3/util/Buffer.h" +#include "opendnp3/util/Uncopyable.h" + +#include + +namespace opendnp3 +{ + +/** + * Select information from a preverified x509 certificate + * that user can can inspect an optionally reject + */ +class X509Info : private Uncopyable +{ +public: + X509Info(int depth_, Buffer sha1thumbprint_, std::string subjectName_) + : depth(depth_), sha1thumbprint(sha1thumbprint_), subjectName(subjectName_) + { + } + + // the depth of the certificate in the chain + int depth; + + // the sha1 thumbprint + Buffer sha1thumbprint; + + // the extracted subject name + std::string subjectName; + +private: + X509Info(); +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/ApplicationIIN.h b/product/src/fes/include/libdnp3/opendnp3/outstation/ApplicationIIN.h new file mode 100644 index 00000000..62f67d24 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/ApplicationIIN.h @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_APPLICATIONIIN_H +#define OPENDNP3_APPLICATIONIIN_H + +#include "opendnp3/app/IINField.h" + +namespace opendnp3 +{ + +/** + Some IIN bits are necessarily controlled by the outstation application, + not the underlying protocol stack. This structure describes the state of + the bits controllable by the application. +*/ +class ApplicationIIN +{ + +public: + ApplicationIIN() = default; + + // flags normally controlled by the application, not the stack + bool needTime = false; + bool localControl = false; + bool deviceTrouble = false; + bool configCorrupt = false; + + // this is only for appliactions that have an additional external event buffer that can overflow + bool eventBufferOverflow = false; + + IINField ToIIN() const; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/DatabaseConfig.h b/product/src/fes/include/libdnp3/opendnp3/outstation/DatabaseConfig.h new file mode 100644 index 00000000..c10f35f9 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/DatabaseConfig.h @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_DATABASECONFIG_H +#define OPENDNP3_DATABASECONFIG_H + +#include "opendnp3/outstation/MeasurementConfig.h" + +#include + +namespace opendnp3 +{ + +struct DatabaseConfig +{ + DatabaseConfig() = default; + + DatabaseConfig(uint16_t all_types); + + std::map binary_input; + std::map double_binary; + std::map analog_input; + std::map counter; + std::map frozen_counter; + std::map binary_output_status; + std::map analog_output_status; + std::map time_and_interval; + std::map octet_string; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/DefaultOutstationApplication.h b/product/src/fes/include/libdnp3/opendnp3/outstation/DefaultOutstationApplication.h new file mode 100644 index 00000000..ce6bb0c7 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/DefaultOutstationApplication.h @@ -0,0 +1,104 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_DEFAULTOUTSTATIONAPPLICATION_H +#define OPENDNP3_DEFAULTOUTSTATIONAPPLICATION_H + +#include "opendnp3/outstation/IOutstationApplication.h" +#include "opendnp3/util/TimeDuration.h" + +#include +#include + +namespace opendnp3 +{ + +/** + * A singleton with default setting useful for examples + */ +class DefaultOutstationApplication : public IOutstationApplication +{ +public: + static std::shared_ptr Create(TimeDuration timeSyncRefreshRate = TimeDuration::Minutes(1)) + { + return std::make_shared(timeSyncRefreshRate); + } + + DefaultOutstationApplication(TimeDuration timeSyncRefreshRate = TimeDuration::Minutes(1)); + virtual ~DefaultOutstationApplication() = default; + + // IDnpTimeSource + virtual DNPTime Now() override; + + // IOutstationApplication + virtual bool SupportsWriteAbsoluteTime() override + { + return true; + } + virtual bool WriteAbsoluteTime(const UTCTimestamp& timestamp) override; + + virtual bool SupportsWriteTimeAndInterval() override + { + return false; + } + virtual bool WriteTimeAndInterval(const ICollection>& values) override + { + return false; + } + + virtual bool SupportsAssignClass() override + { + return true; + } + virtual void RecordClassAssignment(AssignClassType type, PointClass clazz, uint16_t start, uint16_t stop) override + { + } + + virtual ApplicationIIN GetApplicationIIN() const override; + + virtual RestartMode ColdRestartSupport() const override + { + return RestartMode::UNSUPPORTED; + } + virtual RestartMode WarmRestartSupport() const override + { + return RestartMode::UNSUPPORTED; + } + virtual uint16_t ColdRestart() override + { + return 65535; + } + virtual uint16_t WarmRestart() override + { + return 65535; + } + +private: + bool IsTimeValid() const; + bool NeedsTime() const; + + TimeDuration refresh_rate; + UTCTimestamp last_timestamp = UTCTimestamp(); + std::chrono::system_clock::time_point last_update + = std::chrono::system_clock::time_point(std::chrono::milliseconds(0)); +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/EventBufferConfig.h b/product/src/fes/include/libdnp3/opendnp3/outstation/EventBufferConfig.h new file mode 100644 index 00000000..ac78cc7a --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/EventBufferConfig.h @@ -0,0 +1,90 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_EVENTBUFFERCONFIG_H +#define OPENDNP3_EVENTBUFFERCONFIG_H + +#include + +namespace opendnp3 +{ + +/** + + Configuration of maximum event counts per event type. + + The underlying implementation uses a *preallocated* heap buffer to store events + until they are transmitted to the master. The size of this buffer is proportional + to the TotalEvents() method, i.e. the sum of the maximum events for each type. + + Implementations should configure the buffers to store a reasonable number events + given the polling frequency and memory restrictions of the target platform. + +*/ +struct EventBufferConfig +{ + /** + Construct the class using the same maximum for all types. This is mainly used for demo purposes. + You probably don't want to use this method unless your implementation actually reports every type. + */ + static EventBufferConfig AllTypes(uint16_t sizes); + + /** + Construct the class specifying the maximum number of events for each type individually. + */ + EventBufferConfig(uint16_t maxBinaryEvents = 0, + uint16_t maxDoubleBinaryEvents = 0, + uint16_t maxAnalogEvents = 0, + uint16_t maxCounterEvents = 0, + uint16_t maxFrozenCounterEvents = 0, + uint16_t maxBinaryOutputStatusEvents = 0, + uint16_t maxAnalogOutputStatusEvents = 0, + uint16_t maxOctetStringEvents = 0); + + // Returns the sum of all event count maximums (number of elements in preallocated buffer) + uint32_t TotalEvents() const; + + // The number of binary events the outstation will buffer before overflowing + uint16_t maxBinaryEvents; + + // The number of double bit binary events the outstation will buffer before overflowing + uint16_t maxDoubleBinaryEvents; + + // The number of analog events the outstation will buffer before overflowing + uint16_t maxAnalogEvents; + + // The number of counter events the outstation will buffer before overflowing + uint16_t maxCounterEvents; + + // The number of frozen counter events the outstation will buffer before overflowing + uint16_t maxFrozenCounterEvents; + + // The number of binary output status events the outstation will buffer before overflowing + uint16_t maxBinaryOutputStatusEvents; + + // The number of analog output status events the outstation will buffer before overflowing + uint16_t maxAnalogOutputStatusEvents; + + // The number of analog output status events the outstation will buffer before overflowing + uint16_t maxOctetStringEvents; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/ICommandHandler.h b/product/src/fes/include/libdnp3/opendnp3/outstation/ICommandHandler.h new file mode 100644 index 00000000..0de2c5fc --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/ICommandHandler.h @@ -0,0 +1,176 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_ICOMMANDHANDLER_H +#define OPENDNP3_ICOMMANDHANDLER_H + +#include "IUpdateHandler.h" + +#include "opendnp3/app/AnalogOutput.h" +#include "opendnp3/app/ControlRelayOutputBlock.h" +#include "opendnp3/gen/OperateType.h" + +namespace opendnp3 +{ + +/** + * Interface used to dispatch SELECT / OPERATE / DIRECT OPERATE (Binary/Analog output) from the outstation to + * application code. + * + * The ITransactable sub-interface is used to determine the start and end of an ASDU containing commands. + */ +class ICommandHandler +{ +public: + virtual ~ICommandHandler() = default; + + /** + * called when a command APDU begins processing + */ + virtual void Begin() = 0; + + /** + * called when a command APDU ends processing + */ + virtual void End() = 0; + + /** + * Ask if the application supports a ControlRelayOutputBlock - group 12 variation 1 + * + * @param command command to operate + * @param index index of the command + * @return result of request + */ + virtual CommandStatus Select(const ControlRelayOutputBlock& command, uint16_t index) = 0; + + /** + * Operate a ControlRelayOutputBlock - group 12 variation 1 + * + * @param command command to operate + * @param index index of the command + * @param handler interface for loading measurement changes + * @param opType the operation type the outstation received. + * @return result of request + */ + virtual CommandStatus Operate(const ControlRelayOutputBlock& command, + uint16_t index, + IUpdateHandler& handler, + OperateType opType) + = 0; + + /** + * Ask if the application supports a 16 bit analog output - group 41 variation 2 + * + * @param command command to operate + * @param index index of the command + * @return result of request + */ + virtual CommandStatus Select(const AnalogOutputInt16& command, uint16_t index) = 0; + + /** + * Ask if the application supports a 16 bit analog output - group 41 variation 2 + * + * @param command command to operate + * @param index index of the command + * @param handler interface for loading measurement changes + * @param opType the operation type the outstation received. + * @return result of request + */ + virtual CommandStatus Operate(const AnalogOutputInt16& command, + uint16_t index, + IUpdateHandler& handler, + OperateType opType) + = 0; + + /** + * Ask if the application supports a 32 bit analog output - group 41 variation 1 + * + * @param command command to operate + * @param index index of the command + * @return result of request + */ + virtual CommandStatus Select(const AnalogOutputInt32& command, uint16_t index) = 0; + + /** + * Operate a 32 bit analog output - group 41 variation 1 + * + * @param command command to operate + * @param index index of the command + * @param handler interface for loading measurement changes + * @param opType the operation type the outstation received. + * @return result of request + */ + virtual CommandStatus Operate(const AnalogOutputInt32& command, + uint16_t index, + IUpdateHandler& handler, + OperateType opType) + = 0; + + /** + * Ask if the application supports a single precision, floating point analog output - group 41 variation 3 + * + * @param command command to operate + * @param index index of the command + * @return result of request + */ + virtual CommandStatus Select(const AnalogOutputFloat32& command, uint16_t index) = 0; + + /** + * Operate a single precision, floating point analog output - group 41 variation 3 + * + * @param command command to operate + * @param index index of the command + * @param handler interface for loading measurement changes + * @param opType the operation type the outstation received. + * @return result of request + */ + virtual CommandStatus Operate(const AnalogOutputFloat32& command, + uint16_t index, + IUpdateHandler& handler, + OperateType opType) + = 0; + + /** + * Ask if the application supports a double precision, floating point analog output - group 41 variation 4 + * + * @param command command to operate + * @param index index of the command + * @return result of request + */ + virtual CommandStatus Select(const AnalogOutputDouble64& command, uint16_t index) = 0; + + /** + * Operate a double precision, floating point analog output - group 41 variation 4 + * + * @param command command to operate + * @param index index of the command + * @param handler interface for loading measurement changes + * @param opType the operation type the outstation received. + * @return result of request + */ + virtual CommandStatus Operate(const AnalogOutputDouble64& command, + uint16_t index, + IUpdateHandler& handler, + OperateType opType) + = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/IDnpTimeSource.h b/product/src/fes/include/libdnp3/opendnp3/outstation/IDnpTimeSource.h new file mode 100644 index 00000000..fbf66e2c --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/IDnpTimeSource.h @@ -0,0 +1,47 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IDNPTIMESOURCE_H +#define OPENDNP3_IDNPTIMESOURCE_H + +#include "opendnp3/app/DNPTime.h" + +namespace opendnp3 +{ + +/** + * Interface that defines a method to get DNPTime source + */ +class IDnpTimeSource +{ + +public: + /** + * Returns a DNPTime of the current time. + * This value is used when freezing counters. + */ + virtual DNPTime Now() + { + return DNPTime(0, TimestampQuality::INVALID); + } +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/IOutstation.h b/product/src/fes/include/libdnp3/opendnp3/outstation/IOutstation.h new file mode 100644 index 00000000..8664ae56 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/IOutstation.h @@ -0,0 +1,58 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IOUTSTATION_H +#define OPENDNP3_IOUTSTATION_H + +#include "opendnp3/IStack.h" +#include "opendnp3/logging/LogLevels.h" +#include "opendnp3/outstation/Updates.h" + +namespace opendnp3 +{ + +/** + * Interface representing a running outstation. + */ +class IOutstation : public IStack +{ + +public: + ~IOutstation() override = default; + + /** + * @param filters Adjust the filters to this value + */ + virtual void SetLogFilters(const opendnp3::LogLevels& filters) = 0; + + /** + * Sets the restart IIN bit. Normally applications should not + * touch this bit, but it is provided for simulating restarts. + */ + virtual void SetRestartIIN() = 0; + + /** + * Apply a set of measurement updates to the outstation + */ + virtual void Apply(const Updates& updates) = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/IOutstationApplication.h b/product/src/fes/include/libdnp3/opendnp3/outstation/IOutstationApplication.h new file mode 100644 index 00000000..d6d77a28 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/IOutstationApplication.h @@ -0,0 +1,145 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IOUTSTATIONAPPLICATION_H +#define OPENDNP3_IOUTSTATIONAPPLICATION_H + +#include "opendnp3/app/Indexed.h" +#include "opendnp3/app/MeasurementTypes.h" +#include "opendnp3/app/parsing/ICollection.h" +#include "opendnp3/gen/AssignClassType.h" +#include "opendnp3/gen/PointClass.h" +#include "opendnp3/gen/RestartMode.h" +#include "opendnp3/link/ILinkListener.h" +#include "opendnp3/outstation/ApplicationIIN.h" +#include "opendnp3/outstation/IDnpTimeSource.h" +#include "opendnp3/util/UTCTimestamp.h" + +#include + +namespace opendnp3 +{ + +/** + * Interface for all outstation application callback info except for control requests + */ +class IOutstationApplication : public ILinkListener, public IDnpTimeSource +{ +public: + /// Queries whether the the outstation supports absolute time writes + /// If this function returns false, WriteAbsoluteTime will never be called + /// and the outstation will return IIN 2.1 (FUNC_NOT_SUPPORTED) + virtual bool SupportsWriteAbsoluteTime() + { + return false; + } + + /// Write the time to outstation, only called if SupportsWriteAbsoluteTime return true + /// @return boolean value indicating if the time value supplied was accepted. Returning + /// false will cause the outstation to set IIN 2.3 (PARAM_ERROR) in its response. + /// The outstation should clear its NEED_TIME field when handling this response + virtual bool WriteAbsoluteTime(const UTCTimestamp& timestamp) + { + return false; + } + + /// Queries whether the outstation supports the writing of TimeAndInterval + /// If this function returns false, WriteTimeAndInterval will never be called + /// and the outstation will return IIN 2.1 (FUNC_NOT_SUPPORTED) when it receives this request + virtual bool SupportsWriteTimeAndInterval() + { + return false; + } + + /// Write one or more TimeAndInterval values. Only called if SupportsWriteTimeAndInterval returns true. + /// The outstation application code is reponsible for updating TimeAndInterval values in the database if this + /// behavior is desired + /// @return boolean value indicating if the values supplied were accepted. Returning + /// false will cause the outstation to set IIN 2.3 (PARAM_ERROR) in its response. + virtual bool WriteTimeAndInterval(const ICollection>& values) + { + return false; + } + + /// True if the outstation supports the assign class function code + /// If this function returns false, the assign class callbacks will never be called + /// and the outstation will return IIN 2.1 (FUNC_NOT_SUPPORTED) when it receives this function code + virtual bool SupportsAssignClass() + { + return false; + } + + /// Called if SupportsAssignClass returns true + /// The type and range are pre-validated against the outstation's database + /// and class assignments are automatically applied internally. + /// This callback allows user code to persist the changes to non-volatile memory + virtual void RecordClassAssignment(AssignClassType type, PointClass clazz, uint16_t start, uint16_t stop) {} + + /// Returns the application-controlled IIN field + virtual ApplicationIIN GetApplicationIIN() const + { + return ApplicationIIN(); + } + + /// Query the outstation for the cold restart mode it supports + virtual RestartMode ColdRestartSupport() const + { + return RestartMode::UNSUPPORTED; + } + + /// Query the outstation for the warm restart mode it supports + virtual RestartMode WarmRestartSupport() const + { + return RestartMode::UNSUPPORTED; + } + + /// The outstation should perform a complete restart. + /// See the DNP3 specification for a complete descripton of normal behavior + /// @return number of seconds or milliseconds until restart is complete. The value + /// is interpreted based on the Restart Mode returned from ColdRestartSupport() + virtual uint16_t ColdRestart() + { + return 65535; + } + + /// The outstation should perform a partial restart of only the DNP3 application. + /// See the DNP3 specification for a complete descripton of normal behavior + /// @return number of seconds or milliseconds until restart is complete. The value + /// is interpreted based on the Restart Mode returned from WarmRestartSupport() + virtual uint16_t WarmRestart() + { + return 65535; + } + + /// This method notifies that application code that an expected CONFIRM has been + /// received, and events may have cleared from the event buffer. It is informational + /// only. + /// + /// @param is_unsolicited true, if the confirm is for an unsolicited response, false for a solicited response + /// @param num_class1 number of Class 1 events remaining in the event buffer after processing the confirm + /// @param num_class2 number of Class 2 events remaining in the event buffer after processing the confirm + /// @param num_class3 number of Class 3 events remaining in the event buffer after processing the confirm + virtual void OnConfirmProcessed(bool is_unsolicited, uint32_t num_class1, uint32_t num_class2, uint32_t num_class3) {} + + virtual ~IOutstationApplication() = default; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/IUpdateHandler.h b/product/src/fes/include/libdnp3/opendnp3/outstation/IUpdateHandler.h new file mode 100644 index 00000000..0d2debc5 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/IUpdateHandler.h @@ -0,0 +1,131 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_IUPDATEHANDLER_H +#define OPENDNP3_IUPDATEHANDLER_H + +#include "opendnp3/app/MeasurementTypes.h" +#include "opendnp3/app/OctetString.h" +#include "opendnp3/gen/EventMode.h" +#include "opendnp3/gen/FlagsType.h" + +namespace opendnp3 +{ + +/** + * An interface used to update measurement values. + */ +class IUpdateHandler +{ +public: + virtual ~IUpdateHandler() {} + + /** + * Update a Binary measurement + * @param meas measurement to be processed + * @param index index of the measurement + * @param mode Describes how event generation is handled for this method + * @return true if the value exists and it was updated + */ + virtual bool Update(const Binary& meas, uint16_t index, EventMode mode = EventMode::Detect) = 0; + + /** + * Update a DoubleBitBinary measurement + * @param meas measurement to be processed + * @param index index of the measurement + * @param mode Describes how event generation is handled for this method + * @return true if the value exists and it was updated + */ + virtual bool Update(const DoubleBitBinary& meas, uint16_t index, EventMode mode = EventMode::Detect) = 0; + + /** + * Update an Analog measurement + * @param meas measurement to be processed + * @param index index of the measurement + * @param mode Describes how event generation is handled for this method + * @return true if the value exists and it was updated + */ + virtual bool Update(const Analog& meas, uint16_t index, EventMode mode = EventMode::Detect) = 0; + + /** + * Update a Counter measurement + * @param meas measurement to be processed + * @param index index of the measurement + * @param mode Describes how event generation is handled for this method + * @return true if the value exists and it was updated + */ + virtual bool Update(const Counter& meas, uint16_t index, EventMode mode = EventMode::Detect) = 0; + + /** + * Freeze a Counter measurement + * @param index index of the measurement + * @param clear clear the original counter + * @param mode Describes how event generation is handled for this method + * @return true if the value exists and it was updated + */ + virtual bool FreezeCounter(uint16_t index, bool clear = false, EventMode mode = EventMode::Detect) = 0; + + /** + * Update a BinaryOutputStatus measurement + * @param meas measurement to be processed + * @param index index of the measurement + * @param mode Describes how event generation is handled for this method + * @return true if the value exists and it was updated + */ + virtual bool Update(const BinaryOutputStatus& meas, uint16_t index, EventMode mode = EventMode::Detect) = 0; + + /** + * Update a AnalogOutputStatus measurement + * @param meas measurement to be processed + * @param index index of the measurement + * @param mode Describes how event generation is handled for this method + * @return true if the value exists and it was updated + */ + virtual bool Update(const AnalogOutputStatus& meas, uint16_t index, EventMode mode = EventMode::Detect) = 0; + + /** + * Update an octet string value + * @param meas measurement to be processed + * @param index index of the measurement + * @param mode Describes how event generation is handled for this method + * @return true if the value exists and it was updated + */ + virtual bool Update(const OctetString& meas, uint16_t index, EventMode mode = EventMode::Detect) = 0; + + /** + * Update a TimeAndInterval valueindex + * @param meas measurement to be processed + * @param index index of the measurement + * @return true if the value exists and it was updated + */ + virtual bool Update(const TimeAndInterval& meas, uint16_t index) = 0; + + /** + * Update the flags of a measurement without changing it's value + * @param type enumeration specifiy the type to change + * @param start the start index at which to begin changing flags + * @param stop the stop index at which to end changing flags + * @param flags the new value of the flags + */ + virtual bool Modify(FlagsType type, uint16_t start, uint16_t stop, uint8_t flags) = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/MeasurementConfig.h b/product/src/fes/include/libdnp3/opendnp3/outstation/MeasurementConfig.h new file mode 100644 index 00000000..b7c300a4 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/MeasurementConfig.h @@ -0,0 +1,89 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OPENDNP3_MEASUREMENTCONFIG_H +#define OPENDNP3_MEASUREMENTCONFIG_H + +#include "opendnp3/app/MeasurementInfo.h" +#include "opendnp3/gen/PointClass.h" + +namespace opendnp3 +{ + +// All entries have this information +template struct StaticConfig +{ + typename Info::static_variation_t svariation = Info::DefaultStaticVariation; +}; + +template struct EventConfig : StaticConfig +{ + PointClass clazz = PointClass::Class1; + typename Info::event_variation_t evariation = Info::DefaultEventVariation; +}; + +template struct DeadbandConfig : EventConfig +{ + typename Info::value_t deadband = 0; +}; + +struct BinaryConfig : public EventConfig +{ +}; + +struct DoubleBitBinaryConfig : public EventConfig +{ +}; + +struct AnalogConfig : public DeadbandConfig +{ +}; + +struct CounterConfig : public DeadbandConfig +{ +}; + +struct FrozenCounterConfig : public DeadbandConfig +{ +}; + +struct BOStatusConfig : public EventConfig +{ +}; + +struct AOStatusConfig : public DeadbandConfig +{ +}; + +struct OctetStringConfig : public EventConfig +{ +}; + +struct TimeAndIntervalConfig : public StaticConfig +{ +}; + +struct SecurityStatConfig +{ +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/NumRetries.h b/product/src/fes/include/libdnp3/opendnp3/outstation/NumRetries.h new file mode 100644 index 00000000..3dde0b28 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/NumRetries.h @@ -0,0 +1,50 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_NUMRETRIES_H +#define OPENDNP3_NUMRETRIES_H + +#include + +namespace opendnp3 +{ + +/** + * Unsolicited response number of retries + */ +class NumRetries final +{ +public: + static NumRetries Fixed(std::size_t maxNumRetries); + static NumRetries Infinite(); + + bool Retry(); + void Reset(); + +private: + NumRetries(std::size_t maxNumRetries, bool isInfinite); + + std::size_t numRetries; + std::size_t maxNumRetries; + bool isInfinite; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/OutstationConfig.h b/product/src/fes/include/libdnp3/opendnp3/outstation/OutstationConfig.h new file mode 100644 index 00000000..d11c7d00 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/OutstationConfig.h @@ -0,0 +1,50 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_OUTSTATIONCONFIG_H +#define OPENDNP3_OUTSTATIONCONFIG_H + +#include "opendnp3/outstation/EventBufferConfig.h" +#include "opendnp3/outstation/OutstationParams.h" +#include "opendnp3/util/TimeDuration.h" + +namespace opendnp3 +{ + +/** Configuration information for a dnp3 outstation (outstation) + +Used as both input describing the startup configuration of the outstation, and as configuration state of mutable +properties (i.e. unsolicited responses). + +Major feature areas are unsolicited responses, time synchronization requests, event buffer limits, and the DNP3 +object/variations to use by default when the master requests class data or variation 0. + +*/ +struct OutstationConfig +{ + /// Various parameters that govern outstation behavior + OutstationParams params; + + /// Describes the sizes in the event buffer + EventBufferConfig eventBufferConfig; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/OutstationParams.h b/product/src/fes/include/libdnp3/opendnp3/outstation/OutstationParams.h new file mode 100644 index 00000000..98c88eaa --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/OutstationParams.h @@ -0,0 +1,80 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_OUTSTATIONPARAMS_H +#define OPENDNP3_OUTSTATIONPARAMS_H + +#include "opendnp3/app/AppConstants.h" +#include "opendnp3/app/ClassField.h" +#include "opendnp3/outstation/NumRetries.h" +#include "opendnp3/outstation/StaticTypeBitfield.h" +#include "opendnp3/util/TimeDuration.h" + +namespace opendnp3 +{ + +/** + * Static configuration parameters for an outstation session + */ +struct OutstationParams +{ + /// The maximum number of controls the outstation will attempt to process from a single APDU + uint32_t maxControlsPerRequest = 4294967295; + + /// How long the outstation will allow an operate to proceed after a prior select + TimeDuration selectTimeout = TimeDuration::Seconds(10); + + /// Timeout for solicited confirms + TimeDuration solConfirmTimeout = DEFAULT_APP_TIMEOUT; + + /// Timeout for unsolicited confirms + TimeDuration unsolConfirmTimeout = DEFAULT_APP_TIMEOUT; + + /// Number of unsolicited non-regenerated retries + NumRetries numUnsolRetries = NumRetries::Infinite(); + + /// Workaround for test procedure 8.11.2.1. Will respond immediatly to READ requests + /// when waiting for unsolicited NULL responses. + /// + /// @warning This is NOT compliant to IEEE-1815-2012. + bool noDefferedReadDuringUnsolicitedNullResponse = false; + + /// The maximum fragment size the outstation will use for fragments it sends + uint32_t maxTxFragSize = DEFAULT_MAX_APDU_SIZE; + + /// The maximum fragment size the outstation will be able to receive + uint32_t maxRxFragSize = DEFAULT_MAX_APDU_SIZE; + + /// Global enabled / disable for unsolicited messages. If false, the NULL unsolicited message is not even sent + bool allowUnsolicited = false; + + /// A bitmask type that specifies the types allowed in a class 0 reponse + StaticTypeBitField typesAllowedInClass0 = StaticTypeBitField::AllTypes(); + + /// Class mask for unsolicted, default to 0 as unsolicited has to be enabled + ClassField unsolClassMask = ClassField::None(); + + /// If true, the outstation processes responds to any request/confirmation as if it came from the expected master + /// address + bool respondToAnyMaster = false; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/OutstationStackConfig.h b/product/src/fes/include/libdnp3/opendnp3/outstation/OutstationStackConfig.h new file mode 100644 index 00000000..24af2b65 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/OutstationStackConfig.h @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_OUTSTATIONSTACKCONFIG_H +#define OPENDNP3_OUTSTATIONSTACKCONFIG_H + +#include "opendnp3/link/LinkConfig.h" +#include "opendnp3/outstation/DatabaseConfig.h" +#include "opendnp3/outstation/EventBufferConfig.h" +#include "opendnp3/outstation/OutstationConfig.h" + +namespace opendnp3 +{ + +/** + A composite configuration struct that contains all the config + information for a dnp3 outstation stack +*/ +struct OutstationStackConfig +{ + OutstationStackConfig() : link(false) {} + + OutstationStackConfig(const DatabaseConfig& database) : database(database), link(false) {} + + // Configuration of the database + DatabaseConfig database; + + /// Outstation config + OutstationConfig outstation; + + /// Link layer config + LinkConfig link; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/SimpleCommandHandler.h b/product/src/fes/include/libdnp3/opendnp3/outstation/SimpleCommandHandler.h new file mode 100644 index 00000000..696bd8e3 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/SimpleCommandHandler.h @@ -0,0 +1,115 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_SIMPLECOMMANDHANDLER_H +#define OPENDNP3_SIMPLECOMMANDHANDLER_H + +#include "opendnp3/outstation/ICommandHandler.h" + +#include + +namespace opendnp3 +{ + +/** + * Mock ICommandHandler used for examples and demos + */ +class SimpleCommandHandler : public ICommandHandler +{ +public: + /** + * @param status The status value to return in response to all commands + */ + SimpleCommandHandler(CommandStatus status); + + virtual void Begin() override; + virtual void End() override; + + CommandStatus Select(const ControlRelayOutputBlock& command, uint16_t index) override; + CommandStatus Operate(const ControlRelayOutputBlock& command, + uint16_t index, + IUpdateHandler& handler, + OperateType opType) override; + + CommandStatus Select(const AnalogOutputInt16& command, uint16_t index) override; + CommandStatus Operate(const AnalogOutputInt16& command, + uint16_t index, + IUpdateHandler& handler, + OperateType opType) override; + + CommandStatus Select(const AnalogOutputInt32& command, uint16_t index) override; + CommandStatus Operate(const AnalogOutputInt32& command, + uint16_t index, + IUpdateHandler& handler, + OperateType opType) override; + + CommandStatus Select(const AnalogOutputFloat32& command, uint16_t index) override; + CommandStatus Operate(const AnalogOutputFloat32& command, + uint16_t index, + IUpdateHandler& handler, + OperateType opType) override; + + CommandStatus Select(const AnalogOutputDouble64& command, uint16_t index) override; + CommandStatus Operate(const AnalogOutputDouble64& command, + uint16_t index, + IUpdateHandler& handler, + OperateType opType) override; + +protected: + virtual void DoSelect(const ControlRelayOutputBlock& command, uint16_t index) {} + virtual void DoOperate(const ControlRelayOutputBlock& command, uint16_t index, OperateType opType) {} + + virtual void DoSelect(const AnalogOutputInt16& command, uint16_t index) {} + virtual void DoOperate(const AnalogOutputInt16& command, uint16_t index, OperateType opType) {} + + virtual void DoSelect(const AnalogOutputInt32& command, uint16_t index) {} + virtual void DoOperate(const AnalogOutputInt32& command, uint16_t index, OperateType opType) {} + + virtual void DoSelect(const AnalogOutputFloat32& command, uint16_t index) {} + virtual void DoOperate(const AnalogOutputFloat32& command, uint16_t index, OperateType opType) {} + + virtual void DoSelect(const AnalogOutputDouble64& command, uint16_t index) {} + virtual void DoOperate(const AnalogOutputDouble64& command, uint16_t index, OperateType opType) {} + + CommandStatus status; + +public: + uint32_t numOperate; + uint32_t numSelect; + uint32_t numStart; + uint32_t numEnd; +}; + +/** + * A singleton command handler that always returns success + */ +class SuccessCommandHandler : public SimpleCommandHandler +{ +public: + static std::shared_ptr Create() + { + return std::make_shared(); + } + + SuccessCommandHandler() : SimpleCommandHandler(CommandStatus::SUCCESS) {} +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/StaticTypeBitfield.h b/product/src/fes/include/libdnp3/opendnp3/outstation/StaticTypeBitfield.h new file mode 100644 index 00000000..f0debac3 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/StaticTypeBitfield.h @@ -0,0 +1,60 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_STATICTYPEBITFIELD_H +#define OPENDNP3_STATICTYPEBITFIELD_H + +#include "opendnp3/gen/StaticTypeBitmask.h" + +#include + +namespace opendnp3 +{ + +/** + * A bitfield that describes a subset of all static types, e.g. { Binary, Analog } or {Analog, Counter, FrozenCounter } + */ +struct StaticTypeBitField +{ + StaticTypeBitField() : mask(0) {} + + StaticTypeBitField(uint16_t mask) : mask(mask) {} + + static StaticTypeBitField AllTypes() + { + return StaticTypeBitField(~0); + } + + bool IsSet(StaticTypeBitmask type) const + { + return (mask & static_cast(type)) != 0; + } + + StaticTypeBitField Except(StaticTypeBitmask type) const + { + return StaticTypeBitField(mask & ~static_cast(type)); + } + +private: + uint16_t mask; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/UpdateBuilder.h b/product/src/fes/include/libdnp3/opendnp3/outstation/UpdateBuilder.h new file mode 100644 index 00000000..e9361e60 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/UpdateBuilder.h @@ -0,0 +1,56 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_UPDATEBUILDER_H +#define OPENDNP3_UPDATEBUILDER_H + +#include "opendnp3/outstation/IUpdateHandler.h" +#include "opendnp3/outstation/Updates.h" + +namespace opendnp3 +{ + +class UpdateBuilder final : public IUpdateHandler +{ + +public: + bool Update(const Binary& meas, uint16_t index, EventMode mode = EventMode::Detect) override; + bool Update(const DoubleBitBinary& meas, uint16_t index, EventMode mode = EventMode::Detect) override; + bool Update(const Analog& meas, uint16_t index, EventMode mode = EventMode::Detect) override; + bool Update(const Counter& meas, uint16_t index, EventMode mode = EventMode::Detect) override; + bool FreezeCounter(uint16_t index, bool clear, EventMode mode = EventMode::Detect) override; + bool Update(const BinaryOutputStatus& meas, uint16_t index, EventMode mode = EventMode::Detect) override; + bool Update(const AnalogOutputStatus& meas, uint16_t index, EventMode mode = EventMode::Detect) override; + bool Update(const OctetString& meas, uint16_t index, EventMode mode = EventMode::Detect) override; + bool Update(const TimeAndInterval& meas, uint16_t index) override; + bool Modify(FlagsType type, uint16_t start, uint16_t stop, uint8_t flags) override; + + Updates Build(); + +private: + template bool AddMeas(const T& meas, uint16_t index, EventMode mode); + + bool Add(const update_func_t& fun); + + std::shared_ptr updates; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/outstation/Updates.h b/product/src/fes/include/libdnp3/opendnp3/outstation/Updates.h new file mode 100644 index 00000000..c5006712 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/outstation/Updates.h @@ -0,0 +1,64 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_UPDATES_H +#define OPENDNP3_UPDATES_H + +#include "opendnp3/outstation/IUpdateHandler.h" + +#include +#include +#include + +namespace opendnp3 +{ + +typedef std::function update_func_t; +typedef std::vector shared_updates_t; + +class Updates +{ + friend class UpdateBuilder; + +public: + void Apply(IUpdateHandler& handler) const + { + if (!updates) + return; + + for (auto& update : *updates) + { + update(handler); + } + } + + bool IsEmpty() const + { + return updates ? updates->empty() : true; + } + +private: + Updates(std::shared_ptr updates) : updates(std::move(updates)) {} + + const std::shared_ptr updates; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/util/Buffer.h b/product/src/fes/include/libdnp3/opendnp3/util/Buffer.h new file mode 100644 index 00000000..d29a613f --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/util/Buffer.h @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_BUFFER_H +#define OPENDNP3_BUFFER_H + +#include +#include + +namespace opendnp3 +{ + +struct Buffer +{ + Buffer() = default; + Buffer(const uint8_t* data, std::size_t length) : data(data), length(length) {} + + const uint8_t* data = nullptr; + std::size_t length = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/util/StaticOnly.h b/product/src/fes/include/libdnp3/opendnp3/util/StaticOnly.h new file mode 100644 index 00000000..ad631823 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/util/StaticOnly.h @@ -0,0 +1,37 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_STATICONLY_H +#define OPENDNP3_STATICONLY_H + +namespace opendnp3 +{ + +class StaticOnly +{ +private: + // prevent these functions + StaticOnly() = delete; + StaticOnly(const StaticOnly&) = delete; + StaticOnly& operator=(const StaticOnly&) = delete; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/util/TimeDuration.h b/product/src/fes/include/libdnp3/opendnp3/util/TimeDuration.h new file mode 100644 index 00000000..463396bd --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/util/TimeDuration.h @@ -0,0 +1,74 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_TIMEDURATION_H +#define OPENDNP3_TIMEDURATION_H + +#include +#include +#include + +namespace opendnp3 +{ + +/** + * Strong typing for millisecond based time durations + */ +class TimeDuration +{ + friend class Timestamp; + +public: + static TimeDuration Min(); + + static TimeDuration Max(); + + static TimeDuration Zero(); + + static TimeDuration Milliseconds(int64_t milliseconds); + + static TimeDuration Seconds(int64_t seconds); + + static TimeDuration Minutes(int64_t minutes); + + TimeDuration(); + + TimeDuration Double() const; + + bool IsNegative() const; + + std::string ToString() const; + + bool operator==(const TimeDuration& other) const; + bool operator<(const TimeDuration& other) const; + bool operator<=(const TimeDuration& other) const; + bool operator>(const TimeDuration& other) const; + bool operator>=(const TimeDuration& other) const; + + std::chrono::steady_clock::duration value; + +private: + template static TimeDuration FromValue(int64_t value); + + explicit TimeDuration(std::chrono::steady_clock::duration value); +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/util/Timestamp.h b/product/src/fes/include/libdnp3/opendnp3/util/Timestamp.h new file mode 100644 index 00000000..ce1cef1b --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/util/Timestamp.h @@ -0,0 +1,64 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_TIMESTAMP_H +#define OPENDNP3_TIMESTAMP_H + +#include "TimeDuration.h" + +namespace opendnp3 +{ + +/** + * Strong typing for millisecond-based monotonic timestamps + */ +class Timestamp +{ + +public: + static Timestamp Max(); + static Timestamp Min(); + + Timestamp(); + explicit Timestamp(std::chrono::steady_clock::time_point value); + + bool IsMax() const; + bool IsMin() const; + + // overflow capped to maximum value + Timestamp operator+(const TimeDuration& duration) const; + Timestamp& operator+=(const TimeDuration& duration); + Timestamp operator-(const TimeDuration& duration) const; + Timestamp& operator-=(const TimeDuration& duration); + + TimeDuration operator-(const Timestamp& timestamp) const; + + bool operator==(const Timestamp& other) const; + bool operator!=(const Timestamp& other) const; + bool operator<(const Timestamp& other) const; + bool operator<=(const Timestamp& other) const; + bool operator>(const Timestamp& other) const; + bool operator>=(const Timestamp& other) const; + + std::chrono::steady_clock::time_point value; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/util/UTCTimestamp.h b/product/src/fes/include/libdnp3/opendnp3/util/UTCTimestamp.h new file mode 100644 index 00000000..693fc803 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/util/UTCTimestamp.h @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_UTCTIMESTAMP_H +#define OPENDNP3_UTCTIMESTAMP_H + +#include + +namespace opendnp3 +{ + +/** + * Strong typing for UTCTimestamps + */ +class UTCTimestamp +{ + +public: + UTCTimestamp() = default; + + UTCTimestamp(uint64_t msSinceEpoch) : msSinceEpoch(msSinceEpoch) {} + + uint64_t msSinceEpoch = 0; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libdnp3/opendnp3/util/Uncopyable.h b/product/src/fes/include/libdnp3/opendnp3/util/Uncopyable.h new file mode 100644 index 00000000..4123c9c4 --- /dev/null +++ b/product/src/fes/include/libdnp3/opendnp3/util/Uncopyable.h @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2022 Step Function I/O, LLC + * + * Licensed to Green Energy Corp (www.greenenergycorp.com) and Step Function I/O + * LLC (https://stepfunc.io) under one or more contributor license agreements. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Green Energy Corp and Step Function I/O LLC license + * this file to you under the Apache License, Version 2.0 (the "License"); you + * may not use this file except in compliance with the License. You may obtain + * a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OPENDNP3_UNCOPYABLE_H +#define OPENDNP3_UNCOPYABLE_H + +namespace opendnp3 +{ + +/** + * Inherited classes will not have default copy/assignment. + */ +class Uncopyable +{ +protected: + Uncopyable() = default; // allow construction/destruction/move + Uncopyable(Uncopyable&&) = default; + virtual ~Uncopyable() = default; + Uncopyable& operator=(Uncopyable&&) = default; + +private: + // prevent these functions + Uncopyable(const Uncopyable&) = delete; + Uncopyable& operator=(const Uncopyable&) = delete; +}; + +} // namespace opendnp3 + +#endif diff --git a/product/src/fes/include/libiec61850/goose_publisher.h b/product/src/fes/include/libiec61850/goose_publisher.h new file mode 100644 index 00000000..0722d0c2 --- /dev/null +++ b/product/src/fes/include/libiec61850/goose_publisher.h @@ -0,0 +1,220 @@ +/* + * goose_publisher.h + * + * Copyright 2013-2020 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef GOOSE_PUBLISHER_H_ +#define GOOSE_PUBLISHER_H_ + +#include "iec61850_common.h" +#include "linked_list.h" +#include "mms_value.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup goosepub_api_group IEC 61850 GOOSE publisher API + */ +/**@{*/ + +#ifndef GOOSE_SV_COMM_PARAMETERS +#define GOOSE_SV_COMM_PARAMETERS + +typedef struct sCommParameters { + uint8_t vlanPriority; + uint16_t vlanId; + uint16_t appId; + uint8_t dstAddress[6]; +} CommParameters; + +#endif + +typedef struct sGoosePublisher* GoosePublisher; + +/** + * \brief Create a new GoosePublisher instance + * + * NOTE: The created GoosePublisher instance uses VLAN tags + * + * \param parameters GOOSE communication parameters + * \param interfaceId name of the Ethernet interface to use (e.g. "eth0") + */ +LIB61850_API GoosePublisher +GoosePublisher_create(CommParameters* parameters, const char* interfaceID); + +/** + * \brief Create a new GoosePublisher instance + * + * \param parameters GOOSE communication parameters + * \param interfaceId name of the Ethernet interface to use (e.g. "eth0") + * \param useVlanTag enable or disable the usage of VLAN tags in GOOSE messages + */ +LIB61850_API GoosePublisher +GoosePublisher_createEx(CommParameters* parameters, const char* interfaceID, bool useVlanTag); + +/** + * \brief Release all resources of the GoosePublisher instance + * + * \param self GoosePublisher instance + */ +LIB61850_API void +GoosePublisher_destroy(GoosePublisher self); + +/** + * \brief Publish a GOOSE message + * + * NOTE: This function also increased the sequence number of the GOOSE publisher + * + * \param self GoosePublisher instance + * \param dataSet the GOOSE data set to send + */ +LIB61850_API int +GoosePublisher_publish(GoosePublisher self, LinkedList dataSet); + +/** + * \brief Publish a GOOSE message and store the sent message in the provided buffer + * + * \param self GoosePublisher instance + * \param dataSet the GOOSE data set to send + * \param msgBuf to store the sent message + * \param[out] msgLen the length of the sent message + * \param bufSize the size of the buffer to store the sent message + */ +LIB61850_API int +GoosePublisher_publishAndDump(GoosePublisher self, LinkedList dataSet, char* msgBuf, int32_t* msgLen, int32_t bufSize); + +/** + * \brief Sets the GoID used by the GoosePublisher instance + * + * \param self GoosePublisher instance + * \param goID the GoId string + */ +LIB61850_API void +GoosePublisher_setGoID(GoosePublisher self, char* goID); + +/** + * \brief Sets the GoCB reference used by the GoosePublisher instance + * + * \param self GoosePublisher instance + * \param goCbRef the GoCB reference string + */ +LIB61850_API void +GoosePublisher_setGoCbRef(GoosePublisher self, char* goCbRef); + +/** + * \brief Sets the time allowed to live value of the GOOSE messages + * + * \param self GoosePublisher instance + * \param timeAllowedToLive the time allowed to live value in milliseconds + */ +LIB61850_API void +GoosePublisher_setTimeAllowedToLive(GoosePublisher self, uint32_t timeAllowedToLive); + +/** + * \brief Sets the data set reference used by the GoosePublisher instance + * + * \param self GoosePublisher instance + * \param dataSetRef the data set reference string + */ +LIB61850_API void +GoosePublisher_setDataSetRef(GoosePublisher self, char* dataSetRef); + +/** + * \brief Sets the configuration revision used by the GoosePublisher instance + * + * \param self GoosePublisher instance + * \param confRev the configuration revision value + */ +LIB61850_API void +GoosePublisher_setConfRev(GoosePublisher self, uint32_t confRev); + +/** + * \brief Sets simulation flag in sent GOOSE messages + * + * \param self GoosePublisher instance + * \param simulation the value of the simulation flag + */ +LIB61850_API void +GoosePublisher_setSimulation(GoosePublisher self, bool simulation); + +/** + * \brief Manually sets the state number (stNum) of the GoosePublisher instance + * + * NOTE: Only for testing! Use \ref GoosePublisher_increaseStNum instead whenever + * a data set member changes. + * + * \param self GoosePublisher instance + * \param stNum the state number of the next GOOSE message to send + */ +LIB61850_API void +GoosePublisher_setStNum(GoosePublisher self, uint32_t stNum); + +/** + * \brief Manually sets the sequence number (sqNum) of the GoosePublisher instance + * + * NOTE: Only for testing! The sequence number is increase manually whenever \ref GoosePublisher_publish is called. + * + * \param self GoosePublisher instance + * \param stNum the state number of the next GOOSE message to send + */ +LIB61850_API void +GoosePublisher_setSqNum(GoosePublisher self, uint32_t sqNum); + +/** + * \brief Sets the needs commission flag in sent GOOSE messages + * + * \param self GoosePublisher instance + * \param ndsCom the value of the needs commission flag + */ +LIB61850_API void +GoosePublisher_setNeedsCommission(GoosePublisher self, bool ndsCom); + +/** + * \brief Increase the state number (stNum) of the GoosePublisher instance + * + * The state number should be increased whenever a member of the GOOSE data set changed + * + * NOTE: This function also resets the sequence number (sqNum) + * + * \param self GoosePublisher instance + */ +LIB61850_API uint64_t +GoosePublisher_increaseStNum(GoosePublisher self); + +/** + * \brief Reset state and sequence number of the GoosePublisher instance + * + * This function will set the state number (stNum) to 1 and the sequence number (sqNum) to 0. + * + * \param self GoosePublisher instance + */ +LIB61850_API void +GoosePublisher_reset(GoosePublisher self); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif /* GOOSE_PUBLISHER_H_ */ diff --git a/product/src/fes/include/libiec61850/goose_receiver.h b/product/src/fes/include/libiec61850/goose_receiver.h new file mode 100644 index 00000000..5d041d26 --- /dev/null +++ b/product/src/fes/include/libiec61850/goose_receiver.h @@ -0,0 +1,189 @@ +/* + * goose_receiver.h + * + * Copyright 2014-2019 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef GOOSE_RECEIVER_H_ +#define GOOSE_RECEIVER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "hal_ethernet.h" +#include "goose_subscriber.h" + +/** + * \addtogroup goose_api_group + */ +/**@{*/ + +typedef struct sGooseReceiver* GooseReceiver; + +/** + * \brief Create a new receiver instance + * + * A GooseReceiver instance is used to handle all GOOSE messages received on a specific + * network interface. + * + * \return the new GooseReceiver instance + */ +LIB61850_API GooseReceiver +GooseReceiver_create(void); + +/** + * \brief Create a new receiver instance using the provided buffer instead of allocating an own buffer + * + * A GooseReceiver instance is used to handle all GOOSE messages received on a specific + * network interface. + * + * \param buffer buffer to store Ethernet messages or NULL when using \ref GooseReceiver_handleMessage + * + * \return the new GooseReceiver instance + */ +LIB61850_API GooseReceiver +GooseReceiver_createEx(uint8_t* buffer); + +/** + * \brief sets the interface for the GOOSE receiver + * + * \param self the GooseReceiver instance + * \param interfaceId + */ +LIB61850_API void +GooseReceiver_setInterfaceId(GooseReceiver self, const char* interfaceId); + +/** + * \brief return the interface ID used by the GOOSE receiver + * + * \param self the GosseReceiver instance + * + * \return the Ethernet interface ID string + */ +LIB61850_API const char* +GooseReceiver_getInterfaceId(GooseReceiver self); + +/** + * \brief Add a subscriber to this receiver instance + * + * NOTE: Do not call this function while the receiver is running (after GooseReceiver_start + * has been called)! + * + * \param self the GooseReceiver instance + * \param subscriber the GooseSubscriber instance to add + */ +LIB61850_API void +GooseReceiver_addSubscriber(GooseReceiver self, GooseSubscriber subscriber); + +/** + * \brief Remove a subscriber from this receiver instance + * + * NOTE: Do not call this function while the receiver is running (after GooseReceiver_start + * has been called)! + * + * \param self the GooseReceiver instance + * \param subscriber the GooseSubscriber instance to remove + */ +LIB61850_API void +GooseReceiver_removeSubscriber(GooseReceiver self, GooseSubscriber subscriber); + +/** + * \brief start the GOOSE receiver in a separate thread + * + * \param self the GooseReceiver instance + */ +LIB61850_API void +GooseReceiver_start(GooseReceiver self); + +/** + * \brief stop the GOOSE receiver running in a separate thread + * + * This function is used to stop the receiver thread started with GooseReceiver_start + * + * \param self the GooseReceiver instance + */ +LIB61850_API void +GooseReceiver_stop(GooseReceiver self); + +/** + * \brief Check if GOOSE receiver is running + * + * Can be used to check if \ref GooseReceiver_start has been successful. + * + * \param self the GooseReceiver instance + * + * \return true if GOOSE receiver is running, false otherwise + */ +LIB61850_API bool +GooseReceiver_isRunning(GooseReceiver self); + +/** + * \brief Free all resource of the GooseReceiver and all installed GooseSubscribers + * + * \param self the GooseReceiver instance + */ +LIB61850_API void +GooseReceiver_destroy(GooseReceiver self); + +/*************************************** + * Functions for non-threaded operation + ***************************************/ +LIB61850_API EthernetSocket +GooseReceiver_startThreadless(GooseReceiver self); + +LIB61850_API void +GooseReceiver_stopThreadless(GooseReceiver self); + +/** + * \brief Parse GOOSE messages if they are available + * + * Call after reception of an Ethernet frame or periodically + * + * \param self the receiver object + * + * \return true if a message was available and has been parsed, false otherwise + */ +LIB61850_API bool +GooseReceiver_tick(GooseReceiver self); + +/** + * \brief Parse a GOOSE message + * + * Call after reception of an Ethernet frame (can be used as an alternative to \ref GooseReceiver_tick + * to avoid implementing the Ethernet HAL) + * + * \param self the receiver object + * \param buffer a buffer containing the complete Ethernet message + * \param size size of the Ethernet message + */ +LIB61850_API void +GooseReceiver_handleMessage(GooseReceiver self, uint8_t* buffer, int size); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + + +#endif /* GOOSE_RECEIVER_H_ */ diff --git a/product/src/fes/include/libiec61850/goose_subscriber.h b/product/src/fes/include/libiec61850/goose_subscriber.h new file mode 100644 index 00000000..7408d6b5 --- /dev/null +++ b/product/src/fes/include/libiec61850/goose_subscriber.h @@ -0,0 +1,318 @@ +/* + * goose_subscriber.h + * + * Copyright 2013-2021 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef GOOSE_SUBSCRIBER_H_ +#define GOOSE_SUBSCRIBER_H_ + +#include "libiec61850_common_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup goose_api_group IEC 61850 GOOSE subscriber API + */ +/**@{*/ + +#include "mms_value.h" + +typedef enum +{ + GOOSE_PARSE_ERROR_NO_ERROR = 0, + GOOSE_PARSE_ERROR_UNKNOWN_TAG, + GOOSE_PARSE_ERROR_TAGDECODE, + GOOSE_PARSE_ERROR_SUBLEVEL, + GOOSE_PARSE_ERROR_OVERFLOW, + GOOSE_PARSE_ERROR_UNDERFLOW, + GOOSE_PARSE_ERROR_TYPE_MISMATCH, + GOOSE_PARSE_ERROR_LENGTH_MISMATCH, + GOOSE_PARSE_ERROR_INVALID_PADDING +} GooseParseError; + +typedef struct sGooseSubscriber* GooseSubscriber; + +/** + * \brief user provided callback function that will be invoked when a GOOSE message is received. + * + * \param subscriber the subscriber object that invoked the callback function, + * \param parameter a user provided parameter that will be passed to the callback function + */ +typedef void (*GooseListener)(GooseSubscriber subscriber, void* parameter); + +/** + * \brief create a new GOOSE subscriber instance. + * + * A new GOOSE subscriber will be created and connected to a specific GOOSE control block reference. + * + * The parameter goCbRef has to be given in MMS like notation (as it also will appear in the GOOSE message + * sent by the publisher). An example could be "simpleIOGenericIO/LLN0$GO$gcbEvents". + * + * The data set values contained in a GOOSE message will be written to the optionally provided MmsValue instance. + * The MmsValue object has to be of type MMS_ARRAY. The array elements need to be of the same type as + * the data set elements. It is intended that the provided MmsValue instance has been created by the + * IedConnection_getDataSet() method before. + * + * If NULL is given as dataSetValues it will be created the first time when a appropriate GOOSE message + * is received. + * + * \param goCbRef a string containing the object reference of the GOOSE Control Block (GoCB) in MMS notation the + * GOOSE publisher uses. + * \param dataSetValues the MmsValue object where the data set values will be written or NULL. + */ +LIB61850_API GooseSubscriber +GooseSubscriber_create(char* goCbRef, MmsValue* dataSetValues); + +/** + * \brief Get the GoId value of the received GOOSE message + * + * \param self GooseSubscriber instance to operate on. + */ +LIB61850_API char* +GooseSubscriber_getGoId(GooseSubscriber self); + +/** + * \brief Get the GOOSE Control Block reference value of the received GOOSE message + * + * \param self GooseSubscriber instance to operate on. + */ +LIB61850_API char* +GooseSubscriber_getGoCbRef(GooseSubscriber self); + +/** + * \brief Get the DatSet value of the received GOOSE message + * + * \param self GooseSubscriber instance to operate on. + */ +LIB61850_API char* +GooseSubscriber_getDataSet(GooseSubscriber self); + +/** + * \brief set the destination mac address used by the subscriber to filter relevant messages. + * + * If dstMac is set the subscriber will ignore all messages with other dstMac values. + * + * \param self GooseSubscriber instance to operate on. + * \param dstMac the destination mac address + */ +LIB61850_API void +GooseSubscriber_setDstMac(GooseSubscriber self, uint8_t dstMac[6]); + +/** + * \brief set the APPID used by the subscriber to filter relevant messages. + * + * If APPID is set the subscriber will ignore all messages with other APPID values. + * + * \param self GooseSubscriber instance to operate on. + * \param appId the APPID value the subscriber should use to filter messages + */ +LIB61850_API void +GooseSubscriber_setAppId(GooseSubscriber self, uint16_t appId); + +/** + * \brief Check if subscriber state is valid + * + * A GOOSE subscriber is valid if TimeAllowedToLive timeout is not elapsed and GOOSE + * message were received with correct state and sequence ID. + * + */ +LIB61850_API bool +GooseSubscriber_isValid(GooseSubscriber self); + +/** + * \brief Get parse error in case of invalid subscriber state + * + * \param self GooseSubscriber instance to operate on. + * + * \return the error code representing a message parse problem of the last received message + */ +LIB61850_API GooseParseError +GooseSubscriber_getParseError(GooseSubscriber self); + +/** + * \brief Destroy the GooseSubscriber instance + * + * Do not call this function when the GooseSubscriber instance was added to a GooseReceiver. + * The GooseReceiver will call the destructor when \ref GooseReceiver_destroy is called! + * + * \param self GooseSubscriber instance to operate on. + */ +LIB61850_API void +GooseSubscriber_destroy(GooseSubscriber self); + +/** + * \brief set a callback function that will be invoked when a GOOSE message has been received. + * + * \param self GooseSubscriber instance to operate on. + * \param listener user provided callback function + * \param parameter a user provided parameter that will be passed to the callback function + */ +LIB61850_API void +GooseSubscriber_setListener(GooseSubscriber self, GooseListener listener, void* parameter); + +/** + * \brief Get the APPID value of the received GOOSE message + * + * \param self GooseSubscriber instance to operate on. + */ +LIB61850_API int32_t +GooseSubscriber_getAppId(GooseSubscriber self); + +/** + * \brief Get the source MAC address of the received GOOSE message + * + * \param self GooseSubscriber instance to operate on. + * \param buffer buffer to store the MAC address (at least 6 byte) + */ +LIB61850_API void +GooseSubscriber_getSrcMac(GooseSubscriber self, uint8_t* buffer); + +/** + * \brief Get the destination MAC address of the received GOOSE message + * + * \param self GooseSubscriber instance to operate on. + * \param buffer buffer to store the MAC address (at least 6 byte) + */ +LIB61850_API void +GooseSubscriber_getDstMac(GooseSubscriber self, uint8_t* buffer); + +/** + * \brief return the state number (stNum) of the last received GOOSE message. + * + * The state number is increased if any of the values in the GOOSE data set changed due to a valid trigger condition + * + * \param self GooseSubscriber instance to operate on. + * + * \return the state number of the last received GOOSE message + */ +LIB61850_API uint32_t +GooseSubscriber_getStNum(GooseSubscriber self); + +/** + * \brief return the sequence number (sqNum) of the last received GOOSE message. + * + * The sequence number is increased for every consecutive GOOSE message without state change. When a state change occurs (stNum is increased) + * then the sequence number (sqNum) will be reset. + * + * \param self GooseSubscriber instance to operate on. + * + * \return the sequence number of the last received GOOSE message + */ +LIB61850_API uint32_t +GooseSubscriber_getSqNum(GooseSubscriber self); + +/** + * \brief returns the test flag of the last received GOOSE message + * + * IMPORTANT: Goose messages with test=TRUE have to be ignored to be standard compliant! + * + * \param self GooseSubscriber instance to operate on. + * + * \return the state of the test flag of the last received GOOSE message. + */ +LIB61850_API bool +GooseSubscriber_isTest(GooseSubscriber self); + +/** + * \brief returns the confRev value of the last received GOOSE message + * + * \param self GooseSubscriber instance to operate on. + * + * \return the confRev value of the last received GOOSE message. If the message does not contain such + * a value the result is always 0 + */ +LIB61850_API uint32_t +GooseSubscriber_getConfRev(GooseSubscriber self); + +/** + * \brief returns the value of the ndsCom (needs commission) flag of the last received GOOSE message. + * + * IMPORTANT: Goose messages with ndsCom=TRUE have to be ignored to be standard compliant! + * + * \param self GooseSubscriber instance to operate on. + * + * \return the state of the ndsCom flag of the last received GOOSE message. + * + */ +LIB61850_API bool +GooseSubscriber_needsCommission(GooseSubscriber self); + +/** + * \brief Get the TimeAllowedToLive value of the last received message. + * + * \param self GooseSubscriber instance to operate on. + * + * \return the TimeAllowedToLive value of the last received GOOSE message in milliseconds. + */ +LIB61850_API uint32_t +GooseSubscriber_getTimeAllowedToLive(GooseSubscriber self); + +/** + * \brief Get the timestamp of the last received message. + * + * \param self GooseSubscriber instance to operate on. + * + * \return the timestamp value of the last received GOOSE message in milliseconds since epoch (1.1.1970 UTC). + */ +LIB61850_API uint64_t +GooseSubscriber_getTimestamp(GooseSubscriber self); + +/** + * \brief get the data set values received with the last report + * + * Note: To prevent data corruption. The MmsValue instance received should + * only be used inside of the callback function, when the GOOSE receiver is + * running in a separate thread. + * + * \param self GooseSubscriber instance to operate on. + * + * \return MmsValue instance of the report data set + */ +LIB61850_API MmsValue* +GooseSubscriber_getDataSetValues(GooseSubscriber self); + +LIB61850_API bool +GooseSubscriber_isVlanSet(GooseSubscriber self); + +LIB61850_API uint16_t +GooseSubscriber_getVlanId(GooseSubscriber self); + +LIB61850_API uint8_t +GooseSubscriber_getVlanPrio(GooseSubscriber self); + +/** + * \brief Configure the Subscriber to listen to any received GOOSE message + * + * NOTE: When the observer flag is set the subscriber also has access to the + * goCbRef, goId, and datSet values of the received GOOSE message + */ +LIB61850_API void +GooseSubscriber_setObserver(GooseSubscriber self); +#ifdef __cplusplus +} +#endif + + +/**@}*/ + +#endif /* GOOSE_SUBSCRIBER_H_ */ diff --git a/product/src/fes/include/libiec61850/hal_base.h b/product/src/fes/include/libiec61850/hal_base.h new file mode 100644 index 00000000..6fe3a417 --- /dev/null +++ b/product/src/fes/include/libiec61850/hal_base.h @@ -0,0 +1,51 @@ +/* + * hal_base.h + * + * Copyright 2013-2021 Michael Zillgith + * + * This file is part of Platform Abstraction Layer (libpal) + * for libiec61850, libmms, and lib60870. + */ + +#ifndef HAL_INC_HAL_BASE_H_ +#define HAL_INC_HAL_BASE_H_ + +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +#define ATTRIBUTE_PACKED __attribute__ ((__packed__)) +#else +#define ATTRIBUTE_PACKED +#endif + +#ifndef DEPRECATED +#if defined(__GNUC__) || defined(__clang__) + #define DEPRECATED __attribute__((deprecated)) +#else + #define DEPRECATED +#endif +#endif + +#if defined _WIN32 || defined __CYGWIN__ + #ifdef EXPORT_FUNCTIONS_FOR_DLL + #define PAL_API __declspec(dllexport) + #else + #define PAL_API + #endif + + #define PAL_INTERNAL +#else + #if __GNUC__ >= 4 + #define PAL_API __attribute__ ((visibility ("default"))) + #define PAL_INTERNAL __attribute__ ((visibility ("hidden"))) + #else + #define PAL_API + #define PAL_INTERNAL + #endif +#endif + +#endif /* HAL_INC_HAL_BASE_H_ */ diff --git a/product/src/fes/include/libiec61850/hal_ethernet.h b/product/src/fes/include/libiec61850/hal_ethernet.h new file mode 100644 index 00000000..d7e3d207 --- /dev/null +++ b/product/src/fes/include/libiec61850/hal_ethernet.h @@ -0,0 +1,190 @@ +/* + * ethernet_hal.h + * + * Copyright 2013-2021 Michael Zillgith + * + * This file is part of Platform Abstraction Layer (libpal) + * for libiec61850, libmms, and lib60870. + */ + +#ifndef ETHERNET_HAL_H_ +#define ETHERNET_HAL_H_ + +#include "hal_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \addtogroup hal + * + * @{ + */ + +/** + * @defgroup HAL_ETHERNET Direct access to the Ethernet layer (optional - required by GOOSE and Sampled Values) + * + * @{ + */ + + +/** + * \brief Opaque handle that represents an Ethernet "socket". + */ +typedef struct sEthernetSocket* EthernetSocket; + +/** Opaque reference for a set of Ethernet socket handles */ +typedef struct sEthernetHandleSet* EthernetHandleSet; + +typedef enum { + ETHERNET_SOCKET_MODE_PROMISC, /**<< receive all Ethernet messages */ + ETHERNET_SOCKET_MODE_ALL_MULTICAST, /**<< receive all multicast messages */ + ETHERNET_SOCKET_MODE_MULTICAST, /**<< receive only specific multicast messages */ + ETHERNET_SOCKET_MODE_HOST_ONLY /**<< receive only messages for the host */ +} EthernetSocketMode; + +/** + * \brief Create a new connection handle set (EthernetHandleSet) + * + * \return new EthernetHandleSet instance + */ +PAL_API EthernetHandleSet +EthernetHandleSet_new(void); + +/** + * \brief add a socket to an existing handle set + * + * \param self the HandleSet instance + * \param sock the socket to add + */ +PAL_API void +EthernetHandleSet_addSocket(EthernetHandleSet self, const EthernetSocket sock); + +/** + * \brief remove a socket from an existing handle set + * + * \param self the HandleSet instance + * \param sock the socket to add + */ +PAL_API void +EthernetHandleSet_removeSocket(EthernetHandleSet self, const EthernetSocket sock); + +/** + * \brief wait for a socket to become ready + * + * This function is corresponding to the BSD socket select function. + * The function will return after \p timeoutMs ms if no data is pending. + * + * \param self the HandleSet instance + * \param timeoutMs in milliseconds (ms) + * \return It returns the number of sockets on which data is pending + * or 0 if no data is pending on any of the monitored connections. + * The function shall return -1 if a socket error occures. + */ +PAL_API int +EthernetHandleSet_waitReady(EthernetHandleSet self, unsigned int timeoutMs); + +/** + * \brief destroy the EthernetHandleSet instance + * + * \param self the HandleSet instance to destroy + */ +PAL_API void +EthernetHandleSet_destroy(EthernetHandleSet self); + +/** + * \brief Return the MAC address of an Ethernet interface. + * + * The result are the six bytes that make up the Ethernet MAC address. + * + * \param interfaceId the ID of the Ethernet interface + * \param addr pointer to a buffer to store the MAC address + */ +PAL_API void +Ethernet_getInterfaceMACAddress(const char* interfaceId, uint8_t* addr); + +/** + * \brief Create an Ethernet socket using the specified interface and + * destination MAC address. + * + * \param interfaceId the ID of the Ethernet interface + * \param destAddress byte array that contains the Ethernet destination MAC address for sending + */ +PAL_API EthernetSocket +Ethernet_createSocket(const char* interfaceId, uint8_t* destAddress); + +/** + * \brief destroy the ethernet socket + * + * \param ethSocket the ethernet socket handle + */ +PAL_API void +Ethernet_destroySocket(EthernetSocket ethSocket); + +PAL_API void +Ethernet_sendPacket(EthernetSocket ethSocket, uint8_t* buffer, int packetSize); + +/* + * \brief set the receive mode of the Ethernet socket + * + * NOTE: When not implemented the the implementation has to be able to receive + * all messages required by GOOSE and/or SV (usually multicast addresses). + * + * \param ethSocket the ethernet socket handle + * \param mode the mode of the socket + */ +PAL_API void +Ethernet_setMode(EthernetSocket ethSocket, EthernetSocketMode mode); + +/** + * \brief Add a multicast address to be received by the Ethernet socket + * + * Used when mode is ETHERNET_SOCKET_MODE_MULTICAST + * + * \param ethSocket the ethernet socket handle + * \param multicastAddress the multicast Ethernet address (this has to be a byte buffer of at least 6 byte) + */ +PAL_API void +Ethernet_addMulticastAddress(EthernetSocket ethSocket, uint8_t* multicastAddress); + +/* + * \brief set a protocol filter for the specified etherType + * + * NOTE: Implementation is not required but can improve the performance when the ethertype + * filtering can be done on OS/network stack layer. + * + * \param ethSocket the ethernet socket handle + * \param etherType the ether type of messages to accept + */ +PAL_API void +Ethernet_setProtocolFilter(EthernetSocket ethSocket, uint16_t etherType); + +/** + * \brief receive an ethernet packet (non-blocking) + * + * \param ethSocket the ethernet socket handle + * \param buffer the buffer to copy the message to + * \param bufferSize the maximum size of the buffer + * + * \return size of message received in bytes + */ +PAL_API int +Ethernet_receivePacket(EthernetSocket ethSocket, uint8_t* buffer, int bufferSize); + +/** + * \brief Indicates if runtime provides support for direct Ethernet access + * + * \return true if Ethernet support is available, false otherwise + */ +PAL_API bool +Ethernet_isSupported(void); + +/*! @} */ + +/*! @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* ETHERNET_HAL_H_ */ diff --git a/product/src/fes/include/libiec61850/hal_filesystem.h b/product/src/fes/include/libiec61850/hal_filesystem.h new file mode 100644 index 00000000..56184117 --- /dev/null +++ b/product/src/fes/include/libiec61850/hal_filesystem.h @@ -0,0 +1,166 @@ +/* + * filesystem_hal.h + * + * Copyright 2013-2021 Michael Zillgith + * + * This file is part of Platform Abstraction Layer (libpal) + * for libiec61850, libmms, and lib60870. + */ + +#ifndef FILESYSTEM_HAL_H_ +#define FILESYSTEM_HAL_H_ + +#include "hal_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \addtogroup hal + * + * @{ + */ + +/** + * @defgroup HAL_FILESYSTEM Interface to the native file system (optional) + * + * @{ + */ + +typedef void* FileHandle; +typedef struct sDirectoryHandle* DirectoryHandle; + +#ifndef CONFIG_SYSTEM_FILE_SEPARATOR +#define CONFIG_SYSTEM_FILE_SEPARATOR '/' +#endif + +/** + * \brief open a file + * + * \param pathName full name (path + filename) of the file + * \param readWrite true opens the file with read and write access - false opens for read access only + * + * \return a handle for the file. Has to be used by subsequent calls to file functions to identify the file or + * NULL if opening fails + */ +PAL_API FileHandle +FileSystem_openFile(char* pathName, bool readWrite); + +/** + * \brief read from an open file + * + * This function will read the next block of the file. The maximum number of bytes to read + * is given. A call to this function will move the file position by the number of bytes read. + * If the file position reaches the end of file then subsequent calls of this function shall + * return 0. + * + * \param handle the file handle to identify the file + * \param buffer the buffer to write the read data + * \param maxSize maximum number of bytes to read + * + * \return the number of bytes actually read + */ +PAL_API int +FileSystem_readFile(FileHandle handle, uint8_t* buffer, int maxSize); + +/** + * \brief write to an open file + * + * \param handle the file handle to identify the file + * \param buffer the buffer with the data to write + * \param size the number of bytes to write + * + * \return the number of bytes actually written + */ +PAL_API int +FileSystem_writeFile(FileHandle handle, uint8_t* buffer, int size); + +/** + * \brief close an open file + * + * \param handle the file handle to identify the file + */ +PAL_API void +FileSystem_closeFile(FileHandle handle); + +/** + * \brief return attributes of the given file + * + * This function is used by the MMS layer to determine basic file attributes. + * The size of the file has to be returned in bytes. The timestamp of the last modification has + * to be returned as milliseconds since Unix epoch - or 0 if this function is not supported. + * + * \param pathName full name (path + filename) of the file + * \param fileSize a pointer where to store the file size + * \param lastModificationTimestamp is used to store the timestamp of last modification of the file + * + * \return true if file exists, false if not + */ +PAL_API bool +FileSystem_getFileInfo(char* filename, uint32_t* fileSize, uint64_t* lastModificationTimestamp); + +/** + * \brief delete a file + * + * \param pathName full name (path + filename) of the file + * + * \return true on success, false on error + */ +PAL_API bool +FileSystem_deleteFile(char* filename); + +/** + * \brief rename a file + * + * \param oldFileName current full name (path + filename) of the file + * \param newFileName new full name (path + filename) of the file + * + * \return true on success, false on error + */ +PAL_API bool +FileSystem_renameFile(char* oldFilename, char* newFilename); + +/** + * \brief open the directoy with the specified name + * + * \param directoryName + * + * \return a handle for the opened directory to be used in subsequent calls to identify the directory + */ +PAL_API DirectoryHandle +FileSystem_openDirectory(char* directoryName); + +/** + * \brief read the next directory entry + * + * This function returns the next directory entry. The entry is only a valid pointer as long as the + * FileSystem_closeDirectory or another FileSystem_readDirectory function is not called for the given + * DirectoryHandle. + * + * \param directory the handle to identify the directory + * \param isDirectory return value that indicates if the directory entry is itself a directory (true) + * + * \return the name of the directory entry + */ +PAL_API char* +FileSystem_readDirectory(DirectoryHandle directory, bool* isDirectory); + + +/** + * \brief close a directory + * + * \param directory the handle to identify the directory + */ +PAL_API void +FileSystem_closeDirectory(DirectoryHandle directory); + + +/*! @} */ + +/*! @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* FILESYSTEM_HAL_H_ */ diff --git a/product/src/fes/include/libiec61850/hal_socket.h b/product/src/fes/include/libiec61850/hal_socket.h new file mode 100644 index 00000000..bddb98f1 --- /dev/null +++ b/product/src/fes/include/libiec61850/hal_socket.h @@ -0,0 +1,358 @@ +/* + * socket_hal.h + * + * Copyright 2013-2021 Michael Zillgith + * + * This file is part of Platform Abstraction Layer (libpal) + * for libiec61850, libmms, and lib60870. + */ + +#ifndef SOCKET_HAL_H_ +#define SOCKET_HAL_H_ + +#include "hal_base.h" + +/** + * \file hal_socket.h + * \brief Abstraction layer TCP/IP sockets + * Has to be implemented for CS 104 TCP/IP. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \defgroup hal Platform (Hardware/OS) abstraction layer + * + * Platform abstraction layer. These functions have to be implemented when the library is + * to be ported to new platforms. It might not be required to implement all interfaces + * depending on the required library features. + * + * @{ + */ + +/** + * @defgroup HAL_SOCKET Interface to the TCP/IP stack (abstract socket layer) + * + * Thread and Socket abstraction layer. This functions have to be implemented to + * port lib60870 to a new hardware/OS platform when TCP/IP is required. + * + * @{ + */ + +/** Opaque reference for a server socket instance */ +typedef struct sServerSocket* ServerSocket; + +typedef struct sUdpSocket* UdpSocket; + +/** Opaque reference for a client or connection socket instance */ +typedef struct sSocket* Socket; + +/** Opaque reference for a set of server and socket handles */ +typedef struct sHandleSet* HandleSet; + +/** State of an asynchronous connect */ +typedef enum +{ + SOCKET_STATE_CONNECTING = 0, + SOCKET_STATE_FAILED = 1, + SOCKET_STATE_CONNECTED = 2 +} SocketState; + + +/** + * \brief Create a new connection handle set (HandleSet) + * + * \return new HandleSet instance + */ +PAL_API HandleSet +Handleset_new(void); + +/** + * \brief Reset the handle set for reuse + */ +PAL_API void +Handleset_reset(HandleSet self); + +/** + * \brief add a socket to an existing handle set + * + * \param self the HandleSet instance + * \param sock the socket to add + */ +PAL_API void +Handleset_addSocket(HandleSet self, const Socket sock); + +/** + * \brief remove a socket from an existing handle set + */ +void +Handleset_removeSocket(HandleSet self, const Socket sock); + +/** + * \brief wait for a socket to become ready + * + * This function is corresponding to the BSD socket select function. + * It returns the number of sockets on which data is pending or 0 if no data is pending + * on any of the monitored connections. The function will return after "timeout" ms if no + * data is pending. + * The function shall return -1 if a socket error occures. + * + * \param self the HandleSet instance + * \param timeout in milliseconds (ms) + * \return It returns the number of sockets on which data is pending + * or 0 if no data is pending on any of the monitored connections. + * The function shall return -1 if a socket error occures. + */ +PAL_API int +Handleset_waitReady(HandleSet self, unsigned int timeoutMs); + +/** + * \brief destroy the HandleSet instance + * + * \param self the HandleSet instance to destroy + */ +PAL_API void +Handleset_destroy(HandleSet self); + +/** + * \brief Create a new TcpServerSocket instance + * + * Implementation of this function is MANDATORY if server functionality is required. + * + * \param address ip address or hostname to listen on + * \param port the TCP port to listen on + * + * \return the newly create TcpServerSocket instance + */ +PAL_API ServerSocket +TcpServerSocket_create(const char* address, int port); + +PAL_API UdpSocket +UdpSocket_create(void); + +PAL_API bool +UdpSocket_bind(UdpSocket self, const char* address, int port); + +PAL_API bool +UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, int msgSize); + +/** + * \brief Receive data from UDP socket (store data and (optionally) the IP address of the sender + * + * \param self UDP socket instance + * \param address (optional) buffer to store the IP address as string + * \param maxAddrSize (optional) size of the provided buffer to store the IP address + * \param msg buffer to store the UDP message data + * \param msgSize the maximum size of the message to receive + * + * \return number of received bytes or -1 in case of an error + */ +PAL_API int +UdpSocket_receiveFrom(UdpSocket self, char* address, int maxAddrSize, uint8_t* msg, int msgSize); + + +PAL_API void +ServerSocket_listen(ServerSocket self); + +/** + * \brief accept a new incoming connection (non-blocking) + * + * This function shall accept a new incoming connection. It is non-blocking and has to + * return NULL if no new connection is pending. + * + * Implementation of this function is MANDATORY if server functionality is required. + * + * NOTE: The behaviour of this function changed with version 0.8! + * + * \param self server socket instance + * + * \return handle of the new connection socket or NULL if no new connection is available + */ +PAL_API Socket +ServerSocket_accept(ServerSocket self); + +/** + * \brief active TCP keep alive for socket and set keep alive parameters + * + * NOTE: implementation is mandatory for IEC 61850 MMS + * + * \param self server socket instance + * \param idleTime time (in s) between last received message and first keep alive message + * \param interval time (in s) between subsequent keep alive messages if no ACK received + * \param count number of not missing keep alive ACKs until socket is considered dead + */ +PAL_API void +Socket_activateTcpKeepAlive(Socket self, int idleTime, int interval, int count); + +/** + * \brief set the maximum number of pending connections in the queue + * + * Implementation of this function is OPTIONAL. + * + * \param self the server socket instance + * \param backlog the number of pending connections in the queue + * + */ +PAL_API void +ServerSocket_setBacklog(ServerSocket self, int backlog); + +/** + * \brief destroy a server socket instance + * + * Free all resources allocated by this server socket instance. + * + * Implementation of this function is MANDATORY if server functionality is required. + * + * \param self server socket instance + */ +PAL_API void +ServerSocket_destroy(ServerSocket self); + +/** + * \brief create a TCP client socket + * + * Implementation of this function is MANDATORY if client functionality is required. + * + * \return a new client socket instance. + */ +PAL_API Socket +TcpSocket_create(void); + +/** + * \brief set the timeout to establish a new connection + * + * \param self the client socket instance + * \param timeoutInMs the timeout in ms + */ +PAL_API void +Socket_setConnectTimeout(Socket self, uint32_t timeoutInMs); + +/** + * \brief bind a socket to a particular IP address and port (for TcpSocket) + * + * NOTE: Don't use the socket when this functions returns false! + * + * \param self the client socket instance + * \param srcAddress the local IP address or hostname as C string + * \param srcPort the local TCP port to use. When < 1 the OS will chose the TCP port to use. + * + * \return true in case of success, false otherwise + */ +PAL_API bool +Socket_bind(Socket self, const char* srcAddress, int srcPort); + +/** + * \brief connect to a server + * + * Connect to a server application identified by the address and port parameter. + * + * The "address" parameter may either be a hostname or an IP address. The IP address + * has to be provided as a C string (e.g. "10.0.2.1"). + * + * Implementation of this function is MANDATORY if client functionality is required. + * + * NOTE: return type changed from int to bool with version 0.8 + * + * \param self the client socket instance + * \param address the IP address or hostname as C string + * \param port the TCP port of the application to connect to + * + * \return true if the connection was established successfully, false otherwise + */ +PAL_API bool +Socket_connect(Socket self, const char* address, int port); + +PAL_API bool +Socket_connectAsync(Socket self, const char* address, int port); + +PAL_API SocketState +Socket_checkAsyncConnectState(Socket self); + +/** + * \brief read from socket to local buffer (non-blocking) + * + * The function shall return immediately if no data is available. In this case + * the function returns 0. If an error happens the function shall return -1. + * + * Implementation of this function is MANDATORY + * + * NOTE: The behaviour of this function changed with version 0.8! + * + * \param self the client, connection or server socket instance + * \param buf the buffer where the read bytes are copied to + * \param size the maximum number of bytes to read (size of the provided buffer) + * + * \return the number of bytes read or -1 if an error occurred + */ +PAL_API int +Socket_read(Socket self, uint8_t* buf, int size); + +/** + * \brief send a message through the socket + * + * Implementation of this function is MANDATORY + * + * \param self client, connection or server socket instance + * + * \return number of bytes transmitted of -1 in case of an error + */ +PAL_API int +Socket_write(Socket self, uint8_t* buf, int size); + +PAL_API char* +Socket_getLocalAddress(Socket self); + +/** + * \brief Get the address of the peer application (IP address and port number) + * + * The peer address has to be returned as null terminated string + * + * Implementation of this function is MANDATORY (libiec61850) + * + * \param self the client, connection or server socket instance + * + * \return the IP address and port number as strings separated by the ':' character. + */ +PAL_API char* +Socket_getPeerAddress(Socket self); + +/** + * \brief Get the address of the peer application (IP address and port number) + * + * The peer address has to be returned as null terminated string + * + * Implementation of this function is MANDATORY (lib60870 and libiec61850) + * + * \param self the client, connection or server socket instance + * \param peerAddressString a string to store the peer address (the string should have space + * for at least 60 characters) + * + * \return the IP address and port number as strings separated by the ':' character. If the + * address is an IPv6 address the IP part is encapsulated in square brackets. + */ +PAL_API char* +Socket_getPeerAddressStatic(Socket self, char* peerAddressString); + +/** + * \brief destroy a socket (close the socket if a connection is established) + * + * This function shall close the connection (if one is established) and free all + * resources allocated by the socket. + * + * Implementation of this function is MANDATORY + * + * \param self the client, connection or server socket instance + */ +PAL_API void +Socket_destroy(Socket self); + +/*! @} */ + +/*! @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* SOCKET_HAL_H_ */ diff --git a/product/src/fes/include/libiec61850/hal_thread.h b/product/src/fes/include/libiec61850/hal_thread.h new file mode 100644 index 00000000..0a88553e --- /dev/null +++ b/product/src/fes/include/libiec61850/hal_thread.h @@ -0,0 +1,105 @@ +/* + * thread_hal.h + * + * Multi-threading abstraction layer + * + * Copyright 2013-2021 Michael Zillgith + * + * This file is part of Platform Abstraction Layer (libpal) + * for libiec61850, libmms, and lib60870. + */ + +#ifndef THREAD_HAL_H_ +#define THREAD_HAL_H_ + +#include "hal_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file hal_thread.h + * \brief Abstraction layer for threading and synchronization + */ + +/*! \addtogroup hal + * + * @{ + */ + +/** + * @defgroup HAL_THREAD Threading and synchronization API + * + * @{ + */ + +/** Opaque reference of a Thread instance */ +typedef struct sThread* Thread; + +/** Qpaque reference of a Semaphore instance */ +typedef void* Semaphore; + +/** Reference to a function that is called when starting the thread */ +typedef void* (*ThreadExecutionFunction) (void*); + +/** + * \brief Create a new Thread instance + * + * \param function the entry point of the thread + * \param parameter a parameter that is passed to the threads start function + * \param autodestroy the thread is automatically destroyed if the ThreadExecutionFunction has finished. + * + * \return the newly created Thread instance + */ +PAL_API Thread +Thread_create(ThreadExecutionFunction function, void* parameter, bool autodestroy); + +/** + * \brief Start a Thread. + * + * This function invokes the start function of the thread. The thread terminates when + * the start function returns. + * + * \param thread the Thread instance to start + */ +PAL_API void +Thread_start(Thread thread); + +/** + * \brief Destroy a Thread and free all related resources. + * + * \param thread the Thread instance to destroy + */ +PAL_API void +Thread_destroy(Thread thread); + +/** + * \brief Suspend execution of the Thread for the specified number of milliseconds + */ +PAL_API void +Thread_sleep(int millies); + +PAL_API Semaphore +Semaphore_create(int initialValue); + +/* Wait until semaphore value is greater than zero. Then decrease the semaphore value. */ +PAL_API void +Semaphore_wait(Semaphore self); + +PAL_API void +Semaphore_post(Semaphore self); + +PAL_API void +Semaphore_destroy(Semaphore self); + +/*! @} */ + +/*! @} */ + +#ifdef __cplusplus +} +#endif + + +#endif /* THREAD_HAL_H_ */ diff --git a/product/src/fes/include/libiec61850/hal_time.h b/product/src/fes/include/libiec61850/hal_time.h new file mode 100644 index 00000000..b19bcd4b --- /dev/null +++ b/product/src/fes/include/libiec61850/hal_time.h @@ -0,0 +1,80 @@ +/* + * time.c + * + * Copyright 2013-2021 Michael Zillgith + * + * This file is part of Platform Abstraction Layer (libpal) + * for libiec61850, libmms, and lib60870. + */ + +#ifndef HAL_C_ +#define HAL_C_ + +#include "hal_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file hal_time.h + * \brief Abstraction layer for system time access + */ + +/*! \addtogroup hal + * + * @{ + */ + +/** + * @defgroup HAL_TIME Time related functions + * + * @{ + */ + +typedef uint64_t nsSinceEpoch; +typedef uint64_t msSinceEpoch; + +/** + * Get the system time in milliseconds. + * + * The time value returned as 64-bit unsigned integer should represent the milliseconds + * since the UNIX epoch (1970/01/01 00:00 UTC). + * + * \return the system time with millisecond resolution. + */ +PAL_API msSinceEpoch +Hal_getTimeInMs(void); + +/** + * Get the system time in nanoseconds. + * + * The time value returned as 64-bit unsigned integer should represent the nanoseconds + * since the UNIX epoch (1970/01/01 00:00 UTC). + * + * \return the system time with nanosecond resolution. + */ +PAL_API nsSinceEpoch +Hal_getTimeInNs(void); + +/** +* Set the system time from ns time +* +* The time value returned as 64-bit unsigned integer should represent the nanoseconds +* since the UNIX epoch (1970/01/01 00:00 UTC). +* +* \return true on success, otherwise false +*/ +PAL_API bool +Hal_setTimeInNs(nsSinceEpoch nsTime); + +/*! @} */ + +/*! @} */ + +#ifdef __cplusplus +} +#endif + + +#endif /* HAL_C_ */ diff --git a/product/src/fes/include/libiec61850/iec61850_cdc.h b/product/src/fes/include/libiec61850/iec61850_cdc.h new file mode 100644 index 00000000..04a077bf --- /dev/null +++ b/product/src/fes/include/libiec61850/iec61850_cdc.h @@ -0,0 +1,658 @@ +/* + * cdc.h + * + * Copyright 2014 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef CDC_H_ +#define CDC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \addtogroup server_api_group + * @{ + */ + +/** + * @defgroup COMMON_DATA_CLASSES Helper functions to create common data classes (CDC) using the dynamic model API + * + * Currently supports CDCs from IEC 61850-7-3:2010 (Edition 2) + * + * @{ + */ + +/** + * \brief optional parts of CDCs + */ +#define CDC_OPTION_PICS_SUBST (1 << 0) +#define CDC_OPTION_BLK_ENA (1 << 1) + +/** Add d (description) data attribute */ +#define CDC_OPTION_DESC (1 << 2) + +/** Add dU (unicode description) data attribute */ +#define CDC_OPTION_DESC_UNICODE (1 << 3) + +/** Add cdcNs and cdcName required when a CDC is an extension to the standard */ +#define CDC_OPTION_AC_DLNDA (1 << 4) + +/** Add dataNs (data namespace) required for extended CDCs */ +#define CDC_OPTION_AC_DLN (1 << 5) + +/** Add the unit data attribute */ +#define CDC_OPTION_UNIT (1 << 6) + +#define CDC_OPTION_FROZEN_VALUE (1 << 7) + +#define CDC_OPTION_ADDR (1 << 8) +#define CDC_OPTION_ADDINFO (1 << 9) + +#define CDC_OPTION_INST_MAG (1 << 10) +#define CDC_OPTION_RANGE (1 << 11) + +#define CDC_OPTION_UNIT_MULTIPLIER (1 << 12) + +#define CDC_OPTION_AC_SCAV (1 << 13) + +#define CDC_OPTION_MIN (1 << 14) +#define CDC_OPTION_MAX (1 << 15) + +#define CDC_OPTION_AC_CLC_O (1 << 16) + +#define CDC_OPTION_RANGE_ANG (1 << 17) + +#define CDC_OPTION_PHASE_A (1 << 18) +#define CDC_OPTION_PHASE_B (1 << 19) +#define CDC_OPTION_PHASE_C (1 << 20) + +#define CDC_OPTION_PHASE_NEUT (1 << 21) + +#define CDC_OPTION_PHASES_ABC (CDC_OPTION_PHASE_A | CDC_OPTION_PHASE_B | CDC_OPTION_PHASE_C) + +#define CDC_OPTION_PHASES_ALL (CDC_OPTION_PHASE_A | CDC_OPTION_PHASE_B | CDC_OPTION_PHASE_C | CDC_OPTION_PHASE_NEUT) + +#define CDC_OPTION_STEP_SIZE (1 << 22) + +#define CDC_OPTION_ANGLE_REF (1 << 23) + +/** Options that are only valid for DPL CDC */ +#define CDC_OPTION_DPL_HWREV (1 << 17) +#define CDC_OPTION_DPL_SWREV (1 << 18) +#define CDC_OPTION_DPL_SERNUM (1 << 19) +#define CDC_OPTION_DPL_MODEL (1 << 20) +#define CDC_OPTION_DPL_LOCATION (1 << 21) + +/** Add mandatory data attributes for LLN0 (e.g. LBL configRef) */ +#define CDC_OPTION_AC_LN0_M (1 << 24) +#define CDC_OPTION_AC_LN0_EX (1 << 25) +#define CDC_OPTION_AC_DLD_M (1 << 26) + +/** + * \brief Control model types + */ +#define CDC_CTL_MODEL_NONE 0 +#define CDC_CTL_MODEL_DIRECT_NORMAL 1 +#define CDC_CTL_MODEL_SBO_NORMAL 2 +#define CDC_CTL_MODEL_DIRECT_ENHANCED 3 +#define CDC_CTL_MODEL_SBO_ENHANCED 4 + +#define CDC_CTL_MODEL_HAS_CANCEL (1 << 4) +#define CDC_CTL_MODEL_IS_TIME_ACTIVATED (1 << 5) + +#define CDC_CTL_OPTION_ORIGIN (1 << 6) +#define CDC_CTL_OPTION_CTL_NUM (1 << 7) +#define CDC_CTL_OPTION_ST_SELD (1 << 8) +#define CDC_CTL_OPTION_OP_RCVD (1 << 9) +#define CDC_CTL_OPTION_OP_OK (1 << 10) +#define CDC_CTL_OPTION_T_OP_OK (1 << 11) +#define CDC_CTL_OPTION_SBO_TIMEOUT (1 << 12) +#define CDC_CTL_OPTION_SBO_CLASS (1 << 13) +#define CDC_CTL_OPTION_OPER_TIMEOUT (1 << 14) + +/**************************************************** + * Constructed Attribute Classes (CAC) + ***************************************************/ + +LIB61850_API DataAttribute* +CAC_AnalogueValue_create(const char* name, ModelNode* parent, FunctionalConstraint fc, uint8_t triggerOptions, + bool isIntegerNotFloat); + + +/** + * \brief create a ValWithTrans constructed data attribute + * + * \param hasTransInd + */ +LIB61850_API DataAttribute* +CAC_ValWithTrans_create(const char* name, ModelNode* parent, FunctionalConstraint fc, uint8_t triggerOptions, bool hasTransientIndicator); + + +/** + * CDC_OPTION_AC_CLC_O + */ +LIB61850_API DataAttribute* +CAC_Vector_create(const char* name, ModelNode* parent, uint32_t options, FunctionalConstraint fc, uint8_t triggerOptions); + +LIB61850_API DataAttribute* +CAC_Point_create(const char* name, ModelNode* parent, FunctionalConstraint fc, uint8_t triggerOptions, bool hasZVal); + +LIB61850_API DataAttribute* +CAC_ScaledValueConfig_create(const char* name, ModelNode* parent); + +LIB61850_API DataAttribute* +CAC_Unit_create(const char* name, ModelNode* parent, bool hasMagnitude); + +LIB61850_API DataAttribute* +CDA_OperBoolean(ModelNode* parent, bool isTImeActivated); + +/**************************************************** + * Common Data Classes (CDC) + ***************************************************/ + +LIB61850_API DataObject* +CDC_SPS_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +LIB61850_API DataObject* +CDC_DPS_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +LIB61850_API DataObject* +CDC_INS_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +LIB61850_API DataObject* +CDC_ENS_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +LIB61850_API DataObject* +CDC_BCR_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +LIB61850_API DataObject* +CDC_VSS_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +/** + * \brief create a new SEC (Security violation) CDC instance (data object) + * + * Allowed parent types are LogicalNode and DataObject. + * + * options: + * standard (include standard optional elements like extension namespaces and descriptions (d, dU). + * + * CDC_OPTION_ADDR (address of the client causing the security violation) + * CDC_OPTION_ADDINFO (additional info text) + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + */ +LIB61850_API DataObject* +CDC_SEC_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +/** + * \brief create a new MV (Measured value) CDC instance (data object) + * + * Allowed parent types are LogicalNode and DataObject. + * + * possible options: + * CDC_OPTION_INST_MAG + * CDC_OPTION_RANGE + * CDC_OPTION_PICS_SUBST + * standard (include standard optional elements like extension namespaces and descriptions (d, dU). + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * \param isIntegerNotFloat if true the AnalogueValue instance have integer instead of float + * + */ +LIB61850_API DataObject* +CDC_MV_create(const char* dataObjectName, ModelNode* parent, uint32_t options, bool isIntegerNotFloat); + +/** + * CDC_OPTION_INST_MAG + * CDC_OPTION_RANGE + */ +LIB61850_API DataObject* +CDC_CMV_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +/** + * \brief create a new SAV (Sampled analog value) CDC instance (data object) + * + * Allowed parent types are LogicalNode and DataObject. + * + * possible options: + * CDC_OPTION_UNIT + * CDC_OPTION_AC_SCAV + * CDC_OPTION_MIN + * CDC_OPTION_MAX + * standard (include standard optional elements like extension namespaces and descriptions (d, dU). + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * \param isIntegerNotFloat if true the AnalogueValue instance have integer instead of float + * + */ +LIB61850_API DataObject* +CDC_SAV_create(const char* dataObjectName, ModelNode* parent, uint32_t options, bool isIntegerNotFloat); + +/** + * \brief create a new LPL (Logical node name plate) CDC instance (data object) + * + * Allowed parent type is LogicalNode + * + * possible options: + * CDC_OPTION_AC_LN0_M (includes "configRev") + * CDC_OPTION_AC_LN0_EX (includes "ldNs") + * CDC_OPTION_AC_DLD_M (includes "lnNs") + * standard options: + * CDC_OPTION_DESC (includes "d") + * CDC_OPTION_DESC_UNICODE (include "du") + * CDC_OPTION_AC_DLNDA (include "cdcNs" and "cdcName") + * CDC_OPTION_AC_DLN (includes "dataNs") + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * + * \return new DataObject instance + */ +LIB61850_API DataObject* +CDC_LPL_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +/** + * \brief create a new DPL (Device name plate) CDC instance (data object) + * + * Allowed parent type is LogicalNode + * + * possible options: + * CDC_OPTION_DPL_HWREV (includes "hwRev") + * CDC_OPTION_DPL_SWREV (includes "swRev") + * CDC_OPTION_DPL_SERNUM (includes "serNum") + * CDC_OPTION_DPL_MODEL (includes "model") + * CDC_OPTION_DPL_LOCATION (includes "location") + * standard options: + * CDC_OPTION_AC_DLNDA (include "cdcNs" and "cdcName") + * CDC_OPTION_AC_DLN (includes "dataNs") + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * + * \return new DataObject instance + */ +LIB61850_API DataObject* +CDC_DPL_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +LIB61850_API DataObject* +CDC_HST_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint16_t maxPts); + +/** + * \brief Directional protection activation information (ACD) + * + * Allowed parent types are LogicalNode and DataObject. + * + * possible options: + * CDC_OPTION_PHASE_A + * CDC_OPTION_PHASE_B + * CDC_OPTION_PHASE_C + * CDC_OPTION_PHASE_NEUT + * CDC_OPTION_PHASES_ABC + * CDC_OPTION_PHASES_ALL + * standard (include standard optional elements like extension namespaces and descriptions (d, dU). + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + */ +LIB61850_API DataObject* +CDC_ACD_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +/** + * \brief Protection activation information (ACT) + */ +LIB61850_API DataObject* +CDC_ACT_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +/** + * \brief Single point setting (SPG) + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + */ +LIB61850_API DataObject* +CDC_SPG_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +/** + * \brief Visible string setting (VSG) + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + */ +LIB61850_API DataObject* +CDC_VSG_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +/** + * \brief Enumerated status setting (ENG) + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + */ +LIB61850_API DataObject* +CDC_ENG_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +/** + * \brief Integer status setting (ING) + * + * possible options: + * CDC_OPTION_UNIT + * CDC_OPTION_MIN + * CDC_OPTION_MAX + * CDC_OPTION_STEP_SIZE + * standard (include standard optional elements like extension namespaces and descriptions (d, dU). + * + */ +LIB61850_API DataObject* +CDC_ING_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +/** + * \brief Analogue Setting (ASG) + * + * possible options: + * CDC_OPTION_UNIT + * CDC_OPTION_MIN + * CDC_OPTION_MAX + * CDC_OPTION_STEP_SIZE + * standard (include standard optional elements like extension namespaces and descriptions (d, dU). + * + */ +LIB61850_API DataObject* +CDC_ASG_create(const char* dataObjectName, ModelNode* parent, uint32_t options, bool isIntegerNotFloat); + +/** + * \brief Phase to ground/neutral related measured values of a three-phase system (WYE) + * + * possible options: + * CDC_OPTION_ANGLE_REF + */ +LIB61850_API DataObject* +CDC_WYE_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +/** + * \brief Phase to phase related measured values of a three-phase system (DEL) + * + * possible options: + * CDC_OPTION_ANGLE_REF + */ +LIB61850_API DataObject* +CDC_DEL_create(const char* dataObjectName, ModelNode* parent, uint32_t options); + +/*************************** + * Controls + ***************************/ + +/** + * \brief Controllable single point (SPC) + * + * \param controlOptions specify which control model to set as default and other control related options + */ +LIB61850_API DataObject* +CDC_SPC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions); + +/** + * \brief Controllable double point (DPC) + * + * CDC_OPTION_IS_TIME_ACTICATED + * + * substitution options + * CDC_OPTION_BLK_ENA + * standard description and namespace options + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * \param defaultControlModel specify which control model to set as default. + * + */ +LIB61850_API DataObject* +CDC_DPC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions); + +/** + * \brief Controllable integer status (INC) + * + * CDC_OPTION_IS_TIME_ACTICATED + * + * CDC_OPTION_MIN + * CDC_OPTION_MAX + * CDC_OPTION_STEP_SIZE + * + * substitution options + * CDC_OPTION_BLK_ENA + * standard description and namespace options + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * \param defaultControlModel specify which control model to set as default. + * + */ +LIB61850_API DataObject* +CDC_INC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions); + +/** + * \brief Controllable enumerated status (ENC) + * + * CDC_OPTION_IS_TIME_ACTICATED + * + * substitution options + * CDC_OPTION_BLK_ENA + * standard description and namespace options + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * \param defaultControlModel specify which control model to set as default. + * + */ +LIB61850_API DataObject* +CDC_ENC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions); + +/** + * \brief Controllable enumerated status (ENC) + * + * CDC_OPTION_IS_TIME_ACTICATED + * + * substitution options + * CDC_OPTION_BLK_ENA + * standard description and namespace options + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * \param controlOptions specify which control model to set as default and other control specific options + * \param hasTransientIndicator specifies if the step position information contains the transient indicator + * + */ +LIB61850_API DataObject* +CDC_BSC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool hasTransientIndicator); + +/** + * \brief Integer controlled step position information (ISC) + * + * CDC_OPTION_IS_TIME_ACTICATED + * + * substitution options + * CDC_OPTION_BLK_ENA + * standard description and namespace options + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * \param controlOptions specify which control model to set as default and other control specific options + * \param hasTransientIndicator specifies if the step position information contains the transient indicator + * + */ +LIB61850_API DataObject* +CDC_ISC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool hasTransientIndicator); + +/** + * \brief Controllable analogue process value (APC) + * + * CDC_OPTION_IS_TIME_ACTICATED + * + * CDC_OPTION_MIN + * CDC_OPTION_MAX + * + * substitution options + * CDC_OPTION_BLK_ENA + * standard description and namespace options + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * \param controlOptions specify which control model to set as default and other control specific options + * \param isIntegerNotFloat + */ +LIB61850_API DataObject* +CDC_APC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool isIntegerNotFloat); + +/** + * \brief Binary controlled ananlogue process value (BAC) + * + * CDC_OPTION_IS_TIME_ACTICATED + * + * CDC_OPTION_MIN + * CDC_OPTION_MAX + * CDC_OPTION_STEP_SIZE + * + * substitution options + * CDC_OPTION_BLK_ENA + * standard description and namespace options + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * \param controlOptions specify which control model to set as default and other control specific options + * \param isIntegerNotFloat + */ +LIB61850_API DataObject* +CDC_BAC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool isIntegerNotFloat); + +/** Minimum measured value */ +#define CDC_OPTION_61400_MIN_MX_VAL (1 << 10) + +/** Maximum measured value */ +#define CDC_OPTION_61400_MAX_MX_VAL (1 << 11) + +/** Total average value of data */ +#define CDC_OPTION_61400_TOT_AV_VAL (1 << 12) + +/** Standard deviation of data */ +#define CDC_OPTION_61400_SDV_VAL (1 << 13) + +/** Rate of increase */ +#define CDC_OPTION_61400_INC_RATE (1 << 14) + +/** Rate of decrease */ +#define CDC_OPTION_61400_DEC_RATE (1 << 15) + +/** Setpoint or parameter access level (low/medium/high) */ +#define CDC_OPTION_61400_SP_ACS (1 << 16) + +/** Time periodical reset (hourly/daily/weekly/monthly) */ +#define CDC_OPTION_61400_CHA_PER_RS (1 << 17) + +/** Command access level */ +#define CDC_OPTION_61400_CM_ACS (1 << 18) + +/** Total time duration of a state */ +#define CDC_OPTION_61400_TM_TOT (1 << 19) + +/** Daily counting data */ +#define CDC_OPTION_61400_COUNTING_DAILY (1 << 20) + +/** Monthly counting data */ +#define CDC_OPTION_61400_COUNTING_MONTHLY (1 << 21) + +/** Yearly counting data */ +#define CDC_OPTION_61400_COUNTING_YEARLY (1 << 22) + +/** Total counting data */ +#define CDC_OPTION_61400_COUNTING_TOTAL (1 << 23) + +/** All counting data */ +#define CDC_OPTION_61400_COUNTING_ALL (CDC_OPTION_61400_COUNTING_DAILY | CDC_OPTION_61400_COUNTING_MONTHLY | CDC_OPTION_61400_COUNTING_YEARLY | CDC_OPTION_61400_COUNTING_TOTAL) + +LIB61850_API DataObject* +CDC_SPV_create(const char* dataObjectName, ModelNode* parent, + uint32_t options, + uint32_t controlOptions, + uint32_t wpOptions, + bool hasChaManRs); + +LIB61850_API DataObject* +CDC_STV_create(const char* dataObjectName, ModelNode* parent, + uint32_t options, + uint32_t controlOptions, + uint32_t wpOptions, + bool hasOldStatus); + +LIB61850_API DataObject* +CDC_CMD_create(const char* dataObjectName, ModelNode* parent, + uint32_t options, + uint32_t controlOptions, + uint32_t wpOptions, + bool hasOldStatus, + bool hasCmTm, + bool hasCmCt); + +LIB61850_API DataObject* +CDC_ALM_create(const char* dataObjectName, ModelNode* parent, + uint32_t options, + uint32_t controlOptions, + uint32_t wpOptions, + bool hasOldStatus); + +LIB61850_API DataObject* +CDC_CTE_create(const char* dataObjectName, ModelNode* parent, + uint32_t options, + uint32_t controlOptions, + uint32_t wpOptions, + bool hasHisRs); + +LIB61850_API DataObject* +CDC_TMS_create(const char* dataObjectName, ModelNode* parent, + uint32_t options, + uint32_t controlOptions, + uint32_t wpOptions, + bool hasHisRs); + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* CDC_H_ */ diff --git a/product/src/fes/include/libiec61850/iec61850_client.h b/product/src/fes/include/libiec61850/iec61850_client.h new file mode 100644 index 00000000..3acb84af --- /dev/null +++ b/product/src/fes/include/libiec61850/iec61850_client.h @@ -0,0 +1,3108 @@ +/* + * iec61850_client.h + * + * Copyright 2013-2021 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef IEC61850_CLIENT_H_ +#define IEC61850_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libiec61850_common_api.h" +#include "iec61850_common.h" +#include "mms_value.h" +#include "mms_client_connection.h" +#include "linked_list.h" + +/** + * * \defgroup iec61850_client_api_group IEC 61850/MMS client API + */ +/**@{*/ + +/** an opaque handle to the instance data of a ClientDataSet object */ +typedef struct sClientDataSet* ClientDataSet; + +/** an opaque handle to the instance data of a ClientReport object */ +typedef struct sClientReport* ClientReport; + +/** an opaque handle to the instance data of a ClientReportControlBlock object */ +typedef struct sClientReportControlBlock* ClientReportControlBlock; + +/** an opaque handle to the instance data of a ClientGooseControlBlock object */ +typedef struct sClientGooseControlBlock* ClientGooseControlBlock; + +/** + * @defgroup IEC61850_CLIENT_GENERAL General client side connection handling functions and data types + * + * @{ + */ + +/** An opaque handle to the instance data of the IedConnection object */ +typedef struct sIedConnection* IedConnection; + +/** Detailed description of the last application error of the client connection instance */ +typedef struct +{ + int ctlNum; + ControlLastApplError error; + ControlAddCause addCause; +} LastApplError; + +/** Connection state of the IedConnection instance - either closed(idle), connecting, connected, or closing) */ +typedef enum +{ + IED_STATE_CLOSED = 0, + IED_STATE_CONNECTING, + IED_STATE_CONNECTED, + IED_STATE_CLOSING +} IedConnectionState; + +/** used to describe the error reason for most client side service functions */ +typedef enum { + /* general errors */ + + /** No error occurred - service request has been successful */ + IED_ERROR_OK = 0, + + /** The service request can not be executed because the client is not yet connected */ + IED_ERROR_NOT_CONNECTED = 1, + + /** Connect service not execute because the client is already connected */ + IED_ERROR_ALREADY_CONNECTED = 2, + + /** The service request can not be executed caused by a loss of connection */ + IED_ERROR_CONNECTION_LOST = 3, + + /** The service or some given parameters are not supported by the client stack or by the server */ + IED_ERROR_SERVICE_NOT_SUPPORTED = 4, + + /** Connection rejected by server */ + IED_ERROR_CONNECTION_REJECTED = 5, + + /** Cannot send request because outstanding call limit is reached */ + IED_ERROR_OUTSTANDING_CALL_LIMIT_REACHED = 6, + + /* client side errors */ + + /** API function has been called with an invalid argument */ + IED_ERROR_USER_PROVIDED_INVALID_ARGUMENT = 10, + + IED_ERROR_ENABLE_REPORT_FAILED_DATASET_MISMATCH = 11, + + /** The object provided object reference is invalid (there is a syntactical error). */ + IED_ERROR_OBJECT_REFERENCE_INVALID = 12, + + /** Received object is of unexpected type */ + IED_ERROR_UNEXPECTED_VALUE_RECEIVED = 13, + + /* service error - error reported by server */ + + /** The communication to the server failed with a timeout */ + IED_ERROR_TIMEOUT = 20, + + /** The server rejected the access to the requested object/service due to access control */ + IED_ERROR_ACCESS_DENIED = 21, + + /** The server reported that the requested object does not exist (returned by server) */ + IED_ERROR_OBJECT_DOES_NOT_EXIST = 22, + + /** The server reported that the requested object already exists */ + IED_ERROR_OBJECT_EXISTS = 23, + + /** The server does not support the requested access method (returned by server) */ + IED_ERROR_OBJECT_ACCESS_UNSUPPORTED = 24, + + /** The server expected an object of another type (returned by server) */ + IED_ERROR_TYPE_INCONSISTENT = 25, + + /** The object or service is temporarily unavailable (returned by server) */ + IED_ERROR_TEMPORARILY_UNAVAILABLE = 26, + + /** The specified object is not defined in the server (returned by server) */ + IED_ERROR_OBJECT_UNDEFINED = 27, + + /** The specified address is invalid (returned by server) */ + IED_ERROR_INVALID_ADDRESS = 28, + + /** Service failed due to a hardware fault (returned by server) */ + IED_ERROR_HARDWARE_FAULT = 29, + + /** The requested data type is not supported by the server (returned by server) */ + IED_ERROR_TYPE_UNSUPPORTED = 30, + + /** The provided attributes are inconsistent (returned by server) */ + IED_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT = 31, + + /** The provided object value is invalid (returned by server) */ + IED_ERROR_OBJECT_VALUE_INVALID = 32, + + /** The object is invalidated (returned by server) */ + IED_ERROR_OBJECT_INVALIDATED = 33, + + /** Received an invalid response message from the server */ + IED_ERROR_MALFORMED_MESSAGE = 34, + + /** Service not implemented */ + IED_ERROR_SERVICE_NOT_IMPLEMENTED = 98, + + /** unknown error */ + IED_ERROR_UNKNOWN = 99 +} IedClientError; + +/************************************************** + * Connection creation and destruction + **************************************************/ + +/** + * \brief create a new IedConnection instance + * + * This function creates a new IedConnection instance that is used to handle a connection to an IED. + * It allocated all required resources. The new connection is in the "CLOSED" state. Before it can be used + * the connect method has to be called. The connection will be in non-TLS and thread mode. + * + * \return the new IedConnection instance + */ +LIB61850_API IedConnection +IedConnection_create(void); + +/** + * \brief create a new IedConnection instance (extended version) + * + * This function creates a new IedConnection instance that is used to handle a connection to an IED. + * It allocated all required resources. The new connection is in the "CLOSED" state. Before it can be used + * the \ref IedConnection_connect or \ref IedConnection_connectAsync method has to be called. + * The connection will use TLS when a TLSConfiguration object is provided. The useThread is false the + * IedConnection is in non-thread mode and the IedConnection_tick function has to be called periodically to + * receive messages and perform the house-keeping tasks. + * + * \param tlsConfig the TLS configuration to be used, or NULL for non-TLS connection + * \param useThreads when true, the IedConnection is in thread mode + * + * \return the new IedConnection instance + */ +LIB61850_API IedConnection +IedConnection_createEx(TLSConfiguration tlsConfig, bool useThreads); + +/** + * \brief create a new IedConnection instance that has support for TLS + * + * This function creates a new IedConnection instance that is used to handle a connection to an IED. + * It allocated all required resources. The new connection is in the "CLOSED" state. Before it can be used + * the \ref IedConnection_connect or \ref IedConnection_connectAsync method has to be called. + * The connection will use TLS when a TLSConfiguration object is provided. The connection will be in thread mode. + * + * \deprecated Use \ref IedConnection_createEx instead + * + * \param tlsConfig the TLS configuration to be used + * + * \return the new IedConnection instance + */ +LIB61850_API IedConnection +IedConnection_createWithTlsSupport(TLSConfiguration tlsConfig); + +/** + * \brief destroy an IedConnection instance. + * + * The connection will be closed if it is in "connected" state. All allocated resources of the connection + * will be freed. + * + * \param self the connection object + */ +LIB61850_API void +IedConnection_destroy(IedConnection self); + +/** +* \brief Set the local IP address and port to be used by the client +* +* NOTE: This function is optional. When not used the OS decides what IP address and TCP port to use. +* +* \param self IedConnection instance +* \param localIpAddress the local IP address or hostname as C string +* \param localPort the local TCP port to use. When < 1 the OS will chose the TCP port to use. +*/ +LIB61850_API void +IedConnection_setLocalAddress(IedConnection self, const char* localIpAddress, int localPort); + +/** + * \brief set the connect timeout in ms + * + * Set the connect timeout for this connection. This function has to be called before IedConnection_connect + * is called. + * + * \param self the connection object + * \param timoutInMs the connection timeout in ms + */ +LIB61850_API void +IedConnection_setConnectTimeout(IedConnection self, uint32_t timeoutInMs); + +/** + * \brief set the request timeout in ms + * + * Set the request timeout for this connection. You can call this function any time to adjust + * timeout behavior. + * + * \param self the connection object + * \param timoutInMs the connection timeout in ms + */ +LIB61850_API void +IedConnection_setRequestTimeout(IedConnection self, uint32_t timeoutInMs); + +/** + * \brief get the request timeout in ms for this connection + * + * \param self the connection object + * + * \return request timeout in milliseconds + */ +LIB61850_API uint32_t +IedConnection_getRequestTimeout(IedConnection self); + +/** + * \brief Set the time quality for all timestamps generated by this IedConnection instance + * + * \param self the connection object + * \param leapSecondKnown set/unset leap seconds known flag + * \param clockFailure set/unset clock failure flag + * \param clockNotSynchronized set/unset clock not synchronized flag + * \param subsecondPrecision set the subsecond precision (number of significant bits of the fractionOfSecond part of the time stamp) + */ +LIB61850_API void +IedConnection_setTimeQuality(IedConnection self, bool leapSecondKnown, bool clockFailure, bool clockNotSynchronized, int subsecondPrecision); + +/** + * \brief Perform MMS message handling and house-keeping tasks (for non-thread mode only) + * + * This function has to be called periodically by the user application in non-thread mode. The return + * value helps to decide when the stack has nothing to do and other tasks can be executed. + * + * NOTE: When using non-thread mode you should NOT use the synchronous (blocking) API functions. The + * synchronous functions will block forever when IedConnection_tick is not called in a separate thread. + * + * \return true when connection is currently waiting and calling thread can be suspended, false means + * connection is busy and the tick function should be called again as soon as possible. + */ +LIB61850_API bool +IedConnection_tick(IedConnection self); + +/** + * \brief Generic serivce callback handler + * + * NOTE: This callback handler is used by several asynchronous service functions that require + * only a simple feedback in form of a success (IED_ERROR_OK) or failure (other \ref err value). + * + * \param invokeId the invoke ID used by the related service request + * \param parameter user provided parameter + * \param err the result code. IED_ERROR_OK indicates success. + */ +typedef void +(*IedConnection_GenericServiceHandler) (uint32_t invokeId, void* parameter, IedClientError err); + +/************************************************** + * Association service + **************************************************/ + +/** + * \brief Connect to a server + * + * NOTE: Function will block until connection is up or timeout happened. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param hostname the host name or IP address of the server to connect to + * \param tcpPort the TCP port number of the server to connect to + */ +LIB61850_API void +IedConnection_connect(IedConnection self, IedClientError* error, const char* hostname, int tcpPort); + +/** + * \brief Asynchronously connect to a server + * + * The function will return immediately. No error doesn't indicate that the + * connection is established. The current connection state has to be tracked + * by polling the \ref IedConnection_getState function or by using + * \ref IedConnection_StateChangedHandler + * + * \param self the connection object + * \param error the error code if an error occurs + * \param hostname the host name or IP address of the server to connect to + * \param tcpPort the TCP port number of the server to connect to + */ +LIB61850_API void +IedConnection_connectAsync(IedConnection self, IedClientError* error, const char* hostname, int tcpPort); + +/** + * \brief Abort the connection + * + * This will close the MMS association by sending an ACSE abort message to the server. + * After sending the abort message the connection is closed immediately. + * The client can assume the connection to be closed when the function returns and the + * destroy method can be called. If the connection is not in "connected" state an + * IED_ERROR_NOT_CONNECTED error will be reported. + * + * \param self the connection object + * \param error the error code if an error occurs + */ +LIB61850_API void +IedConnection_abort(IedConnection self, IedClientError* error); + +/** + * \brief Asynchronously abort the connection + * + * This will close the MMS association by sending an ACSE abort message to the server. + * After sending the abort message the connection is closed immediately. + * If the connection is not in "connected" state an IED_ERROR_NOT_CONNECTED error will be reported. + * + * NOTE: This function works asynchronously. The IedConnection object should not be destroyed before the + * connection state changes to IED_STATE_CLOSED. + * + * \param self the connection object + * \param error the error code if an error occurs + */ +LIB61850_API void +IedConnection_abortAsync(IedConnection self, IedClientError* error); + +/** + * \brief Release the connection + * + * This will release the MMS association by sending an MMS conclude message to the server. + * The client can NOT assume the connection to be closed when the function returns, It can + * also fail if the server returns with a negative response. To be sure that the connection + * will be close the close or abort methods should be used. If the connection is not in "connected" state an + * IED_ERROR_NOT_CONNECTED error will be reported. + * + * \param self the connection object + * \param error the error code if an error occurs + */ +LIB61850_API void +IedConnection_release(IedConnection self, IedClientError* error); + +/** + * \brief Asynchronously release the connection + * + * This will release the MMS association by sending an MMS conclude message to the server. + * The client can NOT assume the connection to be closed when the function returns, It can + * also fail if the server returns with a negative response. To be sure that the connection + * will be close the close or abort methods should be used. If the connection is not in "connected" state an + * IED_ERROR_NOT_CONNECTED error will be reported. + * + * \param self the connection object + * \param error the error code if an error occurs + */ +LIB61850_API void +IedConnection_releaseAsync(IedConnection self, IedClientError* error); + +/** + * \brief Close the connection + * + * This will close the MMS association and the underlying TCP connection. + * + * \param self the connection object + */ +LIB61850_API void +IedConnection_close(IedConnection self); + +/** + * \brief return the state of the connection. + * + * This function can be used to determine if the connection is established or closed. + * + * \param self the connection object + * + * \return the connection state + */ +LIB61850_API IedConnectionState +IedConnection_getState(IedConnection self); + +/** + * \brief Access to last application error received by the client connection + * + * \param self the connection object + * + * \return the LastApplError value + */ +LIB61850_API LastApplError +IedConnection_getLastApplError(IedConnection self); + +/** + * \brief Callback handler that is invoked when the connection is closed + * + * \deprecated Use \ref IedConnection_StateChangedHandler instead + * + * \param user provided parameter + * \param connection the connection object of the closed connection + */ +typedef void +(*IedConnectionClosedHandler) (void* parameter, IedConnection connection); + +/** + * \brief Install a handler function that is called when the connection is lost/closed. + * + * \deprecated Use \ref IedConnection_StateChangedHandler instead + * + * \param self the connection object + * \param handler that callback function + * \param parameter the user provided parameter that is handed over to the callback function + */ +LIB61850_API void +IedConnection_installConnectionClosedHandler(IedConnection self, IedConnectionClosedHandler handler, + void* parameter); + +/** + * \brief Callback handler that is invoked whenever the connection state (\ref IedConnectionState) changes + * + * \param user provided parameter + * \param connection the related connection + * \param newState the new state of the connection + */ +typedef void +(*IedConnection_StateChangedHandler) (void* parameter, IedConnection connection, IedConnectionState newState); + +/** + * \brief Install a handler function that is called when the connection state changes + * + * \param self the connection object + * \param handler that callback function + * \param parameter the user provided parameter that is handed over to the callback function + */ +LIB61850_API void +IedConnection_installStateChangedHandler(IedConnection self, IedConnection_StateChangedHandler handler, void* parameter); + +/** + * \brief get a handle to the underlying MmsConnection + * + * Get access to the underlying MmsConnection instance used by this IedConnection. + * This can be used to set/change specific MmsConnection parameters or to call low-level MMS services/functions. + * + * \param self the connection object + * + * \return the MmsConnection instance used by this IedConnection. + */ +LIB61850_API MmsConnection +IedConnection_getMmsConnection(IedConnection self); + +/** @} */ + +/** + * @defgroup IEC61850_CLIENT_SV Client side SV control block handling functions + * + * @{ + */ + +/** SV ASDU contains attribute RefrTm */ +#define IEC61850_SV_OPT_REFRESH_TIME 1 + +/** SV ASDU contains attribute SmpSynch */ +#define IEC61850_SV_OPT_SAMPLE_SYNC 2 + +/** SV ASDU contains attribute SmpRate */ +#define IEC61850_SV_OPT_SAMPLE_RATE 4 + +/** SV ASDU contains attribute DatSet */ +#define IEC61850_SV_OPT_DATA_SET 8 + +/** SV ASDU contains attribute Security */ +#define IEC61850_SV_OPT_SECURITY 16 + +#define IEC61850_SV_SMPMOD_SAMPLES_PER_PERIOD 0 + +#define IEC61850_SV_SMPMOD_SAMPLES_PER_SECOND 1 + +#define IEC61850_SV_SMPMOD_SECONDS_PER_SAMPLE 2 + + +/** an opaque handle to the instance data of a ClientSVControlBlock object */ +typedef struct sClientSVControlBlock* ClientSVControlBlock; + +/** + * \brief Create a new ClientSVControlBlock instance + * + * This function simplifies client side access to server MSV/USV control blocks + * NOTE: Do not use the functions after the IedConnection object is invalidated! + * + * The access functions cause synchronous read/write calls to the server. For asynchronous + * access use the \ref IedConnection_readObjectAsync and \ref IedConnection_writeObjectAsync + * functions. + * + * \param connection the IedConnection object with a valid connection to the server. + * \param reference the object reference of the control block + * + * \return the new instance + */ +LIB61850_API ClientSVControlBlock +ClientSVControlBlock_create(IedConnection connection, const char* reference); + +/** + * \brief Free all resources related to the ClientSVControlBlock instance. + * + * \param self the ClientSVControlBlock instance to operate on + */ +LIB61850_API void +ClientSVControlBlock_destroy(ClientSVControlBlock self); + +/** + * \brief Test if this SVCB is multicast + * + * \param self the ClientSVControlBlock instance to operate on + * + * \return true if multicast SCVB, false otherwise (unicast) + */ +LIB61850_API bool +ClientSVControlBlock_isMulticast(ClientSVControlBlock self); + +/** + * \brief Return the error code of the last write or write acccess to the SVCB + * + * \param self the ClientSVControlBlock instance to operate on + * + * \return the error code of the last read or write access + */ +LIB61850_API IedClientError +ClientSVControlBlock_getLastComError(ClientSVControlBlock self); + + +LIB61850_API bool +ClientSVControlBlock_setSvEna(ClientSVControlBlock self, bool value); + +LIB61850_API bool +ClientSVControlBlock_getSvEna(ClientSVControlBlock self); + +LIB61850_API bool +ClientSVControlBlock_setResv(ClientSVControlBlock self, bool value); + +LIB61850_API bool +ClientSVControlBlock_getResv(ClientSVControlBlock self); + +LIB61850_API char* +ClientSVControlBlock_getMsvID(ClientSVControlBlock self); + +/** + * \brief Get the (MMS) reference to the data set + * + * NOTE: the returned string is dynamically allocated with the + * GLOBAL_MALLOC macro. The application is responsible to release + * the memory when the string is no longer needed. + * + * \param self the ClientSVControlBlock instance to operate on + * + * \return the data set reference as a NULL terminated string + */ +LIB61850_API char* +ClientSVControlBlock_getDatSet(ClientSVControlBlock self); + +LIB61850_API uint32_t +ClientSVControlBlock_getConfRev(ClientSVControlBlock self); + +LIB61850_API uint16_t +ClientSVControlBlock_getSmpRate(ClientSVControlBlock self); + + +/** + * \brief returns the destination address of the SV publisher + * + * \param self the ClientSVControlBlock instance to operate on + */ +LIB61850_API PhyComAddress +ClientSVControlBlock_getDstAddress(ClientSVControlBlock self); + +/** + * \brief Gets the OptFlds parameter of the RCB (decides what information to include in a report) + * + * \param self the RCB instance + * \return bit field representing the optional fields of a report (uses flags from \ref REPORT_OPTIONS) + */ +LIB61850_API int +ClientSVControlBlock_getOptFlds(ClientSVControlBlock self); + +/** + * \brief returns number of sample mode of the SV publisher + * + * \param self the ClientSVControlBlock instance to operate on + */ +LIB61850_API uint8_t +ClientSVControlBlock_getSmpMod(ClientSVControlBlock self); + +/** + * \brief returns number of ASDUs included in the SV message + * + * \param self the ClientSVControlBlock instance to operate on + * + * \return the number of ASDU included in a single SV message + */ +LIB61850_API int +ClientSVControlBlock_getNoASDU(ClientSVControlBlock self); + + +/** @} */ + +/** + * @defgroup IEC61850_CLIENT_GOOSE Client side GOOSE control block handling functions + * + * @{ + */ + +/********************************************************* + * GOOSE services handling (MMS part) + ********************************************************/ + +/** Enable GOOSE publisher GoCB block element */ +#define GOCB_ELEMENT_GO_ENA 1 + +/** GOOSE ID GoCB block element */ +#define GOCB_ELEMENT_GO_ID 2 + +/** Data set GoCB block element */ +#define GOCB_ELEMENT_DATSET 4 + +/** Configuration revision GoCB block element (this is usually read-only) */ +#define GOCB_ELEMENT_CONF_REV 8 + +/** Need commission GoCB block element (read-only according to 61850-7-2) */ +#define GOCB_ELEMENT_NDS_COMM 16 + +/** Destination address GoCB block element (read-only according to 61850-7-2) */ +#define GOCB_ELEMENT_DST_ADDRESS 32 + +/** Minimum time GoCB block element (read-only according to 61850-7-2) */ +#define GOCB_ELEMENT_MIN_TIME 64 + +/** Maximum time GoCB block element (read-only according to 61850-7-2) */ +#define GOCB_ELEMENT_MAX_TIME 128 + +/** Fixed offsets GoCB block element (read-only according to 61850-7-2) */ +#define GOCB_ELEMENT_FIXED_OFFS 256 + +/** select all elements of the GoCB */ +#define GOCB_ELEMENT_ALL 511 + + +/************************************************** + * ClientGooseControlBlock class + **************************************************/ + +LIB61850_API ClientGooseControlBlock +ClientGooseControlBlock_create(const char* dataAttributeReference); + +LIB61850_API void +ClientGooseControlBlock_destroy(ClientGooseControlBlock self); + +LIB61850_API bool +ClientGooseControlBlock_getGoEna(ClientGooseControlBlock self); + +LIB61850_API void +ClientGooseControlBlock_setGoEna(ClientGooseControlBlock self, bool goEna); + +LIB61850_API const char* +ClientGooseControlBlock_getGoID(ClientGooseControlBlock self); + +LIB61850_API void +ClientGooseControlBlock_setGoID(ClientGooseControlBlock self, const char* goID); + +LIB61850_API const char* +ClientGooseControlBlock_getDatSet(ClientGooseControlBlock self); + +LIB61850_API void +ClientGooseControlBlock_setDatSet(ClientGooseControlBlock self, const char* datSet); + +LIB61850_API uint32_t +ClientGooseControlBlock_getConfRev(ClientGooseControlBlock self); + +LIB61850_API bool +ClientGooseControlBlock_getNdsComm(ClientGooseControlBlock self); + +LIB61850_API uint32_t +ClientGooseControlBlock_getMinTime(ClientGooseControlBlock self); + +LIB61850_API uint32_t +ClientGooseControlBlock_getMaxTime(ClientGooseControlBlock self); + +LIB61850_API bool +ClientGooseControlBlock_getFixedOffs(ClientGooseControlBlock self); + +LIB61850_API PhyComAddress +ClientGooseControlBlock_getDstAddress(ClientGooseControlBlock self); + +LIB61850_API void +ClientGooseControlBlock_setDstAddress(ClientGooseControlBlock self, PhyComAddress value); + +LIB61850_API DEPRECATED MmsValue* /* MMS_OCTET_STRING */ +ClientGooseControlBlock_getDstAddress_addr(ClientGooseControlBlock self); + +LIB61850_API DEPRECATED void +ClientGooseControlBlock_setDstAddress_addr(ClientGooseControlBlock self, MmsValue* macAddr); + +LIB61850_API DEPRECATED uint8_t +ClientGooseControlBlock_getDstAddress_priority(ClientGooseControlBlock self); + +LIB61850_API DEPRECATED void +ClientGooseControlBlock_setDstAddress_priority(ClientGooseControlBlock self, uint8_t priorityValue); + +LIB61850_API DEPRECATED uint16_t +ClientGooseControlBlock_getDstAddress_vid(ClientGooseControlBlock self); + +LIB61850_API DEPRECATED void +ClientGooseControlBlock_setDstAddress_vid(ClientGooseControlBlock self, uint16_t vidValue); + +LIB61850_API DEPRECATED uint16_t +ClientGooseControlBlock_getDstAddress_appid(ClientGooseControlBlock self); + +LIB61850_API DEPRECATED void +ClientGooseControlBlock_setDstAddress_appid(ClientGooseControlBlock self, uint16_t appidValue); + + +/********************************************************* + * GOOSE services (access to GOOSE Control Blocks (GoCB)) + ********************************************************/ + +/** + * \brief Read access to attributes of a GOOSE control block (GoCB) at the connected server. A GoCB contains + * the configuration values for a single GOOSE publisher. + * + * The requested GoCB has to be specified by its object IEC 61850 ACSI object reference. E.g. + * + * "simpleIOGernericIO/LLN0.gcbEvents" + * + * This function is used to perform the actual read service for the GoCB values. + * To access the received values the functions of ClientGooseControlBlock have to be used. + * + * If called with a NULL argument for the updateGoCB parameter a new ClientGooseControlBlock instance is created + * and populated with the values received by the server. It is up to the user to release this object by + * calling the ClientGooseControlBlock_destroy function when the object is no longer needed. If called with a reference + * to an existing ClientGooseControlBlock instance the values of the attributes will be updated and no new instance + * will be created. + * + * Note: This function maps to a single MMS read request to retrieve the complete GoCB at once. + * + * \param connection the connection object + * \param error the error code if an error occurs + * \param goCBReference IEC 61850-7-2 ACSI object reference of the GOOSE control block + * \param updateRcb a reference to an existing ClientGooseControlBlock instance or NULL + * + * \return new ClientGooseControlBlock instance or the instance provided by the user with + * the updateRcb parameter. + */ +LIB61850_API ClientGooseControlBlock +IedConnection_getGoCBValues(IedConnection self, IedClientError* error, const char* goCBReference, ClientGooseControlBlock updateGoCB); + +/** + * \brief Write access to attributes of a GOOSE control block (GoCB) at the connected server + * + * The GoCB and the values to be written are specified with the goCB parameter. + * + * The parametersMask parameter specifies which attributes of the remote GoCB have to be set by this request. + * You can specify multiple attributes by ORing the defined bit values. If all attributes have to be written + * GOCB_ELEMENT_ALL can be used. + * + * The singleRequest parameter specifies the mapping to the corresponding MMS write request. Standard compliant + * servers should accept both variants. But some server accept only one variant. Then the value of this parameter + * will be of relevance. + * + * \param connection the connection object + * \param error the error code if an error occurs + * \param goCB ClientGooseControlBlock instance that actually holds the parameter + * values to be written. + * \param parametersMask specifies the parameters contained in the setGoCBValues request. + * \param singleRequest specifies if the seGoCBValues services is mapped to a single MMS write request containing + * multiple variables or to multiple MMS write requests. + */ +LIB61850_API void +IedConnection_setGoCBValues(IedConnection self, IedClientError* error, ClientGooseControlBlock goCB, + uint32_t parametersMask, bool singleRequest); + +/** @} */ + + +/**************************************** + * Data model access services + ****************************************/ + +/** + * @defgroup IEC61850_CLIENT_DATA_ACCESS Client side data access (read/write) service functions + * + * @{ + */ + +/** + * \brief read a functional constrained data attribute (FCDA) or functional constrained data (FCD). + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the object/attribute to read + * \param fc the functional constraint of the data attribute or data object to read + * + * \return the MmsValue instance of the received value or NULL if the request failed + */ +LIB61850_API MmsValue* +IedConnection_readObject(IedConnection self, IedClientError* error, const char* dataAttributeReference, FunctionalConstraint fc); + +typedef void +(*IedConnection_ReadObjectHandler) (uint32_t invokeId, void* parameter, IedClientError err, MmsValue* value); + +/** + * \brief read a functional constrained data attribute (FCDA) or functional constrained data (FCD) - async version + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the object/attribute to read + * \param fc the functional constraint of the data attribute or data object to read + * \param handler the user provided callback handler + * \param parameter user provided parameter that is passed to the callback handler + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +IedConnection_readObjectAsync(IedConnection self, IedClientError* error, const char* objRef, FunctionalConstraint fc, + IedConnection_ReadObjectHandler handler, void* parameter); + +/** + * \brief write a functional constrained data attribute (FCDA) or functional constrained data (FCD). + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the object/attribute to write + * \param fc the functional constraint of the data attribute or data object to write + * \param value the MmsValue to write (has to be of the correct type - MMS_STRUCTURE for FCD) + */ +LIB61850_API void +IedConnection_writeObject(IedConnection self, IedClientError* error, const char* dataAttributeReference, FunctionalConstraint fc, + MmsValue* value); + +/** + * \brief write a functional constrained data attribute (FCDA) or functional constrained data (FCD) - async version + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the object/attribute to write + * \param fc the functional constraint of the data attribute or data object to write + * \param value the MmsValue to write (has to be of the correct type - MMS_STRUCTURE for FCD) + * \param handler the user provided callback handler + * \param parameter user provided parameter that is passed to the callback handler + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +IedConnection_writeObjectAsync(IedConnection self, IedClientError* error, const char* objectReference, + FunctionalConstraint fc, MmsValue* value, IedConnection_GenericServiceHandler handler, void* parameter); + +/** + * \brief read a functional constrained data attribute (FCDA) of type boolean + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the data attribute to read + * \param fc the functional constraint of the data attribute to read + */ +LIB61850_API bool +IedConnection_readBooleanValue(IedConnection self, IedClientError* error, const char* objectReference, FunctionalConstraint fc); + +/** + * \brief read a functional constrained data attribute (FCDA) of type float + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the data attribute to read + * \param fc the functional constraint of the data attribute to read + */ +LIB61850_API float +IedConnection_readFloatValue(IedConnection self, IedClientError* error, const char* objectReference, FunctionalConstraint fc); + +/** + * \brief read a functional constrained data attribute (FCDA) of type VisibleString or MmsString + * + * NOTE: the returned char buffer is dynamically allocated and has to be freed by the caller! + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the data attribute to read + * \param fc the functional constraint of the data attribute to read + * + * \return a C string representation of the value. Has to be freed by the caller! + */ +LIB61850_API char* +IedConnection_readStringValue(IedConnection self, IedClientError* error, const char* objectReference, FunctionalConstraint fc); + +/** + * \brief read a functional constrained data attribute (FCDA) of type Integer or Unsigned and return the result as int32_t + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the data attribute to read + * \param fc the functional constraint of the data attribute to read + * + * \return an int32_t value of the read data attributes + */ +LIB61850_API int32_t +IedConnection_readInt32Value(IedConnection self, IedClientError* error, const char* objectReference, FunctionalConstraint fc); + +/** + * \brief read a functional constrained data attribute (FCDA) of type Integer or Unsigned and return the result as int64_t + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the data attribute to read + * \param fc the functional constraint of the data attribute to read + * + * \return an int64_t value of the read data attributes + */ +LIB61850_API int64_t +IedConnection_readInt64Value(IedConnection self, IedClientError* error, const char* objectReference, FunctionalConstraint fc); + +/** + * \brief read a functional constrained data attribute (FCDA) of type Integer or Unsigned and return the result as uint32_t + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the data attribute to read + * \param fc the functional constraint of the data attribute to read + * + * \return an uint32_t value of the read data attributes + */ +LIB61850_API uint32_t +IedConnection_readUnsigned32Value(IedConnection self, IedClientError* error, const char* objectReference, FunctionalConstraint fc); + +/** + * \brief read a functional constrained data attribute (FCDA) of type Timestamp (UTC Time) + * + * NOTE: If the timestamp parameter is set to NULL the function allocates a new timestamp instance. Otherwise the + * return value is a pointer to the user provided timestamp instance. The new timestamp instance has to be freed by + * the caller of the function. + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the data attribute to read + * \param fc the functional constraint of the data attribute to read + * \param timestamp a pointer to a user provided timestamp instance or NULL + * + * \return the timestamp value + */ +LIB61850_API Timestamp* +IedConnection_readTimestampValue(IedConnection self, IedClientError* error, const char* objectReference, FunctionalConstraint fc, + Timestamp* timeStamp); + +/** + * \brief read a functional constrained data attribute (FCDA) of type Quality + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the data attribute to read + * \param fc the functional constraint of the data attribute to read + * + * \return the timestamp value + */ +LIB61850_API Quality +IedConnection_readQualityValue(IedConnection self, IedClientError* error, const char* objectReference, FunctionalConstraint fc); + +/** + * \brief write a functional constrained data attribute (FCDA) of type boolean + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the data attribute to read + * \param fc the functional constraint of the data attribute or data object to write + * \param value the boolean value to write + */ +LIB61850_API void +IedConnection_writeBooleanValue(IedConnection self, IedClientError* error, const char* objectReference, + FunctionalConstraint fc, bool value); + +/** + * \brief write a functional constrained data attribute (FCDA) of type integer + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the data attribute to read + * \param fc the functional constraint of the data attribute or data object to write + * \param value the int32_t value to write + */ +LIB61850_API void +IedConnection_writeInt32Value(IedConnection self, IedClientError* error, const char* objectReference, + FunctionalConstraint fc, int32_t value); + +/** + * \brief write a functional constrained data attribute (FCDA) of type unsigned (integer) + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the data attribute to read + * \param fc the functional constraint of the data attribute or data object to write + * \param value the uint32_t value to write + */ +LIB61850_API void +IedConnection_writeUnsigned32Value(IedConnection self, IedClientError* error, const char* objectReference, + FunctionalConstraint fc, uint32_t value); + +/** + * \brief write a functional constrained data attribute (FCDA) of type float + * + * \param self the connection object to operate on + * \param error the error code if an error occurs + * \param object reference of the data attribute to read + * \param fc the functional constraint of the data attribute or data object to write + * \param value the float value to write + */ +LIB61850_API void +IedConnection_writeFloatValue(IedConnection self, IedClientError* error, const char* objectReference, + FunctionalConstraint fc, float value); + +LIB61850_API void +IedConnection_writeVisibleStringValue(IedConnection self, IedClientError* error, const char* objectReference, + FunctionalConstraint fc, char* value); + +LIB61850_API void +IedConnection_writeOctetString(IedConnection self, IedClientError* error, const char* objectReference, + FunctionalConstraint fc, uint8_t* value, int valueLength); + +/** @} */ + +/******************************************** + * Reporting services + ********************************************/ + +/** + * @defgroup IEC61850_CLIENT_REPORTS Client side report handling services, functions, and data types + * + * @{ + */ + +/** + * \brief Read access to attributes of a report control block (RCB) at the connected server + * + * The requested RCB has to be specified by its object reference. E.g. + * + * "simpleIOGenericIO/LLN0.RP.EventsRCB01" + * + * or + * + * "simpleIOGenericIO/LLN0.BR.EventsBRCB01" + * + * Report control blocks have either "RP" or "BR" as part of their name following the logical node part. + * "RP" is part of the name of unbuffered RCBs whilst "BR" is part of the name of buffered RCBs. + * + * This function is used to perform the actual read service. To access the received values the functions + * of ClientReportControlBlock have to be used. + * + * If called with a NULL argument for the updateRcb parameter a new ClientReportControlBlock instance is created + * and populated with the values received by the server. It is up to the user to release this object by + * calling the ClientReportControlBlock_destroy function when the object is no longer needed. If called with a reference + * to an existing ClientReportControlBlock instance the values of the attributes will be updated and no new instance + * will be created. + * + * Note: This function maps to a single MMS read request to retrieve the complete RCB at once. + * + * \param connection the connection object + * \param error the error code if an error occurs + * \param rcbReference object reference of the report control block + * \param updateRcb a reference to an existing ClientReportControlBlock instance or NULL + * + * \return new ClientReportControlBlock instance or the instance provided by the user with + * the updateRcb parameter. + */ +LIB61850_API ClientReportControlBlock +IedConnection_getRCBValues(IedConnection self, IedClientError* error, const char* rcbReference, + ClientReportControlBlock updateRcb); + +typedef void +(*IedConnection_GetRCBValuesHandler) (uint32_t invokeId, void* parameter, IedClientError err, ClientReportControlBlock rcb); + +LIB61850_API uint32_t +IedConnection_getRCBValuesAsync(IedConnection self, IedClientError* error, const char* rcbReference, ClientReportControlBlock updateRcb, + IedConnection_GetRCBValuesHandler handler, void* parameter); + +/** Describes the reason for the inclusion of the element in the report */ +typedef int ReasonForInclusion; + +/** the element is not included in the received report */ +#define IEC61850_REASON_NOT_INCLUDED 0 + +/** the element is included due to a change of the data value */ +#define IEC61850_REASON_DATA_CHANGE 1 + +/** the element is included due to a change in the quality of data */ +#define IEC61850_REASON_QUALITY_CHANGE 2 + +/** the element is included due to an update of the data value */ +#define IEC61850_REASON_DATA_UPDATE 4 + +/** the element is included due to a periodic integrity report task */ +#define IEC61850_REASON_INTEGRITY 8 + +/** the element is included due to a general interrogation by the client */ +#define IEC61850_REASON_GI 16 + +/** the reason for inclusion is unknown (e.g. report is not configured to include reason-for-inclusion) */ +#define IEC61850_REASON_UNKNOWN 32 + +#define REASON_NOT_INCLUDED IEC61850_REASON_NOT_INCLUDED +#define REASON_DATA_CHANGE IEC61850_REASON_DATA_CHANGE +#define REASON_QUALITY_CHANGE IEC61850_REASON_QUALITY_CHANGE +#define REASON_DATA_UPDATE IEC61850_REASON_DATA_UPDATE +#define REASON_INTEGRITY IEC61850_REASON_INTEGRITY +#define REASON_GI IEC61850_REASON_GI +//#define REASON_UNKNOWN IEC61850_REASON_UNKNOWN + + +/* Element encoding mask values for ClientReportControlBlock */ + +/** include the report ID into the setRCB request */ +#define RCB_ELEMENT_RPT_ID 1 + +/** include the report enable element into the setRCB request */ +#define RCB_ELEMENT_RPT_ENA 2 + +/** include the reservation element into the setRCB request (only available in unbuffered RCBs!) */ +#define RCB_ELEMENT_RESV 4 + +/** include the data set element into the setRCB request */ +#define RCB_ELEMENT_DATSET 8 + +/** include the configuration revision element into the setRCB request */ +#define RCB_ELEMENT_CONF_REV 16 + +/** include the option fields element into the setRCB request */ +#define RCB_ELEMENT_OPT_FLDS 32 + +/** include the bufTm (event buffering time) element into the setRCB request */ +#define RCB_ELEMENT_BUF_TM 64 + +/** include the sequence number element into the setRCB request (should be used!) */ +#define RCB_ELEMENT_SQ_NUM 128 + +/** include the trigger options element into the setRCB request */ +#define RCB_ELEMENT_TRG_OPS 256 + +/** include the integrity period element into the setRCB request */ +#define RCB_ELEMENT_INTG_PD 512 + +/** include the GI (general interrogation) element into the setRCB request */ +#define RCB_ELEMENT_GI 1024 + +/** include the purge buffer element into the setRCB request (only available in buffered RCBs) */ +#define RCB_ELEMENT_PURGE_BUF 2048 + +/** include the entry ID element into the setRCB request (only available in buffered RCBs) */ +#define RCB_ELEMENT_ENTRY_ID 4096 + +/** include the time of entry element into the setRCB request (only available in buffered RCBs) */ +#define RCB_ELEMENT_TIME_OF_ENTRY 8192 + +/** include the reservation time element into the setRCB request (only available in buffered RCBs) */ +#define RCB_ELEMENT_RESV_TMS 16384 + +/** include the owner element into the setRCB request */ +#define RCB_ELEMENT_OWNER 32768 + +/** + * \brief Write access to attributes of a report control block (RCB) at the connected server + * + * The requested RCB has to be specified by its object reference (see also IedConnection_getRCBValues). + * The object reference for the referenced RCB is contained in the provided ClientReportControlBlock instance. + * + * The parametersMask parameter specifies which attributes of the remote RCB have to be set by this request. + * You can specify multiple attributes by ORing the defined bit values. + * + * The singleRequest parameter specifies the mapping to the corresponding MMS write request. Standard compliant + * servers should accept both variants. But some server accept only one variant. Then the value of this parameter + * will be of relevance. + * + * \param connection the connection object + * \param error the error code if an error occurs + * \param rcb object reference of the ClientReportControlBlock instance that actually holds the parameter + * values to be written. + * \param parametersMask specifies the parameters contained in the setRCBValues request. + * \param singleRequest specifies if the setRCBValues services is mapped to a single MMS write request containing + * multiple variables or to multiple MMS write requests. + */ +LIB61850_API void +IedConnection_setRCBValues(IedConnection self, IedClientError* error, ClientReportControlBlock rcb, + uint32_t parametersMask, bool singleRequest); + +LIB61850_API uint32_t +IedConnection_setRCBValuesAsync(IedConnection self, IedClientError* error, ClientReportControlBlock rcb, + uint32_t parametersMask, bool singleRequest, IedConnection_GenericServiceHandler handler, void* parameter); + +/** + * \brief Callback function for receiving reports + * + * \param parameter a user provided parameter that is handed to the callback function + * \param report a ClientReport instance that holds the informations contained in the received report + */ +typedef void (*ReportCallbackFunction) (void* parameter, ClientReport report); + +/** + * \brief Install a report handler function for the specified report control block (RCB) + * + * This function will replace a report handler set earlier for the specified RCB. The report handler + * will be called whenever a report for the specified RCB is received. + * Please note that this function should be called whenever the RCB data set is changed or updated. + * Otherwise the internal data structures storing the received data set values will not be updated + * correctly. + * + * When replacing a report handler you only have to call this function. There is no separate call to + * IedConnection_uninstallReportHandler() required. + * + * \param self the connection object + * \param rcbReference object reference of the report control block + * \param rptId a string that identifies the report. If the rptId is not available then the + * rcbReference is used to identify the report. + * \param handler user provided callback function to be invoked when a report is received. + * \param handlerParameter user provided parameter that will be passed to the callback function + */ +LIB61850_API void +IedConnection_installReportHandler(IedConnection self, const char* rcbReference, const char* rptId, ReportCallbackFunction handler, + void* handlerParameter); + +/** + * \brief uninstall a report handler function for the specified report control block (RCB) + * + * \param self the connection object + * \param rcbReference object reference of the report control block + */ +LIB61850_API void +IedConnection_uninstallReportHandler(IedConnection self, const char* rcbReference); + +/** + * \brief trigger a general interrogation (GI) report for the specified report control block (RCB) + * + * The RCB must have been enabled and GI set as trigger option before this command can be performed. + * + * \deprecated Use ClientReportControlBlock_setGI instead + * + * \param connection the connection object + * \param error the error code if an error occurs + * \param rcbReference object reference of the report control block + */ +LIB61850_API void +IedConnection_triggerGIReport(IedConnection self, IedClientError* error, const char* rcbReference); + +/**************************************** + * Access to received reports + ****************************************/ + +/** + * \brief get the name of the report data set + * + * NOTE: the returned string is only valid as long as the ClientReport instance exists! + * + * \param self the ClientReport instance + * \return report data set name as 0 terminated string + */ +LIB61850_API const char* +ClientReport_getDataSetName(ClientReport self); + +/** + * \brief return the received data set values of the report + * + * NOTE: The returned MmsValue instance is handled by the library and only valid as long as the + * ClientReport instance exists! It should not be used outside the report callback handler to + * avoid concurrency issues. + * + * \param self the ClientReport instance + * \return an MmsValue array instance containing the data set values + */ +LIB61850_API MmsValue* +ClientReport_getDataSetValues(ClientReport self); + +/** + * ȡαлݣҪҵɾ˶ + */ +LIB61850_API MmsValue* +ClientReport_getDataValues(ClientReport self); + +/** +* ȡαλǣ˱ݼЩ +*/ +LIB61850_API MmsValue* +ClientReport_getInclusion(ClientReport self); + +/** +* ȡαеһ +*/ +LIB61850_API int +ClientReport_getValueIndex(ClientReport self); + +/** + * \brief return reference (name) of the server RCB associated with this ClientReport object + * + * \param self the ClientReport instance + * \return report control block reference as string + */ +LIB61850_API char* +ClientReport_getRcbReference(ClientReport self); + +/** + * \brief return RptId of the server RCB associated with this ClientReport object + * + * \param self the ClientReport instance + * \return report control block reference as string + */ +LIB61850_API char* +ClientReport_getRptId(ClientReport self); + +/** + * \brief get the reason code (reason for inclusion) for a specific report data set element + * + * \param self the ClientReport instance + * \param elementIndex index of the data set element (starting with 0) + * + * \return reason code for the inclusion of the specified element + */ +LIB61850_API ReasonForInclusion +ClientReport_getReasonForInclusion(ClientReport self, int elementIndex); + +/** + * \brief get the entry ID of the report + * + * Returns the entryId of the report if included in the report. Otherwise returns NULL. + * + * \param self the ClientReport instance + * + * \return entryId or NULL + */ +LIB61850_API MmsValue* +ClientReport_getEntryId(ClientReport self); + +/** + * \brief determine if the last received report contains a timestamp + * + * \param self the ClientReport instance + * + * \return true if the report contains a timestamp, false otherwise + */ +LIB61850_API bool +ClientReport_hasTimestamp(ClientReport self); + +/** + * \brief determine if the last received report contains a sequence number + * + * \param self the ClientReport instance + * + * \return true if the report contains a sequence number, false otherwise + */ +LIB61850_API bool +ClientReport_hasSeqNum(ClientReport self); + +/** + * \brief get the value of the sequence number + * + * NOTE: The returned value is undefined if the sequence number is not present in report + * + * \param self the ClientReport instance + * + * \returns the number of the sequence number when present + */ +LIB61850_API uint16_t +ClientReport_getSeqNum(ClientReport self); + +/** + * \brief determine if the last received report contains the data set name + * + * \param self the ClientReport instance + * + * \return true if the report contains the data set name, false otherwise + */ +LIB61850_API bool +ClientReport_hasDataSetName(ClientReport self); + +/** + * \brief determine if the last received report contains reason-for-inclusion information + * + * \param self the ClientReport instance + * + * \return true if the report contains reason-for-inclusion information, false otherwise + */ +LIB61850_API bool +ClientReport_hasReasonForInclusion(ClientReport self); + +/** + * \brief determine if the last received report contains the configuration revision + * + * \param self the ClientReport instance + * + * \return true if the report contains the configuration revision, false otherwise + */ +LIB61850_API bool +ClientReport_hasConfRev(ClientReport self); + +/** + * \brief get the value of the configuration revision + * + * NOTE: The returned value is undefined if configuration revision is not present in report + * + * \param self the ClientReport instance + * + * \returns the number of the configuration revision + */ +LIB61850_API uint32_t +ClientReport_getConfRev(ClientReport self); + +/** + * \brief indicates if the report contains the bufOvfl (buffer overflow) flag + * + * \param self the ClientReport instance + * + * \returns true if the report contains the bufOvfl flag, false otherwise + */ +LIB61850_API bool +ClientReport_hasBufOvfl(ClientReport self); + +/** + * \brief get the value of the bufOvfl flag + * + * \param self the ClientReport instance + * + * \returns true if bufOvfl is set, false otherwise + */ +LIB61850_API bool +ClientReport_getBufOvfl(ClientReport self); + +/** + * \brief indicates if the report contains data references for the reported data set members + * + * \param self the ClientReport instance + * + * \returns true if the report contains data-references, false otherwise + */ +LIB61850_API bool +ClientReport_hasDataReference(ClientReport self); + +/** + * \brief get the data-reference of the element of the report data set + * + * This function will only return a non-NULL value if the received report contains data-references. + * This can be determined by the ClientReport_hasDataReference function. + * NOTE: The returned string is allocated and hold by the ClientReport instance and is only valid until + * the ClientReport instance exists! + * + * \param self the ClientReport instance + * \param elementIndex index of the data set element (starting with 0) + * + * \param the data reference as string as provided by the report or NULL if the data reference is not available + */ +LIB61850_API const char* +ClientReport_getDataReference(ClientReport self, int elementIndex); + + +/** + * \brief get the timestamp of the report + * + * Returns the timestamp of the report if included in the report. Otherwise the value is undefined. + * Use the ClientReport_hasTimestamp function first to figure out if the timestamp is valid + * + * \param self the ClientReport instance + * + * \return the timestamp as milliseconds since 1.1.1970 UTC + */ +LIB61850_API uint64_t +ClientReport_getTimestamp(ClientReport self); + +/** + * \brief indicates if the report contains a sub sequence number and a more segments follow flags (for segmented reporting) + * + * \param self the ClientReport instance + * + * \returns true if the report contains sub-sequence-number and more-follows-flag, false otherwise + */ +LIB61850_API bool +ClientReport_hasSubSeqNum(ClientReport self); + +/** + * \brief get the sub sequence number of the report (for segmented reporting) + * + * Returns the sub sequence number of the report. This is 0 for the first report of a segmented report and + * will be increased by one for each report segment. + * + * \param self the ClientReport instance + * + * \return the sub sequence number of the last received report message. + */ +LIB61850_API uint16_t +ClientReport_getSubSeqNum(ClientReport self); + +/** + * \brief get the more segments follow flag of the received report segment (for segmented reporting) + * + * Will return true in case this is part of a segmented report and more report segments will follow or false, if + * the current report is not a segmented report or is the last segment of a segmented report. + * + * \param self the ClientReport instance + * + * \return true when more segments of the current report will follow, false otherwise + */ +LIB61850_API bool +ClientReport_getMoreSeqmentsFollow(ClientReport self); + +/** + * \brief get the reason for inclusion of as a human readable string + * + * \param reasonCode + * + * \return the reason for inclusion as static human readable string + */ +LIB61850_API char* +ReasonForInclusion_getValueAsString(ReasonForInclusion reasonCode); + +/************************************************** + * ClientReportControlBlock access class + **************************************************/ + +LIB61850_API ClientReportControlBlock +ClientReportControlBlock_create(const char* rcbReference); + +LIB61850_API void +ClientReportControlBlock_destroy(ClientReportControlBlock self); + +LIB61850_API char* +ClientReportControlBlock_getObjectReference(ClientReportControlBlock self); + +LIB61850_API bool +ClientReportControlBlock_isBuffered(ClientReportControlBlock self); + +LIB61850_API const char* +ClientReportControlBlock_getRptId(ClientReportControlBlock self); + +LIB61850_API void +ClientReportControlBlock_setRptId(ClientReportControlBlock self, const char* rptId); + +LIB61850_API bool +ClientReportControlBlock_getRptEna(ClientReportControlBlock self); + +LIB61850_API void +ClientReportControlBlock_setRptEna(ClientReportControlBlock self, bool rptEna); + +LIB61850_API bool +ClientReportControlBlock_getResv(ClientReportControlBlock self); + +LIB61850_API void +ClientReportControlBlock_setResv(ClientReportControlBlock self, bool resv); + +LIB61850_API const char* +ClientReportControlBlock_getDataSetReference(ClientReportControlBlock self); + +/** + * \brief set the data set to be observed by the RCB + * + * The data set reference is a mixture of MMS and IEC 61850 syntax! In general the reference has + * the form: + * LDName/LNName$DataSetName + * + * e.g. "simpleIOGenericIO/LLN0$Events" + * + * It is standard that data sets are defined in LN0 logical nodes. But this is not mandatory. + * + * Note: As a result of changing the data set the server will increase the confRev attribute of the RCB. + * + * \param self the RCB instance + * \param dataSetReference the reference of the data set + */ +LIB61850_API void +ClientReportControlBlock_setDataSetReference(ClientReportControlBlock self, const char* dataSetReference); + +LIB61850_API uint32_t +ClientReportControlBlock_getConfRev(ClientReportControlBlock self); + +/** + * \brief Gets the OptFlds parameter of the RCB (decides what information to include in a report) + * + * \param self the RCB instance + * + * \return bit field representing the optional fields of a report (uses flags from \ref REPORT_OPTIONS) + */ +LIB61850_API int +ClientReportControlBlock_getOptFlds(ClientReportControlBlock self); + +/** + * \brief Set the OptFlds parameter of the RCB (decides what information to include in a report) + * + * \param self the RCB instance + * \param optFlds bit field representing the optional fields of a report (use flags from \ref REPORT_OPTIONS) + */ +LIB61850_API void +ClientReportControlBlock_setOptFlds(ClientReportControlBlock self, int optFlds); + +/** + * \brief Get the BufTm (buffer time) parameter of the RCB + * + * The buffer time is the time to wait after a triggering event before the report is actually sent. + * It is used to be able to collect events that happen in a short time period and send them in a single report. + * + * \param self the RCB instance + */ +LIB61850_API uint32_t +ClientReportControlBlock_getBufTm(ClientReportControlBlock self); + +/** + * \brief Set the BufTm (buffer time) parameter of the RCB + * + * The buffer time is the time to wait after a triggering event before the report is actually sent. + * It is used to be able to collect events that happen in a short time period and send them in a single report. + * + * \param self the RCB instance + * \param bufTm the buffer time in ms + */ +LIB61850_API void +ClientReportControlBlock_setBufTm(ClientReportControlBlock self, uint32_t bufTm); + +LIB61850_API uint16_t +ClientReportControlBlock_getSqNum(ClientReportControlBlock self); + +LIB61850_API int +ClientReportControlBlock_getTrgOps(ClientReportControlBlock self); + +LIB61850_API void +ClientReportControlBlock_setTrgOps(ClientReportControlBlock self, int trgOps); + +LIB61850_API uint32_t +ClientReportControlBlock_getIntgPd(ClientReportControlBlock self); + +LIB61850_API void +ClientReportControlBlock_setIntgPd(ClientReportControlBlock self, uint32_t intgPd); + +LIB61850_API bool +ClientReportControlBlock_getGI(ClientReportControlBlock self); + +LIB61850_API void +ClientReportControlBlock_setGI(ClientReportControlBlock self, bool gi); + +LIB61850_API bool +ClientReportControlBlock_getPurgeBuf(ClientReportControlBlock self); + +/** + * \brief Set the "PurgeBuf" attribute value (only BRCB) + * + * When set to true the report buffer will be cleared. + * + * \param purgeBuf attribute value + */ +LIB61850_API void +ClientReportControlBlock_setPurgeBuf(ClientReportControlBlock self, bool purgeBuf); + +/** + * \brief Check if optional attribute "ResvTms" is present in BRCB + * + * \return true when present, false otherwise + */ +LIB61850_API bool +ClientReportControlBlock_hasResvTms(ClientReportControlBlock self); + +LIB61850_API int16_t +ClientReportControlBlock_getResvTms(ClientReportControlBlock self); + +LIB61850_API void +ClientReportControlBlock_setResvTms(ClientReportControlBlock self, int16_t resvTms); + +LIB61850_API MmsValue* /* */ +ClientReportControlBlock_getEntryId(ClientReportControlBlock self); + +LIB61850_API void +ClientReportControlBlock_setEntryId(ClientReportControlBlock self, MmsValue* entryId); + +LIB61850_API uint64_t +ClientReportControlBlock_getEntryTime(ClientReportControlBlock self); + +LIB61850_API MmsValue* /* */ +ClientReportControlBlock_getOwner(ClientReportControlBlock self); + + +/** @} */ + +/**************************************** + * Data set handling + ****************************************/ + +/** + * @defgroup IEC61850_CLIENT_DATA_SET Client side data set service functions and data types + * + * @{ + */ + +/** + * \brief get data set values from the server + * + * The parameter dataSetReference is the name of the data set to read. It is either in the form LDName/LNodeName.dataSetName + * for permanent domain or VMD scope data sets or @dataSetName for an association specific data set. + * If the LDName part of the reference is missing the resulting data set will be of VMD scope. + * The received data set values are stored in a container object of type ClientDataSet that can be reused in a further + * read request. + * + * \param connection the connection object + * \param error the error code if an error occurs + * \param dataSetReference object reference of the data set + * \param dataSet a data set instance where to store the retrieved values or NULL if a new instance + * shall be created. + * + * \return data set instance with retrieved values of NULL if an error occurred. + */ +LIB61850_API ClientDataSet +IedConnection_readDataSetValues(IedConnection self, IedClientError* error, const char* dataSetReference, ClientDataSet dataSet); + +typedef void +(*IedConnection_ReadDataSetHandler) (uint32_t invokeId, void* parameter, IedClientError err, ClientDataSet dataSet); + +/** + * \brief get data set values from the server - async version + * + * The parameter dataSetReference is the name of the data set to read. It is either in the form LDName/LNodeName.dataSetName + * for permanent domain or VMD scope data sets or @dataSetName for an association specific data set. + * If the LDName part of the reference is missing the resulting data set will be of VMD scope. + * The received data set values are stored in a container object of type ClientDataSet that can be reused in a further + * service request. + * + * \param connection the connection object + * \param error the error code if an error occurs + * \param dataSetReference object reference of the data set + * \param dataSet a data set instance where to store the retrieved values or NULL if a new instance + * shall be created. + * \param handler the user provided callback handler + * \param parameter user provided parameter that is passed to the callback handler + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +IedConnection_readDataSetValuesAsync(IedConnection self, IedClientError* error, const char* dataSetReference, ClientDataSet dataSet, + IedConnection_ReadDataSetHandler handler, void* parameter); + +/** + * \brief create a new data set at the connected server device + * + * This function creates a new data set at the server. The parameter dataSetReference is the name of the new data set + * to create. It is either in the form LDName/LNodeName.dataSetName for permanent domain or VMD scope data sets or + * @dataSetName for an association specific data set. If the LDName part of the reference is missing the resulting + * data set will be of VMD scope. + * + * The dataSetElements parameter contains a linked list containing the object references of FCDs or FCDAs. The format of + * this object references is LDName/LNodeName.item(arrayIndex)component[FC]. + * + * \param connection the connection object + * \param error the error code if an error occurs + * \param dataSetReference object reference of the data set + * \param dataSetElements a list of object references defining the members of the new data set + * + */ +LIB61850_API void +IedConnection_createDataSet(IedConnection self, IedClientError* error, const char* dataSetReference, LinkedList /* char* */ dataSetElements); + +/** + * \brief create a new data set at the connected server device + * + * This function creates a new data set at the server. The parameter dataSetReference is the name of the new data set + * to create. It is either in the form LDName/LNodeName.dataSetName for permanent domain or VMD scope data sets or + * @dataSetName for an association specific data set. If the LDName part of the reference is missing the resulting + * data set will be of VMD scope. + * + * The dataSetElements parameter contains a linked list containing the object references of FCDs or FCDAs. The format of + * this object references is LDName/LNodeName.item(arrayIndex)component[FC]. + * + * \param connection the connection object + * \param error the error code if an error occurs + * \param dataSetReference object reference of the data set + * \param dataSetElements a list of object references defining the members of the new data set + * + * \param handler the callback handler that is called when the response is received or timeout + * \param parameter user provided parameter that is passed to the callback handler + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +IedConnection_createDataSetAsync(IedConnection self, IedClientError* error, const char* dataSetReference, LinkedList /* char* */ dataSetElements, + IedConnection_GenericServiceHandler handler, void* parameter); + +/** + * \brief delete a deletable data set at the connected server device + * + * This function deletes a data set at the server. The parameter dataSetReference is the name of the data set + * to delete. It is either in the form LDName/LNodeName.dataSetName or @dataSetName for an association specific data set. + * + * + * \param connection the connection object + * \param error the error code if an error occurs + * \param dataSetReference object reference of the data set + * + * \return true if data set has been deleted, false otherwise + */ +LIB61850_API bool +IedConnection_deleteDataSet(IedConnection self, IedClientError* error, const char* dataSetReference); + +/** + * \brief delete a deletable data set at the connected server device - asynchronous version + * + * This function deletes a data set at the server. The parameter dataSetReference is the name of the data set + * to delete. It is either in the form LDName/LNodeName.dataSetName or @dataSetName for an association specific data set. + * + * The data set was deleted successfully when the callback parameter "error" is IED_ERROR_OK. Otherwise the "error" + * parameter contains a particular error code. + * + * \param connection the connection object + * \param error the error code if an error occurs + * \param dataSetReference object reference of the data set + * \param handler the callback handler that is called when the response is received or timeout + * \param parameter user provided parameter that is passed to the callback handler + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +IedConnection_deleteDataSetAsync(IedConnection self, IedClientError* error, const char* dataSetReference, + IedConnection_GenericServiceHandler handler, void* parameter); + +/** + * \brief read the data set directory + * + * The return value contains a linked list containing the object references of FCDs or FCDAs. The format of + * this object references is LDName/LNodeName.item(arrayIndex)component[FC]. + * + * \param connection the connection object + * \param[out] error the error code if an error occurs + * \param dataSetReference object reference of the data set + * \param[out] isDeletable this is an output parameter indicating that the requested data set is deletable by clients. + * If this information is not required a NULL pointer can be used. + * + * \return LinkedList containing the data set elements as char* strings. + */ +LIB61850_API LinkedList /* */ +IedConnection_getDataSetDirectory(IedConnection self, IedClientError* error, const char* dataSetReference, bool* isDeletable); + +/** + * \brief GetDataSetDirectory response or timeout callback + * + * \param dataSetDirectory a linked list containing the object references of FCDs or FCDAs. The format of + * this object references is LDName/LNodeName.item(arrayIndex)component[FC]. + * \param isDeletable this is an output parameter indicating that the requested data set is deletable by clients. + */ +typedef void +(*IedConnection_GetDataSetDirectoryHandler) (uint32_t invokeId, void* parameter, IedClientError err, LinkedList /* */ dataSetDirectory, bool isDeletable); + +/** + * \brief read the data set directory - asynchronous version + * + * The result data is a linked list containing the object references of FCDs or FCDAs. The format of + * this object references is LDName/LNodeName.item(arrayIndex)component[FC]. + * + * \param connection the connection object + * \param[out] error the error code if an error occurs + * \param dataSetReference object reference of the data set + * \param handler the callback handler that is called when the response is received or timeout + * \param parameter user provided parameter that is passed to the callback handler + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +IedConnection_getDataSetDirectoryAsync(IedConnection self, IedClientError* error, const char* dataSetReference, + IedConnection_GetDataSetDirectoryHandler handler, void* parameter); + +/** + * \brief Write the data set values to the server + * + * The parameter dataSetReference is the name of the data set to write. It is either in the form LDName/LNodeName.dataSetName + * for permanent domain or VMD scope data sets or @dataSetName for an association specific data set. + * If the LDName part of the reference is missing the resulting data set will be of VMD scope. + * The values parameter has to be the same number of elements as are members in the data set. The accessResult return parameter + * contains a value for each data set member. + * + * \param connection the connection object + * \param[out] error the error code if an error occurs + * \param dataSetReference object reference of the data set + * \param values the new data set values + * \param[out] accessResults the access results for each data set member + */ +LIB61850_API void +IedConnection_writeDataSetValues(IedConnection self, IedClientError* error, const char* dataSetReference, + LinkedList/**/ values, /* OUTPUT */LinkedList* /* */accessResults); + +/** + * \brief Callback handler for asynchronous write data set values services (set data set) + * + * \param invokeId the invoke ID of the service request + * \param parameter used provided parameter + * \param err the error code if an error occurs + * \param accessResults the list of access results for the data set entries. + */ +typedef void +(*IedConnection_WriteDataSetHandler) (uint32_t invokeId, void* parameter, IedClientError err, LinkedList /* */accessResults); + +/** + * \brief Write the data set values to the server - async version + * + * The parameter dataSetReference is the name of the data set to write. It is either in the form LDName/LNodeName.dataSetName + * for permanent domain or VMD scope data sets or @dataSetName for an association specific data set. + * If the LDName part of the reference is missing the resulting data set will be of VMD scope. + * The values parameter has to be the same number of elements as are members in the data set. + * + * When the service call had been successful the \ref IedConnection_WriteDataSetHandler is called with an error value of + * IED_ERROR_OK and a list of MmsValue instances of type data access error. These describe the access results of the individual + * data set entries. + * + * \param connection the connection object + * \param[out] error the error code if an error occurs + * \param dataSetReference object reference of the data set + * \param values the new data set values + * \param handler the user provided callback handler + * \param parameter user provided parameter that is passed to the callback handler + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +IedConnection_writeDataSetValuesAsync(IedConnection self, IedClientError* error, const char* dataSetReference, + LinkedList/**/ values, IedConnection_WriteDataSetHandler handler, void* parameter); + + +/******************************************************** + * Data set object (local representation of a data set) + *******************************************************/ + +/** + * \brief destroy an ClientDataSet instance. Has to be called by the application. + * + * Note: A ClientDataSet cannot be created directly by the application but only by the IedConnection_readDataSetValues + * function. Therefore there is no public ClientDataSet_create function. + * + * \param self the ClientDataSet instance + */ +LIB61850_API void +ClientDataSet_destroy(ClientDataSet self); + +/** + * \brief get the data set values locally stored in the ClientDataSet instance. + * + * This function returns a pointer to the locally stored MmsValue instance of this + * ClientDataSet instance. The MmsValue instance is of type MMS_ARRAY and contains one + * array element for each data set member. + * Note: This call does not invoke any interaction with the associated server. It will + * only provide access to already stored value. To update the values with the current values + * of the server the IecConnection_readDataSetValues function has to be called! + * + * \param self the ClientDataSet instance + * + * \return the locally stored data set values as MmsValue object of type MMS_ARRAY. + */ +LIB61850_API MmsValue* +ClientDataSet_getValues(ClientDataSet self); + +/** + * \brief Get the object reference of the data set. + * + * \param self the ClientDataSet instance + * + * \return the object reference of the data set. + */ +LIB61850_API char* +ClientDataSet_getReference(ClientDataSet self); + +/** + * \brief get the size of the data set (number of members) + * + * \param self the ClientDataSet instance + * + * \return the number of member contained in the data set. + */ +LIB61850_API int +ClientDataSet_getDataSetSize(ClientDataSet self); + +/** @} */ + +/************************************ + * Control service functions + ************************************/ + +/** + * @defgroup IEC61850_CLIENT_CONTROL Client side control service functions + * + * @{ + */ + +typedef struct sControlObjectClient* ControlObjectClient; + +/** + * \brief Create a new client control object + * + * A client control object is used to handle all client side functions of a controllable + * data object. A controllable data object is an instance of a controllable CDC like e.g. + * SPC, DPC, APC, ... + * + * NOTE: This function will synchronously request information about the control object + * (like ctlModel) from the server. The function will block until these requests return + * or time-out. + * + * \param objectReference the reference of the controllable data object + * \param connection the connection instance where the control object has to be reached + * + * \return the newly created instance or NULL if the creation failed + */ +LIB61850_API ControlObjectClient +ControlObjectClient_create(const char* objectReference, IedConnection connection, const FunctionalConstraint FC); + +/** + * \brief Create a new client control object - doesn't send requests to the server (doesn't block) + * + * A client control object is used to handle all client side functions of a controllable + * data object. A controllable data object is an instance of a controllable CDC like e.g. + * SPC, DPC, APC, ... + * + * \param objectReference the reference of the controllable data object + * \param connection the connection instance where the control object has to be reached + * \param ctlModel the control model used by the controllable data object + * \param controlObjectSpec specification of the controllable data objects - used to derive required information to handle the control object + */ +LIB61850_API ControlObjectClient +ControlObjectClient_createEx(const char* objectReference, IedConnection connection, ControlModel ctlModel, MmsVariableSpecification* controlObjectSpec); + +/** + * \brief Destroy the client control object instance and release all related resources + * + * \param self the control object instance to use + */ +LIB61850_API void +ControlObjectClient_destroy(ControlObjectClient self); + +/** + * Cause of the \ref ControlObjectClient_ControlActionHandler invocation + */ +typedef enum +{ + CONTROL_ACTION_TYPE_SELECT = 0, /** < callback was invoked because of a select command */ + CONTROL_ACTION_TYPE_OPERATE = 1, /** < callback was invoked because of an operate command */ + CONTROL_ACTION_TYPE_CANCEL = 2 /** < callback was invoked because of a cancel command */ +} ControlActionType; + +/** + * \brief A callback handler that is invoked when a command termination message is received. + * + * This callback is invoked whenever a CommandTermination+ or CommandTermination- message is received. + * To distinguish between a CommandTermination+ and CommandTermination- please use the + * ControlObjectClient_getLastApplError function. + * + * NOTE: Do not call \ref ControlObjectClient_destroy inside of this callback! Doing so will cause a dead-lock. + * + * \param invokeId invoke ID of the command sent by the client + * \param parameter the user parameter that is passed to the callback function + * \param err the error code when an error occurred, or IED_ERROR_OK + * \param type control action type that caused the callback + * \param success true, when the command was successful, false otherwise + * + */ +typedef void +(*ControlObjectClient_ControlActionHandler) (uint32_t invokeId, void* parameter, IedClientError err, ControlActionType type, bool success); + +/** + * \brief Get the object reference of the control data object + * + * \param self the control object instance to use + * + * \return the object reference (string is valid only as long as the \ref ControlObjectClient instance exists). + */ +LIB61850_API const char* +ControlObjectClient_getObjectReference(ControlObjectClient self); + +/** + * \brief Get the current control model (local representation) applied to the control object + * + * \param self the control object instance to use + * + * \return the current applied control model (\ref ControlModel) + */ +LIB61850_API ControlModel +ControlObjectClient_getControlModel(ControlObjectClient self); + +/** + * \brief Set the applied control model + * + * NOTE: This function call will not change the server control model. + * + * \param self the control object instance to use + * \param ctlModel the new control model to apply + */ +LIB61850_API void +ControlObjectClient_setControlModel(ControlObjectClient self, ControlModel ctlModel); + +/** + * \brief Change the control model of the server. + * + * NOTE: Not supported by all servers. Information can be found in the PIXIT of the server. + * Also sets the applied control model for this client control instance. + * + * \param self the control object instance to use + * \param ctlModel the new control model + */ +LIB61850_API void +ControlObjectClient_changeServerControlModel(ControlObjectClient self, ControlModel ctlModel); + +/** + * \brief Get the type of ctlVal. + * + * This type is required for the ctlVal parameter of the \ref ControlObjectClient_operate + * and \ref ControlObjectClient_selectWithValue functions. + * + * \param self the control object instance to use + * + * \return MmsType required for the ctlVal value. + */ +LIB61850_API MmsType +ControlObjectClient_getCtlValType(ControlObjectClient self); + +/** + * \brief Get the error code of the last synchronous control action (operate, select, select-with-value, cancel) + * + * \param self the control object instance to use + * + * \return the client error code + */ +LIB61850_API IedClientError +ControlObjectClient_getLastError(ControlObjectClient self); + +/** + * \brief Send an operate command to the server + * + * \param self the control object instance to use + * \param ctlVal the control value (for APC the value may be either AnalogueValue (MMS_STRUCT) or MMS_FLOAT/MMS_INTEGER + * \param operTime the time when the command has to be executed (for time activated control). The value represents the local time of the + * server in milliseconds since epoch. If this value is 0 the command will be executed instantly. + * + * \return true if operation has been successful, false otherwise. + */ +LIB61850_API bool +ControlObjectClient_operate(ControlObjectClient self, MmsValue* ctlVal, uint64_t operTime,const FunctionalConstraint FC); + +/** + * \brief Send a select command to the server + * + * The select command is only used for the control model "select-before-operate with normal security" + * (CONTROL_MODEL_SBO_NORMAL). The select command has to be sent before the operate command can be used. + * + * \param self the control object instance to use + * + * \return true if operation has been successful, false otherwise. + */ +LIB61850_API bool +ControlObjectClient_select(ControlObjectClient self, const FunctionalConstraint FC); + +/** + * \brief Send an select with value command to the server + * + * The select-with-value command is only used for the control model "select-before-operate with enhanced security" + * (CONTROL_MODEL_SBO_ENHANCED). The select-with-value command has to be sent before the operate command can be used. + * + * \param self the control object instance to use + * \param ctlVal the control value (for APC the value may be either AnalogueValue (MMS_STRUCT) or MMS_FLOAT/MMS_INTEGER + * + * \return true if select has been successful, false otherwise. + */ +LIB61850_API bool +ControlObjectClient_selectWithValue(ControlObjectClient self, MmsValue* ctlVal,const FunctionalConstraint FC); + +/** + * \brief Send a cancel command to the server + * + * The cancel command can be used to stop an ongoing operation (when the server and application + * support this) and to cancel a former select command. + * + * \param self the control object instance to use + * + * \return true if operation has been successful, false otherwise. + */ +LIB61850_API bool +ControlObjectClient_cancel(ControlObjectClient self,const FunctionalConstraint FC); + + +/** + * \brief Send an operate command to the server - async version + * + * \param self the control object instance to use + * \param[out] err error code + * \param ctlVal the control value (for APC the value may be either AnalogueValue (MMS_STRUCT) or MMS_FLOAT/MMS_INTEGER + * \param operTime the time when the command has to be executed (for time activated control). The value represents the local time of the + * server in milliseconds since epoch. If this value is 0 the command will be executed instantly. + * \param handler the user provided callback handler + * \param parameter user provided parameter that is passed to the callback handler + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +ControlObjectClient_operateAsync(ControlObjectClient self, IedClientError* err, MmsValue* ctlVal, uint64_t operTime, + ControlObjectClient_ControlActionHandler handler, void* parameter, const FunctionalConstraint FC); + +/** + * \brief Send a select command to the server - async version + * + * The select command is only used for the control model "select-before-operate with normal security" + * (CONTROL_MODEL_SBO_NORMAL). The select command has to be sent before the operate command can be used. + * + * \param self the control object instance to use + * \param[out] err error code + * \param handler the user provided callback handler + * \param parameter user provided parameter that is passed to the callback handler + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +ControlObjectClient_selectAsync(ControlObjectClient self, IedClientError* err, ControlObjectClient_ControlActionHandler handler, void* parameter, const FunctionalConstraint FC); + +/** + * \brief Send a select-with-value command to the server - async version + * + * The select-with-value command is only used for the control model "select-before-operate with enhanced security" + * (CONTROL_MODEL_SBO_ENHANCED). The select-with-value command has to be sent before the operate command can be used. + * + * \param self the control object instance to use + * \param[out] err error code + * \param ctlVal the control value (for APC the value may be either AnalogueValue (MMS_STRUCT) or MMS_FLOAT/MMS_INTEGER + * \param handler the user provided callback handler + * \param parameter user provided parameter that is passed to the callback handler + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +ControlObjectClient_selectWithValueAsync(ControlObjectClient self, IedClientError* err, MmsValue* ctlVal, + ControlObjectClient_ControlActionHandler handler, void* parameter, const FunctionalConstraint FC); + +/** + * \brief Send a cancel command to the server - async version + * + * The cancel command can be used to stop an ongoing operation (when the server and application + * support this) and to cancel a former select command. + * + * \param self the control object instance to use + * \param[out] err error code + * \param handler the user provided callback handler + * \param parameter user provided parameter that is passed to the callback handler + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +ControlObjectClient_cancelAsync(ControlObjectClient self, IedClientError* err, ControlObjectClient_ControlActionHandler handler, void* parameter, const FunctionalConstraint FC); + +/** + * \brief Get the last received control application error + * + * NOTE: this is the content of the "LastApplError" message received from the server. + * + * \return the value of the last received application error + */ +LIB61850_API LastApplError +ControlObjectClient_getLastApplError(ControlObjectClient self); + +/** + * \brief Send commands in test mode. + * + * When the server supports test mode the commands that are sent with the test flag set + * are not executed (will have no effect on the attached physical process). + * + * \param self the control object instance to use + * \param value value if the test flag (true = test mode). + */ +LIB61850_API void +ControlObjectClient_setTestMode(ControlObjectClient self, bool value); + +/** + * \brief Set the origin parameter for control commands + * + * The origin parameter is used to identify the client/application that sent a control + * command. It is intended for later analysis. + * + * \param self the ControlObjectClient instance + * \param orIdent originator identification can be an arbitrary string + * \param orCat originator category (see \ref ORIGINATOR_CATEGORIES) + */ +LIB61850_API void +ControlObjectClient_setOrigin(ControlObjectClient self, const char* orIdent, int orCat); + +/** + * \brief Use a constant T parameter for all command (select, operate, cancel) of a single control sequence + * + * NOTE: Some non-standard compliant servers may require this to accept oper/cancel requests + * + * \param self the ControlObjectClient instance + * \param useContantT enable this behavior with true, disable with false + */ +LIB61850_API void +ControlObjectClient_useConstantT(ControlObjectClient self, bool useConstantT); + +/** + * \deprecated use ControlObjectClient_setInterlockCheck instead + */ +LIB61850_API DEPRECATED void +ControlObjectClient_enableInterlockCheck(ControlObjectClient self); + +/** + * \deprecated use ControlObjectClient_setSynchroCheck instead + */ +LIB61850_API DEPRECATED void +ControlObjectClient_enableSynchroCheck(ControlObjectClient self); + +/** + * \deprecated Do not use (ctlNum is handled automatically by the library)! Intended for test purposes only. + */ +LIB61850_API DEPRECATED void +ControlObjectClient_setCtlNum(ControlObjectClient self, uint8_t ctlNum); + +/** + * \brief Set the value of the interlock check flag when a control command is sent + * + * \param self the ControlObjectClient instance + * \param value if true the server will perform a interlock check if supported + */ +LIB61850_API void +ControlObjectClient_setInterlockCheck(ControlObjectClient self, bool value); + +/** + * \brief Set the value of the synchro check flag when a control command is sent + * + * \param self the ControlObjectClient instance + * \param value if true the server will perform a synchro check if supported + */ +LIB61850_API void +ControlObjectClient_setSynchroCheck(ControlObjectClient self, bool value); + + +/** + * \brief A callback handler that is invoked when a command termination message is received. + * + * This callback is invoked whenever a CommandTermination+ or CommandTermination- message is received. + * To distinguish between a CommandTermination+ and CommandTermination- please use the + * \ref ControlObjectClient_getLastApplError function. + * + * In case of CommandTermination+ the return value + * of \ref ControlObjectClient_getLastApplError has error=CONTROL_ERROR_NO_ERROR and + * addCause=ADD_CAUSE_UNKNOWN set. When addCause is different from ADD_CAUSE_UNKNOWN then the client + * received a CommandTermination- message. + * + * NOTE: Do not call \ref ControlObjectClient_destroy inside of this callback! Doing so will cause a dead-lock. + * + * \param parameter the user parameter that is passed to the callback function + * \param controlClient the ControlObjectClient instance + */ +typedef void (*CommandTerminationHandler) (void* parameter, ControlObjectClient controlClient); + +/** + * \brief Set the command termination callback handler for this control object + * + * This callback is invoked whenever a CommandTermination+ or CommandTermination- message is received. + * To distinguish between a CommandTermination+ and CommandTermination- please use the + * \ref ControlObjectClient_getLastApplError function. In case of CommandTermination+ the return value + * of \ref ControlObjectClient_getLastApplError has error=CONTROL_ERROR_NO_ERROR and + * addCause=ADD_CAUSE_UNKNOWN set. When addCause is different from ADD_CAUSE_UNKNOWN then the client + * received a CommandTermination- message. + * + * \param self the ControlObjectClient instance + * \param handler the callback function to be used + * \param handlerParameter a user parameter that is passed to the handler + */ +LIB61850_API void +ControlObjectClient_setCommandTerminationHandler(ControlObjectClient self, CommandTerminationHandler handler, + void* handlerParameter); + +/** @} */ + +/************************************* + * Model discovery services + ************************************/ + +/** + * @defgroup IEC61850_CLIENT_MODEL_DISCOVERY Model discovery services + * + * @{ + */ + +/** + * \brief Retrieve the device model from the server + * + * This function retrieves the complete device model from the server. The model is buffered an can be browsed + * by subsequent API calls. This API call is mapped to multiple ACSI services. + * + * \param self the connection object + * \param error the error code if an error occurs + * + */ +LIB61850_API void +IedConnection_getDeviceModelFromServer(IedConnection self, IedClientError* error); + +/** + * \brief Get the list of logical devices available at the server (DEPRECATED) + * + * This function is mapped to the GetServerDirectory(LD) ACSI service. + * + * NOTE: This function will call \ref IedConnection_getDeviceModelFromServer if no buffered data model + * information is available. Otherwise it will use the buffered information. + * + * \param self the connection object + * \param error the error code if an error occurs + * + * \return LinkedList with string elements representing the logical device names + */ +LIB61850_API LinkedList /**/ +IedConnection_getLogicalDeviceList(IedConnection self, IedClientError* error); + +/** + * \brief Get the list of logical devices or files available at the server + * + * GetServerDirectory ACSI service implementation. This function will either return the list of + * logical devices (LD) present at the server or the list of available files. + * + * NOTE: When getFIleNames is false zhis function will call + * \ref IedConnection_getDeviceModelFromServer if no buffered data model + * information is available. Otherwise it will use the buffered information. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param getFileNames get list of files instead of logical device names (TO BE IMPLEMENTED) + * + * \return LinkedList with string elements representing the logical device names or file names + */ +LIB61850_API LinkedList /**/ +IedConnection_getServerDirectory(IedConnection self, IedClientError* error, bool getFileNames); + +/** + * \brief Get the list of logical nodes (LN) of a logical device + * + * GetLogicalDeviceDirectory ACSI service implementation. Returns the list of logical nodes names present + * in a logical device. The list is returned as a linked list of type LinkedList with c style string elements. + * + * NOTE: This function will call \ref IedConnection_getDeviceModelFromServer if no buffered data model + * information is available. Otherwise it will use the buffered information. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param logicalDeviceName the name of the logical device (LD) of interest + * + * \return LinkedList with string elements representing the logical node names + */ +LIB61850_API LinkedList /**/ +IedConnection_getLogicalDeviceDirectory(IedConnection self, IedClientError* error, const char* logicalDeviceName); + +typedef enum { + ACSI_CLASS_DATA_OBJECT, + ACSI_CLASS_DATA_SET, + ACSI_CLASS_BRCB, + ACSI_CLASS_URCB, + ACSI_CLASS_LCB, + ACSI_CLASS_LOG, + ACSI_CLASS_SGCB, + ACSI_CLASS_GoCB, + ACSI_CLASS_GsCB, + ACSI_CLASS_MSVCB, + ACSI_CLASS_USVCB +} ACSIClass; + +/** + * \brief returns a list of all MMS variables that are children of the given logical node + * + * This function cannot be mapped to any ACSI service. It is a convenience function for generic clients that + * wants to show a list of all available children of the MMS named variable representing the logical node. + * + * NOTE: This function will call \ref IedConnection_getDeviceModelFromServer if no buffered data model + * information is available. Otherwise it will use the buffered information. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param logicalNodeReference string that represents the LN reference + * + * \return the list of all MMS named variables as C strings in a LinkedList type + */ +LIB61850_API LinkedList /**/ +IedConnection_getLogicalNodeVariables(IedConnection self, IedClientError* error, + const char* logicalNodeReference); + +/** + * \brief returns the directory of the given logical node (LN) containing elements of the specified ACSI class + * + * Implementation of the GetLogicalNodeDirectory ACSI service. In contrast to the ACSI description this + * function does not always creates a request to the server. For most ACSI classes it simply accesses the + * data model that was retrieved before or calls \ref IedConnection_getDeviceModelFromServer if no buffered data model + * information is available. An exception to this rule are the ACSI classes ACSI_CLASS_DATASET and + * ACSI_CLASS_LOG. Both always perform a request to the server. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param logicalNodeReference string that represents the LN reference + * \param acsiClass specifies the ACSI class + * + * \return list of all logical node elements of the specified ACSI class type as C strings in a LinkedList + */ +LIB61850_API LinkedList /**/ +IedConnection_getLogicalNodeDirectory(IedConnection self, IedClientError* error, + const char* logicalNodeReference, ACSIClass acsiClass); + +/** + * \brief returns the directory of the given data object (DO) + * + * Implementation of the GetDataDirectory ACSI service. This will return the list of + * all data attributes or sub data objects. + * + * NOTE: This function will call \ref IedConnection_getDeviceModelFromServer if no buffered data model + * information is available. Otherwise it will use the buffered information. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param dataReference string that represents the DO reference + * + * \return list of all data attributes or sub data objects as C strings in a LinkedList + */ +LIB61850_API LinkedList /**/ +IedConnection_getDataDirectory(IedConnection self, IedClientError* error, const char* dataReference); + +/** + * \brief returns the directory of the given data object (DO) + * + * Implementation of the GetDataDirectory ACSI service. This will return the list of + * C strings with all data attributes or sub data objects as elements. The returned + * strings will contain the functional constraint appended in square brackets when appropriate. + * + * NOTE: This function will call \ref IedConnection_getDeviceModelFromServer if no buffered data model + * information is available. Otherwise it will use the buffered information. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param dataReference string that represents the DO reference + * + * \return list of all data attributes or sub data objects as C strings in a LinkedList + */ +LIB61850_API LinkedList /**/ +IedConnection_getDataDirectoryFC(IedConnection self, IedClientError* error, const char* dataReference); + +/** + * \brief returns the directory of the given data object/data attribute with the given FC + * + * Implementation of the GetDataDirectory ACSI service. This will return the list of + * C strings with all data attributes or sub data objects as elements. + * + * NOTE: This function will call \ref IedConnection_getDeviceModelFromServer if no buffered data model + * information is available. Otherwise it will use the buffered information. + * + * WARNING: Starting with version 1.0.3 the functional constraint will no longer be appended to + * the name string. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param dataReference string that represents the DO reference + * \param fc the functional constraint + * + * \return list of all data attributes or sub data objects as C strings in a LinkedList + */ +LIB61850_API LinkedList +IedConnection_getDataDirectoryByFC(IedConnection self, IedClientError* error, const char* dataReference, FunctionalConstraint fc); + +/** + * \brief return the MMS variable type specification of the data attribute referenced by dataAttributeReference and function constraint fc. + * + * This function can be used to get the MMS variable type specification for an IEC 61850 data attribute. It is an extension + * of the ACSI that may be required by generic client applications. + * + * NOTE: API user is responsible to free the resources (see \ref MmsVariableSpecification_destroy) + * + * \param self the connection object + * \param error the error code if an error occurs + * \param dataAttributeReference string that represents the DA reference + * \param fc functional constraint of the DA + * + * \return MmsVariableSpecification of the data attribute. + */ +LIB61850_API MmsVariableSpecification* +IedConnection_getVariableSpecification(IedConnection self, IedClientError* error, const char* dataAttributeReference, + FunctionalConstraint fc); + +/** + * \brief Get all variables of the logical device + * + * NOTE: This function will return all MMS variables of the logical device (MMS domain). The result will be in the + * MMS notation (like "GGIO1$ST$Ind1$stVal") and also contain the variables of control blocks. + * + * \param[in] self the connection object + * \param[out] error the error code if an error occurs + * \param[in] ldName the logical device name + * + * \return a \ref LinkedList with the MMS variable names as string. Has to be released by the caller + */ +LIB61850_API LinkedList +IedConnection_getLogicalDeviceVariables(IedConnection self, IedClientError* error, const char* ldName); + +/** + * \brief Get the data set names of the logical device + * + * NOTE: This function will return all data set names (MMS named variable lists) of the logical device (MMS domain). The result will be in the + * MMS notation (like "LLN0$dataset1"). + * + * \param[in] self the connection object + * \param[out] error the error code if an error occurs + * \param[in] ldName the logical device name + * + * \return a \ref LinkedList with data set names as string. Has to be released by the caller. + */ +LIB61850_API LinkedList +IedConnection_getLogicalDeviceDataSets(IedConnection self, IedClientError* error, const char* ldName); + +/***************************************** + * Asynchronous model discovery functions + *****************************************/ + +typedef void +(*IedConnection_GetNameListHandler) (uint32_t invokeId, void* parameter, IedClientError err, LinkedList nameList, bool moreFollows); + +/** + * \brief Get the server directory (logical devices name) - asynchronous version + * + * \param[in] self the connection object + * \param[out] error the error code if an error occurs + * \param[in] continueAfter the name of the last received element when the call is a continuation, or NULL for the first call + * \param[in] result list to store (append) the response names, or NULL to create a new list for the response names + * \param[in] handler will be called when response is received or timed out. + * \param[in] parameter + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +IedConnection_getServerDirectoryAsync(IedConnection self, IedClientError* error, const char* continueAfter, LinkedList result, + IedConnection_GetNameListHandler handler, void* parameter); + +/** + * \brief Get the variables in the logical device - asynchronous version + * + * NOTE: This function will return all MMS variables of the logical device (MMS domain). The result will be in the + * MMS notation (like "GGIO1$ST$Ind1$stVal") and also contain the variables of control blocks. + * + * \param[in] self the connection object + * \param[out] error the error code if an error occurs + * \param[in] ldName the logical device name + * \param[in] continueAfter the name of the last received element when the call is a continuation, or NULL for the first call + * \param[in] result list to store (append) the response names, or NULL to create a new list for the response names + * \param[in] handler will be called when response is received or timed out. + * \param[in] parameter + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +IedConnection_getLogicalDeviceVariablesAsync(IedConnection self, IedClientError* error, const char* ldName, const char* continueAfter, LinkedList result, + IedConnection_GetNameListHandler handler, void* parameter); + +/** + * \brief Get the data set names in the logical device - asynchronous version + * + * NOTE: This function will return all data set names (MMS named variable lists) of the logical device (MMS domain). The result will be in the + * MMS notation (like "LLN0$dataset1"). + * + * \param[in] self the connection object + * \param[out] error the error code if an error occurs + * \param[in] ldName the logical device name + * \param[in] continueAfter the name of the last received element when the call is a continuation, or NULL for the first call + * \param[in] result list to store (append) the response names, or NULL to create a new list for the response names + * \param[in] handler will be called when response is received or timed out. + * \param[in] parameter + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +IedConnection_getLogicalDeviceDataSetsAsync(IedConnection self, IedClientError* error, const char* ldName, const char* continueAfter, LinkedList result, + IedConnection_GetNameListHandler handler, void* parameter); + + +typedef void +(*IedConnection_GetVariableSpecificationHandler) (uint32_t invokeId, void* parameter, IedClientError err, MmsVariableSpecification* spec); + +/** + * \brief Get the specification of a variable (data attribute or functional constraint data object) - asynchronous version + * + * \param[in] self the connection object + * \param[out] error the error code if an error occurs + * \param[in] dataAttributeReference the data attribute reference (FCDA or FCDO) + * \param[in] handler will be called when response is received or timed out. + * \param[in] parameter + * + * \return the invoke ID of the request + */ +LIB61850_API uint32_t +IedConnection_getVariableSpecificationAsync(IedConnection self, IedClientError* error, const char* dataAttributeReference, + FunctionalConstraint fc, IedConnection_GetVariableSpecificationHandler handler, void* parameter); + +/** @} */ + +/** + * @defgroup IEC61850_CLIENT_LOG_SERVICE Log service related functions, data types, and definitions + * + * @{ + */ + +/** + * \brief Implementation of the QueryLogByTime ACSI service + * + * Read log entries from a log at the server. The log entries to read are specified by + * a starting time and an end time. If the complete range does not fit in a single MMS message + * the moreFollows flag will be set to true, to indicate that more entries are available for the + * specified time range. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param logReference log object reference in the form /$ + * \param startTime as millisecond UTC timestamp + * \param endTime as millisecond UTC timestamp + * \param moreFollows (output value) indicates that more entries are available that match the specification. + * + * \return list of MmsJournalEntry objects matching the specification + */ +LIB61850_API LinkedList /* */ +IedConnection_queryLogByTime(IedConnection self, IedClientError* error, const char* logReference, + uint64_t startTime, uint64_t endTime, bool* moreFollows); + +/** + * \brief Implementation of the QueryLogAfter ACSI service + * + * Read log entries from a log at the server following the entry with the specified entryID and timestamp. + * If the complete range does not fit in a single MMS message + * the moreFollows flag will be set to true, to indicate that more entries are available for the + * specified time range. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param logReference log object reference in the form /$ + * \param entryID usually the entryID of the last received entry + * \param timeStamp as millisecond UTC timestamp + * \param moreFollows (output value) indicates that more entries are available that match the specification. + * + * \return list of MmsJournalEntry objects matching the specification + */ +LIB61850_API LinkedList /* */ +IedConnection_queryLogAfter(IedConnection self, IedClientError* error, const char* logReference, + MmsValue* entryID, uint64_t timeStamp, bool* moreFollows); + + +typedef void +(*IedConnection_QueryLogHandler) (uint32_t invokeId, void* parameter, IedClientError mmsError, LinkedList /* */ journalEntries, bool moreFollows); + +LIB61850_API uint32_t +IedConnection_queryLogByTimeAsync(IedConnection self, IedClientError* error, const char* logReference, + uint64_t startTime, uint64_t endTime, IedConnection_QueryLogHandler handler, void* parameter); + +LIB61850_API uint32_t +IedConnection_queryLogAfterAsync(IedConnection self, IedClientError* error, const char* logReference, + MmsValue* entryID, uint64_t timeStamp, IedConnection_QueryLogHandler handler, void* parameter); + +/** @} */ + +/** + * @defgroup IEC61850_CLIENT_FILE_SERVICE File service related functions, data types, and definitions + * + * @{ + */ + +typedef struct sFileDirectoryEntry* FileDirectoryEntry; + +/** + * @deprecated Will be removed from API + */ +LIB61850_API FileDirectoryEntry +FileDirectoryEntry_create(const char* fileName, uint32_t fileSize, uint64_t lastModified); + +/** + * \brief Destroy a FileDirectoryEntry object (free all resources) + * + * NOTE: Usually is called as a parameter of the \ref LinkedList_destroyDeep function. + * + * \param self the FileDirectoryEntry object + */ +LIB61850_API void +FileDirectoryEntry_destroy(FileDirectoryEntry self); + +/** + * \brief Get the name of the file + * + * \param self the FileDirectoryEntry object + * + * \return name of the file as null terminated string + */ +LIB61850_API const char* +FileDirectoryEntry_getFileName(FileDirectoryEntry self); + +/** + * \brief Get the file size in bytes + * + * \param self the FileDirectoryEntry object + * + * \return size of the file in bytes, or 0 if file size is unknown + */ +LIB61850_API uint32_t +FileDirectoryEntry_getFileSize(FileDirectoryEntry self); + +/** + * \brief Get the timestamp of last modification of the file + * + * \param self the FileDirectoryEntry object + * + * \return UTC timestamp in milliseconds + */ +LIB61850_API uint64_t +FileDirectoryEntry_getLastModified(FileDirectoryEntry self); + + +/** + * \brief returns the directory entries of the specified file directory. + * + * Requires the server to support file services. + * + * NOTE: the returned linked list has to be freed by the user. You can user the following statement + * to free the list of directory entries: + * + * LinkedList_destroyDeep(fileNames, (LinkedListValueDeleteFunction) FileDirectoryEntry_destroy); + * + * where fileNames is the return value of this function. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param directoryName the name of the directory or NULL to get the entries of the root directory + * + * \return the list of directory entries. The return type is a LinkedList with FileDirectoryEntry elements + */ +LIB61850_API LinkedList /**/ +IedConnection_getFileDirectory(IedConnection self, IedClientError* error, const char* directoryName); + + +/** + * \brief returns the directory entries of the specified file directory returned by a single file directory request. + * + * This function will only create a single request and the result may only be the directory that fits + * into a single MMS PDU. If the server contains more directory entries, this will be indicated by setting + * the moreFollows variable (if provided by the caller). If the directory entry does not fit into a single MMS + * PDU the next part of the directory list can be requested by setting the continueAfter parameter with the value + * of the last filename of the received list. + * + * Requires the server to support file services. + * + * NOTE: the returned linked list has to be freed by the user. You can user the following statement + * to free the list of directory entries: + * + * LinkedList_destroyDeep(fileNames, (LinkedListValueDeleteFunction) FileDirectoryEntry_destroy); + * + * where fileNames is the return value of this function. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param directoryName the name of the directory or NULL to get the entries of the root directory + * \param continueAfter last received filename to continue after, or NULL for the first request + * \param moreFollows if provided by the caller (non NULL) the function will indicate if more directory entries + * are available. + * + * \return the list of directory entries. The return type is a LinkedList with FileDirectoryEntry elements + */ +LIB61850_API LinkedList /**/ +IedConnection_getFileDirectoryEx(IedConnection self, IedClientError* error, const char* directoryName, const char* continueAfter, + bool* moreFollows); + +/** + * \brief Callback handler for the get file directory service + * + * Will be called once for each file directory entry and after the last entry with \ref moreFollows = false to indicate + * to indicate that no more data will follow. In case of an error the callback will be called with + * \ref err != IED_ERROR_OK and moreFollows = false. + */ + +/** + * \brief Callback handler for the get file directory service + * + * Will be called once for each file directory entry and after the last entry with \ref filename = NULL to indicate + * with \ref moreFollows set to true if more data is available at the server (can only happen when using the \ref IedConnection_getFileDirectoryAsyncEx + * function). In case of an error the callback will be called with \ref err != IED_ERROR_OK and moreFollows = false. + * + * \param invokeId invoke ID of the request + * \param parameter user provided parameter + * \param err error code in case of a problem, otherwise IED_ERROR_OK + * \param filename the filename of the current file directory entry or NULL if no more entries are available + * \param size the file size in byte of the current file directory entry + * \param lastModified the last modified timestamp of the current file directory entry + * + * \return return false when the request has to be stopped (no further callback invokations), true otherwise + */ +typedef bool +(*IedConnection_FileDirectoryEntryHandler) (uint32_t invokeId, void* parameter, IedClientError err, char* filename, uint32_t size, uint64_t lastModfified, + bool moreFollows); + +/** + * \brief Get file directory (single request) - asynchronous version + * + * The provided handler will be called for each received file directory entry. + * + * NOTE: This will only cause a single MMS request. When the resulting file directory doesn't fit into + * a single MMS PDU another request has to be sent indicating a continuation point with the continueAfter + * parameter. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param directoryName the name of the directory or NULL to get the entries of the root directory + * \param continueAfter last received filename to continue after, or NULL for the first request + * \param handler the callback handler + * \param parameter user provided callback parameter + * + * \return the invokeId of the first file directory request + */ +LIB61850_API uint32_t +IedConnection_getFileDirectoryAsyncEx(IedConnection self, IedClientError* error, const char* directoryName, const char* continueAfter, + IedConnection_FileDirectoryEntryHandler handler, void* parameter); + +/** + * \brief user provided handler to receive the data of the GetFile request + * + * This handler will be invoked whenever the clients receives a data block from + * the server. The API user has to copy the data to another location before returning. + * The other location could for example be a file in the clients file system. + * + * \param parameter user provided parameter + * \param buffer pointer to the buffer containing the received data + * \param bytesRead number of bytes available in the buffer + * + * \return true if the client implementation shall continue to download data false if the download + * should be stopped. E.g. if the file cannot be stored client side due to missing resources. + */ +typedef bool +(*IedClientGetFileHandler) (void* parameter, uint8_t* buffer, uint32_t bytesRead); + +/** + * \brief Implementation of the GetFile ACSI service + * + * Download a file from the server. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param fileName the name of the file to be read from the server + * + * \return number of bytes received + */ +LIB61850_API uint32_t +IedConnection_getFile(IedConnection self, IedClientError* error, const char* fileName, IedClientGetFileHandler handler, + void* handlerParameter); + + +/** + * \brief User provided handler to receive the data of the asynchronous GetFile request + * + * This handler will be invoked whenever the clients receives a data block from + * the server. The API user has to copy the data to another location before returning. + * The other location could for example be a file in the clients file system. When the + * last data block is received the moreFollows parameter will be set to false. + * + * \param invokeId invoke ID of the message containing the received data + * \param parameter user provided parameter passed to the callback + * \param err error code in case of an error or IED_ERROR_OK + * \param originalInvokeId the invoke ID of the original (first) request. This is usually the request to open the file. + * \param buffer the buffer that contains the received file data + * \param bytesRead the number of bytes read into the buffer + * \param moreFollows indicates that more file data is following + * + * \return true, continue the file download when moreFollows is true, false, stop file download + */ +typedef bool +(*IedConnection_GetFileAsyncHandler) (uint32_t invokeId, void* parameter, IedClientError err, uint32_t originalInvokeId, + uint8_t* buffer, uint32_t bytesRead, bool moreFollows); + + +/** + * \brief Implementation of the GetFile ACSI service - asynchronous version + * + * Download a file from the server. + * + * NOTE: This function can cause several request messages to be sent until the complete file is received + * or the file transfer is canceled. It allocates a background task and an outstanding call slot. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param fileName the name of the file to be read from the server + * \param hander callback handler that is called for each received data or error message + * \param parameter user provided callback parameter + * + * \return invokeId of the first sent request + */ +LIB61850_API uint32_t +IedConnection_getFileAsync(IedConnection self, IedClientError* error, const char* fileName, IedConnection_GetFileAsyncHandler handler, + void* parameter); + +/** + * \brief Set the virtual filestore basepath for the setFile service + * + * All external file service accesses will be mapped to paths relative to the base directory. + * NOTE: This function is only available when the CONFIG_SET_FILESTORE_BASEPATH_AT_RUNTIME + * option in stack_config.h is set. + * + * \param self the connection object + * \param basepath the new virtual filestore basepath + */ +LIB61850_API void +IedConnection_setFilestoreBasepath(IedConnection, const char* basepath); + +/** + * \brief Implementation of the SetFile ACSI service + * + * Upload a file to the server. The file has to be available in the local VMD filestore. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param sourceFilename the filename of the local (client side) file + * \param destinationFilename the filename of the remote (service side) file + */ +LIB61850_API void +IedConnection_setFile(IedConnection self, IedClientError* error, const char* sourceFilename, const char* destinationFilename); + +/** + * \brief Implementation of the SetFile ACSI service - asynchronous version + * + * Upload a file to the server. The file has to be available in the local VMD filestore. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param sourceFilename the filename of the local (client side) file + * \param destinationFilename the filename of the remote (service side) file + * \param handler callback handler that is called when the obtain file response has been received + * \param parameter user provided callback parameter + */ +LIB61850_API uint32_t +IedConnection_setFileAsync(IedConnection self, IedClientError* error, const char* sourceFilename, const char* destinationFilename, + IedConnection_GenericServiceHandler handler, void* parameter); + +/** + * \brief Implementation of the DeleteFile ACSI service + * + * Delete a file at the server. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param fileName the name of the file to delete + */ +LIB61850_API void +IedConnection_deleteFile(IedConnection self, IedClientError* error, const char* fileName); + +/** + * \brief Implementation of the DeleteFile ACSI service - asynchronous version + * + * Delete a file at the server. + * + * \param self the connection object + * \param error the error code if an error occurs + * \param fileName the name of the file to delete + * \param handler callback handler that is called when the obtain file response has been received + * \param parameter user provided callback parameter + */ +LIB61850_API uint32_t +IedConnection_deleteFileAsync(IedConnection self, IedClientError* error, const char* fileName, + IedConnection_GenericServiceHandler handler, void* parameter); + + +/** @} */ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + + +#endif /* IEC61850_CLIENT_H_ */ diff --git a/product/src/fes/include/libiec61850/iec61850_common.h b/product/src/fes/include/libiec61850/iec61850_common.h new file mode 100644 index 00000000..e8374072 --- /dev/null +++ b/product/src/fes/include/libiec61850/iec61850_common.h @@ -0,0 +1,548 @@ +/* + * iec61850_common.h + * + * Copyright 2013-2019 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef IEC61850_COMMON_H_ +#define IEC61850_COMMON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "libiec61850_common_api.h" +#include "logging_api.h" +#include "linked_list.h" + +/** + * @defgroup iec61850_common_api_group IEC 61850 API common parts + */ +/**@{*/ + +/** IEC 61850 edition 1 */ +#define IEC_61850_EDITION_1 0 + +/** IEC 61850 edition 2 */ +#define IEC_61850_EDITION_2 1 + +/** IEC 61850 edition 2.1 */ +#define IEC_61850_EDITION_2_1 2 + +/** PhyComAddress type contains Ethernet address and VLAN attributes */ +typedef struct { + uint8_t vlanPriority; + uint16_t vlanId; + uint16_t appId; + uint8_t dstAddress[6]; +} PhyComAddress; + +/** + * \brief Control model (represented by "ctlModel" attribute) + */ +typedef enum { + /** + * No support for control functions. Control object only support status information. + */ + CONTROL_MODEL_STATUS_ONLY = 0, + + /** + * Direct control with normal security: Supports Operate, TimeActivatedOperate (optional), + * and Cancel (optional). + */ + CONTROL_MODEL_DIRECT_NORMAL = 1, + + /** + * Select before operate (SBO) with normal security: Supports Select, Operate, TimeActivatedOperate (optional), + * and Cancel (optional). + */ + CONTROL_MODEL_SBO_NORMAL = 2, + + /** + * Direct control with enhanced security (enhanced security includes the CommandTermination service) + */ + CONTROL_MODEL_DIRECT_ENHANCED = 3, + + /** + * Select before operate (SBO) with enhanced security (enhanced security includes the CommandTermination service) + */ + CONTROL_MODEL_SBO_ENHANCED = 4 +} ControlModel; + +/** + * @defgroup TRIGGER_OPTIONS Trigger options (bit values combinable) + * + * @{ + */ + +/** Report will be triggered when data changes */ +#define TRG_OPT_DATA_CHANGED 1 + +/** Report will be triggered when quality changes */ +#define TRG_OPT_QUALITY_CHANGED 2 + +/** Report will be triggered when data is updated */ +#define TRG_OPT_DATA_UPDATE 4 + +/** Report will be triggered periodically */ +#define TRG_OPT_INTEGRITY 8 + +/** Report will be triggered by GI (general interrogation) request */ +#define TRG_OPT_GI 16 + +/** Report will be triggered only on rising edge (transient variable */ +#define TRG_OPT_TRANSIENT 128 +/** @} */ + + + +/** + * @defgroup REPORT_OPTIONS Report options (bit values combinable) + * + * @{ + */ + +/** Report contains sequence number */ +#define RPT_OPT_SEQ_NUM 1 + +/** Report contains a report timestamp */ +#define RPT_OPT_TIME_STAMP 2 + +/** Report contains reason for inclusion value for each included data set member */ +#define RPT_OPT_REASON_FOR_INCLUSION 4 + +/** Report contains data set object reference */ +#define RPT_OPT_DATA_SET 8 + +/** Report contains data reference for each included data set member */ +#define RPT_OPT_DATA_REFERENCE 16 + +/** Report contains buffer overflow flag */ +#define RPT_OPT_BUFFER_OVERFLOW 32 + +/** Report contains entry id */ +#define RPT_OPT_ENTRY_ID 64 + +/** Report contains configuration revision */ +#define RPT_OPT_CONF_REV 128 +/** @} */ + +/** + * @defgroup ORIGINATOR_CATEGORIES Originator categories (orCat) + * + * @{ + */ + +/** Not supported - should not be used */ +#define CONTROL_ORCAT_NOT_SUPPORTED 0 + +/** Control operation issued from an operator using a client located at bay level */ +#define CONTROL_ORCAT_BAY_CONTROL 1 + +/** Control operation issued from an operator using a client located at station level */ +#define CONTROL_ORCAT_STATION_CONTROL 2 + +/** Control operation from a remote operator outside the substation (for example network control center) */ +#define CONTROL_ORCAT_REMOTE_CONTROL 3 + +/** Control operation issued from an automatic function at bay level */ +#define CONTROL_ORCAT_AUTOMATIC_BAY 4 + +/** Control operation issued from an automatic function at station level */ +#define CONTROL_ORCAT_AUTOMATIC_STATION 5 + +/** Control operation issued from a automatic function outside of the substation */ +#define CONTROL_ORCAT_AUTOMATIC_REMOTE 6 + +/** Control operation issued from a maintenance/service tool */ +#define CONTROL_ORCAT_MAINTENANCE 7 + +/** Status change occurred without control action (for example external trip of a circuit breaker or failure inside the breaker) */ +#define CONTROL_ORCAT_PROCESS 8 + +/** @} */ + +/** + * @defgroup CONTROL_ADD_CAUSE Definition for addCause type - used in control models + * + * @{ + */ + +/** AddCause - additional cause information for control model errors */ +typedef enum { + ADD_CAUSE_UNKNOWN = 0, + ADD_CAUSE_NOT_SUPPORTED = 1, + ADD_CAUSE_BLOCKED_BY_SWITCHING_HIERARCHY = 2, + ADD_CAUSE_SELECT_FAILED = 3, + ADD_CAUSE_INVALID_POSITION = 4, + ADD_CAUSE_POSITION_REACHED = 5, + ADD_CAUSE_PARAMETER_CHANGE_IN_EXECUTION = 6, + ADD_CAUSE_STEP_LIMIT = 7, + ADD_CAUSE_BLOCKED_BY_MODE = 8, + ADD_CAUSE_BLOCKED_BY_PROCESS = 9, + ADD_CAUSE_BLOCKED_BY_INTERLOCKING = 10, + ADD_CAUSE_BLOCKED_BY_SYNCHROCHECK = 11, + ADD_CAUSE_COMMAND_ALREADY_IN_EXECUTION = 12, + ADD_CAUSE_BLOCKED_BY_HEALTH = 13, + ADD_CAUSE_1_OF_N_CONTROL = 14, + ADD_CAUSE_ABORTION_BY_CANCEL = 15, + ADD_CAUSE_TIME_LIMIT_OVER = 16, + ADD_CAUSE_ABORTION_BY_TRIP = 17, + ADD_CAUSE_OBJECT_NOT_SELECTED = 18, + ADD_CAUSE_OBJECT_ALREADY_SELECTED = 19, + ADD_CAUSE_NO_ACCESS_AUTHORITY = 20, + ADD_CAUSE_ENDED_WITH_OVERSHOOT = 21, + ADD_CAUSE_ABORTION_DUE_TO_DEVIATION = 22, + ADD_CAUSE_ABORTION_BY_COMMUNICATION_LOSS = 23, + ADD_CAUSE_ABORTION_BY_COMMAND = 24, + ADD_CAUSE_NONE = 25, + ADD_CAUSE_INCONSISTENT_PARAMETERS = 26, + ADD_CAUSE_LOCKED_BY_OTHER_CLIENT = 27 +} ControlAddCause; + +/** @} */ + +/** + * @defgroup CONTROL_LAST_APPL_ERROR Definition for LastAppError error type - used in control models + * + * @{ + */ + +typedef enum { + CONTROL_ERROR_NO_ERROR = 0, + CONTROL_ERROR_UNKNOWN = 1, + CONTROL_ERROR_TIMEOUT_TEST = 2, + CONTROL_ERROR_OPERATOR_TEST = 3 +} ControlLastApplError; + +/** @} */ + +/** + * @defgroup FUNCTIONAL_CONSTRAINTS Definitions and functions related to functional constraints (FCs) + * + * @{ + */ + +#if (CONFIG_PROVIDE_OLD_FC_DEFINES == 1) +#define ST IEC61850_FC_ST +#define MX IEC61850_FC_MX +#define SP IEC61850_FC_SP +#define SV IEC61850_FC_SV +#define CF IEC61850_FC_CF +#define DC IEC61850_FC_DC +#define SG IEC61850_FC_SG +#define SE IEC61850_FC_SE +#define SR IEC61850_FC_SR +#define OR IEC61850_FC_OR +#define BL IEC61850_FC_BL +#define EX IEC61850_FC_EX +#define CO IEC61850_FC_CO +#define ALL IEC61850_FC_ALL +#define NONE IEC61850_FC_NONE +#endif /* (CONFIG_PROVIDE_OLD_FC_DEFINES == 1) */ + + +/** FCs (Functional constraints) according to IEC 61850-7-2 */ +typedef enum eFunctionalConstraint { + /** Status information */ + IEC61850_FC_ST = 0, + /** Measurands - analog values */ + IEC61850_FC_MX = 1, + /** Setpoint */ + IEC61850_FC_SP = 2, + /** Substitution */ + IEC61850_FC_SV = 3, + /** Configuration */ + IEC61850_FC_CF = 4, + /** Description */ + IEC61850_FC_DC = 5, + /** Setting group */ + IEC61850_FC_SG = 6, + /** Setting group editable */ + IEC61850_FC_SE = 7, + /** Service response / Service tracking */ + IEC61850_FC_SR = 8, + /** Operate received */ + IEC61850_FC_OR = 9, + /** Blocking */ + IEC61850_FC_BL = 10, + /** Extended definition */ + IEC61850_FC_EX = 11, + /** Control */ + IEC61850_FC_CO = 12, + /** Unicast SV */ + IEC61850_FC_US = 13, + /** Multicast SV */ + IEC61850_FC_MS = 14, + /** Unbuffered report */ + IEC61850_FC_RP = 15, + /** Buffered report */ + IEC61850_FC_BR = 16, + /** Log control blocks */ + IEC61850_FC_LG = 17, + /** Goose control blocks */ + IEC61850_FC_GO = 18, + + /** All FCs - wildcard value */ + IEC61850_FC_ALL = 99, + IEC61850_FC_NONE = -1 +} FunctionalConstraint; + +/**extern "C" { + * \brief convert a function constraint to a static string + */ +LIB61850_API char* +FunctionalConstraint_toString(FunctionalConstraint fc); + +/** + * \brief parse a string treated as a functional constraint representation + */ +LIB61850_API FunctionalConstraint +FunctionalConstraint_fromString(const char* fcString); + +/** @} */ + +/** + * @defgroup QUALITY Definitions and functions related to data attribute quality + * + * @{ + */ + + +typedef uint16_t Quality; +typedef uint16_t Validity; + +#define QUALITY_VALIDITY_GOOD 0 +#define QUALITY_VALIDITY_INVALID 2 +#define QUALITY_VALIDITY_RESERVED 1 +#define QUALITY_VALIDITY_QUESTIONABLE 3 + +#define QUALITY_DETAIL_OVERFLOW 4 +#define QUALITY_DETAIL_OUT_OF_RANGE 8 +#define QUALITY_DETAIL_BAD_REFERENCE 16 +#define QUALITY_DETAIL_OSCILLATORY 32 +#define QUALITY_DETAIL_FAILURE 64 +#define QUALITY_DETAIL_OLD_DATA 128 +#define QUALITY_DETAIL_INCONSISTENT 256 +#define QUALITY_DETAIL_INACCURATE 512 + +#define QUALITY_SOURCE_SUBSTITUTED 1024 + +#define QUALITY_TEST 2048 + +#define QUALITY_OPERATOR_BLOCKED 4096 + +#define QUALITY_DERIVED 8192 + +LIB61850_API Validity +Quality_getValidity(Quality* self); + +LIB61850_API void +Quality_setValidity(Quality* self, Validity validity); + +LIB61850_API void +Quality_setFlag(Quality* self, int flag); + +LIB61850_API void +Quality_unsetFlag(Quality* self, int flag); + +LIB61850_API bool +Quality_isFlagSet(Quality* self, int flag); + +LIB61850_API Quality +Quality_fromMmsValue(const MmsValue* mmsValue); + +LIB61850_API MmsValue* +Quality_toMmsValue(Quality* self, MmsValue* mmsValue); + +/** @} */ + +/** + * @defgroup DBPOS Definitions and functions related to IEC 61850 Dbpos (a CODED ENUM) data type + * + * @{ + */ + +typedef enum { + DBPOS_INTERMEDIATE_STATE = 0, + DBPOS_OFF = 1, + DBPOS_ON = 2, + DBPOS_BAD_STATE = 3 +} Dbpos; + + +/** + * \brief convert MMS bit string to Dbpos enumeration type + * + * \param mmsValue the MmsValue instance representing the Dbpos value + * + * \return the corresponding Dbpos value + */ +LIB61850_API Dbpos +Dbpos_fromMmsValue(const MmsValue* mmsValue); + +/** + * \brief conver Dbpos to MMS bit string + * + * \param mmsValue the MmsValue instance representing a Dbpos value or NULL to create a new MmsValue instance + * \param a Dbpos value + * + * \return the corresponding MmsValue instance + */ +LIB61850_API MmsValue* +Dbpos_toMmsValue(MmsValue* mmsValue, Dbpos dbpos); + +/** @} */ + +/** + * @defgroup TIMESTAMP Definitions and functions related to IEC 61850 Timestamp (UTC Time) data type + * + * @{ + */ + +typedef union { + uint8_t val[8]; +} Timestamp; + +LIB61850_API Timestamp* +Timestamp_create(void); + +LIB61850_API Timestamp* +Timestamp_createFromByteArray(const uint8_t* byteArray); + +LIB61850_API void +Timestamp_destroy(Timestamp* self); + +LIB61850_API void +Timestamp_clearFlags(Timestamp* self); + +LIB61850_API uint32_t +Timestamp_getTimeInSeconds(Timestamp* self); + +LIB61850_API msSinceEpoch +Timestamp_getTimeInMs(Timestamp* self); + +LIB61850_API nsSinceEpoch +Timestamp_getTimeInNs(Timestamp* self); + +LIB61850_API bool +Timestamp_isLeapSecondKnown(Timestamp* self); + +LIB61850_API void +Timestamp_setLeapSecondKnown(Timestamp* self, bool value); + +LIB61850_API bool +Timestamp_hasClockFailure(Timestamp* self); + +LIB61850_API void +Timestamp_setClockFailure(Timestamp* self, bool value); + +LIB61850_API bool +Timestamp_isClockNotSynchronized(Timestamp* self); + +LIB61850_API void +Timestamp_setClockNotSynchronized(Timestamp* self, bool value); + +LIB61850_API int +Timestamp_getSubsecondPrecision(Timestamp* self); + +/** + * \brief Set the subsecond precision value of the time stamp + * + * \param subsecondPrecision the number of significant bits of the fractionOfSecond part of the time stamp + */ +LIB61850_API void +Timestamp_setSubsecondPrecision(Timestamp* self, int subsecondPrecision); + +/** + * \brief Set the time in seconds + * + * NOTE: the fractionOfSecond part is set to zero + * NOTE: the subSecondPrecision is not touched + * + * \param self the Timestamp instance + * \param secondsSinceEpoch the seconds since unix epoch (unix timestamp) + */ +LIB61850_API void +Timestamp_setTimeInSeconds(Timestamp* self, uint32_t secondsSinceEpoch); + +/** + * \brief Set the time in milliseconds + * + * NOTE: the subSecondPrecision is not touched + * + * \param self the Timestamp instance + * \param msTime the milliseconds since unix epoch + */ +LIB61850_API void +Timestamp_setTimeInMilliseconds(Timestamp* self, msSinceEpoch msTime); + +/** + * \brief Set the time in nanoseconds + * + * NOTE: the subSecondPrecision is not touched + * + * \param self the Timestamp instance + * \param msTime the nanoseconds since unix epoch + */ +LIB61850_API void +Timestamp_setTimeInNanoseconds(Timestamp* self, nsSinceEpoch nsTime); + +LIB61850_API void +Timestamp_setByMmsUtcTime(Timestamp* self, const MmsValue* mmsValue); + +/** + * \brief Set an MmsValue instance of type UTCTime to the timestamp value + * + * \param self the Timestamp instance + * \param mmsValue the mmsValue instance, if NULL a new instance will be created + */ +LIB61850_API MmsValue* +Timestamp_toMmsValue(Timestamp* self, MmsValue* mmsValue); + +/** + * \brief Get the Timestamp value from an MmsValue instance of type MMS_UTC_TIME + * + * \param self the Timestamp instance or NULL to create a new instance + * \param mmsValue the mmsValue instance of type MMS_UTC_TIME + * + * \return the updated Timestamp value or NULL in case of an error + */ +LIB61850_API Timestamp* +Timestamp_fromMmsValue(Timestamp* self, MmsValue* mmsValue); + +/** + * \brief Get the version of the library as string + * + * \return the version of the library (e.g. "1.2.2") + */ +LIB61850_API char* +LibIEC61850_getVersionString(void); + +/** @} */ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* IEC61850_COMMON_H_ */ diff --git a/product/src/fes/include/libiec61850/iec61850_config_file_parser.h b/product/src/fes/include/libiec61850/iec61850_config_file_parser.h new file mode 100644 index 00000000..c1eeda83 --- /dev/null +++ b/product/src/fes/include/libiec61850/iec61850_config_file_parser.h @@ -0,0 +1,64 @@ +/* + * config_file_parser.h + * + * Copyright 2014 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef CONFIG_FILE_PARSER_H_ +#define CONFIG_FILE_PARSER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_filesystem.h" + +/** \addtogroup server_api_group + * @{ + */ + +/** + * @defgroup CONFIG_FILE_PARSER Create data models by configuration files + * + * @{ + */ + +/** + * \brief Create a data model from simple text configuration file + * + * \param filename name or path of the configuraton file + * + * \return the data model to be used by \ref IedServer + */ +LIB61850_API IedModel* +ConfigFileParser_createModelFromConfigFileEx(const char* filename); + +LIB61850_API IedModel* +ConfigFileParser_createModelFromConfigFile(FileHandle fileHandle); + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_FILE_PARSER_H_ */ diff --git a/product/src/fes/include/libiec61850/iec61850_dynamic_model.h b/product/src/fes/include/libiec61850/iec61850_dynamic_model.h new file mode 100644 index 00000000..59829e64 --- /dev/null +++ b/product/src/fes/include/libiec61850/iec61850_dynamic_model.h @@ -0,0 +1,538 @@ +/* + * dynamic_model.h + * + * Copyright 2014 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef DYNAMIC_MODEL_H_ +#define DYNAMIC_MODEL_H_ + +#include "iec61850_model.h" +#include "iec61850_cdc.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \addtogroup server_api_group + * @{ + */ + +/** + * @defgroup DYNAMIC_MODEL General dynamic model creation functions + * + * @{ + */ + + +/** + * \brief create a new IedModel instance + * + * The IedModel object is the root node of an IEC 61850 data model. + * + * \param name the name of the IedModel + * + * \return the new data model instance + */ +LIB61850_API IedModel* +IedModel_create(const char* name); + +/** + * \brief Set the name of the IED (use only for dynamic model!) + * + * This will change the default name (usually "TEMPLATE") to a user configured values. + * NOTE: This function has to be called before IedServer_create ! + * NOTE: For dynamic model (and configuration file date model) this function has to be + * used instead of IedModel_setIedName. + * + * \param model the IedModel instance + * \param the name of the configured IED + */ +LIB61850_API void +IedModel_setIedNameForDynamicModel(IedModel* self, const char* name); + +/** + * \brief destroy a dynamically created data model + * + * This function will free all the memory allocated for the data model. + * + * NOTE: Do not use this function when using a static data model (static_model.c create by static model generator). + * + * \param model the model instance to destroy + */ +LIB61850_API void +IedModel_destroy(IedModel* model); + +/** + * \brief Create a new logical device model and add it to the IED model + * + * \param name the name of the new logical device + * \param parent the parent IED model + * + * \return the newly created LogicalDevice instance + */ +LIB61850_API LogicalDevice* +LogicalDevice_create(const char* name, IedModel* parent); + + +/** + * \brief Create a new logical mode and add it to a logical device + * + * \param name the name of the new logical node + * \param parent the parent logical device + * + * \return the newly created LogicalNode instance + */ +LIB61850_API LogicalNode* +LogicalNode_create(const char* name, LogicalDevice* parent); + +/** + * \brief create a new data object and add it to a parent model node + * + * The parent model node has to be of type DataObject or LogicalNode. + * + * \param name the name of the data object (e.h. "Mod", "Health" ...) + * \param parent the parent model node + * \param arrayElements the number of array elements if the data object is an array or 0 + * + * \return the newly create DataObject instance + */ +LIB61850_API DataObject* +DataObject_create(const char* name, ModelNode* parent, int arrayElements); + +/** + * \brief create a new data attribute and add it to a parent model node + * + * The parent model node has to be of type DataObject or DataAttribute + * + * \param name the name of the data attribute (e.g. "stVal") + * \param parent the parent model node + * \param type the type of the data attribute (CONSTRUCTED if the type contains sub data attributes) + * \param fc the functional constraint (FC) of the data attribute + * \param triggerOptions the trigger options (dupd, dchg, qchg) that cause an event notification + * \param arrayElements the number of array elements if the data attribute is an array or 0 + * \param sAddr an optional short address + * + * \return the newly create DataAttribute instance + */ +LIB61850_API DataAttribute* +DataAttribute_create(const char* name, ModelNode* parent, DataAttributeType type, FunctionalConstraint fc, + uint8_t triggerOptions, int arrayElements, uint32_t sAddr); + +/** + * \brief Get the data type of the data attribute + * + * \param self the data attribute instance + * + * \return the data attribute type + */ +LIB61850_API DataAttributeType +DataAttribute_getType(DataAttribute* self); + +/** + * \brief Get the functional constraint (FC) of the data attribute + * + * \param self the data attribute instance + * + * \return the functional constraint (FC) of the data attribute + */ +LIB61850_API FunctionalConstraint +DataAttribute_getFC(DataAttribute* self); + +/** + * \brief Get the trigger options of the data attribute + * + * \param self the data attribute instance + * + * \return the trigger options (dupd, dchg, qchg) that cause an event notification + */ +LIB61850_API uint8_t +DataAttribute_getTrgOps(DataAttribute* self); + +/** + * \brief Set the value of the data attribute (can be used to set default values before server is created) + * + * \param self the data attribute instance + * \param value the new default value + */ +LIB61850_API void +DataAttribute_setValue(DataAttribute* self, MmsValue* value); + +/** + * \brief create a new report control block (RCB) + * + * Create a new report control block (RCB) and add it to the given logical node (LN). + * + * \param name name of the RCB relative to the parent LN + * \param parent the parent LN. + * \param rptId of the report. If NULL the default report ID (object reference) is used. + * \param isBuffered true for a buffered RCB - false for unbuffered RCB + * \param dataSetName name (object reference) of the default data set or NULL if no data set + * is set by default + * \param confRef the configuration revision + * \param trgOps the trigger options supported by this RCB (bit set) + * \param options the inclusion options. Specifies what elements are included in a report (bit set) + * \param bufTm the buffering time of the RCB in milliseconds (time between the first event and the preparation of the report). + * \param intgPd integrity period in milliseconds + * + * \return the new RCB instance. + */ +LIB61850_API ReportControlBlock* +ReportControlBlock_create(const char* name, LogicalNode* parent, const char* rptId, bool isBuffered, const char* + dataSetName, uint32_t confRef, uint8_t trgOps, uint8_t options, uint32_t bufTm, uint32_t intgPd); + +/** + * \brief Set a pre-configured client for the RCB + * + * If set only the pre configured client should use this RCB instance + * + * \param self the RCB instance + * \param clientType the type of the client (0 = no client, 4 = IPv4 client, 6 = IPv6 client) + * \param clientAddress buffer containing the client address (4 byte in case of an IPv4 address, 16 byte in case of an IPv6 address, NULL for no client) + */ +LIB61850_API void +ReportControlBlock_setPreconfiguredClient(ReportControlBlock* self, uint8_t clientType, const uint8_t* clientAddress); + +/** + * \brief Get the name of the RCB instance + * + * NOTE: the returned string is only valid during the lifetime of the ReportControlBlock instance! + * + * \param self the RCB instance + * + * \return the RCB instance name + */ +LIB61850_API const char* +ReportControlBlock_getName(ReportControlBlock* self); + +/** + * \brief Is the RCB buffered or unbuffered? + * + * \param self the RCB instance + * + * \return true, in case of a buffered RCB, false otherwise + */ +LIB61850_API bool +ReportControlBlock_isBuffered(ReportControlBlock* self); + +/** + * \brief Get the parent (LogicalNode) of the RCB instance + * + * \param self the RCB instance + * + * \return the parent (LogicalNode) of the RCB instance + */ +LIB61850_API LogicalNode* +ReportControlBlock_getParent(ReportControlBlock* self); + +/** + * \brief Get the name of the currently set report ID + * + * \param self the RCB instance + * + * \return a null terminated string containing the current data set name (the string has to be released by the caller!) + */ +LIB61850_API char* +ReportControlBlock_getRptID(ReportControlBlock* self); + +/** + * \brief Check if RCB instance is enabled + * + * \param self the RCB instance + * + * \return true when the RCB instance is enabled, false otherwise + */ +LIB61850_API bool +ReportControlBlock_getRptEna(ReportControlBlock* self); + +/** + * \brief Get the name of the currenlty set data set + * + * \param self the RCB instance + * + * \return a null terminated string containing the current data set name (the string has to be released by the caller!) + */ +LIB61850_API char* +ReportControlBlock_getDataSet(ReportControlBlock* self); + +/** + * \brief Get the confRev value + * + * \param self the RCB instance + * + * \return confRev value + */ +LIB61850_API uint32_t +ReportControlBlock_getConfRev(ReportControlBlock* self); + +/** + * \brief Get the currently set OptFlds value + * + * The OptField (option field) value is a bit field with the following fields: + * - RPT_OPT_SEQ_NUM + * - RPT_OPT_TIME_STAMP + * - RPT_OPT_REASON_FOR_INCLUSION + * - RPT_OPT_DATA_SET + * - RPT_OPT_DATA_REFERENCE + * - RPT_OPT_BUFFER_OVERFLOW + * - RPT_OPT_ENTRY_ID + * - RPT_OPT_CONF_REV + * + * \param self the RCB instance + * + * \return OptFlds options value + */ +LIB61850_API uint32_t +ReportControlBlock_getOptFlds(ReportControlBlock* self); + +/** + * \brief Get the BufTm value (buffer time) + * + * The buffer time is the maximum value between an event and + * the actual report generation. + * + * \param self the RCB instance + * + * \return bufTm value + */ +LIB61850_API uint32_t +ReportControlBlock_getBufTm(ReportControlBlock* self); + +LIB61850_API uint16_t +ReportControlBlock_getSqNum(ReportControlBlock* self); + +/** + * \brief Get the currently set trigger options + * + * The trigger option value is a bit field with the following fields: + * - TRG_OPT_DATA_CHANGED + * - TRG_OPT_QUALITY_CHANGED + * - TRG_OPT_DATA_UPDATE + * - TRG_OPT_INTEGRITY + * - TRG_OPT_GI + * + * \param self the RCB instance + * + * \return trigger options value + */ +LIB61850_API uint32_t +ReportControlBlock_getTrgOps(ReportControlBlock* self); + +LIB61850_API uint32_t +ReportControlBlock_getIntgPd(ReportControlBlock* self); + +LIB61850_API bool +ReportControlBlock_getGI(ReportControlBlock* self); + +LIB61850_API bool +ReportControlBlock_getPurgeBuf(ReportControlBlock* self); + +LIB61850_API MmsValue* +ReportControlBlock_getEntryId(ReportControlBlock* self); + +LIB61850_API uint64_t +ReportControlBlock_getTimeofEntry(ReportControlBlock* self); + +LIB61850_API int16_t +ReportControlBlock_getResvTms(ReportControlBlock* self); + +LIB61850_API bool +ReportControlBlock_getResv(ReportControlBlock* self); + +LIB61850_API MmsValue* +ReportControlBlock_getOwner(ReportControlBlock* self); + +/** + * \brief create a new log control block (LCB) + * + * Create a new log control block (LCB) and add it to the given logical node (LN). + * + * \param name name of the LCB relative to the parent LN + * \param parent the parent LN. + * \param dataSetName name (object reference) of the default data set or NULL if no data set + * is set by default + * \param logRef name (object reference) of the default log or NULL if no log is set by default. THe LDname doesn't contain the IED name! + * \param trgOps the trigger options supported by this LCB (bit set) + * \param intgPd integrity period in milliseconds + * \param logEna if true the log will be enabled by default, false otherwise + * \param reasonCode if true the reasonCode will be included in the log (this is always true in MMS mapping) + * + * \return the new LCB instance + */ +LIB61850_API LogControlBlock* +LogControlBlock_create(const char* name, LogicalNode* parent, const char* dataSetName, const char* logRef, uint8_t trgOps, + uint32_t intgPd, bool logEna, bool reasonCode); + +/** + * \brief create a log (used by the IEC 61850 log service) + * + * \param name name of the LOG relative to the parent LN + * \param parent the parent LN + * + * \return the new LOG instance + */ +LIB61850_API Log* +Log_create(const char* name, LogicalNode* parent); + +/** + * \brief create a setting group control block (SGCB) + * + * Create a new setting group control block (SGCB) and add it to the given logical node (LN). + * + * \param parent the parent LN. + * \param the active setting group on server startup (1..N) + * \param the number of setting groups (N) + * + * \return the new SGCB instance + */ +LIB61850_API SettingGroupControlBlock* +SettingGroupControlBlock_create(LogicalNode* parent, uint8_t actSG, uint8_t numOfSGs); + +/** + * \brief create a new GSE/GOOSE control block (GoCB) + * + * Create a new GOOSE control block (GoCB) and add it to the given logical node (LN) + * + * \param name name of the GoCB relative to the parent LN + * \param parent the parent LN + * \param appId the application ID of the GoCB + * \param dataSet the data set reference to be used by the GoCB + * \param confRev the configuration revision + * \param fixedOffs indicates if GOOSE publisher shall use fixed offsets (NOT YET SUPPORTED) + * \param minTime minimum GOOSE retransmission time (-1 if not specified - uses stack default then) + * \param maxTime GOOSE retransmission time in stable state (-1 if not specified - uses stack default then) + * + * \return the new GoCB instance + */ +LIB61850_API GSEControlBlock* +GSEControlBlock_create(const char* name, LogicalNode* parent, const char* appId, const char* dataSet, uint32_t confRev, + bool fixedOffs, int minTime, int maxTime); + +/** + * \brief create a new Multicast/Unicast Sampled Value (SV) control block (SvCB) + * + * Create a new Sampled Value control block (SvCB) and add it to the given logical node (LN) + * + * \param name name of the SvCB relative to the parent LN + * \param parent the parent LN + * \param svID the application ID of the SvCB + * \param dataSet the data set reference to be used by the SVCB + * \param confRev the configuration revision + * \param smpMod the sampling mode used + * \param smpRate the sampling rate used + * \param optFlds the optional element configuration + * + * \return the new SvCB instance + */ +LIB61850_API SVControlBlock* +SVControlBlock_create(const char* name, LogicalNode* parent, const char* svID, const char* dataSet, uint32_t confRev, uint8_t smpMod, + uint16_t smpRate, uint8_t optFlds, bool isUnicast); + +LIB61850_API void +SVControlBlock_addPhyComAddress(SVControlBlock* self, PhyComAddress* phyComAddress); + +LIB61850_API void +GSEControlBlock_addPhyComAddress(GSEControlBlock* self, PhyComAddress* phyComAddress); + +/** + * \brief create a PhyComAddress object + * + * A PhyComAddress object contains all required addressing information for a GOOSE publisher. + * + * \param vlanPriority the priority field of the VLAN tag + * \param vlanId the ID field of the VLAN tag + * \param appId the application identifier + * \param dstAddress the 6 byte multicast MAC address to specify the destination + * + * \return the new PhyComAddress object + */ +LIB61850_API PhyComAddress* +PhyComAddress_create(uint8_t vlanPriority, uint16_t vlanId, uint16_t appId, uint8_t dstAddress[]); + +/** + * \brief create a new data set + * + * \param name the name of the data set + * \param parent the logical node that hosts the data set (typically a LLN0) + * + * \return the new data set instance + */ +LIB61850_API DataSet* +DataSet_create(const char* name, LogicalNode* parent); + +/** + * \brief Get the name of the data set + * + * \param self the instance of the data set + * + * \returns the name of the data set (not the object reference). + */ +LIB61850_API const char* +DataSet_getName(DataSet* self); + +/** + * \brief returns the number of elements (entries) of the data set + * + * \param self the instance of the data set + * + * \returns the number of data set elements + */ +LIB61850_API int +DataSet_getSize(DataSet* self); + +LIB61850_API DataSetEntry* +DataSet_getFirstEntry(DataSet* self); + +LIB61850_API DataSetEntry* +DataSetEntry_getNext(DataSetEntry* self); + +/** + * \brief create a new data set entry (FCDA) + * + * Create a new FCDA reference and add it to the given data set as a new data set member. + * + * Note: Be aware that data set entries are not IEC 61850 object reference but MMS variable names + * that have to contain the LN name, the FC and subsequent path elements separated by "$" instead of ".". + * This is due to efficiency reasons to avoid the creation of additional strings. + * + * If the variable parameter does not contain a logical device name (separated from the remaining variable + * name by the "/" character) the logical device where the data set resides is used automatically. + * + * \param dataSet the data set to which the new entry will be added + * \param variable the name of the variable as MMS variable name including FC ("$" used as separator!) + * \param index the index if the FCDA is an array element, otherwise -1 + * \param component the name of the component of the variable if the FCDA is a sub element of an array + * element. If this is not the case then NULL should be given here. + * + * \return the new data set entry instance + */ +LIB61850_API DataSetEntry* +DataSetEntry_create(DataSet* dataSet, const char* variable, int index, const char* component); + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* DYNAMIC_MODEL_H_ */ diff --git a/product/src/fes/include/libiec61850/iec61850_model.h b/product/src/fes/include/libiec61850/iec61850_model.h new file mode 100644 index 00000000..6681f5d5 --- /dev/null +++ b/product/src/fes/include/libiec61850/iec61850_model.h @@ -0,0 +1,650 @@ +/* + * model.h + * + * Copyright 2013-2016 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef MODEL_H_ +#define MODEL_H_ + +#include "iec61850_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \addtogroup server_api_group + * @{ + */ + +/** + * @defgroup DATA_MODEL General data model definitions, access and iteration functions + * + * @{ + */ + +/** + * \brief abstract base type for IEC 61850 data model nodes + */ +typedef struct sModelNode ModelNode; + +/** + * \brief IEC 61850 data model element of type data attribute + */ +typedef struct sDataAttribute DataAttribute; + +/** + * \brief IEC 61850 data model element of type data object + */ +typedef struct sDataObject DataObject; + +/** + * \brief IEC 61850 data model element of type logical node + */ +typedef struct sLogicalNode LogicalNode; + +/** + * \brief IEC 61850 data model element of type logical device + */ +typedef struct sLogicalDevice LogicalDevice; + +/** + * \brief Root node of the IEC 61850 data model. This is usually created by the model generator tool (genmodel.jar) + */ +typedef struct sIedModel IedModel; + +typedef struct sDataSet DataSet; +typedef struct sReportControlBlock ReportControlBlock; + +/** + * \brief IEC 61850 data model of setting group control block (SGCB) + */ +typedef struct sSettingGroupControlBlock SettingGroupControlBlock; + +typedef struct sGSEControlBlock GSEControlBlock; + +typedef struct sSVControlBlock SVControlBlock; + +typedef struct sLogControlBlock LogControlBlock; + +typedef struct sLog Log; + +typedef enum { + IEC61850_UNKNOWN_TYPE = -1, + IEC61850_BOOLEAN = 0,/* int */ + IEC61850_INT8 = 1, /* int8_t */ + IEC61850_INT16 = 2, /* int16_t */ + IEC61850_INT32 = 3, /* int32_t */ + IEC61850_INT64 = 4, /* int64_t */ + IEC61850_INT128 = 5, /* no native mapping! */ + IEC61850_INT8U = 6, /* uint8_t */ + IEC61850_INT16U = 7, /* uint16_t */ + IEC61850_INT24U = 8, /* uint32_t */ + IEC61850_INT32U = 9, /* uint32_t */ + IEC61850_FLOAT32 = 10, /* float */ + IEC61850_FLOAT64 = 11, /* double */ + IEC61850_ENUMERATED = 12, + IEC61850_OCTET_STRING_64 = 13, + IEC61850_OCTET_STRING_6 = 14, + IEC61850_OCTET_STRING_8 = 15, + IEC61850_VISIBLE_STRING_32 = 16, + IEC61850_VISIBLE_STRING_64 = 17, + IEC61850_VISIBLE_STRING_65 = 18, + IEC61850_VISIBLE_STRING_129 = 19, + IEC61850_VISIBLE_STRING_255 = 20, + IEC61850_UNICODE_STRING_255 = 21, + IEC61850_TIMESTAMP = 22, + IEC61850_QUALITY = 23, + IEC61850_CHECK = 24, + IEC61850_CODEDENUM = 25, + IEC61850_GENERIC_BITSTRING = 26, + IEC61850_CONSTRUCTED = 27, + IEC61850_ENTRY_TIME = 28, + IEC61850_PHYCOMADDR = 29, + IEC61850_CURRENCY = 30, + IEC61850_OPTFLDS = 31, /* bit-string(10) */ + IEC61850_TRGOPS = 32 /* bit-string(6) */ + + +#if (CONFIG_IEC61850_USE_COMPAT_TYPE_DECLARATIONS == 1) + , + BOOLEAN = 0,/* int */ + INT8 = 1, /* int8_t */ + INT16 = 2, /* int16_t */ + INT32 = 3, /* int32_t */ + INT64 = 4, /* int64_t */ + INT128 = 5, /* no native mapping! */ + INT8U = 6, /* uint8_t */ + INT16U = 7, /* uint16_t */ + INT24U = 8, /* uint32_t */ + INT32U = 9, /* uint32_t */ + FLOAT32 = 10, /* float */ + FLOAT64 = 11, /* double */ + ENUMERATED = 12, + OCTET_STRING_64 = 13, + OCTET_STRING_6 = 14, + OCTET_STRING_8 = 15, + VISIBLE_STRING_32 = 16, + VISIBLE_STRING_64 = 17, + VISIBLE_STRING_65 = 18, + VISIBLE_STRING_129 = 19, + VISIBLE_STRING_255 = 20, + UNICODE_STRING_255 = 21, + TIMESTAMP = 22, + QUALITY = 23, + CHECK = 24, + CODEDENUM = 25, + GENERIC_BITSTRING = 26, + CONSTRUCTED = 27, + ENTRY_TIME = 28, + PHYCOMADDR = 29, + CURRENCY = 30 + OPTFLDS = 31, + TRGOPS = 32 +#endif +} DataAttributeType; + +typedef enum { + LogicalDeviceModelType, + LogicalNodeModelType, + DataObjectModelType, + DataAttributeModelType +} ModelNodeType; + +struct sIedModel { + char* name; + LogicalDevice* firstChild; + DataSet* dataSets; + ReportControlBlock* rcbs; + GSEControlBlock* gseCBs; + SVControlBlock* svCBs; + SettingGroupControlBlock* sgcbs; + LogControlBlock* lcbs; + Log* logs; + void (*initializer) (void); +}; + +struct sLogicalDevice { + ModelNodeType modelType; + char* name; + ModelNode* parent; + ModelNode* sibling; + ModelNode* firstChild; +}; + +struct sModelNode { + ModelNodeType modelType; + char* name; + ModelNode* parent; + ModelNode* sibling; + ModelNode* firstChild; +}; + +struct sLogicalNode { + ModelNodeType modelType; + char* name; + ModelNode* parent; + ModelNode* sibling; + ModelNode* firstChild; +}; + +struct sDataObject { + ModelNodeType modelType; + char* name; + ModelNode* parent; + ModelNode* sibling; + ModelNode* firstChild; + + int elementCount; /* > 0 if this is an array */ +}; + +struct sDataAttribute { + ModelNodeType modelType; + char* name; + ModelNode* parent; + ModelNode* sibling; + ModelNode* firstChild; + + int elementCount; /* > 0 if this is an array */ + + FunctionalConstraint fc; + DataAttributeType type; + + uint8_t triggerOptions; /* TRG_OPT_DATA_CHANGED | TRG_OPT_QUALITY_CHANGED | TRG_OPT_DATA_UPDATE */ + + MmsValue* mmsValue; + + uint32_t sAddr; +}; + +typedef struct sDataSetEntry { + char* logicalDeviceName; + bool isLDNameDynamicallyAllocated; + char* variableName; + int index; + char* componentName; + MmsValue* value; + struct sDataSetEntry* sibling; +} DataSetEntry; + +struct sDataSet { + char* logicalDeviceName; + char* name; /* eg. MMXU1$dataset1 */ + int elementCount; + DataSetEntry* fcdas; + DataSet* sibling; +}; + +struct sReportControlBlock { + LogicalNode* parent; + char* name; + char* rptId; + bool buffered; + char* dataSetName; /* pre loaded with relative name in logical node */ + + uint32_t confRef; /* ConfRef - configuration revision */ + uint8_t trgOps; /* TrgOps - trigger conditions */ + uint8_t options; /* OptFlds */ + uint32_t bufferTime; /* BufTm - time to buffer events until a report is generated */ + uint32_t intPeriod; /* IntgPd - integrity period */ + + /* type (first byte) and address of the pre-configured client + type can be one of (0 - no reservation, 4 - IPv4 client, 6 - IPv6 client) */ + uint8_t clientReservation[17]; + + ReportControlBlock* sibling; /* next control block in list or NULL if this is the last entry + * at runtime reuse as pointer to ReportControl instance! + **/ +}; + +struct sLogControlBlock { + LogicalNode* parent; + + char* name; + + char* dataSetName; + char* logRef; /* object reference to the journal */ + + uint8_t trgOps; /* TrgOps - trigger conditions */ + uint32_t intPeriod; /* IntgPd - integrity period */ + + bool logEna; /* enable log by default */ + bool reasonCode; /* include reason code in log */ + + LogControlBlock* sibling; /* next control block in list or NULL if this is the last entry */ +}; + +struct sLog { + LogicalNode* parent; + + char* name; + + Log* sibling; /* next log instance in list or NULL if this is the last entry */ +}; + +struct sSettingGroupControlBlock { + LogicalNode* parent; + + uint8_t actSG; /* value from SCL file */ + uint8_t numOfSGs; /* value from SCL file */ + + uint8_t editSG; /* 0 at power-up */ + bool cnfEdit; /* false at power-up */ + uint64_t timestamp; + uint16_t resvTms; + + SettingGroupControlBlock* sibling; /* next control block in list or NULL if this is the last entry */ +}; + +struct sGSEControlBlock { + LogicalNode* parent; + char* name; + char* appId; + char* dataSetName; /* pre loaded with relative name in logical node */ + uint32_t confRev; /* ConfRev - configuration revision */ + bool fixedOffs; /* fixed offsets */ + PhyComAddress* address; /* GSE communication parameters */ + int minTime; /* optional minTime parameter --> -1 if not present */ + int maxTime; /* optional maxTime parameter --> -1 if not present */ + GSEControlBlock* sibling; /* next control block in list or NULL if this is the last entry */ +}; + +struct sSVControlBlock { + LogicalNode* parent; + char* name; + + char* svId; /* MsvUD/UsvID */ + char* dataSetName; /* pre loaded with relative name in logical node */ + + uint8_t optFlds; + + uint8_t smpMod; + uint16_t smpRate; + + uint32_t confRev; /* ConfRev - configuration revision */ + + PhyComAddress* dstAddress; /* SV communication parameters */ + + bool isUnicast; + + int noASDU; + + SVControlBlock* sibling; /* next control block in list or NULL if this is the last entry */ +}; + +/** + * \brief get the number of direct children of a model node + * + * \param self the model node instance + * + * \return the number of children of the model node + * ¸ + */ +LIB61850_API int +ModelNode_getChildCount(ModelNode* self); + +/** + * \brief return a child model node + * + * \param self the model node instance + * \param name the name of the child model node + * + * \return the model node instance or NULL if model node does not exist. + */ +LIB61850_API ModelNode* +ModelNode_getChild(ModelNode* self, const char* name); + +/** + * \brief return a child model node with a given functional constraint + * + * Sometimes the name is not enough to identify a model node. This is the case when + * editable setting groups are used. In this case the setting group members have two different + * model nodes associated that differ in their FC (SG and SE). + * + * \param self the model node instance + * \param name the name of the child model node + * \param fc the functional constraint of the model node + * + * \return the model node instance or NULL if model node does not exist. + */ +LIB61850_API ModelNode* +ModelNode_getChildWithFc(ModelNode* self, const char* name, FunctionalConstraint fc); + +/** + * \brief Return the IEC 61850 object reference of a model node + * + * \param self the model node instance + * \param objectReference pointer to a buffer where to write the object reference string. If NULL + * is given the buffer is allocated by the function. + * + * \return the object reference string + */ +LIB61850_API char* +ModelNode_getObjectReference(ModelNode* self, char* objectReference); + +/** + * \brief Return the IEC 61850 object reference of a model node + * + * \param self the model node instance + * \param objectReference pointer to a buffer where to write the object reference string. If NULL + * is given the buffer is allocated by the function. + * \param withoutIedName create object reference without IED name part + * + * \return the object reference string + */ +LIB61850_API char* +ModelNode_getObjectReferenceEx(ModelNode* node, char* objectReference, bool withoutIedName); + +/** + * \brief Get the type of the ModelNode + * + * \param self the ModelNode instance + * + * \return the type of the ModelNode (one of LD, LN, DO, DA) + */ +LIB61850_API ModelNodeType +ModelNode_getType(ModelNode* self); + +/** + * \brief Get the name of the ModelNode + * + * \param self the ModelNode instance + * + * \return the name of the ModelNode + */ +LIB61850_API const char* +ModelNode_getName(ModelNode* self); + +/** + * \brief Get the parent ModelNode of this ModelNode instance + * + * \param self the ModelNode instance + * + * \return the parent instance, or NULL when the ModelNode has no parent + */ +LIB61850_API ModelNode* +ModelNode_getParent(ModelNode* self); + +/** + * \brief Get the list of direct child nodes + * + * \param self the ModelNode instance + * + * \return the list of private child nodes, or NULL when the node has no children + */ +LIB61850_API LinkedList +ModelNode_getChildren(ModelNode* self); + +/** + * \brief Set the name of the IED + * + * This will change the default name (usualy "TEMPLATE") to a user configured values. + * NOTE: This function has to be called before IedServer_create ! + * + * \param model the IedModel instance + * \param the name of the configured IED + */ +LIB61850_API void +IedModel_setIedName(IedModel* self, const char* iedName); + +/** + * \brief Lookup a model node by its object reference + * + * This function uses the full logical device name as part of the object reference + * as it happens to appear on the wire. E.g. if IED name in SCL file would be "IED1" + * and the logical device "WD1" the resulting LD name would be "IED1WD". + * + * \param self the IedModel instance that holds the model node + * \param objectReference the IEC 61850 object reference + * + * \return the model node instance or NULL if model node does not exist. + */ +LIB61850_API ModelNode* +IedModel_getModelNodeByObjectReference(IedModel* self, const char* objectReference); + +LIB61850_API SVControlBlock* +IedModel_getSVControlBlock(IedModel* self, LogicalNode* parentLN, const char* svcbName); + +/** + * \brief Lookup a model node by its short (normalized) reference + * + * This version uses the object reference that does not contain the + * IED name as part of the logical device name. This function is useful for + * devices where the IED name can be configured. + * + * \param self the IedModel instance that holds the model node + * \param objectReference the IEC 61850 object reference + * + * \return the model node instance or NULL if model node does not exist. + */ +LIB61850_API ModelNode* +IedModel_getModelNodeByShortObjectReference(IedModel* self, const char* objectReference); + +/** + * \brief Lookup a model node by its short address + * + * Short address is a 32 bit unsigned integer as specified in the "sAddr" attribute of + * the ICD file or in the configuration file. + * + * \param self the IedModel instance that holds the model node + * \param shortAddress + * + * \return the model node instance or NULL if model node does not exist. + */ +LIB61850_API ModelNode* +IedModel_getModelNodeByShortAddress(IedModel* self, uint32_t shortAddress); + +/** + * \brief Lookup logical device (LD) by device instance name (SCL attribute "inst") + * + * \param self IedModel instance + * \param ldInst the logical device instance name (SCL attribute "inst") + * + * \return The matching LogicalDevice instance + */ +LIB61850_API LogicalDevice* +IedModel_getDeviceByInst(IedModel* self, const char* ldInst); + +/** + * \brief Lookup logical device (LD) instance by index + * + * \param self IedModel instance + * \param index the index of the LD in the range (0 .. number of LDs - 1) + * + * \return the corresponding LogicalDevice* object or NULL if the index is out of range + */ +LIB61850_API LogicalDevice* +IedModel_getDeviceByIndex(IedModel* self, int index); + + +/** + * \brief Lookup a logical node by name that is part of the given logical device + * + * \param device the logical device instance + * \param lnName the logical node name + * + * \return the logical device instance or NULL if it does not exist + */ +LIB61850_API LogicalNode* +LogicalDevice_getLogicalNode(LogicalDevice* self, const char* lnName); + +/** + * \brief Get the setting group control block (SGCB) of the logical device + * + * \param device the logical device instance + * + * \return the SGCB instance or NULL if no SGCB is available + */ +LIB61850_API SettingGroupControlBlock* +LogicalDevice_getSettingGroupControlBlock(LogicalDevice* self); + +/**@}*/ + +/**@}*/ + + +/** + * \brief unset all MmsValue references in the data model + * + * \param self the IedModel instance that holds the model node + */ +LIB61850_API void +IedModel_setAttributeValuesToNull(IedModel* self); + +/** + * \brief Lookup logical device (LD) by device name + * + * \param self IedModel instance + * \param ldInst the logical device name (as it is seen from the protocol side - MMS domain name) + * + * \return The matching LogicalDevice instance + */ +LIB61850_API LogicalDevice* +IedModel_getDevice(IedModel* self, const char* ldName); + +/** + * \brief Lookup a data set in the IED model + * + * \param self IedModel instance + * \param dataSetReference MMS mapping object reference! e.g. ied1Inverter/LLN0$dataset1 + * + * \return The matching DataSet instance + */ +LIB61850_API DataSet* +IedModel_lookupDataSet(IedModel* self, const char* dataSetReference); + +/** + * \brief Lookup a DataAttribute instance with the corresponding MmsValue instance + * + * \param self IedModel instance + * \param value the MmsValue instance (from the MMS value cache) + * + * \return the matching DataAttribute instance + */ +LIB61850_API DataAttribute* +IedModel_lookupDataAttributeByMmsValue(IedModel* self, MmsValue* value); + + +/** + * \brief Get the number of logical devices + * + * \param self IedModel instance + * + * \return the number of logical devices + */ +LIB61850_API int +IedModel_getLogicalDeviceCount(IedModel* self); + +LIB61850_API int +LogicalDevice_getLogicalNodeCount(LogicalDevice* self); + +LIB61850_API ModelNode* +LogicalDevice_getChildByMmsVariableName(LogicalDevice* self, const char* mmsVariableName); + +LIB61850_API bool +LogicalNode_hasFCData(LogicalNode* self, FunctionalConstraint fc); + +LIB61850_API bool +LogicalNode_hasBufferedReports(LogicalNode* self); + +LIB61850_API bool +LogicalNode_hasUnbufferedReports(LogicalNode* self); + +/** + * \brief get a data set instance + * + * \param self the logical node instance of the data set + * \param dataSetName the name of the data set + * + * \return the data set instance or NULL if the data set does not exist + */ +LIB61850_API DataSet* +LogicalNode_getDataSet(LogicalNode* self, const char* dataSetName); + +LIB61850_API bool +DataObject_hasFCData(DataObject* self, FunctionalConstraint fc); + + +#ifdef __cplusplus +} +#endif + + +#endif /* MODEL_H_ */ diff --git a/product/src/fes/include/libiec61850/iec61850_server.h b/product/src/fes/include/libiec61850/iec61850_server.h new file mode 100644 index 00000000..2a7d6f2f --- /dev/null +++ b/product/src/fes/include/libiec61850/iec61850_server.h @@ -0,0 +1,1895 @@ +/* + * iec61850_server.h + * + * IEC 61850 server API for libiec61850. + * + * Copyright 2013-2023 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + * + */ + +#ifndef IED_SERVER_API_H_ +#define IED_SERVER_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup server_api_group IEC 61850/MMS server API + * @{ + */ + +#include "mms_server.h" +#include "iec61850_dynamic_model.h" +#include "iec61850_model.h" +#include "hal_filesystem.h" +#include "iso_connection_parameters.h" +#include "iec61850_config_file_parser.h" + +#define IEC61850_REPORTSETTINGS_RPT_ID 1 +#define IEC61850_REPORTSETTINGS_BUF_TIME 2 +#define IEC61850_REPORTSETTINGS_DATSET 4 +#define IEC61850_REPORTSETTINGS_TRG_OPS 8 +#define IEC61850_REPORTSETTINGS_OPT_FIELDS 16 +#define IEC61850_REPORTSETTINGS_INTG_PD 32 + +/** + * \brief Configuration object to configure IEC 61850 stack features + */ +typedef struct sIedServerConfig* IedServerConfig; + +struct sIedServerConfig +{ + /** size of the report buffer associated with a buffered report control block */ + int reportBufferSize; + + /** size of the report buffer associated with an unbuffered report control block */ + int reportBufferSizeURCBs; + + /** Base path (directory where the file service serves files */ + char* fileServiceBasepath; + + /** when true (default) enable MMS file service */ + bool enableFileService; + + /** when true (default) enable dynamic data set services for MMS */ + bool enableDynamicDataSetService; + + /** the maximum number of allowed association specific data sets */ + int maxAssociationSpecificDataSets; + + /** the maximum number of allowed domain specific data sets */ + int maxDomainSpecificDataSets; + + /** maximum number of data set entries of dynamic data sets */ + int maxDataSetEntries; + + /** when true (default) enable log service */ + bool enableLogService; + + /** when true (default) the integrated GOOSE publisher is used */ + bool useIntegratedGoosePublisher; + + /** IEC 61850 edition (0 = edition 1, 1 = edition 2, 2 = edition 2.1, ...) */ + uint8_t edition; + + /** maximum number of MMS (TCP) connections */ + int maxMmsConnections; + + /** enable EditSG service (default: true) */ + bool enableEditSG; + + /** enable visibility of SGCB.ResvTms (default: true) */ + bool enableResvTmsForSGCB; + + /** BRCB has resvTms attribute - only edition 2 (default: true) */ + bool enableResvTmsForBRCB; + + /** RCB has owner attribute (default: true) */ + bool enableOwnerForRCB; + + /** integrity report start times will by synchronized with straight numbers (default: false) */ + bool syncIntegrityReportTimes; + + /** for each configurable ReportSetting there is a separate flag (default: Dyn = enable write for all) */ + uint8_t reportSettingsWritable; +}; + +/** + * \brief Create a new configuration object + * + * \return a new configuration object with default configuration values + */ +LIB61850_API IedServerConfig +IedServerConfig_create(void); + +/** + * \brief Destroy the configuration object + */ +LIB61850_API void +IedServerConfig_destroy(IedServerConfig self); + +/** + * \brief Set the IEC 61850 standard edition to use (default is edition 2) + * + * \param edition IEC_61850_EDITION_1, IEC_61850_EDITION_2, or IEC_61850_EDITION_2_1 + */ +LIB61850_API void +IedServerConfig_setEdition(IedServerConfig self, uint8_t edition); + +/** + * \brief Get the configued IEC 61850 standard edition + * + * \returns IEC_61850_EDITION_1, IEC_61850_EDITION_2, or IEC_61850_EDITION_2_1 + */ +LIB61850_API uint8_t +IedServerConfig_getEdition(IedServerConfig self); + +/** + * \brief Set the report buffer size for buffered reporting + * + * \param reportBufferSize the buffer size for each buffered report control block + */ +LIB61850_API void +IedServerConfig_setReportBufferSize(IedServerConfig self, int reportBufferSize); + +/** + * \brief Gets the report buffer size for buffered reporting + * + * \return the buffer size for each buffered report control block + */ +LIB61850_API int +IedServerConfig_getReportBufferSize(IedServerConfig self); + +/** + * \brief Set the report buffer size for unbuffered reporting + * + * \param reportBufferSize the buffer size for each unbuffered report control block + */ +LIB61850_API void +IedServerConfig_setReportBufferSizeForURCBs(IedServerConfig self, int reportBufferSize); + +/** + * \brief Gets the report buffer size for unbuffered reporting + * + * \return the buffer size for each unbuffered report control block + */ +LIB61850_API int +IedServerConfig_getReportBufferSizeForURCBs(IedServerConfig self); + +/** + * \brief Set the maximum number of MMS (TCP) connections the server accepts + * + * NOTE: Parameter has to be smaller than CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS if + * CONFIG_MAXIMUM_TCP_CLIENT_CONNECTIONS != -1 + * + * \param maxConnection maximum number of TCP connections + */ +LIB61850_API void +IedServerConfig_setMaxMmsConnections(IedServerConfig self, int maxConnections); + +/** + * \brief Get the maximum number of MMS (TCP) connections the server accepts + * + * \return maximum number of TCP connections + */ +LIB61850_API int +IedServerConfig_getMaxMmsConnections(IedServerConfig self); + +/** + * \brief Enable synchronized integrity report times + * + * NOTE: When this flag is enabled the integrity report generation times are + * aligned with the UTC epoch. Then the unix time stamps are straight multiples of the + * integrity interval. + * + * \param enable when true synchronized integrity report times are enabled + */ +LIB61850_API void +IedServerConfig_setSyncIntegrityReportTimes(IedServerConfig self, bool enable); + +/** + * \brief Check if synchronized integrity report times are enabled + * + * NOTE: When this flag is enabled the integrity report generation times are + * aligned with the UTC epoch. Then the unix time stamps are straight multiples of the + * integrity interval. + * + * \return true, when enabled, false otherwise + */ +LIB61850_API bool +IedServerConfig_getSyncIntegrityReportTimes(IedServerConfig self); + +/** + * \brief Set the basepath of the file services + * + * NOTE: the basepath specifies the local directory that is served by MMS file services + * + * \param basepath new file service base path + */ +LIB61850_API void +IedServerConfig_setFileServiceBasePath(IedServerConfig self, const char* basepath); + +/** + * \brief Get the basepath of the file services + */ +LIB61850_API const char* +IedServerConfig_getFileServiceBasePath(IedServerConfig self); + +/** + * \brief Enable/disable the MMS file service support + * + * \param[in] enable set true to enable the file services, otherwise false + */ +LIB61850_API void +IedServerConfig_enableFileService(IedServerConfig self, bool enable); + +/** + * \brief Is the MMS file service enabled or disabled + * + * \return true if enabled, false otherwise + */ +LIB61850_API bool +IedServerConfig_isFileServiceEnabled(IedServerConfig self); + +/** + * \brief Enable/disable the dynamic data set service for MMS + * + * \param[in] enable set true to enable dynamic data set service, otherwise false + */ +LIB61850_API void +IedServerConfig_enableDynamicDataSetService(IedServerConfig self, bool enable); + +/** + * \brief Is the dynamic data set service for MMS enabled or disabled + * + * \return true if enabled, false otherwise + */ +LIB61850_API bool +IedServerConfig_isDynamicDataSetServiceEnabled(IedServerConfig self); + +/** + * \brief Set the maximum allowed number of association specific (non-permanent) data sets + * + * NOTE: This specifies the maximum number of non-permanent data sets per connection. When + * the connection is closed these data sets are deleted automatically. + * + * \param maxDataSets maximum number of allowed data sets. + */ +LIB61850_API void +IedServerConfig_setMaxAssociationSpecificDataSets(IedServerConfig self, int maxDataSets); + +/** + * \brief Get the maximum allowed number of association specific (non-permanent) data sets + * + * \return maximum number of allowed data sets. + */ +LIB61850_API int +IedServerConfig_getMaxAssociationSpecificDataSets(IedServerConfig self); + +/** + * \brief Set the maximum allowed number of domain specific (permanent) data sets + * + * \param maxDataSets maximum number of allowed data sets. + */ +LIB61850_API void +IedServerConfig_setMaxDomainSpecificDataSets(IedServerConfig self, int maxDataSets); + +/** + * \brief Get the maximum allowed number of domain specific (permanent) data sets + * + * \return maximum number of allowed data sets. + */ +LIB61850_API int +IedServerConfig_getMaxDomainSpecificDataSets(IedServerConfig self); + +/** + * \brief Set the maximum number of entries in dynamic data sets + * + * NOTE: this comprises the base data set entries (can be simple or complex variables). + * When the client tries to create a data set with more member the request will be + * rejected and the data set will not be created. + * + * \param maxDataSetEntries the maximum number of entries allowed in a data set + */ +LIB61850_API void +IedServerConfig_setMaxDataSetEntries(IedServerConfig self, int maxDataSetEntries); + +/** + * \brief Get the maximum number of entries in dynamic data sets + * + * \return the maximum number of entries allowed in a data sets + */ +LIB61850_API int +IedServerConfig_getMaxDatasSetEntries(IedServerConfig self); + +/** + * \brief Enable/disable the log service for MMS + * + * \param[in] enable set true to enable log service, otherwise false + */ +LIB61850_API void +IedServerConfig_enableLogService(IedServerConfig self, bool enable); + +/** + * \brief Enable/disable the EditSG service to allow clients to change setting groups (default is enabled) + * + * NOTE: When disabled SGCB.ResvTms is not available online and the setting of \ref IedServerConfig_enableResvTmsForSGCB + * is ignored. + * + * \param[in] enable set true to enable, otherwise false (default value it true) + */ +LIB61850_API void +IedServerConfig_enableEditSG(IedServerConfig self, bool enable); + +/** + * \brief Enable/disable the SGCB.ResvTms when EditSG is enabled + * + * NOTE: When EditSG is disabled (see \ref IedServerConfig_enableEditSG) then this setting is ignored. + * + * \param[in] enable set true to enable, otherwise false (default value it true) + */ +LIB61850_API void +IedServerConfig_enableResvTmsForSGCB(IedServerConfig self, bool enable); + +/** + * \brief Enable/disable the presence of BRCB.ResvTms (default value is true) + * + * \param[in] enable set true to enable, otherwise false + */ +LIB61850_API void +IedServerConfig_enableResvTmsForBRCB(IedServerConfig self, bool enable); + +/** + * \brief ResvTms for BRCB enabled (visible) + * + * \return true if enabled, false otherwise + */ +LIB61850_API bool +IedServerConfig_isResvTmsForBRCBEnabled(IedServerConfig self); + +/** + * \brief Enable/disable the presence of owner in report control blocks (default value is false); + * + * \param[in] enable set true to enable, otherwise false + */ +LIB61850_API void +IedServerConfig_enableOwnerForRCB(IedServerConfig self, bool enable); + +/** + * \brief Owner for RCBs enabled (visible) + * + * \return true if enabled, false otherwise + */ +LIB61850_API bool +IedServerConfig_isOwnerForRCBEnabled(IedServerConfig self); + +/** + * \brief Enable/disable using the integrated GOOSE publisher for configured GoCBs + * + * This is enabled by default. Disable it when you want to use a separate GOOSE publisher + * + * \param[in] enable set true to enable the integrated GOOSE publisher, otherwise false + */ +LIB61850_API void +IedServerConfig_useIntegratedGoosePublisher(IedServerConfig self, bool enable); + +/** + * \brief Is the log service for MMS enabled or disabled + * + * \return true if enabled, false otherwise + */ +LIB61850_API bool +IedServerConfig_isLogServiceEnabled(IedServerConfig self); + +/** + * \brief Make a configurable report setting writeable or read-only + * + * \note Can be used to implement some of Services\ReportSettings options + * + * \param[in] setting one of IEC61850_REPORTSETTINGS_RPT_ID, _BUF_TIME, _DATSET, _TRG_OPS, _OPT_FIELDS, _INTG_PD + * \param[in] isDyn true, when setting is writable ("Dyn") or false, when read-only + */ +LIB61850_API void +IedServerConfig_setReportSetting(IedServerConfig self, uint8_t setting, bool isDyn); + +/** + * \brief Check if a configurable report setting is writable or read-only + * + * \param[in] setting one of IEC61850_REPORTSETTINGS_RPT_ID, _BUF_TIME, _DATSET, _TRG_OPS, _OPT_FIELDS, _INTG_PD + * + * \return isDyn true, when setting is writable ("Dyn") or false, when read-only + */ +LIB61850_API bool +IedServerConfig_getReportSetting(IedServerConfig self, uint8_t setting); + +/** + * An opaque handle for an IED server instance + */ +typedef struct sIedServer* IedServer; + +/** + * An opaque handle for a client connection + */ +typedef struct sClientConnection* ClientConnection; + +/** + * @defgroup IEC61850_SERVER_GENERAL General server setup and management functions + * + * @{ + */ + + +/** + * \brief Create a new IedServer instance + * + * \param dataModel reference to the IedModel data structure to be used as IEC 61850 data model of the device + * + * \return the new IedServer instance + */ +LIB61850_API IedServer +IedServer_create(IedModel* dataModel); + +/** + * \brief Create a new IedServer with TLS support + * + * \param dataModel reference to the IedModel data structure to be used as IEC 61850 data model of the device + * \param tlsConfiguration TLS configuration object, or NULL to not use TLS + * + * \return the new IedServer instance + */ +LIB61850_API IedServer +IedServer_createWithTlsSupport(IedModel* dataModel, TLSConfiguration tlsConfiguration); + +/** + * \brief Create new new IedServer with extended configurations parameters + * + * \param dataModel reference to the IedModel data structure to be used as IEC 61850 data model of the device + * \param tlsConfiguration TLS configuration object, or NULL to not use TLS + * \param serverConfiguration IED server configuration object for advanced server configuration + */ +LIB61850_API IedServer +IedServer_createWithConfig(IedModel* dataModel, TLSConfiguration tlsConfiguration, IedServerConfig serverConfiguration); + +/** + * \brief Destroy an IedServer instance and release all resources (memory, TCP sockets) + * + * \param self the instance of IedServer to operate on. + */ +LIB61850_API void +IedServer_destroy(IedServer self); + +/** + * \brief Add a new local access point (server will listen to provided IP/port combination) + * + * \param self the instance of IedServer to operate on. + * \param ipAddr the local IP address to listen on + * \param tcpPort the local TCP port to listen on or -1 to use the standard TCP port + * \oaram tlsConfiguration the TLS configuration or NULL when TLS is not used for this access point + * + * \return true in case of success, false otherwise + */ +LIB61850_API bool +IedServer_addAccessPoint(IedServer self, const char* ipAddr, int tcpPort, TLSConfiguration tlsConfiguration); + +/** + * \brief Set the local IP address to listen on + * + * \param self the IedServer instance + * \param localIpAddress the local IP address as C string (an internal copy will be created) + */ +LIB61850_API void +IedServer_setLocalIpAddress(IedServer self, const char* localIpAddress); + +/** + * \brief Set the identify for the MMS identify service + * + * CONFIG_IEC61850_SUPPORT_SERVER_IDENTITY required + * + * \param self the IedServer instance + * \param vendor the IED vendor name + * \param model the IED model name + * \param revision the IED revision/version number + */ +LIB61850_API void +IedServer_setServerIdentity(IedServer self, const char* vendor, const char* model, const char* revision); + +/** + * \brief Set the virtual filestore basepath for the MMS file services + * + * All external file service accesses will be mapped to paths relative to the base directory. + * NOTE: This function is only available when the CONFIG_SET_FILESTORE_BASEPATH_AT_RUNTIME + * option in stack_config.h is set. + * + * \param self the IedServer instance + * \param basepath the new virtual filestore basepath + */ +LIB61850_API void +IedServer_setFilestoreBasepath(IedServer self, const char* basepath); + +/** + * \brief Start handling client connections + * + * \param self the instance of IedServer to operate on. + * \param tcpPort the TCP port the server is listening (-1 for using the default MMS or secure MMS port) + */ +LIB61850_API void +IedServer_start(IedServer self, int tcpPort); + +/** + * \brief Stop handling client connections + * + * \param self the instance of IedServer to operate on. + */ +LIB61850_API void +IedServer_stop(IedServer self); + +/** + * \brief Start handling client connection for non-threaded mode + * + * This function will instruct the TCP(IP stack to listen for incoming connections. + * In order to accept new connection the function IedServer_processIncomingData has to + * be called periodically. + * + * \param self the instance of IedServer to operate on. + * \param tcpPort the TCP port the server is listening (-1 for using the default MMS or secure MMS port) + */ +LIB61850_API void +IedServer_startThreadless(IedServer self, int tcpPort); + +/** + * \brief Wait until a server connection is ready (with timeout) + * + * The function will wait until a server connection is ready (data available) or the + * timeout elapsed. This function is intended for the non-threaded mode. Its use is optional. + * It is equivalent of using select on sockets on Linux. If the return value is != 0 the + * IedServer_processIncomingData function should be called. + * + * \param self the IedServer instance + * \param timeoutMs the timeout to wait when no connection is ready + * + * \return 0 if no connection is ready; otherwise at least one connection is ready + */ +LIB61850_API int +IedServer_waitReady(IedServer self, unsigned int timeoutMs); + +/** + * \brief handle incoming TCP data in non-threaded mode + * + * The function should be called periodically. If the function is called more often + * the response time for incoming messages will be faster. As an alternative the + * function may only be called if new TCP data is available. + * + * \param self the instance of IedServer to operate on. + */ +LIB61850_API void +IedServer_processIncomingData(IedServer self); + +/** + * \brief perform periodic background tasks in non-threaded mode + * + * The function should be called periodically. If the function is called more often + * the more accurate are internal timeouts (e.g. for reports). + * + * \param self the instance of IedServer to operate on. + */ +LIB61850_API void +IedServer_performPeriodicTasks(IedServer self); + +/** + * \brief Stop handling client connections for non-threaded mode + * + * \param self the instance of IedServer to operate on. + */ +LIB61850_API void +IedServer_stopThreadless(IedServer self); + +/** + * \brief Return the data model of the server + * + * \param self the instance of IedServer to operate on. + * + * \return the IedModel* instance of the server + */ +LIB61850_API IedModel* +IedServer_getDataModel(IedServer self); + +/** + * \brief Check if IedServer instance is listening for client connections + * + * \param self the instance of IedServer to operate on. + * + * \return true if IedServer instance is listening for client connections + */ +LIB61850_API bool +IedServer_isRunning(IedServer self); + +/** + * \brief Get number of open MMS connections + * + * \param self the instance of IedServer to operate on + * + * \return the number of open and accepted MMS connections + */ +LIB61850_API int +IedServer_getNumberOfOpenConnections(IedServer self); + +/** + * \brief Get access to the underlying MmsServer instance. + * + * This function should be handled with care. Since direct interaction with the + * MmsServer can interfere with the IedServer. + * + * \param self the instance of IedServer to operate on. + * + * \return MmsServer instance that is used by the IedServer + */ +LIB61850_API MmsServer +IedServer_getMmsServer(IedServer self); + +/** + * \brief Enable all GOOSE control blocks. + * + * This will set the GoEna attribute of all configured GOOSE control blocks + * to true. If this method is not called at the startup or reset of the server + * then configured GOOSE control blocks keep inactive until a MMS client enables + * them by writing to the GOOSE control block. + * + * Note: This function has no effect when CONFIG_INCLUDE_GOOSE_SUPPORT is not set. + * + * \param self the instance of IedServer to operate on. + */ +LIB61850_API void +IedServer_enableGoosePublishing(IedServer self); + +/** + * \brief Disable all GOOSE control blocks. + * + * This will set the GoEna attribute of all configured GOOSE control blocks + * to false. This will stop GOOSE transmission. + * + * Note: This function has no effect when CONFIG_INCLUDE_GOOSE_SUPPORT is not set. + * + * \param self the instance of IedServer to operate on. + */ +LIB61850_API void +IedServer_disableGoosePublishing(IedServer self); + +/** + * \brief Set the Ethernet interface to be used by GOOSE publishing + * + * This function can be used to set the GOOSE interface ID. If not used or set to NULL the + * default interface ID from stack_config.h is used. Note the interface ID is operating system + * specific! + * + * Note: This function has no effect when CONFIG_INCLUDE_GOOSE_SUPPORT is not set. + * + * \param self the instance of IedServer to operate on. + * \param interfaceId the ID of the ethernet interface to be used for GOOSE publishing + */ +LIB61850_API void +IedServer_setGooseInterfaceId(IedServer self, const char* interfaceId); + +/** + * \brief Set the Ethernet interface to be used by GOOSE publishing + * + * This function can be used to set the GOOSE interface ID forG all CBs (parameter ln = NULL) or for + * a specific GCB specified by the logical node instance and the GCB name. + * + * Note: This function has no effect when CONFIG_INCLUDE_GOOSE_SUPPORT is not set. + * + * \param self the instance of IedServer to operate on. + * \param ln the logical node that contains the GCB or NULL to set the ethernet interface ID for all GCBs + * \param gcbName the name (not object reference!) of the GCB + * \param interfaceId the ID of the ethernet interface to be used for GOOSE publishing + */ +LIB61850_API void +IedServer_setGooseInterfaceIdEx(IedServer self, LogicalNode* ln, const char* gcbName, const char* interfaceId); + +/** + * \brief Enable/disable the use of VLAN tags in GOOSE messages + * + * This function can be used to enable/disable VLAN tagging for all GCBs (parameter ln = NULL) or for + * a specific GCB specified by the logical node instance and the GCB name. + * + * Note: This function has no effect when CONFIG_INCLUDE_GOOSE_SUPPORT is not set. + * + * \param self the instance of IedServer to operate on + * \param ln the logical node that contains the GCB or NULL to enable/disable VLAN tagging for all GCBs + * \param gcbName the name (not object reference!) of the GCB + * \param useVlanTag true to enable VLAN tagging, false otherwise + */ +LIB61850_API void +IedServer_useGooseVlanTag(IedServer self, LogicalNode* ln, const char* gcbName, bool useVlanTag); + +/** + * \brief Set the time quality for all timestamps internally generated by this IedServer instance + * + * You can call this function during the initialization of the server or whenever a time quality + * flag has to be updated (on clock failure or change of time synchronization state). + * + * \param self the instance of IedServer to operate on. + * \param leapSecondKnown set/unset leap seconds known flag + * \param clockFailure set/unset clock failure flag + * \param clockNotSynchronized set/unset clock not synchronized flag + * \param subsecondPrecision set the subsecond precision (number of significant bits of the fractionOfSecond part of the time stamp) + */ +LIB61850_API void +IedServer_setTimeQuality(IedServer self, bool leapSecondKnown, bool clockFailure, bool clockNotSynchronized, int subsecondPrecision); + +/**@}*/ + +/** + * @defgroup IEC61850_SERVER_CONNECTION_HANDLING Connection handling and client authentication + * + * @{ + */ + +/** + * \brief set the authenticator for this server + * + * This function sets a user specified authenticator that is used to identify and authenticate clients that + * wants to connect. The authenticator is called on each connection attempt. Depending on the return value + * of the authenticator the client connection is accepted or refused. If no authenticator is set all client + * connections are accepted. + * + * \param self the instance of IedServer to operate on. + * \param authenticator the user provided authenticator callback + * \param authenticatorParameter user provided parameter that is passed to the authenticator + */ +LIB61850_API void +IedServer_setAuthenticator(IedServer self, AcseAuthenticator authenticator, void* authenticatorParameter); + +/** + * \brief get the peer address of this connection as string + * + * Note: the returned string is only valid as long as the client connection exists. It is save to use + * the string inside of the connection indication callback function. + * + * \param self the ClientConnection instance + * \return peer address as C string. + */ +LIB61850_API const char* +ClientConnection_getPeerAddress(ClientConnection self); + +/** + * \brief get the local address of this connection as string + * + * Note: the returned string is only valid as long as the client connection exists. It is save to use + * the string inside of the connection indication callback function. + * + * \param self the ClientConnection instance + * \return local address as C string. + */ +LIB61850_API const char* +ClientConnection_getLocalAddress(ClientConnection self); + +/** + * \brief Get the security token associated with this connection + * + * The security token is an opaque handle that is associated with the connection. It is provided by the + * authenticator (if one is present). If no security token is used then this function returns NULL + * + * \param self the ClientConnection instance + * + * \return the security token or NULL + */ +LIB61850_API void* +ClientConnection_getSecurityToken(ClientConnection self); + +/** + * \brief User provided callback function that is invoked whenever a new client connects or an existing connection is closed + * or detected as lost. + * + * \param self the instance of IedServer where the connection event occured. + * \param connection the new or closed client connect object + * \param connected true if a new connection is indicated, false if the connection has been closed or detected as lost. + * \param parameter a user provided parameter + */ +typedef void (*IedConnectionIndicationHandler) (IedServer self, ClientConnection connection, bool connected, void* parameter); + +/** + * \brief set a callback function that will be called on connection events (open or close). + * + * \param self the instance of IedServer to operate on. + * \param handler the user provided callback function + * \param parameter a user provided parameter that is passed to the callback function. + */ +LIB61850_API void +IedServer_setConnectionIndicationHandler(IedServer self, IedConnectionIndicationHandler handler, void* parameter); + + +/**@}*/ + +/** + * @defgroup IEC61850_SERVER_DATA_MODEL_ACCESS Data model access and data update + * + * @{ + */ + + +/** + * \brief Lock the data model for data update. + * + * This function should be called before the data model is updated. + * After updating the data model the function \ref IedServer_unlockDataModel should be called. + * Client requests will be postponed until the lock is removed. + * + * NOTE: This method should never be called inside of a library callback function. In the context of + * a library callback the data model is always already locked! Calling this function inside of a + * library callback may lead to a deadlock condition. + * + * \param self the instance of IedServer to operate on. + */ +LIB61850_API void +IedServer_lockDataModel(IedServer self); + +/** + * \brief Unlock the data model and process pending client requests. + * + * NOTE: This method should never be called inside of a library callback function. In the context of + * a library callback the data model is always already locked! + * + * \param self the instance of IedServer to operate on. + */ +LIB61850_API void +IedServer_unlockDataModel(IedServer self); + +/** + * \brief Get data attribute value + * + * Get the MmsValue object of an MMS Named Variable that is part of the device model. + * You should not manipulate the received object directly. Instead you should use + * the IedServer_updateValue method. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * + * \return MmsValue object of the MMS Named Variable or NULL if the value does not exist. + */ +LIB61850_API MmsValue* +IedServer_getAttributeValue(IedServer self, DataAttribute* dataAttribute); + +/** + * \brief Get data attribute value of a boolean data attribute + * + * Get the value of a data attribute of type MMS_BOOLEAN. If the data attribute + * is of a different type the returned value is undefined. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * + * \return true or false + */ +LIB61850_API bool +IedServer_getBooleanAttributeValue(IedServer self, const DataAttribute* dataAttribute); + +/** + * \brief Get data attribute value of an integer data attribute + * + * Get the value of a data attribute of type MMS_INTEGER. If the data attribute + * is of a different type the returned value is undefined. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * + * \return the value as 32 bit integer + */ +LIB61850_API int32_t +IedServer_getInt32AttributeValue(IedServer self, const DataAttribute* dataAttribute); + +/** + * \brief Get data attribute value of an integer data attribute + * + * Get the value of a data attribute of type MMS_INTEGER. If the data attribute + * is of a different type the returned value is undefined. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * + * \return the value as 64 bit integer + */ +LIB61850_API int64_t +IedServer_getInt64AttributeValue(IedServer self, const DataAttribute* dataAttribute); + +/** + * \brief Get data attribute value of an unsigned integer data attribute + * + * Get the value of a data attribute of type MMS_UNSIGNED. If the data attribute + * is of a different type the returned value is undefined. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * + * \return the value as 32 bit unsigned integer + */ +LIB61850_API uint32_t +IedServer_getUInt32AttributeValue(IedServer self, const DataAttribute* dataAttribute); + +/** + * \brief Get data attribute value of a floating point data attribute + * + * Get the value of a data attribute of type MMS_FLOAT. If the data attribute + * is of a different type the returned value is undefined. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * + * \return the value as 32 bit float + */ +LIB61850_API float +IedServer_getFloatAttributeValue(IedServer self, const DataAttribute* dataAttribute); + +/** + * \brief Get data attribute value of a UTC time data attribute + * + * Get the value of a data attribute of type MMS_UTC_TIME. If the data attribute + * is of a different type the returned value is undefined. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * + * \return the value as 64 bit unsigned integer representing the time in milliseconds since Epoch + */ +LIB61850_API uint64_t +IedServer_getUTCTimeAttributeValue(IedServer self, const DataAttribute* dataAttribute); + +/** + * \brief Get data attribute value of a bit string data attribute as integer value + * + * Get the value of a data attribute of type MMS_BIT_STRING. If the data attribute + * is of a different type the returned value is undefined. + * NOTE: The returned integer is determined by calculating the according the follwing + * formula: bit0^0 + bit1^1 + ... + bitn^n + * It is not specified in the IEC 61850 specifications how a bit string can be interpreted + * as an integer. Therefore this function has to be used with care. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * + * \return the value a 32 bit integer. + */ +LIB61850_API uint32_t +IedServer_getBitStringAttributeValue(IedServer self, const DataAttribute* dataAttribute); + +/** + * \brief Get data attribute value of a string type data attribute + * + * Get the value of a data attribute of type MMS_STRING or MMS_VISIBLE_STRING. If the data attribute + * is of a different type the returned value is undefined. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * + * \return the value as a C string (null terminated string) + */ +LIB61850_API const char* +IedServer_getStringAttributeValue(IedServer self, const DataAttribute* dataAttribute); + +/** + * \brief Get the MmsValue object related to a functional constrained data object (FCD) + * + * Get the MmsValue from the server cache that is associated with the Functional Constrained Data (FCD) + * object that is specified by the DataObject and the given Function Constraint (FC). + * Accessing the value will directly influence the values presented by the server. This kind of direct + * access will also bypass the report notification mechanism (i.e. changes will not cause a report!). + * Therefore this function should be used with care. It could be useful to access arrays of DataObjects. + * + * \param self the instance of IedServer to operate on. + * \param dataObject the data object to specify the FCD + * \param fc the FC to specify the FCD + * + * \return MmsValue object cached by the server. + */ +LIB61850_API MmsValue* +IedServer_getFunctionalConstrainedData(IedServer self, DataObject* dataObject, FunctionalConstraint fc); + +/** + * \brief Update the MmsValue object of an IEC 61850 data attribute. + * + * The data attribute handle of type DataAttribute* are imported with static_model.h in the case when + * the static data model is used. + * You should use this function instead of directly operating on the MmsValue instance + * that is hold by the MMS server. Otherwise the IEC 61850 server is not aware of the + * changed value and will e.g. not generate a report. + * + * This function will also check if a trigger condition is satisfied in the case when a report or GOOSE + * control block is enabled. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param value MmsValue object used to update the value cached by the server. + */ +LIB61850_API void +IedServer_updateAttributeValue(IedServer self, DataAttribute* dataAttribute, MmsValue* value); + +/** + * \brief Update the value of an IEC 61850 float data attribute. + * + * Update the value of a float data attribute without handling with MmsValue instances. + * + * This function will also check if a trigger condition is satisfied in the case when a report or GOOSE + * control block is enabled. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param value the new float value of the data attribute. + */ +LIB61850_API void +IedServer_updateFloatAttributeValue(IedServer self, DataAttribute* dataAttribute, float value); + +/** + * \brief Update the value of an IEC 61850 integer32 data attribute. + * + * Update the value of a integer data attribute without handling with MmsValue instances. + * + * This function will also check if a trigger condition is satisfied in the case when a report or GOOSE + * control block is enabled. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param value the new integer value of the data attribute. + */ +LIB61850_API void +IedServer_updateInt32AttributeValue(IedServer self, DataAttribute* dataAttribute, int32_t value); + +/** + * \brief Update the value of an IEC 61850 Dbpos (double point/position) data attribute. + * + * Update the value of a integer data attribute without handling with MmsValue instances. + * + * This function will also check if a trigger condition is satisfied in the case when a report or GOOSE + * control block is enabled. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param value the new Dbpos value of the data attribute. + */ +LIB61850_API void +IedServer_updateDbposValue(IedServer self, DataAttribute* dataAttribute, Dbpos value); + +/** + * \brief Update the value of an IEC 61850 integer64 data attribute (like BCR actVal) + * + * Update the value of a integer data attribute without handling with MmsValue instances. + * + * This function will also check if a trigger condition is satisfied in the case when a report or GOOSE + * control block is enabled. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param value the new 64 bit integer value of the data attribute. + */ +LIB61850_API void +IedServer_updateInt64AttributeValue(IedServer self, DataAttribute* dataAttribute, int64_t value); + +/** + * \brief Update the value of an IEC 61850 unsigned integer data attribute. + * + * Update the value of a unsigned data attribute without handling with MmsValue instances. + * + * This function will also check if a trigger condition is satisfied in the case when a report or GOOSE + * control block is enabled. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param value the new unsigned integer value of the data attribute. + */ +LIB61850_API void +IedServer_updateUnsignedAttributeValue(IedServer self, DataAttribute* dataAttribute, uint32_t value); + +/** + * \brief Update the value of an IEC 61850 bit string data attribute. + * + * Update the value of a bit string data attribute without handling with MmsValue instances. + * + * This function will also check if a trigger condition is satisfied in the case when a report or GOOSE + * control block is enabled. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param value the new bit string integer value of the data attribute. + */ +LIB61850_API void +IedServer_updateBitStringAttributeValue(IedServer self, DataAttribute* dataAttribute, uint32_t value); + +/** + * \brief Update the value of an IEC 61850 boolean data attribute. + * + * Update the value of a boolean data attribute without handling with MmsValue instances. + * + * This function will also check if a trigger condition is satisfied in the case when a report or GOOSE + * control block is enabled. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param value the new boolean value of the data attribute. + */ +LIB61850_API void +IedServer_updateBooleanAttributeValue(IedServer self, DataAttribute* dataAttribute, bool value); + +/** + * \brief Update the value of an IEC 61850 visible string data attribute. + * + * Update the value of a visible string data attribute without handling MmsValue instances. + * + * This function will also check if a trigger condition is satisfied in the case when a report or GOOSE + * control block is enabled. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param value the new visible string value of the data attribute. + */ +LIB61850_API void +IedServer_updateVisibleStringAttributeValue(IedServer self, DataAttribute* dataAttribute, char *value); + +/** + * \brief Update the value of an IEC 61850 UTC time (timestamp) data attribute. + * + * Update the value of a UTC time data attribute without handling MmsValue instances. + * + * This function will also check if a trigger condition is satisfied in the case when a report or GOOSE + * control block is enabled. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param value the new UTC time value of the data attribute as a ms timestamp + */ +LIB61850_API void +IedServer_updateUTCTimeAttributeValue(IedServer self, DataAttribute* dataAttribute, uint64_t value); + +/** + * \brief Update the value of an IEC 61850 UTC time (timestamp) data attribute. + * + * Update the value of a UTC time data attribute without handling MmsValue instances. + * + * This function will also check if a trigger condition is satisfied in the case when a report or GOOSE + * control block is enabled. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param value the new UTC time value of the data attribute as a Timestamp + */ +LIB61850_API void +IedServer_updateTimestampAttributeValue(IedServer self, DataAttribute* dataAttribute, Timestamp* timestamp); + +/** + * \brief Update a quality ("q") IEC 61850 data attribute. + * + * This is a specialized function to handle Quality data attributes. It can be used instead of the more + * generic IedServer_updateAttributeValue function. + * + * This function will also check if the quality change (qchg) trigger condition is satisfied and inform a + * report control block accordingly. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute handle + * \param quality the new quality value + * + */ +LIB61850_API void +IedServer_updateQuality(IedServer self, DataAttribute* dataAttribute, Quality quality); + +/**@}*/ + + +LIB61850_API void +IedServer_setLogStorage(IedServer self, const char* logRef, LogStorage logStorage); + +/** + * @defgroup IEC61850_SERVER_SETTING_GROUPS Server side setting group handling + * + * @{ + */ + +/** + * \brief Change active setting group + * + * Inform the IedServer that the active setting group has changed due to an internal event. + * Before calling this function the user should update the relevant data attributes with FC=SG! + * + * \param self the instance of IedServer to operate on. + * \param sgcb the handle of the setting group control block of the setting group + * \param newActiveSg the number of the new active setting group + */ +LIB61850_API void +IedServer_changeActiveSettingGroup(IedServer self, SettingGroupControlBlock* sgcb, uint8_t newActiveSg); + +/** + * \brief Get the active setting group number + * + * \param self the instance of IedServer to operate on. + * \param sgcb the handle of the setting group control block of the setting group + * + * \return the number of the active setting group + */ +LIB61850_API uint8_t +IedServer_getActiveSettingGroup(IedServer self, SettingGroupControlBlock* sgcb); + +/** + * \brief Callback handler that is invoked when the active setting group is about to be changed by an + * external client. + * + * This function is called BEFORE the active setting group is changed. The user can reject to change the + * active setting group by returning false. + * + * \param user provided parameter + * \param sgcb the setting group control block of the setting group that is about to be changed + * \param newActSg the new active setting group + * \param connection the client connection that requests the change + * + * \return true if the change is accepted, false otherwise. + * + */ +typedef bool (*ActiveSettingGroupChangedHandler) (void* parameter, SettingGroupControlBlock* sgcb, + uint8_t newActSg, ClientConnection connection); + +/** + * \brief Set the callback handler for the SetActSG event + * + * \param self the instance of IedServer to operate on. + * \param sgcb the handle of the setting group control block of the setting group. + * \param handler the user provided callback handler. + * \param parameter a user provided parameter that is passed to the control handler. + */ +LIB61850_API void +IedServer_setActiveSettingGroupChangedHandler(IedServer self, SettingGroupControlBlock* sgcb, + ActiveSettingGroupChangedHandler handler, void* parameter); + +/** + * \brief Callback handler that is invoked when the edit setting group is about to be changed by an + * external client. + * + * In this function the user should update all SE data attributes + * associated with the given SettingGroupControlBlock. + * This function is called BEFORE the active setting group is changed. The user can reject to change the + * edit setting group by returning false. This can be used to implement RBAC. + * + * \param user provided parameter + * \param sgcb the setting group control block of the setting group that is about to be changed + * \param newEditSg the new edit setting group + * \param connection the client connection that requests the change + * + * \return true if the change is accepted, false otherwise. + * + */ +typedef bool (*EditSettingGroupChangedHandler) (void* parameter, SettingGroupControlBlock* sgcb, + uint8_t newEditSg, ClientConnection connection); + +/** + * \brief Set the callback handler for the SetEditSG event + * + * \param self the instance of IedServer to operate on. + * \param sgcb the handle of the setting group control block of the setting group. + * \param handler the user provided callback handler. + * \param parameter a user provided parameter that is passed to the control handler. + */ +LIB61850_API void +IedServer_setEditSettingGroupChangedHandler(IedServer self, SettingGroupControlBlock* sgcb, + EditSettingGroupChangedHandler handler, void* parameter); + +/** + * \brief Callback handler that is invoked when the edit setting group has been confirmed by an + * external client. + * + * \param user provided parameter + * \param sgcb the setting group control block of the setting group that is about to be changed + * \param editSg the edit setting group that has been confirmed + * + */ +typedef void (*EditSettingGroupConfirmationHandler) (void* parameter, SettingGroupControlBlock* sgcb, + uint8_t editSg); + +/** + * \brief Set the callback handler for the COnfEditSG event + * + * \param self the instance of IedServer to operate on. + * \param sgcb the handle of the setting group control block of the setting group. + * \param handler the user provided callback handler. + * \param parameter a user provided parameter that is passed to the control handler. + */ +LIB61850_API void +IedServer_setEditSettingGroupConfirmationHandler(IedServer self, SettingGroupControlBlock* sgcb, + EditSettingGroupConfirmationHandler handler, void* parameter); + +/**@}*/ + +/** + * @defgroup IEC61850_SERVER_CONTROL Server side control model handling + * + * @{ + */ + +/** + * \brief result code for ControlPerformCheckHandler + */ +typedef enum { + CONTROL_ACCEPTED = -1, /**< check passed */ + CONTROL_WAITING_FOR_SELECT = 0, /**< select operation in progress - handler will be called again later */ + CONTROL_HARDWARE_FAULT = 1, /**< check failed due to hardware fault */ + CONTROL_TEMPORARILY_UNAVAILABLE = 2, /**< control is already selected or operated */ + CONTROL_OBJECT_ACCESS_DENIED = 3, /**< check failed due to access control reason - access denied for this client or state */ + CONTROL_OBJECT_UNDEFINED = 4, /**< object not visible in this security context ??? */ + CONTROL_VALUE_INVALID = 11 /**< ctlVal out of range */ +} CheckHandlerResult; + +/** + * \brief result codes for control handler (ControlWaitForExecutionHandler and ControlHandler) + */ +typedef enum { + CONTROL_RESULT_FAILED = 0, /**< check or operation failed */ + CONTROL_RESULT_OK = 1, /**< check or operation was successful */ + CONTROL_RESULT_WAITING = 2 /**< check or operation is in progress */ +} ControlHandlerResult; + +typedef void* ControlAction; + +/** + * \brief Sets the error code for the next command termination or application error message + * + * \param self the control action instance + * \param error the error code + */ +LIB61850_API void +ControlAction_setError(ControlAction self, ControlLastApplError error); + +/** + * \brief Sets the add cause for the next command termination or application error message + * + * \param self the control action instance + * \param addCause the additional cause + */ +LIB61850_API void +ControlAction_setAddCause(ControlAction self, ControlAddCause addCause); + +/** + * \brief Gets the originator category provided by the client + * + * \param self the control action instance + * + * \return the originator category + */ +LIB61850_API int +ControlAction_getOrCat(ControlAction self); + +/** + * \brief Gets the originator identifier provided by the client + * + * \param self the control action instance + * + * \return the originator identifier + */ +LIB61850_API uint8_t* +ControlAction_getOrIdent(ControlAction self, int* orIdentSize); + +/** + * \brief Get the ctlNum attribute send by the client + * + * \param self the control action instance + * + * \return the ctlNum value + */ +LIB61850_API int +ControlAction_getCtlNum(ControlAction self); + +/** + * \brief Gets the synchroCheck bit provided by the client + * + * \param self the control action instance + * + * \return the synchroCheck bit + */ +LIB61850_API bool +ControlAction_getSynchroCheck(ControlAction self); + +/** + * \brief Gets the interlockCheck bit provided by the client + * + * \param self the control action instance + * + * \return the interlockCheck bit + */ +LIB61850_API bool +ControlAction_getInterlockCheck(ControlAction self); + +/** + * \brief Check if the control callback is called by a select or operate command + * + * \param self the control action instance + * + * \return true, when called by select, false for operate + */ +LIB61850_API bool +ControlAction_isSelect(ControlAction self); + +/** + * \brief Gets the client object associated with the client that caused the control action + * + * \param self the control action instance + * + * \return client connection instance + */ +LIB61850_API ClientConnection +ControlAction_getClientConnection(ControlAction self); + +/** + * \brief Gets the control object that is subject to this action + * + * \param self the control action instance + * + * \return the controllable data object instance + */ +LIB61850_API DataObject* +ControlAction_getControlObject(ControlAction self); + +/** + * \brief Gets the time of the control, if it's a timeActivatedControl, returns 0, if it's not. + * + * \param self the control action instance + * + * \return the controllable data object instance + */ +LIB61850_API uint64_t +ControlAction_getControlTime(ControlAction self); + +/** + * \brief Control model callback to perform the static tests (optional). + * + * NOTE: Signature changed in version 1.4! + * + * User provided callback function for the control model. It will be invoked after + * a control operation has been invoked by the client. This callback function is + * intended to perform the static tests. It should check if the interlock conditions + * are met if the interlockCheck parameter is true. + * This handler can also be check if the client has the required permissions to execute the + * operation and allow or deny the operation accordingly. + * + * \param action the control action parameter that provides access to additional context information + * \param parameter the parameter that was specified when setting the control handler + * \param ctlVal the control value of the control operation. + * \param test indicates if the operate request is a test operation + * \param interlockCheck the interlockCheck parameter provided by the client + * + * \return CONTROL_ACCEPTED if the static tests had been successful, one of the error codes otherwise + */ +typedef CheckHandlerResult (*ControlPerformCheckHandler) (ControlAction action, void* parameter, MmsValue* ctlVal, bool test, bool interlockCheck); + +/** + * \brief Control model callback to perform the dynamic tests (optional). + * + * NOTE: Signature changed in version 1.4! + * + * User provided callback function for the control model. It will be invoked after + * a control operation has been invoked by the client. This callback function is + * intended to perform the dynamic tests. It should check if the synchronization conditions + * are met if the synchroCheck parameter is set to true. + * NOTE: Since version 0.7.9 this function is intended to return immediately. If the operation + * cannot be performed immediately the function SHOULD return CONTROL_RESULT_WAITING and the + * handler will be invoked again later. + * + * \param action the control action parameter that provides access to additional context information + * \param parameter the parameter that was specified when setting the control handler + * \param ctlVal the control value of the control operation. + * \param test indicates if the operate request is a test operation + * \param synchroCheck the synchroCheck parameter provided by the client + * + * \return CONTROL_RESULT_OK if the dynamic tests had been successful, CONTROL_RESULT_FAILED otherwise, + * CONTROL_RESULT_WAITING if the test is not yet finished + */ +typedef ControlHandlerResult (*ControlWaitForExecutionHandler) (ControlAction action, void* parameter, MmsValue* ctlVal, bool test, bool synchroCheck); + +/** + * \brief Control model callback to actually perform the control operation. + * + * NOTE: Signature changed in version 1.4! + * + * User provided callback function for the control model. It will be invoked when + * a control operation happens (Oper). Here the user should perform the control operation + * (e.g. by setting an digital output or switching a relay). + * NOTE: Since version 0.7.9 this function is intended to return immediately. If the operation + * cannot be performed immediately the function SHOULD return CONTROL_RESULT_WAITING and the + * handler will be invoked again later. + * + * \param action the control action parameter that provides access to additional context information + * \param parameter the parameter that was specified when setting the control handler + * \param ctlVal the control value of the control operation. + * \param test indicates if the operate request is a test operation + * + * \return CONTROL_RESULT_OK if the control action bas been successful, CONTROL_RESULT_FAILED otherwise, + * CONTROL_RESULT_WAITING if the test is not yet finished + */ +typedef ControlHandlerResult (*ControlHandler) (ControlAction action, void* parameter, MmsValue* ctlVal, bool test); + +/** + * \brief Reason why a select state of a control object changed + */ +typedef enum { + SELECT_STATE_REASON_SELECTED, /**< control has been selected */ + SELECT_STATE_REASON_CANCELED, /**< cancel received for the control */ + SELECT_STATE_REASON_TIMEOUT, /**< unselected due to timeout (sboTimeout) */ + SELECT_STATE_REASON_OPERATED, /**< unselected due to successful operate */ + SELECT_STATE_REASON_OPERATE_FAILED, /**< unselected due to failed operate */ + SELECT_STATE_REASON_DISCONNECTED /**< unselected due to disconnection of selecting client */ +} SelectStateChangedReason; + +/** + * \brief Control model callback that is called when the select state of a control changes + * + * New in version 1.5 + * + * \param action the control action parameter that provides access to additional context information + * \param parameter the parameter that was specified when setting the control handler + * \param isSelected true when the control is selected, false otherwise + * \param reason reason why the select state changed + */ +typedef void (*ControlSelectStateChangedHandler) (ControlAction action, void* parameter, bool isSelected, SelectStateChangedReason reason); + +/** + * \brief Set control handler for controllable data object + * + * This functions sets a user provided control handler for a data object. The data object + * has to be an instance of a controllable CDC (Common Data Class) like e.g. SPC, DPC or APC. + * The control handler is a callback function that will be called by the IEC server when a + * client invokes a control operation on the data object. + * + * \param self the instance of IedServer to operate on. + * \param node the controllable data object handle + * \param handler a callback function of type ControlHandler + * \param parameter a user provided parameter that is passed to the control handler. + */ +LIB61850_API void +IedServer_setControlHandler(IedServer self, DataObject* node, ControlHandler handler, void* parameter); + +/** + * \brief Set a handler for a controllable data object to perform operative tests + * + * This functions sets a user provided handler that should perform the operative tests for a control operation. + * Setting this handler is not required. If not set the server assumes that the checks will always be successful. + * The handler has to return true upon a successful test of false if the test fails. In the later case the control + * operation will be aborted. + * + * \param self the instance of IedServer to operate on. + * \param node the controllable data object handle + * \param handler a callback function of type ControlHandler + * \param parameter a user provided parameter that is passed to the control handler. + * + */ +LIB61850_API void +IedServer_setPerformCheckHandler(IedServer self, DataObject* node, ControlPerformCheckHandler handler, void* parameter); + +/** + * \brief Set a handler for a controllable data object to perform dynamic tests + * + * This functions sets a user provided handler that should perform the dynamic tests for a control operation. + * Setting this handler is not required. If not set the server assumes that the checks will always be successful. + * The handler has to return true upon a successful test of false if the test fails. In the later case the control + * operation will be aborted. + * + * \param self the instance of IedServer to operate on. + * \param node the controllable data object handle + * \param handler a callback function of type ControlHandler + * \param parameter a user provided parameter that is passed to the control handler. + * + */ +LIB61850_API void +IedServer_setWaitForExecutionHandler(IedServer self, DataObject* node, ControlWaitForExecutionHandler handler, void* parameter); + + +/** + * \brief Set a callback handler for a controllable data object to track select state changes + * + * The callback is called whenever the select state of a control changes. Reason for changes can be: + * - a successful select or select-with-value by a client + * - select timeout + * - operate or failed operate + * - cancel request by a client + * - the client that selected the control has been disconnected + * + * \param self the instance of IedServer to operate on. + * \param node the controllable data object handle + * \param handler a callback function of type ControlHandler + * \param parameter a user provided parameter that is passed to the callback handler. + */ +LIB61850_API void +IedServer_setSelectStateChangedHandler(IedServer self, DataObject* node, ControlSelectStateChangedHandler handler, void* parameter); + +/** + * \brief Update the control model for the specified controllable data object with the given value and + * update "ctlModel" attribute value. + * + * NOTE: The corresponding control structures for the control model have to be present in the data model! + * + * \param self the instance of IedServer to operate on. + * \param ctlObject the controllable data object handle + * \param value the new control model value + */ +LIB61850_API void +IedServer_updateCtlModel(IedServer self, DataObject* ctlObject, ControlModel value); + +/**@}*/ + +/** + * @defgroup IEC61850_SERVER_RCB Server side report control block (RCB) handling + * + * @{ + */ + +typedef enum { + RCB_EVENT_GET_PARAMETER, /* << parameter read by client (not implemented) */ + RCB_EVENT_SET_PARAMETER, /* << parameter set by client */ + RCB_EVENT_UNRESERVED, /* << RCB reservation canceled */ + RCB_EVENT_RESERVED, /* << RCB reserved */ + RCB_EVENT_ENABLE, /* << RCB enabled */ + RCB_EVENT_DISABLE, /* << RCB disabled */ + RCB_EVENT_GI, /* << GI report triggered */ + RCB_EVENT_PURGEBUF, /* << Purge buffer procedure executed */ + RCB_EVENT_OVERFLOW, /* << Report buffer overflow */ + RCB_EVENT_REPORT_CREATED /* << A new report was created and inserted into the buffer */ +} IedServer_RCBEventType; + +/** + * \brief Callback that is called in case of RCB event + * + * \param parameter user provided parameter + * \param rcb affected report control block + * \param connection client connection that is involved + * \param event event type + * \param parameterName name of the parameter in case of RCB_EVENT_SET_PARAMETER + * \param serviceError service error in case of RCB_EVENT_SET_PARAMETER + */ +typedef void (*IedServer_RCBEventHandler) (void* parameter, ReportControlBlock* rcb, ClientConnection connection, IedServer_RCBEventType event, const char* parameterName, MmsDataAccessError serviceError); + +/** + * \brief Set a handler for report control block (RCB) events + * + * \param self the instance of IedServer to operate on. + * \param handler the event handler to be used + * \param parameter a user provided parameter that is passed to the handler. + */ +LIB61850_API void +IedServer_setRCBEventHandler(IedServer self, IedServer_RCBEventHandler handler, void* parameter); + +/**@}*/ + +/** + * @defgroup IEC61850_SERVER_SVCB Server side sampled values control block (SVCB) handling + * + * @{ + */ + +/** Control block has been enabled by client */ +#define IEC61850_SVCB_EVENT_ENABLE 1 + +/** Control block has been disabled by client */ +#define IEC61850_SVCB_EVENT_DISABLE 0 + +/** + * \brief callback handler for SVCB events. + * + * \param svcb the related SVCB instance + * \param the event type + * \param user defined parameter + */ +typedef void (*SVCBEventHandler) (SVControlBlock* svcb, int event, void* parameter); + +/** + * \brief Set a handler for SVCB control block events (enable/disable) + * + * \param self the instance of IedServer to operate on. + * \param svcb the SVCB control block instance + * \param handler the event handler to be used + * \param parameter a user provided parameter that is passed to the handler. + */ +LIB61850_API void +IedServer_setSVCBHandler(IedServer self, SVControlBlock* svcb, SVCBEventHandler handler, void* parameter); + +/**@}*/ + +/** + * @defgroup IEC61850_SERVER_GOCB Server side GOOSE control block (GoCB) handling + * + * @{ + */ + +typedef struct sMmsGooseControlBlock* MmsGooseControlBlock; + +/** Control block has been enabled by client */ +#define IEC61850_GOCB_EVENT_ENABLE 1 + +/** Control block has been disabled by client */ +#define IEC61850_GOCB_EVENT_DISABLE 0 + +typedef void (*GoCBEventHandler) (MmsGooseControlBlock goCb, int event, void* parameter); + +/** + * \brief Set a callback handler for GoCB events (enabled/disabled) + * + * The callback handler is called whenever a GOOSE control block is enabled or disabled. + * It can be used to integrate the external GOOSE publisher with the IEC 61850/MMS server. + * + * \param self the instance of IedServer to operate on. + * \param handler the callback handler + * \param parameter user provided parameter that is passed to the callback handler + */ +LIB61850_API void +IedServer_setGoCBHandler(IedServer self, GoCBEventHandler handler, void* parameter); + +LIB61850_API char* +MmsGooseControlBlock_getName(MmsGooseControlBlock self); + +LIB61850_API LogicalNode* +MmsGooseControlBlock_getLogicalNode(MmsGooseControlBlock self); + +LIB61850_API DataSet* +MmsGooseControlBlock_getDataSet(MmsGooseControlBlock self); + +LIB61850_API bool +MmsGooseControlBlock_getGoEna(MmsGooseControlBlock self); + +LIB61850_API int +MmsGooseControlBlock_getMinTime(MmsGooseControlBlock self); + +LIB61850_API int +MmsGooseControlBlock_getMaxTime(MmsGooseControlBlock self); + +LIB61850_API bool +MmsGooseControlBlock_getFixedOffs(MmsGooseControlBlock self); + +LIB61850_API bool +MmsGooseControlBlock_getNdsCom(MmsGooseControlBlock self); + +/**@}*/ + +/** + * @defgroup IEC61850_SERVER_EXTERNAL_ACCESS Handle external access to data model and access control + * + * @{ + */ + +/*************************************************************************** + * Access control + **************************************************************************/ + +/** + * \brief callback handler to intercept/control client write access to data attributes + * + * User provided callback function to intercept/control MMS client access to + * IEC 61850 data attributes. The application can install the same handler + * multiple times and distinguish data attributes by the dataAttribute parameter. + * This handler can be used to perform write access control do data attributes. + * One application can be to allow write access only from a specific client. Another + * application could be to check if the value is in the allowed range before the write + * is accepted. + * When the callback returns DATA_ACCESS_ERROR_SUCCESS the write access is accepted and the stack will + * update the value automatically. + * When the callback returns DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE the write access is accepted but the + * stack will not update the value automatically. + * + * \param the data attribute that has been written by an MMS client. + * \param the value the client want to write to the data attribute + * \param connection the connection object of the client connection that invoked the write operation + * \param parameter the user provided parameter + * + * \return DATA_ACCESS_ERROR_SUCCESS, or DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE if access is accepted, DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED if access is denied. + */ +typedef MmsDataAccessError +(*WriteAccessHandler) (DataAttribute* dataAttribute, MmsValue* value, ClientConnection connection, void* parameter); + +/** + * \brief Install a WriteAccessHandler for a data attribute. + * + * This instructs the server to monitor write attempts by MMS clients to specific + * data attributes. If a client tries to write to the monitored data attribute the + * handler is invoked. The handler can decide if the write access will be allowed + * or denied. If a WriteAccessHandler is set for a specific data attribute - the + * default write access policy will not be performed for that data attribute. + * + * NOTE: If the data attribute has sub data attributes, the WriteAccessHandler is not + * set for the sub data attributes and will not be called when the sub data attribute is + * written directly! + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute to monitor + * \param handler the callback function that is invoked if a client tries to write to + * the monitored data attribute. + * \param parameter a user provided parameter that is passed to the WriteAccessHandler when called. + */ +LIB61850_API void +IedServer_handleWriteAccess(IedServer self, DataAttribute* dataAttribute, + WriteAccessHandler handler, void* parameter); + +/** + * \brief Install a WriteAccessHandler for a data attribute and for all sub data attributes + * + * This instructs the server to monitor write attempts by MMS clients to specific + * data attributes. If a client tries to write to the monitored data attribute the + * handler is invoked. The handler can decide if the write access will be allowed + * or denied. If a WriteAccessHandler is set for a specific data attribute - the + * default write access policy will not be performed for that data attribute. + * + * When the data attribute is a complex attribute then the handler will also be installed + * for all sub data attributes. When the data attribute is a basic data attribute then + * this function behaves like \ref IedServer_handleWriteAccess. + * + * \param self the instance of IedServer to operate on. + * \param dataAttribute the data attribute to monitor + * \param handler the callback function that is invoked if a client tries to write to + * the monitored data attribute. + * \param parameter a user provided parameter that is passed to the WriteAccessHandler when called. + */ +LIB61850_API void +IedServer_handleWriteAccessForComplexAttribute(IedServer self, DataAttribute* dataAttribute, + WriteAccessHandler handler, void* parameter); + +typedef enum { + ACCESS_POLICY_ALLOW, + ACCESS_POLICY_DENY +} AccessPolicy; + +/** + * \brief Change the default write access policy for functional constraint data with a specific FC. + * + * \param self the instance of IedServer to operate on. + * \param fc the FC for which to change the default write access policy. + * \param policy the new policy to apply. + * + */ +LIB61850_API void +IedServer_setWriteAccessPolicy(IedServer self, FunctionalConstraint fc, AccessPolicy policy); + +/** + * \brief callback handler to control client read access to data attributes + * + * User provided callback function to control MMS client read access to IEC 61850 + * data objects. The application is to allow read access to data objects for specific clients only. + * It can be used to implement a role based access control (RBAC). + * + * \param ld the logical device the client wants to access + * \param ln the logical node the client wants to access + * \param dataObject the data object the client wants to access + * \param fc the functional constraint of the access + * \param connection the client connection that causes the access + * \param parameter the user provided parameter + * + * \return DATA_ACCESS_ERROR_SUCCESS if access is accepted, DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED if access is denied. + */ +typedef MmsDataAccessError +(*ReadAccessHandler) (LogicalDevice* ld, LogicalNode* ln, DataObject* dataObject, FunctionalConstraint fc, ClientConnection connection, void* parameter); + +/** + * \brief Install the global read access handler + * + * The read access handler will be called for every read access before the server grants access to the client. + * + * \param self the instance of IedServer to operate on. + * \param handler the callback function that is invoked if a client tries to read a data object. + * \param parameter a user provided parameter that is passed to the callback function. + */ +LIB61850_API void +IedServer_setReadAccessHandler(IedServer self, ReadAccessHandler handler, void* parameter); + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* IED_SERVER_API_H_ */ diff --git a/product/src/fes/include/libiec61850/iso_connection_parameters.h b/product/src/fes/include/libiec61850/iso_connection_parameters.h new file mode 100644 index 00000000..3514f437 --- /dev/null +++ b/product/src/fes/include/libiec61850/iso_connection_parameters.h @@ -0,0 +1,301 @@ +/* + * iso_connection_parameters.h + * + * Copyright 2013-2018 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef ISO_CONNECTION_PARAMETERS_H_ +#define ISO_CONNECTION_PARAMETERS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tls_config.h" + +/** + * \addtogroup mms_client_api_group + */ +/**@{*/ + + +/** + * \brief authentication mechanism used by AcseAuthenticator + */ +typedef enum +{ + /** Neither ACSE nor TLS authentication used */ + ACSE_AUTH_NONE = 0, + + /** Use ACSE password for client authentication */ + ACSE_AUTH_PASSWORD = 1, + + /** Use ACSE certificate for client authentication */ + ACSE_AUTH_CERTIFICATE = 2, + + /** Use TLS certificate for client authentication */ + ACSE_AUTH_TLS = 3 +} AcseAuthenticationMechanism; + + +typedef struct sAcseAuthenticationParameter* AcseAuthenticationParameter; + +struct sAcseAuthenticationParameter +{ + AcseAuthenticationMechanism mechanism; + + union + { + struct + { + uint8_t* octetString; + int passwordLength; + } password; /* for mechanism = ACSE_AUTH_PASSWORD */ + + struct + { + uint8_t* buf; + int length; + } certificate; /* for mechanism = ACSE_AUTH_CERTIFICATE or ACSE_AUTH_TLS */ + + } value; +}; + +LIB61850_API AcseAuthenticationParameter +AcseAuthenticationParameter_create(void); + +LIB61850_API void +AcseAuthenticationParameter_destroy(AcseAuthenticationParameter self); + +LIB61850_API void +AcseAuthenticationParameter_setAuthMechanism(AcseAuthenticationParameter self, AcseAuthenticationMechanism mechanism); + +LIB61850_API void +AcseAuthenticationParameter_setPassword(AcseAuthenticationParameter self, char* password); + + +/** + * \brief Callback function to authenticate a client + * + * \param parameter user provided parameter - set when user registers the authenticator + * \param authParameter the authentication parameters provided by the client + * \param securityToken pointer where to store an application specific security token - can be ignored if not used. + * \param appReference ISO application reference (ap-title + ae-qualifier) + * + * \return true if client connection is accepted, false otherwise + */ +typedef bool +(*AcseAuthenticator)(void* parameter, AcseAuthenticationParameter authParameter, void** securityToken, IsoApplicationReference* appReference); + +/** + * \brief COTP T selector + * + * To not use T SEL set size to 0. + */ +typedef struct { + uint8_t size; /** 0 .. 4 - 0 means T-selector is not present */ + uint8_t value[4]; /** T-selector value */ +} TSelector; + +/** + * \brief OSI session selector + * + * To not use S SEL set size to 0 + */ +typedef struct { + uint8_t size; /** 0 .. 16 - 0 means S-selector is not present */ + uint8_t value[16]; /** S-selector value */ +} SSelector; + +/** + * \brief OSI presentation (P) selector + * + * To not use P SEL set size to 0 + */ +typedef struct { + uint8_t size; /** 0 .. 16 - 0 means P-selector is not present */ + uint8_t value[16]; /** P-selector value */ +} PSelector; + +struct sIsoConnectionParameters +{ + AcseAuthenticationParameter acseAuthParameter; + +#if (CONFIG_MMS_SUPPORT_TLS == 1) + TLSConfiguration tlsConfiguration; +#endif + + const char* hostname; + int tcpPort; + + const char* localIpAddress; + int localTcpPort; + + uint8_t remoteApTitle[10]; + int remoteApTitleLen; + int remoteAEQualifier; + PSelector remotePSelector; + SSelector remoteSSelector; + TSelector remoteTSelector; + + + uint8_t localApTitle[10]; + int localApTitleLen; + int localAEQualifier; + PSelector localPSelector; + SSelector localSSelector; + TSelector localTSelector; + +}; + +typedef struct sIsoConnectionParameters* IsoConnectionParameters; + +/** + * \brief create a new IsoConnectionParameters instance (FOR LIBRARY INTERNAL USE) + * + * NOTE: This function used internally by the MMS client library. When using the MMS or IEC 61850 API + * there should be no reason for the user to call this function. + * + * \return new IsoConnectionParameters instance + */ +LIB61850_API IsoConnectionParameters +IsoConnectionParameters_create(void); + +/** + * \brief Destroy an IsoConnectionParameters instance (FOR LIBRARY INTERNAL USE) + * + * NOTE: This function used internally by the MMS client library. When using the MMS or IEC 61850 API + * there should be no reason for the user to call this function. + * + * \param self the IsoConnectionParameters instance + */ +LIB61850_API void +IsoConnectionParameters_destroy(IsoConnectionParameters self); + + +LIB61850_API void +IsoConnectionParameters_setTlsConfiguration(IsoConnectionParameters self, TLSConfiguration tlsConfig); + +/** + * \brief set the authentication parameter + * + * This will set the authentication parameter and activates authentication. + * + * \param self the IsoConnectionParameters instance + * \param acseAuthParameter + */ +LIB61850_API void +IsoConnectionParameters_setAcseAuthenticationParameter(IsoConnectionParameters self, + AcseAuthenticationParameter acseAuthParameter); + +/** + * \brief Set TCP parameters (FOR LIBRARY INTERNAL USE) + * + * NOTE: This function used internally by the MMS client library. When using the MMS or IEC 61850 API + * there should be no reason for the user to call this function + * + * \param self the IsoConnectionParameters instance + * \param hostname the hostname of IP address if the server + * \param tcpPort the TCP port number of the server + */ +LIB61850_API void +IsoConnectionParameters_setTcpParameters(IsoConnectionParameters self, const char* hostname, int tcpPort); + +/** +* \brief Set Local TCP parameters (FOR LIBRARY INTERNAL USE) +* +* NOTE: This function used internally by the MMS Client library. When using the MMS or IEC 61850 API +* there should be no reason for the user to call this function +* +* \param self the IsoConnectionParameters instance +* \param localIpAddress the hostname of local IP address of the server +* \param localTcpPort the local TCP port number of the server +*/ +LIB61850_API void +IsoConnectionParameters_setLocalTcpParameters(IsoConnectionParameters self, const char* localIpAddress, int localTcpPort); + + +/** + * \brief set the remote AP-Title and AE-Qualifier + * + * Calling this function is optional and not recommended. If not called the default + * parameters are used. + * If apTitle is NULL the parameter the AP-Title and AE-Qualifier will not be transmitted. + * This seems to be required by some server devices. + * + * \param self the IsoConnectionParameters instance + * \param apTitle the AP-Title OID as string. + * \param aeQualifier the AP-qualifier + */ +LIB61850_API void +IsoConnectionParameters_setRemoteApTitle(IsoConnectionParameters self, const char* apTitle, int aeQualifier); + +/** + * \brief set remote addresses for the lower layers + * + * This function can be used to set the addresses for the lower layer protocols (presentation, session, and transport + * layer). Calling this function is optional and not recommended. If not called the default + * parameters are used. + * + * \param self the IsoConnectionParameters instance + * \param pSelector the P-Selector (presentation layer address) + * \param sSelector the S-Selector (session layer address) + * \param tSelector the T-Selector (ISO transport layer address) + */ +LIB61850_API void +IsoConnectionParameters_setRemoteAddresses(IsoConnectionParameters self, PSelector pSelector, SSelector sSelector, TSelector tSelector); + +/** + * \brief set the local AP-Title and AE-Qualifier + * + * Calling this function is optional and not recommended. If not called the default + * parameters are used. + * If apTitle is NULL the parameter the AP-Title and AE-Qualifier will not be transmitted. + * This seems to be required by some server devices. + * + * \param self the IsoConnectionParameters instance + * \param apTitle the AP-Title OID as string. + * \param aeQualifier the AP-qualifier + */ +LIB61850_API void +IsoConnectionParameters_setLocalApTitle(IsoConnectionParameters self, const char* apTitle, int aeQualifier); + +/** + * \brief set local addresses for the lower layers + * + * This function can be used to set the addresses for the lower layer protocols (presentation, session, and transport + * layer). Calling this function is optional and not recommended. If not called the default + * parameters are used. + * + * \param self the IsoConnectionParameters instance + * \param pSelector the P-Selector (presentation layer address) + * \param sSelector the S-Selector (session layer address) + * \param tSelector the T-Selector (ISO transport layer address) + */ +LIB61850_API void +IsoConnectionParameters_setLocalAddresses(IsoConnectionParameters self, PSelector pSelector, SSelector sSelector, TSelector tSelector); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* ISO_CONNECTION_PARAMETERS_H_ */ diff --git a/product/src/fes/include/libiec61850/libiec61850_common_api.h b/product/src/fes/include/libiec61850/libiec61850_common_api.h new file mode 100644 index 00000000..a233ccc9 --- /dev/null +++ b/product/src/fes/include/libiec61850/libiec61850_common_api.h @@ -0,0 +1,49 @@ +/* + * libiec61850_common_api.h + */ + +#ifndef LIBIEC61850_COMMON_API_INCLUDES_H_ +#define LIBIEC61850_COMMON_API_INCLUDES_H_ + +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +#define ATTRIBUTE_PACKED __attribute__ ((__packed__)) +#else +#define ATTRIBUTE_PACKED +#endif + +#ifndef DEPRECATED +#if defined(__GNUC__) || defined(__clang__) + #define DEPRECATED __attribute__((deprecated)) +#else + #define DEPRECATED +#endif +#endif + +#if defined _WIN32 || defined __CYGWIN__ + #ifdef EXPORT_FUNCTIONS_FOR_DLL + #define LIB61850_API __declspec(dllexport) + #else + #define LIB61850_API + #endif + + #define LIB61850_INTERNAL +#else + #if __GNUC__ >= 4 + #define LIB61850_API __attribute__ ((visibility ("default"))) + #define LIB61850_INTERNAL __attribute__ ((visibility ("hidden"))) + #else + #define LIB61850_API + #define LIB61850_INTERNAL + #endif +#endif + +#include "hal_time.h" +#include "mms_value.h" + +#endif /* LIBIEC61850_COMMON_API_INCLUDES_H_ */ diff --git a/product/src/fes/include/libiec61850/linked_list.h b/product/src/fes/include/libiec61850/linked_list.h new file mode 100644 index 00000000..cc4b9774 --- /dev/null +++ b/product/src/fes/include/libiec61850/linked_list.h @@ -0,0 +1,193 @@ +/* + * linked_list.h + * + * Copyright 2013-2021 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef LINKED_LIST_H_ +#define LINKED_LIST_H_ + +#include "libiec61850_common_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup common_api_group + */ +/**@{*/ + +/** + * \defgroup LINKED_LIST LinkedList data type definition and handling functions + */ +/**@{*/ + + +struct sLinkedList { + void* data; + struct sLinkedList* next; +}; + +/** + * \brief Reference to a linked list or to a linked list element. + */ +typedef struct sLinkedList* LinkedList; + +/** + * \brief Create a new LinkedList object + * + * \return the newly created LinkedList instance + */ +LIB61850_API LinkedList +LinkedList_create(void); + +/** + * \brief Delete a LinkedList object + * + * This function destroy the LinkedList object. It will free all data structures used by the LinkedList + * instance. It will call free for all elements of the linked list. This function should only be used if + * simple objects (like dynamically allocated strings) are stored in the linked list. + * + * \param self the LinkedList instance + */ +LIB61850_API void +LinkedList_destroy(LinkedList self); + + +typedef void (*LinkedListValueDeleteFunction) (void*); + +/** + * \brief Delete a LinkedList object + * + * This function destroy the LinkedList object. It will free all data structures used by the LinkedList + * instance. It will call a user provided function for each data element. This user provided function is + * responsible to properly free the data element. + * + * \param self the LinkedList instance + * \param valueDeleteFunction a function that is called for each data element of the LinkedList with the pointer + * to the linked list data element. + */ +LIB61850_API void +LinkedList_destroyDeep(LinkedList self, LinkedListValueDeleteFunction valueDeleteFunction); + +/** + * \brief Delete a LinkedList object without freeing the element data + * + * This function should be used statically allocated data objects are stored in the LinkedList instance. + * Other use cases would be if the data elements in the list should not be deleted. + * + * \param self the LinkedList instance + */ +LIB61850_API void +LinkedList_destroyStatic(LinkedList self); + +/** + * \brief Add a new element to the list + * + * This function will add a new data element to the list. The new element will the last element in the + * list. + * + * \param self the LinkedList instance + * \param data data to append to the LinkedList instance + */ +LIB61850_API void +LinkedList_add(LinkedList self, void* data); + +/** + * \brief Check if the specified data is contained in the list + * + * \param self the LinkedList instance + * \param data data to remove from the LinkedList instance + * + * \return true if data is part of the list, false otherwise + */ +LIB61850_API bool +LinkedList_contains(LinkedList self, void* data); + +/** + * \brief Removed the specified element from the list + * + * \param self the LinkedList instance + * \param data data to remove from the LinkedList instance + * + * \return true if data has been removed from the list, false otherwise + */ +LIB61850_API bool +LinkedList_remove(LinkedList self, void* data); + +/** + * \brief Get the list element specified by index (starting with 0). + * + * \param self the LinkedList instance + * \param index index of the requested element. + */ +LIB61850_API LinkedList +LinkedList_get(LinkedList self, int index); + +/** + * \brief Get the next element in the list (iterator). + * + * \param self the LinkedList instance + */ +LIB61850_API LinkedList +LinkedList_getNext(LinkedList self); + +/** + * \brief Get the last element in the list. + * + * \param self the LinkedList instance + */ +LIB61850_API LinkedList +LinkedList_getLastElement(LinkedList self); + +/** + * \brief Insert a new element int the list + * + * \param listElement the LinkedList instance + */ +LIB61850_API LinkedList +LinkedList_insertAfter(LinkedList listElement, void* data); + +/** + * \brief Get the size of the list + * + * \param self the LinkedList instance + * + * \return number of data elements stored in the list + */ +LIB61850_API int +LinkedList_size(LinkedList self); + +LIB61850_API void* +LinkedList_getData(LinkedList self); + +LIB61850_API void +LinkedList_printStringList(LinkedList self); + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* LINKED_LIST_H_ */ diff --git a/product/src/fes/include/libiec61850/logging_api.h b/product/src/fes/include/libiec61850/logging_api.h new file mode 100644 index 00000000..7f5327fc --- /dev/null +++ b/product/src/fes/include/libiec61850/logging_api.h @@ -0,0 +1,213 @@ +/* + * logging_api.h + * + * Copyright 2016 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef LIBIEC61850_SRC_LOGGING_LOGGING_API_H_ +#define LIBIEC61850_SRC_LOGGING_LOGGING_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libiec61850_common_api.h" + + +/** \addtogroup server_api_group + * @{ + */ + +/** + * @defgroup LOGGING_SPI Service provider interface (SPI) for log storage implementations + * + * This interface has to be implemented by the log storage provider. The Log storage provider + * has to provide a specific constructor that creates an instance of LogStorage by allocating + * the required memory for the struct sLogStorage data structure and populate the function + * pointers with provider specific implementation functions. + * + * @{ + */ + +/** The LogStorage object handle */ +typedef struct sLogStorage* LogStorage; + +/** + * \brief Will be called for each new LogEntry by the getEntries and getEntriesAfter functions + * + * \param parameter - a user provided parameter that is passed to the callback handler + * \param timestamp - the entry timestamp of the LogEntry + * \param entryID - the entryID of the LogEntry + * \param moreFollow - more data will follow - if false, the data is not valid and no more data will follow + * + * \return true ready to receive new data, false abort operation + */ +typedef bool (*LogEntryCallback) (void* parameter, uint64_t timestamp, uint64_t entryID, bool moreFollow); + +/** + * \brief Will be called for each new LogEntryData by the getEntries and getEntriesAfter functions + * + * \param parameter - a user provided parameter that is passed to the callback handler + * \param dataRef - the data reference of the LogEntryData + * \param data - the data content as an unstructured binary data block + * \param dataSize - the size of the binary data block + * \param reasonCode - the reasonCode of the LogEntryData + * \param moreFollow - more data will follow - if false, the data is not valid and no more data will follow + * + * \return true ready to receive new data, false abort operation + */ +typedef bool (*LogEntryDataCallback) (void* parameter, const char* dataRef, uint8_t* data, int dataSize, uint8_t reasonCode, bool moreFollow); + +struct sLogStorage { + + void* instanceData; + + int maxLogEntries; + + uint64_t (*addEntry) (LogStorage self, uint64_t timestamp); + + bool (*addEntryData) (LogStorage self, uint64_t entryID, const char* dataRef, uint8_t* data, int dataSize, uint8_t reasonCode); + + bool (*getEntries) (LogStorage self, uint64_t startingTime, uint64_t endingTime, + LogEntryCallback entryCallback, LogEntryDataCallback entryDataCallback, void* parameter); + + bool (*getEntriesAfter) (LogStorage self, uint64_t startingTime, uint64_t entryID, + LogEntryCallback entryCallback, LogEntryDataCallback entryDataCallback, void* parameter); + + bool (*getOldestAndNewestEntries) (LogStorage self, uint64_t* newEntry, uint64_t* newEntryTime, + uint64_t* oldEntry, uint64_t* oldEntryTime); + + void (*destroy) (LogStorage self); +}; + + +/** + * \brief Set the maximum number of log entries for this log + * + * \param self the pointer of the LogStorage instance + * \param maxEntries the maximum number of log entries + */ +LIB61850_API void +LogStorage_setMaxLogEntries(LogStorage self, int maxEntries); + +/** + * \brief Get the maximum allowed number of log entries for this log + * + * \param self the pointer of the LogStorage instance + * + * \return the maximum number of log entries + */ +LIB61850_API int +LogStorage_getMaxLogEntries(LogStorage self); + +/** + * \brief Add an entry to the log + * + * \param self the pointer of the LogStorage instance + * \param timestamp the entry time of the new entry + * + * \return the entryID of the new entry + */ +LIB61850_API uint64_t +LogStorage_addEntry(LogStorage self, uint64_t timestamp); + +/** + * \brief Add new entry data to an existing log entry + * + * \param self the pointer of the LogStorage instance + * \param entryID the ID of the log entry where the data will be added + * \param dataRef the data reference of the log entry data + * \param data the data content as an unstructured binary data block + * \param dataSize - the size of the binary data block + * \param reasonCode - the reasonCode of the LogEntryData + * + * \return true if the entry data was successfully added, false otherwise + */ +LIB61850_API bool +LogStorage_addEntryData(LogStorage self, uint64_t entryID, const char* dataRef, uint8_t* data, int dataSize, uint8_t reasonCode); + +/** + * \brief Get log entries specified by a time range + * + * \param self the pointer of the LogStorage instance + * \param startingTime start time of the time range + * \param endingTime end time of the time range + * \param entryCallback callback function to be called for each new log entry + * \param entryDataCallback callback function to be called for each new log entry data + * \param parameter - a user provided parameter that is passed to the callback handler + * + * \return true if the request has been successful, false otherwise + */ +LIB61850_API bool +LogStorage_getEntries(LogStorage self, uint64_t startingTime, uint64_t endingTime, + LogEntryCallback entryCallback, LogEntryDataCallback entryDataCallback, void* parameter); + +/** + * \brief Get log entries specified by a start log entry + * + * The request will return all log entries that where entered into the log after the + * log entry specified by startingTime and entryID. + * + * \param self the pointer of the LogStorage instance + * \param startingTime timestamp of the start log entry + * \param entryID entryID of the start log entry + * \param entryCallback callback function to be called for each new log entry + * \param entryDataCallback callback function to be called for each new log entry data + * \param parameter - a user provided parameter that is passed to the callback handler + * + * \return true if the request has been successful, false otherwise + */ +LIB61850_API bool +LogStorage_getEntriesAfter(LogStorage self, uint64_t startingTime, uint64_t entryID, + LogEntryCallback entryCallback, LogEntryDataCallback entryDataCallback, void* parameter); + +/** + * \brief Get the entry time and entryID of the oldest and the newest log entries + * + * This function is used to update the log status information in the LCB + * + * \param self the pointer of the LogStorage instance + * \param newEntry pointer to store the entryID of the newest entry + * \param newEntryTime pointer to store the entry time of the newest entry + * \param oldEntry pointer to store the entryID of the oldest entry + * \param oldEntryTime pointer to store the entry time of the oldest entry + * + */ +LIB61850_API bool +LogStorage_getOldestAndNewestEntries(LogStorage self, uint64_t* newEntry, uint64_t* newEntryTime, + uint64_t* oldEntry, uint64_t* oldEntryTime); + +/** + * \brief Destroy the LogStorage instance and free all related resources + * + * \param self the pointer of the LogStorage instance + */ +LIB61850_API void +LogStorage_destroy(LogStorage self); + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* LIBIEC61850_SRC_LOGGING_LOGGING_API_H_ */ diff --git a/product/src/fes/include/libiec61850/mms_client_connection.h b/product/src/fes/include/libiec61850/mms_client_connection.h new file mode 100644 index 00000000..86f12c9b --- /dev/null +++ b/product/src/fes/include/libiec61850/mms_client_connection.h @@ -0,0 +1,1321 @@ +/* + * mms_client_connection.h + * + * Copyright 2013-2018 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef MMS_CLIENT_CONNECTION_H_ +#define MMS_CLIENT_CONNECTION_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup mms_client_api_group MMS client API (for IEC 61850 use IEC 61850 client API instead!) + */ +/**@{*/ + +#include "libiec61850_common_api.h" + +#include "mms_common.h" +#include "mms_type_spec.h" +#include "mms_value.h" +#include "iso_connection_parameters.h" +#include "linked_list.h" +#include "tls_config.h" + +/** + * Contains MMS layer specific parameters + */ +typedef struct sMmsConnectionParameters { + int maxServOutstandingCalling; + int maxServOutstandingCalled; + int dataStructureNestingLevel; + int maxPduSize; /* local detail */ + uint8_t servicesSupported[11]; +} MmsConnectionParameters; + +typedef struct { + char* vendorName; + char* modelName; + char* revision; +} MmsServerIdentity; + +typedef enum { + MMS_CONNECTION_STATE_CLOSED, + MMS_CONNECTION_STATE_CONNECTING, + MMS_CONNECTION_STATE_CONNECTED, + MMS_CONNECTION_STATE_CLOSING +} MmsConnectionState; + +typedef void (*MmsInformationReportHandler) (void* parameter, char* domainName, + char* variableListName, MmsValue* value, bool isVariableListName); + +/** + * Opaque handle for MMS client connection instance. + */ +typedef struct sMmsConnection* MmsConnection; + + +/******************************************************************************* + * Connection management functions + *******************************************************************************/ + +/** + * \brief Create a new MmsConnection instance + * + * \return the newly created instance. + */ +LIB61850_API MmsConnection +MmsConnection_create(void); + +/** + * \brief Create a new secure (TLS enabled) MmsConnection instance + * + * \param tlsConfig TLS configuration parameters and certificates + * + * \return the newly created instance. + */ +LIB61850_API MmsConnection +MmsConnection_createSecure(TLSConfiguration tlsConfig); + +/** + * \brief Create a new MmsConnection instance configured for non-threaded mode + * + * NOTE: This constructor doesn't create a background thread for connection handling. + * The user has to call the MmsConnection_tick function periodically to ensure that + * the MMS connection can be handled properly. + * + * \param tlsConfig TLS configuration parameters and certificates or NULL for non-TLS mode. + * + * \return the newly created instance. + */ +LIB61850_API MmsConnection +MmsConnection_createNonThreaded(TLSConfiguration tlsConfig); + +/** + * \brief Callback function to intercept raw MMS messages + * + * IMPORTANT: the message buffer is only valid in the context of the the callback function. If the + * message data is required elsewhere it has to be copied here! + * + * \param parameter user provided parameter that is passed to the callback function + * \param message buffer of the message. + * \param messageLength length of the message in bytes + * \param received if true message has been received, false when message has been sent. + */ +typedef void (*MmsRawMessageHandler) (void* parameter, uint8_t* message, int messageLength, bool received); + +/** + * \brief Set the callback handler to intercept the raw MMS messages of the connection + * + * This function can be used to log raw MMS messages. It may be useful for debugging purposes + * or advanced test tools. This function will only work when the flag CONFIG_MMS_RAW_MESSAGE_LOGGING + * it set in stack_config.h + * + * \param self MmsConnection instance to operate on + * \param handler the connection specific callback function + * \param a user provided parameter passed to the callback function (use NULL if not required). + */ +LIB61850_API void +MmsConnection_setRawMessageHandler(MmsConnection self, MmsRawMessageHandler handler, void* parameter); + +/** + * \brief Set the virtual filestore basepath for the MMS obtain file services + * + * All external file service accesses will be mapped to paths relative to the base directory. + * NOTE: This function is only available when the CONFIG_SET_FILESTORE_BASEPATH_AT_RUNTIME + * option in stack_config.h is set. + * + * \param self the MmsServer instance + * \param basepath the new virtual filestore basepath + */ +LIB61850_API void +MmsConnection_setFilestoreBasepath(MmsConnection self, const char* basepath); + +/** + * \brief Set the request timeout in ms for this connection + * + * \param self MmsConnection instance to operate on + * \param timeoutInMs request timeout in milliseconds + */ +LIB61850_API void +MmsConnection_setRequestTimeout(MmsConnection self, uint32_t timeoutInMs); + +/** + * \brief Get the request timeout in ms for this connection + * + * \param self MmsConnection instance to operate on + * + * \return request timeout in milliseconds + */ +LIB61850_API uint32_t +MmsConnection_getRequestTimeout(MmsConnection self); + +/** + * \brief Set the connect timeout in ms for this connection instance + * + * \param self MmsConnection instance to operate on + * \param timeoutInMs connect timeout in milliseconds + */ +LIB61850_API void +MmsConnection_setConnectTimeout(MmsConnection self, uint32_t timeoutInMs); + +/** + * \brief Install a handler function for MMS information reports (unsolicited messages from the server). + * + * The handler function will be called whenever the client receives an MMS information report message. + * Note that the API user is responsible to properly free the passed MmsValue object. + * + * \param self MmsConnection instance to operate on + * \param handler the handler function to install for this client connection + * \param parameter a user specified parameter that will be passed to the handler function on each + * invocation. + */ +LIB61850_API void +MmsConnection_setInformationReportHandler(MmsConnection self, MmsInformationReportHandler handler, + void* parameter); + +/** + * \brief Get the ISO connection parameters for an MmsConnection instance + * + * \param self MmsConnection instance to operate on + * \return params the to be used by this connection + */ +LIB61850_API IsoConnectionParameters +MmsConnection_getIsoConnectionParameters(MmsConnection self); + +/** + * \brief Get the MMS specific connection parameters for an MmsConnection instance + * + * \param self MmsConnection instance to operate on + * \return params the to be used by this connection + */ +LIB61850_API MmsConnectionParameters +MmsConnection_getMmsConnectionParameters(MmsConnection self); + +typedef void (*MmsConnectionStateChangedHandler) (MmsConnection connection, void* parameter, MmsConnectionState newState); + +LIB61850_API void +MmsConnection_setConnectionStateChangedHandler(MmsConnection self, MmsConnectionStateChangedHandler handler, void* parameter); + +/** + * \brief User provided handler function that will be called if the connection to the server is lost + * + * \param connection MmsConnection object of the lost connection + * \param parameter user provided parameter. + */ +typedef void (*MmsConnectionLostHandler) (MmsConnection connection, void* parameter); + +/** + * \brief Install a callback function that will be called by the client stack if the MMS connection to the server is lost + * + * \param handler the user provided callback function + * \param handlerParameter a parameter that will be passed to the callback function. Can be set to NULL if not required. + */ +LIB61850_API void +MmsConnection_setConnectionLostHandler(MmsConnection self, MmsConnectionLostHandler handler, void* handlerParameter); + +/** + * \brief Set the ISO connection parameters for a MmsConnection instance + * + * \param self MmsConnection instance to operate on + * \param params the ISO client parameters to use + */ +LIB61850_API void +MmsConnection_setIsoConnectionParameters(MmsConnection self, IsoConnectionParameters* params); + +/** + * \brief Destroy an MmsConnection instance and release all resources + * + * \param self MmsConnection instance to operate on + */ +LIB61850_API void +MmsConnection_destroy(MmsConnection self); + +/******************************************************************************* + * Blocking functions for connection establishment and data access + *******************************************************************************/ + + +/** + * \brief Connect to an MMS server. + * + * This will open a new TCP connection and send a MMS initiate request. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param serverName hostname or IP address of the server to connect + * \param serverPort TCP port number of the server to connect or -1 to use default port (102 for MMS or 3872 for MMS over TLS) + * + * \return true on success. false if the connection attempt failed. + */ +LIB61850_API bool +MmsConnection_connect(MmsConnection self, MmsError* mmsError, const char* serverName, int serverPort); + +LIB61850_API void +MmsConnection_connectAsync(MmsConnection self, MmsError* mmsError, const char* serverName, int serverPort); + +/** + * \brief Call MmsConnection state machine and connection handling code (for non-threaded mode only) + * + * This function has to be called periodically by the user application in non-threaded mode. + * + * \return true when connection is currently waiting and calling thread can be suspended, false means + * connection is busy and the tick function should be called again as soon as possible. + */ +LIB61850_API bool +MmsConnection_tick(MmsConnection self); + +/* NOTE: This function is for test purposes! */ +LIB61850_API void +MmsConnection_sendRawData(MmsConnection self, MmsError* mmsError, uint8_t* buffer, int bufSize); + +/** + * \brief Close the connection - not recommended + * + * This service simply closes the TCP socket without any hand-shaking with the server. + * This behavior is not specified. Use with care! + * + * \param self MmsConnection instance to operate on + */ +LIB61850_API void +MmsConnection_close(MmsConnection self); + +typedef void +(*MmsConnection_ConcludeAbortHandler) (void* parameter, MmsError mmsError, bool success); + +/** + * \brief Uses the MMS/ACSE abort service to close the connection to the server + * + * This service should be used to abruptly interrupt the connection to the server. It is not quite clear what the + * benefit of this service is (simply closing the TCP connection should do the same). Though it is required by + * conformance tests. In case the server doesn't close the connection after the internal timeout interval the + * client will close the TCP connection and set mmsError to MMS_ERROR_SERVICE_TIMEOUT. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + */ +LIB61850_API void +MmsConnection_abort(MmsConnection self, MmsError* mmsError); + +LIB61850_API void +MmsConnection_abortAsync(MmsConnection self, MmsError* mmsError); + +/** + * \brief Uses the MMS conclude service to close the connection to the server + * + * This should be used to orderly release the connection to the server. If the server denies the conclude + * request (by sending a concludeError PDU) this service fails with an error (mmsError set accordingly) and + * the connection remains open. In this case the close or abort methods have to be used to close the connection. + * It is not quite clear if this service is really useful but it is required by conformance tests. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + */ +LIB61850_API void +MmsConnection_conclude(MmsConnection self, MmsError* mmsError); + +LIB61850_API void +MmsConnection_concludeAsync(MmsConnection self, MmsError* mmsError, MmsConnection_ConcludeAbortHandler handler, void* parameter); + +typedef void +(*MmsConnection_GenericServiceHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, bool success); + +typedef void +(*MmsConnection_GetNameListHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, LinkedList nameList, bool moreFollows); + +/** + * \brief Get the names of all VMD scope variables of the server. + * + * This will result in a VMD specific GetNameList request. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * + * \return the of VMD specific variable names or NULL if the request failed. + */ +LIB61850_API LinkedList /* */ +MmsConnection_getVMDVariableNames(MmsConnection self, MmsError* mmsError); + +LIB61850_API void +MmsConnection_getVMDVariableNamesAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* continueAfter, + MmsConnection_GetNameListHandler handler, void* parameter); + +/** + * \brief Get the domains names for all domains of the server. + * + * This will result in a VMD specific GetNameList request. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variaextern "C" {ble to store error code + * + * \return the list of domain names or NULL if the request failed. + * + */ +LIB61850_API LinkedList /* */ +MmsConnection_getDomainNames(MmsConnection self, MmsError* mmsError); + +/** + * \brief Get the domain names of the server (asynchronous version). + * + * \param[in] self MmsConnection instance to operate on + * \param[out] usedInvokeId the invoke ID of the request + * \param[out] mmsError user provided variable to store error code + * \param[in] continueAfter the name of the last received element when the call is a continuation, or NULL for the first call + * \param[in] result list to store (append) the response names, or NULL to create a new list for the response names + * \param[in] handler will be called when response is received or timed out. + * \param[in] parameter + */ +LIB61850_API void +MmsConnection_getDomainNamesAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* continueAfter, LinkedList result, + MmsConnection_GetNameListHandler handler, void* parameter); + +/** + * \brief Get the names of all variables present in a MMS domain of the server. + * + * This will result in a domain specific GetNameList request. + * + * \param[in] self MmsConnection instance to operate on + * \param[out] mmsError user provided variable to store error code + * \param[in] domainId the domain name for the domain specific request + * + * \return the of domain specific variable names or NULL if the request failed. + */ +LIB61850_API LinkedList /* */ +MmsConnection_getDomainVariableNames(MmsConnection self, MmsError* mmsError, const char* domainId); + +/** + * \brief Get the names of all variables present in a MMS domain of the server (asynchronous version). + * + * This will result in a domain specific GetNameList request. + * + * \param[in] self MmsConnection instance to operate on + * \param[out] usedInvokeId the invoke ID of the request + * \param[out] mmsError user provided variable to store error code + * \param[in] domainId the domain name for the domain specific request + * \param[in] continueAfter the name of the last received element when the call is a continuation, or NULL for the first call + * \param[in] result list to store (append) the response names, or NULL to create a new list for the response names + * \param[in] handler will be called when response is received or timed out. + * \param[in] parameter + */ +LIB61850_API void +MmsConnection_getDomainVariableNamesAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* domainId, + const char* continueAfter, LinkedList result, MmsConnection_GetNameListHandler handler, void* parameter); + +/** + * \brief Get the names of all named variable lists present in a MMS domain or VMD scope of the server. + * + * This will result in a domain specific GetNameList request. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name for the domain specific request or NULL for a VMD scope request + * + * \return the domain specific named variable list names or NULL if the request failed. + */ +LIB61850_API LinkedList /* */ +MmsConnection_getDomainVariableListNames(MmsConnection self, MmsError* mmsError, const char* domainId); + +LIB61850_API void +MmsConnection_getDomainVariableListNamesAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* domainId, + const char* continueAfter, LinkedList result, MmsConnection_GetNameListHandler handler, void* parameter); + +/** + * \brief Get the names of all journals present in a MMS domain of the server + * + * This will result in a domain specific GetNameList request. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name for the domain specific request + * + * \return the domain specific journal names or NULL if the request failed. + */ +LIB61850_API LinkedList /* */ +MmsConnection_getDomainJournals(MmsConnection self, MmsError* mmsError, const char* domainId); + +LIB61850_API void +MmsConnection_getDomainJournalsAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* domainId, + const char* continueAfter, MmsConnection_GetNameListHandler handler, void* parameter); + +/** + * \brief Get the names of all named variable lists associated with this client connection. + * + * This will result in an association specific GetNameList request. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * + * \return the association specific named variable list names or NULL if the request failed. + */ +LIB61850_API LinkedList /* */ +MmsConnection_getVariableListNamesAssociationSpecific(MmsConnection self, MmsError* mmsError); + +LIB61850_API void +MmsConnection_getVariableListNamesAssociationSpecificAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* continueAfter, MmsConnection_GetNameListHandler handler, void* parameter); + + +/** + * \brief Read a single variable from the server. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the variable to be read or NULL to read a VMD specific named variable + * \param itemId name of the variable to be read + * + * \return Returns a MmsValue object or NULL if the request failed. The MmsValue object can + * either be a simple value or a complex value or array. It is also possible that the return value is NULL + * even if mmsError = MMS_ERROR_NON. This is the case when the servers returns an empty result list. + */ +LIB61850_API MmsValue* +MmsConnection_readVariable(MmsConnection self, MmsError* mmsError, const char* domainId, const char* itemId); + + +typedef void +(*MmsConnection_ReadVariableHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, MmsValue* value); + +/** + * \brief Read a single variable from the server (asynchronous version) + * + * \param{in] self MmsConnection instance to operate on + * \param[out] usedInvokeId the invoke ID of the request + * \param[out] mmsError user provided variable to store error code + * \param[in] domainId the domain name of the variable to be read or NULL to read a VMD specific named variable + * \param[in] itemId name of the variable to be read + */ +LIB61850_API void +MmsConnection_readVariableAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* domainId, const char* itemId, + MmsConnection_ReadVariableHandler handler, void* parameter); + +/** + * \brief Read a component of a single variable from the server. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the variable to be read or NULL to read a VMD specific named variable + * \param itemId name of the variable to be read + * \param componentId the component name + * + * \return Returns a MmsValue object or NULL if the request failed. The MmsValue object can + * either be a simple value or a complex value or array. It is also possible that the return value is NULL + * even if mmsError = MMS_ERROR_NON. This is the case when the servers returns an empty result list. + */ +LIB61850_API MmsValue* +MmsConnection_readVariableComponent(MmsConnection self, MmsError* mmsError, + const char* domainId, const char* itemId, const char* componentId); + +/** + * \brief Read a component of a single variable from the server (asynchronous version) + * + * \param[in] self MmsConnection instance to operate on + * \param[out] usedInvokeId the invoke ID of the request + * \param[out] mmsError user provided variable to store error code + * \param[in] domainId the domain name of the variable to be read or NULL to read a VMD specific named variable + * \param[in] itemId name of the variable to be read + * \param[in] componentId the component name + * \param[in] handler + * \param[in] parameter + */ +LIB61850_API void +MmsConnection_readVariableComponentAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* domainId, const char* itemId, const char* componentId, + MmsConnection_ReadVariableHandler handler, void* parameter); + +/** + * \brief Read one or more elements of a single array variable from the server. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the variable to be read + * \param itemId name of the variable to be read + * \param startIndex index of element to read or start index if a element range is to be read + * \param numberOfElements Number of elements to read or 0 if a single element is to be read + * + * \return Returns a MmsValue object or NULL if the request failed. The MmsValue object is either + * a simple or complex type if numberOfElements is 0, or an array containing the selected + * array elements of numberOfElements > 0. + */ +LIB61850_API MmsValue* +MmsConnection_readArrayElements(MmsConnection self, MmsError* mmsError, const char* domainId, const char* itemId, + uint32_t startIndex, uint32_t numberOfElements); + +/** + * \brief Read one or more elements of a single array variable from the server (asynchronous version) + * + * NOTE: The MmsValue object received by the callback function is either a simple or complex type if numberOfElements is 0, or an array + * containing the selected array elements of numberOfElements > 0. + * + * \param[in] self MmsConnection instance to operate on + * \param[out] usedInvokeId the invoke ID of the request + * \param[out] mmsError user provided variable to store error code + * \param[in] domainId the domain name of the variable to be read + * \param[in] itemId name of the variable to be read + * \param[in] startIndex index of element to read or start index if a element range is to be read + * \param[in] numberOfElements Number of elements to read or 0 if a single element is to be read + */ +LIB61850_API void +MmsConnection_readArrayElementsAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* domainId, const char* itemId, + uint32_t startIndex, uint32_t numberOfElements, + MmsConnection_ReadVariableHandler handler, void* parameter); + + +/** + * \brief Read a single element (with optional component specification) from the server + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the variable to be read + * \param itemId name of the variable to be read + * \param index array element index + * \param componentId array element component name + * + * \return Returns a MmsValue object or NULL if the request failed. + */ +LIB61850_API MmsValue* +MmsConnection_readSingleArrayElementWithComponent(MmsConnection self, MmsError* mmsError, + const char* domainId, const char* itemId, uint32_t index, const char* componentId); + +LIB61850_API void +MmsConnection_readSingleArrayElementWithComponentAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* domainId, const char* itemId, + uint32_t index, const char* componentId, + MmsConnection_ReadVariableHandler handler, void* parameter); + +/** + * \brief Read multiple variables of a domain from the server with one request message. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the requested variables. + * \param items: LinkedList is the list of item IDs of the requested variables. + * + * \return Returns a MmsValue object or NULL if the request failed. The MmsValue object is + * is of type MMS_ARRAY and contains the variable values of simple or complex type + * in the order as they appeared in the item ID list. + */ +LIB61850_API MmsValue* +MmsConnection_readMultipleVariables(MmsConnection self, MmsError* mmsError, const char* domainId, + LinkedList /**/ items); + +LIB61850_API void +MmsConnection_readMultipleVariablesAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* domainId, LinkedList /**/items, + MmsConnection_ReadVariableHandler handler, void* parameter); + +/** + * \brief Write a single variable to the server. + * + * NOTE: added return value in version 1.1 + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the variable to be written + * \param itemId name of the variable to be written + * \param value value of the variable to be written + * + * \return when successful, the data access error value returned by the server + */ +LIB61850_API MmsDataAccessError +MmsConnection_writeVariable(MmsConnection self, MmsError* mmsError, + const char* domainId, const char* itemId, MmsValue* value); + +typedef void +(*MmsConnection_WriteVariableHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, MmsDataAccessError accessError); + +LIB61850_API void +MmsConnection_writeVariableAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* domainId, const char* itemId, MmsValue* value, + MmsConnection_WriteVariableHandler handler, void* parameter); + + +/** + * \brief Write a single variable to the server (using component alternate access) + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the variable to be written + * \param itemId name of the variable to be written + * \param componentId the name of the variable component + * \param value value of the variable to be written + * + * \return when successful, the data access error value returned by the server + */ +LIB61850_API MmsDataAccessError +MmsConnection_writeVariableComponent(MmsConnection self, MmsError* mmsError, + const char* domainId, const char* itemId, + const char* componentId, MmsValue* value); + +/** + * \brief Write a single array element with a component to an array type variable + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the variable to be written + * \param itemId name of the variable to be written + * \param arrayIndex the index of the array element. + * \param componentId the name of the component of the array element + * \param value value of the array element component to be written. + * + * \return when successful, the data access error value returned by the server + */ +LIB61850_API MmsDataAccessError +MmsConnection_writeSingleArrayElementWithComponent(MmsConnection self, MmsError* mmsError, + const char* domainId, const char* itemId, + uint32_t arrayIndex, const char* componentId, MmsValue* value); + +LIB61850_API void +MmsConnection_writeSingleArrayElementWithComponentAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* domainId, const char* itemId, + uint32_t arrayIndex, const char* componentId, MmsValue* value, + MmsConnection_WriteVariableHandler handler, void* parameter); + +LIB61850_API void +MmsConnection_writeVariableComponentAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* domainId, const char* itemId, const char* componentId, MmsValue* value, + MmsConnection_WriteVariableHandler handler, void* parameter); + +/** + * \brief Write a single array element or a sub array to an array type variable + * + * When a single array element is addressed the MmsValue object value has to be of the type + * of the array elements. When multiple array elements have to be written (index range) the + * MmsValue object value has to be of type MMS_ARRAY containing "numberOfElements" elements. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the variable to be written + * \param index the index of the array element or the start index of a index range + * \param numberOfElements the number of array elements to write starting with index. If 0 only one array element is written. + * \param itemId name of the variable to be written + * \param value value of the array element(s) to be written. Has to be of the type of + * the array elements or of type MMS_ARRAY when it is a sub array (index range) + * + * \return when successful, the data access error value returned by the server + */ +LIB61850_API MmsDataAccessError +MmsConnection_writeArrayElements(MmsConnection self, MmsError* mmsError, + const char* domainId, const char* itemId, int index, int numberOfElements, + MmsValue* value); + +LIB61850_API void +MmsConnection_writeArrayElementsAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* domainId, const char* itemId, int index, int numberOfElements, + MmsValue* value, + MmsConnection_WriteVariableHandler handler, void* parameter); + + +typedef void +(*MmsConnection_WriteMultipleVariablesHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, LinkedList /* */ accessResults); + + +/** + * \brief Write multiple variables to the server. + * + * This function will write multiple variables to the server. + * + * The parameter accessResults is a pointer to a LinkedList reference. The methods will create a new LinkedList + * object that contains the AccessResults of the single variable write attempts. It is up to the user to free this + * objects properly (e.g. with LinkedList_destroyDeep(accessResults, MmsValue_delete)). + * + * \param[in] self MmsConnection instance to operate on + * \param[out] mmsError user provided variable to store error code + * \param[in] domainId the common domain name of all variables to be written + * \param[in] items a linked list containing the names of the variables to be written. The names are C strings. + * \param[out] values values of the variables to be written + * \param[out] the MmsValue objects of type MMS_DATA_ACCESS_ERROR representing the write success of a single variable + * write. + */ +LIB61850_API void +MmsConnection_writeMultipleVariables(MmsConnection self, MmsError* mmsError, const char* domainId, + LinkedList /**/ items, LinkedList /* */ values, + LinkedList* /* */ accessResults); + +LIB61850_API void +MmsConnection_writeMultipleVariablesAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* domainId, + LinkedList /**/ items, LinkedList /* */ values, + MmsConnection_WriteMultipleVariablesHandler handler, void* parameter); + +/** + * \brief Write named variable list values to the server. + * + * The parameter accessResults is a pointer to a LinkedList reference. The methods will create a new LinkedList + * object that contains the AccessResults of the single variable write attempts. It is in the responsibility of + * the user to free this objects properly (e.g. with LinkedList_destroyDeep(accessResults, MmsValue_delete)). + * If accessResult is the to NULL the result will not be stored. + * + * \param[in] self MmsConnection instance to operate on + * \param[out] mmsError user provided variable to store error code + * \param[in] isAssociationSpecifc true if the named variable list is an association specific named variable list + * \param[in] domainId the common domain name of all variables to be written + * \param[out] values values of the variables to be written + * \param[out] the MmsValue objects of type MMS_DATA_ACCESS_ERROR representing the write success of a single variable + * write. + */ +LIB61850_API void +MmsConnection_writeNamedVariableList(MmsConnection self, MmsError* mmsError, bool isAssociationSpecific, + const char* domainId, const char* itemId, LinkedList /* */values, + LinkedList* /* */accessResults); + + +LIB61850_API void +MmsConnection_writeNamedVariableListAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, bool isAssociationSpecific, + const char* domainId, const char* itemId, LinkedList /* */values, + MmsConnection_WriteMultipleVariablesHandler handler, void* parameter); + +/** + * \brief Get the variable access attributes of a MMS named variable of the server + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the variable or NULL for a VMD specific request + * \param itemId name of the variable + * + * \return Returns a MmsTypeSpecification object or NULL if the request failed. + */ +LIB61850_API MmsVariableSpecification* +MmsConnection_getVariableAccessAttributes(MmsConnection self, MmsError* mmsError, + const char* domainId, const char* itemId); + +typedef void +(*MmsConnection_GetVariableAccessAttributesHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, MmsVariableSpecification* spec); + + +LIB61850_API void +MmsConnection_getVariableAccessAttributesAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* domainId, const char* itemId, + MmsConnection_GetVariableAccessAttributesHandler, void* parameter); + +/** + * \brief Read the values of a domain specific named variable list + * + * The resulting named variable list will either be of domain scope (when the domainId argument + * is present) or VMD scope when the domainId argument is NULL. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the requested variables. + * \param listName the name of the named variable list + * \param specWithResult if specWithResult is set to true, a IEC 61850 compliant request will be sent. + * + * \return Returns a MmsValue object or NULL if the request failed. The MmsValue object is + * is of type MMS_ARRAY and contains the variable values of simple or complex type + * in the order as they appeared in named variable list definition. + */ +LIB61850_API MmsValue* +MmsConnection_readNamedVariableListValues(MmsConnection self, MmsError* mmsError, const char* domainId, + const char* listName, bool specWithResult); + +LIB61850_API void +MmsConnection_readNamedVariableListValuesAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* domainId, const char* listName, bool specWithResult, + MmsConnection_ReadVariableHandler handler, void* parameter); + + +/** + * \brief Read the values of a association specific named variable list + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param listName the name of the named variable list + * \param specWithResult if specWithResult is set to true, a IEC 61850 compliant request will be sent. + * + * \return Returns a MmsValue object or NULL if the request failed. The MmsValue object is + * is of type MMS_ARRAY and contains the variable values of simple or complex type + * in the order as they appeared in named variable list definition. + */ +LIB61850_API MmsValue* +MmsConnection_readNamedVariableListValuesAssociationSpecific(MmsConnection self, MmsError* mmsError, + const char* listName, bool specWithResult); + +LIB61850_API void +MmsConnection_readNamedVariableListValuesAssociationSpecificAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* listName, bool specWithResult, + MmsConnection_ReadVariableHandler handler, void* parameter); + +/** + * \brief Define a new VMD or domain scoped named variable list at the server. + * + * The resulting named variable list will either be of domain scope (when the domainId argument + * is present) or VMD scope when the domainId argument is NULL. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the domain for the new variable list + * \param listName the name of the named variable list + * \param variableSpecs a list of variable specifications for the new variable list. The list + * elements have to be of type MmsVariableAccessSpecification*. + */ +LIB61850_API void +MmsConnection_defineNamedVariableList(MmsConnection self, MmsError* mmsError, const char* domainId, + const char* listName, LinkedList variableSpecs); + +LIB61850_API void +MmsConnection_defineNamedVariableListAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* domainId, + const char* listName, LinkedList variableSpecs, + MmsConnection_GenericServiceHandler handler, void* parameter); + + + +/** + * \brief Define a new association specific named variable list at the server. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param listName the name of the named variable list + * \param variableSpecs list of variable specifications for the new variable list.The list + * elements have to be of type MmsVariableAccessSpecification*. + */ +LIB61850_API void +MmsConnection_defineNamedVariableListAssociationSpecific(MmsConnection self, MmsError* mmsError, + const char* listName, LinkedList variableSpecs); + +LIB61850_API void +MmsConnection_defineNamedVariableListAssociationSpecificAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* listName, LinkedList variableSpecs, + MmsConnection_GenericServiceHandler handler, void* parameter); + +/** + * \brief Read the entry list of a named variable list at the server. + * + * The resulting named variable list will either be of domain scope (when the domainId argument + * is present) or VMD scope when the domainId argument is NULL. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the domain of the variable list + * \param listName the name of the named variable list + * \param deletable THIS IS A OUTPUT PARAMETER - indicates if the variable list is deletable by the + * client. The user may provide a NULL pointer if the value doesn't matter. + * + * \return List of names of the variable list entries or NULL if the request failed + */ +LIB61850_API LinkedList /* */ +MmsConnection_readNamedVariableListDirectory(MmsConnection self, MmsError* mmsError, + const char* domainId, const char* listName, bool* deletable); + + +typedef void +(*MmsConnection_ReadNVLDirectoryHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, LinkedList /* */ specs, bool deletable); + + +LIB61850_API void +MmsConnection_readNamedVariableListDirectoryAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* domainId, const char* listName, + MmsConnection_ReadNVLDirectoryHandler handler, void* parameter); + + +/** + * \brief Read the entry list of an association specific named variable list at the server. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param listName the name of the named variable list + * + * \return List of names of the variable list entries or NULL if the request failed + */ +LIB61850_API LinkedList /* */ +MmsConnection_readNamedVariableListDirectoryAssociationSpecific(MmsConnection self, MmsError* mmsError, + const char* listName, bool* deletable); + +LIB61850_API void +MmsConnection_readNamedVariableListDirectoryAssociationSpecificAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + const char* listName, + MmsConnection_ReadNVLDirectoryHandler handler, void* parameter); + +/** + * \brief Delete a named variable list at the server. + * + * The resulting named variable list will either be of domain scope (when the domainId argument + * is present) or VMD scope when the domainId argument is NULL. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param domainId the domain name of the domain of the variable list + * \param listName the name of the named variable list + * + * \return true if named variable list has been deleted, false otherwise + */ +LIB61850_API bool +MmsConnection_deleteNamedVariableList(MmsConnection self, MmsError* mmsError, const char* domainId, const char* listName); + + +LIB61850_API void +MmsConnection_deleteNamedVariableListAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* domainId, const char* listName, + MmsConnection_GenericServiceHandler handler, void* parameter); + +/** + * \brief Delete an association specific named variable list at the server. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param listName the name of the named variable list + * + * \return true if named variable list has been deleted, false otherwise + */ +LIB61850_API bool +MmsConnection_deleteAssociationSpecificNamedVariableList(MmsConnection self, MmsError* mmsError, + const char* listName); + + +LIB61850_API void +MmsConnection_deleteAssociationSpecificNamedVariableListAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* listName, + MmsConnection_GenericServiceHandler handler, void* parameter); + +/** + * \brief Create a new MmsVariableSpecification that can be used to define named variable lists. + * + * The created object can be deleted with free(). If the parameter strings were dynamically + * allocated the deallocation is in the responsibility of the user. + * + * \param domainId the MMS domain name of the variable + * \param itemId the name for the MMS variable + * + * \return reference to the new MmsVariableSpecfication object + */ +LIB61850_API MmsVariableAccessSpecification* +MmsVariableAccessSpecification_create(char* domainId, char* itemId); + +/** + * \brief Create a new MmsVariableSpecification that can be used to define named variable lists. + * + * The created object can be deleted with free(). If the parameter strings were dynamically + * allocated the deallocation is in the responsibility of the user. This function should be + * used for named variable list entries that are array elements or components of array elements + * in the case when the array element is of complex (structured) type. + * + * \param domainId the MMS domain name of the variable + * \param itemId the name for the MMS variable + * \param index the array index to describe an array element + * \param componentName the name of the component of the array element. Should be set to NULL + * if the array element is of simple type or the whole array element is required. + * + * \return reference to the new MmsVariableSpecfication object + */ +LIB61850_API MmsVariableAccessSpecification* +MmsVariableAccessSpecification_createAlternateAccess(char* domainId, char* itemId, int32_t index, + char* componentName); + +/** + * \brief Delete the MmsVariableAccessSpecification data structure + * + * \param self the instance to delete + */ +LIB61850_API void +MmsVariableAccessSpecification_destroy(MmsVariableAccessSpecification* self); + +/** + * \brief Get the MMS local detail parameter (local detail means maximum MMS PDU size). + * + * This defaults to 65000 (or the value specified in the stack_config.h file. + * This function should not be called after a successful connection attempt. + * + * \param self MmsConnection instance to operate on + * \param localDetail the maximum size of the MMS PDU that will be accepted. + */ +LIB61850_API void +MmsConnection_setLocalDetail(MmsConnection self, int32_t localDetail); + +LIB61850_API int32_t +MmsConnection_getLocalDetail(MmsConnection self); + +/** + * \brief get the identity of the connected server + * + * This function will return the identity of the server if the server supports the MMS identify service. + * The server identity consists of a vendor name, model name, and a revision. + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + */ +LIB61850_API MmsServerIdentity* +MmsConnection_identify(MmsConnection self, MmsError* mmsError); + +typedef void +(*MmsConnection_IdentifyHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, + char* vendorName, char* modelName, char* revision); + +LIB61850_API void +MmsConnection_identifyAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, + MmsConnection_IdentifyHandler handler, void* parameter); + +/** + * \brief Destroy (free) an MmsServerIdentity object + * + * \param self the object to destroy + */ +LIB61850_API void +MmsServerIdentity_destroy(MmsServerIdentity* self); + +/** + * \brief get the VMD status of the connected server (is MMS status service) + * + * This function will return the status of the connected server by invoking the MMS status service. + * The services returns the logical and physical states of the server. + * + * \param[in] self MmsConnection instance to operate on + * \param[out] mmsError user provided variable to store error code + * \param[out] vmdLogicalStatus user provided variable to store the logical state of the VMD + * \param[out] vmdPhysicalStatus user provided variable to store the physical state of the VMD + * \param[in] extendedDerivation instructs the server to invoke self-diagnosis routines to determine server status + */ +LIB61850_API void +MmsConnection_getServerStatus(MmsConnection self, MmsError* mmsError, int* vmdLogicalStatus, int* vmdPhysicalStatus, + bool extendedDerivation); + +typedef void +(*MmsConnection_GetServerStatusHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, int vmdLogicalStatus, int vmdPhysicalStatus); + +LIB61850_API void +MmsConnection_getServerStatusAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, bool extendedDerivation, + MmsConnection_GetServerStatusHandler handler, void* parameter); + +/******************************************************************************* + * functions for MMS file services + *******************************************************************************/ + +typedef void +(*MmsFileDirectoryHandler) (void* parameter, char* filename, uint32_t size, uint64_t lastModified); + +/** + * \brief Callback handler for the get file directory service + * + * Will be called once for each file directory entry and after the last entry with \ref filename = NULL to indicate + * with \ref moreFollows set to true when more data is available server side. In case of an error the callback will be called with + * \ref mmsError != MMS_ERROR_NONE and moreFollows = false. + */ +typedef void +(*MmsConnection_FileDirectoryHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, char* filename, uint32_t size, uint64_t lastModfified, + bool moreFollows); + +typedef void +(*MmsFileReadHandler) (void* parameter, int32_t frsmId, uint8_t* buffer, uint32_t bytesReceived); + +/** + * \brief Callback handler for the file read service + * + * Will be called for every received part of the file and when there is an error during reading the file. + * + * \param invokeId invokeID of the response + * \param parameter user provided context parameter + * \param mmsError error code + * \param frsmId ID of the file + * \param buffer buffer where the received bytes are stored + * \param bytesReceived number of bytes received with this response + * \param moreFollows more messages with parts of the file are following + */ +typedef void +(*MmsConnection_FileReadHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, int32_t frsmId, uint8_t* buffer, uint32_t byteReceived, + bool moreFollows); + + +/** + * \brief open a file for read + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * + * \return the FRSM ID (file read state machine) handle of the opened file + */ +LIB61850_API int32_t +MmsConnection_fileOpen(MmsConnection self, MmsError* mmsError, const char* filename, uint32_t initialPosition, + uint32_t* fileSize, uint64_t* lastModified); + +typedef void +(*MmsConnection_FileOpenHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, int32_t frsmId, uint32_t fileSize, uint64_t lastModified); + +LIB61850_API void +MmsConnection_fileOpenAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* filename, uint32_t initialPosition, MmsConnection_FileOpenHandler handler, + void* parameter); + + +/** + * \brief read the next data block from the file + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param frsmId the FRSM ID (file read state machine) handle of the file + * \param handler callback that is invoked to deliver the received data + * \param handlerParameter user provided paramter that is passed to the callback function + * + * \return true if more data follows, false if last data has been received. + */ +LIB61850_API bool +MmsConnection_fileRead(MmsConnection self, MmsError* mmsError, int32_t frsmId, MmsFileReadHandler handler, void* handlerParameter); + +LIB61850_API void +MmsConnection_fileReadAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, int32_t frsmId, MmsConnection_FileReadHandler handler, void* parameter); + +/** + * \brief close the file with the specified frsmID + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param frsmId id of the file to close + */ +LIB61850_API void +MmsConnection_fileClose(MmsConnection self, MmsError* mmsError, int32_t frsmId); + +LIB61850_API void +MmsConnection_fileCloseAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, uint32_t frsmId, MmsConnection_GenericServiceHandler handler, void* parameter); + +/** + * \brief delete the file with the specified name + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param fileName name of the file to delete + */ +LIB61850_API void +MmsConnection_fileDelete(MmsConnection self, MmsError* mmsError, const char* fileName); + +LIB61850_API void +MmsConnection_fileDeleteAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* fileName, + MmsConnection_GenericServiceHandler handler, void* parameter); + +/** + * \brief rename the file with the specified name + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param currentFileName name of the file to rename + * \param newFileName new name of the file + */ +LIB61850_API void +MmsConnection_fileRename(MmsConnection self, MmsError* mmsError, const char* currentFileName, const char* newFileName); + +LIB61850_API void +MmsConnection_fileRenameAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* currentFileName, const char* newFileName, + MmsConnection_GenericServiceHandler handler, void* parameter); + +/** + * \brief Send an obtainFile request to the server (used to initiate file download to server) + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param sourceFile the name of the source file (client side name) + * \param destinationFile the name of the destination file (server side name) + */ +LIB61850_API void +MmsConnection_obtainFile(MmsConnection self, MmsError* mmsError, const char* sourceFile, const char* destinationFile); + +LIB61850_API void +MmsConnection_obtainFileAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* sourceFile, const char* destinationFile, + MmsConnection_GenericServiceHandler handler, void* parameter); + +/** + * \brief get the file directory of the server. + * + * This function will return the directory entries of the given server directory. For each directory entry + * the provided callback handler is called. If the + * + * \param self MmsConnection instance to operate on + * \param mmsError user provided variable to store error code + * \param fileSpecification the file specification of the directory to browse or NULL to browse the root directory + * \param continueAfter continuation point or NULL for the first request. The continuation point is the first entry + * after the provided continuation file name. + * \param handler user provided callback handler + * \param handlerParameter user provided parameter that is passed to the handler + * + * \return (more follows) true if more data is available + */ +LIB61850_API bool +MmsConnection_getFileDirectory(MmsConnection self, MmsError* mmsError, const char* fileSpecification, const char* continueAfter, + MmsFileDirectoryHandler handler, void* handlerParameter); + +LIB61850_API void +MmsConnection_getFileDirectoryAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* fileSpecification, const char* continueAfter, + MmsConnection_FileDirectoryHandler handler, void* parameter); + +typedef struct sMmsJournalEntry* MmsJournalEntry; + +typedef struct sMmsJournalVariable* MmsJournalVariable; + +struct sMmsJournalEntry { + MmsValue* entryID; /* type MMS_OCTET_STRING */ + MmsValue* occurenceTime; /* type MMS_BINARY_TIME */ + LinkedList journalVariables; +}; + +struct sMmsJournalVariable { + char* tag; + MmsValue* value; +}; + +/** + * \brief Destroy a single MmsJournalEntry instance. + * + * This function will destroy the whole MmsJournalEntry object including the attached list + * of MmsJournalVariable objects. It is intended to be used in conjunction with the + * LinkedList_destroyDeep function in order to free the result of MmsConnection_readJournalTimeRange + * or MmsConnection_readJournalStartAfter + * + * LinkedList_destroyDeep(journalEntries, (LinkedListValueDeleteFunction) + * MmsJournalEntry_destroy); + * + * \param self the MmsJournalEntry instance to destroy + */ +LIB61850_API void +MmsJournalEntry_destroy(MmsJournalEntry self); + +LIB61850_API MmsValue* +MmsJournalEntry_getEntryID(MmsJournalEntry self); + +LIB61850_API MmsValue* +MmsJournalEntry_getOccurenceTime(MmsJournalEntry self); + +LIB61850_API LinkedList /* */ +MmsJournalEntry_getJournalVariables(MmsJournalEntry self); + +LIB61850_API const char* +MmsJournalVariable_getTag(MmsJournalVariable self); + +LIB61850_API MmsValue* +MmsJournalVariable_getValue(MmsJournalVariable self); + +typedef void +(*MmsConnection_ReadJournalHandler) (uint32_t invokeId, void* parameter, MmsError mmsError, LinkedList /* */ journalEntries, bool moreFollows); + + +LIB61850_API LinkedList /* */ +MmsConnection_readJournalTimeRange(MmsConnection self, MmsError* mmsError, const char* domainId, const char* itemId, + MmsValue* startTime, MmsValue* endTime, bool* moreFollows); + +LIB61850_API void +MmsConnection_readJournalTimeRangeAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* domainId, const char* itemId, + MmsValue* startTime, MmsValue* endTime, MmsConnection_ReadJournalHandler handler, void* parameter); + +LIB61850_API LinkedList /* */ +MmsConnection_readJournalStartAfter(MmsConnection self, MmsError* mmsError, const char* domainId, const char* itemId, + MmsValue* timeSpecification, MmsValue* entrySpecification, bool* moreFollows); + +LIB61850_API void +MmsConnection_readJournalStartAfterAsync(MmsConnection self, uint32_t* usedInvokeId, MmsError* mmsError, const char* domainId, const char* itemId, + MmsValue* timeSpecification, MmsValue* entrySpecification, MmsConnection_ReadJournalHandler handler, void* parameter); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* MMS_CLIENT_CONNECTION_H_ */ diff --git a/product/src/fes/include/libiec61850/mms_common.h b/product/src/fes/include/libiec61850/mms_common.h new file mode 100644 index 00000000..a60d8f6c --- /dev/null +++ b/product/src/fes/include/libiec61850/mms_common.h @@ -0,0 +1,181 @@ +/* + * mms_common.h + * + * Copyright 2013-2018 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#include "libiec61850_common_api.h" + +#ifndef MMS_COMMON_H_ +#define MMS_COMMON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup common_api_group + */ +/**@{*/ + +typedef enum +{ + /* generic error codes */ + MMS_ERROR_NONE = 0, + MMS_ERROR_CONNECTION_REJECTED = 1, + MMS_ERROR_CONNECTION_LOST = 2, + MMS_ERROR_SERVICE_TIMEOUT = 3, + MMS_ERROR_PARSING_RESPONSE = 4, + MMS_ERROR_HARDWARE_FAULT = 5, + MMS_ERROR_CONCLUDE_REJECTED = 6, + MMS_ERROR_INVALID_ARGUMENTS = 7, + MMS_ERROR_OUTSTANDING_CALL_LIMIT = 8, + + MMS_ERROR_OTHER = 9, + + /* confirmed error PDU codes */ + MMS_ERROR_VMDSTATE_OTHER = 10, + + MMS_ERROR_APPLICATION_REFERENCE_OTHER = 20, + + MMS_ERROR_DEFINITION_OTHER = 30, + MMS_ERROR_DEFINITION_INVALID_ADDRESS = 31, + MMS_ERROR_DEFINITION_TYPE_UNSUPPORTED = 32, + MMS_ERROR_DEFINITION_TYPE_INCONSISTENT = 33, + MMS_ERROR_DEFINITION_OBJECT_UNDEFINED = 34, + MMS_ERROR_DEFINITION_OBJECT_EXISTS = 35, + MMS_ERROR_DEFINITION_OBJECT_ATTRIBUTE_INCONSISTENT = 36, + + MMS_ERROR_RESOURCE_OTHER = 40, + MMS_ERROR_RESOURCE_CAPABILITY_UNAVAILABLE = 41, + + MMS_ERROR_SERVICE_OTHER = 50, + MMS_ERROR_SERVICE_OBJECT_CONSTRAINT_CONFLICT = 55, + + MMS_ERROR_SERVICE_PREEMPT_OTHER = 60, + + MMS_ERROR_TIME_RESOLUTION_OTHER = 70, + + MMS_ERROR_ACCESS_OTHER = 80, + MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT = 81, + MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED = 82, + MMS_ERROR_ACCESS_OBJECT_ACCESS_DENIED = 83, + MMS_ERROR_ACCESS_OBJECT_INVALIDATED = 84, + MMS_ERROR_ACCESS_OBJECT_VALUE_INVALID = 85, /* for DataAccessError 11 */ + MMS_ERROR_ACCESS_TEMPORARILY_UNAVAILABLE = 86, /* for DataAccessError 2 */ + + MMS_ERROR_FILE_OTHER = 90, + MMS_ERROR_FILE_FILENAME_AMBIGUOUS = 91, + MMS_ERROR_FILE_FILE_BUSY = 92, + MMS_ERROR_FILE_FILENAME_SYNTAX_ERROR = 93, + MMS_ERROR_FILE_CONTENT_TYPE_INVALID = 94, + MMS_ERROR_FILE_POSITION_INVALID = 95, + MMS_ERROR_FILE_FILE_ACCESS_DENIED = 96, + MMS_ERROR_FILE_FILE_NON_EXISTENT = 97, + MMS_ERROR_FILE_DUPLICATE_FILENAME = 98, + MMS_ERROR_FILE_INSUFFICIENT_SPACE_IN_FILESTORE = 99, + + /* reject codes */ + MMS_ERROR_REJECT_OTHER = 100, + MMS_ERROR_REJECT_UNKNOWN_PDU_TYPE = 101, + MMS_ERROR_REJECT_INVALID_PDU = 102, + MMS_ERROR_REJECT_UNRECOGNIZED_SERVICE = 103, + MMS_ERROR_REJECT_UNRECOGNIZED_MODIFIER = 104, + MMS_ERROR_REJECT_REQUEST_INVALID_ARGUMENT = 105 + +} MmsError; + +typedef enum +{ + /*! this represents all MMS array types (arrays contain uniform elements) */ + MMS_ARRAY = 0, + /*! this represents all complex MMS types (structures) */ + MMS_STRUCTURE = 1, + /*! boolean value */ + MMS_BOOLEAN = 2, + /*! bit string */ + MMS_BIT_STRING = 3, + /*! represents all signed integer types */ + MMS_INTEGER = 4, + /*! represents all unsigned integer types */ + MMS_UNSIGNED = 5, + /*! represents all float type (32 and 64 bit) */ + MMS_FLOAT = 6, + /*! octet string (unstructured bytes) */ + MMS_OCTET_STRING = 7, + /*! MMS visible string */ + MMS_VISIBLE_STRING = 8, + MMS_GENERALIZED_TIME = 9, + MMS_BINARY_TIME = 10, + MMS_BCD = 11, + MMS_OBJ_ID = 12, + /*! MMS unicode string */ + MMS_STRING = 13, + /*! MMS UTC time type */ + MMS_UTC_TIME = 14, + /*! This represents an error code as returned by MMS read services */ + MMS_DATA_ACCESS_ERROR = 15 +} MmsType; + +typedef struct sMmsDomain MmsDomain; + +typedef struct sMmsAccessSpecifier +{ + MmsDomain* domain; + char* variableName; + int arrayIndex; /* -1 --> no index present / ignore index */ + char* componentName; +} MmsAccessSpecifier; + +typedef struct +{ + char* domainId; + char* itemId; + int32_t arrayIndex; /* -1 --> no index present / ignore index */ + char* componentName; +} MmsVariableAccessSpecification; + +typedef struct sMmsNamedVariableList* MmsNamedVariableList; +typedef struct sMmsAccessSpecifier* MmsNamedVariableListEntry; + +/** + * \brief ITU (International Telecommunication Union) object identifier (OID) + */ +typedef struct { + uint16_t arc[10]; + int arcCount; +} ItuObjectIdentifier; + +/** + * \brief ISO application reference (specifies an ISO application endpoint) + */ +typedef struct { + ItuObjectIdentifier apTitle; + int aeQualifier; +} IsoApplicationReference; + +/**@}*/ + + +#ifdef __cplusplus +} +#endif + +#endif /* MMS_COMMON_H_ */ diff --git a/product/src/fes/include/libiec61850/mms_server.h b/product/src/fes/include/libiec61850/mms_server.h new file mode 100644 index 00000000..7e6118d0 --- /dev/null +++ b/product/src/fes/include/libiec61850/mms_server.h @@ -0,0 +1,379 @@ +/* + * mms_server.h + * + * Copyright 2013-2018 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef MMS_SERVER_H_ +#define MMS_SERVER_H_ + +/** \addtogroup mms_server_api_group + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mms_value.h" +#include "iso_connection_parameters.h" + +typedef enum { + MMS_SERVER_NEW_CONNECTION, + MMS_SERVER_CONNECTION_CLOSED, + MMS_SERVER_CONNECTION_TICK +} MmsServerEvent; + +typedef struct sMmsServer* MmsServer; + +typedef struct sMmsServerConnection* MmsServerConnection; + +typedef enum { + MMS_DOMAIN_SPECIFIC, + MMS_ASSOCIATION_SPECIFIC, + MMS_VMD_SPECIFIC +} MmsVariableListType; + +LIB61850_INTERNAL void +MmsServer_setLocalIpAddress(MmsServer self, const char* localIpAddress); + +LIB61850_INTERNAL bool +MmsServer_isRunning(MmsServer self); + +/** + * \brief callback handler that is called whenever a named variable list changes + * + * \param parameter a user provided parameter + * \param create if true the the request if a request to create a new variable list, false is a delete request + * \param listType the type (scope) of the named variable list (either domain, association or VMD specific) + * \param domain the MMS domain the list is belonging to (is NULL for association or VMD specific lists!) + * \param listName the name + * \param connection client connection that requests the creation of deletion of the variable list + * + * \return MMS_ERROR_NONE if the request is accepted, otherwise the MmsError value that has to be sent back to the client + */ +typedef MmsError (*MmsNamedVariableListChangedHandler)(void* parameter, bool create, MmsVariableListType listType, MmsDomain* domain, + char* listName, MmsServerConnection connection); + +/** + * \brief Install callback handler that is called when a named variable list changes (is created or deleted) + * + * \param self the MmsServer instance to operate on + * \param handler the callback handler function + * \param parameter user provided parameter that is passed to the callback handler + */ +LIB61850_INTERNAL void +MmsServer_installVariableListChangedHandler(MmsServer self, MmsNamedVariableListChangedHandler handler, void* parameter); + +/** + * \brief ObtainFile service callback handler + * + * This is invoked when the obtainFile service is requested by the client. It can be used to accept or deny the + * write access to the file system based on the client connection. + * + * \param parameter user provided parameter that is passed to the callback handler + * \param connection the connection that requested the service + * \param sourceFilename the source file name on the client side system + * \param destinationFilename the target file name on the server side system + */ +typedef bool (*MmsObtainFileHandler)(void* parameter, MmsServerConnection connection, const char* sourceFilename, const char* destinationFilename); + +/** + * \brief Install callback handler that is invoked when the file upload (obtainFile service) is invoked by the client + * + * This handler can be used to apply access restrictions on the file upload (obtainFile) service + * + * \param self the MmsServer instance to operate on + * \param handler the callback handler function + * \param parameter user provided parameter that is passed to the callback handler + */ +LIB61850_INTERNAL void +MmsServer_installObtainFileHandler(MmsServer self, MmsObtainFileHandler handler, void* parameter); + +/** + * \brief Get file complete (obtainFile service terminated) callback handler + * + * This handler can be used to invoke some actions after a file upload is complete. + * + * \param parameter user provided parameter that is passed to the callback handler + * \param connection the connection that requested the service + * \param destinationFilename the target file name on the server side system + */ +typedef void (*MmsGetFileCompleteHandler)(void* parameter, MmsServerConnection connection, const char* destinationFilename); + +/** + * \brief Install callback handler that is invoked when the file upload (obtainFile service) is completed and the + * file has been uploaded. + * + * \param self the MmsServer instance + * \param handler the callback handler function + * \param parameter user provided parameter that is passed to the callback handler + */ +LIB61850_INTERNAL void +MmsServer_installGetFileCompleteHandler(MmsServer self, MmsGetFileCompleteHandler handler, void* parameter); + + +typedef enum { + MMS_FILE_ACCESS_TYPE_READ_DIRECTORY, + MMS_FILE_ACCESS_TYPE_OPEN, + MMS_FILE_ACCESS_TYPE_OBTAIN, + MMS_FILE_ACCESS_TYPE_DELETE, + MMS_FILE_ACCESS_TYPE_RENAME +} MmsFileServiceType; + +/** + * \brief MmsFileAccessHandler callback function. Use to monitor and control file access + * + * \param parameter user provided parameter that is passed to the callback handler + * \param connection the connection that requested the service + * \param service the requested file service + * \param localFilename the requested file or directory name at the server + * \param otherFilename a second file name parameter (e.g. source file of the ObtainFile or new file of rename file) + * + * \return MMS_ERROR_NONE when the request is accepted, otherwise use the appropriate error code (e.g. MMS_ERROR_FILE_FILE_ACCESS_DENIED) + */ +typedef MmsError (*MmsFileAccessHandler) (void* parameter, MmsServerConnection connection, MmsFileServiceType service, + const char* localFilename, const char* otherFilename); + + +/** + * \brief Install a callback handler this is invoked when the client requests a file server. This function can be + * used to monitor and control file access + * + * \param self the MmsServer instance + * \param handler the callback handler function + * \param parameter user provided parameter that is passed to the callback handler + */ +LIB61850_API void +MmsServer_installFileAccessHandler(MmsServer self, MmsFileAccessHandler handler, void* parameter); + +/** + * \brief Set the virtual filestore basepath for the MMS file services + * + * All external file service accesses will be mapped to paths relative to the base directory. + * NOTE: This function is only available when the CONFIG_SET_FILESTORE_BASEPATH_AT_RUNTIME + * option in stack_config.h is set. + * + * \param self the MmsServer instance + * \param basepath the new virtual filestore basepath + */ +LIB61850_INTERNAL void +MmsServer_setFilestoreBasepath(MmsServer self, const char* basepath); + +/** + * \brief Set the maximum number of TCP client connections + * + * \param[in] maxConnections the maximum number of TCP client connections to accept + */ +LIB61850_INTERNAL void +MmsServer_setMaxConnections(MmsServer self, int maxConnections); + +/** + * \brief Enable/disable MMS file services at runtime + * + * NOTE: requires CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME = 1 in stack configuration + * + * \param[in] self the MmsServer instance + * \param[in] enable true to enable file services, false to disable + */ +LIB61850_INTERNAL void +MmsServer_enableFileService(MmsServer self, bool enable); + +/** + * \brief Enable/disable dynamic named variable list (data set) service + * + * NOTE: requires CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME = 1 in stack configuration + * + * \param[in] self the MmsServer instance + * \param[in] enable true to enable named variable list services, false to disable + */ +LIB61850_INTERNAL void +MmsServer_enableDynamicNamedVariableListService(MmsServer self, bool enable); + +/** + * \brief Set the maximum number of association specific data sets (per connection) + * + * \param[in] self the MmsServer instance + * \param[in] maxDataSets maximum number association specific data sets + */ +LIB61850_INTERNAL void +MmsServer_setMaxAssociationSpecificDataSets(MmsServer self, int maxDataSets); + +/** + * \brief Set the maximum number of domain specific data sets + * + * \param[in] self the MmsServer instance + * \param[in] maxDataSets maximum number domain specific data sets + */ +LIB61850_INTERNAL void +MmsServer_setMaxDomainSpecificDataSets(MmsServer self, int maxDataSets); + +/** + * \brief Set the maximum number of data set entries (for dynamic data sets) + * + * \param[in] self the MmsServer instance + * \param[in] maxDataSetEntries maximum number of dynamic data set entries + */ +LIB61850_INTERNAL void +MmsServer_setMaxDataSetEntries(MmsServer self, int maxDataSetEntries); + +/** + * \brief Enable/disable journal service + * + * NOTE: requires CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME = 1 in stack configuration + * + * \param[in] self the MmsServer instance + * \param[in] enable true to enable journal service, false to disable + */ +LIB61850_INTERNAL void +MmsServer_enableJournalService(MmsServer self, bool enable); + + + + + +/*************************************************** + * Functions for MMS identify service + ***************************************************/ + +/** + * \brief set the values that the server will give as response for an MMS identify request + * + * With this function the VMD identity attributes can be set programmatically. If not set by this + * function the default values form stack_config.h are used. + * + * \param self the MmsServer instance to operate on + * \param vendorName the vendor name attribute of the VMD + * \param modelName the model name attribute of the VMD + * \param revision the revision attribute of the VMD + */ +LIB61850_INTERNAL void +MmsServer_setServerIdentity(MmsServer self, char* vendorName, char* modelName, char* revision); + +/** + * \brief get the vendor name attribute of the VMD identity + * + * \param self the MmsServer instance to operate on + * \return the vendor name attribute of the VMD as C string + */ +LIB61850_INTERNAL char* +MmsServer_getVendorName(MmsServer self); + +/** + * \brief get the model name attribute of the VMD identity + * + * \param self the MmsServer instance to operate on + * \return the model name attribute of the VMD as C string + */ +LIB61850_INTERNAL char* +MmsServer_getModelName(MmsServer self); + +/** + * \brief get the revision attribute of the VMD identity + * + * \param self the MmsServer instance to operate on + * \return the revision attribute of the VMD as C string + */ +LIB61850_INTERNAL char* +MmsServer_getRevision(MmsServer self); + +/*************************************************** + * Functions for MMS status service + ***************************************************/ + +#define MMS_LOGICAL_STATE_STATE_CHANGES_ALLOWED 0 +#define MMS_LOGICAL_STATE_NO_STATE_CHANGES_ALLOWED 1 +#define MMS_LOGICAL_STATE_LIMITED_SERVICES_PERMITTED 2 +#define MMS_LOGICAL_STATE_SUPPORT_SERVICES_ALLOWED 3 + +#define MMS_PHYSICAL_STATE_OPERATIONAL 0 +#define MMS_PHYSICAL_STATE_PARTIALLY_OPERATIONAL 1 +#define MMS_PHYSICAL_STATE_INOPERATIONAL 2 +#define MMS_PHYSICAL_STATE_NEEDS_COMMISSIONING 3 + +/** + * \brief User provided handler that is invoked on a MMS status request + * + * The extendedDerivation parameter indicates that the client requests the server to perform + * self diagnosis tests before answering the request. + * + * \param parameter is a user provided parameter + * \param mmsServer is the MmsServer instance + * \param connection is the MmsServerConnection instance that received the MMS status request + * \param extendedDerivation indicates if the request contains the extendedDerivation parameter + */ +typedef void (*MmsStatusRequestListener)(void* parameter, MmsServer mmsServer, MmsServerConnection connection, bool extendedDerivation); + +/** + * \brief set the VMD state values for the VMD status service + * + * \param self the MmsServer instance to operate on + * \param vmdLogicalStatus the logical status attribute of the VMD + * \param vmdPhysicalStatus the physical status attribute of the VMD + */ +LIB61850_INTERNAL void +MmsServer_setVMDStatus(MmsServer self, int vmdLogicalStatus, int vmdPhysicalStatus); + +/** + * \brief get the logical status attribute of the VMD + * + * \param self the MmsServer instance to operate on + */ +LIB61850_INTERNAL int +MmsServer_getVMDLogicalStatus(MmsServer self); + +/** + * \brief get the physical status attribute of the VMD + * + * \param self the MmsServer instance to operate on + */ +LIB61850_INTERNAL int +MmsServer_getVMDPhysicalStatus(MmsServer self); + +/** + * \brief set the MmsStatusRequestListener for this MmsServer + * + * With this function the API user can register a listener that is invoked whenever a + * MMS status request is received from a client. Inside of the handler the user can + * provide new status values with the MmsServer_setVMDStatus function. + * + * \param self the MmsServer instance to operate on + * \param listener the listener that is called when a MMS status request is received + * \param parameter a user provided parameter that is handed over to the listener + */ +LIB61850_INTERNAL void +MmsServer_setStatusRequestListener(MmsServer self, MmsStatusRequestListener listener, void* parameter); + +LIB61850_INTERNAL char* +MmsServerConnection_getClientAddress(MmsServerConnection self); + +LIB61850_INTERNAL char* +MmsServerConnection_getLocalAddress(MmsServerConnection self); + +LIB61850_INTERNAL void* +MmsServerConnection_getSecurityToken(MmsServerConnection self); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* MMS_SERVER_H_ */ diff --git a/product/src/fes/include/libiec61850/mms_type_spec.h b/product/src/fes/include/libiec61850/mms_type_spec.h new file mode 100644 index 00000000..2dec2bf5 --- /dev/null +++ b/product/src/fes/include/libiec61850/mms_type_spec.h @@ -0,0 +1,164 @@ +/* + * mms_type_spec.h + * + * MmsTypeSpecfication objects are used to describe simple and complex MMS types. + * Complex types are arrays or structures of simple and complex types. + * They also represent MMS NamedVariables. + * + * Copyright 2013-2019 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef MMS_TYPE_SPEC_H_ +#define MMS_TYPE_SPEC_H_ + +#include "libiec61850_common_api.h" +#include "mms_common.h" +#include "mms_types.h" +#include "linked_list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup common_api_group + */ +/**@{*/ + +/** + * \defgroup MMS_VAR_SPEC MmsVariableSpecification data type specifications + */ +/**@{*/ + +/** + * \brief Delete MmsTypeSpecification object (recursive). + * + * \param self the MmsVariableSpecification instance + */ +LIB61850_API void +MmsVariableSpecification_destroy(MmsVariableSpecification* self); + +/** + * \brief Get the corresponding child of value according to childId. + * + * This function assumes that value is the corresponding value of the MMS variable self. + * Given the relative name of a child of self this function returns the corresponding child + * of the value object. Note: the child name has to be provided in MMS mapping syntax (with + * "$" sign as separator between path name elements! + * + * \param self the MmsVariableSpecification instance + * \param value the MmsValue instance + * \param childId the relative MMS name to the child MMS variable (with "$" separators!) + * + */ +LIB61850_API MmsValue* +MmsVariableSpecification_getChildValue(MmsVariableSpecification* self, MmsValue* value, const char* childId); + +/** + * \brief Get the child of self specified by its relative name + * + * \param self the MmsVariableSpecification instance + * \param nameId the relative MMS name to the child MMS variable (with "$" separators!) + * + * \return the variable specification of the child or NULL if not existing. + */ +LIB61850_API MmsVariableSpecification* +MmsVariableSpecification_getNamedVariableRecursive(MmsVariableSpecification* self, const char* nameId); + +/** + * \brief get the MMS type of the variable + * + * \param self the MmsVariableSpecification instance + * + * \return the MMS type of the variable + */ +LIB61850_API MmsType +MmsVariableSpecification_getType(MmsVariableSpecification* self); + +/** + * \brief Check if the value has exactly the same type as this variable specfication + * + * \param self the MmsVariableSpecification instance + * \param value the value to check + * + * \return true if type is matching, false otherwise + */ +LIB61850_API bool +MmsVariableSpecification_isValueOfType(MmsVariableSpecification* self, const MmsValue* value); + +/** + * \brief get the name of the variable + * + * Note: the return string is only valid as long as the MmsVariableSpecification + * instance exists! + * + * \param self the MmsVariableSpecification instance + * + * \return the name of the variable + */ +LIB61850_API const char* +MmsVariableSpecification_getName(MmsVariableSpecification* self); + +LIB61850_API LinkedList /* */ +MmsVariableSpecification_getStructureElements(MmsVariableSpecification* self); + +/** + * \brief returns the number of elements if the type is a complex type (structure, array) or the + * bit size of integers, unsigned integers, floats, bit strings, visible and MMS strings and octet strings. + * + * + * + * \param self the MmsVariableSpecification object + * + * \return the number of elements or -1 if not applicable + */ +LIB61850_API int +MmsVariableSpecification_getSize(MmsVariableSpecification* self); + +LIB61850_API MmsVariableSpecification* +MmsVariableSpecification_getChildSpecificationByIndex(MmsVariableSpecification* self, int index); + +/** + * \brief return the MmsVariableSpecification of a structure element with the given name + * + * \param self the MmsVariableSpecification object + * \param name the name of the component (structure element) + * \param index (OUT) if not NULL the index of the structure element will be stored there + * + * \return the type specification of the component or NULL if the component was not found + */ +LIB61850_API MmsVariableSpecification* +MmsVariableSpecification_getChildSpecificationByName(MmsVariableSpecification* self, const char* name, int* index); + +LIB61850_API MmsVariableSpecification* +MmsVariableSpecification_getArrayElementSpecification(MmsVariableSpecification* self); + +LIB61850_API int +MmsVariableSpecification_getExponentWidth(MmsVariableSpecification* self); + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* MMS_TYPE_SPEC_H_ */ diff --git a/product/src/fes/include/libiec61850/mms_types.h b/product/src/fes/include/libiec61850/mms_types.h new file mode 100644 index 00000000..b2689620 --- /dev/null +++ b/product/src/fes/include/libiec61850/mms_types.h @@ -0,0 +1,81 @@ +/* + * mms_types.h + * + * Copyright 2013, 2014 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef MMS_TYPES_H_ +#define MMS_TYPES_H_ + +#include "libiec61850_common_api.h" + +typedef enum { + MMS_VALUE_NO_RESPONSE, + MMS_VALUE_OK, + MMS_VALUE_ACCESS_DENIED, + MMS_VALUE_VALUE_INVALID, + MMS_VALUE_TEMPORARILY_UNAVAILABLE, + MMS_VALUE_OBJECT_ACCESS_UNSUPPORTED +} MmsValueIndication; + +/** + * \addtogroup MMS_VAR_SPEC + */ +/**@{*/ + +/** + * Type definition for MMS Named Variables + */ +typedef struct sMmsVariableSpecification MmsVariableSpecification; + +/**@}*/ + +struct ATTRIBUTE_PACKED sMmsVariableSpecification { + MmsType type; + char* name; + union uMmsTypeSpecification + { + struct sMmsArray { + int elementCount; /* number of array elements */ + MmsVariableSpecification* elementTypeSpec; + } array; + struct sMmsStructure { + int elementCount; + MmsVariableSpecification** elements; + } structure; + int boolean; /* dummy - not required */ + int integer; /* size of integer in bits */ + int unsignedInteger; /* size of integer in bits */ + struct sMmsFloat + { + uint8_t exponentWidth; + uint8_t formatWidth; + } floatingpoint; + int bitString; /* Number of bits in bitstring */ + int octetString; /* Number of octets in octet string */ + int visibleString; /* Maximum size of string */ + int mmsString; + int utctime; /* dummy - not required */ + int binaryTime; /* size: either 4 or 6 */ + } typeSpec; +}; + + +#endif /* MMS_TYPES_H_ */ diff --git a/product/src/fes/include/libiec61850/mms_value.h b/product/src/fes/include/libiec61850/mms_value.h new file mode 100644 index 00000000..7497265d --- /dev/null +++ b/product/src/fes/include/libiec61850/mms_value.h @@ -0,0 +1,1064 @@ +/* + * mms_value.h + * + * Copyright 2013-2018 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef MMS_VALUE_H_ +#define MMS_VALUE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "libiec61850_common_api.h" +#include "mms_common.h" +#include "mms_types.h" + +/** + * \defgroup common_api_group libIEC61850 API common parts + */ +/**@{*/ + +/** + * \defgroup MMS_VALUE MmsValue data type definition and handling functions + */ +/**@{*/ + + +typedef enum { + DATA_ACCESS_ERROR_SUCCESS_NO_UPDATE = -3, + DATA_ACCESS_ERROR_NO_RESPONSE = -2, /* for server internal purposes only! */ + DATA_ACCESS_ERROR_SUCCESS = -1, + DATA_ACCESS_ERROR_OBJECT_INVALIDATED = 0, + DATA_ACCESS_ERROR_HARDWARE_FAULT = 1, + DATA_ACCESS_ERROR_TEMPORARILY_UNAVAILABLE = 2, + DATA_ACCESS_ERROR_OBJECT_ACCESS_DENIED = 3, + DATA_ACCESS_ERROR_OBJECT_UNDEFINED = 4, + DATA_ACCESS_ERROR_INVALID_ADDRESS = 5, + DATA_ACCESS_ERROR_TYPE_UNSUPPORTED = 6, + DATA_ACCESS_ERROR_TYPE_INCONSISTENT = 7, + DATA_ACCESS_ERROR_OBJECT_ATTRIBUTE_INCONSISTENT = 8, + DATA_ACCESS_ERROR_OBJECT_ACCESS_UNSUPPORTED = 9, + DATA_ACCESS_ERROR_OBJECT_NONE_EXISTENT = 10, + DATA_ACCESS_ERROR_OBJECT_VALUE_INVALID = 11, + DATA_ACCESS_ERROR_UNKNOWN = 12 +} MmsDataAccessError; + +/** + * MmsValue - complex value type for MMS Client API + */ +typedef struct sMmsValue MmsValue; + +/************************************************************************************* + * Array functions + *************************************************************************************/ + +/** + * \brief Create an Array and initialize elements with default values. + * + * \param elementType type description for the elements the new array + * \param size the size of the new array + * + * \return a newly created array instance + */ +LIB61850_API MmsValue* +MmsValue_createArray(const MmsVariableSpecification* elementType, int size); + +/** + * \brief Get the size of an array. + * + * \param self MmsValue instance to operate on. Has to be of type MMS_ARRAY. + * + * \return the size of the array + */ +LIB61850_API uint32_t +MmsValue_getArraySize(const MmsValue* self); + +/** + * \brief Get an element of an array or structure. + * + * \param self MmsValue instance to operate on. Has to be of type MMS_ARRAY or MMS_STRUCTURE. + * \param index ndex of the requested array or structure element + * + * \return the element object + */ +LIB61850_API MmsValue* +MmsValue_getElement(const MmsValue* array, int index); + +/** + * \brief Create an emtpy array. + * + * \param size the size of the new array + * + * \return a newly created empty array instance + */ +LIB61850_API MmsValue* +MmsValue_createEmptyArray(int size); + +/** + * \brief Set an element of a complex type + * + * NOTE: If the element already exists it will simply be replaced by the provided new value. + * The caller is responsible to free the replaced value. + * + * \param complexValue MmsValue instance to operate on. Has to be of a type MMS_STRUCTURE or MMS_ARRAY + * \param the index of the element to set/replace + * \param elementValue the (new) value of the element + */ +LIB61850_API void +MmsValue_setElement(MmsValue* complexValue, int index, MmsValue* elementValue); + + +/************************************************************************************* + * Basic type functions + *************************************************************************************/ + +LIB61850_API MmsDataAccessError +MmsValue_getDataAccessError(const MmsValue* self); + +/** + * \brief Get the int64_t value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_INTEGER or MMS_UNSIGNED + * + * \return signed 64 bit integer + */ +LIB61850_API int64_t +MmsValue_toInt64(const MmsValue* self); + +/** + * \brief Get the int32_t value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_INTEGER or MMS_UNSIGNED + * + * \return signed 32 bit integer + */ +LIB61850_API int32_t +MmsValue_toInt32(const MmsValue* value); + +/** + * \brief Get the uint32_t value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_INTEGER or MMS_UNSIGNED + * + * \return unsigned 32 bit integer + */ +LIB61850_API uint32_t +MmsValue_toUint32(const MmsValue* value); + +/** + * \brief Get the double value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of type MMS_FLOAT. + * + * \return 64 bit floating point value + */ +LIB61850_API double +MmsValue_toDouble(const MmsValue* self); + +/** + * \brief Get the float value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of type MMS_FLOAT. + * + * \return 32 bit floating point value + */ +LIB61850_API float +MmsValue_toFloat(const MmsValue* self); + +/** + * \brief Get the unix timestamp of a MmsValue object of type MMS_UTCTIME. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UTC_TIME. + * + * \return unix timestamp of the MMS_UTCTIME variable. + */ +LIB61850_API uint32_t +MmsValue_toUnixTimestamp(const MmsValue* self); + +/** + * \brief Set the float value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_FLOAT. + */ +LIB61850_API void +MmsValue_setFloat(MmsValue* self, float newFloatValue); + +/** + * \brief Set the double value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_FLOAT. + */ +LIB61850_API void +MmsValue_setDouble(MmsValue* self, double newFloatValue); + +/** + * \brief Set the Int8 value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_INTEGER. + * \param integer the new value to set + */ +LIB61850_API void +MmsValue_setInt8(MmsValue* value, int8_t integer); + +/** + * \brief Set the Int16 value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_INTEGER. + * \param integer the new value to set + */ +LIB61850_API void +MmsValue_setInt16(MmsValue* value, int16_t integer); + +/** + * \brief Set the Int32 value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_INTEGER. + * \param integer the new value to set + */ +LIB61850_API void +MmsValue_setInt32(MmsValue* self, int32_t integer); + +/** + * \brief Set the Int64 value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_INTEGER. + * \param integer the new value to set + */ +LIB61850_API void +MmsValue_setInt64(MmsValue* value, int64_t integer); + +/** + * \brief Set the UInt8 value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UNSIGNED. + * \param integer the new value to set + */ +LIB61850_API void +MmsValue_setUint8(MmsValue* value, uint8_t integer); + +/** + * \brief Set the UInt16 value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UNSIGNED. + * \param integer the new value to set + */ +LIB61850_API void +MmsValue_setUint16(MmsValue* value, uint16_t integer); + +/** + * \brief Set the UInt32 value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UNSIGNED. + * \param integer the new value to set + */ +LIB61850_API void +MmsValue_setUint32(MmsValue* value, uint32_t integer); + + +/** + * \brief Set the bool value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BOOLEAN. + * \param boolValue a bool value + */ +LIB61850_API void +MmsValue_setBoolean(MmsValue* value, bool boolValue); + +/** + * \brief Get the bool value of a MmsValue object. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BOOLEAN. + * \return the MmsValue value as bool value + */ +LIB61850_API bool +MmsValue_getBoolean(const MmsValue* value); + +/** + * \brief Returns the value of an MMS_VISIBLE_STRING object as C string + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_VISIBLE_STRING or MMS_STRING. + * + * \returns the string value as 0 terminated C string + */ +LIB61850_API const char* +MmsValue_toString(MmsValue* self); + +/** + * \brief Returns the (maximum) length of the string + * + * NOTE: this function return the amount of memory allocated for the string buffer - 1. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_VISIBLE_STRING or MMS_STRING. + */ +LIB61850_API int +MmsValue_getStringSize(MmsValue* self); + +LIB61850_API void +MmsValue_setVisibleString(MmsValue* self, const char* string); + + +/** + * \brief Set a single bit (set to one) of an MmsType object of type MMS_BITSTRING + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BITSTRING. + * \param bitPos the position of the bit in the bit string. Starting with 0. The bit + * with position 0 is the first bit if the MmsValue instance is serialized. + * \param value the new value of the bit (true = 1 / false = 0) + */ +LIB61850_API void +MmsValue_setBitStringBit(MmsValue* self, int bitPos, bool value); + +/** + * \brief Get the value of a single bit (set to one) of an MmsType object of type MMS_BITSTRING + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BITSTRING. + * \param bitPos the position of the bit in the bit string. Starting with 0. The bit + * with position 0 is the first bit if the MmsValue instance is serialized. + * \return the value of the bit (true = 1 / false = 0) + */ +LIB61850_API bool +MmsValue_getBitStringBit(const MmsValue* self, int bitPos); + +/** + * \brief Delete all bits (set to zero) of an MmsType object of type MMS_BITSTRING + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BITSTRING. + */ +LIB61850_API void +MmsValue_deleteAllBitStringBits(MmsValue* self); + + +/** + * \brief Get the size of a bit string in bits. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BITSTRING. + */ +LIB61850_API int +MmsValue_getBitStringSize(const MmsValue* self); + +/** + * \brief Get the number of bytes required by this bitString + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BITSTRING. + */ +LIB61850_API int +MmsValue_getBitStringByteSize(const MmsValue* self); + +/** + * \brief Count the number of set bits in a bit string. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BITSTRING. + */ +LIB61850_API int +MmsValue_getNumberOfSetBits(const MmsValue* self); + +/** + * Set all bits (set to one) of an MmsType object of type MMS_BITSTRING + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BITSTRING. + */ +LIB61850_API void +MmsValue_setAllBitStringBits(MmsValue* self); + +/** + * \brief Convert a bit string to an unsigned integer + * + * This function assumes that the first bit in the bit string is the + * least significant bit (little endian bit order). + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BITSTRING. + */ +LIB61850_API uint32_t +MmsValue_getBitStringAsInteger(const MmsValue* self); + +/** + * \brief Convert an unsigned integer to a bit string + * + * The integer representation in the bit string assumes the first bit is the + * least significant bit (little endian bit order). + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BITSTRING. + * \param intValue the integer value that is used to set the bit string + */ +LIB61850_API void +MmsValue_setBitStringFromInteger(MmsValue* self, uint32_t intValue); + +/** + * \brief Convert a bit string to an unsigned integer (big endian bit order) + * + * This function assumes that the first bit in the bit string is the + * most significant bit (big endian bit order). + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BITSTRING. + */ +LIB61850_API uint32_t +MmsValue_getBitStringAsIntegerBigEndian(const MmsValue* self); + +/** + * \brief Convert an unsigned integer to a bit string (big endian bit order) + * + * The integer representation in the bit string assumes the first bit is the + * most significant bit (big endian bit order). + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BITSTRING. + * \param intValue the integer value that is used to set the bit string + */ +LIB61850_API void +MmsValue_setBitStringFromIntegerBigEndian(MmsValue* self, uint32_t intValue); + +/** + * \brief Update an MmsValue object of UtcTime type with a timestamp in s + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BOOLEAN. + * \param timeval the new value in seconds since epoch (1970/01/01 00:00 UTC) + */ +LIB61850_API MmsValue* +MmsValue_setUtcTime(MmsValue* self, uint32_t timeval); + +/** + * \brief Update an MmsValue object of type MMS_UTCTIME with a millisecond time. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UTCTIME. + * \param timeval the new value in milliseconds since epoch (1970/01/01 00:00 UTC) + */ +LIB61850_API MmsValue* +MmsValue_setUtcTimeMs(MmsValue* self, uint64_t timeval); + +/** + * \brief Update an MmsValue object of type MMS_UTCTIME with a buffer containing a BER encoded UTCTime. + * + * The buffer must have a size of 8 bytes! + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UTCTIME. + * \param buffer buffer containing the encoded UTCTime. + */ +LIB61850_API void +MmsValue_setUtcTimeByBuffer(MmsValue* self, const uint8_t* buffer); + +/** + * \brief return the raw buffer containing the UTC time data + * + * Note: This will return the address of the raw byte buffer. The array length is 8 byte. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UTCTIME. + * + * \return the buffer containing the raw data + */ +LIB61850_API uint8_t* +MmsValue_getUtcTimeBuffer(MmsValue* self); + +/** + * \brief Get a millisecond time value from an MmsValue object of MMS_UTCTIME type. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UTCTIME. + * + * \return the value in milliseconds since epoch (1970/01/01 00:00 UTC) + */ +LIB61850_API uint64_t +MmsValue_getUtcTimeInMs(const MmsValue* value); + +/** + * \brief Get a millisecond time value and optional us part from an MmsValue object of MMS_UTCTIME type. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UTCTIME. + * \param usec a pointer to store the us (microsecond) value. + * + * \return the value in milliseconds since epoch (1970/01/01 00:00 UTC) + */ +LIB61850_API uint64_t +MmsValue_getUtcTimeInMsWithUs(const MmsValue* self, uint32_t* usec); + +/** + * \brief set the TimeQuality byte of the UtcTime + * + * Meaning of the bits in the timeQuality byte: + * + * bit 7 = leapSecondsKnown + * bit 6 = clockFailure + * bit 5 = clockNotSynchronized + * bit 0-4 = subsecond time accuracy (number of significant bits of subsecond time) + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UTCTIME. + * \param timeQuality the byte representing the time quality + */ +LIB61850_API void +MmsValue_setUtcTimeQuality(MmsValue* self, uint8_t timeQuality); + +/** + * \brief Update an MmsValue object of type MMS_UTCTIME with a millisecond time. + * + * Meaning of the bits in the timeQuality byte: + * + * bit 7 = leapSecondsKnown + * bit 6 = clockFailure + * bit 5 = clockNotSynchronized + * bit 0-4 = subsecond time accuracy (number of significant bits of subsecond time) + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UTCTIME. + * \param timeval the new value in milliseconds since epoch (1970/01/01 00:00 UTC) + * \param timeQuality the byte representing the time quality + * + * \return the updated MmsValue instance + */ +LIB61850_API MmsValue* +MmsValue_setUtcTimeMsEx(MmsValue* self, uint64_t timeval, uint8_t timeQuality); + +/** + * \brief get the TimeQuality byte of the UtcTime + * + * Meaning of the bits in the timeQuality byte: + * + * bit 7 = leapSecondsKnown + * bit 6 = clockFailure + * bit 5 = clockNotSynchronized + * bit 0-4 = subsecond time accuracy (number of significant bits of subsecond time) + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UTCTIME. + * + * \return the byte representing the time quality + */ +LIB61850_API uint8_t +MmsValue_getUtcTimeQuality(const MmsValue* self); + +/** + * \brief Update an MmsValue object of type MMS_BINARYTIME with a millisecond time. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_UTCTIME. + * \param timeval the new value in milliseconds since epoch (1970/01/01 00:00 UTC) + */ +LIB61850_API void +MmsValue_setBinaryTime(MmsValue* self, uint64_t timestamp); + +/** + * \brief Get a millisecond time value from an MmsValue object of type MMS_BINARYTIME. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_BINARYTIME. + * + * \return the value in milliseconds since epoch (1970/01/01 00:00 UTC) + */ +LIB61850_API uint64_t +MmsValue_getBinaryTimeAsUtcMs(const MmsValue* self); + +/** + * \brief Set the value of an MmsValue object of type MMS_OCTET_STRING. + * + * This method will copy the provided buffer to the internal buffer of the + * MmsValue instance. This will only happen if the internal buffer size is large + * enough for the new value. Otherwise the object value is not changed. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_OCTET_STRING. + * \param buf the buffer that contains the new value + * \param size the size of the buffer that contains the new value + */ +LIB61850_API void +MmsValue_setOctetString(MmsValue* self, const uint8_t* buf, int size); + +/** + * \brief Set a single octet of an MmsValue object of type MMS_OCTET_STRING. + * + * This method will copy the provided octet to the internal buffer of the + * MmsValue instance, at the 'octetPos' position. This will only happen + * if the internal buffer size is large enough. Otherwise the object value is not changed. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_OCTET_STRING. + * \param octetPos the position of the octet in the octet string. Starting with 0. + * The octet with position 0 is the first octet if the MmsValue instance is serialized. + * \param value the new value of the octet (0 to 255, or 0x00 to 0xFF) + */ +LIB61850_API void +MmsValue_setOctetStringOctet(MmsValue* self, int octetPos, uint8_t value); + +/** + * \brief Returns the size in bytes of an MmsValue object of type MMS_OCTET_STRING. + * + * NOTE: To access the byte in the buffer the function \ref MmsValue_getOctetStringBuffer + * has to be used. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_OCTET_STRING. + * + * \return size in bytes + */ +LIB61850_API uint16_t +MmsValue_getOctetStringSize(const MmsValue* self); + +/** + * \brief Returns the maximum size in bytes of an MmsValue object of type MMS_OCTET_STRING. + * + * Returns the maximum size if bytes of the MmsValue object of type MMS_OCTET_STRING. This + * is the size of the internally allocated buffer to hold the octet string data. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_OCTET_STRING. + * + * \return maximum size in bytes + */ +LIB61850_API uint16_t +MmsValue_getOctetStringMaxSize(MmsValue* self); + +/** + * \brief Returns the reference to the internally hold buffer of an MmsValue object of type MMS_OCTET_STRING. + * + * NOTE: The size of the buffer can be requested with the \ref MmsValue_getOctetStringSize function. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_OCTET_STRING. + * + * \return reference to the buffer + */ +LIB61850_API uint8_t* +MmsValue_getOctetStringBuffer(MmsValue* self); + +/** + * \brief Get the value of a single octet of an MmsType object of type MMS_OCTET_STRING + * + * NOTE: The octet quantity of the octet string can be requested with + * the \ref MmsValue_getOctetStringSize function. + * + * \param self MmsValue instance to operate on. Has to be of a type MMS_OCTET_STRING. + * \param octetPos the position of the octet in the octet string. Starting with 0. The octet + * with position 0 is the first octet if the MmsValue instance is serialized. + * \return the value of the octet (0 to 255, or 0x00 to 0xFF) + */ +LIB61850_API uint8_t +MmsValue_getOctetStringOctet(MmsValue* self, int octetPos); + +/** + * \brief Update the value of an MmsValue instance by the value of another MmsValue instance. + * + * Both instances should be of same time. E.g. is self is of type MMS_INTEGER then + * source has also to be of type MMS_INTEGER. Otherwise the call will have no effect. + * + * \param self MmsValue instance to operate on. + * \param source MmsValue used as source for the update. Has to be of same type as self + * + * \return indicates if the update has been successful (false if not) + */ +LIB61850_API bool +MmsValue_update(MmsValue* self, const MmsValue* source); + +/** + * \brief Check if two instances of MmsValue have the same value. + * + * Both instances should be of same type. E.g. is self is of type MMS_INTEGER then + * source has also to be of type MMS_INTEGER. Otherwise the call will return false. + * + * \param self MmsValue instance to operate on. + * \param otherValue MmsValue that is used to test + * + * \return true if both instances are of the same type and have the same value + */ +LIB61850_API bool +MmsValue_equals(const MmsValue* self, const MmsValue* otherValue); + +/** + * \brief Check if two (complex) instances of MmsValue have the same type. + * + * This function will test if the two values are of the same type. The function + * will return true only if all child instances in the MmsValue instance tree are + * also of equal type. + * + * \param self MmsValue instance to operate on. + * \param otherValue MmsValue that is used to test + * + * \return true if both instances and all their children are of the same type. + */ +LIB61850_API bool +MmsValue_equalTypes(const MmsValue* self, const MmsValue* otherValue); + +/************************************************************************************* + * Constructors and destructors + *************************************************************************************/ + + +LIB61850_API MmsValue* +MmsValue_newDataAccessError(MmsDataAccessError accessError); + +LIB61850_API MmsValue* +MmsValue_newInteger(int size); + +LIB61850_API MmsValue* +MmsValue_newUnsigned(int size); + +LIB61850_API MmsValue* +MmsValue_newBoolean(bool boolean); + +/** + * \brief Create a new MmsValue instance of type MMS_BITSTRING. + * + * \param bitSize the size of the bit string in bit + * + * \return new MmsValue instance of type MMS_BITSTRING + */ +LIB61850_API MmsValue* +MmsValue_newBitString(int bitSize); + +LIB61850_API MmsValue* +MmsValue_resizeBitString(MmsValue* self, int bitSize); + +LIB61850_API MmsValue* +MmsValue_newOctetString(int size, int maxSize); + +LIB61850_API MmsValue* +MmsValue_newStructure(const MmsVariableSpecification* typeSpec); + +LIB61850_API MmsValue* +MmsValue_createEmptyStructure(int size); + +LIB61850_API MmsValue* +MmsValue_newDefaultValue(const MmsVariableSpecification* typeSpec); + +LIB61850_API MmsValue* +MmsValue_newIntegerFromInt8(int8_t integer); + +LIB61850_API MmsValue* +MmsValue_newIntegerFromInt16(int16_t integer); + +LIB61850_API MmsValue* +MmsValue_newIntegerFromInt32(int32_t integer); + +LIB61850_API MmsValue* +MmsValue_newIntegerFromInt64(int64_t integer); + +LIB61850_API MmsValue* +MmsValue_newUnsignedFromUint32(uint32_t integer); + +/** + * \brief Create a new 32 bit wide float variable and initialize with value + * + * \param value the initial value + * + * \return new MmsValue instance of type MMS_FLOAT + */ +LIB61850_API MmsValue* +MmsValue_newFloat(float value); + +/** + * \brief Create a new 64 bit wide float variable and initialize with value + * + * \param value the initial value + * + * \return new MmsValue instance of type MMS_FLOAT + */ +LIB61850_API MmsValue* +MmsValue_newDouble(double value); + +/** + * \brief Create a (deep) copy of an MmsValue instance + * + * This operation will allocate dynamic memory. It is up to the caller to + * free this memory by calling MmsValue_delete() later. + * + * \param self the MmsValue instance that will be cloned + * + * \return an MmsValue instance that is an exact copy of the given instance. + */ +LIB61850_API MmsValue* +MmsValue_clone(const MmsValue* self); + +/** + * \brief Create a (deep) copy of an MmsValue instance in a user provided buffer + * + * This operation copies the give MmsValue instance to a user provided buffer. + * + * \param self the MmsValue instance that will be cloned + * \param destinationAddress the start address of the user provided buffer + * + * \return a pointer to the position in the buffer just after the last byte written. + */ +LIB61850_API uint8_t* +MmsValue_cloneToBuffer(const MmsValue* self, uint8_t* destinationAddress); + +/** + * \brief Determine the required amount of bytes by a clone. + * + * This function is intended to be used to determine the buffer size of a clone operation + * (MmsValue_cloneToBuffer) in advance. + * + * \param self the MmsValue instance + * + * \return the number of bytes required by a clone + */ +LIB61850_API int +MmsValue_getSizeInMemory(const MmsValue* self); + +/** + * \brief Delete an MmsValue instance. + * + * This operation frees all dynamically allocated memory of the MmsValue instance. + * If the instance is of type MMS_STRUCTURE or MMS_ARRAY all child elements will + * be deleted too. + * + * \param self the MmsValue instance to be deleted. + */ +LIB61850_API void +MmsValue_delete(MmsValue* self); + +/** + * \brief Delete an MmsValue instance. + * + * This operation frees all dynamically allocated memory of the MmsValue instance. + * If the instance is of type MMS_STRUCTURE or MMS_ARRAY all child elements will + * be deleted too. + * + * NOTE: this functions only frees the instance if deleteValue field = 0! + * + * + * \param self the MmsValue instance to be deleted. + */ +LIB61850_API void +MmsValue_deleteConditional(MmsValue* value); + +/** + * \brief Create a new MmsValue instance of type MMS_VISIBLE_STRING. + * + * This function will allocate as much memory as required to hold the string and sets the maximum size of + * the string to this size. + * + * \param string a text string that should be the value of the new instance of NULL for an empty string. + * + * \return new MmsValue instance of type MMS_VISIBLE_STRING + */ +LIB61850_API MmsValue* +MmsValue_newVisibleString(const char* string); + +/** + * \brief Create a new MmsValue instance of type MMS_VISIBLE_STRING. + * + * This function will create a new empty MmsValue string object. The maximum size of the string is set + * according to the size parameter. The function allocates as much memory as is required to hold a string + * of the maximum size. + * + * \param size the new maximum size of the string. + * + * \return new MmsValue instance of type MMS_VISIBLE_STRING + */ +LIB61850_API MmsValue* +MmsValue_newVisibleStringWithSize(int size); + +/** + * \brief Create a new MmsValue instance of type MMS_STRING. + * + * This function will create a new empty MmsValue string object. The maximum size of the string is set + * according to the size parameter. The function allocates as much memory as is required to hold a string + * of the maximum size. + * + * \param size the new maximum size of the string. + * + * \return new MmsValue instance of type MMS_STRING + */ +LIB61850_API MmsValue* +MmsValue_newMmsStringWithSize(int size); + +/** + * \brief Create a new MmsValue instance of type MMS_BINARYTIME. + * + * If the timeOfDay parameter is set to true then the resulting + * MMS_BINARYTIME object is only 4 octets long and includes only + * the seconds since midnight. Otherwise the MMS_BINARYTIME + * + * \param timeOfDay if true only the TimeOfDay value is included. + * + * \return new MmsValue instance of type MMS_BINARYTIME + */ +LIB61850_API MmsValue* +MmsValue_newBinaryTime(bool timeOfDay); + +/** + * \brief Create a new MmsValue instance of type MMS_VISIBLE_STRING from the specified byte array + * + * \param byteArray the byte array containing the string data + * \param size the size of the byte array + * + * \return new MmsValue instance of type MMS_VISIBLE_STRING + */ +LIB61850_API MmsValue* +MmsValue_newVisibleStringFromByteArray(const uint8_t* byteArray, int size); + +/** + * \brief Create a new MmsValue instance of type MMS_STRING from the specified byte array + * + * \param byteArray the byte array containing the string data + * \param size the size of the byte array + * + * \return new MmsValue instance of type MMS_STRING + */ +LIB61850_API MmsValue* +MmsValue_newMmsStringFromByteArray(const uint8_t* byteArray, int size); + +/** + * \brief Create a new MmsValue instance of type MMS_STRING. + * + * \param string a text string that should be the value of the new instance of NULL for an empty string. + * + * \return new MmsValue instance of type MMS_STRING + */ +LIB61850_API MmsValue* +MmsValue_newMmsString(const char* string); + +/** + * \brief Set the value of MmsValue instance of type MMS_STRING + * + * \param string a text string that will be the new value of the instance + */ +LIB61850_API void +MmsValue_setMmsString(MmsValue* value, const char* string); + +/** + * \brief Create a new MmsValue instance of type MMS_UTCTIME. + * + * \param timeval time value as UNIX timestamp (seconds since epoch) + * + * \return new MmsValue instance of type MMS_UTCTIME + */ +LIB61850_API MmsValue* +MmsValue_newUtcTime(uint32_t timeval); + +/** + * \brief Create a new MmsValue instance of type MMS_UTCTIME. + * + * \param timeval time value as millisecond timestamp (milliseconds since epoch) + * + * \return new MmsValue instance of type MMS_UTCTIME + */ +LIB61850_API MmsValue* +MmsValue_newUtcTimeByMsTime(uint64_t timeval); + + +LIB61850_API void +MmsValue_setDeletable(MmsValue* self); + +LIB61850_API void +MmsValue_setDeletableRecursive(MmsValue* value); + +/** + * \brief Check if the MmsValue instance has the deletable flag set. + * + * The deletable flag indicates if an libiec61850 API client should call the + * MmsValue_delete() method or not if the MmsValue instance was passed to the + * client by an API call or callback method. + * + * \param self the MmsValue instance + * + * \return 1 if deletable flag is set, otherwise 0 + */ +LIB61850_API int +MmsValue_isDeletable(MmsValue* self); + +/** + * \brief Get the MmsType of an MmsValue instance + * + * \param self the MmsValue instance + */ +LIB61850_API MmsType +MmsValue_getType(const MmsValue* self); + +/** + * \brief Get a sub-element of a MMS_STRUCTURE value specified by a path name. + * + * \param self the MmsValue instance + * \param varSpec - type specification if the MMS_STRUCTURE value + * \param mmsPath - path (in MMS variable name syntax) to specify the sub element. + * + * \return the sub elements MmsValue instance or NULL if the element does not exist + */ +LIB61850_API MmsValue* +MmsValue_getSubElement(MmsValue* self, MmsVariableSpecification* varSpec, char* mmsPath); + +/** + * \brief return the value type as a human readable string + * + * \param self the MmsValue instance + * + * \return the value type as a human readable string + */ +LIB61850_API char* +MmsValue_getTypeString(MmsValue* self); + +/** + * \brief create a string representation of the MmsValue object in the provided buffer + * + * NOTE: This function is for debugging purposes only. It may not be aimed to be used + * in embedded systems. It requires a full featured snprintf function. + * + * \param self the MmsValue instance + * \param buffer the buffer where to copy the string representation + * \param bufferSize the size of the provided buffer + * + * \return a pointer to the start of the buffer + */ +LIB61850_API const char* +MmsValue_printToBuffer(const MmsValue* self, char* buffer, int bufferSize); + +/** + * \brief create a new MmsValue instance from a BER encoded MMS Data element (deserialize) + * + * WARNING: API changed with version 1.0.3 (added endBufPos parameter) + * + * \param buffer the buffer to read from + * \param bufPos the start position of the mms value data in the buffer + * \param bufferLength the length of the buffer + * \param endBufPos the position in the buffer after the read MMS data element (NULL if not required) + * + * \return the MmsValue instance created from the buffer + */ +LIB61850_API MmsValue* +MmsValue_decodeMmsData(uint8_t* buffer, int bufPos, int bufferLength, int* endBufPos); + +/** + * \brief Serialize the MmsValue instance as BER encoded MMS Data element + * + * \param self the MmsValue instance + * + * \param buffer the buffer to encode the MMS data element + * \param bufPos the position in the buffer where to start encoding + * \param encode encode to buffer (true) or calculate length only (false) + * + * \return the encoded length of the corresponding MMS data element + */ +LIB61850_API int +MmsValue_encodeMmsData(MmsValue* self, uint8_t* buffer, int bufPos, bool encode); + +/** + * \brief Get the maximum possible BER encoded size of the MMS data element + * + * \param self the MmsValue instance + * + * \return the maximum encoded size in bytes of the MMS data element + */ +LIB61850_API int +MmsValue_getMaxEncodedSize(MmsValue* self); + +/** + * \brief Calculate the maximum encoded size of a variable of this type + * + * \param self the MMS variable specification instance + */ +LIB61850_API int +MmsVariableSpecification_getMaxEncodedSize(MmsVariableSpecification* self); + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* MMS_VALUE_H_ */ diff --git a/product/src/fes/include/libiec61850/sv_publisher.h b/product/src/fes/include/libiec61850/sv_publisher.h new file mode 100644 index 00000000..f753dc5d --- /dev/null +++ b/product/src/fes/include/libiec61850/sv_publisher.h @@ -0,0 +1,498 @@ +/* + * sv_publisher.h + * + * Copyright 2016-2018 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + + +#ifndef LIBIEC61850_SRC_SAMPLED_VALUES_SV_PUBLISHER_H_ +#define LIBIEC61850_SRC_SAMPLED_VALUES_SV_PUBLISHER_H_ + +#include "iec61850_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GOOSE_SV_COMM_PARAMETERS +#define GOOSE_SV_COMM_PARAMETERS + +typedef struct sCommParameters { + uint8_t vlanPriority; + uint16_t vlanId; + uint16_t appId; + uint8_t dstAddress[6]; +} CommParameters; + +#endif + +/** + * \defgroup sv_publisher_api_group IEC 61850 Sampled Values (SV) publisher API + */ +/**@{*/ + +#define IEC61850_SV_SMPSYNC_NOT_SYNCHRONIZED 0 +#define IEC61850_SV_SMPSYNC_SYNCED_UNSPEC_LOCAL_CLOCK 1 +#define IEC61850_SV_SMPSYNC_SYNCED_GLOBAL_CLOCK 2 + +#define IEC61850_SV_SMPMOD_PER_NOMINAL_PERIOD 0 +#define IEC61850_SV_SMPMOD_SAMPLES_PER_SECOND 1 +#define IEC61850_SV_SMPMOD_SECONDS_PER_SAMPLE 2 + +/** + * \brief An opaque type representing an IEC 61850-9-2 Sampled Values publisher. + */ +typedef struct sSVPublisher* SVPublisher; + +/** + * \brief An opaque type representing an IEC 61850-9-2 Sampled Values Application Service Data Unit (ASDU). + */ +typedef struct sSVPublisher_ASDU* SVPublisher_ASDU; + +/** + * \brief Create a new IEC61850-9-2 Sampled Values publisher. + * + * NOTE: VLAN tagging is enabled when calling this constructor. To disable VLAN tagging + * use \ref SVPublisher_createEx instead. + * + * \param[in] interfaceId the name of the interface over which the SV publisher should send SV packets. + * \param[in] parameters optional parameters for setting VLAN options and destination MAC address. Use NULL for default values. + * \return the new SV publisher instance. + */ +LIB61850_API SVPublisher +SVPublisher_create(CommParameters* parameters, const char* interfaceId); + +/** + * \brief Create a new IEC61850-9-2 Sampled Values publisher. + * + * \param[in] interfaceId the name of the interface over which the SV publisher should send SV packets. + * \param[in] parameters optional parameters for setting VLAN options and destination MAC address. Use NULL for default values. + * \param[in] useVlanTags enable(true)/disable(false) VLAN tagging + * \return the new SV publisher instance. + */ +LIB61850_API SVPublisher +SVPublisher_createEx(CommParameters* parameters, const char* interfaceId, bool useVlanTag); + +/** + * \brief Create an Application Service Data Unit (ASDU) and add it to an existing Sampled Values publisher. + * + * \param[in] svID + * \param[in] datset + * \param[in] confRev Configuration revision number. Should be incremented each time that the configuration of the logical device changes. + * \return the new ASDU instance. + */ +LIB61850_API SVPublisher_ASDU +SVPublisher_addASDU(SVPublisher self, const char* svID, const char* datset, uint32_t confRev); + +/** + * \brief Prepare the publisher for publishing. + * + * This method must be called before SVPublisher_publish(). + * + * \param[in] self the Sampled Values publisher instance. + */ +LIB61850_API void +SVPublisher_setupComplete(SVPublisher self); + +/** + * \brief Publish all registered ASDUs + * + * \param[in] self the Sampled Values publisher instance. + */ +LIB61850_API void +SVPublisher_publish(SVPublisher self); + +/** + * \brief Destroy an IEC61850-9-2 Sampled Values instance. + * + * \param[in] self the Sampled Values publisher instance. + */ +LIB61850_API void +SVPublisher_destroy(SVPublisher self); + +/** + * \addtogroup sv_publisher_asdu_group Values Application Service Data Unit (ASDU) + * @{ + */ + +/** + * \brief Reset the internal data buffer of an ASDU. + * + * All data elements added by SVPublisher_ASDU_add*() functions are removed. + * SVPublisher_setupComplete() must be called afterwards. + * + * \param[in] self the Sampled Values ASDU instance. + */ +LIB61850_API void +SVPublisher_ASDU_resetBuffer(SVPublisher_ASDU self); + +/** + * \brief Reserve memory for a signed 8-bit integer in the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \return the offset in bytes within the ASDU data block. + */ +LIB61850_API int +SVPublisher_ASDU_addINT8(SVPublisher_ASDU self); + +/** + * \brief Set the value of a 8-bit integer in the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] index The offset within the data block of the ASDU in bytes. + * \param[in] value The value which should be set. + */ +LIB61850_API void +SVPublisher_ASDU_setINT8(SVPublisher_ASDU self, int index, int8_t value); + +/** + * \brief Reserve memory for a signed 32-bit integer in the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \return the offset in bytes within the ASDU data block. + */ +LIB61850_API int +SVPublisher_ASDU_addINT32(SVPublisher_ASDU self); + +/** + * \brief Set the value of a 32-bit integer in the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] index The offset within the data block of the ASDU in bytes. + * \param[in] value The value which should be set. + */ +LIB61850_API void +SVPublisher_ASDU_setINT32(SVPublisher_ASDU self, int index, int32_t value); + +/** + * \brief Reserve memory for a signed 64-bit integer in the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \return the offset in bytes of the new element within the ASDU data block. + */ +LIB61850_API int +SVPublisher_ASDU_addINT64(SVPublisher_ASDU self); + +/** + * \brief Set the value of a 64-bit integer in the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] index The offset within the data block of the ASDU in bytes. + * \param[in] value The value which should be set. + */ +LIB61850_API void +SVPublisher_ASDU_setINT64(SVPublisher_ASDU self, int index, int64_t value); + +/** + * \brief Reserve memory for a single precision floating point number in the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \return the offset in bytes of the new element within the ASDU data block. + */ +LIB61850_API int +SVPublisher_ASDU_addFLOAT(SVPublisher_ASDU self); + +/** + * \brief Set the value of a single precision floating point number in the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] index The offset within the data block of the ASDU in bytes. + * \param[in] value The value which should be set. + */ +LIB61850_API void +SVPublisher_ASDU_setFLOAT(SVPublisher_ASDU self, int index, float value); + +/** + * \brief Reserve memory for a double precision floating point number in the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \return the offset in bytes of the new element within the ASDU data block. + */ +LIB61850_API int +SVPublisher_ASDU_addFLOAT64(SVPublisher_ASDU self); + +/** + * \brief Set the value of a double precision floating pointer number in the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] index The offset within the data block of the ASDU in bytes. + * \param[in] value The value which should be set. + */ +LIB61850_API void +SVPublisher_ASDU_setFLOAT64(SVPublisher_ASDU self, int index, double value); + +/** + * \brief Reserve memory for a 64 bit time stamp in the ASDU + * + * \param[in] self the Sampled Values ASDU instance. + * \return the offset in bytes of the new element within the ASDU data block. + */ +LIB61850_API int +SVPublisher_ASDU_addTimestamp(SVPublisher_ASDU self); + +/** + * \brief Set the value of a 64 bit time stamp in the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] index The offset within the data block of the ASDU in bytes. + * \param[in] value The value which should be set. + */ +LIB61850_API void +SVPublisher_ASDU_setTimestamp(SVPublisher_ASDU self, int index, Timestamp value); + +/** + * \brief Reserve memory for a quality value in the ASDU + * + * NOTE: Quality is encoded as BITSTRING (4 byte) + * + * \param[in] self the Sampled Values ASDU instance. + * \return the offset in bytes of the new element within the ASDU data block. + */ +LIB61850_API int +SVPublisher_ASDU_addQuality(SVPublisher_ASDU self); + +/** + * \brief Set the value of a quality attribute in the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] index The offset within the data block of the ASDU in bytes. + * \param[in] value The value which should be set. + */ +LIB61850_API void +SVPublisher_ASDU_setQuality(SVPublisher_ASDU self, int index, Quality value); + +/** + * \brief Set the sample count attribute of the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] value the new value of the attribute. + */ +LIB61850_API void +SVPublisher_ASDU_setSmpCnt(SVPublisher_ASDU self, uint16_t value); + +/** + * \brief Get the sample count attribute of the ASDU. + * + * \param[in] self the Sampled Values ASDU instance. + */ +LIB61850_API uint16_t +SVPublisher_ASDU_getSmpCnt(SVPublisher_ASDU self); + +/** + * \brief Increment the sample count attribute of the ASDU. + * + * The parameter SmpCnt shall contain the values of a counter, which is incremented each time a new sample of the analogue value is taken. + * The sample values shall be kept in the right order. + * If the counter is used to indicate time consistency of various sampled values, the counter shall be reset by an external synchronization event. + * + * \param[in] self the Sampled Values ASDU instance. + */ +LIB61850_API void +SVPublisher_ASDU_increaseSmpCnt(SVPublisher_ASDU self); + +/** + * \brief Set the roll-over (wrap) limit for the sample counter. When reaching the limit the + * sample counter will be reset to 0 (default is no limit) + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] value the new sample counter limit + */ +LIB61850_API void +SVPublisher_ASDU_setSmpCntWrap(SVPublisher_ASDU self, uint16_t value); + +/** + * \brief Enables the transmission of refresh time attribute of the ASDU + * + * The refresh time is the time when the data in put into the sampled values buffer + * + * \param[in] self the Sampled Values ASDU instance. + */ +LIB61850_API void +SVPublisher_ASDU_enableRefrTm(SVPublisher_ASDU self); + +/** + * \brief Set the refresh time attribute of the ASDU with nanosecond resolution + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] refrTmNs the refresh time value with nanoseconds resolution. + */ +LIB61850_API void +SVPublisher_ASDU_setRefrTmNs(SVPublisher_ASDU self, nsSinceEpoch refrTmNs); + +/** + * \brief Set the refresh time attribute of the ASDU with millisecond resolution + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] refrTmNs the refresh time value with with milliseconds resolution. + */ +LIB61850_API void +SVPublisher_ASDU_setRefrTm(SVPublisher_ASDU self, msSinceEpoch refrTm); + +/** + * \brief Set the refresh time attribute of the ASDU + * + * NOTE: Using this function you can control the time quality flags and the + * sub second precision (number of valid bits) of the RefrTm value. + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] refrTm the refresh time value + */ +LIB61850_API void +SVPublisher_ASDU_setRefrTmByTimestamp(SVPublisher_ASDU self, Timestamp* refrTm); + +/** + * \brief Set the sample mode attribute of the ASDU. + * + * The attribute SmpMod shall specify if the sample rate is defined in units of samples per nominal period, samples per second or seconds per sample. + * If it is missing, the default value is samples per period. + * + * NOTE: Function has to be called before calling \ref SVPublisher_setupComplete + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] smpMod one of IEC61850_SV_SMPMOD_PER_NOMINAL_PERIOD, IEC61850_SV_SMPMOD_SAMPLES_PER_SECOND or IEC61850_SV_SMPMOD_SECONDS_PER_SAMPLE + */ +LIB61850_API void +SVPublisher_ASDU_setSmpMod(SVPublisher_ASDU self, uint8_t smpMod); + +/** + * \brief Set the sample rate attribute of the ASDU. + * + * The attribute SmpRate shall specify the sample rate. + * The value shall be interpreted depending on the value of the SmpMod attribute. + * + * NOTE: Function has to be called before calling \ref SVPublisher_setupComplete + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] smpRate Amount of samples (default per nominal period, see SmpMod). + */ +LIB61850_API void +SVPublisher_ASDU_setSmpRate(SVPublisher_ASDU self, uint16_t smpRate); + +/** + * \brief Set the clock synchronization information + * + * Default value is not synchronized (0). + * Possible values are: + * 0 = SV are not synchronized by an external clock signal. + * 1 = SV are synchronized by a clock signal from an unspecified local area clock. + * 2 = SV are synchronized by a global area clock signal (time traceable). + * 5 to 254 = SV are synchronized by a clock signal from a local area clock identified by this value. + * 3;4;255 = Reserved values – Do not use. + * + * \param[in] self the Sampled Values ASDU instance. + * \param[in] smpSynch the clock synchronization state + */ +LIB61850_API void +SVPublisher_ASDU_setSmpSynch(SVPublisher_ASDU self, uint16_t smpSynch); + +/**@} @}*/ + +#ifndef DEPRECATED +#if defined(__GNUC__) || defined(__clang__) + #define DEPRECATED __attribute__((deprecated)) +#else + #define DEPRECATED +#endif +#endif + +/** + * \addtogroup sv_publisher_deprecated_api_group Deprecated API + * \ingroup sv_publisher_api_group IEC 61850 Sampled Values (SV) publisher API + * \deprecated + * @{ + */ + +typedef struct sSVPublisher* SampledValuesPublisher; + +typedef struct sSV_ASDU* SV_ASDU; + +LIB61850_API DEPRECATED SVPublisher +SampledValuesPublisher_create(CommParameters* parameters, const char* interfaceId); + +LIB61850_API DEPRECATED SVPublisher_ASDU +SampledValuesPublisher_addASDU(SVPublisher self, char* svID, char* datset, uint32_t confRev); + +LIB61850_API DEPRECATED void +SampledValuesPublisher_setupComplete(SVPublisher self); + +LIB61850_API DEPRECATED void +SampledValuesPublisher_publish(SVPublisher self); + +LIB61850_API DEPRECATED void +SampledValuesPublisher_destroy(SVPublisher self); + +LIB61850_API DEPRECATED void +SV_ASDU_resetBuffer(SVPublisher_ASDU self); + +LIB61850_API DEPRECATED int +SV_ASDU_addINT8(SVPublisher_ASDU self); + +LIB61850_API DEPRECATED void +SV_ASDU_setINT8(SVPublisher_ASDU self, int index, int8_t value); + +LIB61850_API DEPRECATED int +SV_ASDU_addINT32(SVPublisher_ASDU self); + +LIB61850_API DEPRECATED void +SV_ASDU_setINT32(SVPublisher_ASDU self, int index, int32_t value); + +LIB61850_API DEPRECATED int +SV_ASDU_addINT64(SVPublisher_ASDU self); + +LIB61850_API DEPRECATED void +SV_ASDU_setINT64(SVPublisher_ASDU self, int index, int64_t value); + +LIB61850_API DEPRECATED int +SV_ASDU_addFLOAT(SVPublisher_ASDU self); + +LIB61850_API DEPRECATED void +SV_ASDU_setFLOAT(SVPublisher_ASDU self, int index, float value); + +LIB61850_API DEPRECATED int +SV_ASDU_addFLOAT64(SVPublisher_ASDU self); + +LIB61850_API DEPRECATED void +SV_ASDU_setFLOAT64(SVPublisher_ASDU self, int index, double value); + +LIB61850_API DEPRECATED void +SV_ASDU_setSmpCnt(SVPublisher_ASDU self, uint16_t value); + +LIB61850_API DEPRECATED uint16_t +SV_ASDU_getSmpCnt(SVPublisher_ASDU self); + +LIB61850_API DEPRECATED void +SV_ASDU_increaseSmpCnt(SVPublisher_ASDU self); + +LIB61850_API DEPRECATED void +SV_ASDU_setRefrTm(SVPublisher_ASDU self, uint64_t refrTm); + +LIB61850_API DEPRECATED void +SV_ASDU_setSmpMod(SVPublisher_ASDU self, uint8_t smpMod); + +LIB61850_API DEPRECATED void +SV_ASDU_setSmpRate(SVPublisher_ASDU self, uint16_t smpRate); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* LIBIEC61850_SRC_SAMPLED_VALUES_SV_PUBLISHER_H_ */ diff --git a/product/src/fes/include/libiec61850/sv_subscriber.h b/product/src/fes/include/libiec61850/sv_subscriber.h new file mode 100644 index 00000000..5c0b6905 --- /dev/null +++ b/product/src/fes/include/libiec61850/sv_subscriber.h @@ -0,0 +1,623 @@ +/* + * sv_subscriber.h + * + * Copyright 2015-2018 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#ifndef SAMPLED_VALUES_SV_SUBSCRIBER_H_ +#define SAMPLED_VALUES_SV_SUBSCRIBER_H_ + +#include "libiec61850_common_api.h" +#include "iec61850_common.h" +#include "hal_ethernet.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup sv_subscriber_api_group IEC 61850 Sampled Values (SV) subscriber API + * + * The sampled values (SV) subscriber API consists of three different objects. + * The \ref SVReceiver object is responsible for handling all SV Ethernet messages + * for a specific Ethernet interface. If you want to receive SV messages on multiple + * Ethernet interfaces you have to use several \ref SVReceiver instances. + * An \ref SVSubscriber object is associated to a SV data stream that is identified by its appID + * and destination Ethernet address. The \reg SVSubscriber object is used to install a callback + * handler \ref SVUpdateListener that is invoked for each ASDU (application service data unit) received for the + * associated stream. An \ref SVSubscriber_ASDU is an object that represents a single ASDU. Each ASDU contains + * some meta information that can be obtained by specific access functions like e.g. + * \ref SVSubscriber_ASDU_getSmpCnt to access the "SmpCnt" (sample count) attribute of the ASDU. The actual + * measurement data contained in the ASDU does not consist of structured ASN.1 data but stored as raw binary + * data. Without a priori knowledge of the dataset associated with the ASDU data stream it is not + * possible to interpret the received data correctly. Therefore you have to provide the data access functions + * with an index value to indicate the data type and the start of the data in the data block of the ASDU. + * E.g. reading a data set consisting of two FLOAT32 values you can use two subsequent calls of + * \ref SVSubscriber_ASDU_getFLOAT32 one with index = 0 and the second one with index = 4. + * + * | IEC 61850 type | required bytes | + * | -------------- | -------------- | + * | BOOLEAN | 1 byte | + * | INT8 | 1 byte | + * | INT16 | 2 byte | + * | INT32 | 4 byte | + * | INT64 | 8 byte | + * | INT8U | 1 byte | + * | INT16U | 2 byte | + * | INT24U | 3 byte | + * | INT32U | 4 byte | + * | INT64U | 8 byte | + * | FLOAT32 | 4 byte | + * | FLOAT64 | 8 byte | + * | ENUMERATED | 4 byte | + * | CODED ENUM | 4 byte | + * | OCTET STRING | 20 byte | + * | VISIBLE STRING | 35 byte | + * | TimeStamp | 8 byte | + * | EntryTime | 6 byte | + * | BITSTRING | 4 byte | + * | Quality | 4 byte | + * + * The SV subscriber API can be used independent of the IEC 61850 client API. In order to access the SVCB via MMS you + * have to use the IEC 61850 client API. Please see \ref ClientSVControlBlock object in section \ref IEC61850_CLIENT_SV. + * + */ +/**@{*/ + + +/** + * \brief opaque handle to a SV ASDU (Application service data unit) instance. + * + * Sampled Values (SV) ASDUs (application service data units) are the basic units for + * sampled value data. Each ASDU represents a single sample consisting of multiple measurement + * values with a single dedicated timestamp. + * + * NOTE: SVSubscriber_ASDU are statically allocated and are only valid inside of the SVUpdateListener + * function when called by the library. If you need the data contained in the ASDU elsewhere + * you have to copy and store the data by yourself! + */ +typedef struct sSVSubscriber_ASDU* SVSubscriber_ASDU; + +/** + * \brief opaque handle to a SV subscriber instance + * + * A subscriber is an instance associated with a single stream of measurement data. It is identified + * by the Ethernet destination address, the appID value (both are on SV message level) and the svID value + * that is part of each ASDU (SVSubscriber_ASDU object). + */ +typedef struct sSVSubscriber* SVSubscriber; + +/** + * \brief Callback function for received SV messages + * + * Will be called for each ASDU contained in a SV message! + * + * \param subscriber the subscriber that was associated with the received SV message + * \param parameter a user provided parameter that is simply passed to the callback + * \param asdu SV ASDU data structure. This structure is only valid inside of the callback function + */ +typedef void (*SVUpdateListener)(SVSubscriber subscriber, void* parameter, SVSubscriber_ASDU asdu); + +/** + * \brief opaque handle to a SV receiver instance + */ +typedef struct sSVReceiver* SVReceiver; + +/** + * \brief Create a new SV receiver instance. + * + * A receiver is responsible for processing all SV message for a single Ethernet interface. + * In order to process messages from multiple Ethernet interfaces you have to create multiple + * instances. + * + * \return the newly created receiver instance + */ +LIB61850_API SVReceiver +SVReceiver_create(void); + +/** + * \brief Disable check for destination address of the received SV messages + * + * \param self the receiver instance reference + */ +LIB61850_API void +SVReceiver_disableDestAddrCheck(SVReceiver self); + +/** + * \brief Enable check for destination address of the received SV messages + * + * Per default only the appID is checked to identify relevant SV messages and the + * destination address is ignored for performance reasons. This only works when the + * appIDs are unique in the local system. Otherwise the destination address check + * has to be enabled. + * + * \param self the receiver instance reference + */ +LIB61850_API void +SVReceiver_enableDestAddrCheck(SVReceiver self); + +/** + * \brief Set the Ethernet interface ID for the receiver instance + * + * Use this function if you want to use a different interface than + * the default interface set by CONFIG_ETHERNET_INTERFACE_ID (stack_config.h) + * NOTE: This function has to be called before calling SVReceiver_start. + * + * \param self the receiver instance reference + * \param interfaceId the Ethernet interface id (platform specific e.g. eth0 for linux). + */ +LIB61850_API void +SVReceiver_setInterfaceId(SVReceiver self, const char* interfaceId); + +/** + * \brief Add a subscriber instance to the receiver + * + * The given subscriber will be connected to the receiver instance. + * + * \param self the receiver instance reference + * \param subscriber the subscriber instance to connect + */ +LIB61850_API void +SVReceiver_addSubscriber(SVReceiver self, SVSubscriber subscriber); + +/** + * \brief Disconnect subscriber and receiver + * + * \param self the receiver instance reference + * \param subscriber the subscriber instance to disconnect + */ +LIB61850_API void +SVReceiver_removeSubscriber(SVReceiver self, SVSubscriber subscriber); + +/** + * \brief Receiver starts listening for SV messages. + * + * NOTE: This call will start a new background thread. + * + * \param self the receiver instance reference + */ +LIB61850_API void +SVReceiver_start(SVReceiver self); + +/** + * \brief Receiver stops listening for SV messages + * + * \param self the receiver instance reference + */ +LIB61850_API void +SVReceiver_stop(SVReceiver self); + +/** + * \brief Check if SV receiver is running + * + * Can be used to check if \ref SVReceiver_start has been successful. + * + * \param self the receiver instance reference + * + * \return true if SV receiver is running, false otherwise + */ +LIB61850_API bool +SVReceiver_isRunning(SVReceiver self); + +/** + * \brief Destroy receiver instance (cleanup resources) + * + * \param self the receiver instance reference + */ +LIB61850_API void +SVReceiver_destroy(SVReceiver self); + +/*************************************** + * Functions for non-threaded operation + ***************************************/ + +LIB61850_API EthernetSocket +SVReceiver_startThreadless(SVReceiver self); + +LIB61850_API void +SVReceiver_stopThreadless(SVReceiver self); + +/** + * \brief Parse SV messages if they are available. + * + * Call after reception of ethernet frame and periodically to to house keeping tasks + * + * \param self the receiver object + * + * \return true if a message was available and has been parsed, false otherwise + */ +LIB61850_API bool +SVReceiver_tick(SVReceiver self); + +/* + * \brief Create a new SV subscriber instance + * + * \param ethAddr optional destination address (NULL to not specify the destination address) + * \param appID the APP-ID to identify matching SV messages + * + * \return the new subscriber instance + */ + +LIB61850_API SVSubscriber +SVSubscriber_create(const uint8_t* ethAddr, uint16_t appID); + +/** + * \brief Set a callback handler to process received SV messages + * + * If the received SV message contains multiple ASDUs (application service data units) the callback + * function will be called for each ASDU separately. If a callback function has already been installed + * for this SVSubscriber object the old callback will be replaced. + * + * \param self The subscriber object + * \param listener the callback function to install + * \param a user provided parameter that is provided to the callback function + */ +LIB61850_API void +SVSubscriber_setListener(SVSubscriber self, SVUpdateListener listener, void* parameter); + +LIB61850_API void +SVSubscriber_destroy(SVSubscriber self); + +/************************************************************************* + * SVSubscriber_ASDU object methods + **************************************************************************/ + +/** + * \addtogroup sv_subscriber_asdu_group Values Application Service Data Unit (ASDU) + * @{ + */ + +/** + * \brief return the SmpCnt value included in the SV ASDU + * + * The SmpCnt (sample counter) is increased for each ASDU to + * identify the sample. + * + * \param self ASDU object instance + */ +LIB61850_API uint16_t +SVSubscriber_ASDU_getSmpCnt(SVSubscriber_ASDU self); + +/** + * \brief return the SvID value included in the SV ASDU + * + * \param self ASDU object instance + */ +LIB61850_API const char* +SVSubscriber_ASDU_getSvId(SVSubscriber_ASDU self); + +/** + * \brief return the DatSet value included in the SV ASDU + * + * \param self ASDU object instance + */ +LIB61850_API const char* +SVSubscriber_ASDU_getDatSet(SVSubscriber_ASDU self); + +/** + * \brief return the ConfRev value included in the SV ASDU + * + * \param self ASDU object instance + */ +LIB61850_API uint32_t +SVSubscriber_ASDU_getConfRev(SVSubscriber_ASDU self); + +/** + * \brief return the SmpMod value included in the SV ASDU + * + * \param self ASDU object instance + */ +LIB61850_API uint8_t +SVSubscriber_ASDU_getSmpMod(SVSubscriber_ASDU self); + +/** + * \brief return the SmpRate value included in the SV ASDU + * + * \param self ASDU object instance + */ +LIB61850_API uint16_t +SVSubscriber_ASDU_getSmpRate(SVSubscriber_ASDU self); + +/** + * \brief Check if DatSet value is included in the SV ASDU + * + * \param self ASDU object instance + * + * \return true if DatSet value is present, false otherwise + */ +LIB61850_API bool +SVSubscriber_ASDU_hasDatSet(SVSubscriber_ASDU self); + +/** + * \brief Check if RefrTm value is included in the SV ASDU + * + * \param self ASDU object instance + * + * \return true if RefrTm value is present, false otherwise + */ +LIB61850_API bool +SVSubscriber_ASDU_hasRefrTm(SVSubscriber_ASDU self); + +/** + * \brief Check if SmpMod value is included in the SV ASDU + * + * \param self ASDU object instance + * + * \return true if SmpMod value is present, false otherwise + */ +LIB61850_API bool +SVSubscriber_ASDU_hasSmpMod(SVSubscriber_ASDU self); + +/** + * \brief Check if SmpRate value is included in the SV ASDU + * + * \param self ASDU object instance + * + * \return true if SmpRate value is present, false otherwise + */ +LIB61850_API bool +SVSubscriber_ASDU_hasSmpRate(SVSubscriber_ASDU self); + +/** + * \brief Get the RefrTim value included in SV ASDU as milliseconds timestamp + * + * \param self ASDU object instance + * + * \return the time value as ms timestamp or 0 if RefrTm is not present in the SV ASDU + */ +LIB61850_API uint64_t +SVSubscriber_ASDU_getRefrTmAsMs(SVSubscriber_ASDU self); + +/** + * \brief Get the RefrTim value included in SV ASDU as nanoseconds timestamp + * + * \param self ASDU object instance + * + * \return the time value as nanoseconds timestamp or 0 if RefrTm is not present in the SV ASDU + */ +LIB61850_API nsSinceEpoch +SVSubscriber_ASDU_getRefrTmAsNs(SVSubscriber_ASDU self); + +/** + * \brief Get an INT8 data value in the data part of the ASDU + * + * \param self ASDU object instance + * \param index the index (byte position of the start) of the data in the data part + * + * \return SV data + */ +LIB61850_API int8_t +SVSubscriber_ASDU_getINT8(SVSubscriber_ASDU self, int index); + +/** + * \brief Get an INT16 data value in the data part of the ASDU + * + * \param self ASDU object instance + * \param index the index (byte position of the start) of the data in the data part + * + * \return SV data + */ +LIB61850_API int16_t +SVSubscriber_ASDU_getINT16(SVSubscriber_ASDU self, int index); + +/** + * \brief Get an INT32 data value in the data part of the ASDU + * + * \param self ASDU object instance + * \param index the index (byte position of the start) of the data in the data part + * + * \return SV data + */ +LIB61850_API int32_t +SVSubscriber_ASDU_getINT32(SVSubscriber_ASDU self, int index); + +/** + * \brief Get an INT64 data value in the data part of the ASDU + * + * \param self ASDU object instance + * \param index the index (byte position of the start) of the data in the data part + * + * \return SV data + */ +LIB61850_API int64_t +SVSubscriber_ASDU_getINT64(SVSubscriber_ASDU self, int index); + +/** + * \brief Get an INT8U data value in the data part of the ASDU + * + * \param self ASDU object instance + * \param index the index (byte position of the start) of the data in the data part + * + * \return SV data + */ +LIB61850_API uint8_t +SVSubscriber_ASDU_getINT8U(SVSubscriber_ASDU self, int index); + +/** + * \brief Get an INT16U data value in the data part of the ASDU + * + * \param self ASDU object instance + * \param index the index (byte position of the start) of the data in the data part + * + * \return SV data + */ +LIB61850_API uint16_t +SVSubscriber_ASDU_getINT16U(SVSubscriber_ASDU self, int index); + +/** + * \brief Get an INT32U data value in the data part of the ASDU + * + * \param self ASDU object instance + * \param index the index (byte position of the start) of the data in the data part + * + * \return SV data + */ +LIB61850_API uint32_t +SVSubscriber_ASDU_getINT32U(SVSubscriber_ASDU self, int index); + +/** + * \brief Get an INT64U data value in the data part of the ASDU + * + * \param self ASDU object instance + * \param index the index (byte position of the start) of the data in the data part + * + * \return SV data + */ +LIB61850_API uint64_t +SVSubscriber_ASDU_getINT64U(SVSubscriber_ASDU self, int index); + +/** + * \brief Get an FLOAT32 data value in the data part of the ASDU + * + * \param self ASDU object instance + * \param index the index (byte position of the start) of the data in the data part + * + * \return SV data + */ +LIB61850_API float +SVSubscriber_ASDU_getFLOAT32(SVSubscriber_ASDU self, int index); + +/** + * \brief Get an FLOAT64 data value in the data part of the ASDU + * + * \param self ASDU object instance + * \param index the index (byte position of the start) of the data in the data part + * + * \return SV data + */ +LIB61850_API double +SVSubscriber_ASDU_getFLOAT64(SVSubscriber_ASDU self, int index); + +/** + * \brief Get a timestamp data value in the data part of the ASDU + * + * \param self ASDU object instance + * \param index the index (byte position of the start) of the data in the data part + * + * \return SV data + */ +LIB61850_API Timestamp +SVSubscriber_ASDU_getTimestamp(SVSubscriber_ASDU self, int index); + +/** + * \brief Get a quality value in the data part of the ASDU + * + * NOTE: Quality is encoded as BITSTRING (4 byte) + * + * \param self ASDU object instance + * \param index the index (byte position of the start) of the data in the data part + * + * \return SV data + */ +LIB61850_API Quality +SVSubscriber_ASDU_getQuality(SVSubscriber_ASDU self, int index); + +/** + * \brief Returns the size of the data part of the ASDU + * + * \param self ASDU object instance + * + * \return size of the ASDU data part in bytes. + */ +LIB61850_API int +SVSubscriber_ASDU_getDataSize(SVSubscriber_ASDU self); + +/** + * \brief return the SmpSynch value included in the SV ASDU + * + * The SmpSynch gives information about the clock synchronization. + * + * \param self ASDU object instance + */ +uint8_t +SVSubscriber_ASDU_getSmpSynch(SVSubscriber_ASDU self); + +#ifndef DEPRECATED +#if defined(__GNUC__) || defined(__clang__) + #define DEPRECATED __attribute__((deprecated)) +#else + #define DEPRECATED +#endif +#endif + +/** + * \addtogroup sv_subscriber_deprecated_api_group Deprecated API + * \ingroup sv_subscriber_api_group IEC 61850 Sampled Values (SV) publisher API + * \deprecated + * @{ + */ + +typedef struct sSVSubscriberASDU* SVClientASDU; + +LIB61850_API DEPRECATED uint16_t +SVClientASDU_getSmpCnt(SVSubscriber_ASDU self); + +LIB61850_API DEPRECATED const char* +SVClientASDU_getSvId(SVSubscriber_ASDU self); + +LIB61850_API DEPRECATED uint32_t +SVClientASDU_getConfRev(SVSubscriber_ASDU self); + +LIB61850_API DEPRECATED bool +SVClientASDU_hasRefrTm(SVSubscriber_ASDU self); + +LIB61850_API DEPRECATED uint64_t +SVClientASDU_getRefrTmAsMs(SVSubscriber_ASDU self); + +LIB61850_API DEPRECATED int8_t +SVClientASDU_getINT8(SVSubscriber_ASDU self, int index); + +LIB61850_API DEPRECATED int16_t +SVClientASDU_getINT16(SVSubscriber_ASDU self, int index); + +LIB61850_API DEPRECATED int32_t +SVClientASDU_getINT32(SVSubscriber_ASDU self, int index); + +LIB61850_API DEPRECATED int64_t +SVClientASDU_getINT64(SVSubscriber_ASDU self, int index); + +LIB61850_API DEPRECATED uint8_t +SVClientASDU_getINT8U(SVSubscriber_ASDU self, int index); + +LIB61850_API DEPRECATED uint16_t +SVClientASDU_getINT16U(SVSubscriber_ASDU self, int index); + +LIB61850_API DEPRECATED uint32_t +SVClientASDU_getINT32U(SVSubscriber_ASDU self, int index); + +LIB61850_API DEPRECATED uint64_t +SVClientASDU_getINT64U(SVSubscriber_ASDU self, int index); + +LIB61850_API DEPRECATED float +SVClientASDU_getFLOAT32(SVSubscriber_ASDU self, int index); + +LIB61850_API DEPRECATED double +SVClientASDU_getFLOAT64(SVSubscriber_ASDU self, int index); + +LIB61850_API DEPRECATED int +SVClientASDU_getDataSize(SVSubscriber_ASDU self); + +/**@} @}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* SAMPLED_VALUES_SV_SUBSCRIBER_ */ diff --git a/product/src/fes/include/libiec61850/tls_config.h b/product/src/fes/include/libiec61850/tls_config.h new file mode 100644 index 00000000..2896a108 --- /dev/null +++ b/product/src/fes/include/libiec61850/tls_config.h @@ -0,0 +1,322 @@ +/* + * tls_config.h + * + * TLS Configuration API for protocol stacks using TCP/IP + * + * Copyright 2017-2022 Michael Zillgith + * + * Abstraction layer for configuration of different TLS implementations + * + */ + +#ifndef SRC_TLS_CONFIG_H_ +#define SRC_TLS_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hal_base.h" + +/** + * \file tls_config.h + * \brief TLS API functions + */ + +/*! \addtogroup hal Platform (Hardware/OS) abstraction layer + * + * @{ + */ + +/** + * @defgroup TLS_CONFIG_API TLS configuration + * + * @{ + */ + +typedef struct sTLSConfiguration* TLSConfiguration; + +/** + * \brief Create a new \ref TLSConfiguration object to represent TLS configuration and certificates + * + * WARNING: Configuration cannot be changed after using for the first time. + * + * \return the new TLS configuration + */ +PAL_API TLSConfiguration +TLSConfiguration_create(void); + +/* will be called by stack automatically when appropriate */ +PAL_API void +TLSConfiguration_setClientMode(TLSConfiguration self); + +typedef enum { + TLS_VERSION_NOT_SELECTED = 0, + TLS_VERSION_SSL_3_0 = 3, + TLS_VERSION_TLS_1_0 = 4, + TLS_VERSION_TLS_1_1 = 5, + TLS_VERSION_TLS_1_2 = 6, + TLS_VERSION_TLS_1_3 = 7 +} TLSConfigVersion; + +/** + * \brief Convert TLS version number to string + * + * \param version TLS version number + * + * \return the TLS version as null terminated string + */ +PAL_API const char* +TLSConfigVersion_toString(TLSConfigVersion version); + +typedef enum { + TLS_SEC_EVT_INFO = 0, + TLS_SEC_EVT_WARNING = 1, + TLS_SEC_EVT_INCIDENT = 2 +} TLSEventLevel; + +#define TLS_EVENT_CODE_ALM_ALGO_NOT_SUPPORTED 1 +#define TLS_EVENT_CODE_ALM_UNSECURE_COMMUNICATION 2 +#define TLS_EVENT_CODE_ALM_CERT_UNAVAILABLE 3 +#define TLS_EVENT_CODE_ALM_BAD_CERT 4 +#define TLS_EVENT_CODE_ALM_CERT_SIZE_EXCEEDED 5 +#define TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED 6 +#define TLS_EVENT_CODE_ALM_CERT_REQUIRED 7 +#define TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON 8 +#define TLS_EVENT_CODE_WRN_INSECURE_TLS_VERSION 9 +#define TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION 10 +#define TLS_EVENT_CODE_ALM_CERT_EXPIRED 11 +#define TLS_EVENT_CODE_ALM_CERT_REVOKED 12 +#define TLS_EVENT_CODE_ALM_CERT_NOT_CONFIGURED 13 +#define TLS_EVENT_CODE_ALM_CERT_NOT_TRUSTED 14 +#define TLS_EVENT_CODE_ALM_NO_CIPHER 15 + +typedef struct sTLSConnection* TLSConnection; + +/** + * \brief Get the peer address of the TLS connection + * + * \param self the TLS connection instance + * \param peerAddrBuf user provided buffer that can hold at least 60 characters, or NULL to allow the function to allocate the memory for the buffer + * + * \returns peer address:port as null terminated string + */ +PAL_API char* +TLSConnection_getPeerAddress(TLSConnection self, char* peerAddrBuf); + +/** + * \brief Get the TLS certificate used by the peer + * + * \param self the TLS connection instance + * \param certSize[OUT] the certificate size in bytes + * + * \return address of the certificate buffer + */ +PAL_API uint8_t* +TLSConnection_getPeerCertificate(TLSConnection self, int* certSize); + +/** + * \brief Get the TLS version used by the connection + * + * \param self the TLS connection instance + * + * \return TLS version + */ +PAL_API TLSConfigVersion +TLSConnection_getTLSVersion(TLSConnection self); + +typedef void (*TLSConfiguration_EventHandler)(void* parameter, TLSEventLevel eventLevel, int eventCode, const char* message, TLSConnection con); + +/** + * \brief Set the security event handler + * + * \param handler the security event callback handler + * \param parameter user provided parameter to be passed to the callback handler + */ +PAL_API void +TLSConfiguration_setEventHandler(TLSConfiguration self, TLSConfiguration_EventHandler handler, void* parameter); + +/** + * \brief enable or disable TLS session resumption (default: enabled) + * + * NOTE: Depending on the used TLS version this is implemented by + * session IDs or by session tickets. + * + * \param enable true to enable session resumption, false otherwise + */ +PAL_API void +TLSConfiguration_enableSessionResumption(TLSConfiguration self, bool enable); + +/** + * \brief Set the maximum life time of a cached TLS session for session resumption in seconds + * + * \param intervalInSeconds the maximum lifetime of a cached TLS session + */ +PAL_API void +TLSConfiguration_setSessionResumptionInterval(TLSConfiguration self, int intervalInSeconds); + +/** + * \brief Enables the validation of the certificate trust chain (enabled by default) + * + * \param value true to enable chain validation, false to disable + */ +PAL_API void +TLSConfiguration_setChainValidation(TLSConfiguration self, bool value); + +/** + * \brief Set if only known certificates are accepted. + * + * If set to true only known certificates are accepted. Connections with unknown certificates + * are rejected even if they are signed by a trusted authority. + * + * \param value true to enable setting, false otherwise + */ +PAL_API void +TLSConfiguration_setAllowOnlyKnownCertificates(TLSConfiguration self, bool value); + +/** + * \brief Set own certificate (identity) from a byte buffer + * + * \param certificate the certificate buffer + * \param certLen the lenght of the certificate + * + * \return true, when the certificate was set, false otherwise (e.g. unknown certificate format) + */ +PAL_API bool +TLSConfiguration_setOwnCertificate(TLSConfiguration self, uint8_t* certificate, int certLen); + +/** + * \brief Set own certificate (identity) from a certificate file + * + * \param filename of the certificate file + * + * \return true, when the certificate was set, false otherwise (e.g. unknown certificate format) + */ +PAL_API bool +TLSConfiguration_setOwnCertificateFromFile(TLSConfiguration self, const char* filename); + +/** + * \brief Set the own private key from a byte buffer + * + * \param key the private key to use + * \param keyLen the length of the key + * \param password the password of the key or null if the key is not password protected + * + * \return true, when the key was set, false otherwise (e.g. unknown key format) + */ +PAL_API bool +TLSConfiguration_setOwnKey(TLSConfiguration self, uint8_t* key, int keyLen, const char* keyPassword); + +/** + * \brief Set the own private key from a key file + * + * \param filename filename/path of the key file + * \param password the password of the key or null if the key is not password protected + * + * \return true, when the key was set, false otherwise (e.g. unknown key format) + */ +PAL_API bool +TLSConfiguration_setOwnKeyFromFile(TLSConfiguration self, const char* filename, const char* keyPassword); + +/** + * Add a certificate to the list of allowed peer certificates from a byte buffer + * + * \param certificate the certificate buffer + * \param certLen the length of the certificate buffer + * \return true, when the certificate was set, false otherwise (e.g. unknown certificate format) + */ +PAL_API bool +TLSConfiguration_addAllowedCertificate(TLSConfiguration self, uint8_t* certificate, int certLen); + +/** + * \brief Add a certificate to the list of allowed peer certificates + * + * \param filename filename of the certificate file + * \return true, when the certificate was set, false otherwise (e.g. unknown certificate format) + */ +PAL_API bool +TLSConfiguration_addAllowedCertificateFromFile(TLSConfiguration self, const char* filename); + +/** + * \brief Add a CA certificate used to validate peer certificates from a byte buffer + * + * \param certificate the certificate buffer + * \param certLen the length of the certificate buffer + * \return true, when the certificate was set, false otherwise (e.g. unknown certificate format) + */ +PAL_API bool +TLSConfiguration_addCACertificate(TLSConfiguration self, uint8_t* certificate, int certLen); + +/** + * \brief Add a CA certificate used to validate peer certificates from a file + * + * \param filename filename of the certificate file + * \return true, when the certificate was set, false otherwise (e.g. unknown certificate format) + */ +PAL_API bool +TLSConfiguration_addCACertificateFromFile(TLSConfiguration self, const char* filename); + +/** + * \brief Set the renegotiation timeout. + * + * After the timeout elapsed a TLS session renegotiation has to occur. + * + * \param timeInMs session renegotiation timeout in milliseconds + */ +PAL_API void +TLSConfiguration_setRenegotiationTime(TLSConfiguration self, int timeInMs); + +/** + * \brief Set minimal allowed TLS version to use + */ +PAL_API void +TLSConfiguration_setMinTlsVersion(TLSConfiguration self, TLSConfigVersion version); + +/** + * \brief Set maximal allowed TLS version to use + */ +PAL_API void +TLSConfiguration_setMaxTlsVersion(TLSConfiguration self, TLSConfigVersion version); + +/** + * \brief Add a CRL (certificate revocation list) from buffer + * + * \param crl the buffer containing the CRL + * \param crlLen the length of the CRL buffer + * \return true, when the CRL was imported, false otherwise (e.g. unknown format) + */ +PAL_API bool +TLSConfiguration_addCRL(TLSConfiguration self, uint8_t* crl, int crlLen); + +/** + * \brief Add a CRL (certificate revocation list) from a file + * + * \param filename filename of the CRL file + * \return true, when the CRL was imported, false otherwise (e.g. unknown format) + */ +PAL_API bool +TLSConfiguration_addCRLFromFile(TLSConfiguration self, const char* filename); + +/** + * \brief Removes any CRL (certificate revocation list) currently in use + */ +PAL_API void +TLSConfiguration_resetCRL(TLSConfiguration self); + +/** + * Release all resource allocated by the TLSConfiguration instance + * + * NOTE: Do not use the object after calling this function! + */ +PAL_API void +TLSConfiguration_destroy(TLSConfiguration self); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* SRC_TLS_CONFIG_H_ */ diff --git a/product/src/fes/include/open62541/client.h b/product/src/fes/include/open62541/client.h new file mode 100644 index 00000000..7ab9ace1 --- /dev/null +++ b/product/src/fes/include/open62541/client.h @@ -0,0 +1,955 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2015-2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2015-2016 (c) Sten Grüner + * Copyright 2015-2016 (c) Chris Iatrou + * Copyright 2015-2017 (c) Florian Palm + * Copyright 2015 (c) Holger Jeromin + * Copyright 2015 (c) Oleksiy Vasylyev + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2018 (c) Thomas Stalder, Blue Time Concept SA + * Copyright 2018 (c) Kalycito Infotech Private Limited + * Copyright 2020 (c) Christian von Arnim, ISW University of Stuttgart + * Copyright 2022 (c) Linutronix GmbH (Author: Muddasir Shakil) + */ + +#ifndef UA_CLIENT_H_ +#define UA_CLIENT_H_ + +#include +#include +#include + +#include +#include +#include + +/* Forward declarations */ +struct UA_ClientConfig; +typedef struct UA_ClientConfig UA_ClientConfig; + +_UA_BEGIN_DECLS + +/** + * .. _client: + * + * Client + * ====== + * + * The client implementation allows remote access to all OPC UA services. For + * convenience, some functionality has been wrapped in :ref:`high-level + * abstractions `. + * + * **However**: At this time, the client does not yet contain its own thread or + * event-driven main-loop, meaning that the client will not perform any actions + * automatically in the background. This is especially relevant for + * connection/session management and subscriptions. The user will have to + * periodically call `UA_Client_run_iterate` to ensure that asynchronous events + * are handled, including keeping a secure connection established. + * See more about :ref:`asynchronicity` and + * :ref:`subscriptions`. + * + * .. _client-config: + * + * Client Configuration + * -------------------- + * + * The client configuration is used for setting connection parameters and + * additional settings used by the client. + * The configuration should not be modified after it is passed to a client. + * Currently, only one client can use a configuration at a time. + * + * Examples for configurations are provided in the ``/plugins`` folder. + * The usual usage is as follows: + * + * 1. Create a client configuration with default settings as a starting point + * 2. Modifiy the configuration, e.g. modifying the timeout + * 3. Instantiate a client with it + * 4. After shutdown of the client, clean up the configuration (free memory) + * + * The :ref:`tutorials` provide a good starting point for this. */ + +struct UA_ClientConfig { + void *clientContext; /* User-defined pointer attached to the client */ + UA_Logger *logging; /* Plugin for log output */ + + /* Response timeout in ms (0 -> no timeout). If the server does not answer a + * request within this time a StatusCode UA_STATUSCODE_BADTIMEOUT is + * returned. This timeout can be overridden for individual requests by + * setting a non-null "timeoutHint" in the request header. */ + UA_UInt32 timeout; + + /* The description must be internally consistent. + * - The ApplicationUri set in the ApplicationDescription must match the + * URI set in the certificate */ + UA_ApplicationDescription clientDescription; + + /* The endpoint for the client to connect to. + * Such as "opc.tcp://host:port". */ + UA_String endpointUrl; + + /** + * Connection configuration + * ~~~~~~~~~~~~~~~~~~~~~~~~ + * + * The following configuration elements reduce the "degrees of freedom" the + * client has when connecting to a server. If no connection can be made + * under these restrictions, then the connection will abort with an error + * message. */ + UA_ExtensionObject userIdentityToken; /* Configured User-Identity Token */ + UA_MessageSecurityMode securityMode; /* None, Sign, SignAndEncrypt. The + * default is "invalid". This + * indicates the client to select any + * matching endpoint. */ + UA_String securityPolicyUri; /* SecurityPolicy for the SecureChannel. An + * empty string indicates the client to select + * any matching SecurityPolicy. */ + + UA_Boolean noSession; /* Only open a SecureChannel, but no Session */ + UA_Boolean noReconnect; /* Don't reconnect SecureChannel when the connection + * is lost without explicitly closing. */ + UA_Boolean noNewSession; /* Don't automatically create a new Session when + * the intial one is lost. Instead abort the + * connection when the Session is lost. */ + + /** + * If either endpoint or userTokenPolicy has been set, then they are used + * directly. Otherwise this information comes from the GetEndpoints response + * from the server (filtered and selected for the SecurityMode, etc.). */ + UA_EndpointDescription endpoint; + UA_UserTokenPolicy userTokenPolicy; + + /** + * If the EndpointDescription has not been defined, the ApplicationURI + * filters the servers considered in the FindServers service and the + * Endpoints considered in the GetEndpoints service. */ + UA_String applicationUri; + + /** + * Custom Data Types + * ~~~~~~~~~~~~~~~~~ + * The following is a linked list of arrays with custom data types. All data + * types that are accessible from here are automatically considered for the + * decoding of received messages. Custom data types are not cleaned up + * together with the configuration. So it is possible to allocate them on + * ROM. + * + * See the section on :ref:`generic-types`. Examples for working with custom + * data types are provided in ``/examples/custom_datatype/``. */ + const UA_DataTypeArray *customDataTypes; + + /** + * Advanced Client Configuration + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + UA_UInt32 secureChannelLifeTime; /* Lifetime in ms (then the channel needs + to be renewed) */ + UA_UInt32 requestedSessionTimeout; /* Session timeout in ms */ + UA_ConnectionConfig localConnectionConfig; + UA_UInt32 connectivityCheckInterval; /* Connectivity check interval in ms. + * 0 = background task disabled */ + + /* EventLoop */ + UA_EventLoop *eventLoop; + UA_Boolean externalEventLoop; /* The EventLoop is not deleted with the config */ + + /* Available SecurityPolicies */ + size_t securityPoliciesSize; + UA_SecurityPolicy *securityPolicies; + + /* Certificate Verification Plugin */ + UA_CertificateVerification certificateVerification; + + /* Available SecurityPolicies for Authentication. The policy defined by the + * AccessControl is selected. If no policy is defined, the policy of the + * secure channel is selected.*/ + size_t authSecurityPoliciesSize; + UA_SecurityPolicy *authSecurityPolicies; + + /* SecurityPolicyUri for the Authentication. */ + UA_String authSecurityPolicyUri; + + /* Callback for state changes. The client state is differentated into the + * SecureChannel state and the Session state. The connectStatus is set if + * the client connection (including reconnects) has failed and the client + * has to "give up". If the connectStatus is not set, the client still has + * hope to connect or recover. */ + void (*stateCallback)(UA_Client *client, + UA_SecureChannelState channelState, + UA_SessionState sessionState, + UA_StatusCode connectStatus); + + /* When connectivityCheckInterval is greater than 0, every + * connectivityCheckInterval (in ms), an async read request is performed on + * the server. inactivityCallback is called when the client receive no + * response for this read request The connection can be closed, this in an + * attempt to recreate a healthy connection. */ + void (*inactivityCallback)(UA_Client *client); + + /* Number of PublishResponse queued up in the server */ + UA_UInt16 outStandingPublishRequests; + + /* If the client does not receive a PublishResponse after the defined delay + * of ``(sub->publishingInterval * sub->maxKeepAliveCount) + + * client->config.timeout)``, then subscriptionInactivityCallback is called + * for the subscription.. */ + void (*subscriptionInactivityCallback)(UA_Client *client, + UA_UInt32 subscriptionId, + void *subContext); + + /* Session config */ + UA_String sessionName; + UA_LocaleId *sessionLocaleIds; + size_t sessionLocaleIdsSize; + +#ifdef UA_ENABLE_ENCRYPTION + /* If the private key is in PEM format and password protected, this callback + * is called during initialization to get the password to decrypt the + * private key. The memory containing the password is freed by the client + * after use. The callback should be set early, other parts of the client + * config setup may depend on it. */ + UA_StatusCode (*privateKeyPasswordCallback)(UA_ClientConfig *cc, + UA_ByteString *password); +#endif +}; + +/** + * @brief It makes a partial deep copy of the clientconfig. It makes a shallow + * copies of the plugins (logger, eventloop, securitypolicy). + * + * NOTE: It makes a shallow copy of all the plugins from source to destination. + * Therefore calling _clear on the dst object will also delete the plugins in src + * object. + */ +UA_EXPORT UA_StatusCode +UA_ClientConfig_copy(UA_ClientConfig const *src, UA_ClientConfig *dst); + +/** + * @brief It cleans the client config and frees the pointer. + */ +UA_EXPORT void +UA_ClientConfig_delete(UA_ClientConfig *config); + +/** + * @brief It cleans the client config and deletes the plugins, whereas + * _copy makes a shallow copy of the plugins. + */ +UA_EXPORT void +UA_ClientConfig_clear(UA_ClientConfig *config); + +/* Configure Username/Password for the Session authentication. Also see + * UA_ClientConfig_setAuthenticationCert for x509-based authentication, which is + * implemented as a plugin (as it can be based on different crypto + * libraries). */ +static UA_INLINE UA_StatusCode +UA_ClientConfig_setAuthenticationUsername(UA_ClientConfig *config, + const char *username, + const char *password) { + UA_UserNameIdentityToken* identityToken = UA_UserNameIdentityToken_new(); + if(!identityToken) + return UA_STATUSCODE_BADOUTOFMEMORY; + identityToken->userName = UA_STRING_ALLOC(username); + identityToken->password = UA_STRING_ALLOC(password); + + UA_ExtensionObject_clear(&config->userIdentityToken); + UA_ExtensionObject_setValue(&config->userIdentityToken, identityToken, + &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]); + return UA_STATUSCODE_GOOD; +} + +/** + * Client Lifecycle + * ---------------- */ + +/* Create a new client with a default configuration that adds plugins for + * networking, security, logging and so on. See `client_config_default.h` for + * more detailed options. + * + * The default configuration can be used as the starting point to adjust the + * client configuration to individual needs. UA_Client_new is implemented in the + * /plugins folder under the CC0 license. Furthermore the client confiugration + * only uses the public server API. + * + * @return Returns the configured client or NULL if an error occurs. */ +UA_EXPORT UA_Client * UA_Client_new(void); + +/* Creates a new client. Moves the config into the client with a shallow copy. + * The config content is cleared together with the client. */ +UA_Client UA_EXPORT * +UA_Client_newWithConfig(const UA_ClientConfig *config); + +/* Returns the current state. All arguments except ``client`` can be NULL. */ +void UA_EXPORT UA_THREADSAFE +UA_Client_getState(UA_Client *client, + UA_SecureChannelState *channelState, + UA_SessionState *sessionState, + UA_StatusCode *connectStatus); + +/* Get the client configuration */ +UA_EXPORT UA_ClientConfig * +UA_Client_getConfig(UA_Client *client); + +/* Get the client context */ +static UA_INLINE void * +UA_Client_getContext(UA_Client *client) { + return UA_Client_getConfig(client)->clientContext; /* Cannot fail */ +} + +/* (Disconnect and) delete the client */ +void UA_EXPORT +UA_Client_delete(UA_Client *client); + +/** + * Connection Attrbiutes + * --------------------- + * + * Besides the client configuration, some attributes of the connection are + * defined only at runtime. For example the choice of SecurityPolicy or the + * ApplicationDescripton from the server. This API allows to access such + * connection attributes. + * + * The currently defined connection attributes are: + * + * - 0:serverDescription [UA_ApplicationDescription]: Server description + * - 0:securityPolicyUri [UA_String]: Uri of the SecurityPolicy used + * - 0:securityMode [UA_MessageSecurityMode]: SecurityMode of the SecureChannel + */ + +/* Returns a shallow copy of the attribute. Don't _clear or _delete the value + * variant. Don't use the value after returning the control flow to the client. + * Also don't use this in a multi-threaded application. */ +UA_EXPORT UA_StatusCode +UA_Client_getConnectionAttribute(UA_Client *client, const UA_QualifiedName key, + UA_Variant *outValue); + +/* Return a deep copy of the attribute */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Client_getConnectionAttributeCopy(UA_Client *client, const UA_QualifiedName key, + UA_Variant *outValue); + +/* Returns NULL if the attribute is not defined or not a scalar or not of the + * right datatype. Otherwise a shallow copy of the scalar value is created at + * the target location of the void pointer. Hence don't use this in a + * multi-threaded application. */ +UA_EXPORT UA_StatusCode +UA_Client_getConnectionAttribute_scalar(UA_Client *client, + const UA_QualifiedName key, + const UA_DataType *type, + void *outValue); + +/** + * Connect to a Server + * ------------------- + * + * Once a client is connected to an endpointUrl, it is not possible to switch to + * another server. A new client has to be created for that. + * + * Once a connection is established, the client keeps the connection open and + * reconnects if necessary. + * + * If the connection fails unrecoverably (state->connectStatus is set to an + * error), the client is no longer usable. Create a new client if required. */ + +/* Connect with the client configuration. For the async connection, finish + * connecting via UA_Client_run_iterate (or manually running a configured + * external EventLoop). */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +__UA_Client_connect(UA_Client *client, UA_Boolean async); + +/* Connect to the server. First a SecureChannel is opened, then a Session. The + * client configuration restricts the SecureChannel selection and contains the + * UserIdentityToken for the Session. + * + * @param client to use + * @param endpointURL to connect (for example "opc.tcp://localhost:4840") + * @return Indicates whether the operation succeeded or returns an error code */ +static UA_INLINE UA_StatusCode +UA_Client_connect(UA_Client *client, const char *endpointUrl) { + /* Update the configuration */ + UA_ClientConfig *cc = UA_Client_getConfig(client); + cc->noSession = false; /* Open a Session */ + UA_String_clear(&cc->endpointUrl); + cc->endpointUrl = UA_STRING_ALLOC(endpointUrl); + + /* Connect */ + return __UA_Client_connect(client, false); +} + +/* Connect async (non-blocking) to the server. After initiating the connection, + * call UA_Client_run_iterate repeatedly until the connection is fully + * established. You can set a callback to client->config.stateCallback to be + * notified when the connection status changes. Or use UA_Client_getState to get + * the state manually. */ +static UA_INLINE UA_StatusCode +UA_Client_connectAsync(UA_Client *client, const char *endpointUrl) { + /* Update the configuration */ + UA_ClientConfig *cc = UA_Client_getConfig(client); + cc->noSession = false; /* Open a Session */ + UA_String_clear(&cc->endpointUrl); + cc->endpointUrl = UA_STRING_ALLOC(endpointUrl); + + /* Connect */ + return __UA_Client_connect(client, true); +} + +/* Connect to the server without creating a session + * + * @param client to use + * @param endpointURL to connect (for example "opc.tcp://localhost:4840") + * @return Indicates whether the operation succeeded or returns an error code */ +static UA_INLINE UA_StatusCode +UA_Client_connectSecureChannel(UA_Client *client, const char *endpointUrl) { + /* Update the configuration */ + UA_ClientConfig *cc = UA_Client_getConfig(client); + cc->noSession = true; /* Don't open a Session */ + UA_String_clear(&cc->endpointUrl); + cc->endpointUrl = UA_STRING_ALLOC(endpointUrl); + + /* Connect */ + return __UA_Client_connect(client, false); +} + +/* Connect async (non-blocking) only the SecureChannel */ +static UA_INLINE UA_StatusCode +UA_Client_connectSecureChannelAsync(UA_Client *client, const char *endpointUrl) { + /* Update the configuration */ + UA_ClientConfig *cc = UA_Client_getConfig(client); + cc->noSession = true; /* Don't open a Session */ + UA_String_clear(&cc->endpointUrl); + cc->endpointUrl = UA_STRING_ALLOC(endpointUrl); + + /* Connect */ + return __UA_Client_connect(client, true); +} + +/* Connect to the server and create+activate a Session with the given username + * and password. This first set the UserIdentityToken in the client config and + * then calls the regular connect method. */ +static UA_INLINE UA_StatusCode +UA_Client_connectUsername(UA_Client *client, const char *endpointUrl, + const char *username, const char *password) { + /* Set the user identity token */ + UA_ClientConfig *cc = UA_Client_getConfig(client); + UA_StatusCode res = + UA_ClientConfig_setAuthenticationUsername(cc, username, password); + if(res != UA_STATUSCODE_GOOD) + return res; + + /* Connect */ + return UA_Client_connect(client, endpointUrl); +} + +/* Sets up a listening socket for incoming reverse connect requests by OPC UA + * servers. After the first server has connected, the listening socket is + * removed. The client state callback is also used for reverse connect. An + * implementation could for example issue a new call to + * UA_Client_startListeningForReverseConnect after the server has closed the + * connection. If the client is connected to any server while + * UA_Client_startListeningForReverseConnect is called, the connection will be + * closed. + * + * The reverse connect is closed by calling the standard disconnect functions + * like for a "normal" connection that was initiated by the client. Calling one + * of the connect methods will also close the listening socket and the + * connection to the remote server. */ +UA_StatusCode UA_EXPORT +UA_Client_startListeningForReverseConnect( + UA_Client *client, const UA_String *listenHostnames, + size_t listenHostnamesLength, UA_UInt16 port); + +/* Disconnect and close a connection to the selected server. Disconnection is + * always performed async (without blocking). */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_disconnect(UA_Client *client); + +/* Disconnect async. Run UA_Client_run_iterate until the callback notifies that + * all connections are closed. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_disconnectAsync(UA_Client *client); + +/* Disconnect the SecureChannel but keep the Session intact (if it exists). */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_disconnectSecureChannel(UA_Client *client); + +/* Disconnect the SecureChannel but keep the Session intact (if it exists). This + * is an async operation. Iterate the client until the SecureChannel was fully + * cleaned up. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_disconnectSecureChannelAsync(UA_Client *client); + +/* Get the AuthenticationToken and ServerNonce required to activate the current + * Session on a different SecureChannel. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_getSessionAuthenticationToken( + UA_Client *client, UA_NodeId *authenticationToken, UA_ByteString *serverNonce); + +/* Re-activate the current session. A change of prefered locales can be done by + * updating the client configuration. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_activateCurrentSession(UA_Client *client); + +/* Async version of UA_Client_activateCurrentSession */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_activateCurrentSessionAsync(UA_Client *client); + +/* Activate an already created Session. This allows a Session to be transferred + * from a different client instance. The AuthenticationToken and ServerNonce + * must be provided for this. Both can be retrieved for an activated Session + * with UA_Client_getSessionAuthenticationToken. + * + * The UserIdentityToken used for authentication must be identical to the + * original activation of the Session. The UserIdentityToken is set in the + * client configuration. + * + * Note the noNewSession option if there should not be a new Session + * automatically created when this one closes. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_activateSession(UA_Client *client, + const UA_NodeId authenticationToken, + const UA_ByteString serverNonce); + +/* Async version of UA_Client_activateSession */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_activateSessionAsync(UA_Client *client, + const UA_NodeId authenticationToken, + const UA_ByteString serverNonce); + +/** + * Discovery + * --------- */ + +/* Gets a list of endpoints of a server + * + * @param client to use. Must be connected to the same endpoint given in + * serverUrl or otherwise in disconnected state. + * @param serverUrl url to connect (for example "opc.tcp://localhost:4840") + * @param endpointDescriptionsSize size of the array of endpoint descriptions + * @param endpointDescriptions array of endpoint descriptions that is allocated + * by the function (you need to free manually) + * @return Indicates whether the operation succeeded or returns an error code */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_getEndpoints(UA_Client *client, const char *serverUrl, + size_t* endpointDescriptionsSize, + UA_EndpointDescription** endpointDescriptions); + +/* Gets a list of all registered servers at the given server. + * + * You can pass an optional filter for serverUris. If the given server is not + * registered, an empty array will be returned. If the server is registered, + * only that application description will be returned. + * + * Additionally you can optionally indicate which locale you want for the server + * name in the returned application description. The array indicates the order + * of preference. A server may have localized names. + * + * @param client to use. Must be connected to the same endpoint given in + * serverUrl or otherwise in disconnected state. + * @param serverUrl url to connect (for example "opc.tcp://localhost:4840") + * @param serverUrisSize Optional filter for specific server uris + * @param serverUris Optional filter for specific server uris + * @param localeIdsSize Optional indication which locale you prefer + * @param localeIds Optional indication which locale you prefer + * @param registeredServersSize size of returned array, i.e., number of + * found/registered servers + * @param registeredServers array containing found/registered servers + * @return Indicates whether the operation succeeded or returns an error code */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_findServers(UA_Client *client, const char *serverUrl, + size_t serverUrisSize, UA_String *serverUris, + size_t localeIdsSize, UA_String *localeIds, + size_t *registeredServersSize, + UA_ApplicationDescription **registeredServers); + +/* Get a list of all known server in the network. Only supported by LDS servers. + * + * @param client to use. Must be connected to the same endpoint given in + * serverUrl or otherwise in disconnected state. + * @param serverUrl url to connect (for example "opc.tcp://localhost:4840") + * @param startingRecordId optional. Only return the records with an ID higher + * or equal the given. Can be used for pagination to only get a subset of + * the full list + * @param maxRecordsToReturn optional. Only return this number of records + + * @param serverCapabilityFilterSize optional. Filter the returned list to only + * get servers with given capabilities, e.g. "LDS" + * @param serverCapabilityFilter optional. Filter the returned list to only get + * servers with given capabilities, e.g. "LDS" + * @param serverOnNetworkSize size of returned array, i.e., number of + * known/registered servers + * @param serverOnNetwork array containing known/registered servers + * @return Indicates whether the operation succeeded or returns an error code */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_findServersOnNetwork(UA_Client *client, const char *serverUrl, + UA_UInt32 startingRecordId, + UA_UInt32 maxRecordsToReturn, + size_t serverCapabilityFilterSize, + UA_String *serverCapabilityFilter, + size_t *serverOnNetworkSize, + UA_ServerOnNetwork **serverOnNetwork); + +/** + * .. _client-services: + * + * Services + * -------- + * + * The raw OPC UA services are exposed to the client. But most of the time, it + * is better to use the convenience functions from ``ua_client_highlevel.h`` + * that wrap the raw services. */ +/* Don't use this function. Use the type versions below instead. */ +void UA_EXPORT UA_THREADSAFE +__UA_Client_Service(UA_Client *client, const void *request, + const UA_DataType *requestType, void *response, + const UA_DataType *responseType); + +/* + * Attribute Service Set + * ^^^^^^^^^^^^^^^^^^^^^ */ +static UA_INLINE UA_THREADSAFE UA_ReadResponse +UA_Client_Service_read(UA_Client *client, const UA_ReadRequest request) { + UA_ReadResponse response; + __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_READREQUEST], + &response, &UA_TYPES[UA_TYPES_READRESPONSE]); + return response; +} + +static UA_INLINE UA_THREADSAFE UA_WriteResponse +UA_Client_Service_write(UA_Client *client, const UA_WriteRequest request) { + UA_WriteResponse response; + __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_WRITEREQUEST], + &response, &UA_TYPES[UA_TYPES_WRITERESPONSE]); + return response; +} + +/* + * Historical Access Service Set + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ +static UA_INLINE UA_THREADSAFE UA_HistoryReadResponse +UA_Client_Service_historyRead(UA_Client *client, + const UA_HistoryReadRequest request) { + UA_HistoryReadResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_HISTORYREADREQUEST], + &response, &UA_TYPES[UA_TYPES_HISTORYREADRESPONSE]); + return response; +} + +static UA_INLINE UA_THREADSAFE UA_HistoryUpdateResponse +UA_Client_Service_historyUpdate(UA_Client *client, + const UA_HistoryUpdateRequest request) { + UA_HistoryUpdateResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_HISTORYUPDATEREQUEST], + &response, &UA_TYPES[UA_TYPES_HISTORYUPDATERESPONSE]); + return response; +} + +/* + * Method Service Set + * ^^^^^^^^^^^^^^^^^^ */ +static UA_INLINE UA_THREADSAFE UA_CallResponse +UA_Client_Service_call(UA_Client *client, + const UA_CallRequest request) { + UA_CallResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_CALLREQUEST], + &response, &UA_TYPES[UA_TYPES_CALLRESPONSE]); + return response; +} + +/* + * NodeManagement Service Set + * ^^^^^^^^^^^^^^^^^^^^^^^^^^ */ +static UA_INLINE UA_THREADSAFE UA_AddNodesResponse +UA_Client_Service_addNodes(UA_Client *client, + const UA_AddNodesRequest request) { + UA_AddNodesResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_ADDNODESREQUEST], + &response, &UA_TYPES[UA_TYPES_ADDNODESRESPONSE]); + return response; +} + +static UA_INLINE UA_THREADSAFE UA_AddReferencesResponse +UA_Client_Service_addReferences(UA_Client *client, + const UA_AddReferencesRequest request) { + UA_AddReferencesResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST], + &response, &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE]); + return response; +} + +static UA_INLINE UA_THREADSAFE UA_DeleteNodesResponse +UA_Client_Service_deleteNodes(UA_Client *client, + const UA_DeleteNodesRequest request) { + UA_DeleteNodesResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_DELETENODESREQUEST], + &response, &UA_TYPES[UA_TYPES_DELETENODESRESPONSE]); + return response; +} + +static UA_INLINE UA_THREADSAFE UA_DeleteReferencesResponse +UA_Client_Service_deleteReferences( + UA_Client *client, const UA_DeleteReferencesRequest request) { + UA_DeleteReferencesResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST], + &response, &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE]); + return response; +} + +/* + * View Service Set + * ^^^^^^^^^^^^^^^^ */ +static UA_INLINE UA_THREADSAFE UA_BrowseResponse +UA_Client_Service_browse(UA_Client *client, + const UA_BrowseRequest request) { + UA_BrowseResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_BROWSEREQUEST], + &response, &UA_TYPES[UA_TYPES_BROWSERESPONSE]); + return response; +} + +static UA_INLINE UA_THREADSAFE UA_BrowseNextResponse +UA_Client_Service_browseNext(UA_Client *client, + const UA_BrowseNextRequest request) { + UA_BrowseNextResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST], + &response, &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE]); + return response; +} + +static UA_INLINE UA_THREADSAFE UA_TranslateBrowsePathsToNodeIdsResponse +UA_Client_Service_translateBrowsePathsToNodeIds( + UA_Client *client, + const UA_TranslateBrowsePathsToNodeIdsRequest request) { + UA_TranslateBrowsePathsToNodeIdsResponse response; + __UA_Client_Service( + client, &request, + &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST], + &response, + &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE]); + return response; +} + +static UA_INLINE UA_THREADSAFE UA_RegisterNodesResponse +UA_Client_Service_registerNodes(UA_Client *client, + const UA_RegisterNodesRequest request) { + UA_RegisterNodesResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST], + &response, &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE]); + return response; +} + +static UA_INLINE UA_THREADSAFE UA_UnregisterNodesResponse +UA_Client_Service_unregisterNodes( + UA_Client *client, const UA_UnregisterNodesRequest request) { + UA_UnregisterNodesResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST], + &response, &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE]); + return response; +} + +/* + * Query Service Set + * ^^^^^^^^^^^^^^^^^ */ +#ifdef UA_ENABLE_QUERY + +static UA_INLINE UA_THREADSAFE UA_QueryFirstResponse +UA_Client_Service_queryFirst(UA_Client *client, + const UA_QueryFirstRequest request) { + UA_QueryFirstResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_QUERYFIRSTREQUEST], + &response, &UA_TYPES[UA_TYPES_QUERYFIRSTRESPONSE]); + return response; +} + +static UA_INLINE UA_THREADSAFE UA_QueryNextResponse +UA_Client_Service_queryNext(UA_Client *client, + const UA_QueryNextRequest request) { + UA_QueryNextResponse response; + __UA_Client_Service( + client, &request, &UA_TYPES[UA_TYPES_QUERYFIRSTREQUEST], + &response, &UA_TYPES[UA_TYPES_QUERYFIRSTRESPONSE]); + return response; +} + +#endif + +/** + * .. _client-async-services: + * + * Asynchronous Services + * --------------------- + * All OPC UA services are asynchronous in nature. So several service calls can + * be made without waiting for the individual responses. Depending on the + * server's priorities responses may come in a different ordering than sent. Use + * the typed wrappers for async service requests instead of + * `__UA_Client_AsyncService` directly. See :ref:`client_async`. However, the + * general mechanism of async service calls is explained here. + * + * Connection and session management are performed in `UA_Client_run_iterate`, + * so to keep a connection healthy any client needs to consider how and when it + * is appropriate to do the call. This is especially true for the periodic + * renewal of a SecureChannel's SecurityToken which is designed to have a + * limited lifetime and will invalidate the connection if not renewed. + * + * We say that an async service call has been dispatched once + * __UA_Client_AsyncService returns UA_STATUSCODE_GOOD. If there is an error + * after an async service has been dispatched, the callback is called with an + * "empty" response where the StatusCode has been set accordingly. This is also + * done if the client is shutting down and the list of dispatched async services + * is emptied. + * + * The StatusCode received when the client is shutting down is + * UA_STATUSCODE_BADSHUTDOWN. The StatusCode received when the client doesn't + * receive response after the specified in config->timeout (can be overridden + * via the "timeoutHint" in the request header) is UA_STATUSCODE_BADTIMEOUT. + * + * The userdata and requestId arguments can be NULL. The (optional) requestId + * output can be used to cancel the service while it is still pending. The + * requestId is unique for each service request. Alternatively the requestHandle + * can be manually set (non necessarily unique) in the request header for full + * service call. This can be used to cancel all outstanding requests using that + * handle together. Note that the client will auto-generate a requestHandle + * >100,000 if none is defined. Avoid these when manually setting a requetHandle + * in the requestHeader to avoid clashes. */ + +typedef void +(*UA_ClientAsyncServiceCallback)(UA_Client *client, void *userdata, + UA_UInt32 requestId, void *response); + +UA_StatusCode UA_EXPORT UA_THREADSAFE +__UA_Client_AsyncService(UA_Client *client, const void *request, + const UA_DataType *requestType, + UA_ClientAsyncServiceCallback callback, + const UA_DataType *responseType, + void *userdata, UA_UInt32 *requestId); + +/* Cancel all dispatched requests with the given requestHandle. + * The number if cancelled requests is returned by the server. + * The output argument cancelCount is not set if NULL. */ +UA_EXPORT UA_THREADSAFE UA_StatusCode +UA_Client_cancelByRequestHandle(UA_Client *client, UA_UInt32 requestHandle, + UA_UInt32 *cancelCount); + +/* Map the requestId to the requestHandle used for that request and call the + * Cancel service for that requestHandle. */ +UA_EXPORT UA_THREADSAFE UA_StatusCode +UA_Client_cancelByRequestId(UA_Client *client, UA_UInt32 requestId, + UA_UInt32 *cancelCount); + +/* Set new userdata and callback for an existing request. + * + * @param client Pointer to the UA_Client + * @param requestId RequestId of the request, which was returned by + * __UA_Client_AsyncService before + * @param userdata The new userdata + * @param callback The new callback + * @return UA_StatusCode UA_STATUSCODE_GOOD on success + * UA_STATUSCODE_BADNOTFOUND when no request with requestId is found. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_modifyAsyncCallback(UA_Client *client, UA_UInt32 requestId, + void *userdata, UA_ClientAsyncServiceCallback callback); + +/* Listen on the network and process arriving asynchronous responses in the + * background. Internal housekeeping, renewal of SecureChannels and subscription + * management is done as well. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_run_iterate(UA_Client *client, UA_UInt32 timeout); + +/* Force the manual renewal of the SecureChannel. This is useful to renew the + * SecureChannel during a downtime when no time-critical operations are + * performed. This method is asynchronous. The renewal is triggered (the OPN + * message is sent) but not completed. The OPN response is handled with + * ``UA_Client_run_iterate`` or a synchronous service-call operation. + * + * @return The return value is UA_STATUSCODE_GOODCALLAGAIN if the SecureChannel + * has not elapsed at least 75% of its lifetime. Otherwise the + * ``connectStatus`` is returned. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_renewSecureChannel(UA_Client *client); + +/** + * Timed Callbacks + * --------------- + * Repeated callbacks can be attached to a client and will be executed in the + * defined interval. */ + +typedef void (*UA_ClientCallback)(UA_Client *client, void *data); + +/* Add a callback for execution at a specified time. If the indicated time lies + * in the past, then the callback is executed at the next iteration of the + * server's main loop. + * + * @param client The client object. + * @param callback The callback that shall be added. + * @param data Data that is forwarded to the callback. + * @param date The timestamp for the execution time. + * @param callbackId Set to the identifier of the repeated callback. This can + * be used to cancel the callback later on. If the pointer is null, the + * identifier is not set. + * @return Upon success, UA_STATUSCODE_GOOD is returned. An error code + * otherwise. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_addTimedCallback(UA_Client *client, UA_ClientCallback callback, + void *data, UA_DateTime date, UA_UInt64 *callbackId); + +/* Add a callback for cyclic repetition to the client. + * + * @param client The client object. + * @param callback The callback that shall be added. + * @param data Data that is forwarded to the callback. + * @param interval_ms The callback shall be repeatedly executed with the given + * interval (in ms). The interval must be positive. The first execution + * occurs at now() + interval at the latest. + * @param callbackId Set to the identifier of the repeated callback. This can + * be used to cancel the callback later on. If the pointer is null, the + * identifier is not set. + * @return Upon success, UA_STATUSCODE_GOOD is returned. An error code + * otherwise. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_addRepeatedCallback(UA_Client *client, UA_ClientCallback callback, + void *data, UA_Double interval_ms, + UA_UInt64 *callbackId); + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Client_changeRepeatedCallbackInterval(UA_Client *client, + UA_UInt64 callbackId, + UA_Double interval_ms); + +void UA_EXPORT UA_THREADSAFE +UA_Client_removeCallback(UA_Client *client, UA_UInt64 callbackId); + +#define UA_Client_removeRepeatedCallback(server, callbackId) \ + UA_Client_removeCallback(server, callbackId); + +/** + * Client Utility Functions + * ------------------------ */ + +/* Lookup a datatype by its NodeId. Takes the custom types in the client + * configuration into account. Return NULL if none found. */ +UA_EXPORT const UA_DataType * +UA_Client_findDataType(UA_Client *client, const UA_NodeId *typeId); + +/** + * .. toctree:: + * + * client_highlevel + * client_highlevel_async + * client_subscriptions */ + +_UA_END_DECLS + +#endif /* UA_CLIENT_H_ */ diff --git a/product/src/fes/include/open62541/client_config_default.h b/product/src/fes/include/open62541/client_config_default.h new file mode 100644 index 00000000..83b62a22 --- /dev/null +++ b/product/src/fes/include/open62541/client_config_default.h @@ -0,0 +1,37 @@ +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB + */ + +#ifndef UA_CLIENT_CONFIG_DEFAULT_H_ +#define UA_CLIENT_CONFIG_DEFAULT_H_ + +#include + +_UA_BEGIN_DECLS + +UA_StatusCode UA_EXPORT +UA_ClientConfig_setDefault(UA_ClientConfig *config); + +/* If certificates are used for authentication, this is only possible when + * openssl or mbedtls is used. Libressl is currently not supported.*/ +#if defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_MBEDTLS) +UA_StatusCode UA_EXPORT +UA_ClientConfig_setAuthenticationCert(UA_ClientConfig *config, + UA_ByteString certificateAuth, UA_ByteString privateKeyAuth); +#endif + +#ifdef UA_ENABLE_ENCRYPTION +UA_StatusCode UA_EXPORT +UA_ClientConfig_setDefaultEncryption(UA_ClientConfig *config, + UA_ByteString localCertificate, UA_ByteString privateKey, + const UA_ByteString *trustList, size_t trustListSize, + const UA_ByteString *revocationList, size_t revocationListSize); +#endif + +_UA_END_DECLS + +#endif /* UA_CLIENT_CONFIG_DEFAULT_H_ */ diff --git a/product/src/fes/include/open62541/client_highlevel.h b/product/src/fes/include/open62541/client_highlevel.h new file mode 100644 index 00000000..80068f2d --- /dev/null +++ b/product/src/fes/include/open62541/client_highlevel.h @@ -0,0 +1,665 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2015-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2015 (c) Oleksiy Vasylyev + * Copyright 2017 (c) Florian Palm + * Copyright 2016 (c) Chris Iatrou + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2017 (c) Frank Meerkötter + * Copyright 2018 (c) Fabian Arndt + * Copyright 2018 (c) Peter Rustler, basyskom GmbH + */ + +#ifndef UA_CLIENT_HIGHLEVEL_H_ +#define UA_CLIENT_HIGHLEVEL_H_ + +#include + +_UA_BEGIN_DECLS + +/** + * .. _client-highlevel: + * + * Highlevel Client Functionality + * ------------------------------ + * + * The following definitions are convenience functions making use of the + * standard OPC UA services in the background. This is a less flexible way of + * handling the stack, because at many places sensible defaults are presumed; at + * the same time using these functions is the easiest way of implementing an OPC + * UA application, as you will not have to consider all the details that go into + * the OPC UA services. If more flexibility is needed, you can always achieve + * the same functionality using the raw :ref:`OPC UA services + * `. + * + * Read Attributes + * ^^^^^^^^^^^^^^^ + * The following functions can be used to retrieve a single node attribute. Use + * the regular service to read several attributes at once. */ + +/* Don't call this function, use the typed versions */ +UA_StatusCode UA_EXPORT +__UA_Client_readAttribute(UA_Client *client, const UA_NodeId *nodeId, + UA_AttributeId attributeId, void *out, + const UA_DataType *outDataType); + +static UA_INLINE UA_StatusCode +UA_Client_readNodeIdAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_NodeId *outNodeId) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_NODEID, + outNodeId, &UA_TYPES[UA_TYPES_NODEID]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readNodeClassAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_NodeClass *outNodeClass) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_NODECLASS, + outNodeClass, &UA_TYPES[UA_TYPES_NODECLASS]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readBrowseNameAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_QualifiedName *outBrowseName) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_BROWSENAME, + outBrowseName, + &UA_TYPES[UA_TYPES_QUALIFIEDNAME]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readDisplayNameAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_LocalizedText *outDisplayName) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_DISPLAYNAME, + outDisplayName, + &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readDescriptionAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_LocalizedText *outDescription) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_DESCRIPTION, + outDescription, + &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readWriteMaskAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_UInt32 *outWriteMask) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_WRITEMASK, + outWriteMask, &UA_TYPES[UA_TYPES_UINT32]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readUserWriteMaskAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_UInt32 *outUserWriteMask) { + return __UA_Client_readAttribute(client, &nodeId, + UA_ATTRIBUTEID_USERWRITEMASK, + outUserWriteMask, + &UA_TYPES[UA_TYPES_UINT32]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readIsAbstractAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_Boolean *outIsAbstract) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_ISABSTRACT, + outIsAbstract, &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readSymmetricAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_Boolean *outSymmetric) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_SYMMETRIC, + outSymmetric, &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readInverseNameAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_LocalizedText *outInverseName) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_INVERSENAME, + outInverseName, + &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readContainsNoLoopsAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_Boolean *outContainsNoLoops) { + return __UA_Client_readAttribute(client, &nodeId, + UA_ATTRIBUTEID_CONTAINSNOLOOPS, + outContainsNoLoops, + &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readEventNotifierAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_Byte *outEventNotifier) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_EVENTNOTIFIER, + outEventNotifier, &UA_TYPES[UA_TYPES_BYTE]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readValueAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_Variant *outValue) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_VALUE, + outValue, &UA_TYPES[UA_TYPES_VARIANT]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readDataTypeAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_NodeId *outDataType) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_DATATYPE, + outDataType, &UA_TYPES[UA_TYPES_NODEID]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readValueRankAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_Int32 *outValueRank) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_VALUERANK, + outValueRank, &UA_TYPES[UA_TYPES_INT32]); +} + +UA_StatusCode UA_EXPORT +UA_Client_readArrayDimensionsAttribute(UA_Client *client, const UA_NodeId nodeId, + size_t *outArrayDimensionsSize, + UA_UInt32 **outArrayDimensions); + +static UA_INLINE UA_StatusCode +UA_Client_readAccessLevelAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_Byte *outAccessLevel) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_ACCESSLEVEL, + outAccessLevel, &UA_TYPES[UA_TYPES_BYTE]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readAccessLevelExAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_UInt32 *outAccessLevelEx) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_ACCESSLEVELEX, + outAccessLevelEx, &UA_TYPES[UA_TYPES_UINT32]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readUserAccessLevelAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_Byte *outUserAccessLevel) { + return __UA_Client_readAttribute(client, &nodeId, + UA_ATTRIBUTEID_USERACCESSLEVEL, + outUserAccessLevel, + &UA_TYPES[UA_TYPES_BYTE]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readMinimumSamplingIntervalAttribute(UA_Client *client, + const UA_NodeId nodeId, + UA_Double *outMinSamplingInterval) { + return __UA_Client_readAttribute(client, &nodeId, + UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, + outMinSamplingInterval, + &UA_TYPES[UA_TYPES_DOUBLE]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readHistorizingAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_Boolean *outHistorizing) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_HISTORIZING, + outHistorizing, &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readExecutableAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_Boolean *outExecutable) { + return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_EXECUTABLE, + outExecutable, &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE UA_StatusCode +UA_Client_readUserExecutableAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_Boolean *outUserExecutable) { + return __UA_Client_readAttribute(client, &nodeId, + UA_ATTRIBUTEID_USEREXECUTABLE, + outUserExecutable, + &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +/** + * Historical Access + * ^^^^^^^^^^^^^^^^^ + * The following functions can be used to read a single node historically. + * Use the regular service to read several nodes at once. */ + +typedef UA_Boolean +(*UA_HistoricalIteratorCallback)( + UA_Client *client, const UA_NodeId *nodeId, UA_Boolean moreDataAvailable, + const UA_ExtensionObject *data, void *callbackContext); + +UA_StatusCode UA_EXPORT +UA_Client_HistoryRead_events( + UA_Client *client, const UA_NodeId *nodeId, + const UA_HistoricalIteratorCallback callback, UA_DateTime startTime, + UA_DateTime endTime, UA_String indexRange, const UA_EventFilter filter, + UA_UInt32 numValuesPerNode, UA_TimestampsToReturn timestampsToReturn, + void *callbackContext); + +UA_StatusCode UA_EXPORT +UA_Client_HistoryRead_raw( + UA_Client *client, const UA_NodeId *nodeId, + const UA_HistoricalIteratorCallback callback, UA_DateTime startTime, + UA_DateTime endTime, UA_String indexRange, UA_Boolean returnBounds, + UA_UInt32 numValuesPerNode, UA_TimestampsToReturn timestampsToReturn, + void *callbackContext); + +UA_StatusCode UA_EXPORT +UA_Client_HistoryRead_modified( + UA_Client *client, const UA_NodeId *nodeId, + const UA_HistoricalIteratorCallback callback, UA_DateTime startTime, + UA_DateTime endTime, UA_String indexRange, UA_Boolean returnBounds, + UA_UInt32 numValuesPerNode, UA_TimestampsToReturn timestampsToReturn, + void *callbackContext); + +UA_StatusCode UA_EXPORT +UA_Client_HistoryUpdate_insert( + UA_Client *client, const UA_NodeId *nodeId, UA_DataValue *value); + +UA_StatusCode UA_EXPORT +UA_Client_HistoryUpdate_replace( + UA_Client *client, const UA_NodeId *nodeId, UA_DataValue *value); + +UA_StatusCode UA_EXPORT +UA_Client_HistoryUpdate_update( + UA_Client *client, const UA_NodeId *nodeId, UA_DataValue *value); + +UA_StatusCode UA_EXPORT +UA_Client_HistoryUpdate_deleteRaw( + UA_Client *client, const UA_NodeId *nodeId, + UA_DateTime startTimestamp, UA_DateTime endTimestamp); + +/** + * Write Attributes + * ^^^^^^^^^^^^^^^^ + * + * The following functions can be use to write a single node attribute at a + * time. Use the regular write service to write several attributes at once. */ + +/* Don't call this function, use the typed versions */ +UA_StatusCode UA_EXPORT +__UA_Client_writeAttribute(UA_Client *client, const UA_NodeId *nodeId, + UA_AttributeId attributeId, const void *in, + const UA_DataType *inDataType); + +static UA_INLINE UA_StatusCode +UA_Client_writeNodeIdAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_NodeId *newNodeId) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_NODEID, + newNodeId, &UA_TYPES[UA_TYPES_NODEID]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeNodeClassAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_NodeClass *newNodeClass) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_NODECLASS, + newNodeClass, &UA_TYPES[UA_TYPES_NODECLASS]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeBrowseNameAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_QualifiedName *newBrowseName) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_BROWSENAME, + newBrowseName, + &UA_TYPES[UA_TYPES_QUALIFIEDNAME]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeDisplayNameAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_LocalizedText *newDisplayName) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_DISPLAYNAME, + newDisplayName, + &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeDescriptionAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_LocalizedText *newDescription) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_DESCRIPTION, + newDescription, + &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeWriteMaskAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_UInt32 *newWriteMask) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_WRITEMASK, + newWriteMask, &UA_TYPES[UA_TYPES_UINT32]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeUserWriteMaskAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_UInt32 *newUserWriteMask) { + return __UA_Client_writeAttribute(client, &nodeId, + UA_ATTRIBUTEID_USERWRITEMASK, + newUserWriteMask, + &UA_TYPES[UA_TYPES_UINT32]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeIsAbstractAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_Boolean *newIsAbstract) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_ISABSTRACT, + newIsAbstract, &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeSymmetricAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_Boolean *newSymmetric) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_SYMMETRIC, + newSymmetric, &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeInverseNameAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_LocalizedText *newInverseName) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_INVERSENAME, + newInverseName, + &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeContainsNoLoopsAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_Boolean *newContainsNoLoops) { + return __UA_Client_writeAttribute(client, &nodeId, + UA_ATTRIBUTEID_CONTAINSNOLOOPS, + newContainsNoLoops, + &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeEventNotifierAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_Byte *newEventNotifier) { + return __UA_Client_writeAttribute(client, &nodeId, + UA_ATTRIBUTEID_EVENTNOTIFIER, + newEventNotifier, + &UA_TYPES[UA_TYPES_BYTE]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeValueAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_Variant *newValue) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_VALUE, + newValue, &UA_TYPES[UA_TYPES_VARIANT]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeValueAttribute_scalar(UA_Client *client, const UA_NodeId nodeId, + const void *newValue, + const UA_DataType *valueType) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_VALUE, + newValue, valueType); +} + +/* Write a DataValue that can include timestamps and status codes */ +static UA_INLINE UA_StatusCode +UA_Client_writeValueAttributeEx(UA_Client *client, const UA_NodeId nodeId, + const UA_DataValue *newValue) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_VALUE, + newValue, &UA_TYPES[UA_TYPES_DATAVALUE]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeDataTypeAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_NodeId *newDataType) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_DATATYPE, + newDataType, &UA_TYPES[UA_TYPES_NODEID]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeValueRankAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_Int32 *newValueRank) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_VALUERANK, + newValueRank, &UA_TYPES[UA_TYPES_INT32]); +} + +UA_StatusCode UA_EXPORT +UA_Client_writeArrayDimensionsAttribute(UA_Client *client, const UA_NodeId nodeId, + size_t newArrayDimensionsSize, + const UA_UInt32 *newArrayDimensions); + +static UA_INLINE UA_StatusCode +UA_Client_writeAccessLevelAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_Byte *newAccessLevel) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_ACCESSLEVEL, + newAccessLevel, &UA_TYPES[UA_TYPES_BYTE]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeAccessLevelExAttribute(UA_Client *client, const UA_NodeId nodeId, + UA_UInt32 *newAccessLevelEx) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_ACCESSLEVELEX, + newAccessLevelEx, &UA_TYPES[UA_TYPES_UINT32]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeUserAccessLevelAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_Byte *newUserAccessLevel) { + return __UA_Client_writeAttribute(client, &nodeId, + UA_ATTRIBUTEID_USERACCESSLEVEL, + newUserAccessLevel, + &UA_TYPES[UA_TYPES_BYTE]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeMinimumSamplingIntervalAttribute(UA_Client *client, + const UA_NodeId nodeId, + const UA_Double *newMinInterval) { + return __UA_Client_writeAttribute(client, &nodeId, + UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, + newMinInterval, &UA_TYPES[UA_TYPES_DOUBLE]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeHistorizingAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_Boolean *newHistorizing) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_HISTORIZING, + newHistorizing, &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeExecutableAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_Boolean *newExecutable) { + return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_EXECUTABLE, + newExecutable, &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeUserExecutableAttribute(UA_Client *client, const UA_NodeId nodeId, + const UA_Boolean *newUserExecutable) { + return __UA_Client_writeAttribute(client, &nodeId, + UA_ATTRIBUTEID_USEREXECUTABLE, + newUserExecutable, + &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +/** + * Method Calling + * ^^^^^^^^^^^^^^ */ + +UA_StatusCode UA_EXPORT +UA_Client_call(UA_Client *client, + const UA_NodeId objectId, const UA_NodeId methodId, + size_t inputSize, const UA_Variant *input, + size_t *outputSize, UA_Variant **output); + +/** + * Node Management + * ^^^^^^^^^^^^^^^ + * See the section on :ref:`server-side node management `. */ + +UA_StatusCode UA_EXPORT +UA_Client_addReference(UA_Client *client, const UA_NodeId sourceNodeId, + const UA_NodeId referenceTypeId, UA_Boolean isForward, + const UA_String targetServerUri, + const UA_ExpandedNodeId targetNodeId, + UA_NodeClass targetNodeClass); + +UA_StatusCode UA_EXPORT +UA_Client_deleteReference(UA_Client *client, const UA_NodeId sourceNodeId, + const UA_NodeId referenceTypeId, UA_Boolean isForward, + const UA_ExpandedNodeId targetNodeId, + UA_Boolean deleteBidirectional); + +UA_StatusCode UA_EXPORT +UA_Client_deleteNode(UA_Client *client, const UA_NodeId nodeId, + UA_Boolean deleteTargetReferences); + +/* Don't call this function, use the typed versions */ +UA_StatusCode UA_EXPORT +__UA_Client_addNode(UA_Client *client, const UA_NodeClass nodeClass, + const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_NodeId typeDefinition, const UA_NodeAttributes *attr, + const UA_DataType *attributeType, UA_NodeId *outNewNodeId); + +static UA_INLINE UA_StatusCode +UA_Client_addVariableNode(UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_NodeId typeDefinition, + const UA_VariableAttributes attr, + UA_NodeId *outNewNodeId) { + return __UA_Client_addNode(client, UA_NODECLASS_VARIABLE, requestedNewNodeId, + parentNodeId, referenceTypeId, browseName, + typeDefinition, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], + outNewNodeId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addVariableTypeNode(UA_Client *client, + const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_VariableTypeAttributes attr, + UA_NodeId *outNewNodeId) { + return __UA_Client_addNode(client, UA_NODECLASS_VARIABLETYPE, + requestedNewNodeId, + parentNodeId, referenceTypeId, browseName, + UA_NODEID_NULL, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES], + outNewNodeId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addObjectNode(UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_NodeId typeDefinition, + const UA_ObjectAttributes attr, UA_NodeId *outNewNodeId) { + return __UA_Client_addNode(client, UA_NODECLASS_OBJECT, requestedNewNodeId, + parentNodeId, referenceTypeId, browseName, + typeDefinition, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], outNewNodeId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addObjectTypeNode(UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_ObjectTypeAttributes attr, + UA_NodeId *outNewNodeId) { + return __UA_Client_addNode(client, UA_NODECLASS_OBJECTTYPE, requestedNewNodeId, + parentNodeId, referenceTypeId, browseName, + UA_NODEID_NULL, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES], + outNewNodeId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addViewNode(UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_ViewAttributes attr, + UA_NodeId *outNewNodeId) { + return __UA_Client_addNode(client, UA_NODECLASS_VIEW, requestedNewNodeId, + parentNodeId, referenceTypeId, browseName, + UA_NODEID_NULL, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_VIEWATTRIBUTES], outNewNodeId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addReferenceTypeNode(UA_Client *client, + const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_ReferenceTypeAttributes attr, + UA_NodeId *outNewNodeId) { + return __UA_Client_addNode(client, UA_NODECLASS_REFERENCETYPE, + requestedNewNodeId, + parentNodeId, referenceTypeId, browseName, + UA_NODEID_NULL, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES], + outNewNodeId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addDataTypeNode(UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_DataTypeAttributes attr, + UA_NodeId *outNewNodeId) { + return __UA_Client_addNode(client, UA_NODECLASS_DATATYPE, requestedNewNodeId, + parentNodeId, referenceTypeId, browseName, + UA_NODEID_NULL, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES], + outNewNodeId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addMethodNode(UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_MethodAttributes attr, + UA_NodeId *outNewNodeId) { + return __UA_Client_addNode(client, UA_NODECLASS_METHOD, requestedNewNodeId, + parentNodeId, referenceTypeId, browseName, + UA_NODEID_NULL, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_METHODATTRIBUTES], outNewNodeId); +} + +/** + * Misc Highlevel Functionality + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ + +/* Get the namespace-index of a namespace-URI + * + * @param client The UA_Client struct for this connection + * @param namespaceUri The interested namespace URI + * @param namespaceIndex The namespace index of the URI. The value is unchanged + * in case of an error + * @return Indicates whether the operation succeeded or returns an error code */ +UA_StatusCode UA_EXPORT +UA_Client_NamespaceGetIndex(UA_Client *client, UA_String *namespaceUri, + UA_UInt16 *namespaceIndex); + +#ifndef HAVE_NODEITER_CALLBACK +#define HAVE_NODEITER_CALLBACK +/* Iterate over all nodes referenced by parentNodeId by calling the callback + * function for each child node */ +typedef UA_StatusCode +(*UA_NodeIteratorCallback)(UA_NodeId childId, UA_Boolean isInverse, + UA_NodeId referenceTypeId, void *handle); +#endif + +UA_StatusCode UA_EXPORT +UA_Client_forEachChildNodeCall( + UA_Client *client, UA_NodeId parentNodeId, + UA_NodeIteratorCallback callback, void *handle); + +_UA_END_DECLS + +#endif /* UA_CLIENT_HIGHLEVEL_H_ */ diff --git a/product/src/fes/include/open62541/client_highlevel_async.h b/product/src/fes/include/open62541/client_highlevel_async.h new file mode 100644 index 00000000..5efc051b --- /dev/null +++ b/product/src/fes/include/open62541/client_highlevel_async.h @@ -0,0 +1,805 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2018 (c) Thomas Stalder, Blue Time Concept SA + * Copyright 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + */ + +#ifndef UA_CLIENT_HIGHLEVEL_ASYNC_H_ +#define UA_CLIENT_HIGHLEVEL_ASYNC_H_ + +#include + +_UA_BEGIN_DECLS + +/** + * .. _client_async: + * + * Async Services + * ^^^^^^^^^^^^^^ + * + * Call OPC UA Services asynchronously with a callback. The (optional) requestId + * output can be used to cancel the service while it is still pending. */ + +typedef void +(*UA_ClientAsyncReadCallback)( + UA_Client *client, void *userdata, + UA_UInt32 requestId, UA_ReadResponse *rr); + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Client_sendAsyncReadRequest( + UA_Client *client, UA_ReadRequest *request, + UA_ClientAsyncReadCallback readCallback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_AsyncService( + client, request, &UA_TYPES[UA_TYPES_READREQUEST], + (UA_ClientAsyncServiceCallback)readCallback, + &UA_TYPES[UA_TYPES_READRESPONSE], userdata, reqId); +} + +typedef void +(*UA_ClientAsyncWriteCallback)( + UA_Client *client, void *userdata, + UA_UInt32 requestId, UA_WriteResponse *wr); + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Client_sendAsyncWriteRequest( + UA_Client *client, UA_WriteRequest *request, + UA_ClientAsyncWriteCallback writeCallback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_AsyncService( + client, request, &UA_TYPES[UA_TYPES_WRITEREQUEST], + (UA_ClientAsyncServiceCallback)writeCallback, + &UA_TYPES[UA_TYPES_WRITERESPONSE], userdata, reqId); +} + +typedef void +(*UA_ClientAsyncBrowseCallback)( + UA_Client *client, void *userdata, + UA_UInt32 requestId, UA_BrowseResponse *wr); + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Client_sendAsyncBrowseRequest( + UA_Client *client, UA_BrowseRequest *request, + UA_ClientAsyncBrowseCallback browseCallback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_AsyncService( + client, request, &UA_TYPES[UA_TYPES_BROWSEREQUEST], + (UA_ClientAsyncServiceCallback)browseCallback, + &UA_TYPES[UA_TYPES_BROWSERESPONSE], userdata, reqId); +} + +typedef void +(*UA_ClientAsyncBrowseNextCallback)( + UA_Client *client, void *userdata, + UA_UInt32 requestId, UA_BrowseNextResponse *wr); + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Client_sendAsyncBrowseNextRequest( + UA_Client *client, UA_BrowseNextRequest *request, + UA_ClientAsyncBrowseNextCallback browseNextCallback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_AsyncService( + client, request, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST], + (UA_ClientAsyncServiceCallback)browseNextCallback, + &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE], userdata, reqId); +} + +/** + * Asynchronous Operations + * ^^^^^^^^^^^^^^^^^^^^^^^ + * + * Many Services can be called with an array of operations. For example, a + * request to the Read Service contains an array of ReadValueId, each + * corresponding to a single read operation. For convenience, wrappers are + * provided to call single operations for the most common Services. + * + * All async operations have a callback of the following structure: The returned + * StatusCode is split in two parts. The status indicates the overall success of + * the request and the operation. The result argument is non-NULL only if the + * status is no good. */ +typedef void +(*UA_ClientAsyncOperationCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, void *result); + +/** + * Read Attribute + * ^^^^^^^^^^^^^^ + * + * Asynchronously read a single attribute. The attribute is unpacked from the + * response as the datatype of the attribute is known ahead of time. Value + * attributes are variants. + * + * Note that the last argument (value pointer) of the callbacks can be NULL if + * the status of the operation is not good. */ + +/* Reading a single attribute */ +typedef void +(*UA_ClientAsyncReadAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_DataValue *attribute); + +UA_StatusCode UA_EXPORT +UA_Client_readAttribute_async( + UA_Client *client, const UA_ReadValueId *rvi, + UA_TimestampsToReturn timestampsToReturn, + UA_ClientAsyncReadAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single Value attribute */ +typedef void +(*UA_ClientAsyncReadValueAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_DataValue *value); + +UA_StatusCode UA_EXPORT +UA_Client_readValueAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadValueAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single DataType attribute */ +typedef void +(*UA_ClientAsyncReadDataTypeAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_NodeId *dataType); + +UA_StatusCode UA_EXPORT +UA_Client_readDataTypeAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadDataTypeAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single ArrayDimensions attribute. If the status is good, the variant + * carries an UInt32 array. */ +typedef void +(*UA_ClientReadArrayDimensionsAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_Variant *arrayDimensions); + +UA_StatusCode UA_EXPORT +UA_Client_readArrayDimensionsAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientReadArrayDimensionsAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single NodeClass attribute */ +typedef void +(*UA_ClientAsyncReadNodeClassAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_NodeClass *nodeClass); + +UA_StatusCode UA_EXPORT +UA_Client_readNodeClassAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadNodeClassAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single BrowseName attribute */ +typedef void +(*UA_ClientAsyncReadBrowseNameAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_QualifiedName *browseName); + +UA_StatusCode UA_EXPORT +UA_Client_readBrowseNameAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadBrowseNameAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single DisplayName attribute */ +typedef void +(*UA_ClientAsyncReadDisplayNameAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_LocalizedText *displayName); + +UA_StatusCode UA_EXPORT +UA_Client_readDisplayNameAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadDisplayNameAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single Description attribute */ +typedef void +(*UA_ClientAsyncReadDescriptionAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_LocalizedText *description); + +UA_StatusCode UA_EXPORT +UA_Client_readDescriptionAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadDescriptionAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single WriteMask attribute */ +typedef void +(*UA_ClientAsyncReadWriteMaskAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_UInt32 *writeMask); + +UA_StatusCode UA_EXPORT +UA_Client_readWriteMaskAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadWriteMaskAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single UserWriteMask attribute */ +typedef void +(*UA_ClientAsyncReadUserWriteMaskAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_UInt32 *writeMask); + +UA_StatusCode UA_EXPORT +UA_Client_readUserWriteMaskAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadUserWriteMaskAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single IsAbstract attribute */ +typedef void +(*UA_ClientAsyncReadIsAbstractAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_Boolean *isAbstract); + +UA_StatusCode UA_EXPORT +UA_Client_readIsAbstractAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadIsAbstractAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single Symmetric attribute */ +typedef void +(*UA_ClientAsyncReadSymmetricAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_Boolean *symmetric); + +UA_StatusCode UA_EXPORT +UA_Client_readSymmetricAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadSymmetricAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single InverseName attribute */ +typedef void +(*UA_ClientAsyncReadInverseNameAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_LocalizedText *inverseName); + +UA_StatusCode UA_EXPORT +UA_Client_readInverseNameAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadInverseNameAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single ContainsNoLoops attribute */ +typedef void +(*UA_ClientAsyncReadContainsNoLoopsAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_Boolean *containsNoLoops); + +UA_StatusCode UA_EXPORT +UA_Client_readContainsNoLoopsAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadContainsNoLoopsAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single EventNotifier attribute */ +typedef void +(*UA_ClientAsyncReadEventNotifierAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_Byte *eventNotifier); + +UA_StatusCode UA_EXPORT +UA_Client_readEventNotifierAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadEventNotifierAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single ValueRank attribute */ +typedef void +(*UA_ClientAsyncReadValueRankAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_Int32 *valueRank); + +UA_StatusCode UA_EXPORT +UA_Client_readValueRankAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadValueRankAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single AccessLevel attribute */ +typedef void +(*UA_ClientAsyncReadAccessLevelAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_Byte *accessLevel); + +UA_StatusCode UA_EXPORT +UA_Client_readAccessLevelAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadAccessLevelAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single AccessLevelEx attribute */ +typedef void +(*UA_ClientAsyncReadAccessLevelExAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_UInt32 *accessLevelEx); + +UA_StatusCode UA_EXPORT +UA_Client_readAccessLevelExAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadAccessLevelExAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single UserAccessLevel attribute */ +typedef void +(*UA_ClientAsyncReadUserAccessLevelAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_Byte *userAccessLevel); + +UA_StatusCode UA_EXPORT +UA_Client_readUserAccessLevelAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadUserAccessLevelAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single MinimumSamplingInterval attribute */ +typedef void +(*UA_ClientAsyncReadMinimumSamplingIntervalAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_Double *minimumSamplingInterval); + +UA_StatusCode UA_EXPORT +UA_Client_readMinimumSamplingIntervalAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadMinimumSamplingIntervalAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single Historizing attribute */ +typedef void +(*UA_ClientAsyncReadHistorizingAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_Boolean *historizing); + +UA_StatusCode UA_EXPORT +UA_Client_readHistorizingAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadHistorizingAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single Executable attribute */ +typedef void +(*UA_ClientAsyncReadExecutableAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_Boolean *executable); + +UA_StatusCode UA_EXPORT +UA_Client_readExecutableAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadExecutableAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Read a single UserExecutable attribute */ +typedef void +(*UA_ClientAsyncReadUserExecutableAttributeCallback)( + UA_Client *client, void *userdata, UA_UInt32 requestId, + UA_StatusCode status, UA_Boolean *userExecutable); + +UA_StatusCode UA_EXPORT +UA_Client_readUserExecutableAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + UA_ClientAsyncReadUserExecutableAttributeCallback callback, + void *userdata, UA_UInt32 *requestId); + +/** + * Write Attribute + * ^^^^^^^^^^^^^^^ */ + +UA_StatusCode UA_EXPORT +__UA_Client_writeAttribute_async( + UA_Client *client, const UA_NodeId *nodeId, + UA_AttributeId attributeId, const void *in, + const UA_DataType *inDataType, + UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId); + +static UA_INLINE UA_StatusCode +UA_Client_writeValueAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_Variant *attr, UA_ClientAsyncWriteCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_VALUE, attr, + &UA_TYPES[UA_TYPES_VARIANT], + (UA_ClientAsyncServiceCallback)callback, + userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeNodeIdAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_NodeId *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_NODEID, attr, + &UA_TYPES[UA_TYPES_NODEID], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeNodeClassAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_NodeClass *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_NODECLASS, attr, + &UA_TYPES[UA_TYPES_NODECLASS], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeBrowseNameAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_QualifiedName *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_BROWSENAME, attr, + &UA_TYPES[UA_TYPES_QUALIFIEDNAME], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeDisplayNameAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_LocalizedText *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_DISPLAYNAME, attr, + &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeDescriptionAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_LocalizedText *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_DESCRIPTION, attr, + &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeWriteMaskAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_UInt32 *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_WRITEMASK, attr, + &UA_TYPES[UA_TYPES_UINT32], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeUserWriteMaskAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_UInt32 *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_USERWRITEMASK, attr, + &UA_TYPES[UA_TYPES_UINT32], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeIsAbstractAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_Boolean *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_ISABSTRACT, attr, + &UA_TYPES[UA_TYPES_BOOLEAN], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeSymmetricAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_Boolean *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_SYMMETRIC, attr, + &UA_TYPES[UA_TYPES_BOOLEAN], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeInverseNameAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_LocalizedText *attr, + UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_INVERSENAME, attr, + &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeContainsNoLoopsAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_Boolean *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_CONTAINSNOLOOPS, attr, + &UA_TYPES[UA_TYPES_BOOLEAN], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeEventNotifierAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_Byte *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_EVENTNOTIFIER, attr, + &UA_TYPES[UA_TYPES_BYTE], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeDataTypeAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_NodeId *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_DATATYPE, attr, + &UA_TYPES[UA_TYPES_NODEID], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeValueRankAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_Int32 *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_VALUERANK, attr, + &UA_TYPES[UA_TYPES_INT32], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeAccessLevelAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_Byte *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_ACCESSLEVEL, attr, + &UA_TYPES[UA_TYPES_BYTE], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeAccessLevelExAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_UInt32 *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_ACCESSLEVELEX, attr, + &UA_TYPES[UA_TYPES_UINT32], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeUserAccessLevelAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_Byte *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_USERACCESSLEVEL, attr, + &UA_TYPES[UA_TYPES_BYTE], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeMinimumSamplingIntervalAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_Double *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, + attr, &UA_TYPES[UA_TYPES_DOUBLE], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeHistorizingAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_Boolean *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_HISTORIZING, attr, + &UA_TYPES[UA_TYPES_BOOLEAN], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeExecutableAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_Boolean *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_EXECUTABLE, attr, + &UA_TYPES[UA_TYPES_BOOLEAN], callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_writeUserExecutableAttribute_async( + UA_Client *client, const UA_NodeId nodeId, + const UA_Boolean *attr, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_writeAttribute_async( + client, &nodeId, UA_ATTRIBUTEID_USEREXECUTABLE, attr, + &UA_TYPES[UA_TYPES_BOOLEAN], callback, userdata, reqId); +} + +/** + * Method Calling + * ^^^^^^^^^^^^^^ */ +UA_StatusCode UA_EXPORT +__UA_Client_call_async( + UA_Client *client, + const UA_NodeId objectId, const UA_NodeId methodId, + size_t inputSize, const UA_Variant *input, + UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId); + +typedef void +(*UA_ClientAsyncCallCallback)( + UA_Client *client, void *userdata, + UA_UInt32 requestId, UA_CallResponse *cr); + +static UA_INLINE UA_StatusCode +UA_Client_call_async( + UA_Client *client, + const UA_NodeId objectId, const UA_NodeId methodId, + size_t inputSize, const UA_Variant *input, + UA_ClientAsyncCallCallback callback, void *userdata, + UA_UInt32 *reqId) { + return __UA_Client_call_async( + client, objectId, methodId, inputSize, input, + (UA_ClientAsyncServiceCallback)callback, userdata, reqId); +} + +/** + * Node Management + * ^^^^^^^^^^^^^^^ */ +typedef void +(*UA_ClientAsyncAddNodesCallback)( + UA_Client *client, void *userdata, + UA_UInt32 requestId, UA_AddNodesResponse *ar); + +UA_StatusCode UA_EXPORT +__UA_Client_addNode_async( + UA_Client *client, const UA_NodeClass nodeClass, + const UA_NodeId requestedNewNodeId, const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, const UA_QualifiedName browseName, + const UA_NodeId typeDefinition, const UA_NodeAttributes *attr, + const UA_DataType *attributeType, UA_NodeId *outNewNodeId, + UA_ClientAsyncServiceCallback callback, void *userdata, + UA_UInt32 *reqId); + +static UA_INLINE UA_StatusCode +UA_Client_addVariableNode_async( + UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, const UA_NodeId typeDefinition, + const UA_VariableAttributes attr, UA_NodeId *outNewNodeId, + UA_ClientAsyncAddNodesCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_addNode_async( + client, UA_NODECLASS_VARIABLE, requestedNewNodeId, + parentNodeId, referenceTypeId, browseName, + typeDefinition, (const UA_NodeAttributes *)&attr, + &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], outNewNodeId, + (UA_ClientAsyncServiceCallback)callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addVariableTypeNode_async( + UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_VariableTypeAttributes attr, + UA_NodeId *outNewNodeId, UA_ClientAsyncAddNodesCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_addNode_async( + client, UA_NODECLASS_VARIABLETYPE, + requestedNewNodeId, parentNodeId, + referenceTypeId, browseName, UA_NODEID_NULL, + (const UA_NodeAttributes *)&attr, + &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES], + outNewNodeId, (UA_ClientAsyncServiceCallback)callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addObjectNode_async( + UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, const UA_NodeId typeDefinition, + const UA_ObjectAttributes attr, UA_NodeId *outNewNodeId, + UA_ClientAsyncAddNodesCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_addNode_async( + client, UA_NODECLASS_OBJECT, requestedNewNodeId, + parentNodeId, referenceTypeId, + browseName, typeDefinition, (const UA_NodeAttributes *)&attr, + &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], outNewNodeId, + (UA_ClientAsyncServiceCallback)callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addObjectTypeNode_async( + UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_ObjectTypeAttributes attr, + UA_NodeId *outNewNodeId, UA_ClientAsyncAddNodesCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_addNode_async( + client, UA_NODECLASS_OBJECTTYPE, requestedNewNodeId, parentNodeId, + referenceTypeId, browseName, UA_NODEID_NULL, + (const UA_NodeAttributes *)&attr, + &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES], outNewNodeId, + (UA_ClientAsyncServiceCallback)callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addViewNode_async( + UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, const UA_ViewAttributes attr, + UA_NodeId *outNewNodeId, UA_ClientAsyncAddNodesCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_addNode_async( + client, UA_NODECLASS_VIEW, requestedNewNodeId, + parentNodeId, referenceTypeId, + browseName, UA_NODEID_NULL, (const UA_NodeAttributes *)&attr, + &UA_TYPES[UA_TYPES_VIEWATTRIBUTES], outNewNodeId, + (UA_ClientAsyncServiceCallback)callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addReferenceTypeNode_async( + UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_ReferenceTypeAttributes attr, + UA_NodeId *outNewNodeId, UA_ClientAsyncAddNodesCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_addNode_async( + client, UA_NODECLASS_REFERENCETYPE, requestedNewNodeId, parentNodeId, + referenceTypeId, browseName, UA_NODEID_NULL, + (const UA_NodeAttributes *)&attr, + &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES], outNewNodeId, + (UA_ClientAsyncServiceCallback)callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addDataTypeNode_async( + UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, const UA_DataTypeAttributes attr, + UA_NodeId *outNewNodeId, UA_ClientAsyncAddNodesCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_addNode_async( + client, UA_NODECLASS_DATATYPE, requestedNewNodeId, + parentNodeId, referenceTypeId, browseName, + UA_NODEID_NULL, (const UA_NodeAttributes *)&attr, + &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES], outNewNodeId, + (UA_ClientAsyncServiceCallback)callback, userdata, reqId); +} + +static UA_INLINE UA_StatusCode +UA_Client_addMethodNode_async( + UA_Client *client, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, const UA_MethodAttributes attr, + UA_NodeId *outNewNodeId, UA_ClientAsyncAddNodesCallback callback, + void *userdata, UA_UInt32 *reqId) { + return __UA_Client_addNode_async( + client, UA_NODECLASS_METHOD, requestedNewNodeId, parentNodeId, + referenceTypeId, browseName, UA_NODEID_NULL, + (const UA_NodeAttributes *)&attr, + &UA_TYPES[UA_TYPES_METHODATTRIBUTES], outNewNodeId, + (UA_ClientAsyncServiceCallback)callback, userdata, reqId); +} + +_UA_END_DECLS + +#endif /* UA_CLIENT_HIGHLEVEL_ASYNC_H_ */ diff --git a/product/src/fes/include/open62541/client_subscriptions.h b/product/src/fes/include/open62541/client_subscriptions.h new file mode 100644 index 00000000..9e355590 --- /dev/null +++ b/product/src/fes/include/open62541/client_subscriptions.h @@ -0,0 +1,282 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef UA_CLIENT_SUBSCRIPTIONS_H_ +#define UA_CLIENT_SUBSCRIPTIONS_H_ + +#include + +_UA_BEGIN_DECLS + +/** + * .. _client-subscriptions: + * + * Subscriptions + * ------------- + * + * Subscriptions in OPC UA are asynchronous. That is, the client sends several + * PublishRequests to the server. The server returns PublishResponses with + * notifications. But only when a notification has been generated. The client + * does not wait for the responses and continues normal operations. + * + * Note the difference between Subscriptions and MonitoredItems. Subscriptions + * are used to report back notifications. MonitoredItems are used to generate + * notifications. Every MonitoredItem is attached to exactly one Subscription. + * And a Subscription can contain many MonitoredItems. + * + * The client automatically processes PublishResponses (with a callback) in the + * background and keeps enough PublishRequests in transit. The PublishResponses + * may be recieved during a synchronous service call or in + * ``UA_Client_run_iterate``. See more about + * :ref:`asynchronicity`. + */ + +/* Callbacks defined for Subscriptions */ +typedef void (*UA_Client_DeleteSubscriptionCallback) + (UA_Client *client, UA_UInt32 subId, void *subContext); + +typedef void (*UA_Client_StatusChangeNotificationCallback) + (UA_Client *client, UA_UInt32 subId, void *subContext, + UA_StatusChangeNotification *notification); + +/* Provides default values for a new subscription. + * + * RequestedPublishingInterval: 500.0 [ms] + * RequestedLifetimeCount: 10000 + * RequestedMaxKeepAliveCount: 10 + * MaxNotificationsPerPublish: 0 (unlimited) + * PublishingEnabled: true + * Priority: 0 */ +static UA_INLINE UA_CreateSubscriptionRequest +UA_CreateSubscriptionRequest_default(void) { + UA_CreateSubscriptionRequest request; + UA_CreateSubscriptionRequest_init(&request); + + request.requestedPublishingInterval = 500.0; + request.requestedLifetimeCount = 10000; + request.requestedMaxKeepAliveCount = 10; + request.maxNotificationsPerPublish = 0; + request.publishingEnabled = true; + request.priority = 0; + return request; +} + +UA_CreateSubscriptionResponse UA_EXPORT +UA_Client_Subscriptions_create(UA_Client *client, + const UA_CreateSubscriptionRequest request, + void *subscriptionContext, + UA_Client_StatusChangeNotificationCallback statusChangeCallback, + UA_Client_DeleteSubscriptionCallback deleteCallback); + +UA_StatusCode UA_EXPORT +UA_Client_Subscriptions_create_async(UA_Client *client, + const UA_CreateSubscriptionRequest request, + void *subscriptionContext, + UA_Client_StatusChangeNotificationCallback statusChangeCallback, + UA_Client_DeleteSubscriptionCallback deleteCallback, + UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *requestId); + +UA_ModifySubscriptionResponse UA_EXPORT +UA_Client_Subscriptions_modify(UA_Client *client, + const UA_ModifySubscriptionRequest request); + +UA_StatusCode UA_EXPORT +UA_Client_Subscriptions_modify_async(UA_Client *client, + const UA_ModifySubscriptionRequest request, + UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *requestId); + +UA_DeleteSubscriptionsResponse UA_EXPORT +UA_Client_Subscriptions_delete(UA_Client *client, + const UA_DeleteSubscriptionsRequest request); + +UA_StatusCode UA_EXPORT +UA_Client_Subscriptions_delete_async(UA_Client *client, + const UA_DeleteSubscriptionsRequest request, + UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *requestId); + +/* Delete a single subscription */ +UA_StatusCode UA_EXPORT +UA_Client_Subscriptions_deleteSingle(UA_Client *client, UA_UInt32 subscriptionId); + +static UA_INLINE UA_SetPublishingModeResponse +UA_Client_Subscriptions_setPublishingMode(UA_Client *client, + const UA_SetPublishingModeRequest request) { + UA_SetPublishingModeResponse response; + __UA_Client_Service(client, + &request, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST], + &response, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE]); + return response; +} + +/** + * MonitoredItems + * -------------- + * + * MonitoredItems for Events indicate the ``EventNotifier`` attribute. This + * indicates to the server not to monitor changes of the attribute, but to + * forward Event notifications from that node. + * + * During the creation of a MonitoredItem, the server may return changed + * adjusted parameters. Check the returned ``UA_CreateMonitoredItemsResponse`` + * to get the current parameters. */ + +/* Provides default values for a new monitored item. */ +static UA_INLINE UA_MonitoredItemCreateRequest +UA_MonitoredItemCreateRequest_default(UA_NodeId nodeId) { + UA_MonitoredItemCreateRequest request; + UA_MonitoredItemCreateRequest_init(&request); + request.itemToMonitor.nodeId = nodeId; + request.itemToMonitor.attributeId = UA_ATTRIBUTEID_VALUE; + request.monitoringMode = UA_MONITORINGMODE_REPORTING; + request.requestedParameters.samplingInterval = 250; + request.requestedParameters.discardOldest = true; + request.requestedParameters.queueSize = 1; + return request; +} + +/** + * The clientHandle parameter cannot be set by the user, any value will be replaced + * by the client before sending the request to the server. */ + +/* Callback for the deletion of a MonitoredItem */ +typedef void (*UA_Client_DeleteMonitoredItemCallback) + (UA_Client *client, UA_UInt32 subId, void *subContext, + UA_UInt32 monId, void *monContext); + +/* Callback for DataChange notifications */ +typedef void (*UA_Client_DataChangeNotificationCallback) + (UA_Client *client, UA_UInt32 subId, void *subContext, + UA_UInt32 monId, void *monContext, + UA_DataValue *value); + +/* Callback for Event notifications */ +typedef void (*UA_Client_EventNotificationCallback) + (UA_Client *client, UA_UInt32 subId, void *subContext, + UA_UInt32 monId, void *monContext, + size_t nEventFields, UA_Variant *eventFields); + +/* Don't use to monitor the EventNotifier attribute */ +UA_CreateMonitoredItemsResponse UA_EXPORT +UA_Client_MonitoredItems_createDataChanges(UA_Client *client, + const UA_CreateMonitoredItemsRequest request, void **contexts, + UA_Client_DataChangeNotificationCallback *callbacks, + UA_Client_DeleteMonitoredItemCallback *deleteCallbacks); + +UA_StatusCode UA_EXPORT +UA_Client_MonitoredItems_createDataChanges_async(UA_Client *client, + const UA_CreateMonitoredItemsRequest request, void **contexts, + UA_Client_DataChangeNotificationCallback *callbacks, + UA_Client_DeleteMonitoredItemCallback *deleteCallbacks, + UA_ClientAsyncServiceCallback createCallback, + void *userdata, UA_UInt32 *requestId); + +UA_MonitoredItemCreateResult UA_EXPORT +UA_Client_MonitoredItems_createDataChange(UA_Client *client, + UA_UInt32 subscriptionId, + UA_TimestampsToReturn timestampsToReturn, + const UA_MonitoredItemCreateRequest item, + void *context, UA_Client_DataChangeNotificationCallback callback, + UA_Client_DeleteMonitoredItemCallback deleteCallback); + +/* Monitor the EventNotifier attribute only */ +UA_CreateMonitoredItemsResponse UA_EXPORT +UA_Client_MonitoredItems_createEvents(UA_Client *client, + const UA_CreateMonitoredItemsRequest request, void **contexts, + UA_Client_EventNotificationCallback *callback, + UA_Client_DeleteMonitoredItemCallback *deleteCallback); + +/* Monitor the EventNotifier attribute only */ +UA_StatusCode UA_EXPORT +UA_Client_MonitoredItems_createEvents_async(UA_Client *client, + const UA_CreateMonitoredItemsRequest request, void **contexts, + UA_Client_EventNotificationCallback *callbacks, + UA_Client_DeleteMonitoredItemCallback *deleteCallbacks, + UA_ClientAsyncServiceCallback createCallback, + void *userdata, UA_UInt32 *requestId); + +UA_MonitoredItemCreateResult UA_EXPORT +UA_Client_MonitoredItems_createEvent(UA_Client *client, + UA_UInt32 subscriptionId, + UA_TimestampsToReturn timestampsToReturn, + const UA_MonitoredItemCreateRequest item, + void *context, UA_Client_EventNotificationCallback callback, + UA_Client_DeleteMonitoredItemCallback deleteCallback); + +UA_DeleteMonitoredItemsResponse UA_EXPORT +UA_Client_MonitoredItems_delete(UA_Client *client, + const UA_DeleteMonitoredItemsRequest); + +UA_StatusCode UA_EXPORT +UA_Client_MonitoredItems_delete_async(UA_Client *client, + const UA_DeleteMonitoredItemsRequest request, + UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *requestId); + +UA_StatusCode UA_EXPORT +UA_Client_MonitoredItems_deleteSingle(UA_Client *client, + UA_UInt32 subscriptionId, UA_UInt32 monitoredItemId); + +/* The clientHandle parameter will be filled automatically */ +UA_ModifyMonitoredItemsResponse UA_EXPORT +UA_Client_MonitoredItems_modify(UA_Client *client, + const UA_ModifyMonitoredItemsRequest request); + +UA_StatusCode UA_EXPORT +UA_Client_MonitoredItems_modify_async(UA_Client *client, + const UA_ModifyMonitoredItemsRequest request, + UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *requestId); + +/** + * The following service calls go directly to the server. The MonitoredItem + * settings are not stored in the client. */ + +static UA_INLINE UA_SetMonitoringModeResponse +UA_Client_MonitoredItems_setMonitoringMode(UA_Client *client, + const UA_SetMonitoringModeRequest request) { + UA_SetMonitoringModeResponse response; + __UA_Client_Service(client, + &request, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST], + &response, &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE]); + return response; +} + +static UA_INLINE UA_StatusCode +UA_Client_MonitoredItems_setMonitoringMode_async(UA_Client *client, + const UA_SetMonitoringModeRequest request, + UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *requestId) { + return __UA_Client_AsyncService(client, &request, + &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST], callback, + &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE], + userdata, requestId); +} + +static UA_INLINE UA_SetTriggeringResponse +UA_Client_MonitoredItems_setTriggering(UA_Client *client, + const UA_SetTriggeringRequest request) { + UA_SetTriggeringResponse response; + __UA_Client_Service(client, + &request, &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST], + &response, &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE]); + return response; +} + +static UA_INLINE UA_StatusCode +UA_Client_MonitoredItems_setTriggering_async(UA_Client *client, + const UA_SetTriggeringRequest request, + UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *requestId) { + return __UA_Client_AsyncService(client, &request, + &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST], callback, + &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE], + userdata, requestId); +} + +_UA_END_DECLS + +#endif /* UA_CLIENT_SUBSCRIPTIONS_H_ */ diff --git a/product/src/fes/include/open62541/common.h b/product/src/fes/include/open62541/common.h new file mode 100644 index 00000000..0299a24a --- /dev/null +++ b/product/src/fes/include/open62541/common.h @@ -0,0 +1,286 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2016-2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2016 (c) Sten Grüner + * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2017 (c) Florian Palm + * Copyright 2020 (c) HMS Industrial Networks AB (Author: Jonas Green) + */ + +#ifndef UA_COMMON_H_ +#define UA_COMMON_H_ + +#include +#include + +_UA_BEGIN_DECLS + +/** + * Common Definitions + * ================== + * + * Common definitions for Client, Server and PubSub. + * + * .. _attribute-id: + * + * Attribute Id + * ------------ + * Every node in an OPC UA information model contains attributes depending on + * the node type. Possible attributes are as follows: */ + +typedef enum { + UA_ATTRIBUTEID_NODEID = 1, + UA_ATTRIBUTEID_NODECLASS = 2, + UA_ATTRIBUTEID_BROWSENAME = 3, + UA_ATTRIBUTEID_DISPLAYNAME = 4, + UA_ATTRIBUTEID_DESCRIPTION = 5, + UA_ATTRIBUTEID_WRITEMASK = 6, + UA_ATTRIBUTEID_USERWRITEMASK = 7, + UA_ATTRIBUTEID_ISABSTRACT = 8, + UA_ATTRIBUTEID_SYMMETRIC = 9, + UA_ATTRIBUTEID_INVERSENAME = 10, + UA_ATTRIBUTEID_CONTAINSNOLOOPS = 11, + UA_ATTRIBUTEID_EVENTNOTIFIER = 12, + UA_ATTRIBUTEID_VALUE = 13, + UA_ATTRIBUTEID_DATATYPE = 14, + UA_ATTRIBUTEID_VALUERANK = 15, + UA_ATTRIBUTEID_ARRAYDIMENSIONS = 16, + UA_ATTRIBUTEID_ACCESSLEVEL = 17, + UA_ATTRIBUTEID_USERACCESSLEVEL = 18, + UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL = 19, + UA_ATTRIBUTEID_HISTORIZING = 20, + UA_ATTRIBUTEID_EXECUTABLE = 21, + UA_ATTRIBUTEID_USEREXECUTABLE = 22, + UA_ATTRIBUTEID_DATATYPEDEFINITION = 23, + UA_ATTRIBUTEID_ROLEPERMISSIONS = 24, + UA_ATTRIBUTEID_USERROLEPERMISSIONS = 25, + UA_ATTRIBUTEID_ACCESSRESTRICTIONS = 26, + UA_ATTRIBUTEID_ACCESSLEVELEX = 27 +} UA_AttributeId; + +/** + * .. _access-level-mask: + * + * Access Level Masks + * ------------------ + * The access level to a node is given by the following constants that are ANDed + * with the overall access level. */ + +#define UA_ACCESSLEVELMASK_READ (0x01u << 0u) +#define UA_ACCESSLEVELMASK_WRITE (0x01u << 1u) +#define UA_ACCESSLEVELMASK_HISTORYREAD (0x01u << 2u) +#define UA_ACCESSLEVELMASK_HISTORYWRITE (0x01u << 3u) +#define UA_ACCESSLEVELMASK_SEMANTICCHANGE (0x01u << 4u) +#define UA_ACCESSLEVELMASK_STATUSWRITE (0x01u << 5u) +#define UA_ACCESSLEVELMASK_TIMESTAMPWRITE (0x01u << 6u) + +/** + * .. _write-mask: + * + * Write Masks + * ----------- + * The write mask and user write mask is given by the following constants that + * are ANDed for the overall write mask. Part 3: 5.2.7 Table 2 */ + +#define UA_WRITEMASK_ACCESSLEVEL (0x01u << 0u) +#define UA_WRITEMASK_ARRRAYDIMENSIONS (0x01u << 1u) +#define UA_WRITEMASK_BROWSENAME (0x01u << 2u) +#define UA_WRITEMASK_CONTAINSNOLOOPS (0x01u << 3u) +#define UA_WRITEMASK_DATATYPE (0x01u << 4u) +#define UA_WRITEMASK_DESCRIPTION (0x01u << 5u) +#define UA_WRITEMASK_DISPLAYNAME (0x01u << 6u) +#define UA_WRITEMASK_EVENTNOTIFIER (0x01u << 7u) +#define UA_WRITEMASK_EXECUTABLE (0x01u << 8u) +#define UA_WRITEMASK_HISTORIZING (0x01u << 9u) +#define UA_WRITEMASK_INVERSENAME (0x01u << 10u) +#define UA_WRITEMASK_ISABSTRACT (0x01u << 11u) +#define UA_WRITEMASK_MINIMUMSAMPLINGINTERVAL (0x01u << 12u) +#define UA_WRITEMASK_NODECLASS (0x01u << 13u) +#define UA_WRITEMASK_NODEID (0x01u << 14u) +#define UA_WRITEMASK_SYMMETRIC (0x01u << 15u) +#define UA_WRITEMASK_USERACCESSLEVEL (0x01u << 16u) +#define UA_WRITEMASK_USEREXECUTABLE (0x01u << 17u) +#define UA_WRITEMASK_USERWRITEMASK (0x01u << 18u) +#define UA_WRITEMASK_VALUERANK (0x01u << 19u) +#define UA_WRITEMASK_WRITEMASK (0x01u << 20u) +#define UA_WRITEMASK_VALUEFORVARIABLETYPE (0x01u << 21u) +#define UA_WRITEMASK_ACCESSLEVELEX (0x01u << 25u) + +/** + * .. _valuerank-defines: + * + * ValueRank + * --------- + * The following are the most common ValueRanks used for Variables, + * VariableTypes and method arguments. ValueRanks higher than 3 are valid as + * well (but less common). */ + +#define UA_VALUERANK_SCALAR_OR_ONE_DIMENSION -3 +#define UA_VALUERANK_ANY -2 +#define UA_VALUERANK_SCALAR -1 +#define UA_VALUERANK_ONE_OR_MORE_DIMENSIONS 0 +#define UA_VALUERANK_ONE_DIMENSION 1 +#define UA_VALUERANK_TWO_DIMENSIONS 2 +#define UA_VALUERANK_THREE_DIMENSIONS 3 + +/** + * .. _eventnotifier: + * + * EventNotifier + * ------------- + * The following are the available EventNotifier used for Nodes. + * The EventNotifier Attribute is used to indicate if the Node can be used + * to subscribe to Events or to read / write historic Events. + * Part 3: 5.4 Table 10 */ + +#define UA_EVENTNOTIFIER_SUBSCRIBE_TO_EVENT (0x01u << 0u) +#define UA_EVENTNOTIFIER_HISTORY_READ (0x01u << 2u) +#define UA_EVENTNOTIFIER_HISTORY_WRITE (0x01u << 3u) + +/** + * .. _rule-handling: + * + * Rule Handling + * ------------- + * + * The RuleHanding settings define how error cases that result from rules in the + * OPC UA specification shall be handled. The rule handling can be softened, + * e.g. to workaround misbehaving implementations or to mitigate the impact of + * additional rules that are introduced in later versions of the OPC UA + * specification. */ +typedef enum { + UA_RULEHANDLING_DEFAULT = 0, + UA_RULEHANDLING_ABORT, /* Abort the operation and return an error code */ + UA_RULEHANDLING_WARN, /* Print a message in the logs and continue */ + UA_RULEHANDLING_ACCEPT, /* Continue and disregard the broken rule */ +} UA_RuleHandling; + +/** + * Order + * ----- + * + * The Order enum is used to establish an absolute ordering between elements. + */ + +typedef enum { + UA_ORDER_LESS = -1, + UA_ORDER_EQ = 0, + UA_ORDER_MORE = 1 +} UA_Order; + +/** + * Connection State + * ---------------- */ + +typedef enum { + UA_CONNECTIONSTATE_CLOSED, /* The socket has been closed and the connection + * will be deleted */ + UA_CONNECTIONSTATE_OPENING, /* The socket is open, but the HEL/ACK handshake + * is not done */ + UA_CONNECTIONSTATE_ESTABLISHED,/* The socket is open and the connection + * configured */ + UA_CONNECTIONSTATE_CLOSING /* The socket is closing down */ +} UA_ConnectionState; + + +typedef enum { + UA_SECURECHANNELSTATE_CLOSED = 0, + UA_SECURECHANNELSTATE_REVERSE_LISTENING, + UA_SECURECHANNELSTATE_CONNECTING, + UA_SECURECHANNELSTATE_CONNECTED, + UA_SECURECHANNELSTATE_REVERSE_CONNECTED, + UA_SECURECHANNELSTATE_RHE_SENT, + UA_SECURECHANNELSTATE_HEL_SENT, + UA_SECURECHANNELSTATE_HEL_RECEIVED, + UA_SECURECHANNELSTATE_ACK_SENT, + UA_SECURECHANNELSTATE_ACK_RECEIVED, + UA_SECURECHANNELSTATE_OPN_SENT, + UA_SECURECHANNELSTATE_OPEN, + UA_SECURECHANNELSTATE_CLOSING, +} UA_SecureChannelState; + +typedef enum { + UA_SESSIONSTATE_CLOSED = 0, + UA_SESSIONSTATE_CREATE_REQUESTED, + UA_SESSIONSTATE_CREATED, + UA_SESSIONSTATE_ACTIVATE_REQUESTED, + UA_SESSIONSTATE_ACTIVATED, + UA_SESSIONSTATE_CLOSING +} UA_SessionState; + +/** + * Statistic Counters + * ------------------ + * + * The stack manages statistic counters for SecureChannels and Sessions. + * + * The Session layer counters are matching the counters of the + * ServerDiagnosticsSummaryDataType that are defined in the OPC UA Part 5 + * specification. The SecureChannel counters are not defined in the OPC UA spec, + * but are harmonized with the Session layer counters if possible. */ + +typedef enum { + UA_SHUTDOWNREASON_CLOSE = 0, + UA_SHUTDOWNREASON_REJECT, + UA_SHUTDOWNREASON_SECURITYREJECT, + UA_SHUTDOWNREASON_TIMEOUT, + UA_SHUTDOWNREASON_ABORT, + UA_SHUTDOWNREASON_PURGE +} UA_ShutdownReason; + +typedef struct { + size_t currentChannelCount; + size_t cumulatedChannelCount; + size_t rejectedChannelCount; + size_t channelTimeoutCount; /* only used by servers */ + size_t channelAbortCount; + size_t channelPurgeCount; /* only used by servers */ +} UA_SecureChannelStatistics; + +typedef struct { + size_t currentSessionCount; + size_t cumulatedSessionCount; + size_t securityRejectedSessionCount; /* only used by servers */ + size_t rejectedSessionCount; + size_t sessionTimeoutCount; /* only used by servers */ + size_t sessionAbortCount; /* only used by servers */ +} UA_SessionStatistics; + +/** + * Lifecycle States + * ---------------- + * + * Generic lifecycle states. The STOPPING state indicates that the lifecycle is + * being terminated. But it might take time to (asynchronously) perform a + * graceful shutdown. */ + +typedef enum { + UA_LIFECYCLESTATE_STOPPED = 0, + UA_LIFECYCLESTATE_STARTED, + UA_LIFECYCLESTATE_STOPPING +} UA_LifecycleState; + +/** + * Forward Declarations + * -------------------- + * Opaque pointers used in Client, Server and PubSub. */ + +struct UA_Server; +typedef struct UA_Server UA_Server; + +struct UA_ServerConfig; +typedef struct UA_ServerConfig UA_ServerConfig; + +typedef void (*UA_ServerCallback)(UA_Server *server, void *data); + +struct UA_Client; +typedef struct UA_Client UA_Client; + +/** + * .. include:: util.rst */ + +_UA_END_DECLS + +#endif /* UA_COMMON_H_ */ diff --git a/product/src/fes/include/open62541/config.h b/product/src/fes/include/open62541/config.h new file mode 100644 index 00000000..d7695d23 --- /dev/null +++ b/product/src/fes/include/open62541/config.h @@ -0,0 +1,673 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef UA_CONFIG_H_ +#define UA_CONFIG_H_ + +/** + * open62541 Version + * ----------------- */ +#define UA_OPEN62541_VER_MAJOR 1 +#define UA_OPEN62541_VER_MINOR 4 +#define UA_OPEN62541_VER_PATCH 10 +#define UA_OPEN62541_VER_LABEL "-undefined" /* Release candidate label, etc. */ +#define UA_OPEN62541_VER_COMMIT "unknown-commit" +#define UA_OPEN62541_VERSION "v1.4.10-undefined" + +/** + * Architecture + * ------------ + * Define one of the following. */ + +/* #undef UA_ARCHITECTURE_WIN32 */ + +#if defined _WIN32 || defined __CYGWIN__ +#define UA_ARCHITECTURE_WIN32 +#else +#define UA_ARCHITECTURE_POSIX +#endif + + +/* Select default architecture if none is selected */ +#if !defined(UA_ARCHITECTURE_WIN32) && !defined(UA_ARCHITECTURE_POSIX) +# ifdef _WIN32 +# define UA_ARCHITECTURE_WIN32 +# else +# define UA_ARCHITECTURE_POSIX +# endif +#endif + +/** + * Feature Options + * --------------- + * Changing the feature options has no effect on a pre-compiled library. */ + +#define UA_LOGLEVEL 100 +#ifndef UA_ENABLE_AMALGAMATION +/* #undef UA_ENABLE_AMALGAMATION */ +#endif +#define UA_ENABLE_METHODCALLS +#define UA_ENABLE_NODEMANAGEMENT +#define UA_ENABLE_SUBSCRIPTIONS +#define UA_ENABLE_PUBSUB +/* #undef UA_ENABLE_PUBSUB_ENCRYPTION */ +/* #undef UA_ENABLE_PUBSUB_FILE_CONFIG */ +#define UA_ENABLE_PUBSUB_INFORMATIONMODEL +#define UA_ENABLE_DA +#define UA_ENABLE_DIAGNOSTICS +#define UA_ENABLE_HISTORIZING +#define UA_ENABLE_PARSING +#define UA_ENABLE_SUBSCRIPTIONS_EVENTS +#define UA_ENABLE_JSON_ENCODING +/* #undef UA_ENABLE_XML_ENCODING */ +/* #undef UA_ENABLE_MQTT */ +/* #undef UA_ENABLE_NODESET_INJECTOR */ +/* #undef UA_INFORMATION_MODEL_AUTOLOAD */ +/* #undef UA_ENABLE_ENCRYPTION_MBEDTLS */ +/* #undef UA_ENABLE_CERT_REJECTED_DIR */ +/* #undef UA_ENABLE_TPM2_SECURITY */ +/* #undef UA_ENABLE_ENCRYPTION_OPENSSL */ +/* #undef UA_ENABLE_ENCRYPTION_LIBRESSL */ +#if defined(UA_ENABLE_ENCRYPTION_MBEDTLS) || defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL) +#define UA_ENABLE_ENCRYPTION +#endif +/* #undef UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS */ + +/* Multithreading */ +/* #undef UA_ENABLE_IMMUTABLE_NODES */ +#define UA_MULTITHREADING 100 + +/* Advanced Options */ +#define UA_ENABLE_STATUSCODE_DESCRIPTIONS +#define UA_ENABLE_TYPEDESCRIPTION +/* #undef UA_ENABLE_INLINABLE_EXPORT */ +#define UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS +/* #undef UA_ENABLE_DETERMINISTIC_RNG */ +#define UA_ENABLE_DISCOVERY +/* #undef UA_ENABLE_DISCOVERY_MULTICAST */ +/* #undef UA_ENABLE_QUERY */ +/* #undef UA_ENABLE_MALLOC_SINGLETON */ +#define UA_ENABLE_DISCOVERY_SEMAPHORE +#define UA_GENERATED_NAMESPACE_ZERO +/* #undef UA_GENERATED_NAMESPACE_ZERO_FULL */ +/* #undef UA_ENABLE_PUBSUB_MONITORING */ +/* #undef UA_ENABLE_PUBSUB_BUFMALLOC */ +/* #undef UA_ENABLE_PUBSUB_SKS */ + +/* Options for Debugging */ +#define UA_DEBUG +/* #undef UA_DEBUG_DUMP_PKGS */ +/* #undef UA_DEBUG_FILE_LINE_INFO */ + +/* Options for Tests */ +/* #undef UA_ENABLE_ALLOW_REUSEADDR */ + +/** + * Function Export + * --------------- + * On Win32: Define ``UA_DYNAMIC_LINKING`` and ``UA_DYNAMIC_LINKING_EXPORT`` in + * order to export symbols for a DLL. Define ``UA_DYNAMIC_LINKING`` only to + * import symbols from a DLL.*/ +#define UA_DYNAMIC_LINKING + +/* Shortcuts for extern "C" declarations */ +#if !defined(_UA_BEGIN_DECLS) +# ifdef __cplusplus +# define _UA_BEGIN_DECLS extern "C" { +# else +# define _UA_BEGIN_DECLS +# endif +#endif +#if !defined(_UA_END_DECLS) +# ifdef __cplusplus +# define _UA_END_DECLS } +# else +# define _UA_END_DECLS +# endif +#endif + +/** + * POSIX Feature Flags + * ------------------- + * These feature flags have to be set before including the first POSIX + * header. + * + * Special note for FreeBSD: Defining _XOPEN_SOURCE will hide lots of socket + * definitions as they are not defined by POSIX. Defining _BSD_SOURCE will + * not help as the symbols undergo a consistency check and get adjusted in + * the headers. */ +#ifdef UA_ARCHITECTURE_POSIX +# if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) +# define _XOPEN_SOURCE 600 +# endif +# ifndef _DEFAULT_SOURCE +# define _DEFAULT_SOURCE +# endif + +/* On older systems we need to define _BSD_SOURCE. + * _DEFAULT_SOURCE is an alias for that. */ +# ifndef _BSD_SOURCE +# define _BSD_SOURCE +# endif + +/* Define _GNU_SOURCE to get functions like poll. Comment this out to + * only use standard POSIX definitions. */ +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif + +#define UA_HAS_GETIFADDR 1 +#endif + +/** + * C99 Definitions + * --------------- */ +#include +#include +#include +#include +#include +#include + +/** + * Inline Functions + * ---------------- */ +#ifdef _MSC_VER +# define UA_INLINE __inline +#else +# define UA_INLINE inline +#endif + +/* An inlinable method is typically defined as "static inline". Some + * applications, such as language bindings with a C FFI (foreign function + * interface), can however not work with static inline methods. These can set + * the global UA_ENABLE_INLINABLE_EXPORT macro which causes all inlinable + * methods to be exported as a regular public API method. + * + * Note that UA_ENABLE_INLINABLE_EXPORT has a negative impact for both size and + * performance of the library. */ +#if defined(UA_ENABLE_INLINABLE_EXPORT) && defined(UA_INLINABLE_IMPL) +# define UA_INLINABLE(decl, impl) UA_EXPORT decl; decl impl +#elif defined(UA_ENABLE_INLINABLE_EXPORT) +# define UA_INLINABLE(decl, impl) UA_EXPORT decl; +#else +# define UA_INLINABLE(decl, impl) static UA_INLINE decl impl +#endif + +/** + * Thread-local variables + * ---------------------- */ +#if UA_MULTITHREADING >= 100 +# if defined(__GNUC__) /* Also covers clang */ +# define UA_THREAD_LOCAL __thread +# elif defined(_MSC_VER) +# define UA_THREAD_LOCAL __declspec(thread) +# endif +#endif +#ifndef UA_THREAD_LOCAL +# define UA_THREAD_LOCAL +#endif + +/** + * Atomic Operations + * ----------------- + * + * Atomic operations synchronize across processor cores and enable lockless + * multi-threading. */ + +/* Intrinsic atomic operations are not available everywhere for MSVC. + * Use the win32 API. Prevent duplicate definitions by via winsock2. */ +#if UA_MULTITHREADING >= 100 && defined(_WIN32) +# ifndef _WINSOCKAPI_ +# define _NO_WINSOCKAPI_ +# endif +# define _WINSOCKAPI_ +# include +# ifdef _NO_WINSOCKAPI_ +# undef _WINSOCKAPI_ +# endif +#endif + +static UA_INLINE void * +UA_atomic_xchg(void * volatile * addr, void *newptr) { +#if UA_MULTITHREADING >= 100 && defined(_WIN32) /* Visual Studio */ + return InterlockedExchangePointer(addr, newptr); +#elif UA_MULTITHREADING >= 100 && defined(__GNUC__) /* GCC/Clang */ + return __sync_lock_test_and_set(addr, newptr); +#else +# if UA_MULTITHREADING >= 100 +# warning Atomic operations not implemented +# endif + void *old = *addr; + *addr = newptr; + return old; +#endif +} + +static UA_INLINE void * +UA_atomic_cmpxchg(void * volatile * addr, void *expected, void *newptr) { +#if UA_MULTITHREADING >= 100 && defined(_WIN32) /* Visual Studio */ + return InterlockedCompareExchangePointer(addr, newptr, expected); +#elif UA_MULTITHREADING >= 100 && defined(__GNUC__) /* GCC/Clang */ + return __sync_val_compare_and_swap(addr, expected, newptr); +#else + void *old = *addr; + if(old == expected) + *addr = newptr; + return old; +#endif +} + +/** + * Memory Management + * ----------------- + * + * The flag ``UA_ENABLE_MALLOC_SINGLETON`` enables singleton (global) variables + * with method pointers for memory management (malloc et al.). The method + * pointers can be switched out at runtime. Use-cases for this are testing of + * constrained memory conditions and arena-based custom memory management. + * + * If the flag is undefined, then ``UA_malloc`` etc. are set to the default + * malloc, as defined in ``/arch//ua_architecture.h``. + */ + +#ifdef UA_ENABLE_MALLOC_SINGLETON +extern UA_THREAD_LOCAL void * (*UA_mallocSingleton)(size_t size); +extern UA_THREAD_LOCAL void (*UA_freeSingleton)(void *ptr); +extern UA_THREAD_LOCAL void * (*UA_callocSingleton)(size_t nelem, size_t elsize); +extern UA_THREAD_LOCAL void * (*UA_reallocSingleton)(void *ptr, size_t size); +# define UA_malloc(size) UA_mallocSingleton(size) +# define UA_free(ptr) UA_freeSingleton(ptr) +# define UA_calloc(num, size) UA_callocSingleton(num, size) +# define UA_realloc(ptr, size) UA_reallocSingleton(ptr, size) +#else +# include +# define UA_free free +# define UA_malloc malloc +# define UA_calloc calloc +# define UA_realloc realloc +#endif + +/* Stack-allocation of memory. Use C99 variable-length arrays if possible. + * Otherwise revert to alloca. Note that alloca is not supported on some + * plattforms. */ +#ifndef UA_STACKARRAY +# if defined(__GNUC__) || defined(__clang__) +# define UA_STACKARRAY(TYPE, NAME, SIZE) TYPE NAME[SIZE] +# else +# if defined(__GNUC__) || defined(__clang__) +# define UA_alloca(size) __builtin_alloca (size) +# elif defined(_WIN32) +# define UA_alloca(SIZE) _alloca(SIZE) +# else +# include +# define UA_alloca(SIZE) alloca(SIZE) +# endif +# define UA_STACKARRAY(TYPE, NAME, SIZE) \ + /* cppcheck-suppress allocaCalled */ \ + TYPE *(NAME) = (TYPE*)UA_alloca(sizeof(TYPE) * (SIZE)) +# endif +#endif + +/** + * Assertions + * ---------- + * The assert macro is disabled by defining NDEBUG. It is often forgotten to + * include -DNDEBUG in the compiler flags when using the single-file release. So + * we make assertions dependent on the UA_DEBUG definition handled by CMake. */ +#ifdef UA_DEBUG +# include +# define UA_assert(ignore) assert(ignore) +#else +# define UA_assert(ignore) do {} while(0) +#endif + +/* Outputs an error message at compile time if the assert fails. + * Example usage: + * UA_STATIC_ASSERT(sizeof(long)==7, use_another_compiler_luke) + * See: https://stackoverflow.com/a/4815532/869402 */ +#if defined(__cplusplus) && __cplusplus >= 201103L /* C++11 or above */ +# define UA_STATIC_ASSERT(cond,msg) static_assert(cond, #msg) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L /* C11 or above */ +# define UA_STATIC_ASSERT(cond,msg) _Static_assert(cond, #msg) +#elif defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) /* GCC, Clang, MSC */ +# define UA_CTASTR2(pre,post) pre ## post +# define UA_CTASTR(pre,post) UA_CTASTR2(pre,post) +# ifndef __COUNTER__ /* PPC GCC fix */ +# define __COUNTER__ __LINE__ +# endif +# define UA_STATIC_ASSERT(cond,msg) \ + typedef struct { \ + unsigned int UA_CTASTR(static_assertion_failed_,msg) : !!(cond); \ + } UA_CTASTR(static_assertion_failed_,__COUNTER__) +#else /* Everybody else */ +# define UA_STATIC_ASSERT(cond,msg) typedef char static_assertion_##msg[(cond)?1:-1] +#endif + +/** + * Locking for Multithreading + * -------------------------- + * If locking is enabled, the locks must be reentrant. That is, the same thread + * must be able to take the same lock several times. This is required because we + * sometimes call a user-defined callback when the server-lock is still held. + * The user-defined code then should be able to call (public) methods which + * again take the server-lock. */ + +#if UA_MULTITHREADING < 100 + +# define UA_LOCK_INIT(lock) +# define UA_LOCK_DESTROY(lock) +# define UA_LOCK(lock) +# define UA_UNLOCK(lock) +# define UA_LOCK_ASSERT(lock, num) + +#elif defined(UA_ARCHITECTURE_WIN32) + +typedef struct { + /* Critical sections on win32 are always recursive */ + CRITICAL_SECTION mutex; + int mutexCounter; +} UA_Lock; + +static UA_INLINE void +UA_LOCK_INIT(UA_Lock *lock) { + InitializeCriticalSection(&lock->mutex); + lock->mutexCounter = 0; +} + +static UA_INLINE void +UA_LOCK_DESTROY(UA_Lock *lock) { + DeleteCriticalSection(&lock->mutex); +} + +static UA_INLINE void +UA_LOCK(UA_Lock *lock) { + EnterCriticalSection(&lock->mutex); + ++lock->mutexCounter; +} + +static UA_INLINE void +UA_UNLOCK(UA_Lock *lock) { + --lock->mutexCounter; + LeaveCriticalSection(&lock->mutex); +} + +static UA_INLINE void +UA_LOCK_ASSERT(UA_Lock *lock, int num) { + UA_assert(num <= 0 || lock->mutexCounter > 0); +} + +#elif defined(UA_ARCHITECTURE_POSIX) + +#include + +typedef struct { + pthread_mutex_t mutex; + int mutexCounter; +} UA_Lock; + +static UA_INLINE void +UA_LOCK_INIT(UA_Lock *lock) { + pthread_mutexattr_t mattr; + pthread_mutexattr_init(&mattr); + pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&lock->mutex, &mattr); + lock->mutexCounter = 0; +} + +static UA_INLINE void +UA_LOCK_DESTROY(UA_Lock *lock) { + pthread_mutex_destroy(&lock->mutex); +} + +static UA_INLINE void +UA_LOCK(UA_Lock *lock) { + pthread_mutex_lock(&lock->mutex); + lock->mutexCounter++; +} + +static UA_INLINE void +UA_UNLOCK(UA_Lock *lock) { + lock->mutexCounter--; + pthread_mutex_unlock(&lock->mutex); +} + +static UA_INLINE void +UA_LOCK_ASSERT(UA_Lock *lock, int num) { + UA_assert(num <= 0 || lock->mutexCounter > 0); +} + +#endif + +/** + * Dynamic Linking + * --------------- + * Explicit attribute for functions to be exported in a shared library. */ +#if defined(_WIN32) && defined(UA_DYNAMIC_LINKING) +# ifdef UA_DYNAMIC_LINKING_EXPORT /* export dll */ +# ifdef __GNUC__ +# define UA_EXPORT __attribute__ ((dllexport)) +# else +# define UA_EXPORT __declspec(dllexport) +# endif +# else /* import dll */ +# ifdef __GNUC__ +# define UA_EXPORT __attribute__ ((dllimport)) +# else +# define UA_EXPORT __declspec(dllimport) +# endif +# endif +#else /* non win32 */ +# if __GNUC__ || __clang__ +# define UA_EXPORT __attribute__ ((visibility ("default"))) +# endif +#endif +#ifndef UA_EXPORT +# define UA_EXPORT /* fallback to default */ +#endif + +/** + * Threadsafe functions + * -------------------- + * Functions that can be called from independent threads are marked with + * the UA_THREADSAFE macro. This is currently only an information for the + * developer. It can be used in the future for instrumentation and static + * code analysis. */ +#define UA_THREADSAFE + +/** + * Non-aliasing pointers + * -------------------- */ +#ifdef _MSC_VER +# define UA_RESTRICT __restrict +#elif defined(__GNUC__) +# define UA_RESTRICT __restrict__ +#elif defined(__CODEGEARC__) +# define UA_RESTRICT _RESTRICT +#else +# define UA_RESTRICT restrict +#endif + +/** + * Likely/Unlikely Conditions + * -------------------------- + * Condition is likely/unlikely, to help branch prediction. */ +#if defined(__GNUC__) || defined(__clang__) +# define UA_LIKELY(x) __builtin_expect((x), 1) +# define UA_UNLIKELY(x) __builtin_expect((x), 0) +#else +# define UA_LIKELY(x) x +# define UA_UNLIKELY(x) x +#endif + +/** + * Function attributes + * ------------------- */ +#if defined(__GNUC__) || defined(__clang__) +# define UA_FUNC_ATTR_MALLOC __attribute__((malloc)) +# define UA_FUNC_ATTR_PURE __attribute__ ((pure)) +# define UA_FUNC_ATTR_CONST __attribute__((const)) +# define UA_FUNC_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# define UA_FORMAT(X,Y) __attribute__ ((format (printf, X, Y))) +#elif defined(_MSC_VER) && _MSC_VER >= 1800 +# include +# define UA_FUNC_ATTR_MALLOC +# define UA_FUNC_ATTR_PURE +# define UA_FUNC_ATTR_CONST +# define UA_FUNC_ATTR_WARN_UNUSED_RESULT _Check_return_ +# define UA_FORMAT(X,Y) +#else +# define UA_FUNC_ATTR_MALLOC +# define UA_FUNC_ATTR_PURE +# define UA_FUNC_ATTR_CONST +# define UA_FUNC_ATTR_WARN_UNUSED_RESULT +# define UA_FORMAT(X,Y) +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define UA_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +# define UA_DEPRECATED __declspec(deprecated) +#else +# define UA_DEPRECATED +#endif + +/** + * Internal Attributes + * ------------------- + * These attributes are only defined if the macro UA_INTERNAL is defined. That + * way public methods can be annotated (e.g. to warn for unused results) but + * warnings are only triggered for internal code. */ + +#if defined(UA_INTERNAL) && (defined(__GNUC__) || defined(__clang__)) +# define UA_INTERNAL_DEPRECATED \ + _Pragma ("GCC warning \"Macro is deprecated for internal use\"") +#else +# define UA_INTERNAL_DEPRECATED +#endif + +#if defined(UA_INTERNAL) && (defined(__GNUC__) || defined(__clang__)) +# define UA_INTERNAL_FUNC_ATTR_WARN_UNUSED_RESULT \ + __attribute__((warn_unused_result)) +#else +# define UA_INTERNAL_FUNC_ATTR_WARN_UNUSED_RESULT +#endif + +/** + * Detect Endianness and IEEE 754 floating point + * --------------------------------------------- + * Integers and floating point numbers are transmitted in little-endian (IEEE + * 754 for floating point) encoding. If the target architecture uses the same + * format, numeral datatypes can be memcpy'd (overlayed) on the network buffer. + * Otherwise, a slow default encoding routine is used that works for every + * architecture. + * + * Integer Endianness + * ^^^^^^^^^^^^^^^^^^ + * The definition ``UA_LITTLE_ENDIAN`` is true when the integer representation + * of the target architecture is little-endian. */ +#if defined(_WIN32) +# define UA_LITTLE_ENDIAN 1 +#elif defined(__i386__) || defined(__x86_64__) || defined(__amd64__) +# define UA_LITTLE_ENDIAN 1 +#elif (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) +# define UA_LITTLE_ENDIAN 1 +#elif defined(__linux__) /* Linux (including Android) */ +# include +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define UA_LITTLE_ENDIAN 1 +# endif +#elif defined(__OpenBSD__) /* OpenBSD */ +# include +# if BYTE_ORDER == LITTLE_ENDIAN +# define UA_LITTLE_ENDIAN 1 +# endif +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) /* Other BSD */ +# include +# if _BYTE_ORDER == _LITTLE_ENDIAN +# define UA_LITTLE_ENDIAN 1 +# endif +#elif defined(__APPLE__) /* Apple (MacOS, iOS) */ +# include +# if defined(__LITTLE_ENDIAN__) +# define UA_LITTLE_ENDIAN 1 +# endif +#elif defined(__QNX__) || defined(__QNXNTO__) /* QNX */ +# include +# if defined(__LITTLEENDIAN__) +# define UA_LITTLE_ENDIAN 1 +# endif +#elif defined(_OS9000) /* OS-9 */ +# if defined(_LIL_END) +# define UA_LITTLE_ENDIAN 1 +# endif +#endif +#ifndef UA_LITTLE_ENDIAN +# define UA_LITTLE_ENDIAN 0 +#endif + +/* Can the integers be memcpy'd onto the network buffer? Add additional checks + * here. Some platforms (e.g. QNX) have sizeof(bool) > 1. Manually disable + * overlayed integer encoding if that is the case. */ +#if (UA_LITTLE_ENDIAN == 1) +UA_STATIC_ASSERT(sizeof(bool) == 1, cannot_overlay_integers_with_large_bool); +# define UA_BINARY_OVERLAYABLE_INTEGER 1 +#else +# define UA_BINARY_OVERLAYABLE_INTEGER 0 +#endif + +/** + * Float Endianness + * ^^^^^^^^^^^^^^^^ + * The definition ``UA_FLOAT_IEEE754`` is set to true when the floating point + * number representation of the target architecture is IEEE 754. The definition + * ``UA_FLOAT_LITTLE_ENDIAN`` is set to true when the floating point number + * representation is in little-endian encoding. */ + +#ifndef UA_FLOAT_IEEE754 +#if defined(_WIN32) +# define UA_FLOAT_IEEE754 1 +#elif defined(__i386__) || defined(__x86_64__) || defined(__amd64__) || \ + defined(__ia64__) || defined(__powerpc__) || defined(__sparc__) || \ + defined(__arm__) +# define UA_FLOAT_IEEE754 1 +#elif defined(__STDC_IEC_559__) +# define UA_FLOAT_IEEE754 1 +#elif defined(ESP_PLATFORM) +# define UA_FLOAT_IEEE754 1 +#else +# define UA_FLOAT_IEEE754 0 +#endif +#endif + +/* Wikipedia says (https://en.wikipedia.org/wiki/Endianness): Although the + * ubiquitous x86 processors of today use little-endian storage for all types of + * data (integer, floating point, BCD), there are a number of hardware + * architectures where floating-point numbers are represented in big-endian form + * while integers are represented in little-endian form. */ +#if defined(_WIN32) +# define UA_FLOAT_LITTLE_ENDIAN 1 +#elif defined(__i386__) || defined(__x86_64__) || defined(__amd64__) +# define UA_FLOAT_LITTLE_ENDIAN 1 +#elif defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__) /* Defined only in GCC */ +# define UA_FLOAT_LITTLE_ENDIAN 1 +#elif defined(__FLOAT_WORD_ORDER) && defined(__LITTLE_ENDIAN) && \ + (__FLOAT_WORD_ORDER == __LITTLE_ENDIAN) /* Defined only in GCC */ +# define UA_FLOAT_LITTLE_ENDIAN 1 +#endif +#ifndef UA_FLOAT_LITTLE_ENDIAN +# define UA_FLOAT_LITTLE_ENDIAN 0 +#endif + +/* Only if the floating points are litle-endian **and** in IEEE 754 format can + * we memcpy directly onto the network buffer. */ +#if (UA_FLOAT_IEEE754 == 1) && (UA_FLOAT_LITTLE_ENDIAN == 1) +# define UA_BINARY_OVERLAYABLE_FLOAT 1 +#else +# define UA_BINARY_OVERLAYABLE_FLOAT 0 +#endif + +#endif /* UA_CONFIG_H_ */ diff --git a/product/src/fes/include/open62541/config.h.in b/product/src/fes/include/open62541/config.h.in new file mode 100644 index 00000000..e2461802 --- /dev/null +++ b/product/src/fes/include/open62541/config.h.in @@ -0,0 +1,667 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef UA_CONFIG_H_ +#define UA_CONFIG_H_ + +/** + * open62541 Version + * ----------------- */ +#define UA_OPEN62541_VER_MAJOR ${OPEN62541_VER_MAJOR} +#define UA_OPEN62541_VER_MINOR ${OPEN62541_VER_MINOR} +#define UA_OPEN62541_VER_PATCH ${OPEN62541_VER_PATCH} +#define UA_OPEN62541_VER_LABEL "${OPEN62541_VER_LABEL}" /* Release candidate label, etc. */ +#define UA_OPEN62541_VER_COMMIT "${OPEN62541_VER_COMMIT}" +#define UA_OPEN62541_VERSION "${OPEN62541_VERSION}" + +/** + * Architecture + * ------------ + * Define one of the following. */ + +#cmakedefine UA_ARCHITECTURE_WIN32 +#cmakedefine UA_ARCHITECTURE_POSIX + +/* Select default architecture if none is selected */ +#if !defined(UA_ARCHITECTURE_WIN32) && !defined(UA_ARCHITECTURE_POSIX) +# ifdef _WIN32 +# define UA_ARCHITECTURE_WIN32 +# else +# define UA_ARCHITECTURE_POSIX +# endif +#endif + +/** + * Feature Options + * --------------- + * Changing the feature options has no effect on a pre-compiled library. */ + +#define UA_LOGLEVEL ${UA_LOGLEVEL} +#ifndef UA_ENABLE_AMALGAMATION +#cmakedefine UA_ENABLE_AMALGAMATION +#endif +#cmakedefine UA_ENABLE_METHODCALLS +#cmakedefine UA_ENABLE_NODEMANAGEMENT +#cmakedefine UA_ENABLE_SUBSCRIPTIONS +#cmakedefine UA_ENABLE_PUBSUB +#cmakedefine UA_ENABLE_PUBSUB_ENCRYPTION +#cmakedefine UA_ENABLE_PUBSUB_FILE_CONFIG +#cmakedefine UA_ENABLE_PUBSUB_INFORMATIONMODEL +#cmakedefine UA_ENABLE_DA +#cmakedefine UA_ENABLE_DIAGNOSTICS +#cmakedefine UA_ENABLE_HISTORIZING +#cmakedefine UA_ENABLE_PARSING +#cmakedefine UA_ENABLE_SUBSCRIPTIONS_EVENTS +#cmakedefine UA_ENABLE_JSON_ENCODING +#cmakedefine UA_ENABLE_XML_ENCODING +#cmakedefine UA_ENABLE_MQTT +#cmakedefine UA_ENABLE_NODESET_INJECTOR +#cmakedefine UA_INFORMATION_MODEL_AUTOLOAD +#cmakedefine UA_ENABLE_ENCRYPTION_MBEDTLS +#cmakedefine UA_ENABLE_CERT_REJECTED_DIR +#cmakedefine UA_ENABLE_TPM2_SECURITY +#cmakedefine UA_ENABLE_ENCRYPTION_OPENSSL +#cmakedefine UA_ENABLE_ENCRYPTION_LIBRESSL +#if defined(UA_ENABLE_ENCRYPTION_MBEDTLS) || defined(UA_ENABLE_ENCRYPTION_OPENSSL) || defined(UA_ENABLE_ENCRYPTION_LIBRESSL) +#define UA_ENABLE_ENCRYPTION +#endif +#cmakedefine UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS + +/* Multithreading */ +#cmakedefine UA_ENABLE_IMMUTABLE_NODES +#define UA_MULTITHREADING ${UA_MULTITHREADING} + +/* Advanced Options */ +#cmakedefine UA_ENABLE_STATUSCODE_DESCRIPTIONS +#cmakedefine UA_ENABLE_TYPEDESCRIPTION +#cmakedefine UA_ENABLE_INLINABLE_EXPORT +#cmakedefine UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS +#cmakedefine UA_ENABLE_DETERMINISTIC_RNG +#cmakedefine UA_ENABLE_DISCOVERY +#cmakedefine UA_ENABLE_DISCOVERY_MULTICAST +#cmakedefine UA_ENABLE_QUERY +#cmakedefine UA_ENABLE_MALLOC_SINGLETON +#cmakedefine UA_ENABLE_DISCOVERY_SEMAPHORE +#cmakedefine UA_GENERATED_NAMESPACE_ZERO +#cmakedefine UA_GENERATED_NAMESPACE_ZERO_FULL +#cmakedefine UA_ENABLE_PUBSUB_MONITORING +#cmakedefine UA_ENABLE_PUBSUB_BUFMALLOC +#cmakedefine UA_ENABLE_PUBSUB_SKS + +/* Options for Debugging */ +#cmakedefine UA_DEBUG +#cmakedefine UA_DEBUG_DUMP_PKGS +#cmakedefine UA_DEBUG_FILE_LINE_INFO + +/* Options for Tests */ +#cmakedefine UA_ENABLE_ALLOW_REUSEADDR + +/** + * Function Export + * --------------- + * On Win32: Define ``UA_DYNAMIC_LINKING`` and ``UA_DYNAMIC_LINKING_EXPORT`` in + * order to export symbols for a DLL. Define ``UA_DYNAMIC_LINKING`` only to + * import symbols from a DLL.*/ +#cmakedefine UA_DYNAMIC_LINKING + +/* Shortcuts for extern "C" declarations */ +#if !defined(_UA_BEGIN_DECLS) +# ifdef __cplusplus +# define _UA_BEGIN_DECLS extern "C" { +# else +# define _UA_BEGIN_DECLS +# endif +#endif +#if !defined(_UA_END_DECLS) +# ifdef __cplusplus +# define _UA_END_DECLS } +# else +# define _UA_END_DECLS +# endif +#endif + +/** + * POSIX Feature Flags + * ------------------- + * These feature flags have to be set before including the first POSIX + * header. + * + * Special note for FreeBSD: Defining _XOPEN_SOURCE will hide lots of socket + * definitions as they are not defined by POSIX. Defining _BSD_SOURCE will + * not help as the symbols undergo a consistency check and get adjusted in + * the headers. */ +#ifdef UA_ARCHITECTURE_POSIX +# if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) +# define _XOPEN_SOURCE 600 +# endif +# ifndef _DEFAULT_SOURCE +# define _DEFAULT_SOURCE +# endif + +/* On older systems we need to define _BSD_SOURCE. + * _DEFAULT_SOURCE is an alias for that. */ +# ifndef _BSD_SOURCE +# define _BSD_SOURCE +# endif + +/* Define _GNU_SOURCE to get functions like poll. Comment this out to + * only use standard POSIX definitions. */ +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif + +#define UA_HAS_GETIFADDR 1 +#endif + +/** + * C99 Definitions + * --------------- */ +#include +#include +#include +#include +#include +#include + +/** + * Inline Functions + * ---------------- */ +#ifdef _MSC_VER +# define UA_INLINE __inline +#else +# define UA_INLINE inline +#endif + +/* An inlinable method is typically defined as "static inline". Some + * applications, such as language bindings with a C FFI (foreign function + * interface), can however not work with static inline methods. These can set + * the global UA_ENABLE_INLINABLE_EXPORT macro which causes all inlinable + * methods to be exported as a regular public API method. + * + * Note that UA_ENABLE_INLINABLE_EXPORT has a negative impact for both size and + * performance of the library. */ +#if defined(UA_ENABLE_INLINABLE_EXPORT) && defined(UA_INLINABLE_IMPL) +# define UA_INLINABLE(decl, impl) UA_EXPORT decl; decl impl +#elif defined(UA_ENABLE_INLINABLE_EXPORT) +# define UA_INLINABLE(decl, impl) UA_EXPORT decl; +#else +# define UA_INLINABLE(decl, impl) static UA_INLINE decl impl +#endif + +/** + * Thread-local variables + * ---------------------- */ +#if UA_MULTITHREADING >= 100 +# if defined(__GNUC__) /* Also covers clang */ +# define UA_THREAD_LOCAL __thread +# elif defined(_MSC_VER) +# define UA_THREAD_LOCAL __declspec(thread) +# endif +#endif +#ifndef UA_THREAD_LOCAL +# define UA_THREAD_LOCAL +#endif + +/** + * Atomic Operations + * ----------------- + * + * Atomic operations synchronize across processor cores and enable lockless + * multi-threading. */ + +/* Intrinsic atomic operations are not available everywhere for MSVC. + * Use the win32 API. Prevent duplicate definitions by via winsock2. */ +#if UA_MULTITHREADING >= 100 && defined(_WIN32) +# ifndef _WINSOCKAPI_ +# define _NO_WINSOCKAPI_ +# endif +# define _WINSOCKAPI_ +# include +# ifdef _NO_WINSOCKAPI_ +# undef _WINSOCKAPI_ +# endif +#endif + +static UA_INLINE void * +UA_atomic_xchg(void * volatile * addr, void *newptr) { +#if UA_MULTITHREADING >= 100 && defined(_WIN32) /* Visual Studio */ + return InterlockedExchangePointer(addr, newptr); +#elif UA_MULTITHREADING >= 100 && defined(__GNUC__) /* GCC/Clang */ + return __sync_lock_test_and_set(addr, newptr); +#else +# if UA_MULTITHREADING >= 100 +# warning Atomic operations not implemented +# endif + void *old = *addr; + *addr = newptr; + return old; +#endif +} + +static UA_INLINE void * +UA_atomic_cmpxchg(void * volatile * addr, void *expected, void *newptr) { +#if UA_MULTITHREADING >= 100 && defined(_WIN32) /* Visual Studio */ + return InterlockedCompareExchangePointer(addr, newptr, expected); +#elif UA_MULTITHREADING >= 100 && defined(__GNUC__) /* GCC/Clang */ + return __sync_val_compare_and_swap(addr, expected, newptr); +#else + void *old = *addr; + if(old == expected) + *addr = newptr; + return old; +#endif +} + +/** + * Memory Management + * ----------------- + * + * The flag ``UA_ENABLE_MALLOC_SINGLETON`` enables singleton (global) variables + * with method pointers for memory management (malloc et al.). The method + * pointers can be switched out at runtime. Use-cases for this are testing of + * constrained memory conditions and arena-based custom memory management. + * + * If the flag is undefined, then ``UA_malloc`` etc. are set to the default + * malloc, as defined in ``/arch//ua_architecture.h``. + */ + +#ifdef UA_ENABLE_MALLOC_SINGLETON +extern UA_THREAD_LOCAL void * (*UA_mallocSingleton)(size_t size); +extern UA_THREAD_LOCAL void (*UA_freeSingleton)(void *ptr); +extern UA_THREAD_LOCAL void * (*UA_callocSingleton)(size_t nelem, size_t elsize); +extern UA_THREAD_LOCAL void * (*UA_reallocSingleton)(void *ptr, size_t size); +# define UA_malloc(size) UA_mallocSingleton(size) +# define UA_free(ptr) UA_freeSingleton(ptr) +# define UA_calloc(num, size) UA_callocSingleton(num, size) +# define UA_realloc(ptr, size) UA_reallocSingleton(ptr, size) +#else +# include +# define UA_free free +# define UA_malloc malloc +# define UA_calloc calloc +# define UA_realloc realloc +#endif + +/* Stack-allocation of memory. Use C99 variable-length arrays if possible. + * Otherwise revert to alloca. Note that alloca is not supported on some + * plattforms. */ +#ifndef UA_STACKARRAY +# if defined(__GNUC__) || defined(__clang__) +# define UA_STACKARRAY(TYPE, NAME, SIZE) TYPE NAME[SIZE] +# else +# if defined(__GNUC__) || defined(__clang__) +# define UA_alloca(size) __builtin_alloca (size) +# elif defined(_WIN32) +# define UA_alloca(SIZE) _alloca(SIZE) +# else +# include +# define UA_alloca(SIZE) alloca(SIZE) +# endif +# define UA_STACKARRAY(TYPE, NAME, SIZE) \ + /* cppcheck-suppress allocaCalled */ \ + TYPE *(NAME) = (TYPE*)UA_alloca(sizeof(TYPE) * (SIZE)) +# endif +#endif + +/** + * Assertions + * ---------- + * The assert macro is disabled by defining NDEBUG. It is often forgotten to + * include -DNDEBUG in the compiler flags when using the single-file release. So + * we make assertions dependent on the UA_DEBUG definition handled by CMake. */ +#ifdef UA_DEBUG +# include +# define UA_assert(ignore) assert(ignore) +#else +# define UA_assert(ignore) do {} while(0) +#endif + +/* Outputs an error message at compile time if the assert fails. + * Example usage: + * UA_STATIC_ASSERT(sizeof(long)==7, use_another_compiler_luke) + * See: https://stackoverflow.com/a/4815532/869402 */ +#if defined(__cplusplus) && __cplusplus >= 201103L /* C++11 or above */ +# define UA_STATIC_ASSERT(cond,msg) static_assert(cond, #msg) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L /* C11 or above */ +# define UA_STATIC_ASSERT(cond,msg) _Static_assert(cond, #msg) +#elif defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) /* GCC, Clang, MSC */ +# define UA_CTASTR2(pre,post) pre ## post +# define UA_CTASTR(pre,post) UA_CTASTR2(pre,post) +# ifndef __COUNTER__ /* PPC GCC fix */ +# define __COUNTER__ __LINE__ +# endif +# define UA_STATIC_ASSERT(cond,msg) \ + typedef struct { \ + unsigned int UA_CTASTR(static_assertion_failed_,msg) : !!(cond); \ + } UA_CTASTR(static_assertion_failed_,__COUNTER__) +#else /* Everybody else */ +# define UA_STATIC_ASSERT(cond,msg) typedef char static_assertion_##msg[(cond)?1:-1] +#endif + +/** + * Locking for Multithreading + * -------------------------- + * If locking is enabled, the locks must be reentrant. That is, the same thread + * must be able to take the same lock several times. This is required because we + * sometimes call a user-defined callback when the server-lock is still held. + * The user-defined code then should be able to call (public) methods which + * again take the server-lock. */ + +#if UA_MULTITHREADING < 100 + +# define UA_LOCK_INIT(lock) +# define UA_LOCK_DESTROY(lock) +# define UA_LOCK(lock) +# define UA_UNLOCK(lock) +# define UA_LOCK_ASSERT(lock, num) + +#elif defined(UA_ARCHITECTURE_WIN32) + +typedef struct { + /* Critical sections on win32 are always recursive */ + CRITICAL_SECTION mutex; + int mutexCounter; +} UA_Lock; + +static UA_INLINE void +UA_LOCK_INIT(UA_Lock *lock) { + InitializeCriticalSection(&lock->mutex); + lock->mutexCounter = 0; +} + +static UA_INLINE void +UA_LOCK_DESTROY(UA_Lock *lock) { + DeleteCriticalSection(&lock->mutex); +} + +static UA_INLINE void +UA_LOCK(UA_Lock *lock) { + EnterCriticalSection(&lock->mutex); + ++lock->mutexCounter; +} + +static UA_INLINE void +UA_UNLOCK(UA_Lock *lock) { + --lock->mutexCounter; + LeaveCriticalSection(&lock->mutex); +} + +static UA_INLINE void +UA_LOCK_ASSERT(UA_Lock *lock, int num) { + UA_assert(num <= 0 || lock->mutexCounter > 0); +} + +#elif defined(UA_ARCHITECTURE_POSIX) + +#include + +typedef struct { + pthread_mutex_t mutex; + int mutexCounter; +} UA_Lock; + +static UA_INLINE void +UA_LOCK_INIT(UA_Lock *lock) { + pthread_mutexattr_t mattr; + pthread_mutexattr_init(&mattr); + pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&lock->mutex, &mattr); + lock->mutexCounter = 0; +} + +static UA_INLINE void +UA_LOCK_DESTROY(UA_Lock *lock) { + pthread_mutex_destroy(&lock->mutex); +} + +static UA_INLINE void +UA_LOCK(UA_Lock *lock) { + pthread_mutex_lock(&lock->mutex); + lock->mutexCounter++; +} + +static UA_INLINE void +UA_UNLOCK(UA_Lock *lock) { + lock->mutexCounter--; + pthread_mutex_unlock(&lock->mutex); +} + +static UA_INLINE void +UA_LOCK_ASSERT(UA_Lock *lock, int num) { + UA_assert(num <= 0 || lock->mutexCounter > 0); +} + +#endif + +/** + * Dynamic Linking + * --------------- + * Explicit attribute for functions to be exported in a shared library. */ +#if defined(_WIN32) && defined(UA_DYNAMIC_LINKING) +# ifdef UA_DYNAMIC_LINKING_EXPORT /* export dll */ +# ifdef __GNUC__ +# define UA_EXPORT __attribute__ ((dllexport)) +# else +# define UA_EXPORT __declspec(dllexport) +# endif +# else /* import dll */ +# ifdef __GNUC__ +# define UA_EXPORT __attribute__ ((dllimport)) +# else +# define UA_EXPORT __declspec(dllimport) +# endif +# endif +#else /* non win32 */ +# if __GNUC__ || __clang__ +# define UA_EXPORT __attribute__ ((visibility ("default"))) +# endif +#endif +#ifndef UA_EXPORT +# define UA_EXPORT /* fallback to default */ +#endif + +/** + * Threadsafe functions + * -------------------- + * Functions that can be called from independent threads are marked with + * the UA_THREADSAFE macro. This is currently only an information for the + * developer. It can be used in the future for instrumentation and static + * code analysis. */ +#define UA_THREADSAFE + +/** + * Non-aliasing pointers + * -------------------- */ +#ifdef _MSC_VER +# define UA_RESTRICT __restrict +#elif defined(__GNUC__) +# define UA_RESTRICT __restrict__ +#elif defined(__CODEGEARC__) +# define UA_RESTRICT _RESTRICT +#else +# define UA_RESTRICT restrict +#endif + +/** + * Likely/Unlikely Conditions + * -------------------------- + * Condition is likely/unlikely, to help branch prediction. */ +#if defined(__GNUC__) || defined(__clang__) +# define UA_LIKELY(x) __builtin_expect((x), 1) +# define UA_UNLIKELY(x) __builtin_expect((x), 0) +#else +# define UA_LIKELY(x) x +# define UA_UNLIKELY(x) x +#endif + +/** + * Function attributes + * ------------------- */ +#if defined(__GNUC__) || defined(__clang__) +# define UA_FUNC_ATTR_MALLOC __attribute__((malloc)) +# define UA_FUNC_ATTR_PURE __attribute__ ((pure)) +# define UA_FUNC_ATTR_CONST __attribute__((const)) +# define UA_FUNC_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# define UA_FORMAT(X,Y) __attribute__ ((format (printf, X, Y))) +#elif defined(_MSC_VER) && _MSC_VER >= 1800 +# include +# define UA_FUNC_ATTR_MALLOC +# define UA_FUNC_ATTR_PURE +# define UA_FUNC_ATTR_CONST +# define UA_FUNC_ATTR_WARN_UNUSED_RESULT _Check_return_ +# define UA_FORMAT(X,Y) +#else +# define UA_FUNC_ATTR_MALLOC +# define UA_FUNC_ATTR_PURE +# define UA_FUNC_ATTR_CONST +# define UA_FUNC_ATTR_WARN_UNUSED_RESULT +# define UA_FORMAT(X,Y) +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define UA_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +# define UA_DEPRECATED __declspec(deprecated) +#else +# define UA_DEPRECATED +#endif + +/** + * Internal Attributes + * ------------------- + * These attributes are only defined if the macro UA_INTERNAL is defined. That + * way public methods can be annotated (e.g. to warn for unused results) but + * warnings are only triggered for internal code. */ + +#if defined(UA_INTERNAL) && (defined(__GNUC__) || defined(__clang__)) +# define UA_INTERNAL_DEPRECATED \ + _Pragma ("GCC warning \"Macro is deprecated for internal use\"") +#else +# define UA_INTERNAL_DEPRECATED +#endif + +#if defined(UA_INTERNAL) && (defined(__GNUC__) || defined(__clang__)) +# define UA_INTERNAL_FUNC_ATTR_WARN_UNUSED_RESULT \ + __attribute__((warn_unused_result)) +#else +# define UA_INTERNAL_FUNC_ATTR_WARN_UNUSED_RESULT +#endif + +/** + * Detect Endianness and IEEE 754 floating point + * --------------------------------------------- + * Integers and floating point numbers are transmitted in little-endian (IEEE + * 754 for floating point) encoding. If the target architecture uses the same + * format, numeral datatypes can be memcpy'd (overlayed) on the network buffer. + * Otherwise, a slow default encoding routine is used that works for every + * architecture. + * + * Integer Endianness + * ^^^^^^^^^^^^^^^^^^ + * The definition ``UA_LITTLE_ENDIAN`` is true when the integer representation + * of the target architecture is little-endian. */ +#if defined(_WIN32) +# define UA_LITTLE_ENDIAN 1 +#elif defined(__i386__) || defined(__x86_64__) || defined(__amd64__) +# define UA_LITTLE_ENDIAN 1 +#elif (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) +# define UA_LITTLE_ENDIAN 1 +#elif defined(__linux__) /* Linux (including Android) */ +# include +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define UA_LITTLE_ENDIAN 1 +# endif +#elif defined(__OpenBSD__) /* OpenBSD */ +# include +# if BYTE_ORDER == LITTLE_ENDIAN +# define UA_LITTLE_ENDIAN 1 +# endif +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) /* Other BSD */ +# include +# if _BYTE_ORDER == _LITTLE_ENDIAN +# define UA_LITTLE_ENDIAN 1 +# endif +#elif defined(__APPLE__) /* Apple (MacOS, iOS) */ +# include +# if defined(__LITTLE_ENDIAN__) +# define UA_LITTLE_ENDIAN 1 +# endif +#elif defined(__QNX__) || defined(__QNXNTO__) /* QNX */ +# include +# if defined(__LITTLEENDIAN__) +# define UA_LITTLE_ENDIAN 1 +# endif +#elif defined(_OS9000) /* OS-9 */ +# if defined(_LIL_END) +# define UA_LITTLE_ENDIAN 1 +# endif +#endif +#ifndef UA_LITTLE_ENDIAN +# define UA_LITTLE_ENDIAN 0 +#endif + +/* Can the integers be memcpy'd onto the network buffer? Add additional checks + * here. Some platforms (e.g. QNX) have sizeof(bool) > 1. Manually disable + * overlayed integer encoding if that is the case. */ +#if (UA_LITTLE_ENDIAN == 1) +UA_STATIC_ASSERT(sizeof(bool) == 1, cannot_overlay_integers_with_large_bool); +# define UA_BINARY_OVERLAYABLE_INTEGER 1 +#else +# define UA_BINARY_OVERLAYABLE_INTEGER 0 +#endif + +/** + * Float Endianness + * ^^^^^^^^^^^^^^^^ + * The definition ``UA_FLOAT_IEEE754`` is set to true when the floating point + * number representation of the target architecture is IEEE 754. The definition + * ``UA_FLOAT_LITTLE_ENDIAN`` is set to true when the floating point number + * representation is in little-endian encoding. */ + +#ifndef UA_FLOAT_IEEE754 +#if defined(_WIN32) +# define UA_FLOAT_IEEE754 1 +#elif defined(__i386__) || defined(__x86_64__) || defined(__amd64__) || \ + defined(__ia64__) || defined(__powerpc__) || defined(__sparc__) || \ + defined(__arm__) +# define UA_FLOAT_IEEE754 1 +#elif defined(__STDC_IEC_559__) +# define UA_FLOAT_IEEE754 1 +#elif defined(ESP_PLATFORM) +# define UA_FLOAT_IEEE754 1 +#else +# define UA_FLOAT_IEEE754 0 +#endif +#endif + +/* Wikipedia says (https://en.wikipedia.org/wiki/Endianness): Although the + * ubiquitous x86 processors of today use little-endian storage for all types of + * data (integer, floating point, BCD), there are a number of hardware + * architectures where floating-point numbers are represented in big-endian form + * while integers are represented in little-endian form. */ +#if defined(_WIN32) +# define UA_FLOAT_LITTLE_ENDIAN 1 +#elif defined(__i386__) || defined(__x86_64__) || defined(__amd64__) +# define UA_FLOAT_LITTLE_ENDIAN 1 +#elif defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__) /* Defined only in GCC */ +# define UA_FLOAT_LITTLE_ENDIAN 1 +#elif defined(__FLOAT_WORD_ORDER) && defined(__LITTLE_ENDIAN) && \ + (__FLOAT_WORD_ORDER == __LITTLE_ENDIAN) /* Defined only in GCC */ +# define UA_FLOAT_LITTLE_ENDIAN 1 +#endif +#ifndef UA_FLOAT_LITTLE_ENDIAN +# define UA_FLOAT_LITTLE_ENDIAN 0 +#endif + +/* Only if the floating points are litle-endian **and** in IEEE 754 format can + * we memcpy directly onto the network buffer. */ +#if (UA_FLOAT_IEEE754 == 1) && (UA_FLOAT_LITTLE_ENDIAN == 1) +# define UA_BINARY_OVERLAYABLE_FLOAT 1 +#else +# define UA_BINARY_OVERLAYABLE_FLOAT 0 +#endif + +#endif /* UA_CONFIG_H_ */ diff --git a/product/src/fes/include/open62541/namespace0_generated.h b/product/src/fes/include/open62541/namespace0_generated.h new file mode 100644 index 00000000..ec71c7d1 --- /dev/null +++ b/product/src/fes/include/open62541/namespace0_generated.h @@ -0,0 +1,50 @@ +/* WARNING: This is a generated file. + * Any manual changes will be overwritten. */ + +#ifndef NAMESPACE0_GENERATED_H_ +#define NAMESPACE0_GENERATED_H_ + + +#ifdef UA_ENABLE_AMALGAMATION +# include "open62541.h" + +/* The following declarations are in the open62541.c file so here's needed when compiling nodesets externally */ + +# ifndef UA_INTERNAL //this definition is needed to hide this code in the amalgamated .c file + +typedef UA_StatusCode (*UA_exchangeEncodeBuffer)(void *handle, UA_Byte **bufPos, + const UA_Byte **bufEnd); + +UA_StatusCode +UA_encodeBinary(const void *src, const UA_DataType *type, + UA_Byte **bufPos, const UA_Byte **bufEnd, + UA_exchangeEncodeBuffer exchangeCallback, + void *exchangeHandle) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + +UA_StatusCode +UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, + const UA_DataType *type, size_t customTypesSize, + const UA_DataType *customTypes) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + +size_t +UA_calcSizeBinary(void *p, const UA_DataType *type); + +const UA_DataType * +UA_findDataTypeByBinary(const UA_NodeId *typeId); + +# endif // UA_INTERNAL + +#else // UA_ENABLE_AMALGAMATION +# include +#endif + + + + +_UA_BEGIN_DECLS + +extern UA_StatusCode namespace0_generated(UA_Server *server); + +_UA_END_DECLS + +#endif /* NAMESPACE0_GENERATED_H_ */ diff --git a/product/src/fes/include/open62541/nodeids.h b/product/src/fes/include/open62541/nodeids.h new file mode 100644 index 00000000..117dfc14 --- /dev/null +++ b/product/src/fes/include/open62541/nodeids.h @@ -0,0 +1,20529 @@ +/********************************** + * Autogenerated -- do not modify * + **********************************/ + +#ifndef UA_NODEIDS_NS0_H_ +#define UA_NODEIDS_NS0_H_ + +/** + * Namespace Zero NodeIds + * ---------------------- + * Numeric identifiers of standard-defined nodes in namespace zero. The + * following definitions are autogenerated from a CSV file */ + +#define UA_NS0ID_BOOLEAN 1 /* DataType */ +#define UA_NS0ID_SBYTE 2 /* DataType */ +#define UA_NS0ID_BYTE 3 /* DataType */ +#define UA_NS0ID_INT16 4 /* DataType */ +#define UA_NS0ID_UINT16 5 /* DataType */ +#define UA_NS0ID_INT32 6 /* DataType */ +#define UA_NS0ID_UINT32 7 /* DataType */ +#define UA_NS0ID_INT64 8 /* DataType */ +#define UA_NS0ID_UINT64 9 /* DataType */ +#define UA_NS0ID_FLOAT 10 /* DataType */ +#define UA_NS0ID_DOUBLE 11 /* DataType */ +#define UA_NS0ID_STRING 12 /* DataType */ +#define UA_NS0ID_DATETIME 13 /* DataType */ +#define UA_NS0ID_GUID 14 /* DataType */ +#define UA_NS0ID_BYTESTRING 15 /* DataType */ +#define UA_NS0ID_XMLELEMENT 16 /* DataType */ +#define UA_NS0ID_NODEID 17 /* DataType */ +#define UA_NS0ID_EXPANDEDNODEID 18 /* DataType */ +#define UA_NS0ID_STATUSCODE 19 /* DataType */ +#define UA_NS0ID_QUALIFIEDNAME 20 /* DataType */ +#define UA_NS0ID_LOCALIZEDTEXT 21 /* DataType */ +#define UA_NS0ID_STRUCTURE 22 /* DataType */ +#define UA_NS0ID_DATAVALUE 23 /* DataType */ +#define UA_NS0ID_BASEDATATYPE 24 /* DataType */ +#define UA_NS0ID_DIAGNOSTICINFO 25 /* DataType */ +#define UA_NS0ID_NUMBER 26 /* DataType */ +#define UA_NS0ID_INTEGER 27 /* DataType */ +#define UA_NS0ID_UINTEGER 28 /* DataType */ +#define UA_NS0ID_ENUMERATION 29 /* DataType */ +#define UA_NS0ID_IMAGE 30 /* DataType */ +#define UA_NS0ID_REFERENCES 31 /* ReferenceType */ +#define UA_NS0ID_NONHIERARCHICALREFERENCES 32 /* ReferenceType */ +#define UA_NS0ID_HIERARCHICALREFERENCES 33 /* ReferenceType */ +#define UA_NS0ID_HASCHILD 34 /* ReferenceType */ +#define UA_NS0ID_ORGANIZES 35 /* ReferenceType */ +#define UA_NS0ID_HASEVENTSOURCE 36 /* ReferenceType */ +#define UA_NS0ID_HASMODELLINGRULE 37 /* ReferenceType */ +#define UA_NS0ID_HASENCODING 38 /* ReferenceType */ +#define UA_NS0ID_HASDESCRIPTION 39 /* ReferenceType */ +#define UA_NS0ID_HASTYPEDEFINITION 40 /* ReferenceType */ +#define UA_NS0ID_GENERATESEVENT 41 /* ReferenceType */ +#define UA_NS0ID_AGGREGATES 44 /* ReferenceType */ +#define UA_NS0ID_HASSUBTYPE 45 /* ReferenceType */ +#define UA_NS0ID_HASPROPERTY 46 /* ReferenceType */ +#define UA_NS0ID_HASCOMPONENT 47 /* ReferenceType */ +#define UA_NS0ID_HASNOTIFIER 48 /* ReferenceType */ +#define UA_NS0ID_HASORDEREDCOMPONENT 49 /* ReferenceType */ +#define UA_NS0ID_DECIMAL 50 /* DataType */ +#define UA_NS0ID_FROMSTATE 51 /* ReferenceType */ +#define UA_NS0ID_TOSTATE 52 /* ReferenceType */ +#define UA_NS0ID_HASCAUSE 53 /* ReferenceType */ +#define UA_NS0ID_HASEFFECT 54 /* ReferenceType */ +#define UA_NS0ID_HASHISTORICALCONFIGURATION 56 /* ReferenceType */ +#define UA_NS0ID_BASEOBJECTTYPE 58 /* ObjectType */ +#define UA_NS0ID_FOLDERTYPE 61 /* ObjectType */ +#define UA_NS0ID_BASEVARIABLETYPE 62 /* VariableType */ +#define UA_NS0ID_BASEDATAVARIABLETYPE 63 /* VariableType */ +#define UA_NS0ID_PROPERTYTYPE 68 /* VariableType */ +#define UA_NS0ID_DATATYPEDESCRIPTIONTYPE 69 /* VariableType */ +#define UA_NS0ID_DATATYPEDICTIONARYTYPE 72 /* VariableType */ +#define UA_NS0ID_DATATYPESYSTEMTYPE 75 /* ObjectType */ +#define UA_NS0ID_DATATYPEENCODINGTYPE 76 /* ObjectType */ +#define UA_NS0ID_MODELLINGRULETYPE 77 /* ObjectType */ +#define UA_NS0ID_MODELLINGRULE_MANDATORY 78 /* Object */ +#define UA_NS0ID_MODELLINGRULE_OPTIONAL 80 /* Object */ +#define UA_NS0ID_MODELLINGRULE_EXPOSESITSARRAY 83 /* Object */ +#define UA_NS0ID_ROOTFOLDER 84 /* Object */ +#define UA_NS0ID_OBJECTSFOLDER 85 /* Object */ +#define UA_NS0ID_TYPESFOLDER 86 /* Object */ +#define UA_NS0ID_VIEWSFOLDER 87 /* Object */ +#define UA_NS0ID_OBJECTTYPESFOLDER 88 /* Object */ +#define UA_NS0ID_VARIABLETYPESFOLDER 89 /* Object */ +#define UA_NS0ID_DATATYPESFOLDER 90 /* Object */ +#define UA_NS0ID_REFERENCETYPESFOLDER 91 /* Object */ +#define UA_NS0ID_XMLSCHEMA_TYPESYSTEM 92 /* Object */ +#define UA_NS0ID_OPCBINARYSCHEMA_TYPESYSTEM 93 /* Object */ +#define UA_NS0ID_PERMISSIONTYPE 94 /* DataType */ +#define UA_NS0ID_ACCESSRESTRICTIONTYPE 95 /* DataType */ +#define UA_NS0ID_ROLEPERMISSIONTYPE 96 /* DataType */ +#define UA_NS0ID_DATATYPEDEFINITION 97 /* DataType */ +#define UA_NS0ID_STRUCTURETYPE 98 /* DataType */ +#define UA_NS0ID_STRUCTUREDEFINITION 99 /* DataType */ +#define UA_NS0ID_ENUMDEFINITION 100 /* DataType */ +#define UA_NS0ID_STRUCTUREFIELD 101 /* DataType */ +#define UA_NS0ID_ENUMFIELD 102 /* DataType */ +#define UA_NS0ID_DATATYPEDESCRIPTIONTYPE_DATATYPEVERSION 104 /* Variable */ +#define UA_NS0ID_DATATYPEDESCRIPTIONTYPE_DICTIONARYFRAGMENT 105 /* Variable */ +#define UA_NS0ID_DATATYPEDICTIONARYTYPE_DATATYPEVERSION 106 /* Variable */ +#define UA_NS0ID_DATATYPEDICTIONARYTYPE_NAMESPACEURI 107 /* Variable */ +#define UA_NS0ID_HASSUBSTATEMACHINE 117 /* ReferenceType */ +#define UA_NS0ID_NAMINGRULETYPE 120 /* DataType */ +#define UA_NS0ID_DATATYPEDEFINITION_ENCODING_DEFAULTBINARY 121 /* Object */ +#define UA_NS0ID_STRUCTUREDEFINITION_ENCODING_DEFAULTBINARY 122 /* Object */ +#define UA_NS0ID_ENUMDEFINITION_ENCODING_DEFAULTBINARY 123 /* Object */ +#define UA_NS0ID_DATASETMETADATATYPE_ENCODING_DEFAULTBINARY 124 /* Object */ +#define UA_NS0ID_DATATYPEDESCRIPTION_ENCODING_DEFAULTBINARY 125 /* Object */ +#define UA_NS0ID_STRUCTUREDESCRIPTION_ENCODING_DEFAULTBINARY 126 /* Object */ +#define UA_NS0ID_ENUMDESCRIPTION_ENCODING_DEFAULTBINARY 127 /* Object */ +#define UA_NS0ID_ROLEPERMISSIONTYPE_ENCODING_DEFAULTBINARY 128 /* Object */ +#define UA_NS0ID_HASARGUMENTDESCRIPTION 129 /* ReferenceType */ +#define UA_NS0ID_HASOPTIONALINPUTARGUMENTDESCRIPTION 131 /* ReferenceType */ +#define UA_NS0ID_IDTYPE 256 /* DataType */ +#define UA_NS0ID_NODECLASS 257 /* DataType */ +#define UA_NS0ID_NODE 258 /* DataType */ +#define UA_NS0ID_NODE_ENCODING_DEFAULTXML 259 /* Object */ +#define UA_NS0ID_NODE_ENCODING_DEFAULTBINARY 260 /* Object */ +#define UA_NS0ID_OBJECTNODE 261 /* DataType */ +#define UA_NS0ID_OBJECTNODE_ENCODING_DEFAULTXML 262 /* Object */ +#define UA_NS0ID_OBJECTNODE_ENCODING_DEFAULTBINARY 263 /* Object */ +#define UA_NS0ID_OBJECTTYPENODE 264 /* DataType */ +#define UA_NS0ID_OBJECTTYPENODE_ENCODING_DEFAULTXML 265 /* Object */ +#define UA_NS0ID_OBJECTTYPENODE_ENCODING_DEFAULTBINARY 266 /* Object */ +#define UA_NS0ID_VARIABLENODE 267 /* DataType */ +#define UA_NS0ID_VARIABLENODE_ENCODING_DEFAULTXML 268 /* Object */ +#define UA_NS0ID_VARIABLENODE_ENCODING_DEFAULTBINARY 269 /* Object */ +#define UA_NS0ID_VARIABLETYPENODE 270 /* DataType */ +#define UA_NS0ID_VARIABLETYPENODE_ENCODING_DEFAULTXML 271 /* Object */ +#define UA_NS0ID_VARIABLETYPENODE_ENCODING_DEFAULTBINARY 272 /* Object */ +#define UA_NS0ID_REFERENCETYPENODE 273 /* DataType */ +#define UA_NS0ID_REFERENCETYPENODE_ENCODING_DEFAULTXML 274 /* Object */ +#define UA_NS0ID_REFERENCETYPENODE_ENCODING_DEFAULTBINARY 275 /* Object */ +#define UA_NS0ID_METHODNODE 276 /* DataType */ +#define UA_NS0ID_METHODNODE_ENCODING_DEFAULTXML 277 /* Object */ +#define UA_NS0ID_METHODNODE_ENCODING_DEFAULTBINARY 278 /* Object */ +#define UA_NS0ID_VIEWNODE 279 /* DataType */ +#define UA_NS0ID_VIEWNODE_ENCODING_DEFAULTXML 280 /* Object */ +#define UA_NS0ID_VIEWNODE_ENCODING_DEFAULTBINARY 281 /* Object */ +#define UA_NS0ID_DATATYPENODE 282 /* DataType */ +#define UA_NS0ID_DATATYPENODE_ENCODING_DEFAULTXML 283 /* Object */ +#define UA_NS0ID_DATATYPENODE_ENCODING_DEFAULTBINARY 284 /* Object */ +#define UA_NS0ID_REFERENCENODE 285 /* DataType */ +#define UA_NS0ID_REFERENCENODE_ENCODING_DEFAULTXML 286 /* Object */ +#define UA_NS0ID_REFERENCENODE_ENCODING_DEFAULTBINARY 287 /* Object */ +#define UA_NS0ID_INTEGERID 288 /* DataType */ +#define UA_NS0ID_COUNTER 289 /* DataType */ +#define UA_NS0ID_DURATION 290 /* DataType */ +#define UA_NS0ID_NUMERICRANGE 291 /* DataType */ +#define UA_NS0ID_UTCTIME 294 /* DataType */ +#define UA_NS0ID_LOCALEID 295 /* DataType */ +#define UA_NS0ID_ARGUMENT 296 /* DataType */ +#define UA_NS0ID_ARGUMENT_ENCODING_DEFAULTXML 297 /* Object */ +#define UA_NS0ID_ARGUMENT_ENCODING_DEFAULTBINARY 298 /* Object */ +#define UA_NS0ID_STATUSRESULT 299 /* DataType */ +#define UA_NS0ID_STATUSRESULT_ENCODING_DEFAULTXML 300 /* Object */ +#define UA_NS0ID_STATUSRESULT_ENCODING_DEFAULTBINARY 301 /* Object */ +#define UA_NS0ID_MESSAGESECURITYMODE 302 /* DataType */ +#define UA_NS0ID_USERTOKENTYPE 303 /* DataType */ +#define UA_NS0ID_USERTOKENPOLICY 304 /* DataType */ +#define UA_NS0ID_USERTOKENPOLICY_ENCODING_DEFAULTXML 305 /* Object */ +#define UA_NS0ID_USERTOKENPOLICY_ENCODING_DEFAULTBINARY 306 /* Object */ +#define UA_NS0ID_APPLICATIONTYPE 307 /* DataType */ +#define UA_NS0ID_APPLICATIONDESCRIPTION 308 /* DataType */ +#define UA_NS0ID_APPLICATIONDESCRIPTION_ENCODING_DEFAULTXML 309 /* Object */ +#define UA_NS0ID_APPLICATIONDESCRIPTION_ENCODING_DEFAULTBINARY 310 /* Object */ +#define UA_NS0ID_APPLICATIONINSTANCECERTIFICATE 311 /* DataType */ +#define UA_NS0ID_ENDPOINTDESCRIPTION 312 /* DataType */ +#define UA_NS0ID_ENDPOINTDESCRIPTION_ENCODING_DEFAULTXML 313 /* Object */ +#define UA_NS0ID_ENDPOINTDESCRIPTION_ENCODING_DEFAULTBINARY 314 /* Object */ +#define UA_NS0ID_SECURITYTOKENREQUESTTYPE 315 /* DataType */ +#define UA_NS0ID_USERIDENTITYTOKEN 316 /* DataType */ +#define UA_NS0ID_USERIDENTITYTOKEN_ENCODING_DEFAULTXML 317 /* Object */ +#define UA_NS0ID_USERIDENTITYTOKEN_ENCODING_DEFAULTBINARY 318 /* Object */ +#define UA_NS0ID_ANONYMOUSIDENTITYTOKEN 319 /* DataType */ +#define UA_NS0ID_ANONYMOUSIDENTITYTOKEN_ENCODING_DEFAULTXML 320 /* Object */ +#define UA_NS0ID_ANONYMOUSIDENTITYTOKEN_ENCODING_DEFAULTBINARY 321 /* Object */ +#define UA_NS0ID_USERNAMEIDENTITYTOKEN 322 /* DataType */ +#define UA_NS0ID_USERNAMEIDENTITYTOKEN_ENCODING_DEFAULTXML 323 /* Object */ +#define UA_NS0ID_USERNAMEIDENTITYTOKEN_ENCODING_DEFAULTBINARY 324 /* Object */ +#define UA_NS0ID_X509IDENTITYTOKEN 325 /* DataType */ +#define UA_NS0ID_X509IDENTITYTOKEN_ENCODING_DEFAULTXML 326 /* Object */ +#define UA_NS0ID_X509IDENTITYTOKEN_ENCODING_DEFAULTBINARY 327 /* Object */ +#define UA_NS0ID_ENDPOINTCONFIGURATION 331 /* DataType */ +#define UA_NS0ID_ENDPOINTCONFIGURATION_ENCODING_DEFAULTXML 332 /* Object */ +#define UA_NS0ID_ENDPOINTCONFIGURATION_ENCODING_DEFAULTBINARY 333 /* Object */ +#define UA_NS0ID_BUILDINFO 338 /* DataType */ +#define UA_NS0ID_BUILDINFO_ENCODING_DEFAULTXML 339 /* Object */ +#define UA_NS0ID_BUILDINFO_ENCODING_DEFAULTBINARY 340 /* Object */ +#define UA_NS0ID_SIGNEDSOFTWARECERTIFICATE 344 /* DataType */ +#define UA_NS0ID_SIGNEDSOFTWARECERTIFICATE_ENCODING_DEFAULTXML 345 /* Object */ +#define UA_NS0ID_SIGNEDSOFTWARECERTIFICATE_ENCODING_DEFAULTBINARY 346 /* Object */ +#define UA_NS0ID_ATTRIBUTEWRITEMASK 347 /* DataType */ +#define UA_NS0ID_NODEATTRIBUTESMASK 348 /* DataType */ +#define UA_NS0ID_NODEATTRIBUTES 349 /* DataType */ +#define UA_NS0ID_NODEATTRIBUTES_ENCODING_DEFAULTXML 350 /* Object */ +#define UA_NS0ID_NODEATTRIBUTES_ENCODING_DEFAULTBINARY 351 /* Object */ +#define UA_NS0ID_OBJECTATTRIBUTES 352 /* DataType */ +#define UA_NS0ID_OBJECTATTRIBUTES_ENCODING_DEFAULTXML 353 /* Object */ +#define UA_NS0ID_OBJECTATTRIBUTES_ENCODING_DEFAULTBINARY 354 /* Object */ +#define UA_NS0ID_VARIABLEATTRIBUTES 355 /* DataType */ +#define UA_NS0ID_VARIABLEATTRIBUTES_ENCODING_DEFAULTXML 356 /* Object */ +#define UA_NS0ID_VARIABLEATTRIBUTES_ENCODING_DEFAULTBINARY 357 /* Object */ +#define UA_NS0ID_METHODATTRIBUTES 358 /* DataType */ +#define UA_NS0ID_METHODATTRIBUTES_ENCODING_DEFAULTXML 359 /* Object */ +#define UA_NS0ID_METHODATTRIBUTES_ENCODING_DEFAULTBINARY 360 /* Object */ +#define UA_NS0ID_OBJECTTYPEATTRIBUTES 361 /* DataType */ +#define UA_NS0ID_OBJECTTYPEATTRIBUTES_ENCODING_DEFAULTXML 362 /* Object */ +#define UA_NS0ID_OBJECTTYPEATTRIBUTES_ENCODING_DEFAULTBINARY 363 /* Object */ +#define UA_NS0ID_VARIABLETYPEATTRIBUTES 364 /* DataType */ +#define UA_NS0ID_VARIABLETYPEATTRIBUTES_ENCODING_DEFAULTXML 365 /* Object */ +#define UA_NS0ID_VARIABLETYPEATTRIBUTES_ENCODING_DEFAULTBINARY 366 /* Object */ +#define UA_NS0ID_REFERENCETYPEATTRIBUTES 367 /* DataType */ +#define UA_NS0ID_REFERENCETYPEATTRIBUTES_ENCODING_DEFAULTXML 368 /* Object */ +#define UA_NS0ID_REFERENCETYPEATTRIBUTES_ENCODING_DEFAULTBINARY 369 /* Object */ +#define UA_NS0ID_DATATYPEATTRIBUTES 370 /* DataType */ +#define UA_NS0ID_DATATYPEATTRIBUTES_ENCODING_DEFAULTXML 371 /* Object */ +#define UA_NS0ID_DATATYPEATTRIBUTES_ENCODING_DEFAULTBINARY 372 /* Object */ +#define UA_NS0ID_VIEWATTRIBUTES 373 /* DataType */ +#define UA_NS0ID_VIEWATTRIBUTES_ENCODING_DEFAULTXML 374 /* Object */ +#define UA_NS0ID_VIEWATTRIBUTES_ENCODING_DEFAULTBINARY 375 /* Object */ +#define UA_NS0ID_ADDNODESITEM 376 /* DataType */ +#define UA_NS0ID_ADDNODESITEM_ENCODING_DEFAULTXML 377 /* Object */ +#define UA_NS0ID_ADDNODESITEM_ENCODING_DEFAULTBINARY 378 /* Object */ +#define UA_NS0ID_ADDREFERENCESITEM 379 /* DataType */ +#define UA_NS0ID_ADDREFERENCESITEM_ENCODING_DEFAULTXML 380 /* Object */ +#define UA_NS0ID_ADDREFERENCESITEM_ENCODING_DEFAULTBINARY 381 /* Object */ +#define UA_NS0ID_DELETENODESITEM 382 /* DataType */ +#define UA_NS0ID_DELETENODESITEM_ENCODING_DEFAULTXML 383 /* Object */ +#define UA_NS0ID_DELETENODESITEM_ENCODING_DEFAULTBINARY 384 /* Object */ +#define UA_NS0ID_DELETEREFERENCESITEM 385 /* DataType */ +#define UA_NS0ID_DELETEREFERENCESITEM_ENCODING_DEFAULTXML 386 /* Object */ +#define UA_NS0ID_DELETEREFERENCESITEM_ENCODING_DEFAULTBINARY 387 /* Object */ +#define UA_NS0ID_SESSIONAUTHENTICATIONTOKEN 388 /* DataType */ +#define UA_NS0ID_REQUESTHEADER 389 /* DataType */ +#define UA_NS0ID_REQUESTHEADER_ENCODING_DEFAULTXML 390 /* Object */ +#define UA_NS0ID_REQUESTHEADER_ENCODING_DEFAULTBINARY 391 /* Object */ +#define UA_NS0ID_RESPONSEHEADER 392 /* DataType */ +#define UA_NS0ID_RESPONSEHEADER_ENCODING_DEFAULTXML 393 /* Object */ +#define UA_NS0ID_RESPONSEHEADER_ENCODING_DEFAULTBINARY 394 /* Object */ +#define UA_NS0ID_SERVICEFAULT 395 /* DataType */ +#define UA_NS0ID_SERVICEFAULT_ENCODING_DEFAULTXML 396 /* Object */ +#define UA_NS0ID_SERVICEFAULT_ENCODING_DEFAULTBINARY 397 /* Object */ +#define UA_NS0ID_FINDSERVERSREQUEST 420 /* DataType */ +#define UA_NS0ID_FINDSERVERSREQUEST_ENCODING_DEFAULTXML 421 /* Object */ +#define UA_NS0ID_FINDSERVERSREQUEST_ENCODING_DEFAULTBINARY 422 /* Object */ +#define UA_NS0ID_FINDSERVERSRESPONSE 423 /* DataType */ +#define UA_NS0ID_FINDSERVERSRESPONSE_ENCODING_DEFAULTXML 424 /* Object */ +#define UA_NS0ID_FINDSERVERSRESPONSE_ENCODING_DEFAULTBINARY 425 /* Object */ +#define UA_NS0ID_GETENDPOINTSREQUEST 426 /* DataType */ +#define UA_NS0ID_GETENDPOINTSREQUEST_ENCODING_DEFAULTXML 427 /* Object */ +#define UA_NS0ID_GETENDPOINTSREQUEST_ENCODING_DEFAULTBINARY 428 /* Object */ +#define UA_NS0ID_GETENDPOINTSRESPONSE 429 /* DataType */ +#define UA_NS0ID_GETENDPOINTSRESPONSE_ENCODING_DEFAULTXML 430 /* Object */ +#define UA_NS0ID_GETENDPOINTSRESPONSE_ENCODING_DEFAULTBINARY 431 /* Object */ +#define UA_NS0ID_REGISTEREDSERVER 432 /* DataType */ +#define UA_NS0ID_REGISTEREDSERVER_ENCODING_DEFAULTXML 433 /* Object */ +#define UA_NS0ID_REGISTEREDSERVER_ENCODING_DEFAULTBINARY 434 /* Object */ +#define UA_NS0ID_REGISTERSERVERREQUEST 435 /* DataType */ +#define UA_NS0ID_REGISTERSERVERREQUEST_ENCODING_DEFAULTXML 436 /* Object */ +#define UA_NS0ID_REGISTERSERVERREQUEST_ENCODING_DEFAULTBINARY 437 /* Object */ +#define UA_NS0ID_REGISTERSERVERRESPONSE 438 /* DataType */ +#define UA_NS0ID_REGISTERSERVERRESPONSE_ENCODING_DEFAULTXML 439 /* Object */ +#define UA_NS0ID_REGISTERSERVERRESPONSE_ENCODING_DEFAULTBINARY 440 /* Object */ +#define UA_NS0ID_CHANNELSECURITYTOKEN 441 /* DataType */ +#define UA_NS0ID_CHANNELSECURITYTOKEN_ENCODING_DEFAULTXML 442 /* Object */ +#define UA_NS0ID_CHANNELSECURITYTOKEN_ENCODING_DEFAULTBINARY 443 /* Object */ +#define UA_NS0ID_OPENSECURECHANNELREQUEST 444 /* DataType */ +#define UA_NS0ID_OPENSECURECHANNELREQUEST_ENCODING_DEFAULTXML 445 /* Object */ +#define UA_NS0ID_OPENSECURECHANNELREQUEST_ENCODING_DEFAULTBINARY 446 /* Object */ +#define UA_NS0ID_OPENSECURECHANNELRESPONSE 447 /* DataType */ +#define UA_NS0ID_OPENSECURECHANNELRESPONSE_ENCODING_DEFAULTXML 448 /* Object */ +#define UA_NS0ID_OPENSECURECHANNELRESPONSE_ENCODING_DEFAULTBINARY 449 /* Object */ +#define UA_NS0ID_CLOSESECURECHANNELREQUEST 450 /* DataType */ +#define UA_NS0ID_CLOSESECURECHANNELREQUEST_ENCODING_DEFAULTXML 451 /* Object */ +#define UA_NS0ID_CLOSESECURECHANNELREQUEST_ENCODING_DEFAULTBINARY 452 /* Object */ +#define UA_NS0ID_CLOSESECURECHANNELRESPONSE 453 /* DataType */ +#define UA_NS0ID_CLOSESECURECHANNELRESPONSE_ENCODING_DEFAULTXML 454 /* Object */ +#define UA_NS0ID_CLOSESECURECHANNELRESPONSE_ENCODING_DEFAULTBINARY 455 /* Object */ +#define UA_NS0ID_SIGNATUREDATA 456 /* DataType */ +#define UA_NS0ID_SIGNATUREDATA_ENCODING_DEFAULTXML 457 /* Object */ +#define UA_NS0ID_SIGNATUREDATA_ENCODING_DEFAULTBINARY 458 /* Object */ +#define UA_NS0ID_CREATESESSIONREQUEST 459 /* DataType */ +#define UA_NS0ID_CREATESESSIONREQUEST_ENCODING_DEFAULTXML 460 /* Object */ +#define UA_NS0ID_CREATESESSIONREQUEST_ENCODING_DEFAULTBINARY 461 /* Object */ +#define UA_NS0ID_CREATESESSIONRESPONSE 462 /* DataType */ +#define UA_NS0ID_CREATESESSIONRESPONSE_ENCODING_DEFAULTXML 463 /* Object */ +#define UA_NS0ID_CREATESESSIONRESPONSE_ENCODING_DEFAULTBINARY 464 /* Object */ +#define UA_NS0ID_ACTIVATESESSIONREQUEST 465 /* DataType */ +#define UA_NS0ID_ACTIVATESESSIONREQUEST_ENCODING_DEFAULTXML 466 /* Object */ +#define UA_NS0ID_ACTIVATESESSIONREQUEST_ENCODING_DEFAULTBINARY 467 /* Object */ +#define UA_NS0ID_ACTIVATESESSIONRESPONSE 468 /* DataType */ +#define UA_NS0ID_ACTIVATESESSIONRESPONSE_ENCODING_DEFAULTXML 469 /* Object */ +#define UA_NS0ID_ACTIVATESESSIONRESPONSE_ENCODING_DEFAULTBINARY 470 /* Object */ +#define UA_NS0ID_CLOSESESSIONREQUEST 471 /* DataType */ +#define UA_NS0ID_CLOSESESSIONREQUEST_ENCODING_DEFAULTXML 472 /* Object */ +#define UA_NS0ID_CLOSESESSIONREQUEST_ENCODING_DEFAULTBINARY 473 /* Object */ +#define UA_NS0ID_CLOSESESSIONRESPONSE 474 /* DataType */ +#define UA_NS0ID_CLOSESESSIONRESPONSE_ENCODING_DEFAULTXML 475 /* Object */ +#define UA_NS0ID_CLOSESESSIONRESPONSE_ENCODING_DEFAULTBINARY 476 /* Object */ +#define UA_NS0ID_CANCELREQUEST 477 /* DataType */ +#define UA_NS0ID_CANCELREQUEST_ENCODING_DEFAULTXML 478 /* Object */ +#define UA_NS0ID_CANCELREQUEST_ENCODING_DEFAULTBINARY 479 /* Object */ +#define UA_NS0ID_CANCELRESPONSE 480 /* DataType */ +#define UA_NS0ID_CANCELRESPONSE_ENCODING_DEFAULTXML 481 /* Object */ +#define UA_NS0ID_CANCELRESPONSE_ENCODING_DEFAULTBINARY 482 /* Object */ +#define UA_NS0ID_ADDNODESRESULT 483 /* DataType */ +#define UA_NS0ID_ADDNODESRESULT_ENCODING_DEFAULTXML 484 /* Object */ +#define UA_NS0ID_ADDNODESRESULT_ENCODING_DEFAULTBINARY 485 /* Object */ +#define UA_NS0ID_ADDNODESREQUEST 486 /* DataType */ +#define UA_NS0ID_ADDNODESREQUEST_ENCODING_DEFAULTXML 487 /* Object */ +#define UA_NS0ID_ADDNODESREQUEST_ENCODING_DEFAULTBINARY 488 /* Object */ +#define UA_NS0ID_ADDNODESRESPONSE 489 /* DataType */ +#define UA_NS0ID_ADDNODESRESPONSE_ENCODING_DEFAULTXML 490 /* Object */ +#define UA_NS0ID_ADDNODESRESPONSE_ENCODING_DEFAULTBINARY 491 /* Object */ +#define UA_NS0ID_ADDREFERENCESREQUEST 492 /* DataType */ +#define UA_NS0ID_ADDREFERENCESREQUEST_ENCODING_DEFAULTXML 493 /* Object */ +#define UA_NS0ID_ADDREFERENCESREQUEST_ENCODING_DEFAULTBINARY 494 /* Object */ +#define UA_NS0ID_ADDREFERENCESRESPONSE 495 /* DataType */ +#define UA_NS0ID_ADDREFERENCESRESPONSE_ENCODING_DEFAULTXML 496 /* Object */ +#define UA_NS0ID_ADDREFERENCESRESPONSE_ENCODING_DEFAULTBINARY 497 /* Object */ +#define UA_NS0ID_DELETENODESREQUEST 498 /* DataType */ +#define UA_NS0ID_DELETENODESREQUEST_ENCODING_DEFAULTXML 499 /* Object */ +#define UA_NS0ID_DELETENODESREQUEST_ENCODING_DEFAULTBINARY 500 /* Object */ +#define UA_NS0ID_DELETENODESRESPONSE 501 /* DataType */ +#define UA_NS0ID_DELETENODESRESPONSE_ENCODING_DEFAULTXML 502 /* Object */ +#define UA_NS0ID_DELETENODESRESPONSE_ENCODING_DEFAULTBINARY 503 /* Object */ +#define UA_NS0ID_DELETEREFERENCESREQUEST 504 /* DataType */ +#define UA_NS0ID_DELETEREFERENCESREQUEST_ENCODING_DEFAULTXML 505 /* Object */ +#define UA_NS0ID_DELETEREFERENCESREQUEST_ENCODING_DEFAULTBINARY 506 /* Object */ +#define UA_NS0ID_DELETEREFERENCESRESPONSE 507 /* DataType */ +#define UA_NS0ID_DELETEREFERENCESRESPONSE_ENCODING_DEFAULTXML 508 /* Object */ +#define UA_NS0ID_DELETEREFERENCESRESPONSE_ENCODING_DEFAULTBINARY 509 /* Object */ +#define UA_NS0ID_BROWSEDIRECTION 510 /* DataType */ +#define UA_NS0ID_VIEWDESCRIPTION 511 /* DataType */ +#define UA_NS0ID_VIEWDESCRIPTION_ENCODING_DEFAULTXML 512 /* Object */ +#define UA_NS0ID_VIEWDESCRIPTION_ENCODING_DEFAULTBINARY 513 /* Object */ +#define UA_NS0ID_BROWSEDESCRIPTION 514 /* DataType */ +#define UA_NS0ID_BROWSEDESCRIPTION_ENCODING_DEFAULTXML 515 /* Object */ +#define UA_NS0ID_BROWSEDESCRIPTION_ENCODING_DEFAULTBINARY 516 /* Object */ +#define UA_NS0ID_BROWSERESULTMASK 517 /* DataType */ +#define UA_NS0ID_REFERENCEDESCRIPTION 518 /* DataType */ +#define UA_NS0ID_REFERENCEDESCRIPTION_ENCODING_DEFAULTXML 519 /* Object */ +#define UA_NS0ID_REFERENCEDESCRIPTION_ENCODING_DEFAULTBINARY 520 /* Object */ +#define UA_NS0ID_CONTINUATIONPOINT 521 /* DataType */ +#define UA_NS0ID_BROWSERESULT 522 /* DataType */ +#define UA_NS0ID_BROWSERESULT_ENCODING_DEFAULTXML 523 /* Object */ +#define UA_NS0ID_BROWSERESULT_ENCODING_DEFAULTBINARY 524 /* Object */ +#define UA_NS0ID_BROWSEREQUEST 525 /* DataType */ +#define UA_NS0ID_BROWSEREQUEST_ENCODING_DEFAULTXML 526 /* Object */ +#define UA_NS0ID_BROWSEREQUEST_ENCODING_DEFAULTBINARY 527 /* Object */ +#define UA_NS0ID_BROWSERESPONSE 528 /* DataType */ +#define UA_NS0ID_BROWSERESPONSE_ENCODING_DEFAULTXML 529 /* Object */ +#define UA_NS0ID_BROWSERESPONSE_ENCODING_DEFAULTBINARY 530 /* Object */ +#define UA_NS0ID_BROWSENEXTREQUEST 531 /* DataType */ +#define UA_NS0ID_BROWSENEXTREQUEST_ENCODING_DEFAULTXML 532 /* Object */ +#define UA_NS0ID_BROWSENEXTREQUEST_ENCODING_DEFAULTBINARY 533 /* Object */ +#define UA_NS0ID_BROWSENEXTRESPONSE 534 /* DataType */ +#define UA_NS0ID_BROWSENEXTRESPONSE_ENCODING_DEFAULTXML 535 /* Object */ +#define UA_NS0ID_BROWSENEXTRESPONSE_ENCODING_DEFAULTBINARY 536 /* Object */ +#define UA_NS0ID_RELATIVEPATHELEMENT 537 /* DataType */ +#define UA_NS0ID_RELATIVEPATHELEMENT_ENCODING_DEFAULTXML 538 /* Object */ +#define UA_NS0ID_RELATIVEPATHELEMENT_ENCODING_DEFAULTBINARY 539 /* Object */ +#define UA_NS0ID_RELATIVEPATH 540 /* DataType */ +#define UA_NS0ID_RELATIVEPATH_ENCODING_DEFAULTXML 541 /* Object */ +#define UA_NS0ID_RELATIVEPATH_ENCODING_DEFAULTBINARY 542 /* Object */ +#define UA_NS0ID_BROWSEPATH 543 /* DataType */ +#define UA_NS0ID_BROWSEPATH_ENCODING_DEFAULTXML 544 /* Object */ +#define UA_NS0ID_BROWSEPATH_ENCODING_DEFAULTBINARY 545 /* Object */ +#define UA_NS0ID_BROWSEPATHTARGET 546 /* DataType */ +#define UA_NS0ID_BROWSEPATHTARGET_ENCODING_DEFAULTXML 547 /* Object */ +#define UA_NS0ID_BROWSEPATHTARGET_ENCODING_DEFAULTBINARY 548 /* Object */ +#define UA_NS0ID_BROWSEPATHRESULT 549 /* DataType */ +#define UA_NS0ID_BROWSEPATHRESULT_ENCODING_DEFAULTXML 550 /* Object */ +#define UA_NS0ID_BROWSEPATHRESULT_ENCODING_DEFAULTBINARY 551 /* Object */ +#define UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSREQUEST 552 /* DataType */ +#define UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSREQUEST_ENCODING_DEFAULTXML 553 /* Object */ +#define UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSREQUEST_ENCODING_DEFAULTBINARY 554 /* Object */ +#define UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE 555 /* DataType */ +#define UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE_ENCODING_DEFAULTXML 556 /* Object */ +#define UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE_ENCODING_DEFAULTBINARY 557 /* Object */ +#define UA_NS0ID_REGISTERNODESREQUEST 558 /* DataType */ +#define UA_NS0ID_REGISTERNODESREQUEST_ENCODING_DEFAULTXML 559 /* Object */ +#define UA_NS0ID_REGISTERNODESREQUEST_ENCODING_DEFAULTBINARY 560 /* Object */ +#define UA_NS0ID_REGISTERNODESRESPONSE 561 /* DataType */ +#define UA_NS0ID_REGISTERNODESRESPONSE_ENCODING_DEFAULTXML 562 /* Object */ +#define UA_NS0ID_REGISTERNODESRESPONSE_ENCODING_DEFAULTBINARY 563 /* Object */ +#define UA_NS0ID_UNREGISTERNODESREQUEST 564 /* DataType */ +#define UA_NS0ID_UNREGISTERNODESREQUEST_ENCODING_DEFAULTXML 565 /* Object */ +#define UA_NS0ID_UNREGISTERNODESREQUEST_ENCODING_DEFAULTBINARY 566 /* Object */ +#define UA_NS0ID_UNREGISTERNODESRESPONSE 567 /* DataType */ +#define UA_NS0ID_UNREGISTERNODESRESPONSE_ENCODING_DEFAULTXML 568 /* Object */ +#define UA_NS0ID_UNREGISTERNODESRESPONSE_ENCODING_DEFAULTBINARY 569 /* Object */ +#define UA_NS0ID_QUERYDATADESCRIPTION 570 /* DataType */ +#define UA_NS0ID_QUERYDATADESCRIPTION_ENCODING_DEFAULTXML 571 /* Object */ +#define UA_NS0ID_QUERYDATADESCRIPTION_ENCODING_DEFAULTBINARY 572 /* Object */ +#define UA_NS0ID_NODETYPEDESCRIPTION 573 /* DataType */ +#define UA_NS0ID_NODETYPEDESCRIPTION_ENCODING_DEFAULTXML 574 /* Object */ +#define UA_NS0ID_NODETYPEDESCRIPTION_ENCODING_DEFAULTBINARY 575 /* Object */ +#define UA_NS0ID_FILTEROPERATOR 576 /* DataType */ +#define UA_NS0ID_QUERYDATASET 577 /* DataType */ +#define UA_NS0ID_QUERYDATASET_ENCODING_DEFAULTXML 578 /* Object */ +#define UA_NS0ID_QUERYDATASET_ENCODING_DEFAULTBINARY 579 /* Object */ +#define UA_NS0ID_NODEREFERENCE 580 /* DataType */ +#define UA_NS0ID_NODEREFERENCE_ENCODING_DEFAULTXML 581 /* Object */ +#define UA_NS0ID_NODEREFERENCE_ENCODING_DEFAULTBINARY 582 /* Object */ +#define UA_NS0ID_CONTENTFILTERELEMENT 583 /* DataType */ +#define UA_NS0ID_CONTENTFILTERELEMENT_ENCODING_DEFAULTXML 584 /* Object */ +#define UA_NS0ID_CONTENTFILTERELEMENT_ENCODING_DEFAULTBINARY 585 /* Object */ +#define UA_NS0ID_CONTENTFILTER 586 /* DataType */ +#define UA_NS0ID_CONTENTFILTER_ENCODING_DEFAULTXML 587 /* Object */ +#define UA_NS0ID_CONTENTFILTER_ENCODING_DEFAULTBINARY 588 /* Object */ +#define UA_NS0ID_FILTEROPERAND 589 /* DataType */ +#define UA_NS0ID_FILTEROPERAND_ENCODING_DEFAULTXML 590 /* Object */ +#define UA_NS0ID_FILTEROPERAND_ENCODING_DEFAULTBINARY 591 /* Object */ +#define UA_NS0ID_ELEMENTOPERAND 592 /* DataType */ +#define UA_NS0ID_ELEMENTOPERAND_ENCODING_DEFAULTXML 593 /* Object */ +#define UA_NS0ID_ELEMENTOPERAND_ENCODING_DEFAULTBINARY 594 /* Object */ +#define UA_NS0ID_LITERALOPERAND 595 /* DataType */ +#define UA_NS0ID_LITERALOPERAND_ENCODING_DEFAULTXML 596 /* Object */ +#define UA_NS0ID_LITERALOPERAND_ENCODING_DEFAULTBINARY 597 /* Object */ +#define UA_NS0ID_ATTRIBUTEOPERAND 598 /* DataType */ +#define UA_NS0ID_ATTRIBUTEOPERAND_ENCODING_DEFAULTXML 599 /* Object */ +#define UA_NS0ID_ATTRIBUTEOPERAND_ENCODING_DEFAULTBINARY 600 /* Object */ +#define UA_NS0ID_SIMPLEATTRIBUTEOPERAND 601 /* DataType */ +#define UA_NS0ID_SIMPLEATTRIBUTEOPERAND_ENCODING_DEFAULTXML 602 /* Object */ +#define UA_NS0ID_SIMPLEATTRIBUTEOPERAND_ENCODING_DEFAULTBINARY 603 /* Object */ +#define UA_NS0ID_CONTENTFILTERELEMENTRESULT 604 /* DataType */ +#define UA_NS0ID_CONTENTFILTERELEMENTRESULT_ENCODING_DEFAULTXML 605 /* Object */ +#define UA_NS0ID_CONTENTFILTERELEMENTRESULT_ENCODING_DEFAULTBINARY 606 /* Object */ +#define UA_NS0ID_CONTENTFILTERRESULT 607 /* DataType */ +#define UA_NS0ID_CONTENTFILTERRESULT_ENCODING_DEFAULTXML 608 /* Object */ +#define UA_NS0ID_CONTENTFILTERRESULT_ENCODING_DEFAULTBINARY 609 /* Object */ +#define UA_NS0ID_PARSINGRESULT 610 /* DataType */ +#define UA_NS0ID_PARSINGRESULT_ENCODING_DEFAULTXML 611 /* Object */ +#define UA_NS0ID_PARSINGRESULT_ENCODING_DEFAULTBINARY 612 /* Object */ +#define UA_NS0ID_QUERYFIRSTREQUEST 613 /* DataType */ +#define UA_NS0ID_QUERYFIRSTREQUEST_ENCODING_DEFAULTXML 614 /* Object */ +#define UA_NS0ID_QUERYFIRSTREQUEST_ENCODING_DEFAULTBINARY 615 /* Object */ +#define UA_NS0ID_QUERYFIRSTRESPONSE 616 /* DataType */ +#define UA_NS0ID_QUERYFIRSTRESPONSE_ENCODING_DEFAULTXML 617 /* Object */ +#define UA_NS0ID_QUERYFIRSTRESPONSE_ENCODING_DEFAULTBINARY 618 /* Object */ +#define UA_NS0ID_QUERYNEXTREQUEST 619 /* DataType */ +#define UA_NS0ID_QUERYNEXTREQUEST_ENCODING_DEFAULTXML 620 /* Object */ +#define UA_NS0ID_QUERYNEXTREQUEST_ENCODING_DEFAULTBINARY 621 /* Object */ +#define UA_NS0ID_QUERYNEXTRESPONSE 622 /* DataType */ +#define UA_NS0ID_QUERYNEXTRESPONSE_ENCODING_DEFAULTXML 623 /* Object */ +#define UA_NS0ID_QUERYNEXTRESPONSE_ENCODING_DEFAULTBINARY 624 /* Object */ +#define UA_NS0ID_TIMESTAMPSTORETURN 625 /* DataType */ +#define UA_NS0ID_READVALUEID 626 /* DataType */ +#define UA_NS0ID_READVALUEID_ENCODING_DEFAULTXML 627 /* Object */ +#define UA_NS0ID_READVALUEID_ENCODING_DEFAULTBINARY 628 /* Object */ +#define UA_NS0ID_READREQUEST 629 /* DataType */ +#define UA_NS0ID_READREQUEST_ENCODING_DEFAULTXML 630 /* Object */ +#define UA_NS0ID_READREQUEST_ENCODING_DEFAULTBINARY 631 /* Object */ +#define UA_NS0ID_READRESPONSE 632 /* DataType */ +#define UA_NS0ID_READRESPONSE_ENCODING_DEFAULTXML 633 /* Object */ +#define UA_NS0ID_READRESPONSE_ENCODING_DEFAULTBINARY 634 /* Object */ +#define UA_NS0ID_HISTORYREADVALUEID 635 /* DataType */ +#define UA_NS0ID_HISTORYREADVALUEID_ENCODING_DEFAULTXML 636 /* Object */ +#define UA_NS0ID_HISTORYREADVALUEID_ENCODING_DEFAULTBINARY 637 /* Object */ +#define UA_NS0ID_HISTORYREADRESULT 638 /* DataType */ +#define UA_NS0ID_HISTORYREADRESULT_ENCODING_DEFAULTXML 639 /* Object */ +#define UA_NS0ID_HISTORYREADRESULT_ENCODING_DEFAULTBINARY 640 /* Object */ +#define UA_NS0ID_HISTORYREADDETAILS 641 /* DataType */ +#define UA_NS0ID_HISTORYREADDETAILS_ENCODING_DEFAULTXML 642 /* Object */ +#define UA_NS0ID_HISTORYREADDETAILS_ENCODING_DEFAULTBINARY 643 /* Object */ +#define UA_NS0ID_READEVENTDETAILS 644 /* DataType */ +#define UA_NS0ID_READEVENTDETAILS_ENCODING_DEFAULTXML 645 /* Object */ +#define UA_NS0ID_READEVENTDETAILS_ENCODING_DEFAULTBINARY 646 /* Object */ +#define UA_NS0ID_READRAWMODIFIEDDETAILS 647 /* DataType */ +#define UA_NS0ID_READRAWMODIFIEDDETAILS_ENCODING_DEFAULTXML 648 /* Object */ +#define UA_NS0ID_READRAWMODIFIEDDETAILS_ENCODING_DEFAULTBINARY 649 /* Object */ +#define UA_NS0ID_READPROCESSEDDETAILS 650 /* DataType */ +#define UA_NS0ID_READPROCESSEDDETAILS_ENCODING_DEFAULTXML 651 /* Object */ +#define UA_NS0ID_READPROCESSEDDETAILS_ENCODING_DEFAULTBINARY 652 /* Object */ +#define UA_NS0ID_READATTIMEDETAILS 653 /* DataType */ +#define UA_NS0ID_READATTIMEDETAILS_ENCODING_DEFAULTXML 654 /* Object */ +#define UA_NS0ID_READATTIMEDETAILS_ENCODING_DEFAULTBINARY 655 /* Object */ +#define UA_NS0ID_HISTORYDATA 656 /* DataType */ +#define UA_NS0ID_HISTORYDATA_ENCODING_DEFAULTXML 657 /* Object */ +#define UA_NS0ID_HISTORYDATA_ENCODING_DEFAULTBINARY 658 /* Object */ +#define UA_NS0ID_HISTORYEVENT 659 /* DataType */ +#define UA_NS0ID_HISTORYEVENT_ENCODING_DEFAULTXML 660 /* Object */ +#define UA_NS0ID_HISTORYEVENT_ENCODING_DEFAULTBINARY 661 /* Object */ +#define UA_NS0ID_HISTORYREADREQUEST 662 /* DataType */ +#define UA_NS0ID_HISTORYREADREQUEST_ENCODING_DEFAULTXML 663 /* Object */ +#define UA_NS0ID_HISTORYREADREQUEST_ENCODING_DEFAULTBINARY 664 /* Object */ +#define UA_NS0ID_HISTORYREADRESPONSE 665 /* DataType */ +#define UA_NS0ID_HISTORYREADRESPONSE_ENCODING_DEFAULTXML 666 /* Object */ +#define UA_NS0ID_HISTORYREADRESPONSE_ENCODING_DEFAULTBINARY 667 /* Object */ +#define UA_NS0ID_WRITEVALUE 668 /* DataType */ +#define UA_NS0ID_WRITEVALUE_ENCODING_DEFAULTXML 669 /* Object */ +#define UA_NS0ID_WRITEVALUE_ENCODING_DEFAULTBINARY 670 /* Object */ +#define UA_NS0ID_WRITEREQUEST 671 /* DataType */ +#define UA_NS0ID_WRITEREQUEST_ENCODING_DEFAULTXML 672 /* Object */ +#define UA_NS0ID_WRITEREQUEST_ENCODING_DEFAULTBINARY 673 /* Object */ +#define UA_NS0ID_WRITERESPONSE 674 /* DataType */ +#define UA_NS0ID_WRITERESPONSE_ENCODING_DEFAULTXML 675 /* Object */ +#define UA_NS0ID_WRITERESPONSE_ENCODING_DEFAULTBINARY 676 /* Object */ +#define UA_NS0ID_HISTORYUPDATEDETAILS 677 /* DataType */ +#define UA_NS0ID_HISTORYUPDATEDETAILS_ENCODING_DEFAULTXML 678 /* Object */ +#define UA_NS0ID_HISTORYUPDATEDETAILS_ENCODING_DEFAULTBINARY 679 /* Object */ +#define UA_NS0ID_UPDATEDATADETAILS 680 /* DataType */ +#define UA_NS0ID_UPDATEDATADETAILS_ENCODING_DEFAULTXML 681 /* Object */ +#define UA_NS0ID_UPDATEDATADETAILS_ENCODING_DEFAULTBINARY 682 /* Object */ +#define UA_NS0ID_UPDATEEVENTDETAILS 683 /* DataType */ +#define UA_NS0ID_UPDATEEVENTDETAILS_ENCODING_DEFAULTXML 684 /* Object */ +#define UA_NS0ID_UPDATEEVENTDETAILS_ENCODING_DEFAULTBINARY 685 /* Object */ +#define UA_NS0ID_DELETERAWMODIFIEDDETAILS 686 /* DataType */ +#define UA_NS0ID_DELETERAWMODIFIEDDETAILS_ENCODING_DEFAULTXML 687 /* Object */ +#define UA_NS0ID_DELETERAWMODIFIEDDETAILS_ENCODING_DEFAULTBINARY 688 /* Object */ +#define UA_NS0ID_DELETEATTIMEDETAILS 689 /* DataType */ +#define UA_NS0ID_DELETEATTIMEDETAILS_ENCODING_DEFAULTXML 690 /* Object */ +#define UA_NS0ID_DELETEATTIMEDETAILS_ENCODING_DEFAULTBINARY 691 /* Object */ +#define UA_NS0ID_DELETEEVENTDETAILS 692 /* DataType */ +#define UA_NS0ID_DELETEEVENTDETAILS_ENCODING_DEFAULTXML 693 /* Object */ +#define UA_NS0ID_DELETEEVENTDETAILS_ENCODING_DEFAULTBINARY 694 /* Object */ +#define UA_NS0ID_HISTORYUPDATERESULT 695 /* DataType */ +#define UA_NS0ID_HISTORYUPDATERESULT_ENCODING_DEFAULTXML 696 /* Object */ +#define UA_NS0ID_HISTORYUPDATERESULT_ENCODING_DEFAULTBINARY 697 /* Object */ +#define UA_NS0ID_HISTORYUPDATEREQUEST 698 /* DataType */ +#define UA_NS0ID_HISTORYUPDATEREQUEST_ENCODING_DEFAULTXML 699 /* Object */ +#define UA_NS0ID_HISTORYUPDATEREQUEST_ENCODING_DEFAULTBINARY 700 /* Object */ +#define UA_NS0ID_HISTORYUPDATERESPONSE 701 /* DataType */ +#define UA_NS0ID_HISTORYUPDATERESPONSE_ENCODING_DEFAULTXML 702 /* Object */ +#define UA_NS0ID_HISTORYUPDATERESPONSE_ENCODING_DEFAULTBINARY 703 /* Object */ +#define UA_NS0ID_CALLMETHODREQUEST 704 /* DataType */ +#define UA_NS0ID_CALLMETHODREQUEST_ENCODING_DEFAULTXML 705 /* Object */ +#define UA_NS0ID_CALLMETHODREQUEST_ENCODING_DEFAULTBINARY 706 /* Object */ +#define UA_NS0ID_CALLMETHODRESULT 707 /* DataType */ +#define UA_NS0ID_CALLMETHODRESULT_ENCODING_DEFAULTXML 708 /* Object */ +#define UA_NS0ID_CALLMETHODRESULT_ENCODING_DEFAULTBINARY 709 /* Object */ +#define UA_NS0ID_CALLREQUEST 710 /* DataType */ +#define UA_NS0ID_CALLREQUEST_ENCODING_DEFAULTXML 711 /* Object */ +#define UA_NS0ID_CALLREQUEST_ENCODING_DEFAULTBINARY 712 /* Object */ +#define UA_NS0ID_CALLRESPONSE 713 /* DataType */ +#define UA_NS0ID_CALLRESPONSE_ENCODING_DEFAULTXML 714 /* Object */ +#define UA_NS0ID_CALLRESPONSE_ENCODING_DEFAULTBINARY 715 /* Object */ +#define UA_NS0ID_MONITORINGMODE 716 /* DataType */ +#define UA_NS0ID_DATACHANGETRIGGER 717 /* DataType */ +#define UA_NS0ID_DEADBANDTYPE 718 /* DataType */ +#define UA_NS0ID_MONITORINGFILTER 719 /* DataType */ +#define UA_NS0ID_MONITORINGFILTER_ENCODING_DEFAULTXML 720 /* Object */ +#define UA_NS0ID_MONITORINGFILTER_ENCODING_DEFAULTBINARY 721 /* Object */ +#define UA_NS0ID_DATACHANGEFILTER 722 /* DataType */ +#define UA_NS0ID_DATACHANGEFILTER_ENCODING_DEFAULTXML 723 /* Object */ +#define UA_NS0ID_DATACHANGEFILTER_ENCODING_DEFAULTBINARY 724 /* Object */ +#define UA_NS0ID_EVENTFILTER 725 /* DataType */ +#define UA_NS0ID_EVENTFILTER_ENCODING_DEFAULTXML 726 /* Object */ +#define UA_NS0ID_EVENTFILTER_ENCODING_DEFAULTBINARY 727 /* Object */ +#define UA_NS0ID_AGGREGATEFILTER 728 /* DataType */ +#define UA_NS0ID_AGGREGATEFILTER_ENCODING_DEFAULTXML 729 /* Object */ +#define UA_NS0ID_AGGREGATEFILTER_ENCODING_DEFAULTBINARY 730 /* Object */ +#define UA_NS0ID_MONITORINGFILTERRESULT 731 /* DataType */ +#define UA_NS0ID_MONITORINGFILTERRESULT_ENCODING_DEFAULTXML 732 /* Object */ +#define UA_NS0ID_MONITORINGFILTERRESULT_ENCODING_DEFAULTBINARY 733 /* Object */ +#define UA_NS0ID_EVENTFILTERRESULT 734 /* DataType */ +#define UA_NS0ID_EVENTFILTERRESULT_ENCODING_DEFAULTXML 735 /* Object */ +#define UA_NS0ID_EVENTFILTERRESULT_ENCODING_DEFAULTBINARY 736 /* Object */ +#define UA_NS0ID_AGGREGATEFILTERRESULT 737 /* DataType */ +#define UA_NS0ID_AGGREGATEFILTERRESULT_ENCODING_DEFAULTXML 738 /* Object */ +#define UA_NS0ID_AGGREGATEFILTERRESULT_ENCODING_DEFAULTBINARY 739 /* Object */ +#define UA_NS0ID_MONITORINGPARAMETERS 740 /* DataType */ +#define UA_NS0ID_MONITORINGPARAMETERS_ENCODING_DEFAULTXML 741 /* Object */ +#define UA_NS0ID_MONITORINGPARAMETERS_ENCODING_DEFAULTBINARY 742 /* Object */ +#define UA_NS0ID_MONITOREDITEMCREATEREQUEST 743 /* DataType */ +#define UA_NS0ID_MONITOREDITEMCREATEREQUEST_ENCODING_DEFAULTXML 744 /* Object */ +#define UA_NS0ID_MONITOREDITEMCREATEREQUEST_ENCODING_DEFAULTBINARY 745 /* Object */ +#define UA_NS0ID_MONITOREDITEMCREATERESULT 746 /* DataType */ +#define UA_NS0ID_MONITOREDITEMCREATERESULT_ENCODING_DEFAULTXML 747 /* Object */ +#define UA_NS0ID_MONITOREDITEMCREATERESULT_ENCODING_DEFAULTBINARY 748 /* Object */ +#define UA_NS0ID_CREATEMONITOREDITEMSREQUEST 749 /* DataType */ +#define UA_NS0ID_CREATEMONITOREDITEMSREQUEST_ENCODING_DEFAULTXML 750 /* Object */ +#define UA_NS0ID_CREATEMONITOREDITEMSREQUEST_ENCODING_DEFAULTBINARY 751 /* Object */ +#define UA_NS0ID_CREATEMONITOREDITEMSRESPONSE 752 /* DataType */ +#define UA_NS0ID_CREATEMONITOREDITEMSRESPONSE_ENCODING_DEFAULTXML 753 /* Object */ +#define UA_NS0ID_CREATEMONITOREDITEMSRESPONSE_ENCODING_DEFAULTBINARY 754 /* Object */ +#define UA_NS0ID_MONITOREDITEMMODIFYREQUEST 755 /* DataType */ +#define UA_NS0ID_MONITOREDITEMMODIFYREQUEST_ENCODING_DEFAULTXML 756 /* Object */ +#define UA_NS0ID_MONITOREDITEMMODIFYREQUEST_ENCODING_DEFAULTBINARY 757 /* Object */ +#define UA_NS0ID_MONITOREDITEMMODIFYRESULT 758 /* DataType */ +#define UA_NS0ID_MONITOREDITEMMODIFYRESULT_ENCODING_DEFAULTXML 759 /* Object */ +#define UA_NS0ID_MONITOREDITEMMODIFYRESULT_ENCODING_DEFAULTBINARY 760 /* Object */ +#define UA_NS0ID_MODIFYMONITOREDITEMSREQUEST 761 /* DataType */ +#define UA_NS0ID_MODIFYMONITOREDITEMSREQUEST_ENCODING_DEFAULTXML 762 /* Object */ +#define UA_NS0ID_MODIFYMONITOREDITEMSREQUEST_ENCODING_DEFAULTBINARY 763 /* Object */ +#define UA_NS0ID_MODIFYMONITOREDITEMSRESPONSE 764 /* DataType */ +#define UA_NS0ID_MODIFYMONITOREDITEMSRESPONSE_ENCODING_DEFAULTXML 765 /* Object */ +#define UA_NS0ID_MODIFYMONITOREDITEMSRESPONSE_ENCODING_DEFAULTBINARY 766 /* Object */ +#define UA_NS0ID_SETMONITORINGMODEREQUEST 767 /* DataType */ +#define UA_NS0ID_SETMONITORINGMODEREQUEST_ENCODING_DEFAULTXML 768 /* Object */ +#define UA_NS0ID_SETMONITORINGMODEREQUEST_ENCODING_DEFAULTBINARY 769 /* Object */ +#define UA_NS0ID_SETMONITORINGMODERESPONSE 770 /* DataType */ +#define UA_NS0ID_SETMONITORINGMODERESPONSE_ENCODING_DEFAULTXML 771 /* Object */ +#define UA_NS0ID_SETMONITORINGMODERESPONSE_ENCODING_DEFAULTBINARY 772 /* Object */ +#define UA_NS0ID_SETTRIGGERINGREQUEST 773 /* DataType */ +#define UA_NS0ID_SETTRIGGERINGREQUEST_ENCODING_DEFAULTXML 774 /* Object */ +#define UA_NS0ID_SETTRIGGERINGREQUEST_ENCODING_DEFAULTBINARY 775 /* Object */ +#define UA_NS0ID_SETTRIGGERINGRESPONSE 776 /* DataType */ +#define UA_NS0ID_SETTRIGGERINGRESPONSE_ENCODING_DEFAULTXML 777 /* Object */ +#define UA_NS0ID_SETTRIGGERINGRESPONSE_ENCODING_DEFAULTBINARY 778 /* Object */ +#define UA_NS0ID_DELETEMONITOREDITEMSREQUEST 779 /* DataType */ +#define UA_NS0ID_DELETEMONITOREDITEMSREQUEST_ENCODING_DEFAULTXML 780 /* Object */ +#define UA_NS0ID_DELETEMONITOREDITEMSREQUEST_ENCODING_DEFAULTBINARY 781 /* Object */ +#define UA_NS0ID_DELETEMONITOREDITEMSRESPONSE 782 /* DataType */ +#define UA_NS0ID_DELETEMONITOREDITEMSRESPONSE_ENCODING_DEFAULTXML 783 /* Object */ +#define UA_NS0ID_DELETEMONITOREDITEMSRESPONSE_ENCODING_DEFAULTBINARY 784 /* Object */ +#define UA_NS0ID_CREATESUBSCRIPTIONREQUEST 785 /* DataType */ +#define UA_NS0ID_CREATESUBSCRIPTIONREQUEST_ENCODING_DEFAULTXML 786 /* Object */ +#define UA_NS0ID_CREATESUBSCRIPTIONREQUEST_ENCODING_DEFAULTBINARY 787 /* Object */ +#define UA_NS0ID_CREATESUBSCRIPTIONRESPONSE 788 /* DataType */ +#define UA_NS0ID_CREATESUBSCRIPTIONRESPONSE_ENCODING_DEFAULTXML 789 /* Object */ +#define UA_NS0ID_CREATESUBSCRIPTIONRESPONSE_ENCODING_DEFAULTBINARY 790 /* Object */ +#define UA_NS0ID_MODIFYSUBSCRIPTIONREQUEST 791 /* DataType */ +#define UA_NS0ID_MODIFYSUBSCRIPTIONREQUEST_ENCODING_DEFAULTXML 792 /* Object */ +#define UA_NS0ID_MODIFYSUBSCRIPTIONREQUEST_ENCODING_DEFAULTBINARY 793 /* Object */ +#define UA_NS0ID_MODIFYSUBSCRIPTIONRESPONSE 794 /* DataType */ +#define UA_NS0ID_MODIFYSUBSCRIPTIONRESPONSE_ENCODING_DEFAULTXML 795 /* Object */ +#define UA_NS0ID_MODIFYSUBSCRIPTIONRESPONSE_ENCODING_DEFAULTBINARY 796 /* Object */ +#define UA_NS0ID_SETPUBLISHINGMODEREQUEST 797 /* DataType */ +#define UA_NS0ID_SETPUBLISHINGMODEREQUEST_ENCODING_DEFAULTXML 798 /* Object */ +#define UA_NS0ID_SETPUBLISHINGMODEREQUEST_ENCODING_DEFAULTBINARY 799 /* Object */ +#define UA_NS0ID_SETPUBLISHINGMODERESPONSE 800 /* DataType */ +#define UA_NS0ID_SETPUBLISHINGMODERESPONSE_ENCODING_DEFAULTXML 801 /* Object */ +#define UA_NS0ID_SETPUBLISHINGMODERESPONSE_ENCODING_DEFAULTBINARY 802 /* Object */ +#define UA_NS0ID_NOTIFICATIONMESSAGE 803 /* DataType */ +#define UA_NS0ID_NOTIFICATIONMESSAGE_ENCODING_DEFAULTXML 804 /* Object */ +#define UA_NS0ID_NOTIFICATIONMESSAGE_ENCODING_DEFAULTBINARY 805 /* Object */ +#define UA_NS0ID_MONITOREDITEMNOTIFICATION 806 /* DataType */ +#define UA_NS0ID_MONITOREDITEMNOTIFICATION_ENCODING_DEFAULTXML 807 /* Object */ +#define UA_NS0ID_MONITOREDITEMNOTIFICATION_ENCODING_DEFAULTBINARY 808 /* Object */ +#define UA_NS0ID_DATACHANGENOTIFICATION 809 /* DataType */ +#define UA_NS0ID_DATACHANGENOTIFICATION_ENCODING_DEFAULTXML 810 /* Object */ +#define UA_NS0ID_DATACHANGENOTIFICATION_ENCODING_DEFAULTBINARY 811 /* Object */ +#define UA_NS0ID_STATUSCHANGENOTIFICATION 818 /* DataType */ +#define UA_NS0ID_STATUSCHANGENOTIFICATION_ENCODING_DEFAULTXML 819 /* Object */ +#define UA_NS0ID_STATUSCHANGENOTIFICATION_ENCODING_DEFAULTBINARY 820 /* Object */ +#define UA_NS0ID_SUBSCRIPTIONACKNOWLEDGEMENT 821 /* DataType */ +#define UA_NS0ID_SUBSCRIPTIONACKNOWLEDGEMENT_ENCODING_DEFAULTXML 822 /* Object */ +#define UA_NS0ID_SUBSCRIPTIONACKNOWLEDGEMENT_ENCODING_DEFAULTBINARY 823 /* Object */ +#define UA_NS0ID_PUBLISHREQUEST 824 /* DataType */ +#define UA_NS0ID_PUBLISHREQUEST_ENCODING_DEFAULTXML 825 /* Object */ +#define UA_NS0ID_PUBLISHREQUEST_ENCODING_DEFAULTBINARY 826 /* Object */ +#define UA_NS0ID_PUBLISHRESPONSE 827 /* DataType */ +#define UA_NS0ID_PUBLISHRESPONSE_ENCODING_DEFAULTXML 828 /* Object */ +#define UA_NS0ID_PUBLISHRESPONSE_ENCODING_DEFAULTBINARY 829 /* Object */ +#define UA_NS0ID_REPUBLISHREQUEST 830 /* DataType */ +#define UA_NS0ID_REPUBLISHREQUEST_ENCODING_DEFAULTXML 831 /* Object */ +#define UA_NS0ID_REPUBLISHREQUEST_ENCODING_DEFAULTBINARY 832 /* Object */ +#define UA_NS0ID_REPUBLISHRESPONSE 833 /* DataType */ +#define UA_NS0ID_REPUBLISHRESPONSE_ENCODING_DEFAULTXML 834 /* Object */ +#define UA_NS0ID_REPUBLISHRESPONSE_ENCODING_DEFAULTBINARY 835 /* Object */ +#define UA_NS0ID_TRANSFERRESULT 836 /* DataType */ +#define UA_NS0ID_TRANSFERRESULT_ENCODING_DEFAULTXML 837 /* Object */ +#define UA_NS0ID_TRANSFERRESULT_ENCODING_DEFAULTBINARY 838 /* Object */ +#define UA_NS0ID_TRANSFERSUBSCRIPTIONSREQUEST 839 /* DataType */ +#define UA_NS0ID_TRANSFERSUBSCRIPTIONSREQUEST_ENCODING_DEFAULTXML 840 /* Object */ +#define UA_NS0ID_TRANSFERSUBSCRIPTIONSREQUEST_ENCODING_DEFAULTBINARY 841 /* Object */ +#define UA_NS0ID_TRANSFERSUBSCRIPTIONSRESPONSE 842 /* DataType */ +#define UA_NS0ID_TRANSFERSUBSCRIPTIONSRESPONSE_ENCODING_DEFAULTXML 843 /* Object */ +#define UA_NS0ID_TRANSFERSUBSCRIPTIONSRESPONSE_ENCODING_DEFAULTBINARY 844 /* Object */ +#define UA_NS0ID_DELETESUBSCRIPTIONSREQUEST 845 /* DataType */ +#define UA_NS0ID_DELETESUBSCRIPTIONSREQUEST_ENCODING_DEFAULTXML 846 /* Object */ +#define UA_NS0ID_DELETESUBSCRIPTIONSREQUEST_ENCODING_DEFAULTBINARY 847 /* Object */ +#define UA_NS0ID_DELETESUBSCRIPTIONSRESPONSE 848 /* DataType */ +#define UA_NS0ID_DELETESUBSCRIPTIONSRESPONSE_ENCODING_DEFAULTXML 849 /* Object */ +#define UA_NS0ID_DELETESUBSCRIPTIONSRESPONSE_ENCODING_DEFAULTBINARY 850 /* Object */ +#define UA_NS0ID_REDUNDANCYSUPPORT 851 /* DataType */ +#define UA_NS0ID_SERVERSTATE 852 /* DataType */ +#define UA_NS0ID_REDUNDANTSERVERDATATYPE 853 /* DataType */ +#define UA_NS0ID_REDUNDANTSERVERDATATYPE_ENCODING_DEFAULTXML 854 /* Object */ +#define UA_NS0ID_REDUNDANTSERVERDATATYPE_ENCODING_DEFAULTBINARY 855 /* Object */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSDATATYPE 856 /* DataType */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSDATATYPE_ENCODING_DEFAULTXML 857 /* Object */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSDATATYPE_ENCODING_DEFAULTBINARY 858 /* Object */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYDATATYPE 859 /* DataType */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYDATATYPE_ENCODING_DEFAULTXML 860 /* Object */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYDATATYPE_ENCODING_DEFAULTBINARY 861 /* Object */ +#define UA_NS0ID_SERVERSTATUSDATATYPE 862 /* DataType */ +#define UA_NS0ID_SERVERSTATUSDATATYPE_ENCODING_DEFAULTXML 863 /* Object */ +#define UA_NS0ID_SERVERSTATUSDATATYPE_ENCODING_DEFAULTBINARY 864 /* Object */ +#define UA_NS0ID_SESSIONDIAGNOSTICSDATATYPE 865 /* DataType */ +#define UA_NS0ID_SESSIONDIAGNOSTICSDATATYPE_ENCODING_DEFAULTXML 866 /* Object */ +#define UA_NS0ID_SESSIONDIAGNOSTICSDATATYPE_ENCODING_DEFAULTBINARY 867 /* Object */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSDATATYPE 868 /* DataType */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSDATATYPE_ENCODING_DEFAULTXML 869 /* Object */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSDATATYPE_ENCODING_DEFAULTBINARY 870 /* Object */ +#define UA_NS0ID_SERVICECOUNTERDATATYPE 871 /* DataType */ +#define UA_NS0ID_SERVICECOUNTERDATATYPE_ENCODING_DEFAULTXML 872 /* Object */ +#define UA_NS0ID_SERVICECOUNTERDATATYPE_ENCODING_DEFAULTBINARY 873 /* Object */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSDATATYPE 874 /* DataType */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSDATATYPE_ENCODING_DEFAULTXML 875 /* Object */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSDATATYPE_ENCODING_DEFAULTBINARY 876 /* Object */ +#define UA_NS0ID_MODELCHANGESTRUCTUREDATATYPE 877 /* DataType */ +#define UA_NS0ID_MODELCHANGESTRUCTUREDATATYPE_ENCODING_DEFAULTXML 878 /* Object */ +#define UA_NS0ID_MODELCHANGESTRUCTUREDATATYPE_ENCODING_DEFAULTBINARY 879 /* Object */ +#define UA_NS0ID_RANGE 884 /* DataType */ +#define UA_NS0ID_RANGE_ENCODING_DEFAULTXML 885 /* Object */ +#define UA_NS0ID_RANGE_ENCODING_DEFAULTBINARY 886 /* Object */ +#define UA_NS0ID_EUINFORMATION 887 /* DataType */ +#define UA_NS0ID_EUINFORMATION_ENCODING_DEFAULTXML 888 /* Object */ +#define UA_NS0ID_EUINFORMATION_ENCODING_DEFAULTBINARY 889 /* Object */ +#define UA_NS0ID_EXCEPTIONDEVIATIONFORMAT 890 /* DataType */ +#define UA_NS0ID_ANNOTATION 891 /* DataType */ +#define UA_NS0ID_ANNOTATION_ENCODING_DEFAULTXML 892 /* Object */ +#define UA_NS0ID_ANNOTATION_ENCODING_DEFAULTBINARY 893 /* Object */ +#define UA_NS0ID_PROGRAMDIAGNOSTICDATATYPE 894 /* DataType */ +#define UA_NS0ID_PROGRAMDIAGNOSTICDATATYPE_ENCODING_DEFAULTXML 895 /* Object */ +#define UA_NS0ID_PROGRAMDIAGNOSTICDATATYPE_ENCODING_DEFAULTBINARY 896 /* Object */ +#define UA_NS0ID_SEMANTICCHANGESTRUCTUREDATATYPE 897 /* DataType */ +#define UA_NS0ID_SEMANTICCHANGESTRUCTUREDATATYPE_ENCODING_DEFAULTXML 898 /* Object */ +#define UA_NS0ID_SEMANTICCHANGESTRUCTUREDATATYPE_ENCODING_DEFAULTBINARY 899 /* Object */ +#define UA_NS0ID_EVENTNOTIFICATIONLIST 914 /* DataType */ +#define UA_NS0ID_EVENTNOTIFICATIONLIST_ENCODING_DEFAULTXML 915 /* Object */ +#define UA_NS0ID_EVENTNOTIFICATIONLIST_ENCODING_DEFAULTBINARY 916 /* Object */ +#define UA_NS0ID_EVENTFIELDLIST 917 /* DataType */ +#define UA_NS0ID_EVENTFIELDLIST_ENCODING_DEFAULTXML 918 /* Object */ +#define UA_NS0ID_EVENTFIELDLIST_ENCODING_DEFAULTBINARY 919 /* Object */ +#define UA_NS0ID_HISTORYEVENTFIELDLIST 920 /* DataType */ +#define UA_NS0ID_HISTORYEVENTFIELDLIST_ENCODING_DEFAULTXML 921 /* Object */ +#define UA_NS0ID_HISTORYEVENTFIELDLIST_ENCODING_DEFAULTBINARY 922 /* Object */ +#define UA_NS0ID_ISSUEDIDENTITYTOKEN 938 /* DataType */ +#define UA_NS0ID_ISSUEDIDENTITYTOKEN_ENCODING_DEFAULTXML 939 /* Object */ +#define UA_NS0ID_ISSUEDIDENTITYTOKEN_ENCODING_DEFAULTBINARY 940 /* Object */ +#define UA_NS0ID_NOTIFICATIONDATA 945 /* DataType */ +#define UA_NS0ID_NOTIFICATIONDATA_ENCODING_DEFAULTXML 946 /* Object */ +#define UA_NS0ID_NOTIFICATIONDATA_ENCODING_DEFAULTBINARY 947 /* Object */ +#define UA_NS0ID_AGGREGATECONFIGURATION 948 /* DataType */ +#define UA_NS0ID_AGGREGATECONFIGURATION_ENCODING_DEFAULTXML 949 /* Object */ +#define UA_NS0ID_AGGREGATECONFIGURATION_ENCODING_DEFAULTBINARY 950 /* Object */ +#define UA_NS0ID_IMAGEBMP 2000 /* DataType */ +#define UA_NS0ID_IMAGEGIF 2001 /* DataType */ +#define UA_NS0ID_IMAGEJPG 2002 /* DataType */ +#define UA_NS0ID_IMAGEPNG 2003 /* DataType */ +#define UA_NS0ID_SERVERTYPE 2004 /* ObjectType */ +#define UA_NS0ID_SERVERTYPE_SERVERARRAY 2005 /* Variable */ +#define UA_NS0ID_SERVERTYPE_NAMESPACEARRAY 2006 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS 2007 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVICELEVEL 2008 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES 2009 /* Object */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS 2010 /* Object */ +#define UA_NS0ID_SERVERTYPE_VENDORSERVERINFO 2011 /* Object */ +#define UA_NS0ID_SERVERTYPE_SERVERREDUNDANCY 2012 /* Object */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE 2013 /* ObjectType */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_SERVERPROFILEARRAY 2014 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_LOCALEIDARRAY 2016 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MINSUPPORTEDSAMPLERATE 2017 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MODELLINGRULES 2019 /* Object */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE 2020 /* ObjectType */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY 2021 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SAMPLINGINTERVALDIAGNOSTICSARRAY 2022 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SUBSCRIPTIONDIAGNOSTICSARRAY 2023 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_ENABLEDFLAG 2025 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE 2026 /* ObjectType */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_SESSIONDIAGNOSTICSARRAY 2027 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_SESSIONSECURITYDIAGNOSTICSARRAY 2028 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE 2029 /* ObjectType */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS 2030 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONSECURITYDIAGNOSTICS 2031 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SUBSCRIPTIONDIAGNOSTICSARRAY 2032 /* Variable */ +#define UA_NS0ID_VENDORSERVERINFOTYPE 2033 /* ObjectType */ +#define UA_NS0ID_SERVERREDUNDANCYTYPE 2034 /* ObjectType */ +#define UA_NS0ID_SERVERREDUNDANCYTYPE_REDUNDANCYSUPPORT 2035 /* Variable */ +#define UA_NS0ID_TRANSPARENTREDUNDANCYTYPE 2036 /* ObjectType */ +#define UA_NS0ID_TRANSPARENTREDUNDANCYTYPE_CURRENTSERVERID 2037 /* Variable */ +#define UA_NS0ID_TRANSPARENTREDUNDANCYTYPE_REDUNDANTSERVERARRAY 2038 /* Variable */ +#define UA_NS0ID_NONTRANSPARENTREDUNDANCYTYPE 2039 /* ObjectType */ +#define UA_NS0ID_NONTRANSPARENTREDUNDANCYTYPE_SERVERURIARRAY 2040 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE 2041 /* ObjectType */ +#define UA_NS0ID_BASEEVENTTYPE_EVENTID 2042 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE_EVENTTYPE 2043 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE_SOURCENODE 2044 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE_SOURCENAME 2045 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE_TIME 2046 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE_RECEIVETIME 2047 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE_MESSAGE 2050 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE_SEVERITY 2051 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE 2052 /* ObjectType */ +#define UA_NS0ID_AUDITEVENTTYPE_ACTIONTIMESTAMP 2053 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_STATUS 2054 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_SERVERID 2055 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_CLIENTAUDITENTRYID 2056 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_CLIENTUSERID 2057 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE 2058 /* ObjectType */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE 2059 /* ObjectType */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE 2060 /* ObjectType */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_CLIENTCERTIFICATE 2061 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_REQUESTTYPE 2062 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_SECURITYPOLICYURI 2063 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_SECURITYMODE 2065 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_REQUESTEDLIFETIME 2066 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE 2069 /* ObjectType */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_SESSIONID 2070 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE 2071 /* ObjectType */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_SECURECHANNELID 2072 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_CLIENTCERTIFICATE 2073 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_REVISEDSESSIONTIMEOUT 2074 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE 2075 /* ObjectType */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_CLIENTSOFTWARECERTIFICATES 2076 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_USERIDENTITYTOKEN 2077 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE 2078 /* ObjectType */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_REQUESTHANDLE 2079 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE 2080 /* ObjectType */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_CERTIFICATE 2081 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE 2082 /* ObjectType */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_INVALIDHOSTNAME 2083 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_INVALIDURI 2084 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE 2085 /* ObjectType */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE 2086 /* ObjectType */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE 2087 /* ObjectType */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE 2088 /* ObjectType */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE 2089 /* ObjectType */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE 2090 /* ObjectType */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE 2091 /* ObjectType */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_NODESTOADD 2092 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE 2093 /* ObjectType */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_NODESTODELETE 2094 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE 2095 /* ObjectType */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_REFERENCESTOADD 2096 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE 2097 /* ObjectType */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_REFERENCESTODELETE 2098 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE 2099 /* ObjectType */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE 2100 /* ObjectType */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_INDEXRANGE 2101 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_OLDVALUE 2102 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_NEWVALUE 2103 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE 2104 /* ObjectType */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE 2127 /* ObjectType */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_METHODID 2128 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_INPUTARGUMENTS 2129 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE 2130 /* ObjectType */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE 2131 /* ObjectType */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE 2132 /* ObjectType */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE 2133 /* ObjectType */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_CHANGES 2134 /* Variable */ +#define UA_NS0ID_SERVERVENDORCAPABILITYTYPE 2137 /* VariableType */ +#define UA_NS0ID_SERVERSTATUSTYPE 2138 /* VariableType */ +#define UA_NS0ID_SERVERSTATUSTYPE_STARTTIME 2139 /* Variable */ +#define UA_NS0ID_SERVERSTATUSTYPE_CURRENTTIME 2140 /* Variable */ +#define UA_NS0ID_SERVERSTATUSTYPE_STATE 2141 /* Variable */ +#define UA_NS0ID_SERVERSTATUSTYPE_BUILDINFO 2142 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE 2150 /* VariableType */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE_SERVERVIEWCOUNT 2151 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE_CURRENTSESSIONCOUNT 2152 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE_CUMULATEDSESSIONCOUNT 2153 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE_SECURITYREJECTEDSESSIONCOUNT 2154 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE_REJECTEDSESSIONCOUNT 2155 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE_SESSIONTIMEOUTCOUNT 2156 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE_SESSIONABORTCOUNT 2157 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE_PUBLISHINGINTERVALCOUNT 2159 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE_CURRENTSUBSCRIPTIONCOUNT 2160 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE_CUMULATEDSUBSCRIPTIONCOUNT 2161 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE_SECURITYREJECTEDREQUESTSCOUNT 2162 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYTYPE_REJECTEDREQUESTSCOUNT 2163 /* Variable */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSARRAYTYPE 2164 /* VariableType */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSTYPE 2165 /* VariableType */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSTYPE_SAMPLINGINTERVAL 2166 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE 2171 /* VariableType */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE 2172 /* VariableType */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_SESSIONID 2173 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_SUBSCRIPTIONID 2174 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_PRIORITY 2175 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_PUBLISHINGINTERVAL 2176 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_MAXKEEPALIVECOUNT 2177 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_MAXNOTIFICATIONSPERPUBLISH 2179 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_PUBLISHINGENABLED 2180 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_MODIFYCOUNT 2181 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_ENABLECOUNT 2182 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_DISABLECOUNT 2183 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_REPUBLISHREQUESTCOUNT 2184 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_REPUBLISHMESSAGEREQUESTCOUNT 2185 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_REPUBLISHMESSAGECOUNT 2186 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_TRANSFERREQUESTCOUNT 2187 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_TRANSFERREDTOALTCLIENTCOUNT 2188 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_TRANSFERREDTOSAMECLIENTCOUNT 2189 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_PUBLISHREQUESTCOUNT 2190 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_DATACHANGENOTIFICATIONSCOUNT 2191 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_NOTIFICATIONSCOUNT 2193 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE 2196 /* VariableType */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE 2197 /* VariableType */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_SESSIONID 2198 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_SESSIONNAME 2199 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_CLIENTDESCRIPTION 2200 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_SERVERURI 2201 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_ENDPOINTURL 2202 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_LOCALEIDS 2203 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_ACTUALSESSIONTIMEOUT 2204 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_CLIENTCONNECTIONTIME 2205 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_CLIENTLASTCONTACTTIME 2206 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_CURRENTSUBSCRIPTIONSCOUNT 2207 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_CURRENTMONITOREDITEMSCOUNT 2208 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_CURRENTPUBLISHREQUESTSINQUEUE 2209 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_READCOUNT 2217 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_HISTORYREADCOUNT 2218 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_WRITECOUNT 2219 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_HISTORYUPDATECOUNT 2220 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_CALLCOUNT 2221 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_CREATEMONITOREDITEMSCOUNT 2222 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_MODIFYMONITOREDITEMSCOUNT 2223 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_SETMONITORINGMODECOUNT 2224 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_SETTRIGGERINGCOUNT 2225 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_DELETEMONITOREDITEMSCOUNT 2226 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_CREATESUBSCRIPTIONCOUNT 2227 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_MODIFYSUBSCRIPTIONCOUNT 2228 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_SETPUBLISHINGMODECOUNT 2229 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_PUBLISHCOUNT 2230 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_REPUBLISHCOUNT 2231 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_TRANSFERSUBSCRIPTIONSCOUNT 2232 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_DELETESUBSCRIPTIONSCOUNT 2233 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_ADDNODESCOUNT 2234 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_ADDREFERENCESCOUNT 2235 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_DELETENODESCOUNT 2236 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_DELETEREFERENCESCOUNT 2237 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_BROWSECOUNT 2238 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_BROWSENEXTCOUNT 2239 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_TRANSLATEBROWSEPATHSTONODEIDSCOUNT 2240 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_QUERYFIRSTCOUNT 2241 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_QUERYNEXTCOUNT 2242 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSARRAYTYPE 2243 /* VariableType */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSTYPE 2244 /* VariableType */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSTYPE_SESSIONID 2245 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSTYPE_CLIENTUSERIDOFSESSION 2246 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSTYPE_CLIENTUSERIDHISTORY 2247 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSTYPE_AUTHENTICATIONMECHANISM 2248 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSTYPE_ENCODING 2249 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSTYPE_TRANSPORTPROTOCOL 2250 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSTYPE_SECURITYMODE 2251 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSTYPE_SECURITYPOLICYURI 2252 /* Variable */ +#define UA_NS0ID_SERVER 2253 /* Object */ +#define UA_NS0ID_SERVER_SERVERARRAY 2254 /* Variable */ +#define UA_NS0ID_SERVER_NAMESPACEARRAY 2255 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS 2256 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS_STARTTIME 2257 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME 2258 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS_STATE 2259 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO 2260 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME 2261 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTURI 2262 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_MANUFACTURERNAME 2263 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_SOFTWAREVERSION 2264 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDNUMBER 2265 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDDATE 2266 /* Variable */ +#define UA_NS0ID_SERVER_SERVICELEVEL 2267 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES 2268 /* Object */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_SERVERPROFILEARRAY 2269 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_LOCALEIDARRAY 2271 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MINSUPPORTEDSAMPLERATE 2272 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS 2274 /* Object */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY 2275 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SERVERVIEWCOUNT 2276 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CURRENTSESSIONCOUNT 2277 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CUMULATEDSESSIONCOUNT 2278 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SECURITYREJECTEDSESSIONCOUNT 2279 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SESSIONTIMEOUTCOUNT 2281 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SESSIONABORTCOUNT 2282 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_PUBLISHINGINTERVALCOUNT 2284 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CURRENTSUBSCRIPTIONCOUNT 2285 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CUMULATEDSUBSCRIPTIONCOUNT 2286 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SECURITYREJECTEDREQUESTSCOUNT 2287 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_REJECTEDREQUESTSCOUNT 2288 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SAMPLINGINTERVALDIAGNOSTICSARRAY 2289 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SUBSCRIPTIONDIAGNOSTICSARRAY 2290 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_ENABLEDFLAG 2294 /* Variable */ +#define UA_NS0ID_SERVER_VENDORSERVERINFO 2295 /* Object */ +#define UA_NS0ID_SERVER_SERVERREDUNDANCY 2296 /* Object */ +#define UA_NS0ID_STATEMACHINETYPE 2299 /* ObjectType */ +#define UA_NS0ID_STATETYPE 2307 /* ObjectType */ +#define UA_NS0ID_STATETYPE_STATENUMBER 2308 /* Variable */ +#define UA_NS0ID_INITIALSTATETYPE 2309 /* ObjectType */ +#define UA_NS0ID_TRANSITIONTYPE 2310 /* ObjectType */ +#define UA_NS0ID_TRANSITIONEVENTTYPE 2311 /* ObjectType */ +#define UA_NS0ID_TRANSITIONTYPE_TRANSITIONNUMBER 2312 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE 2315 /* ObjectType */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE 2318 /* ObjectType */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_STEPPED 2323 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_DEFINITION 2324 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_MAXTIMEINTERVAL 2325 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_MINTIMEINTERVAL 2326 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_EXCEPTIONDEVIATION 2327 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_EXCEPTIONDEVIATIONFORMAT 2328 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE 2330 /* ObjectType */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_ACCESSHISTORYDATACAPABILITY 2331 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_ACCESSHISTORYEVENTSCAPABILITY 2332 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_INSERTDATACAPABILITY 2334 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_REPLACEDATACAPABILITY 2335 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_UPDATEDATACAPABILITY 2336 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_DELETERAWCAPABILITY 2337 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_DELETEATTIMECAPABILITY 2338 /* Variable */ +#define UA_NS0ID_AGGREGATEFUNCTIONTYPE 2340 /* ObjectType */ +#define UA_NS0ID_AGGREGATEFUNCTION_INTERPOLATIVE 2341 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_AVERAGE 2342 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_TIMEAVERAGE 2343 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_TOTAL 2344 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_MINIMUM 2346 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_MAXIMUM 2347 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_MINIMUMACTUALTIME 2348 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_MAXIMUMACTUALTIME 2349 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_RANGE 2350 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_ANNOTATIONCOUNT 2351 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_COUNT 2352 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_NUMBEROFTRANSITIONS 2355 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_START 2357 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_END 2358 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_DELTA 2359 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_DURATIONGOOD 2360 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_DURATIONBAD 2361 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_PERCENTGOOD 2362 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_PERCENTBAD 2363 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_WORSTQUALITY 2364 /* Object */ +#define UA_NS0ID_DATAITEMTYPE 2365 /* VariableType */ +#define UA_NS0ID_DATAITEMTYPE_DEFINITION 2366 /* Variable */ +#define UA_NS0ID_DATAITEMTYPE_VALUEPRECISION 2367 /* Variable */ +#define UA_NS0ID_ANALOGITEMTYPE 2368 /* VariableType */ +#define UA_NS0ID_ANALOGITEMTYPE_EURANGE 2369 /* Variable */ +#define UA_NS0ID_ANALOGITEMTYPE_INSTRUMENTRANGE 2370 /* Variable */ +#define UA_NS0ID_ANALOGITEMTYPE_ENGINEERINGUNITS 2371 /* Variable */ +#define UA_NS0ID_DISCRETEITEMTYPE 2372 /* VariableType */ +#define UA_NS0ID_TWOSTATEDISCRETETYPE 2373 /* VariableType */ +#define UA_NS0ID_TWOSTATEDISCRETETYPE_FALSESTATE 2374 /* Variable */ +#define UA_NS0ID_TWOSTATEDISCRETETYPE_TRUESTATE 2375 /* Variable */ +#define UA_NS0ID_MULTISTATEDISCRETETYPE 2376 /* VariableType */ +#define UA_NS0ID_MULTISTATEDISCRETETYPE_ENUMSTRINGS 2377 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE 2378 /* ObjectType */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_INTERMEDIATERESULT 2379 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTICTYPE 2380 /* VariableType */ +#define UA_NS0ID_PROGRAMDIAGNOSTICTYPE_CREATESESSIONID 2381 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTICTYPE_CREATECLIENTNAME 2382 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTICTYPE_INVOCATIONCREATIONTIME 2383 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTICTYPE_LASTTRANSITIONTIME 2384 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTICTYPE_LASTMETHODCALL 2385 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTICTYPE_LASTMETHODSESSIONID 2386 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTICTYPE_LASTMETHODINPUTARGUMENTS 2387 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTICTYPE_LASTMETHODOUTPUTARGUMENTS 2388 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTICTYPE_LASTMETHODCALLTIME 2389 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTICTYPE_LASTMETHODRETURNSTATUS 2390 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE 2391 /* ObjectType */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_CREATABLE 2392 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_DELETABLE 2393 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_AUTODELETE 2394 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_RECYCLECOUNT 2395 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_INSTANCECOUNT 2396 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_MAXINSTANCECOUNT 2397 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_MAXRECYCLECOUNT 2398 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC 2399 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_READY 2400 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_READY_STATENUMBER 2401 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_RUNNING 2402 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_RUNNING_STATENUMBER 2403 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_SUSPENDED 2404 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_SUSPENDED_STATENUMBER 2405 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_HALTED 2406 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_HALTED_STATENUMBER 2407 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_HALTEDTOREADY 2408 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_HALTEDTOREADY_TRANSITIONNUMBER 2409 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_READYTORUNNING 2410 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_READYTORUNNING_TRANSITIONNUMBER 2411 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_RUNNINGTOHALTED 2412 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_RUNNINGTOHALTED_TRANSITIONNUMBER 2413 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_RUNNINGTOREADY 2414 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_RUNNINGTOREADY_TRANSITIONNUMBER 2415 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_RUNNINGTOSUSPENDED 2416 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_RUNNINGTOSUSPENDED_TRANSITIONNUMBER 2417 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_SUSPENDEDTORUNNING 2418 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_SUSPENDEDTORUNNING_TRANSITIONNUMBER 2419 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_SUSPENDEDTOHALTED 2420 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_SUSPENDEDTOHALTED_TRANSITIONNUMBER 2421 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_SUSPENDEDTOREADY 2422 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_SUSPENDEDTOREADY_TRANSITIONNUMBER 2423 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_READYTOHALTED 2424 /* Object */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_READYTOHALTED_TRANSITIONNUMBER 2425 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_START 2426 /* Method */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_SUSPEND 2427 /* Method */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_RESUME 2428 /* Method */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_HALT 2429 /* Method */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_RESET 2430 /* Method */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_REGISTERNODESCOUNT 2730 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_UNREGISTERNODESCOUNT 2731 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXBROWSECONTINUATIONPOINTS 2732 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXQUERYCONTINUATIONPOINTS 2733 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXHISTORYCONTINUATIONPOINTS 2734 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXBROWSECONTINUATIONPOINTS 2735 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXQUERYCONTINUATIONPOINTS 2736 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXHISTORYCONTINUATIONPOINTS 2737 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE 2738 /* ObjectType */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_CHANGES 2739 /* Variable */ +#define UA_NS0ID_SERVERTYPE_AUDITING 2742 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SESSIONSDIAGNOSTICSSUMMARY 2744 /* Object */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_SECURECHANNELID 2745 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_CLIENTCERTIFICATETHUMBPRINT 2746 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_CLIENTCERTIFICATETHUMBPRINT 2747 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE 2748 /* ObjectType */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_ENDPOINTURL 2749 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_ATTRIBUTEID 2750 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_PARAMETERDATATYPEID 2751 /* Variable */ +#define UA_NS0ID_SERVERSTATUSTYPE_SECONDSTILLSHUTDOWN 2752 /* Variable */ +#define UA_NS0ID_SERVERSTATUSTYPE_SHUTDOWNREASON 2753 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_AGGREGATEFUNCTIONS 2754 /* Object */ +#define UA_NS0ID_STATEVARIABLETYPE 2755 /* VariableType */ +#define UA_NS0ID_STATEVARIABLETYPE_ID 2756 /* Variable */ +#define UA_NS0ID_STATEVARIABLETYPE_NAME 2757 /* Variable */ +#define UA_NS0ID_STATEVARIABLETYPE_NUMBER 2758 /* Variable */ +#define UA_NS0ID_STATEVARIABLETYPE_EFFECTIVEDISPLAYNAME 2759 /* Variable */ +#define UA_NS0ID_FINITESTATEVARIABLETYPE 2760 /* VariableType */ +#define UA_NS0ID_FINITESTATEVARIABLETYPE_ID 2761 /* Variable */ +#define UA_NS0ID_TRANSITIONVARIABLETYPE 2762 /* VariableType */ +#define UA_NS0ID_TRANSITIONVARIABLETYPE_ID 2763 /* Variable */ +#define UA_NS0ID_TRANSITIONVARIABLETYPE_NAME 2764 /* Variable */ +#define UA_NS0ID_TRANSITIONVARIABLETYPE_NUMBER 2765 /* Variable */ +#define UA_NS0ID_TRANSITIONVARIABLETYPE_TRANSITIONTIME 2766 /* Variable */ +#define UA_NS0ID_FINITETRANSITIONVARIABLETYPE 2767 /* VariableType */ +#define UA_NS0ID_FINITETRANSITIONVARIABLETYPE_ID 2768 /* Variable */ +#define UA_NS0ID_STATEMACHINETYPE_CURRENTSTATE 2769 /* Variable */ +#define UA_NS0ID_STATEMACHINETYPE_LASTTRANSITION 2770 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE 2771 /* ObjectType */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_CURRENTSTATE 2772 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_LASTTRANSITION 2773 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_TRANSITION 2774 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_FROMSTATE 2775 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_TOSTATE 2776 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_OLDSTATEID 2777 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_NEWSTATEID 2778 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE 2782 /* ObjectType */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE 2787 /* ObjectType */ +#define UA_NS0ID_REFRESHENDEVENTTYPE 2788 /* ObjectType */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE 2789 /* ObjectType */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE 2790 /* ObjectType */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE 2803 /* ObjectType */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE 2829 /* ObjectType */ +#define UA_NS0ID_DIALOGCONDITIONTYPE 2830 /* ObjectType */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_PROMPT 2831 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE 2881 /* ObjectType */ +#define UA_NS0ID_ALARMCONDITIONTYPE 2915 /* ObjectType */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE 2929 /* ObjectType */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_UNSHELVED 2930 /* Object */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_TIMEDSHELVED 2932 /* Object */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_ONESHOTSHELVED 2933 /* Object */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_UNSHELVEDTOTIMEDSHELVED 2935 /* Object */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_UNSHELVEDTOONESHOTSHELVED 2936 /* Object */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_TIMEDSHELVEDTOUNSHELVED 2940 /* Object */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_TIMEDSHELVEDTOONESHOTSHELVED 2942 /* Object */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_ONESHOTSHELVEDTOUNSHELVED 2943 /* Object */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_ONESHOTSHELVEDTOTIMEDSHELVED 2945 /* Object */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_UNSHELVE 2947 /* Method */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_ONESHOTSHELVE 2948 /* Method */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_TIMEDSHELVE 2949 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE 2955 /* ObjectType */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_TIMEDSHELVE_INPUTARGUMENTS 2991 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS_SECONDSTILLSHUTDOWN 2992 /* Variable */ +#define UA_NS0ID_SERVER_SERVERSTATUS_SHUTDOWNREASON 2993 /* Variable */ +#define UA_NS0ID_SERVER_AUDITING 2994 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES 2996 /* Object */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_AGGREGATEFUNCTIONS 2997 /* Object */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_EVENTNOTIFICATIONSCOUNT 2998 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE 2999 /* ObjectType */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_FILTER 3003 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE 3006 /* ObjectType */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE 3012 /* ObjectType */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE 3014 /* ObjectType */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_ISDELETEMODIFIED 3015 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_STARTTIME 3016 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_ENDTIME 3017 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE 3019 /* ObjectType */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_REQTIMES 3020 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_OLDVALUES 3021 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE 3022 /* ObjectType */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_EVENTIDS 3023 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_OLDVALUES 3024 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_UPDATEDNODE 3025 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_UPDATEDNODE 3026 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_UPDATEDNODE 3027 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_PERFORMINSERTREPLACE 3028 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_NEWVALUES 3029 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_OLDVALUES 3030 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_PERFORMINSERTREPLACE 3031 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_NEWVALUES 3032 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_OLDVALUES 3033 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_OLDVALUES 3034 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE 3035 /* ObjectType */ +#define UA_NS0ID_EVENTTYPESFOLDER 3048 /* Object */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_SOFTWARECERTIFICATES 3049 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_MAXRESPONSEMESSAGESIZE 3050 /* Variable */ +#define UA_NS0ID_BUILDINFOTYPE 3051 /* VariableType */ +#define UA_NS0ID_BUILDINFOTYPE_PRODUCTURI 3052 /* Variable */ +#define UA_NS0ID_BUILDINFOTYPE_MANUFACTURERNAME 3053 /* Variable */ +#define UA_NS0ID_BUILDINFOTYPE_PRODUCTNAME 3054 /* Variable */ +#define UA_NS0ID_BUILDINFOTYPE_SOFTWAREVERSION 3055 /* Variable */ +#define UA_NS0ID_BUILDINFOTYPE_BUILDNUMBER 3056 /* Variable */ +#define UA_NS0ID_BUILDINFOTYPE_BUILDDATE 3057 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSTYPE_CLIENTCERTIFICATE 3058 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_AGGREGATECONFIGURATION 3059 /* Object */ +#define UA_NS0ID_DEFAULTBINARY 3062 /* Object */ +#define UA_NS0ID_DEFAULTXML 3063 /* Object */ +#define UA_NS0ID_ALWAYSGENERATESEVENT 3065 /* ReferenceType */ +#define UA_NS0ID_ICON 3067 /* Variable */ +#define UA_NS0ID_NODEVERSION 3068 /* Variable */ +#define UA_NS0ID_LOCALTIME 3069 /* Variable */ +#define UA_NS0ID_ALLOWNULLS 3070 /* Variable */ +#define UA_NS0ID_ENUMVALUES 3071 /* Variable */ +#define UA_NS0ID_INPUTARGUMENTS 3072 /* Variable */ +#define UA_NS0ID_OUTPUTARGUMENTS 3073 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS_STARTTIME 3074 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS_CURRENTTIME 3075 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS_STATE 3076 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS_BUILDINFO 3077 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS_BUILDINFO_PRODUCTURI 3078 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS_BUILDINFO_MANUFACTURERNAME 3079 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS_BUILDINFO_PRODUCTNAME 3080 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS_BUILDINFO_SOFTWAREVERSION 3081 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS_BUILDINFO_BUILDNUMBER 3082 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS_BUILDINFO_BUILDDATE 3083 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS_SECONDSTILLSHUTDOWN 3084 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERSTATUS_SHUTDOWNREASON 3085 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_SERVERPROFILEARRAY 3086 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_LOCALEIDARRAY 3087 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MINSUPPORTEDSAMPLERATE 3088 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXBROWSECONTINUATIONPOINTS 3089 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXQUERYCONTINUATIONPOINTS 3090 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXHISTORYCONTINUATIONPOINTS 3091 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_SOFTWARECERTIFICATES 3092 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MODELLINGRULES 3093 /* Object */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_AGGREGATEFUNCTIONS 3094 /* Object */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY 3095 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SERVERVIEWCOUNT 3096 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CURRENTSESSIONCOUNT 3097 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CUMULATEDSESSIONCOUNT 3098 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SECURITYREJECTEDSESSIONCOUNT 3099 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_REJECTEDSESSIONCOUNT 3100 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SESSIONTIMEOUTCOUNT 3101 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SESSIONABORTCOUNT 3102 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_PUBLISHINGINTERVALCOUNT 3104 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CURRENTSUBSCRIPTIONCOUNT 3105 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_CUMULATEDSUBSCRIPTIONCOUNT 3106 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_SECURITYREJECTEDREQUESTSCOUNT 3107 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_REJECTEDREQUESTSCOUNT 3108 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SAMPLINGINTERVALDIAGNOSTICSARRAY 3109 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SUBSCRIPTIONDIAGNOSTICSARRAY 3110 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY 3111 /* Object */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY_SESSIONDIAGNOSTICSARRAY 3112 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY_SESSIONSECURITYDIAGNOSTICSARRAY 3113 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERDIAGNOSTICS_ENABLEDFLAG 3114 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERREDUNDANCY_REDUNDANCYSUPPORT 3115 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY_SERVERVIEWCOUNT 3116 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY_CURRENTSESSIONCOUNT 3117 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY_CUMULATEDSESSIONCOUNT 3118 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY_SECURITYREJECTEDSESSIONCOUNT 3119 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY_REJECTEDSESSIONCOUNT 3120 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY_SESSIONTIMEOUTCOUNT 3121 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY_SESSIONABORTCOUNT 3122 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY_PUBLISHINGINTERVALCOUNT 3124 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY_CURRENTSUBSCRIPTIONCOUNT 3125 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY_CUMULATEDSUBSCRIPTIONCOUNT 3126 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY_SECURITYREJECTEDREQUESTSCOUNT 3127 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SERVERDIAGNOSTICSSUMMARY_REJECTEDREQUESTSCOUNT 3128 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SESSIONSDIAGNOSTICSSUMMARY_SESSIONDIAGNOSTICSARRAY 3129 /* Variable */ +#define UA_NS0ID_SERVERDIAGNOSTICSTYPE_SESSIONSDIAGNOSTICSSUMMARY_SESSIONSECURITYDIAGNOSTICSARRAY 3130 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_SESSIONID 3131 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_SESSIONNAME 3132 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_CLIENTDESCRIPTION 3133 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_SERVERURI 3134 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_ENDPOINTURL 3135 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_LOCALEIDS 3136 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_ACTUALSESSIONTIMEOUT 3137 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_MAXRESPONSEMESSAGESIZE 3138 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_CLIENTCONNECTIONTIME 3139 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_CLIENTLASTCONTACTTIME 3140 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_CURRENTSUBSCRIPTIONSCOUNT 3141 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_CURRENTMONITOREDITEMSCOUNT 3142 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_CURRENTPUBLISHREQUESTSINQUEUE 3143 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_READCOUNT 3151 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_HISTORYREADCOUNT 3152 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_WRITECOUNT 3153 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_HISTORYUPDATECOUNT 3154 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_CALLCOUNT 3155 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_CREATEMONITOREDITEMSCOUNT 3156 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_MODIFYMONITOREDITEMSCOUNT 3157 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_SETMONITORINGMODECOUNT 3158 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_SETTRIGGERINGCOUNT 3159 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_DELETEMONITOREDITEMSCOUNT 3160 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_CREATESUBSCRIPTIONCOUNT 3161 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_MODIFYSUBSCRIPTIONCOUNT 3162 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_SETPUBLISHINGMODECOUNT 3163 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_PUBLISHCOUNT 3164 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_REPUBLISHCOUNT 3165 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_TRANSFERSUBSCRIPTIONSCOUNT 3166 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_DELETESUBSCRIPTIONSCOUNT 3167 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_ADDNODESCOUNT 3168 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_ADDREFERENCESCOUNT 3169 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_DELETENODESCOUNT 3170 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_DELETEREFERENCESCOUNT 3171 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_BROWSECOUNT 3172 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_BROWSENEXTCOUNT 3173 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_TRANSLATEBROWSEPATHSTONODEIDSCOUNT 3174 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_QUERYFIRSTCOUNT 3175 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_QUERYNEXTCOUNT 3176 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_REGISTERNODESCOUNT 3177 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_UNREGISTERNODESCOUNT 3178 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONSECURITYDIAGNOSTICS_SESSIONID 3179 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONSECURITYDIAGNOSTICS_CLIENTUSERIDOFSESSION 3180 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONSECURITYDIAGNOSTICS_CLIENTUSERIDHISTORY 3181 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONSECURITYDIAGNOSTICS_AUTHENTICATIONMECHANISM 3182 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONSECURITYDIAGNOSTICS_ENCODING 3183 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONSECURITYDIAGNOSTICS_TRANSPORTPROTOCOL 3184 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONSECURITYDIAGNOSTICS_SECURITYMODE 3185 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONSECURITYDIAGNOSTICS_SECURITYPOLICYURI 3186 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONSECURITYDIAGNOSTICS_CLIENTCERTIFICATE 3187 /* Variable */ +#define UA_NS0ID_TRANSPARENTREDUNDANCYTYPE_REDUNDANCYSUPPORT 3188 /* Variable */ +#define UA_NS0ID_NONTRANSPARENTREDUNDANCYTYPE_REDUNDANCYSUPPORT 3189 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE_LOCALTIME 3190 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_EVENTID 3191 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_EVENTTYPE 3192 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_SOURCENODE 3193 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_SOURCENAME 3194 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_TIME 3195 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_RECEIVETIME 3196 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_LOCALTIME 3197 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_MESSAGE 3198 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_SEVERITY 3199 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_EVENTID 3200 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_EVENTTYPE 3201 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_SOURCENODE 3202 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_SOURCENAME 3203 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_TIME 3204 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_RECEIVETIME 3205 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_LOCALTIME 3206 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_MESSAGE 3207 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_SEVERITY 3208 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_EVENTID 3209 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_EVENTTYPE 3210 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_SOURCENODE 3211 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_SOURCENAME 3212 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_TIME 3213 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_RECEIVETIME 3214 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_LOCALTIME 3215 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_MESSAGE 3216 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_SEVERITY 3217 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_ACTIONTIMESTAMP 3218 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_STATUS 3219 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_SERVERID 3220 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_CLIENTAUDITENTRYID 3221 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_CLIENTUSERID 3222 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_EVENTID 3223 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_EVENTTYPE 3224 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_SOURCENODE 3225 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_SOURCENAME 3226 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_TIME 3227 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_RECEIVETIME 3228 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_LOCALTIME 3229 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_MESSAGE 3230 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_SEVERITY 3231 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_ACTIONTIMESTAMP 3232 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_STATUS 3233 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_SERVERID 3234 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_CLIENTAUDITENTRYID 3235 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_CLIENTUSERID 3236 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_EVENTID 3237 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_EVENTTYPE 3238 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_SOURCENODE 3239 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_SOURCENAME 3240 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_TIME 3241 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_RECEIVETIME 3242 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_LOCALTIME 3243 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_MESSAGE 3244 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_SEVERITY 3245 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_ACTIONTIMESTAMP 3246 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_STATUS 3247 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_SERVERID 3248 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_CLIENTAUDITENTRYID 3249 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_CLIENTUSERID 3250 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_SECURECHANNELID 3251 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_EVENTID 3252 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_EVENTTYPE 3253 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_SOURCENODE 3254 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_SOURCENAME 3255 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_TIME 3256 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_RECEIVETIME 3257 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_LOCALTIME 3258 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_MESSAGE 3259 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_SEVERITY 3260 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_ACTIONTIMESTAMP 3261 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_STATUS 3262 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_SERVERID 3263 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_CLIENTAUDITENTRYID 3264 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_CLIENTUSERID 3265 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_EVENTID 3266 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_EVENTTYPE 3267 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_SOURCENODE 3268 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_SOURCENAME 3269 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_TIME 3270 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_RECEIVETIME 3271 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_LOCALTIME 3272 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_MESSAGE 3273 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_SEVERITY 3274 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_ACTIONTIMESTAMP 3275 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_STATUS 3276 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_SERVERID 3277 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_CLIENTAUDITENTRYID 3278 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_CLIENTUSERID 3279 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_EVENTID 3281 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_EVENTTYPE 3282 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_SOURCENODE 3283 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_SOURCENAME 3284 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_TIME 3285 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_RECEIVETIME 3286 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_LOCALTIME 3287 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_MESSAGE 3288 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_SEVERITY 3289 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_ACTIONTIMESTAMP 3290 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_STATUS 3291 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_SERVERID 3292 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_CLIENTAUDITENTRYID 3293 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_CLIENTUSERID 3294 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_SECURECHANNELID 3296 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_CLIENTCERTIFICATE 3297 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_CLIENTCERTIFICATETHUMBPRINT 3298 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_REVISEDSESSIONTIMEOUT 3299 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_EVENTID 3300 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_EVENTTYPE 3301 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_SOURCENODE 3302 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_SOURCENAME 3303 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_TIME 3304 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_RECEIVETIME 3305 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_LOCALTIME 3306 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_MESSAGE 3307 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_SEVERITY 3308 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_ACTIONTIMESTAMP 3309 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_STATUS 3310 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_SERVERID 3311 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_CLIENTAUDITENTRYID 3312 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_CLIENTUSERID 3313 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_SESSIONID 3314 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_EVENTID 3315 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_EVENTTYPE 3316 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_SOURCENODE 3317 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_SOURCENAME 3318 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_TIME 3319 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_RECEIVETIME 3320 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_LOCALTIME 3321 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_MESSAGE 3322 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_SEVERITY 3323 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_ACTIONTIMESTAMP 3324 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_STATUS 3325 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_SERVERID 3326 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_CLIENTAUDITENTRYID 3327 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_CLIENTUSERID 3328 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_SESSIONID 3329 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_EVENTID 3330 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_EVENTTYPE 3331 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_SOURCENODE 3332 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_SOURCENAME 3333 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_TIME 3334 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_RECEIVETIME 3335 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_LOCALTIME 3336 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_MESSAGE 3337 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_SEVERITY 3338 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_ACTIONTIMESTAMP 3339 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_STATUS 3340 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_SERVERID 3341 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_CLIENTAUDITENTRYID 3342 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_CLIENTUSERID 3343 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_EVENTID 3344 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_EVENTTYPE 3345 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_SOURCENODE 3346 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_SOURCENAME 3347 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_TIME 3348 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_RECEIVETIME 3349 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_LOCALTIME 3350 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_MESSAGE 3351 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_SEVERITY 3352 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_ACTIONTIMESTAMP 3353 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_STATUS 3354 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_SERVERID 3355 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_CLIENTAUDITENTRYID 3356 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_CLIENTUSERID 3357 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_CERTIFICATE 3358 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_EVENTID 3359 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_EVENTTYPE 3360 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_SOURCENODE 3361 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_SOURCENAME 3362 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_TIME 3363 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_RECEIVETIME 3364 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_LOCALTIME 3365 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_MESSAGE 3366 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_SEVERITY 3367 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_ACTIONTIMESTAMP 3368 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_STATUS 3369 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_SERVERID 3370 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_CLIENTAUDITENTRYID 3371 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_CLIENTUSERID 3372 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_CERTIFICATE 3373 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_EVENTID 3374 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_EVENTTYPE 3375 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_SOURCENODE 3376 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_SOURCENAME 3377 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_TIME 3378 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_RECEIVETIME 3379 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_LOCALTIME 3380 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_MESSAGE 3381 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_SEVERITY 3382 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_ACTIONTIMESTAMP 3383 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_STATUS 3384 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_SERVERID 3385 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_CLIENTAUDITENTRYID 3386 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_CLIENTUSERID 3387 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_CERTIFICATE 3388 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_EVENTID 3389 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_EVENTTYPE 3390 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_SOURCENODE 3391 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_SOURCENAME 3392 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_TIME 3393 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_RECEIVETIME 3394 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_LOCALTIME 3395 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_MESSAGE 3396 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_SEVERITY 3397 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_ACTIONTIMESTAMP 3398 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_STATUS 3399 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_SERVERID 3400 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_CLIENTAUDITENTRYID 3401 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_CLIENTUSERID 3402 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_CERTIFICATE 3403 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_EVENTID 3404 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_EVENTTYPE 3405 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_SOURCENODE 3406 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_SOURCENAME 3407 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_TIME 3408 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_RECEIVETIME 3409 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_LOCALTIME 3410 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_MESSAGE 3411 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_SEVERITY 3412 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_ACTIONTIMESTAMP 3413 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_STATUS 3414 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_SERVERID 3415 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_CLIENTAUDITENTRYID 3416 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_CLIENTUSERID 3417 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_CERTIFICATE 3418 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_EVENTID 3419 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_EVENTTYPE 3420 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_SOURCENODE 3421 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_SOURCENAME 3422 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_TIME 3423 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_RECEIVETIME 3424 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_LOCALTIME 3425 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_MESSAGE 3426 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_SEVERITY 3427 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_ACTIONTIMESTAMP 3428 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_STATUS 3429 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_SERVERID 3430 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_CLIENTAUDITENTRYID 3431 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_CLIENTUSERID 3432 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_CERTIFICATE 3433 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_EVENTID 3434 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_EVENTTYPE 3435 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_SOURCENODE 3436 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_SOURCENAME 3437 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_TIME 3438 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_RECEIVETIME 3439 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_LOCALTIME 3440 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_MESSAGE 3441 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_SEVERITY 3442 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_ACTIONTIMESTAMP 3443 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_STATUS 3444 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_SERVERID 3445 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_CLIENTAUDITENTRYID 3446 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_CLIENTUSERID 3447 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_EVENTID 3448 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_EVENTTYPE 3449 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_SOURCENODE 3450 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_SOURCENAME 3451 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_TIME 3452 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_RECEIVETIME 3453 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_LOCALTIME 3454 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_MESSAGE 3455 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_SEVERITY 3456 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_ACTIONTIMESTAMP 3457 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_STATUS 3458 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_SERVERID 3459 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_CLIENTAUDITENTRYID 3460 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_CLIENTUSERID 3461 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_EVENTID 3462 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_EVENTTYPE 3463 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_SOURCENODE 3464 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_SOURCENAME 3465 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_TIME 3466 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_RECEIVETIME 3467 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_LOCALTIME 3468 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_MESSAGE 3469 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_SEVERITY 3470 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_ACTIONTIMESTAMP 3471 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_STATUS 3472 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_SERVERID 3473 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_CLIENTAUDITENTRYID 3474 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_CLIENTUSERID 3475 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_EVENTID 3476 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_EVENTTYPE 3477 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_SOURCENODE 3478 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_SOURCENAME 3479 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_TIME 3480 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_RECEIVETIME 3481 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_LOCALTIME 3482 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_MESSAGE 3483 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_SEVERITY 3484 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_ACTIONTIMESTAMP 3485 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_STATUS 3486 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_SERVERID 3487 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_CLIENTAUDITENTRYID 3488 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_CLIENTUSERID 3489 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_EVENTID 3490 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_EVENTTYPE 3491 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_SOURCENODE 3492 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_SOURCENAME 3493 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_TIME 3494 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_RECEIVETIME 3495 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_LOCALTIME 3496 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_MESSAGE 3497 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_SEVERITY 3498 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_ACTIONTIMESTAMP 3499 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_STATUS 3500 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_SERVERID 3501 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_CLIENTAUDITENTRYID 3502 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_CLIENTUSERID 3503 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_EVENTID 3504 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_EVENTTYPE 3505 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_SOURCENODE 3506 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_SOURCENAME 3507 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_TIME 3508 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_RECEIVETIME 3509 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_LOCALTIME 3510 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_MESSAGE 3511 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_SEVERITY 3512 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_ACTIONTIMESTAMP 3513 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_STATUS 3514 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_SERVERID 3515 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_CLIENTAUDITENTRYID 3516 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_CLIENTUSERID 3517 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_EVENTID 3518 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_EVENTTYPE 3519 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_SOURCENODE 3520 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_SOURCENAME 3521 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_TIME 3522 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_RECEIVETIME 3523 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_LOCALTIME 3524 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_MESSAGE 3525 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_SEVERITY 3526 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_ACTIONTIMESTAMP 3527 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_STATUS 3528 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_SERVERID 3529 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_CLIENTAUDITENTRYID 3530 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_CLIENTUSERID 3531 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_EVENTID 3532 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_EVENTTYPE 3533 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_SOURCENODE 3534 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_SOURCENAME 3535 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_TIME 3536 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_RECEIVETIME 3537 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_LOCALTIME 3538 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_MESSAGE 3539 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_SEVERITY 3540 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_ACTIONTIMESTAMP 3541 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_STATUS 3542 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_SERVERID 3543 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_CLIENTAUDITENTRYID 3544 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_CLIENTUSERID 3545 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_EVENTID 3546 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_EVENTTYPE 3547 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_SOURCENODE 3548 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_SOURCENAME 3549 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_TIME 3550 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_RECEIVETIME 3551 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_LOCALTIME 3552 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_MESSAGE 3553 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_SEVERITY 3554 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_ACTIONTIMESTAMP 3555 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_STATUS 3556 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_SERVERID 3557 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_CLIENTAUDITENTRYID 3558 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_CLIENTUSERID 3559 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_PARAMETERDATATYPEID 3560 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_EVENTID 3561 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_EVENTTYPE 3562 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_SOURCENODE 3563 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_SOURCENAME 3564 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_TIME 3565 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_RECEIVETIME 3566 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_LOCALTIME 3567 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_MESSAGE 3568 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_SEVERITY 3569 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_ACTIONTIMESTAMP 3570 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_STATUS 3571 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_SERVERID 3572 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_CLIENTAUDITENTRYID 3573 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_CLIENTUSERID 3574 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_PARAMETERDATATYPEID 3575 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_EVENTID 3576 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_EVENTTYPE 3577 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_SOURCENODE 3578 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_SOURCENAME 3579 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_TIME 3580 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_RECEIVETIME 3581 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_LOCALTIME 3582 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_MESSAGE 3583 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_SEVERITY 3584 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_ACTIONTIMESTAMP 3585 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_STATUS 3586 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_SERVERID 3587 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_CLIENTAUDITENTRYID 3588 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_CLIENTUSERID 3589 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_PARAMETERDATATYPEID 3590 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_EVENTID 3591 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_EVENTTYPE 3592 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_SOURCENODE 3593 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_SOURCENAME 3594 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_TIME 3595 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_RECEIVETIME 3596 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_LOCALTIME 3597 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_MESSAGE 3598 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_SEVERITY 3599 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_ACTIONTIMESTAMP 3600 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_STATUS 3601 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_SERVERID 3602 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_CLIENTAUDITENTRYID 3603 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_CLIENTUSERID 3604 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_PARAMETERDATATYPEID 3605 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_UPDATEDNODE 3606 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_EVENTID 3607 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_EVENTTYPE 3608 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_SOURCENODE 3609 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_SOURCENAME 3610 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_TIME 3611 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_RECEIVETIME 3612 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_LOCALTIME 3613 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_MESSAGE 3614 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_SEVERITY 3615 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_ACTIONTIMESTAMP 3616 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_STATUS 3617 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_SERVERID 3618 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_CLIENTAUDITENTRYID 3619 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_CLIENTUSERID 3620 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_PARAMETERDATATYPEID 3621 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_UPDATEDNODE 3622 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_EVENTID 3623 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_EVENTTYPE 3624 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_SOURCENODE 3625 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_SOURCENAME 3626 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_TIME 3627 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_RECEIVETIME 3628 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_LOCALTIME 3629 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_MESSAGE 3630 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_SEVERITY 3631 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_ACTIONTIMESTAMP 3632 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_STATUS 3633 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_SERVERID 3634 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_CLIENTAUDITENTRYID 3635 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_CLIENTUSERID 3636 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_PARAMETERDATATYPEID 3637 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_UPDATEDNODE 3638 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_EVENTID 3639 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_EVENTTYPE 3640 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_SOURCENODE 3641 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_SOURCENAME 3642 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_TIME 3643 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_RECEIVETIME 3644 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_LOCALTIME 3645 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_MESSAGE 3646 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_SEVERITY 3647 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_ACTIONTIMESTAMP 3648 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_STATUS 3649 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_SERVERID 3650 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_CLIENTAUDITENTRYID 3651 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_CLIENTUSERID 3652 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_EVENTID 3653 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_EVENTTYPE 3654 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_SOURCENODE 3655 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_SOURCENAME 3656 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_TIME 3657 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_RECEIVETIME 3658 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_LOCALTIME 3659 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_MESSAGE 3660 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_SEVERITY 3661 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_EVENTID 3662 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_EVENTTYPE 3663 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_SOURCENODE 3664 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_SOURCENAME 3665 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_TIME 3666 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_RECEIVETIME 3667 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_LOCALTIME 3668 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_MESSAGE 3669 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_SEVERITY 3670 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_EVENTID 3671 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_EVENTTYPE 3672 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_SOURCENODE 3673 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_SOURCENAME 3674 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_TIME 3675 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_RECEIVETIME 3676 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_LOCALTIME 3677 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_MESSAGE 3678 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_SEVERITY 3679 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_EVENTID 3680 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_EVENTTYPE 3681 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_SOURCENODE 3682 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_SOURCENAME 3683 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_TIME 3684 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_RECEIVETIME 3685 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_LOCALTIME 3686 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_MESSAGE 3687 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_SEVERITY 3688 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_EVENTID 3689 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_EVENTTYPE 3690 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_SOURCENODE 3691 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_SOURCENAME 3692 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_TIME 3693 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_RECEIVETIME 3694 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_LOCALTIME 3695 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_MESSAGE 3696 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_SEVERITY 3697 /* Variable */ +#define UA_NS0ID_SERVERSTATUSTYPE_BUILDINFO_PRODUCTURI 3698 /* Variable */ +#define UA_NS0ID_SERVERSTATUSTYPE_BUILDINFO_MANUFACTURERNAME 3699 /* Variable */ +#define UA_NS0ID_SERVERSTATUSTYPE_BUILDINFO_PRODUCTNAME 3700 /* Variable */ +#define UA_NS0ID_SERVERSTATUSTYPE_BUILDINFO_SOFTWAREVERSION 3701 /* Variable */ +#define UA_NS0ID_SERVERSTATUSTYPE_BUILDINFO_BUILDNUMBER 3702 /* Variable */ +#define UA_NS0ID_SERVERSTATUSTYPE_BUILDINFO_BUILDDATE 3703 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_SOFTWARECERTIFICATES 3704 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY_REJECTEDSESSIONCOUNT 3705 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY 3706 /* Object */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY_SESSIONDIAGNOSTICSARRAY 3707 /* Variable */ +#define UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY_SESSIONSECURITYDIAGNOSTICSARRAY 3708 /* Variable */ +#define UA_NS0ID_SERVER_SERVERREDUNDANCY_REDUNDANCYSUPPORT 3709 /* Variable */ +#define UA_NS0ID_FINITESTATEVARIABLETYPE_NAME 3714 /* Variable */ +#define UA_NS0ID_FINITESTATEVARIABLETYPE_NUMBER 3715 /* Variable */ +#define UA_NS0ID_FINITESTATEVARIABLETYPE_EFFECTIVEDISPLAYNAME 3716 /* Variable */ +#define UA_NS0ID_FINITETRANSITIONVARIABLETYPE_NAME 3717 /* Variable */ +#define UA_NS0ID_FINITETRANSITIONVARIABLETYPE_NUMBER 3718 /* Variable */ +#define UA_NS0ID_FINITETRANSITIONVARIABLETYPE_TRANSITIONTIME 3719 /* Variable */ +#define UA_NS0ID_STATEMACHINETYPE_CURRENTSTATE_ID 3720 /* Variable */ +#define UA_NS0ID_STATEMACHINETYPE_CURRENTSTATE_NAME 3721 /* Variable */ +#define UA_NS0ID_STATEMACHINETYPE_CURRENTSTATE_NUMBER 3722 /* Variable */ +#define UA_NS0ID_STATEMACHINETYPE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 3723 /* Variable */ +#define UA_NS0ID_STATEMACHINETYPE_LASTTRANSITION_ID 3724 /* Variable */ +#define UA_NS0ID_STATEMACHINETYPE_LASTTRANSITION_NAME 3725 /* Variable */ +#define UA_NS0ID_STATEMACHINETYPE_LASTTRANSITION_NUMBER 3726 /* Variable */ +#define UA_NS0ID_STATEMACHINETYPE_LASTTRANSITION_TRANSITIONTIME 3727 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_CURRENTSTATE_ID 3728 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_CURRENTSTATE_NAME 3729 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_CURRENTSTATE_NUMBER 3730 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 3731 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_LASTTRANSITION_ID 3732 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_LASTTRANSITION_NAME 3733 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_LASTTRANSITION_NUMBER 3734 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_LASTTRANSITION_TRANSITIONTIME 3735 /* Variable */ +#define UA_NS0ID_INITIALSTATETYPE_STATENUMBER 3736 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_EVENTID 3737 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_EVENTTYPE 3738 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_SOURCENODE 3739 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_SOURCENAME 3740 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_TIME 3741 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_RECEIVETIME 3742 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_LOCALTIME 3743 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_MESSAGE 3744 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_SEVERITY 3745 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_FROMSTATE_ID 3746 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_FROMSTATE_NAME 3747 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_FROMSTATE_NUMBER 3748 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_FROMSTATE_EFFECTIVEDISPLAYNAME 3749 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_TOSTATE_ID 3750 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_TOSTATE_NAME 3751 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_TOSTATE_NUMBER 3752 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_TOSTATE_EFFECTIVEDISPLAYNAME 3753 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_TRANSITION_ID 3754 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_TRANSITION_NAME 3755 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_TRANSITION_NUMBER 3756 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_TRANSITION_TRANSITIONTIME 3757 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_EVENTID 3758 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_EVENTTYPE 3759 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_SOURCENODE 3760 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_SOURCENAME 3761 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_TIME 3762 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_RECEIVETIME 3763 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_LOCALTIME 3764 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_MESSAGE 3765 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_SEVERITY 3766 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_ACTIONTIMESTAMP 3767 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_STATUS 3768 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_SERVERID 3769 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_CLIENTAUDITENTRYID 3770 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_CLIENTUSERID 3771 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_METHODID 3772 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_INPUTARGUMENTS 3773 /* Variable */ +#define UA_NS0ID_ANALOGITEMTYPE_DEFINITION 3774 /* Variable */ +#define UA_NS0ID_ANALOGITEMTYPE_VALUEPRECISION 3775 /* Variable */ +#define UA_NS0ID_DISCRETEITEMTYPE_DEFINITION 3776 /* Variable */ +#define UA_NS0ID_DISCRETEITEMTYPE_VALUEPRECISION 3777 /* Variable */ +#define UA_NS0ID_TWOSTATEDISCRETETYPE_DEFINITION 3778 /* Variable */ +#define UA_NS0ID_TWOSTATEDISCRETETYPE_VALUEPRECISION 3779 /* Variable */ +#define UA_NS0ID_MULTISTATEDISCRETETYPE_DEFINITION 3780 /* Variable */ +#define UA_NS0ID_MULTISTATEDISCRETETYPE_VALUEPRECISION 3781 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_EVENTID 3782 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_EVENTTYPE 3783 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_SOURCENODE 3784 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_SOURCENAME 3785 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_TIME 3786 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_RECEIVETIME 3787 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_LOCALTIME 3788 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_MESSAGE 3789 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_SEVERITY 3790 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_FROMSTATE 3791 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_FROMSTATE_ID 3792 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_FROMSTATE_NAME 3793 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_FROMSTATE_NUMBER 3794 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_FROMSTATE_EFFECTIVEDISPLAYNAME 3795 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_TOSTATE 3796 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_TOSTATE_ID 3797 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_TOSTATE_NAME 3798 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_TOSTATE_NUMBER 3799 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_TOSTATE_EFFECTIVEDISPLAYNAME 3800 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_TRANSITION 3801 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_TRANSITION_ID 3802 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_TRANSITION_NAME 3803 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_TRANSITION_NUMBER 3804 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_TRANSITION_TRANSITIONTIME 3805 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE 3806 /* ObjectType */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_EVENTID 3807 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_EVENTTYPE 3808 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_SOURCENODE 3809 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_SOURCENAME 3810 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_TIME 3811 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_RECEIVETIME 3812 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_LOCALTIME 3813 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_MESSAGE 3814 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_SEVERITY 3815 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_ACTIONTIMESTAMP 3816 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_STATUS 3817 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_SERVERID 3818 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_CLIENTAUDITENTRYID 3819 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_CLIENTUSERID 3820 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_METHODID 3821 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_INPUTARGUMENTS 3822 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_OLDSTATEID 3823 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_NEWSTATEID 3824 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_TRANSITION 3825 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_TRANSITION_ID 3826 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_TRANSITION_NAME 3827 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_TRANSITION_NUMBER 3828 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_TRANSITION_TRANSITIONTIME 3829 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_CURRENTSTATE 3830 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_CURRENTSTATE_ID 3831 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_CURRENTSTATE_NAME 3832 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_CURRENTSTATE_NUMBER 3833 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 3834 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_LASTTRANSITION 3835 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_LASTTRANSITION_ID 3836 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_LASTTRANSITION_NAME 3837 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_LASTTRANSITION_NUMBER 3838 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_LASTTRANSITION_TRANSITIONTIME 3839 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC_CREATESESSIONID 3840 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC_CREATECLIENTNAME 3841 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC_INVOCATIONCREATIONTIME 3842 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC_LASTTRANSITIONTIME 3843 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC_LASTMETHODCALL 3844 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC_LASTMETHODSESSIONID 3845 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC_LASTMETHODINPUTARGUMENTS 3846 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC_LASTMETHODOUTPUTARGUMENTS 3847 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC_LASTMETHODCALLTIME 3848 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC_LASTMETHODRETURNSTATUS 3849 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_FINALRESULTDATA 3850 /* Object */ +#define UA_NS0ID_ADDCOMMENTMETHODTYPE 3863 /* Method */ +#define UA_NS0ID_ADDCOMMENTMETHODTYPE_INPUTARGUMENTS 3864 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_EVENTID 3865 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_EVENTTYPE 3866 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_SOURCENODE 3867 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_SOURCENAME 3868 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_TIME 3869 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_RECEIVETIME 3870 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_LOCALTIME 3871 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_MESSAGE 3872 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_SEVERITY 3873 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_RETAIN 3874 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_CONDITIONREFRESH 3875 /* Method */ +#define UA_NS0ID_CONDITIONTYPE_CONDITIONREFRESH_INPUTARGUMENTS 3876 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_EVENTID 3969 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_EVENTTYPE 3970 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_SOURCENODE 3971 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_SOURCENAME 3972 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_TIME 3973 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_RECEIVETIME 3974 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_LOCALTIME 3975 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_MESSAGE 3976 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_SEVERITY 3977 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_EVENTID 3978 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_EVENTTYPE 3979 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_SOURCENODE 3980 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_SOURCENAME 3981 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_TIME 3982 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_RECEIVETIME 3983 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_LOCALTIME 3984 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_MESSAGE 3985 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_SEVERITY 3986 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_EVENTID 3987 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_EVENTTYPE 3988 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_SOURCENODE 3989 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_SOURCENAME 3990 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_TIME 3991 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_RECEIVETIME 3992 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_LOCALTIME 3993 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_MESSAGE 3994 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_SEVERITY 3995 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_EVENTID 3996 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_EVENTTYPE 3997 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_SOURCENODE 3998 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_SOURCENAME 3999 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_TIME 4000 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_RECEIVETIME 4001 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_LOCALTIME 4002 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_MESSAGE 4003 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_SEVERITY 4004 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_ACTIONTIMESTAMP 4005 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_STATUS 4006 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_SERVERID 4007 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_CLIENTAUDITENTRYID 4008 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_CLIENTUSERID 4009 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_METHODID 4010 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_INPUTARGUMENTS 4011 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_EVENTID 4106 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_EVENTTYPE 4107 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_SOURCENODE 4108 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_SOURCENAME 4109 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_TIME 4110 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_RECEIVETIME 4111 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_LOCALTIME 4112 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_MESSAGE 4113 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_SEVERITY 4114 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_ACTIONTIMESTAMP 4115 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_STATUS 4116 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_SERVERID 4117 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_CLIENTAUDITENTRYID 4118 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_CLIENTUSERID 4119 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_METHODID 4120 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_INPUTARGUMENTS 4121 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_EVENTID 4170 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_EVENTTYPE 4171 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_SOURCENODE 4172 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_SOURCENAME 4173 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_TIME 4174 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_RECEIVETIME 4175 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_LOCALTIME 4176 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_MESSAGE 4177 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_SEVERITY 4178 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_ACTIONTIMESTAMP 4179 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_STATUS 4180 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_SERVERID 4181 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_CLIENTAUDITENTRYID 4182 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_CLIENTUSERID 4183 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_METHODID 4184 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_INPUTARGUMENTS 4185 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_EVENTID 4188 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_EVENTTYPE 4189 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_SOURCENODE 4190 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_SOURCENAME 4191 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_TIME 4192 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_RECEIVETIME 4193 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_LOCALTIME 4194 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_MESSAGE 4195 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_SEVERITY 4196 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_RETAIN 4197 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_CONDITIONREFRESH 4198 /* Method */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_CONDITIONREFRESH_INPUTARGUMENTS 4199 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_EVENTID 5113 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_EVENTTYPE 5114 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_SOURCENODE 5115 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_SOURCENAME 5116 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_TIME 5117 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_RECEIVETIME 5118 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_LOCALTIME 5119 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_MESSAGE 5120 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_SEVERITY 5121 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_RETAIN 5122 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONDITIONREFRESH 5123 /* Method */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONDITIONREFRESH_INPUTARGUMENTS 5124 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_EVENTID 5540 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_EVENTTYPE 5541 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SOURCENODE 5542 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SOURCENAME 5543 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_TIME 5544 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_RECEIVETIME 5545 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_LOCALTIME 5546 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_MESSAGE 5547 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SEVERITY 5548 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_RETAIN 5549 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONDITIONREFRESH 5550 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONDITIONREFRESH_INPUTARGUMENTS 5551 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_CURRENTSTATE 6088 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_CURRENTSTATE_ID 6089 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_CURRENTSTATE_NAME 6090 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_CURRENTSTATE_NUMBER 6091 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 6092 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_LASTTRANSITION 6093 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_LASTTRANSITION_ID 6094 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_LASTTRANSITION_NAME 6095 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_LASTTRANSITION_NUMBER 6096 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_LASTTRANSITION_TRANSITIONTIME 6097 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_UNSHELVED_STATENUMBER 6098 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_TIMEDSHELVED_STATENUMBER 6100 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_ONESHOTSHELVED_STATENUMBER 6101 /* Variable */ +#define UA_NS0ID_TIMEDSHELVEMETHODTYPE 6102 /* Method */ +#define UA_NS0ID_TIMEDSHELVEMETHODTYPE_INPUTARGUMENTS 6103 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_EVENTID 6116 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_EVENTTYPE 6117 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SOURCENODE 6118 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SOURCENAME 6119 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_TIME 6120 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_RECEIVETIME 6121 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LOCALTIME 6122 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_MESSAGE 6123 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SEVERITY 6124 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_RETAIN 6125 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONDITIONREFRESH 6126 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 6127 /* Variable */ +#define UA_NS0ID_IDTYPE_ENUMSTRINGS 7591 /* Variable */ +#define UA_NS0ID_ENUMVALUETYPE 7594 /* DataType */ +#define UA_NS0ID_MESSAGESECURITYMODE_ENUMSTRINGS 7595 /* Variable */ +#define UA_NS0ID_USERTOKENTYPE_ENUMSTRINGS 7596 /* Variable */ +#define UA_NS0ID_APPLICATIONTYPE_ENUMSTRINGS 7597 /* Variable */ +#define UA_NS0ID_SECURITYTOKENREQUESTTYPE_ENUMSTRINGS 7598 /* Variable */ +#define UA_NS0ID_BROWSEDIRECTION_ENUMSTRINGS 7603 /* Variable */ +#define UA_NS0ID_FILTEROPERATOR_ENUMSTRINGS 7605 /* Variable */ +#define UA_NS0ID_TIMESTAMPSTORETURN_ENUMSTRINGS 7606 /* Variable */ +#define UA_NS0ID_MONITORINGMODE_ENUMSTRINGS 7608 /* Variable */ +#define UA_NS0ID_DATACHANGETRIGGER_ENUMSTRINGS 7609 /* Variable */ +#define UA_NS0ID_DEADBANDTYPE_ENUMSTRINGS 7610 /* Variable */ +#define UA_NS0ID_REDUNDANCYSUPPORT_ENUMSTRINGS 7611 /* Variable */ +#define UA_NS0ID_SERVERSTATE_ENUMSTRINGS 7612 /* Variable */ +#define UA_NS0ID_EXCEPTIONDEVIATIONFORMAT_ENUMSTRINGS 7614 /* Variable */ +#define UA_NS0ID_ENUMVALUETYPE_ENCODING_DEFAULTXML 7616 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA 7617 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATATYPEVERSION 7618 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_NAMESPACEURI 7619 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ARGUMENT 7650 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ARGUMENT_DATATYPEVERSION 7651 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ARGUMENT_DICTIONARYFRAGMENT 7652 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENUMVALUETYPE 7656 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENUMVALUETYPE_DATATYPEVERSION 7657 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENUMVALUETYPE_DICTIONARYFRAGMENT 7658 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STATUSRESULT 7659 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STATUSRESULT_DATATYPEVERSION 7660 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STATUSRESULT_DICTIONARYFRAGMENT 7661 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_USERTOKENPOLICY 7662 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_USERTOKENPOLICY_DATATYPEVERSION 7663 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_USERTOKENPOLICY_DICTIONARYFRAGMENT 7664 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_APPLICATIONDESCRIPTION 7665 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_APPLICATIONDESCRIPTION_DATATYPEVERSION 7666 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_APPLICATIONDESCRIPTION_DICTIONARYFRAGMENT 7667 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENDPOINTDESCRIPTION 7668 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENDPOINTDESCRIPTION_DATATYPEVERSION 7669 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENDPOINTDESCRIPTION_DICTIONARYFRAGMENT 7670 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_USERIDENTITYTOKEN 7671 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_USERIDENTITYTOKEN_DATATYPEVERSION 7672 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_USERIDENTITYTOKEN_DICTIONARYFRAGMENT 7673 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ANONYMOUSIDENTITYTOKEN 7674 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ANONYMOUSIDENTITYTOKEN_DATATYPEVERSION 7675 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ANONYMOUSIDENTITYTOKEN_DICTIONARYFRAGMENT 7676 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_USERNAMEIDENTITYTOKEN 7677 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_USERNAMEIDENTITYTOKEN_DATATYPEVERSION 7678 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_USERNAMEIDENTITYTOKEN_DICTIONARYFRAGMENT 7679 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_X509IDENTITYTOKEN 7680 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_X509IDENTITYTOKEN_DATATYPEVERSION 7681 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_X509IDENTITYTOKEN_DICTIONARYFRAGMENT 7682 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ISSUEDIDENTITYTOKEN 7683 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ISSUEDIDENTITYTOKEN_DATATYPEVERSION 7684 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ISSUEDIDENTITYTOKEN_DICTIONARYFRAGMENT 7685 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENDPOINTCONFIGURATION 7686 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENDPOINTCONFIGURATION_DATATYPEVERSION 7687 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENDPOINTCONFIGURATION_DICTIONARYFRAGMENT 7688 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BUILDINFO 7692 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BUILDINFO_DATATYPEVERSION 7693 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BUILDINFO_DICTIONARYFRAGMENT 7694 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SIGNEDSOFTWARECERTIFICATE 7698 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SIGNEDSOFTWARECERTIFICATE_DATATYPEVERSION 7699 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SIGNEDSOFTWARECERTIFICATE_DICTIONARYFRAGMENT 7700 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ADDNODESITEM 7728 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ADDNODESITEM_DATATYPEVERSION 7729 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ADDNODESITEM_DICTIONARYFRAGMENT 7730 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ADDREFERENCESITEM 7731 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ADDREFERENCESITEM_DATATYPEVERSION 7732 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ADDREFERENCESITEM_DICTIONARYFRAGMENT 7733 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DELETENODESITEM 7734 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DELETENODESITEM_DATATYPEVERSION 7735 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DELETENODESITEM_DICTIONARYFRAGMENT 7736 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DELETEREFERENCESITEM 7737 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DELETEREFERENCESITEM_DATATYPEVERSION 7738 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DELETEREFERENCESITEM_DICTIONARYFRAGMENT 7739 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_REGISTEREDSERVER 7782 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_REGISTEREDSERVER_DATATYPEVERSION 7783 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_REGISTEREDSERVER_DICTIONARYFRAGMENT 7784 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CONTENTFILTERELEMENT 7929 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CONTENTFILTERELEMENT_DATATYPEVERSION 7930 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CONTENTFILTERELEMENT_DICTIONARYFRAGMENT 7931 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CONTENTFILTER 7932 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CONTENTFILTER_DATATYPEVERSION 7933 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CONTENTFILTER_DICTIONARYFRAGMENT 7934 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_FILTEROPERAND 7935 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_FILTEROPERAND_DATATYPEVERSION 7936 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_FILTEROPERAND_DICTIONARYFRAGMENT 7937 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ELEMENTOPERAND 7938 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ELEMENTOPERAND_DATATYPEVERSION 7939 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ELEMENTOPERAND_DICTIONARYFRAGMENT 7940 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_LITERALOPERAND 7941 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_LITERALOPERAND_DATATYPEVERSION 7942 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_LITERALOPERAND_DICTIONARYFRAGMENT 7943 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ATTRIBUTEOPERAND 7944 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ATTRIBUTEOPERAND_DATATYPEVERSION 7945 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ATTRIBUTEOPERAND_DICTIONARYFRAGMENT 7946 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SIMPLEATTRIBUTEOPERAND 7947 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SIMPLEATTRIBUTEOPERAND_DATATYPEVERSION 7948 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SIMPLEATTRIBUTEOPERAND_DICTIONARYFRAGMENT 7949 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_HISTORYEVENT 8004 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_HISTORYEVENT_DATATYPEVERSION 8005 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_HISTORYEVENT_DICTIONARYFRAGMENT 8006 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_MONITORINGFILTER 8067 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_MONITORINGFILTER_DATATYPEVERSION 8068 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_MONITORINGFILTER_DICTIONARYFRAGMENT 8069 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_EVENTFILTER 8073 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_EVENTFILTER_DATATYPEVERSION 8074 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_EVENTFILTER_DICTIONARYFRAGMENT 8075 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_AGGREGATECONFIGURATION 8076 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_AGGREGATECONFIGURATION_DATATYPEVERSION 8077 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_AGGREGATECONFIGURATION_DICTIONARYFRAGMENT 8078 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_HISTORYEVENTFIELDLIST 8172 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_HISTORYEVENTFIELDLIST_DATATYPEVERSION 8173 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_HISTORYEVENTFIELDLIST_DICTIONARYFRAGMENT 8174 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_REDUNDANTSERVERDATATYPE 8208 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_REDUNDANTSERVERDATATYPE_DATATYPEVERSION 8209 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_REDUNDANTSERVERDATATYPE_DICTIONARYFRAGMENT 8210 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SAMPLINGINTERVALDIAGNOSTICSDATATYPE 8211 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SAMPLINGINTERVALDIAGNOSTICSDATATYPE_DATATYPEVERSION 8212 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SAMPLINGINTERVALDIAGNOSTICSDATATYPE_DICTIONARYFRAGMENT 8213 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SERVERDIAGNOSTICSSUMMARYDATATYPE 8214 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SERVERDIAGNOSTICSSUMMARYDATATYPE_DATATYPEVERSION 8215 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SERVERDIAGNOSTICSSUMMARYDATATYPE_DICTIONARYFRAGMENT 8216 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SERVERSTATUSDATATYPE 8217 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SERVERSTATUSDATATYPE_DATATYPEVERSION 8218 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SERVERSTATUSDATATYPE_DICTIONARYFRAGMENT 8219 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SESSIONDIAGNOSTICSDATATYPE 8220 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SESSIONDIAGNOSTICSDATATYPE_DATATYPEVERSION 8221 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SESSIONDIAGNOSTICSDATATYPE_DICTIONARYFRAGMENT 8222 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SESSIONSECURITYDIAGNOSTICSDATATYPE 8223 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SESSIONSECURITYDIAGNOSTICSDATATYPE_DATATYPEVERSION 8224 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SESSIONSECURITYDIAGNOSTICSDATATYPE_DICTIONARYFRAGMENT 8225 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SERVICECOUNTERDATATYPE 8226 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SERVICECOUNTERDATATYPE_DATATYPEVERSION 8227 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SERVICECOUNTERDATATYPE_DICTIONARYFRAGMENT 8228 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SUBSCRIPTIONDIAGNOSTICSDATATYPE 8229 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SUBSCRIPTIONDIAGNOSTICSDATATYPE_DATATYPEVERSION 8230 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SUBSCRIPTIONDIAGNOSTICSDATATYPE_DICTIONARYFRAGMENT 8231 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_MODELCHANGESTRUCTUREDATATYPE 8232 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_MODELCHANGESTRUCTUREDATATYPE_DATATYPEVERSION 8233 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_MODELCHANGESTRUCTUREDATATYPE_DICTIONARYFRAGMENT 8234 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SEMANTICCHANGESTRUCTUREDATATYPE 8235 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SEMANTICCHANGESTRUCTUREDATATYPE_DATATYPEVERSION 8236 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SEMANTICCHANGESTRUCTUREDATATYPE_DICTIONARYFRAGMENT 8237 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RANGE 8238 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RANGE_DATATYPEVERSION 8239 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RANGE_DICTIONARYFRAGMENT 8240 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_EUINFORMATION 8241 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_EUINFORMATION_DATATYPEVERSION 8242 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_EUINFORMATION_DICTIONARYFRAGMENT 8243 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ANNOTATION 8244 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ANNOTATION_DATATYPEVERSION 8245 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ANNOTATION_DICTIONARYFRAGMENT 8246 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PROGRAMDIAGNOSTICDATATYPE 8247 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PROGRAMDIAGNOSTICDATATYPE_DATATYPEVERSION 8248 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PROGRAMDIAGNOSTICDATATYPE_DICTIONARYFRAGMENT 8249 /* Variable */ +#define UA_NS0ID_ENUMVALUETYPE_ENCODING_DEFAULTBINARY 8251 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA 8252 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATATYPEVERSION 8253 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_NAMESPACEURI 8254 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ARGUMENT 8285 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ARGUMENT_DATATYPEVERSION 8286 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ARGUMENT_DICTIONARYFRAGMENT 8287 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENUMVALUETYPE 8291 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENUMVALUETYPE_DATATYPEVERSION 8292 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENUMVALUETYPE_DICTIONARYFRAGMENT 8293 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STATUSRESULT 8294 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STATUSRESULT_DATATYPEVERSION 8295 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STATUSRESULT_DICTIONARYFRAGMENT 8296 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_USERTOKENPOLICY 8297 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_USERTOKENPOLICY_DATATYPEVERSION 8298 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_USERTOKENPOLICY_DICTIONARYFRAGMENT 8299 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_APPLICATIONDESCRIPTION 8300 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_APPLICATIONDESCRIPTION_DATATYPEVERSION 8301 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_APPLICATIONDESCRIPTION_DICTIONARYFRAGMENT 8302 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENDPOINTDESCRIPTION 8303 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENDPOINTDESCRIPTION_DATATYPEVERSION 8304 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENDPOINTDESCRIPTION_DICTIONARYFRAGMENT 8305 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_USERIDENTITYTOKEN 8306 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_USERIDENTITYTOKEN_DATATYPEVERSION 8307 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_USERIDENTITYTOKEN_DICTIONARYFRAGMENT 8308 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ANONYMOUSIDENTITYTOKEN 8309 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ANONYMOUSIDENTITYTOKEN_DATATYPEVERSION 8310 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ANONYMOUSIDENTITYTOKEN_DICTIONARYFRAGMENT 8311 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_USERNAMEIDENTITYTOKEN 8312 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_USERNAMEIDENTITYTOKEN_DATATYPEVERSION 8313 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_USERNAMEIDENTITYTOKEN_DICTIONARYFRAGMENT 8314 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_X509IDENTITYTOKEN 8315 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_X509IDENTITYTOKEN_DATATYPEVERSION 8316 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_X509IDENTITYTOKEN_DICTIONARYFRAGMENT 8317 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ISSUEDIDENTITYTOKEN 8318 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ISSUEDIDENTITYTOKEN_DATATYPEVERSION 8319 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ISSUEDIDENTITYTOKEN_DICTIONARYFRAGMENT 8320 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENDPOINTCONFIGURATION 8321 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENDPOINTCONFIGURATION_DATATYPEVERSION 8322 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENDPOINTCONFIGURATION_DICTIONARYFRAGMENT 8323 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BUILDINFO 8327 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BUILDINFO_DATATYPEVERSION 8328 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BUILDINFO_DICTIONARYFRAGMENT 8329 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SIGNEDSOFTWARECERTIFICATE 8333 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SIGNEDSOFTWARECERTIFICATE_DATATYPEVERSION 8334 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SIGNEDSOFTWARECERTIFICATE_DICTIONARYFRAGMENT 8335 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ADDNODESITEM 8363 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ADDNODESITEM_DATATYPEVERSION 8364 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ADDNODESITEM_DICTIONARYFRAGMENT 8365 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ADDREFERENCESITEM 8366 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ADDREFERENCESITEM_DATATYPEVERSION 8367 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ADDREFERENCESITEM_DICTIONARYFRAGMENT 8368 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DELETENODESITEM 8369 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DELETENODESITEM_DATATYPEVERSION 8370 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DELETENODESITEM_DICTIONARYFRAGMENT 8371 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DELETEREFERENCESITEM 8372 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DELETEREFERENCESITEM_DATATYPEVERSION 8373 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DELETEREFERENCESITEM_DICTIONARYFRAGMENT 8374 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_REGISTEREDSERVER 8417 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_REGISTEREDSERVER_DATATYPEVERSION 8418 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_REGISTEREDSERVER_DICTIONARYFRAGMENT 8419 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CONTENTFILTERELEMENT 8564 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CONTENTFILTERELEMENT_DATATYPEVERSION 8565 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CONTENTFILTERELEMENT_DICTIONARYFRAGMENT 8566 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CONTENTFILTER 8567 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CONTENTFILTER_DATATYPEVERSION 8568 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CONTENTFILTER_DICTIONARYFRAGMENT 8569 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_FILTEROPERAND 8570 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_FILTEROPERAND_DATATYPEVERSION 8571 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_FILTEROPERAND_DICTIONARYFRAGMENT 8572 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ELEMENTOPERAND 8573 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ELEMENTOPERAND_DATATYPEVERSION 8574 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ELEMENTOPERAND_DICTIONARYFRAGMENT 8575 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_LITERALOPERAND 8576 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_LITERALOPERAND_DATATYPEVERSION 8577 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_LITERALOPERAND_DICTIONARYFRAGMENT 8578 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ATTRIBUTEOPERAND 8579 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ATTRIBUTEOPERAND_DATATYPEVERSION 8580 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ATTRIBUTEOPERAND_DICTIONARYFRAGMENT 8581 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SIMPLEATTRIBUTEOPERAND 8582 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SIMPLEATTRIBUTEOPERAND_DATATYPEVERSION 8583 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SIMPLEATTRIBUTEOPERAND_DICTIONARYFRAGMENT 8584 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_HISTORYEVENT 8639 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_HISTORYEVENT_DATATYPEVERSION 8640 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_HISTORYEVENT_DICTIONARYFRAGMENT 8641 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_MONITORINGFILTER 8702 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_MONITORINGFILTER_DATATYPEVERSION 8703 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_MONITORINGFILTER_DICTIONARYFRAGMENT 8704 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_EVENTFILTER 8708 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_EVENTFILTER_DATATYPEVERSION 8709 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_EVENTFILTER_DICTIONARYFRAGMENT 8710 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_AGGREGATECONFIGURATION 8711 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_AGGREGATECONFIGURATION_DATATYPEVERSION 8712 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_AGGREGATECONFIGURATION_DICTIONARYFRAGMENT 8713 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_HISTORYEVENTFIELDLIST 8807 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_HISTORYEVENTFIELDLIST_DATATYPEVERSION 8808 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_HISTORYEVENTFIELDLIST_DICTIONARYFRAGMENT 8809 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_REDUNDANTSERVERDATATYPE 8843 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_REDUNDANTSERVERDATATYPE_DATATYPEVERSION 8844 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_REDUNDANTSERVERDATATYPE_DICTIONARYFRAGMENT 8845 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SAMPLINGINTERVALDIAGNOSTICSDATATYPE 8846 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SAMPLINGINTERVALDIAGNOSTICSDATATYPE_DATATYPEVERSION 8847 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SAMPLINGINTERVALDIAGNOSTICSDATATYPE_DICTIONARYFRAGMENT 8848 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SERVERDIAGNOSTICSSUMMARYDATATYPE 8849 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SERVERDIAGNOSTICSSUMMARYDATATYPE_DATATYPEVERSION 8850 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SERVERDIAGNOSTICSSUMMARYDATATYPE_DICTIONARYFRAGMENT 8851 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SERVERSTATUSDATATYPE 8852 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SERVERSTATUSDATATYPE_DATATYPEVERSION 8853 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SERVERSTATUSDATATYPE_DICTIONARYFRAGMENT 8854 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SESSIONDIAGNOSTICSDATATYPE 8855 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SESSIONDIAGNOSTICSDATATYPE_DATATYPEVERSION 8856 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SESSIONDIAGNOSTICSDATATYPE_DICTIONARYFRAGMENT 8857 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SESSIONSECURITYDIAGNOSTICSDATATYPE 8858 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SESSIONSECURITYDIAGNOSTICSDATATYPE_DATATYPEVERSION 8859 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SESSIONSECURITYDIAGNOSTICSDATATYPE_DICTIONARYFRAGMENT 8860 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SERVICECOUNTERDATATYPE 8861 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SERVICECOUNTERDATATYPE_DATATYPEVERSION 8862 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SERVICECOUNTERDATATYPE_DICTIONARYFRAGMENT 8863 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SUBSCRIPTIONDIAGNOSTICSDATATYPE 8864 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SUBSCRIPTIONDIAGNOSTICSDATATYPE_DATATYPEVERSION 8865 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SUBSCRIPTIONDIAGNOSTICSDATATYPE_DICTIONARYFRAGMENT 8866 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_MODELCHANGESTRUCTUREDATATYPE 8867 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_MODELCHANGESTRUCTUREDATATYPE_DATATYPEVERSION 8868 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_MODELCHANGESTRUCTUREDATATYPE_DICTIONARYFRAGMENT 8869 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SEMANTICCHANGESTRUCTUREDATATYPE 8870 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SEMANTICCHANGESTRUCTUREDATATYPE_DATATYPEVERSION 8871 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SEMANTICCHANGESTRUCTUREDATATYPE_DICTIONARYFRAGMENT 8872 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RANGE 8873 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RANGE_DATATYPEVERSION 8874 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RANGE_DICTIONARYFRAGMENT 8875 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_EUINFORMATION 8876 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_EUINFORMATION_DATATYPEVERSION 8877 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_EUINFORMATION_DICTIONARYFRAGMENT 8878 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ANNOTATION 8879 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ANNOTATION_DATATYPEVERSION 8880 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ANNOTATION_DICTIONARYFRAGMENT 8881 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PROGRAMDIAGNOSTICDATATYPE 8882 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PROGRAMDIAGNOSTICDATATYPE_DATATYPEVERSION 8883 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PROGRAMDIAGNOSTICDATATYPE_DICTIONARYFRAGMENT 8884 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_MAXLIFETIMECOUNT 8888 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_LATEPUBLISHREQUESTCOUNT 8889 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_CURRENTKEEPALIVECOUNT 8890 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_CURRENTLIFETIMECOUNT 8891 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_UNACKNOWLEDGEDMESSAGECOUNT 8892 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_DISCARDEDMESSAGECOUNT 8893 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_MONITOREDITEMCOUNT 8894 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_DISABLEDMONITOREDITEMCOUNT 8895 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_MONITORINGQUEUEOVERFLOWCOUNT 8896 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_NEXTSEQUENCENUMBER 8897 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_TOTALREQUESTCOUNT 8898 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_TOTALREQUESTCOUNT 8900 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSTYPE_EVENTQUEUEOVERFLOWCOUNT 8902 /* Variable */ +#define UA_NS0ID_TIMEZONEDATATYPE 8912 /* DataType */ +#define UA_NS0ID_TIMEZONEDATATYPE_ENCODING_DEFAULTXML 8913 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TIMEZONEDATATYPE 8914 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TIMEZONEDATATYPE_DATATYPEVERSION 8915 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TIMEZONEDATATYPE_DICTIONARYFRAGMENT 8916 /* Variable */ +#define UA_NS0ID_TIMEZONEDATATYPE_ENCODING_DEFAULTBINARY 8917 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TIMEZONEDATATYPE 8918 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TIMEZONEDATATYPE_DATATYPEVERSION 8919 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TIMEZONEDATATYPE_DICTIONARYFRAGMENT 8920 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE 8927 /* ObjectType */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_EVENTID 8928 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_EVENTTYPE 8929 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_SOURCENODE 8930 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_SOURCENAME 8931 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_TIME 8932 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_RECEIVETIME 8933 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_LOCALTIME 8934 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_MESSAGE 8935 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_SEVERITY 8936 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_ACTIONTIMESTAMP 8937 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_STATUS 8938 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_SERVERID 8939 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_CLIENTAUDITENTRYID 8940 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_CLIENTUSERID 8941 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_METHODID 8942 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_INPUTARGUMENTS 8943 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE 8944 /* ObjectType */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_EVENTID 8945 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_EVENTTYPE 8946 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_SOURCENODE 8947 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_SOURCENAME 8948 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_TIME 8949 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_RECEIVETIME 8950 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_LOCALTIME 8951 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_MESSAGE 8952 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_SEVERITY 8953 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_ACTIONTIMESTAMP 8954 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_STATUS 8955 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_SERVERID 8956 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_CLIENTAUDITENTRYID 8957 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_CLIENTUSERID 8958 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_METHODID 8959 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_INPUTARGUMENTS 8960 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE 8961 /* ObjectType */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_EVENTID 8962 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_EVENTTYPE 8963 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_SOURCENODE 8964 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_SOURCENAME 8965 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_TIME 8966 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_RECEIVETIME 8967 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_LOCALTIME 8968 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_MESSAGE 8969 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_SEVERITY 8970 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_ACTIONTIMESTAMP 8971 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_STATUS 8972 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_SERVERID 8973 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_CLIENTAUDITENTRYID 8974 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_CLIENTUSERID 8975 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_METHODID 8976 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_INPUTARGUMENTS 8977 /* Variable */ +#define UA_NS0ID_TWOSTATEVARIABLETYPE 8995 /* VariableType */ +#define UA_NS0ID_TWOSTATEVARIABLETYPE_ID 8996 /* Variable */ +#define UA_NS0ID_TWOSTATEVARIABLETYPE_NAME 8997 /* Variable */ +#define UA_NS0ID_TWOSTATEVARIABLETYPE_NUMBER 8998 /* Variable */ +#define UA_NS0ID_TWOSTATEVARIABLETYPE_EFFECTIVEDISPLAYNAME 8999 /* Variable */ +#define UA_NS0ID_TWOSTATEVARIABLETYPE_TRANSITIONTIME 9000 /* Variable */ +#define UA_NS0ID_TWOSTATEVARIABLETYPE_EFFECTIVETRANSITIONTIME 9001 /* Variable */ +#define UA_NS0ID_CONDITIONVARIABLETYPE 9002 /* VariableType */ +#define UA_NS0ID_CONDITIONVARIABLETYPE_SOURCETIMESTAMP 9003 /* Variable */ +#define UA_NS0ID_HASTRUESUBSTATE 9004 /* ReferenceType */ +#define UA_NS0ID_HASFALSESUBSTATE 9005 /* ReferenceType */ +#define UA_NS0ID_HASCONDITION 9006 /* ReferenceType */ +#define UA_NS0ID_CONDITIONREFRESHMETHODTYPE 9007 /* Method */ +#define UA_NS0ID_CONDITIONREFRESHMETHODTYPE_INPUTARGUMENTS 9008 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_CONDITIONNAME 9009 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_BRANCHID 9010 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_ENABLEDSTATE 9011 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_ENABLEDSTATE_ID 9012 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_ENABLEDSTATE_NAME 9013 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_ENABLEDSTATE_NUMBER 9014 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 9015 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_ENABLEDSTATE_TRANSITIONTIME 9016 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 9017 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_ENABLEDSTATE_TRUESTATE 9018 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_ENABLEDSTATE_FALSESTATE 9019 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_QUALITY 9020 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_QUALITY_SOURCETIMESTAMP 9021 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_LASTSEVERITY 9022 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_LASTSEVERITY_SOURCETIMESTAMP 9023 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_COMMENT 9024 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_COMMENT_SOURCETIMESTAMP 9025 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_CLIENTUSERID 9026 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_ENABLE 9027 /* Method */ +#define UA_NS0ID_CONDITIONTYPE_DISABLE 9028 /* Method */ +#define UA_NS0ID_CONDITIONTYPE_ADDCOMMENT 9029 /* Method */ +#define UA_NS0ID_CONDITIONTYPE_ADDCOMMENT_INPUTARGUMENTS 9030 /* Variable */ +#define UA_NS0ID_DIALOGRESPONSEMETHODTYPE 9031 /* Method */ +#define UA_NS0ID_DIALOGRESPONSEMETHODTYPE_INPUTARGUMENTS 9032 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_CONDITIONNAME 9033 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_BRANCHID 9034 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_ENABLEDSTATE 9035 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_ENABLEDSTATE_ID 9036 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_ENABLEDSTATE_NAME 9037 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_ENABLEDSTATE_NUMBER 9038 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 9039 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_ENABLEDSTATE_TRANSITIONTIME 9040 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 9041 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_ENABLEDSTATE_TRUESTATE 9042 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_ENABLEDSTATE_FALSESTATE 9043 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_QUALITY 9044 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_QUALITY_SOURCETIMESTAMP 9045 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_LASTSEVERITY 9046 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_LASTSEVERITY_SOURCETIMESTAMP 9047 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_COMMENT 9048 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_COMMENT_SOURCETIMESTAMP 9049 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_CLIENTUSERID 9050 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_ENABLE 9051 /* Method */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_DISABLE 9052 /* Method */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_ADDCOMMENT 9053 /* Method */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_ADDCOMMENT_INPUTARGUMENTS 9054 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_DIALOGSTATE 9055 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_DIALOGSTATE_ID 9056 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_DIALOGSTATE_NAME 9057 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_DIALOGSTATE_NUMBER 9058 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_DIALOGSTATE_EFFECTIVEDISPLAYNAME 9059 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_DIALOGSTATE_TRANSITIONTIME 9060 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_DIALOGSTATE_EFFECTIVETRANSITIONTIME 9061 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_DIALOGSTATE_TRUESTATE 9062 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_DIALOGSTATE_FALSESTATE 9063 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_RESPONSEOPTIONSET 9064 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_DEFAULTRESPONSE 9065 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_OKRESPONSE 9066 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_CANCELRESPONSE 9067 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_LASTRESPONSE 9068 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_RESPOND 9069 /* Method */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_RESPOND_INPUTARGUMENTS 9070 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONDITIONNAME 9071 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_BRANCHID 9072 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ENABLEDSTATE 9073 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ENABLEDSTATE_ID 9074 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ENABLEDSTATE_NAME 9075 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ENABLEDSTATE_NUMBER 9076 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 9077 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ENABLEDSTATE_TRANSITIONTIME 9078 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 9079 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ENABLEDSTATE_TRUESTATE 9080 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ENABLEDSTATE_FALSESTATE 9081 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_QUALITY 9082 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_QUALITY_SOURCETIMESTAMP 9083 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_LASTSEVERITY 9084 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_LASTSEVERITY_SOURCETIMESTAMP 9085 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_COMMENT 9086 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_COMMENT_SOURCETIMESTAMP 9087 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CLIENTUSERID 9088 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ENABLE 9089 /* Method */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_DISABLE 9090 /* Method */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ADDCOMMENT 9091 /* Method */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ADDCOMMENT_INPUTARGUMENTS 9092 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ACKEDSTATE 9093 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ACKEDSTATE_ID 9094 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ACKEDSTATE_NAME 9095 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ACKEDSTATE_NUMBER 9096 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 9097 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ACKEDSTATE_TRANSITIONTIME 9098 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 9099 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ACKEDSTATE_TRUESTATE 9100 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ACKEDSTATE_FALSESTATE 9101 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONFIRMEDSTATE 9102 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONFIRMEDSTATE_ID 9103 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONFIRMEDSTATE_NAME 9104 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONFIRMEDSTATE_NUMBER 9105 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 9106 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONFIRMEDSTATE_TRANSITIONTIME 9107 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 9108 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONFIRMEDSTATE_TRUESTATE 9109 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONFIRMEDSTATE_FALSESTATE 9110 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ACKNOWLEDGE 9111 /* Method */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_ACKNOWLEDGE_INPUTARGUMENTS 9112 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONFIRM 9113 /* Method */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONFIRM_INPUTARGUMENTS 9114 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_UNSHELVETIME 9115 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONDITIONNAME 9116 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_BRANCHID 9117 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ENABLEDSTATE 9118 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ENABLEDSTATE_ID 9119 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ENABLEDSTATE_NAME 9120 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ENABLEDSTATE_NUMBER 9121 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 9122 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ENABLEDSTATE_TRANSITIONTIME 9123 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 9124 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ENABLEDSTATE_TRUESTATE 9125 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ENABLEDSTATE_FALSESTATE 9126 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_QUALITY 9127 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_QUALITY_SOURCETIMESTAMP 9128 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_LASTSEVERITY 9129 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_LASTSEVERITY_SOURCETIMESTAMP 9130 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_COMMENT 9131 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_COMMENT_SOURCETIMESTAMP 9132 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CLIENTUSERID 9133 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ENABLE 9134 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_DISABLE 9135 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ADDCOMMENT 9136 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ADDCOMMENT_INPUTARGUMENTS 9137 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACKEDSTATE 9138 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACKEDSTATE_ID 9139 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACKEDSTATE_NAME 9140 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACKEDSTATE_NUMBER 9141 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 9142 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACKEDSTATE_TRANSITIONTIME 9143 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 9144 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACKEDSTATE_TRUESTATE 9145 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACKEDSTATE_FALSESTATE 9146 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONFIRMEDSTATE 9147 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONFIRMEDSTATE_ID 9148 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONFIRMEDSTATE_NAME 9149 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONFIRMEDSTATE_NUMBER 9150 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 9151 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONFIRMEDSTATE_TRANSITIONTIME 9152 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 9153 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONFIRMEDSTATE_TRUESTATE 9154 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONFIRMEDSTATE_FALSESTATE 9155 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACKNOWLEDGE 9156 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACKNOWLEDGE_INPUTARGUMENTS 9157 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONFIRM 9158 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONFIRM_INPUTARGUMENTS 9159 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACTIVESTATE 9160 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACTIVESTATE_ID 9161 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACTIVESTATE_NAME 9162 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACTIVESTATE_NUMBER 9163 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 9164 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACTIVESTATE_TRANSITIONTIME 9165 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 9166 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACTIVESTATE_TRUESTATE 9167 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ACTIVESTATE_FALSESTATE 9168 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESSEDSTATE 9169 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESSEDSTATE_ID 9170 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESSEDSTATE_NAME 9171 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESSEDSTATE_NUMBER 9172 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 9173 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 9174 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 9175 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESSEDSTATE_TRUESTATE 9176 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESSEDSTATE_FALSESTATE 9177 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE 9178 /* Object */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_CURRENTSTATE 9179 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_CURRENTSTATE_ID 9180 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 9181 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 9182 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 9183 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_LASTTRANSITION 9184 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_LASTTRANSITION_ID 9185 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 9186 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 9187 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 9188 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_UNSHELVETIME 9189 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_UNSHELVE 9211 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_ONESHOTSHELVE 9212 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_TIMEDSHELVE 9213 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 9214 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESSEDORSHELVED 9215 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_MAXTIMESHELVED 9216 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONDITIONNAME 9217 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_BRANCHID 9218 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ENABLEDSTATE 9219 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ENABLEDSTATE_ID 9220 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ENABLEDSTATE_NAME 9221 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ENABLEDSTATE_NUMBER 9222 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 9223 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 9224 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 9225 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ENABLEDSTATE_TRUESTATE 9226 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ENABLEDSTATE_FALSESTATE 9227 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_QUALITY 9228 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_QUALITY_SOURCETIMESTAMP 9229 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LASTSEVERITY 9230 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 9231 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_COMMENT 9232 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_COMMENT_SOURCETIMESTAMP 9233 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CLIENTUSERID 9234 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ENABLE 9235 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_DISABLE 9236 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_ADDCOMMENT 9237 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 9238 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACKEDSTATE 9239 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACKEDSTATE_ID 9240 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACKEDSTATE_NAME 9241 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACKEDSTATE_NUMBER 9242 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 9243 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACKEDSTATE_TRANSITIONTIME 9244 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 9245 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACKEDSTATE_TRUESTATE 9246 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACKEDSTATE_FALSESTATE 9247 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONFIRMEDSTATE 9248 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONFIRMEDSTATE_ID 9249 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONFIRMEDSTATE_NAME 9250 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONFIRMEDSTATE_NUMBER 9251 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 9252 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 9253 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 9254 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONFIRMEDSTATE_TRUESTATE 9255 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONFIRMEDSTATE_FALSESTATE 9256 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACKNOWLEDGE 9257 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 9258 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONFIRM 9259 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_CONFIRM_INPUTARGUMENTS 9260 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACTIVESTATE 9261 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACTIVESTATE_ID 9262 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACTIVESTATE_NAME 9263 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACTIVESTATE_NUMBER 9264 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 9265 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACTIVESTATE_TRANSITIONTIME 9266 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 9267 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACTIVESTATE_TRUESTATE 9268 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ACTIVESTATE_FALSESTATE 9269 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESSEDSTATE 9270 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESSEDSTATE_ID 9271 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESSEDSTATE_NAME 9272 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESSEDSTATE_NUMBER 9273 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 9274 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 9275 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 9276 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 9277 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 9278 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE 9279 /* Object */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE 9280 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 9281 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 9282 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 9283 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 9284 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION 9285 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 9286 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 9287 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 9288 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 9289 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_UNSHELVETIME 9290 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_UNSHELVE 9312 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 9313 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 9314 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 9315 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESSEDORSHELVED 9316 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_MAXTIMESHELVED 9317 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE 9318 /* ObjectType */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_CURRENTSTATE 9319 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_CURRENTSTATE_ID 9320 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_CURRENTSTATE_NAME 9321 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_CURRENTSTATE_NUMBER 9322 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 9323 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LASTTRANSITION 9324 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LASTTRANSITION_ID 9325 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LASTTRANSITION_NAME 9326 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LASTTRANSITION_NUMBER 9327 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LASTTRANSITION_TRANSITIONTIME 9328 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_HIGHHIGH 9329 /* Object */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_HIGHHIGH_STATENUMBER 9330 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_HIGH 9331 /* Object */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_HIGH_STATENUMBER 9332 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LOW 9333 /* Object */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LOW_STATENUMBER 9334 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LOWLOW 9335 /* Object */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LOWLOW_STATENUMBER 9336 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LOWLOWTOLOW 9337 /* Object */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LOWTOLOWLOW 9338 /* Object */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_HIGHHIGHTOHIGH 9339 /* Object */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_HIGHTOHIGHHIGH 9340 /* Object */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE 9341 /* ObjectType */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_EVENTID 9342 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_EVENTTYPE 9343 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SOURCENODE 9344 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SOURCENAME 9345 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_TIME 9346 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_RECEIVETIME 9347 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LOCALTIME 9348 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_MESSAGE 9349 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SEVERITY 9350 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONDITIONNAME 9351 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_BRANCHID 9352 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_RETAIN 9353 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ENABLEDSTATE 9354 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_ID 9355 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_NAME 9356 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_NUMBER 9357 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 9358 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 9359 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 9360 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_TRUESTATE 9361 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_FALSESTATE 9362 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_QUALITY 9363 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_QUALITY_SOURCETIMESTAMP 9364 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LASTSEVERITY 9365 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 9366 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_COMMENT 9367 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_COMMENT_SOURCETIMESTAMP 9368 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CLIENTUSERID 9369 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ENABLE 9370 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_DISABLE 9371 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ADDCOMMENT 9372 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 9373 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONDITIONREFRESH 9374 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 9375 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACKEDSTATE 9376 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACKEDSTATE_ID 9377 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACKEDSTATE_NAME 9378 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACKEDSTATE_NUMBER 9379 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 9380 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACKEDSTATE_TRANSITIONTIME 9381 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 9382 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACKEDSTATE_TRUESTATE 9383 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACKEDSTATE_FALSESTATE 9384 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE 9385 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_ID 9386 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_NAME 9387 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_NUMBER 9388 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 9389 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 9390 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 9391 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_TRUESTATE 9392 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_FALSESTATE 9393 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACKNOWLEDGE 9394 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 9395 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONFIRM 9396 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONFIRM_INPUTARGUMENTS 9397 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACTIVESTATE 9398 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACTIVESTATE_ID 9399 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACTIVESTATE_NAME 9400 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACTIVESTATE_NUMBER 9401 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 9402 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACTIVESTATE_TRANSITIONTIME 9403 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 9404 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACTIVESTATE_TRUESTATE 9405 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ACTIVESTATE_FALSESTATE 9406 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE 9407 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_ID 9408 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_NAME 9409 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_NUMBER 9410 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 9411 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 9412 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 9413 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 9414 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 9415 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE 9416 /* Object */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE 9417 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 9418 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 9419 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 9420 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 9421 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION 9422 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 9423 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 9424 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 9425 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 9426 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_UNSHELVETIME 9427 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_UNSHELVE 9449 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 9450 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 9451 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 9452 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESSEDORSHELVED 9453 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_MAXTIMESHELVED 9454 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE 9455 /* Object */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_CURRENTSTATE 9456 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_CURRENTSTATE_ID 9457 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_CURRENTSTATE_NAME 9458 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_CURRENTSTATE_NUMBER 9459 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 9460 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_LASTTRANSITION 9461 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_LASTTRANSITION_ID 9462 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_LASTTRANSITION_NAME 9463 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_LASTTRANSITION_NUMBER 9464 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_LASTTRANSITION_TRANSITIONTIME 9465 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_HIGHHIGHLIMIT 9478 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_HIGHLIMIT 9479 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LOWLIMIT 9480 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LOWLOWLIMIT 9481 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE 9482 /* ObjectType */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_EVENTID 9483 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_EVENTTYPE 9484 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SOURCENODE 9485 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SOURCENAME 9486 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_TIME 9487 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_RECEIVETIME 9488 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LOCALTIME 9489 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_MESSAGE 9490 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SEVERITY 9491 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONDITIONNAME 9492 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_BRANCHID 9493 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_RETAIN 9494 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ENABLEDSTATE 9495 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_ID 9496 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_NAME 9497 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_NUMBER 9498 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 9499 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 9500 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 9501 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_TRUESTATE 9502 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_FALSESTATE 9503 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_QUALITY 9504 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_QUALITY_SOURCETIMESTAMP 9505 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LASTSEVERITY 9506 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 9507 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_COMMENT 9508 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_COMMENT_SOURCETIMESTAMP 9509 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CLIENTUSERID 9510 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ENABLE 9511 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_DISABLE 9512 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ADDCOMMENT 9513 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 9514 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONDITIONREFRESH 9515 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 9516 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACKEDSTATE 9517 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACKEDSTATE_ID 9518 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACKEDSTATE_NAME 9519 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACKEDSTATE_NUMBER 9520 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 9521 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACKEDSTATE_TRANSITIONTIME 9522 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 9523 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACKEDSTATE_TRUESTATE 9524 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACKEDSTATE_FALSESTATE 9525 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE 9526 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_ID 9527 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_NAME 9528 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_NUMBER 9529 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 9530 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 9531 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 9532 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_TRUESTATE 9533 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_FALSESTATE 9534 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACKNOWLEDGE 9535 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 9536 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONFIRM 9537 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONFIRM_INPUTARGUMENTS 9538 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACTIVESTATE 9539 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACTIVESTATE_ID 9540 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACTIVESTATE_NAME 9541 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACTIVESTATE_NUMBER 9542 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 9543 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACTIVESTATE_TRANSITIONTIME 9544 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 9545 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACTIVESTATE_TRUESTATE 9546 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ACTIVESTATE_FALSESTATE 9547 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE 9548 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_ID 9549 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_NAME 9550 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_NUMBER 9551 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 9552 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 9553 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 9554 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 9555 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 9556 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE 9557 /* Object */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_CURRENTSTATE 9558 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 9559 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 9560 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 9561 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 9562 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_LASTTRANSITION 9563 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 9564 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 9565 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 9566 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 9567 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_UNSHELVETIME 9568 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_UNSHELVE 9590 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 9591 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 9592 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 9593 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESSEDORSHELVED 9594 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_MAXTIMESHELVED 9595 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE 9596 /* Object */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_CURRENTSTATE 9597 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_CURRENTSTATE_ID 9598 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_CURRENTSTATE_NAME 9599 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_CURRENTSTATE_NUMBER 9600 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 9601 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_LASTTRANSITION 9602 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_LASTTRANSITION_ID 9603 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_LASTTRANSITION_NAME 9604 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_LASTTRANSITION_NUMBER 9605 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_LASTTRANSITION_TRANSITIONTIME 9606 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_HIGHHIGHLIMIT 9619 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_HIGHLIMIT 9620 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LOWLIMIT 9621 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LOWLOWLIMIT 9622 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE 9623 /* ObjectType */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_EVENTID 9624 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_EVENTTYPE 9625 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SOURCENODE 9626 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SOURCENAME 9627 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_TIME 9628 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_RECEIVETIME 9629 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LOCALTIME 9630 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_MESSAGE 9631 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SEVERITY 9632 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONNAME 9633 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_BRANCHID 9634 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_RETAIN 9635 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE 9636 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_ID 9637 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_NAME 9638 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_NUMBER 9639 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 9640 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 9641 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 9642 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_TRUESTATE 9643 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_FALSESTATE 9644 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_QUALITY 9645 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_QUALITY_SOURCETIMESTAMP 9646 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LASTSEVERITY 9647 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 9648 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_COMMENT 9649 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_COMMENT_SOURCETIMESTAMP 9650 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CLIENTUSERID 9651 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ENABLE 9652 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_DISABLE 9653 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ADDCOMMENT 9654 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 9655 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONREFRESH 9656 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 9657 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE 9658 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_ID 9659 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_NAME 9660 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_NUMBER 9661 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 9662 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_TRANSITIONTIME 9663 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 9664 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_TRUESTATE 9665 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_FALSESTATE 9666 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE 9667 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_ID 9668 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_NAME 9669 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_NUMBER 9670 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 9671 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 9672 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 9673 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_TRUESTATE 9674 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_FALSESTATE 9675 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACKNOWLEDGE 9676 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 9677 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRM 9678 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRM_INPUTARGUMENTS 9679 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE 9680 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_ID 9681 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_NAME 9682 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_NUMBER 9683 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 9684 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_TRANSITIONTIME 9685 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 9686 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_TRUESTATE 9687 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_FALSESTATE 9688 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE 9689 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_ID 9690 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_NAME 9691 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_NUMBER 9692 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 9693 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 9694 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 9695 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 9696 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 9697 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE 9698 /* Object */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_CURRENTSTATE 9699 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 9700 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 9701 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 9702 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 9703 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_LASTTRANSITION 9704 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 9705 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 9706 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 9707 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 9708 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_UNSHELVETIME 9709 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_UNSHELVE 9731 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 9732 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 9733 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 9734 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDORSHELVED 9735 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_MAXTIMESHELVED 9736 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE 9737 /* Object */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_CURRENTSTATE 9738 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_CURRENTSTATE_ID 9739 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_CURRENTSTATE_NAME 9740 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_CURRENTSTATE_NUMBER 9741 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 9742 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_LASTTRANSITION 9743 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_LASTTRANSITION_ID 9744 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_LASTTRANSITION_NAME 9745 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_LASTTRANSITION_NUMBER 9746 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_LASTTRANSITION_TRANSITIONTIME 9747 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHLIMIT 9760 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_HIGHLIMIT 9761 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LOWLIMIT 9762 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWLIMIT 9763 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE 9764 /* ObjectType */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_EVENTID 9765 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_EVENTTYPE 9766 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SOURCENODE 9767 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SOURCENAME 9768 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_TIME 9769 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_RECEIVETIME 9770 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LOCALTIME 9771 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_MESSAGE 9772 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SEVERITY 9773 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONDITIONNAME 9774 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_BRANCHID 9775 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_RETAIN 9776 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE 9777 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_ID 9778 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_NAME 9779 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_NUMBER 9780 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 9781 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 9782 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 9783 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_TRUESTATE 9784 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_FALSESTATE 9785 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_QUALITY 9786 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_QUALITY_SOURCETIMESTAMP 9787 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LASTSEVERITY 9788 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 9789 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_COMMENT 9790 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_COMMENT_SOURCETIMESTAMP 9791 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CLIENTUSERID 9792 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ENABLE 9793 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_DISABLE 9794 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ADDCOMMENT 9795 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 9796 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONDITIONREFRESH 9797 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 9798 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE 9799 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_ID 9800 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_NAME 9801 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_NUMBER 9802 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 9803 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_TRANSITIONTIME 9804 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 9805 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_TRUESTATE 9806 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_FALSESTATE 9807 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE 9808 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_ID 9809 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_NAME 9810 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_NUMBER 9811 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 9812 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 9813 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 9814 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_TRUESTATE 9815 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_FALSESTATE 9816 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACKNOWLEDGE 9817 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 9818 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONFIRM 9819 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONFIRM_INPUTARGUMENTS 9820 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE 9821 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_ID 9822 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_NAME 9823 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_NUMBER 9824 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 9825 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_TRANSITIONTIME 9826 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 9827 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_TRUESTATE 9828 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_FALSESTATE 9829 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE 9830 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_ID 9831 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_NAME 9832 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_NUMBER 9833 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 9834 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 9835 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 9836 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 9837 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 9838 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE 9839 /* Object */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE 9840 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 9841 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 9842 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 9843 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 9844 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION 9845 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 9846 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 9847 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 9848 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 9849 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_UNSHELVETIME 9850 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_UNSHELVE 9872 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 9873 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 9874 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 9875 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDORSHELVED 9876 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_MAXTIMESHELVED 9877 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE 9878 /* Object */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_CURRENTSTATE 9879 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_CURRENTSTATE_ID 9880 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_CURRENTSTATE_NAME 9881 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_CURRENTSTATE_NUMBER 9882 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 9883 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_LASTTRANSITION 9884 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_LASTTRANSITION_ID 9885 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_LASTTRANSITION_NAME 9886 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_LASTTRANSITION_NUMBER 9887 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_LASTTRANSITION_TRANSITIONTIME 9888 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHLIMIT 9901 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_HIGHLIMIT 9902 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LOWLIMIT 9903 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LOWLOWLIMIT 9904 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SETPOINTNODE 9905 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE 9906 /* ObjectType */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_EVENTID 9907 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_EVENTTYPE 9908 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SOURCENODE 9909 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SOURCENAME 9910 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_TIME 9911 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_RECEIVETIME 9912 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOCALTIME 9913 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_MESSAGE 9914 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SEVERITY 9915 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONDITIONNAME 9916 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_BRANCHID 9917 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_RETAIN 9918 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ENABLEDSTATE 9919 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_ID 9920 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_NAME 9921 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_NUMBER 9922 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 9923 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 9924 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 9925 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_TRUESTATE 9926 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ENABLEDSTATE_FALSESTATE 9927 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_QUALITY 9928 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_QUALITY_SOURCETIMESTAMP 9929 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LASTSEVERITY 9930 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 9931 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_COMMENT 9932 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_COMMENT_SOURCETIMESTAMP 9933 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CLIENTUSERID 9934 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ENABLE 9935 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_DISABLE 9936 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ADDCOMMENT 9937 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 9938 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONDITIONREFRESH 9939 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 9940 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACKEDSTATE 9941 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACKEDSTATE_ID 9942 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACKEDSTATE_NAME 9943 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACKEDSTATE_NUMBER 9944 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 9945 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACKEDSTATE_TRANSITIONTIME 9946 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 9947 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACKEDSTATE_TRUESTATE 9948 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACKEDSTATE_FALSESTATE 9949 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE 9950 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_ID 9951 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_NAME 9952 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_NUMBER 9953 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 9954 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 9955 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 9956 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_TRUESTATE 9957 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONFIRMEDSTATE_FALSESTATE 9958 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACKNOWLEDGE 9959 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 9960 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONFIRM 9961 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONFIRM_INPUTARGUMENTS 9962 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACTIVESTATE 9963 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACTIVESTATE_ID 9964 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACTIVESTATE_NAME 9965 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACTIVESTATE_NUMBER 9966 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 9967 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACTIVESTATE_TRANSITIONTIME 9968 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 9969 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACTIVESTATE_TRUESTATE 9970 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ACTIVESTATE_FALSESTATE 9971 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE 9972 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_ID 9973 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_NAME 9974 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_NUMBER 9975 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 9976 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 9977 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 9978 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 9979 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 9980 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE 9981 /* Object */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE 9982 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 9983 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 9984 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 9985 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 9986 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION 9987 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 9988 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 9989 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 9990 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 9991 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_UNSHELVETIME 9992 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_UNSHELVE 10014 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 10015 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 10016 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 10017 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESSEDORSHELVED 10018 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_MAXTIMESHELVED 10019 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHHIGHSTATE 10020 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHHIGHSTATE_ID 10021 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHHIGHSTATE_NAME 10022 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHHIGHSTATE_NUMBER 10023 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHHIGHSTATE_EFFECTIVEDISPLAYNAME 10024 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHHIGHSTATE_TRANSITIONTIME 10025 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHHIGHSTATE_EFFECTIVETRANSITIONTIME 10026 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHHIGHSTATE_TRUESTATE 10027 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHHIGHSTATE_FALSESTATE 10028 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHSTATE 10029 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHSTATE_ID 10030 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHSTATE_NAME 10031 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHSTATE_NUMBER 10032 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHSTATE_EFFECTIVEDISPLAYNAME 10033 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHSTATE_TRANSITIONTIME 10034 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHSTATE_EFFECTIVETRANSITIONTIME 10035 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHSTATE_TRUESTATE 10036 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHSTATE_FALSESTATE 10037 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWSTATE 10038 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWSTATE_ID 10039 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWSTATE_NAME 10040 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWSTATE_NUMBER 10041 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWSTATE_EFFECTIVEDISPLAYNAME 10042 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWSTATE_TRANSITIONTIME 10043 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWSTATE_EFFECTIVETRANSITIONTIME 10044 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWSTATE_TRUESTATE 10045 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWSTATE_FALSESTATE 10046 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWLOWSTATE 10047 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWLOWSTATE_ID 10048 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWLOWSTATE_NAME 10049 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWLOWSTATE_NUMBER 10050 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWLOWSTATE_EFFECTIVEDISPLAYNAME 10051 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWLOWSTATE_TRANSITIONTIME 10052 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWLOWSTATE_EFFECTIVETRANSITIONTIME 10053 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWLOWSTATE_TRUESTATE 10054 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWLOWSTATE_FALSESTATE 10055 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHHIGHLIMIT 10056 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHLIMIT 10057 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWLIMIT 10058 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWLOWLIMIT 10059 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE 10060 /* ObjectType */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_EVENTID 10061 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_EVENTTYPE 10062 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SOURCENODE 10063 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SOURCENAME 10064 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_TIME 10065 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_RECEIVETIME 10066 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOCALTIME 10067 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_MESSAGE 10068 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SEVERITY 10069 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONDITIONNAME 10070 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_BRANCHID 10071 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_RETAIN 10072 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ENABLEDSTATE 10073 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_ID 10074 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_NAME 10075 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_NUMBER 10076 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 10077 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 10078 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 10079 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_TRUESTATE 10080 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ENABLEDSTATE_FALSESTATE 10081 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_QUALITY 10082 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_QUALITY_SOURCETIMESTAMP 10083 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LASTSEVERITY 10084 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 10085 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_COMMENT 10086 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_COMMENT_SOURCETIMESTAMP 10087 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CLIENTUSERID 10088 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ENABLE 10089 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_DISABLE 10090 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ADDCOMMENT 10091 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 10092 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONDITIONREFRESH 10093 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 10094 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACKEDSTATE 10095 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACKEDSTATE_ID 10096 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACKEDSTATE_NAME 10097 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACKEDSTATE_NUMBER 10098 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 10099 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACKEDSTATE_TRANSITIONTIME 10100 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 10101 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACKEDSTATE_TRUESTATE 10102 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACKEDSTATE_FALSESTATE 10103 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE 10104 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_ID 10105 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_NAME 10106 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_NUMBER 10107 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 10108 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 10109 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 10110 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_TRUESTATE 10111 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONFIRMEDSTATE_FALSESTATE 10112 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACKNOWLEDGE 10113 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 10114 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONFIRM 10115 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONFIRM_INPUTARGUMENTS 10116 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACTIVESTATE 10117 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACTIVESTATE_ID 10118 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACTIVESTATE_NAME 10119 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACTIVESTATE_NUMBER 10120 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 10121 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACTIVESTATE_TRANSITIONTIME 10122 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 10123 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACTIVESTATE_TRUESTATE 10124 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ACTIVESTATE_FALSESTATE 10125 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE 10126 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_ID 10127 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_NAME 10128 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_NUMBER 10129 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 10130 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 10131 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 10132 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 10133 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 10134 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE 10135 /* Object */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_CURRENTSTATE 10136 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 10137 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 10138 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 10139 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 10140 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_LASTTRANSITION 10141 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 10142 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 10143 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 10144 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 10145 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_UNSHELVETIME 10146 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_UNSHELVE 10168 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 10169 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 10170 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 10171 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESSEDORSHELVED 10172 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_MAXTIMESHELVED 10173 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHHIGHSTATE 10174 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHHIGHSTATE_ID 10175 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHHIGHSTATE_NAME 10176 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHHIGHSTATE_NUMBER 10177 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHHIGHSTATE_EFFECTIVEDISPLAYNAME 10178 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHHIGHSTATE_TRANSITIONTIME 10179 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHHIGHSTATE_EFFECTIVETRANSITIONTIME 10180 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHHIGHSTATE_TRUESTATE 10181 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHHIGHSTATE_FALSESTATE 10182 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHSTATE 10183 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHSTATE_ID 10184 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHSTATE_NAME 10185 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHSTATE_NUMBER 10186 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHSTATE_EFFECTIVEDISPLAYNAME 10187 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHSTATE_TRANSITIONTIME 10188 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHSTATE_EFFECTIVETRANSITIONTIME 10189 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHSTATE_TRUESTATE 10190 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHSTATE_FALSESTATE 10191 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWSTATE 10192 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWSTATE_ID 10193 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWSTATE_NAME 10194 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWSTATE_NUMBER 10195 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWSTATE_EFFECTIVEDISPLAYNAME 10196 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWSTATE_TRANSITIONTIME 10197 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWSTATE_EFFECTIVETRANSITIONTIME 10198 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWSTATE_TRUESTATE 10199 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWSTATE_FALSESTATE 10200 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWLOWSTATE 10201 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWLOWSTATE_ID 10202 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWLOWSTATE_NAME 10203 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWLOWSTATE_NUMBER 10204 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWLOWSTATE_EFFECTIVEDISPLAYNAME 10205 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWLOWSTATE_TRANSITIONTIME 10206 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWLOWSTATE_EFFECTIVETRANSITIONTIME 10207 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWLOWSTATE_TRUESTATE 10208 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWLOWSTATE_FALSESTATE 10209 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHHIGHLIMIT 10210 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHLIMIT 10211 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWLIMIT 10212 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWLOWLIMIT 10213 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE 10214 /* ObjectType */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_EVENTID 10215 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_EVENTTYPE 10216 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SOURCENODE 10217 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SOURCENAME 10218 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_TIME 10219 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_RECEIVETIME 10220 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOCALTIME 10221 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_MESSAGE 10222 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SEVERITY 10223 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONNAME 10224 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_BRANCHID 10225 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_RETAIN 10226 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE 10227 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_ID 10228 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_NAME 10229 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_NUMBER 10230 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 10231 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 10232 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 10233 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_TRUESTATE 10234 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ENABLEDSTATE_FALSESTATE 10235 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_QUALITY 10236 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_QUALITY_SOURCETIMESTAMP 10237 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LASTSEVERITY 10238 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 10239 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_COMMENT 10240 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_COMMENT_SOURCETIMESTAMP 10241 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CLIENTUSERID 10242 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ENABLE 10243 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_DISABLE 10244 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ADDCOMMENT 10245 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 10246 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONREFRESH 10247 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 10248 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE 10249 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_ID 10250 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_NAME 10251 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_NUMBER 10252 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 10253 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_TRANSITIONTIME 10254 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 10255 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_TRUESTATE 10256 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACKEDSTATE_FALSESTATE 10257 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE 10258 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_ID 10259 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_NAME 10260 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_NUMBER 10261 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 10262 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 10263 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 10264 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_TRUESTATE 10265 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRMEDSTATE_FALSESTATE 10266 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACKNOWLEDGE 10267 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 10268 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRM 10269 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONFIRM_INPUTARGUMENTS 10270 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE 10271 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_ID 10272 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_NAME 10273 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_NUMBER 10274 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 10275 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_TRANSITIONTIME 10276 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 10277 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_TRUESTATE 10278 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ACTIVESTATE_FALSESTATE 10279 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE 10280 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_ID 10281 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_NAME 10282 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_NUMBER 10283 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 10284 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 10285 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 10286 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 10287 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 10288 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE 10289 /* Object */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_CURRENTSTATE 10290 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 10291 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 10292 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 10293 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 10294 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_LASTTRANSITION 10295 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 10296 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 10297 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 10298 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 10299 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_UNSHELVETIME 10300 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_UNSHELVE 10322 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 10323 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 10324 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 10325 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESSEDORSHELVED 10326 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_MAXTIMESHELVED 10327 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHSTATE 10328 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHSTATE_ID 10329 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHSTATE_NAME 10330 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHSTATE_NUMBER 10331 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHSTATE_EFFECTIVEDISPLAYNAME 10332 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHSTATE_TRANSITIONTIME 10333 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHSTATE_EFFECTIVETRANSITIONTIME 10334 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHSTATE_TRUESTATE 10335 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHSTATE_FALSESTATE 10336 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHSTATE 10337 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHSTATE_ID 10338 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHSTATE_NAME 10339 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHSTATE_NUMBER 10340 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHSTATE_EFFECTIVEDISPLAYNAME 10341 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHSTATE_TRANSITIONTIME 10342 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHSTATE_EFFECTIVETRANSITIONTIME 10343 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHSTATE_TRUESTATE 10344 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHSTATE_FALSESTATE 10345 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWSTATE 10346 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWSTATE_ID 10347 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWSTATE_NAME 10348 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWSTATE_NUMBER 10349 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWSTATE_EFFECTIVEDISPLAYNAME 10350 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWSTATE_TRANSITIONTIME 10351 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWSTATE_EFFECTIVETRANSITIONTIME 10352 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWSTATE_TRUESTATE 10353 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWSTATE_FALSESTATE 10354 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWSTATE 10355 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWSTATE_ID 10356 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWSTATE_NAME 10357 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWSTATE_NUMBER 10358 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWSTATE_EFFECTIVEDISPLAYNAME 10359 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWSTATE_TRANSITIONTIME 10360 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWSTATE_EFFECTIVETRANSITIONTIME 10361 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWSTATE_TRUESTATE 10362 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWSTATE_FALSESTATE 10363 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHLIMIT 10364 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHLIMIT 10365 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWLIMIT 10366 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWLIMIT 10367 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE 10368 /* ObjectType */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_EVENTID 10369 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_EVENTTYPE 10370 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SOURCENODE 10371 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SOURCENAME 10372 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_TIME 10373 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_RECEIVETIME 10374 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOCALTIME 10375 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_MESSAGE 10376 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SEVERITY 10377 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONDITIONNAME 10378 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_BRANCHID 10379 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_RETAIN 10380 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE 10381 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_ID 10382 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_NAME 10383 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_NUMBER 10384 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 10385 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 10386 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 10387 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_TRUESTATE 10388 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ENABLEDSTATE_FALSESTATE 10389 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_QUALITY 10390 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_QUALITY_SOURCETIMESTAMP 10391 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LASTSEVERITY 10392 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 10393 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_COMMENT 10394 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_COMMENT_SOURCETIMESTAMP 10395 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CLIENTUSERID 10396 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ENABLE 10397 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_DISABLE 10398 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ADDCOMMENT 10399 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 10400 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONDITIONREFRESH 10401 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 10402 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE 10403 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_ID 10404 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_NAME 10405 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_NUMBER 10406 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 10407 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_TRANSITIONTIME 10408 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 10409 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_TRUESTATE 10410 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACKEDSTATE_FALSESTATE 10411 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE 10412 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_ID 10413 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_NAME 10414 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_NUMBER 10415 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 10416 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 10417 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 10418 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_TRUESTATE 10419 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONFIRMEDSTATE_FALSESTATE 10420 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACKNOWLEDGE 10421 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 10422 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONFIRM 10423 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONFIRM_INPUTARGUMENTS 10424 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE 10425 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_ID 10426 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_NAME 10427 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_NUMBER 10428 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 10429 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_TRANSITIONTIME 10430 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 10431 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_TRUESTATE 10432 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ACTIVESTATE_FALSESTATE 10433 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE 10434 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_ID 10435 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_NAME 10436 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_NUMBER 10437 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 10438 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 10439 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 10440 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 10441 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 10442 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE 10443 /* Object */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE 10444 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 10445 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 10446 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 10447 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 10448 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION 10449 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 10450 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 10451 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 10452 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 10453 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_UNSHELVETIME 10454 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_UNSHELVE 10476 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 10477 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 10478 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 10479 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESSEDORSHELVED 10480 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_MAXTIMESHELVED 10481 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHSTATE 10482 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHSTATE_ID 10483 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHSTATE_NAME 10484 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHSTATE_NUMBER 10485 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHSTATE_EFFECTIVEDISPLAYNAME 10486 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHSTATE_TRANSITIONTIME 10487 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHSTATE_EFFECTIVETRANSITIONTIME 10488 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHSTATE_TRUESTATE 10489 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHSTATE_FALSESTATE 10490 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHSTATE 10491 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHSTATE_ID 10492 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHSTATE_NAME 10493 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHSTATE_NUMBER 10494 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHSTATE_EFFECTIVEDISPLAYNAME 10495 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHSTATE_TRANSITIONTIME 10496 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHSTATE_EFFECTIVETRANSITIONTIME 10497 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHSTATE_TRUESTATE 10498 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHSTATE_FALSESTATE 10499 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWSTATE 10500 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWSTATE_ID 10501 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWSTATE_NAME 10502 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWSTATE_NUMBER 10503 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWSTATE_EFFECTIVEDISPLAYNAME 10504 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWSTATE_TRANSITIONTIME 10505 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWSTATE_EFFECTIVETRANSITIONTIME 10506 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWSTATE_TRUESTATE 10507 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWSTATE_FALSESTATE 10508 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWLOWSTATE 10509 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWLOWSTATE_ID 10510 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWLOWSTATE_NAME 10511 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWLOWSTATE_NUMBER 10512 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWLOWSTATE_EFFECTIVEDISPLAYNAME 10513 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWLOWSTATE_TRANSITIONTIME 10514 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWLOWSTATE_EFFECTIVETRANSITIONTIME 10515 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWLOWSTATE_TRUESTATE 10516 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWLOWSTATE_FALSESTATE 10517 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHLIMIT 10518 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHLIMIT 10519 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWLIMIT 10520 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWLOWLIMIT 10521 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SETPOINTNODE 10522 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE 10523 /* ObjectType */ +#define UA_NS0ID_DISCRETEALARMTYPE_EVENTID 10524 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_EVENTTYPE 10525 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SOURCENODE 10526 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SOURCENAME 10527 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_TIME 10528 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_RECEIVETIME 10529 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_LOCALTIME 10530 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_MESSAGE 10531 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SEVERITY 10532 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONDITIONNAME 10533 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_BRANCHID 10534 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_RETAIN 10535 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ENABLEDSTATE 10536 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ENABLEDSTATE_ID 10537 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ENABLEDSTATE_NAME 10538 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ENABLEDSTATE_NUMBER 10539 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 10540 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 10541 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 10542 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ENABLEDSTATE_TRUESTATE 10543 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ENABLEDSTATE_FALSESTATE 10544 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_QUALITY 10545 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_QUALITY_SOURCETIMESTAMP 10546 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_LASTSEVERITY 10547 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 10548 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_COMMENT 10549 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_COMMENT_SOURCETIMESTAMP 10550 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CLIENTUSERID 10551 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ENABLE 10552 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_DISABLE 10553 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_ADDCOMMENT 10554 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 10555 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONDITIONREFRESH 10556 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 10557 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACKEDSTATE 10558 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACKEDSTATE_ID 10559 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACKEDSTATE_NAME 10560 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACKEDSTATE_NUMBER 10561 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 10562 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACKEDSTATE_TRANSITIONTIME 10563 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 10564 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACKEDSTATE_TRUESTATE 10565 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACKEDSTATE_FALSESTATE 10566 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONFIRMEDSTATE 10567 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONFIRMEDSTATE_ID 10568 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONFIRMEDSTATE_NAME 10569 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONFIRMEDSTATE_NUMBER 10570 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 10571 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 10572 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 10573 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONFIRMEDSTATE_TRUESTATE 10574 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONFIRMEDSTATE_FALSESTATE 10575 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACKNOWLEDGE 10576 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 10577 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONFIRM 10578 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONFIRM_INPUTARGUMENTS 10579 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACTIVESTATE 10580 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACTIVESTATE_ID 10581 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACTIVESTATE_NAME 10582 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACTIVESTATE_NUMBER 10583 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 10584 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACTIVESTATE_TRANSITIONTIME 10585 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 10586 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACTIVESTATE_TRUESTATE 10587 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ACTIVESTATE_FALSESTATE 10588 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESSEDSTATE 10589 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESSEDSTATE_ID 10590 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESSEDSTATE_NAME 10591 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESSEDSTATE_NUMBER 10592 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 10593 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 10594 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 10595 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 10596 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 10597 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE 10598 /* Object */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_CURRENTSTATE 10599 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 10600 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 10601 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 10602 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 10603 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_LASTTRANSITION 10604 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 10605 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 10606 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 10607 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 10608 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_UNSHELVETIME 10609 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_UNSHELVE 10631 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 10632 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 10633 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 10634 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESSEDORSHELVED 10635 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_MAXTIMESHELVED 10636 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE 10637 /* ObjectType */ +#define UA_NS0ID_OFFNORMALALARMTYPE_EVENTID 10638 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_EVENTTYPE 10639 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SOURCENODE 10640 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SOURCENAME 10641 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_TIME 10642 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_RECEIVETIME 10643 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_LOCALTIME 10644 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_MESSAGE 10645 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SEVERITY 10646 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONDITIONNAME 10647 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_BRANCHID 10648 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_RETAIN 10649 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ENABLEDSTATE 10650 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ENABLEDSTATE_ID 10651 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ENABLEDSTATE_NAME 10652 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ENABLEDSTATE_NUMBER 10653 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 10654 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 10655 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 10656 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ENABLEDSTATE_TRUESTATE 10657 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ENABLEDSTATE_FALSESTATE 10658 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_QUALITY 10659 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_QUALITY_SOURCETIMESTAMP 10660 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_LASTSEVERITY 10661 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 10662 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_COMMENT 10663 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_COMMENT_SOURCETIMESTAMP 10664 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CLIENTUSERID 10665 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ENABLE 10666 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_DISABLE 10667 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ADDCOMMENT 10668 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 10669 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONDITIONREFRESH 10670 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 10671 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACKEDSTATE 10672 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACKEDSTATE_ID 10673 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACKEDSTATE_NAME 10674 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACKEDSTATE_NUMBER 10675 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 10676 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACKEDSTATE_TRANSITIONTIME 10677 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 10678 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACKEDSTATE_TRUESTATE 10679 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACKEDSTATE_FALSESTATE 10680 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONFIRMEDSTATE 10681 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONFIRMEDSTATE_ID 10682 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONFIRMEDSTATE_NAME 10683 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONFIRMEDSTATE_NUMBER 10684 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 10685 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 10686 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 10687 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONFIRMEDSTATE_TRUESTATE 10688 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONFIRMEDSTATE_FALSESTATE 10689 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACKNOWLEDGE 10690 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 10691 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONFIRM 10692 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONFIRM_INPUTARGUMENTS 10693 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACTIVESTATE 10694 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACTIVESTATE_ID 10695 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACTIVESTATE_NAME 10696 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACTIVESTATE_NUMBER 10697 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 10698 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACTIVESTATE_TRANSITIONTIME 10699 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 10700 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACTIVESTATE_TRUESTATE 10701 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ACTIVESTATE_FALSESTATE 10702 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESSEDSTATE 10703 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESSEDSTATE_ID 10704 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESSEDSTATE_NAME 10705 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESSEDSTATE_NUMBER 10706 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 10707 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 10708 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 10709 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 10710 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 10711 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE 10712 /* Object */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_CURRENTSTATE 10713 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 10714 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 10715 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 10716 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 10717 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_LASTTRANSITION 10718 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 10719 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 10720 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 10721 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 10722 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_UNSHELVETIME 10723 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_UNSHELVE 10745 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 10746 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 10747 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 10748 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESSEDORSHELVED 10749 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_MAXTIMESHELVED 10750 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE 10751 /* ObjectType */ +#define UA_NS0ID_TRIPALARMTYPE_EVENTID 10752 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_EVENTTYPE 10753 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SOURCENODE 10754 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SOURCENAME 10755 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_TIME 10756 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_RECEIVETIME 10757 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_LOCALTIME 10758 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_MESSAGE 10759 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SEVERITY 10760 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONDITIONNAME 10761 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_BRANCHID 10762 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_RETAIN 10763 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ENABLEDSTATE 10764 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ENABLEDSTATE_ID 10765 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ENABLEDSTATE_NAME 10766 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ENABLEDSTATE_NUMBER 10767 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 10768 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 10769 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 10770 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ENABLEDSTATE_TRUESTATE 10771 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ENABLEDSTATE_FALSESTATE 10772 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_QUALITY 10773 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_QUALITY_SOURCETIMESTAMP 10774 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_LASTSEVERITY 10775 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 10776 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_COMMENT 10777 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_COMMENT_SOURCETIMESTAMP 10778 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CLIENTUSERID 10779 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ENABLE 10780 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_DISABLE 10781 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_ADDCOMMENT 10782 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 10783 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONDITIONREFRESH 10784 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 10785 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACKEDSTATE 10786 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACKEDSTATE_ID 10787 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACKEDSTATE_NAME 10788 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACKEDSTATE_NUMBER 10789 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 10790 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACKEDSTATE_TRANSITIONTIME 10791 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 10792 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACKEDSTATE_TRUESTATE 10793 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACKEDSTATE_FALSESTATE 10794 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONFIRMEDSTATE 10795 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONFIRMEDSTATE_ID 10796 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONFIRMEDSTATE_NAME 10797 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONFIRMEDSTATE_NUMBER 10798 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 10799 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 10800 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 10801 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONFIRMEDSTATE_TRUESTATE 10802 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONFIRMEDSTATE_FALSESTATE 10803 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACKNOWLEDGE 10804 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 10805 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONFIRM 10806 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_CONFIRM_INPUTARGUMENTS 10807 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACTIVESTATE 10808 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACTIVESTATE_ID 10809 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACTIVESTATE_NAME 10810 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACTIVESTATE_NUMBER 10811 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 10812 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACTIVESTATE_TRANSITIONTIME 10813 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 10814 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACTIVESTATE_TRUESTATE 10815 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_ACTIVESTATE_FALSESTATE 10816 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESSEDSTATE 10817 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESSEDSTATE_ID 10818 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESSEDSTATE_NAME 10819 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESSEDSTATE_NUMBER 10820 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 10821 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 10822 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 10823 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 10824 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 10825 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE 10826 /* Object */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_CURRENTSTATE 10827 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 10828 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 10829 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 10830 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 10831 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_LASTTRANSITION 10832 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 10833 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 10834 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 10835 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 10836 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_UNSHELVETIME 10837 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_UNSHELVE 10859 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 10860 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 10861 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 10862 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESSEDORSHELVED 10863 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_MAXTIMESHELVED 10864 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE 11093 /* ObjectType */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_EVENTID 11094 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_EVENTTYPE 11095 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_SOURCENODE 11096 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_SOURCENAME 11097 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_TIME 11098 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_RECEIVETIME 11099 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_LOCALTIME 11100 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_MESSAGE 11101 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_SEVERITY 11102 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_ACTIONTIMESTAMP 11103 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_STATUS 11104 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_SERVERID 11105 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_CLIENTAUDITENTRYID 11106 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_CLIENTUSERID 11107 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_METHODID 11108 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_INPUTARGUMENTS 11109 /* Variable */ +#define UA_NS0ID_TWOSTATEVARIABLETYPE_TRUESTATE 11110 /* Variable */ +#define UA_NS0ID_TWOSTATEVARIABLETYPE_FALSESTATE 11111 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_CONDITIONCLASSID 11112 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_CONDITIONCLASSNAME 11113 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_CONDITIONCLASSID 11114 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_CONDITIONCLASSNAME 11115 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONDITIONCLASSID 11116 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONDITIONCLASSNAME 11117 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONDITIONCLASSID 11118 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONDITIONCLASSNAME 11119 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_INPUTNODE 11120 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONDITIONCLASSID 11121 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONDITIONCLASSNAME 11122 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_INPUTNODE 11123 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_HIGHHIGHLIMIT 11124 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_HIGHLIMIT 11125 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LOWLIMIT 11126 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LOWLOWLIMIT 11127 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONDITIONCLASSID 11128 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONDITIONCLASSNAME 11129 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_INPUTNODE 11130 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONDITIONCLASSID 11131 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONDITIONCLASSNAME 11132 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_INPUTNODE 11133 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONCLASSID 11134 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONCLASSNAME 11135 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_INPUTNODE 11136 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONDITIONCLASSID 11137 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONDITIONCLASSNAME 11138 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_INPUTNODE 11139 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONDITIONCLASSID 11140 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONDITIONCLASSNAME 11141 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_INPUTNODE 11142 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONDITIONCLASSID 11143 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONDITIONCLASSNAME 11144 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_INPUTNODE 11145 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONCLASSID 11146 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONCLASSNAME 11147 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_INPUTNODE 11148 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONDITIONCLASSID 11149 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONDITIONCLASSNAME 11150 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_INPUTNODE 11151 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONDITIONCLASSID 11152 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONDITIONCLASSNAME 11153 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_INPUTNODE 11154 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONDITIONCLASSID 11155 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONDITIONCLASSNAME 11156 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_INPUTNODE 11157 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_NORMALSTATE 11158 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONDITIONCLASSID 11159 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONDITIONCLASSNAME 11160 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_INPUTNODE 11161 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_NORMALSTATE 11162 /* Variable */ +#define UA_NS0ID_BASECONDITIONCLASSTYPE 11163 /* ObjectType */ +#define UA_NS0ID_PROCESSCONDITIONCLASSTYPE 11164 /* ObjectType */ +#define UA_NS0ID_MAINTENANCECONDITIONCLASSTYPE 11165 /* ObjectType */ +#define UA_NS0ID_SYSTEMCONDITIONCLASSTYPE 11166 /* ObjectType */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_AGGREGATECONFIGURATION_TREATUNCERTAINASBAD 11168 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_AGGREGATECONFIGURATION_PERCENTDATABAD 11169 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_AGGREGATECONFIGURATION_PERCENTDATAGOOD 11170 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_AGGREGATECONFIGURATION_USESLOPEDEXTRAPOLATION 11171 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_AGGREGATEFUNCTIONS 11172 /* Object */ +#define UA_NS0ID_AGGREGATECONFIGURATIONTYPE 11187 /* ObjectType */ +#define UA_NS0ID_AGGREGATECONFIGURATIONTYPE_TREATUNCERTAINASBAD 11188 /* Variable */ +#define UA_NS0ID_AGGREGATECONFIGURATIONTYPE_PERCENTDATABAD 11189 /* Variable */ +#define UA_NS0ID_AGGREGATECONFIGURATIONTYPE_PERCENTDATAGOOD 11190 /* Variable */ +#define UA_NS0ID_AGGREGATECONFIGURATIONTYPE_USESLOPEDEXTRAPOLATION 11191 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES 11192 /* Object */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_ACCESSHISTORYDATACAPABILITY 11193 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_INSERTDATACAPABILITY 11196 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_REPLACEDATACAPABILITY 11197 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_UPDATEDATACAPABILITY 11198 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_DELETERAWCAPABILITY 11199 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_DELETEATTIMECAPABILITY 11200 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_AGGREGATEFUNCTIONS 11201 /* Object */ +#define UA_NS0ID_HACONFIGURATION 11202 /* Object */ +#define UA_NS0ID_HACONFIGURATION_AGGREGATECONFIGURATION 11203 /* Object */ +#define UA_NS0ID_HACONFIGURATION_AGGREGATECONFIGURATION_TREATUNCERTAINASBAD 11204 /* Variable */ +#define UA_NS0ID_HACONFIGURATION_AGGREGATECONFIGURATION_PERCENTDATABAD 11205 /* Variable */ +#define UA_NS0ID_HACONFIGURATION_AGGREGATECONFIGURATION_PERCENTDATAGOOD 11206 /* Variable */ +#define UA_NS0ID_HACONFIGURATION_AGGREGATECONFIGURATION_USESLOPEDEXTRAPOLATION 11207 /* Variable */ +#define UA_NS0ID_HACONFIGURATION_STEPPED 11208 /* Variable */ +#define UA_NS0ID_HACONFIGURATION_DEFINITION 11209 /* Variable */ +#define UA_NS0ID_HACONFIGURATION_MAXTIMEINTERVAL 11210 /* Variable */ +#define UA_NS0ID_HACONFIGURATION_MINTIMEINTERVAL 11211 /* Variable */ +#define UA_NS0ID_HACONFIGURATION_EXCEPTIONDEVIATION 11212 /* Variable */ +#define UA_NS0ID_HACONFIGURATION_EXCEPTIONDEVIATIONFORMAT 11213 /* Variable */ +#define UA_NS0ID_ANNOTATIONS 11214 /* Variable */ +#define UA_NS0ID_HISTORICALEVENTFILTER 11215 /* Variable */ +#define UA_NS0ID_MODIFICATIONINFO 11216 /* DataType */ +#define UA_NS0ID_HISTORYMODIFIEDDATA 11217 /* DataType */ +#define UA_NS0ID_MODIFICATIONINFO_ENCODING_DEFAULTXML 11218 /* Object */ +#define UA_NS0ID_HISTORYMODIFIEDDATA_ENCODING_DEFAULTXML 11219 /* Object */ +#define UA_NS0ID_MODIFICATIONINFO_ENCODING_DEFAULTBINARY 11226 /* Object */ +#define UA_NS0ID_HISTORYMODIFIEDDATA_ENCODING_DEFAULTBINARY 11227 /* Object */ +#define UA_NS0ID_HISTORYUPDATETYPE 11234 /* DataType */ +#define UA_NS0ID_MULTISTATEVALUEDISCRETETYPE 11238 /* VariableType */ +#define UA_NS0ID_MULTISTATEVALUEDISCRETETYPE_DEFINITION 11239 /* Variable */ +#define UA_NS0ID_MULTISTATEVALUEDISCRETETYPE_VALUEPRECISION 11240 /* Variable */ +#define UA_NS0ID_MULTISTATEVALUEDISCRETETYPE_ENUMVALUES 11241 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_ACCESSHISTORYEVENTSCAPABILITY 11242 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_MAXRETURNDATAVALUES 11268 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_MAXRETURNEVENTVALUES 11269 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_INSERTANNOTATIONCAPABILITY 11270 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_MAXRETURNDATAVALUES 11273 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_MAXRETURNEVENTVALUES 11274 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_INSERTANNOTATIONCAPABILITY 11275 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_INSERTEVENTCAPABILITY 11278 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_REPLACEEVENTCAPABILITY 11279 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_UPDATEEVENTCAPABILITY 11280 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_INSERTEVENTCAPABILITY 11281 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_REPLACEEVENTCAPABILITY 11282 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_UPDATEEVENTCAPABILITY 11283 /* Variable */ +#define UA_NS0ID_AGGREGATEFUNCTION_TIMEAVERAGE2 11285 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_MINIMUM2 11286 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_MAXIMUM2 11287 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_RANGE2 11288 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_WORSTQUALITY2 11292 /* Object */ +#define UA_NS0ID_PERFORMUPDATETYPE 11293 /* DataType */ +#define UA_NS0ID_UPDATESTRUCTUREDATADETAILS 11295 /* DataType */ +#define UA_NS0ID_UPDATESTRUCTUREDATADETAILS_ENCODING_DEFAULTXML 11296 /* Object */ +#define UA_NS0ID_UPDATESTRUCTUREDATADETAILS_ENCODING_DEFAULTBINARY 11300 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_TOTAL2 11304 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_MINIMUMACTUALTIME2 11305 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_MAXIMUMACTUALTIME2 11306 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_DURATIONINSTATEZERO 11307 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_DURATIONINSTATENONZERO 11308 /* Object */ +#define UA_NS0ID_SERVER_SERVERREDUNDANCY_CURRENTSERVERID 11312 /* Variable */ +#define UA_NS0ID_SERVER_SERVERREDUNDANCY_REDUNDANTSERVERARRAY 11313 /* Variable */ +#define UA_NS0ID_SERVER_SERVERREDUNDANCY_SERVERURIARRAY 11314 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_UNSHELVEDTOTIMEDSHELVED_TRANSITIONNUMBER 11322 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_UNSHELVEDTOONESHOTSHELVED_TRANSITIONNUMBER 11323 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_TIMEDSHELVEDTOUNSHELVED_TRANSITIONNUMBER 11324 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_TIMEDSHELVEDTOONESHOTSHELVED_TRANSITIONNUMBER 11325 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_ONESHOTSHELVEDTOUNSHELVED_TRANSITIONNUMBER 11326 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_ONESHOTSHELVEDTOTIMEDSHELVED_TRANSITIONNUMBER 11327 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LOWLOWTOLOW_TRANSITIONNUMBER 11340 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LOWTOLOWLOW_TRANSITIONNUMBER 11341 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_HIGHHIGHTOHIGH_TRANSITIONNUMBER 11342 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_HIGHTOHIGHHIGH_TRANSITIONNUMBER 11343 /* Variable */ +#define UA_NS0ID_AGGREGATEFUNCTION_STANDARDDEVIATIONSAMPLE 11426 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_STANDARDDEVIATIONPOPULATION 11427 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_VARIANCESAMPLE 11428 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_VARIANCEPOPULATION 11429 /* Object */ +#define UA_NS0ID_ENUMSTRINGS 11432 /* Variable */ +#define UA_NS0ID_VALUEASTEXT 11433 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE 11436 /* ObjectType */ +#define UA_NS0ID_PROGRESSEVENTTYPE_EVENTID 11437 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_EVENTTYPE 11438 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_SOURCENODE 11439 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_SOURCENAME 11440 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_TIME 11441 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_RECEIVETIME 11442 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_LOCALTIME 11443 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_MESSAGE 11444 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_SEVERITY 11445 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE 11446 /* ObjectType */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_EVENTID 11447 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_EVENTTYPE 11448 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_SOURCENODE 11449 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_SOURCENAME 11450 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_TIME 11451 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_RECEIVETIME 11452 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_LOCALTIME 11453 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_MESSAGE 11454 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_SEVERITY 11455 /* Variable */ +#define UA_NS0ID_TRANSITIONVARIABLETYPE_EFFECTIVETRANSITIONTIME 11456 /* Variable */ +#define UA_NS0ID_FINITETRANSITIONVARIABLETYPE_EFFECTIVETRANSITIONTIME 11457 /* Variable */ +#define UA_NS0ID_STATEMACHINETYPE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11458 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11459 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_TRANSITION_EFFECTIVETRANSITIONTIME 11460 /* Variable */ +#define UA_NS0ID_MULTISTATEVALUEDISCRETETYPE_VALUEASTEXT 11461 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_TRANSITION_EFFECTIVETRANSITIONTIME 11462 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_TRANSITION_EFFECTIVETRANSITIONTIME 11463 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11464 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11465 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11466 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11467 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11468 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11469 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11470 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11471 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11472 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11473 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11474 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11475 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11476 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11477 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11478 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11479 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11480 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11481 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11482 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11483 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_SECURECHANNELID 11485 /* Variable */ +#define UA_NS0ID_OPTIONSETTYPE 11487 /* VariableType */ +#define UA_NS0ID_OPTIONSETTYPE_OPTIONSETVALUES 11488 /* Variable */ +#define UA_NS0ID_SERVERTYPE_GETMONITOREDITEMS 11489 /* Method */ +#define UA_NS0ID_SERVERTYPE_GETMONITOREDITEMS_INPUTARGUMENTS 11490 /* Variable */ +#define UA_NS0ID_SERVERTYPE_GETMONITOREDITEMS_OUTPUTARGUMENTS 11491 /* Variable */ +#define UA_NS0ID_SERVER_GETMONITOREDITEMS 11492 /* Method */ +#define UA_NS0ID_SERVER_GETMONITOREDITEMS_INPUTARGUMENTS 11493 /* Variable */ +#define UA_NS0ID_SERVER_GETMONITOREDITEMS_OUTPUTARGUMENTS 11494 /* Variable */ +#define UA_NS0ID_GETMONITOREDITEMSMETHODTYPE 11495 /* Method */ +#define UA_NS0ID_GETMONITOREDITEMSMETHODTYPE_INPUTARGUMENTS 11496 /* Variable */ +#define UA_NS0ID_GETMONITOREDITEMSMETHODTYPE_OUTPUTARGUMENTS 11497 /* Variable */ +#define UA_NS0ID_MAXSTRINGLENGTH 11498 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_STARTOFARCHIVE 11499 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_STARTOFONLINEARCHIVE 11500 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_DELETEEVENTCAPABILITY 11501 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_DELETEEVENTCAPABILITY 11502 /* Variable */ +#define UA_NS0ID_HACONFIGURATION_STARTOFARCHIVE 11503 /* Variable */ +#define UA_NS0ID_HACONFIGURATION_STARTOFONLINEARCHIVE 11504 /* Variable */ +#define UA_NS0ID_AGGREGATEFUNCTION_STARTBOUND 11505 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_ENDBOUND 11506 /* Object */ +#define UA_NS0ID_AGGREGATEFUNCTION_DELTABOUNDS 11507 /* Object */ +#define UA_NS0ID_MODELLINGRULE_OPTIONALPLACEHOLDER 11508 /* Object */ +#define UA_NS0ID_MODELLINGRULE_MANDATORYPLACEHOLDER 11510 /* Object */ +#define UA_NS0ID_MAXARRAYLENGTH 11512 /* Variable */ +#define UA_NS0ID_ENGINEERINGUNITS 11513 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXARRAYLENGTH 11514 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXSTRINGLENGTH 11515 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS 11516 /* Object */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREAD 11517 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERWRITE 11519 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERMETHODCALL 11521 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERBROWSE 11522 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREGISTERNODES 11523 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERTRANSLATEBROWSEPATHSTONODEIDS 11524 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERNODEMANAGEMENT 11525 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS_MAXMONITOREDITEMSPERCALL 11526 /* Variable */ +#define UA_NS0ID_SERVERTYPE_NAMESPACES 11527 /* Object */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXARRAYLENGTH 11549 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXSTRINGLENGTH 11550 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS 11551 /* Object */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS_MAXNODESPERREAD 11552 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS_MAXNODESPERWRITE 11554 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS_MAXNODESPERMETHODCALL 11556 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS_MAXNODESPERBROWSE 11557 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS_MAXNODESPERREGISTERNODES 11558 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS_MAXNODESPERTRANSLATEBROWSEPATHSTONODEIDS 11559 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS_MAXNODESPERNODEMANAGEMENT 11560 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS_MAXMONITOREDITEMSPERCALL 11561 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_VENDORCAPABILITY_PLACEHOLDER 11562 /* Variable */ +#define UA_NS0ID_OPERATIONLIMITSTYPE 11564 /* ObjectType */ +#define UA_NS0ID_OPERATIONLIMITSTYPE_MAXNODESPERREAD 11565 /* Variable */ +#define UA_NS0ID_OPERATIONLIMITSTYPE_MAXNODESPERWRITE 11567 /* Variable */ +#define UA_NS0ID_OPERATIONLIMITSTYPE_MAXNODESPERMETHODCALL 11569 /* Variable */ +#define UA_NS0ID_OPERATIONLIMITSTYPE_MAXNODESPERBROWSE 11570 /* Variable */ +#define UA_NS0ID_OPERATIONLIMITSTYPE_MAXNODESPERREGISTERNODES 11571 /* Variable */ +#define UA_NS0ID_OPERATIONLIMITSTYPE_MAXNODESPERTRANSLATEBROWSEPATHSTONODEIDS 11572 /* Variable */ +#define UA_NS0ID_OPERATIONLIMITSTYPE_MAXNODESPERNODEMANAGEMENT 11573 /* Variable */ +#define UA_NS0ID_OPERATIONLIMITSTYPE_MAXMONITOREDITEMSPERCALL 11574 /* Variable */ +#define UA_NS0ID_FILETYPE 11575 /* ObjectType */ +#define UA_NS0ID_FILETYPE_SIZE 11576 /* Variable */ +#define UA_NS0ID_FILETYPE_OPENCOUNT 11579 /* Variable */ +#define UA_NS0ID_FILETYPE_OPEN 11580 /* Method */ +#define UA_NS0ID_FILETYPE_OPEN_INPUTARGUMENTS 11581 /* Variable */ +#define UA_NS0ID_FILETYPE_OPEN_OUTPUTARGUMENTS 11582 /* Variable */ +#define UA_NS0ID_FILETYPE_CLOSE 11583 /* Method */ +#define UA_NS0ID_FILETYPE_CLOSE_INPUTARGUMENTS 11584 /* Variable */ +#define UA_NS0ID_FILETYPE_READ 11585 /* Method */ +#define UA_NS0ID_FILETYPE_READ_INPUTARGUMENTS 11586 /* Variable */ +#define UA_NS0ID_FILETYPE_READ_OUTPUTARGUMENTS 11587 /* Variable */ +#define UA_NS0ID_FILETYPE_WRITE 11588 /* Method */ +#define UA_NS0ID_FILETYPE_WRITE_INPUTARGUMENTS 11589 /* Variable */ +#define UA_NS0ID_FILETYPE_GETPOSITION 11590 /* Method */ +#define UA_NS0ID_FILETYPE_GETPOSITION_INPUTARGUMENTS 11591 /* Variable */ +#define UA_NS0ID_FILETYPE_GETPOSITION_OUTPUTARGUMENTS 11592 /* Variable */ +#define UA_NS0ID_FILETYPE_SETPOSITION 11593 /* Method */ +#define UA_NS0ID_FILETYPE_SETPOSITION_INPUTARGUMENTS 11594 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE 11595 /* ObjectType */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_SIZE 11596 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_OPENCOUNT 11599 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_OPEN 11600 /* Method */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_OPEN_INPUTARGUMENTS 11601 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_OPEN_OUTPUTARGUMENTS 11602 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_CLOSE 11603 /* Method */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_CLOSE_INPUTARGUMENTS 11604 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_READ 11605 /* Method */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_READ_INPUTARGUMENTS 11606 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_READ_OUTPUTARGUMENTS 11607 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_WRITE 11608 /* Method */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_WRITE_INPUTARGUMENTS 11609 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_GETPOSITION 11610 /* Method */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_GETPOSITION_INPUTARGUMENTS 11611 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_GETPOSITION_OUTPUTARGUMENTS 11612 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_SETPOSITION 11613 /* Method */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_SETPOSITION_INPUTARGUMENTS 11614 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_EXPORTNAMESPACE 11615 /* Method */ +#define UA_NS0ID_NAMESPACEMETADATATYPE 11616 /* ObjectType */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEURI 11617 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEVERSION 11618 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEPUBLICATIONDATE 11619 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_ISNAMESPACESUBSET 11620 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_STATICNODEIDTYPES 11621 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_STATICNUMERICNODEIDRANGE 11622 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_STATICSTRINGNODEIDPATTERN 11623 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE 11624 /* Object */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_SIZE 11625 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_OPENCOUNT 11628 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_OPEN 11629 /* Method */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_OPEN_INPUTARGUMENTS 11630 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_OPEN_OUTPUTARGUMENTS 11631 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_CLOSE 11632 /* Method */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_CLOSE_INPUTARGUMENTS 11633 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_READ 11634 /* Method */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_READ_INPUTARGUMENTS 11635 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_READ_OUTPUTARGUMENTS 11636 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_WRITE 11637 /* Method */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_WRITE_INPUTARGUMENTS 11638 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_GETPOSITION 11639 /* Method */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_GETPOSITION_INPUTARGUMENTS 11640 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_GETPOSITION_OUTPUTARGUMENTS 11641 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_SETPOSITION 11642 /* Method */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_SETPOSITION_INPUTARGUMENTS 11643 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_EXPORTNAMESPACE 11644 /* Method */ +#define UA_NS0ID_NAMESPACESTYPE 11645 /* ObjectType */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER 11646 /* Object */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEURI 11647 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEVERSION 11648 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEPUBLICATIONDATE 11649 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_ISNAMESPACESUBSET 11650 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_STATICNODEIDTYPES 11651 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_STATICNUMERICNODEIDRANGE 11652 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_STATICSTRINGNODEIDPATTERN 11653 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE 11654 /* Object */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_SIZE 11655 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_OPENCOUNT 11658 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_OPEN 11659 /* Method */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_OPEN_INPUTARGUMENTS 11660 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_OPEN_OUTPUTARGUMENTS 11661 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_CLOSE 11662 /* Method */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_CLOSE_INPUTARGUMENTS 11663 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_READ 11664 /* Method */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_READ_INPUTARGUMENTS 11665 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_READ_OUTPUTARGUMENTS 11666 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_WRITE 11667 /* Method */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_WRITE_INPUTARGUMENTS 11668 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_GETPOSITION 11669 /* Method */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_GETPOSITION_INPUTARGUMENTS 11670 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_GETPOSITION_OUTPUTARGUMENTS 11671 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_SETPOSITION 11672 /* Method */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_SETPOSITION_INPUTARGUMENTS 11673 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_EXPORTNAMESPACE 11674 /* Method */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_SYSTEMSTATE 11696 /* Variable */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSTYPE_SAMPLEDMONITOREDITEMSCOUNT 11697 /* Variable */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSTYPE_MAXSAMPLEDMONITOREDITEMSCOUNT 11698 /* Variable */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSTYPE_DISABLEDMONITOREDITEMSSAMPLINGCOUNT 11699 /* Variable */ +#define UA_NS0ID_OPTIONSETTYPE_BITMASK 11701 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXARRAYLENGTH 11702 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXSTRINGLENGTH 11703 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS 11704 /* Object */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREAD 11705 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERWRITE 11707 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERMETHODCALL 11709 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERBROWSE 11710 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREGISTERNODES 11711 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERTRANSLATEBROWSEPATHSTONODEIDS 11712 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERNODEMANAGEMENT 11713 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXMONITOREDITEMSPERCALL 11714 /* Variable */ +#define UA_NS0ID_SERVER_NAMESPACES 11715 /* Object */ +#define UA_NS0ID_BITFIELDMASKDATATYPE 11737 /* DataType */ +#define UA_NS0ID_OPENMETHODTYPE 11738 /* Method */ +#define UA_NS0ID_OPENMETHODTYPE_INPUTARGUMENTS 11739 /* Variable */ +#define UA_NS0ID_OPENMETHODTYPE_OUTPUTARGUMENTS 11740 /* Variable */ +#define UA_NS0ID_CLOSEMETHODTYPE 11741 /* Method */ +#define UA_NS0ID_CLOSEMETHODTYPE_INPUTARGUMENTS 11742 /* Variable */ +#define UA_NS0ID_READMETHODTYPE 11743 /* Method */ +#define UA_NS0ID_READMETHODTYPE_INPUTARGUMENTS 11744 /* Variable */ +#define UA_NS0ID_READMETHODTYPE_OUTPUTARGUMENTS 11745 /* Variable */ +#define UA_NS0ID_WRITEMETHODTYPE 11746 /* Method */ +#define UA_NS0ID_WRITEMETHODTYPE_INPUTARGUMENTS 11747 /* Variable */ +#define UA_NS0ID_GETPOSITIONMETHODTYPE 11748 /* Method */ +#define UA_NS0ID_GETPOSITIONMETHODTYPE_INPUTARGUMENTS 11749 /* Variable */ +#define UA_NS0ID_GETPOSITIONMETHODTYPE_OUTPUTARGUMENTS 11750 /* Variable */ +#define UA_NS0ID_SETPOSITIONMETHODTYPE 11751 /* Method */ +#define UA_NS0ID_SETPOSITIONMETHODTYPE_INPUTARGUMENTS 11752 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE 11753 /* ObjectType */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_EVENTID 11754 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_EVENTTYPE 11755 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SOURCENODE 11756 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SOURCENAME 11757 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_TIME 11758 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_RECEIVETIME 11759 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_LOCALTIME 11760 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_MESSAGE 11761 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SEVERITY 11762 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONDITIONCLASSID 11763 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONDITIONCLASSNAME 11764 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONDITIONNAME 11765 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_BRANCHID 11766 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_RETAIN 11767 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ENABLEDSTATE 11768 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ENABLEDSTATE_ID 11769 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ENABLEDSTATE_NAME 11770 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ENABLEDSTATE_NUMBER 11771 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 11772 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 11773 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 11774 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ENABLEDSTATE_TRUESTATE 11775 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ENABLEDSTATE_FALSESTATE 11776 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_QUALITY 11777 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_QUALITY_SOURCETIMESTAMP 11778 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_LASTSEVERITY 11779 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 11780 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_COMMENT 11781 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_COMMENT_SOURCETIMESTAMP 11782 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CLIENTUSERID 11783 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_DISABLE 11784 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ENABLE 11785 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ADDCOMMENT 11786 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 11787 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONDITIONREFRESH 11788 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 11789 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACKEDSTATE 11790 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACKEDSTATE_ID 11791 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACKEDSTATE_NAME 11792 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACKEDSTATE_NUMBER 11793 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 11794 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACKEDSTATE_TRANSITIONTIME 11795 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 11796 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACKEDSTATE_TRUESTATE 11797 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACKEDSTATE_FALSESTATE 11798 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONFIRMEDSTATE 11799 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONFIRMEDSTATE_ID 11800 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONFIRMEDSTATE_NAME 11801 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONFIRMEDSTATE_NUMBER 11802 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 11803 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 11804 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 11805 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONFIRMEDSTATE_TRUESTATE 11806 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONFIRMEDSTATE_FALSESTATE 11807 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACKNOWLEDGE 11808 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 11809 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONFIRM 11810 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONFIRM_INPUTARGUMENTS 11811 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACTIVESTATE 11812 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACTIVESTATE_ID 11813 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACTIVESTATE_NAME 11814 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACTIVESTATE_NUMBER 11815 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 11816 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACTIVESTATE_TRANSITIONTIME 11817 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 11818 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACTIVESTATE_TRUESTATE 11819 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ACTIVESTATE_FALSESTATE 11820 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_INPUTNODE 11821 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESSEDSTATE 11822 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESSEDSTATE_ID 11823 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESSEDSTATE_NAME 11824 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESSEDSTATE_NUMBER 11825 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 11826 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 11827 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 11828 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 11829 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 11830 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE 11831 /* Object */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_CURRENTSTATE 11832 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 11833 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 11834 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 11835 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 11836 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_LASTTRANSITION 11837 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 11838 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 11839 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 11840 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 11841 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 11842 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_UNSHELVETIME 11843 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_UNSHELVE 11844 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 11845 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 11846 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 11847 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESSEDORSHELVED 11848 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_MAXTIMESHELVED 11849 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_NORMALSTATE 11850 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_COMMENT 11851 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_SELECTEDRESPONSE 11852 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_COMMENT 11853 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_COMMENT 11854 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_SHELVINGTIME 11855 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE 11856 /* ObjectType */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_EVENTID 11857 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_EVENTTYPE 11858 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_SOURCENODE 11859 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_SOURCENAME 11860 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_TIME 11861 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_RECEIVETIME 11862 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_LOCALTIME 11863 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_MESSAGE 11864 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_SEVERITY 11865 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_ACTIONTIMESTAMP 11866 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_STATUS 11867 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_SERVERID 11868 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_CLIENTAUDITENTRYID 11869 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_CLIENTUSERID 11870 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_METHODID 11871 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_INPUTARGUMENTS 11872 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_OLDSTATEID 11873 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_NEWSTATEID 11874 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_TRANSITIONNUMBER 11875 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_AGGREGATEFUNCTIONS 11876 /* Object */ +#define UA_NS0ID_HACONFIGURATION_AGGREGATEFUNCTIONS 11877 /* Object */ +#define UA_NS0ID_NODECLASS_ENUMVALUES 11878 /* Variable */ +#define UA_NS0ID_INSTANCENODE 11879 /* DataType */ +#define UA_NS0ID_TYPENODE 11880 /* DataType */ +#define UA_NS0ID_NODEATTRIBUTESMASK_ENUMVALUES 11881 /* Variable */ +#define UA_NS0ID_BROWSERESULTMASK_ENUMVALUES 11883 /* Variable */ +#define UA_NS0ID_HISTORYUPDATETYPE_ENUMVALUES 11884 /* Variable */ +#define UA_NS0ID_PERFORMUPDATETYPE_ENUMVALUES 11885 /* Variable */ +#define UA_NS0ID_INSTANCENODE_ENCODING_DEFAULTXML 11887 /* Object */ +#define UA_NS0ID_TYPENODE_ENCODING_DEFAULTXML 11888 /* Object */ +#define UA_NS0ID_INSTANCENODE_ENCODING_DEFAULTBINARY 11889 /* Object */ +#define UA_NS0ID_TYPENODE_ENCODING_DEFAULTBINARY 11890 /* Object */ +#define UA_NS0ID_SESSIONDIAGNOSTICSOBJECTTYPE_SESSIONDIAGNOSTICS_UNAUTHORIZEDREQUESTCOUNT 11891 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSVARIABLETYPE_UNAUTHORIZEDREQUESTCOUNT 11892 /* Variable */ +#define UA_NS0ID_OPENFILEMODE 11939 /* DataType */ +#define UA_NS0ID_OPENFILEMODE_ENUMVALUES 11940 /* Variable */ +#define UA_NS0ID_MODELCHANGESTRUCTUREVERBMASK 11941 /* DataType */ +#define UA_NS0ID_MODELCHANGESTRUCTUREVERBMASK_ENUMVALUES 11942 /* Variable */ +#define UA_NS0ID_ENDPOINTURLLISTDATATYPE 11943 /* DataType */ +#define UA_NS0ID_NETWORKGROUPDATATYPE 11944 /* DataType */ +#define UA_NS0ID_NONTRANSPARENTNETWORKREDUNDANCYTYPE 11945 /* ObjectType */ +#define UA_NS0ID_NONTRANSPARENTNETWORKREDUNDANCYTYPE_REDUNDANCYSUPPORT 11946 /* Variable */ +#define UA_NS0ID_NONTRANSPARENTNETWORKREDUNDANCYTYPE_SERVERURIARRAY 11947 /* Variable */ +#define UA_NS0ID_NONTRANSPARENTNETWORKREDUNDANCYTYPE_SERVERNETWORKGROUPS 11948 /* Variable */ +#define UA_NS0ID_ENDPOINTURLLISTDATATYPE_ENCODING_DEFAULTXML 11949 /* Object */ +#define UA_NS0ID_NETWORKGROUPDATATYPE_ENCODING_DEFAULTXML 11950 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENDPOINTURLLISTDATATYPE 11951 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENDPOINTURLLISTDATATYPE_DATATYPEVERSION 11952 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENDPOINTURLLISTDATATYPE_DICTIONARYFRAGMENT 11953 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_NETWORKGROUPDATATYPE 11954 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_NETWORKGROUPDATATYPE_DATATYPEVERSION 11955 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_NETWORKGROUPDATATYPE_DICTIONARYFRAGMENT 11956 /* Variable */ +#define UA_NS0ID_ENDPOINTURLLISTDATATYPE_ENCODING_DEFAULTBINARY 11957 /* Object */ +#define UA_NS0ID_NETWORKGROUPDATATYPE_ENCODING_DEFAULTBINARY 11958 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENDPOINTURLLISTDATATYPE 11959 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENDPOINTURLLISTDATATYPE_DATATYPEVERSION 11960 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENDPOINTURLLISTDATATYPE_DICTIONARYFRAGMENT 11961 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_NETWORKGROUPDATATYPE 11962 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_NETWORKGROUPDATATYPE_DATATYPEVERSION 11963 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_NETWORKGROUPDATATYPE_DICTIONARYFRAGMENT 11964 /* Variable */ +#define UA_NS0ID_ARRAYITEMTYPE 12021 /* VariableType */ +#define UA_NS0ID_ARRAYITEMTYPE_DEFINITION 12022 /* Variable */ +#define UA_NS0ID_ARRAYITEMTYPE_VALUEPRECISION 12023 /* Variable */ +#define UA_NS0ID_ARRAYITEMTYPE_INSTRUMENTRANGE 12024 /* Variable */ +#define UA_NS0ID_ARRAYITEMTYPE_EURANGE 12025 /* Variable */ +#define UA_NS0ID_ARRAYITEMTYPE_ENGINEERINGUNITS 12026 /* Variable */ +#define UA_NS0ID_ARRAYITEMTYPE_TITLE 12027 /* Variable */ +#define UA_NS0ID_ARRAYITEMTYPE_AXISSCALETYPE 12028 /* Variable */ +#define UA_NS0ID_YARRAYITEMTYPE 12029 /* VariableType */ +#define UA_NS0ID_YARRAYITEMTYPE_DEFINITION 12030 /* Variable */ +#define UA_NS0ID_YARRAYITEMTYPE_VALUEPRECISION 12031 /* Variable */ +#define UA_NS0ID_YARRAYITEMTYPE_INSTRUMENTRANGE 12032 /* Variable */ +#define UA_NS0ID_YARRAYITEMTYPE_EURANGE 12033 /* Variable */ +#define UA_NS0ID_YARRAYITEMTYPE_ENGINEERINGUNITS 12034 /* Variable */ +#define UA_NS0ID_YARRAYITEMTYPE_TITLE 12035 /* Variable */ +#define UA_NS0ID_YARRAYITEMTYPE_AXISSCALETYPE 12036 /* Variable */ +#define UA_NS0ID_YARRAYITEMTYPE_XAXISDEFINITION 12037 /* Variable */ +#define UA_NS0ID_XYARRAYITEMTYPE 12038 /* VariableType */ +#define UA_NS0ID_XYARRAYITEMTYPE_DEFINITION 12039 /* Variable */ +#define UA_NS0ID_XYARRAYITEMTYPE_VALUEPRECISION 12040 /* Variable */ +#define UA_NS0ID_XYARRAYITEMTYPE_INSTRUMENTRANGE 12041 /* Variable */ +#define UA_NS0ID_XYARRAYITEMTYPE_EURANGE 12042 /* Variable */ +#define UA_NS0ID_XYARRAYITEMTYPE_ENGINEERINGUNITS 12043 /* Variable */ +#define UA_NS0ID_XYARRAYITEMTYPE_TITLE 12044 /* Variable */ +#define UA_NS0ID_XYARRAYITEMTYPE_AXISSCALETYPE 12045 /* Variable */ +#define UA_NS0ID_XYARRAYITEMTYPE_XAXISDEFINITION 12046 /* Variable */ +#define UA_NS0ID_IMAGEITEMTYPE 12047 /* VariableType */ +#define UA_NS0ID_IMAGEITEMTYPE_DEFINITION 12048 /* Variable */ +#define UA_NS0ID_IMAGEITEMTYPE_VALUEPRECISION 12049 /* Variable */ +#define UA_NS0ID_IMAGEITEMTYPE_INSTRUMENTRANGE 12050 /* Variable */ +#define UA_NS0ID_IMAGEITEMTYPE_EURANGE 12051 /* Variable */ +#define UA_NS0ID_IMAGEITEMTYPE_ENGINEERINGUNITS 12052 /* Variable */ +#define UA_NS0ID_IMAGEITEMTYPE_TITLE 12053 /* Variable */ +#define UA_NS0ID_IMAGEITEMTYPE_AXISSCALETYPE 12054 /* Variable */ +#define UA_NS0ID_IMAGEITEMTYPE_XAXISDEFINITION 12055 /* Variable */ +#define UA_NS0ID_IMAGEITEMTYPE_YAXISDEFINITION 12056 /* Variable */ +#define UA_NS0ID_CUBEITEMTYPE 12057 /* VariableType */ +#define UA_NS0ID_CUBEITEMTYPE_DEFINITION 12058 /* Variable */ +#define UA_NS0ID_CUBEITEMTYPE_VALUEPRECISION 12059 /* Variable */ +#define UA_NS0ID_CUBEITEMTYPE_INSTRUMENTRANGE 12060 /* Variable */ +#define UA_NS0ID_CUBEITEMTYPE_EURANGE 12061 /* Variable */ +#define UA_NS0ID_CUBEITEMTYPE_ENGINEERINGUNITS 12062 /* Variable */ +#define UA_NS0ID_CUBEITEMTYPE_TITLE 12063 /* Variable */ +#define UA_NS0ID_CUBEITEMTYPE_AXISSCALETYPE 12064 /* Variable */ +#define UA_NS0ID_CUBEITEMTYPE_XAXISDEFINITION 12065 /* Variable */ +#define UA_NS0ID_CUBEITEMTYPE_YAXISDEFINITION 12066 /* Variable */ +#define UA_NS0ID_CUBEITEMTYPE_ZAXISDEFINITION 12067 /* Variable */ +#define UA_NS0ID_NDIMENSIONARRAYITEMTYPE 12068 /* VariableType */ +#define UA_NS0ID_NDIMENSIONARRAYITEMTYPE_DEFINITION 12069 /* Variable */ +#define UA_NS0ID_NDIMENSIONARRAYITEMTYPE_VALUEPRECISION 12070 /* Variable */ +#define UA_NS0ID_NDIMENSIONARRAYITEMTYPE_INSTRUMENTRANGE 12071 /* Variable */ +#define UA_NS0ID_NDIMENSIONARRAYITEMTYPE_EURANGE 12072 /* Variable */ +#define UA_NS0ID_NDIMENSIONARRAYITEMTYPE_ENGINEERINGUNITS 12073 /* Variable */ +#define UA_NS0ID_NDIMENSIONARRAYITEMTYPE_TITLE 12074 /* Variable */ +#define UA_NS0ID_NDIMENSIONARRAYITEMTYPE_AXISSCALETYPE 12075 /* Variable */ +#define UA_NS0ID_NDIMENSIONARRAYITEMTYPE_AXISDEFINITION 12076 /* Variable */ +#define UA_NS0ID_AXISSCALEENUMERATION 12077 /* DataType */ +#define UA_NS0ID_AXISSCALEENUMERATION_ENUMSTRINGS 12078 /* Variable */ +#define UA_NS0ID_AXISINFORMATION 12079 /* DataType */ +#define UA_NS0ID_XVTYPE 12080 /* DataType */ +#define UA_NS0ID_AXISINFORMATION_ENCODING_DEFAULTXML 12081 /* Object */ +#define UA_NS0ID_XVTYPE_ENCODING_DEFAULTXML 12082 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_AXISINFORMATION 12083 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_AXISINFORMATION_DATATYPEVERSION 12084 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_AXISINFORMATION_DICTIONARYFRAGMENT 12085 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_XVTYPE 12086 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_XVTYPE_DATATYPEVERSION 12087 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_XVTYPE_DICTIONARYFRAGMENT 12088 /* Variable */ +#define UA_NS0ID_AXISINFORMATION_ENCODING_DEFAULTBINARY 12089 /* Object */ +#define UA_NS0ID_XVTYPE_ENCODING_DEFAULTBINARY 12090 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_AXISINFORMATION 12091 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_AXISINFORMATION_DATATYPEVERSION 12092 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_AXISINFORMATION_DICTIONARYFRAGMENT 12093 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_XVTYPE 12094 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_XVTYPE_DATATYPEVERSION 12095 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_XVTYPE_DICTIONARYFRAGMENT 12096 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER 12097 /* Object */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS 12098 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_SESSIONID 12099 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_SESSIONNAME 12100 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_CLIENTDESCRIPTION 12101 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_SERVERURI 12102 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_ENDPOINTURL 12103 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_LOCALEIDS 12104 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_ACTUALSESSIONTIMEOUT 12105 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_MAXRESPONSEMESSAGESIZE 12106 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_CLIENTCONNECTIONTIME 12107 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_CLIENTLASTCONTACTTIME 12108 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_CURRENTSUBSCRIPTIONSCOUNT 12109 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_CURRENTMONITOREDITEMSCOUNT 12110 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_CURRENTPUBLISHREQUESTSINQUEUE 12111 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_TOTALREQUESTCOUNT 12112 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_UNAUTHORIZEDREQUESTCOUNT 12113 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_READCOUNT 12114 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_HISTORYREADCOUNT 12115 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_WRITECOUNT 12116 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_HISTORYUPDATECOUNT 12117 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_CALLCOUNT 12118 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_CREATEMONITOREDITEMSCOUNT 12119 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_MODIFYMONITOREDITEMSCOUNT 12120 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_SETMONITORINGMODECOUNT 12121 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_SETTRIGGERINGCOUNT 12122 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_DELETEMONITOREDITEMSCOUNT 12123 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_CREATESUBSCRIPTIONCOUNT 12124 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_MODIFYSUBSCRIPTIONCOUNT 12125 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_SETPUBLISHINGMODECOUNT 12126 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_PUBLISHCOUNT 12127 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_REPUBLISHCOUNT 12128 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_TRANSFERSUBSCRIPTIONSCOUNT 12129 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_DELETESUBSCRIPTIONSCOUNT 12130 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_ADDNODESCOUNT 12131 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_ADDREFERENCESCOUNT 12132 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_DELETENODESCOUNT 12133 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_DELETEREFERENCESCOUNT 12134 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_BROWSECOUNT 12135 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_BROWSENEXTCOUNT 12136 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_TRANSLATEBROWSEPATHSTONODEIDSCOUNT 12137 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_QUERYFIRSTCOUNT 12138 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_QUERYNEXTCOUNT 12139 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_REGISTERNODESCOUNT 12140 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONDIAGNOSTICS_UNREGISTERNODESCOUNT 12141 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONSECURITYDIAGNOSTICS 12142 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONSECURITYDIAGNOSTICS_SESSIONID 12143 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONSECURITYDIAGNOSTICS_CLIENTUSERIDOFSESSION 12144 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONSECURITYDIAGNOSTICS_CLIENTUSERIDHISTORY 12145 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONSECURITYDIAGNOSTICS_AUTHENTICATIONMECHANISM 12146 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONSECURITYDIAGNOSTICS_ENCODING 12147 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONSECURITYDIAGNOSTICS_TRANSPORTPROTOCOL 12148 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONSECURITYDIAGNOSTICS_SECURITYMODE 12149 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONSECURITYDIAGNOSTICS_SECURITYPOLICYURI 12150 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SESSIONSECURITYDIAGNOSTICS_CLIENTCERTIFICATE 12151 /* Variable */ +#define UA_NS0ID_SESSIONSDIAGNOSTICSSUMMARYTYPE_CLIENTNAME_PLACEHOLDER_SUBSCRIPTIONDIAGNOSTICSARRAY 12152 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYREADDATA 12153 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYREADEVENTS 12154 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYUPDATEDATA 12155 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYUPDATEEVENTS 12156 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS_MAXNODESPERHISTORYREADDATA 12157 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS_MAXNODESPERHISTORYREADEVENTS 12158 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS_MAXNODESPERHISTORYUPDATEDATA 12159 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_OPERATIONLIMITS_MAXNODESPERHISTORYUPDATEEVENTS 12160 /* Variable */ +#define UA_NS0ID_OPERATIONLIMITSTYPE_MAXNODESPERHISTORYREADDATA 12161 /* Variable */ +#define UA_NS0ID_OPERATIONLIMITSTYPE_MAXNODESPERHISTORYREADEVENTS 12162 /* Variable */ +#define UA_NS0ID_OPERATIONLIMITSTYPE_MAXNODESPERHISTORYUPDATEDATA 12163 /* Variable */ +#define UA_NS0ID_OPERATIONLIMITSTYPE_MAXNODESPERHISTORYUPDATEEVENTS 12164 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYREADDATA 12165 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYREADEVENTS 12166 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYUPDATEDATA 12167 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYUPDATEEVENTS 12168 /* Variable */ +#define UA_NS0ID_NAMINGRULETYPE_ENUMVALUES 12169 /* Variable */ +#define UA_NS0ID_VIEWVERSION 12170 /* Variable */ +#define UA_NS0ID_COMPLEXNUMBERTYPE 12171 /* DataType */ +#define UA_NS0ID_DOUBLECOMPLEXNUMBERTYPE 12172 /* DataType */ +#define UA_NS0ID_COMPLEXNUMBERTYPE_ENCODING_DEFAULTXML 12173 /* Object */ +#define UA_NS0ID_DOUBLECOMPLEXNUMBERTYPE_ENCODING_DEFAULTXML 12174 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_COMPLEXNUMBERTYPE 12175 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_COMPLEXNUMBERTYPE_DATATYPEVERSION 12176 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_COMPLEXNUMBERTYPE_DICTIONARYFRAGMENT 12177 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DOUBLECOMPLEXNUMBERTYPE 12178 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DOUBLECOMPLEXNUMBERTYPE_DATATYPEVERSION 12179 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DOUBLECOMPLEXNUMBERTYPE_DICTIONARYFRAGMENT 12180 /* Variable */ +#define UA_NS0ID_COMPLEXNUMBERTYPE_ENCODING_DEFAULTBINARY 12181 /* Object */ +#define UA_NS0ID_DOUBLECOMPLEXNUMBERTYPE_ENCODING_DEFAULTBINARY 12182 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_COMPLEXNUMBERTYPE 12183 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_COMPLEXNUMBERTYPE_DATATYPEVERSION 12184 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_COMPLEXNUMBERTYPE_DICTIONARYFRAGMENT 12185 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DOUBLECOMPLEXNUMBERTYPE 12186 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DOUBLECOMPLEXNUMBERTYPE_DATATYPEVERSION 12187 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DOUBLECOMPLEXNUMBERTYPE_DICTIONARYFRAGMENT 12188 /* Variable */ +#define UA_NS0ID_SERVERONNETWORK 12189 /* DataType */ +#define UA_NS0ID_FINDSERVERSONNETWORKREQUEST 12190 /* DataType */ +#define UA_NS0ID_FINDSERVERSONNETWORKRESPONSE 12191 /* DataType */ +#define UA_NS0ID_REGISTERSERVER2REQUEST 12193 /* DataType */ +#define UA_NS0ID_REGISTERSERVER2RESPONSE 12194 /* DataType */ +#define UA_NS0ID_SERVERONNETWORK_ENCODING_DEFAULTXML 12195 /* Object */ +#define UA_NS0ID_FINDSERVERSONNETWORKREQUEST_ENCODING_DEFAULTXML 12196 /* Object */ +#define UA_NS0ID_FINDSERVERSONNETWORKRESPONSE_ENCODING_DEFAULTXML 12197 /* Object */ +#define UA_NS0ID_REGISTERSERVER2REQUEST_ENCODING_DEFAULTXML 12199 /* Object */ +#define UA_NS0ID_REGISTERSERVER2RESPONSE_ENCODING_DEFAULTXML 12200 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SERVERONNETWORK 12201 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SERVERONNETWORK_DATATYPEVERSION 12202 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SERVERONNETWORK_DICTIONARYFRAGMENT 12203 /* Variable */ +#define UA_NS0ID_SERVERONNETWORK_ENCODING_DEFAULTBINARY 12207 /* Object */ +#define UA_NS0ID_FINDSERVERSONNETWORKREQUEST_ENCODING_DEFAULTBINARY 12208 /* Object */ +#define UA_NS0ID_FINDSERVERSONNETWORKRESPONSE_ENCODING_DEFAULTBINARY 12209 /* Object */ +#define UA_NS0ID_REGISTERSERVER2REQUEST_ENCODING_DEFAULTBINARY 12211 /* Object */ +#define UA_NS0ID_REGISTERSERVER2RESPONSE_ENCODING_DEFAULTBINARY 12212 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SERVERONNETWORK 12213 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SERVERONNETWORK_DATATYPEVERSION 12214 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SERVERONNETWORK_DICTIONARYFRAGMENT 12215 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_CONTEXT 12502 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_PROGRESS 12503 /* Variable */ +#define UA_NS0ID_OPENWITHMASKSMETHODTYPE 12513 /* Method */ +#define UA_NS0ID_OPENWITHMASKSMETHODTYPE_INPUTARGUMENTS 12514 /* Variable */ +#define UA_NS0ID_OPENWITHMASKSMETHODTYPE_OUTPUTARGUMENTS 12515 /* Variable */ +#define UA_NS0ID_CLOSEANDUPDATEMETHODTYPE 12516 /* Method */ +#define UA_NS0ID_CLOSEANDUPDATEMETHODTYPE_OUTPUTARGUMENTS 12517 /* Variable */ +#define UA_NS0ID_ADDCERTIFICATEMETHODTYPE 12518 /* Method */ +#define UA_NS0ID_ADDCERTIFICATEMETHODTYPE_INPUTARGUMENTS 12519 /* Variable */ +#define UA_NS0ID_REMOVECERTIFICATEMETHODTYPE 12520 /* Method */ +#define UA_NS0ID_REMOVECERTIFICATEMETHODTYPE_INPUTARGUMENTS 12521 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE 12522 /* ObjectType */ +#define UA_NS0ID_TRUSTLISTTYPE_SIZE 12523 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_OPENCOUNT 12526 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_OPEN 12527 /* Method */ +#define UA_NS0ID_TRUSTLISTTYPE_OPEN_INPUTARGUMENTS 12528 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_OPEN_OUTPUTARGUMENTS 12529 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_CLOSE 12530 /* Method */ +#define UA_NS0ID_TRUSTLISTTYPE_CLOSE_INPUTARGUMENTS 12531 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_READ 12532 /* Method */ +#define UA_NS0ID_TRUSTLISTTYPE_READ_INPUTARGUMENTS 12533 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_READ_OUTPUTARGUMENTS 12534 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_WRITE 12535 /* Method */ +#define UA_NS0ID_TRUSTLISTTYPE_WRITE_INPUTARGUMENTS 12536 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_GETPOSITION 12537 /* Method */ +#define UA_NS0ID_TRUSTLISTTYPE_GETPOSITION_INPUTARGUMENTS 12538 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_GETPOSITION_OUTPUTARGUMENTS 12539 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_SETPOSITION 12540 /* Method */ +#define UA_NS0ID_TRUSTLISTTYPE_SETPOSITION_INPUTARGUMENTS 12541 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_LASTUPDATETIME 12542 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_OPENWITHMASKS 12543 /* Method */ +#define UA_NS0ID_TRUSTLISTTYPE_OPENWITHMASKS_INPUTARGUMENTS 12544 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_OPENWITHMASKS_OUTPUTARGUMENTS 12545 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_CLOSEANDUPDATE 12546 /* Method */ +#define UA_NS0ID_TRUSTLISTTYPE_CLOSEANDUPDATE_OUTPUTARGUMENTS 12547 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_ADDCERTIFICATE 12548 /* Method */ +#define UA_NS0ID_TRUSTLISTTYPE_ADDCERTIFICATE_INPUTARGUMENTS 12549 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_REMOVECERTIFICATE 12550 /* Method */ +#define UA_NS0ID_TRUSTLISTTYPE_REMOVECERTIFICATE_INPUTARGUMENTS 12551 /* Variable */ +#define UA_NS0ID_TRUSTLISTMASKS 12552 /* DataType */ +#define UA_NS0ID_TRUSTLISTMASKS_ENUMVALUES 12553 /* Variable */ +#define UA_NS0ID_TRUSTLISTDATATYPE 12554 /* DataType */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE 12555 /* ObjectType */ +#define UA_NS0ID_CERTIFICATETYPE 12556 /* ObjectType */ +#define UA_NS0ID_APPLICATIONCERTIFICATETYPE 12557 /* ObjectType */ +#define UA_NS0ID_HTTPSCERTIFICATETYPE 12558 /* ObjectType */ +#define UA_NS0ID_RSAMINAPPLICATIONCERTIFICATETYPE 12559 /* ObjectType */ +#define UA_NS0ID_RSASHA256APPLICATIONCERTIFICATETYPE 12560 /* ObjectType */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE 12561 /* ObjectType */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_EVENTID 12562 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_EVENTTYPE 12563 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_SOURCENODE 12564 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_SOURCENAME 12565 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_TIME 12566 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_RECEIVETIME 12567 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_LOCALTIME 12568 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_MESSAGE 12569 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_SEVERITY 12570 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_ACTIONTIMESTAMP 12571 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_STATUS 12572 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_SERVERID 12573 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_CLIENTAUDITENTRYID 12574 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_CLIENTUSERID 12575 /* Variable */ +#define UA_NS0ID_UPDATECERTIFICATEMETHODTYPE 12578 /* Method */ +#define UA_NS0ID_UPDATECERTIFICATEMETHODTYPE_INPUTARGUMENTS 12579 /* Variable */ +#define UA_NS0ID_UPDATECERTIFICATEMETHODTYPE_OUTPUTARGUMENTS 12580 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE 12581 /* ObjectType */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_SUPPORTEDPRIVATEKEYFORMATS 12583 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_MAXTRUSTLISTSIZE 12584 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_MULTICASTDNSENABLED 12585 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_UPDATECERTIFICATE 12616 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_UPDATECERTIFICATE_INPUTARGUMENTS 12617 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_UPDATECERTIFICATE_OUTPUTARGUMENTS 12618 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE 12620 /* ObjectType */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_EVENTID 12621 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_EVENTTYPE 12622 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_SOURCENODE 12623 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_SOURCENAME 12624 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_TIME 12625 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_RECEIVETIME 12626 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_LOCALTIME 12627 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_MESSAGE 12628 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_SEVERITY 12629 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_ACTIONTIMESTAMP 12630 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_STATUS 12631 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_SERVERID 12632 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_CLIENTAUDITENTRYID 12633 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_CLIENTUSERID 12634 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION 12637 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_SUPPORTEDPRIVATEKEYFORMATS 12639 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_MAXTRUSTLISTSIZE 12640 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_MULTICASTDNSENABLED 12641 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST 12642 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SIZE 12643 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENCOUNT 12646 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN 12647 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 12648 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 12649 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSE 12650 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 12651 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ 12652 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ_INPUTARGUMENTS 12653 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 12654 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITE 12655 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 12656 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION 12657 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 12658 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 12659 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SETPOSITION 12660 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 12661 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_LASTUPDATETIME 12662 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS 12663 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 12664 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 12665 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE 12666 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 12667 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ADDCERTIFICATE 12668 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 12669 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_REMOVECERTIFICATE 12670 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 12671 /* Variable */ +#define UA_NS0ID_TRUSTLISTDATATYPE_ENCODING_DEFAULTXML 12676 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TRUSTLISTDATATYPE 12677 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TRUSTLISTDATATYPE_DATATYPEVERSION 12678 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TRUSTLISTDATATYPE_DICTIONARYFRAGMENT 12679 /* Variable */ +#define UA_NS0ID_TRUSTLISTDATATYPE_ENCODING_DEFAULTBINARY 12680 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TRUSTLISTDATATYPE 12681 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TRUSTLISTDATATYPE_DATATYPEVERSION 12682 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TRUSTLISTDATATYPE_DICTIONARYFRAGMENT 12683 /* Variable */ +#define UA_NS0ID_FILETYPE_WRITABLE 12686 /* Variable */ +#define UA_NS0ID_FILETYPE_USERWRITABLE 12687 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_WRITABLE 12688 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_USERWRITABLE 12689 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_WRITABLE 12690 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_USERWRITABLE 12691 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_WRITABLE 12692 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_USERWRITABLE 12693 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_WRITABLE 12698 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_USERWRITABLE 12699 /* Variable */ +#define UA_NS0ID_CLOSEANDUPDATEMETHODTYPE_INPUTARGUMENTS 12704 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_CLOSEANDUPDATE_INPUTARGUMENTS 12705 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_SERVERCAPABILITIES 12708 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_SERVERCAPABILITIES 12710 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RELATIVEPATHELEMENT 12712 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RELATIVEPATHELEMENT_DATATYPEVERSION 12713 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RELATIVEPATHELEMENT_DICTIONARYFRAGMENT 12714 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RELATIVEPATH 12715 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RELATIVEPATH_DATATYPEVERSION 12716 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RELATIVEPATH_DICTIONARYFRAGMENT 12717 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RELATIVEPATHELEMENT 12718 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RELATIVEPATHELEMENT_DATATYPEVERSION 12719 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RELATIVEPATHELEMENT_DICTIONARYFRAGMENT 12720 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RELATIVEPATH 12721 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RELATIVEPATH_DATATYPEVERSION 12722 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RELATIVEPATH_DICTIONARYFRAGMENT 12723 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CREATESIGNINGREQUEST 12731 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CREATESIGNINGREQUEST_INPUTARGUMENTS 12732 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CREATESIGNINGREQUEST_OUTPUTARGUMENTS 12733 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_APPLYCHANGES 12734 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CREATESIGNINGREQUEST 12737 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CREATESIGNINGREQUEST_INPUTARGUMENTS 12738 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CREATESIGNINGREQUEST_OUTPUTARGUMENTS 12739 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_APPLYCHANGES 12740 /* Method */ +#define UA_NS0ID_CREATESIGNINGREQUESTMETHODTYPE 12741 /* Method */ +#define UA_NS0ID_CREATESIGNINGREQUESTMETHODTYPE_INPUTARGUMENTS 12742 /* Variable */ +#define UA_NS0ID_CREATESIGNINGREQUESTMETHODTYPE_OUTPUTARGUMENTS 12743 /* Variable */ +#define UA_NS0ID_OPTIONSETVALUES 12745 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SETSUBSCRIPTIONDURABLE 12746 /* Method */ +#define UA_NS0ID_SERVERTYPE_SETSUBSCRIPTIONDURABLE_INPUTARGUMENTS 12747 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SETSUBSCRIPTIONDURABLE_OUTPUTARGUMENTS 12748 /* Variable */ +#define UA_NS0ID_SERVER_SETSUBSCRIPTIONDURABLE 12749 /* Method */ +#define UA_NS0ID_SERVER_SETSUBSCRIPTIONDURABLE_INPUTARGUMENTS 12750 /* Variable */ +#define UA_NS0ID_SERVER_SETSUBSCRIPTIONDURABLE_OUTPUTARGUMENTS 12751 /* Variable */ +#define UA_NS0ID_SETSUBSCRIPTIONDURABLEMETHODTYPE 12752 /* Method */ +#define UA_NS0ID_SETSUBSCRIPTIONDURABLEMETHODTYPE_INPUTARGUMENTS 12753 /* Variable */ +#define UA_NS0ID_SETSUBSCRIPTIONDURABLEMETHODTYPE_OUTPUTARGUMENTS 12754 /* Variable */ +#define UA_NS0ID_OPTIONSET 12755 /* DataType */ +#define UA_NS0ID_UNION 12756 /* DataType */ +#define UA_NS0ID_OPTIONSET_ENCODING_DEFAULTXML 12757 /* Object */ +#define UA_NS0ID_UNION_ENCODING_DEFAULTXML 12758 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_OPTIONSET 12759 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_OPTIONSET_DATATYPEVERSION 12760 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_OPTIONSET_DICTIONARYFRAGMENT 12761 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UNION 12762 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UNION_DATATYPEVERSION 12763 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UNION_DICTIONARYFRAGMENT 12764 /* Variable */ +#define UA_NS0ID_OPTIONSET_ENCODING_DEFAULTBINARY 12765 /* Object */ +#define UA_NS0ID_UNION_ENCODING_DEFAULTBINARY 12766 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_OPTIONSET 12767 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_OPTIONSET_DATATYPEVERSION 12768 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_OPTIONSET_DICTIONARYFRAGMENT 12769 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UNION 12770 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UNION_DATATYPEVERSION 12771 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UNION_DICTIONARYFRAGMENT 12772 /* Variable */ +#define UA_NS0ID_GETREJECTEDLISTMETHODTYPE 12773 /* Method */ +#define UA_NS0ID_GETREJECTEDLISTMETHODTYPE_OUTPUTARGUMENTS 12774 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_GETREJECTEDLIST 12775 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_GETREJECTEDLIST_OUTPUTARGUMENTS 12776 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_GETREJECTEDLIST 12777 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_GETREJECTEDLIST_OUTPUTARGUMENTS 12778 /* Variable */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSARRAYTYPE_SAMPLINGINTERVALDIAGNOSTICS 12779 /* Variable */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSARRAYTYPE_SAMPLINGINTERVALDIAGNOSTICS_SAMPLINGINTERVAL 12780 /* Variable */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSARRAYTYPE_SAMPLINGINTERVALDIAGNOSTICS_SAMPLEDMONITOREDITEMSCOUNT 12781 /* Variable */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSARRAYTYPE_SAMPLINGINTERVALDIAGNOSTICS_MAXSAMPLEDMONITOREDITEMSCOUNT 12782 /* Variable */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSARRAYTYPE_SAMPLINGINTERVALDIAGNOSTICS_DISABLEDMONITOREDITEMSSAMPLINGCOUNT 12783 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS 12784 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_SESSIONID 12785 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_SUBSCRIPTIONID 12786 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_PRIORITY 12787 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_PUBLISHINGINTERVAL 12788 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_MAXKEEPALIVECOUNT 12789 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_MAXLIFETIMECOUNT 12790 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_MAXNOTIFICATIONSPERPUBLISH 12791 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_PUBLISHINGENABLED 12792 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_MODIFYCOUNT 12793 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_ENABLECOUNT 12794 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_DISABLECOUNT 12795 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_REPUBLISHREQUESTCOUNT 12796 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_REPUBLISHMESSAGEREQUESTCOUNT 12797 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_REPUBLISHMESSAGECOUNT 12798 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_TRANSFERREQUESTCOUNT 12799 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_TRANSFERREDTOALTCLIENTCOUNT 12800 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_TRANSFERREDTOSAMECLIENTCOUNT 12801 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_PUBLISHREQUESTCOUNT 12802 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_DATACHANGENOTIFICATIONSCOUNT 12803 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_EVENTNOTIFICATIONSCOUNT 12804 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_NOTIFICATIONSCOUNT 12805 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_LATEPUBLISHREQUESTCOUNT 12806 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_CURRENTKEEPALIVECOUNT 12807 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_CURRENTLIFETIMECOUNT 12808 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_UNACKNOWLEDGEDMESSAGECOUNT 12809 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_DISCARDEDMESSAGECOUNT 12810 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_MONITOREDITEMCOUNT 12811 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_DISABLEDMONITOREDITEMCOUNT 12812 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_MONITORINGQUEUEOVERFLOWCOUNT 12813 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_NEXTSEQUENCENUMBER 12814 /* Variable */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSARRAYTYPE_SUBSCRIPTIONDIAGNOSTICS_EVENTQUEUEOVERFLOWCOUNT 12815 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS 12816 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_SESSIONID 12817 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_SESSIONNAME 12818 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_CLIENTDESCRIPTION 12819 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_SERVERURI 12820 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_ENDPOINTURL 12821 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_LOCALEIDS 12822 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_ACTUALSESSIONTIMEOUT 12823 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_MAXRESPONSEMESSAGESIZE 12824 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_CLIENTCONNECTIONTIME 12825 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_CLIENTLASTCONTACTTIME 12826 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_CURRENTSUBSCRIPTIONSCOUNT 12827 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_CURRENTMONITOREDITEMSCOUNT 12828 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_CURRENTPUBLISHREQUESTSINQUEUE 12829 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_TOTALREQUESTCOUNT 12830 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_UNAUTHORIZEDREQUESTCOUNT 12831 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_READCOUNT 12832 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_HISTORYREADCOUNT 12833 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_WRITECOUNT 12834 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_HISTORYUPDATECOUNT 12835 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_CALLCOUNT 12836 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_CREATEMONITOREDITEMSCOUNT 12837 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_MODIFYMONITOREDITEMSCOUNT 12838 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_SETMONITORINGMODECOUNT 12839 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_SETTRIGGERINGCOUNT 12840 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_DELETEMONITOREDITEMSCOUNT 12841 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_CREATESUBSCRIPTIONCOUNT 12842 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_MODIFYSUBSCRIPTIONCOUNT 12843 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_SETPUBLISHINGMODECOUNT 12844 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_PUBLISHCOUNT 12845 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_REPUBLISHCOUNT 12846 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_TRANSFERSUBSCRIPTIONSCOUNT 12847 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_DELETESUBSCRIPTIONSCOUNT 12848 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_ADDNODESCOUNT 12849 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_ADDREFERENCESCOUNT 12850 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_DELETENODESCOUNT 12851 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_DELETEREFERENCESCOUNT 12852 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_BROWSECOUNT 12853 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_BROWSENEXTCOUNT 12854 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_TRANSLATEBROWSEPATHSTONODEIDSCOUNT 12855 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_QUERYFIRSTCOUNT 12856 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_QUERYNEXTCOUNT 12857 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_REGISTERNODESCOUNT 12858 /* Variable */ +#define UA_NS0ID_SESSIONDIAGNOSTICSARRAYTYPE_SESSIONDIAGNOSTICS_UNREGISTERNODESCOUNT 12859 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSARRAYTYPE_SESSIONSECURITYDIAGNOSTICS 12860 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSARRAYTYPE_SESSIONSECURITYDIAGNOSTICS_SESSIONID 12861 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSARRAYTYPE_SESSIONSECURITYDIAGNOSTICS_CLIENTUSERIDOFSESSION 12862 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSARRAYTYPE_SESSIONSECURITYDIAGNOSTICS_CLIENTUSERIDHISTORY 12863 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSARRAYTYPE_SESSIONSECURITYDIAGNOSTICS_AUTHENTICATIONMECHANISM 12864 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSARRAYTYPE_SESSIONSECURITYDIAGNOSTICS_ENCODING 12865 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSARRAYTYPE_SESSIONSECURITYDIAGNOSTICS_TRANSPORTPROTOCOL 12866 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSARRAYTYPE_SESSIONSECURITYDIAGNOSTICS_SECURITYMODE 12867 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSARRAYTYPE_SESSIONSECURITYDIAGNOSTICS_SECURITYPOLICYURI 12868 /* Variable */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSARRAYTYPE_SESSIONSECURITYDIAGNOSTICS_CLIENTCERTIFICATE 12869 /* Variable */ +#define UA_NS0ID_SERVERTYPE_RESENDDATA 12871 /* Method */ +#define UA_NS0ID_SERVERTYPE_RESENDDATA_INPUTARGUMENTS 12872 /* Variable */ +#define UA_NS0ID_SERVER_RESENDDATA 12873 /* Method */ +#define UA_NS0ID_SERVER_RESENDDATA_INPUTARGUMENTS 12874 /* Variable */ +#define UA_NS0ID_RESENDDATAMETHODTYPE 12875 /* Method */ +#define UA_NS0ID_RESENDDATAMETHODTYPE_INPUTARGUMENTS 12876 /* Variable */ +#define UA_NS0ID_NORMALIZEDSTRING 12877 /* DataType */ +#define UA_NS0ID_DECIMALSTRING 12878 /* DataType */ +#define UA_NS0ID_DURATIONSTRING 12879 /* DataType */ +#define UA_NS0ID_TIMESTRING 12880 /* DataType */ +#define UA_NS0ID_DATESTRING 12881 /* DataType */ +#define UA_NS0ID_SERVERTYPE_ESTIMATEDRETURNTIME 12882 /* Variable */ +#define UA_NS0ID_SERVERTYPE_REQUESTSERVERSTATECHANGE 12883 /* Method */ +#define UA_NS0ID_SERVERTYPE_REQUESTSERVERSTATECHANGE_INPUTARGUMENTS 12884 /* Variable */ +#define UA_NS0ID_SERVER_ESTIMATEDRETURNTIME 12885 /* Variable */ +#define UA_NS0ID_SERVER_REQUESTSERVERSTATECHANGE 12886 /* Method */ +#define UA_NS0ID_SERVER_REQUESTSERVERSTATECHANGE_INPUTARGUMENTS 12887 /* Variable */ +#define UA_NS0ID_REQUESTSERVERSTATECHANGEMETHODTYPE 12888 /* Method */ +#define UA_NS0ID_REQUESTSERVERSTATECHANGEMETHODTYPE_INPUTARGUMENTS 12889 /* Variable */ +#define UA_NS0ID_DISCOVERYCONFIGURATION 12890 /* DataType */ +#define UA_NS0ID_MDNSDISCOVERYCONFIGURATION 12891 /* DataType */ +#define UA_NS0ID_DISCOVERYCONFIGURATION_ENCODING_DEFAULTXML 12892 /* Object */ +#define UA_NS0ID_MDNSDISCOVERYCONFIGURATION_ENCODING_DEFAULTXML 12893 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DISCOVERYCONFIGURATION 12894 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DISCOVERYCONFIGURATION_DATATYPEVERSION 12895 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DISCOVERYCONFIGURATION_DICTIONARYFRAGMENT 12896 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_MDNSDISCOVERYCONFIGURATION 12897 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_MDNSDISCOVERYCONFIGURATION_DATATYPEVERSION 12898 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_MDNSDISCOVERYCONFIGURATION_DICTIONARYFRAGMENT 12899 /* Variable */ +#define UA_NS0ID_DISCOVERYCONFIGURATION_ENCODING_DEFAULTBINARY 12900 /* Object */ +#define UA_NS0ID_MDNSDISCOVERYCONFIGURATION_ENCODING_DEFAULTBINARY 12901 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DISCOVERYCONFIGURATION 12902 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DISCOVERYCONFIGURATION_DATATYPEVERSION 12903 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DISCOVERYCONFIGURATION_DICTIONARYFRAGMENT 12904 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_MDNSDISCOVERYCONFIGURATION 12905 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_MDNSDISCOVERYCONFIGURATION_DATATYPEVERSION 12906 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_MDNSDISCOVERYCONFIGURATION_DICTIONARYFRAGMENT 12907 /* Variable */ +#define UA_NS0ID_MAXBYTESTRINGLENGTH 12908 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXBYTESTRINGLENGTH 12909 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXBYTESTRINGLENGTH 12910 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXBYTESTRINGLENGTH 12911 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_CONDITIONREFRESH2 12912 /* Method */ +#define UA_NS0ID_CONDITIONTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 12913 /* Variable */ +#define UA_NS0ID_CONDITIONREFRESH2METHODTYPE 12914 /* Method */ +#define UA_NS0ID_CONDITIONREFRESH2METHODTYPE_INPUTARGUMENTS 12915 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_CONDITIONREFRESH2 12916 /* Method */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 12917 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONDITIONREFRESH2 12918 /* Method */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 12919 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONDITIONREFRESH2 12984 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 12985 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONDITIONREFRESH2 12986 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 12987 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONDITIONREFRESH2 12988 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 12989 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONDITIONREFRESH2 12990 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 12991 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONDITIONREFRESH2 12992 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 12993 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONDITIONREFRESH2 12994 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 12995 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONDITIONREFRESH2 12996 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 12997 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONDITIONREFRESH2 12998 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 12999 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONREFRESH2 13000 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 13001 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONREFRESH2 13002 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 13003 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONDITIONREFRESH2 13004 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 13005 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONDITIONREFRESH2 13006 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 13007 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONDITIONREFRESH2 13008 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 13009 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONDITIONREFRESH2 13010 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 13011 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE 13225 /* ObjectType */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_EVENTID 13226 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_EVENTTYPE 13227 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SOURCENODE 13228 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SOURCENAME 13229 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_TIME 13230 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_RECEIVETIME 13231 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_LOCALTIME 13232 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_MESSAGE 13233 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SEVERITY 13234 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONDITIONCLASSID 13235 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONDITIONCLASSNAME 13236 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONDITIONNAME 13237 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_BRANCHID 13238 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_RETAIN 13239 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ENABLEDSTATE 13240 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ENABLEDSTATE_ID 13241 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ENABLEDSTATE_NAME 13242 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ENABLEDSTATE_NUMBER 13243 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 13244 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 13245 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 13246 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ENABLEDSTATE_TRUESTATE 13247 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ENABLEDSTATE_FALSESTATE 13248 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_QUALITY 13249 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_QUALITY_SOURCETIMESTAMP 13250 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_LASTSEVERITY 13251 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 13252 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_COMMENT 13253 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_COMMENT_SOURCETIMESTAMP 13254 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CLIENTUSERID 13255 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_DISABLE 13256 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ENABLE 13257 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ADDCOMMENT 13258 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 13259 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONDITIONREFRESH 13260 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 13261 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONDITIONREFRESH2 13262 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 13263 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACKEDSTATE 13264 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACKEDSTATE_ID 13265 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACKEDSTATE_NAME 13266 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACKEDSTATE_NUMBER 13267 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 13268 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACKEDSTATE_TRANSITIONTIME 13269 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 13270 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACKEDSTATE_TRUESTATE 13271 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACKEDSTATE_FALSESTATE 13272 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONFIRMEDSTATE 13273 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONFIRMEDSTATE_ID 13274 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONFIRMEDSTATE_NAME 13275 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONFIRMEDSTATE_NUMBER 13276 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 13277 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 13278 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 13279 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONFIRMEDSTATE_TRUESTATE 13280 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONFIRMEDSTATE_FALSESTATE 13281 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACKNOWLEDGE 13282 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 13283 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONFIRM 13284 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONFIRM_INPUTARGUMENTS 13285 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACTIVESTATE 13286 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACTIVESTATE_ID 13287 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACTIVESTATE_NAME 13288 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACTIVESTATE_NUMBER 13289 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 13290 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACTIVESTATE_TRANSITIONTIME 13291 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 13292 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACTIVESTATE_TRUESTATE 13293 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ACTIVESTATE_FALSESTATE 13294 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_INPUTNODE 13295 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESSEDSTATE 13296 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESSEDSTATE_ID 13297 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESSEDSTATE_NAME 13298 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESSEDSTATE_NUMBER 13299 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 13300 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 13301 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 13302 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 13303 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 13304 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE 13305 /* Object */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE 13306 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 13307 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 13308 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 13309 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 13310 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION 13311 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 13312 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 13313 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 13314 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 13315 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 13316 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_UNSHELVETIME 13317 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_UNSHELVE 13318 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 13319 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 13320 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 13321 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESSEDORSHELVED 13322 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_MAXTIMESHELVED 13323 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_NORMALSTATE 13324 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_EXPIRATIONDATE 13325 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CERTIFICATETYPE 13326 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CERTIFICATE 13327 /* Variable */ +#define UA_NS0ID_FILETYPE_MIMETYPE 13341 /* Variable */ +#define UA_NS0ID_CREATEDIRECTORYMETHODTYPE 13342 /* Method */ +#define UA_NS0ID_CREATEDIRECTORYMETHODTYPE_INPUTARGUMENTS 13343 /* Variable */ +#define UA_NS0ID_CREATEDIRECTORYMETHODTYPE_OUTPUTARGUMENTS 13344 /* Variable */ +#define UA_NS0ID_CREATEFILEMETHODTYPE 13345 /* Method */ +#define UA_NS0ID_CREATEFILEMETHODTYPE_INPUTARGUMENTS 13346 /* Variable */ +#define UA_NS0ID_CREATEFILEMETHODTYPE_OUTPUTARGUMENTS 13347 /* Variable */ +#define UA_NS0ID_DELETEFILEMETHODTYPE 13348 /* Method */ +#define UA_NS0ID_DELETEFILEMETHODTYPE_INPUTARGUMENTS 13349 /* Variable */ +#define UA_NS0ID_MOVEORCOPYMETHODTYPE 13350 /* Method */ +#define UA_NS0ID_MOVEORCOPYMETHODTYPE_INPUTARGUMENTS 13351 /* Variable */ +#define UA_NS0ID_MOVEORCOPYMETHODTYPE_OUTPUTARGUMENTS 13352 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE 13353 /* ObjectType */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILEDIRECTORYNAME_PLACEHOLDER 13354 /* Object */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILEDIRECTORYNAME_PLACEHOLDER_CREATEDIRECTORY 13355 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILEDIRECTORYNAME_PLACEHOLDER_CREATEDIRECTORY_INPUTARGUMENTS 13356 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILEDIRECTORYNAME_PLACEHOLDER_CREATEDIRECTORY_OUTPUTARGUMENTS 13357 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILEDIRECTORYNAME_PLACEHOLDER_CREATEFILE 13358 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILEDIRECTORYNAME_PLACEHOLDER_CREATEFILE_INPUTARGUMENTS 13359 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILEDIRECTORYNAME_PLACEHOLDER_CREATEFILE_OUTPUTARGUMENTS 13360 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILEDIRECTORYNAME_PLACEHOLDER_MOVEORCOPY 13363 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILEDIRECTORYNAME_PLACEHOLDER_MOVEORCOPY_INPUTARGUMENTS 13364 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILEDIRECTORYNAME_PLACEHOLDER_MOVEORCOPY_OUTPUTARGUMENTS 13365 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER 13366 /* Object */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_SIZE 13367 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_WRITABLE 13368 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_USERWRITABLE 13369 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_OPENCOUNT 13370 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_MIMETYPE 13371 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_OPEN 13372 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_OPEN_INPUTARGUMENTS 13373 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_OPEN_OUTPUTARGUMENTS 13374 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_CLOSE 13375 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_CLOSE_INPUTARGUMENTS 13376 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_READ 13377 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_READ_INPUTARGUMENTS 13378 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_READ_OUTPUTARGUMENTS 13379 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_WRITE 13380 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_WRITE_INPUTARGUMENTS 13381 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_GETPOSITION 13382 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_GETPOSITION_INPUTARGUMENTS 13383 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_GETPOSITION_OUTPUTARGUMENTS 13384 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_SETPOSITION 13385 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_SETPOSITION_INPUTARGUMENTS 13386 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_CREATEDIRECTORY 13387 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_CREATEDIRECTORY_INPUTARGUMENTS 13388 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_CREATEDIRECTORY_OUTPUTARGUMENTS 13389 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_CREATEFILE 13390 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_CREATEFILE_INPUTARGUMENTS 13391 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_CREATEFILE_OUTPUTARGUMENTS 13392 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_DELETEFILESYSTEMOBJECT 13393 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_DELETEFILESYSTEMOBJECT_INPUTARGUMENTS 13394 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_MOVEORCOPY 13395 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_MOVEORCOPY_INPUTARGUMENTS 13396 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_MOVEORCOPY_OUTPUTARGUMENTS 13397 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_MIMETYPE 13398 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_MIMETYPE 13399 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_MIMETYPE 13400 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_MIMETYPE 13403 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST 13599 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_SIZE 13600 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_WRITABLE 13601 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_USERWRITABLE 13602 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_OPENCOUNT 13603 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_MIMETYPE 13604 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_OPEN 13605 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_OPEN_INPUTARGUMENTS 13606 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_OPEN_OUTPUTARGUMENTS 13607 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_CLOSE 13608 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_CLOSE_INPUTARGUMENTS 13609 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_READ 13610 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_READ_INPUTARGUMENTS 13611 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_READ_OUTPUTARGUMENTS 13612 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_WRITE 13613 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_WRITE_INPUTARGUMENTS 13614 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_GETPOSITION 13615 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 13616 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 13617 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_SETPOSITION 13618 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 13619 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_LASTUPDATETIME 13620 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_OPENWITHMASKS 13621 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 13622 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 13623 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_CLOSEANDUPDATE 13624 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 13625 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 13626 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_ADDCERTIFICATE 13627 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 13628 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_REMOVECERTIFICATE 13629 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 13630 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATETYPES 13631 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_CERTIFICATEGROUP 13735 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_CERTIFICATETYPE 13736 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_UPDATECERTIFICATE 13737 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_UPDATECERTIFICATE_INPUTARGUMENTS 13738 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_UPDATECERTIFICATE_OUTPUTARGUMENTS 13739 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE 13813 /* ObjectType */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP 13814 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST 13815 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SIZE 13816 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITABLE 13817 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_USERWRITABLE 13818 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENCOUNT 13819 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_MIMETYPE 13820 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN 13821 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 13822 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 13823 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSE 13824 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 13825 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ 13826 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ_INPUTARGUMENTS 13827 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 13828 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITE 13829 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 13830 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION 13831 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 13832 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 13833 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SETPOSITION 13834 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 13835 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_LASTUPDATETIME 13836 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS 13837 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 13838 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 13839 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE 13840 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 13841 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 13842 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ADDCERTIFICATE 13843 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 13844 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_REMOVECERTIFICATE 13845 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 13846 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATETYPES 13847 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP 13848 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST 13849 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_SIZE 13850 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_WRITABLE 13851 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_USERWRITABLE 13852 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_OPENCOUNT 13853 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_MIMETYPE 13854 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN 13855 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 13856 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 13857 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSE 13858 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 13859 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_READ 13860 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_READ_INPUTARGUMENTS 13861 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 13862 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_WRITE 13863 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 13864 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION 13865 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 13866 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 13867 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_SETPOSITION 13868 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 13869 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_LASTUPDATETIME 13870 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS 13871 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 13872 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 13873 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE 13874 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 13875 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 13876 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_ADDCERTIFICATE 13877 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 13878 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_REMOVECERTIFICATE 13879 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 13880 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATETYPES 13881 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP 13882 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST 13883 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_SIZE 13884 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITABLE 13885 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_USERWRITABLE 13886 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENCOUNT 13887 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_MIMETYPE 13888 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN 13889 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 13890 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 13891 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSE 13892 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 13893 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ 13894 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ_INPUTARGUMENTS 13895 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 13896 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITE 13897 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 13898 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION 13899 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 13900 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 13901 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_SETPOSITION 13902 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 13903 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_LASTUPDATETIME 13904 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS 13905 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 13906 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 13907 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE 13908 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 13909 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 13910 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_ADDCERTIFICATE 13911 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 13912 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_REMOVECERTIFICATE 13913 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 13914 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATETYPES 13915 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER 13916 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST 13917 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_SIZE 13918 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_WRITABLE 13919 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_USERWRITABLE 13920 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_OPENCOUNT 13921 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_MIMETYPE 13922 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_OPEN 13923 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_OPEN_INPUTARGUMENTS 13924 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_OPEN_OUTPUTARGUMENTS 13925 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_CLOSE 13926 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_CLOSE_INPUTARGUMENTS 13927 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_READ 13928 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_READ_INPUTARGUMENTS 13929 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_READ_OUTPUTARGUMENTS 13930 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_WRITE 13931 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_WRITE_INPUTARGUMENTS 13932 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_GETPOSITION 13933 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 13934 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 13935 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_SETPOSITION 13936 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 13937 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_LASTUPDATETIME 13938 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_OPENWITHMASKS 13939 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 13940 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 13941 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_CLOSEANDUPDATE 13942 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 13943 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 13944 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_ADDCERTIFICATE 13945 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 13946 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_REMOVECERTIFICATE 13947 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 13948 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATETYPES 13949 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS 13950 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP 13951 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST 13952 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SIZE 13953 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITABLE 13954 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_USERWRITABLE 13955 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENCOUNT 13956 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_MIMETYPE 13957 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN 13958 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 13959 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 13960 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSE 13961 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 13962 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ 13963 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ_INPUTARGUMENTS 13964 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 13965 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITE 13966 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 13967 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION 13968 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 13969 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 13970 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SETPOSITION 13971 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 13972 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_LASTUPDATETIME 13973 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS 13974 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 13975 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 13976 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE 13977 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 13978 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 13979 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ADDCERTIFICATE 13980 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 13981 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_REMOVECERTIFICATE 13982 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 13983 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATETYPES 13984 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP 13985 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST 13986 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SIZE 13987 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITABLE 13988 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_USERWRITABLE 13989 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENCOUNT 13990 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_MIMETYPE 13991 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN 13992 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 13993 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 13994 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSE 13995 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 13996 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ 13997 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ_INPUTARGUMENTS 13998 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 13999 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITE 14000 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 14001 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION 14002 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 14003 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 14004 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SETPOSITION 14005 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 14006 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_LASTUPDATETIME 14007 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS 14008 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 14009 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 14010 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE 14011 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 14012 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 14013 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ADDCERTIFICATE 14014 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 14015 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_REMOVECERTIFICATE 14016 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 14017 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATETYPES 14018 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP 14019 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST 14020 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SIZE 14021 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITABLE 14022 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_USERWRITABLE 14023 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENCOUNT 14024 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_MIMETYPE 14025 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN 14026 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 14027 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 14028 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSE 14029 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 14030 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ 14031 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ_INPUTARGUMENTS 14032 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 14033 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITE 14034 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 14035 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION 14036 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 14037 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 14038 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SETPOSITION 14039 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 14040 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_LASTUPDATETIME 14041 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS 14042 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 14043 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 14044 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE 14045 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 14046 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 14047 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ADDCERTIFICATE 14048 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 14049 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_REMOVECERTIFICATE 14050 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 14051 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATETYPES 14052 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS 14053 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP 14088 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST 14089 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SIZE 14090 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITABLE 14091 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_USERWRITABLE 14092 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENCOUNT 14093 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_MIMETYPE 14094 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN 14095 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 14096 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 14097 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSE 14098 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 14099 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ 14100 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ_INPUTARGUMENTS 14101 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 14102 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITE 14103 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 14104 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION 14105 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 14106 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 14107 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SETPOSITION 14108 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 14109 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_LASTUPDATETIME 14110 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS 14111 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 14112 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 14113 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE 14114 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 14115 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 14116 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ADDCERTIFICATE 14117 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 14118 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_REMOVECERTIFICATE 14119 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 14120 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATETYPES 14121 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP 14122 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST 14123 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SIZE 14124 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITABLE 14125 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_USERWRITABLE 14126 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENCOUNT 14127 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_MIMETYPE 14128 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN 14129 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 14130 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 14131 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSE 14132 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 14133 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ 14134 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ_INPUTARGUMENTS 14135 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 14136 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITE 14137 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 14138 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION 14139 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 14140 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 14141 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SETPOSITION 14142 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 14143 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_LASTUPDATETIME 14144 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS 14145 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 14146 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 14147 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE 14148 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 14149 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 14150 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ADDCERTIFICATE 14151 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 14152 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_REMOVECERTIFICATE 14153 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 14154 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATETYPES 14155 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP 14156 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITABLE 14157 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_USERWRITABLE 14158 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_MIMETYPE 14159 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 14160 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATETYPES 14161 /* Variable */ +#define UA_NS0ID_REMOVECONNECTIONMETHODTYPE 14183 /* Method */ +#define UA_NS0ID_REMOVECONNECTIONMETHODTYPE_INPUTARGUMENTS 14184 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE 14209 /* ObjectType */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDRESS 14221 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_REMOVEGROUP 14225 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_REMOVEGROUP_INPUTARGUMENTS 14226 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPE 14232 /* ObjectType */ +#define UA_NS0ID_PUBLISHEDVARIABLEDATATYPE 14273 /* DataType */ +#define UA_NS0ID_PUBLISHEDVARIABLEDATATYPE_ENCODING_DEFAULTXML 14319 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDVARIABLEDATATYPE 14320 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDVARIABLEDATATYPE_DATATYPEVERSION 14321 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDVARIABLEDATATYPE_DICTIONARYFRAGMENT 14322 /* Variable */ +#define UA_NS0ID_PUBLISHEDVARIABLEDATATYPE_ENCODING_DEFAULTBINARY 14323 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDVARIABLEDATATYPE 14324 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDVARIABLEDATATYPE_DATATYPEVERSION 14325 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDVARIABLEDATATYPE_DICTIONARYFRAGMENT 14326 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_SESSIONID 14413 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_SESSIONID 14414 /* Variable */ +#define UA_NS0ID_SERVER_SERVERREDUNDANCY_SERVERNETWORKGROUPS 14415 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE 14416 /* ObjectType */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER 14417 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_PUBLISHERID 14418 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_STATUS 14419 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_STATUS_STATE 14420 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_STATUS_ENABLE 14421 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_STATUS_DISABLE 14422 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_ADDRESS 14423 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_REMOVEGROUP 14424 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_REMOVEGROUP_INPUTARGUMENTS 14425 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_REMOVECONNECTION 14432 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_REMOVECONNECTION_INPUTARGUMENTS 14433 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS 14434 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMS 14435 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMS_INPUTARGUMENTS 14436 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMS_OUTPUTARGUMENTS 14437 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTS 14438 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTS_INPUTARGUMENTS 14439 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTS_OUTPUTARGUMENTS 14440 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_REMOVEPUBLISHEDDATASET 14441 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_REMOVEPUBLISHEDDATASET_INPUTARGUMENTS 14442 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE 14443 /* Object */ +#define UA_NS0ID_HASPUBSUBCONNECTION 14476 /* ReferenceType */ +#define UA_NS0ID_DATASETFOLDERTYPE 14477 /* ObjectType */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER 14478 /* Object */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDPUBLISHEDDATAITEMS 14479 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDPUBLISHEDDATAITEMS_INPUTARGUMENTS 14480 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDPUBLISHEDDATAITEMS_OUTPUTARGUMENTS 14481 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDPUBLISHEDEVENTS 14482 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDPUBLISHEDEVENTS_INPUTARGUMENTS 14483 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDPUBLISHEDEVENTS_OUTPUTARGUMENTS 14484 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_REMOVEPUBLISHEDDATASET 14485 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_REMOVEPUBLISHEDDATASET_INPUTARGUMENTS 14486 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_PUBLISHEDDATASETNAME_PLACEHOLDER 14487 /* Object */ +#define UA_NS0ID_DATASETFOLDERTYPE_PUBLISHEDDATASETNAME_PLACEHOLDER_CONFIGURATIONVERSION 14489 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMS 14493 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMS_INPUTARGUMENTS 14494 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMS_OUTPUTARGUMENTS 14495 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDEVENTS 14496 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDEVENTS_INPUTARGUMENTS 14497 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDEVENTS_OUTPUTARGUMENTS 14498 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_REMOVEPUBLISHEDDATASET 14499 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_REMOVEPUBLISHEDDATASET_INPUTARGUMENTS 14500 /* Variable */ +#define UA_NS0ID_ADDPUBLISHEDDATAITEMSMETHODTYPE 14501 /* Method */ +#define UA_NS0ID_ADDPUBLISHEDDATAITEMSMETHODTYPE_INPUTARGUMENTS 14502 /* Variable */ +#define UA_NS0ID_ADDPUBLISHEDDATAITEMSMETHODTYPE_OUTPUTARGUMENTS 14503 /* Variable */ +#define UA_NS0ID_ADDPUBLISHEDEVENTSMETHODTYPE 14504 /* Method */ +#define UA_NS0ID_ADDPUBLISHEDEVENTSMETHODTYPE_INPUTARGUMENTS 14505 /* Variable */ +#define UA_NS0ID_ADDPUBLISHEDEVENTSMETHODTYPE_OUTPUTARGUMENTS 14506 /* Variable */ +#define UA_NS0ID_REMOVEPUBLISHEDDATASETMETHODTYPE 14507 /* Method */ +#define UA_NS0ID_REMOVEPUBLISHEDDATASETMETHODTYPE_INPUTARGUMENTS 14508 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE 14509 /* ObjectType */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_CONFIGURATIONVERSION 14519 /* Variable */ +#define UA_NS0ID_DATASETMETADATATYPE 14523 /* DataType */ +#define UA_NS0ID_FIELDMETADATA 14524 /* DataType */ +#define UA_NS0ID_DATATYPEDESCRIPTION 14525 /* DataType */ +#define UA_NS0ID_STRUCTURETYPE_ENUMSTRINGS 14528 /* Variable */ +#define UA_NS0ID_KEYVALUEPAIR 14533 /* DataType */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE 14534 /* ObjectType */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_CONFIGURATIONVERSION 14544 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_PUBLISHEDDATA 14548 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_ADDVARIABLES 14555 /* Method */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_ADDVARIABLES_INPUTARGUMENTS 14556 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_ADDVARIABLES_OUTPUTARGUMENTS 14557 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_REMOVEVARIABLES 14558 /* Method */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_REMOVEVARIABLES_INPUTARGUMENTS 14559 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_REMOVEVARIABLES_OUTPUTARGUMENTS 14560 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSADDVARIABLESMETHODTYPE 14564 /* Method */ +#define UA_NS0ID_PUBLISHEDDATAITEMSADDVARIABLESMETHODTYPE_INPUTARGUMENTS 14565 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSADDVARIABLESMETHODTYPE_OUTPUTARGUMENTS 14566 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSREMOVEVARIABLESMETHODTYPE 14567 /* Method */ +#define UA_NS0ID_PUBLISHEDDATAITEMSREMOVEVARIABLESMETHODTYPE_INPUTARGUMENTS 14568 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSREMOVEVARIABLESMETHODTYPE_OUTPUTARGUMENTS 14569 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE 14572 /* ObjectType */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_CONFIGURATIONVERSION 14582 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_PUBSUBEVENTNOTIFIER 14586 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_SELECTEDFIELDS 14587 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_FILTER 14588 /* Variable */ +#define UA_NS0ID_CONFIGURATIONVERSIONDATATYPE 14593 /* DataType */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_PUBLISHERID 14595 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_STATUS 14600 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_STATUS_STATE 14601 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_STATUS_ENABLE 14602 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_STATUS_DISABLE 14603 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPEREMOVEGROUPMETHODTYPE 14604 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPEREMOVEGROUPMETHODTYPE_INPUTARGUMENTS 14605 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPEREMOVEWRITERMETHODTYPE 14623 /* Method */ +#define UA_NS0ID_PUBSUBGROUPTYPEREMOVEWRITERMETHODTYPE_INPUTARGUMENTS 14624 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPEREMOVEREADERMETHODTYPE 14625 /* Method */ +#define UA_NS0ID_PUBSUBGROUPTYPEREMOVEREADERMETHODTYPE_INPUTARGUMENTS 14626 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSTYPE 14643 /* ObjectType */ +#define UA_NS0ID_PUBSUBSTATUSTYPE_STATE 14644 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSTYPE_ENABLE 14645 /* Method */ +#define UA_NS0ID_PUBSUBSTATUSTYPE_DISABLE 14646 /* Method */ +#define UA_NS0ID_PUBSUBSTATE 14647 /* DataType */ +#define UA_NS0ID_PUBSUBSTATE_ENUMSTRINGS 14648 /* Variable */ +#define UA_NS0ID_FIELDTARGETDATATYPE 14744 /* DataType */ +#define UA_NS0ID_DATASETMETADATATYPE_ENCODING_DEFAULTXML 14794 /* Object */ +#define UA_NS0ID_FIELDMETADATA_ENCODING_DEFAULTXML 14795 /* Object */ +#define UA_NS0ID_DATATYPEDESCRIPTION_ENCODING_DEFAULTXML 14796 /* Object */ +#define UA_NS0ID_DATATYPEDEFINITION_ENCODING_DEFAULTXML 14797 /* Object */ +#define UA_NS0ID_STRUCTUREDEFINITION_ENCODING_DEFAULTXML 14798 /* Object */ +#define UA_NS0ID_ENUMDEFINITION_ENCODING_DEFAULTXML 14799 /* Object */ +#define UA_NS0ID_STRUCTUREFIELD_ENCODING_DEFAULTXML 14800 /* Object */ +#define UA_NS0ID_ENUMFIELD_ENCODING_DEFAULTXML 14801 /* Object */ +#define UA_NS0ID_KEYVALUEPAIR_ENCODING_DEFAULTXML 14802 /* Object */ +#define UA_NS0ID_CONFIGURATIONVERSIONDATATYPE_ENCODING_DEFAULTXML 14803 /* Object */ +#define UA_NS0ID_FIELDTARGETDATATYPE_ENCODING_DEFAULTXML 14804 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETMETADATATYPE 14805 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETMETADATATYPE_DATATYPEVERSION 14806 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETMETADATATYPE_DICTIONARYFRAGMENT 14807 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_FIELDMETADATA 14808 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_FIELDMETADATA_DATATYPEVERSION 14809 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_FIELDMETADATA_DICTIONARYFRAGMENT 14810 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATATYPEDESCRIPTION 14811 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATATYPEDESCRIPTION_DATATYPEVERSION 14812 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATATYPEDESCRIPTION_DICTIONARYFRAGMENT 14813 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENUMFIELD 14826 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENUMFIELD_DATATYPEVERSION 14827 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENUMFIELD_DICTIONARYFRAGMENT 14828 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_KEYVALUEPAIR 14829 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_KEYVALUEPAIR_DATATYPEVERSION 14830 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_KEYVALUEPAIR_DICTIONARYFRAGMENT 14831 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CONFIGURATIONVERSIONDATATYPE 14832 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CONFIGURATIONVERSIONDATATYPE_DATATYPEVERSION 14833 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CONFIGURATIONVERSIONDATATYPE_DICTIONARYFRAGMENT 14834 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_FIELDTARGETDATATYPE 14835 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_FIELDTARGETDATATYPE_DATATYPEVERSION 14836 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_FIELDTARGETDATATYPE_DICTIONARYFRAGMENT 14837 /* Variable */ +#define UA_NS0ID_FIELDMETADATA_ENCODING_DEFAULTBINARY 14839 /* Object */ +#define UA_NS0ID_STRUCTUREFIELD_ENCODING_DEFAULTBINARY 14844 /* Object */ +#define UA_NS0ID_ENUMFIELD_ENCODING_DEFAULTBINARY 14845 /* Object */ +#define UA_NS0ID_KEYVALUEPAIR_ENCODING_DEFAULTBINARY 14846 /* Object */ +#define UA_NS0ID_CONFIGURATIONVERSIONDATATYPE_ENCODING_DEFAULTBINARY 14847 /* Object */ +#define UA_NS0ID_FIELDTARGETDATATYPE_ENCODING_DEFAULTBINARY 14848 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETMETADATATYPE 14849 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETMETADATATYPE_DATATYPEVERSION 14850 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETMETADATATYPE_DICTIONARYFRAGMENT 14851 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_FIELDMETADATA 14852 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_FIELDMETADATA_DATATYPEVERSION 14853 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_FIELDMETADATA_DICTIONARYFRAGMENT 14854 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATATYPEDESCRIPTION 14855 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATATYPEDESCRIPTION_DATATYPEVERSION 14856 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATATYPEDESCRIPTION_DICTIONARYFRAGMENT 14857 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENUMFIELD 14870 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENUMFIELD_DATATYPEVERSION 14871 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENUMFIELD_DICTIONARYFRAGMENT 14872 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_KEYVALUEPAIR 14873 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_KEYVALUEPAIR_DATATYPEVERSION 14874 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_KEYVALUEPAIR_DICTIONARYFRAGMENT 14875 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CONFIGURATIONVERSIONDATATYPE 14876 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CONFIGURATIONVERSIONDATATYPE_DATATYPEVERSION 14877 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CONFIGURATIONVERSIONDATATYPE_DICTIONARYFRAGMENT 14878 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_FIELDTARGETDATATYPE_DATATYPEVERSION 14880 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_FIELDTARGETDATATYPE_DICTIONARYFRAGMENT 14881 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_EXPIRATIONLIMIT 14900 /* Variable */ +#define UA_NS0ID_DATASETTOWRITER 14936 /* ReferenceType */ +#define UA_NS0ID_DATATYPEDICTIONARYTYPE_DEPRECATED 15001 /* Variable */ +#define UA_NS0ID_MAXCHARACTERS 15002 /* Variable */ +#define UA_NS0ID_SERVERTYPE_URISVERSION 15003 /* Variable */ +#define UA_NS0ID_SERVER_URISVERSION 15004 /* Variable */ +#define UA_NS0ID_SIMPLETYPEDESCRIPTION 15005 /* DataType */ +#define UA_NS0ID_UABINARYFILEDATATYPE 15006 /* DataType */ +#define UA_NS0ID_BROKERCONNECTIONTRANSPORTDATATYPE 15007 /* DataType */ +#define UA_NS0ID_BROKERTRANSPORTQUALITYOFSERVICE 15008 /* DataType */ +#define UA_NS0ID_BROKERTRANSPORTQUALITYOFSERVICE_ENUMSTRINGS 15009 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPNAME_PLACEHOLDER_KEYLIFETIME 15010 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPNAME_PLACEHOLDER_SECURITYPOLICYURI 15011 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPNAME_PLACEHOLDER_MAXFUTUREKEYCOUNT 15012 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE 15013 /* ObjectType */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_EVENTID 15014 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_EVENTTYPE 15015 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_SOURCENODE 15016 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_SOURCENAME 15017 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_TIME 15018 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_RECEIVETIME 15019 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_LOCALTIME 15020 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_MESSAGE 15021 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_SEVERITY 15022 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_ACTIONTIMESTAMP 15023 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_STATUS 15024 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_SERVERID 15025 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_CLIENTAUDITENTRYID 15026 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_CLIENTUSERID 15027 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_METHODID 15028 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_INPUTARGUMENTS 15029 /* Variable */ +#define UA_NS0ID_PERMISSIONTYPE_OPTIONSETVALUES 15030 /* Variable */ +#define UA_NS0ID_ACCESSLEVELTYPE 15031 /* DataType */ +#define UA_NS0ID_ACCESSLEVELTYPE_OPTIONSETVALUES 15032 /* Variable */ +#define UA_NS0ID_EVENTNOTIFIERTYPE 15033 /* DataType */ +#define UA_NS0ID_EVENTNOTIFIERTYPE_OPTIONSETVALUES 15034 /* Variable */ +#define UA_NS0ID_ACCESSRESTRICTIONTYPE_OPTIONSETVALUES 15035 /* Variable */ +#define UA_NS0ID_ATTRIBUTEWRITEMASK_OPTIONSETVALUES 15036 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DEPRECATED 15037 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC_LASTMETHODINPUTVALUES 15038 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DEPRECATED 15039 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_PROGRAMDIAGNOSTIC_LASTMETHODOUTPUTVALUES 15040 /* Variable */ +#define UA_NS0ID_KEYVALUEPAIR_ENCODING_DEFAULTJSON 15041 /* Object */ +#define UA_NS0ID_IDENTITYMAPPINGRULETYPE_ENCODING_DEFAULTJSON 15042 /* Object */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPNAME_PLACEHOLDER_MAXPASTKEYCOUNT 15043 /* Variable */ +#define UA_NS0ID_TRUSTLISTDATATYPE_ENCODING_DEFAULTJSON 15044 /* Object */ +#define UA_NS0ID_DECIMALDATATYPE_ENCODING_DEFAULTJSON 15045 /* Object */ +#define UA_NS0ID_SECURITYGROUPTYPE_KEYLIFETIME 15046 /* Variable */ +#define UA_NS0ID_SECURITYGROUPTYPE_SECURITYPOLICYURI 15047 /* Variable */ +#define UA_NS0ID_SECURITYGROUPTYPE_MAXFUTUREKEYCOUNT 15048 /* Variable */ +#define UA_NS0ID_CONFIGURATIONVERSIONDATATYPE_ENCODING_DEFAULTJSON 15049 /* Object */ +#define UA_NS0ID_DATASETMETADATATYPE_ENCODING_DEFAULTJSON 15050 /* Object */ +#define UA_NS0ID_FIELDMETADATA_ENCODING_DEFAULTJSON 15051 /* Object */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_MODIFYFIELDSELECTION 15052 /* Method */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_MODIFYFIELDSELECTION_INPUTARGUMENTS 15053 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPEMODIFYFIELDSELECTIONMETHODTYPE 15054 /* Method */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPEMODIFYFIELDSELECTIONMETHODTYPE_INPUTARGUMENTS 15055 /* Variable */ +#define UA_NS0ID_SECURITYGROUPTYPE_MAXPASTKEYCOUNT 15056 /* Variable */ +#define UA_NS0ID_DATATYPEDESCRIPTION_ENCODING_DEFAULTJSON 15057 /* Object */ +#define UA_NS0ID_STRUCTUREDESCRIPTION_ENCODING_DEFAULTJSON 15058 /* Object */ +#define UA_NS0ID_ENUMDESCRIPTION_ENCODING_DEFAULTJSON 15059 /* Object */ +#define UA_NS0ID_PUBLISHEDVARIABLEDATATYPE_ENCODING_DEFAULTJSON 15060 /* Object */ +#define UA_NS0ID_FIELDTARGETDATATYPE_ENCODING_DEFAULTJSON 15061 /* Object */ +#define UA_NS0ID_ROLEPERMISSIONTYPE_ENCODING_DEFAULTJSON 15062 /* Object */ +#define UA_NS0ID_DATATYPEDEFINITION_ENCODING_DEFAULTJSON 15063 /* Object */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTTYPE 15064 /* ObjectType */ +#define UA_NS0ID_STRUCTUREFIELD_ENCODING_DEFAULTJSON 15065 /* Object */ +#define UA_NS0ID_STRUCTUREDEFINITION_ENCODING_DEFAULTJSON 15066 /* Object */ +#define UA_NS0ID_ENUMDEFINITION_ENCODING_DEFAULTJSON 15067 /* Object */ +#define UA_NS0ID_NODE_ENCODING_DEFAULTJSON 15068 /* Object */ +#define UA_NS0ID_INSTANCENODE_ENCODING_DEFAULTJSON 15069 /* Object */ +#define UA_NS0ID_TYPENODE_ENCODING_DEFAULTJSON 15070 /* Object */ +#define UA_NS0ID_OBJECTNODE_ENCODING_DEFAULTJSON 15071 /* Object */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTTYPE_DISCOVERYADDRESS 15072 /* Object */ +#define UA_NS0ID_OBJECTTYPENODE_ENCODING_DEFAULTJSON 15073 /* Object */ +#define UA_NS0ID_VARIABLENODE_ENCODING_DEFAULTJSON 15074 /* Object */ +#define UA_NS0ID_VARIABLETYPENODE_ENCODING_DEFAULTJSON 15075 /* Object */ +#define UA_NS0ID_REFERENCETYPENODE_ENCODING_DEFAULTJSON 15076 /* Object */ +#define UA_NS0ID_METHODNODE_ENCODING_DEFAULTJSON 15077 /* Object */ +#define UA_NS0ID_VIEWNODE_ENCODING_DEFAULTJSON 15078 /* Object */ +#define UA_NS0ID_DATATYPENODE_ENCODING_DEFAULTJSON 15079 /* Object */ +#define UA_NS0ID_REFERENCENODE_ENCODING_DEFAULTJSON 15080 /* Object */ +#define UA_NS0ID_ARGUMENT_ENCODING_DEFAULTJSON 15081 /* Object */ +#define UA_NS0ID_ENUMVALUETYPE_ENCODING_DEFAULTJSON 15082 /* Object */ +#define UA_NS0ID_ENUMFIELD_ENCODING_DEFAULTJSON 15083 /* Object */ +#define UA_NS0ID_OPTIONSET_ENCODING_DEFAULTJSON 15084 /* Object */ +#define UA_NS0ID_UNION_ENCODING_DEFAULTJSON 15085 /* Object */ +#define UA_NS0ID_TIMEZONEDATATYPE_ENCODING_DEFAULTJSON 15086 /* Object */ +#define UA_NS0ID_APPLICATIONDESCRIPTION_ENCODING_DEFAULTJSON 15087 /* Object */ +#define UA_NS0ID_REQUESTHEADER_ENCODING_DEFAULTJSON 15088 /* Object */ +#define UA_NS0ID_RESPONSEHEADER_ENCODING_DEFAULTJSON 15089 /* Object */ +#define UA_NS0ID_SERVICEFAULT_ENCODING_DEFAULTJSON 15090 /* Object */ +#define UA_NS0ID_SESSIONLESSINVOKEREQUESTTYPE_ENCODING_DEFAULTJSON 15091 /* Object */ +#define UA_NS0ID_SESSIONLESSINVOKERESPONSETYPE_ENCODING_DEFAULTJSON 15092 /* Object */ +#define UA_NS0ID_FINDSERVERSREQUEST_ENCODING_DEFAULTJSON 15093 /* Object */ +#define UA_NS0ID_FINDSERVERSRESPONSE_ENCODING_DEFAULTJSON 15094 /* Object */ +#define UA_NS0ID_SERVERONNETWORK_ENCODING_DEFAULTJSON 15095 /* Object */ +#define UA_NS0ID_FINDSERVERSONNETWORKREQUEST_ENCODING_DEFAULTJSON 15096 /* Object */ +#define UA_NS0ID_FINDSERVERSONNETWORKRESPONSE_ENCODING_DEFAULTJSON 15097 /* Object */ +#define UA_NS0ID_USERTOKENPOLICY_ENCODING_DEFAULTJSON 15098 /* Object */ +#define UA_NS0ID_ENDPOINTDESCRIPTION_ENCODING_DEFAULTJSON 15099 /* Object */ +#define UA_NS0ID_GETENDPOINTSREQUEST_ENCODING_DEFAULTJSON 15100 /* Object */ +#define UA_NS0ID_GETENDPOINTSRESPONSE_ENCODING_DEFAULTJSON 15101 /* Object */ +#define UA_NS0ID_REGISTEREDSERVER_ENCODING_DEFAULTJSON 15102 /* Object */ +#define UA_NS0ID_REGISTERSERVERREQUEST_ENCODING_DEFAULTJSON 15103 /* Object */ +#define UA_NS0ID_REGISTERSERVERRESPONSE_ENCODING_DEFAULTJSON 15104 /* Object */ +#define UA_NS0ID_DISCOVERYCONFIGURATION_ENCODING_DEFAULTJSON 15105 /* Object */ +#define UA_NS0ID_MDNSDISCOVERYCONFIGURATION_ENCODING_DEFAULTJSON 15106 /* Object */ +#define UA_NS0ID_REGISTERSERVER2REQUEST_ENCODING_DEFAULTJSON 15107 /* Object */ +#define UA_NS0ID_SUBSCRIBEDDATASETTYPE 15108 /* ObjectType */ +#define UA_NS0ID_CHOICESTATETYPE 15109 /* ObjectType */ +#define UA_NS0ID_CHOICESTATETYPE_STATENUMBER 15110 /* Variable */ +#define UA_NS0ID_TARGETVARIABLESTYPE 15111 /* ObjectType */ +#define UA_NS0ID_HASGUARD 15112 /* ReferenceType */ +#define UA_NS0ID_GUARDVARIABLETYPE 15113 /* VariableType */ +#define UA_NS0ID_TARGETVARIABLESTYPE_TARGETVARIABLES 15114 /* Variable */ +#define UA_NS0ID_TARGETVARIABLESTYPE_ADDTARGETVARIABLES 15115 /* Method */ +#define UA_NS0ID_TARGETVARIABLESTYPE_ADDTARGETVARIABLES_INPUTARGUMENTS 15116 /* Variable */ +#define UA_NS0ID_TARGETVARIABLESTYPE_ADDTARGETVARIABLES_OUTPUTARGUMENTS 15117 /* Variable */ +#define UA_NS0ID_TARGETVARIABLESTYPE_REMOVETARGETVARIABLES 15118 /* Method */ +#define UA_NS0ID_TARGETVARIABLESTYPE_REMOVETARGETVARIABLES_INPUTARGUMENTS 15119 /* Variable */ +#define UA_NS0ID_TARGETVARIABLESTYPE_REMOVETARGETVARIABLES_OUTPUTARGUMENTS 15120 /* Variable */ +#define UA_NS0ID_TARGETVARIABLESTYPEADDTARGETVARIABLESMETHODTYPE 15121 /* Method */ +#define UA_NS0ID_TARGETVARIABLESTYPEADDTARGETVARIABLESMETHODTYPE_INPUTARGUMENTS 15122 /* Variable */ +#define UA_NS0ID_TARGETVARIABLESTYPEADDTARGETVARIABLESMETHODTYPE_OUTPUTARGUMENTS 15123 /* Variable */ +#define UA_NS0ID_TARGETVARIABLESTYPEREMOVETARGETVARIABLESMETHODTYPE 15124 /* Method */ +#define UA_NS0ID_TARGETVARIABLESTYPEREMOVETARGETVARIABLESMETHODTYPE_INPUTARGUMENTS 15125 /* Variable */ +#define UA_NS0ID_TARGETVARIABLESTYPEREMOVETARGETVARIABLESMETHODTYPE_OUTPUTARGUMENTS 15126 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETMIRRORTYPE 15127 /* ObjectType */ +#define UA_NS0ID_EXPRESSIONGUARDVARIABLETYPE 15128 /* VariableType */ +#define UA_NS0ID_EXPRESSIONGUARDVARIABLETYPE_EXPRESSION 15129 /* Variable */ +#define UA_NS0ID_REGISTERSERVER2RESPONSE_ENCODING_DEFAULTJSON 15130 /* Object */ +#define UA_NS0ID_CHANNELSECURITYTOKEN_ENCODING_DEFAULTJSON 15131 /* Object */ +#define UA_NS0ID_OPENSECURECHANNELREQUEST_ENCODING_DEFAULTJSON 15132 /* Object */ +#define UA_NS0ID_OPENSECURECHANNELRESPONSE_ENCODING_DEFAULTJSON 15133 /* Object */ +#define UA_NS0ID_CLOSESECURECHANNELREQUEST_ENCODING_DEFAULTJSON 15134 /* Object */ +#define UA_NS0ID_CLOSESECURECHANNELRESPONSE_ENCODING_DEFAULTJSON 15135 /* Object */ +#define UA_NS0ID_SIGNEDSOFTWARECERTIFICATE_ENCODING_DEFAULTJSON 15136 /* Object */ +#define UA_NS0ID_SIGNATUREDATA_ENCODING_DEFAULTJSON 15137 /* Object */ +#define UA_NS0ID_CREATESESSIONREQUEST_ENCODING_DEFAULTJSON 15138 /* Object */ +#define UA_NS0ID_CREATESESSIONRESPONSE_ENCODING_DEFAULTJSON 15139 /* Object */ +#define UA_NS0ID_USERIDENTITYTOKEN_ENCODING_DEFAULTJSON 15140 /* Object */ +#define UA_NS0ID_ANONYMOUSIDENTITYTOKEN_ENCODING_DEFAULTJSON 15141 /* Object */ +#define UA_NS0ID_USERNAMEIDENTITYTOKEN_ENCODING_DEFAULTJSON 15142 /* Object */ +#define UA_NS0ID_X509IDENTITYTOKEN_ENCODING_DEFAULTJSON 15143 /* Object */ +#define UA_NS0ID_ISSUEDIDENTITYTOKEN_ENCODING_DEFAULTJSON 15144 /* Object */ +#define UA_NS0ID_ACTIVATESESSIONREQUEST_ENCODING_DEFAULTJSON 15145 /* Object */ +#define UA_NS0ID_ACTIVATESESSIONRESPONSE_ENCODING_DEFAULTJSON 15146 /* Object */ +#define UA_NS0ID_CLOSESESSIONREQUEST_ENCODING_DEFAULTJSON 15147 /* Object */ +#define UA_NS0ID_CLOSESESSIONRESPONSE_ENCODING_DEFAULTJSON 15148 /* Object */ +#define UA_NS0ID_CANCELREQUEST_ENCODING_DEFAULTJSON 15149 /* Object */ +#define UA_NS0ID_CANCELRESPONSE_ENCODING_DEFAULTJSON 15150 /* Object */ +#define UA_NS0ID_NODEATTRIBUTES_ENCODING_DEFAULTJSON 15151 /* Object */ +#define UA_NS0ID_OBJECTATTRIBUTES_ENCODING_DEFAULTJSON 15152 /* Object */ +#define UA_NS0ID_VARIABLEATTRIBUTES_ENCODING_DEFAULTJSON 15153 /* Object */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTTYPE_DISCOVERYADDRESS_NETWORKINTERFACE 15154 /* Variable */ +#define UA_NS0ID_BROKERCONNECTIONTRANSPORTTYPE 15155 /* ObjectType */ +#define UA_NS0ID_BROKERCONNECTIONTRANSPORTTYPE_RESOURCEURI 15156 /* Variable */ +#define UA_NS0ID_METHODATTRIBUTES_ENCODING_DEFAULTJSON 15157 /* Object */ +#define UA_NS0ID_OBJECTTYPEATTRIBUTES_ENCODING_DEFAULTJSON 15158 /* Object */ +#define UA_NS0ID_VARIABLETYPEATTRIBUTES_ENCODING_DEFAULTJSON 15159 /* Object */ +#define UA_NS0ID_REFERENCETYPEATTRIBUTES_ENCODING_DEFAULTJSON 15160 /* Object */ +#define UA_NS0ID_DATATYPEATTRIBUTES_ENCODING_DEFAULTJSON 15161 /* Object */ +#define UA_NS0ID_VIEWATTRIBUTES_ENCODING_DEFAULTJSON 15162 /* Object */ +#define UA_NS0ID_GENERICATTRIBUTEVALUE_ENCODING_DEFAULTJSON 15163 /* Object */ +#define UA_NS0ID_GENERICATTRIBUTES_ENCODING_DEFAULTJSON 15164 /* Object */ +#define UA_NS0ID_ADDNODESITEM_ENCODING_DEFAULTJSON 15165 /* Object */ +#define UA_NS0ID_ADDNODESRESULT_ENCODING_DEFAULTJSON 15166 /* Object */ +#define UA_NS0ID_ADDNODESREQUEST_ENCODING_DEFAULTJSON 15167 /* Object */ +#define UA_NS0ID_ADDNODESRESPONSE_ENCODING_DEFAULTJSON 15168 /* Object */ +#define UA_NS0ID_ADDREFERENCESITEM_ENCODING_DEFAULTJSON 15169 /* Object */ +#define UA_NS0ID_ADDREFERENCESREQUEST_ENCODING_DEFAULTJSON 15170 /* Object */ +#define UA_NS0ID_ADDREFERENCESRESPONSE_ENCODING_DEFAULTJSON 15171 /* Object */ +#define UA_NS0ID_DELETENODESITEM_ENCODING_DEFAULTJSON 15172 /* Object */ +#define UA_NS0ID_DELETENODESREQUEST_ENCODING_DEFAULTJSON 15173 /* Object */ +#define UA_NS0ID_DELETENODESRESPONSE_ENCODING_DEFAULTJSON 15174 /* Object */ +#define UA_NS0ID_DELETEREFERENCESITEM_ENCODING_DEFAULTJSON 15175 /* Object */ +#define UA_NS0ID_DELETEREFERENCESREQUEST_ENCODING_DEFAULTJSON 15176 /* Object */ +#define UA_NS0ID_DELETEREFERENCESRESPONSE_ENCODING_DEFAULTJSON 15177 /* Object */ +#define UA_NS0ID_BROKERCONNECTIONTRANSPORTTYPE_AUTHENTICATIONPROFILEURI 15178 /* Variable */ +#define UA_NS0ID_VIEWDESCRIPTION_ENCODING_DEFAULTJSON 15179 /* Object */ +#define UA_NS0ID_BROWSEDESCRIPTION_ENCODING_DEFAULTJSON 15180 /* Object */ +#define UA_NS0ID_USERCREDENTIALCERTIFICATETYPE 15181 /* ObjectType */ +#define UA_NS0ID_REFERENCEDESCRIPTION_ENCODING_DEFAULTJSON 15182 /* Object */ +#define UA_NS0ID_BROWSERESULT_ENCODING_DEFAULTJSON 15183 /* Object */ +#define UA_NS0ID_BROWSEREQUEST_ENCODING_DEFAULTJSON 15184 /* Object */ +#define UA_NS0ID_BROWSERESPONSE_ENCODING_DEFAULTJSON 15185 /* Object */ +#define UA_NS0ID_BROWSENEXTREQUEST_ENCODING_DEFAULTJSON 15186 /* Object */ +#define UA_NS0ID_BROWSENEXTRESPONSE_ENCODING_DEFAULTJSON 15187 /* Object */ +#define UA_NS0ID_RELATIVEPATHELEMENT_ENCODING_DEFAULTJSON 15188 /* Object */ +#define UA_NS0ID_RELATIVEPATH_ENCODING_DEFAULTJSON 15189 /* Object */ +#define UA_NS0ID_BROWSEPATH_ENCODING_DEFAULTJSON 15190 /* Object */ +#define UA_NS0ID_BROWSEPATHTARGET_ENCODING_DEFAULTJSON 15191 /* Object */ +#define UA_NS0ID_BROWSEPATHRESULT_ENCODING_DEFAULTJSON 15192 /* Object */ +#define UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSREQUEST_ENCODING_DEFAULTJSON 15193 /* Object */ +#define UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE_ENCODING_DEFAULTJSON 15194 /* Object */ +#define UA_NS0ID_REGISTERNODESREQUEST_ENCODING_DEFAULTJSON 15195 /* Object */ +#define UA_NS0ID_REGISTERNODESRESPONSE_ENCODING_DEFAULTJSON 15196 /* Object */ +#define UA_NS0ID_UNREGISTERNODESREQUEST_ENCODING_DEFAULTJSON 15197 /* Object */ +#define UA_NS0ID_UNREGISTERNODESRESPONSE_ENCODING_DEFAULTJSON 15198 /* Object */ +#define UA_NS0ID_ENDPOINTCONFIGURATION_ENCODING_DEFAULTJSON 15199 /* Object */ +#define UA_NS0ID_QUERYDATADESCRIPTION_ENCODING_DEFAULTJSON 15200 /* Object */ +#define UA_NS0ID_NODETYPEDESCRIPTION_ENCODING_DEFAULTJSON 15201 /* Object */ +#define UA_NS0ID_QUERYDATASET_ENCODING_DEFAULTJSON 15202 /* Object */ +#define UA_NS0ID_NODEREFERENCE_ENCODING_DEFAULTJSON 15203 /* Object */ +#define UA_NS0ID_CONTENTFILTERELEMENT_ENCODING_DEFAULTJSON 15204 /* Object */ +#define UA_NS0ID_CONTENTFILTER_ENCODING_DEFAULTJSON 15205 /* Object */ +#define UA_NS0ID_FILTEROPERAND_ENCODING_DEFAULTJSON 15206 /* Object */ +#define UA_NS0ID_ELEMENTOPERAND_ENCODING_DEFAULTJSON 15207 /* Object */ +#define UA_NS0ID_LITERALOPERAND_ENCODING_DEFAULTJSON 15208 /* Object */ +#define UA_NS0ID_ATTRIBUTEOPERAND_ENCODING_DEFAULTJSON 15209 /* Object */ +#define UA_NS0ID_SIMPLEATTRIBUTEOPERAND_ENCODING_DEFAULTJSON 15210 /* Object */ +#define UA_NS0ID_CONTENTFILTERELEMENTRESULT_ENCODING_DEFAULTJSON 15211 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_GETSECURITYKEYS 15212 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_GETSECURITYKEYS_INPUTARGUMENTS 15213 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_GETSECURITYKEYS_OUTPUTARGUMENTS 15214 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_GETSECURITYKEYS 15215 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_GETSECURITYKEYS_INPUTARGUMENTS 15216 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_GETSECURITYKEYS_OUTPUTARGUMENTS 15217 /* Variable */ +#define UA_NS0ID_GETSECURITYKEYSMETHODTYPE 15218 /* Method */ +#define UA_NS0ID_GETSECURITYKEYSMETHODTYPE_INPUTARGUMENTS 15219 /* Variable */ +#define UA_NS0ID_GETSECURITYKEYSMETHODTYPE_OUTPUTARGUMENTS 15220 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_PUBLISHEDDATASETNAME_PLACEHOLDER_DATASETMETADATA 15221 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER 15222 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS 15223 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS_STATE 15224 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS_ENABLE 15225 /* Method */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS_DISABLE 15226 /* Method */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_TRANSPORTSETTINGS 15227 /* Object */ +#define UA_NS0ID_CONTENTFILTERRESULT_ENCODING_DEFAULTJSON 15228 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETMETADATA 15229 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER 15230 /* Object */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS 15231 /* Object */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS_STATE 15232 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS_ENABLE 15233 /* Method */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS_DISABLE 15234 /* Method */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_TRANSPORTSETTINGS 15235 /* Object */ +#define UA_NS0ID_PARSINGRESULT_ENCODING_DEFAULTJSON 15236 /* Object */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETMETADATA 15237 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER 15238 /* Object */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS 15239 /* Object */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS_STATE 15240 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS_ENABLE 15241 /* Method */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS_DISABLE 15242 /* Method */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_TRANSPORTSETTINGS 15243 /* Object */ +#define UA_NS0ID_QUERYFIRSTREQUEST_ENCODING_DEFAULTJSON 15244 /* Object */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETMETADATA 15245 /* Variable */ +#define UA_NS0ID_BROKERWRITERGROUPTRANSPORTTYPE_RESOURCEURI 15246 /* Variable */ +#define UA_NS0ID_BROKERWRITERGROUPTRANSPORTTYPE_AUTHENTICATIONPROFILEURI 15247 /* Variable */ +#define UA_NS0ID_CREATECREDENTIALMETHODTYPE 15248 /* Method */ +#define UA_NS0ID_BROKERWRITERGROUPTRANSPORTTYPE_REQUESTEDDELIVERYGUARANTEE 15249 /* Variable */ +#define UA_NS0ID_BROKERDATASETWRITERTRANSPORTTYPE_RESOURCEURI 15250 /* Variable */ +#define UA_NS0ID_BROKERDATASETWRITERTRANSPORTTYPE_AUTHENTICATIONPROFILEURI 15251 /* Variable */ +#define UA_NS0ID_QUERYFIRSTRESPONSE_ENCODING_DEFAULTJSON 15252 /* Object */ +#define UA_NS0ID_CREATECREDENTIALMETHODTYPE_INPUTARGUMENTS 15253 /* Variable */ +#define UA_NS0ID_QUERYNEXTREQUEST_ENCODING_DEFAULTJSON 15254 /* Object */ +#define UA_NS0ID_QUERYNEXTRESPONSE_ENCODING_DEFAULTJSON 15255 /* Object */ +#define UA_NS0ID_READVALUEID_ENCODING_DEFAULTJSON 15256 /* Object */ +#define UA_NS0ID_READREQUEST_ENCODING_DEFAULTJSON 15257 /* Object */ +#define UA_NS0ID_READRESPONSE_ENCODING_DEFAULTJSON 15258 /* Object */ +#define UA_NS0ID_HISTORYREADVALUEID_ENCODING_DEFAULTJSON 15259 /* Object */ +#define UA_NS0ID_HISTORYREADRESULT_ENCODING_DEFAULTJSON 15260 /* Object */ +#define UA_NS0ID_HISTORYREADDETAILS_ENCODING_DEFAULTJSON 15261 /* Object */ +#define UA_NS0ID_READEVENTDETAILS_ENCODING_DEFAULTJSON 15262 /* Object */ +#define UA_NS0ID_READRAWMODIFIEDDETAILS_ENCODING_DEFAULTJSON 15263 /* Object */ +#define UA_NS0ID_READPROCESSEDDETAILS_ENCODING_DEFAULTJSON 15264 /* Object */ +#define UA_NS0ID_PUBSUBGROUPTYPE_STATUS 15265 /* Object */ +#define UA_NS0ID_PUBSUBGROUPTYPE_STATUS_STATE 15266 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPE_STATUS_ENABLE 15267 /* Method */ +#define UA_NS0ID_PUBSUBGROUPTYPE_STATUS_DISABLE 15268 /* Method */ +#define UA_NS0ID_READATTIMEDETAILS_ENCODING_DEFAULTJSON 15269 /* Object */ +#define UA_NS0ID_HISTORYDATA_ENCODING_DEFAULTJSON 15270 /* Object */ +#define UA_NS0ID_MODIFICATIONINFO_ENCODING_DEFAULTJSON 15271 /* Object */ +#define UA_NS0ID_HISTORYMODIFIEDDATA_ENCODING_DEFAULTJSON 15272 /* Object */ +#define UA_NS0ID_HISTORYEVENT_ENCODING_DEFAULTJSON 15273 /* Object */ +#define UA_NS0ID_HISTORYREADREQUEST_ENCODING_DEFAULTJSON 15274 /* Object */ +#define UA_NS0ID_HISTORYREADRESPONSE_ENCODING_DEFAULTJSON 15275 /* Object */ +#define UA_NS0ID_WRITEVALUE_ENCODING_DEFAULTJSON 15276 /* Object */ +#define UA_NS0ID_WRITEREQUEST_ENCODING_DEFAULTJSON 15277 /* Object */ +#define UA_NS0ID_WRITERESPONSE_ENCODING_DEFAULTJSON 15278 /* Object */ +#define UA_NS0ID_HISTORYUPDATEDETAILS_ENCODING_DEFAULTJSON 15279 /* Object */ +#define UA_NS0ID_UPDATEDATADETAILS_ENCODING_DEFAULTJSON 15280 /* Object */ +#define UA_NS0ID_UPDATESTRUCTUREDATADETAILS_ENCODING_DEFAULTJSON 15281 /* Object */ +#define UA_NS0ID_UPDATEEVENTDETAILS_ENCODING_DEFAULTJSON 15282 /* Object */ +#define UA_NS0ID_DELETERAWMODIFIEDDETAILS_ENCODING_DEFAULTJSON 15283 /* Object */ +#define UA_NS0ID_DELETEATTIMEDETAILS_ENCODING_DEFAULTJSON 15284 /* Object */ +#define UA_NS0ID_DELETEEVENTDETAILS_ENCODING_DEFAULTJSON 15285 /* Object */ +#define UA_NS0ID_HISTORYUPDATERESULT_ENCODING_DEFAULTJSON 15286 /* Object */ +#define UA_NS0ID_HISTORYUPDATEREQUEST_ENCODING_DEFAULTJSON 15287 /* Object */ +#define UA_NS0ID_HISTORYUPDATERESPONSE_ENCODING_DEFAULTJSON 15288 /* Object */ +#define UA_NS0ID_CALLMETHODREQUEST_ENCODING_DEFAULTJSON 15289 /* Object */ +#define UA_NS0ID_CALLMETHODRESULT_ENCODING_DEFAULTJSON 15290 /* Object */ +#define UA_NS0ID_CALLREQUEST_ENCODING_DEFAULTJSON 15291 /* Object */ +#define UA_NS0ID_CALLRESPONSE_ENCODING_DEFAULTJSON 15292 /* Object */ +#define UA_NS0ID_MONITORINGFILTER_ENCODING_DEFAULTJSON 15293 /* Object */ +#define UA_NS0ID_DATACHANGEFILTER_ENCODING_DEFAULTJSON 15294 /* Object */ +#define UA_NS0ID_EVENTFILTER_ENCODING_DEFAULTJSON 15295 /* Object */ +#define UA_NS0ID_HASDATASETWRITER 15296 /* ReferenceType */ +#define UA_NS0ID_HASDATASETREADER 15297 /* ReferenceType */ +#define UA_NS0ID_DATASETWRITERTYPE 15298 /* ObjectType */ +#define UA_NS0ID_DATASETWRITERTYPE_STATUS 15299 /* Object */ +#define UA_NS0ID_DATASETWRITERTYPE_STATUS_STATE 15300 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_STATUS_ENABLE 15301 /* Method */ +#define UA_NS0ID_DATASETWRITERTYPE_STATUS_DISABLE 15302 /* Method */ +#define UA_NS0ID_DATASETWRITERTYPE_TRANSPORTSETTINGS 15303 /* Object */ +#define UA_NS0ID_AGGREGATECONFIGURATION_ENCODING_DEFAULTJSON 15304 /* Object */ +#define UA_NS0ID_DATASETWRITERTRANSPORTTYPE 15305 /* ObjectType */ +#define UA_NS0ID_DATASETREADERTYPE 15306 /* ObjectType */ +#define UA_NS0ID_DATASETREADERTYPE_STATUS 15307 /* Object */ +#define UA_NS0ID_DATASETREADERTYPE_STATUS_STATE 15308 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_STATUS_ENABLE 15309 /* Method */ +#define UA_NS0ID_DATASETREADERTYPE_STATUS_DISABLE 15310 /* Method */ +#define UA_NS0ID_DATASETREADERTYPE_TRANSPORTSETTINGS 15311 /* Object */ +#define UA_NS0ID_AGGREGATEFILTER_ENCODING_DEFAULTJSON 15312 /* Object */ +#define UA_NS0ID_MONITORINGFILTERRESULT_ENCODING_DEFAULTJSON 15313 /* Object */ +#define UA_NS0ID_EVENTFILTERRESULT_ENCODING_DEFAULTJSON 15314 /* Object */ +#define UA_NS0ID_AGGREGATEFILTERRESULT_ENCODING_DEFAULTJSON 15315 /* Object */ +#define UA_NS0ID_DATASETREADERTYPE_SUBSCRIBEDDATASET 15316 /* Object */ +#define UA_NS0ID_ELSEGUARDVARIABLETYPE 15317 /* VariableType */ +#define UA_NS0ID_BASEANALOGTYPE 15318 /* VariableType */ +#define UA_NS0ID_DATASETREADERTRANSPORTTYPE 15319 /* ObjectType */ +#define UA_NS0ID_MONITORINGPARAMETERS_ENCODING_DEFAULTJSON 15320 /* Object */ +#define UA_NS0ID_MONITOREDITEMCREATEREQUEST_ENCODING_DEFAULTJSON 15321 /* Object */ +#define UA_NS0ID_MONITOREDITEMCREATERESULT_ENCODING_DEFAULTJSON 15322 /* Object */ +#define UA_NS0ID_CREATEMONITOREDITEMSREQUEST_ENCODING_DEFAULTJSON 15323 /* Object */ +#define UA_NS0ID_CREATEMONITOREDITEMSRESPONSE_ENCODING_DEFAULTJSON 15324 /* Object */ +#define UA_NS0ID_MONITOREDITEMMODIFYREQUEST_ENCODING_DEFAULTJSON 15325 /* Object */ +#define UA_NS0ID_MONITOREDITEMMODIFYRESULT_ENCODING_DEFAULTJSON 15326 /* Object */ +#define UA_NS0ID_MODIFYMONITOREDITEMSREQUEST_ENCODING_DEFAULTJSON 15327 /* Object */ +#define UA_NS0ID_MODIFYMONITOREDITEMSRESPONSE_ENCODING_DEFAULTJSON 15328 /* Object */ +#define UA_NS0ID_SETMONITORINGMODEREQUEST_ENCODING_DEFAULTJSON 15329 /* Object */ +#define UA_NS0ID_BROKERDATASETWRITERTRANSPORTTYPE_REQUESTEDDELIVERYGUARANTEE 15330 /* Variable */ +#define UA_NS0ID_SETMONITORINGMODERESPONSE_ENCODING_DEFAULTJSON 15331 /* Object */ +#define UA_NS0ID_SETTRIGGERINGREQUEST_ENCODING_DEFAULTJSON 15332 /* Object */ +#define UA_NS0ID_SETTRIGGERINGRESPONSE_ENCODING_DEFAULTJSON 15333 /* Object */ +#define UA_NS0ID_BROKERDATASETREADERTRANSPORTTYPE_RESOURCEURI 15334 /* Variable */ +#define UA_NS0ID_DELETEMONITOREDITEMSREQUEST_ENCODING_DEFAULTJSON 15335 /* Object */ +#define UA_NS0ID_DELETEMONITOREDITEMSRESPONSE_ENCODING_DEFAULTJSON 15336 /* Object */ +#define UA_NS0ID_CREATESUBSCRIPTIONREQUEST_ENCODING_DEFAULTJSON 15337 /* Object */ +#define UA_NS0ID_CREATESUBSCRIPTIONRESPONSE_ENCODING_DEFAULTJSON 15338 /* Object */ +#define UA_NS0ID_MODIFYSUBSCRIPTIONREQUEST_ENCODING_DEFAULTJSON 15339 /* Object */ +#define UA_NS0ID_MODIFYSUBSCRIPTIONRESPONSE_ENCODING_DEFAULTJSON 15340 /* Object */ +#define UA_NS0ID_SETPUBLISHINGMODEREQUEST_ENCODING_DEFAULTJSON 15341 /* Object */ +#define UA_NS0ID_SETPUBLISHINGMODERESPONSE_ENCODING_DEFAULTJSON 15342 /* Object */ +#define UA_NS0ID_NOTIFICATIONMESSAGE_ENCODING_DEFAULTJSON 15343 /* Object */ +#define UA_NS0ID_NOTIFICATIONDATA_ENCODING_DEFAULTJSON 15344 /* Object */ +#define UA_NS0ID_DATACHANGENOTIFICATION_ENCODING_DEFAULTJSON 15345 /* Object */ +#define UA_NS0ID_MONITOREDITEMNOTIFICATION_ENCODING_DEFAULTJSON 15346 /* Object */ +#define UA_NS0ID_EVENTNOTIFICATIONLIST_ENCODING_DEFAULTJSON 15347 /* Object */ +#define UA_NS0ID_EVENTFIELDLIST_ENCODING_DEFAULTJSON 15348 /* Object */ +#define UA_NS0ID_HISTORYEVENTFIELDLIST_ENCODING_DEFAULTJSON 15349 /* Object */ +#define UA_NS0ID_STATUSCHANGENOTIFICATION_ENCODING_DEFAULTJSON 15350 /* Object */ +#define UA_NS0ID_SUBSCRIPTIONACKNOWLEDGEMENT_ENCODING_DEFAULTJSON 15351 /* Object */ +#define UA_NS0ID_PUBLISHREQUEST_ENCODING_DEFAULTJSON 15352 /* Object */ +#define UA_NS0ID_PUBLISHRESPONSE_ENCODING_DEFAULTJSON 15353 /* Object */ +#define UA_NS0ID_REPUBLISHREQUEST_ENCODING_DEFAULTJSON 15354 /* Object */ +#define UA_NS0ID_REPUBLISHRESPONSE_ENCODING_DEFAULTJSON 15355 /* Object */ +#define UA_NS0ID_TRANSFERRESULT_ENCODING_DEFAULTJSON 15356 /* Object */ +#define UA_NS0ID_TRANSFERSUBSCRIPTIONSREQUEST_ENCODING_DEFAULTJSON 15357 /* Object */ +#define UA_NS0ID_TRANSFERSUBSCRIPTIONSRESPONSE_ENCODING_DEFAULTJSON 15358 /* Object */ +#define UA_NS0ID_DELETESUBSCRIPTIONSREQUEST_ENCODING_DEFAULTJSON 15359 /* Object */ +#define UA_NS0ID_DELETESUBSCRIPTIONSRESPONSE_ENCODING_DEFAULTJSON 15360 /* Object */ +#define UA_NS0ID_BUILDINFO_ENCODING_DEFAULTJSON 15361 /* Object */ +#define UA_NS0ID_REDUNDANTSERVERDATATYPE_ENCODING_DEFAULTJSON 15362 /* Object */ +#define UA_NS0ID_ENDPOINTURLLISTDATATYPE_ENCODING_DEFAULTJSON 15363 /* Object */ +#define UA_NS0ID_NETWORKGROUPDATATYPE_ENCODING_DEFAULTJSON 15364 /* Object */ +#define UA_NS0ID_SAMPLINGINTERVALDIAGNOSTICSDATATYPE_ENCODING_DEFAULTJSON 15365 /* Object */ +#define UA_NS0ID_SERVERDIAGNOSTICSSUMMARYDATATYPE_ENCODING_DEFAULTJSON 15366 /* Object */ +#define UA_NS0ID_SERVERSTATUSDATATYPE_ENCODING_DEFAULTJSON 15367 /* Object */ +#define UA_NS0ID_SESSIONDIAGNOSTICSDATATYPE_ENCODING_DEFAULTJSON 15368 /* Object */ +#define UA_NS0ID_SESSIONSECURITYDIAGNOSTICSDATATYPE_ENCODING_DEFAULTJSON 15369 /* Object */ +#define UA_NS0ID_SERVICECOUNTERDATATYPE_ENCODING_DEFAULTJSON 15370 /* Object */ +#define UA_NS0ID_STATUSRESULT_ENCODING_DEFAULTJSON 15371 /* Object */ +#define UA_NS0ID_SUBSCRIPTIONDIAGNOSTICSDATATYPE_ENCODING_DEFAULTJSON 15372 /* Object */ +#define UA_NS0ID_MODELCHANGESTRUCTUREDATATYPE_ENCODING_DEFAULTJSON 15373 /* Object */ +#define UA_NS0ID_SEMANTICCHANGESTRUCTUREDATATYPE_ENCODING_DEFAULTJSON 15374 /* Object */ +#define UA_NS0ID_RANGE_ENCODING_DEFAULTJSON 15375 /* Object */ +#define UA_NS0ID_EUINFORMATION_ENCODING_DEFAULTJSON 15376 /* Object */ +#define UA_NS0ID_COMPLEXNUMBERTYPE_ENCODING_DEFAULTJSON 15377 /* Object */ +#define UA_NS0ID_DOUBLECOMPLEXNUMBERTYPE_ENCODING_DEFAULTJSON 15378 /* Object */ +#define UA_NS0ID_AXISINFORMATION_ENCODING_DEFAULTJSON 15379 /* Object */ +#define UA_NS0ID_XVTYPE_ENCODING_DEFAULTJSON 15380 /* Object */ +#define UA_NS0ID_PROGRAMDIAGNOSTICDATATYPE_ENCODING_DEFAULTJSON 15381 /* Object */ +#define UA_NS0ID_ANNOTATION_ENCODING_DEFAULTJSON 15382 /* Object */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE 15383 /* VariableType */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE_CREATESESSIONID 15384 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE_CREATECLIENTNAME 15385 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE_INVOCATIONCREATIONTIME 15386 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE_LASTTRANSITIONTIME 15387 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE_LASTMETHODCALL 15388 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE_LASTMETHODSESSIONID 15389 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE_LASTMETHODINPUTARGUMENTS 15390 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE_LASTMETHODOUTPUTARGUMENTS 15391 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE_LASTMETHODINPUTVALUES 15392 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE_LASTMETHODOUTPUTVALUES 15393 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE_LASTMETHODCALLTIME 15394 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2TYPE_LASTMETHODRETURNSTATUS 15395 /* Variable */ +#define UA_NS0ID_ACCESSLEVELEXTYPE 15406 /* DataType */ +#define UA_NS0ID_ACCESSLEVELEXTYPE_OPTIONSETVALUES 15407 /* Variable */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_APPLICATIONSEXCLUDE 15408 /* Variable */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_ENDPOINTSEXCLUDE 15409 /* Variable */ +#define UA_NS0ID_ROLETYPE_APPLICATIONSEXCLUDE 15410 /* Variable */ +#define UA_NS0ID_ROLETYPE_ENDPOINTSEXCLUDE 15411 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_APPLICATIONSEXCLUDE 15412 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_ENDPOINTSEXCLUDE 15413 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_APPLICATIONSEXCLUDE 15414 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_ENDPOINTSEXCLUDE 15415 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_APPLICATIONSEXCLUDE 15416 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_ENDPOINTSEXCLUDE 15417 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_APPLICATIONSEXCLUDE 15418 /* Variable */ +#define UA_NS0ID_BROKERDATASETREADERTRANSPORTTYPE_AUTHENTICATIONPROFILEURI 15419 /* Variable */ +#define UA_NS0ID_BROKERDATASETREADERTRANSPORTTYPE_REQUESTEDDELIVERYGUARANTEE 15420 /* Variable */ +#define UA_NS0ID_SIMPLETYPEDESCRIPTION_ENCODING_DEFAULTBINARY 15421 /* Object */ +#define UA_NS0ID_UABINARYFILEDATATYPE_ENCODING_DEFAULTBINARY 15422 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_ENDPOINTSEXCLUDE 15423 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_APPLICATIONSEXCLUDE 15424 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_ENDPOINTSEXCLUDE 15425 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_APPLICATIONSEXCLUDE 15426 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_ENDPOINTSEXCLUDE 15427 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_APPLICATIONSEXCLUDE 15428 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_ENDPOINTSEXCLUDE 15429 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_APPLICATIONSEXCLUDE 15430 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_GETSECURITYGROUP 15431 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_GETSECURITYGROUP_INPUTARGUMENTS 15432 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_GETSECURITYGROUP_OUTPUTARGUMENTS 15433 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SECURITYGROUPS 15434 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SECURITYGROUPS_ADDSECURITYGROUP 15435 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SECURITYGROUPS_ADDSECURITYGROUP_INPUTARGUMENTS 15436 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SECURITYGROUPS_ADDSECURITYGROUP_OUTPUTARGUMENTS 15437 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SECURITYGROUPS_REMOVESECURITYGROUP 15438 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SECURITYGROUPS_REMOVESECURITYGROUP_INPUTARGUMENTS 15439 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_GETSECURITYGROUP 15440 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_GETSECURITYGROUP_INPUTARGUMENTS 15441 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_GETSECURITYGROUP_OUTPUTARGUMENTS 15442 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SECURITYGROUPS 15443 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SECURITYGROUPS_ADDSECURITYGROUP 15444 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SECURITYGROUPS_ADDSECURITYGROUP_INPUTARGUMENTS 15445 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SECURITYGROUPS_ADDSECURITYGROUP_OUTPUTARGUMENTS 15446 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SECURITYGROUPS_REMOVESECURITYGROUP 15447 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SECURITYGROUPS_REMOVESECURITYGROUP_INPUTARGUMENTS 15448 /* Variable */ +#define UA_NS0ID_GETSECURITYGROUPMETHODTYPE 15449 /* Method */ +#define UA_NS0ID_GETSECURITYGROUPMETHODTYPE_INPUTARGUMENTS 15450 /* Variable */ +#define UA_NS0ID_GETSECURITYGROUPMETHODTYPE_OUTPUTARGUMENTS 15451 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE 15452 /* ObjectType */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPFOLDERNAME_PLACEHOLDER 15453 /* Object */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPFOLDERNAME_PLACEHOLDER_ADDSECURITYGROUP 15454 /* Method */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPFOLDERNAME_PLACEHOLDER_ADDSECURITYGROUP_INPUTARGUMENTS 15455 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPFOLDERNAME_PLACEHOLDER_ADDSECURITYGROUP_OUTPUTARGUMENTS 15456 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPFOLDERNAME_PLACEHOLDER_REMOVESECURITYGROUP 15457 /* Method */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPFOLDERNAME_PLACEHOLDER_REMOVESECURITYGROUP_INPUTARGUMENTS 15458 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPNAME_PLACEHOLDER 15459 /* Object */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPNAME_PLACEHOLDER_SECURITYGROUPID 15460 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_ADDSECURITYGROUP 15461 /* Method */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_ADDSECURITYGROUP_INPUTARGUMENTS 15462 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_ADDSECURITYGROUP_OUTPUTARGUMENTS 15463 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_REMOVESECURITYGROUP 15464 /* Method */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_REMOVESECURITYGROUP_INPUTARGUMENTS 15465 /* Variable */ +#define UA_NS0ID_ADDSECURITYGROUPMETHODTYPE 15466 /* Method */ +#define UA_NS0ID_ADDSECURITYGROUPMETHODTYPE_INPUTARGUMENTS 15467 /* Variable */ +#define UA_NS0ID_ADDSECURITYGROUPMETHODTYPE_OUTPUTARGUMENTS 15468 /* Variable */ +#define UA_NS0ID_REMOVESECURITYGROUPMETHODTYPE 15469 /* Method */ +#define UA_NS0ID_REMOVESECURITYGROUPMETHODTYPE_INPUTARGUMENTS 15470 /* Variable */ +#define UA_NS0ID_SECURITYGROUPTYPE 15471 /* ObjectType */ +#define UA_NS0ID_SECURITYGROUPTYPE_SECURITYGROUPID 15472 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_PUBLISHEDDATASETNAME_PLACEHOLDER_EXTENSIONFIELDS 15473 /* Object */ +#define UA_NS0ID_DATASETFOLDERTYPE_PUBLISHEDDATASETNAME_PLACEHOLDER_EXTENSIONFIELDS_ADDEXTENSIONFIELD 15474 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_PUBLISHEDDATASETNAME_PLACEHOLDER_EXTENSIONFIELDS_ADDEXTENSIONFIELD_INPUTARGUMENTS 15475 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_PUBLISHEDDATASETNAME_PLACEHOLDER_EXTENSIONFIELDS_ADDEXTENSIONFIELD_OUTPUTARGUMENTS 15476 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_PUBLISHEDDATASETNAME_PLACEHOLDER_EXTENSIONFIELDS_REMOVEEXTENSIONFIELD 15477 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_PUBLISHEDDATASETNAME_PLACEHOLDER_EXTENSIONFIELDS_REMOVEEXTENSIONFIELD_INPUTARGUMENTS 15478 /* Variable */ +#define UA_NS0ID_BROKERCONNECTIONTRANSPORTDATATYPE_ENCODING_DEFAULTBINARY 15479 /* Object */ +#define UA_NS0ID_WRITERGROUPDATATYPE 15480 /* DataType */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_EXTENSIONFIELDS 15481 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_EXTENSIONFIELDS_ADDEXTENSIONFIELD 15482 /* Method */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_EXTENSIONFIELDS_ADDEXTENSIONFIELD_INPUTARGUMENTS 15483 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_EXTENSIONFIELDS_ADDEXTENSIONFIELD_OUTPUTARGUMENTS 15484 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_EXTENSIONFIELDS_REMOVEEXTENSIONFIELD 15485 /* Method */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_EXTENSIONFIELDS_REMOVEEXTENSIONFIELD_INPUTARGUMENTS 15486 /* Variable */ +#define UA_NS0ID_STRUCTUREDESCRIPTION 15487 /* DataType */ +#define UA_NS0ID_ENUMDESCRIPTION 15488 /* DataType */ +#define UA_NS0ID_EXTENSIONFIELDSTYPE 15489 /* ObjectType */ +#define UA_NS0ID_EXTENSIONFIELDSTYPE_EXTENSIONFIELDNAME_PLACEHOLDER 15490 /* Variable */ +#define UA_NS0ID_EXTENSIONFIELDSTYPE_ADDEXTENSIONFIELD 15491 /* Method */ +#define UA_NS0ID_EXTENSIONFIELDSTYPE_ADDEXTENSIONFIELD_INPUTARGUMENTS 15492 /* Variable */ +#define UA_NS0ID_EXTENSIONFIELDSTYPE_ADDEXTENSIONFIELD_OUTPUTARGUMENTS 15493 /* Variable */ +#define UA_NS0ID_EXTENSIONFIELDSTYPE_REMOVEEXTENSIONFIELD 15494 /* Method */ +#define UA_NS0ID_EXTENSIONFIELDSTYPE_REMOVEEXTENSIONFIELD_INPUTARGUMENTS 15495 /* Variable */ +#define UA_NS0ID_ADDEXTENSIONFIELDMETHODTYPE 15496 /* Method */ +#define UA_NS0ID_ADDEXTENSIONFIELDMETHODTYPE_INPUTARGUMENTS 15497 /* Variable */ +#define UA_NS0ID_ADDEXTENSIONFIELDMETHODTYPE_OUTPUTARGUMENTS 15498 /* Variable */ +#define UA_NS0ID_REMOVEEXTENSIONFIELDMETHODTYPE 15499 /* Method */ +#define UA_NS0ID_REMOVEEXTENSIONFIELDMETHODTYPE_INPUTARGUMENTS 15500 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SIMPLETYPEDESCRIPTION 15501 /* Variable */ +#define UA_NS0ID_NETWORKADDRESSDATATYPE 15502 /* DataType */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_EXTENSIONFIELDS 15503 /* Object */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_EXTENSIONFIELDS_ADDEXTENSIONFIELD 15504 /* Method */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_EXTENSIONFIELDS_ADDEXTENSIONFIELD_INPUTARGUMENTS 15505 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_EXTENSIONFIELDS_ADDEXTENSIONFIELD_OUTPUTARGUMENTS 15506 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_EXTENSIONFIELDS_REMOVEEXTENSIONFIELD 15507 /* Method */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_EXTENSIONFIELDS_REMOVEEXTENSIONFIELD_INPUTARGUMENTS 15508 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SIMPLETYPEDESCRIPTION_DATATYPEVERSION 15509 /* Variable */ +#define UA_NS0ID_NETWORKADDRESSURLDATATYPE 15510 /* DataType */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_EXTENSIONFIELDS 15511 /* Object */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_EXTENSIONFIELDS_ADDEXTENSIONFIELD 15512 /* Method */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_EXTENSIONFIELDS_ADDEXTENSIONFIELD_INPUTARGUMENTS 15513 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_EXTENSIONFIELDS_ADDEXTENSIONFIELD_OUTPUTARGUMENTS 15514 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_EXTENSIONFIELDS_REMOVEEXTENSIONFIELD 15515 /* Method */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_EXTENSIONFIELDS_REMOVEEXTENSIONFIELD_INPUTARGUMENTS 15516 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_MODIFYFIELDSELECTION_OUTPUTARGUMENTS 15517 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPEMODIFYFIELDSELECTIONMETHODTYPE_OUTPUTARGUMENTS 15518 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SIMPLETYPEDESCRIPTION_DICTIONARYFRAGMENT 15519 /* Variable */ +#define UA_NS0ID_READERGROUPDATATYPE 15520 /* DataType */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UABINARYFILEDATATYPE 15521 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UABINARYFILEDATATYPE_DATATYPEVERSION 15522 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UABINARYFILEDATATYPE_DICTIONARYFRAGMENT 15523 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BROKERCONNECTIONTRANSPORTDATATYPE 15524 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BROKERCONNECTIONTRANSPORTDATATYPE_DATATYPEVERSION 15525 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BROKERCONNECTIONTRANSPORTDATATYPE_DICTIONARYFRAGMENT 15526 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_ENDPOINTSEXCLUDE 15527 /* Variable */ +#define UA_NS0ID_ENDPOINTTYPE 15528 /* DataType */ +#define UA_NS0ID_SIMPLETYPEDESCRIPTION_ENCODING_DEFAULTXML 15529 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATIONDATATYPE 15530 /* DataType */ +#define UA_NS0ID_UABINARYFILEDATATYPE_ENCODING_DEFAULTXML 15531 /* Object */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTDATATYPE 15532 /* DataType */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_ADDRESS_NETWORKINTERFACE 15533 /* Variable */ +#define UA_NS0ID_DATATYPESCHEMAHEADER 15534 /* DataType */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE 15535 /* ObjectType */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_EVENTID 15536 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_EVENTTYPE 15537 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_SOURCENODE 15538 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_SOURCENAME 15539 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_TIME 15540 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_RECEIVETIME 15541 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_LOCALTIME 15542 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_MESSAGE 15543 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_SEVERITY 15544 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_CONNECTIONID 15545 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_GROUPID 15546 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_STATE 15547 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE 15548 /* ObjectType */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_EVENTID 15549 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_EVENTTYPE 15550 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_SOURCENODE 15551 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_SOURCENAME 15552 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_TIME 15553 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_RECEIVETIME 15554 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_LOCALTIME 15555 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_MESSAGE 15556 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_SEVERITY 15557 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_CONNECTIONID 15558 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_GROUPID 15559 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_STATE 15560 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_ACTUAL 15561 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_MAXIMUM 15562 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE 15563 /* ObjectType */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_EVENTID 15564 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_EVENTTYPE 15565 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_SOURCENODE 15566 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_SOURCENAME 15567 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_TIME 15568 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_RECEIVETIME 15569 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_LOCALTIME 15570 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_MESSAGE 15571 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_SEVERITY 15572 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_CONNECTIONID 15573 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_GROUPID 15574 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_STATE 15575 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_ERROR 15576 /* Variable */ +#define UA_NS0ID_DATASETFIELDFLAGS_OPTIONSETVALUES 15577 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETDATATYPE 15578 /* DataType */ +#define UA_NS0ID_BROKERCONNECTIONTRANSPORTDATATYPE_ENCODING_DEFAULTXML 15579 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETSOURCEDATATYPE 15580 /* DataType */ +#define UA_NS0ID_PUBLISHEDDATAITEMSDATATYPE 15581 /* DataType */ +#define UA_NS0ID_PUBLISHEDEVENTSDATATYPE 15582 /* DataType */ +#define UA_NS0ID_DATASETFIELDCONTENTMASK 15583 /* DataType */ +#define UA_NS0ID_DATASETFIELDCONTENTMASK_OPTIONSETVALUES 15584 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SIMPLETYPEDESCRIPTION 15585 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SIMPLETYPEDESCRIPTION_DATATYPEVERSION 15586 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SIMPLETYPEDESCRIPTION_DICTIONARYFRAGMENT 15587 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UABINARYFILEDATATYPE 15588 /* Variable */ +#define UA_NS0ID_STRUCTUREDESCRIPTION_ENCODING_DEFAULTXML 15589 /* Object */ +#define UA_NS0ID_ENUMDESCRIPTION_ENCODING_DEFAULTXML 15590 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STRUCTUREDESCRIPTION 15591 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STRUCTUREDESCRIPTION_DATATYPEVERSION 15592 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STRUCTUREDESCRIPTION_DICTIONARYFRAGMENT 15593 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENUMDESCRIPTION 15594 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENUMDESCRIPTION_DATATYPEVERSION 15595 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENUMDESCRIPTION_DICTIONARYFRAGMENT 15596 /* Variable */ +#define UA_NS0ID_DATASETWRITERDATATYPE 15597 /* DataType */ +#define UA_NS0ID_DATASETWRITERTRANSPORTDATATYPE 15598 /* DataType */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STRUCTUREDESCRIPTION 15599 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STRUCTUREDESCRIPTION_DATATYPEVERSION 15600 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STRUCTUREDESCRIPTION_DICTIONARYFRAGMENT 15601 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENUMDESCRIPTION 15602 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENUMDESCRIPTION_DATATYPEVERSION 15603 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENUMDESCRIPTION_DICTIONARYFRAGMENT 15604 /* Variable */ +#define UA_NS0ID_DATASETWRITERMESSAGEDATATYPE 15605 /* DataType */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_ROLESET 15606 /* Object */ +#define UA_NS0ID_ROLESETTYPE 15607 /* ObjectType */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER 15608 /* Object */ +#define UA_NS0ID_PUBSUBGROUPDATATYPE 15609 /* DataType */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UABINARYFILEDATATYPE_DATATYPEVERSION 15610 /* Variable */ +#define UA_NS0ID_WRITERGROUPTRANSPORTDATATYPE 15611 /* DataType */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_ADDIDENTITY 15612 /* Method */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_ADDIDENTITY_INPUTARGUMENTS 15613 /* Variable */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_REMOVEIDENTITY 15614 /* Method */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_REMOVEIDENTITY_INPUTARGUMENTS 15615 /* Variable */ +#define UA_NS0ID_WRITERGROUPMESSAGEDATATYPE 15616 /* DataType */ +#define UA_NS0ID_PUBSUBCONNECTIONDATATYPE 15617 /* DataType */ +#define UA_NS0ID_CONNECTIONTRANSPORTDATATYPE 15618 /* DataType */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UABINARYFILEDATATYPE_DICTIONARYFRAGMENT 15619 /* Variable */ +#define UA_NS0ID_ROLETYPE 15620 /* ObjectType */ +#define UA_NS0ID_READERGROUPTRANSPORTDATATYPE 15621 /* DataType */ +#define UA_NS0ID_READERGROUPMESSAGEDATATYPE 15622 /* DataType */ +#define UA_NS0ID_DATASETREADERDATATYPE 15623 /* DataType */ +#define UA_NS0ID_ROLETYPE_ADDIDENTITY 15624 /* Method */ +#define UA_NS0ID_ROLETYPE_ADDIDENTITY_INPUTARGUMENTS 15625 /* Variable */ +#define UA_NS0ID_ROLETYPE_REMOVEIDENTITY 15626 /* Method */ +#define UA_NS0ID_ROLETYPE_REMOVEIDENTITY_INPUTARGUMENTS 15627 /* Variable */ +#define UA_NS0ID_DATASETREADERTRANSPORTDATATYPE 15628 /* DataType */ +#define UA_NS0ID_DATASETREADERMESSAGEDATATYPE 15629 /* DataType */ +#define UA_NS0ID_SUBSCRIBEDDATASETDATATYPE 15630 /* DataType */ +#define UA_NS0ID_TARGETVARIABLESDATATYPE 15631 /* DataType */ +#define UA_NS0ID_IDENTITYCRITERIATYPE 15632 /* DataType */ +#define UA_NS0ID_IDENTITYCRITERIATYPE_ENUMVALUES 15633 /* Variable */ +#define UA_NS0ID_IDENTITYMAPPINGRULETYPE 15634 /* DataType */ +#define UA_NS0ID_SUBSCRIBEDDATASETMIRRORDATATYPE 15635 /* DataType */ +#define UA_NS0ID_ADDIDENTITYMETHODTYPE 15636 /* Method */ +#define UA_NS0ID_ADDIDENTITYMETHODTYPE_INPUTARGUMENTS 15637 /* Variable */ +#define UA_NS0ID_REMOVEIDENTITYMETHODTYPE 15638 /* Method */ +#define UA_NS0ID_REMOVEIDENTITYMETHODTYPE_INPUTARGUMENTS 15639 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BROKERCONNECTIONTRANSPORTDATATYPE 15640 /* Variable */ +#define UA_NS0ID_DATASETORDERINGTYPE_ENUMSTRINGS 15641 /* Variable */ +#define UA_NS0ID_UADPNETWORKMESSAGECONTENTMASK 15642 /* DataType */ +#define UA_NS0ID_UADPNETWORKMESSAGECONTENTMASK_OPTIONSETVALUES 15643 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS 15644 /* Object */ +#define UA_NS0ID_UADPWRITERGROUPMESSAGEDATATYPE 15645 /* DataType */ +#define UA_NS0ID_UADPDATASETMESSAGECONTENTMASK 15646 /* DataType */ +#define UA_NS0ID_UADPDATASETMESSAGECONTENTMASK_OPTIONSETVALUES 15647 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_ADDIDENTITY 15648 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_ADDIDENTITY_INPUTARGUMENTS 15649 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_REMOVEIDENTITY 15650 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_REMOVEIDENTITY_INPUTARGUMENTS 15651 /* Variable */ +#define UA_NS0ID_UADPDATASETWRITERMESSAGEDATATYPE 15652 /* DataType */ +#define UA_NS0ID_UADPDATASETREADERMESSAGEDATATYPE 15653 /* DataType */ +#define UA_NS0ID_JSONNETWORKMESSAGECONTENTMASK 15654 /* DataType */ +#define UA_NS0ID_JSONNETWORKMESSAGECONTENTMASK_OPTIONSETVALUES 15655 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER 15656 /* Object */ +#define UA_NS0ID_JSONWRITERGROUPMESSAGEDATATYPE 15657 /* DataType */ +#define UA_NS0ID_JSONDATASETMESSAGECONTENTMASK 15658 /* DataType */ +#define UA_NS0ID_JSONDATASETMESSAGECONTENTMASK_OPTIONSETVALUES 15659 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_ADDIDENTITY 15660 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_ADDIDENTITY_INPUTARGUMENTS 15661 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_REMOVEIDENTITY 15662 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_REMOVEIDENTITY_INPUTARGUMENTS 15663 /* Variable */ +#define UA_NS0ID_JSONDATASETWRITERMESSAGEDATATYPE 15664 /* DataType */ +#define UA_NS0ID_JSONDATASETREADERMESSAGEDATATYPE 15665 /* DataType */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BROKERCONNECTIONTRANSPORTDATATYPE_DATATYPEVERSION 15666 /* Variable */ +#define UA_NS0ID_BROKERWRITERGROUPTRANSPORTDATATYPE 15667 /* DataType */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER 15668 /* Object */ +#define UA_NS0ID_BROKERDATASETWRITERTRANSPORTDATATYPE 15669 /* DataType */ +#define UA_NS0ID_BROKERDATASETREADERTRANSPORTDATATYPE 15670 /* DataType */ +#define UA_NS0ID_ENDPOINTTYPE_ENCODING_DEFAULTBINARY 15671 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_ADDIDENTITY 15672 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_ADDIDENTITY_INPUTARGUMENTS 15673 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_REMOVEIDENTITY 15674 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_REMOVEIDENTITY_INPUTARGUMENTS 15675 /* Variable */ +#define UA_NS0ID_DATATYPESCHEMAHEADER_ENCODING_DEFAULTBINARY 15676 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETDATATYPE_ENCODING_DEFAULTBINARY 15677 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETSOURCEDATATYPE_ENCODING_DEFAULTBINARY 15678 /* Object */ +#define UA_NS0ID_PUBLISHEDDATAITEMSDATATYPE_ENCODING_DEFAULTBINARY 15679 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR 15680 /* Object */ +#define UA_NS0ID_PUBLISHEDEVENTSDATATYPE_ENCODING_DEFAULTBINARY 15681 /* Object */ +#define UA_NS0ID_DATASETWRITERDATATYPE_ENCODING_DEFAULTBINARY 15682 /* Object */ +#define UA_NS0ID_DATASETWRITERTRANSPORTDATATYPE_ENCODING_DEFAULTBINARY 15683 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_ADDIDENTITY 15684 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_ADDIDENTITY_INPUTARGUMENTS 15685 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_REMOVEIDENTITY 15686 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_REMOVEIDENTITY_INPUTARGUMENTS 15687 /* Variable */ +#define UA_NS0ID_DATASETWRITERMESSAGEDATATYPE_ENCODING_DEFAULTBINARY 15688 /* Object */ +#define UA_NS0ID_PUBSUBGROUPDATATYPE_ENCODING_DEFAULTBINARY 15689 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BROKERCONNECTIONTRANSPORTDATATYPE_DICTIONARYFRAGMENT 15690 /* Variable */ +#define UA_NS0ID_WRITERGROUPTRANSPORTDATATYPE_ENCODING_DEFAULTBINARY 15691 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR 15692 /* Object */ +#define UA_NS0ID_WRITERGROUPMESSAGEDATATYPE_ENCODING_DEFAULTBINARY 15693 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONDATATYPE_ENCODING_DEFAULTBINARY 15694 /* Object */ +#define UA_NS0ID_CONNECTIONTRANSPORTDATATYPE_ENCODING_DEFAULTBINARY 15695 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_ADDIDENTITY 15696 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_ADDIDENTITY_INPUTARGUMENTS 15697 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_REMOVEIDENTITY 15698 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_REMOVEIDENTITY_INPUTARGUMENTS 15699 /* Variable */ +#define UA_NS0ID_SIMPLETYPEDESCRIPTION_ENCODING_DEFAULTJSON 15700 /* Object */ +#define UA_NS0ID_READERGROUPTRANSPORTDATATYPE_ENCODING_DEFAULTBINARY 15701 /* Object */ +#define UA_NS0ID_READERGROUPMESSAGEDATATYPE_ENCODING_DEFAULTBINARY 15702 /* Object */ +#define UA_NS0ID_DATASETREADERDATATYPE_ENCODING_DEFAULTBINARY 15703 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN 15704 /* Object */ +#define UA_NS0ID_DATASETREADERTRANSPORTDATATYPE_ENCODING_DEFAULTBINARY 15705 /* Object */ +#define UA_NS0ID_DATASETREADERMESSAGEDATATYPE_ENCODING_DEFAULTBINARY 15706 /* Object */ +#define UA_NS0ID_SUBSCRIBEDDATASETDATATYPE_ENCODING_DEFAULTBINARY 15707 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_ADDIDENTITY 15708 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_ADDIDENTITY_INPUTARGUMENTS 15709 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_REMOVEIDENTITY 15710 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_REMOVEIDENTITY_INPUTARGUMENTS 15711 /* Variable */ +#define UA_NS0ID_TARGETVARIABLESDATATYPE_ENCODING_DEFAULTBINARY 15712 /* Object */ +#define UA_NS0ID_SUBSCRIBEDDATASETMIRRORDATATYPE_ENCODING_DEFAULTBINARY 15713 /* Object */ +#define UA_NS0ID_UABINARYFILEDATATYPE_ENCODING_DEFAULTJSON 15714 /* Object */ +#define UA_NS0ID_UADPWRITERGROUPMESSAGEDATATYPE_ENCODING_DEFAULTBINARY 15715 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN 15716 /* Object */ +#define UA_NS0ID_UADPDATASETWRITERMESSAGEDATATYPE_ENCODING_DEFAULTBINARY 15717 /* Object */ +#define UA_NS0ID_UADPDATASETREADERMESSAGEDATATYPE_ENCODING_DEFAULTBINARY 15718 /* Object */ +#define UA_NS0ID_JSONWRITERGROUPMESSAGEDATATYPE_ENCODING_DEFAULTBINARY 15719 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_ADDIDENTITY 15720 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_ADDIDENTITY_INPUTARGUMENTS 15721 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_REMOVEIDENTITY 15722 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_REMOVEIDENTITY_INPUTARGUMENTS 15723 /* Variable */ +#define UA_NS0ID_JSONDATASETWRITERMESSAGEDATATYPE_ENCODING_DEFAULTBINARY 15724 /* Object */ +#define UA_NS0ID_JSONDATASETREADERMESSAGEDATATYPE_ENCODING_DEFAULTBINARY 15725 /* Object */ +#define UA_NS0ID_BROKERCONNECTIONTRANSPORTDATATYPE_ENCODING_DEFAULTJSON 15726 /* Object */ +#define UA_NS0ID_BROKERWRITERGROUPTRANSPORTDATATYPE_ENCODING_DEFAULTBINARY 15727 /* Object */ +#define UA_NS0ID_IDENTITYMAPPINGRULETYPE_ENCODING_DEFAULTXML 15728 /* Object */ +#define UA_NS0ID_BROKERDATASETWRITERTRANSPORTDATATYPE_ENCODING_DEFAULTBINARY 15729 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_IDENTITYMAPPINGRULETYPE 15730 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_IDENTITYMAPPINGRULETYPE_DATATYPEVERSION 15731 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_IDENTITYMAPPINGRULETYPE_DICTIONARYFRAGMENT 15732 /* Variable */ +#define UA_NS0ID_BROKERDATASETREADERTRANSPORTDATATYPE_ENCODING_DEFAULTBINARY 15733 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENDPOINTTYPE 15734 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENDPOINTTYPE_DATATYPEVERSION 15735 /* Variable */ +#define UA_NS0ID_IDENTITYMAPPINGRULETYPE_ENCODING_DEFAULTBINARY 15736 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENDPOINTTYPE_DICTIONARYFRAGMENT 15737 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_IDENTITYMAPPINGRULETYPE 15738 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_IDENTITYMAPPINGRULETYPE_DATATYPEVERSION 15739 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_IDENTITYMAPPINGRULETYPE_DICTIONARYFRAGMENT 15740 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATATYPESCHEMAHEADER 15741 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATATYPESCHEMAHEADER_DATATYPEVERSION 15742 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATATYPESCHEMAHEADER_DICTIONARYFRAGMENT 15743 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE 15744 /* ObjectType */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_CLIENTPROCESSINGTIMEOUT 15745 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_GENERATEFILEFORREAD 15746 /* Method */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_GENERATEFILEFORREAD_INPUTARGUMENTS 15747 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_GENERATEFILEFORREAD_OUTPUTARGUMENTS 15748 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_GENERATEFILEFORWRITE 15749 /* Method */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_GENERATEFILEFORWRITE_OUTPUTARGUMENTS 15750 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_CLOSEANDCOMMIT 15751 /* Method */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_CLOSEANDCOMMIT_INPUTARGUMENTS 15752 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_CLOSEANDCOMMIT_OUTPUTARGUMENTS 15753 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER 15754 /* Object */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_CURRENTSTATE 15755 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_CURRENTSTATE_ID 15756 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_CURRENTSTATE_NAME 15757 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_CURRENTSTATE_NUMBER 15758 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_CURRENTSTATE_EFFECTIVEDISPLAYNAME 15759 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_LASTTRANSITION 15760 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_LASTTRANSITION_ID 15761 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_LASTTRANSITION_NAME 15762 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_LASTTRANSITION_NUMBER 15763 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_LASTTRANSITION_TRANSITIONTIME 15764 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_LASTTRANSITION_EFFECTIVETRANSITIONTIME 15765 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDDATASETDATATYPE 15766 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDDATASETDATATYPE_DATATYPEVERSION 15767 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDDATASETDATATYPE_DICTIONARYFRAGMENT 15768 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDDATASETSOURCEDATATYPE 15769 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDDATASETSOURCEDATATYPE_DATATYPEVERSION 15770 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDDATASETSOURCEDATATYPE_DICTIONARYFRAGMENT 15771 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDDATAITEMSDATATYPE 15772 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDDATAITEMSDATATYPE_DATATYPEVERSION 15773 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDDATAITEMSDATATYPE_DICTIONARYFRAGMENT 15774 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDEVENTSDATATYPE 15775 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDEVENTSDATATYPE_DATATYPEVERSION 15776 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDEVENTSDATATYPE_DICTIONARYFRAGMENT 15777 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETWRITERDATATYPE 15778 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETWRITERDATATYPE_DATATYPEVERSION 15779 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETWRITERDATATYPE_DICTIONARYFRAGMENT 15780 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETWRITERTRANSPORTDATATYPE 15781 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETWRITERTRANSPORTDATATYPE_DATATYPEVERSION 15782 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETWRITERTRANSPORTDATATYPE_DICTIONARYFRAGMENT 15783 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETWRITERMESSAGEDATATYPE 15784 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETWRITERMESSAGEDATATYPE_DATATYPEVERSION 15785 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETWRITERMESSAGEDATATYPE_DICTIONARYFRAGMENT 15786 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBGROUPDATATYPE 15787 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBGROUPDATATYPE_DATATYPEVERSION 15788 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBGROUPDATATYPE_DICTIONARYFRAGMENT 15789 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER 15790 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_PUBLISHERID 15791 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_TRANSPORTPROFILEURI 15792 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_WRITERGROUPTRANSPORTDATATYPE 15793 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_RESET 15794 /* Method */ +#define UA_NS0ID_GENERATEFILEFORREADMETHODTYPE 15795 /* Method */ +#define UA_NS0ID_GENERATEFILEFORREADMETHODTYPE_INPUTARGUMENTS 15796 /* Variable */ +#define UA_NS0ID_GENERATEFILEFORREADMETHODTYPE_OUTPUTARGUMENTS 15797 /* Variable */ +#define UA_NS0ID_GENERATEFILEFORWRITEMETHODTYPE 15798 /* Method */ +#define UA_NS0ID_GENERATEFILEFORWRITEMETHODTYPE_OUTPUTARGUMENTS 15799 /* Variable */ +#define UA_NS0ID_CLOSEANDCOMMITMETHODTYPE 15800 /* Method */ +#define UA_NS0ID_CLOSEANDCOMMITMETHODTYPE_INPUTARGUMENTS 15801 /* Variable */ +#define UA_NS0ID_CLOSEANDCOMMITMETHODTYPE_OUTPUTARGUMENTS 15802 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE 15803 /* ObjectType */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_CURRENTSTATE 15804 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_CURRENTSTATE_ID 15805 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_CURRENTSTATE_NAME 15806 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_CURRENTSTATE_NUMBER 15807 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 15808 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_LASTTRANSITION 15809 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_LASTTRANSITION_ID 15810 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_LASTTRANSITION_NAME 15811 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_LASTTRANSITION_NUMBER 15812 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_LASTTRANSITION_TRANSITIONTIME 15813 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 15814 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_IDLE 15815 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_IDLE_STATENUMBER 15816 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_READPREPARE 15817 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_READPREPARE_STATENUMBER 15818 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_READTRANSFER 15819 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_READTRANSFER_STATENUMBER 15820 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_APPLYWRITE 15821 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_APPLYWRITE_STATENUMBER 15822 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_ERROR 15823 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_ERROR_STATENUMBER 15824 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_IDLETOREADPREPARE 15825 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_IDLETOREADPREPARE_TRANSITIONNUMBER 15826 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_READPREPARETOREADTRANSFER 15827 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_READPREPARETOREADTRANSFER_TRANSITIONNUMBER 15828 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_READTRANSFERTOIDLE 15829 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_READTRANSFERTOIDLE_TRANSITIONNUMBER 15830 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_IDLETOAPPLYWRITE 15831 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_IDLETOAPPLYWRITE_TRANSITIONNUMBER 15832 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_APPLYWRITETOIDLE 15833 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_APPLYWRITETOIDLE_TRANSITIONNUMBER 15834 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_READPREPARETOERROR 15835 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_READPREPARETOERROR_TRANSITIONNUMBER 15836 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_READTRANSFERTOERROR 15837 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_READTRANSFERTOERROR_TRANSITIONNUMBER 15838 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_APPLYWRITETOERROR 15839 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_APPLYWRITETOERROR_TRANSITIONNUMBER 15840 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_ERRORTOIDLE 15841 /* Object */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_ERRORTOIDLE_TRANSITIONNUMBER 15842 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_RESET 15843 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_STATUS 15844 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_STATUS_STATE 15845 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_STATUS_ENABLE 15846 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_STATUS_DISABLE 15847 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_TRANSPORTPROFILEURI_SELECTIONS 15848 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_TRANSPORTPROFILEURI_SELECTIONDESCRIPTIONS 15849 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_TRANSPORTPROFILEURI_RESTRICTTOLIST 15850 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_ADDRESS 15851 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_WRITERGROUPTRANSPORTDATATYPE_DATATYPEVERSION 15852 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_WRITERGROUPTRANSPORTDATATYPE_DICTIONARYFRAGMENT 15853 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_WRITERGROUPMESSAGEDATATYPE 15854 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_WRITERGROUPMESSAGEDATATYPE_DATATYPEVERSION 15855 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_WRITERGROUPMESSAGEDATATYPE_DICTIONARYFRAGMENT 15856 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONNECTIONDATATYPE 15857 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONNECTIONDATATYPE_DATATYPEVERSION 15858 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONNECTIONDATATYPE_DICTIONARYFRAGMENT 15859 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CONNECTIONTRANSPORTDATATYPE 15860 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CONNECTIONTRANSPORTDATATYPE_DATATYPEVERSION 15861 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CONNECTIONTRANSPORTDATATYPE_DICTIONARYFRAGMENT 15862 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_ADDRESS_NETWORKINTERFACE 15863 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_TRANSPORTSETTINGS 15864 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_STATUS 15865 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_READERGROUPTRANSPORTDATATYPE 15866 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_READERGROUPTRANSPORTDATATYPE_DATATYPEVERSION 15867 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_READERGROUPTRANSPORTDATATYPE_DICTIONARYFRAGMENT 15868 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_READERGROUPMESSAGEDATATYPE 15869 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_READERGROUPMESSAGEDATATYPE_DATATYPEVERSION 15870 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_READERGROUPMESSAGEDATATYPE_DICTIONARYFRAGMENT 15871 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETREADERDATATYPE 15872 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETREADERDATATYPE_DATATYPEVERSION 15873 /* Variable */ +#define UA_NS0ID_OVERRIDEVALUEHANDLING 15874 /* DataType */ +#define UA_NS0ID_OVERRIDEVALUEHANDLING_ENUMSTRINGS 15875 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETREADERDATATYPE_DICTIONARYFRAGMENT 15876 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETREADERTRANSPORTDATATYPE 15877 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETREADERTRANSPORTDATATYPE_DATATYPEVERSION 15878 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETREADERTRANSPORTDATATYPE_DICTIONARYFRAGMENT 15879 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETREADERMESSAGEDATATYPE 15880 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETREADERMESSAGEDATATYPE_DATATYPEVERSION 15881 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATASETREADERMESSAGEDATATYPE_DICTIONARYFRAGMENT 15882 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SUBSCRIBEDDATASETDATATYPE 15883 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SUBSCRIBEDDATASETDATATYPE_DATATYPEVERSION 15884 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SUBSCRIBEDDATASETDATATYPE_DICTIONARYFRAGMENT 15885 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TARGETVARIABLESDATATYPE 15886 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TARGETVARIABLESDATATYPE_DATATYPEVERSION 15887 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TARGETVARIABLESDATATYPE_DICTIONARYFRAGMENT 15888 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SUBSCRIBEDDATASETMIRRORDATATYPE 15889 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SUBSCRIBEDDATASETMIRRORDATATYPE_DATATYPEVERSION 15890 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SUBSCRIBEDDATASETMIRRORDATATYPE_DICTIONARYFRAGMENT 15891 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_STATUS_STATE 15892 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_STATUS_ENABLE 15893 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_STATUS_DISABLE 15894 /* Method */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UADPWRITERGROUPMESSAGEDATATYPE 15895 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UADPWRITERGROUPMESSAGEDATATYPE_DATATYPEVERSION 15896 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UADPWRITERGROUPMESSAGEDATATYPE_DICTIONARYFRAGMENT 15897 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UADPDATASETWRITERMESSAGEDATATYPE 15898 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UADPDATASETWRITERMESSAGEDATATYPE_DATATYPEVERSION 15899 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UADPDATASETWRITERMESSAGEDATATYPE_DICTIONARYFRAGMENT 15900 /* Variable */ +#define UA_NS0ID_SESSIONLESSINVOKEREQUESTTYPE 15901 /* DataType */ +#define UA_NS0ID_SESSIONLESSINVOKEREQUESTTYPE_ENCODING_DEFAULTXML 15902 /* Object */ +#define UA_NS0ID_SESSIONLESSINVOKEREQUESTTYPE_ENCODING_DEFAULTBINARY 15903 /* Object */ +#define UA_NS0ID_DATASETFIELDFLAGS 15904 /* DataType */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_TRANSPORTSETTINGS 15905 /* Object */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE 15906 /* ObjectType */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_GETSECURITYKEYS 15907 /* Method */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_GETSECURITYKEYS_INPUTARGUMENTS 15908 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_GETSECURITYKEYS_OUTPUTARGUMENTS 15909 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_GETSECURITYGROUP 15910 /* Method */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_GETSECURITYGROUP_INPUTARGUMENTS 15911 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_GETSECURITYGROUP_OUTPUTARGUMENTS 15912 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_SECURITYGROUPS 15913 /* Object */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_SECURITYGROUPS_ADDSECURITYGROUP 15914 /* Method */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_SECURITYGROUPS_ADDSECURITYGROUP_INPUTARGUMENTS 15915 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_SECURITYGROUPS_ADDSECURITYGROUP_OUTPUTARGUMENTS 15916 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_SECURITYGROUPS_REMOVESECURITYGROUP 15917 /* Method */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_SECURITYGROUPS_REMOVESECURITYGROUP_INPUTARGUMENTS 15918 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UADPDATASETREADERMESSAGEDATATYPE 15919 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UADPDATASETREADERMESSAGEDATATYPE_DATATYPEVERSION 15920 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UADPDATASETREADERMESSAGEDATATYPE_DICTIONARYFRAGMENT 15921 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_JSONWRITERGROUPMESSAGEDATATYPE 15922 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_JSONWRITERGROUPMESSAGEDATATYPE_DATATYPEVERSION 15923 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_JSONWRITERGROUPMESSAGEDATATYPE_DICTIONARYFRAGMENT 15924 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_JSONDATASETWRITERMESSAGEDATATYPE 15925 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPE_SECURITYMODE 15926 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPE_SECURITYGROUPID 15927 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPE_SECURITYKEYSERVICES 15928 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_JSONDATASETWRITERMESSAGEDATATYPE_DATATYPEVERSION 15929 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_JSONDATASETWRITERMESSAGEDATATYPE_DICTIONARYFRAGMENT 15930 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_JSONDATASETREADERMESSAGEDATATYPE 15931 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_SECURITYMODE 15932 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_SECURITYGROUPID 15933 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_SECURITYKEYSERVICES 15934 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_JSONDATASETREADERMESSAGEDATATYPE_DATATYPEVERSION 15935 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_JSONDATASETREADERMESSAGEDATATYPE_DICTIONARYFRAGMENT 15936 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS 15937 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_DIAGNOSTICSLEVEL 15938 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION 15939 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BROKERWRITERGROUPTRANSPORTDATATYPE 15940 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BROKERWRITERGROUPTRANSPORTDATATYPE_DATATYPEVERSION 15941 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BROKERWRITERGROUPTRANSPORTDATATYPE_DICTIONARYFRAGMENT 15942 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BROKERDATASETWRITERTRANSPORTDATATYPE 15943 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BROKERDATASETWRITERTRANSPORTDATATYPE_DATATYPEVERSION 15944 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BROKERDATASETWRITERTRANSPORTDATATYPE_DICTIONARYFRAGMENT 15945 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BROKERDATASETREADERTRANSPORTDATATYPE 15946 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BROKERDATASETREADERTRANSPORTDATATYPE_DATATYPEVERSION 15947 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_BROKERDATASETREADERTRANSPORTDATATYPE_DICTIONARYFRAGMENT 15948 /* Variable */ +#define UA_NS0ID_ENDPOINTTYPE_ENCODING_DEFAULTXML 15949 /* Object */ +#define UA_NS0ID_DATATYPESCHEMAHEADER_ENCODING_DEFAULTXML 15950 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETDATATYPE_ENCODING_DEFAULTXML 15951 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETSOURCEDATATYPE_ENCODING_DEFAULTXML 15952 /* Object */ +#define UA_NS0ID_PUBLISHEDDATAITEMSDATATYPE_ENCODING_DEFAULTXML 15953 /* Object */ +#define UA_NS0ID_PUBLISHEDEVENTSDATATYPE_ENCODING_DEFAULTXML 15954 /* Object */ +#define UA_NS0ID_DATASETWRITERDATATYPE_ENCODING_DEFAULTXML 15955 /* Object */ +#define UA_NS0ID_DATASETWRITERTRANSPORTDATATYPE_ENCODING_DEFAULTXML 15956 /* Object */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA 15957 /* Object */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEURI 15958 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEVERSION 15959 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEPUBLICATIONDATE 15960 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_ISNAMESPACESUBSET 15961 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_STATICNODEIDTYPES 15962 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_STATICNUMERICNODEIDRANGE 15963 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_STATICSTRINGNODEIDPATTERN 15964 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE 15965 /* Object */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_SIZE 15966 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_WRITABLE 15967 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_USERWRITABLE 15968 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_OPENCOUNT 15969 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_MIMETYPE 15970 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_OPEN 15971 /* Method */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_OPEN_INPUTARGUMENTS 15972 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_OPEN_OUTPUTARGUMENTS 15973 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_CLOSE 15974 /* Method */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_CLOSE_INPUTARGUMENTS 15975 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_READ 15976 /* Method */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_READ_INPUTARGUMENTS 15977 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_READ_OUTPUTARGUMENTS 15978 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_WRITE 15979 /* Method */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_WRITE_INPUTARGUMENTS 15980 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_GETPOSITION 15981 /* Method */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_GETPOSITION_INPUTARGUMENTS 15982 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_GETPOSITION_OUTPUTARGUMENTS 15983 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_SETPOSITION 15984 /* Method */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_SETPOSITION_INPUTARGUMENTS 15985 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_EXPORTNAMESPACE 15986 /* Method */ +#define UA_NS0ID_DATASETWRITERMESSAGEDATATYPE_ENCODING_DEFAULTXML 15987 /* Object */ +#define UA_NS0ID_PUBSUBGROUPDATATYPE_ENCODING_DEFAULTXML 15988 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 15989 /* Variable */ +#define UA_NS0ID_WRITERGROUPTRANSPORTDATATYPE_ENCODING_DEFAULTXML 15990 /* Object */ +#define UA_NS0ID_WRITERGROUPMESSAGEDATATYPE_ENCODING_DEFAULTXML 15991 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONDATATYPE_ENCODING_DEFAULTXML 15992 /* Object */ +#define UA_NS0ID_CONNECTIONTRANSPORTDATATYPE_ENCODING_DEFAULTXML 15993 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 15994 /* Variable */ +#define UA_NS0ID_READERGROUPTRANSPORTDATATYPE_ENCODING_DEFAULTXML 15995 /* Object */ +#define UA_NS0ID_READERGROUPMESSAGEDATATYPE_ENCODING_DEFAULTXML 15996 /* Object */ +#define UA_NS0ID_ROLESETTYPE_ADDROLE 15997 /* Method */ +#define UA_NS0ID_ROLESETTYPE_ADDROLE_INPUTARGUMENTS 15998 /* Variable */ +#define UA_NS0ID_ROLESETTYPE_ADDROLE_OUTPUTARGUMENTS 15999 /* Variable */ +#define UA_NS0ID_ROLESETTYPE_REMOVEROLE 16000 /* Method */ +#define UA_NS0ID_ROLESETTYPE_REMOVEROLE_INPUTARGUMENTS 16001 /* Variable */ +#define UA_NS0ID_ADDROLEMETHODTYPE 16002 /* Method */ +#define UA_NS0ID_ADDROLEMETHODTYPE_INPUTARGUMENTS 16003 /* Variable */ +#define UA_NS0ID_ADDROLEMETHODTYPE_OUTPUTARGUMENTS 16004 /* Variable */ +#define UA_NS0ID_REMOVEROLEMETHODTYPE 16005 /* Method */ +#define UA_NS0ID_REMOVEROLEMETHODTYPE_INPUTARGUMENTS 16006 /* Variable */ +#define UA_NS0ID_DATASETREADERDATATYPE_ENCODING_DEFAULTXML 16007 /* Object */ +#define UA_NS0ID_DATASETREADERTRANSPORTDATATYPE_ENCODING_DEFAULTXML 16008 /* Object */ +#define UA_NS0ID_DATASETREADERMESSAGEDATATYPE_ENCODING_DEFAULTXML 16009 /* Object */ +#define UA_NS0ID_SUBSCRIBEDDATASETDATATYPE_ENCODING_DEFAULTXML 16010 /* Object */ +#define UA_NS0ID_TARGETVARIABLESDATATYPE_ENCODING_DEFAULTXML 16011 /* Object */ +#define UA_NS0ID_SUBSCRIBEDDATASETMIRRORDATATYPE_ENCODING_DEFAULTXML 16012 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 16013 /* Variable */ +#define UA_NS0ID_UADPWRITERGROUPMESSAGEDATATYPE_ENCODING_DEFAULTXML 16014 /* Object */ +#define UA_NS0ID_UADPDATASETWRITERMESSAGEDATATYPE_ENCODING_DEFAULTXML 16015 /* Object */ +#define UA_NS0ID_UADPDATASETREADERMESSAGEDATATYPE_ENCODING_DEFAULTXML 16016 /* Object */ +#define UA_NS0ID_JSONWRITERGROUPMESSAGEDATATYPE_ENCODING_DEFAULTXML 16017 /* Object */ +#define UA_NS0ID_JSONDATASETWRITERMESSAGEDATATYPE_ENCODING_DEFAULTXML 16018 /* Object */ +#define UA_NS0ID_JSONDATASETREADERMESSAGEDATATYPE_ENCODING_DEFAULTXML 16019 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 16020 /* Variable */ +#define UA_NS0ID_BROKERWRITERGROUPTRANSPORTDATATYPE_ENCODING_DEFAULTXML 16021 /* Object */ +#define UA_NS0ID_BROKERDATASETWRITERTRANSPORTDATATYPE_ENCODING_DEFAULTXML 16022 /* Object */ +#define UA_NS0ID_BROKERDATASETREADERTRANSPORTDATATYPE_ENCODING_DEFAULTXML 16023 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENDPOINTTYPE 16024 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENDPOINTTYPE_DATATYPEVERSION 16025 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENDPOINTTYPE_DICTIONARYFRAGMENT 16026 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATATYPESCHEMAHEADER 16027 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATATYPESCHEMAHEADER_DATATYPEVERSION 16028 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATATYPESCHEMAHEADER_DICTIONARYFRAGMENT 16029 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDDATASETDATATYPE 16030 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDDATASETDATATYPE_DATATYPEVERSION 16031 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDDATASETDATATYPE_DICTIONARYFRAGMENT 16032 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDDATASETSOURCEDATATYPE 16033 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDDATASETSOURCEDATATYPE_DATATYPEVERSION 16034 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDDATASETSOURCEDATATYPE_DICTIONARYFRAGMENT 16035 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER 16036 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDDATAITEMSDATATYPE 16037 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDDATAITEMSDATATYPE_DATATYPEVERSION 16038 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDDATAITEMSDATATYPE_DICTIONARYFRAGMENT 16039 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDEVENTSDATATYPE 16040 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_ADDIDENTITY 16041 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_ADDIDENTITY_INPUTARGUMENTS 16042 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_REMOVEIDENTITY 16043 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_REMOVEIDENTITY_INPUTARGUMENTS 16044 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDEVENTSDATATYPE_DATATYPEVERSION 16045 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDEVENTSDATATYPE_DICTIONARYFRAGMENT 16046 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETWRITERDATATYPE 16047 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETWRITERDATATYPE_DATATYPEVERSION 16048 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETWRITERDATATYPE_DICTIONARYFRAGMENT 16049 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETWRITERTRANSPORTDATATYPE 16050 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETWRITERTRANSPORTDATATYPE_DATATYPEVERSION 16051 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETWRITERTRANSPORTDATATYPE_DICTIONARYFRAGMENT 16052 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETWRITERMESSAGEDATATYPE 16053 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETWRITERMESSAGEDATATYPE_DATATYPEVERSION 16054 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETWRITERMESSAGEDATATYPE_DICTIONARYFRAGMENT 16055 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBGROUPDATATYPE 16056 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBGROUPDATATYPE_DATATYPEVERSION 16057 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBGROUPDATATYPE_DICTIONARYFRAGMENT 16058 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR 16059 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_ACTIVE 16060 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 16061 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_WRITERGROUPTRANSPORTDATATYPE 16062 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_WRITERGROUPTRANSPORTDATATYPE_DATATYPEVERSION 16063 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_WRITERGROUPTRANSPORTDATATYPE_DICTIONARYFRAGMENT 16064 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_WRITERGROUPMESSAGEDATATYPE 16065 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_WRITERGROUPMESSAGEDATATYPE_DATATYPEVERSION 16066 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_WRITERGROUPMESSAGEDATATYPE_DICTIONARYFRAGMENT 16067 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONNECTIONDATATYPE 16068 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONNECTIONDATATYPE_DATATYPEVERSION 16069 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONNECTIONDATATYPE_DICTIONARYFRAGMENT 16070 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CONNECTIONTRANSPORTDATATYPE 16071 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CONNECTIONTRANSPORTDATATYPE_DATATYPEVERSION 16072 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CONNECTIONTRANSPORTDATATYPE_DICTIONARYFRAGMENT 16073 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 16074 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 16075 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_RESET 16076 /* Method */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_READERGROUPTRANSPORTDATATYPE 16077 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_READERGROUPTRANSPORTDATATYPE_DATATYPEVERSION 16078 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_READERGROUPTRANSPORTDATATYPE_DICTIONARYFRAGMENT 16079 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_READERGROUPMESSAGEDATATYPE 16080 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_READERGROUPMESSAGEDATATYPE_DATATYPEVERSION 16081 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_READERGROUPMESSAGEDATATYPE_DICTIONARYFRAGMENT 16082 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETREADERDATATYPE 16083 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETREADERDATATYPE_DATATYPEVERSION 16084 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETREADERDATATYPE_DICTIONARYFRAGMENT 16085 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETREADERTRANSPORTDATATYPE 16086 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETREADERTRANSPORTDATATYPE_DATATYPEVERSION 16087 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETREADERTRANSPORTDATATYPE_DICTIONARYFRAGMENT 16088 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETREADERMESSAGEDATATYPE 16089 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETREADERMESSAGEDATATYPE_DATATYPEVERSION 16090 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATASETREADERMESSAGEDATATYPE_DICTIONARYFRAGMENT 16091 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SUBSCRIBEDDATASETDATATYPE 16092 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SUBSCRIBEDDATASETDATATYPE_DATATYPEVERSION 16093 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SUBSCRIBEDDATASETDATATYPE_DICTIONARYFRAGMENT 16094 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TARGETVARIABLESDATATYPE 16095 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TARGETVARIABLESDATATYPE_DATATYPEVERSION 16096 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TARGETVARIABLESDATATYPE_DICTIONARYFRAGMENT 16097 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SUBSCRIBEDDATASETMIRRORDATATYPE 16098 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SUBSCRIBEDDATASETMIRRORDATATYPE_DATATYPEVERSION 16099 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SUBSCRIBEDDATASETMIRRORDATATYPE_DICTIONARYFRAGMENT 16100 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_SUBERROR 16101 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS 16102 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR 16103 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UADPWRITERGROUPMESSAGEDATATYPE 16104 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UADPWRITERGROUPMESSAGEDATATYPE_DATATYPEVERSION 16105 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UADPWRITERGROUPMESSAGEDATATYPE_DICTIONARYFRAGMENT 16106 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UADPDATASETWRITERMESSAGEDATATYPE 16107 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UADPDATASETWRITERMESSAGEDATATYPE_DATATYPEVERSION 16108 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UADPDATASETWRITERMESSAGEDATATYPE_DICTIONARYFRAGMENT 16109 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UADPDATASETREADERMESSAGEDATATYPE 16110 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UADPDATASETREADERMESSAGEDATATYPE_DATATYPEVERSION 16111 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UADPDATASETREADERMESSAGEDATATYPE_DICTIONARYFRAGMENT 16112 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_JSONWRITERGROUPMESSAGEDATATYPE 16113 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_JSONWRITERGROUPMESSAGEDATATYPE_DATATYPEVERSION 16114 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_JSONWRITERGROUPMESSAGEDATATYPE_DICTIONARYFRAGMENT 16115 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_JSONDATASETWRITERMESSAGEDATATYPE 16116 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_JSONDATASETWRITERMESSAGEDATATYPE_DATATYPEVERSION 16117 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_JSONDATASETWRITERMESSAGEDATATYPE_DICTIONARYFRAGMENT 16118 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_JSONDATASETREADERMESSAGEDATATYPE 16119 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_JSONDATASETREADERMESSAGEDATATYPE_DATATYPEVERSION 16120 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_JSONDATASETREADERMESSAGEDATATYPE_DICTIONARYFRAGMENT 16121 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 16122 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 16123 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 16124 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BROKERWRITERGROUPTRANSPORTDATATYPE 16125 /* Variable */ +#define UA_NS0ID_ROLEPERMISSIONTYPE_ENCODING_DEFAULTXML 16126 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ROLEPERMISSIONTYPE 16127 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ROLEPERMISSIONTYPE_DATATYPEVERSION 16128 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ROLEPERMISSIONTYPE_DICTIONARYFRAGMENT 16129 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BROKERWRITERGROUPTRANSPORTDATATYPE_DATATYPEVERSION 16130 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ROLEPERMISSIONTYPE 16131 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ROLEPERMISSIONTYPE_DATATYPEVERSION 16132 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ROLEPERMISSIONTYPE_DICTIONARYFRAGMENT 16133 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_DEFAULTROLEPERMISSIONS 16134 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_DEFAULTUSERROLEPERMISSIONS 16135 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_DEFAULTACCESSRESTRICTIONS 16136 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_DEFAULTROLEPERMISSIONS 16137 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_DEFAULTUSERROLEPERMISSIONS 16138 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_DEFAULTACCESSRESTRICTIONS 16139 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_DEFAULTROLEPERMISSIONS 16140 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_DEFAULTUSERROLEPERMISSIONS 16141 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_DEFAULTACCESSRESTRICTIONS 16142 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BROKERWRITERGROUPTRANSPORTDATATYPE_DICTIONARYFRAGMENT 16143 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BROKERDATASETWRITERTRANSPORTDATATYPE 16144 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BROKERDATASETWRITERTRANSPORTDATATYPE_DATATYPEVERSION 16145 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BROKERDATASETWRITERTRANSPORTDATATYPE_DICTIONARYFRAGMENT 16146 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BROKERDATASETREADERTRANSPORTDATATYPE 16147 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BROKERDATASETREADERTRANSPORTDATATYPE_DATATYPEVERSION 16148 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_BROKERDATASETREADERTRANSPORTDATATYPE_DICTIONARYFRAGMENT 16149 /* Variable */ +#define UA_NS0ID_ENDPOINTTYPE_ENCODING_DEFAULTJSON 16150 /* Object */ +#define UA_NS0ID_DATATYPESCHEMAHEADER_ENCODING_DEFAULTJSON 16151 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETDATATYPE_ENCODING_DEFAULTJSON 16152 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETSOURCEDATATYPE_ENCODING_DEFAULTJSON 16153 /* Object */ +#define UA_NS0ID_PUBLISHEDDATAITEMSDATATYPE_ENCODING_DEFAULTJSON 16154 /* Object */ +#define UA_NS0ID_PUBLISHEDEVENTSDATATYPE_ENCODING_DEFAULTJSON 16155 /* Object */ +#define UA_NS0ID_DATASETWRITERDATATYPE_ENCODING_DEFAULTJSON 16156 /* Object */ +#define UA_NS0ID_DATASETWRITERTRANSPORTDATATYPE_ENCODING_DEFAULTJSON 16157 /* Object */ +#define UA_NS0ID_DATASETWRITERMESSAGEDATATYPE_ENCODING_DEFAULTJSON 16158 /* Object */ +#define UA_NS0ID_PUBSUBGROUPDATATYPE_ENCODING_DEFAULTJSON 16159 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 16160 /* Variable */ +#define UA_NS0ID_WRITERGROUPTRANSPORTDATATYPE_ENCODING_DEFAULTJSON 16161 /* Object */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_IDENTITIES 16162 /* Variable */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_APPLICATIONS 16163 /* Variable */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_ENDPOINTS 16164 /* Variable */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_ADDAPPLICATION 16165 /* Method */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_ADDAPPLICATION_INPUTARGUMENTS 16166 /* Variable */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_REMOVEAPPLICATION 16167 /* Method */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_REMOVEAPPLICATION_INPUTARGUMENTS 16168 /* Variable */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_ADDENDPOINT 16169 /* Method */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_ADDENDPOINT_INPUTARGUMENTS 16170 /* Variable */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_REMOVEENDPOINT 16171 /* Method */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_REMOVEENDPOINT_INPUTARGUMENTS 16172 /* Variable */ +#define UA_NS0ID_ROLETYPE_IDENTITIES 16173 /* Variable */ +#define UA_NS0ID_ROLETYPE_APPLICATIONS 16174 /* Variable */ +#define UA_NS0ID_ROLETYPE_ENDPOINTS 16175 /* Variable */ +#define UA_NS0ID_ROLETYPE_ADDAPPLICATION 16176 /* Method */ +#define UA_NS0ID_ROLETYPE_ADDAPPLICATION_INPUTARGUMENTS 16177 /* Variable */ +#define UA_NS0ID_ROLETYPE_REMOVEAPPLICATION 16178 /* Method */ +#define UA_NS0ID_ROLETYPE_REMOVEAPPLICATION_INPUTARGUMENTS 16179 /* Variable */ +#define UA_NS0ID_ROLETYPE_ADDENDPOINT 16180 /* Method */ +#define UA_NS0ID_ROLETYPE_ADDENDPOINT_INPUTARGUMENTS 16181 /* Variable */ +#define UA_NS0ID_ROLETYPE_REMOVEENDPOINT 16182 /* Method */ +#define UA_NS0ID_ROLETYPE_REMOVEENDPOINT_INPUTARGUMENTS 16183 /* Variable */ +#define UA_NS0ID_ADDAPPLICATIONMETHODTYPE 16184 /* Method */ +#define UA_NS0ID_ADDAPPLICATIONMETHODTYPE_INPUTARGUMENTS 16185 /* Variable */ +#define UA_NS0ID_REMOVEAPPLICATIONMETHODTYPE 16186 /* Method */ +#define UA_NS0ID_REMOVEAPPLICATIONMETHODTYPE_INPUTARGUMENTS 16187 /* Variable */ +#define UA_NS0ID_ADDENDPOINTMETHODTYPE 16188 /* Method */ +#define UA_NS0ID_ADDENDPOINTMETHODTYPE_INPUTARGUMENTS 16189 /* Variable */ +#define UA_NS0ID_REMOVEENDPOINTMETHODTYPE 16190 /* Method */ +#define UA_NS0ID_REMOVEENDPOINTMETHODTYPE_INPUTARGUMENTS 16191 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_IDENTITIES 16192 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_APPLICATIONS 16193 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_ENDPOINTS 16194 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_ADDAPPLICATION 16195 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_ADDAPPLICATION_INPUTARGUMENTS 16196 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_REMOVEAPPLICATION 16197 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_REMOVEAPPLICATION_INPUTARGUMENTS 16198 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_ADDENDPOINT 16199 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_ADDENDPOINT_INPUTARGUMENTS 16200 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_REMOVEENDPOINT 16201 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_REMOVEENDPOINT_INPUTARGUMENTS 16202 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_IDENTITIES 16203 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_APPLICATIONS 16204 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_ENDPOINTS 16205 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_ADDAPPLICATION 16206 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_ADDAPPLICATION_INPUTARGUMENTS 16207 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_REMOVEAPPLICATION 16208 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_REMOVEAPPLICATION_INPUTARGUMENTS 16209 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_ADDENDPOINT 16210 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_ADDENDPOINT_INPUTARGUMENTS 16211 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_REMOVEENDPOINT 16212 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_REMOVEENDPOINT_INPUTARGUMENTS 16213 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_IDENTITIES 16214 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_APPLICATIONS 16215 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_ENDPOINTS 16216 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_ADDAPPLICATION 16217 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_ADDAPPLICATION_INPUTARGUMENTS 16218 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_REMOVEAPPLICATION 16219 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_REMOVEAPPLICATION_INPUTARGUMENTS 16220 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_ADDENDPOINT 16221 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_ADDENDPOINT_INPUTARGUMENTS 16222 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_REMOVEENDPOINT 16223 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_REMOVEENDPOINT_INPUTARGUMENTS 16224 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_IDENTITIES 16225 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_APPLICATIONS 16226 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_ENDPOINTS 16227 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_ADDAPPLICATION 16228 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_ADDAPPLICATION_INPUTARGUMENTS 16229 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_REMOVEAPPLICATION 16230 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_REMOVEAPPLICATION_INPUTARGUMENTS 16231 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_ADDENDPOINT 16232 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_ADDENDPOINT_INPUTARGUMENTS 16233 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_REMOVEENDPOINT 16234 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_REMOVEENDPOINT_INPUTARGUMENTS 16235 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_IDENTITIES 16236 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_APPLICATIONS 16237 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_ENDPOINTS 16238 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_ADDAPPLICATION 16239 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_ADDAPPLICATION_INPUTARGUMENTS 16240 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_REMOVEAPPLICATION 16241 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_REMOVEAPPLICATION_INPUTARGUMENTS 16242 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_ADDENDPOINT 16243 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_ADDENDPOINT_INPUTARGUMENTS 16244 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_REMOVEENDPOINT 16245 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_REMOVEENDPOINT_INPUTARGUMENTS 16246 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_IDENTITIES 16247 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_APPLICATIONS 16248 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_ENDPOINTS 16249 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_ADDAPPLICATION 16250 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_ADDAPPLICATION_INPUTARGUMENTS 16251 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_REMOVEAPPLICATION 16252 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_REMOVEAPPLICATION_INPUTARGUMENTS 16253 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_ADDENDPOINT 16254 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_ADDENDPOINT_INPUTARGUMENTS 16255 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_REMOVEENDPOINT 16256 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_REMOVEENDPOINT_INPUTARGUMENTS 16257 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_IDENTITIES 16258 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_APPLICATIONS 16259 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_ENDPOINTS 16260 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_ADDAPPLICATION 16261 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_ADDAPPLICATION_INPUTARGUMENTS 16262 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_REMOVEAPPLICATION 16263 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_REMOVEAPPLICATION_INPUTARGUMENTS 16264 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_ADDENDPOINT 16265 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_ADDENDPOINT_INPUTARGUMENTS 16266 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_REMOVEENDPOINT 16267 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_REMOVEENDPOINT_INPUTARGUMENTS 16268 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_IDENTITIES 16269 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_APPLICATIONS 16270 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_ENDPOINTS 16271 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_ADDAPPLICATION 16272 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_ADDAPPLICATION_INPUTARGUMENTS 16273 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_REMOVEAPPLICATION 16274 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_REMOVEAPPLICATION_INPUTARGUMENTS 16275 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_ADDENDPOINT 16276 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_ADDENDPOINT_INPUTARGUMENTS 16277 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_REMOVEENDPOINT 16278 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_REMOVEENDPOINT_INPUTARGUMENTS 16279 /* Variable */ +#define UA_NS0ID_WRITERGROUPMESSAGEDATATYPE_ENCODING_DEFAULTJSON 16280 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONDATATYPE_ENCODING_DEFAULTJSON 16281 /* Object */ +#define UA_NS0ID_CONNECTIONTRANSPORTDATATYPE_ENCODING_DEFAULTJSON 16282 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 16283 /* Variable */ +#define UA_NS0ID_READERGROUPTRANSPORTDATATYPE_ENCODING_DEFAULTJSON 16284 /* Object */ +#define UA_NS0ID_READERGROUPMESSAGEDATATYPE_ENCODING_DEFAULTJSON 16285 /* Object */ +#define UA_NS0ID_DATASETREADERDATATYPE_ENCODING_DEFAULTJSON 16286 /* Object */ +#define UA_NS0ID_DATASETREADERTRANSPORTDATATYPE_ENCODING_DEFAULTJSON 16287 /* Object */ +#define UA_NS0ID_DATASETREADERMESSAGEDATATYPE_ENCODING_DEFAULTJSON 16288 /* Object */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_ROLESET 16289 /* Object */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_ROLESET_ADDROLE 16290 /* Method */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_ROLESET_ADDROLE_INPUTARGUMENTS 16291 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_ROLESET_ADDROLE_OUTPUTARGUMENTS 16292 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_ROLESET_REMOVEROLE 16293 /* Method */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_ROLESET_REMOVEROLE_INPUTARGUMENTS 16294 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_ROLESET 16295 /* Object */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_ROLESET_ADDROLE 16296 /* Method */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_ROLESET_ADDROLE_INPUTARGUMENTS 16297 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_ROLESET_ADDROLE_OUTPUTARGUMENTS 16298 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_ROLESET_REMOVEROLE 16299 /* Method */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_ROLESET_REMOVEROLE_INPUTARGUMENTS 16300 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_ROLESET_ADDROLE 16301 /* Method */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_ROLESET_ADDROLE_INPUTARGUMENTS 16302 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_ROLESET_ADDROLE_OUTPUTARGUMENTS 16303 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_ROLESET_REMOVEROLE 16304 /* Method */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_ROLESET_REMOVEROLE_INPUTARGUMENTS 16305 /* Variable */ +#define UA_NS0ID_AUDIODATATYPE 16307 /* DataType */ +#define UA_NS0ID_SUBSCRIBEDDATASETDATATYPE_ENCODING_DEFAULTJSON 16308 /* Object */ +#define UA_NS0ID_SELECTIONLISTTYPE 16309 /* VariableType */ +#define UA_NS0ID_TARGETVARIABLESDATATYPE_ENCODING_DEFAULTJSON 16310 /* Object */ +#define UA_NS0ID_SUBSCRIBEDDATASETMIRRORDATATYPE_ENCODING_DEFAULTJSON 16311 /* Object */ +#define UA_NS0ID_SELECTIONLISTTYPE_RESTRICTTOLIST 16312 /* Variable */ +#define UA_NS0ID_ADDITIONALPARAMETERSTYPE 16313 /* DataType */ +#define UA_NS0ID_FILESYSTEM 16314 /* Object */ +#define UA_NS0ID_FILESYSTEM_FILEDIRECTORYNAME_PLACEHOLDER 16315 /* Object */ +#define UA_NS0ID_FILESYSTEM_FILEDIRECTORYNAME_PLACEHOLDER_CREATEDIRECTORY 16316 /* Method */ +#define UA_NS0ID_FILESYSTEM_FILEDIRECTORYNAME_PLACEHOLDER_CREATEDIRECTORY_INPUTARGUMENTS 16317 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILEDIRECTORYNAME_PLACEHOLDER_CREATEDIRECTORY_OUTPUTARGUMENTS 16318 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILEDIRECTORYNAME_PLACEHOLDER_CREATEFILE 16319 /* Method */ +#define UA_NS0ID_FILESYSTEM_FILEDIRECTORYNAME_PLACEHOLDER_CREATEFILE_INPUTARGUMENTS 16320 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILEDIRECTORYNAME_PLACEHOLDER_CREATEFILE_OUTPUTARGUMENTS 16321 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 16322 /* Variable */ +#define UA_NS0ID_UADPWRITERGROUPMESSAGEDATATYPE_ENCODING_DEFAULTJSON 16323 /* Object */ +#define UA_NS0ID_FILESYSTEM_FILEDIRECTORYNAME_PLACEHOLDER_MOVEORCOPY 16324 /* Method */ +#define UA_NS0ID_FILESYSTEM_FILEDIRECTORYNAME_PLACEHOLDER_MOVEORCOPY_INPUTARGUMENTS 16325 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILEDIRECTORYNAME_PLACEHOLDER_MOVEORCOPY_OUTPUTARGUMENTS 16326 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER 16327 /* Object */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_SIZE 16328 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_WRITABLE 16329 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_USERWRITABLE 16330 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_OPENCOUNT 16331 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_MIMETYPE 16332 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_OPEN 16333 /* Method */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_OPEN_INPUTARGUMENTS 16334 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_OPEN_OUTPUTARGUMENTS 16335 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_CLOSE 16336 /* Method */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_CLOSE_INPUTARGUMENTS 16337 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_READ 16338 /* Method */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_READ_INPUTARGUMENTS 16339 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_READ_OUTPUTARGUMENTS 16340 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_WRITE 16341 /* Method */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_WRITE_INPUTARGUMENTS 16342 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_GETPOSITION 16343 /* Method */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_GETPOSITION_INPUTARGUMENTS 16344 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_GETPOSITION_OUTPUTARGUMENTS 16345 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_SETPOSITION 16346 /* Method */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_SETPOSITION_INPUTARGUMENTS 16347 /* Variable */ +#define UA_NS0ID_FILESYSTEM_CREATEDIRECTORY 16348 /* Method */ +#define UA_NS0ID_FILESYSTEM_CREATEDIRECTORY_INPUTARGUMENTS 16349 /* Variable */ +#define UA_NS0ID_FILESYSTEM_CREATEDIRECTORY_OUTPUTARGUMENTS 16350 /* Variable */ +#define UA_NS0ID_FILESYSTEM_CREATEFILE 16351 /* Method */ +#define UA_NS0ID_FILESYSTEM_CREATEFILE_INPUTARGUMENTS 16352 /* Variable */ +#define UA_NS0ID_FILESYSTEM_CREATEFILE_OUTPUTARGUMENTS 16353 /* Variable */ +#define UA_NS0ID_FILESYSTEM_DELETEFILESYSTEMOBJECT 16354 /* Method */ +#define UA_NS0ID_FILESYSTEM_DELETEFILESYSTEMOBJECT_INPUTARGUMENTS 16355 /* Variable */ +#define UA_NS0ID_FILESYSTEM_MOVEORCOPY 16356 /* Method */ +#define UA_NS0ID_FILESYSTEM_MOVEORCOPY_INPUTARGUMENTS 16357 /* Variable */ +#define UA_NS0ID_FILESYSTEM_MOVEORCOPY_OUTPUTARGUMENTS 16358 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_GENERATEFILEFORWRITE_INPUTARGUMENTS 16359 /* Variable */ +#define UA_NS0ID_GENERATEFILEFORWRITEMETHODTYPE_INPUTARGUMENTS 16360 /* Variable */ +#define UA_NS0ID_HASALARMSUPPRESSIONGROUP 16361 /* ReferenceType */ +#define UA_NS0ID_ALARMGROUPMEMBER 16362 /* ReferenceType */ +#define UA_NS0ID_CONDITIONTYPE_CONDITIONSUBCLASSID 16363 /* Variable */ +#define UA_NS0ID_CONDITIONTYPE_CONDITIONSUBCLASSNAME 16364 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_CONDITIONSUBCLASSID 16365 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_CONDITIONSUBCLASSNAME 16366 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONDITIONSUBCLASSID 16367 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_CONDITIONSUBCLASSNAME 16368 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONDITIONSUBCLASSID 16369 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_CONDITIONSUBCLASSNAME 16370 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_OUTOFSERVICESTATE 16371 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_OUTOFSERVICESTATE_ID 16372 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_OUTOFSERVICESTATE_NAME 16373 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_OUTOFSERVICESTATE_NUMBER 16374 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16375 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16376 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16377 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_OUTOFSERVICESTATE_TRUESTATE 16378 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_OUTOFSERVICESTATE_FALSESTATE 16379 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SILENCESTATE 16380 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SILENCESTATE_ID 16381 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SILENCESTATE_NAME 16382 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SILENCESTATE_NUMBER 16383 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16384 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SILENCESTATE_TRANSITIONTIME 16385 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16386 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SILENCESTATE_TRUESTATE 16387 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SILENCESTATE_FALSESTATE 16388 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_AUDIBLEENABLED 16389 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_AUDIBLESOUND 16390 /* Variable */ +#define UA_NS0ID_UADPDATASETWRITERMESSAGEDATATYPE_ENCODING_DEFAULTJSON 16391 /* Object */ +#define UA_NS0ID_UADPDATASETREADERMESSAGEDATATYPE_ENCODING_DEFAULTJSON 16392 /* Object */ +#define UA_NS0ID_JSONWRITERGROUPMESSAGEDATATYPE_ENCODING_DEFAULTJSON 16393 /* Object */ +#define UA_NS0ID_JSONDATASETWRITERMESSAGEDATATYPE_ENCODING_DEFAULTJSON 16394 /* Object */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ONDELAY 16395 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_OFFDELAY 16396 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_FIRSTINGROUPFLAG 16397 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_FIRSTINGROUP 16398 /* Object */ +#define UA_NS0ID_ALARMCONDITIONTYPE_ALARMGROUP_PLACEHOLDER 16399 /* Object */ +#define UA_NS0ID_ALARMCONDITIONTYPE_REALARMTIME 16400 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_REALARMREPEATCOUNT 16401 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SILENCE 16402 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESS 16403 /* Method */ +#define UA_NS0ID_JSONDATASETREADERMESSAGEDATATYPE_ENCODING_DEFAULTJSON 16404 /* Object */ +#define UA_NS0ID_ALARMGROUPTYPE 16405 /* ObjectType */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER 16406 /* Object */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_EVENTID 16407 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_EVENTTYPE 16408 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SOURCENODE 16409 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SOURCENAME 16410 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_TIME 16411 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_RECEIVETIME 16412 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LOCALTIME 16413 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_MESSAGE 16414 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SEVERITY 16415 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONDITIONCLASSID 16416 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONDITIONCLASSNAME 16417 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONDITIONSUBCLASSID 16418 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONDITIONSUBCLASSNAME 16419 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONDITIONNAME 16420 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_BRANCHID 16421 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_RETAIN 16422 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE 16423 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_ID 16424 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_NAME 16425 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_NUMBER 16426 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 16427 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_TRANSITIONTIME 16428 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 16429 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_TRUESTATE 16430 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_FALSESTATE 16431 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_QUALITY 16432 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_QUALITY_SOURCETIMESTAMP 16433 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LASTSEVERITY 16434 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LASTSEVERITY_SOURCETIMESTAMP 16435 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_COMMENT 16436 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_COMMENT_SOURCETIMESTAMP 16437 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CLIENTUSERID 16438 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_DISABLE 16439 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLE 16440 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ADDCOMMENT 16441 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ADDCOMMENT_INPUTARGUMENTS 16442 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE 16443 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_ID 16444 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_NAME 16445 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_NUMBER 16446 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_EFFECTIVEDISPLAYNAME 16447 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_TRANSITIONTIME 16448 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_EFFECTIVETRANSITIONTIME 16449 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_TRUESTATE 16450 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_FALSESTATE 16451 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE 16452 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_ID 16453 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_NAME 16454 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_NUMBER 16455 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 16456 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_TRANSITIONTIME 16457 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 16458 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_TRUESTATE 16459 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_FALSESTATE 16460 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKNOWLEDGE 16461 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKNOWLEDGE_INPUTARGUMENTS 16462 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRM 16463 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRM_INPUTARGUMENTS 16464 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE 16465 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_ID 16466 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_NAME 16467 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_NUMBER 16468 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_EFFECTIVEDISPLAYNAME 16469 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_TRANSITIONTIME 16470 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_EFFECTIVETRANSITIONTIME 16471 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_TRUESTATE 16472 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_FALSESTATE 16473 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_INPUTNODE 16474 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE 16475 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_ID 16476 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_NAME 16477 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_NUMBER 16478 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 16479 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_TRANSITIONTIME 16480 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 16481 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_TRUESTATE 16482 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_FALSESTATE 16483 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE 16484 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_ID 16485 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_NAME 16486 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_NUMBER 16487 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16488 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_TRANSITIONTIME 16489 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16490 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_TRUESTATE 16491 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_FALSESTATE 16492 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE 16493 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_ID 16494 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_NAME 16495 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_NUMBER 16496 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_EFFECTIVEDISPLAYNAME 16497 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_TRANSITIONTIME 16498 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_EFFECTIVETRANSITIONTIME 16499 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_TRUESTATE 16500 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_FALSESTATE 16501 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE 16502 /* Object */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_CURRENTSTATE 16503 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_CURRENTSTATE_ID 16504 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_CURRENTSTATE_NAME 16505 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_CURRENTSTATE_NUMBER 16506 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 16507 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_LASTTRANSITION 16508 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_LASTTRANSITION_ID 16509 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_LASTTRANSITION_NAME 16510 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_LASTTRANSITION_NUMBER 16511 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 16512 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 16513 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_UNSHELVETIME 16514 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_UNSHELVE 16515 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_ONESHOTSHELVE 16516 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_TIMEDSHELVE 16517 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 16518 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDORSHELVED 16519 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_MAXTIMESHELVED 16520 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_AUDIBLEENABLED 16521 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_AUDIBLESOUND 16522 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 16523 /* Variable */ +#define UA_NS0ID_BROKERWRITERGROUPTRANSPORTDATATYPE_ENCODING_DEFAULTJSON 16524 /* Object */ +#define UA_NS0ID_BROKERDATASETWRITERTRANSPORTDATATYPE_ENCODING_DEFAULTJSON 16525 /* Object */ +#define UA_NS0ID_BROKERDATASETREADERTRANSPORTDATATYPE_ENCODING_DEFAULTJSON 16526 /* Object */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ONDELAY 16527 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OFFDELAY 16528 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_FIRSTINGROUPFLAG 16529 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_FIRSTINGROUP 16530 /* Object */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_REALARMTIME 16531 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_REALARMREPEATCOUNT 16532 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCE 16533 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESS 16534 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_ADDWRITERGROUP 16535 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_CONDITIONSUBCLASSID 16536 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_CONDITIONSUBCLASSNAME 16537 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_OUTOFSERVICESTATE 16538 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_OUTOFSERVICESTATE_ID 16539 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_OUTOFSERVICESTATE_NAME 16540 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_OUTOFSERVICESTATE_NUMBER 16541 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16542 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16543 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16544 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 16545 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 16546 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SILENCESTATE 16547 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SILENCESTATE_ID 16548 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SILENCESTATE_NAME 16549 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SILENCESTATE_NUMBER 16550 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16551 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SILENCESTATE_TRANSITIONTIME 16552 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16553 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SILENCESTATE_TRUESTATE 16554 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SILENCESTATE_FALSESTATE 16555 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_AUDIBLEENABLED 16556 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_AUDIBLESOUND 16557 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_ADDWRITERGROUP_INPUTARGUMENTS 16558 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_ADDWRITERGROUP_OUTPUTARGUMENTS 16559 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_ADDREADERGROUP 16560 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_ADDREADERGROUP_INPUTARGUMENTS 16561 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_ONDELAY 16562 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_OFFDELAY 16563 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_FIRSTINGROUPFLAG 16564 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_FIRSTINGROUP 16565 /* Object */ +#define UA_NS0ID_LIMITALARMTYPE_ALARMGROUP_PLACEHOLDER 16566 /* Object */ +#define UA_NS0ID_LIMITALARMTYPE_REALARMTIME 16567 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_REALARMREPEATCOUNT 16568 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SILENCE 16569 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESS 16570 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_ADDREADERGROUP_OUTPUTARGUMENTS 16571 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_BASEHIGHHIGHLIMIT 16572 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_BASEHIGHLIMIT 16573 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_BASELOWLIMIT 16574 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_BASELOWLOWLIMIT 16575 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONDITIONSUBCLASSID 16576 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_CONDITIONSUBCLASSNAME 16577 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE 16578 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_ID 16579 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_NAME 16580 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_NUMBER 16581 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16582 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16583 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16584 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 16585 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 16586 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SILENCESTATE 16587 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SILENCESTATE_ID 16588 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SILENCESTATE_NAME 16589 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SILENCESTATE_NUMBER 16590 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16591 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SILENCESTATE_TRANSITIONTIME 16592 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16593 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SILENCESTATE_TRUESTATE 16594 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SILENCESTATE_FALSESTATE 16595 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_AUDIBLEENABLED 16596 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_AUDIBLESOUND 16597 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_ADDCONNECTION 16598 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_ADDCONNECTION_INPUTARGUMENTS 16599 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_ADDCONNECTION_OUTPUTARGUMENTS 16600 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMSTEMPLATE 16601 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ONDELAY 16602 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_OFFDELAY 16603 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_FIRSTINGROUPFLAG 16604 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_FIRSTINGROUP 16605 /* Object */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_ALARMGROUP_PLACEHOLDER 16606 /* Object */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_REALARMTIME 16607 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_REALARMREPEATCOUNT 16608 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SILENCE 16609 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESS 16610 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMSTEMPLATE_INPUTARGUMENTS 16611 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_BASEHIGHHIGHLIMIT 16612 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_BASEHIGHLIMIT 16613 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_BASELOWLIMIT 16614 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_BASELOWLOWLIMIT 16615 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONDITIONSUBCLASSID 16616 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_CONDITIONSUBCLASSNAME 16617 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE 16618 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_ID 16619 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_NAME 16620 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_NUMBER 16621 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16622 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16623 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16624 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 16625 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 16626 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SILENCESTATE 16627 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SILENCESTATE_ID 16628 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SILENCESTATE_NAME 16629 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SILENCESTATE_NUMBER 16630 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16631 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SILENCESTATE_TRANSITIONTIME 16632 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16633 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SILENCESTATE_TRUESTATE 16634 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SILENCESTATE_FALSESTATE 16635 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_AUDIBLEENABLED 16636 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_AUDIBLESOUND 16637 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMSTEMPLATE_OUTPUTARGUMENTS 16638 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTSTEMPLATE 16639 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTSTEMPLATE_INPUTARGUMENTS 16640 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTSTEMPLATE_OUTPUTARGUMENTS 16641 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ONDELAY 16642 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_OFFDELAY 16643 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_FIRSTINGROUPFLAG 16644 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_FIRSTINGROUP 16645 /* Object */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_ALARMGROUP_PLACEHOLDER 16646 /* Object */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_REALARMTIME 16647 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_REALARMREPEATCOUNT 16648 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SILENCE 16649 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESS 16650 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDDATASETFOLDER 16651 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_BASEHIGHHIGHLIMIT 16652 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_BASEHIGHLIMIT 16653 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_BASELOWLIMIT 16654 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_BASELOWLOWLIMIT 16655 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONDITIONSUBCLASSID 16656 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_CONDITIONSUBCLASSNAME 16657 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE 16658 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_ID 16659 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_NAME 16660 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_NUMBER 16661 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16662 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16663 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16664 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 16665 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 16666 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SILENCESTATE 16667 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SILENCESTATE_ID 16668 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SILENCESTATE_NAME 16669 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SILENCESTATE_NUMBER 16670 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16671 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SILENCESTATE_TRANSITIONTIME 16672 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16673 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SILENCESTATE_TRUESTATE 16674 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SILENCESTATE_FALSESTATE 16675 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_AUDIBLEENABLED 16676 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_AUDIBLESOUND 16677 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDDATASETFOLDER_INPUTARGUMENTS 16678 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_ADDDATASETFOLDER_OUTPUTARGUMENTS 16679 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_REMOVEDATASETFOLDER 16680 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBLISHEDDATASETS_REMOVEDATASETFOLDER_INPUTARGUMENTS 16681 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ONDELAY 16682 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_OFFDELAY 16683 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_FIRSTINGROUPFLAG 16684 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_FIRSTINGROUP 16685 /* Object */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_ALARMGROUP_PLACEHOLDER 16686 /* Object */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_REALARMTIME 16687 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_REALARMREPEATCOUNT 16688 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SILENCE 16689 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESS 16690 /* Method */ +#define UA_NS0ID_ADDCONNECTIONMETHODTYPE 16691 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_BASEHIGHHIGHLIMIT 16692 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_BASEHIGHLIMIT 16693 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_BASELOWLIMIT 16694 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_BASELOWLOWLIMIT 16695 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONDITIONSUBCLASSID 16696 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_CONDITIONSUBCLASSNAME 16697 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE 16698 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_ID 16699 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_NAME 16700 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_NUMBER 16701 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16702 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16703 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16704 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 16705 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 16706 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SILENCESTATE 16707 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SILENCESTATE_ID 16708 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SILENCESTATE_NAME 16709 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SILENCESTATE_NUMBER 16710 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16711 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SILENCESTATE_TRANSITIONTIME 16712 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16713 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SILENCESTATE_TRUESTATE 16714 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SILENCESTATE_FALSESTATE 16715 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_AUDIBLEENABLED 16716 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_AUDIBLESOUND 16717 /* Variable */ +#define UA_NS0ID_ADDCONNECTIONMETHODTYPE_INPUTARGUMENTS 16718 /* Variable */ +#define UA_NS0ID_ADDCONNECTIONMETHODTYPE_OUTPUTARGUMENTS 16719 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DATASETWRITERID 16720 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DATASETFIELDCONTENTMASK 16721 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ONDELAY 16722 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_OFFDELAY 16723 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_FIRSTINGROUPFLAG 16724 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_FIRSTINGROUP 16725 /* Object */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_ALARMGROUP_PLACEHOLDER 16726 /* Object */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_REALARMTIME 16727 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_REALARMREPEATCOUNT 16728 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SILENCE 16729 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESS 16730 /* Method */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_KEYFRAMECOUNT 16731 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_BASEHIGHHIGHLIMIT 16732 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_BASEHIGHLIMIT 16733 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_BASELOWLIMIT 16734 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_BASELOWLOWLIMIT 16735 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONDITIONSUBCLASSID 16736 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_CONDITIONSUBCLASSNAME 16737 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE 16738 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_ID 16739 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_NAME 16740 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_NUMBER 16741 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16742 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16743 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16744 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 16745 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 16746 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE 16747 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_ID 16748 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_NAME 16749 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_NUMBER 16750 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16751 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_TRANSITIONTIME 16752 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16753 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_TRUESTATE 16754 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_FALSESTATE 16755 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_AUDIBLEENABLED 16756 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_AUDIBLESOUND 16757 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_MESSAGESETTINGS 16758 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETCLASSID 16759 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DATASETWRITERID 16760 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DATASETFIELDCONTENTMASK 16761 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ONDELAY 16762 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_OFFDELAY 16763 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_FIRSTINGROUPFLAG 16764 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_FIRSTINGROUP 16765 /* Object */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_ALARMGROUP_PLACEHOLDER 16766 /* Object */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_REALARMTIME 16767 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_REALARMREPEATCOUNT 16768 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SILENCE 16769 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESS 16770 /* Method */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_KEYFRAMECOUNT 16771 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_BASEHIGHHIGHLIMIT 16772 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_BASEHIGHLIMIT 16773 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_BASELOWLIMIT 16774 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_BASELOWLOWLIMIT 16775 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_BASESETPOINTNODE 16776 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONDITIONSUBCLASSID 16777 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_CONDITIONSUBCLASSNAME 16778 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE 16779 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_ID 16780 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_NAME 16781 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_NUMBER 16782 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16783 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16784 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16785 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 16786 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 16787 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE 16788 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_ID 16789 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_NAME 16790 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_NUMBER 16791 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16792 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_TRANSITIONTIME 16793 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16794 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_TRUESTATE 16795 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SILENCESTATE_FALSESTATE 16796 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_AUDIBLEENABLED 16797 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_AUDIBLESOUND 16798 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_MESSAGESETTINGS 16799 /* Object */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETCLASSID 16800 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DATASETWRITERID 16801 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DATASETFIELDCONTENTMASK 16802 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ONDELAY 16803 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_OFFDELAY 16804 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_FIRSTINGROUPFLAG 16805 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_FIRSTINGROUP 16806 /* Object */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_ALARMGROUP_PLACEHOLDER 16807 /* Object */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_REALARMTIME 16808 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_REALARMREPEATCOUNT 16809 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SILENCE 16810 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESS 16811 /* Method */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_KEYFRAMECOUNT 16812 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_BASEHIGHHIGHLIMIT 16813 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_BASEHIGHLIMIT 16814 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_BASELOWLIMIT 16815 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_BASELOWLOWLIMIT 16816 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_BASESETPOINTNODE 16817 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONSUBCLASSID 16818 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONSUBCLASSNAME 16819 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE 16820 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_ID 16821 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_NAME 16822 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_NUMBER 16823 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16824 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16825 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16826 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 16827 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 16828 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE 16829 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_ID 16830 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_NAME 16831 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_NUMBER 16832 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16833 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_TRANSITIONTIME 16834 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16835 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_TRUESTATE 16836 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_FALSESTATE 16837 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_AUDIBLEENABLED 16838 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_AUDIBLESOUND 16839 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_MESSAGESETTINGS 16840 /* Object */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETCLASSID 16841 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDPUBLISHEDDATAITEMSTEMPLATE 16842 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDPUBLISHEDDATAITEMSTEMPLATE_INPUTARGUMENTS 16843 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ONDELAY 16844 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_OFFDELAY 16845 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_FIRSTINGROUPFLAG 16846 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_FIRSTINGROUP 16847 /* Object */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ALARMGROUP_PLACEHOLDER 16848 /* Object */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_REALARMTIME 16849 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_REALARMREPEATCOUNT 16850 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SILENCE 16851 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESS 16852 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDPUBLISHEDDATAITEMSTEMPLATE_OUTPUTARGUMENTS 16853 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_BASEHIGHHIGHLIMIT 16854 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_BASEHIGHLIMIT 16855 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_BASELOWLIMIT 16856 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_BASELOWLOWLIMIT 16857 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_ENGINEERINGUNITS 16858 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONSUBCLASSID 16859 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_CONDITIONSUBCLASSNAME 16860 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE 16861 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_ID 16862 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_NAME 16863 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_NUMBER 16864 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16865 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16866 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16867 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 16868 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 16869 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE 16870 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_ID 16871 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_NAME 16872 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_NUMBER 16873 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16874 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_TRANSITIONTIME 16875 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16876 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_TRUESTATE 16877 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SILENCESTATE_FALSESTATE 16878 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_AUDIBLEENABLED 16879 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_AUDIBLESOUND 16880 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDPUBLISHEDEVENTSTEMPLATE 16881 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDPUBLISHEDEVENTSTEMPLATE_INPUTARGUMENTS 16882 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDPUBLISHEDEVENTSTEMPLATE_OUTPUTARGUMENTS 16883 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDDATASETFOLDER 16884 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ONDELAY 16885 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_OFFDELAY 16886 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_FIRSTINGROUPFLAG 16887 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_FIRSTINGROUP 16888 /* Object */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ALARMGROUP_PLACEHOLDER 16889 /* Object */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_REALARMTIME 16890 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_REALARMREPEATCOUNT 16891 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SILENCE 16892 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESS 16893 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDDATASETFOLDER_INPUTARGUMENTS 16894 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_BASEHIGHHIGHLIMIT 16895 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_BASEHIGHLIMIT 16896 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_BASELOWLIMIT 16897 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_BASELOWLOWLIMIT 16898 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_ENGINEERINGUNITS 16899 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONDITIONSUBCLASSID 16900 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_CONDITIONSUBCLASSNAME 16901 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_OUTOFSERVICESTATE 16902 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_OUTOFSERVICESTATE_ID 16903 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_OUTOFSERVICESTATE_NAME 16904 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_OUTOFSERVICESTATE_NUMBER 16905 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16906 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16907 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16908 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 16909 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 16910 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SILENCESTATE 16911 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SILENCESTATE_ID 16912 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SILENCESTATE_NAME 16913 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SILENCESTATE_NUMBER 16914 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16915 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SILENCESTATE_TRANSITIONTIME 16916 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16917 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SILENCESTATE_TRUESTATE 16918 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SILENCESTATE_FALSESTATE 16919 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_AUDIBLEENABLED 16920 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_AUDIBLESOUND 16921 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_ADDDATASETFOLDER_OUTPUTARGUMENTS 16922 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_REMOVEDATASETFOLDER 16923 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_DATASETFOLDERNAME_PLACEHOLDER_REMOVEDATASETFOLDER_INPUTARGUMENTS 16924 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_PUBLISHEDDATASETNAME_PLACEHOLDER_DATASETCLASSID 16925 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_ONDELAY 16926 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_OFFDELAY 16927 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_FIRSTINGROUPFLAG 16928 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_FIRSTINGROUP 16929 /* Object */ +#define UA_NS0ID_DISCRETEALARMTYPE_ALARMGROUP_PLACEHOLDER 16930 /* Object */ +#define UA_NS0ID_DISCRETEALARMTYPE_REALARMTIME 16931 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_REALARMREPEATCOUNT 16932 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SILENCE 16933 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESS 16934 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMSTEMPLATE 16935 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONDITIONSUBCLASSID 16936 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_CONDITIONSUBCLASSNAME 16937 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_OUTOFSERVICESTATE 16938 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_OUTOFSERVICESTATE_ID 16939 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_OUTOFSERVICESTATE_NAME 16940 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_OUTOFSERVICESTATE_NUMBER 16941 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16942 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16943 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16944 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 16945 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 16946 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SILENCESTATE 16947 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SILENCESTATE_ID 16948 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SILENCESTATE_NAME 16949 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SILENCESTATE_NUMBER 16950 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16951 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SILENCESTATE_TRANSITIONTIME 16952 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16953 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SILENCESTATE_TRUESTATE 16954 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SILENCESTATE_FALSESTATE 16955 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_AUDIBLEENABLED 16956 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_AUDIBLESOUND 16957 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMSTEMPLATE_INPUTARGUMENTS 16958 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMSTEMPLATE_OUTPUTARGUMENTS 16959 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDEVENTSTEMPLATE 16960 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDEVENTSTEMPLATE_INPUTARGUMENTS 16961 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ONDELAY 16962 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_OFFDELAY 16963 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_FIRSTINGROUPFLAG 16964 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_FIRSTINGROUP 16965 /* Object */ +#define UA_NS0ID_OFFNORMALALARMTYPE_ALARMGROUP_PLACEHOLDER 16966 /* Object */ +#define UA_NS0ID_OFFNORMALALARMTYPE_REALARMTIME 16967 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_REALARMREPEATCOUNT 16968 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SILENCE 16969 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESS 16970 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDEVENTSTEMPLATE_OUTPUTARGUMENTS 16971 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONDITIONSUBCLASSID 16972 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_CONDITIONSUBCLASSNAME 16973 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_OUTOFSERVICESTATE 16974 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_OUTOFSERVICESTATE_ID 16975 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_OUTOFSERVICESTATE_NAME 16976 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_OUTOFSERVICESTATE_NUMBER 16977 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 16978 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 16979 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 16980 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 16981 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 16982 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SILENCESTATE 16983 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SILENCESTATE_ID 16984 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SILENCESTATE_NAME 16985 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SILENCESTATE_NUMBER 16986 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 16987 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SILENCESTATE_TRANSITIONTIME 16988 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 16989 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SILENCESTATE_TRUESTATE 16990 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SILENCESTATE_FALSESTATE 16991 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_AUDIBLEENABLED 16992 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_AUDIBLESOUND 16993 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDDATASETFOLDER 16994 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDDATASETFOLDER_INPUTARGUMENTS 16995 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_ADDDATASETFOLDER_OUTPUTARGUMENTS 16996 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_REMOVEDATASETFOLDER 16997 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ONDELAY 16998 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_OFFDELAY 16999 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_FIRSTINGROUPFLAG 17000 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_FIRSTINGROUP 17001 /* Object */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_ALARMGROUP_PLACEHOLDER 17002 /* Object */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_REALARMTIME 17003 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_REALARMREPEATCOUNT 17004 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SILENCE 17005 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESS 17006 /* Method */ +#define UA_NS0ID_DATASETFOLDERTYPE_REMOVEDATASETFOLDER_INPUTARGUMENTS 17007 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONDITIONSUBCLASSID 17008 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_CONDITIONSUBCLASSNAME 17009 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_OUTOFSERVICESTATE 17010 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_OUTOFSERVICESTATE_ID 17011 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_OUTOFSERVICESTATE_NAME 17012 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_OUTOFSERVICESTATE_NUMBER 17013 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 17014 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 17015 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 17016 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 17017 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 17018 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SILENCESTATE 17019 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SILENCESTATE_ID 17020 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SILENCESTATE_NAME 17021 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SILENCESTATE_NUMBER 17022 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 17023 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SILENCESTATE_TRANSITIONTIME 17024 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 17025 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SILENCESTATE_TRUESTATE 17026 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SILENCESTATE_FALSESTATE 17027 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_AUDIBLEENABLED 17028 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_AUDIBLESOUND 17029 /* Variable */ +#define UA_NS0ID_ADDPUBLISHEDDATAITEMSTEMPLATEMETHODTYPE 17030 /* Method */ +#define UA_NS0ID_ADDPUBLISHEDDATAITEMSTEMPLATEMETHODTYPE_INPUTARGUMENTS 17031 /* Variable */ +#define UA_NS0ID_ADDPUBLISHEDDATAITEMSTEMPLATEMETHODTYPE_OUTPUTARGUMENTS 17032 /* Variable */ +#define UA_NS0ID_ADDPUBLISHEDEVENTSTEMPLATEMETHODTYPE 17033 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_ONDELAY 17034 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_OFFDELAY 17035 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_FIRSTINGROUPFLAG 17036 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_FIRSTINGROUP 17037 /* Object */ +#define UA_NS0ID_TRIPALARMTYPE_ALARMGROUP_PLACEHOLDER 17038 /* Object */ +#define UA_NS0ID_TRIPALARMTYPE_REALARMTIME 17039 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_REALARMREPEATCOUNT 17040 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SILENCE 17041 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESS 17042 /* Method */ +#define UA_NS0ID_ADDPUBLISHEDEVENTSTEMPLATEMETHODTYPE_INPUTARGUMENTS 17043 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONDITIONSUBCLASSID 17044 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_CONDITIONSUBCLASSNAME 17045 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_OUTOFSERVICESTATE 17046 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_OUTOFSERVICESTATE_ID 17047 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_OUTOFSERVICESTATE_NAME 17048 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_OUTOFSERVICESTATE_NUMBER 17049 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 17050 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 17051 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 17052 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 17053 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 17054 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SILENCESTATE 17055 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SILENCESTATE_ID 17056 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SILENCESTATE_NAME 17057 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SILENCESTATE_NUMBER 17058 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 17059 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SILENCESTATE_TRANSITIONTIME 17060 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 17061 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SILENCESTATE_TRUESTATE 17062 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SILENCESTATE_FALSESTATE 17063 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_AUDIBLEENABLED 17064 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_AUDIBLESOUND 17065 /* Variable */ +#define UA_NS0ID_ADDPUBLISHEDEVENTSTEMPLATEMETHODTYPE_OUTPUTARGUMENTS 17066 /* Variable */ +#define UA_NS0ID_ADDDATASETFOLDERMETHODTYPE 17067 /* Method */ +#define UA_NS0ID_ADDDATASETFOLDERMETHODTYPE_INPUTARGUMENTS 17068 /* Variable */ +#define UA_NS0ID_ADDDATASETFOLDERMETHODTYPE_OUTPUTARGUMENTS 17069 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ONDELAY 17070 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_OFFDELAY 17071 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_FIRSTINGROUPFLAG 17072 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_FIRSTINGROUP 17073 /* Object */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_ALARMGROUP_PLACEHOLDER 17074 /* Object */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_REALARMTIME 17075 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_REALARMREPEATCOUNT 17076 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SILENCE 17077 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESS 17078 /* Method */ +#define UA_NS0ID_REMOVEDATASETFOLDERMETHODTYPE 17079 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE 17080 /* ObjectType */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_EVENTID 17081 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_EVENTTYPE 17082 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SOURCENODE 17083 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SOURCENAME 17084 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_TIME 17085 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_RECEIVETIME 17086 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_LOCALTIME 17087 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_MESSAGE 17088 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SEVERITY 17089 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONDITIONCLASSID 17090 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONDITIONCLASSNAME 17091 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONDITIONSUBCLASSID 17092 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONDITIONSUBCLASSNAME 17093 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONDITIONNAME 17094 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_BRANCHID 17095 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_RETAIN 17096 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ENABLEDSTATE 17097 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ENABLEDSTATE_ID 17098 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ENABLEDSTATE_NAME 17099 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ENABLEDSTATE_NUMBER 17100 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 17101 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 17102 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 17103 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ENABLEDSTATE_TRUESTATE 17104 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ENABLEDSTATE_FALSESTATE 17105 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_QUALITY 17106 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_QUALITY_SOURCETIMESTAMP 17107 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_LASTSEVERITY 17108 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 17109 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_COMMENT 17110 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_COMMENT_SOURCETIMESTAMP 17111 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CLIENTUSERID 17112 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_DISABLE 17113 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ENABLE 17114 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ADDCOMMENT 17115 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 17116 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONDITIONREFRESH 17117 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 17118 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONDITIONREFRESH2 17119 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 17120 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACKEDSTATE 17121 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACKEDSTATE_ID 17122 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACKEDSTATE_NAME 17123 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACKEDSTATE_NUMBER 17124 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 17125 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACKEDSTATE_TRANSITIONTIME 17126 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 17127 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACKEDSTATE_TRUESTATE 17128 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACKEDSTATE_FALSESTATE 17129 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONFIRMEDSTATE 17130 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONFIRMEDSTATE_ID 17131 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONFIRMEDSTATE_NAME 17132 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONFIRMEDSTATE_NUMBER 17133 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 17134 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 17135 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 17136 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONFIRMEDSTATE_TRUESTATE 17137 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONFIRMEDSTATE_FALSESTATE 17138 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACKNOWLEDGE 17139 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 17140 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONFIRM 17141 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_CONFIRM_INPUTARGUMENTS 17142 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACTIVESTATE 17143 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACTIVESTATE_ID 17144 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACTIVESTATE_NAME 17145 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACTIVESTATE_NUMBER 17146 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 17147 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACTIVESTATE_TRANSITIONTIME 17148 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 17149 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACTIVESTATE_TRUESTATE 17150 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ACTIVESTATE_FALSESTATE 17151 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_INPUTNODE 17152 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESSEDSTATE 17153 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESSEDSTATE_ID 17154 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESSEDSTATE_NAME 17155 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESSEDSTATE_NUMBER 17156 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 17157 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 17158 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 17159 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 17160 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 17161 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_OUTOFSERVICESTATE 17162 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_OUTOFSERVICESTATE_ID 17163 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_OUTOFSERVICESTATE_NAME 17164 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_OUTOFSERVICESTATE_NUMBER 17165 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 17166 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 17167 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 17168 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 17169 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 17170 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SILENCESTATE 17171 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SILENCESTATE_ID 17172 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SILENCESTATE_NAME 17173 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SILENCESTATE_NUMBER 17174 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 17175 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SILENCESTATE_TRANSITIONTIME 17176 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 17177 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SILENCESTATE_TRUESTATE 17178 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SILENCESTATE_FALSESTATE 17179 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE 17180 /* Object */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_CURRENTSTATE 17181 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 17182 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 17183 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 17184 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 17185 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_LASTTRANSITION 17186 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 17187 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 17188 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 17189 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 17190 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 17191 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_UNSHELVETIME 17192 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_UNSHELVE 17193 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 17194 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 17195 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 17196 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESSEDORSHELVED 17197 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_MAXTIMESHELVED 17198 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_AUDIBLEENABLED 17199 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_AUDIBLESOUND 17200 /* Variable */ +#define UA_NS0ID_REMOVEDATASETFOLDERMETHODTYPE_INPUTARGUMENTS 17201 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDRESS_NETWORKINTERFACE 17202 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_TRANSPORTSETTINGS 17203 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_MAXNETWORKMESSAGESIZE 17204 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ONDELAY 17205 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_OFFDELAY 17206 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_FIRSTINGROUPFLAG 17207 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_FIRSTINGROUP 17208 /* Object */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_ALARMGROUP_PLACEHOLDER 17209 /* Object */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_REALARMTIME 17210 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_REALARMREPEATCOUNT 17211 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SILENCE 17212 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESS 17213 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_WRITERGROUPID 17214 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_TARGETVALUENODE 17215 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_EXPECTEDTIME 17216 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_TOLERANCE 17217 /* Variable */ +#define UA_NS0ID_SAFETYCONDITIONCLASSTYPE 17218 /* ObjectType */ +#define UA_NS0ID_HIGHLYMANAGEDALARMCONDITIONCLASSTYPE 17219 /* ObjectType */ +#define UA_NS0ID_TRAININGCONDITIONCLASSTYPE 17220 /* ObjectType */ +#define UA_NS0ID_TESTINGCONDITIONCLASSTYPE 17221 /* ObjectType */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_CONDITIONEVENTID 17222 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_CONDITIONEVENTID 17223 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_CONDITIONEVENTID 17224 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE 17225 /* ObjectType */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_EVENTID 17226 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_EVENTTYPE 17227 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_SOURCENODE 17228 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_SOURCENAME 17229 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_TIME 17230 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_RECEIVETIME 17231 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_LOCALTIME 17232 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_MESSAGE 17233 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_SEVERITY 17234 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_ACTIONTIMESTAMP 17235 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_STATUS 17236 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_SERVERID 17237 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_CLIENTAUDITENTRYID 17238 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_CLIENTUSERID 17239 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_METHODID 17240 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_INPUTARGUMENTS 17241 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE 17242 /* ObjectType */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_EVENTID 17243 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_EVENTTYPE 17244 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_SOURCENODE 17245 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_SOURCENAME 17246 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_TIME 17247 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_RECEIVETIME 17248 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_LOCALTIME 17249 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_MESSAGE 17250 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_SEVERITY 17251 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_ACTIONTIMESTAMP 17252 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_STATUS 17253 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_SERVERID 17254 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_CLIENTAUDITENTRYID 17255 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_CLIENTUSERID 17256 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_METHODID 17257 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_INPUTARGUMENTS 17258 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE 17259 /* ObjectType */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_EVENTID 17260 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_EVENTTYPE 17261 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_SOURCENODE 17262 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_SOURCENAME 17263 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_TIME 17264 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_RECEIVETIME 17265 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_LOCALTIME 17266 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_MESSAGE 17267 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_SEVERITY 17268 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_ACTIONTIMESTAMP 17269 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_STATUS 17270 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_SERVERID 17271 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_CLIENTAUDITENTRYID 17272 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_CLIENTUSERID 17273 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_METHODID 17274 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_INPUTARGUMENTS 17275 /* Variable */ +#define UA_NS0ID_HASEFFECTDISABLE 17276 /* ReferenceType */ +#define UA_NS0ID_ALARMRATEVARIABLETYPE 17277 /* VariableType */ +#define UA_NS0ID_ALARMRATEVARIABLETYPE_RATE 17278 /* Variable */ +#define UA_NS0ID_ALARMMETRICSTYPE 17279 /* ObjectType */ +#define UA_NS0ID_ALARMMETRICSTYPE_ALARMCOUNT 17280 /* Variable */ +#define UA_NS0ID_ALARMMETRICSTYPE_MAXIMUMACTIVESTATE 17281 /* Variable */ +#define UA_NS0ID_ALARMMETRICSTYPE_MAXIMUMUNACK 17282 /* Variable */ +#define UA_NS0ID_ALARMMETRICSTYPE_MAXIMUMREALARMCOUNT 17283 /* Variable */ +#define UA_NS0ID_ALARMMETRICSTYPE_CURRENTALARMRATE 17284 /* Variable */ +#define UA_NS0ID_ALARMMETRICSTYPE_CURRENTALARMRATE_RATE 17285 /* Variable */ +#define UA_NS0ID_ALARMMETRICSTYPE_MAXIMUMALARMRATE 17286 /* Variable */ +#define UA_NS0ID_ALARMMETRICSTYPE_MAXIMUMALARMRATE_RATE 17287 /* Variable */ +#define UA_NS0ID_ALARMMETRICSTYPE_AVERAGEALARMRATE 17288 /* Variable */ +#define UA_NS0ID_ALARMMETRICSTYPE_AVERAGEALARMRATE_RATE 17289 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_TRANSPORTSETTINGS 17290 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_MESSAGESETTINGS 17291 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_TRANSPORTPROFILEURI 17292 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_ADDDATASETWRITER 17293 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_ADDDATASETWRITER_INPUTARGUMENTS 17294 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_TRANSPORTPROFILEURI_RESTRICTTOLIST 17295 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SETSECURITYKEYS 17296 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SETSECURITYKEYS_INPUTARGUMENTS 17297 /* Variable */ +#define UA_NS0ID_SETSECURITYKEYSMETHODTYPE 17298 /* Method */ +#define UA_NS0ID_SETSECURITYKEYSMETHODTYPE_INPUTARGUMENTS 17299 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 17300 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_ADDDATASETWRITER_OUTPUTARGUMENTS 17301 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_MAXNETWORKMESSAGESIZE 17302 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 17303 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 17304 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 17305 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_TRANSPORTPROFILEURI 17306 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_TRANSPORTSETTINGS 17307 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_MESSAGESETTINGS 17308 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_TRANSPORTPROFILEURI_RESTRICTTOLIST 17309 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER 17310 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_SECURITYMODE 17311 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_SECURITYGROUPID 17312 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_SECURITYKEYSERVICES 17313 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_STATUS 17314 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_STATUS_STATE 17315 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_STATUS_ENABLE 17316 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_STATUS_DISABLE 17317 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_PUBLISHINGINTERVAL 17318 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_KEEPALIVETIME 17319 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 17320 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_PRIORITY 17321 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_LOCALEIDS 17322 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_REMOVEDATASETWRITER 17323 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_REMOVEDATASETWRITER_INPUTARGUMENTS 17324 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER 17325 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_SECURITYMODE 17326 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_SECURITYGROUPID 17327 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_SECURITYKEYSERVICES 17328 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_STATUS 17329 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_STATUS_STATE 17330 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_STATUS_ENABLE 17331 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_STATUS_DISABLE 17332 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_REMOVEDATASETREADER 17333 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_REMOVEDATASETREADER_INPUTARGUMENTS 17334 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 17335 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 17336 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 17337 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 17338 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 17339 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 17340 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 17341 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 17342 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 17343 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 17344 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 17345 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 17346 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 17347 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 17348 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 17349 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 17350 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 17351 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES 17352 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_RESOLVEDADDRESS 17353 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_RESOLVEDADDRESS_DIAGNOSTICSLEVEL 17354 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_ADDDATASETREADER 17355 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_ADDWRITERGROUP 17356 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_ADDWRITERGROUP_INPUTARGUMENTS 17357 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_ADDWRITERGROUP_OUTPUTARGUMENTS 17358 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_ADDREADERGROUP 17359 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_ADDREADERGROUP_INPUTARGUMENTS 17360 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_ADDREADERGROUP_OUTPUTARGUMENTS 17361 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_REMOVEGROUP 17362 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_REMOVEGROUP_INPUTARGUMENTS 17363 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SETSECURITYKEYS 17364 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SETSECURITYKEYS_INPUTARGUMENTS 17365 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_ADDCONNECTION 17366 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_ADDCONNECTION_INPUTARGUMENTS 17367 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_ADDCONNECTION_OUTPUTARGUMENTS 17368 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_REMOVECONNECTION 17369 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_REMOVECONNECTION_INPUTARGUMENTS 17370 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS 17371 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMS 17372 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMS_INPUTARGUMENTS 17373 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMS_OUTPUTARGUMENTS 17374 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTS 17375 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTS_INPUTARGUMENTS 17376 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTS_OUTPUTARGUMENTS 17377 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMSTEMPLATE 17378 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMSTEMPLATE_INPUTARGUMENTS 17379 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMSTEMPLATE_OUTPUTARGUMENTS 17380 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTSTEMPLATE 17381 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTSTEMPLATE_INPUTARGUMENTS 17382 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTSTEMPLATE_OUTPUTARGUMENTS 17383 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_REMOVEPUBLISHEDDATASET 17384 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_REMOVEPUBLISHEDDATASET_INPUTARGUMENTS 17385 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_CREATETARGETVARIABLES 17386 /* Method */ +#define UA_NS0ID_DATASETREADERTYPE_CREATETARGETVARIABLES_INPUTARGUMENTS 17387 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_CREATETARGETVARIABLES_OUTPUTARGUMENTS 17388 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_CREATEDATASETMIRROR 17389 /* Method */ +#define UA_NS0ID_DATASETREADERTYPE_CREATEDATASETMIRROR_INPUTARGUMENTS 17390 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_CREATEDATASETMIRROR_OUTPUTARGUMENTS 17391 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPECREATETARGETVARIABLESMETHODTYPE 17392 /* Method */ +#define UA_NS0ID_DATASETREADERTYPECREATETARGETVARIABLESMETHODTYPE_INPUTARGUMENTS 17393 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPECREATETARGETVARIABLESMETHODTYPE_OUTPUTARGUMENTS 17394 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPECREATEDATASETMIRRORMETHODTYPE 17395 /* Method */ +#define UA_NS0ID_DATASETREADERTYPECREATEDATASETMIRRORMETHODTYPE_INPUTARGUMENTS 17396 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPECREATEDATASETMIRRORMETHODTYPE_OUTPUTARGUMENTS 17397 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDDATASETFOLDER 17398 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_ADDDATASETREADER_INPUTARGUMENTS 17399 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_ADDDATASETREADER_OUTPUTARGUMENTS 17400 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDDATASETFOLDER_INPUTARGUMENTS 17401 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_ADDDATASETFOLDER_OUTPUTARGUMENTS 17402 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_REMOVEDATASETFOLDER 17403 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS_REMOVEDATASETFOLDER_INPUTARGUMENTS 17404 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_STATUS 17405 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_STATUS_STATE 17406 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_STATUS_ENABLE 17407 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_STATUS_DISABLE 17408 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS 17409 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_DIAGNOSTICSLEVEL 17410 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_TOTALINFORMATION 17411 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 17412 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 17413 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 17414 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 17415 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_TOTALERROR 17416 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_TOTALERROR_ACTIVE 17417 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 17418 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 17419 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 17420 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_RESET 17421 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_SUBERROR 17422 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS 17423 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEERROR 17424 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 17425 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 17426 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDWRITERGROUP 17427 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDWRITERGROUP_INPUTARGUMENTS 17428 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 17429 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 17430 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 17431 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 17432 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 17433 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 17434 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 17435 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 17436 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 17437 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 17438 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 17439 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 17440 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 17441 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 17442 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 17443 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 17444 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 17445 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 17446 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 17447 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 17448 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 17449 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 17450 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 17451 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 17452 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 17453 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 17454 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 17455 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDWRITERGROUP_OUTPUTARGUMENTS 17456 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_LIVEVALUES 17457 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETWRITERS 17458 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETWRITERS_DIAGNOSTICSLEVEL 17459 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETREADERS 17460 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETREADERS_DIAGNOSTICSLEVEL 17461 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETWRITERS 17462 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETWRITERS_DIAGNOSTICSLEVEL 17463 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETREADERS 17464 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDREADERGROUP 17465 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETREADERS_DIAGNOSTICSLEVEL 17466 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTDATATYPE 17467 /* DataType */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTDATATYPE_ENCODING_DEFAULTBINARY 17468 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMCONNECTIONTRANSPORTDATATYPE 17469 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMCONNECTIONTRANSPORTDATATYPE_DATATYPEVERSION 17470 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMCONNECTIONTRANSPORTDATATYPE_DICTIONARYFRAGMENT 17471 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTDATATYPE_ENCODING_DEFAULTXML 17472 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMCONNECTIONTRANSPORTDATATYPE 17473 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMCONNECTIONTRANSPORTDATATYPE_DATATYPEVERSION 17474 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMCONNECTIONTRANSPORTDATATYPE_DICTIONARYFRAGMENT 17475 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTDATATYPE_ENCODING_DEFAULTJSON 17476 /* Object */ +#define UA_NS0ID_UADPDATASETREADERMESSAGETYPE_DATASETOFFSET 17477 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_CONNECTIONPROPERTIES 17478 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SUPPORTEDTRANSPORTPROFILES 17479 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_CONNECTIONPROPERTIES 17480 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SUPPORTEDTRANSPORTPROFILES 17481 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DATASETWRITERPROPERTIES 17482 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DATASETWRITERPROPERTIES 17483 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DATASETWRITERPROPERTIES 17484 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_CONNECTIONPROPERTIES 17485 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_GROUPPROPERTIES 17486 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_GROUPPROPERTIES 17487 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPE_GROUPPROPERTIES 17488 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_GROUPPROPERTIES 17489 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DATASETWRITERPROPERTIES 17490 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_GROUPPROPERTIES 17491 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DATASETREADERPROPERTIES 17492 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DATASETWRITERPROPERTIES 17493 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DATASETREADERPROPERTIES 17494 /* Variable */ +#define UA_NS0ID_CREATECREDENTIALMETHODTYPE_OUTPUTARGUMENTS 17495 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE 17496 /* ObjectType */ +#define UA_NS0ID_ANALOGUNITTYPE 17497 /* VariableType */ +#define UA_NS0ID_ANALOGUNITTYPE_DEFINITION 17498 /* Variable */ +#define UA_NS0ID_ANALOGUNITTYPE_VALUEPRECISION 17499 /* Variable */ +#define UA_NS0ID_ANALOGUNITTYPE_INSTRUMENTRANGE 17500 /* Variable */ +#define UA_NS0ID_ANALOGUNITTYPE_EURANGE 17501 /* Variable */ +#define UA_NS0ID_ANALOGUNITTYPE_ENGINEERINGUNITS 17502 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_ADDRESS_NETWORKINTERFACE_SELECTIONS 17503 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_ADDRESS_NETWORKINTERFACE_SELECTIONDESCRIPTIONS 17504 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_ADDRESS_NETWORKINTERFACE_RESTRICTTOLIST 17505 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_ADDRESS_NETWORKINTERFACE_SELECTIONS 17506 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDREADERGROUP_INPUTARGUMENTS 17507 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDREADERGROUP_OUTPUTARGUMENTS 17508 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_ADDRESS_NETWORKINTERFACE_SELECTIONDESCRIPTIONS 17509 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONNECTIONNAME_PLACEHOLDER_ADDRESS_NETWORKINTERFACE_RESTRICTTOLIST 17510 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER 17511 /* Object */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_RESOURCEURI 17512 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_PROFILEURI 17513 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_ENDPOINTURLS 17514 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_SERVICESTATUS 17515 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_GETENCRYPTINGKEY 17516 /* Method */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_GETENCRYPTINGKEY_INPUTARGUMENTS 17517 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_GETENCRYPTINGKEY_OUTPUTARGUMENTS 17518 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_UPDATECREDENTIAL 17519 /* Method */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_UPDATECREDENTIAL_INPUTARGUMENTS 17520 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_DELETECREDENTIAL 17521 /* Method */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_CREATECREDENTIAL 17522 /* Method */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_CREATECREDENTIAL_INPUTARGUMENTS 17523 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONFOLDERTYPE_CREATECREDENTIAL_OUTPUTARGUMENTS 17524 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_SERVICENAME_PLACEHOLDER_GETENCRYPTINGKEY 17525 /* Method */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_SERVICENAME_PLACEHOLDER_GETENCRYPTINGKEY_INPUTARGUMENTS 17526 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_SERVICENAME_PLACEHOLDER_GETENCRYPTINGKEY_OUTPUTARGUMENTS 17527 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_CREATECREDENTIAL 17528 /* Method */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_CREATECREDENTIAL_INPUTARGUMENTS 17529 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_CREATECREDENTIAL_OUTPUTARGUMENTS 17530 /* Variable */ +#define UA_NS0ID_GETENCRYPTINGKEYMETHODTYPE 17531 /* Method */ +#define UA_NS0ID_GETENCRYPTINGKEYMETHODTYPE_INPUTARGUMENTS 17532 /* Variable */ +#define UA_NS0ID_GETENCRYPTINGKEYMETHODTYPE_OUTPUTARGUMENTS 17533 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONTYPE_GETENCRYPTINGKEY 17534 /* Method */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONTYPE_GETENCRYPTINGKEY_INPUTARGUMENTS 17535 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONTYPE_GETENCRYPTINGKEY_OUTPUTARGUMENTS 17536 /* Variable */ +#define UA_NS0ID_ADDITIONALPARAMETERSTYPE_ENCODING_DEFAULTBINARY 17537 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ADDITIONALPARAMETERSTYPE 17538 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ADDITIONALPARAMETERSTYPE_DATATYPEVERSION 17539 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ADDITIONALPARAMETERSTYPE_DICTIONARYFRAGMENT 17540 /* Variable */ +#define UA_NS0ID_ADDITIONALPARAMETERSTYPE_ENCODING_DEFAULTXML 17541 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ADDITIONALPARAMETERSTYPE 17542 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ADDITIONALPARAMETERSTYPE_DATATYPEVERSION 17543 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ADDITIONALPARAMETERSTYPE_DICTIONARYFRAGMENT 17544 /* Variable */ +#define UA_NS0ID_RSAENCRYPTEDSECRET 17545 /* DataType */ +#define UA_NS0ID_ECCENCRYPTEDSECRET 17546 /* DataType */ +#define UA_NS0ID_ADDITIONALPARAMETERSTYPE_ENCODING_DEFAULTJSON 17547 /* Object */ +#define UA_NS0ID_EPHEMERALKEYTYPE 17548 /* DataType */ +#define UA_NS0ID_EPHEMERALKEYTYPE_ENCODING_DEFAULTBINARY 17549 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_EPHEMERALKEYTYPE 17550 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_EPHEMERALKEYTYPE_DATATYPEVERSION 17551 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_EPHEMERALKEYTYPE_DICTIONARYFRAGMENT 17552 /* Variable */ +#define UA_NS0ID_EPHEMERALKEYTYPE_ENCODING_DEFAULTXML 17553 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_EPHEMERALKEYTYPE 17554 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_EPHEMERALKEYTYPE_DATATYPEVERSION 17555 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_EPHEMERALKEYTYPE_DICTIONARYFRAGMENT 17556 /* Variable */ +#define UA_NS0ID_EPHEMERALKEYTYPE_ENCODING_DEFAULTJSON 17557 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_HEADERLAYOUTURI 17558 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_HEADERLAYOUTURI 17559 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_KEYFRAMECOUNT 17560 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPEADDWRITERGROUPMETHODTYPE 17561 /* Method */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_HEADERLAYOUTURI 17562 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_KEYFRAMECOUNT 17563 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_HEADERLAYOUTURI 17564 /* Variable */ +#define UA_NS0ID_BASEANALOGTYPE_DEFINITION 17565 /* Variable */ +#define UA_NS0ID_BASEANALOGTYPE_VALUEPRECISION 17566 /* Variable */ +#define UA_NS0ID_BASEANALOGTYPE_INSTRUMENTRANGE 17567 /* Variable */ +#define UA_NS0ID_BASEANALOGTYPE_EURANGE 17568 /* Variable */ +#define UA_NS0ID_BASEANALOGTYPE_ENGINEERINGUNITS 17569 /* Variable */ +#define UA_NS0ID_ANALOGUNITRANGETYPE 17570 /* VariableType */ +#define UA_NS0ID_ANALOGUNITRANGETYPE_DEFINITION 17571 /* Variable */ +#define UA_NS0ID_ANALOGUNITRANGETYPE_VALUEPRECISION 17572 /* Variable */ +#define UA_NS0ID_ANALOGUNITRANGETYPE_INSTRUMENTRANGE 17573 /* Variable */ +#define UA_NS0ID_ANALOGUNITRANGETYPE_EURANGE 17574 /* Variable */ +#define UA_NS0ID_ANALOGUNITRANGETYPE_ENGINEERINGUNITS 17575 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDRESS_NETWORKINTERFACE_SELECTIONS 17576 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDRESS_NETWORKINTERFACE_SELECTIONDESCRIPTIONS 17577 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDRESS_NETWORKINTERFACE_RESTRICTTOLIST 17578 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTTYPE_DISCOVERYADDRESS_NETWORKINTERFACE_SELECTIONS 17579 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTTYPE_DISCOVERYADDRESS_NETWORKINTERFACE_SELECTIONDESCRIPTIONS 17580 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTTYPE_DISCOVERYADDRESS_NETWORKINTERFACE_RESTRICTTOLIST 17581 /* Variable */ +#define UA_NS0ID_NETWORKADDRESSTYPE_NETWORKINTERFACE_SELECTIONS 17582 /* Variable */ +#define UA_NS0ID_NETWORKADDRESSTYPE_NETWORKINTERFACE_SELECTIONDESCRIPTIONS 17583 /* Variable */ +#define UA_NS0ID_NETWORKADDRESSTYPE_NETWORKINTERFACE_RESTRICTTOLIST 17584 /* Variable */ +#define UA_NS0ID_NETWORKADDRESSURLTYPE_NETWORKINTERFACE_SELECTIONS 17585 /* Variable */ +#define UA_NS0ID_NETWORKADDRESSURLTYPE_NETWORKINTERFACE_SELECTIONDESCRIPTIONS 17586 /* Variable */ +#define UA_NS0ID_NETWORKADDRESSURLTYPE_NETWORKINTERFACE_RESTRICTTOLIST 17587 /* Variable */ +#define UA_NS0ID_INDEX 17588 /* DataType */ +#define UA_NS0ID_DICTIONARYENTRYTYPE 17589 /* ObjectType */ +#define UA_NS0ID_DICTIONARYENTRYTYPE_DICTIONARYENTRYNAME_PLACEHOLDER 17590 /* Object */ +#define UA_NS0ID_DICTIONARYFOLDERTYPE 17591 /* ObjectType */ +#define UA_NS0ID_DICTIONARYFOLDERTYPE_DICTIONARYFOLDERNAME_PLACEHOLDER 17592 /* Object */ +#define UA_NS0ID_DICTIONARYFOLDERTYPE_DICTIONARYENTRYNAME_PLACEHOLDER 17593 /* Object */ +#define UA_NS0ID_DICTIONARIES 17594 /* Object */ +#define UA_NS0ID_DICTIONARIES_DICTIONARYFOLDERNAME_PLACEHOLDER 17595 /* Object */ +#define UA_NS0ID_DICTIONARIES_DICTIONARYENTRYNAME_PLACEHOLDER 17596 /* Object */ +#define UA_NS0ID_HASDICTIONARYENTRY 17597 /* ReferenceType */ +#define UA_NS0ID_IRDIDICTIONARYENTRYTYPE 17598 /* ObjectType */ +#define UA_NS0ID_IRDIDICTIONARYENTRYTYPE_DICTIONARYENTRYNAME_PLACEHOLDER 17599 /* Object */ +#define UA_NS0ID_URIDICTIONARYENTRYTYPE 17600 /* ObjectType */ +#define UA_NS0ID_URIDICTIONARYENTRYTYPE_DICTIONARYENTRYNAME_PLACEHOLDER 17601 /* Object */ +#define UA_NS0ID_BASEINTERFACETYPE 17602 /* ObjectType */ +#define UA_NS0ID_HASINTERFACE 17603 /* ReferenceType */ +#define UA_NS0ID_HASADDIN 17604 /* ReferenceType */ +#define UA_NS0ID_DEFAULTINSTANCEBROWSENAME 17605 /* Variable */ +#define UA_NS0ID_GENERICATTRIBUTEVALUE 17606 /* DataType */ +#define UA_NS0ID_GENERICATTRIBUTES 17607 /* DataType */ +#define UA_NS0ID_GENERICATTRIBUTEVALUE_ENCODING_DEFAULTXML 17608 /* Object */ +#define UA_NS0ID_GENERICATTRIBUTES_ENCODING_DEFAULTXML 17609 /* Object */ +#define UA_NS0ID_GENERICATTRIBUTEVALUE_ENCODING_DEFAULTBINARY 17610 /* Object */ +#define UA_NS0ID_GENERICATTRIBUTES_ENCODING_DEFAULTBINARY 17611 /* Object */ +#define UA_NS0ID_SERVERTYPE_LOCALTIME 17612 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPEADDWRITERGROUPMETHODTYPE_INPUTARGUMENTS 17613 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPEADDWRITERGROUPMETHODTYPE_OUTPUTARGUMENTS 17614 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_STATUSCODEID 17615 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_STATUSCODEID 17616 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_STATUSCODEID 17617 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_STATUSCODEID 17618 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_STATUSCODEID 17619 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_STATUSCODEID 17620 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_STATUSCODEID 17621 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_STATUSCODEID 17622 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_STATUSCODEID 17623 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_STATUSCODEID 17624 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_STATUSCODEID 17625 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_STATUSCODEID 17626 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_STATUSCODEID 17627 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_STATUSCODEID 17628 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_STATUSCODEID 17629 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONADDREADERGROUPGROUPMETHODTYPE 17630 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONADDREADERGROUPGROUPMETHODTYPE_INPUTARGUMENTS 17631 /* Variable */ +#define UA_NS0ID_SELECTIONLISTTYPE_SELECTIONS 17632 /* Variable */ +#define UA_NS0ID_SELECTIONLISTTYPE_SELECTIONDESCRIPTIONS 17633 /* Variable */ +#define UA_NS0ID_SERVER_LOCALTIME 17634 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_AVAILABLESTATES 17635 /* Variable */ +#define UA_NS0ID_FINITESTATEMACHINETYPE_AVAILABLETRANSITIONS 17636 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_AVAILABLESTATES 17637 /* Variable */ +#define UA_NS0ID_TEMPORARYFILETRANSFERTYPE_TRANSFERSTATE_PLACEHOLDER_AVAILABLETRANSITIONS 17638 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_AVAILABLESTATES 17639 /* Variable */ +#define UA_NS0ID_FILETRANSFERSTATEMACHINETYPE_AVAILABLETRANSITIONS 17640 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE 17641 /* ObjectType */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_EVENTID 17642 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_EVENTTYPE 17643 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_SOURCENODE 17644 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_SOURCENAME 17645 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_TIME 17646 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_RECEIVETIME 17647 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_LOCALTIME 17648 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_MESSAGE 17649 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_SEVERITY 17650 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_ACTIONTIMESTAMP 17651 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_STATUS 17652 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_SERVERID 17653 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_CLIENTAUDITENTRYID 17654 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_CLIENTUSERID 17655 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_METHODID 17656 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_INPUTARGUMENTS 17657 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_AVAILABLESTATES 17658 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17659 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_AVAILABLESTATES 17660 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_AVAILABLETRANSITIONS 17661 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_AVAILABLESTATES 17662 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_AVAILABLETRANSITIONS 17663 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17664 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17665 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_AVAILABLESTATES 17666 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITSTATEMACHINETYPE_AVAILABLETRANSITIONS 17667 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17668 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17669 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_AVAILABLESTATES 17670 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LIMITSTATE_AVAILABLETRANSITIONS 17671 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17672 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17673 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17674 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17675 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17676 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17677 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_AVAILABLESTATES 17678 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LIMITSTATE_AVAILABLETRANSITIONS 17679 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17680 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17681 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17682 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17683 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_AVAILABLESTATES 17684 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LIMITSTATE_AVAILABLETRANSITIONS 17685 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17686 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17687 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17688 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17689 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_AVAILABLESTATES 17690 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LIMITSTATE_AVAILABLETRANSITIONS 17691 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17692 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17693 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17694 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17695 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17696 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17697 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17698 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17699 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17700 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17701 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 17702 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 17703 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_AVAILABLESTATES 17704 /* Variable */ +#define UA_NS0ID_PROGRAMSTATEMACHINETYPE_AVAILABLETRANSITIONS 17705 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_TRANSPORTPROFILEURI_SELECTIONS 17706 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_TRANSPORTPROFILEURI_SELECTIONDESCRIPTIONS 17707 /* Variable */ +#define UA_NS0ID_INTERFACETYPES 17708 /* Object */ +#define UA_NS0ID_RATIONALNUMBERTYPE 17709 /* VariableType */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_TRANSPORTPROFILEURI_SELECTIONS 17710 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_TRANSPORTPROFILEURI_SELECTIONDESCRIPTIONS 17711 /* Variable */ +#define UA_NS0ID_RATIONALNUMBERTYPE_NUMERATOR 17712 /* Variable */ +#define UA_NS0ID_RATIONALNUMBERTYPE_DENOMINATOR 17713 /* Variable */ +#define UA_NS0ID_VECTORTYPE 17714 /* VariableType */ +#define UA_NS0ID_VECTORTYPE_VECTORUNIT 17715 /* Variable */ +#define UA_NS0ID_THREEDVECTORTYPE 17716 /* VariableType */ +#define UA_NS0ID_THREEDVECTORTYPE_VECTORUNIT 17717 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILEDIRECTORYNAME_PLACEHOLDER_DELETEFILESYSTEMOBJECT 17718 /* Method */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILEDIRECTORYNAME_PLACEHOLDER_DELETEFILESYSTEMOBJECT_INPUTARGUMENTS 17719 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONADDREADERGROUPGROUPMETHODTYPE_OUTPUTARGUMENTS 17720 /* Variable */ +#define UA_NS0ID_CONNECTIONTRANSPORTTYPE 17721 /* ObjectType */ +#define UA_NS0ID_FILESYSTEM_FILEDIRECTORYNAME_PLACEHOLDER_DELETEFILESYSTEMOBJECT 17722 /* Method */ +#define UA_NS0ID_FILESYSTEM_FILEDIRECTORYNAME_PLACEHOLDER_DELETEFILESYSTEMOBJECT_INPUTARGUMENTS 17723 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPE_MAXNETWORKMESSAGESIZE 17724 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE 17725 /* ObjectType */ +#define UA_NS0ID_WRITERGROUPTYPE_SECURITYMODE 17726 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_SECURITYGROUPID 17727 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_SECURITYKEYSERVICES 17728 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_MAXNETWORKMESSAGESIZE 17729 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_STATUS 17730 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_STATUS_STATE 17731 /* Variable */ +#define UA_NS0ID_AUTHORIZATIONSERVICES 17732 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_STATUS_ENABLE 17734 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_STATUS_DISABLE 17735 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_WRITERGROUPID 17736 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_PUBLISHINGINTERVAL 17737 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_KEEPALIVETIME 17738 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_PRIORITY 17739 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_LOCALEIDS 17740 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_TRANSPORTSETTINGS 17741 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_MESSAGESETTINGS 17742 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER 17743 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DATASETWRITERID 17744 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DATASETFIELDCONTENTMASK 17745 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_KEYFRAMECOUNT 17746 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_TRANSPORTSETTINGS 17747 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_MESSAGESETTINGS 17748 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS 17749 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS_STATE 17750 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS_ENABLE 17751 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_STATUS_DISABLE 17752 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS 17753 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_DIAGNOSTICSLEVEL 17754 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION 17755 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 17756 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 17757 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 17758 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 17759 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR 17760 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_ACTIVE 17761 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 17762 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 17763 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 17764 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_RESET 17765 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_SUBERROR 17766 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS 17767 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR 17768 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 17769 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 17770 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 17771 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 17772 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 17773 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 17774 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 17775 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 17776 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 17777 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 17778 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 17779 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 17780 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 17781 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 17782 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 17783 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 17784 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 17785 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 17786 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 17787 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 17788 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 17789 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 17790 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 17791 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 17792 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 17793 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 17794 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 17795 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 17796 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 17797 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES 17798 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES 17799 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_ACTIVE 17800 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_CLASSIFICATION 17801 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_DIAGNOSTICSLEVEL 17802 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_TIMEFIRSTCHANGE 17803 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER 17804 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER_DIAGNOSTICSLEVEL 17805 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_STATUSCODE 17806 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_STATUSCODE_DIAGNOSTICSLEVEL 17807 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MAJORVERSION 17808 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MAJORVERSION_DIAGNOSTICSLEVEL 17809 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MINORVERSION 17810 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MINORVERSION_DIAGNOSTICSLEVEL 17811 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS 17812 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_DIAGNOSTICSLEVEL 17813 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_TOTALINFORMATION 17814 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 17815 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 17816 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 17817 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 17818 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_TOTALERROR 17819 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_TOTALERROR_ACTIVE 17820 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 17821 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 17822 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 17823 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_RESET 17824 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_SUBERROR 17825 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS 17826 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEERROR 17827 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 17828 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 17829 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 17830 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 17831 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 17832 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 17833 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 17834 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 17835 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 17836 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 17837 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 17838 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 17839 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 17840 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 17841 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 17842 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 17843 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 17844 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 17845 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 17846 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 17847 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 17848 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 17849 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 17850 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 17851 /* Variable */ +#define UA_NS0ID_AUTHORIZATIONSERVICECONFIGURATIONTYPE 17852 /* ObjectType */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 17853 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 17854 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 17855 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 17856 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 17857 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_LIVEVALUES 17858 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_SENTNETWORKMESSAGES 17859 /* Variable */ +#define UA_NS0ID_AUTHORIZATIONSERVICECONFIGURATIONTYPE_SERVICECERTIFICATE 17860 /* Variable */ +#define UA_NS0ID_DECIMALDATATYPE 17861 /* DataType */ +#define UA_NS0ID_DECIMALDATATYPE_ENCODING_DEFAULTXML 17862 /* Object */ +#define UA_NS0ID_DECIMALDATATYPE_ENCODING_DEFAULTBINARY 17863 /* Object */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_SENTNETWORKMESSAGES_ACTIVE 17864 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_AUDIBLESOUND_LISTID 17865 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_AUDIBLESOUND_AGENCYID 17866 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_AUDIBLESOUND_VERSIONID 17867 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_UNSUPPRESS 17868 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_REMOVEFROMSERVICE 17869 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_PLACEINSERVICE 17870 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_SENTNETWORKMESSAGES_CLASSIFICATION 17871 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_SENTNETWORKMESSAGES_DIAGNOSTICSLEVEL 17872 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_SENTNETWORKMESSAGES_TIMEFIRSTCHANGE 17873 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_FAILEDTRANSMISSIONS 17874 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_UNSUPPRESS 17875 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_REMOVEFROMSERVICE 17876 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_PLACEINSERVICE 17877 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_FAILEDTRANSMISSIONS_ACTIVE 17878 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_AUDIBLESOUND_LISTID 17879 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_AUDIBLESOUND_AGENCYID 17880 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_AUDIBLESOUND_VERSIONID 17881 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_UNSUPPRESS 17882 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_REMOVEFROMSERVICE 17883 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_PLACEINSERVICE 17884 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_FAILEDTRANSMISSIONS_CLASSIFICATION 17885 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_AUDIBLESOUND_LISTID 17886 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_AUDIBLESOUND_AGENCYID 17887 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_AUDIBLESOUND_VERSIONID 17888 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_UNSUPPRESS 17889 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_REMOVEFROMSERVICE 17890 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_PLACEINSERVICE 17891 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_FAILEDTRANSMISSIONS_DIAGNOSTICSLEVEL 17892 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_AUDIBLESOUND_LISTID 17893 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_AUDIBLESOUND_AGENCYID 17894 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_AUDIBLESOUND_VERSIONID 17895 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_UNSUPPRESS 17896 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_REMOVEFROMSERVICE 17897 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_PLACEINSERVICE 17898 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_FAILEDTRANSMISSIONS_TIMEFIRSTCHANGE 17899 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_ENCRYPTIONERRORS 17900 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_ENCRYPTIONERRORS_ACTIVE 17901 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_ENCRYPTIONERRORS_CLASSIFICATION 17902 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_ENCRYPTIONERRORS_DIAGNOSTICSLEVEL 17903 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_REMOVEFROMSERVICE 17904 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_PLACEINSERVICE 17905 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_COUNTERS_ENCRYPTIONERRORS_TIMEFIRSTCHANGE 17906 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_AUDIBLESOUND_LISTID 17907 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_AUDIBLESOUND_AGENCYID 17908 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_AUDIBLESOUND_VERSIONID 17909 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_UNSUPPRESS 17910 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_REMOVEFROMSERVICE 17911 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_PLACEINSERVICE 17912 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETWRITERS 17913 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_AUDIBLESOUND_LISTID 17914 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_AUDIBLESOUND_AGENCYID 17915 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_AUDIBLESOUND_VERSIONID 17916 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_UNSUPPRESS 17917 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_REMOVEFROMSERVICE 17918 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_PLACEINSERVICE 17919 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETWRITERS_DIAGNOSTICSLEVEL 17920 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_AUDIBLESOUND_LISTID 17921 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_AUDIBLESOUND_AGENCYID 17922 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_AUDIBLESOUND_VERSIONID 17923 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_UNSUPPRESS 17924 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_REMOVEFROMSERVICE 17925 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_PLACEINSERVICE 17926 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETWRITERS 17927 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_AUDIBLESOUND_LISTID 17928 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_AUDIBLESOUND_AGENCYID 17929 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_AUDIBLESOUND_VERSIONID 17930 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_UNSUPPRESS 17931 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_REMOVEFROMSERVICE 17932 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_PLACEINSERVICE 17933 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETWRITERS_DIAGNOSTICSLEVEL 17934 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_AUDIBLESOUND_LISTID 17935 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_AUDIBLESOUND_AGENCYID 17936 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_AUDIBLESOUND_VERSIONID 17937 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_UNSUPPRESS 17938 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_REMOVEFROMSERVICE 17939 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_PLACEINSERVICE 17940 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_LIVEVALUES_SECURITYTOKENID 17941 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_AUDIBLESOUND_LISTID 17942 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_AUDIBLESOUND_AGENCYID 17943 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_AUDIBLESOUND_VERSIONID 17944 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_UNSUPPRESS 17945 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_REMOVEFROMSERVICE 17946 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_PLACEINSERVICE 17947 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_LIVEVALUES_SECURITYTOKENID_DIAGNOSTICSLEVEL 17948 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_AUDIBLESOUND_LISTID 17949 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_AUDIBLESOUND_AGENCYID 17950 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_AUDIBLESOUND_VERSIONID 17951 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_UNSUPPRESS 17952 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_REMOVEFROMSERVICE 17953 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_PLACEINSERVICE 17954 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_LIVEVALUES_TIMETONEXTTOKENID 17955 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_AUDIBLESOUND_LISTID 17956 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_AUDIBLESOUND_AGENCYID 17957 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_AUDIBLESOUND_VERSIONID 17958 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_UNSUPPRESS 17959 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_REMOVEFROMSERVICE 17960 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_PLACEINSERVICE 17961 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_DIAGNOSTICS_LIVEVALUES_TIMETONEXTTOKENID_DIAGNOSTICSLEVEL 17962 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_AUDIBLESOUND_LISTID 17963 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_AUDIBLESOUND_AGENCYID 17964 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_AUDIBLESOUND_VERSIONID 17965 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_UNSUPPRESS 17966 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_REMOVEFROMSERVICE 17967 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_PLACEINSERVICE 17968 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_ADDDATASETWRITER 17969 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_AUDIBLESOUND_LISTID 17970 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_AUDIBLESOUND_AGENCYID 17971 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_AUDIBLESOUND_VERSIONID 17972 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_UNSUPPRESS 17973 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_REMOVEFROMSERVICE 17974 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_PLACEINSERVICE 17975 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_ADDDATASETWRITER_INPUTARGUMENTS 17976 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_AUDIBLESOUND_LISTID 17977 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_AUDIBLESOUND_AGENCYID 17978 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_AUDIBLESOUND_VERSIONID 17979 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_UNSUPPRESS 17980 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_REMOVEFROMSERVICE 17981 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_PLACEINSERVICE 17982 /* Method */ +#define UA_NS0ID_HASEFFECTENABLE 17983 /* ReferenceType */ +#define UA_NS0ID_HASEFFECTSUPPRESSED 17984 /* ReferenceType */ +#define UA_NS0ID_HASEFFECTUNSUPPRESSED 17985 /* ReferenceType */ +#define UA_NS0ID_AUDIOVARIABLETYPE 17986 /* VariableType */ +#define UA_NS0ID_WRITERGROUPTYPE_ADDDATASETWRITER_OUTPUTARGUMENTS 17987 /* Variable */ +#define UA_NS0ID_AUDIOVARIABLETYPE_LISTID 17988 /* Variable */ +#define UA_NS0ID_AUDIOVARIABLETYPE_AGENCYID 17989 /* Variable */ +#define UA_NS0ID_AUDIOVARIABLETYPE_VERSIONID 17990 /* Variable */ +#define UA_NS0ID_ALARMMETRICSTYPE_STARTTIME 17991 /* Variable */ +#define UA_NS0ID_WRITERGROUPTYPE_REMOVEDATASETWRITER 17992 /* Method */ +#define UA_NS0ID_WRITERGROUPTYPE_REMOVEDATASETWRITER_INPUTARGUMENTS 17993 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPEADDWRITERMETHODTYPE 17994 /* Method */ +#define UA_NS0ID_PUBSUBGROUPTYPEADDWRITERMETHODTYPE_INPUTARGUMENTS 17995 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPEADDWRITERMETHODTYPE_OUTPUTARGUMENTS 17996 /* Variable */ +#define UA_NS0ID_WRITERGROUPTRANSPORTTYPE 17997 /* ObjectType */ +#define UA_NS0ID_WRITERGROUPMESSAGETYPE 17998 /* ObjectType */ +#define UA_NS0ID_READERGROUPTYPE 17999 /* ObjectType */ +#define UA_NS0ID_READERGROUPTYPE_SECURITYMODE 18000 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONTYPE 18001 /* ObjectType */ +#define UA_NS0ID_READERGROUPTYPE_SECURITYGROUPID 18002 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_SECURITYKEYSERVICES 18003 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONTYPE_ENDPOINTURLS 18004 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONTYPE_SERVICESTATUS 18005 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONTYPE_UPDATECREDENTIAL 18006 /* Method */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONTYPE_UPDATECREDENTIAL_INPUTARGUMENTS 18007 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONTYPE_DELETECREDENTIAL 18008 /* Method */ +#define UA_NS0ID_KEYCREDENTIALUPDATEMETHODTYPE 18009 /* Method */ +#define UA_NS0ID_KEYCREDENTIALUPDATEMETHODTYPE_INPUTARGUMENTS 18010 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE 18011 /* ObjectType */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_EVENTID 18012 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_EVENTTYPE 18013 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_SOURCENODE 18014 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_SOURCENAME 18015 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_TIME 18016 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_RECEIVETIME 18017 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_LOCALTIME 18018 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_MESSAGE 18019 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_SEVERITY 18020 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_ACTIONTIMESTAMP 18021 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_STATUS 18022 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_SERVERID 18023 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_CLIENTAUDITENTRYID 18024 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_CLIENTUSERID 18025 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_METHODID 18026 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_INPUTARGUMENTS 18027 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_RESOURCEURI 18028 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE 18029 /* ObjectType */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_EVENTID 18030 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_EVENTTYPE 18031 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_SOURCENODE 18032 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_SOURCENAME 18033 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_TIME 18034 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_RECEIVETIME 18035 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_LOCALTIME 18036 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_MESSAGE 18037 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_SEVERITY 18038 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_ACTIONTIMESTAMP 18039 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_STATUS 18040 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_SERVERID 18041 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_CLIENTAUDITENTRYID 18042 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_CLIENTUSERID 18043 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_METHODID 18044 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_INPUTARGUMENTS 18045 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_RESOURCEURI 18046 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE 18047 /* ObjectType */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_EVENTID 18048 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_EVENTTYPE 18049 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_SOURCENODE 18050 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_SOURCENAME 18051 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_TIME 18052 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_RECEIVETIME 18053 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_LOCALTIME 18054 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_MESSAGE 18055 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_SEVERITY 18056 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_ACTIONTIMESTAMP 18057 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_STATUS 18058 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_SERVERID 18059 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_CLIENTAUDITENTRYID 18060 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_CLIENTUSERID 18061 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_METHODID 18062 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_INPUTARGUMENTS 18063 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_RESOURCEURI 18064 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_MAXNETWORKMESSAGESIZE 18065 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_STATUS 18067 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_STATUS_STATE 18068 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONTYPE_RESOURCEURI 18069 /* Variable */ +#define UA_NS0ID_AUTHORIZATIONSERVICECONFIGURATIONTYPE_SERVICEURI 18072 /* Variable */ +#define UA_NS0ID_AUTHORIZATIONSERVICECONFIGURATIONTYPE_ISSUERENDPOINTURL 18073 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_STATUS_ENABLE 18074 /* Method */ +#define UA_NS0ID_READERGROUPTYPE_STATUS_DISABLE 18075 /* Method */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER 18076 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_PUBLISHERID 18077 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_WRITERGROUPID 18078 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DATASETWRITERID 18079 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DATASETMETADATA 18080 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DATASETFIELDCONTENTMASK 18081 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_MESSAGERECEIVETIMEOUT 18082 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_SECURITYMODE 18083 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_SECURITYGROUPID 18084 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_SECURITYKEYSERVICES 18085 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_TRANSPORTSETTINGS 18086 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_MESSAGESETTINGS 18087 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_STATUS 18088 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_STATUS_STATE 18089 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_STATUS_ENABLE 18090 /* Method */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_STATUS_DISABLE 18091 /* Method */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS 18092 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_DIAGNOSTICSLEVEL 18093 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION 18094 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 18095 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 18096 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 18097 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 18098 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR 18099 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_ACTIVE 18100 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 18101 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 18102 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 18103 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_RESET 18104 /* Method */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_SUBERROR 18105 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS 18106 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR 18107 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 18108 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 18109 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 18110 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 18111 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 18112 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 18113 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 18114 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 18115 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 18116 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 18117 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 18118 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 18119 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 18120 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 18121 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 18122 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 18123 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 18124 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 18125 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 18126 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 18127 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 18128 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 18129 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 18130 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 18131 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 18132 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 18133 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 18134 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 18135 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 18136 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES 18137 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES 18138 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_ACTIVE 18139 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_CLASSIFICATION 18140 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_DIAGNOSTICSLEVEL 18141 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_TIMEFIRSTCHANGE 18142 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS 18143 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_ACTIVE 18144 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_CLASSIFICATION 18145 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_DIAGNOSTICSLEVEL 18146 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_TIMEFIRSTCHANGE 18147 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER 18148 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER_DIAGNOSTICSLEVEL 18149 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_STATUSCODE 18150 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_STATUSCODE_DIAGNOSTICSLEVEL 18151 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MAJORVERSION 18152 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MAJORVERSION_DIAGNOSTICSLEVEL 18153 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MINORVERSION 18154 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION 18155 /* Object */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_SERVICENAME_PLACEHOLDER 18156 /* Object */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_SERVICENAME_PLACEHOLDER_RESOURCEURI 18157 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MINORVERSION_DIAGNOSTICSLEVEL 18158 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_SERVICENAME_PLACEHOLDER_ENDPOINTURLS 18159 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_SERVICENAME_PLACEHOLDER_SERVICESTATUS 18160 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_SERVICENAME_PLACEHOLDER_UPDATECREDENTIAL 18161 /* Method */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_SERVICENAME_PLACEHOLDER_UPDATECREDENTIAL_INPUTARGUMENTS 18162 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_SERVICENAME_PLACEHOLDER_DELETECREDENTIAL 18163 /* Method */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATION_SERVICENAME_PLACEHOLDER_PROFILEURI 18164 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALCONFIGURATIONTYPE_PROFILEURI 18165 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATATYPEDEFINITION 18166 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATATYPEDEFINITION_DATATYPEVERSION 18167 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATATYPEDEFINITION_DICTIONARYFRAGMENT 18168 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STRUCTUREFIELD 18169 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STRUCTUREFIELD_DATATYPEVERSION 18170 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STRUCTUREFIELD_DICTIONARYFRAGMENT 18171 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STRUCTUREDEFINITION 18172 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STRUCTUREDEFINITION_DATATYPEVERSION 18173 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STRUCTUREDEFINITION_DICTIONARYFRAGMENT 18174 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENUMDEFINITION 18175 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENUMDEFINITION_DATATYPEVERSION 18176 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ENUMDEFINITION_DICTIONARYFRAGMENT 18177 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATATYPEDEFINITION 18178 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATATYPEDEFINITION_DATATYPEVERSION 18179 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATATYPEDEFINITION_DICTIONARYFRAGMENT 18180 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STRUCTUREFIELD 18181 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STRUCTUREFIELD_DATATYPEVERSION 18182 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STRUCTUREFIELD_DICTIONARYFRAGMENT 18183 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STRUCTUREDEFINITION 18184 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STRUCTUREDEFINITION_DATATYPEVERSION 18185 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STRUCTUREDEFINITION_DICTIONARYFRAGMENT 18186 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENUMDEFINITION 18187 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENUMDEFINITION_DATATYPEVERSION 18188 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ENUMDEFINITION_DICTIONARYFRAGMENT 18189 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_LATCHEDSTATE 18190 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_LATCHEDSTATE_ID 18191 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_LATCHEDSTATE_NAME 18192 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_LATCHEDSTATE_NUMBER 18193 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18194 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_LATCHEDSTATE_TRANSITIONTIME 18195 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18196 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_LATCHEDSTATE_TRUESTATE 18197 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_LATCHEDSTATE_FALSESTATE 18198 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_RESET 18199 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_AUDIBLESOUND_LISTID 18200 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_AUDIBLESOUND_AGENCYID 18201 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_AUDIBLESOUND_VERSIONID 18202 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE 18203 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_ID 18204 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_NAME 18205 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_NUMBER 18206 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18207 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_TRANSITIONTIME 18208 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18209 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_TRUESTATE 18210 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_FALSESTATE 18211 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_RESET 18212 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_LATCHEDSTATE 18213 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LATCHEDSTATE_ID 18214 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LATCHEDSTATE_NAME 18215 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LATCHEDSTATE_NUMBER 18216 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18217 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18218 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18219 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LATCHEDSTATE_TRUESTATE 18220 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LATCHEDSTATE_FALSESTATE 18221 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_RESET 18222 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LATCHEDSTATE 18223 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_ID 18224 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_NAME 18225 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_NUMBER 18226 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18227 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18228 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18229 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_TRUESTATE 18230 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_FALSESTATE 18231 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_RESET 18232 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LATCHEDSTATE 18233 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_ID 18234 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_NAME 18235 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_NUMBER 18236 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18237 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18238 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18239 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_TRUESTATE 18240 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LATCHEDSTATE_FALSESTATE 18241 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_RESET 18242 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_AUDIBLESOUND_LISTID 18243 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_AUDIBLESOUND_AGENCYID 18244 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_AUDIBLESOUND_VERSIONID 18245 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LATCHEDSTATE 18246 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_ID 18247 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_NAME 18248 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_NUMBER 18249 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18250 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18251 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18252 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_TRUESTATE 18253 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_FALSESTATE 18254 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_UNSUPPRESS 18255 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_RESET 18256 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LATCHEDSTATE 18257 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_ID 18258 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_NAME 18259 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_NUMBER 18260 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18261 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18262 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18263 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_TRUESTATE 18264 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LATCHEDSTATE_FALSESTATE 18265 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_RESET 18266 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE 18267 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_ID 18268 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_NAME 18269 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_NUMBER 18270 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18271 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18272 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18273 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_TRUESTATE 18274 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_FALSESTATE 18275 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_RESET 18276 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE 18277 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_ID 18278 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_NAME 18279 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_NUMBER 18280 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18281 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18282 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18283 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_TRUESTATE 18284 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_FALSESTATE 18285 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_RESET 18286 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE 18287 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_ID 18288 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_NAME 18289 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_NUMBER 18290 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18291 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18292 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18293 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_TRUESTATE 18294 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LATCHEDSTATE_FALSESTATE 18295 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_RESET 18296 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE 18297 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_ID 18298 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_NAME 18299 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_NUMBER 18300 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18301 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18302 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18303 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_TRUESTATE 18304 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LATCHEDSTATE_FALSESTATE 18305 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_RESET 18306 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_LATCHEDSTATE 18307 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_LATCHEDSTATE_ID 18308 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_LATCHEDSTATE_NAME 18309 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_LATCHEDSTATE_NUMBER 18310 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18311 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18312 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18313 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_LATCHEDSTATE_TRUESTATE 18314 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_LATCHEDSTATE_FALSESTATE 18315 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_RESET 18316 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_LATCHEDSTATE 18317 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_LATCHEDSTATE_ID 18318 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_LATCHEDSTATE_NAME 18319 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_LATCHEDSTATE_NUMBER 18320 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18321 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18322 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18323 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_LATCHEDSTATE_TRUESTATE 18324 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_LATCHEDSTATE_FALSESTATE 18325 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_RESET 18326 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_LATCHEDSTATE 18327 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_LATCHEDSTATE_ID 18328 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_LATCHEDSTATE_NAME 18329 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_LATCHEDSTATE_NUMBER 18330 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18331 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18332 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18333 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_LATCHEDSTATE_TRUESTATE 18334 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_LATCHEDSTATE_FALSESTATE 18335 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_RESET 18336 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_LATCHEDSTATE 18337 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_LATCHEDSTATE_ID 18338 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_LATCHEDSTATE_NAME 18339 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_LATCHEDSTATE_NUMBER 18340 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18341 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18342 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18343 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_LATCHEDSTATE_TRUESTATE 18344 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_LATCHEDSTATE_FALSESTATE 18345 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_RESET 18346 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE 18347 /* ObjectType */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_EVENTID 18348 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_EVENTTYPE 18349 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SOURCENODE 18350 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SOURCENAME 18351 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_TIME 18352 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_RECEIVETIME 18353 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_LOCALTIME 18354 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_MESSAGE 18355 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SEVERITY 18356 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONDITIONCLASSID 18357 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONDITIONCLASSNAME 18358 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONDITIONSUBCLASSID 18359 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONDITIONSUBCLASSNAME 18360 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONDITIONNAME 18361 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_BRANCHID 18362 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_RETAIN 18363 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ENABLEDSTATE 18364 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ENABLEDSTATE_ID 18365 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ENABLEDSTATE_NAME 18366 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ENABLEDSTATE_NUMBER 18367 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 18368 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 18369 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 18370 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ENABLEDSTATE_TRUESTATE 18371 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ENABLEDSTATE_FALSESTATE 18372 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_QUALITY 18373 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_QUALITY_SOURCETIMESTAMP 18374 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_LASTSEVERITY 18375 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 18376 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_COMMENT 18377 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_COMMENT_SOURCETIMESTAMP 18378 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CLIENTUSERID 18379 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_DISABLE 18380 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ENABLE 18381 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ADDCOMMENT 18382 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 18383 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONDITIONREFRESH 18384 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 18385 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONDITIONREFRESH2 18386 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 18387 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACKEDSTATE 18388 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACKEDSTATE_ID 18389 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACKEDSTATE_NAME 18390 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACKEDSTATE_NUMBER 18391 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 18392 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACKEDSTATE_TRANSITIONTIME 18393 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 18394 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACKEDSTATE_TRUESTATE 18395 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACKEDSTATE_FALSESTATE 18396 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONFIRMEDSTATE 18397 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_ID 18398 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_NAME 18399 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_NUMBER 18400 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 18401 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 18402 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 18403 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_TRUESTATE 18404 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_FALSESTATE 18405 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACKNOWLEDGE 18406 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 18407 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONFIRM 18408 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_CONFIRM_INPUTARGUMENTS 18409 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACTIVESTATE 18410 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACTIVESTATE_ID 18411 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACTIVESTATE_NAME 18412 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACTIVESTATE_NUMBER 18413 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 18414 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACTIVESTATE_TRANSITIONTIME 18415 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 18416 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACTIVESTATE_TRUESTATE 18417 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ACTIVESTATE_FALSESTATE 18418 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_INPUTNODE 18419 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE 18420 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_ID 18421 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_NAME 18422 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_NUMBER 18423 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 18424 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 18425 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 18426 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 18427 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 18428 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE 18429 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_ID 18430 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_NAME 18431 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_NUMBER 18432 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 18433 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 18434 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 18435 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 18436 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 18437 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE 18438 /* Object */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_CURRENTSTATE 18439 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 18440 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 18441 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 18442 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 18443 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_LASTTRANSITION 18444 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 18445 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 18446 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 18447 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 18448 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 18449 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 18450 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 18451 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_UNSHELVETIME 18452 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 18453 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 18454 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_UNSHELVE 18455 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 18456 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESSEDORSHELVED 18457 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_MAXTIMESHELVED 18458 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_AUDIBLEENABLED 18459 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_AUDIBLESOUND 18460 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_AUDIBLESOUND_LISTID 18461 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_AUDIBLESOUND_AGENCYID 18462 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_AUDIBLESOUND_VERSIONID 18463 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SILENCESTATE 18464 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SILENCESTATE_ID 18465 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SILENCESTATE_NAME 18466 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SILENCESTATE_NUMBER 18467 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 18468 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SILENCESTATE_TRANSITIONTIME 18469 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 18470 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SILENCESTATE_TRUESTATE 18471 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SILENCESTATE_FALSESTATE 18472 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ONDELAY 18473 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_OFFDELAY 18474 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_FIRSTINGROUPFLAG 18475 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_FIRSTINGROUP 18476 /* Object */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_LATCHEDSTATE 18477 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_LATCHEDSTATE_ID 18478 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_LATCHEDSTATE_NAME 18479 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_LATCHEDSTATE_NUMBER 18480 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18481 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18482 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18483 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_LATCHEDSTATE_TRUESTATE 18484 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_LATCHEDSTATE_FALSESTATE 18485 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_ALARMGROUP_PLACEHOLDER 18486 /* Object */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_REALARMTIME 18487 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_REALARMREPEATCOUNT 18488 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SILENCE 18489 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESS 18490 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_UNSUPPRESS 18491 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_REMOVEFROMSERVICE 18492 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_PLACEINSERVICE 18493 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_RESET 18494 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_NORMALSTATE 18495 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE 18496 /* ObjectType */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_EVENTID 18497 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_EVENTTYPE 18498 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SOURCENODE 18499 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SOURCENAME 18500 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_TIME 18501 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_RECEIVETIME 18502 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_LOCALTIME 18503 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_MESSAGE 18504 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SEVERITY 18505 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONDITIONCLASSID 18506 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONDITIONCLASSNAME 18507 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONDITIONSUBCLASSID 18508 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONDITIONSUBCLASSNAME 18509 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONDITIONNAME 18510 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_BRANCHID 18511 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_RETAIN 18512 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ENABLEDSTATE 18513 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ENABLEDSTATE_ID 18514 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ENABLEDSTATE_NAME 18515 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ENABLEDSTATE_NUMBER 18516 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 18517 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 18518 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 18519 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ENABLEDSTATE_TRUESTATE 18520 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ENABLEDSTATE_FALSESTATE 18521 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_QUALITY 18522 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_QUALITY_SOURCETIMESTAMP 18523 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_LASTSEVERITY 18524 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 18525 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_COMMENT 18526 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_COMMENT_SOURCETIMESTAMP 18527 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CLIENTUSERID 18528 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_DISABLE 18529 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ENABLE 18530 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ADDCOMMENT 18531 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 18532 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONDITIONREFRESH 18533 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 18534 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONDITIONREFRESH2 18535 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 18536 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACKEDSTATE 18537 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACKEDSTATE_ID 18538 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACKEDSTATE_NAME 18539 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACKEDSTATE_NUMBER 18540 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 18541 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACKEDSTATE_TRANSITIONTIME 18542 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 18543 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACKEDSTATE_TRUESTATE 18544 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACKEDSTATE_FALSESTATE 18545 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONFIRMEDSTATE 18546 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_ID 18547 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_NAME 18548 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_NUMBER 18549 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 18550 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 18551 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 18552 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_TRUESTATE 18553 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONFIRMEDSTATE_FALSESTATE 18554 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACKNOWLEDGE 18555 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 18556 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONFIRM 18557 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_CONFIRM_INPUTARGUMENTS 18558 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACTIVESTATE 18559 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACTIVESTATE_ID 18560 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACTIVESTATE_NAME 18561 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACTIVESTATE_NUMBER 18562 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 18563 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACTIVESTATE_TRANSITIONTIME 18564 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 18565 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACTIVESTATE_TRUESTATE 18566 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ACTIVESTATE_FALSESTATE 18567 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_INPUTNODE 18568 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE 18569 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_ID 18570 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_NAME 18571 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_NUMBER 18572 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 18573 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 18574 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 18575 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 18576 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 18577 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE 18578 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_ID 18579 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_NAME 18580 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_NUMBER 18581 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 18582 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 18583 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 18584 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 18585 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 18586 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE 18587 /* Object */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_CURRENTSTATE 18588 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 18589 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 18590 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 18591 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 18592 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_LASTTRANSITION 18593 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 18594 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 18595 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 18596 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 18597 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 18598 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 18599 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 18600 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_UNSHELVETIME 18601 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 18602 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 18603 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_UNSHELVE 18604 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 18605 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESSEDORSHELVED 18606 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_MAXTIMESHELVED 18607 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_AUDIBLEENABLED 18608 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_AUDIBLESOUND 18609 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_AUDIBLESOUND_LISTID 18610 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_AUDIBLESOUND_AGENCYID 18611 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_AUDIBLESOUND_VERSIONID 18612 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SILENCESTATE 18613 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SILENCESTATE_ID 18614 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SILENCESTATE_NAME 18615 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SILENCESTATE_NUMBER 18616 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 18617 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SILENCESTATE_TRANSITIONTIME 18618 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 18619 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SILENCESTATE_TRUESTATE 18620 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SILENCESTATE_FALSESTATE 18621 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ONDELAY 18622 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_OFFDELAY 18623 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_FIRSTINGROUPFLAG 18624 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_FIRSTINGROUP 18625 /* Object */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_LATCHEDSTATE 18626 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_LATCHEDSTATE_ID 18627 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_LATCHEDSTATE_NAME 18628 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_LATCHEDSTATE_NUMBER 18629 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18630 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18631 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18632 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_LATCHEDSTATE_TRUESTATE 18633 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_LATCHEDSTATE_FALSESTATE 18634 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_ALARMGROUP_PLACEHOLDER 18635 /* Object */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_REALARMTIME 18636 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_REALARMREPEATCOUNT 18637 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SILENCE 18638 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESS 18639 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_UNSUPPRESS 18640 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_REMOVEFROMSERVICE 18641 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_PLACEINSERVICE 18642 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_RESET 18643 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_NORMALSTATE 18644 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_LATCHEDSTATE 18645 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_LATCHEDSTATE_ID 18646 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_LATCHEDSTATE_NAME 18647 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_LATCHEDSTATE_NUMBER 18648 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18649 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18650 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18651 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_LATCHEDSTATE_TRUESTATE 18652 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_LATCHEDSTATE_FALSESTATE 18653 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_RESET 18654 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_LATCHEDSTATE 18655 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_LATCHEDSTATE_ID 18656 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_LATCHEDSTATE_NAME 18657 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_LATCHEDSTATE_NUMBER 18658 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 18659 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 18660 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 18661 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_LATCHEDSTATE_TRUESTATE 18662 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_LATCHEDSTATE_FALSESTATE 18663 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_RESET 18664 /* Method */ +#define UA_NS0ID_STATISTICALCONDITIONCLASSTYPE 18665 /* ObjectType */ +#define UA_NS0ID_ALARMMETRICSTYPE_RESET 18666 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS 18667 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_DIAGNOSTICSLEVEL 18668 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION 18669 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 18670 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 18671 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 18672 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 18673 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR 18674 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_ACTIVE 18675 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 18676 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 18677 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 18678 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_RESET 18679 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_SUBERROR 18680 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS 18681 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR 18682 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 18683 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 18684 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 18685 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 18686 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 18687 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 18688 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 18689 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 18690 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 18691 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 18692 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 18693 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 18694 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 18695 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 18696 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 18697 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 18698 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 18699 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 18700 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 18701 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 18702 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 18703 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 18704 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 18705 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 18706 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 18707 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 18708 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 18709 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 18710 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 18711 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES 18712 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_RESOLVEDADDRESS 18713 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_RESOLVEDADDRESS_DIAGNOSTICSLEVEL 18714 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS 18715 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_DIAGNOSTICSLEVEL 18716 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_TOTALINFORMATION 18717 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 18718 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 18719 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 18720 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 18721 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_TOTALERROR 18722 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_TOTALERROR_ACTIVE 18723 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 18724 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 18725 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 18726 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_RESET 18727 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_SUBERROR 18728 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS 18729 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEERROR 18730 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 18731 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 18732 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 18733 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 18734 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 18735 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 18736 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 18737 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 18738 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 18739 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 18740 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 18741 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 18742 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 18743 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 18744 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 18745 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 18746 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 18747 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 18748 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 18749 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 18750 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 18751 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 18752 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 18753 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 18754 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 18755 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 18756 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 18757 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 18758 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 18759 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_LIVEVALUES 18760 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETWRITERS 18761 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETWRITERS_DIAGNOSTICSLEVEL 18762 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETREADERS 18763 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETREADERS_DIAGNOSTICSLEVEL 18764 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETWRITERS 18765 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETWRITERS_DIAGNOSTICSLEVEL 18766 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETREADERS 18767 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETREADERS_DIAGNOSTICSLEVEL 18768 /* Variable */ +#define UA_NS0ID_THREEDVECTORTYPE_X 18769 /* Variable */ +#define UA_NS0ID_THREEDVECTORTYPE_Y 18770 /* Variable */ +#define UA_NS0ID_THREEDVECTORTYPE_Z 18771 /* Variable */ +#define UA_NS0ID_CARTESIANCOORDINATESTYPE 18772 /* VariableType */ +#define UA_NS0ID_CARTESIANCOORDINATESTYPE_LENGTHUNIT 18773 /* Variable */ +#define UA_NS0ID_THREEDCARTESIANCOORDINATESTYPE 18774 /* VariableType */ +#define UA_NS0ID_THREEDCARTESIANCOORDINATESTYPE_LENGTHUNIT 18775 /* Variable */ +#define UA_NS0ID_THREEDCARTESIANCOORDINATESTYPE_X 18776 /* Variable */ +#define UA_NS0ID_THREEDCARTESIANCOORDINATESTYPE_Y 18777 /* Variable */ +#define UA_NS0ID_THREEDCARTESIANCOORDINATESTYPE_Z 18778 /* Variable */ +#define UA_NS0ID_ORIENTATIONTYPE 18779 /* VariableType */ +#define UA_NS0ID_ORIENTATIONTYPE_ANGLEUNIT 18780 /* Variable */ +#define UA_NS0ID_THREEDORIENTATIONTYPE 18781 /* VariableType */ +#define UA_NS0ID_THREEDORIENTATIONTYPE_ANGLEUNIT 18782 /* Variable */ +#define UA_NS0ID_THREEDORIENTATIONTYPE_A 18783 /* Variable */ +#define UA_NS0ID_THREEDORIENTATIONTYPE_B 18784 /* Variable */ +#define UA_NS0ID_THREEDORIENTATIONTYPE_C 18785 /* Variable */ +#define UA_NS0ID_FRAMETYPE 18786 /* VariableType */ +#define UA_NS0ID_FRAMETYPE_ORIENTATION 18787 /* Variable */ +#define UA_NS0ID_FRAMETYPE_CONSTANT 18788 /* Variable */ +#define UA_NS0ID_FRAMETYPE_BASEFRAME 18789 /* Variable */ +#define UA_NS0ID_FRAMETYPE_FIXEDBASE 18790 /* Variable */ +#define UA_NS0ID_THREEDFRAMETYPE 18791 /* VariableType */ +#define UA_NS0ID_THREEDFRAMETYPE_ORIENTATION 18792 /* Variable */ +#define UA_NS0ID_THREEDFRAMETYPE_CONSTANT 18793 /* Variable */ +#define UA_NS0ID_THREEDFRAMETYPE_BASEFRAME 18794 /* Variable */ +#define UA_NS0ID_THREEDFRAMETYPE_FIXEDBASE 18795 /* Variable */ +#define UA_NS0ID_THREEDFRAMETYPE_CARTESIANCOORDINATES 18796 /* Variable */ +#define UA_NS0ID_THREEDFRAMETYPE_CARTESIANCOORDINATES_LENGTHUNIT 18797 /* Variable */ +#define UA_NS0ID_THREEDFRAMETYPE_CARTESIANCOORDINATES_X 18798 /* Variable */ +#define UA_NS0ID_THREEDFRAMETYPE_CARTESIANCOORDINATES_Y 18799 /* Variable */ +#define UA_NS0ID_THREEDFRAMETYPE_CARTESIANCOORDINATES_Z 18800 /* Variable */ +#define UA_NS0ID_FRAMETYPE_CARTESIANCOORDINATES 18801 /* Variable */ +#define UA_NS0ID_FRAMETYPE_CARTESIANCOORDINATES_LENGTHUNIT 18802 /* Variable */ +#define UA_NS0ID_FRAMETYPE_ORIENTATION_ANGLEUNIT 18803 /* Variable */ +#define UA_NS0ID_HASWRITERGROUP 18804 /* ReferenceType */ +#define UA_NS0ID_HASREADERGROUP 18805 /* ReferenceType */ +#define UA_NS0ID_RATIONALNUMBER 18806 /* DataType */ +#define UA_NS0ID_VECTOR 18807 /* DataType */ +#define UA_NS0ID_THREEDVECTOR 18808 /* DataType */ +#define UA_NS0ID_CARTESIANCOORDINATES 18809 /* DataType */ +#define UA_NS0ID_THREEDCARTESIANCOORDINATES 18810 /* DataType */ +#define UA_NS0ID_ORIENTATION 18811 /* DataType */ +#define UA_NS0ID_THREEDORIENTATION 18812 /* DataType */ +#define UA_NS0ID_FRAME 18813 /* DataType */ +#define UA_NS0ID_THREEDFRAME 18814 /* DataType */ +#define UA_NS0ID_RATIONALNUMBER_ENCODING_DEFAULTBINARY 18815 /* Object */ +#define UA_NS0ID_VECTOR_ENCODING_DEFAULTBINARY 18816 /* Object */ +#define UA_NS0ID_THREEDVECTOR_ENCODING_DEFAULTBINARY 18817 /* Object */ +#define UA_NS0ID_CARTESIANCOORDINATES_ENCODING_DEFAULTBINARY 18818 /* Object */ +#define UA_NS0ID_THREEDCARTESIANCOORDINATES_ENCODING_DEFAULTBINARY 18819 /* Object */ +#define UA_NS0ID_ORIENTATION_ENCODING_DEFAULTBINARY 18820 /* Object */ +#define UA_NS0ID_THREEDORIENTATION_ENCODING_DEFAULTBINARY 18821 /* Object */ +#define UA_NS0ID_FRAME_ENCODING_DEFAULTBINARY 18822 /* Object */ +#define UA_NS0ID_THREEDFRAME_ENCODING_DEFAULTBINARY 18823 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RATIONALNUMBER 18824 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RATIONALNUMBER_DATATYPEVERSION 18825 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RATIONALNUMBER_DICTIONARYFRAGMENT 18826 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_VECTOR 18827 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_VECTOR_DATATYPEVERSION 18828 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_VECTOR_DICTIONARYFRAGMENT 18829 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_THREEDVECTOR 18830 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_THREEDVECTOR_DATATYPEVERSION 18831 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_THREEDVECTOR_DICTIONARYFRAGMENT 18832 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CARTESIANCOORDINATES 18833 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CARTESIANCOORDINATES_DATATYPEVERSION 18834 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CARTESIANCOORDINATES_DICTIONARYFRAGMENT 18835 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_THREEDCARTESIANCOORDINATES 18836 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_THREEDCARTESIANCOORDINATES_DATATYPEVERSION 18837 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_THREEDCARTESIANCOORDINATES_DICTIONARYFRAGMENT 18838 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ORIENTATION 18839 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ORIENTATION_DATATYPEVERSION 18840 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ORIENTATION_DICTIONARYFRAGMENT 18841 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_THREEDORIENTATION 18842 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_THREEDORIENTATION_DATATYPEVERSION 18843 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_THREEDORIENTATION_DICTIONARYFRAGMENT 18844 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_FRAME 18845 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_FRAME_DATATYPEVERSION 18846 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_FRAME_DICTIONARYFRAGMENT 18847 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_THREEDFRAME 18848 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_THREEDFRAME_DATATYPEVERSION 18849 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_THREEDFRAME_DICTIONARYFRAGMENT 18850 /* Variable */ +#define UA_NS0ID_RATIONALNUMBER_ENCODING_DEFAULTXML 18851 /* Object */ +#define UA_NS0ID_VECTOR_ENCODING_DEFAULTXML 18852 /* Object */ +#define UA_NS0ID_THREEDVECTOR_ENCODING_DEFAULTXML 18853 /* Object */ +#define UA_NS0ID_CARTESIANCOORDINATES_ENCODING_DEFAULTXML 18854 /* Object */ +#define UA_NS0ID_THREEDCARTESIANCOORDINATES_ENCODING_DEFAULTXML 18855 /* Object */ +#define UA_NS0ID_ORIENTATION_ENCODING_DEFAULTXML 18856 /* Object */ +#define UA_NS0ID_THREEDORIENTATION_ENCODING_DEFAULTXML 18857 /* Object */ +#define UA_NS0ID_FRAME_ENCODING_DEFAULTXML 18858 /* Object */ +#define UA_NS0ID_THREEDFRAME_ENCODING_DEFAULTXML 18859 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RATIONALNUMBER 18860 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RATIONALNUMBER_DATATYPEVERSION 18861 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RATIONALNUMBER_DICTIONARYFRAGMENT 18862 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_VECTOR 18863 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_VECTOR_DATATYPEVERSION 18864 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_VECTOR_DICTIONARYFRAGMENT 18865 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_THREEDVECTOR 18866 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_THREEDVECTOR_DATATYPEVERSION 18867 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_THREEDVECTOR_DICTIONARYFRAGMENT 18868 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CARTESIANCOORDINATES 18869 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CARTESIANCOORDINATES_DATATYPEVERSION 18870 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS 18871 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_DIAGNOSTICSLEVEL 18872 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION 18873 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 18874 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 18875 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 18876 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 18877 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR 18878 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_ACTIVE 18879 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 18880 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 18881 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 18882 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_RESET 18883 /* Method */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_SUBERROR 18884 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS 18885 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR 18886 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 18887 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 18888 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 18889 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 18890 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 18891 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 18892 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 18893 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 18894 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 18895 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 18896 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 18897 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 18898 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 18899 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 18900 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 18901 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 18902 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 18903 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 18904 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 18905 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 18906 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 18907 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 18908 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 18909 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 18910 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 18911 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 18912 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 18913 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 18914 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 18915 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES 18916 /* Object */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES 18917 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_ACTIVE 18918 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_CLASSIFICATION 18919 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_DIAGNOSTICSLEVEL 18920 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_TIMEFIRSTCHANGE 18921 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER 18922 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER_DIAGNOSTICSLEVEL 18923 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_STATUSCODE 18924 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_STATUSCODE_DIAGNOSTICSLEVEL 18925 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MAJORVERSION 18926 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MAJORVERSION_DIAGNOSTICSLEVEL 18927 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MINORVERSION 18928 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MINORVERSION_DIAGNOSTICSLEVEL 18929 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS 18930 /* Object */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_DIAGNOSTICSLEVEL 18931 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION 18932 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 18933 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 18934 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 18935 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 18936 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR 18937 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_ACTIVE 18938 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 18939 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 18940 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 18941 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_RESET 18942 /* Method */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_SUBERROR 18943 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS 18944 /* Object */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR 18945 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 18946 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 18947 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 18948 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 18949 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 18950 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 18951 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 18952 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 18953 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 18954 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 18955 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 18956 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 18957 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 18958 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 18959 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 18960 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 18961 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 18962 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 18963 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 18964 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 18965 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 18966 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 18967 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 18968 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 18969 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 18970 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 18971 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 18972 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 18973 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 18974 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES 18975 /* Object */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES 18976 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_ACTIVE 18977 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_CLASSIFICATION 18978 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_DIAGNOSTICSLEVEL 18979 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_TIMEFIRSTCHANGE 18980 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER 18981 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER_DIAGNOSTICSLEVEL 18982 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_STATUSCODE 18983 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_STATUSCODE_DIAGNOSTICSLEVEL 18984 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MAJORVERSION 18985 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MAJORVERSION_DIAGNOSTICSLEVEL 18986 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MINORVERSION 18987 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MINORVERSION_DIAGNOSTICSLEVEL 18988 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS 18989 /* Object */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_DIAGNOSTICSLEVEL 18990 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION 18991 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 18992 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 18993 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 18994 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 18995 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR 18996 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_ACTIVE 18997 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 18998 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 18999 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 19000 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_RESET 19001 /* Method */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_SUBERROR 19002 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS 19003 /* Object */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR 19004 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 19005 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 19006 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 19007 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 19008 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 19009 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 19010 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 19011 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 19012 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 19013 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 19014 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 19015 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 19016 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 19017 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 19018 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 19019 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 19020 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 19021 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 19022 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 19023 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 19024 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 19025 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 19026 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 19027 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 19028 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 19029 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 19030 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 19031 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 19032 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 19033 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES 19034 /* Object */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES 19035 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_ACTIVE 19036 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_CLASSIFICATION 19037 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_DIAGNOSTICSLEVEL 19038 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_TIMEFIRSTCHANGE 19039 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER 19040 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER_DIAGNOSTICSLEVEL 19041 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_STATUSCODE 19042 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_STATUSCODE_DIAGNOSTICSLEVEL 19043 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MAJORVERSION 19044 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MAJORVERSION_DIAGNOSTICSLEVEL 19045 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MINORVERSION 19046 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_DATASETWRITERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_MINORVERSION_DIAGNOSTICSLEVEL 19047 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CARTESIANCOORDINATES_DICTIONARYFRAGMENT 19048 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_THREEDCARTESIANCOORDINATES 19049 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_THREEDCARTESIANCOORDINATES_DATATYPEVERSION 19050 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_THREEDCARTESIANCOORDINATES_DICTIONARYFRAGMENT 19051 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ORIENTATION 19052 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ORIENTATION_DATATYPEVERSION 19053 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ORIENTATION_DICTIONARYFRAGMENT 19054 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_THREEDORIENTATION 19055 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_THREEDORIENTATION_DATATYPEVERSION 19056 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_THREEDORIENTATION_DICTIONARYFRAGMENT 19057 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_FRAME 19058 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_FRAME_DATATYPEVERSION 19059 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_FRAME_DICTIONARYFRAGMENT 19060 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_THREEDFRAME 19061 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_THREEDFRAME_DATATYPEVERSION 19062 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_THREEDFRAME_DICTIONARYFRAGMENT 19063 /* Variable */ +#define UA_NS0ID_RATIONALNUMBER_ENCODING_DEFAULTJSON 19064 /* Object */ +#define UA_NS0ID_VECTOR_ENCODING_DEFAULTJSON 19065 /* Object */ +#define UA_NS0ID_THREEDVECTOR_ENCODING_DEFAULTJSON 19066 /* Object */ +#define UA_NS0ID_CARTESIANCOORDINATES_ENCODING_DEFAULTJSON 19067 /* Object */ +#define UA_NS0ID_THREEDCARTESIANCOORDINATES_ENCODING_DEFAULTJSON 19068 /* Object */ +#define UA_NS0ID_ORIENTATION_ENCODING_DEFAULTJSON 19069 /* Object */ +#define UA_NS0ID_THREEDORIENTATION_ENCODING_DEFAULTJSON 19070 /* Object */ +#define UA_NS0ID_FRAME_ENCODING_DEFAULTJSON 19071 /* Object */ +#define UA_NS0ID_THREEDFRAME_ENCODING_DEFAULTJSON 19072 /* Object */ +#define UA_NS0ID_THREEDFRAMETYPE_ORIENTATION_ANGLEUNIT 19073 /* Variable */ +#define UA_NS0ID_THREEDFRAMETYPE_ORIENTATION_A 19074 /* Variable */ +#define UA_NS0ID_THREEDFRAMETYPE_ORIENTATION_B 19075 /* Variable */ +#define UA_NS0ID_THREEDFRAMETYPE_ORIENTATION_C 19076 /* Variable */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETEBASETYPE 19077 /* VariableType */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETEBASETYPE_DEFINITION 19078 /* Variable */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETEBASETYPE_VALUEPRECISION 19079 /* Variable */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETEBASETYPE_ENUMVALUES 19080 /* Variable */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETEBASETYPE_VALUEASTEXT 19081 /* Variable */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETEBASETYPE_ENUMDICTIONARYENTRIES 19082 /* Variable */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETEBASETYPE_VALUEASDICTIONARYENTRIES 19083 /* Variable */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETETYPE 19084 /* VariableType */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETETYPE_DEFINITION 19085 /* Variable */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETETYPE_VALUEPRECISION 19086 /* Variable */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETETYPE_ENUMVALUES 19087 /* Variable */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETETYPE_VALUEASTEXT 19088 /* Variable */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETETYPE_ENUMDICTIONARYENTRIES 19089 /* Variable */ +#define UA_NS0ID_MULTISTATEDICTIONARYENTRYDISCRETETYPE_VALUEASDICTIONARYENTRIES 19090 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIES_SERVERTIMESTAMPSUPPORTED 19091 /* Variable */ +#define UA_NS0ID_HISTORICALDATACONFIGURATIONTYPE_SERVERTIMESTAMPSUPPORTED 19092 /* Variable */ +#define UA_NS0ID_HACONFIGURATION_SERVERTIMESTAMPSUPPORTED 19093 /* Variable */ +#define UA_NS0ID_HISTORYSERVERCAPABILITIESTYPE_SERVERTIMESTAMPSUPPORTED 19094 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE 19095 /* ObjectType */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_EVENTID 19096 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_EVENTTYPE 19097 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_SOURCENODE 19098 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_SOURCENAME 19099 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_TIME 19100 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_RECEIVETIME 19101 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_LOCALTIME 19102 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_MESSAGE 19103 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_SEVERITY 19104 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_ACTIONTIMESTAMP 19105 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_STATUS 19106 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS 19107 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_DIAGNOSTICSLEVEL 19108 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION 19109 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 19110 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 19111 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 19112 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 19113 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR 19114 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_ACTIVE 19115 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 19116 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 19117 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 19118 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_RESET 19119 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_SUBERROR 19120 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS 19121 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR 19122 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 19123 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 19124 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 19125 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 19126 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 19127 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 19128 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 19129 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 19130 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 19131 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 19132 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 19133 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 19134 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 19135 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 19136 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 19137 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 19138 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 19139 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 19140 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 19141 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 19142 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 19143 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 19144 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 19145 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 19146 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 19147 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 19148 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 19149 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 19150 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 19151 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES 19152 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_SENTNETWORKMESSAGES 19153 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_SENTNETWORKMESSAGES_ACTIVE 19154 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_SENTNETWORKMESSAGES_CLASSIFICATION 19155 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_SENTNETWORKMESSAGES_DIAGNOSTICSLEVEL 19156 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_SENTNETWORKMESSAGES_TIMEFIRSTCHANGE 19157 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDTRANSMISSIONS 19158 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDTRANSMISSIONS_ACTIVE 19159 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDTRANSMISSIONS_CLASSIFICATION 19160 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDTRANSMISSIONS_DIAGNOSTICSLEVEL 19161 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_FAILEDTRANSMISSIONS_TIMEFIRSTCHANGE 19162 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_ENCRYPTIONERRORS 19163 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_ENCRYPTIONERRORS_ACTIVE 19164 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_ENCRYPTIONERRORS_CLASSIFICATION 19165 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_ENCRYPTIONERRORS_DIAGNOSTICSLEVEL 19166 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_ENCRYPTIONERRORS_TIMEFIRSTCHANGE 19167 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETWRITERS 19168 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETWRITERS_DIAGNOSTICSLEVEL 19169 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETWRITERS 19170 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETWRITERS_DIAGNOSTICSLEVEL 19171 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_SECURITYTOKENID 19172 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_SECURITYTOKENID_DIAGNOSTICSLEVEL 19173 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_TIMETONEXTTOKENID 19174 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_WRITERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_TIMETONEXTTOKENID_DIAGNOSTICSLEVEL 19175 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS 19176 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_DIAGNOSTICSLEVEL 19177 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION 19178 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 19179 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 19180 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 19181 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 19182 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR 19183 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_ACTIVE 19184 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 19185 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 19186 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 19187 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_RESET 19188 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_SUBERROR 19189 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS 19190 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR 19191 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 19192 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 19193 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 19194 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 19195 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 19196 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 19197 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 19198 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 19199 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 19200 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 19201 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 19202 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 19203 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 19204 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 19205 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 19206 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 19207 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 19208 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 19209 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 19210 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 19211 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 19212 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 19213 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 19214 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 19215 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 19216 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 19217 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 19218 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 19219 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 19220 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES 19221 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_RECEIVEDNETWORKMESSAGES 19222 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_RECEIVEDNETWORKMESSAGES_ACTIVE 19223 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_RECEIVEDNETWORKMESSAGES_CLASSIFICATION 19224 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_RECEIVEDNETWORKMESSAGES_DIAGNOSTICSLEVEL 19225 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_RECEIVEDNETWORKMESSAGES_TIMEFIRSTCHANGE 19226 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES 19227 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES_ACTIVE 19228 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES_CLASSIFICATION 19229 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES_DIAGNOSTICSLEVEL 19230 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES_TIMEFIRSTCHANGE 19231 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS 19232 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_ACTIVE 19233 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_CLASSIFICATION 19234 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_DIAGNOSTICSLEVEL 19235 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_TIMEFIRSTCHANGE 19236 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETREADERS 19237 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETREADERS_DIAGNOSTICSLEVEL 19238 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETREADERS 19239 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_READERGROUPNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETREADERS_DIAGNOSTICSLEVEL 19240 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS 19241 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_DIAGNOSTICSLEVEL 19242 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_TOTALINFORMATION 19243 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 19244 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 19245 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 19246 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 19247 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_TOTALERROR 19248 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_TOTALERROR_ACTIVE 19249 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 19250 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 19251 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 19252 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_RESET 19253 /* Method */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_SUBERROR 19254 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS 19255 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEERROR 19256 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 19257 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 19258 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 19259 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 19260 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 19261 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 19262 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 19263 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 19264 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 19265 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 19266 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 19267 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 19268 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 19269 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 19270 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 19271 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 19272 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 19273 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 19274 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 19275 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 19276 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 19277 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 19278 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 19279 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 19280 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 19281 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 19282 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 19283 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 19284 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 19285 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_LIVEVALUES 19286 /* Object */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_LIVEVALUES_RESOLVEDADDRESS 19287 /* Variable */ +#define UA_NS0ID_PUBSUBCONNECTIONTYPE_DIAGNOSTICS_LIVEVALUES_RESOLVEDADDRESS_DIAGNOSTICSLEVEL 19288 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_SERVERID 19289 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_CLIENTAUDITENTRYID 19290 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_CLIENTUSERID 19291 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_PARAMETERDATATYPEID 19292 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_PERFORMINSERTREPLACE 19293 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_NEWVALUES 19294 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_OLDVALUES 19295 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_UPDATEFREQUENCY 19296 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE 19297 /* ObjectType */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_EVENTID 19298 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_EVENTTYPE 19299 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SOURCENODE 19300 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SOURCENAME 19301 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_TIME 19302 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_RECEIVETIME 19303 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LOCALTIME 19304 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_MESSAGE 19305 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SEVERITY 19306 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONDITIONCLASSID 19307 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONDITIONCLASSNAME 19308 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONDITIONSUBCLASSID 19309 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONDITIONSUBCLASSNAME 19310 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONDITIONNAME 19311 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_BRANCHID 19312 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_RETAIN 19313 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ENABLEDSTATE 19314 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ENABLEDSTATE_ID 19315 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ENABLEDSTATE_NAME 19316 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ENABLEDSTATE_NUMBER 19317 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 19318 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ENABLEDSTATE_TRANSITIONTIME 19319 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 19320 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ENABLEDSTATE_TRUESTATE 19321 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ENABLEDSTATE_FALSESTATE 19322 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_QUALITY 19323 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_QUALITY_SOURCETIMESTAMP 19324 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LASTSEVERITY 19325 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LASTSEVERITY_SOURCETIMESTAMP 19326 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_COMMENT 19327 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_COMMENT_SOURCETIMESTAMP 19328 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CLIENTUSERID 19329 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_DISABLE 19330 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ENABLE 19331 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ADDCOMMENT 19332 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ADDCOMMENT_INPUTARGUMENTS 19333 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONDITIONREFRESH 19334 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONDITIONREFRESH_INPUTARGUMENTS 19335 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONDITIONREFRESH2 19336 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONDITIONREFRESH2_INPUTARGUMENTS 19337 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACKEDSTATE 19338 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACKEDSTATE_ID 19339 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACKEDSTATE_NAME 19340 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACKEDSTATE_NUMBER 19341 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 19342 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACKEDSTATE_TRANSITIONTIME 19343 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 19344 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACKEDSTATE_TRUESTATE 19345 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACKEDSTATE_FALSESTATE 19346 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONFIRMEDSTATE 19347 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONFIRMEDSTATE_ID 19348 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONFIRMEDSTATE_NAME 19349 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONFIRMEDSTATE_NUMBER 19350 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 19351 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONFIRMEDSTATE_TRANSITIONTIME 19352 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 19353 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONFIRMEDSTATE_TRUESTATE 19354 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONFIRMEDSTATE_FALSESTATE 19355 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACKNOWLEDGE 19356 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACKNOWLEDGE_INPUTARGUMENTS 19357 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONFIRM 19358 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_CONFIRM_INPUTARGUMENTS 19359 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACTIVESTATE 19360 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACTIVESTATE_ID 19361 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACTIVESTATE_NAME 19362 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACTIVESTATE_NUMBER 19363 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 19364 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACTIVESTATE_TRANSITIONTIME 19365 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 19366 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACTIVESTATE_TRUESTATE 19367 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ACTIVESTATE_FALSESTATE 19368 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_INPUTNODE 19369 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESSEDSTATE 19370 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESSEDSTATE_ID 19371 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESSEDSTATE_NAME 19372 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESSEDSTATE_NUMBER 19373 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 19374 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESSEDSTATE_TRANSITIONTIME 19375 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 19376 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESSEDSTATE_TRUESTATE 19377 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESSEDSTATE_FALSESTATE 19378 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_OUTOFSERVICESTATE 19379 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_OUTOFSERVICESTATE_ID 19380 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_OUTOFSERVICESTATE_NAME 19381 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_OUTOFSERVICESTATE_NUMBER 19382 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 19383 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_OUTOFSERVICESTATE_TRANSITIONTIME 19384 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 19385 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_OUTOFSERVICESTATE_TRUESTATE 19386 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_OUTOFSERVICESTATE_FALSESTATE 19387 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE 19388 /* Object */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_CURRENTSTATE 19389 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_ID 19390 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NAME 19391 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_NUMBER 19392 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 19393 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_LASTTRANSITION 19394 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_ID 19395 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NAME 19396 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_NUMBER 19397 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 19398 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 19399 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_AVAILABLESTATES 19400 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_AVAILABLETRANSITIONS 19401 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_UNSHELVETIME 19402 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE 19403 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 19404 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_UNSHELVE 19405 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE 19406 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESSEDORSHELVED 19407 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_MAXTIMESHELVED 19408 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_AUDIBLEENABLED 19409 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_AUDIBLESOUND 19410 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_AUDIBLESOUND_LISTID 19411 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_AUDIBLESOUND_AGENCYID 19412 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_AUDIBLESOUND_VERSIONID 19413 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SILENCESTATE 19414 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SILENCESTATE_ID 19415 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SILENCESTATE_NAME 19416 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SILENCESTATE_NUMBER 19417 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SILENCESTATE_EFFECTIVEDISPLAYNAME 19418 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SILENCESTATE_TRANSITIONTIME 19419 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SILENCESTATE_EFFECTIVETRANSITIONTIME 19420 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SILENCESTATE_TRUESTATE 19421 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SILENCESTATE_FALSESTATE 19422 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ONDELAY 19423 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_OFFDELAY 19424 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_FIRSTINGROUPFLAG 19425 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_FIRSTINGROUP 19426 /* Object */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LATCHEDSTATE 19427 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LATCHEDSTATE_ID 19428 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LATCHEDSTATE_NAME 19429 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LATCHEDSTATE_NUMBER 19430 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 19431 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LATCHEDSTATE_TRANSITIONTIME 19432 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 19433 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LATCHEDSTATE_TRUESTATE 19434 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LATCHEDSTATE_FALSESTATE 19435 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_ALARMGROUP_PLACEHOLDER 19436 /* Object */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_REALARMTIME 19437 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_REALARMREPEATCOUNT 19438 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SILENCE 19439 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESS 19440 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_UNSUPPRESS 19441 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_REMOVEFROMSERVICE 19442 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_PLACEINSERVICE 19443 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_RESET 19444 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_NORMALSTATE 19445 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_TRUSTLISTID 19446 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_LASTUPDATETIME 19447 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_UPDATEFREQUENCY 19448 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_UPDATEFREQUENCY 19449 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED 19450 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_EVENTID 19451 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_EVENTTYPE 19452 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SOURCENODE 19453 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SOURCENAME 19454 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_TIME 19455 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_RECEIVETIME 19456 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_LOCALTIME 19457 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_MESSAGE 19458 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SEVERITY 19459 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONDITIONCLASSID 19460 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 19461 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 19462 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 19463 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONDITIONNAME 19464 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_BRANCHID 19465 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_RETAIN 19466 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ENABLEDSTATE 19467 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 19468 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 19469 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 19470 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 19471 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 19472 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 19473 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 19474 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 19475 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_QUALITY 19476 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 19477 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_LASTSEVERITY 19478 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 19479 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_COMMENT 19480 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 19481 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CLIENTUSERID 19482 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_DISABLE 19483 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ENABLE 19484 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ADDCOMMENT 19485 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 19486 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACKEDSTATE 19487 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACKEDSTATE_ID 19488 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 19489 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 19490 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 19491 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 19492 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 19493 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 19494 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 19495 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONFIRMEDSTATE 19496 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 19497 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 19498 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 19499 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 19500 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 19501 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 19502 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 19503 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 19504 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACKNOWLEDGE 19505 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 19506 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONFIRM 19507 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 19508 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACTIVESTATE 19509 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACTIVESTATE_ID 19510 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 19511 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 19512 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 19513 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 19514 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 19515 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 19516 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 19517 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_INPUTNODE 19518 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 19519 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 19520 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 19521 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 19522 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 19523 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 19524 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 19525 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 19526 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 19527 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 19528 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 19529 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 19530 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 19531 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 19532 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 19533 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 19534 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 19535 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 19536 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE 19537 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 19538 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 19539 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 19540 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 19541 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 19542 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 19543 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 19544 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 19545 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 19546 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 19547 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 19548 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 19549 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS 19550 /* Object */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_DIAGNOSTICSLEVEL 19551 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_TOTALINFORMATION 19552 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 19553 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 19554 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 19555 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 19556 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_TOTALERROR 19557 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_TOTALERROR_ACTIVE 19558 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 19559 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 19560 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 19561 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_RESET 19562 /* Method */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_SUBERROR 19563 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS 19564 /* Object */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEERROR 19565 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 19566 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 19567 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 19568 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 19569 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 19570 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 19571 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 19572 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 19573 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 19574 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 19575 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 19576 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 19577 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 19578 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 19579 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 19580 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 19581 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 19582 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 19583 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 19584 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 19585 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 19586 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 19587 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 19588 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 19589 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 19590 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 19591 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 19592 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 19593 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 19594 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_LIVEVALUES 19595 /* Object */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES 19596 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_ACTIVE 19597 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_CLASSIFICATION 19598 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_DIAGNOSTICSLEVEL 19599 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_TIMEFIRSTCHANGE 19600 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER 19601 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER_DIAGNOSTICSLEVEL 19602 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_LIVEVALUES_STATUSCODE 19603 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_LIVEVALUES_STATUSCODE_DIAGNOSTICSLEVEL 19604 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_LIVEVALUES_MAJORVERSION 19605 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_LIVEVALUES_MAJORVERSION_DIAGNOSTICSLEVEL 19606 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_LIVEVALUES_MINORVERSION 19607 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DIAGNOSTICS_LIVEVALUES_MINORVERSION_DIAGNOSTICSLEVEL 19608 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS 19609 /* Object */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_DIAGNOSTICSLEVEL 19610 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_TOTALINFORMATION 19611 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 19612 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 19613 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 19614 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 19615 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_TOTALERROR 19616 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_TOTALERROR_ACTIVE 19617 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 19618 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 19619 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 19620 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_RESET 19621 /* Method */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_SUBERROR 19622 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS 19623 /* Object */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEERROR 19624 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 19625 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 19626 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 19627 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 19628 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 19629 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 19630 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 19631 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 19632 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 19633 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 19634 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 19635 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 19636 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 19637 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 19638 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 19639 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 19640 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 19641 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 19642 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 19643 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 19644 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 19645 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 19646 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 19647 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 19648 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 19649 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 19650 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 19651 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 19652 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 19653 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES 19654 /* Object */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES 19655 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_ACTIVE 19656 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_CLASSIFICATION 19657 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_DIAGNOSTICSLEVEL 19658 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_FAILEDDATASETMESSAGES_TIMEFIRSTCHANGE 19659 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS 19660 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_ACTIVE 19661 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_CLASSIFICATION 19662 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_DIAGNOSTICSLEVEL 19663 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_TIMEFIRSTCHANGE 19664 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER 19665 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES_MESSAGESEQUENCENUMBER_DIAGNOSTICSLEVEL 19666 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES_STATUSCODE 19667 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES_STATUSCODE_DIAGNOSTICSLEVEL 19668 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES_MAJORVERSION 19669 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES_MAJORVERSION_DIAGNOSTICSLEVEL 19670 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES_MINORVERSION 19671 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES_MINORVERSION_DIAGNOSTICSLEVEL 19672 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES_SECURITYTOKENID 19673 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES_SECURITYTOKENID_DIAGNOSTICSLEVEL 19674 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES_TIMETONEXTTOKENID 19675 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DIAGNOSTICS_LIVEVALUES_TIMETONEXTTOKENID_DIAGNOSTICSLEVEL 19676 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE 19677 /* ObjectType */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_DIAGNOSTICSLEVEL 19678 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_TOTALINFORMATION 19679 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_TOTALINFORMATION_ACTIVE 19680 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_TOTALINFORMATION_CLASSIFICATION 19681 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_TOTALINFORMATION_DIAGNOSTICSLEVEL 19682 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_TOTALINFORMATION_TIMEFIRSTCHANGE 19683 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_TOTALERROR 19684 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_TOTALERROR_ACTIVE 19685 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_TOTALERROR_CLASSIFICATION 19686 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_TOTALERROR_DIAGNOSTICSLEVEL 19687 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_TOTALERROR_TIMEFIRSTCHANGE 19688 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_RESET 19689 /* Method */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_SUBERROR 19690 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS 19691 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEERROR 19692 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEERROR_ACTIVE 19693 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEERROR_CLASSIFICATION 19694 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 19695 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 19696 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALBYMETHOD 19697 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 19698 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 19699 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 19700 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 19701 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALBYPARENT 19702 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 19703 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 19704 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 19705 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 19706 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALFROMERROR 19707 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 19708 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 19709 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 19710 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 19711 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEPAUSEDBYPARENT 19712 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 19713 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 19714 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 19715 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 19716 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEDISABLEDBYMETHOD 19717 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 19718 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 19719 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 19720 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 19721 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSTYPE_LIVEVALUES 19722 /* Object */ +#define UA_NS0ID_DIAGNOSTICSLEVEL 19723 /* DataType */ +#define UA_NS0ID_DIAGNOSTICSLEVEL_ENUMSTRINGS 19724 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCOUNTERTYPE 19725 /* VariableType */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCOUNTERTYPE_ACTIVE 19726 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCOUNTERTYPE_CLASSIFICATION 19727 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCOUNTERTYPE_DIAGNOSTICSLEVEL 19728 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCOUNTERTYPE_TIMEFIRSTCHANGE 19729 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION 19730 /* DataType */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION_ENUMSTRINGS 19731 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE 19732 /* ObjectType */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_DIAGNOSTICSLEVEL 19733 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_TOTALINFORMATION 19734 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_TOTALINFORMATION_ACTIVE 19735 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_TOTALINFORMATION_CLASSIFICATION 19736 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_TOTALINFORMATION_DIAGNOSTICSLEVEL 19737 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_TOTALINFORMATION_TIMEFIRSTCHANGE 19738 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_TOTALERROR 19739 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_TOTALERROR_ACTIVE 19740 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_TOTALERROR_CLASSIFICATION 19741 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_TOTALERROR_DIAGNOSTICSLEVEL 19742 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_TOTALERROR_TIMEFIRSTCHANGE 19743 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_RESET 19744 /* Method */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_SUBERROR 19745 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS 19746 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEERROR 19747 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEERROR_ACTIVE 19748 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEERROR_CLASSIFICATION 19749 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 19750 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 19751 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALBYMETHOD 19752 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 19753 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 19754 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 19755 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 19756 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALBYPARENT 19757 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 19758 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 19759 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 19760 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 19761 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALFROMERROR 19762 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 19763 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 19764 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 19765 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 19766 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEPAUSEDBYPARENT 19767 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 19768 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 19769 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 19770 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 19771 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEDISABLEDBYMETHOD 19772 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 19773 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 19774 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 19775 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 19776 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_LIVEVALUES 19777 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_LIVEVALUES_CONFIGUREDDATASETWRITERS 19778 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_LIVEVALUES_CONFIGUREDDATASETWRITERS_DIAGNOSTICSLEVEL 19779 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_LIVEVALUES_CONFIGUREDDATASETREADERS 19780 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_LIVEVALUES_CONFIGUREDDATASETREADERS_DIAGNOSTICSLEVEL 19781 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_LIVEVALUES_OPERATIONALDATASETWRITERS 19782 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_LIVEVALUES_OPERATIONALDATASETWRITERS_DIAGNOSTICSLEVEL 19783 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_LIVEVALUES_OPERATIONALDATASETREADERS 19784 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSROOTTYPE_LIVEVALUES_OPERATIONALDATASETREADERS_DIAGNOSTICSLEVEL 19785 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE 19786 /* ObjectType */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_DIAGNOSTICSLEVEL 19787 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_TOTALINFORMATION 19788 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_TOTALINFORMATION_ACTIVE 19789 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_TOTALINFORMATION_CLASSIFICATION 19790 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_TOTALINFORMATION_DIAGNOSTICSLEVEL 19791 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_TOTALINFORMATION_TIMEFIRSTCHANGE 19792 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_TOTALERROR 19793 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_TOTALERROR_ACTIVE 19794 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_TOTALERROR_CLASSIFICATION 19795 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_TOTALERROR_DIAGNOSTICSLEVEL 19796 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_TOTALERROR_TIMEFIRSTCHANGE 19797 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_RESET 19798 /* Method */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_SUBERROR 19799 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS 19800 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEERROR 19801 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEERROR_ACTIVE 19802 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEERROR_CLASSIFICATION 19803 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 19804 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 19805 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALBYMETHOD 19806 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 19807 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 19808 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 19809 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 19810 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALBYPARENT 19811 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 19812 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 19813 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 19814 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 19815 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALFROMERROR 19816 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 19817 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 19818 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 19819 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 19820 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEPAUSEDBYPARENT 19821 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 19822 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 19823 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 19824 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 19825 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEDISABLEDBYMETHOD 19826 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 19827 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 19828 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 19829 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 19830 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_LIVEVALUES 19831 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_LIVEVALUES_RESOLVEDADDRESS 19832 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSCONNECTIONTYPE_LIVEVALUES_RESOLVEDADDRESS_DIAGNOSTICSLEVEL 19833 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE 19834 /* ObjectType */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_DIAGNOSTICSLEVEL 19835 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_TOTALINFORMATION 19836 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_TOTALINFORMATION_ACTIVE 19837 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_TOTALINFORMATION_CLASSIFICATION 19838 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_TOTALINFORMATION_DIAGNOSTICSLEVEL 19839 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_TOTALINFORMATION_TIMEFIRSTCHANGE 19840 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_TOTALERROR 19841 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_TOTALERROR_ACTIVE 19842 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_TOTALERROR_CLASSIFICATION 19843 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_TOTALERROR_DIAGNOSTICSLEVEL 19844 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_TOTALERROR_TIMEFIRSTCHANGE 19845 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_RESET 19846 /* Method */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_SUBERROR 19847 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS 19848 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEERROR 19849 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEERROR_ACTIVE 19850 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEERROR_CLASSIFICATION 19851 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 19852 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 19853 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALBYMETHOD 19854 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 19855 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 19856 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 19857 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 19858 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALBYPARENT 19859 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 19860 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 19861 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 19862 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 19863 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALFROMERROR 19864 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 19865 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 19866 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 19867 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 19868 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEPAUSEDBYPARENT 19869 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 19870 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 19871 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 19872 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 19873 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEDISABLEDBYMETHOD 19874 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 19875 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 19876 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 19877 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 19878 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_LIVEVALUES 19879 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_SENTNETWORKMESSAGES 19880 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_SENTNETWORKMESSAGES_ACTIVE 19881 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_SENTNETWORKMESSAGES_CLASSIFICATION 19882 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_SENTNETWORKMESSAGES_DIAGNOSTICSLEVEL 19883 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_SENTNETWORKMESSAGES_TIMEFIRSTCHANGE 19884 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_FAILEDTRANSMISSIONS 19885 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_FAILEDTRANSMISSIONS_ACTIVE 19886 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_FAILEDTRANSMISSIONS_CLASSIFICATION 19887 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_FAILEDTRANSMISSIONS_DIAGNOSTICSLEVEL 19888 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_FAILEDTRANSMISSIONS_TIMEFIRSTCHANGE 19889 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_ENCRYPTIONERRORS 19890 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_ENCRYPTIONERRORS_ACTIVE 19891 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_ENCRYPTIONERRORS_CLASSIFICATION 19892 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_ENCRYPTIONERRORS_DIAGNOSTICSLEVEL 19893 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_COUNTERS_ENCRYPTIONERRORS_TIMEFIRSTCHANGE 19894 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_LIVEVALUES_CONFIGUREDDATASETWRITERS 19895 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_LIVEVALUES_CONFIGUREDDATASETWRITERS_DIAGNOSTICSLEVEL 19896 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_LIVEVALUES_OPERATIONALDATASETWRITERS 19897 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_LIVEVALUES_OPERATIONALDATASETWRITERS_DIAGNOSTICSLEVEL 19898 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_LIVEVALUES_SECURITYTOKENID 19899 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_LIVEVALUES_SECURITYTOKENID_DIAGNOSTICSLEVEL 19900 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_LIVEVALUES_TIMETONEXTTOKENID 19901 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSWRITERGROUPTYPE_LIVEVALUES_TIMETONEXTTOKENID_DIAGNOSTICSLEVEL 19902 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE 19903 /* ObjectType */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_DIAGNOSTICSLEVEL 19904 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_TOTALINFORMATION 19905 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_TOTALINFORMATION_ACTIVE 19906 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_TOTALINFORMATION_CLASSIFICATION 19907 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_TOTALINFORMATION_DIAGNOSTICSLEVEL 19908 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_TOTALINFORMATION_TIMEFIRSTCHANGE 19909 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_TOTALERROR 19910 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_TOTALERROR_ACTIVE 19911 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_TOTALERROR_CLASSIFICATION 19912 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_TOTALERROR_DIAGNOSTICSLEVEL 19913 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_TOTALERROR_TIMEFIRSTCHANGE 19914 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_RESET 19915 /* Method */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_SUBERROR 19916 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS 19917 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEERROR 19918 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEERROR_ACTIVE 19919 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEERROR_CLASSIFICATION 19920 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 19921 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 19922 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALBYMETHOD 19923 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 19924 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 19925 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 19926 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 19927 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALBYPARENT 19928 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 19929 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 19930 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 19931 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 19932 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALFROMERROR 19933 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 19934 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 19935 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 19936 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 19937 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEPAUSEDBYPARENT 19938 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 19939 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 19940 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 19941 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 19942 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEDISABLEDBYMETHOD 19943 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 19944 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 19945 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 19946 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 19947 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_LIVEVALUES 19948 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_RECEIVEDNETWORKMESSAGES 19949 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_RECEIVEDNETWORKMESSAGES_ACTIVE 19950 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_RECEIVEDNETWORKMESSAGES_CLASSIFICATION 19951 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_RECEIVEDNETWORKMESSAGES_DIAGNOSTICSLEVEL 19952 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_RECEIVEDNETWORKMESSAGES_TIMEFIRSTCHANGE 19953 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES 19954 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES_ACTIVE 19955 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES_CLASSIFICATION 19956 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES_DIAGNOSTICSLEVEL 19957 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES_TIMEFIRSTCHANGE 19958 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_DECRYPTIONERRORS 19959 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_DECRYPTIONERRORS_ACTIVE 19960 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_DECRYPTIONERRORS_CLASSIFICATION 19961 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_DECRYPTIONERRORS_DIAGNOSTICSLEVEL 19962 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_COUNTERS_DECRYPTIONERRORS_TIMEFIRSTCHANGE 19963 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_LIVEVALUES_CONFIGUREDDATASETREADERS 19964 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_LIVEVALUES_CONFIGUREDDATASETREADERS_DIAGNOSTICSLEVEL 19965 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_LIVEVALUES_OPERATIONALDATASETREADERS 19966 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSREADERGROUPTYPE_LIVEVALUES_OPERATIONALDATASETREADERS_DIAGNOSTICSLEVEL 19967 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE 19968 /* ObjectType */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_DIAGNOSTICSLEVEL 19969 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_TOTALINFORMATION 19970 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_TOTALINFORMATION_ACTIVE 19971 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_TOTALINFORMATION_CLASSIFICATION 19972 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_TOTALINFORMATION_DIAGNOSTICSLEVEL 19973 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_TOTALINFORMATION_TIMEFIRSTCHANGE 19974 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_TOTALERROR 19975 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_TOTALERROR_ACTIVE 19976 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_TOTALERROR_CLASSIFICATION 19977 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_TOTALERROR_DIAGNOSTICSLEVEL 19978 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_TOTALERROR_TIMEFIRSTCHANGE 19979 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_RESET 19980 /* Method */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_SUBERROR 19981 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS 19982 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEERROR 19983 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEERROR_ACTIVE 19984 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEERROR_CLASSIFICATION 19985 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 19986 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 19987 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALBYMETHOD 19988 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 19989 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 19990 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 19991 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 19992 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALBYPARENT 19993 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 19994 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 19995 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 19996 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 19997 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALFROMERROR 19998 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 19999 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 20000 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 20001 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 20002 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEPAUSEDBYPARENT 20003 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 20004 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 20005 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 20006 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 20007 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEDISABLEDBYMETHOD 20008 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 20009 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 20010 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 20011 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 20012 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_LIVEVALUES 20013 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_FAILEDDATASETMESSAGES 20014 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_FAILEDDATASETMESSAGES_ACTIVE 20015 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_FAILEDDATASETMESSAGES_CLASSIFICATION 20016 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_FAILEDDATASETMESSAGES_DIAGNOSTICSLEVEL 20017 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_COUNTERS_FAILEDDATASETMESSAGES_TIMEFIRSTCHANGE 20018 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_LIVEVALUES_MESSAGESEQUENCENUMBER 20019 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_LIVEVALUES_MESSAGESEQUENCENUMBER_DIAGNOSTICSLEVEL 20020 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_LIVEVALUES_STATUSCODE 20021 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_LIVEVALUES_STATUSCODE_DIAGNOSTICSLEVEL 20022 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_LIVEVALUES_MAJORVERSION 20023 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_LIVEVALUES_MAJORVERSION_DIAGNOSTICSLEVEL 20024 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_LIVEVALUES_MINORVERSION 20025 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETWRITERTYPE_LIVEVALUES_MINORVERSION_DIAGNOSTICSLEVEL 20026 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE 20027 /* ObjectType */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_DIAGNOSTICSLEVEL 20028 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_TOTALINFORMATION 20029 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_TOTALINFORMATION_ACTIVE 20030 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_TOTALINFORMATION_CLASSIFICATION 20031 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_TOTALINFORMATION_DIAGNOSTICSLEVEL 20032 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_TOTALINFORMATION_TIMEFIRSTCHANGE 20033 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_TOTALERROR 20034 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_TOTALERROR_ACTIVE 20035 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_TOTALERROR_CLASSIFICATION 20036 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_TOTALERROR_DIAGNOSTICSLEVEL 20037 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_TOTALERROR_TIMEFIRSTCHANGE 20038 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_RESET 20039 /* Method */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_SUBERROR 20040 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS 20041 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEERROR 20042 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEERROR_ACTIVE 20043 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEERROR_CLASSIFICATION 20044 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 20045 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 20046 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALBYMETHOD 20047 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 20048 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 20049 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 20050 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 20051 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALBYPARENT 20052 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 20053 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 20054 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 20055 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 20056 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALFROMERROR 20057 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 20058 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 20059 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 20060 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 20061 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEPAUSEDBYPARENT 20062 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 20063 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 20064 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 20065 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 20066 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEDISABLEDBYMETHOD 20067 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 20068 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 20069 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 20070 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 20071 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES 20072 /* Object */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_FAILEDDATASETMESSAGES 20073 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_FAILEDDATASETMESSAGES_ACTIVE 20074 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_FAILEDDATASETMESSAGES_CLASSIFICATION 20075 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_FAILEDDATASETMESSAGES_DIAGNOSTICSLEVEL 20076 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_FAILEDDATASETMESSAGES_TIMEFIRSTCHANGE 20077 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_DECRYPTIONERRORS 20078 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_DECRYPTIONERRORS_ACTIVE 20079 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_DECRYPTIONERRORS_CLASSIFICATION 20080 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_DECRYPTIONERRORS_DIAGNOSTICSLEVEL 20081 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_COUNTERS_DECRYPTIONERRORS_TIMEFIRSTCHANGE 20082 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES_MESSAGESEQUENCENUMBER 20083 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES_MESSAGESEQUENCENUMBER_DIAGNOSTICSLEVEL 20084 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES_STATUSCODE 20085 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES_STATUSCODE_DIAGNOSTICSLEVEL 20086 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES_MAJORVERSION 20087 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES_MAJORVERSION_DIAGNOSTICSLEVEL 20088 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES_MINORVERSION 20089 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES_MINORVERSION_DIAGNOSTICSLEVEL 20090 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES_SECURITYTOKENID 20091 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES_SECURITYTOKENID_DIAGNOSTICSLEVEL 20092 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES_TIMETONEXTTOKENID 20093 /* Variable */ +#define UA_NS0ID_PUBSUBDIAGNOSTICSDATASETREADERTYPE_LIVEVALUES_TIMETONEXTTOKENID_DIAGNOSTICSLEVEL 20094 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 20095 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 20096 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 20097 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 20098 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 20099 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 20100 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 20101 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_MAXTIMESHELVED 20102 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_AUDIBLEENABLED 20103 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_AUDIBLESOUND 20104 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 20105 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 20106 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 20107 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SILENCESTATE 20108 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SILENCESTATE_ID 20109 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SILENCESTATE_NAME 20110 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 20111 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 20112 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 20113 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 20114 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 20115 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 20116 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_ONDELAY 20117 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_OFFDELAY 20118 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 20119 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_FIRSTINGROUP 20120 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_LATCHEDSTATE 20121 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 20122 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 20123 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 20124 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 20125 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 20126 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 20127 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 20128 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 20129 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_REALARMTIME 20130 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 20131 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SILENCE 20132 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESS 20133 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_UNSUPPRESS 20134 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 20135 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_PLACEINSERVICE 20136 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_RESET 20137 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_NORMALSTATE 20138 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_EXPIRATIONDATE 20139 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 20140 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CERTIFICATETYPE 20141 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_CERTIFICATE 20142 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE 20143 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_EVENTID 20144 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_EVENTTYPE 20145 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SOURCENODE 20146 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SOURCENAME 20147 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_TIME 20148 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_RECEIVETIME 20149 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LOCALTIME 20150 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_MESSAGE 20151 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SEVERITY 20152 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 20153 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 20154 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 20155 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 20156 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONDITIONNAME 20157 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_BRANCHID 20158 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_RETAIN 20159 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ENABLEDSTATE 20160 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 20161 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 20162 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 20163 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 20164 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 20165 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 20166 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 20167 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 20168 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_QUALITY 20169 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 20170 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LASTSEVERITY 20171 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 20172 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_COMMENT 20173 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 20174 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CLIENTUSERID 20175 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_DISABLE 20176 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ENABLE 20177 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ADDCOMMENT 20178 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 20179 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACKEDSTATE 20180 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 20181 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 20182 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 20183 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 20184 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 20185 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 20186 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 20187 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 20188 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 20189 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 20190 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 20191 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 20192 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 20193 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 20194 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 20195 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 20196 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 20197 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 20198 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 20199 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONFIRM 20200 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 20201 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACTIVESTATE 20202 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 20203 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 20204 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 20205 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 20206 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 20207 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 20208 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 20209 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 20210 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_INPUTNODE 20211 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 20212 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 20213 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 20214 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 20215 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 20216 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 20217 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 20218 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 20219 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 20220 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 20221 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 20222 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 20223 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 20224 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 20225 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 20226 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 20227 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 20228 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 20229 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE 20230 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 20231 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 20232 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 20233 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 20234 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 20235 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 20236 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 20237 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 20238 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 20239 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 20240 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 20241 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 20242 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 20243 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 20244 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 20245 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 20246 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 20247 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 20248 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 20249 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 20250 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 20251 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_AUDIBLESOUND 20252 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 20253 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 20254 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 20255 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SILENCESTATE 20256 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 20257 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 20258 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 20259 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 20260 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 20261 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 20262 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 20263 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 20264 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_ONDELAY 20265 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_OFFDELAY 20266 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 20267 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_FIRSTINGROUP 20268 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LATCHEDSTATE 20269 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 20270 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 20271 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 20272 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 20273 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 20274 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 20275 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 20276 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 20277 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_REALARMTIME 20278 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 20279 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SILENCE 20280 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESS 20281 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_UNSUPPRESS 20282 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 20283 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_PLACEINSERVICE 20284 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_RESET 20285 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_NORMALSTATE 20286 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_TRUSTLISTID 20287 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_LASTUPDATETIME 20288 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 20289 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_UPDATEFREQUENCY 20290 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED 20291 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EVENTID 20292 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EVENTTYPE 20293 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SOURCENODE 20294 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SOURCENAME 20295 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_TIME 20296 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RECEIVETIME 20297 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LOCALTIME 20298 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_MESSAGE 20299 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SEVERITY 20300 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 20301 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 20302 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 20303 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 20304 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 20305 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_BRANCHID 20306 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RETAIN 20307 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 20308 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 20309 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 20310 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 20311 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 20312 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 20313 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 20314 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 20315 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 20316 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_QUALITY 20317 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 20318 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 20319 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 20320 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_COMMENT 20321 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 20322 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 20323 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_DISABLE 20324 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLE 20325 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 20326 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 20327 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 20328 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 20329 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 20330 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 20331 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 20332 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 20333 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 20334 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 20335 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 20336 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 20337 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 20338 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 20339 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 20340 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 20341 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 20342 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 20343 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 20344 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 20345 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 20346 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 20347 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRM 20348 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 20349 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 20350 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 20351 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 20352 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 20353 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 20354 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 20355 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 20356 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 20357 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 20358 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_INPUTNODE 20359 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 20360 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 20361 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 20362 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 20363 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 20364 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 20365 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 20366 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 20367 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 20368 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 20369 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 20370 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 20371 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 20372 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 20373 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 20374 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 20375 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 20376 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 20377 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 20378 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 20379 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 20380 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 20381 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 20382 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 20383 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 20384 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 20385 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 20386 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 20387 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 20388 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 20389 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 20390 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 20391 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 20392 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 20393 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 20394 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 20395 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 20396 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 20397 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 20398 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 20399 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 20400 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 20401 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 20402 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 20403 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE 20404 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 20405 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 20406 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 20407 /* Variable */ +#define UA_NS0ID_DATASETORDERINGTYPE 20408 /* DataType */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_SECURITYTOKENID 20409 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 20410 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 20411 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 20412 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 20413 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 20414 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ONDELAY 20415 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OFFDELAY 20416 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 20417 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 20418 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 20419 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 20420 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 20421 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 20422 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 20423 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 20424 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 20425 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 20426 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 20427 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REALARMTIME 20428 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 20429 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCE 20430 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS 20431 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 20432 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 20433 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 20434 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET 20435 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_NORMALSTATE 20436 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 20437 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 20438 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 20439 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CERTIFICATE 20440 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE 20441 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_EVENTID 20442 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 20443 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 20444 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 20445 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_TIME 20446 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 20447 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 20448 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_MESSAGE 20449 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SEVERITY 20450 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 20451 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 20452 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 20453 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 20454 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 20455 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_BRANCHID 20456 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RETAIN 20457 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 20458 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 20459 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 20460 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 20461 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 20462 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 20463 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 20464 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 20465 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 20466 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_QUALITY 20467 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 20468 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 20469 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 20470 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_COMMENT 20471 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 20472 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 20473 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_DISABLE 20474 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLE 20475 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 20476 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 20477 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 20478 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 20479 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 20480 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 20481 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 20482 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 20483 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 20484 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 20485 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 20486 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 20487 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 20488 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 20489 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 20490 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 20491 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 20492 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 20493 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 20494 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 20495 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 20496 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 20497 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRM 20498 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 20499 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 20500 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 20501 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 20502 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 20503 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 20504 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 20505 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 20506 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 20507 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 20508 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 20509 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 20510 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 20511 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 20512 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 20513 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 20514 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 20515 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 20516 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 20517 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 20518 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 20519 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 20520 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 20521 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 20522 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 20523 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 20524 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 20525 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 20526 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 20527 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 20528 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 20529 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 20530 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 20531 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 20532 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 20533 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 20534 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 20535 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 20536 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 20537 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 20538 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 20539 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 20540 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 20541 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 20542 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 20543 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 20544 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 20545 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 20546 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 20547 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 20548 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 20549 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 20550 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 20551 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 20552 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 20553 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 20554 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 20555 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 20556 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 20557 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 20558 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 20559 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 20560 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 20561 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 20562 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ONDELAY 20563 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 20564 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 20565 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 20566 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 20567 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 20568 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 20569 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 20570 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 20571 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 20572 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 20573 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 20574 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 20575 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 20576 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 20577 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCE 20578 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 20579 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 20580 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 20581 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 20582 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET 20583 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 20584 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 20585 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 20586 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 20587 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_UPDATEFREQUENCY 20588 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED 20589 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EVENTID 20590 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EVENTTYPE 20591 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SOURCENODE 20592 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SOURCENAME 20593 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_TIME 20594 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RECEIVETIME 20595 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LOCALTIME 20596 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_MESSAGE 20597 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SEVERITY 20598 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 20599 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 20600 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 20601 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 20602 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 20603 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_BRANCHID 20604 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RETAIN 20605 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 20606 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 20607 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 20608 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 20609 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 20610 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 20611 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 20612 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 20613 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 20614 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_QUALITY 20615 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 20616 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 20617 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 20618 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_COMMENT 20619 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 20620 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 20621 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_DISABLE 20622 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLE 20623 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 20624 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 20625 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 20626 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 20627 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 20628 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 20629 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 20630 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 20631 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 20632 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 20633 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 20634 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 20635 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 20636 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 20637 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 20638 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 20639 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 20640 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 20641 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 20642 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 20643 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 20644 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 20645 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRM 20646 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 20647 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 20648 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 20649 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 20650 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 20651 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 20652 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 20653 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 20654 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 20655 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 20656 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_INPUTNODE 20657 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 20658 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 20659 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 20660 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 20661 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 20662 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 20663 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 20664 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 20665 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 20666 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 20667 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 20668 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 20669 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 20670 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 20671 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 20672 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 20673 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 20674 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 20675 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 20676 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 20677 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 20678 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 20679 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 20680 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 20681 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 20682 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 20683 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 20684 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 20685 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 20686 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 20687 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 20688 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 20689 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 20690 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 20691 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 20692 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 20693 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 20694 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 20695 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 20696 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 20697 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 20698 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 20699 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 20700 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 20701 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE 20702 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 20703 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 20704 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 20705 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 20706 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 20707 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 20708 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 20709 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 20710 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ONDELAY 20711 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OFFDELAY 20712 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 20713 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 20714 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 20715 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 20716 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 20717 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 20718 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 20719 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 20720 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 20721 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 20722 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 20723 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REALARMTIME 20724 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 20725 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCE 20726 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS 20727 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 20728 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 20729 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 20730 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET 20731 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_NORMALSTATE 20732 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 20733 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 20734 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 20735 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CERTIFICATE 20736 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE 20737 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_EVENTID 20738 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 20739 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 20740 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 20741 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_TIME 20742 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 20743 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 20744 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_MESSAGE 20745 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SEVERITY 20746 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 20747 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 20748 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 20749 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 20750 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 20751 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_BRANCHID 20752 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RETAIN 20753 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 20754 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 20755 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 20756 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 20757 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 20758 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 20759 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 20760 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 20761 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 20762 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_QUALITY 20763 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 20764 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 20765 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 20766 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_COMMENT 20767 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 20768 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 20769 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_DISABLE 20770 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLE 20771 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 20772 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 20773 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 20774 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 20775 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 20776 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 20777 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 20778 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 20779 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 20780 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 20781 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 20782 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 20783 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 20784 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 20785 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 20786 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 20787 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 20788 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 20789 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 20790 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 20791 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 20792 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 20793 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRM 20794 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 20795 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 20796 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 20797 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 20798 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 20799 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 20800 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 20801 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 20802 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 20803 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 20804 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 20805 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 20806 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 20807 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 20808 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 20809 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 20810 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 20811 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 20812 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 20813 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 20814 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 20815 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 20816 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 20817 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 20818 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 20819 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 20820 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 20821 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 20822 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 20823 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 20824 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 20825 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 20826 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 20827 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 20828 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 20829 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 20830 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 20831 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 20832 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 20833 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 20834 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 20835 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 20836 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 20837 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 20838 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 20839 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 20840 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 20841 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 20842 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 20843 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 20844 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 20845 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 20846 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 20847 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 20848 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 20849 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 20850 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 20851 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 20852 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 20853 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 20854 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 20855 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 20856 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 20857 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 20858 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ONDELAY 20859 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 20860 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 20861 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 20862 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 20863 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 20864 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 20865 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 20866 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 20867 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 20868 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 20869 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 20870 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 20871 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 20872 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 20873 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCE 20874 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 20875 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 20876 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 20877 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 20878 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET 20879 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 20880 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 20881 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 20882 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 20883 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_UPDATEFREQUENCY 20884 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED 20885 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EVENTID 20886 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EVENTTYPE 20887 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SOURCENODE 20888 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SOURCENAME 20889 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_TIME 20890 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RECEIVETIME 20891 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LOCALTIME 20892 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_MESSAGE 20893 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SEVERITY 20894 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 20895 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 20896 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 20897 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 20898 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 20899 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_BRANCHID 20900 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RETAIN 20901 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 20902 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 20903 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 20904 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 20905 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 20906 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 20907 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 20908 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 20909 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 20910 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_QUALITY 20911 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 20912 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 20913 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 20914 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_COMMENT 20915 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 20916 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 20917 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_DISABLE 20918 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLE 20919 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 20920 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 20921 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 20922 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 20923 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 20924 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 20925 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 20926 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 20927 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 20928 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 20929 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 20930 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 20931 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 20932 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 20933 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 20934 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 20935 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 20936 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 20937 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 20938 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 20939 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 20940 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 20941 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRM 20942 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 20943 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 20944 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 20945 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 20946 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 20947 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 20948 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 20949 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 20950 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 20951 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 20952 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_INPUTNODE 20953 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 20954 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 20955 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 20956 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 20957 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 20958 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 20959 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 20960 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 20961 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 20962 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 20963 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 20964 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 20965 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 20966 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 20967 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 20968 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 20969 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 20970 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 20971 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 20972 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 20973 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 20974 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 20975 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 20976 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 20977 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 20978 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 20979 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 20980 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 20981 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 20982 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 20983 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 20984 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 20985 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 20986 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 20987 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 20988 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 20989 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 20990 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 20991 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 20992 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 20993 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 20994 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 20995 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 20996 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 20997 /* Variable */ +#define UA_NS0ID_VERSIONTIME 20998 /* DataType */ +#define UA_NS0ID_SESSIONLESSINVOKERESPONSETYPE 20999 /* DataType */ +#define UA_NS0ID_SESSIONLESSINVOKERESPONSETYPE_ENCODING_DEFAULTXML 21000 /* Object */ +#define UA_NS0ID_SESSIONLESSINVOKERESPONSETYPE_ENCODING_DEFAULTBINARY 21001 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_FIELDTARGETDATATYPE 21002 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_SECURITYTOKENID_DIAGNOSTICSLEVEL 21003 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_TIMETONEXTTOKENID 21004 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_TIMETONEXTTOKENID_DIAGNOSTICSLEVEL 21005 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_SUBSCRIBEDDATASET 21006 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE 21007 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 21008 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_CREATETARGETVARIABLES 21009 /* Method */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_CREATETARGETVARIABLES_INPUTARGUMENTS 21010 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_CREATETARGETVARIABLES_OUTPUTARGUMENTS 21011 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_CREATEDATASETMIRROR 21012 /* Method */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_CREATEDATASETMIRROR_INPUTARGUMENTS 21013 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DATASETREADERNAME_PLACEHOLDER_CREATEDATASETMIRROR_OUTPUTARGUMENTS 21014 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS 21015 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_DIAGNOSTICSLEVEL 21016 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_TOTALINFORMATION 21017 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 21018 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 21019 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 21020 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 21021 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_TOTALERROR 21022 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_TOTALERROR_ACTIVE 21023 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 21024 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 21025 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 21026 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_RESET 21027 /* Method */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_SUBERROR 21028 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS 21029 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEERROR 21030 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 21031 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 21032 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 21033 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 21034 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 21035 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 21036 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 21037 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 21038 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 21039 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 21040 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 21041 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 21042 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 21043 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 21044 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 21045 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 21046 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 21047 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 21048 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 21049 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 21050 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 21051 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 21052 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 21053 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 21054 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 21055 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 21056 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 21057 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 21058 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 21059 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_LIVEVALUES 21060 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_RECEIVEDNETWORKMESSAGES 21061 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_RECEIVEDNETWORKMESSAGES_ACTIVE 21062 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_RECEIVEDNETWORKMESSAGES_CLASSIFICATION 21063 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_RECEIVEDNETWORKMESSAGES_DIAGNOSTICSLEVEL 21064 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_RECEIVEDNETWORKMESSAGES_TIMEFIRSTCHANGE 21065 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES 21066 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES_ACTIVE 21067 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES_CLASSIFICATION 21068 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES_DIAGNOSTICSLEVEL 21069 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_RECEIVEDINVALIDNETWORKMESSAGES_TIMEFIRSTCHANGE 21070 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS 21071 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_ACTIVE 21072 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_CLASSIFICATION 21073 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_DIAGNOSTICSLEVEL 21074 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_COUNTERS_DECRYPTIONERRORS_TIMEFIRSTCHANGE 21075 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETREADERS 21076 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETREADERS_DIAGNOSTICSLEVEL 21077 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETREADERS 21078 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETREADERS_DIAGNOSTICSLEVEL 21079 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_TRANSPORTSETTINGS 21080 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_MESSAGESETTINGS 21081 /* Object */ +#define UA_NS0ID_READERGROUPTYPE_ADDDATASETREADER 21082 /* Method */ +#define UA_NS0ID_READERGROUPTYPE_ADDDATASETREADER_INPUTARGUMENTS 21083 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_ADDDATASETREADER_OUTPUTARGUMENTS 21084 /* Variable */ +#define UA_NS0ID_READERGROUPTYPE_REMOVEDATASETREADER 21085 /* Method */ +#define UA_NS0ID_READERGROUPTYPE_REMOVEDATASETREADER_INPUTARGUMENTS 21086 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPEADDREADERMETHODTYPE 21087 /* Method */ +#define UA_NS0ID_PUBSUBGROUPTYPEADDREADERMETHODTYPE_INPUTARGUMENTS 21088 /* Variable */ +#define UA_NS0ID_PUBSUBGROUPTYPEADDREADERMETHODTYPE_OUTPUTARGUMENTS 21089 /* Variable */ +#define UA_NS0ID_READERGROUPTRANSPORTTYPE 21090 /* ObjectType */ +#define UA_NS0ID_READERGROUPMESSAGETYPE 21091 /* ObjectType */ +#define UA_NS0ID_DATASETWRITERTYPE_DATASETWRITERID 21092 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_DATASETFIELDCONTENTMASK 21093 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_KEYFRAMECOUNT 21094 /* Variable */ +#define UA_NS0ID_DATASETWRITERTYPE_MESSAGESETTINGS 21095 /* Object */ +#define UA_NS0ID_DATASETWRITERMESSAGETYPE 21096 /* ObjectType */ +#define UA_NS0ID_DATASETREADERTYPE_PUBLISHERID 21097 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_WRITERGROUPID 21098 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DATASETWRITERID 21099 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DATASETMETADATA 21100 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_DATASETFIELDCONTENTMASK 21101 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_MESSAGERECEIVETIMEOUT 21102 /* Variable */ +#define UA_NS0ID_DATASETREADERTYPE_MESSAGESETTINGS 21103 /* Object */ +#define UA_NS0ID_DATASETREADERMESSAGETYPE 21104 /* ObjectType */ +#define UA_NS0ID_UADPWRITERGROUPMESSAGETYPE 21105 /* ObjectType */ +#define UA_NS0ID_UADPWRITERGROUPMESSAGETYPE_GROUPVERSION 21106 /* Variable */ +#define UA_NS0ID_UADPWRITERGROUPMESSAGETYPE_DATASETORDERING 21107 /* Variable */ +#define UA_NS0ID_UADPWRITERGROUPMESSAGETYPE_NETWORKMESSAGECONTENTMASK 21108 /* Variable */ +#define UA_NS0ID_UADPWRITERGROUPMESSAGETYPE_SAMPLINGOFFSET 21109 /* Variable */ +#define UA_NS0ID_UADPWRITERGROUPMESSAGETYPE_PUBLISHINGOFFSET 21110 /* Variable */ +#define UA_NS0ID_UADPDATASETWRITERMESSAGETYPE 21111 /* ObjectType */ +#define UA_NS0ID_UADPDATASETWRITERMESSAGETYPE_DATASETMESSAGECONTENTMASK 21112 /* Variable */ +#define UA_NS0ID_UADPDATASETWRITERMESSAGETYPE_CONFIGUREDSIZE 21113 /* Variable */ +#define UA_NS0ID_UADPDATASETWRITERMESSAGETYPE_NETWORKMESSAGENUMBER 21114 /* Variable */ +#define UA_NS0ID_UADPDATASETWRITERMESSAGETYPE_DATASETOFFSET 21115 /* Variable */ +#define UA_NS0ID_UADPDATASETREADERMESSAGETYPE 21116 /* ObjectType */ +#define UA_NS0ID_UADPDATASETREADERMESSAGETYPE_GROUPVERSION 21117 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 21118 /* Variable */ +#define UA_NS0ID_UADPDATASETREADERMESSAGETYPE_NETWORKMESSAGENUMBER 21119 /* Variable */ +#define UA_NS0ID_UADPDATASETREADERMESSAGETYPE_DATASETCLASSID 21120 /* Variable */ +#define UA_NS0ID_UADPDATASETREADERMESSAGETYPE_NETWORKMESSAGECONTENTMASK 21121 /* Variable */ +#define UA_NS0ID_UADPDATASETREADERMESSAGETYPE_DATASETMESSAGECONTENTMASK 21122 /* Variable */ +#define UA_NS0ID_UADPDATASETREADERMESSAGETYPE_PUBLISHINGINTERVAL 21123 /* Variable */ +#define UA_NS0ID_UADPDATASETREADERMESSAGETYPE_PROCESSINGOFFSET 21124 /* Variable */ +#define UA_NS0ID_UADPDATASETREADERMESSAGETYPE_RECEIVEOFFSET 21125 /* Variable */ +#define UA_NS0ID_JSONWRITERGROUPMESSAGETYPE 21126 /* ObjectType */ +#define UA_NS0ID_JSONWRITERGROUPMESSAGETYPE_NETWORKMESSAGECONTENTMASK 21127 /* Variable */ +#define UA_NS0ID_JSONDATASETWRITERMESSAGETYPE 21128 /* ObjectType */ +#define UA_NS0ID_JSONDATASETWRITERMESSAGETYPE_DATASETMESSAGECONTENTMASK 21129 /* Variable */ +#define UA_NS0ID_JSONDATASETREADERMESSAGETYPE 21130 /* ObjectType */ +#define UA_NS0ID_JSONDATASETREADERMESSAGETYPE_NETWORKMESSAGECONTENTMASK 21131 /* Variable */ +#define UA_NS0ID_JSONDATASETREADERMESSAGETYPE_DATASETMESSAGECONTENTMASK 21132 /* Variable */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTTYPE 21133 /* ObjectType */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTTYPE_MESSAGEREPEATCOUNT 21134 /* Variable */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTTYPE_MESSAGEREPEATDELAY 21135 /* Variable */ +#define UA_NS0ID_BROKERWRITERGROUPTRANSPORTTYPE 21136 /* ObjectType */ +#define UA_NS0ID_BROKERWRITERGROUPTRANSPORTTYPE_QUEUENAME 21137 /* Variable */ +#define UA_NS0ID_BROKERDATASETWRITERTRANSPORTTYPE 21138 /* ObjectType */ +#define UA_NS0ID_BROKERDATASETWRITERTRANSPORTTYPE_QUEUENAME 21139 /* Variable */ +#define UA_NS0ID_BROKERDATASETWRITERTRANSPORTTYPE_METADATAQUEUENAME 21140 /* Variable */ +#define UA_NS0ID_BROKERDATASETWRITERTRANSPORTTYPE_METADATAUPDATETIME 21141 /* Variable */ +#define UA_NS0ID_BROKERDATASETREADERTRANSPORTTYPE 21142 /* ObjectType */ +#define UA_NS0ID_BROKERDATASETREADERTRANSPORTTYPE_QUEUENAME 21143 /* Variable */ +#define UA_NS0ID_BROKERDATASETREADERTRANSPORTTYPE_METADATAQUEUENAME 21144 /* Variable */ +#define UA_NS0ID_NETWORKADDRESSTYPE 21145 /* ObjectType */ +#define UA_NS0ID_NETWORKADDRESSTYPE_NETWORKINTERFACE 21146 /* Variable */ +#define UA_NS0ID_NETWORKADDRESSURLTYPE 21147 /* ObjectType */ +#define UA_NS0ID_NETWORKADDRESSURLTYPE_NETWORKINTERFACE 21148 /* Variable */ +#define UA_NS0ID_NETWORKADDRESSURLTYPE_URL 21149 /* Variable */ +#define UA_NS0ID_WRITERGROUPDATATYPE_ENCODING_DEFAULTBINARY 21150 /* Object */ +#define UA_NS0ID_NETWORKADDRESSDATATYPE_ENCODING_DEFAULTBINARY 21151 /* Object */ +#define UA_NS0ID_NETWORKADDRESSURLDATATYPE_ENCODING_DEFAULTBINARY 21152 /* Object */ +#define UA_NS0ID_READERGROUPDATATYPE_ENCODING_DEFAULTBINARY 21153 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATIONDATATYPE_ENCODING_DEFAULTBINARY 21154 /* Object */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTDATATYPE_ENCODING_DEFAULTBINARY 21155 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_WRITERGROUPDATATYPE 21156 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_WRITERGROUPDATATYPE_DATATYPEVERSION 21157 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_WRITERGROUPDATATYPE_DICTIONARYFRAGMENT 21158 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_NETWORKADDRESSDATATYPE 21159 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_NETWORKADDRESSDATATYPE_DATATYPEVERSION 21160 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_NETWORKADDRESSDATATYPE_DICTIONARYFRAGMENT 21161 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_NETWORKADDRESSURLDATATYPE 21162 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_NETWORKADDRESSURLDATATYPE_DATATYPEVERSION 21163 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_NETWORKADDRESSURLDATATYPE_DICTIONARYFRAGMENT 21164 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_READERGROUPDATATYPE 21165 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_READERGROUPDATATYPE_DATATYPEVERSION 21166 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_READERGROUPDATATYPE_DICTIONARYFRAGMENT 21167 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONFIGURATIONDATATYPE 21168 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONFIGURATIONDATATYPE_DATATYPEVERSION 21169 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONFIGURATIONDATATYPE_DICTIONARYFRAGMENT 21170 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMWRITERGROUPTRANSPORTDATATYPE 21171 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMWRITERGROUPTRANSPORTDATATYPE_DATATYPEVERSION 21172 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMWRITERGROUPTRANSPORTDATATYPE_DICTIONARYFRAGMENT 21173 /* Variable */ +#define UA_NS0ID_WRITERGROUPDATATYPE_ENCODING_DEFAULTXML 21174 /* Object */ +#define UA_NS0ID_NETWORKADDRESSDATATYPE_ENCODING_DEFAULTXML 21175 /* Object */ +#define UA_NS0ID_NETWORKADDRESSURLDATATYPE_ENCODING_DEFAULTXML 21176 /* Object */ +#define UA_NS0ID_READERGROUPDATATYPE_ENCODING_DEFAULTXML 21177 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATIONDATATYPE_ENCODING_DEFAULTXML 21178 /* Object */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTDATATYPE_ENCODING_DEFAULTXML 21179 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_WRITERGROUPDATATYPE 21180 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_WRITERGROUPDATATYPE_DATATYPEVERSION 21181 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_WRITERGROUPDATATYPE_DICTIONARYFRAGMENT 21182 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_NETWORKADDRESSDATATYPE 21183 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_NETWORKADDRESSDATATYPE_DATATYPEVERSION 21184 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_NETWORKADDRESSDATATYPE_DICTIONARYFRAGMENT 21185 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_NETWORKADDRESSURLDATATYPE 21186 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_NETWORKADDRESSURLDATATYPE_DATATYPEVERSION 21187 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_NETWORKADDRESSURLDATATYPE_DICTIONARYFRAGMENT 21188 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_READERGROUPDATATYPE 21189 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_READERGROUPDATATYPE_DATATYPEVERSION 21190 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_READERGROUPDATATYPE_DICTIONARYFRAGMENT 21191 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONFIGURATIONDATATYPE 21192 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONFIGURATIONDATATYPE_DATATYPEVERSION 21193 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONFIGURATIONDATATYPE_DICTIONARYFRAGMENT 21194 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMWRITERGROUPTRANSPORTDATATYPE 21195 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMWRITERGROUPTRANSPORTDATATYPE_DATATYPEVERSION 21196 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMWRITERGROUPTRANSPORTDATATYPE_DICTIONARYFRAGMENT 21197 /* Variable */ +#define UA_NS0ID_WRITERGROUPDATATYPE_ENCODING_DEFAULTJSON 21198 /* Object */ +#define UA_NS0ID_NETWORKADDRESSDATATYPE_ENCODING_DEFAULTJSON 21199 /* Object */ +#define UA_NS0ID_NETWORKADDRESSURLDATATYPE_ENCODING_DEFAULTJSON 21200 /* Object */ +#define UA_NS0ID_READERGROUPDATATYPE_ENCODING_DEFAULTJSON 21201 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATIONDATATYPE_ENCODING_DEFAULTJSON 21202 /* Object */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTDATATYPE_ENCODING_DEFAULTJSON 21203 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 21204 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 21205 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 21206 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 21207 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 21208 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 21209 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ONDELAY 21210 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OFFDELAY 21211 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 21212 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 21213 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 21214 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 21215 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 21216 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 21217 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 21218 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 21219 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 21220 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 21221 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 21222 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REALARMTIME 21223 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 21224 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCE 21225 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS 21226 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 21227 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 21228 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 21229 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET 21230 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_NORMALSTATE 21231 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 21232 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 21233 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 21234 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CERTIFICATE 21235 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE 21236 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_EVENTID 21237 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 21238 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 21239 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 21240 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_TIME 21241 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 21242 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 21243 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_MESSAGE 21244 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SEVERITY 21245 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 21246 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 21247 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 21248 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 21249 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 21250 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_BRANCHID 21251 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RETAIN 21252 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 21253 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 21254 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 21255 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 21256 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 21257 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 21258 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 21259 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 21260 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 21261 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_QUALITY 21262 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 21263 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 21264 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 21265 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_COMMENT 21266 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 21267 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 21268 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_DISABLE 21269 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLE 21270 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 21271 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 21272 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 21273 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 21274 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 21275 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 21276 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 21277 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 21278 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 21279 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 21280 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 21281 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 21282 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 21283 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 21284 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 21285 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 21286 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 21287 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 21288 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 21289 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 21290 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 21291 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 21292 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRM 21293 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 21294 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 21295 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 21296 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 21297 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 21298 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 21299 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 21300 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 21301 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 21302 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 21303 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 21304 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 21305 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 21306 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 21307 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 21308 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 21309 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 21310 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 21311 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 21312 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 21313 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 21314 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 21315 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 21316 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 21317 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 21318 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 21319 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 21320 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 21321 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 21322 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 21323 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 21324 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 21325 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 21326 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 21327 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 21328 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 21329 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 21330 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 21331 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 21332 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 21333 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 21334 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 21335 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 21336 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 21337 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 21338 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 21339 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 21340 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 21341 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 21342 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 21343 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 21344 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 21345 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 21346 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 21347 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 21348 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 21349 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 21350 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 21351 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 21352 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 21353 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 21354 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 21355 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 21356 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 21357 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ONDELAY 21358 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 21359 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 21360 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 21361 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 21362 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 21363 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 21364 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 21365 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 21366 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 21367 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 21368 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 21369 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 21370 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 21371 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 21372 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCE 21373 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 21374 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 21375 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 21376 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 21377 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET 21378 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 21379 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 21380 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 21381 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 21382 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_UPDATEFREQUENCY 21383 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED 21384 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_EVENTID 21385 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_EVENTTYPE 21386 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SOURCENODE 21387 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SOURCENAME 21388 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_TIME 21389 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_RECEIVETIME 21390 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_LOCALTIME 21391 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_MESSAGE 21392 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SEVERITY 21393 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONDITIONCLASSID 21394 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 21395 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 21396 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 21397 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONDITIONNAME 21398 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_BRANCHID 21399 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_RETAIN 21400 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ENABLEDSTATE 21401 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 21402 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 21403 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 21404 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 21405 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 21406 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 21407 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 21408 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 21409 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_QUALITY 21410 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 21411 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_LASTSEVERITY 21412 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 21413 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_COMMENT 21414 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 21415 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CLIENTUSERID 21416 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_DISABLE 21417 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ENABLE 21418 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ADDCOMMENT 21419 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 21420 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACKEDSTATE 21421 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACKEDSTATE_ID 21422 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 21423 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 21424 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 21425 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 21426 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 21427 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 21428 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 21429 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONFIRMEDSTATE 21430 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 21431 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 21432 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 21433 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 21434 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 21435 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 21436 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 21437 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 21438 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACKNOWLEDGE 21439 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 21440 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONFIRM 21441 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 21442 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACTIVESTATE 21443 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACTIVESTATE_ID 21444 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 21445 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 21446 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 21447 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 21448 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 21449 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 21450 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 21451 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_INPUTNODE 21452 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 21453 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 21454 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 21455 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 21456 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 21457 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 21458 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 21459 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 21460 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 21461 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 21462 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 21463 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 21464 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 21465 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 21466 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 21467 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 21468 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 21469 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 21470 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE 21471 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 21472 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 21473 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 21474 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 21475 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 21476 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 21477 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 21478 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 21479 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 21480 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 21481 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 21482 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 21483 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 21484 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 21485 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 21486 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 21487 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 21488 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 21489 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 21490 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_MAXTIMESHELVED 21491 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_AUDIBLEENABLED 21492 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_AUDIBLESOUND 21493 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 21494 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 21495 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 21496 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SILENCESTATE 21497 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SILENCESTATE_ID 21498 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SILENCESTATE_NAME 21499 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 21500 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 21501 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 21502 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 21503 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 21504 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 21505 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_ONDELAY 21506 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_OFFDELAY 21507 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 21508 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_FIRSTINGROUP 21509 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_LATCHEDSTATE 21510 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 21511 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 21512 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 21513 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 21514 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 21515 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 21516 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 21517 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 21518 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_REALARMTIME 21519 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 21520 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SILENCE 21521 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESS 21522 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_UNSUPPRESS 21523 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 21524 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_PLACEINSERVICE 21525 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_RESET 21526 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_NORMALSTATE 21527 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_EXPIRATIONDATE 21528 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 21529 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CERTIFICATETYPE 21530 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_CERTIFICATE 21531 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE 21532 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_EVENTID 21533 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_EVENTTYPE 21534 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SOURCENODE 21535 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SOURCENAME 21536 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_TIME 21537 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_RECEIVETIME 21538 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LOCALTIME 21539 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_MESSAGE 21540 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SEVERITY 21541 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 21542 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 21543 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 21544 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 21545 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONDITIONNAME 21546 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_BRANCHID 21547 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_RETAIN 21548 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ENABLEDSTATE 21549 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 21550 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 21551 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 21552 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 21553 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 21554 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 21555 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 21556 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 21557 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_QUALITY 21558 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 21559 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LASTSEVERITY 21560 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 21561 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_COMMENT 21562 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 21563 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CLIENTUSERID 21564 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_DISABLE 21565 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ENABLE 21566 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ADDCOMMENT 21567 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 21568 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACKEDSTATE 21569 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 21570 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 21571 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 21572 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 21573 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 21574 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 21575 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 21576 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 21577 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 21578 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 21579 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 21580 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 21581 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 21582 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 21583 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 21584 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 21585 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 21586 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 21587 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 21588 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONFIRM 21589 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 21590 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACTIVESTATE 21591 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 21592 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 21593 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 21594 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 21595 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 21596 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 21597 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 21598 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 21599 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_INPUTNODE 21600 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 21601 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 21602 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 21603 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 21604 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 21605 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 21606 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 21607 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 21608 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 21609 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 21610 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 21611 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 21612 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 21613 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 21614 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 21615 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 21616 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 21617 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 21618 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE 21619 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 21620 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 21621 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 21622 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 21623 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 21624 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 21625 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 21626 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 21627 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 21628 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 21629 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 21630 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 21631 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 21632 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 21633 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 21634 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 21635 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 21636 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 21637 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 21638 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 21639 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 21640 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_AUDIBLESOUND 21641 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 21642 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 21643 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 21644 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SILENCESTATE 21645 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 21646 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 21647 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 21648 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 21649 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 21650 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 21651 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 21652 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 21653 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_ONDELAY 21654 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_OFFDELAY 21655 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 21656 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_FIRSTINGROUP 21657 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LATCHEDSTATE 21658 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 21659 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 21660 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 21661 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 21662 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 21663 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 21664 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 21665 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 21666 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_REALARMTIME 21667 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 21668 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SILENCE 21669 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESS 21670 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_UNSUPPRESS 21671 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 21672 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_PLACEINSERVICE 21673 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_RESET 21674 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_NORMALSTATE 21675 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_TRUSTLISTID 21676 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_LASTUPDATETIME 21677 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 21678 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_UPDATEFREQUENCY 21679 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED 21680 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EVENTID 21681 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EVENTTYPE 21682 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SOURCENODE 21683 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SOURCENAME 21684 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_TIME 21685 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RECEIVETIME 21686 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LOCALTIME 21687 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_MESSAGE 21688 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SEVERITY 21689 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 21690 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 21691 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 21692 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 21693 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 21694 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_BRANCHID 21695 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RETAIN 21696 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 21697 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 21698 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 21699 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 21700 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 21701 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 21702 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 21703 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 21704 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 21705 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_QUALITY 21706 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 21707 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 21708 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 21709 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_COMMENT 21710 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 21711 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 21712 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_DISABLE 21713 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLE 21714 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 21715 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 21716 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 21717 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 21718 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 21719 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 21720 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 21721 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 21722 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 21723 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 21724 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 21725 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 21726 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 21727 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 21728 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 21729 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 21730 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 21731 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 21732 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 21733 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 21734 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 21735 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 21736 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRM 21737 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 21738 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 21739 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 21740 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 21741 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 21742 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 21743 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 21744 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 21745 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 21746 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 21747 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_INPUTNODE 21748 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 21749 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 21750 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 21751 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 21752 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 21753 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 21754 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 21755 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 21756 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 21757 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 21758 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 21759 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 21760 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 21761 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 21762 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 21763 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 21764 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 21765 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 21766 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 21767 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 21768 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 21769 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 21770 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 21771 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 21772 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 21773 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 21774 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 21775 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 21776 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 21777 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 21778 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 21779 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 21780 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 21781 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 21782 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 21783 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 21784 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 21785 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 21786 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 21787 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 21788 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 21789 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 21790 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 21791 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 21792 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE 21793 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 21794 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 21795 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 21796 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 21797 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 21798 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 21799 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 21800 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 21801 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ONDELAY 21802 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OFFDELAY 21803 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 21804 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 21805 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 21806 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 21807 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 21808 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 21809 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 21810 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 21811 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 21812 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 21813 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 21814 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REALARMTIME 21815 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 21816 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCE 21817 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS 21818 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 21819 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 21820 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 21821 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET 21822 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_NORMALSTATE 21823 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 21824 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 21825 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 21826 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CERTIFICATE 21827 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE 21828 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_EVENTID 21829 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 21830 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 21831 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 21832 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_TIME 21833 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 21834 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 21835 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_MESSAGE 21836 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SEVERITY 21837 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 21838 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 21839 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 21840 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 21841 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 21842 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_BRANCHID 21843 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RETAIN 21844 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 21845 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 21846 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 21847 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 21848 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 21849 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 21850 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 21851 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 21852 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 21853 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_QUALITY 21854 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 21855 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 21856 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 21857 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_COMMENT 21858 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 21859 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 21860 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_DISABLE 21861 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLE 21862 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 21863 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 21864 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 21865 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 21866 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 21867 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 21868 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 21869 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 21870 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 21871 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 21872 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 21873 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 21874 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 21875 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 21876 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 21877 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 21878 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 21879 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 21880 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 21881 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 21882 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 21883 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 21884 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRM 21885 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 21886 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 21887 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 21888 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 21889 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 21890 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 21891 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 21892 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 21893 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 21894 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 21895 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 21896 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 21897 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 21898 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 21899 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 21900 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 21901 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 21902 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 21903 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 21904 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 21905 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 21906 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 21907 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 21908 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 21909 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 21910 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 21911 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 21912 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 21913 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 21914 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 21915 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 21916 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 21917 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 21918 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 21919 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 21920 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 21921 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 21922 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 21923 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 21924 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 21925 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 21926 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 21927 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 21928 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 21929 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 21930 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 21931 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 21932 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 21933 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 21934 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 21935 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 21936 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 21937 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 21938 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 21939 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 21940 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 21941 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 21942 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 21943 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 21944 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 21945 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 21946 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 21947 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 21948 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 21949 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ONDELAY 21950 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 21951 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 21952 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 21953 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 21954 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 21955 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 21956 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 21957 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 21958 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 21959 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 21960 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 21961 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 21962 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 21963 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 21964 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCE 21965 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 21966 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 21967 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 21968 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 21969 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET 21970 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 21971 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 21972 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 21973 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 21974 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_UPDATEFREQUENCY 21975 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED 21976 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EVENTID 21977 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EVENTTYPE 21978 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SOURCENODE 21979 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SOURCENAME 21980 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_TIME 21981 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RECEIVETIME 21982 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LOCALTIME 21983 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_MESSAGE 21984 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SEVERITY 21985 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 21986 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 21987 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 21988 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 21989 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 21990 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_BRANCHID 21991 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RETAIN 21992 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 21993 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 21994 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 21995 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 21996 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 21997 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 21998 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 21999 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 22000 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 22001 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_QUALITY 22002 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 22003 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 22004 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 22005 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_COMMENT 22006 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 22007 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 22008 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_DISABLE 22009 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLE 22010 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 22011 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 22012 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 22013 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 22014 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 22015 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 22016 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 22017 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 22018 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 22019 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 22020 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 22021 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 22022 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 22023 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 22024 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 22025 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 22026 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 22027 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 22028 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 22029 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 22030 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 22031 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 22032 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRM 22033 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 22034 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 22035 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 22036 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 22037 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 22038 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 22039 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 22040 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 22041 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 22042 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 22043 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_INPUTNODE 22044 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 22045 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 22046 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 22047 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 22048 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 22049 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 22050 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 22051 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 22052 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 22053 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 22054 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 22055 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 22056 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 22057 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 22058 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 22059 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 22060 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 22061 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 22062 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 22063 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 22064 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 22065 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 22066 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 22067 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 22068 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 22069 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 22070 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 22071 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 22072 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 22073 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 22074 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 22075 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 22076 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 22077 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 22078 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 22079 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 22080 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 22081 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 22082 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 22083 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 22084 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 22085 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 22086 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 22087 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 22088 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE 22089 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 22090 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 22091 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 22092 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 22093 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 22094 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 22095 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 22096 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 22097 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ONDELAY 22098 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OFFDELAY 22099 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 22100 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 22101 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 22102 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 22103 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 22104 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 22105 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 22106 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 22107 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 22108 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 22109 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 22110 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REALARMTIME 22111 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 22112 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCE 22113 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS 22114 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 22115 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 22116 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 22117 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET 22118 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_NORMALSTATE 22119 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 22120 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 22121 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 22122 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CERTIFICATE 22123 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE 22124 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_EVENTID 22125 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 22126 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 22127 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 22128 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_TIME 22129 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 22130 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 22131 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_MESSAGE 22132 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SEVERITY 22133 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 22134 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 22135 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 22136 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 22137 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 22138 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_BRANCHID 22139 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RETAIN 22140 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 22141 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 22142 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 22143 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 22144 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 22145 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 22146 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 22147 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 22148 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 22149 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_QUALITY 22150 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 22151 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 22152 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 22153 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_COMMENT 22154 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 22155 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 22156 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_DISABLE 22157 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLE 22158 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 22159 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 22160 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 22161 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 22162 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 22163 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 22164 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 22165 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 22166 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 22167 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 22168 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 22169 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 22170 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 22171 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 22172 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 22173 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 22174 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 22175 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 22176 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 22177 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 22178 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 22179 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 22180 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRM 22181 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 22182 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 22183 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 22184 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 22185 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 22186 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 22187 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 22188 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 22189 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 22190 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 22191 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 22192 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 22193 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 22194 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 22195 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 22196 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 22197 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 22198 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 22199 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 22200 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 22201 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 22202 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 22203 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 22204 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 22205 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 22206 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 22207 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 22208 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 22209 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 22210 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 22211 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 22212 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 22213 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 22214 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 22215 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 22216 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 22217 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 22218 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 22219 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 22220 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 22221 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 22222 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 22223 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 22224 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 22225 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 22226 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 22227 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 22228 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 22229 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 22230 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 22231 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 22232 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 22233 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 22234 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 22235 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 22236 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 22237 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 22238 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 22239 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 22240 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 22241 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 22242 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 22243 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 22244 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 22245 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ONDELAY 22246 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 22247 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 22248 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 22249 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 22250 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 22251 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 22252 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 22253 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 22254 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 22255 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 22256 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 22257 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 22258 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 22259 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 22260 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCE 22261 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 22262 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 22263 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 22264 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 22265 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET 22266 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 22267 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 22268 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 22269 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 22270 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_UPDATEFREQUENCY 22271 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED 22272 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EVENTID 22273 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EVENTTYPE 22274 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SOURCENODE 22275 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SOURCENAME 22276 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_TIME 22277 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RECEIVETIME 22278 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LOCALTIME 22279 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_MESSAGE 22280 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SEVERITY 22281 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 22282 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 22283 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 22284 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 22285 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 22286 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_BRANCHID 22287 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RETAIN 22288 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 22289 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 22290 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 22291 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 22292 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 22293 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 22294 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 22295 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 22296 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 22297 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_QUALITY 22298 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 22299 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 22300 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 22301 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_COMMENT 22302 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 22303 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 22304 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_DISABLE 22305 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLE 22306 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 22307 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 22308 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 22309 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 22310 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 22311 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 22312 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 22313 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 22314 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 22315 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 22316 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 22317 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 22318 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 22319 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 22320 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 22321 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 22322 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 22323 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 22324 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 22325 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 22326 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 22327 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 22328 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRM 22329 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 22330 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 22331 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 22332 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 22333 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 22334 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 22335 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 22336 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 22337 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 22338 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 22339 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_INPUTNODE 22340 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 22341 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 22342 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 22343 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 22344 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 22345 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 22346 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 22347 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 22348 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 22349 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 22350 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 22351 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 22352 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 22353 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 22354 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 22355 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 22356 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 22357 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 22358 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 22359 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 22360 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 22361 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 22362 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 22363 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 22364 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 22365 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 22366 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 22367 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 22368 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 22369 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 22370 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 22371 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 22372 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 22373 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 22374 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 22375 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 22376 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 22377 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 22378 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 22379 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 22380 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 22381 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 22382 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 22383 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 22384 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE 22385 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 22386 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 22387 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 22388 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 22389 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 22390 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 22391 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 22392 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 22393 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ONDELAY 22394 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OFFDELAY 22395 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 22396 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 22397 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 22398 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 22399 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 22400 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 22401 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 22402 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 22403 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 22404 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 22405 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 22406 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REALARMTIME 22407 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 22408 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCE 22409 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS 22410 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 22411 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 22412 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 22413 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET 22414 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_NORMALSTATE 22415 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 22416 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 22417 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 22418 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CERTIFICATE 22419 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE 22420 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_EVENTID 22421 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 22422 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 22423 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 22424 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_TIME 22425 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 22426 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 22427 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_MESSAGE 22428 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SEVERITY 22429 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 22430 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 22431 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 22432 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 22433 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 22434 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_BRANCHID 22435 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RETAIN 22436 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 22437 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 22438 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 22439 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 22440 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 22441 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 22442 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 22443 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 22444 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 22445 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_QUALITY 22446 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 22447 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 22448 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 22449 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_COMMENT 22450 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 22451 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 22452 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_DISABLE 22453 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLE 22454 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 22455 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 22456 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 22457 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 22458 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 22459 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 22460 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 22461 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 22462 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 22463 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 22464 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 22465 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 22466 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 22467 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 22468 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 22469 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 22470 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 22471 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 22472 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 22473 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 22474 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 22475 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 22476 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRM 22477 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 22478 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 22479 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 22480 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 22481 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 22482 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 22483 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 22484 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 22485 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 22486 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 22487 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 22488 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 22489 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 22490 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 22491 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 22492 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 22493 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 22494 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 22495 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 22496 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 22497 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 22498 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 22499 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 22500 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 22501 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 22502 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 22503 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 22504 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 22505 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 22506 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 22507 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 22508 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 22509 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 22510 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 22511 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 22512 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 22513 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 22514 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 22515 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 22516 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 22517 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 22518 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 22519 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 22520 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 22521 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 22522 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 22523 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 22524 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 22525 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 22526 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 22527 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 22528 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 22529 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 22530 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 22531 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 22532 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 22533 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 22534 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 22535 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 22536 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 22537 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 22538 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 22539 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 22540 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 22541 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ONDELAY 22542 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 22543 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 22544 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 22545 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 22546 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 22547 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 22548 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 22549 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 22550 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 22551 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 22552 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 22553 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 22554 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 22555 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 22556 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCE 22557 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 22558 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 22559 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 22560 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 22561 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET 22562 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 22563 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 22564 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 22565 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 22566 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_UPDATEFREQUENCY 22567 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED 22568 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EVENTID 22569 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EVENTTYPE 22570 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SOURCENODE 22571 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SOURCENAME 22572 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_TIME 22573 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RECEIVETIME 22574 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LOCALTIME 22575 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_MESSAGE 22576 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SEVERITY 22577 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 22578 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 22579 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 22580 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 22581 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 22582 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_BRANCHID 22583 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RETAIN 22584 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 22585 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 22586 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 22587 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 22588 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 22589 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 22590 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 22591 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 22592 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 22593 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_QUALITY 22594 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 22595 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 22596 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 22597 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_COMMENT 22598 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 22599 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 22600 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_DISABLE 22601 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLE 22602 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 22603 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 22604 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 22605 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 22606 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 22607 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 22608 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 22609 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 22610 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 22611 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 22612 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 22613 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 22614 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 22615 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 22616 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 22617 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 22618 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 22619 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 22620 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 22621 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 22622 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 22623 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 22624 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRM 22625 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 22626 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 22627 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 22628 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 22629 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 22630 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 22631 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 22632 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 22633 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 22634 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 22635 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_INPUTNODE 22636 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 22637 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 22638 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 22639 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 22640 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 22641 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 22642 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 22643 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 22644 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 22645 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 22646 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 22647 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 22648 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 22649 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 22650 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 22651 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 22652 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 22653 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 22654 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 22655 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 22656 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 22657 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 22658 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 22659 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 22660 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 22661 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 22662 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 22663 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 22664 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 22665 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 22666 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 22667 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 22668 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 22669 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 22670 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 22671 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 22672 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 22673 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 22674 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 22675 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 22676 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 22677 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 22678 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 22679 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 22680 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE 22681 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 22682 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 22683 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 22684 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 22685 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 22686 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 22687 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 22688 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 22689 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ONDELAY 22690 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OFFDELAY 22691 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 22692 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 22693 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 22694 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 22695 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 22696 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 22697 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 22698 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 22699 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 22700 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 22701 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 22702 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REALARMTIME 22703 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 22704 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCE 22705 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS 22706 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 22707 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 22708 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 22709 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET 22710 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_NORMALSTATE 22711 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 22712 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 22713 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 22714 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CERTIFICATE 22715 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE 22716 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_EVENTID 22717 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 22718 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 22719 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 22720 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_TIME 22721 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 22722 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 22723 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_MESSAGE 22724 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SEVERITY 22725 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 22726 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 22727 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 22728 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 22729 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 22730 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_BRANCHID 22731 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RETAIN 22732 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 22733 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 22734 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 22735 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 22736 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 22737 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 22738 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 22739 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 22740 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 22741 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_QUALITY 22742 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 22743 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 22744 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 22745 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_COMMENT 22746 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 22747 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 22748 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_DISABLE 22749 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLE 22750 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 22751 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 22752 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 22753 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 22754 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 22755 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 22756 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 22757 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 22758 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 22759 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 22760 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 22761 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 22762 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 22763 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 22764 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 22765 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 22766 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 22767 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 22768 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 22769 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 22770 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 22771 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 22772 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRM 22773 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 22774 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 22775 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 22776 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 22777 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 22778 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 22779 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 22780 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 22781 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 22782 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 22783 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 22784 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 22785 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 22786 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 22787 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 22788 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 22789 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 22790 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 22791 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 22792 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 22793 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 22794 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 22795 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 22796 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 22797 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 22798 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 22799 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 22800 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 22801 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 22802 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 22803 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 22804 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 22805 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 22806 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 22807 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 22808 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 22809 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 22810 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 22811 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 22812 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 22813 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 22814 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 22815 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 22816 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 22817 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 22818 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 22819 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 22820 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 22821 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 22822 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 22823 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 22824 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 22825 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 22826 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 22827 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 22828 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 22829 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 22830 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 22831 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 22832 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 22833 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 22834 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 22835 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 22836 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 22837 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ONDELAY 22838 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 22839 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 22840 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 22841 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 22842 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 22843 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 22844 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 22845 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 22846 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 22847 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 22848 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 22849 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 22850 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 22851 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 22852 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCE 22853 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 22854 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 22855 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 22856 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 22857 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET 22858 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 22859 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 22860 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 22861 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 22862 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_UPDATEFREQUENCY 22863 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED 22864 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EVENTID 22865 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EVENTTYPE 22866 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SOURCENODE 22867 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SOURCENAME 22868 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_TIME 22869 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RECEIVETIME 22870 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LOCALTIME 22871 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_MESSAGE 22872 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SEVERITY 22873 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 22874 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 22875 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 22876 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 22877 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 22878 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_BRANCHID 22879 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RETAIN 22880 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 22881 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 22882 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 22883 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 22884 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 22885 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 22886 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 22887 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 22888 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 22889 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_QUALITY 22890 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 22891 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 22892 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 22893 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_COMMENT 22894 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 22895 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 22896 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_DISABLE 22897 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLE 22898 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 22899 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 22900 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 22901 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 22902 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 22903 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 22904 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 22905 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 22906 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 22907 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 22908 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 22909 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 22910 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 22911 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 22912 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 22913 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 22914 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 22915 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 22916 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 22917 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 22918 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 22919 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 22920 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRM 22921 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 22922 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 22923 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 22924 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 22925 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 22926 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 22927 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 22928 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 22929 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 22930 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 22931 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_INPUTNODE 22932 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 22933 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 22934 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 22935 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 22936 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 22937 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 22938 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 22939 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 22940 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 22941 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 22942 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 22943 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 22944 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 22945 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 22946 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 22947 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 22948 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 22949 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 22950 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 22951 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 22952 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 22953 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 22954 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 22955 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 22956 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 22957 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 22958 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 22959 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 22960 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 22961 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 22962 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 22963 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 22964 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 22965 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 22966 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 22967 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 22968 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 22969 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 22970 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 22971 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 22972 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 22973 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 22974 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 22975 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 22976 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE 22977 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 22978 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 22979 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 22980 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 22981 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 22982 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 22983 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 22984 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 22985 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ONDELAY 22986 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OFFDELAY 22987 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 22988 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 22989 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 22990 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 22991 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 22992 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 22993 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 22994 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 22995 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 22996 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 22997 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 22998 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REALARMTIME 22999 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 23000 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCE 23001 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS 23002 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 23003 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 23004 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 23005 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET 23006 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_NORMALSTATE 23007 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 23008 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 23009 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 23010 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CERTIFICATE 23011 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE 23012 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_EVENTID 23013 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 23014 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 23015 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 23016 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_TIME 23017 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 23018 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 23019 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_MESSAGE 23020 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SEVERITY 23021 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 23022 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 23023 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 23024 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 23025 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 23026 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_BRANCHID 23027 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RETAIN 23028 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 23029 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 23030 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 23031 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 23032 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 23033 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 23034 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 23035 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 23036 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 23037 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_QUALITY 23038 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 23039 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 23040 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 23041 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_COMMENT 23042 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 23043 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 23044 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_DISABLE 23045 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLE 23046 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 23047 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 23048 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 23049 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 23050 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 23051 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 23052 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 23053 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 23054 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 23055 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 23056 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 23057 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 23058 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 23059 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 23060 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 23061 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 23062 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 23063 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 23064 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 23065 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 23066 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 23067 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 23068 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRM 23069 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 23070 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 23071 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 23072 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 23073 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 23074 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 23075 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 23076 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 23077 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 23078 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 23079 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 23080 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 23081 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 23082 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 23083 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 23084 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 23085 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 23086 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 23087 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 23088 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 23089 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 23090 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 23091 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 23092 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 23093 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 23094 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 23095 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 23096 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 23097 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 23098 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 23099 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 23100 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 23101 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 23102 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 23103 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 23104 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 23105 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 23106 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 23107 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 23108 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 23109 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 23110 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 23111 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 23112 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 23113 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 23114 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 23115 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 23116 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 23117 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 23118 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 23119 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 23120 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 23121 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 23122 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 23123 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 23124 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 23125 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 23126 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 23127 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 23128 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 23129 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 23130 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 23131 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 23132 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 23133 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ONDELAY 23134 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 23135 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 23136 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 23137 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 23138 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 23139 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 23140 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 23141 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 23142 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 23143 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 23144 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 23145 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 23146 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 23147 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 23148 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCE 23149 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 23150 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 23151 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 23152 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 23153 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET 23154 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 23155 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 23156 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 23157 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 23158 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_UPDATEFREQUENCY 23159 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED 23160 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EVENTID 23161 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EVENTTYPE 23162 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SOURCENODE 23163 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SOURCENAME 23164 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_TIME 23165 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RECEIVETIME 23166 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LOCALTIME 23167 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_MESSAGE 23168 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SEVERITY 23169 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 23170 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 23171 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 23172 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 23173 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 23174 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_BRANCHID 23175 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RETAIN 23176 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 23177 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 23178 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 23179 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 23180 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 23181 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 23182 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 23183 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 23184 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 23185 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_QUALITY 23186 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 23187 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 23188 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 23189 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_COMMENT 23190 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 23191 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 23192 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_DISABLE 23193 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLE 23194 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 23195 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 23196 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 23197 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 23198 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 23199 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 23200 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 23201 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 23202 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 23203 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 23204 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 23205 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 23206 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 23207 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 23208 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 23209 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 23210 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 23211 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 23212 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 23213 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 23214 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 23215 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 23216 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRM 23217 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 23218 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 23219 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 23220 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 23221 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 23222 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 23223 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 23224 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 23225 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 23226 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 23227 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_INPUTNODE 23228 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 23229 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 23230 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 23231 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 23232 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 23233 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 23234 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 23235 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 23236 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 23237 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 23238 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 23239 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 23240 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 23241 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 23242 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 23243 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 23244 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 23245 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 23246 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 23247 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 23248 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 23249 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 23250 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 23251 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 23252 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 23253 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 23254 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 23255 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 23256 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 23257 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 23258 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 23259 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 23260 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 23261 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 23262 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 23263 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 23264 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 23265 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 23266 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 23267 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 23268 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 23269 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 23270 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 23271 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 23272 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE 23273 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 23274 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 23275 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 23276 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 23277 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 23278 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 23279 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 23280 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 23281 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ONDELAY 23282 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OFFDELAY 23283 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 23284 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 23285 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 23286 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 23287 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 23288 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 23289 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 23290 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 23291 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 23292 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 23293 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 23294 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REALARMTIME 23295 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 23296 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCE 23297 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS 23298 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 23299 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 23300 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 23301 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET 23302 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_NORMALSTATE 23303 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 23304 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 23305 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 23306 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CERTIFICATE 23307 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE 23308 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_EVENTID 23309 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 23310 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 23311 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 23312 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_TIME 23313 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 23314 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 23315 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_MESSAGE 23316 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SEVERITY 23317 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 23318 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 23319 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 23320 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 23321 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 23322 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_BRANCHID 23323 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RETAIN 23324 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 23325 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 23326 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 23327 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 23328 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 23329 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 23330 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 23331 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 23332 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 23333 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_QUALITY 23334 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 23335 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 23336 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 23337 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_COMMENT 23338 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 23339 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 23340 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_DISABLE 23341 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLE 23342 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 23343 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 23344 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 23345 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 23346 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 23347 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 23348 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 23349 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 23350 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 23351 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 23352 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 23353 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 23354 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 23355 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 23356 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 23357 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 23358 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 23359 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 23360 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 23361 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 23362 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 23363 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 23364 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRM 23365 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 23366 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 23367 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 23368 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 23369 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 23370 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 23371 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 23372 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 23373 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 23374 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 23375 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 23376 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 23377 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 23378 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 23379 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 23380 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 23381 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 23382 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 23383 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 23384 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 23385 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 23386 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 23387 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 23388 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 23389 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 23390 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 23391 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 23392 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 23393 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 23394 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 23395 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 23396 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 23397 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 23398 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 23399 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 23400 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 23401 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 23402 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 23403 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 23404 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 23405 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 23406 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 23407 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 23408 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 23409 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 23410 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 23411 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 23412 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 23413 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 23414 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 23415 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 23416 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 23417 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 23418 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 23419 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 23420 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 23421 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 23422 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 23423 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 23424 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 23425 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 23426 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 23427 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 23428 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 23429 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ONDELAY 23430 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 23431 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 23432 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 23433 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 23434 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 23435 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 23436 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 23437 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 23438 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 23439 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 23440 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 23441 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 23442 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 23443 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 23444 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCE 23445 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 23446 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 23447 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 23448 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 23449 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET 23450 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 23451 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 23452 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 23453 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 23454 /* Variable */ +#define UA_NS0ID_ALIASNAMETYPE 23455 /* ObjectType */ +#define UA_NS0ID_ALIASNAMECATEGORYTYPE 23456 /* ObjectType */ +#define UA_NS0ID_ALIASNAMECATEGORYTYPE_ALIAS_PLACEHOLDER 23457 /* Object */ +#define UA_NS0ID_ALIASNAMECATEGORYTYPE_SUBALIASNAMECATEGORIES_PLACEHOLDER 23458 /* Object */ +#define UA_NS0ID_ALIASNAMECATEGORYTYPE_SUBALIASNAMECATEGORIES_PLACEHOLDER_FINDALIAS 23459 /* Method */ +#define UA_NS0ID_ALIASNAMECATEGORYTYPE_SUBALIASNAMECATEGORIES_PLACEHOLDER_FINDALIAS_INPUTARGUMENTS 23460 /* Variable */ +#define UA_NS0ID_ALIASNAMECATEGORYTYPE_SUBALIASNAMECATEGORIES_PLACEHOLDER_FINDALIAS_OUTPUTARGUMENTS 23461 /* Variable */ +#define UA_NS0ID_ALIASNAMECATEGORYTYPE_FINDALIAS 23462 /* Method */ +#define UA_NS0ID_ALIASNAMECATEGORYTYPE_FINDALIAS_INPUTARGUMENTS 23463 /* Variable */ +#define UA_NS0ID_ALIASNAMECATEGORYTYPE_FINDALIAS_OUTPUTARGUMENTS 23464 /* Variable */ +#define UA_NS0ID_FINDALIASMETHODTYPE 23465 /* Method */ +#define UA_NS0ID_FINDALIASMETHODTYPE_INPUTARGUMENTS 23466 /* Variable */ +#define UA_NS0ID_FINDALIASMETHODTYPE_OUTPUTARGUMENTS 23467 /* Variable */ +#define UA_NS0ID_ALIASNAMEDATATYPE 23468 /* DataType */ +#define UA_NS0ID_ALIASFOR 23469 /* ReferenceType */ +#define UA_NS0ID_ALIASES 23470 /* Object */ +#define UA_NS0ID_ALIASES_ALIAS_PLACEHOLDER 23471 /* Object */ +#define UA_NS0ID_ALIASES_SUBALIASNAMECATEGORIES_PLACEHOLDER 23472 /* Object */ +#define UA_NS0ID_ALIASES_SUBALIASNAMECATEGORIES_PLACEHOLDER_FINDALIAS 23473 /* Method */ +#define UA_NS0ID_ALIASES_SUBALIASNAMECATEGORIES_PLACEHOLDER_FINDALIAS_INPUTARGUMENTS 23474 /* Variable */ +#define UA_NS0ID_ALIASES_SUBALIASNAMECATEGORIES_PLACEHOLDER_FINDALIAS_OUTPUTARGUMENTS 23475 /* Variable */ +#define UA_NS0ID_ALIASES_FINDALIAS 23476 /* Method */ +#define UA_NS0ID_ALIASES_FINDALIAS_INPUTARGUMENTS 23477 /* Variable */ +#define UA_NS0ID_ALIASES_FINDALIAS_OUTPUTARGUMENTS 23478 /* Variable */ +#define UA_NS0ID_TAGVARIABLES 23479 /* Object */ +#define UA_NS0ID_TAGVARIABLES_ALIAS_PLACEHOLDER 23480 /* Object */ +#define UA_NS0ID_TAGVARIABLES_SUBALIASNAMECATEGORIES_PLACEHOLDER 23481 /* Object */ +#define UA_NS0ID_TAGVARIABLES_SUBALIASNAMECATEGORIES_PLACEHOLDER_FINDALIAS 23482 /* Method */ +#define UA_NS0ID_TAGVARIABLES_SUBALIASNAMECATEGORIES_PLACEHOLDER_FINDALIAS_INPUTARGUMENTS 23483 /* Variable */ +#define UA_NS0ID_TAGVARIABLES_SUBALIASNAMECATEGORIES_PLACEHOLDER_FINDALIAS_OUTPUTARGUMENTS 23484 /* Variable */ +#define UA_NS0ID_TAGVARIABLES_FINDALIAS 23485 /* Method */ +#define UA_NS0ID_TAGVARIABLES_FINDALIAS_INPUTARGUMENTS 23486 /* Variable */ +#define UA_NS0ID_TAGVARIABLES_FINDALIAS_OUTPUTARGUMENTS 23487 /* Variable */ +#define UA_NS0ID_TOPICS 23488 /* Object */ +#define UA_NS0ID_TOPICS_ALIAS_PLACEHOLDER 23489 /* Object */ +#define UA_NS0ID_TOPICS_SUBALIASNAMECATEGORIES_PLACEHOLDER 23490 /* Object */ +#define UA_NS0ID_TOPICS_SUBALIASNAMECATEGORIES_PLACEHOLDER_FINDALIAS 23491 /* Method */ +#define UA_NS0ID_TOPICS_SUBALIASNAMECATEGORIES_PLACEHOLDER_FINDALIAS_INPUTARGUMENTS 23492 /* Variable */ +#define UA_NS0ID_TOPICS_SUBALIASNAMECATEGORIES_PLACEHOLDER_FINDALIAS_OUTPUTARGUMENTS 23493 /* Variable */ +#define UA_NS0ID_TOPICS_FINDALIAS 23494 /* Method */ +#define UA_NS0ID_TOPICS_FINDALIAS_INPUTARGUMENTS 23495 /* Variable */ +#define UA_NS0ID_TOPICS_FINDALIAS_OUTPUTARGUMENTS 23496 /* Variable */ +#define UA_NS0ID_READANNOTATIONDATADETAILS 23497 /* DataType */ +#define UA_NS0ID_CURRENCYUNITTYPE 23498 /* DataType */ +#define UA_NS0ID_ALIASNAMEDATATYPE_ENCODING_DEFAULTBINARY 23499 /* Object */ +#define UA_NS0ID_READANNOTATIONDATADETAILS_ENCODING_DEFAULTBINARY 23500 /* Object */ +#define UA_NS0ID_CURRENCYUNIT 23501 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ALIASNAMEDATATYPE 23502 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ALIASNAMEDATATYPE_DATATYPEVERSION 23503 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_ALIASNAMEDATATYPE_DICTIONARYFRAGMENT 23504 /* Variable */ +#define UA_NS0ID_ALIASNAMEDATATYPE_ENCODING_DEFAULTXML 23505 /* Object */ +#define UA_NS0ID_READANNOTATIONDATADETAILS_ENCODING_DEFAULTXML 23506 /* Object */ +#define UA_NS0ID_CURRENCYUNITTYPE_ENCODING_DEFAULTBINARY 23507 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ALIASNAMEDATATYPE 23508 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ALIASNAMEDATATYPE_DATATYPEVERSION 23509 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_ALIASNAMEDATATYPE_DICTIONARYFRAGMENT 23510 /* Variable */ +#define UA_NS0ID_ALIASNAMEDATATYPE_ENCODING_DEFAULTJSON 23511 /* Object */ +#define UA_NS0ID_READANNOTATIONDATADETAILS_ENCODING_DEFAULTJSON 23512 /* Object */ +#define UA_NS0ID_IORDEREDOBJECTTYPE 23513 /* ObjectType */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CURRENCYUNITTYPE 23514 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CURRENCYUNITTYPE_DATATYPEVERSION 23515 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_CURRENCYUNITTYPE_DICTIONARYFRAGMENT 23516 /* Variable */ +#define UA_NS0ID_IORDEREDOBJECTTYPE_NUMBERINLIST 23517 /* Variable */ +#define UA_NS0ID_ORDEREDLISTTYPE 23518 /* ObjectType */ +#define UA_NS0ID_ORDEREDLISTTYPE_ORDEREDOBJECT_PLACEHOLDER 23519 /* Object */ +#define UA_NS0ID_CURRENCYUNITTYPE_ENCODING_DEFAULTXML 23520 /* Object */ +#define UA_NS0ID_ORDEREDLISTTYPE_ORDEREDOBJECT_PLACEHOLDER_NUMBERINLIST 23521 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CURRENCYUNITTYPE 23522 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CURRENCYUNITTYPE_DATATYPEVERSION 23523 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_CURRENCYUNITTYPE_DICTIONARYFRAGMENT 23524 /* Variable */ +#define UA_NS0ID_ORDEREDLISTTYPE_NODEVERSION 23525 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_GETREJECTEDLIST 23526 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_GETREJECTEDLIST_OUTPUTARGUMENTS 23527 /* Variable */ +#define UA_NS0ID_CURRENCYUNITTYPE_ENCODING_DEFAULTJSON 23528 /* Object */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_GETREJECTEDLIST 23529 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 23530 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_GETREJECTEDLIST 23531 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 23532 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_GETREJECTEDLIST 23533 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 23534 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_GETREJECTEDLIST 23535 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_GETREJECTEDLIST_OUTPUTARGUMENTS 23536 /* Variable */ +#define UA_NS0ID_ECCAPPLICATIONCERTIFICATETYPE 23537 /* ObjectType */ +#define UA_NS0ID_ECCNISTP256APPLICATIONCERTIFICATETYPE 23538 /* ObjectType */ +#define UA_NS0ID_ECCNISTP384APPLICATIONCERTIFICATETYPE 23539 /* ObjectType */ +#define UA_NS0ID_ECCBRAINPOOLP256R1APPLICATIONCERTIFICATETYPE 23540 /* ObjectType */ +#define UA_NS0ID_ECCBRAINPOOLP384R1APPLICATIONCERTIFICATETYPE 23541 /* ObjectType */ +#define UA_NS0ID_ECCCURVE25519APPLICATIONCERTIFICATETYPE 23542 /* ObjectType */ +#define UA_NS0ID_ECCCURVE448APPLICATIONCERTIFICATETYPE 23543 /* ObjectType */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_GETREJECTEDLIST 23544 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 23545 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_GETREJECTEDLIST 23546 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 23547 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_GETREJECTEDLIST 23548 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 23549 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_GETREJECTEDLIST 23550 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 23551 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_GETREJECTEDLIST 23552 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 23553 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_GETREJECTEDLIST 23554 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 23555 /* Variable */ +#define UA_NS0ID_AUTHORIZATIONSERVICESCONFIGURATIONFOLDERTYPE 23556 /* ObjectType */ +#define UA_NS0ID_AUTHORIZATIONSERVICESCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER 23557 /* Object */ +#define UA_NS0ID_AUTHORIZATIONSERVICESCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_SERVICEURI 23558 /* Variable */ +#define UA_NS0ID_AUTHORIZATIONSERVICESCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_SERVICECERTIFICATE 23559 /* Variable */ +#define UA_NS0ID_AUTHORIZATIONSERVICESCONFIGURATIONFOLDERTYPE_SERVICENAME_PLACEHOLDER_ISSUERENDPOINTURL 23560 /* Variable */ +#define UA_NS0ID_ISDEPRECATED 23562 /* ReferenceType */ +#define UA_NS0ID_TRUSTLISTTYPE_DEFAULTVALIDATIONOPTIONS 23563 /* Variable */ +#define UA_NS0ID_TRUSTLISTVALIDATIONOPTIONS 23564 /* DataType */ +#define UA_NS0ID_TRUSTLISTVALIDATIONOPTIONS_OPTIONSETVALUES 23565 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 23566 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 23567 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 23568 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 23569 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 23570 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 23571 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 23572 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 23573 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 23574 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 23575 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 23576 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_HASSECUREELEMENT 23593 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_HASSECUREELEMENT 23597 /* Variable */ +#define UA_NS0ID_STANDALONESUBSCRIBEDDATASETREFDATATYPE 23599 /* DataType */ +#define UA_NS0ID_STANDALONESUBSCRIBEDDATASETDATATYPE 23600 /* DataType */ +#define UA_NS0ID_SECURITYGROUPDATATYPE 23601 /* DataType */ +#define UA_NS0ID_PUBSUBCONFIGURATION2DATATYPE 23602 /* DataType */ +#define UA_NS0ID_QOSDATATYPE 23603 /* DataType */ +#define UA_NS0ID_TRANSMITQOSDATATYPE 23604 /* DataType */ +#define UA_NS0ID_TRANSMITQOSPRIORITYDATATYPE 23605 /* DataType */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE 23606 /* ObjectType */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_EVENTID 23607 /* Variable */ +#define UA_NS0ID_RECEIVEQOSDATATYPE 23608 /* DataType */ +#define UA_NS0ID_RECEIVEQOSPRIORITYDATATYPE 23609 /* DataType */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_EVENTTYPE 23610 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_SOURCENODE 23611 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORT2DATATYPE 23612 /* DataType */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE 23613 /* DataType */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTDATATYPE 23614 /* DataType */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SUBSCRIBEDDATASETS 23622 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SUBSCRIBEDDATASETS_ADDDATASETFOLDER 23637 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SUBSCRIBEDDATASETS_ADDDATASETFOLDER_INPUTARGUMENTS 23638 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SUBSCRIBEDDATASETS_ADDDATASETFOLDER_OUTPUTARGUMENTS 23639 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SUBSCRIBEDDATASETS_REMOVEDATASETFOLDER 23640 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SUBSCRIBEDDATASETS_REMOVEDATASETFOLDER_INPUTARGUMENTS 23641 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCAPABLITIES 23642 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCAPABLITIES_MAXPUBSUBCONNECTIONS 23643 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCAPABLITIES_MAXWRITERGROUPS 23644 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCAPABLITIES_MAXREADERGROUPS 23645 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCAPABLITIES_MAXDATASETWRITERS 23646 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCAPABLITIES_MAXDATASETREADERS 23647 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCAPABLITIES_MAXFIELDSPERDATASET 23648 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DATASETCLASSES 23649 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SUBSCRIBEDDATASETS 23658 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SUBSCRIBEDDATASETS_ADDDATASETFOLDER 23673 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SUBSCRIBEDDATASETS_ADDDATASETFOLDER_INPUTARGUMENTS 23674 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SUBSCRIBEDDATASETS_ADDDATASETFOLDER_OUTPUTARGUMENTS 23675 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SUBSCRIBEDDATASETS_REMOVEDATASETFOLDER 23676 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SUBSCRIBEDDATASETS_REMOVEDATASETFOLDER_INPUTARGUMENTS 23677 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCAPABLITIES 23678 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCAPABLITIES_MAXPUBSUBCONNECTIONS 23679 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCAPABLITIES_MAXWRITERGROUPS 23680 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCAPABLITIES_MAXREADERGROUPS 23681 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCAPABLITIES_MAXDATASETWRITERS 23682 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCAPABLITIES_MAXDATASETREADERS 23683 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCAPABLITIES_MAXFIELDSPERDATASET 23684 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DATASETCLASSES 23685 /* Object */ +#define UA_NS0ID_GETCONNECTIONMETHODTYPE 23726 /* Method */ +#define UA_NS0ID_GETCONNECTIONMETHODTYPE_INPUTARGUMENTS 23727 /* Variable */ +#define UA_NS0ID_GETCONNECTIONMETHODTYPE_OUTPUTARGUMENTS 23728 /* Variable */ +#define UA_NS0ID_MODIFYCONNECTIONMETHODTYPE 23729 /* Method */ +#define UA_NS0ID_MODIFYCONNECTIONMETHODTYPE_INPUTARGUMENTS 23730 /* Variable */ +#define UA_NS0ID_MODIFYCONNECTIONMETHODTYPE_OUTPUTARGUMENTS 23731 /* Variable */ +#define UA_NS0ID_GETWRITERGROUPMETHODTYPE 23745 /* Method */ +#define UA_NS0ID_GETWRITERGROUPMETHODTYPE_INPUTARGUMENTS 23746 /* Variable */ +#define UA_NS0ID_GETWRITERGROUPMETHODTYPE_OUTPUTARGUMENTS 23747 /* Variable */ +#define UA_NS0ID_MODIFYWRITERGROUPMETHODTYPE 23748 /* Method */ +#define UA_NS0ID_MODIFYWRITERGROUPMETHODTYPE_INPUTARGUMENTS 23749 /* Variable */ +#define UA_NS0ID_MODIFYWRITERGROUPMETHODTYPE_OUTPUTARGUMENTS 23750 /* Variable */ +#define UA_NS0ID_URISTRING 23751 /* DataType */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXSESSIONS 23752 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXSUBSCRIPTIONS 23753 /* Variable */ +#define UA_NS0ID_GETREADERGROUPMETHODTYPE 23767 /* Method */ +#define UA_NS0ID_GETREADERGROUPMETHODTYPE_INPUTARGUMENTS 23768 /* Variable */ +#define UA_NS0ID_GETREADERGROUPMETHODTYPE_OUTPUTARGUMENTS 23769 /* Variable */ +#define UA_NS0ID_MODIFYREADERGROUPMETHODTYPE 23770 /* Method */ +#define UA_NS0ID_MODIFYREADERGROUPMETHODTYPE_INPUTARGUMENTS 23771 /* Variable */ +#define UA_NS0ID_MODIFYREADERGROUPMETHODTYPE_OUTPUTARGUMENTS 23772 /* Variable */ +#define UA_NS0ID_GETDATASETWRITERMETHODTYPE 23779 /* Method */ +#define UA_NS0ID_GETDATASETWRITERMETHODTYPE_OUTPUTARGUMENTS 23780 /* Variable */ +#define UA_NS0ID_MODIFYDATASETWRITERMETHODTYPE 23781 /* Method */ +#define UA_NS0ID_MODIFYDATASETWRITERMETHODTYPE_INPUTARGUMENTS 23782 /* Variable */ +#define UA_NS0ID_MODIFYDATASETWRITERMETHODTYPE_OUTPUTARGUMENTS 23783 /* Variable */ +#define UA_NS0ID_GETDATASETREADERMETHODTYPE 23790 /* Method */ +#define UA_NS0ID_GETDATASETREADERMETHODTYPE_OUTPUTARGUMENTS 23791 /* Variable */ +#define UA_NS0ID_MODIFYDATASETREADERMETHODTYPE 23792 /* Method */ +#define UA_NS0ID_MODIFYDATASETREADERMETHODTYPE_INPUTARGUMENTS 23793 /* Variable */ +#define UA_NS0ID_MODIFYDATASETREADERMETHODTYPE_OUTPUTARGUMENTS 23794 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE 23795 /* ObjectType */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_SUBSCRIBEDDATASETFOLDERNAME_PLACEHOLDER 23796 /* Object */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_SUBSCRIBEDDATASETFOLDERNAME_PLACEHOLDER_ADDSUBSCRIBEDDATASET 23797 /* Method */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_SUBSCRIBEDDATASETFOLDERNAME_PLACEHOLDER_ADDSUBSCRIBEDDATASET_INPUTARGUMENTS 23798 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_SUBSCRIBEDDATASETFOLDERNAME_PLACEHOLDER_ADDSUBSCRIBEDDATASET_OUTPUTARGUMENTS 23799 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_SUBSCRIBEDDATASETFOLDERNAME_PLACEHOLDER_REMOVESUBSCRIBEDDATASET 23800 /* Method */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_SUBSCRIBEDDATASETFOLDERNAME_PLACEHOLDER_REMOVESUBSCRIBEDDATASET_INPUTARGUMENTS 23801 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_SUBSCRIBEDDATASETFOLDERNAME_PLACEHOLDER_ADDDATASETFOLDER 23802 /* Method */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_SUBSCRIBEDDATASETFOLDERNAME_PLACEHOLDER_ADDDATASETFOLDER_INPUTARGUMENTS 23803 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_SUBSCRIBEDDATASETFOLDERNAME_PLACEHOLDER_ADDDATASETFOLDER_OUTPUTARGUMENTS 23804 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_SUBSCRIBEDDATASETFOLDERNAME_PLACEHOLDER_REMOVEDATASETFOLDER 23805 /* Method */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_SUBSCRIBEDDATASETFOLDERNAME_PLACEHOLDER_REMOVEDATASETFOLDER_INPUTARGUMENTS 23806 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_STANDALONESUBSCRIBEDDATASETNAME_PLACEHOLDER 23807 /* Object */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_STANDALONESUBSCRIBEDDATASETNAME_PLACEHOLDER_SUBSCRIBEDDATASET 23808 /* Object */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_STANDALONESUBSCRIBEDDATASETNAME_PLACEHOLDER_DATASETMETADATA 23809 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_STANDALONESUBSCRIBEDDATASETNAME_PLACEHOLDER_ISCONNECTED 23810 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_ADDSUBSCRIBEDDATASET 23811 /* Method */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_ADDSUBSCRIBEDDATASET_INPUTARGUMENTS 23812 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_ADDSUBSCRIBEDDATASET_OUTPUTARGUMENTS 23813 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_REMOVESUBSCRIBEDDATASET 23814 /* Method */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_REMOVESUBSCRIBEDDATASET_INPUTARGUMENTS 23815 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_ADDDATASETFOLDER 23816 /* Method */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_ADDDATASETFOLDER_INPUTARGUMENTS 23817 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_ADDDATASETFOLDER_OUTPUTARGUMENTS 23818 /* Variable */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_REMOVEDATASETFOLDER 23819 /* Method */ +#define UA_NS0ID_SUBSCRIBEDDATASETFOLDERTYPE_REMOVEDATASETFOLDER_INPUTARGUMENTS 23820 /* Variable */ +#define UA_NS0ID_ADDSUBSCRIBEDDATASETMETHODTYPE 23821 /* Method */ +#define UA_NS0ID_ADDSUBSCRIBEDDATASETMETHODTYPE_INPUTARGUMENTS 23822 /* Variable */ +#define UA_NS0ID_ADDSUBSCRIBEDDATASETMETHODTYPE_OUTPUTARGUMENTS 23823 /* Variable */ +#define UA_NS0ID_REMOVESUBSCRIBEDDATASETMETHODTYPE 23824 /* Method */ +#define UA_NS0ID_REMOVESUBSCRIBEDDATASETMETHODTYPE_INPUTARGUMENTS 23825 /* Variable */ +#define UA_NS0ID_STANDALONESUBSCRIBEDDATASETTYPE 23828 /* ObjectType */ +#define UA_NS0ID_STANDALONESUBSCRIBEDDATASETTYPE_SUBSCRIBEDDATASET 23829 /* Object */ +#define UA_NS0ID_STANDALONESUBSCRIBEDDATASETTYPE_DATASETMETADATA 23830 /* Variable */ +#define UA_NS0ID_STANDALONESUBSCRIBEDDATASETTYPE_ISCONNECTED 23831 /* Variable */ +#define UA_NS0ID_PUBSUBCAPABILITIESTYPE 23832 /* ObjectType */ +#define UA_NS0ID_PUBSUBCAPABILITIESTYPE_MAXPUBSUBCONNECTIONS 23833 /* Variable */ +#define UA_NS0ID_PUBSUBCAPABILITIESTYPE_MAXWRITERGROUPS 23834 /* Variable */ +#define UA_NS0ID_PUBSUBCAPABILITIESTYPE_MAXREADERGROUPS 23835 /* Variable */ +#define UA_NS0ID_PUBSUBCAPABILITIESTYPE_MAXDATASETWRITERS 23836 /* Variable */ +#define UA_NS0ID_PUBSUBCAPABILITIESTYPE_MAXDATASETREADERS 23837 /* Variable */ +#define UA_NS0ID_PUBSUBCAPABILITIESTYPE_MAXFIELDSPERDATASET 23838 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTTYPE_DISCOVERYANNOUNCERATE 23839 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTTYPE_DISCOVERYMAXMESSAGESIZE 23840 /* Variable */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTTYPE_ADDRESS 23842 /* Object */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTTYPE_ADDRESS_NETWORKINTERFACE 23843 /* Variable */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTTYPE_ADDRESS_NETWORKINTERFACE_SELECTIONS 23844 /* Variable */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTTYPE_ADDRESS_NETWORKINTERFACE_SELECTIONDESCRIPTIONS 23845 /* Variable */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTTYPE_ADDRESS_NETWORKINTERFACE_RESTRICTTOLIST 23846 /* Variable */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTTYPE_DATAGRAMQOS 23847 /* Variable */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTTYPE_DISCOVERYANNOUNCERATE 23848 /* Variable */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTTYPE_TOPIC 23849 /* Variable */ +#define UA_NS0ID_STANDALONESUBSCRIBEDDATASETREFDATATYPE_ENCODING_DEFAULTBINARY 23851 /* Object */ +#define UA_NS0ID_STANDALONESUBSCRIBEDDATASETDATATYPE_ENCODING_DEFAULTBINARY 23852 /* Object */ +#define UA_NS0ID_SECURITYGROUPDATATYPE_ENCODING_DEFAULTBINARY 23853 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATION2DATATYPE_ENCODING_DEFAULTBINARY 23854 /* Object */ +#define UA_NS0ID_QOSDATATYPE_ENCODING_DEFAULTBINARY 23855 /* Object */ +#define UA_NS0ID_TRANSMITQOSDATATYPE_ENCODING_DEFAULTBINARY 23856 /* Object */ +#define UA_NS0ID_TRANSMITQOSPRIORITYDATATYPE_ENCODING_DEFAULTBINARY 23857 /* Object */ +#define UA_NS0ID_RECEIVEQOSDATATYPE_ENCODING_DEFAULTBINARY 23860 /* Object */ +#define UA_NS0ID_RECEIVEQOSPRIORITYDATATYPE_ENCODING_DEFAULTBINARY 23861 /* Object */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORT2DATATYPE_ENCODING_DEFAULTBINARY 23864 /* Object */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE_ENCODING_DEFAULTBINARY 23865 /* Object */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTDATATYPE_ENCODING_DEFAULTBINARY 23866 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STANDALONESUBSCRIBEDDATASETREFDATATYPE 23870 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STANDALONESUBSCRIBEDDATASETREFDATATYPE_DATATYPEVERSION 23871 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STANDALONESUBSCRIBEDDATASETREFDATATYPE_DICTIONARYFRAGMENT 23872 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STANDALONESUBSCRIBEDDATASETDATATYPE 23873 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STANDALONESUBSCRIBEDDATASETDATATYPE_DATATYPEVERSION 23874 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_STANDALONESUBSCRIBEDDATASETDATATYPE_DICTIONARYFRAGMENT 23875 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SECURITYGROUPDATATYPE 23876 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SECURITYGROUPDATATYPE_DATATYPEVERSION 23877 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_SECURITYGROUPDATATYPE_DICTIONARYFRAGMENT 23878 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONFIGURATION2DATATYPE 23879 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONFIGURATION2DATATYPE_DATATYPEVERSION 23880 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONFIGURATION2DATATYPE_DICTIONARYFRAGMENT 23881 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_QOSDATATYPE 23882 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_QOSDATATYPE_DATATYPEVERSION 23883 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_QOSDATATYPE_DICTIONARYFRAGMENT 23884 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TRANSMITQOSDATATYPE 23885 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TRANSMITQOSDATATYPE_DATATYPEVERSION 23886 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TRANSMITQOSDATATYPE_DICTIONARYFRAGMENT 23887 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TRANSMITQOSPRIORITYDATATYPE 23888 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TRANSMITQOSPRIORITYDATATYPE_DATATYPEVERSION 23889 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TRANSMITQOSPRIORITYDATATYPE_DICTIONARYFRAGMENT 23890 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_SOURCENAME 23891 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_TIME 23892 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_RECEIVETIME 23893 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_LOCALTIME 23894 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_MESSAGE 23895 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_SEVERITY 23896 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RECEIVEQOSDATATYPE 23897 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RECEIVEQOSDATATYPE_DATATYPEVERSION 23898 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RECEIVEQOSDATATYPE_DICTIONARYFRAGMENT 23899 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RECEIVEQOSPRIORITYDATATYPE 23900 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RECEIVEQOSPRIORITYDATATYPE_DATATYPEVERSION 23901 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_RECEIVEQOSPRIORITYDATATYPE_DICTIONARYFRAGMENT 23902 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_ACTIONTIMESTAMP 23903 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_STATUS 23904 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_SERVERID 23905 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_CLIENTAUDITENTRYID 23906 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_CLIENTUSERID 23907 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_SERVERURI 23908 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMCONNECTIONTRANSPORT2DATATYPE 23909 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMCONNECTIONTRANSPORT2DATATYPE_DATATYPEVERSION 23910 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMCONNECTIONTRANSPORT2DATATYPE_DICTIONARYFRAGMENT 23911 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE 23912 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE_DATATYPEVERSION 23913 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE_DICTIONARYFRAGMENT 23914 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMDATASETREADERTRANSPORTDATATYPE 23915 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMDATASETREADERTRANSPORTDATATYPE_DATATYPEVERSION 23916 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_DATAGRAMDATASETREADERTRANSPORTDATATYPE_DICTIONARYFRAGMENT 23917 /* Variable */ +#define UA_NS0ID_STANDALONESUBSCRIBEDDATASETREFDATATYPE_ENCODING_DEFAULTXML 23919 /* Object */ +#define UA_NS0ID_STANDALONESUBSCRIBEDDATASETDATATYPE_ENCODING_DEFAULTXML 23920 /* Object */ +#define UA_NS0ID_SECURITYGROUPDATATYPE_ENCODING_DEFAULTXML 23921 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATION2DATATYPE_ENCODING_DEFAULTXML 23922 /* Object */ +#define UA_NS0ID_QOSDATATYPE_ENCODING_DEFAULTXML 23923 /* Object */ +#define UA_NS0ID_TRANSMITQOSDATATYPE_ENCODING_DEFAULTXML 23924 /* Object */ +#define UA_NS0ID_TRANSMITQOSPRIORITYDATATYPE_ENCODING_DEFAULTXML 23925 /* Object */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE 23926 /* ObjectType */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_EVENTID 23927 /* Variable */ +#define UA_NS0ID_RECEIVEQOSDATATYPE_ENCODING_DEFAULTXML 23928 /* Object */ +#define UA_NS0ID_RECEIVEQOSPRIORITYDATATYPE_ENCODING_DEFAULTXML 23929 /* Object */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_EVENTTYPE 23930 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_SOURCENODE 23931 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORT2DATATYPE_ENCODING_DEFAULTXML 23932 /* Object */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE_ENCODING_DEFAULTXML 23933 /* Object */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTDATATYPE_ENCODING_DEFAULTXML 23934 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STANDALONESUBSCRIBEDDATASETREFDATATYPE 23938 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STANDALONESUBSCRIBEDDATASETREFDATATYPE_DATATYPEVERSION 23939 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STANDALONESUBSCRIBEDDATASETREFDATATYPE_DICTIONARYFRAGMENT 23940 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STANDALONESUBSCRIBEDDATASETDATATYPE 23941 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STANDALONESUBSCRIBEDDATASETDATATYPE_DATATYPEVERSION 23942 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_STANDALONESUBSCRIBEDDATASETDATATYPE_DICTIONARYFRAGMENT 23943 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SECURITYGROUPDATATYPE 23944 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SECURITYGROUPDATATYPE_DATATYPEVERSION 23945 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_SECURITYGROUPDATATYPE_DICTIONARYFRAGMENT 23946 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONFIGURATION2DATATYPE 23947 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONFIGURATION2DATATYPE_DATATYPEVERSION 23948 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONFIGURATION2DATATYPE_DICTIONARYFRAGMENT 23949 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_QOSDATATYPE 23950 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_QOSDATATYPE_DATATYPEVERSION 23951 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_QOSDATATYPE_DICTIONARYFRAGMENT 23952 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TRANSMITQOSDATATYPE 23953 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TRANSMITQOSDATATYPE_DATATYPEVERSION 23954 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TRANSMITQOSDATATYPE_DICTIONARYFRAGMENT 23955 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TRANSMITQOSPRIORITYDATATYPE 23956 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TRANSMITQOSPRIORITYDATATYPE_DATATYPEVERSION 23957 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TRANSMITQOSPRIORITYDATATYPE_DICTIONARYFRAGMENT 23958 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_SOURCENAME 23959 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_TIME 23960 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_RECEIVETIME 23961 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_LOCALTIME 23962 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_MESSAGE 23963 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_SEVERITY 23964 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RECEIVEQOSDATATYPE 23965 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RECEIVEQOSDATATYPE_DATATYPEVERSION 23966 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RECEIVEQOSDATATYPE_DICTIONARYFRAGMENT 23967 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RECEIVEQOSPRIORITYDATATYPE 23968 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RECEIVEQOSPRIORITYDATATYPE_DATATYPEVERSION 23969 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_RECEIVEQOSPRIORITYDATATYPE_DICTIONARYFRAGMENT 23970 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_ACTIONTIMESTAMP 23971 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_STATUS 23972 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_SERVERID 23973 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_CLIENTAUDITENTRYID 23974 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_CLIENTUSERID 23975 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_SERVERURI 23976 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMCONNECTIONTRANSPORT2DATATYPE 23977 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMCONNECTIONTRANSPORT2DATATYPE_DATATYPEVERSION 23978 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMCONNECTIONTRANSPORT2DATATYPE_DICTIONARYFRAGMENT 23979 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE 23980 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE_DATATYPEVERSION 23981 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE_DICTIONARYFRAGMENT 23982 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMDATASETREADERTRANSPORTDATATYPE 23983 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMDATASETREADERTRANSPORTDATATYPE_DATATYPEVERSION 23984 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_DATAGRAMDATASETREADERTRANSPORTDATATYPE_DICTIONARYFRAGMENT 23985 /* Variable */ +#define UA_NS0ID_STANDALONESUBSCRIBEDDATASETREFDATATYPE_ENCODING_DEFAULTJSON 23987 /* Object */ +#define UA_NS0ID_STANDALONESUBSCRIBEDDATASETDATATYPE_ENCODING_DEFAULTJSON 23988 /* Object */ +#define UA_NS0ID_SECURITYGROUPDATATYPE_ENCODING_DEFAULTJSON 23989 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATION2DATATYPE_ENCODING_DEFAULTJSON 23990 /* Object */ +#define UA_NS0ID_QOSDATATYPE_ENCODING_DEFAULTJSON 23991 /* Object */ +#define UA_NS0ID_TRANSMITQOSDATATYPE_ENCODING_DEFAULTJSON 23992 /* Object */ +#define UA_NS0ID_TRANSMITQOSPRIORITYDATATYPE_ENCODING_DEFAULTJSON 23993 /* Object */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_OBJECTID 23994 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_METHODID 23995 /* Variable */ +#define UA_NS0ID_RECEIVEQOSDATATYPE_ENCODING_DEFAULTJSON 23996 /* Object */ +#define UA_NS0ID_RECEIVEQOSPRIORITYDATATYPE_ENCODING_DEFAULTJSON 23997 /* Object */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_STATUSCODEID 23998 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_INPUTARGUMENTS 23999 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORT2DATATYPE_ENCODING_DEFAULTJSON 24000 /* Object */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE_ENCODING_DEFAULTJSON 24001 /* Object */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTDATATYPE_ENCODING_DEFAULTJSON 24002 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SUBSCRIBEDDATASETS_ADDSUBSCRIBEDDATASET 24004 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SUBSCRIBEDDATASETS_ADDSUBSCRIBEDDATASET_INPUTARGUMENTS 24005 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SUBSCRIBEDDATASETS_ADDSUBSCRIBEDDATASET_OUTPUTARGUMENTS 24006 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SUBSCRIBEDDATASETS_REMOVESUBSCRIBEDDATASET 24007 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SUBSCRIBEDDATASETS_REMOVESUBSCRIBEDDATASET_INPUTARGUMENTS 24008 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DATASETCLASSES_DATASETNAME_PLACEHOLDER 24009 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SUBSCRIBEDDATASETS_ADDSUBSCRIBEDDATASET 24010 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SUBSCRIBEDDATASETS_ADDSUBSCRIBEDDATASET_INPUTARGUMENTS 24011 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SUBSCRIBEDDATASETS_ADDSUBSCRIBEDDATASET_OUTPUTARGUMENTS 24012 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SUBSCRIBEDDATASETS_REMOVESUBSCRIBEDDATASET 24013 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SUBSCRIBEDDATASETS_REMOVESUBSCRIBEDDATASET_INPUTARGUMENTS 24014 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DATASETCLASSES_DATASETNAME_PLACEHOLDER 24015 /* Variable */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTTYPE 24016 /* ObjectType */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTTYPE_ADDRESS 24017 /* Object */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTTYPE_ADDRESS_NETWORKINTERFACE 24018 /* Variable */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTTYPE_ADDRESS_NETWORKINTERFACE_SELECTIONS 24019 /* Variable */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTTYPE_ADDRESS_NETWORKINTERFACE_SELECTIONDESCRIPTIONS 24020 /* Variable */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTTYPE_ADDRESS_NETWORKINTERFACE_RESTRICTTOLIST 24021 /* Variable */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTTYPE_DATAGRAMQOS 24022 /* Variable */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTTYPE_TOPIC 24023 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2DATATYPE 24033 /* DataType */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2DATATYPE_ENCODING_DEFAULTBINARY 24034 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PROGRAMDIAGNOSTIC2DATATYPE 24035 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PROGRAMDIAGNOSTIC2DATATYPE_DATATYPEVERSION 24036 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PROGRAMDIAGNOSTIC2DATATYPE_DICTIONARYFRAGMENT 24037 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2DATATYPE_ENCODING_DEFAULTXML 24038 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PROGRAMDIAGNOSTIC2DATATYPE 24039 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PROGRAMDIAGNOSTIC2DATATYPE_DATATYPEVERSION 24040 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PROGRAMDIAGNOSTIC2DATATYPE_DICTIONARYFRAGMENT 24041 /* Variable */ +#define UA_NS0ID_PROGRAMDIAGNOSTIC2DATATYPE_ENCODING_DEFAULTJSON 24042 /* Object */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXMONITOREDITEMS 24083 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXSUBSCRIPTIONSPERSESSION 24084 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXSELECTCLAUSEPARAMETERS 24085 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXWHERECLAUSEPARAMETERS 24086 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_CONFORMANCEUNITS 24087 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXSESSIONS 24088 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXSUBSCRIPTIONS 24089 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXMONITOREDITEMS 24090 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXSUBSCRIPTIONSPERSESSION 24091 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXSELECTCLAUSEPARAMETERS 24092 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXWHERECLAUSEPARAMETERS 24093 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_CONFORMANCEUNITS 24094 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXSESSIONS 24095 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXSUBSCRIPTIONS 24096 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXMONITOREDITEMS 24097 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXSUBSCRIPTIONSPERSESSION 24098 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXSELECTCLAUSEPARAMETERS 24099 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXWHERECLAUSEPARAMETERS 24100 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_CONFORMANCEUNITS 24101 /* Variable */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXMONITOREDITEMSPERSUBSCRIPTION 24102 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXMONITOREDITEMSPERSUBSCRIPTION 24103 /* Variable */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXMONITOREDITEMSPERSUBSCRIPTION 24104 /* Variable */ +#define UA_NS0ID_PORTABLEQUALIFIEDNAME 24105 /* DataType */ +#define UA_NS0ID_PORTABLENODEID 24106 /* DataType */ +#define UA_NS0ID_UNSIGNEDRATIONALNUMBER 24107 /* DataType */ +#define UA_NS0ID_PORTABLEQUALIFIEDNAME_ENCODING_DEFAULTBINARY 24108 /* Object */ +#define UA_NS0ID_PORTABLENODEID_ENCODING_DEFAULTBINARY 24109 /* Object */ +#define UA_NS0ID_UNSIGNEDRATIONALNUMBER_ENCODING_DEFAULTBINARY 24110 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PORTABLEQUALIFIEDNAME 24111 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PORTABLEQUALIFIEDNAME_DATATYPEVERSION 24112 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PORTABLEQUALIFIEDNAME_DICTIONARYFRAGMENT 24113 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PORTABLENODEID 24114 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PORTABLENODEID_DATATYPEVERSION 24115 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PORTABLENODEID_DICTIONARYFRAGMENT 24116 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UNSIGNEDRATIONALNUMBER 24117 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UNSIGNEDRATIONALNUMBER_DATATYPEVERSION 24118 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_UNSIGNEDRATIONALNUMBER_DICTIONARYFRAGMENT 24119 /* Variable */ +#define UA_NS0ID_PORTABLEQUALIFIEDNAME_ENCODING_DEFAULTXML 24120 /* Object */ +#define UA_NS0ID_PORTABLENODEID_ENCODING_DEFAULTXML 24121 /* Object */ +#define UA_NS0ID_UNSIGNEDRATIONALNUMBER_ENCODING_DEFAULTXML 24122 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PORTABLEQUALIFIEDNAME 24123 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PORTABLEQUALIFIEDNAME_DATATYPEVERSION 24124 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PORTABLEQUALIFIEDNAME_DICTIONARYFRAGMENT 24125 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PORTABLENODEID 24126 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PORTABLENODEID_DATATYPEVERSION 24127 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PORTABLENODEID_DICTIONARYFRAGMENT 24128 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UNSIGNEDRATIONALNUMBER 24129 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UNSIGNEDRATIONALNUMBER_DATATYPEVERSION 24130 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_UNSIGNEDRATIONALNUMBER_DICTIONARYFRAGMENT 24131 /* Variable */ +#define UA_NS0ID_PORTABLEQUALIFIEDNAME_ENCODING_DEFAULTJSON 24132 /* Object */ +#define UA_NS0ID_PORTABLENODEID_ENCODING_DEFAULTJSON 24133 /* Object */ +#define UA_NS0ID_UNSIGNEDRATIONALNUMBER_ENCODING_DEFAULTJSON 24134 /* Object */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_CERTIFICATEERROREVENTID 24135 /* Variable */ +#define UA_NS0ID_HASSTRUCTUREDCOMPONENT 24136 /* ReferenceType */ +#define UA_NS0ID_ASSOCIATEDWITH 24137 /* ReferenceType */ +#define UA_NS0ID_ROLESETTYPE_ROLENAME_PLACEHOLDER_CUSTOMCONFIGURATION 24138 /* Variable */ +#define UA_NS0ID_ROLETYPE_CUSTOMCONFIGURATION 24139 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ANONYMOUS_CUSTOMCONFIGURATION 24140 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_AUTHENTICATEDUSER_CUSTOMCONFIGURATION 24141 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OBSERVER_CUSTOMCONFIGURATION 24142 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_OPERATOR_CUSTOMCONFIGURATION 24143 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_ENGINEER_CUSTOMCONFIGURATION 24144 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SUPERVISOR_CUSTOMCONFIGURATION 24145 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_CONFIGUREADMIN_CUSTOMCONFIGURATION 24146 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYADMIN_CUSTOMCONFIGURATION 24147 /* Variable */ +#define UA_NS0ID_IIETFBASENETWORKINTERFACETYPE 24148 /* ObjectType */ +#define UA_NS0ID_IIETFBASENETWORKINTERFACETYPE_ADMINSTATUS 24149 /* Variable */ +#define UA_NS0ID_IIETFBASENETWORKINTERFACETYPE_OPERSTATUS 24150 /* Variable */ +#define UA_NS0ID_IIETFBASENETWORKINTERFACETYPE_PHYSADDRESS 24151 /* Variable */ +#define UA_NS0ID_IIETFBASENETWORKINTERFACETYPE_SPEED 24152 /* Variable */ +#define UA_NS0ID_IIETFBASENETWORKINTERFACETYPE_SPEED_DEFINITION 24153 /* Variable */ +#define UA_NS0ID_IIETFBASENETWORKINTERFACETYPE_SPEED_VALUEPRECISION 24154 /* Variable */ +#define UA_NS0ID_IIETFBASENETWORKINTERFACETYPE_SPEED_INSTRUMENTRANGE 24155 /* Variable */ +#define UA_NS0ID_IIETFBASENETWORKINTERFACETYPE_SPEED_EURANGE 24156 /* Variable */ +#define UA_NS0ID_IIETFBASENETWORKINTERFACETYPE_SPEED_ENGINEERINGUNITS 24157 /* Variable */ +#define UA_NS0ID_IIEEEBASEETHERNETPORTTYPE 24158 /* ObjectType */ +#define UA_NS0ID_IIEEEBASEETHERNETPORTTYPE_SPEED 24159 /* Variable */ +#define UA_NS0ID_IIEEEBASEETHERNETPORTTYPE_SPEED_DEFINITION 24160 /* Variable */ +#define UA_NS0ID_IIEEEBASEETHERNETPORTTYPE_SPEED_VALUEPRECISION 24161 /* Variable */ +#define UA_NS0ID_IIEEEBASEETHERNETPORTTYPE_SPEED_INSTRUMENTRANGE 24162 /* Variable */ +#define UA_NS0ID_IIEEEBASEETHERNETPORTTYPE_SPEED_EURANGE 24163 /* Variable */ +#define UA_NS0ID_IIEEEBASEETHERNETPORTTYPE_SPEED_ENGINEERINGUNITS 24164 /* Variable */ +#define UA_NS0ID_IIEEEBASEETHERNETPORTTYPE_DUPLEX 24165 /* Variable */ +#define UA_NS0ID_IIEEEBASEETHERNETPORTTYPE_MAXFRAMELENGTH 24166 /* Variable */ +#define UA_NS0ID_IBASEETHERNETCAPABILITIESTYPE 24167 /* ObjectType */ +#define UA_NS0ID_IBASEETHERNETCAPABILITIESTYPE_VLANTAGCAPABLE 24168 /* Variable */ +#define UA_NS0ID_ISRCLASSTYPE 24169 /* ObjectType */ +#define UA_NS0ID_ISRCLASSTYPE_ID 24170 /* Variable */ +#define UA_NS0ID_ISRCLASSTYPE_PRIORITY 24171 /* Variable */ +#define UA_NS0ID_ISRCLASSTYPE_VID 24172 /* Variable */ +#define UA_NS0ID_IIEEEBASETSNSTREAMTYPE 24173 /* ObjectType */ +#define UA_NS0ID_IIEEEBASETSNSTREAMTYPE_STREAMID 24174 /* Variable */ +#define UA_NS0ID_IIEEEBASETSNSTREAMTYPE_STREAMNAME 24175 /* Variable */ +#define UA_NS0ID_IIEEEBASETSNSTREAMTYPE_STATE 24176 /* Variable */ +#define UA_NS0ID_IIEEEBASETSNSTREAMTYPE_ACCUMULATEDLATENCY 24177 /* Variable */ +#define UA_NS0ID_IIEEEBASETSNSTREAMTYPE_SRCLASSID 24178 /* Variable */ +#define UA_NS0ID_IIEEEBASETSNTRAFFICSPECIFICATIONTYPE 24179 /* ObjectType */ +#define UA_NS0ID_IIEEEBASETSNTRAFFICSPECIFICATIONTYPE_MAXINTERVALFRAMES 24180 /* Variable */ +#define UA_NS0ID_IIEEEBASETSNTRAFFICSPECIFICATIONTYPE_MAXFRAMESIZE 24181 /* Variable */ +#define UA_NS0ID_IIEEEBASETSNTRAFFICSPECIFICATIONTYPE_INTERVAL 24182 /* Variable */ +#define UA_NS0ID_IIEEEBASETSNSTATUSSTREAMTYPE 24183 /* ObjectType */ +#define UA_NS0ID_IIEEEBASETSNSTATUSSTREAMTYPE_TALKERSTATUS 24184 /* Variable */ +#define UA_NS0ID_IIEEEBASETSNSTATUSSTREAMTYPE_LISTENERSTATUS 24185 /* Variable */ +#define UA_NS0ID_IIEEEBASETSNSTATUSSTREAMTYPE_FAILURECODE 24186 /* Variable */ +#define UA_NS0ID_IIEEEBASETSNSTATUSSTREAMTYPE_FAILURESYSTEMIDENTIFIER 24187 /* Variable */ +#define UA_NS0ID_IIEEETSNINTERFACECONFIGURATIONTYPE 24188 /* ObjectType */ +#define UA_NS0ID_IIEEETSNINTERFACECONFIGURATIONTYPE_MACADDRESS 24189 /* Variable */ +#define UA_NS0ID_IIEEETSNINTERFACECONFIGURATIONTYPE_INTERFACENAME 24190 /* Variable */ +#define UA_NS0ID_IIEEETSNINTERFACECONFIGURATIONTALKERTYPE 24191 /* ObjectType */ +#define UA_NS0ID_IIEEETSNINTERFACECONFIGURATIONTALKERTYPE_MACADDRESS 24192 /* Variable */ +#define UA_NS0ID_IIEEETSNINTERFACECONFIGURATIONTALKERTYPE_INTERFACENAME 24193 /* Variable */ +#define UA_NS0ID_IIEEETSNINTERFACECONFIGURATIONTALKERTYPE_TIMEAWAREOFFSET 24194 /* Variable */ +#define UA_NS0ID_IIEEETSNINTERFACECONFIGURATIONLISTENERTYPE 24195 /* ObjectType */ +#define UA_NS0ID_IIEEETSNINTERFACECONFIGURATIONLISTENERTYPE_MACADDRESS 24196 /* Variable */ +#define UA_NS0ID_IIEEETSNINTERFACECONFIGURATIONLISTENERTYPE_INTERFACENAME 24197 /* Variable */ +#define UA_NS0ID_IIEEETSNINTERFACECONFIGURATIONLISTENERTYPE_RECEIVEOFFSET 24198 /* Variable */ +#define UA_NS0ID_IIEEETSNMACADDRESSTYPE 24199 /* ObjectType */ +#define UA_NS0ID_IIEEETSNMACADDRESSTYPE_DESTINATIONADDRESS 24200 /* Variable */ +#define UA_NS0ID_IIEEETSNMACADDRESSTYPE_SOURCEADDRESS 24201 /* Variable */ +#define UA_NS0ID_IIEEETSNVLANTAGTYPE 24202 /* ObjectType */ +#define UA_NS0ID_IIEEETSNVLANTAGTYPE_VLANID 24203 /* Variable */ +#define UA_NS0ID_IIEEETSNVLANTAGTYPE_PRIORITYCODEPOINT 24204 /* Variable */ +#define UA_NS0ID_IPRIORITYMAPPINGENTRYTYPE 24205 /* ObjectType */ +#define UA_NS0ID_IPRIORITYMAPPINGENTRYTYPE_MAPPINGURI 24206 /* Variable */ +#define UA_NS0ID_IPRIORITYMAPPINGENTRYTYPE_PRIORITYLABEL 24207 /* Variable */ +#define UA_NS0ID_IPRIORITYMAPPINGENTRYTYPE_PRIORITYVALUE_PCP 24208 /* Variable */ +#define UA_NS0ID_IPRIORITYMAPPINGENTRYTYPE_PRIORITYVALUE_DSCP 24209 /* Variable */ +#define UA_NS0ID_DUPLEX 24210 /* DataType */ +#define UA_NS0ID_INTERFACEADMINSTATUS 24212 /* DataType */ +#define UA_NS0ID_INTERFACEOPERSTATUS 24214 /* DataType */ +#define UA_NS0ID_NEGOTIATIONSTATUS 24216 /* DataType */ +#define UA_NS0ID_TSNFAILURECODE 24218 /* DataType */ +#define UA_NS0ID_TSNSTREAMSTATE 24220 /* DataType */ +#define UA_NS0ID_TSNTALKERSTATUS 24222 /* DataType */ +#define UA_NS0ID_TSNLISTENERSTATUS 24224 /* DataType */ +#define UA_NS0ID_RESOURCES 24226 /* Object */ +#define UA_NS0ID_COMMUNICATION 24227 /* Object */ +#define UA_NS0ID_MAPPINGTABLES 24228 /* Object */ +#define UA_NS0ID_NETWORKINTERFACES 24229 /* Object */ +#define UA_NS0ID_STREAMS 24230 /* Object */ +#define UA_NS0ID_TALKERSTREAMS 24231 /* Object */ +#define UA_NS0ID_LISTENERSTREAMS 24232 /* Object */ +#define UA_NS0ID_IIEEEAUTONEGOTIATIONSTATUSTYPE 24233 /* ObjectType */ +#define UA_NS0ID_IIEEEAUTONEGOTIATIONSTATUSTYPE_NEGOTIATIONSTATUS 24234 /* Variable */ +#define UA_NS0ID_DUPLEX_ENUMVALUES 24235 /* Variable */ +#define UA_NS0ID_INTERFACEADMINSTATUS_ENUMVALUES 24236 /* Variable */ +#define UA_NS0ID_INTERFACEOPERSTATUS_ENUMVALUES 24237 /* Variable */ +#define UA_NS0ID_NEGOTIATIONSTATUS_ENUMVALUES 24238 /* Variable */ +#define UA_NS0ID_TSNFAILURECODE_ENUMVALUES 24239 /* Variable */ +#define UA_NS0ID_TSNSTREAMSTATE_ENUMVALUES 24240 /* Variable */ +#define UA_NS0ID_TSNTALKERSTATUS_ENUMVALUES 24241 /* Variable */ +#define UA_NS0ID_TSNLISTENERSTATUS_ENUMVALUES 24242 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_MAXBYTESTRINGLENGTH 24243 /* Variable */ +#define UA_NS0ID_FILETYPE_MAXBYTESTRINGLENGTH 24244 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_MAXBYTESTRINGLENGTH 24245 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_MAXBYTESTRINGLENGTH 24246 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_MAXBYTESTRINGLENGTH 24247 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_MAXBYTESTRINGLENGTH 24248 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_MAXBYTESTRINGLENGTH 24249 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_MAXBYTESTRINGLENGTH 24250 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_MAXBYTESTRINGLENGTH 24251 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 24252 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 24253 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 24254 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_MAXBYTESTRINGLENGTH 24255 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 24256 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 24257 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 24258 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 24259 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 24260 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 24261 /* Variable */ +#define UA_NS0ID_SEMANTICVERSIONSTRING 24263 /* DataType */ +#define UA_NS0ID_USERMANAGEMENTTYPE 24264 /* ObjectType */ +#define UA_NS0ID_USERMANAGEMENTTYPE_USERS 24265 /* Variable */ +#define UA_NS0ID_USERMANAGEMENTTYPE_PASSWORDLENGTH 24266 /* Variable */ +#define UA_NS0ID_USERMANAGEMENTTYPE_PASSWORDOPTIONS 24267 /* Variable */ +#define UA_NS0ID_USERMANAGEMENTTYPE_PASSWORDRESTRICTIONS 24268 /* Variable */ +#define UA_NS0ID_USERMANAGEMENTTYPE_ADDUSER 24269 /* Method */ +#define UA_NS0ID_USERMANAGEMENTTYPE_ADDUSER_INPUTARGUMENTS 24270 /* Variable */ +#define UA_NS0ID_USERMANAGEMENTTYPE_MODIFYUSER 24271 /* Method */ +#define UA_NS0ID_USERMANAGEMENTTYPE_MODIFYUSER_INPUTARGUMENTS 24272 /* Variable */ +#define UA_NS0ID_USERMANAGEMENTTYPE_REMOVEUSER 24273 /* Method */ +#define UA_NS0ID_USERMANAGEMENTTYPE_REMOVEUSER_INPUTARGUMENTS 24274 /* Variable */ +#define UA_NS0ID_USERMANAGEMENTTYPE_CHANGEPASSWORD 24275 /* Method */ +#define UA_NS0ID_USERMANAGEMENTTYPE_CHANGEPASSWORD_INPUTARGUMENTS 24276 /* Variable */ +#define UA_NS0ID_PASSWORDOPTIONSMASK 24277 /* DataType */ +#define UA_NS0ID_PASSWORDOPTIONSMASK_OPTIONSETVALUES 24278 /* Variable */ +#define UA_NS0ID_USERCONFIGURATIONMASK 24279 /* DataType */ +#define UA_NS0ID_USERCONFIGURATIONMASK_OPTIONSETVALUES 24280 /* Variable */ +#define UA_NS0ID_USERMANAGEMENTDATATYPE 24281 /* DataType */ +#define UA_NS0ID_ADDUSERMETHODTYPE 24282 /* Method */ +#define UA_NS0ID_ADDUSERMETHODTYPE_INPUTARGUMENTS 24283 /* Variable */ +#define UA_NS0ID_MODIFYUSERMETHODTYPE 24284 /* Method */ +#define UA_NS0ID_MODIFYUSERMETHODTYPE_INPUTARGUMENTS 24285 /* Variable */ +#define UA_NS0ID_REMOVEUSERMETHODTYPE 24286 /* Method */ +#define UA_NS0ID_REMOVEUSERMETHODTYPE_INPUTARGUMENTS 24287 /* Variable */ +#define UA_NS0ID_CHANGEPASSWORDMETHODTYPE 24288 /* Method */ +#define UA_NS0ID_CHANGEPASSWORDMETHODTYPE_INPUTARGUMENTS 24289 /* Variable */ +#define UA_NS0ID_USERMANAGEMENT 24290 /* Object */ +#define UA_NS0ID_USERMANAGEMENT_PASSWORDRESTRICTIONS 24291 /* Variable */ +#define UA_NS0ID_USERMANAGEMENTDATATYPE_ENCODING_DEFAULTBINARY 24292 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_USERMANAGEMENTDATATYPE 24293 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_USERMANAGEMENTDATATYPE_DATATYPEVERSION 24294 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_USERMANAGEMENTDATATYPE_DICTIONARYFRAGMENT 24295 /* Variable */ +#define UA_NS0ID_USERMANAGEMENTDATATYPE_ENCODING_DEFAULTXML 24296 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_USERMANAGEMENTDATATYPE 24297 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_USERMANAGEMENTDATATYPE_DATATYPEVERSION 24298 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_USERMANAGEMENTDATATYPE_DICTIONARYFRAGMENT 24299 /* Variable */ +#define UA_NS0ID_USERMANAGEMENTDATATYPE_ENCODING_DEFAULTJSON 24300 /* Object */ +#define UA_NS0ID_USERMANAGEMENT_USERS 24301 /* Variable */ +#define UA_NS0ID_USERMANAGEMENT_PASSWORDLENGTH 24302 /* Variable */ +#define UA_NS0ID_USERMANAGEMENT_PASSWORDOPTIONS 24303 /* Variable */ +#define UA_NS0ID_USERMANAGEMENT_ADDUSER 24304 /* Method */ +#define UA_NS0ID_USERMANAGEMENT_ADDUSER_INPUTARGUMENTS 24305 /* Variable */ +#define UA_NS0ID_USERMANAGEMENT_MODIFYUSER 24306 /* Method */ +#define UA_NS0ID_USERMANAGEMENT_MODIFYUSER_INPUTARGUMENTS 24307 /* Variable */ +#define UA_NS0ID_USERMANAGEMENT_REMOVEUSER 24308 /* Method */ +#define UA_NS0ID_USERMANAGEMENT_REMOVEUSER_INPUTARGUMENTS 24309 /* Variable */ +#define UA_NS0ID_USERMANAGEMENT_CHANGEPASSWORD 24310 /* Method */ +#define UA_NS0ID_USERMANAGEMENT_CHANGEPASSWORD_INPUTARGUMENTS 24311 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_RESPOND2 24312 /* Method */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_RESPOND2_INPUTARGUMENTS 24313 /* Variable */ +#define UA_NS0ID_DIALOGRESPONSE2METHODTYPE 24314 /* Method */ +#define UA_NS0ID_DIALOGRESPONSE2METHODTYPE_INPUTARGUMENTS 24315 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESS2 24316 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPRESS2_INPUTARGUMENTS 24317 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_UNSUPPRESS2 24318 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_UNSUPPRESS2_INPUTARGUMENTS 24319 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_REMOVEFROMSERVICE2 24320 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24321 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_PLACEINSERVICE2 24322 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24323 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_RESET2 24324 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_RESET2_INPUTARGUMENTS 24325 /* Variable */ +#define UA_NS0ID_WITHCOMMENTMETHODTYPE 24326 /* Method */ +#define UA_NS0ID_WITHCOMMENTMETHODTYPE_INPUTARGUMENTS 24327 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESS2 24328 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESS2_INPUTARGUMENTS 24329 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_UNSUPPRESS2 24330 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_UNSUPPRESS2_INPUTARGUMENTS 24331 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_REMOVEFROMSERVICE2 24332 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_REMOVEFROMSERVICE2_INPUTARGUMENTS 24333 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_PLACEINSERVICE2 24334 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_PLACEINSERVICE2_INPUTARGUMENTS 24335 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_RESET2 24336 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_RESET2_INPUTARGUMENTS 24337 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESS2 24338 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24339 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_UNSUPPRESS2 24340 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24341 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_REMOVEFROMSERVICE2 24342 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24343 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_PLACEINSERVICE2 24344 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24345 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_RESET2 24346 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_RESET2_INPUTARGUMENTS 24347 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESS2 24348 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24349 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_UNSUPPRESS2 24350 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24351 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_REMOVEFROMSERVICE2 24352 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24353 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_PLACEINSERVICE2 24354 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24355 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_RESET2 24356 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_RESET2_INPUTARGUMENTS 24357 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESS2 24358 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24359 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_UNSUPPRESS2 24360 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24361 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_REMOVEFROMSERVICE2 24362 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24363 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_PLACEINSERVICE2 24364 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24365 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_RESET2 24366 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_RESET2_INPUTARGUMENTS 24367 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESS2 24368 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24369 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_UNSUPPRESS2 24370 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24371 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_REMOVEFROMSERVICE2 24372 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24373 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_PLACEINSERVICE2 24374 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24375 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_RESET2 24376 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_RESET2_INPUTARGUMENTS 24377 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESS2 24378 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24379 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_UNSUPPRESS2 24380 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24381 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_REMOVEFROMSERVICE2 24382 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24383 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_PLACEINSERVICE2 24384 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24385 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_RESET2 24386 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_RESET2_INPUTARGUMENTS 24387 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESS2 24388 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24389 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_UNSUPPRESS2 24390 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24391 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_REMOVEFROMSERVICE2 24392 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24393 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_PLACEINSERVICE2 24394 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24395 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_RESET2 24396 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_RESET2_INPUTARGUMENTS 24397 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESS2 24398 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24399 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_UNSUPPRESS2 24400 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24401 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_REMOVEFROMSERVICE2 24402 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24403 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_PLACEINSERVICE2 24404 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24405 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_RESET2 24406 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_RESET2_INPUTARGUMENTS 24407 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESS2 24408 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24409 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_UNSUPPRESS2 24410 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24411 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_REMOVEFROMSERVICE2 24412 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24413 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_PLACEINSERVICE2 24414 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24415 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_RESET2 24416 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_RESET2_INPUTARGUMENTS 24417 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESS2 24418 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24419 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_UNSUPPRESS2 24420 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24421 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_REMOVEFROMSERVICE2 24422 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24423 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_PLACEINSERVICE2 24424 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24425 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_RESET2 24426 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_RESET2_INPUTARGUMENTS 24427 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESS2 24428 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24429 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_UNSUPPRESS2 24430 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24431 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_REMOVEFROMSERVICE2 24432 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24433 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_PLACEINSERVICE2 24434 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24435 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_RESET2 24436 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_RESET2_INPUTARGUMENTS 24437 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESS2 24438 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24439 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_UNSUPPRESS2 24440 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24441 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_REMOVEFROMSERVICE2 24442 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24443 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_PLACEINSERVICE2 24444 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24445 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_RESET2 24446 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_RESET2_INPUTARGUMENTS 24447 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESS2 24448 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24449 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_UNSUPPRESS2 24450 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24451 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_REMOVEFROMSERVICE2 24452 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24453 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_PLACEINSERVICE2 24454 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24455 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_RESET2 24456 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_RESET2_INPUTARGUMENTS 24457 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESS2 24458 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24459 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_UNSUPPRESS2 24460 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24461 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_REMOVEFROMSERVICE2 24462 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24463 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_PLACEINSERVICE2 24464 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24465 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_RESET2 24466 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_RESET2_INPUTARGUMENTS 24467 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESS2 24468 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24469 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_UNSUPPRESS2 24470 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24471 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_REMOVEFROMSERVICE2 24472 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24473 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_PLACEINSERVICE2 24474 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24475 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_RESET2 24476 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_RESET2_INPUTARGUMENTS 24477 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESS2 24478 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24479 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_UNSUPPRESS2 24480 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24481 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_REMOVEFROMSERVICE2 24482 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24483 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_PLACEINSERVICE2 24484 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24485 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_RESET2 24486 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_RESET2_INPUTARGUMENTS 24487 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESS2 24488 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24489 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_UNSUPPRESS2 24490 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24491 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_REMOVEFROMSERVICE2 24492 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24493 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_PLACEINSERVICE2 24494 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24495 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_RESET2 24496 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_RESET2_INPUTARGUMENTS 24497 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESS2 24498 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24499 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_UNSUPPRESS2 24500 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24501 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_REMOVEFROMSERVICE2 24502 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24503 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_PLACEINSERVICE2 24504 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24505 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_RESET2 24506 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_RESET2_INPUTARGUMENTS 24507 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESS2 24508 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPRESS2_INPUTARGUMENTS 24509 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_UNSUPPRESS2 24510 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_UNSUPPRESS2_INPUTARGUMENTS 24511 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_REMOVEFROMSERVICE2 24512 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24513 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_PLACEINSERVICE2 24514 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_PLACEINSERVICE2_INPUTARGUMENTS 24515 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_RESET2 24516 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_RESET2_INPUTARGUMENTS 24517 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESS2 24518 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 24519 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_UNSUPPRESS2 24520 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 24521 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 24522 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 24523 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_PLACEINSERVICE2 24524 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 24525 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_RESET2 24526 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 24527 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESS2 24528 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 24529 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_UNSUPPRESS2 24530 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 24531 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 24532 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24533 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 24534 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 24535 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_RESET2 24536 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 24537 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS2 24538 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 24539 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 24540 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 24541 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 24542 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 24543 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 24544 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 24545 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET2 24546 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 24547 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 24548 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 24549 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 24550 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 24551 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 24552 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24553 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 24554 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 24555 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET2 24556 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 24557 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS2 24558 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 24559 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 24560 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 24561 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 24562 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 24563 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 24564 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 24565 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET2 24566 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 24567 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 24568 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 24569 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 24570 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 24571 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 24572 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24573 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 24574 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 24575 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET2 24576 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 24577 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS2 24578 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 24579 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 24580 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 24581 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 24582 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 24583 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 24584 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 24585 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET2 24586 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 24587 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 24588 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 24589 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 24590 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 24591 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 24592 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24593 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 24594 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 24595 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET2 24596 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 24597 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESS2 24598 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 24599 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_UNSUPPRESS2 24600 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 24601 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 24602 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 24603 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_PLACEINSERVICE2 24604 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 24605 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_RESET2 24606 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 24607 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESS2 24608 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 24609 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_UNSUPPRESS2 24610 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 24611 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 24612 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24613 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 24614 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 24615 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_RESET2 24616 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 24617 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS2 24618 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 24619 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 24620 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 24621 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 24622 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 24623 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 24624 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 24625 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET2 24626 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 24627 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 24628 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 24629 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 24630 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 24631 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 24632 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24633 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 24634 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 24635 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET2 24636 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 24637 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS2 24638 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 24639 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 24640 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 24641 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 24642 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 24643 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 24644 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 24645 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET2 24646 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 24647 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 24648 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 24649 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 24650 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 24651 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 24652 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24653 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 24654 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 24655 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET2 24656 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 24657 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS2 24658 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 24659 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 24660 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 24661 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 24662 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 24663 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 24664 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 24665 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET2 24666 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 24667 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 24668 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 24669 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 24670 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 24671 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 24672 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24673 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 24674 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 24675 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET2 24676 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 24677 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS2 24678 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 24679 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 24680 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 24681 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 24682 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 24683 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 24684 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 24685 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET2 24686 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 24687 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 24688 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 24689 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 24690 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 24691 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 24692 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24693 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 24694 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 24695 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET2 24696 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 24697 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS2 24698 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 24699 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 24700 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 24701 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 24702 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 24703 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 24704 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 24705 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET2 24706 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 24707 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 24708 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 24709 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 24710 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 24711 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 24712 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24713 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 24714 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 24715 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET2 24716 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 24717 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS2 24718 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 24719 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 24720 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 24721 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 24722 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 24723 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 24724 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 24725 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET2 24726 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 24727 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 24728 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 24729 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 24730 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 24731 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 24732 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 24733 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 24734 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 24735 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET2 24736 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 24737 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_TIMEDSHELVE2 24738 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24739 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_UNSHELVE2 24740 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24741 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24742 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24743 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_GETGROUPMEMBERSHIPS 24744 /* Method */ +#define UA_NS0ID_GETGROUPMEMBERSHIPSMETHODTYPE 24746 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_TIMEDSHELVE2 24748 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24749 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_UNSHELVE2 24750 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24751 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_ONESHOTSHELVE2 24752 /* Method */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24753 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_GETGROUPMEMBERSHIPS 24754 /* Method */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_TIMEDSHELVE2 24756 /* Method */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_TIMEDSHELVE2_INPUTARGUMENTS 24757 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_UNSHELVE2 24758 /* Method */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_UNSHELVE2_INPUTARGUMENTS 24759 /* Variable */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_ONESHOTSHELVE2 24760 /* Method */ +#define UA_NS0ID_SHELVEDSTATEMACHINETYPE_ONESHOTSHELVE2_INPUTARGUMENTS 24761 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24762 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24763 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_UNSHELVE2 24764 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24765 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24766 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24767 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_GETGROUPMEMBERSHIPS 24768 /* Method */ +#define UA_NS0ID_LIMITALARMTYPE_SEVERITYHIGHHIGH 24770 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SEVERITYHIGH 24771 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SEVERITYLOW 24772 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SEVERITYLOWLOW 24773 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_HIGHHIGHDEADBAND 24774 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_HIGHDEADBAND 24775 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LOWDEADBAND 24776 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_LOWLOWDEADBAND 24777 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24778 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24779 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_UNSHELVE2 24780 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24781 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24782 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24783 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_GETGROUPMEMBERSHIPS 24784 /* Method */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SEVERITYHIGHHIGH 24786 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SEVERITYHIGH 24787 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SEVERITYLOW 24788 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SEVERITYLOWLOW 24789 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_HIGHHIGHDEADBAND 24790 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_HIGHDEADBAND 24791 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LOWDEADBAND 24792 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_LOWLOWDEADBAND 24793 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24794 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24795 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_UNSHELVE2 24796 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24797 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24798 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24799 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_GETGROUPMEMBERSHIPS 24800 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SEVERITYHIGHHIGH 24802 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SEVERITYHIGH 24803 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SEVERITYLOW 24804 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SEVERITYLOWLOW 24805 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHHIGHDEADBAND 24806 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_HIGHDEADBAND 24807 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWDEADBAND 24808 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_LOWLOWDEADBAND 24809 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24810 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24811 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_UNSHELVE2 24812 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24813 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24814 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24815 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_GETGROUPMEMBERSHIPS 24816 /* Method */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SEVERITYHIGHHIGH 24818 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SEVERITYHIGH 24819 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SEVERITYLOW 24820 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SEVERITYLOWLOW 24821 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHHIGHDEADBAND 24822 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_HIGHDEADBAND 24823 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWDEADBAND 24824 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_LOWLOWDEADBAND 24825 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24826 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24827 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_UNSHELVE2 24828 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24829 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24830 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24831 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_GETGROUPMEMBERSHIPS 24832 /* Method */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SEVERITYHIGHHIGH 24834 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SEVERITYHIGH 24835 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SEVERITYLOW 24836 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SEVERITYLOWLOW 24837 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_HIGHHIGHDEADBAND 24838 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_HIGHDEADBAND 24839 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LOWDEADBAND 24840 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_LOWLOWDEADBAND 24841 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24842 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24843 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_UNSHELVE2 24844 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24845 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24846 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24847 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_GETGROUPMEMBERSHIPS 24848 /* Method */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SEVERITYHIGHHIGH 24850 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SEVERITYHIGH 24851 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SEVERITYLOW 24852 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SEVERITYLOWLOW 24853 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHDEADBAND 24854 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_HIGHDEADBAND 24855 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWDEADBAND 24856 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_LOWLOWDEADBAND 24857 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24858 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24859 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_UNSHELVE2 24860 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24861 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24862 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24863 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_GETGROUPMEMBERSHIPS 24864 /* Method */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SEVERITYHIGHHIGH 24866 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SEVERITYHIGH 24867 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SEVERITYLOW 24868 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SEVERITYLOWLOW 24869 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHDEADBAND 24870 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_HIGHDEADBAND 24871 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWDEADBAND 24872 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWDEADBAND 24873 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24874 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24875 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_UNSHELVE2 24876 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24877 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24878 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24879 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_GETGROUPMEMBERSHIPS 24880 /* Method */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SEVERITYHIGHHIGH 24882 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SEVERITYHIGH 24883 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SEVERITYLOW 24884 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SEVERITYLOWLOW 24885 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_HIGHHIGHDEADBAND 24886 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_HIGHDEADBAND 24887 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LOWDEADBAND 24888 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_LOWLOWDEADBAND 24889 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24890 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24891 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_UNSHELVE2 24892 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24893 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24894 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24895 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_GETGROUPMEMBERSHIPS 24896 /* Method */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SEVERITYHIGHHIGH 24898 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SEVERITYHIGH 24899 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SEVERITYLOW 24900 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SEVERITYLOWLOW 24901 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_HIGHHIGHDEADBAND 24902 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_HIGHDEADBAND 24903 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LOWDEADBAND 24904 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_LOWLOWDEADBAND 24905 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24906 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24907 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_UNSHELVE2 24908 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24909 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24910 /* Method */ +#define UA_NS0ID_DISCRETEALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24911 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_GETGROUPMEMBERSHIPS 24912 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24914 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24915 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_UNSHELVE2 24916 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24917 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24918 /* Method */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24919 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_GETGROUPMEMBERSHIPS 24920 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24922 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24923 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_UNSHELVE2 24924 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24925 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24926 /* Method */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24927 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_GETGROUPMEMBERSHIPS 24928 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24930 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24931 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_UNSHELVE2 24932 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24933 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24934 /* Method */ +#define UA_NS0ID_TRIPALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24935 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_GETGROUPMEMBERSHIPS 24936 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24938 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24939 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_UNSHELVE2 24940 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24941 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24942 /* Method */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24943 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_GETGROUPMEMBERSHIPS 24944 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24946 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24947 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_UNSHELVE2 24948 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24949 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24950 /* Method */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24951 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_GETGROUPMEMBERSHIPS 24952 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24954 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24955 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_UNSHELVE2 24956 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24957 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24958 /* Method */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24959 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_GETGROUPMEMBERSHIPS 24960 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24962 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24963 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_UNSHELVE2 24964 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24965 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24966 /* Method */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24967 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_GETGROUPMEMBERSHIPS 24968 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2 24970 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24971 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_UNSHELVE2 24972 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24973 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2 24974 /* Method */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24975 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_GETGROUPMEMBERSHIPS 24976 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 24978 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24979 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 24980 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24981 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 24982 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24983 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 24984 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 24986 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24987 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 24988 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24989 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 24990 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24991 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 24992 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 24994 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 24995 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 24996 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 24997 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 24998 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 24999 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 25000 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 25002 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25003 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 25004 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25005 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 25006 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25007 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 25008 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 25010 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25011 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 25012 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25013 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 25014 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25015 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 25016 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 25018 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25019 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 25020 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25021 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 25022 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25023 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 25024 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 25026 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25027 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 25028 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25029 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 25030 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25031 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 25032 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 25034 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25035 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 25036 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25037 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 25038 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25039 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 25040 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 25042 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25043 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 25044 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25045 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 25046 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25047 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 25048 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 25050 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25051 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 25052 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25053 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 25054 /* Method */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25055 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 25056 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 25058 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25059 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 25060 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25061 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 25062 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25063 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 25064 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 25066 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25067 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 25068 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25069 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 25070 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25071 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 25072 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 25074 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25075 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 25076 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25077 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 25078 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25079 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 25080 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 25082 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25083 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 25084 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25085 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 25086 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25087 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 25088 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 25090 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25091 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 25092 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25093 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 25094 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25095 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 25096 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 25098 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25099 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 25100 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25101 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 25102 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25103 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 25104 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 25106 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25107 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 25108 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25109 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 25110 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25111 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 25112 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 25114 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25115 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 25116 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25117 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 25118 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25119 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 25120 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 25122 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25123 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 25124 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25125 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 25126 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25127 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 25128 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 25130 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25131 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 25132 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25133 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 25134 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25135 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 25136 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 25138 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25139 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 25140 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25141 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 25142 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25143 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 25144 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 25146 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25147 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 25148 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25149 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 25150 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25151 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 25152 /* Method */ +#define UA_NS0ID_ALARMCONDITIONTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25154 /* Variable */ +#define UA_NS0ID_GETGROUPMEMBERSHIPSMETHODTYPE_OUTPUTARGUMENTS 25155 /* Variable */ +#define UA_NS0ID_ALARMGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25156 /* Variable */ +#define UA_NS0ID_TIMEDSHELVE2METHODTYPE 25157 /* Method */ +#define UA_NS0ID_TIMEDSHELVE2METHODTYPE_INPUTARGUMENTS 25158 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25159 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25160 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25161 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25162 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25163 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25164 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25165 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25166 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25167 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25168 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25169 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25170 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25171 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25172 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25173 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25174 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25175 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25176 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25177 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25178 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25179 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25180 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25181 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25182 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25183 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25184 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25185 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25186 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25187 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25188 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25189 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25190 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25191 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25192 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25193 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25194 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25195 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25196 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25197 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25198 /* Variable */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_NAMESPACEFILE_LASTMODIFIEDTIME 25199 /* Variable */ +#define UA_NS0ID_FILETYPE_LASTMODIFIEDTIME 25200 /* Variable */ +#define UA_NS0ID_ADDRESSSPACEFILETYPE_LASTMODIFIEDTIME 25201 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_NAMESPACEFILE_LASTMODIFIEDTIME 25202 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_NAMESPACEFILE_LASTMODIFIEDTIME 25203 /* Variable */ +#define UA_NS0ID_FILEDIRECTORYTYPE_FILENAME_PLACEHOLDER_LASTMODIFIEDTIME 25204 /* Variable */ +#define UA_NS0ID_FILESYSTEM_FILENAME_PLACEHOLDER_LASTMODIFIEDTIME 25205 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_LASTMODIFIEDTIME 25206 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_LASTMODIFIEDTIME 25207 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_LASTMODIFIEDTIME 25208 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_LASTMODIFIEDTIME 25209 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_LASTMODIFIEDTIME 25210 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_LASTMODIFIEDTIME 25211 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_LASTMODIFIEDTIME 25212 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_LASTMODIFIEDTIME 25213 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_LASTMODIFIEDTIME 25214 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_LASTMODIFIEDTIME 25215 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_LASTMODIFIEDTIME 25216 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_LASTMODIFIEDTIME 25217 /* Variable */ +#define UA_NS0ID_IVLANIDTYPE 25218 /* ObjectType */ +#define UA_NS0ID_IVLANIDTYPE_VLANID 25219 /* Variable */ +#define UA_NS0ID_PRIORITYMAPPINGENTRYTYPE 25220 /* DataType */ +#define UA_NS0ID_IETFBASENETWORKINTERFACETYPE 25221 /* ObjectType */ +#define UA_NS0ID_IETFBASENETWORKINTERFACETYPE_ADMINSTATUS 25222 /* Variable */ +#define UA_NS0ID_IETFBASENETWORKINTERFACETYPE_OPERSTATUS 25223 /* Variable */ +#define UA_NS0ID_IETFBASENETWORKINTERFACETYPE_PHYSADDRESS 25224 /* Variable */ +#define UA_NS0ID_IETFBASENETWORKINTERFACETYPE_SPEED 25225 /* Variable */ +#define UA_NS0ID_IETFBASENETWORKINTERFACETYPE_INTERFACENAME_PLACEHOLDER 25226 /* Object */ +#define UA_NS0ID_PRIORITYMAPPINGTABLETYPE 25227 /* ObjectType */ +#define UA_NS0ID_PRIORITYMAPPINGTABLETYPE_PRIORITYMAPPPINGENTRIES 25228 /* Variable */ +#define UA_NS0ID_PRIORITYMAPPINGTABLETYPE_ADDPRIORITYMAPPINGENTRY 25229 /* Method */ +#define UA_NS0ID_PRIORITYMAPPINGTABLETYPE_ADDPRIORITYMAPPINGENTRY_INPUTARGUMENTS 25230 /* Variable */ +#define UA_NS0ID_PRIORITYMAPPINGTABLETYPE_DELETEPRIORITYMAPPINGENTRY 25231 /* Method */ +#define UA_NS0ID_PRIORITYMAPPINGTABLETYPE_DELETEPRIORITYMAPPINGENTRY_INPUTARGUMENTS 25232 /* Variable */ +#define UA_NS0ID_ADDPRIORITYMAPPINGENTRYMETHODTYPE 25233 /* Method */ +#define UA_NS0ID_ADDPRIORITYMAPPINGENTRYMETHODTYPE_INPUTARGUMENTS 25234 /* Variable */ +#define UA_NS0ID_DELETEPRIORITYMAPPINGENTRYMETHODTYPE 25235 /* Method */ +#define UA_NS0ID_DELETEPRIORITYMAPPINGENTRYMETHODTYPE_INPUTARGUMENTS 25236 /* Variable */ +#define UA_NS0ID_USESPRIORITYMAPPINGTABLE 25237 /* ReferenceType */ +#define UA_NS0ID_HASLOWERLAYERINTERFACE 25238 /* ReferenceType */ +#define UA_NS0ID_PRIORITYMAPPINGENTRYTYPE_ENCODING_DEFAULTBINARY 25239 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PRIORITYMAPPINGENTRYTYPE 25240 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PRIORITYMAPPINGENTRYTYPE_DATATYPEVERSION 25241 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PRIORITYMAPPINGENTRYTYPE_DICTIONARYFRAGMENT 25242 /* Variable */ +#define UA_NS0ID_PRIORITYMAPPINGENTRYTYPE_ENCODING_DEFAULTXML 25243 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PRIORITYMAPPINGENTRYTYPE 25244 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PRIORITYMAPPINGENTRYTYPE_DATATYPEVERSION 25245 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PRIORITYMAPPINGENTRYTYPE_DICTIONARYFRAGMENT 25246 /* Variable */ +#define UA_NS0ID_PRIORITYMAPPINGENTRYTYPE_ENCODING_DEFAULTJSON 25247 /* Object */ +#define UA_NS0ID_IETFBASENETWORKINTERFACETYPE_SPEED_DEFINITION 25248 /* Variable */ +#define UA_NS0ID_IETFBASENETWORKINTERFACETYPE_SPEED_VALUEPRECISION 25249 /* Variable */ +#define UA_NS0ID_IETFBASENETWORKINTERFACETYPE_SPEED_INSTRUMENTRANGE 25250 /* Variable */ +#define UA_NS0ID_IETFBASENETWORKINTERFACETYPE_SPEED_EURANGE 25251 /* Variable */ +#define UA_NS0ID_IETFBASENETWORKINTERFACETYPE_SPEED_ENGINEERINGUNITS 25252 /* Variable */ +#define UA_NS0ID_ISEXECUTABLEON 25253 /* ReferenceType */ +#define UA_NS0ID_CONTROLS 25254 /* ReferenceType */ +#define UA_NS0ID_UTILIZES 25255 /* ReferenceType */ +#define UA_NS0ID_REQUIRES 25256 /* ReferenceType */ +#define UA_NS0ID_ISPHYSICALLYCONNECTEDTO 25257 /* ReferenceType */ +#define UA_NS0ID_REPRESENTSSAMEENTITYAS 25258 /* ReferenceType */ +#define UA_NS0ID_REPRESENTSSAMEHARDWAREAS 25259 /* ReferenceType */ +#define UA_NS0ID_REPRESENTSSAMEFUNCTIONALITYAS 25260 /* ReferenceType */ +#define UA_NS0ID_ISHOSTEDBY 25261 /* ReferenceType */ +#define UA_NS0ID_HASPHYSICALCOMPONENT 25262 /* ReferenceType */ +#define UA_NS0ID_HASCONTAINEDCOMPONENT 25263 /* ReferenceType */ +#define UA_NS0ID_HASATTACHEDCOMPONENT 25264 /* ReferenceType */ +#define UA_NS0ID_ISEXECUTINGON 25265 /* ReferenceType */ +#define UA_NS0ID_OPCUANAMESPACEMETADATA_CONFIGURATIONVERSION 25266 /* Variable */ +#define UA_NS0ID_NAMESPACEMETADATATYPE_CONFIGURATIONVERSION 25267 /* Variable */ +#define UA_NS0ID_NAMESPACESTYPE_NAMESPACEIDENTIFIER_PLACEHOLDER_CONFIGURATIONVERSION 25268 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE 25269 /* DataType */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETDATATYPE 25270 /* DataType */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_SECURITYGROUPS_ADDSECURITYGROUPFOLDER 25271 /* Method */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_SECURITYGROUPS_ADDSECURITYGROUPFOLDER_INPUTARGUMENTS 25272 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_SECURITYGROUPS_ADDSECURITYGROUPFOLDER_OUTPUTARGUMENTS 25273 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_SECURITYGROUPS_REMOVESECURITYGROUPFOLDER 25274 /* Method */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_SECURITYGROUPS_REMOVESECURITYGROUPFOLDER_INPUTARGUMENTS 25275 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_SECURITYGROUPS_SUPPORTEDSECURITYPOLICYURIS 25276 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_KEYPUSHTARGETS 25277 /* Object */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_KEYPUSHTARGETS_ADDPUSHTARGET 25278 /* Method */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_KEYPUSHTARGETS_ADDPUSHTARGET_INPUTARGUMENTS 25279 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_KEYPUSHTARGETS_ADDPUSHTARGET_OUTPUTARGUMENTS 25280 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_KEYPUSHTARGETS_REMOVEPUSHTARGET 25281 /* Method */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_KEYPUSHTARGETS_REMOVEPUSHTARGET_INPUTARGUMENTS 25282 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_KEYPUSHTARGETS_ADDPUSHTARGETFOLDER 25283 /* Method */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_KEYPUSHTARGETS_ADDPUSHTARGETFOLDER_INPUTARGUMENTS 25284 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_KEYPUSHTARGETS_ADDPUSHTARGETFOLDER_OUTPUTARGUMENTS 25285 /* Variable */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_KEYPUSHTARGETS_REMOVEPUSHTARGETFOLDER 25286 /* Method */ +#define UA_NS0ID_PUBSUBKEYSERVICETYPE_KEYPUSHTARGETS_REMOVEPUSHTARGETFOLDER_INPUTARGUMENTS 25287 /* Variable */ +#define UA_NS0ID_ADDSECURITYGROUPFOLDERMETHODTYPE 25288 /* Method */ +#define UA_NS0ID_ADDSECURITYGROUPFOLDERMETHODTYPE_INPUTARGUMENTS 25289 /* Variable */ +#define UA_NS0ID_ADDSECURITYGROUPFOLDERMETHODTYPE_OUTPUTARGUMENTS 25290 /* Variable */ +#define UA_NS0ID_REMOVESECURITYGROUPFOLDERMETHODTYPE 25291 /* Method */ +#define UA_NS0ID_REMOVESECURITYGROUPFOLDERMETHODTYPE_INPUTARGUMENTS 25292 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPFOLDERNAME_PLACEHOLDER_ADDSECURITYGROUPFOLDER 25293 /* Method */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPFOLDERNAME_PLACEHOLDER_ADDSECURITYGROUPFOLDER_INPUTARGUMENTS 25294 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPFOLDERNAME_PLACEHOLDER_ADDSECURITYGROUPFOLDER_OUTPUTARGUMENTS 25295 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPFOLDERNAME_PLACEHOLDER_REMOVESECURITYGROUPFOLDER 25296 /* Method */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPFOLDERNAME_PLACEHOLDER_REMOVESECURITYGROUPFOLDER_INPUTARGUMENTS 25297 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPFOLDERNAME_PLACEHOLDER_SUPPORTEDSECURITYPOLICYURIS 25298 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_ADDSECURITYGROUPFOLDER 25312 /* Method */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_ADDSECURITYGROUPFOLDER_INPUTARGUMENTS 25313 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_ADDSECURITYGROUPFOLDER_OUTPUTARGUMENTS 25314 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_REMOVESECURITYGROUPFOLDER 25315 /* Method */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_REMOVESECURITYGROUPFOLDER_INPUTARGUMENTS 25316 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SUPPORTEDSECURITYPOLICYURIS 25317 /* Variable */ +#define UA_NS0ID_CONNECTSECURITYGROUPSMETHODTYPE 25331 /* Method */ +#define UA_NS0ID_CONNECTSECURITYGROUPSMETHODTYPE_INPUTARGUMENTS 25332 /* Variable */ +#define UA_NS0ID_CONNECTSECURITYGROUPSMETHODTYPE_OUTPUTARGUMENTS 25333 /* Variable */ +#define UA_NS0ID_DISCONNECTSECURITYGROUPSMETHODTYPE 25334 /* Method */ +#define UA_NS0ID_DISCONNECTSECURITYGROUPSMETHODTYPE_INPUTARGUMENTS 25335 /* Variable */ +#define UA_NS0ID_DISCONNECTSECURITYGROUPSMETHODTYPE_OUTPUTARGUMENTS 25336 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE 25337 /* ObjectType */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_SECURITYPOLICYURI 25340 /* Variable */ +#define UA_NS0ID_HASPUSHEDSECURITYGROUP 25345 /* ReferenceType */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE 25346 /* ObjectType */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETFOLDERNAME_PLACEHOLDER 25347 /* Object */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETFOLDERNAME_PLACEHOLDER_ADDPUSHTARGET 25348 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETFOLDERNAME_PLACEHOLDER_ADDPUSHTARGET_INPUTARGUMENTS 25349 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETFOLDERNAME_PLACEHOLDER_ADDPUSHTARGET_OUTPUTARGUMENTS 25350 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETFOLDERNAME_PLACEHOLDER_REMOVEPUSHTARGET 25351 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETFOLDERNAME_PLACEHOLDER_REMOVEPUSHTARGET_INPUTARGUMENTS 25352 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETFOLDERNAME_PLACEHOLDER_ADDPUSHTARGETFOLDER 25353 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETFOLDERNAME_PLACEHOLDER_ADDPUSHTARGETFOLDER_INPUTARGUMENTS 25354 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETFOLDERNAME_PLACEHOLDER_ADDPUSHTARGETFOLDER_OUTPUTARGUMENTS 25355 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETFOLDERNAME_PLACEHOLDER_REMOVEPUSHTARGETFOLDER 25356 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETFOLDERNAME_PLACEHOLDER_REMOVEPUSHTARGETFOLDER_INPUTARGUMENTS 25357 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER 25358 /* Object */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_SECURITYPOLICYURI 25361 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_ADDPUSHTARGET 25366 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_ADDPUSHTARGET_INPUTARGUMENTS 25367 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_ADDPUSHTARGET_OUTPUTARGUMENTS 25368 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_REMOVEPUSHTARGET 25369 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_REMOVEPUSHTARGET_INPUTARGUMENTS 25370 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_ADDPUSHTARGETFOLDER 25371 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_ADDPUSHTARGETFOLDER_INPUTARGUMENTS 25372 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_ADDPUSHTARGETFOLDER_OUTPUTARGUMENTS 25373 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_REMOVEPUSHTARGETFOLDER 25374 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_REMOVEPUSHTARGETFOLDER_INPUTARGUMENTS 25375 /* Variable */ +#define UA_NS0ID_ADDPUSHTARGETMETHODTYPE 25376 /* Method */ +#define UA_NS0ID_ADDPUSHTARGETMETHODTYPE_INPUTARGUMENTS 25377 /* Variable */ +#define UA_NS0ID_ADDPUSHTARGETMETHODTYPE_OUTPUTARGUMENTS 25378 /* Variable */ +#define UA_NS0ID_REMOVEPUSHTARGETMETHODTYPE 25379 /* Method */ +#define UA_NS0ID_REMOVEPUSHTARGETMETHODTYPE_INPUTARGUMENTS 25380 /* Variable */ +#define UA_NS0ID_ADDPUSHTARGETFOLDERMETHODTYPE 25381 /* Method */ +#define UA_NS0ID_ADDPUSHTARGETFOLDERMETHODTYPE_INPUTARGUMENTS 25382 /* Variable */ +#define UA_NS0ID_ADDPUSHTARGETFOLDERMETHODTYPE_OUTPUTARGUMENTS 25383 /* Variable */ +#define UA_NS0ID_REMOVEPUSHTARGETFOLDERMETHODTYPE 25384 /* Method */ +#define UA_NS0ID_REMOVEPUSHTARGETFOLDERMETHODTYPE_INPUTARGUMENTS 25385 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SECURITYGROUPS_ADDSECURITYGROUPFOLDER 25386 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SECURITYGROUPS_ADDSECURITYGROUPFOLDER_INPUTARGUMENTS 25387 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SECURITYGROUPS_ADDSECURITYGROUPFOLDER_OUTPUTARGUMENTS 25388 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SECURITYGROUPS_REMOVESECURITYGROUPFOLDER 25389 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SECURITYGROUPS_REMOVESECURITYGROUPFOLDER_INPUTARGUMENTS 25390 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_SECURITYGROUPS_SUPPORTEDSECURITYPOLICYURIS 25391 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_KEYPUSHTARGETS 25392 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_KEYPUSHTARGETS_ADDPUSHTARGET 25393 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_KEYPUSHTARGETS_ADDPUSHTARGET_INPUTARGUMENTS 25394 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_KEYPUSHTARGETS_ADDPUSHTARGET_OUTPUTARGUMENTS 25395 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_KEYPUSHTARGETS_REMOVEPUSHTARGET 25396 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_KEYPUSHTARGETS_REMOVEPUSHTARGET_INPUTARGUMENTS 25397 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_KEYPUSHTARGETS_ADDPUSHTARGETFOLDER 25398 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_KEYPUSHTARGETS_ADDPUSHTARGETFOLDER_INPUTARGUMENTS 25399 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_KEYPUSHTARGETS_ADDPUSHTARGETFOLDER_OUTPUTARGUMENTS 25400 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_KEYPUSHTARGETS_REMOVEPUSHTARGETFOLDER 25401 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_KEYPUSHTARGETS_REMOVEPUSHTARGETFOLDER_INPUTARGUMENTS 25402 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION 25403 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_SIZE 25404 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_WRITABLE 25405 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_USERWRITABLE 25406 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_OPENCOUNT 25407 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_MIMETYPE 25408 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_MAXBYTESTRINGLENGTH 25409 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_LASTMODIFIEDTIME 25410 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_OPEN 25411 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_OPEN_INPUTARGUMENTS 25412 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_OPEN_OUTPUTARGUMENTS 25413 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_CLOSE 25414 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_CLOSE_INPUTARGUMENTS 25415 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_READ 25416 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_READ_INPUTARGUMENTS 25417 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_READ_OUTPUTARGUMENTS 25418 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_WRITE 25419 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_WRITE_INPUTARGUMENTS 25420 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_GETPOSITION 25421 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_GETPOSITION_INPUTARGUMENTS 25422 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_GETPOSITION_OUTPUTARGUMENTS 25423 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_SETPOSITION 25424 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_SETPOSITION_INPUTARGUMENTS 25425 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_RESERVEIDS 25426 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_RESERVEIDS_INPUTARGUMENTS 25427 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_RESERVEIDS_OUTPUTARGUMENTS 25428 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_CLOSEANDUPDATE 25429 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_CLOSEANDUPDATE_INPUTARGUMENTS 25430 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCONFIGURATION_CLOSEANDUPDATE_OUTPUTARGUMENTS 25431 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DEFAULTDATAGRAMPUBLISHERID 25432 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONFIGURATIONVERSION 25433 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SECURITYGROUPS_ADDSECURITYGROUPFOLDER 25434 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SECURITYGROUPS_ADDSECURITYGROUPFOLDER_INPUTARGUMENTS 25435 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SECURITYGROUPS_ADDSECURITYGROUPFOLDER_OUTPUTARGUMENTS 25436 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SECURITYGROUPS_REMOVESECURITYGROUPFOLDER 25437 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SECURITYGROUPS_REMOVESECURITYGROUPFOLDER_INPUTARGUMENTS 25438 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_SECURITYGROUPS_SUPPORTEDSECURITYPOLICYURIS 25439 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_KEYPUSHTARGETS 25440 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_KEYPUSHTARGETS_ADDPUSHTARGET 25441 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_KEYPUSHTARGETS_ADDPUSHTARGET_INPUTARGUMENTS 25442 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_KEYPUSHTARGETS_ADDPUSHTARGET_OUTPUTARGUMENTS 25443 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_KEYPUSHTARGETS_REMOVEPUSHTARGET 25444 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_KEYPUSHTARGETS_REMOVEPUSHTARGET_INPUTARGUMENTS 25445 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_KEYPUSHTARGETS_ADDPUSHTARGETFOLDER 25446 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_KEYPUSHTARGETS_ADDPUSHTARGETFOLDER_INPUTARGUMENTS 25447 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_KEYPUSHTARGETS_ADDPUSHTARGETFOLDER_OUTPUTARGUMENTS 25448 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_KEYPUSHTARGETS_REMOVEPUSHTARGETFOLDER 25449 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_KEYPUSHTARGETS_REMOVEPUSHTARGETFOLDER_INPUTARGUMENTS 25450 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION 25451 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_SIZE 25452 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_WRITABLE 25453 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_USERWRITABLE 25454 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_OPENCOUNT 25455 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_MIMETYPE 25456 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_MAXBYTESTRINGLENGTH 25457 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_LASTMODIFIEDTIME 25458 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_OPEN 25459 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_OPEN_INPUTARGUMENTS 25460 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_OPEN_OUTPUTARGUMENTS 25461 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_CLOSE 25462 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_CLOSE_INPUTARGUMENTS 25463 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_READ 25464 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_READ_INPUTARGUMENTS 25465 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_READ_OUTPUTARGUMENTS 25466 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_WRITE 25467 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_WRITE_INPUTARGUMENTS 25468 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_GETPOSITION 25469 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_GETPOSITION_INPUTARGUMENTS 25470 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_GETPOSITION_OUTPUTARGUMENTS 25471 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_SETPOSITION 25472 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_SETPOSITION_INPUTARGUMENTS 25473 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_RESERVEIDS 25474 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_RESERVEIDS_INPUTARGUMENTS 25475 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_RESERVEIDS_OUTPUTARGUMENTS 25476 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_CLOSEANDUPDATE 25477 /* Method */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_CLOSEANDUPDATE_INPUTARGUMENTS 25478 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCONFIGURATION_CLOSEANDUPDATE_OUTPUTARGUMENTS 25479 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DEFAULTDATAGRAMPUBLISHERID 25480 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONFIGURATIONVERSION 25481 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE 25482 /* ObjectType */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_SIZE 25483 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_WRITABLE 25484 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_USERWRITABLE 25485 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_OPENCOUNT 25486 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_MIMETYPE 25487 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_MAXBYTESTRINGLENGTH 25488 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_LASTMODIFIEDTIME 25489 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_OPEN 25490 /* Method */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_OPEN_INPUTARGUMENTS 25491 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_OPEN_OUTPUTARGUMENTS 25492 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_CLOSE 25493 /* Method */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_CLOSE_INPUTARGUMENTS 25494 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_READ 25495 /* Method */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_READ_INPUTARGUMENTS 25496 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_READ_OUTPUTARGUMENTS 25497 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_WRITE 25498 /* Method */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_WRITE_INPUTARGUMENTS 25499 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_GETPOSITION 25500 /* Method */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_GETPOSITION_INPUTARGUMENTS 25501 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_GETPOSITION_OUTPUTARGUMENTS 25502 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_SETPOSITION 25503 /* Method */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_SETPOSITION_INPUTARGUMENTS 25504 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_RESERVEIDS 25505 /* Method */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_RESERVEIDS_INPUTARGUMENTS 25506 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_RESERVEIDS_OUTPUTARGUMENTS 25507 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_CLOSEANDUPDATE 25508 /* Method */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_CLOSEANDUPDATE_INPUTARGUMENTS 25509 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPE_CLOSEANDUPDATE_OUTPUTARGUMENTS 25510 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPERESERVEIDSMETHODTYPE 25511 /* Method */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPERESERVEIDSMETHODTYPE_INPUTARGUMENTS 25512 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPERESERVEIDSMETHODTYPE_OUTPUTARGUMENTS 25513 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPECLOSEANDUPDATEMETHODTYPE 25514 /* Method */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPECLOSEANDUPDATEMETHODTYPE_INPUTARGUMENTS 25515 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONTYPECLOSEANDUPDATEMETHODTYPE_OUTPUTARGUMENTS 25516 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONREFMASK 25517 /* DataType */ +#define UA_NS0ID_PUBSUBCONFIGURATIONREFMASK_OPTIONSETVALUES 25518 /* Variable */ +#define UA_NS0ID_PUBSUBCONFIGURATIONREFDATATYPE 25519 /* DataType */ +#define UA_NS0ID_PUBSUBCONFIGURATIONVALUEDATATYPE 25520 /* DataType */ +#define UA_NS0ID_PUBLISHEDDATASETTYPE_CYCLICDATASET 25521 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATAITEMSTYPE_CYCLICDATASET 25522 /* Variable */ +#define UA_NS0ID_PUBLISHEDEVENTSTYPE_CYCLICDATASET 25523 /* Variable */ +#define UA_NS0ID_DATASETFOLDERTYPE_PUBLISHEDDATASETNAME_PLACEHOLDER_CYCLICDATASET 25524 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTTYPE_QOSCATEGORY 25525 /* Variable */ +#define UA_NS0ID_DATAGRAMCONNECTIONTRANSPORTTYPE_DATAGRAMQOS 25526 /* Variable */ +#define UA_NS0ID_DATAGRAMWRITERGROUPTRANSPORTTYPE_QOSCATEGORY 25527 /* Variable */ +#define UA_NS0ID_DATAGRAMDATASETREADERTRANSPORTTYPE_QOSCATEGORY 25528 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE_ENCODING_DEFAULTBINARY 25529 /* Object */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETDATATYPE_ENCODING_DEFAULTBINARY 25530 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATIONREFDATATYPE_ENCODING_DEFAULTBINARY 25531 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATIONVALUEDATATYPE_ENCODING_DEFAULTBINARY 25532 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE 25533 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE_DATATYPEVERSION 25534 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE_DICTIONARYFRAGMENT 25535 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBKEYPUSHTARGETDATATYPE 25536 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBKEYPUSHTARGETDATATYPE_DATATYPEVERSION 25537 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBKEYPUSHTARGETDATATYPE_DICTIONARYFRAGMENT 25538 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONFIGURATIONREFDATATYPE 25539 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONFIGURATIONREFDATATYPE_DATATYPEVERSION 25540 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONFIGURATIONREFDATATYPE_DICTIONARYFRAGMENT 25541 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONFIGURATIONVALUEDATATYPE 25542 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONFIGURATIONVALUEDATATYPE_DATATYPEVERSION 25543 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_PUBSUBCONFIGURATIONVALUEDATATYPE_DICTIONARYFRAGMENT 25544 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE_ENCODING_DEFAULTXML 25545 /* Object */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETDATATYPE_ENCODING_DEFAULTXML 25546 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATIONREFDATATYPE_ENCODING_DEFAULTXML 25547 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATIONVALUEDATATYPE_ENCODING_DEFAULTXML 25548 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE 25549 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE_DATATYPEVERSION 25550 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE_DICTIONARYFRAGMENT 25551 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBKEYPUSHTARGETDATATYPE 25552 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBKEYPUSHTARGETDATATYPE_DATATYPEVERSION 25553 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBKEYPUSHTARGETDATATYPE_DICTIONARYFRAGMENT 25554 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONFIGURATIONREFDATATYPE 25555 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONFIGURATIONREFDATATYPE_DATATYPEVERSION 25556 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONFIGURATIONREFDATATYPE_DICTIONARYFRAGMENT 25557 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONFIGURATIONVALUEDATATYPE 25558 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONFIGURATIONVALUEDATATYPE_DATATYPEVERSION 25559 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_PUBSUBCONFIGURATIONVALUEDATATYPE_DICTIONARYFRAGMENT 25560 /* Variable */ +#define UA_NS0ID_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE_ENCODING_DEFAULTJSON 25561 /* Object */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETDATATYPE_ENCODING_DEFAULTJSON 25562 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATIONREFDATATYPE_ENCODING_DEFAULTJSON 25563 /* Object */ +#define UA_NS0ID_PUBSUBCONFIGURATIONVALUEDATATYPE_ENCODING_DEFAULTJSON 25564 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN 25565 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_IDENTITIES 25566 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_APPLICATIONSEXCLUDE 25567 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_APPLICATIONS 25568 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_ENDPOINTSEXCLUDE 25569 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_ENDPOINTS 25570 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_CUSTOMCONFIGURATION 25571 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_ADDIDENTITY 25572 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_ADDIDENTITY_INPUTARGUMENTS 25573 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_REMOVEIDENTITY 25574 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_REMOVEIDENTITY_INPUTARGUMENTS 25575 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_ADDAPPLICATION 25576 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_ADDAPPLICATION_INPUTARGUMENTS 25577 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_REMOVEAPPLICATION 25578 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_REMOVEAPPLICATION_INPUTARGUMENTS 25579 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_ADDENDPOINT 25580 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_ADDENDPOINT_INPUTARGUMENTS 25581 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_REMOVEENDPOINT 25582 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERADMIN_REMOVEENDPOINT_INPUTARGUMENTS 25583 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH 25584 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_IDENTITIES 25585 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_APPLICATIONSEXCLUDE 25586 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_APPLICATIONS 25587 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_ENDPOINTSEXCLUDE 25588 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_ENDPOINTS 25589 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_CUSTOMCONFIGURATION 25590 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_ADDIDENTITY 25591 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_ADDIDENTITY_INPUTARGUMENTS 25592 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_REMOVEIDENTITY 25593 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_REMOVEIDENTITY_INPUTARGUMENTS 25594 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_ADDAPPLICATION 25595 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_ADDAPPLICATION_INPUTARGUMENTS 25596 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_REMOVEAPPLICATION 25597 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_REMOVEAPPLICATION_INPUTARGUMENTS 25598 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_ADDENDPOINT 25599 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_ADDENDPOINT_INPUTARGUMENTS 25600 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_REMOVEENDPOINT 25601 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERPUSH_REMOVEENDPOINT_INPUTARGUMENTS 25602 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS 25603 /* Object */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_IDENTITIES 25604 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_APPLICATIONSEXCLUDE 25605 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_APPLICATIONS 25606 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_ENDPOINTSEXCLUDE 25607 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_ENDPOINTS 25608 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_CUSTOMCONFIGURATION 25609 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_ADDIDENTITY 25610 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_ADDIDENTITY_INPUTARGUMENTS 25611 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_REMOVEIDENTITY 25612 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_REMOVEIDENTITY_INPUTARGUMENTS 25613 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_ADDAPPLICATION 25614 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_ADDAPPLICATION_INPUTARGUMENTS 25615 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_REMOVEAPPLICATION 25616 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_REMOVEAPPLICATION_INPUTARGUMENTS 25617 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_ADDENDPOINT 25618 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_ADDENDPOINT_INPUTARGUMENTS 25619 /* Variable */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_REMOVEENDPOINT 25620 /* Method */ +#define UA_NS0ID_WELLKNOWNROLE_SECURITYKEYSERVERACCESS_REMOVEENDPOINT_INPUTARGUMENTS 25621 /* Variable */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPNAME_PLACEHOLDER_INVALIDATEKEYS 25622 /* Method */ +#define UA_NS0ID_SECURITYGROUPFOLDERTYPE_SECURITYGROUPNAME_PLACEHOLDER_FORCEKEYROTATION 25623 /* Method */ +#define UA_NS0ID_SECURITYGROUPTYPE_INVALIDATEKEYS 25624 /* Method */ +#define UA_NS0ID_SECURITYGROUPTYPE_FORCEKEYROTATION 25625 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_SECURITYGROUPNAME_PLACEHOLDER 25626 /* Object */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_SECURITYGROUPNAME_PLACEHOLDER_SECURITYGROUPID 25627 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_SECURITYGROUPNAME_PLACEHOLDER_KEYLIFETIME 25628 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_SECURITYGROUPNAME_PLACEHOLDER_SECURITYPOLICYURI 25629 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_SECURITYGROUPNAME_PLACEHOLDER_MAXFUTUREKEYCOUNT 25630 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_SECURITYGROUPNAME_PLACEHOLDER_MAXPASTKEYCOUNT 25631 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_SECURITYGROUPNAME_PLACEHOLDER_INVALIDATEKEYS 25632 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_SECURITYGROUPNAME_PLACEHOLDER_FORCEKEYROTATION 25633 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_APPLICATIONURI 25634 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_ENDPOINTURL 25635 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_USERTOKENTYPE 25636 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_REQUESTEDKEYCOUNT 25637 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_RETRYINTERVAL 25638 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_LASTPUSHEXECUTIONTIME 25639 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_LASTPUSHERRORTIME 25640 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_CONNECTSECURITYGROUPS 25641 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_CONNECTSECURITYGROUPS_INPUTARGUMENTS 25642 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_CONNECTSECURITYGROUPS_OUTPUTARGUMENTS 25643 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_DISCONNECTSECURITYGROUPS 25644 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_DISCONNECTSECURITYGROUPS_INPUTARGUMENTS 25645 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_DISCONNECTSECURITYGROUPS_OUTPUTARGUMENTS 25646 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETTYPE_TRIGGERKEYUPDATE 25647 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_APPLICATIONURI 25648 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_ENDPOINTURL 25649 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_USERTOKENTYPE 25650 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_REQUESTEDKEYCOUNT 25651 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_RETRYINTERVAL 25652 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_LASTPUSHEXECUTIONTIME 25653 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_LASTPUSHERRORTIME 25654 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_CONNECTSECURITYGROUPS 25655 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_CONNECTSECURITYGROUPS_INPUTARGUMENTS 25656 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_CONNECTSECURITYGROUPS_OUTPUTARGUMENTS 25657 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_DISCONNECTSECURITYGROUPS 25658 /* Method */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_DISCONNECTSECURITYGROUPS_INPUTARGUMENTS 25659 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_DISCONNECTSECURITYGROUPS_OUTPUTARGUMENTS 25660 /* Variable */ +#define UA_NS0ID_PUBSUBKEYPUSHTARGETFOLDERTYPE_PUSHTARGETNAME_PLACEHOLDER_TRIGGERKEYUPDATE 25661 /* Method */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_OUTPUTARGUMENTS 25684 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_APPLICATIONURI 25696 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_APPLICATIONTYPE 25697 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CANCELCHANGES 25698 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_RESETTOSERVERDEFAULTS 25699 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_APPLICATIONURI 25706 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_APPLICATIONTYPE 25707 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CANCELCHANGES 25708 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_RESETTOSERVERDEFAULTS 25709 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_SETADMINPASSWORD 25710 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_PRODUCTURI 25724 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_PRODUCTURI 25725 /* Variable */ +#define UA_NS0ID_ENCODEDTICKET 25726 /* DataType */ +#define UA_NS0ID_REQUESTTICKETSMETHODTYPE 25727 /* Method */ +#define UA_NS0ID_REQUESTTICKETSMETHODTYPE_OUTPUTARGUMENTS 25728 /* Variable */ +#define UA_NS0ID_SETREGISTRARENDPOINTSMETHODTYPE 25729 /* Method */ +#define UA_NS0ID_SETREGISTRARENDPOINTSMETHODTYPE_INPUTARGUMENTS 25730 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE 25731 /* ObjectType */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS 25732 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP 25733 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST 25734 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SIZE 25735 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITABLE 25736 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_USERWRITABLE 25737 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENCOUNT 25738 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_MIMETYPE 25739 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 25740 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_LASTMODIFIEDTIME 25741 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN 25742 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 25743 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 25744 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSE 25745 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 25746 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ 25747 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ_INPUTARGUMENTS 25748 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 25749 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITE 25750 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 25751 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION 25752 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 25753 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 25754 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SETPOSITION 25755 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 25756 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_LASTUPDATETIME 25757 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_UPDATEFREQUENCY 25758 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 25759 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS 25760 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 25761 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 25762 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE 25763 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 25764 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 25765 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ADDCERTIFICATE 25766 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 25767 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_REMOVECERTIFICATE 25768 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 25769 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATETYPES 25770 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_GETREJECTEDLIST 25772 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 25773 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED 25774 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EVENTID 25775 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EVENTTYPE 25776 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SOURCENODE 25777 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SOURCENAME 25778 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_TIME 25779 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RECEIVETIME 25780 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LOCALTIME 25781 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_MESSAGE 25782 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SEVERITY 25783 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 25784 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 25785 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 25786 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 25787 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 25788 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_BRANCHID 25789 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RETAIN 25790 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 25791 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 25792 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 25793 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 25794 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 25795 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 25796 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 25797 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 25798 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 25799 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_QUALITY 25800 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 25801 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 25802 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 25803 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_COMMENT 25804 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 25805 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 25806 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_DISABLE 25807 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLE 25808 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 25809 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 25810 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 25811 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 25812 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 25813 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 25814 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 25815 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 25816 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 25817 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 25818 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 25819 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 25820 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 25821 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 25822 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 25823 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 25824 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 25825 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 25826 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 25827 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 25828 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 25829 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 25830 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRM 25831 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 25832 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 25833 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 25834 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 25835 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 25836 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 25837 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 25838 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 25839 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 25840 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 25841 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_INPUTNODE 25842 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 25843 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 25844 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 25845 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 25846 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 25847 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 25848 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 25849 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 25850 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 25851 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 25852 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 25853 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 25854 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 25855 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 25856 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 25857 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 25858 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 25859 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 25860 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 25861 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 25862 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 25863 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 25864 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 25865 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 25866 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 25867 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 25868 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 25869 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 25870 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 25871 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 25872 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 25873 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 25874 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 25875 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 25876 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 25877 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 25878 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 25879 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 25880 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 25881 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 25882 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 25883 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 25884 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 25885 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 25886 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 25887 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 25888 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 25889 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 25890 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 25891 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 25892 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE 25893 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 25894 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 25895 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 25896 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 25897 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 25898 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 25899 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 25900 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 25901 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ONDELAY 25902 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OFFDELAY 25903 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 25904 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 25905 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 25906 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 25907 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 25908 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 25909 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 25910 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 25911 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 25912 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 25913 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 25914 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REALARMTIME 25915 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 25916 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCE 25917 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS 25918 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS2 25919 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 25920 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 25921 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 25922 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 25923 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 25924 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 25925 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 25926 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 25927 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 25928 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 25929 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET 25930 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET2 25931 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 25932 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 25933 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 25934 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_NORMALSTATE 25935 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 25936 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 25937 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 25938 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CERTIFICATE 25939 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE 25940 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_EVENTID 25941 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 25942 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 25943 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 25944 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_TIME 25945 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 25946 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 25947 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_MESSAGE 25948 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SEVERITY 25949 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 25950 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 25951 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 25952 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 25953 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 25954 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_BRANCHID 25955 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RETAIN 25956 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 25957 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 25958 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 25959 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 25960 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 25961 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 25962 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 25963 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 25964 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 25965 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_QUALITY 25966 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 25967 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 25968 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 25969 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_COMMENT 25970 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 25971 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 25972 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_DISABLE 25973 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLE 25974 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 25975 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 25976 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 25977 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 25978 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 25979 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 25980 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 25981 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 25982 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 25983 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 25984 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 25985 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 25986 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 25987 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 25988 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 25989 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 25990 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 25991 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 25992 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 25993 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 25994 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 25995 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 25996 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRM 25997 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 25998 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 25999 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 26000 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 26001 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 26002 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 26003 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 26004 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 26005 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 26006 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 26007 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 26008 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 26009 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 26010 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 26011 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 26012 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 26013 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 26014 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 26015 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 26016 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 26017 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 26018 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 26019 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 26020 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 26021 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 26022 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 26023 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 26024 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 26025 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 26026 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 26027 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 26028 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 26029 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 26030 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 26031 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 26032 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 26033 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 26034 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 26035 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 26036 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 26037 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 26038 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 26039 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 26040 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 26041 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 26042 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 26043 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 26044 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 26045 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 26046 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 26047 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 26048 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 26049 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 26050 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 26051 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 26052 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 26053 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 26054 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 26055 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 26056 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 26057 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 26058 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 26059 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 26060 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 26061 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 26062 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 26063 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 26064 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 26065 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 26066 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 26067 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ONDELAY 26068 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 26069 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 26070 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 26071 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 26072 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 26073 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 26074 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 26075 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 26076 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 26077 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 26078 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 26079 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 26080 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 26081 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 26082 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCE 26083 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 26084 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 26085 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 26086 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 26087 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 26088 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 26089 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 26090 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 26091 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 26092 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 26093 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 26094 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 26095 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET 26096 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET2 26097 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 26098 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 26099 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 26100 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 26101 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 26102 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 26103 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 26104 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP 26105 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST 26106 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SIZE 26107 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITABLE 26108 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_USERWRITABLE 26109 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENCOUNT 26110 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_MIMETYPE 26111 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 26112 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_LASTMODIFIEDTIME 26113 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN 26114 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 26115 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 26116 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSE 26117 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 26118 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ 26119 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ_INPUTARGUMENTS 26120 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 26121 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITE 26122 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 26123 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION 26124 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 26125 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 26126 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SETPOSITION 26127 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 26128 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_LASTUPDATETIME 26129 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_UPDATEFREQUENCY 26130 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 26131 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS 26132 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 26133 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 26134 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE 26135 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 26136 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 26137 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ADDCERTIFICATE 26138 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 26139 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_REMOVECERTIFICATE 26140 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 26141 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATETYPES 26142 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_GETREJECTEDLIST 26144 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 26145 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED 26146 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EVENTID 26147 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EVENTTYPE 26148 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SOURCENODE 26149 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SOURCENAME 26150 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_TIME 26151 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RECEIVETIME 26152 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LOCALTIME 26153 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_MESSAGE 26154 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SEVERITY 26155 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 26156 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 26157 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 26158 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 26159 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 26160 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_BRANCHID 26161 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RETAIN 26162 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 26163 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 26164 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 26165 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 26166 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 26167 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 26168 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 26169 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 26170 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 26171 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_QUALITY 26172 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 26173 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 26174 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 26175 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_COMMENT 26176 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 26177 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 26178 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_DISABLE 26179 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLE 26180 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 26181 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 26182 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 26183 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 26184 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 26185 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 26186 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 26187 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 26188 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 26189 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 26190 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 26191 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 26192 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 26193 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 26194 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 26195 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 26196 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 26197 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 26198 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 26199 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 26200 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 26201 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 26202 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRM 26203 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 26204 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 26205 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 26206 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 26207 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 26208 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 26209 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 26210 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 26211 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 26212 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 26213 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_INPUTNODE 26214 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 26215 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 26216 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 26217 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 26218 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 26219 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 26220 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 26221 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 26222 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 26223 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 26224 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 26225 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 26226 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 26227 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 26228 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 26229 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 26230 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 26231 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 26232 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 26233 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 26234 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 26235 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 26236 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 26237 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 26238 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 26239 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 26240 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 26241 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 26242 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 26243 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 26244 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 26245 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 26246 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 26247 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 26248 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 26249 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 26250 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 26251 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 26252 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 26253 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 26254 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 26255 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 26256 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 26257 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 26258 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 26259 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 26260 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 26261 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 26262 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 26263 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 26264 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE 26265 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 26266 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 26267 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 26268 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 26269 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 26270 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 26271 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 26272 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 26273 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ONDELAY 26274 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OFFDELAY 26275 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 26276 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 26277 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 26278 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 26279 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 26280 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 26281 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 26282 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 26283 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 26284 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 26285 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 26286 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REALARMTIME 26287 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 26288 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCE 26289 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS 26290 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS2 26291 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 26292 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 26293 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 26294 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 26295 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 26296 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 26297 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 26298 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 26299 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 26300 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 26301 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET 26302 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET2 26303 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 26304 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 26305 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 26306 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_NORMALSTATE 26307 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 26308 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 26309 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 26310 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CERTIFICATE 26311 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE 26312 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_EVENTID 26313 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 26314 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 26315 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 26316 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_TIME 26317 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 26318 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 26319 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_MESSAGE 26320 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SEVERITY 26321 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 26322 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 26323 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 26324 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 26325 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 26326 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_BRANCHID 26327 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RETAIN 26328 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 26329 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 26330 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 26331 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 26332 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 26333 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 26334 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 26335 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 26336 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 26337 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_QUALITY 26338 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 26339 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 26340 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 26341 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_COMMENT 26342 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 26343 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 26344 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_DISABLE 26345 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLE 26346 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 26347 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 26348 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 26349 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 26350 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 26351 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 26352 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 26353 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 26354 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 26355 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 26356 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 26357 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 26358 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 26359 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 26360 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 26361 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 26362 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 26363 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 26364 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 26365 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 26366 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 26367 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 26368 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRM 26369 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 26370 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 26371 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 26372 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 26373 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 26374 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 26375 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 26376 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 26377 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 26378 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 26379 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 26380 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 26381 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 26382 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 26383 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 26384 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 26385 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 26386 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 26387 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 26388 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 26389 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 26390 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 26391 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 26392 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 26393 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 26394 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 26395 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 26396 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 26397 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 26398 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 26399 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 26400 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 26401 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 26402 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 26403 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 26404 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 26405 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 26406 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 26407 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 26408 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 26409 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 26410 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 26411 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 26412 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 26413 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 26414 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 26415 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 26416 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 26417 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 26418 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 26419 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 26420 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 26421 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 26422 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 26423 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 26424 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 26425 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 26426 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 26427 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 26428 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 26429 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 26430 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 26431 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 26432 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 26433 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 26434 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 26435 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 26436 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 26437 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 26438 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 26439 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ONDELAY 26440 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 26441 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 26442 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 26443 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 26444 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 26445 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 26446 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 26447 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 26448 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 26449 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 26450 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 26451 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 26452 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 26453 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 26454 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCE 26455 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 26456 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 26457 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 26458 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 26459 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 26460 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 26461 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 26462 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 26463 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 26464 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 26465 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 26466 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 26467 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET 26468 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET2 26469 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 26470 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 26471 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 26472 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 26473 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 26474 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 26475 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 26476 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP 26477 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST 26478 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SIZE 26479 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITABLE 26480 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_USERWRITABLE 26481 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENCOUNT 26482 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_MIMETYPE 26483 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 26484 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_LASTMODIFIEDTIME 26485 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN 26486 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 26487 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 26488 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSE 26489 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 26490 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ 26491 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ_INPUTARGUMENTS 26492 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 26493 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITE 26494 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 26495 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION 26496 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 26497 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 26498 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SETPOSITION 26499 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 26500 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_LASTUPDATETIME 26501 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_UPDATEFREQUENCY 26502 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 26503 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS 26504 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 26505 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 26506 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE 26507 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 26508 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 26509 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ADDCERTIFICATE 26510 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 26511 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_REMOVECERTIFICATE 26512 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 26513 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATETYPES 26514 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_GETREJECTEDLIST 26516 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 26517 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED 26518 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EVENTID 26519 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EVENTTYPE 26520 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SOURCENODE 26521 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SOURCENAME 26522 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_TIME 26523 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RECEIVETIME 26524 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LOCALTIME 26525 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_MESSAGE 26526 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SEVERITY 26527 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 26528 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 26529 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 26530 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 26531 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 26532 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_BRANCHID 26533 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RETAIN 26534 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 26535 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 26536 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 26537 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 26538 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 26539 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 26540 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 26541 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 26542 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 26543 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_QUALITY 26544 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 26545 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 26546 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 26547 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_COMMENT 26548 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 26549 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 26550 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_DISABLE 26551 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLE 26552 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 26553 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 26554 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 26555 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 26556 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 26557 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 26558 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 26559 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 26560 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 26561 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 26562 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 26563 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 26564 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 26565 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 26566 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 26567 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 26568 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 26569 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 26570 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 26571 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 26572 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 26573 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 26574 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRM 26575 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 26576 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 26577 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 26578 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 26579 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 26580 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 26581 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 26582 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 26583 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 26584 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 26585 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_INPUTNODE 26586 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 26587 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 26588 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 26589 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 26590 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 26591 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 26592 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 26593 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 26594 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 26595 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 26596 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 26597 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 26598 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 26599 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 26600 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 26601 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 26602 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 26603 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 26604 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 26605 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 26606 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 26607 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 26608 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 26609 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 26610 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 26611 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 26612 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 26613 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 26614 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 26615 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 26616 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 26617 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 26618 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 26619 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 26620 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 26621 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 26622 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 26623 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 26624 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 26625 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 26626 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 26627 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 26628 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 26629 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 26630 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 26631 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 26632 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 26633 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 26634 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 26635 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 26636 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE 26637 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 26638 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 26639 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 26640 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 26641 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 26642 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 26643 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 26644 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 26645 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ONDELAY 26646 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OFFDELAY 26647 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 26648 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 26649 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 26650 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 26651 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 26652 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 26653 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 26654 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 26655 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 26656 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 26657 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 26658 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REALARMTIME 26659 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 26660 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCE 26661 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS 26662 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS2 26663 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 26664 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 26665 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 26666 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 26667 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 26668 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 26669 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 26670 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 26671 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 26672 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 26673 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET 26674 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET2 26675 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 26676 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 26677 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 26678 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_NORMALSTATE 26679 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 26680 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 26681 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 26682 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CERTIFICATE 26683 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE 26684 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_EVENTID 26685 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 26686 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 26687 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 26688 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_TIME 26689 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 26690 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 26691 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_MESSAGE 26692 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SEVERITY 26693 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 26694 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 26695 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 26696 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 26697 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 26698 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_BRANCHID 26699 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RETAIN 26700 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 26701 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 26702 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 26703 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 26704 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 26705 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 26706 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 26707 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 26708 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 26709 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_QUALITY 26710 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 26711 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 26712 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 26713 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_COMMENT 26714 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 26715 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 26716 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_DISABLE 26717 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLE 26718 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 26719 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 26720 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 26721 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 26722 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 26723 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 26724 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 26725 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 26726 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 26727 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 26728 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 26729 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 26730 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 26731 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 26732 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 26733 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 26734 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 26735 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 26736 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 26737 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 26738 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 26739 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 26740 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRM 26741 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 26742 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 26743 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 26744 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 26745 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 26746 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 26747 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 26748 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 26749 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 26750 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 26751 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 26752 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 26753 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 26754 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 26755 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 26756 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 26757 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 26758 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 26759 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 26760 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 26761 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 26762 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 26763 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 26764 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 26765 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 26766 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 26767 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 26768 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 26769 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 26770 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 26771 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 26772 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 26773 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 26774 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 26775 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 26776 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 26777 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 26778 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 26779 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 26780 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 26781 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 26782 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 26783 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 26784 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 26785 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 26786 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 26787 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 26788 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 26789 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 26790 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 26791 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 26792 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 26793 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 26794 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 26795 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 26796 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 26797 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 26798 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 26799 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 26800 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 26801 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 26802 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 26803 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 26804 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 26805 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 26806 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 26807 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 26808 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 26809 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 26810 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 26811 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ONDELAY 26812 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 26813 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 26814 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 26815 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 26816 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 26817 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 26818 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 26819 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 26820 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 26821 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 26822 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 26823 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 26824 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 26825 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 26826 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCE 26827 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 26828 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 26829 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 26830 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 26831 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 26832 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 26833 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 26834 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 26835 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 26836 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 26837 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 26838 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 26839 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET 26840 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET2 26841 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 26842 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 26843 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 26844 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 26845 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 26846 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 26847 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 26848 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_ENABLED 26849 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_APPLICATIONURI 26850 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_PRODUCTURI 26851 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_APPLICATIONTYPE 26852 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_SERVERCAPABILITIES 26853 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_SUPPORTEDPRIVATEKEYFORMATS 26854 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_MAXTRUSTLISTSIZE 26855 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_MULTICASTDNSENABLED 26856 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_HASSECUREELEMENT 26857 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_UPDATECERTIFICATE 26858 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_UPDATECERTIFICATE_INPUTARGUMENTS 26859 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_UPDATECERTIFICATE_OUTPUTARGUMENTS 26860 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_APPLYCHANGES 26861 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CANCELCHANGES 26862 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CREATESIGNINGREQUEST 26863 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CREATESIGNINGREQUEST_INPUTARGUMENTS 26864 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CREATESIGNINGREQUEST_OUTPUTARGUMENTS 26865 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_GETREJECTEDLIST 26866 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_GETREJECTEDLIST_OUTPUTARGUMENTS 26867 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_RESETTOSERVERDEFAULTS 26868 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE 26871 /* ObjectType */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_ISSINGLETON 26872 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_REQUESTTICKETS 26873 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_REQUESTTICKETS_OUTPUTARGUMENTS 26874 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_SETREGISTRARENDPOINTS 26875 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_SETREGISTRARENDPOINTS_INPUTARGUMENTS 26876 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER 26878 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS 26879 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP 26880 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST 26881 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SIZE 26882 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITABLE 26883 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_USERWRITABLE 26884 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENCOUNT 26885 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_MIMETYPE 26886 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 26887 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_LASTMODIFIEDTIME 26888 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN 26889 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 26890 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 26891 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSE 26892 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 26893 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ 26894 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ_INPUTARGUMENTS 26895 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 26896 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITE 26897 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 26898 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION 26899 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 26900 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 26901 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SETPOSITION 26902 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 26903 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_LASTUPDATETIME 26904 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_UPDATEFREQUENCY 26905 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 26906 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS 26907 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 26908 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 26909 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE 26910 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 26911 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 26912 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ADDCERTIFICATE 26913 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 26914 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_REMOVECERTIFICATE 26915 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 26916 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATETYPES 26917 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_GETREJECTEDLIST 26919 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 26920 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED 26921 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EVENTID 26922 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EVENTTYPE 26923 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SOURCENODE 26924 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SOURCENAME 26925 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_TIME 26926 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RECEIVETIME 26927 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LOCALTIME 26928 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_MESSAGE 26929 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SEVERITY 26930 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 26931 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 26932 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 26933 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 26934 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 26935 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_BRANCHID 26936 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RETAIN 26937 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 26938 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 26939 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 26940 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 26941 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 26942 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 26943 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 26944 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 26945 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 26946 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_QUALITY 26947 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 26948 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 26949 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 26950 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_COMMENT 26951 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 26952 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 26953 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_DISABLE 26954 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLE 26955 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 26956 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 26957 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 26958 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 26959 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 26960 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 26961 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 26962 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 26963 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 26964 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 26965 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 26966 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 26967 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 26968 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 26969 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 26970 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 26971 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 26972 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 26973 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 26974 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 26975 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 26976 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 26977 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRM 26978 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 26979 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 26980 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 26981 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 26982 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 26983 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 26984 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 26985 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 26986 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 26987 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 26988 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_INPUTNODE 26989 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 26990 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 26991 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 26992 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 26993 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 26994 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 26995 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 26996 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 26997 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 26998 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 26999 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 27000 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 27001 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 27002 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 27003 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 27004 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 27005 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 27006 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 27007 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 27008 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 27009 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 27010 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 27011 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 27012 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 27013 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 27014 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 27015 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 27016 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 27017 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 27018 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 27019 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 27020 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 27021 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 27022 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 27023 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 27024 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 27025 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 27026 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 27027 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 27028 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 27029 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 27030 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 27031 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 27032 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 27033 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 27034 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 27035 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 27036 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 27037 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 27038 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 27039 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE 27040 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 27041 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 27042 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 27043 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 27044 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 27045 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 27046 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 27047 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 27048 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ONDELAY 27049 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OFFDELAY 27050 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 27051 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 27052 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 27053 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 27054 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 27055 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 27056 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 27057 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 27058 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 27059 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 27060 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 27061 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REALARMTIME 27062 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 27063 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCE 27064 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS 27065 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS2 27066 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 27067 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 27068 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 27069 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 27070 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 27071 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 27072 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 27073 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 27074 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 27075 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 27076 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET 27077 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET2 27078 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 27079 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 27080 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 27081 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_NORMALSTATE 27082 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 27083 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 27084 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 27085 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CERTIFICATE 27086 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE 27087 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_EVENTID 27088 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 27089 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 27090 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 27091 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_TIME 27092 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 27093 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 27094 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_MESSAGE 27095 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SEVERITY 27096 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 27097 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 27098 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 27099 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 27100 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 27101 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_BRANCHID 27102 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RETAIN 27103 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 27104 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 27105 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 27106 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 27107 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 27108 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 27109 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 27110 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 27111 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 27112 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_QUALITY 27113 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 27114 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 27115 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 27116 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_COMMENT 27117 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 27118 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 27119 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_DISABLE 27120 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLE 27121 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 27122 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 27123 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 27124 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 27125 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 27126 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 27127 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 27128 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 27129 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 27130 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 27131 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 27132 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 27133 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 27134 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 27135 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 27136 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 27137 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 27138 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 27139 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 27140 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 27141 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 27142 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 27143 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRM 27144 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 27145 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 27146 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 27147 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 27148 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 27149 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 27150 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 27151 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 27152 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 27153 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 27154 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 27155 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 27156 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 27157 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 27158 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 27159 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 27160 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 27161 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 27162 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 27163 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 27164 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 27165 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 27166 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 27167 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 27168 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 27169 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 27170 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 27171 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 27172 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 27173 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 27174 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 27175 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 27176 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 27177 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 27178 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 27179 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 27180 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 27181 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 27182 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 27183 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 27184 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 27185 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 27186 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 27187 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 27188 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 27189 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 27190 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 27191 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 27192 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 27193 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 27194 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 27195 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 27196 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 27197 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 27198 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 27199 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 27200 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 27201 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 27202 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 27203 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 27204 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 27205 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 27206 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 27207 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 27208 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 27209 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 27210 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 27211 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 27212 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 27213 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 27214 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ONDELAY 27215 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 27216 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 27217 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 27218 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 27219 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 27220 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 27221 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 27222 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 27223 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 27224 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 27225 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 27226 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 27227 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 27228 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 27229 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCE 27230 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 27231 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 27232 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 27233 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 27234 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 27235 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 27236 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 27237 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 27238 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 27239 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 27240 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 27241 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 27242 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET 27243 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET2 27244 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 27245 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 27246 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 27247 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 27248 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 27249 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 27250 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 27251 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP 27252 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST 27253 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SIZE 27254 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITABLE 27255 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_USERWRITABLE 27256 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENCOUNT 27257 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_MIMETYPE 27258 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 27259 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_LASTMODIFIEDTIME 27260 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN 27261 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 27262 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 27263 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSE 27264 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 27265 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ 27266 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ_INPUTARGUMENTS 27267 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 27268 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITE 27269 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 27270 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION 27271 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 27272 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 27273 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SETPOSITION 27274 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 27275 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_LASTUPDATETIME 27276 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_UPDATEFREQUENCY 27277 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 27278 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS 27279 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 27280 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 27281 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE 27282 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 27283 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 27284 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ADDCERTIFICATE 27285 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 27286 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_REMOVECERTIFICATE 27287 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 27288 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATETYPES 27289 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_GETREJECTEDLIST 27291 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 27292 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED 27293 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EVENTID 27294 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EVENTTYPE 27295 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SOURCENODE 27296 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SOURCENAME 27297 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_TIME 27298 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RECEIVETIME 27299 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LOCALTIME 27300 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_MESSAGE 27301 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SEVERITY 27302 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 27303 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 27304 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 27305 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 27306 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 27307 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_BRANCHID 27308 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RETAIN 27309 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 27310 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 27311 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 27312 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 27313 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 27314 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 27315 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 27316 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 27317 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 27318 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_QUALITY 27319 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 27320 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 27321 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 27322 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_COMMENT 27323 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 27324 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 27325 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_DISABLE 27326 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLE 27327 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 27328 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 27329 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 27330 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 27331 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 27332 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 27333 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 27334 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 27335 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 27336 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 27337 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 27338 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 27339 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 27340 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 27341 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 27342 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 27343 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 27344 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 27345 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 27346 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 27347 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 27348 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 27349 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRM 27350 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 27351 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 27352 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 27353 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 27354 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 27355 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 27356 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 27357 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 27358 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 27359 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 27360 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_INPUTNODE 27361 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 27362 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 27363 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 27364 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 27365 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 27366 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 27367 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 27368 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 27369 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 27370 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 27371 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 27372 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 27373 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 27374 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 27375 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 27376 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 27377 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 27378 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 27379 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 27380 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 27381 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 27382 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 27383 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 27384 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 27385 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 27386 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 27387 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 27388 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 27389 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 27390 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 27391 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 27392 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 27393 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 27394 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 27395 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 27396 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 27397 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 27398 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 27399 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 27400 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 27401 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 27402 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 27403 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 27404 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 27405 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 27406 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 27407 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 27408 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 27409 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 27410 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 27411 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE 27412 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 27413 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 27414 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 27415 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 27416 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 27417 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 27418 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 27419 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 27420 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ONDELAY 27421 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OFFDELAY 27422 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 27423 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 27424 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 27425 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 27426 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 27427 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 27428 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 27429 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 27430 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 27431 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 27432 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 27433 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REALARMTIME 27434 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 27435 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCE 27436 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS 27437 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS2 27438 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 27439 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 27440 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 27441 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 27442 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 27443 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 27444 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 27445 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 27446 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 27447 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 27448 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET 27449 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET2 27450 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 27451 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 27452 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 27453 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_NORMALSTATE 27454 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 27455 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 27456 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 27457 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CERTIFICATE 27458 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE 27459 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_EVENTID 27460 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 27461 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 27462 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 27463 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_TIME 27464 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 27465 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 27466 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_MESSAGE 27467 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SEVERITY 27468 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 27469 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 27470 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 27471 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 27472 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 27473 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_BRANCHID 27474 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RETAIN 27475 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 27476 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 27477 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 27478 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 27479 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 27480 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 27481 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 27482 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 27483 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 27484 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_QUALITY 27485 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 27486 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 27487 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 27488 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_COMMENT 27489 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 27490 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 27491 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_DISABLE 27492 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLE 27493 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 27494 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 27495 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 27496 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 27497 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 27498 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 27499 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 27500 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 27501 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 27502 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 27503 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 27504 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 27505 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 27506 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 27507 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 27508 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 27509 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 27510 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 27511 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 27512 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 27513 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 27514 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 27515 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRM 27516 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 27517 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 27518 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 27519 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 27520 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 27521 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 27522 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 27523 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 27524 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 27525 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 27526 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 27527 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 27528 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 27529 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 27530 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 27531 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 27532 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 27533 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 27534 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 27535 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 27536 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 27537 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 27538 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 27539 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 27540 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 27541 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 27542 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 27543 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 27544 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 27545 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 27546 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 27547 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 27548 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 27549 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 27550 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 27551 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 27552 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 27553 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 27554 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 27555 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 27556 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 27557 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 27558 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 27559 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 27560 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 27561 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 27562 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 27563 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 27564 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 27565 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 27566 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 27567 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 27568 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 27569 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 27570 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 27571 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 27572 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 27573 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 27574 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 27575 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 27576 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 27577 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 27578 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 27579 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 27580 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 27581 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 27582 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 27583 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 27584 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 27585 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 27586 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ONDELAY 27587 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 27588 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 27589 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 27590 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 27591 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 27592 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 27593 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 27594 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 27595 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 27596 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 27597 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 27598 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 27599 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 27600 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 27601 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCE 27602 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 27603 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 27604 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 27605 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 27606 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 27607 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 27608 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 27609 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 27610 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 27611 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 27612 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 27613 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 27614 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET 27615 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET2 27616 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 27617 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 27618 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 27619 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 27620 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 27621 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 27622 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 27623 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP 27624 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST 27625 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SIZE 27626 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITABLE 27627 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_USERWRITABLE 27628 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENCOUNT 27629 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_MIMETYPE 27630 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 27631 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_LASTMODIFIEDTIME 27632 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN 27633 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 27634 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 27635 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSE 27636 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 27637 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ 27638 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ_INPUTARGUMENTS 27639 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 27640 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITE 27641 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 27642 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION 27643 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 27644 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 27645 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SETPOSITION 27646 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 27647 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_LASTUPDATETIME 27648 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_UPDATEFREQUENCY 27649 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 27650 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS 27651 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 27652 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 27653 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE 27654 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 27655 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 27656 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ADDCERTIFICATE 27657 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 27658 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_REMOVECERTIFICATE 27659 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 27660 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATETYPES 27661 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_GETREJECTEDLIST 27663 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 27664 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED 27665 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EVENTID 27666 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EVENTTYPE 27667 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SOURCENODE 27668 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SOURCENAME 27669 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_TIME 27670 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RECEIVETIME 27671 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LOCALTIME 27672 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_MESSAGE 27673 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SEVERITY 27674 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 27675 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 27676 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 27677 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 27678 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 27679 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_BRANCHID 27680 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RETAIN 27681 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 27682 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 27683 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 27684 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 27685 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 27686 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 27687 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 27688 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 27689 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 27690 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_QUALITY 27691 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 27692 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 27693 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 27694 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_COMMENT 27695 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 27696 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 27697 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_DISABLE 27698 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLE 27699 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 27700 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 27701 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 27702 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 27703 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 27704 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 27705 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 27706 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 27707 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 27708 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 27709 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 27710 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 27711 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 27712 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 27713 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 27714 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 27715 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 27716 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 27717 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 27718 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 27719 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 27720 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 27721 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRM 27722 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 27723 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 27724 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 27725 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 27726 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 27727 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 27728 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 27729 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 27730 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 27731 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 27732 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_INPUTNODE 27733 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 27734 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 27735 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 27736 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 27737 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 27738 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 27739 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 27740 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 27741 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 27742 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 27743 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 27744 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 27745 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 27746 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 27747 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 27748 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 27749 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 27750 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 27751 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 27752 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 27753 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 27754 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 27755 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 27756 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 27757 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 27758 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 27759 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 27760 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 27761 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 27762 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 27763 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 27764 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 27765 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 27766 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 27767 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 27768 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 27769 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 27770 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 27771 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 27772 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 27773 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 27774 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 27775 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 27776 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 27777 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 27778 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 27779 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 27780 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 27781 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 27782 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 27783 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE 27784 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 27785 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 27786 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 27787 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 27788 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 27789 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 27790 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 27791 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 27792 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ONDELAY 27793 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OFFDELAY 27794 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 27795 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 27796 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 27797 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 27798 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 27799 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 27800 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 27801 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 27802 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 27803 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 27804 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 27805 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REALARMTIME 27806 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 27807 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCE 27808 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS 27809 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS2 27810 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 27811 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 27812 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 27813 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 27814 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 27815 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 27816 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 27817 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 27818 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 27819 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 27820 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET 27821 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET2 27822 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 27823 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 27824 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 27825 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_NORMALSTATE 27826 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 27827 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 27828 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 27829 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CERTIFICATE 27830 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE 27831 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_EVENTID 27832 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 27833 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 27834 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 27835 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_TIME 27836 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 27837 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 27838 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_MESSAGE 27839 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SEVERITY 27840 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 27841 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 27842 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 27843 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 27844 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 27845 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_BRANCHID 27846 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RETAIN 27847 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 27848 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 27849 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 27850 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 27851 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 27852 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 27853 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 27854 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 27855 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 27856 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_QUALITY 27857 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 27858 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 27859 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 27860 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_COMMENT 27861 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 27862 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 27863 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_DISABLE 27864 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLE 27865 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 27866 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 27867 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 27868 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 27869 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 27870 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 27871 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 27872 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 27873 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 27874 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 27875 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 27876 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 27877 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 27878 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 27879 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 27880 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 27881 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 27882 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 27883 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 27884 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 27885 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 27886 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 27887 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRM 27888 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 27889 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 27890 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 27891 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 27892 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 27893 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 27894 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 27895 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 27896 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 27897 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 27898 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 27899 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 27900 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 27901 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 27902 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 27903 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 27904 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 27905 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 27906 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 27907 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 27908 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 27909 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 27910 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 27911 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 27912 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 27913 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 27914 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 27915 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 27916 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 27917 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 27918 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 27919 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 27920 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 27921 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 27922 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 27923 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 27924 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 27925 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 27926 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 27927 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 27928 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 27929 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 27930 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 27931 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 27932 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 27933 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 27934 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 27935 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 27936 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 27937 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 27938 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 27939 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 27940 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 27941 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 27942 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 27943 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 27944 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 27945 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 27946 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 27947 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 27948 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 27949 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 27950 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 27951 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 27952 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 27953 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 27954 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 27955 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 27956 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 27957 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 27958 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ONDELAY 27959 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 27960 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 27961 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 27962 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 27963 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 27964 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 27965 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 27966 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 27967 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 27968 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 27969 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 27970 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 27971 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 27972 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 27973 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCE 27974 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 27975 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 27976 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 27977 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 27978 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 27979 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 27980 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 27981 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 27982 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 27983 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 27984 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 27985 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 27986 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET 27987 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET2 27988 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 27989 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 27990 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 27991 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 27992 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 27993 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 27994 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 27995 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_ENABLED 27996 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_APPLICATIONURI 27997 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_PRODUCTURI 27998 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_APPLICATIONTYPE 27999 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_SERVERCAPABILITIES 28000 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_SUPPORTEDPRIVATEKEYFORMATS 28001 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_MAXTRUSTLISTSIZE 28002 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_MULTICASTDNSENABLED 28003 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_HASSECUREELEMENT 28004 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_UPDATECERTIFICATE 28005 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_UPDATECERTIFICATE_INPUTARGUMENTS 28006 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_UPDATECERTIFICATE_OUTPUTARGUMENTS 28007 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_APPLYCHANGES 28008 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CANCELCHANGES 28009 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CREATESIGNINGREQUEST 28010 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CREATESIGNINGREQUEST_INPUTARGUMENTS 28011 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CREATESIGNINGREQUEST_OUTPUTARGUMENTS 28012 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_GETREJECTEDLIST 28013 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_GETREJECTEDLIST_OUTPUTARGUMENTS 28014 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_RESETTOSERVERDEFAULTS 28015 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE 29878 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_ISSINGLETON 29879 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_REQUESTTICKETS 29880 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_REQUESTTICKETS_OUTPUTARGUMENTS 29881 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_SETREGISTRARENDPOINTS 29882 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_SETREGISTRARENDPOINTS_INPUTARGUMENTS 29883 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER 29885 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS 29886 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP 29887 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST 29888 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SIZE 29889 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITABLE 29890 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_USERWRITABLE 29891 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENCOUNT 29892 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_MIMETYPE 29893 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 29894 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_LASTMODIFIEDTIME 29895 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN 29896 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 29897 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 29898 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSE 29899 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 29900 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ 29901 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ_INPUTARGUMENTS 29902 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 29903 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITE 29904 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 29905 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION 29906 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 29907 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 29908 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SETPOSITION 29909 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 29910 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_LASTUPDATETIME 29911 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_UPDATEFREQUENCY 29912 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 29913 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS 29914 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 29915 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 29916 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE 29917 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 29918 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 29919 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ADDCERTIFICATE 29920 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 29921 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_REMOVECERTIFICATE 29922 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 29923 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATETYPES 29924 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_GETREJECTEDLIST 29926 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 29927 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED 29928 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EVENTID 29929 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EVENTTYPE 29930 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SOURCENODE 29931 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SOURCENAME 29932 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_TIME 29933 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RECEIVETIME 29934 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LOCALTIME 29935 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_MESSAGE 29936 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SEVERITY 29937 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 29938 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 29939 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 29940 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 29941 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 29942 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_BRANCHID 29943 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RETAIN 29944 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 29945 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 29946 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 29947 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 29948 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 29949 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 29950 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 29951 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 29952 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 29953 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_QUALITY 29954 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 29955 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 29956 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 29957 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_COMMENT 29958 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 29959 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 29960 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_DISABLE 29961 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ENABLE 29962 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 29963 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 29964 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 29965 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 29966 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 29967 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 29968 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 29969 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 29970 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 29971 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 29972 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 29973 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 29974 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 29975 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 29976 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 29977 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 29978 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 29979 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 29980 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 29981 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 29982 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 29983 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 29984 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRM 29985 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 29986 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 29987 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 29988 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 29989 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 29990 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 29991 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 29992 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 29993 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 29994 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 29995 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_INPUTNODE 29996 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 29997 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 29998 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 29999 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 30000 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 30001 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 30002 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 30003 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 30004 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 30005 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 30006 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 30007 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 30008 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 30009 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 30010 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 30011 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 30012 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 30013 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 30014 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 30015 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 30016 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 30017 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 30018 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 30019 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 30020 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 30021 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 30022 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 30023 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 30024 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 30025 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 30026 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 30027 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 30028 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 30029 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 30030 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 30031 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 30032 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 30033 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 30034 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 30035 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 30036 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 30037 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 30038 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 30039 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 30040 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 30041 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 30042 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 30043 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 30044 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 30045 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 30046 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE 30047 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 30048 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 30049 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 30050 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 30051 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 30052 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 30053 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 30054 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 30055 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_ONDELAY 30056 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_OFFDELAY 30057 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 30058 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 30059 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 30060 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 30061 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 30062 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 30063 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 30064 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 30065 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 30066 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 30067 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 30068 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REALARMTIME 30069 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 30070 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SILENCE 30071 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS 30072 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS2 30073 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 30074 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 30075 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 30076 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 30077 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 30078 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 30079 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 30080 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 30081 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 30082 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 30083 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET 30084 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET2 30085 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 30086 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 30087 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 30088 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_NORMALSTATE 30089 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 30090 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 30091 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 30092 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_CERTIFICATEEXPIRED_CERTIFICATE 30093 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE 30094 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_EVENTID 30095 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 30096 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 30097 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 30098 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_TIME 30099 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 30100 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 30101 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_MESSAGE 30102 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SEVERITY 30103 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 30104 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 30105 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 30106 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 30107 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 30108 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_BRANCHID 30109 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RETAIN 30110 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 30111 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 30112 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 30113 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 30114 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 30115 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 30116 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 30117 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 30118 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 30119 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_QUALITY 30120 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 30121 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 30122 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 30123 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_COMMENT 30124 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 30125 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 30126 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_DISABLE 30127 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ENABLE 30128 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 30129 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 30130 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 30131 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 30132 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 30133 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 30134 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 30135 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 30136 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 30137 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 30138 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 30139 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 30140 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 30141 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 30142 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 30143 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 30144 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 30145 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 30146 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 30147 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 30148 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 30149 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 30150 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRM 30151 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 30152 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 30153 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 30154 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 30155 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 30156 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 30157 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 30158 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 30159 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 30160 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 30161 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 30162 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 30163 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 30164 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 30165 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 30166 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 30167 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 30168 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 30169 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 30170 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 30171 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 30172 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 30173 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 30174 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 30175 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 30176 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 30177 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 30178 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 30179 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 30180 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 30181 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 30182 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 30183 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 30184 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 30185 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 30186 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 30187 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 30188 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 30189 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 30190 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 30191 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 30192 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 30193 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 30194 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 30195 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 30196 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 30197 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 30198 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 30199 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 30200 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 30201 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 30202 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 30203 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 30204 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 30205 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 30206 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 30207 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 30208 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 30209 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 30210 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 30211 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 30212 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 30213 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 30214 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 30215 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 30216 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 30217 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 30218 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 30219 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 30220 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 30221 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_ONDELAY 30222 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 30223 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 30224 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 30225 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 30226 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 30227 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 30228 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 30229 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 30230 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 30231 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 30232 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 30233 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 30234 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 30235 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 30236 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SILENCE 30237 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 30238 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 30239 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 30240 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 30241 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 30242 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 30243 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 30244 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 30245 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 30246 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 30247 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 30248 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 30249 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET 30250 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET2 30251 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 30252 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 30253 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 30254 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 30255 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 30256 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 30257 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 30258 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP 30259 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST 30260 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SIZE 30261 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITABLE 30262 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_USERWRITABLE 30263 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENCOUNT 30264 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_MIMETYPE 30265 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 30266 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_LASTMODIFIEDTIME 30267 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN 30268 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 30269 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 30270 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSE 30271 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 30272 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ 30273 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ_INPUTARGUMENTS 30274 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 30275 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITE 30276 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 30277 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION 30278 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 30279 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 30280 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SETPOSITION 30281 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 30282 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_LASTUPDATETIME 30283 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_UPDATEFREQUENCY 30284 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 30285 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS 30286 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 30287 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 30288 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE 30289 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 30290 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 30291 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ADDCERTIFICATE 30292 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 30293 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_REMOVECERTIFICATE 30294 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 30295 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATETYPES 30296 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_GETREJECTEDLIST 30298 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 30299 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED 30300 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EVENTID 30301 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EVENTTYPE 30302 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SOURCENODE 30303 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SOURCENAME 30304 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_TIME 30305 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RECEIVETIME 30306 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LOCALTIME 30307 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_MESSAGE 30308 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SEVERITY 30309 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 30310 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 30311 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 30312 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 30313 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 30314 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_BRANCHID 30315 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RETAIN 30316 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 30317 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 30318 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 30319 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 30320 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 30321 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 30322 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 30323 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 30324 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 30325 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_QUALITY 30326 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 30327 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 30328 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 30329 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_COMMENT 30330 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 30331 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 30332 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_DISABLE 30333 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ENABLE 30334 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 30335 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 30336 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 30337 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 30338 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 30339 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 30340 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 30341 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 30342 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 30343 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 30344 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 30345 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 30346 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 30347 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 30348 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 30349 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 30350 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 30351 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 30352 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 30353 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 30354 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 30355 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 30356 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRM 30357 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 30358 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 30359 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 30360 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 30361 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 30362 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 30363 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 30364 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 30365 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 30366 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 30367 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_INPUTNODE 30368 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 30369 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 30370 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 30371 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 30372 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 30373 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 30374 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 30375 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 30376 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 30377 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 30378 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 30379 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 30380 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 30381 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 30382 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 30383 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 30384 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 30385 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 30386 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 30387 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 30388 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 30389 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 30390 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 30391 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 30392 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 30393 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 30394 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 30395 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 30396 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 30397 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 30398 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 30399 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 30400 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 30401 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 30402 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 30403 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 30404 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 30405 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 30406 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 30407 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 30408 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 30409 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 30410 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 30411 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 30412 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 30413 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 30414 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 30415 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 30416 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 30417 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 30418 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE 30419 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 30420 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 30421 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 30422 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 30423 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 30424 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 30425 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 30426 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 30427 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_ONDELAY 30428 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_OFFDELAY 30429 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 30430 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 30431 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 30432 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 30433 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 30434 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 30435 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 30436 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 30437 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 30438 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 30439 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 30440 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REALARMTIME 30441 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 30442 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SILENCE 30443 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS 30444 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS2 30445 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 30446 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 30447 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 30448 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 30449 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 30450 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 30451 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 30452 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 30453 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 30454 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 30455 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET 30456 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET2 30457 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 30458 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 30459 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 30460 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_NORMALSTATE 30461 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 30462 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 30463 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 30464 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_CERTIFICATEEXPIRED_CERTIFICATE 30465 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE 30466 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_EVENTID 30467 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 30468 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 30469 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 30470 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_TIME 30471 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 30472 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 30473 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_MESSAGE 30474 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SEVERITY 30475 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 30476 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 30477 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 30478 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 30479 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 30480 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_BRANCHID 30481 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RETAIN 30482 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 30483 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 30484 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 30485 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 30486 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 30487 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 30488 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 30489 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 30490 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 30491 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_QUALITY 30492 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 30493 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 30494 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 30495 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_COMMENT 30496 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 30497 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 30498 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_DISABLE 30499 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ENABLE 30500 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 30501 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 30502 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 30503 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 30504 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 30505 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 30506 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 30507 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 30508 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 30509 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 30510 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 30511 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 30512 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 30513 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 30514 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 30515 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 30516 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 30517 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 30518 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 30519 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 30520 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 30521 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 30522 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRM 30523 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 30524 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 30525 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 30526 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 30527 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 30528 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 30529 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 30530 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 30531 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 30532 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 30533 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 30534 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 30535 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 30536 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 30537 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 30538 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 30539 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 30540 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 30541 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 30542 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 30543 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 30544 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 30545 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 30546 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 30547 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 30548 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 30549 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 30550 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 30551 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 30552 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 30553 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 30554 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 30555 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 30556 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 30557 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 30558 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 30559 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 30560 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 30561 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 30562 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 30563 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 30564 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 30565 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 30566 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 30567 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 30568 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 30569 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 30570 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 30571 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 30572 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 30573 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 30574 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 30575 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 30576 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 30577 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 30578 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 30579 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 30580 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 30581 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 30582 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 30583 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 30584 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 30585 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 30586 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 30587 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 30588 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 30589 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 30590 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 30591 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 30592 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 30593 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_ONDELAY 30594 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 30595 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 30596 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 30597 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 30598 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 30599 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 30600 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 30601 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 30602 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 30603 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 30604 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 30605 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 30606 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 30607 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 30608 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SILENCE 30609 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 30610 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 30611 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 30612 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 30613 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 30614 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 30615 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 30616 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 30617 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 30618 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 30619 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 30620 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 30621 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET 30622 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET2 30623 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 30624 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 30625 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 30626 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 30627 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 30628 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 30629 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 30630 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP 30631 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST 30632 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SIZE 30633 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITABLE 30634 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_USERWRITABLE 30635 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENCOUNT 30636 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_MIMETYPE 30637 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_MAXBYTESTRINGLENGTH 30638 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_LASTMODIFIEDTIME 30639 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN 30640 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN_INPUTARGUMENTS 30641 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPEN_OUTPUTARGUMENTS 30642 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSE 30643 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSE_INPUTARGUMENTS 30644 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ 30645 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ_INPUTARGUMENTS 30646 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_READ_OUTPUTARGUMENTS 30647 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITE 30648 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_WRITE_INPUTARGUMENTS 30649 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION 30650 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION_INPUTARGUMENTS 30651 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_GETPOSITION_OUTPUTARGUMENTS 30652 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SETPOSITION 30653 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_SETPOSITION_INPUTARGUMENTS 30654 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_LASTUPDATETIME 30655 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_UPDATEFREQUENCY 30656 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_DEFAULTVALIDATIONOPTIONS 30657 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS 30658 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS_INPUTARGUMENTS 30659 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_OPENWITHMASKS_OUTPUTARGUMENTS 30660 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE 30661 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE_INPUTARGUMENTS 30662 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_CLOSEANDUPDATE_OUTPUTARGUMENTS 30663 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ADDCERTIFICATE 30664 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ADDCERTIFICATE_INPUTARGUMENTS 30665 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_REMOVECERTIFICATE 30666 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_REMOVECERTIFICATE_INPUTARGUMENTS 30667 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATETYPES 30668 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_GETREJECTEDLIST 30670 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_GETREJECTEDLIST_OUTPUTARGUMENTS 30671 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED 30672 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EVENTID 30673 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EVENTTYPE 30674 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SOURCENODE 30675 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SOURCENAME 30676 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_TIME 30677 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RECEIVETIME 30678 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LOCALTIME 30679 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_MESSAGE 30680 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SEVERITY 30681 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSID 30682 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONCLASSNAME 30683 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSID 30684 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONSUBCLASSNAME 30685 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONDITIONNAME 30686 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_BRANCHID 30687 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RETAIN 30688 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE 30689 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_ID 30690 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NAME 30691 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_NUMBER 30692 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 30693 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRANSITIONTIME 30694 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 30695 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_TRUESTATE 30696 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLEDSTATE_FALSESTATE 30697 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_QUALITY 30698 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_QUALITY_SOURCETIMESTAMP 30699 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LASTSEVERITY 30700 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LASTSEVERITY_SOURCETIMESTAMP 30701 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_COMMENT 30702 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_COMMENT_SOURCETIMESTAMP 30703 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CLIENTUSERID 30704 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_DISABLE 30705 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ENABLE 30706 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ADDCOMMENT 30707 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ADDCOMMENT_INPUTARGUMENTS 30708 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE 30709 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_ID 30710 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NAME 30711 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_NUMBER 30712 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVEDISPLAYNAME 30713 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRANSITIONTIME 30714 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_EFFECTIVETRANSITIONTIME 30715 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_TRUESTATE 30716 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKEDSTATE_FALSESTATE 30717 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE 30718 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_ID 30719 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NAME 30720 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_NUMBER 30721 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 30722 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRANSITIONTIME 30723 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 30724 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_TRUESTATE 30725 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRMEDSTATE_FALSESTATE 30726 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE 30727 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACKNOWLEDGE_INPUTARGUMENTS 30728 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRM 30729 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CONFIRM_INPUTARGUMENTS 30730 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE 30731 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_ID 30732 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NAME 30733 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_NUMBER 30734 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVEDISPLAYNAME 30735 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRANSITIONTIME 30736 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_EFFECTIVETRANSITIONTIME 30737 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_TRUESTATE 30738 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ACTIVESTATE_FALSESTATE 30739 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_INPUTNODE 30740 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE 30741 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_ID 30742 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NAME 30743 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_NUMBER 30744 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 30745 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRANSITIONTIME 30746 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 30747 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_TRUESTATE 30748 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDSTATE_FALSESTATE 30749 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE 30750 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_ID 30751 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NAME 30752 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_NUMBER 30753 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 30754 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRANSITIONTIME 30755 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 30756 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_TRUESTATE 30757 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OUTOFSERVICESTATE_FALSESTATE 30758 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE 30759 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE 30760 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_ID 30761 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NAME 30762 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_NUMBER 30763 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 30764 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION 30765 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_ID 30766 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NAME 30767 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_NUMBER 30768 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 30769 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 30770 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLESTATES 30771 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_AVAILABLETRANSITIONS 30772 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVETIME 30773 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE 30774 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 30775 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2 30776 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 30777 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE 30778 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2 30779 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 30780 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE 30781 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2 30782 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 30783 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESSEDORSHELVED 30784 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_MAXTIMESHELVED 30785 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLEENABLED 30786 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND 30787 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_LISTID 30788 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_AGENCYID 30789 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_AUDIBLESOUND_VERSIONID 30790 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE 30791 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_ID 30792 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NAME 30793 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_NUMBER 30794 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVEDISPLAYNAME 30795 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRANSITIONTIME 30796 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_EFFECTIVETRANSITIONTIME 30797 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_TRUESTATE 30798 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCESTATE_FALSESTATE 30799 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_ONDELAY 30800 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_OFFDELAY 30801 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_FIRSTINGROUPFLAG 30802 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_FIRSTINGROUP 30803 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE 30804 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_ID 30805 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NAME 30806 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_NUMBER 30807 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 30808 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRANSITIONTIME 30809 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 30810 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_TRUESTATE 30811 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_LATCHEDSTATE_FALSESTATE 30812 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REALARMTIME 30813 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REALARMREPEATCOUNT 30814 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SILENCE 30815 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS 30816 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS2 30817 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_SUPPRESS2_INPUTARGUMENTS 30818 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS 30819 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2 30820 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_UNSUPPRESS2_INPUTARGUMENTS 30821 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE 30822 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2 30823 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_REMOVEFROMSERVICE2_INPUTARGUMENTS 30824 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE 30825 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2 30826 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_PLACEINSERVICE2_INPUTARGUMENTS 30827 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET 30828 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET2 30829 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_RESET2_INPUTARGUMENTS 30830 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS 30831 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 30832 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_NORMALSTATE 30833 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EXPIRATIONDATE 30834 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_EXPIRATIONLIMIT 30835 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CERTIFICATETYPE 30836 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_CERTIFICATEEXPIRED_CERTIFICATE 30837 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE 30838 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_EVENTID 30839 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_EVENTTYPE 30840 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SOURCENODE 30841 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SOURCENAME 30842 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_TIME 30843 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RECEIVETIME 30844 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LOCALTIME 30845 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_MESSAGE 30846 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SEVERITY 30847 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSID 30848 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONCLASSNAME 30849 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSID 30850 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONSUBCLASSNAME 30851 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONDITIONNAME 30852 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_BRANCHID 30853 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RETAIN 30854 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE 30855 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_ID 30856 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NAME 30857 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_NUMBER 30858 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 30859 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRANSITIONTIME 30860 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 30861 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_TRUESTATE 30862 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLEDSTATE_FALSESTATE 30863 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_QUALITY 30864 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_QUALITY_SOURCETIMESTAMP 30865 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY 30866 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTSEVERITY_SOURCETIMESTAMP 30867 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_COMMENT 30868 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_COMMENT_SOURCETIMESTAMP 30869 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CLIENTUSERID 30870 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_DISABLE 30871 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ENABLE 30872 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT 30873 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ADDCOMMENT_INPUTARGUMENTS 30874 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE 30875 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_ID 30876 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NAME 30877 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_NUMBER 30878 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVEDISPLAYNAME 30879 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRANSITIONTIME 30880 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_EFFECTIVETRANSITIONTIME 30881 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_TRUESTATE 30882 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKEDSTATE_FALSESTATE 30883 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE 30884 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_ID 30885 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NAME 30886 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_NUMBER 30887 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 30888 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRANSITIONTIME 30889 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 30890 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_TRUESTATE 30891 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRMEDSTATE_FALSESTATE 30892 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE 30893 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACKNOWLEDGE_INPUTARGUMENTS 30894 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRM 30895 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_CONFIRM_INPUTARGUMENTS 30896 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE 30897 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_ID 30898 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NAME 30899 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_NUMBER 30900 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVEDISPLAYNAME 30901 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRANSITIONTIME 30902 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_EFFECTIVETRANSITIONTIME 30903 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_TRUESTATE 30904 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ACTIVESTATE_FALSESTATE 30905 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_INPUTNODE 30906 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE 30907 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_ID 30908 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NAME 30909 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_NUMBER 30910 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 30911 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRANSITIONTIME 30912 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 30913 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_TRUESTATE 30914 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDSTATE_FALSESTATE 30915 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE 30916 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_ID 30917 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NAME 30918 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_NUMBER 30919 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 30920 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRANSITIONTIME 30921 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 30922 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_TRUESTATE 30923 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OUTOFSERVICESTATE_FALSESTATE 30924 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE 30925 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE 30926 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_ID 30927 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NAME 30928 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_NUMBER 30929 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 30930 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION 30931 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_ID 30932 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NAME 30933 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_NUMBER 30934 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 30935 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 30936 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLESTATES 30937 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_AVAILABLETRANSITIONS 30938 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVETIME 30939 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE 30940 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 30941 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2 30942 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 30943 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE 30944 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2 30945 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 30946 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE 30947 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2 30948 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 30949 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESSEDORSHELVED 30950 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_MAXTIMESHELVED 30951 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLEENABLED 30952 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND 30953 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_LISTID 30954 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_AGENCYID 30955 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_AUDIBLESOUND_VERSIONID 30956 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE 30957 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_ID 30958 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NAME 30959 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_NUMBER 30960 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVEDISPLAYNAME 30961 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRANSITIONTIME 30962 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_EFFECTIVETRANSITIONTIME 30963 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_TRUESTATE 30964 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCESTATE_FALSESTATE 30965 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_ONDELAY 30966 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_OFFDELAY 30967 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUPFLAG 30968 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_FIRSTINGROUP 30969 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE 30970 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_ID 30971 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NAME 30972 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_NUMBER 30973 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 30974 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRANSITIONTIME 30975 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 30976 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_TRUESTATE 30977 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LATCHEDSTATE_FALSESTATE 30978 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REALARMTIME 30979 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REALARMREPEATCOUNT 30980 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SILENCE 30981 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS 30982 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2 30983 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_SUPPRESS2_INPUTARGUMENTS 30984 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS 30985 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2 30986 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UNSUPPRESS2_INPUTARGUMENTS 30987 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE 30988 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2 30989 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_REMOVEFROMSERVICE2_INPUTARGUMENTS 30990 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE 30991 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2 30992 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_PLACEINSERVICE2_INPUTARGUMENTS 30993 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET 30994 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET2 30995 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_RESET2_INPUTARGUMENTS 30996 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS 30997 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 30998 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_NORMALSTATE 30999 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_TRUSTLISTID 31000 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_LASTUPDATETIME 31001 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLISTOUTOFDATE_UPDATEFREQUENCY 31002 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_ENABLED 31375 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_APPLICATIONURI 31376 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_PRODUCTURI 31377 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_APPLICATIONTYPE 31378 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_SERVERCAPABILITIES 31379 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_SUPPORTEDPRIVATEKEYFORMATS 31380 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_MAXTRUSTLISTSIZE 31381 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_MULTICASTDNSENABLED 31382 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_HASSECUREELEMENT 31383 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_UPDATECERTIFICATE 31384 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_UPDATECERTIFICATE_INPUTARGUMENTS 31385 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_UPDATECERTIFICATE_OUTPUTARGUMENTS 31386 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_APPLYCHANGES 31387 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CANCELCHANGES 31388 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CREATESIGNINGREQUEST 31389 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CREATESIGNINGREQUEST_INPUTARGUMENTS 31390 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CREATESIGNINGREQUEST_OUTPUTARGUMENTS 31391 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_GETREJECTEDLIST 31392 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_GETREJECTEDLIST_OUTPUTARGUMENTS 31393 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_RESETTOSERVERDEFAULTS 31394 /* Method */ +#define UA_NS0ID_SERVERTYPE_SERVERCAPABILITIES_MAXMONITOREDITEMSQUEUESIZE 31769 /* Variable */ +#define UA_NS0ID_SERVERCAPABILITIESTYPE_MAXMONITOREDITEMSQUEUESIZE 31770 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE_CONDITIONCLASSID 31771 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE_CONDITIONCLASSNAME 31772 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE_CONDITIONSUBCLASSID 31773 /* Variable */ +#define UA_NS0ID_BASEEVENTTYPE_CONDITIONSUBCLASSNAME 31774 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_CONDITIONCLASSID 31775 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_CONDITIONCLASSNAME 31776 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_CONDITIONSUBCLASSID 31777 /* Variable */ +#define UA_NS0ID_AUDITEVENTTYPE_CONDITIONSUBCLASSNAME 31778 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_CONDITIONCLASSID 31779 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_CONDITIONCLASSNAME 31780 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_CONDITIONSUBCLASSID 31781 /* Variable */ +#define UA_NS0ID_AUDITSECURITYEVENTTYPE_CONDITIONSUBCLASSNAME 31782 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_CONDITIONCLASSID 31783 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_CONDITIONCLASSNAME 31784 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_CONDITIONSUBCLASSID 31785 /* Variable */ +#define UA_NS0ID_AUDITCHANNELEVENTTYPE_CONDITIONSUBCLASSNAME 31786 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_CONDITIONCLASSID 31787 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_CONDITIONCLASSNAME 31788 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_CONDITIONSUBCLASSID 31789 /* Variable */ +#define UA_NS0ID_AUDITOPENSECURECHANNELEVENTTYPE_CONDITIONSUBCLASSNAME 31790 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_CONDITIONCLASSID 31791 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_CONDITIONCLASSNAME 31792 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_CONDITIONSUBCLASSID 31793 /* Variable */ +#define UA_NS0ID_AUDITSESSIONEVENTTYPE_CONDITIONSUBCLASSNAME 31794 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_CONDITIONCLASSID 31795 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_CONDITIONCLASSNAME 31796 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_CONDITIONSUBCLASSID 31797 /* Variable */ +#define UA_NS0ID_AUDITCREATESESSIONEVENTTYPE_CONDITIONSUBCLASSNAME 31798 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_CONDITIONCLASSID 31799 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_CONDITIONCLASSNAME 31800 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_CONDITIONSUBCLASSID 31801 /* Variable */ +#define UA_NS0ID_AUDITURLMISMATCHEVENTTYPE_CONDITIONSUBCLASSNAME 31802 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_CONDITIONCLASSID 31803 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_CONDITIONCLASSNAME 31804 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_CONDITIONSUBCLASSID 31805 /* Variable */ +#define UA_NS0ID_AUDITACTIVATESESSIONEVENTTYPE_CONDITIONSUBCLASSNAME 31806 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_CONDITIONCLASSID 31807 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_CONDITIONCLASSNAME 31808 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_CONDITIONSUBCLASSID 31809 /* Variable */ +#define UA_NS0ID_AUDITCANCELEVENTTYPE_CONDITIONSUBCLASSNAME 31810 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_CONDITIONCLASSID 31811 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_CONDITIONCLASSNAME 31812 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_CONDITIONSUBCLASSID 31813 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEVENTTYPE_CONDITIONSUBCLASSNAME 31814 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_CONDITIONCLASSID 31815 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_CONDITIONCLASSNAME 31816 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_CONDITIONSUBCLASSID 31817 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEDATAMISMATCHEVENTTYPE_CONDITIONSUBCLASSNAME 31818 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_CONDITIONCLASSID 31819 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_CONDITIONCLASSNAME 31820 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_CONDITIONSUBCLASSID 31821 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEEXPIREDEVENTTYPE_CONDITIONSUBCLASSNAME 31822 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_CONDITIONCLASSID 31823 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_CONDITIONCLASSNAME 31824 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_CONDITIONSUBCLASSID 31825 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEINVALIDEVENTTYPE_CONDITIONSUBCLASSNAME 31826 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_CONDITIONCLASSID 31827 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_CONDITIONCLASSNAME 31828 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_CONDITIONSUBCLASSID 31829 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEUNTRUSTEDEVENTTYPE_CONDITIONSUBCLASSNAME 31830 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_CONDITIONCLASSID 31831 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_CONDITIONCLASSNAME 31832 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_CONDITIONSUBCLASSID 31833 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEREVOKEDEVENTTYPE_CONDITIONSUBCLASSNAME 31834 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_CONDITIONCLASSID 31835 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_CONDITIONCLASSNAME 31836 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_CONDITIONSUBCLASSID 31837 /* Variable */ +#define UA_NS0ID_AUDITCERTIFICATEMISMATCHEVENTTYPE_CONDITIONSUBCLASSNAME 31838 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_CONDITIONCLASSID 31839 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_CONDITIONCLASSNAME 31840 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_CONDITIONSUBCLASSID 31841 /* Variable */ +#define UA_NS0ID_AUDITNODEMANAGEMENTEVENTTYPE_CONDITIONSUBCLASSNAME 31842 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_CONDITIONCLASSID 31843 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_CONDITIONCLASSNAME 31844 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_CONDITIONSUBCLASSID 31845 /* Variable */ +#define UA_NS0ID_AUDITADDNODESEVENTTYPE_CONDITIONSUBCLASSNAME 31846 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_CONDITIONCLASSID 31847 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_CONDITIONCLASSNAME 31848 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_CONDITIONSUBCLASSID 31849 /* Variable */ +#define UA_NS0ID_AUDITDELETENODESEVENTTYPE_CONDITIONSUBCLASSNAME 31850 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_CONDITIONCLASSID 31851 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_CONDITIONCLASSNAME 31852 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_CONDITIONSUBCLASSID 31853 /* Variable */ +#define UA_NS0ID_AUDITADDREFERENCESEVENTTYPE_CONDITIONSUBCLASSNAME 31854 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_CONDITIONCLASSID 31855 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_CONDITIONCLASSNAME 31856 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_CONDITIONSUBCLASSID 31857 /* Variable */ +#define UA_NS0ID_AUDITDELETEREFERENCESEVENTTYPE_CONDITIONSUBCLASSNAME 31858 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_CONDITIONCLASSID 31859 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_CONDITIONCLASSNAME 31860 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_CONDITIONSUBCLASSID 31861 /* Variable */ +#define UA_NS0ID_AUDITUPDATEEVENTTYPE_CONDITIONSUBCLASSNAME 31862 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_CONDITIONCLASSID 31863 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_CONDITIONCLASSNAME 31864 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_CONDITIONSUBCLASSID 31865 /* Variable */ +#define UA_NS0ID_AUDITWRITEUPDATEEVENTTYPE_CONDITIONSUBCLASSNAME 31866 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_CONDITIONCLASSID 31867 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_CONDITIONCLASSNAME 31868 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_CONDITIONSUBCLASSID 31869 /* Variable */ +#define UA_NS0ID_AUDITHISTORYUPDATEEVENTTYPE_CONDITIONSUBCLASSNAME 31870 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_CONDITIONCLASSID 31871 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_CONDITIONCLASSNAME 31872 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_CONDITIONSUBCLASSID 31873 /* Variable */ +#define UA_NS0ID_AUDITUPDATEMETHODEVENTTYPE_CONDITIONSUBCLASSNAME 31874 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_CONDITIONCLASSID 31875 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_CONDITIONCLASSNAME 31876 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_CONDITIONSUBCLASSID 31877 /* Variable */ +#define UA_NS0ID_SYSTEMEVENTTYPE_CONDITIONSUBCLASSNAME 31878 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_CONDITIONCLASSID 31879 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_CONDITIONCLASSNAME 31880 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_CONDITIONSUBCLASSID 31881 /* Variable */ +#define UA_NS0ID_DEVICEFAILUREEVENTTYPE_CONDITIONSUBCLASSNAME 31882 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_CONDITIONCLASSID 31883 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_CONDITIONCLASSNAME 31884 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_CONDITIONSUBCLASSID 31885 /* Variable */ +#define UA_NS0ID_SYSTEMSTATUSCHANGEEVENTTYPE_CONDITIONSUBCLASSNAME 31886 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_CONDITIONCLASSID 31887 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_CONDITIONCLASSNAME 31888 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_CONDITIONSUBCLASSID 31889 /* Variable */ +#define UA_NS0ID_BASEMODELCHANGEEVENTTYPE_CONDITIONSUBCLASSNAME 31890 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_CONDITIONCLASSID 31891 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_CONDITIONCLASSNAME 31892 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_CONDITIONSUBCLASSID 31893 /* Variable */ +#define UA_NS0ID_GENERALMODELCHANGEEVENTTYPE_CONDITIONSUBCLASSNAME 31894 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_CONDITIONCLASSID 31895 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_CONDITIONCLASSNAME 31896 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_CONDITIONSUBCLASSID 31897 /* Variable */ +#define UA_NS0ID_SEMANTICCHANGEEVENTTYPE_CONDITIONSUBCLASSNAME 31898 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_CONDITIONCLASSID 31899 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_CONDITIONCLASSNAME 31900 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_CONDITIONSUBCLASSID 31901 /* Variable */ +#define UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE_CONDITIONSUBCLASSNAME 31902 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_CONDITIONCLASSID 31903 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_CONDITIONCLASSNAME 31904 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_CONDITIONSUBCLASSID 31905 /* Variable */ +#define UA_NS0ID_PROGRESSEVENTTYPE_CONDITIONSUBCLASSNAME 31906 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_CONDITIONCLASSID 31907 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_CONDITIONCLASSNAME 31908 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_CONDITIONSUBCLASSID 31909 /* Variable */ +#define UA_NS0ID_AUDITCLIENTEVENTTYPE_CONDITIONSUBCLASSNAME 31910 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_CONDITIONCLASSID 31911 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_CONDITIONCLASSNAME 31912 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_CONDITIONSUBCLASSID 31913 /* Variable */ +#define UA_NS0ID_AUDITCLIENTUPDATEMETHODRESULTEVENTTYPE_CONDITIONSUBCLASSNAME 31914 /* Variable */ +#define UA_NS0ID_LOCATIONS 31915 /* Object */ +#define UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXMONITOREDITEMSQUEUESIZE 31916 /* Variable */ +#define UA_NS0ID_HANDLE 31917 /* DataType */ +#define UA_NS0ID_TRIMMEDSTRING 31918 /* DataType */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_CONDITIONCLASSID 31919 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_CONDITIONCLASSNAME 31920 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_CONDITIONSUBCLASSID 31921 /* Variable */ +#define UA_NS0ID_TRANSITIONEVENTTYPE_CONDITIONSUBCLASSNAME 31922 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_CONDITIONCLASSID 31923 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_CONDITIONCLASSNAME 31924 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_CONDITIONSUBCLASSID 31925 /* Variable */ +#define UA_NS0ID_AUDITUPDATESTATEEVENTTYPE_CONDITIONSUBCLASSNAME 31926 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_CONDITIONCLASSID 31927 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_CONDITIONCLASSNAME 31928 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_CONDITIONSUBCLASSID 31929 /* Variable */ +#define UA_NS0ID_ROLEMAPPINGRULECHANGEDAUDITEVENTTYPE_CONDITIONSUBCLASSNAME 31930 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_CONDITIONCLASSID 31931 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_CONDITIONCLASSNAME 31932 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_CONDITIONSUBCLASSID 31933 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONEVENTTYPE_CONDITIONSUBCLASSNAME 31934 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_CONDITIONCLASSID 31935 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_CONDITIONCLASSNAME 31936 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_CONDITIONSUBCLASSID 31937 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONENABLEEVENTTYPE_CONDITIONSUBCLASSNAME 31938 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_CONDITIONCLASSID 31939 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_CONDITIONCLASSNAME 31940 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_CONDITIONSUBCLASSID 31941 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCOMMENTEVENTTYPE_CONDITIONSUBCLASSNAME 31942 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_CONDITIONCLASSID 31943 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_CONDITIONCLASSNAME 31944 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_CONDITIONSUBCLASSID 31945 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESPONDEVENTTYPE_CONDITIONSUBCLASSNAME 31946 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_CONDITIONCLASSID 31947 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_CONDITIONCLASSNAME 31948 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_CONDITIONSUBCLASSID 31949 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONACKNOWLEDGEEVENTTYPE_CONDITIONSUBCLASSNAME 31950 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_CONDITIONCLASSID 31951 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_CONDITIONCLASSNAME 31952 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_CONDITIONSUBCLASSID 31953 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONCONFIRMEVENTTYPE_CONDITIONSUBCLASSNAME 31954 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_CONDITIONCLASSID 31955 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_CONDITIONCLASSNAME 31956 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_CONDITIONSUBCLASSID 31957 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSHELVINGEVENTTYPE_CONDITIONSUBCLASSNAME 31958 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_CONDITIONCLASSID 31959 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_CONDITIONCLASSNAME 31960 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_CONDITIONSUBCLASSID 31961 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSUPPRESSIONEVENTTYPE_CONDITIONSUBCLASSNAME 31962 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_CONDITIONCLASSID 31963 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_CONDITIONCLASSNAME 31964 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_CONDITIONSUBCLASSID 31965 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONSILENCEEVENTTYPE_CONDITIONSUBCLASSNAME 31966 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_CONDITIONCLASSID 31967 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_CONDITIONCLASSNAME 31968 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_CONDITIONSUBCLASSID 31969 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONRESETEVENTTYPE_CONDITIONSUBCLASSNAME 31970 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_CONDITIONCLASSID 31971 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_CONDITIONCLASSNAME 31972 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_CONDITIONSUBCLASSID 31973 /* Variable */ +#define UA_NS0ID_AUDITCONDITIONOUTOFSERVICEEVENTTYPE_CONDITIONSUBCLASSNAME 31974 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_CONDITIONCLASSID 31975 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_CONDITIONCLASSNAME 31976 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_CONDITIONSUBCLASSID 31977 /* Variable */ +#define UA_NS0ID_REFRESHSTARTEVENTTYPE_CONDITIONSUBCLASSNAME 31978 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_CONDITIONCLASSID 31979 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_CONDITIONCLASSNAME 31980 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_CONDITIONSUBCLASSID 31981 /* Variable */ +#define UA_NS0ID_REFRESHENDEVENTTYPE_CONDITIONSUBCLASSNAME 31982 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_CONDITIONCLASSID 31983 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_CONDITIONCLASSNAME 31984 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_CONDITIONSUBCLASSID 31985 /* Variable */ +#define UA_NS0ID_REFRESHREQUIREDEVENTTYPE_CONDITIONSUBCLASSNAME 31986 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_CONDITIONCLASSID 31987 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_CONDITIONCLASSNAME 31988 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_CONDITIONSUBCLASSID 31989 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONEVENTTYPE_CONDITIONSUBCLASSNAME 31990 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_CONDITIONCLASSID 31991 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_CONDITIONCLASSNAME 31992 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_CONDITIONSUBCLASSID 31993 /* Variable */ +#define UA_NS0ID_AUDITPROGRAMTRANSITIONEVENTTYPE_CONDITIONSUBCLASSNAME 31994 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_CONDITIONCLASSID 31995 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_CONDITIONCLASSNAME 31996 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_CONDITIONSUBCLASSID 31997 /* Variable */ +#define UA_NS0ID_PROGRAMTRANSITIONAUDITEVENTTYPE_CONDITIONSUBCLASSNAME 31998 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_CONDITIONCLASSID 31999 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_CONDITIONCLASSNAME 32000 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_CONDITIONSUBCLASSID 32001 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTUPDATEEVENTTYPE_CONDITIONSUBCLASSNAME 32002 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_CONDITIONCLASSID 32003 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_CONDITIONCLASSNAME 32004 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_CONDITIONSUBCLASSID 32005 /* Variable */ +#define UA_NS0ID_AUDITHISTORYVALUEUPDATEEVENTTYPE_CONDITIONSUBCLASSNAME 32006 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_CONDITIONCLASSID 32007 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_CONDITIONCLASSNAME 32008 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_CONDITIONSUBCLASSID 32009 /* Variable */ +#define UA_NS0ID_AUDITHISTORYANNOTATIONUPDATEEVENTTYPE_CONDITIONSUBCLASSNAME 32010 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_CONDITIONCLASSID 32011 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_CONDITIONCLASSNAME 32012 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_CONDITIONSUBCLASSID 32013 /* Variable */ +#define UA_NS0ID_AUDITHISTORYDELETEEVENTTYPE_CONDITIONSUBCLASSNAME 32014 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_CONDITIONCLASSID 32015 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_CONDITIONCLASSNAME 32016 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_CONDITIONSUBCLASSID 32017 /* Variable */ +#define UA_NS0ID_AUDITHISTORYRAWMODIFYDELETEEVENTTYPE_CONDITIONSUBCLASSNAME 32018 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_CONDITIONCLASSID 32019 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_CONDITIONCLASSNAME 32020 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_CONDITIONSUBCLASSID 32021 /* Variable */ +#define UA_NS0ID_AUDITHISTORYATTIMEDELETEEVENTTYPE_CONDITIONSUBCLASSNAME 32022 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_CONDITIONCLASSID 32023 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_CONDITIONCLASSNAME 32024 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_CONDITIONSUBCLASSID 32025 /* Variable */ +#define UA_NS0ID_AUDITHISTORYEVENTDELETEEVENTTYPE_CONDITIONSUBCLASSNAME 32026 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_CONDITIONCLASSID 32027 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_CONDITIONCLASSNAME 32028 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_CONDITIONSUBCLASSID 32029 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_CONDITIONSUBCLASSNAME 32030 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_CONDITIONCLASSID 32031 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_CONDITIONCLASSNAME 32032 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_CONDITIONSUBCLASSID 32033 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEDAUDITEVENTTYPE_CONDITIONSUBCLASSNAME 32034 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_CONDITIONCLASSID 32035 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_CONDITIONCLASSNAME 32036 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_CONDITIONSUBCLASSID 32037 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALAUDITEVENTTYPE_CONDITIONSUBCLASSNAME 32038 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_CONDITIONCLASSID 32039 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_CONDITIONCLASSNAME 32040 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_CONDITIONSUBCLASSID 32041 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALUPDATEDAUDITEVENTTYPE_CONDITIONSUBCLASSNAME 32042 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_CONDITIONCLASSID 32043 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_CONDITIONCLASSNAME 32044 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_CONDITIONSUBCLASSID 32045 /* Variable */ +#define UA_NS0ID_KEYCREDENTIALDELETEDAUDITEVENTTYPE_CONDITIONSUBCLASSNAME 32046 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_CONDITIONCLASSID 32047 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_CONDITIONCLASSNAME 32048 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_CONDITIONSUBCLASSID 32049 /* Variable */ +#define UA_NS0ID_PUBSUBSTATUSEVENTTYPE_CONDITIONSUBCLASSNAME 32050 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_CONDITIONCLASSID 32051 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_CONDITIONCLASSNAME 32052 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_CONDITIONSUBCLASSID 32053 /* Variable */ +#define UA_NS0ID_PUBSUBTRANSPORTLIMITSEXCEEDEVENTTYPE_CONDITIONSUBCLASSNAME 32054 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_CONDITIONCLASSID 32055 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_CONDITIONCLASSNAME 32056 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_CONDITIONSUBCLASSID 32057 /* Variable */ +#define UA_NS0ID_PUBSUBCOMMUNICATIONFAILUREEVENTTYPE_CONDITIONSUBCLASSNAME 32058 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPMEMBER 32059 /* ReferenceType */ +#define UA_NS0ID_CONDITIONTYPE_SUPPORTSFILTEREDRETAIN 32060 /* Variable */ +#define UA_NS0ID_DIALOGCONDITIONTYPE_SUPPORTSFILTEREDRETAIN 32061 /* Variable */ +#define UA_NS0ID_ACKNOWLEDGEABLECONDITIONTYPE_SUPPORTSFILTEREDRETAIN 32062 /* Variable */ +#define UA_NS0ID_ALARMCONDITIONTYPE_SUPPORTSFILTEREDRETAIN 32063 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE 32064 /* ObjectType */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER 32065 /* Object */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_EVENTID 32066 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_EVENTTYPE 32067 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SOURCENODE 32068 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SOURCENAME 32069 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_TIME 32070 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_RECEIVETIME 32071 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LOCALTIME 32072 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_MESSAGE 32073 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SEVERITY 32074 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONDITIONCLASSID 32075 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONDITIONCLASSNAME 32076 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONDITIONSUBCLASSID 32077 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONDITIONSUBCLASSNAME 32078 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONDITIONNAME 32079 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_BRANCHID 32080 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_RETAIN 32081 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE 32082 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_ID 32083 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_NAME 32084 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_NUMBER 32085 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_EFFECTIVEDISPLAYNAME 32086 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_TRANSITIONTIME 32087 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_EFFECTIVETRANSITIONTIME 32088 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_TRUESTATE 32089 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLEDSTATE_FALSESTATE 32090 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_QUALITY 32091 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_QUALITY_SOURCETIMESTAMP 32092 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LASTSEVERITY 32093 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LASTSEVERITY_SOURCETIMESTAMP 32094 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_COMMENT 32095 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_COMMENT_SOURCETIMESTAMP 32096 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CLIENTUSERID 32097 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_DISABLE 32098 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ENABLE 32099 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ADDCOMMENT 32100 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ADDCOMMENT_INPUTARGUMENTS 32101 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE 32102 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_ID 32103 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_NAME 32104 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_NUMBER 32105 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_EFFECTIVEDISPLAYNAME 32106 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_TRANSITIONTIME 32107 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_EFFECTIVETRANSITIONTIME 32108 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_TRUESTATE 32109 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKEDSTATE_FALSESTATE 32110 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE 32111 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_ID 32112 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_NAME 32113 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_NUMBER 32114 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_EFFECTIVEDISPLAYNAME 32115 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_TRANSITIONTIME 32116 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_EFFECTIVETRANSITIONTIME 32117 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_TRUESTATE 32118 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRMEDSTATE_FALSESTATE 32119 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKNOWLEDGE 32120 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACKNOWLEDGE_INPUTARGUMENTS 32121 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRM 32122 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_CONFIRM_INPUTARGUMENTS 32123 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE 32124 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_ID 32125 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_NAME 32126 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_NUMBER 32127 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_EFFECTIVEDISPLAYNAME 32128 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_TRANSITIONTIME 32129 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_EFFECTIVETRANSITIONTIME 32130 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_TRUESTATE 32131 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ACTIVESTATE_FALSESTATE 32132 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_INPUTNODE 32133 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE 32134 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_ID 32135 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_NAME 32136 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_NUMBER 32137 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_EFFECTIVEDISPLAYNAME 32138 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_TRANSITIONTIME 32139 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_EFFECTIVETRANSITIONTIME 32140 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_TRUESTATE 32141 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDSTATE_FALSESTATE 32142 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE 32143 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_ID 32144 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_NAME 32145 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_NUMBER 32146 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_EFFECTIVEDISPLAYNAME 32147 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_TRANSITIONTIME 32148 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_EFFECTIVETRANSITIONTIME 32149 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_TRUESTATE 32150 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OUTOFSERVICESTATE_FALSESTATE 32151 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE 32152 /* Object */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_CURRENTSTATE 32153 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_CURRENTSTATE_ID 32154 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_CURRENTSTATE_NAME 32155 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_CURRENTSTATE_NUMBER 32156 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_CURRENTSTATE_EFFECTIVEDISPLAYNAME 32157 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_LASTTRANSITION 32158 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_LASTTRANSITION_ID 32159 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_LASTTRANSITION_NAME 32160 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_LASTTRANSITION_NUMBER 32161 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_LASTTRANSITION_TRANSITIONTIME 32162 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_LASTTRANSITION_EFFECTIVETRANSITIONTIME 32163 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_AVAILABLESTATES 32164 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_AVAILABLETRANSITIONS 32165 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_UNSHELVETIME 32166 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_TIMEDSHELVE 32167 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_TIMEDSHELVE_INPUTARGUMENTS 32168 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_TIMEDSHELVE2 32169 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_TIMEDSHELVE2_INPUTARGUMENTS 32170 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_UNSHELVE 32171 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_UNSHELVE2 32172 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_UNSHELVE2_INPUTARGUMENTS 32173 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_ONESHOTSHELVE 32174 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_ONESHOTSHELVE2 32175 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SHELVINGSTATE_ONESHOTSHELVE2_INPUTARGUMENTS 32176 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESSEDORSHELVED 32177 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_MAXTIMESHELVED 32178 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_AUDIBLEENABLED 32179 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_AUDIBLESOUND 32180 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_AUDIBLESOUND_LISTID 32181 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_AUDIBLESOUND_AGENCYID 32182 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_AUDIBLESOUND_VERSIONID 32183 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE 32184 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_ID 32185 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_NAME 32186 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_NUMBER 32187 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_EFFECTIVEDISPLAYNAME 32188 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_TRANSITIONTIME 32189 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_EFFECTIVETRANSITIONTIME 32190 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_TRUESTATE 32191 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCESTATE_FALSESTATE 32192 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_ONDELAY 32193 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_OFFDELAY 32194 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_FIRSTINGROUPFLAG 32195 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_FIRSTINGROUP 32196 /* Object */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE 32197 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_ID 32198 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_NAME 32199 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_NUMBER 32200 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_EFFECTIVEDISPLAYNAME 32201 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_TRANSITIONTIME 32202 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_EFFECTIVETRANSITIONTIME 32203 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_TRUESTATE 32204 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_LATCHEDSTATE_FALSESTATE 32205 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_REALARMTIME 32206 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_REALARMREPEATCOUNT 32207 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SILENCE 32208 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESS 32209 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESS2 32210 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_SUPPRESS2_INPUTARGUMENTS 32211 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_UNSUPPRESS 32212 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_UNSUPPRESS2 32213 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_UNSUPPRESS2_INPUTARGUMENTS 32214 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_REMOVEFROMSERVICE 32215 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_REMOVEFROMSERVICE2 32216 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_REMOVEFROMSERVICE2_INPUTARGUMENTS 32217 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_PLACEINSERVICE 32218 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_PLACEINSERVICE2 32219 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_PLACEINSERVICE2_INPUTARGUMENTS 32220 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_RESET 32221 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_RESET2 32222 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_RESET2_INPUTARGUMENTS 32223 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_GETGROUPMEMBERSHIPS 32224 /* Method */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_ALARMCONDITIONINSTANCE_PLACEHOLDER_GETGROUPMEMBERSHIPS_OUTPUTARGUMENTS 32225 /* Variable */ +#define UA_NS0ID_ALARMSUPPRESSIONGROUPTYPE_DIGITALVARIABLE_PLACEHOLDER 32226 /* Variable */ +#define UA_NS0ID_LIMITALARMTYPE_SUPPORTSFILTEREDRETAIN 32227 /* Variable */ +#define UA_NS0ID_EXCLUSIVELIMITALARMTYPE_SUPPORTSFILTEREDRETAIN 32228 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELIMITALARMTYPE_SUPPORTSFILTEREDRETAIN 32229 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVELEVELALARMTYPE_SUPPORTSFILTEREDRETAIN 32230 /* Variable */ +#define UA_NS0ID_EXCLUSIVELEVELALARMTYPE_SUPPORTSFILTEREDRETAIN 32231 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVEDEVIATIONALARMTYPE_SUPPORTSFILTEREDRETAIN 32232 /* Variable */ +#define UA_NS0ID_NONEXCLUSIVERATEOFCHANGEALARMTYPE_SUPPORTSFILTEREDRETAIN 32233 /* Variable */ +#define UA_NS0ID_EXCLUSIVEDEVIATIONALARMTYPE_SUPPORTSFILTEREDRETAIN 32234 /* Variable */ +#define UA_NS0ID_EXCLUSIVERATEOFCHANGEALARMTYPE_SUPPORTSFILTEREDRETAIN 32235 /* Variable */ +#define UA_NS0ID_DISCRETEALARMTYPE_SUPPORTSFILTEREDRETAIN 32236 /* Variable */ +#define UA_NS0ID_OFFNORMALALARMTYPE_SUPPORTSFILTEREDRETAIN 32237 /* Variable */ +#define UA_NS0ID_SYSTEMOFFNORMALALARMTYPE_SUPPORTSFILTEREDRETAIN 32238 /* Variable */ +#define UA_NS0ID_TRIPALARMTYPE_SUPPORTSFILTEREDRETAIN 32239 /* Variable */ +#define UA_NS0ID_INSTRUMENTDIAGNOSTICALARMTYPE_SUPPORTSFILTEREDRETAIN 32240 /* Variable */ +#define UA_NS0ID_SYSTEMDIAGNOSTICALARMTYPE_SUPPORTSFILTEREDRETAIN 32241 /* Variable */ +#define UA_NS0ID_CERTIFICATEEXPIRATIONALARMTYPE_SUPPORTSFILTEREDRETAIN 32242 /* Variable */ +#define UA_NS0ID_DISCREPANCYALARMTYPE_SUPPORTSFILTEREDRETAIN 32243 /* Variable */ +#define UA_NS0ID_ALARMSTATEVARIABLETYPE 32244 /* VariableType */ +#define UA_NS0ID_ALARMSTATEVARIABLETYPE_HIGHESTACTIVESEVERITY 32245 /* Variable */ +#define UA_NS0ID_ALARMSTATEVARIABLETYPE_HIGHESTUNACKSEVERITY 32246 /* Variable */ +#define UA_NS0ID_ALARMSTATEVARIABLETYPE_ACTIVECOUNT 32247 /* Variable */ +#define UA_NS0ID_ALARMSTATEVARIABLETYPE_UNACKNOWLEDGEDCOUNT 32248 /* Variable */ +#define UA_NS0ID_ALARMSTATEVARIABLETYPE_UNCONFIRMEDCOUNT 32249 /* Variable */ +#define UA_NS0ID_ALARMSTATEVARIABLETYPE_FILTER 32250 /* Variable */ +#define UA_NS0ID_ALARMMASK 32251 /* DataType */ +#define UA_NS0ID_ALARMMASK_OPTIONSETVALUES 32252 /* Variable */ +#define UA_NS0ID_TRUSTLISTOUTOFDATEALARMTYPE_SUPPORTSFILTEREDRETAIN 32253 /* Variable */ +#define UA_NS0ID_TRUSTLISTTYPE_ACTIVITYTIMEOUT 32254 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPTYPE_TRUSTLIST_ACTIVITYTIMEOUT 32255 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32256 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTHTTPSGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32257 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_DEFAULTUSERTOKENGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32258 /* Variable */ +#define UA_NS0ID_CERTIFICATEGROUPFOLDERTYPE_ADDITIONALGROUP_PLACEHOLDER_TRUSTLIST_ACTIVITYTIMEOUT 32259 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE 32260 /* ObjectType */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_EVENTID 32261 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_EVENTTYPE 32262 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_SOURCENODE 32263 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_SOURCENAME 32264 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_TIME 32265 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_RECEIVETIME 32266 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_LOCALTIME 32267 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_MESSAGE 32268 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_SEVERITY 32269 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_CONDITIONCLASSID 32270 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_CONDITIONCLASSNAME 32271 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_CONDITIONSUBCLASSID 32272 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_CONDITIONSUBCLASSNAME 32273 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_ACTIONTIMESTAMP 32274 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_STATUS 32275 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_SERVERID 32276 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_CLIENTAUDITENTRYID 32277 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_CLIENTUSERID 32278 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_METHODID 32279 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEREQUESTEDAUDITEVENTTYPE_INPUTARGUMENTS 32280 /* Variable */ +#define UA_NS0ID_TRUSTLISTUPDATEDAUDITEVENTTYPE_TRUSTLISTID 32281 /* Variable */ +#define UA_NS0ID_GETCERTIFICATESMETHODTYPE 32282 /* Method */ +#define UA_NS0ID_GETCERTIFICATESMETHODTYPE_INPUTARGUMENTS 32283 /* Variable */ +#define UA_NS0ID_GETCERTIFICATESMETHODTYPE_OUTPUTARGUMENTS 32284 /* Variable */ +#define UA_NS0ID_TRANSACTIONERRORTYPE 32285 /* DataType */ +#define UA_NS0ID_TRANSACTIONDIAGNOSTICSTYPE 32286 /* ObjectType */ +#define UA_NS0ID_TRANSACTIONDIAGNOSTICSTYPE_STARTTIME 32287 /* Variable */ +#define UA_NS0ID_TRANSACTIONDIAGNOSTICSTYPE_ENDTIME 32288 /* Variable */ +#define UA_NS0ID_TRANSACTIONDIAGNOSTICSTYPE_RESULT 32289 /* Variable */ +#define UA_NS0ID_TRANSACTIONDIAGNOSTICSTYPE_AFFECTEDTRUSTLISTS 32290 /* Variable */ +#define UA_NS0ID_TRANSACTIONDIAGNOSTICSTYPE_AFFECTEDCERTIFICATEGROUPS 32291 /* Variable */ +#define UA_NS0ID_TRANSACTIONDIAGNOSTICSTYPE_ERRORS 32292 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32293 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32294 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32295 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_GETCERTIFICATES 32296 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_GETCERTIFICATES_INPUTARGUMENTS 32297 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_GETCERTIFICATES_OUTPUTARGUMENTS 32298 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS 32299 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS_STARTTIME 32300 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS_ENDTIME 32301 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS_RESULT 32302 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS_AFFECTEDTRUSTLISTS 32303 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS_AFFECTEDCERTIFICATEGROUPS 32304 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS_ERRORS 32305 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE 32306 /* ObjectType */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_EVENTID 32307 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_EVENTTYPE 32308 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_SOURCENODE 32309 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_SOURCENAME 32310 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_TIME 32311 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_RECEIVETIME 32312 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_LOCALTIME 32313 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_MESSAGE 32314 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_SEVERITY 32315 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_CONDITIONCLASSID 32316 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_CONDITIONCLASSNAME 32317 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_CONDITIONSUBCLASSID 32318 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_CONDITIONSUBCLASSNAME 32319 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_ACTIONTIMESTAMP 32320 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_STATUS 32321 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_SERVERID 32322 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_CLIENTAUDITENTRYID 32323 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_CLIENTUSERID 32324 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_METHODID 32325 /* Variable */ +#define UA_NS0ID_CERTIFICATEUPDATEREQUESTEDAUDITEVENTTYPE_INPUTARGUMENTS 32326 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32330 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32331 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32332 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_GETCERTIFICATES 32333 /* Method */ +#define UA_NS0ID_SERVERCONFIGURATION_GETCERTIFICATES_INPUTARGUMENTS 32334 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_GETCERTIFICATES_OUTPUTARGUMENTS 32335 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_TRANSACTIONDIAGNOSTICS 32336 /* Object */ +#define UA_NS0ID_SERVERCONFIGURATION_TRANSACTIONDIAGNOSTICS_STARTTIME 32337 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_TRANSACTIONDIAGNOSTICS_ENDTIME 32338 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_TRANSACTIONDIAGNOSTICS_RESULT 32339 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_TRANSACTIONDIAGNOSTICS_AFFECTEDTRUSTLISTS 32340 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_TRANSACTIONDIAGNOSTICS_AFFECTEDCERTIFICATEGROUPS 32341 /* Variable */ +#define UA_NS0ID_SERVERCONFIGURATION_TRANSACTIONDIAGNOSTICS_ERRORS 32342 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32343 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32344 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32345 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_GETCERTIFICATES 32346 /* Method */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_GETCERTIFICATES_INPUTARGUMENTS 32347 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_GETCERTIFICATES_OUTPUTARGUMENTS 32348 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS 32349 /* Object */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS_STARTTIME 32350 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS_ENDTIME 32351 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS_RESULT 32352 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS_AFFECTEDTRUSTLISTS 32353 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS_AFFECTEDCERTIFICATEGROUPS 32354 /* Variable */ +#define UA_NS0ID_APPLICATIONCONFIGURATIONTYPE_TRANSACTIONDIAGNOSTICS_ERRORS 32355 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32356 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32357 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32358 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_GETCERTIFICATES 32359 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_GETCERTIFICATES_INPUTARGUMENTS 32360 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_GETCERTIFICATES_OUTPUTARGUMENTS 32361 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS 32362 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS_STARTTIME 32363 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS_ENDTIME 32364 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS_RESULT 32365 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS_AFFECTEDTRUSTLISTS 32366 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS_AFFECTEDCERTIFICATEGROUPS 32367 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICETYPE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS_ERRORS 32368 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTAPPLICATIONGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32369 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTHTTPSGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32370 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_CERTIFICATEGROUPS_DEFAULTUSERTOKENGROUP_TRUSTLIST_ACTIVITYTIMEOUT 32371 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_GETCERTIFICATES 32372 /* Method */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_GETCERTIFICATES_INPUTARGUMENTS 32373 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_GETCERTIFICATES_OUTPUTARGUMENTS 32374 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS 32375 /* Object */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS_STARTTIME 32376 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS_ENDTIME 32377 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS_RESULT 32378 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS_AFFECTEDTRUSTLISTS 32379 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS_AFFECTEDCERTIFICATEGROUPS 32380 /* Variable */ +#define UA_NS0ID_PROVISIONABLEDEVICE_APPLICATIONNAME_PLACEHOLDER_TRANSACTIONDIAGNOSTICS_ERRORS 32381 /* Variable */ +#define UA_NS0ID_TRANSACTIONERRORTYPE_ENCODING_DEFAULTBINARY 32382 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TRANSACTIONERRORTYPE 32383 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TRANSACTIONERRORTYPE_DATATYPEVERSION 32384 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_TRANSACTIONERRORTYPE_DICTIONARYFRAGMENT 32385 /* Variable */ +#define UA_NS0ID_TRANSACTIONERRORTYPE_ENCODING_DEFAULTXML 32386 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TRANSACTIONERRORTYPE 32387 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TRANSACTIONERRORTYPE_DATATYPEVERSION 32388 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_TRANSACTIONERRORTYPE_DICTIONARYFRAGMENT 32389 /* Variable */ +#define UA_NS0ID_TRANSACTIONERRORTYPE_ENCODING_DEFAULTJSON 32390 /* Object */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCAPABLITIES_MAXDATASETWRITERSPERGROUP 32391 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCAPABLITIES_MAXNETWORKMESSAGESIZEDATAGRAM 32392 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCAPABLITIES_MAXNETWORKMESSAGESIZEBROKER 32393 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCAPABLITIES_SUPPORTSECURITYKEYPULL 32394 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_PUBSUBCAPABLITIES_SUPPORTSECURITYKEYPUSH 32395 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_DEFAULTSECURITYKEYSERVICES 32396 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBETYPE_CONFIGURATIONPROPERTIES 32397 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCAPABLITIES_MAXDATASETWRITERSPERGROUP 32398 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCAPABLITIES_MAXNETWORKMESSAGESIZEDATAGRAM 32399 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCAPABLITIES_MAXNETWORKMESSAGESIZEBROKER 32400 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCAPABLITIES_SUPPORTSECURITYKEYPULL 32401 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_PUBSUBCAPABLITIES_SUPPORTSECURITYKEYPUSH 32402 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_DEFAULTSECURITYKEYSERVICES 32403 /* Variable */ +#define UA_NS0ID_PUBLISHSUBSCRIBE_CONFIGURATIONPROPERTIES 32404 /* Variable */ +#define UA_NS0ID_DATASETCLASSES 32405 /* Object */ +#define UA_NS0ID_DATASETCLASSES_GETSECURITYKEYS 32406 /* Method */ +#define UA_NS0ID_DATASETCLASSES_GETSECURITYKEYS_INPUTARGUMENTS 32407 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_GETSECURITYKEYS_OUTPUTARGUMENTS 32408 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_GETSECURITYGROUP 32409 /* Method */ +#define UA_NS0ID_DATASETCLASSES_GETSECURITYGROUP_INPUTARGUMENTS 32410 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_GETSECURITYGROUP_OUTPUTARGUMENTS 32411 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SECURITYGROUPS 32412 /* Object */ +#define UA_NS0ID_DATASETCLASSES_SECURITYGROUPS_ADDSECURITYGROUP 32413 /* Method */ +#define UA_NS0ID_DATASETCLASSES_SECURITYGROUPS_ADDSECURITYGROUP_INPUTARGUMENTS 32414 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SECURITYGROUPS_ADDSECURITYGROUP_OUTPUTARGUMENTS 32415 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SECURITYGROUPS_REMOVESECURITYGROUP 32416 /* Method */ +#define UA_NS0ID_DATASETCLASSES_SECURITYGROUPS_REMOVESECURITYGROUP_INPUTARGUMENTS 32417 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SECURITYGROUPS_ADDSECURITYGROUPFOLDER 32418 /* Method */ +#define UA_NS0ID_DATASETCLASSES_SECURITYGROUPS_ADDSECURITYGROUPFOLDER_INPUTARGUMENTS 32419 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SECURITYGROUPS_ADDSECURITYGROUPFOLDER_OUTPUTARGUMENTS 32420 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SECURITYGROUPS_REMOVESECURITYGROUPFOLDER 32421 /* Method */ +#define UA_NS0ID_DATASETCLASSES_SECURITYGROUPS_REMOVESECURITYGROUPFOLDER_INPUTARGUMENTS 32422 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SECURITYGROUPS_SUPPORTEDSECURITYPOLICYURIS 32423 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_KEYPUSHTARGETS 32424 /* Object */ +#define UA_NS0ID_DATASETCLASSES_KEYPUSHTARGETS_ADDPUSHTARGET 32425 /* Method */ +#define UA_NS0ID_DATASETCLASSES_KEYPUSHTARGETS_ADDPUSHTARGET_INPUTARGUMENTS 32426 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_KEYPUSHTARGETS_ADDPUSHTARGET_OUTPUTARGUMENTS 32427 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_KEYPUSHTARGETS_REMOVEPUSHTARGET 32428 /* Method */ +#define UA_NS0ID_DATASETCLASSES_KEYPUSHTARGETS_REMOVEPUSHTARGET_INPUTARGUMENTS 32429 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_KEYPUSHTARGETS_ADDPUSHTARGETFOLDER 32430 /* Method */ +#define UA_NS0ID_DATASETCLASSES_KEYPUSHTARGETS_ADDPUSHTARGETFOLDER_INPUTARGUMENTS 32431 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_KEYPUSHTARGETS_ADDPUSHTARGETFOLDER_OUTPUTARGUMENTS 32432 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_KEYPUSHTARGETS_REMOVEPUSHTARGETFOLDER 32433 /* Method */ +#define UA_NS0ID_DATASETCLASSES_KEYPUSHTARGETS_REMOVEPUSHTARGETFOLDER_INPUTARGUMENTS 32434 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER 32435 /* Object */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_PUBLISHERID 32436 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_TRANSPORTPROFILEURI 32437 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_TRANSPORTPROFILEURI_SELECTIONS 32438 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_TRANSPORTPROFILEURI_SELECTIONDESCRIPTIONS 32439 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_TRANSPORTPROFILEURI_RESTRICTTOLIST 32440 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_CONNECTIONPROPERTIES 32441 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_ADDRESS 32442 /* Object */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_ADDRESS_NETWORKINTERFACE 32443 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_ADDRESS_NETWORKINTERFACE_SELECTIONS 32444 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_ADDRESS_NETWORKINTERFACE_SELECTIONDESCRIPTIONS 32445 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_ADDRESS_NETWORKINTERFACE_RESTRICTTOLIST 32446 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_TRANSPORTSETTINGS 32447 /* Object */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_STATUS 32448 /* Object */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_STATUS_STATE 32449 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_STATUS_ENABLE 32450 /* Method */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_STATUS_DISABLE 32451 /* Method */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS 32452 /* Object */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_DIAGNOSTICSLEVEL 32453 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION 32454 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 32455 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 32456 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 32457 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 32458 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR 32459 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_ACTIVE 32460 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 32461 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 32462 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 32463 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_RESET 32464 /* Method */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_SUBERROR 32465 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS 32466 /* Object */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR 32467 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 32468 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 32469 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 32470 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 32471 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 32472 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 32473 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 32474 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 32475 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 32476 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 32477 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 32478 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 32479 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 32480 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 32481 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 32482 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 32483 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 32484 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 32485 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 32486 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 32487 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 32488 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 32489 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 32490 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 32491 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 32492 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 32493 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 32494 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 32495 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 32496 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES 32497 /* Object */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_RESOLVEDADDRESS 32498 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_DIAGNOSTICS_LIVEVALUES_RESOLVEDADDRESS_DIAGNOSTICSLEVEL 32499 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_ADDWRITERGROUP 32500 /* Method */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_ADDWRITERGROUP_INPUTARGUMENTS 32501 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_ADDWRITERGROUP_OUTPUTARGUMENTS 32502 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_ADDREADERGROUP 32503 /* Method */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_ADDREADERGROUP_INPUTARGUMENTS 32504 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_ADDREADERGROUP_OUTPUTARGUMENTS 32505 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_REMOVEGROUP 32506 /* Method */ +#define UA_NS0ID_DATASETCLASSES_CONNECTIONNAME_PLACEHOLDER_REMOVEGROUP_INPUTARGUMENTS 32507 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SETSECURITYKEYS 32508 /* Method */ +#define UA_NS0ID_DATASETCLASSES_SETSECURITYKEYS_INPUTARGUMENTS 32509 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_ADDCONNECTION 32510 /* Method */ +#define UA_NS0ID_DATASETCLASSES_ADDCONNECTION_INPUTARGUMENTS 32511 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_ADDCONNECTION_OUTPUTARGUMENTS 32512 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_REMOVECONNECTION 32513 /* Method */ +#define UA_NS0ID_DATASETCLASSES_REMOVECONNECTION_INPUTARGUMENTS 32514 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS 32515 /* Object */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMS 32516 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMS_INPUTARGUMENTS 32517 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMS_OUTPUTARGUMENTS 32518 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTS 32519 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTS_INPUTARGUMENTS 32520 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTS_OUTPUTARGUMENTS 32521 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMSTEMPLATE 32522 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMSTEMPLATE_INPUTARGUMENTS 32523 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDPUBLISHEDDATAITEMSTEMPLATE_OUTPUTARGUMENTS 32524 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTSTEMPLATE 32525 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTSTEMPLATE_INPUTARGUMENTS 32526 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDPUBLISHEDEVENTSTEMPLATE_OUTPUTARGUMENTS 32527 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_REMOVEPUBLISHEDDATASET 32528 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_REMOVEPUBLISHEDDATASET_INPUTARGUMENTS 32529 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDDATASETFOLDER 32530 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDDATASETFOLDER_INPUTARGUMENTS 32531 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_ADDDATASETFOLDER_OUTPUTARGUMENTS 32532 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_REMOVEDATASETFOLDER 32533 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBLISHEDDATASETS_REMOVEDATASETFOLDER_INPUTARGUMENTS 32534 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SUBSCRIBEDDATASETS 32535 /* Object */ +#define UA_NS0ID_DATASETCLASSES_SUBSCRIBEDDATASETS_ADDSUBSCRIBEDDATASET 32536 /* Method */ +#define UA_NS0ID_DATASETCLASSES_SUBSCRIBEDDATASETS_ADDSUBSCRIBEDDATASET_INPUTARGUMENTS 32537 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SUBSCRIBEDDATASETS_ADDSUBSCRIBEDDATASET_OUTPUTARGUMENTS 32538 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SUBSCRIBEDDATASETS_REMOVESUBSCRIBEDDATASET 32539 /* Method */ +#define UA_NS0ID_DATASETCLASSES_SUBSCRIBEDDATASETS_REMOVESUBSCRIBEDDATASET_INPUTARGUMENTS 32540 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SUBSCRIBEDDATASETS_ADDDATASETFOLDER 32541 /* Method */ +#define UA_NS0ID_DATASETCLASSES_SUBSCRIBEDDATASETS_ADDDATASETFOLDER_INPUTARGUMENTS 32542 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SUBSCRIBEDDATASETS_ADDDATASETFOLDER_OUTPUTARGUMENTS 32543 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SUBSCRIBEDDATASETS_REMOVEDATASETFOLDER 32544 /* Method */ +#define UA_NS0ID_DATASETCLASSES_SUBSCRIBEDDATASETS_REMOVEDATASETFOLDER_INPUTARGUMENTS 32545 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION 32546 /* Object */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_SIZE 32547 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_WRITABLE 32548 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_USERWRITABLE 32549 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_OPENCOUNT 32550 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_MIMETYPE 32551 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_MAXBYTESTRINGLENGTH 32552 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_LASTMODIFIEDTIME 32553 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_OPEN 32554 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_OPEN_INPUTARGUMENTS 32555 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_OPEN_OUTPUTARGUMENTS 32556 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_CLOSE 32557 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_CLOSE_INPUTARGUMENTS 32558 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_READ 32559 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_READ_INPUTARGUMENTS 32560 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_READ_OUTPUTARGUMENTS 32561 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_WRITE 32562 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_WRITE_INPUTARGUMENTS 32563 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_GETPOSITION 32564 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_GETPOSITION_INPUTARGUMENTS 32565 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_GETPOSITION_OUTPUTARGUMENTS 32566 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_SETPOSITION 32567 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_SETPOSITION_INPUTARGUMENTS 32568 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_RESERVEIDS 32569 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_RESERVEIDS_INPUTARGUMENTS 32570 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_RESERVEIDS_OUTPUTARGUMENTS 32571 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_CLOSEANDUPDATE 32572 /* Method */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_CLOSEANDUPDATE_INPUTARGUMENTS 32573 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCONFIGURATION_CLOSEANDUPDATE_OUTPUTARGUMENTS 32574 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_STATUS 32575 /* Object */ +#define UA_NS0ID_DATASETCLASSES_STATUS_STATE 32576 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_STATUS_ENABLE 32577 /* Method */ +#define UA_NS0ID_DATASETCLASSES_STATUS_DISABLE 32578 /* Method */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS 32579 /* Object */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_DIAGNOSTICSLEVEL 32580 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_TOTALINFORMATION 32581 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_TOTALINFORMATION_ACTIVE 32582 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_TOTALINFORMATION_CLASSIFICATION 32583 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_TOTALINFORMATION_DIAGNOSTICSLEVEL 32584 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_TOTALINFORMATION_TIMEFIRSTCHANGE 32585 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_TOTALERROR 32586 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_TOTALERROR_ACTIVE 32587 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_TOTALERROR_CLASSIFICATION 32588 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_TOTALERROR_DIAGNOSTICSLEVEL 32589 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_TOTALERROR_TIMEFIRSTCHANGE 32590 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_RESET 32591 /* Method */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_SUBERROR 32592 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS 32593 /* Object */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEERROR 32594 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEERROR_ACTIVE 32595 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEERROR_CLASSIFICATION 32596 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEERROR_DIAGNOSTICSLEVEL 32597 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEERROR_TIMEFIRSTCHANGE 32598 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD 32599 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_ACTIVE 32600 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_CLASSIFICATION 32601 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_DIAGNOSTICSLEVEL 32602 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYMETHOD_TIMEFIRSTCHANGE 32603 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT 32604 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_ACTIVE 32605 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_CLASSIFICATION 32606 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_DIAGNOSTICSLEVEL 32607 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALBYPARENT_TIMEFIRSTCHANGE 32608 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR 32609 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_ACTIVE 32610 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_CLASSIFICATION 32611 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_DIAGNOSTICSLEVEL 32612 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEOPERATIONALFROMERROR_TIMEFIRSTCHANGE 32613 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT 32614 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_ACTIVE 32615 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_CLASSIFICATION 32616 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_DIAGNOSTICSLEVEL 32617 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEPAUSEDBYPARENT_TIMEFIRSTCHANGE 32618 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD 32619 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_ACTIVE 32620 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_CLASSIFICATION 32621 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_DIAGNOSTICSLEVEL 32622 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_COUNTERS_STATEDISABLEDBYMETHOD_TIMEFIRSTCHANGE 32623 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_LIVEVALUES 32624 /* Object */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETWRITERS 32625 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETWRITERS_DIAGNOSTICSLEVEL 32626 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETREADERS 32627 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_LIVEVALUES_CONFIGUREDDATASETREADERS_DIAGNOSTICSLEVEL 32628 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETWRITERS 32629 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETWRITERS_DIAGNOSTICSLEVEL 32630 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETREADERS 32631 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DIAGNOSTICS_LIVEVALUES_OPERATIONALDATASETREADERS_DIAGNOSTICSLEVEL 32632 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCAPABLITIES 32633 /* Object */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCAPABLITIES_MAXPUBSUBCONNECTIONS 32634 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCAPABLITIES_MAXWRITERGROUPS 32635 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCAPABLITIES_MAXREADERGROUPS 32636 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCAPABLITIES_MAXDATASETWRITERS 32637 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCAPABLITIES_MAXDATASETREADERS 32638 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCAPABLITIES_MAXDATASETWRITERSPERGROUP 32639 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCAPABLITIES_MAXNETWORKMESSAGESIZEDATAGRAM 32640 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCAPABLITIES_MAXNETWORKMESSAGESIZEBROKER 32641 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCAPABLITIES_SUPPORTSECURITYKEYPULL 32642 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCAPABLITIES_SUPPORTSECURITYKEYPUSH 32643 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DATASETCLASSES 32644 /* Object */ +#define UA_NS0ID_DATASETCLASSES_DATASETCLASSES_DATASETNAME_PLACEHOLDER 32645 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_SUPPORTEDTRANSPORTPROFILES 32646 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DEFAULTDATAGRAMPUBLISHERID 32647 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONFIGURATIONVERSION 32648 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_DEFAULTSECURITYKEYSERVICES 32649 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_CONFIGURATIONPROPERTIES 32650 /* Variable */ +#define UA_NS0ID_PUBSUBCAPABILITIESTYPE_MAXDATASETWRITERSPERGROUP 32651 /* Variable */ +#define UA_NS0ID_PUBSUBCAPABILITIESTYPE_MAXNETWORKMESSAGESIZEDATAGRAM 32652 /* Variable */ +#define UA_NS0ID_PUBSUBCAPABILITIESTYPE_MAXNETWORKMESSAGESIZEBROKER 32653 /* Variable */ +#define UA_NS0ID_PUBSUBCAPABILITIESTYPE_SUPPORTSECURITYKEYPULL 32654 /* Variable */ +#define UA_NS0ID_PUBSUBCAPABILITIESTYPE_SUPPORTSECURITYKEYPUSH 32655 /* Variable */ +#define UA_NS0ID_DATASETCLASSES_PUBSUBCAPABLITIES_MAXFIELDSPERDATASET 32656 /* Variable */ +#define UA_NS0ID_REFERENCEDESCRIPTIONVARIABLETYPE 32657 /* VariableType */ +#define UA_NS0ID_REFERENCEDESCRIPTIONVARIABLETYPE_REFERENCEREFINEMENT 32658 /* Variable */ +#define UA_NS0ID_REFERENCEDESCRIPTIONDATATYPE 32659 /* DataType */ +#define UA_NS0ID_REFERENCELISTENTRYDATATYPE 32660 /* DataType */ +#define UA_NS0ID_REFERENCEDESCRIPTIONDATATYPE_ENCODING_DEFAULTBINARY 32661 /* Object */ +#define UA_NS0ID_REFERENCELISTENTRYDATATYPE_ENCODING_DEFAULTBINARY 32662 /* Object */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_REFERENCEDESCRIPTIONDATATYPE 32663 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_REFERENCEDESCRIPTIONDATATYPE_DATATYPEVERSION 32664 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_REFERENCEDESCRIPTIONDATATYPE_DICTIONARYFRAGMENT 32665 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_REFERENCELISTENTRYDATATYPE 32666 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_REFERENCELISTENTRYDATATYPE_DATATYPEVERSION 32667 /* Variable */ +#define UA_NS0ID_OPCUA_BINARYSCHEMA_REFERENCELISTENTRYDATATYPE_DICTIONARYFRAGMENT 32668 /* Variable */ +#define UA_NS0ID_REFERENCEDESCRIPTIONDATATYPE_ENCODING_DEFAULTXML 32669 /* Object */ +#define UA_NS0ID_REFERENCELISTENTRYDATATYPE_ENCODING_DEFAULTXML 32670 /* Object */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_REFERENCEDESCRIPTIONDATATYPE 32671 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_REFERENCEDESCRIPTIONDATATYPE_DATATYPEVERSION 32672 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_REFERENCEDESCRIPTIONDATATYPE_DICTIONARYFRAGMENT 32673 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_REFERENCELISTENTRYDATATYPE 32674 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_REFERENCELISTENTRYDATATYPE_DATATYPEVERSION 32675 /* Variable */ +#define UA_NS0ID_OPCUA_XMLSCHEMA_REFERENCELISTENTRYDATATYPE_DICTIONARYFRAGMENT 32676 /* Variable */ +#define UA_NS0ID_REFERENCEDESCRIPTIONDATATYPE_ENCODING_DEFAULTJSON 32677 /* Object */ +#define UA_NS0ID_REFERENCELISTENTRYDATATYPE_ENCODING_DEFAULTJSON 32678 /* Object */ +#define UA_NS0ID_HASREFERENCEDESCRIPTION 32679 /* ReferenceType */ +#define UA_NS0ID_OPTIONSETLENGTH 32750 /* Variable */ +#endif /* UA_NODEIDS_NS0_H_ */ diff --git a/product/src/fes/include/open62541/plugin/accesscontrol.h b/product/src/fes/include/open62541/plugin/accesscontrol.h new file mode 100644 index 00000000..0ddb0d4b --- /dev/null +++ b/product/src/fes/include/open62541/plugin/accesscontrol.h @@ -0,0 +1,134 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + */ + +#ifndef UA_PLUGIN_ACCESS_CONTROL_H_ +#define UA_PLUGIN_ACCESS_CONTROL_H_ + +#include + +_UA_BEGIN_DECLS + +struct UA_AccessControl; +typedef struct UA_AccessControl UA_AccessControl; + +/** + * .. _access-control: + * + * Access Control Plugin API + * ========================= + * The access control callback is used to authenticate sessions and grant access + * rights accordingly. + * + * The ``sessionId`` and ``sessionContext`` can be both NULL. This is the case + * when, for example, a MonitoredItem (the underlying Subscription) is detached + * from its Session but continues to run. */ + +struct UA_AccessControl { + void *context; + void (*clear)(UA_AccessControl *ac); + + /* Supported login mechanisms. The server endpoints are created from here. */ + size_t userTokenPoliciesSize; + UA_UserTokenPolicy *userTokenPolicies; + + /* Authenticate a session. The session context is attached to the session + * and later passed into the node-based access control callbacks. The new + * session is rejected if a StatusCode other than UA_STATUSCODE_GOOD is + * returned. + * + * Note that this callback can be called several times for a Session. For + * example when a Session is recovered (activated) on a new + * SecureChannel. */ + UA_StatusCode (*activateSession)(UA_Server *server, UA_AccessControl *ac, + const UA_EndpointDescription *endpointDescription, + const UA_ByteString *secureChannelRemoteCertificate, + const UA_NodeId *sessionId, + const UA_ExtensionObject *userIdentityToken, + void **sessionContext); + + /* Deauthenticate a session and cleanup */ + void (*closeSession)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext); + + /* Access control for all nodes*/ + UA_UInt32 (*getUserRightsMask)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeId, void *nodeContext); + + /* Additional access control for variable nodes */ + UA_Byte (*getUserAccessLevel)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeId, void *nodeContext); + + /* Additional access control for method nodes */ + UA_Boolean (*getUserExecutable)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *methodId, void *methodContext); + + /* Additional access control for calling a method node in the context of a + * specific object */ + UA_Boolean (*getUserExecutableOnObject)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext); + + /* Allow adding a node */ + UA_Boolean (*allowAddNode)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_AddNodesItem *item); + + /* Allow adding a reference */ + UA_Boolean (*allowAddReference)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_AddReferencesItem *item); + + /* Allow deleting a node */ + UA_Boolean (*allowDeleteNode)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_DeleteNodesItem *item); + + /* Allow deleting a reference */ + UA_Boolean (*allowDeleteReference)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_DeleteReferencesItem *item); + + /* Allow browsing a node */ + UA_Boolean (*allowBrowseNode)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeId, void *nodeContext); + +#ifdef UA_ENABLE_SUBSCRIPTIONS + /* Allow transfer of a subscription to another session. The Server shall + * validate that the Client of that Session is operating on behalf of the + * same user */ + UA_Boolean (*allowTransferSubscription)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *oldSessionId, void *oldSessionContext, + const UA_NodeId *newSessionId, void *newSessionContext); +#endif + +#ifdef UA_ENABLE_HISTORIZING + /* Allow insert,replace,update of historical data */ + UA_Boolean (*allowHistoryUpdateUpdateData)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeId, + UA_PerformUpdateType performInsertReplace, + const UA_DataValue *value); + + /* Allow delete of historical data */ + UA_Boolean (*allowHistoryUpdateDeleteRawModified)(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeId, + UA_DateTime startTimestamp, + UA_DateTime endTimestamp, + bool isDeleteModified); +#endif +}; + +_UA_END_DECLS + +#endif /* UA_PLUGIN_ACCESS_CONTROL_H_ */ diff --git a/product/src/fes/include/open62541/plugin/accesscontrol_default.h b/product/src/fes/include/open62541/plugin/accesscontrol_default.h new file mode 100644 index 00000000..f593b6a4 --- /dev/null +++ b/product/src/fes/include/open62541/plugin/accesscontrol_default.h @@ -0,0 +1,52 @@ +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2016-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + */ + +#ifndef UA_ACCESSCONTROL_DEFAULT_H_ +#define UA_ACCESSCONTROL_DEFAULT_H_ + +#include +#include + +_UA_BEGIN_DECLS + +typedef struct { + UA_String username; + UA_String password; +} UA_UsernamePasswordLogin; + +typedef UA_StatusCode (*UA_UsernamePasswordLoginCallback) + (const UA_String *userName, const UA_ByteString *password, + size_t usernamePasswordLoginSize, const UA_UsernamePasswordLogin + *usernamePasswordLogin, void **sessionContext, void *loginContext); + +/* Default access control. The login can be anonymous, username-password or + * certificate-based. A logged-in user has all access rights. + * + * The plugin stores the UserIdentityToken in the session context. So that + * cannot be used for other purposes. + * + * The certificate verification plugin lifecycle is moved to the access control + * system. So it is cleared up eventually together with the AccessControl. */ +UA_EXPORT UA_StatusCode +UA_AccessControl_default(UA_ServerConfig *config, + UA_Boolean allowAnonymous, + const UA_ByteString *userTokenPolicyUri, + size_t usernamePasswordLoginSize, + const UA_UsernamePasswordLogin *usernamePasswordLogin); + +UA_EXPORT UA_StatusCode +UA_AccessControl_defaultWithLoginCallback(UA_ServerConfig *config, + UA_Boolean allowAnonymous, + const UA_ByteString *userTokenPolicyUri, + size_t usernamePasswordLoginSize, + const UA_UsernamePasswordLogin *usernamePasswordLogin, + UA_UsernamePasswordLoginCallback loginCallback, + void *loginContext); + +_UA_END_DECLS + +#endif /* UA_ACCESSCONTROL_DEFAULT_H_ */ diff --git a/product/src/fes/include/open62541/plugin/create_certificate.h b/product/src/fes/include/open62541/plugin/create_certificate.h new file mode 100644 index 00000000..7d48290f --- /dev/null +++ b/product/src/fes/include/open62541/plugin/create_certificate.h @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2021 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati) + */ + +#ifndef CREATE_CERTIFICATE_H_ +#define CREATE_CERTIFICATE_H_ + +#include +#include +#include + +_UA_BEGIN_DECLS + +#ifdef UA_ENABLE_ENCRYPTION +typedef enum { + UA_CERTIFICATEFORMAT_DER, + UA_CERTIFICATEFORMAT_PEM +} UA_CertificateFormat; + +/** + * Create a self-signed certificate + * + * It is recommended to store the generated certificate on disk for reuse, so the + * application can be recognized across several executions. + * + * \param subject Elements for the subject, + * e.g. ["C=DE", "O=SampleOrganization", "CN=Open62541Server@localhost"] + * \param subjectAltName Elements for SubjectAltName, + * e.g. ["DNS:localhost", "URI:urn:open62541.server.application"] + * \param params key value map with optional parameters: + * - expires-in-days after these the cert expires default: 365 + * - key-size-bits Size of the generated key in bits. Possible values are: + * [0, 1024 (deprecated), 2048, 4096] default: 4096 + */ +UA_StatusCode UA_EXPORT +UA_CreateCertificate(const UA_Logger *logger, const UA_String *subject, + size_t subjectSize, const UA_String *subjectAltName, + size_t subjectAltNameSize, UA_CertificateFormat certFormat, + UA_KeyValueMap *params, UA_ByteString *outPrivateKey, + UA_ByteString *outCertificate); +#endif + +_UA_END_DECLS + +#endif /* CREATE_CERTIFICATE_H_ */ diff --git a/product/src/fes/include/open62541/plugin/eventloop.h b/product/src/fes/include/open62541/plugin/eventloop.h new file mode 100644 index 00000000..22351999 --- /dev/null +++ b/product/src/fes/include/open62541/plugin/eventloop.h @@ -0,0 +1,690 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2021 (c) Fraunhofer IOSB (Author: Jan Hermes) + */ + +#ifndef UA_EVENTLOOP_H_ +#define UA_EVENTLOOP_H_ + +#include +#include +#include +#include + +_UA_BEGIN_DECLS + +struct UA_EventLoop; +typedef struct UA_EventLoop UA_EventLoop; + +struct UA_EventSource; +typedef struct UA_EventSource UA_EventSource; + +struct UA_ConnectionManager; +typedef struct UA_ConnectionManager UA_ConnectionManager; + +struct UA_InterruptManager; +typedef struct UA_InterruptManager UA_InterruptManager; + +/** + * Event Loop Subsystem + * ==================== + * An OPC UA-enabled application can have several clients and servers. And + * server can serve different transport-level protocols for OPC UA. The + * EventLoop is a central module that provides a unified control-flow for all of + * these. Hence, several applications can share an EventLoop. + * + * The EventLoop and the ConnectionManager implementation is + * architecture-specific. The goal is to have a single call to "poll" (epoll, + * kqueue, ...) in the EventLoop that covers all ConnectionManagers. Hence the + * EventLoop plugin implementation must know implementation details of the + * ConnectionManager implementations. So the EventLoop can extract socket + * information, etc. from the ConnectionManagers. + * + * Timer Policies + * -------------- + * A timer comes with a cyclic interval in which a callback is executed. If an + * application is congested the interval can be missed. Two different policies + * can be used when this happens. Either schedule the next execution after the + * interval has elapsed again from the current time onwards or stay within the + * regular interval with respect to the original basetime. */ + +typedef enum { + UA_TIMER_HANDLE_CYCLEMISS_WITH_CURRENTTIME, + UA_TIMER_HANDLE_CYCLEMISS_WITH_BASETIME +} UA_TimerPolicy; + +/** + * Event Loop + * ---------- + * The EventLoop implementation is part of the selected architecture. For + * example, "Win32/POSIX" stands for a Windows environment with an EventLoop + * that uses the POSIX API. Several EventLoops can be instantiated in parallel. + * But the globally defined functions are the same everywhere. */ + +typedef void (*UA_Callback)(void *application, void *context); + +/* Delayed callbacks are executed not when they are registered, but in the + * following EventLoop cycle */ +typedef struct UA_DelayedCallback { + struct UA_DelayedCallback *next; /* Singly-linked list */ + UA_Callback callback; + void *application; + void *context; +} UA_DelayedCallback; + +typedef enum { + UA_EVENTLOOPSTATE_FRESH = 0, + UA_EVENTLOOPSTATE_STOPPED, + UA_EVENTLOOPSTATE_STARTED, + UA_EVENTLOOPSTATE_STOPPING /* Stopping in progress, needs EventLoop + * cycles to finish */ +} UA_EventLoopState; + +struct UA_EventLoop { + /* Configuration + * ~~~~~~~~~~~~~~~ + * The configuration should be set before the EventLoop is started */ + + const UA_Logger *logger; + UA_KeyValueMap *params; /* See the implementation-specific documentation */ + + /* EventLoop Lifecycle + * ~~~~~~~~~~~~~~~~~~~~ + * The EventLoop state also controls the state of the configured + * EventSources. Stopping the EventLoop gracefully closes e.g. the open + * network connections. The only way to process incoming events is to call + * the 'run' method. Events are then triggering their respective callbacks + * from within that method.*/ + + const volatile UA_EventLoopState state; /* Only read the state from outside */ + + /* Start the EventLoop and start all already registered EventSources */ + UA_StatusCode (*start)(UA_EventLoop *el); + + /* Stop all EventSources. This is asynchronous and might need a few + * iterations of the main-loop to succeed. */ + void (*stop)(UA_EventLoop *el); + + /* Process events for at most "timeout" ms or until an unrecoverable error + * occurs. If timeout==0, then only already received events are + * processed. */ + UA_StatusCode (*run)(UA_EventLoop *el, UA_UInt32 timeout); + + /* Clean up the EventLoop and free allocated memory. Can fail if the + * EventLoop is not stopped. */ + UA_StatusCode (*free)(UA_EventLoop *el); + + /* EventLoop Time Domain + * ~~~~~~~~~~~~~~~~~~~~~ + * Each EventLoop instance can manage its own time domain. This affects the + * execution of timed/cyclic callbacks and time-based sending of network + * packets (if this is implemented). Managing independent time domains is + * important when different parts of a system a synchronized to different + * external (network-wide) clocks. + * + * Note that the logger configured in the EventLoop generates timestamps + * internally as well. If the logger uses a different time domain than the + * EventLoop, discrepancies may appear in the logs. + * + * The time domain of the EventLoop is exposed via the following functons. + * See `open62541/types.h` for the documentation of their equivalent + * globally defined functions. */ + + UA_DateTime (*dateTime_now)(UA_EventLoop *el); + UA_DateTime (*dateTime_nowMonotonic)(UA_EventLoop *el); + UA_Int64 (*dateTime_localTimeUtcOffset)(UA_EventLoop *el); + + /* Timed Callbacks + * ~~~~~~~~~~~~~~~ + * Cyclic callbacks are executed regularly with an interval. + * A timed callback is executed only once. */ + + /* Time of the next cyclic callback. Returns the max DateTime if no cyclic + * callback is registered. */ + UA_DateTime (*nextCyclicTime)(UA_EventLoop *el); + + /* The execution interval is in ms. Returns the callbackId if the pointer is + * non-NULL. */ + UA_StatusCode + (*addCyclicCallback)(UA_EventLoop *el, UA_Callback cb, void *application, + void *data, UA_Double interval_ms, UA_DateTime *baseTime, + UA_TimerPolicy timerPolicy, UA_UInt64 *callbackId); + + UA_StatusCode + (*modifyCyclicCallback)(UA_EventLoop *el, UA_UInt64 callbackId, + UA_Double interval_ms, UA_DateTime *baseTime, + UA_TimerPolicy timerPolicy); + + void (*removeCyclicCallback)(UA_EventLoop *el, UA_UInt64 callbackId); + + /* Like a cyclic callback, but executed only once */ + UA_StatusCode + (*addTimedCallback)(UA_EventLoop *el, UA_Callback cb, void *application, + void *data, UA_DateTime date, UA_UInt64 *callbackId); + + /* Delayed Callbacks + * ~~~~~~~~~~~~~~~~~ + * Delayed callbacks are executed once in the next iteration of the + * EventLoop and then deregistered automatically. A typical use case is to + * delay a resource cleanup to a point where it is known that the resource + * has no remaining users. + * + * The delayed callbacks are processed in each of the cycle of the EventLoop + * between the handling of timed cyclic callbacks and polling for (network) + * events. The memory for the delayed callback is *NOT* automatically freed + * after the execution. */ + + void (*addDelayedCallback)(UA_EventLoop *el, UA_DelayedCallback *dc); + void (*removeDelayedCallback)(UA_EventLoop *el, UA_DelayedCallback *dc); + + /* EventSources + * ~~~~~~~~~~~~ + * EventSources are stored in a singly-linked list for direct access. But + * only the below methods shall be used for adding and removing - this + * impacts the lifecycle of the EventSource. For example it may be + * auto-started if the EventLoop is already running. */ + + /* Linked list of EventSources */ + UA_EventSource *eventSources; + + /* Register the ES. Immediately starts the ES if the EventLoop is already + * started. Otherwise the ES is started together with the EventLoop. */ + UA_StatusCode + (*registerEventSource)(UA_EventLoop *el, UA_EventSource *es); + + /* Stops the EventSource before deregistrering it */ + UA_StatusCode + (*deregisterEventSource)(UA_EventLoop *el, UA_EventSource *es); + + /* Locking + * ~~~~~~~ + * + * For multi-threading the EventLoop is protected by a mutex. The mutex is + * expected to be recursive (can be taken more than once from the same + * thread). A common approach to avoid deadlocks is to establish an absolute + * ordering between the locks. Where the "lower" locks needs to be taken + * before the "upper" lock. The EventLoop-mutex is exposed here to allow it + * to be taken from the outside. */ + void (*lock)(UA_EventLoop *el); + void (*unlock)(UA_EventLoop *el); +}; + +/** + * Event Source + * ------------ + * Event Sources are attached to an EventLoop. Typically the event source and + * the EventLoop are developed together and share a private API in the + * background. */ + +typedef enum { + UA_EVENTSOURCESTATE_FRESH = 0, + UA_EVENTSOURCESTATE_STOPPED, /* Registered but stopped */ + UA_EVENTSOURCESTATE_STARTING, + UA_EVENTSOURCESTATE_STARTED, + UA_EVENTSOURCESTATE_STOPPING /* Stopping in progress, needs + * EventLoop cycles to finish */ +} UA_EventSourceState; + +/* Type-tag for proper casting of the difference EventSource (e.g. when they are + * looked up via UA_EventLoop_findEventSource). */ +typedef enum { + UA_EVENTSOURCETYPE_CONNECTIONMANAGER, + UA_EVENTSOURCETYPE_INTERRUPTMANAGER +} UA_EventSourceType; + +struct UA_EventSource { + struct UA_EventSource *next; /* Singly-linked list for use by the + * application that registered the ES */ + + UA_EventSourceType eventSourceType; + + /* Configuration + * ~~~~~~~~~~~~~ */ + UA_String name; /* Unique name of the ES */ + UA_EventLoop *eventLoop; /* EventLoop where the ES is registered */ + UA_KeyValueMap params; + + /* Lifecycle + * ~~~~~~~~~ */ + UA_EventSourceState state; + UA_StatusCode (*start)(UA_EventSource *es); + void (*stop)(UA_EventSource *es); /* Asynchronous. Iterate theven EventLoop + * until the EventSource is stopped. */ + UA_StatusCode (*free)(UA_EventSource *es); +}; + +/** + * Connection Manager + * ------------------ + * Every Connection is created by a ConnectionManager. Every ConnectionManager + * belongs to just one application. A ConnectionManager can act purely as a + * passive "Factory" for Connections. But it can also be stateful. For example, + * it can keep a session to an MQTT broker open which is used by individual + * connections that are each bound to an MQTT topic. */ + +/* The ConnectionCallback is the only interface from the connection back to + * the application. + * + * - The connectionId is initially unknown to the target application and + * "announced" to the application when first used first in this callback. + * + * - The context is attached to the connection. Initially a default context + * is set. The context can be replaced within the callback (via the + * double-pointer). + * + * - The state argument indicates the lifecycle of the connection. Every + * connection calls the callback a last time with UA_CONNECTIONSTATE_CLOSING. + * Protocols individually can forward diagnostic information relevant to the + * state as part of the key-value parameters. + * + * - The parameters are a key-value list with additional information. The + * possible keys and their meaning are documented for the individual + * ConnectionManager implementations. + * + * - The msg ByteString is the message (or packet) received on the + * connection. Can be empty. */ +typedef void +(*UA_ConnectionManager_connectionCallback) + (UA_ConnectionManager *cm, uintptr_t connectionId, + void *application, void **connectionContext, UA_ConnectionState state, + const UA_KeyValueMap *params, UA_ByteString msg); + +struct UA_ConnectionManager { + /* Every ConnectionManager is treated like an EventSource from the + * perspective of the EventLoop. */ + UA_EventSource eventSource; + + /* Name of the protocol supported by the ConnectionManager. For example + * "mqtt", "udp", "mqtt". */ + UA_String protocol; + + /* Open a Connection + * ~~~~~~~~~~~~~~~~~ + * Connecting is asynchronous. The connection-callback is called when the + * connection is open (status=GOOD) or aborted (status!=GOOD) when + * connecting failed. + * + * Some ConnectionManagers can also passively listen for new connections. + * Configuration parameters for this are passed via the key-value list. The + * `context` pointer of the listening connection is also set as the initial + * context of newly opened connections. + * + * The parameters describe the connection. For example hostname and port + * (for TCP). Other protocols (e.g. MQTT, AMQP, etc.) may required + * additional arguments to open a connection in the key-value list. + * + * The provided context is set as the initial context attached to this + * connection. It is already set before the first call to + * connectionCallback. + * + * The connection can be opened synchronously or asynchronously. + * + * - For synchronous connection, the connectionCallback is called with the + * status UA_CONNECTIONSTATE_ESTABLISHED immediately from within the + * openConnection operation. + * + * - In the asynchronous case the connectionCallback is called immediately + * from within the openConnection operation with the status + * UA_CONNECTIONSTATE_OPENING. The connectionCallback is called with the + * status UA_CONNECTIONSTATE_ESTABLISHED once the connection has fully + * opened. + * + * Note that a single call to openConnection might open multiple + * connections. For example listening on IPv4 and IPv6 for a single + * hostname. Each protocol implementation documents whether multiple + * connections might be opened at once. */ + UA_StatusCode + (*openConnection)(UA_ConnectionManager *cm, const UA_KeyValueMap *params, + void *application, void *context, + UA_ConnectionManager_connectionCallback connectionCallback); + + /* Send a message over a Connection + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Sending is asynchronous. That is, the function returns before the message + * is ACKed from remote. The memory for the buffer is expected to be + * allocated with allocNetworkBuffer and is released internally (also if + * sending fails). + * + * Some ConnectionManagers can accept additional parameters for sending. For + * example a tx-time for sending in time-synchronized TSN settings. */ + UA_StatusCode + (*sendWithConnection)(UA_ConnectionManager *cm, uintptr_t connectionId, + const UA_KeyValueMap *params, UA_ByteString *buf); + + /* Close a Connection + * ~~~~~~~~~~~~~~~~~~ + * When a connection is closed its `connectionCallback` is called with + * (status=BadConnectionClosed, msg=empty). Then the connection is cleared + * up inside the ConnectionManager. This is the case both for connections + * that are actively closed and those that are closed remotely. The return + * code is non-good only if the connection is already closed. */ + UA_StatusCode + (*closeConnection)(UA_ConnectionManager *cm, uintptr_t connectionId); + + /* Buffer Management + * ~~~~~~~~~~~~~~~~~ + * Each ConnectionManager allocates and frees his own memory for the network + * buffers. This enables, for example, zero-copy neworking mechanisms. The + * connectionId is part of the API to enable cases where memory is + * statically allocated for every connection */ + UA_StatusCode + (*allocNetworkBuffer)(UA_ConnectionManager *cm, uintptr_t connectionId, + UA_ByteString *buf, size_t bufSize); + void + (*freeNetworkBuffer)(UA_ConnectionManager *cm, uintptr_t connectionId, + UA_ByteString *buf); +}; + +/** + * Interrupt Manager + * ----------------- + * The Interrupt Manager allows to register to listen for system interrupts. + * Triggering the interrupt calls the callback associated with it. + * + * The implementations of the interrupt manager for the different platforms + * shall be designed such that: + * + * - Registered interrupts are only intercepted from within the running EventLoop + * - Processing an interrupt in the EventLoop is handled similarly to handling a + * network event: all methods and also memory allocation are available from + * within the interrupt callback. */ + +/* Interrupts can have additional key-value 'instanceInfos' for each individual + * triggering. See the architecture-specific documentation. */ +typedef void +(*UA_InterruptCallback)(UA_InterruptManager *im, + uintptr_t interruptHandle, void *interruptContext, + const UA_KeyValueMap *instanceInfos); + +struct UA_InterruptManager { + /* Every InterruptManager is treated like an EventSource from the + * perspective of the EventLoop. */ + UA_EventSource eventSource; + + /* Register an interrupt. The handle and context information is passed + * through to the callback. + * + * The interruptHandle is a numerical identifier of the interrupt. In some + * cases, such as POSIX signals, this is enough information to register + * callback. For other interrupt systems (architectures) additional + * parameters may be required and can be passed in via the parameters + * key-value list. See the implementation-specific documentation. + * + * The interruptContext is opaque user-defined information and passed + * through to the callback without modification. */ + UA_StatusCode + (*registerInterrupt)(UA_InterruptManager *im, uintptr_t interruptHandle, + const UA_KeyValueMap *params, + UA_InterruptCallback callback, void *interruptContext); + + /* Remove a registered interrupt. Returns no error code if the interrupt is + * already deregistered. */ + void + (*deregisterInterrupt)(UA_InterruptManager *im, uintptr_t interruptHandle); +}; + +/** + * POSIX-Specific Implementation + * ----------------------------- + * The POSIX compatibility of WIN32 is 'close enough'. So a joint implementation + * is provided. */ + +#if defined(UA_ARCHITECTURE_POSIX) || defined(UA_ARCHITECTURE_WIN32) + +UA_EXPORT UA_EventLoop * +UA_EventLoop_new_POSIX(const UA_Logger *logger); + +/** + * TCP Connection Manager + * ~~~~~~~~~~~~~~~~~~~~~~ + * Listens on the network and manages TCP connections. This should be available + * for all architectures. + * + * The `openConnection` callback is used to create both client and server + * sockets. A server socket listens and accepts incoming connections (creates an + * active connection). This is distinguished by the key-value parameters passed + * to `openConnection`. Note that a single call to `openConnection` for a server + * connection may actually create multiple connections (one per hostname / + * device). + * + * The `connectionCallback` of the server socket and `context` of the server + * socket is reused for each new connection. But the key-value parameters for + * the first callback are different between server and client connections. + * + * The following list defines the parameters and their type. Note that some + * parameters are only set for the first callback when a new connection opens. + * + * **Configuration parameters for the entire ConnectionManager:** + * + * 0:recv-bufsize [uint32] + * Size of the buffer that is allocated for receiving messages (default 64kB). + * + * **Open Connection Parameters:** + * + * 0:address [string | array of string] + * Hostname or IPv4/v6 address for the connection (scalar parameter required + * for active connections). For listen-connections the address contains the + * local hostnames or IP addresses for listening. If undefined, listen on all + * interfaces INADDR_ANY. (default: undefined) + * + * 0:port [uint16] + * Port of the target host (required). + * + * 0:listen [boolean] + * Listen-connection or active-connection (default: false) + * + * 0:validate [boolean] + * If true, the connection setup will act as a dry-run without actually + * creating any connection but solely validating the provided parameters + * (default: false) + * + * **Active Connection Connection Callback Parameters (first callback only):** + * + * 0:remote-address [string] + * Address of the remote side (hostname or IP address). + * + * **Listen Connection Connection Callback Parameters (first callback only):** + * + * 0:listen-address [string] + * Local address (IP or hostname) for the new listen-connection. + * + * 0:listen-port [uint16] + * Port on which the new connection listens. + * + * **Send Parameters:** + * + * No additional parameters for sending over an established TCP socket + * defined. */ +UA_EXPORT UA_ConnectionManager * +UA_ConnectionManager_new_POSIX_TCP(const UA_String eventSourceName); + +/** + * UDP Connection Manager + * ~~~~~~~~~~~~~~~~~~~~~~ + * Manages UDP connections. This should be available for all architectures. The + * configuration parameters have to set before calling _start to take effect. + * + * **Configuration Parameters:** + * + * 0:recv-bufsize [uint32] + * Size of the buffer that is allocated for receiving messages (default + * 64kB). + * + * **Open Connection Parameters:** + * + * 0:listen [boolean] + * Use the connection for listening or for sending (default: false) + * + * 0:address [string | string array] + * Hostname (or IPv4/v6 address) for sending or receiving. A scalar is + * required for sending. For listening a string array for the list-hostnames + * is possible as well (default: list on all hostnames). + * + * 0:port [uint16] + * Port for sending or listening (required). + * + * 0:interface [string] + * Network interface for listening or sending (e.g. when using multicast + * addresses). Can be either the IP address of the network interface + * or the interface name (e.g. 'eth0'). + * + * 0:ttl [uint32] + * Multicast time to live, (optional, default: 1 - meaning multicast is + * available only to the local subnet). + * + * 0:loopback [boolean] + * Whether or not to use multicast loopback, enabling local interfaces + * belonging to the multicast group to receive packages. (default: enabled). + * + * 0:reuse [boolean] + * Enables sharing of the same listening address on different sockets + * (default: disabled). + * + * 0:sockpriority [uint32] + * The socket priority (optional) - only available on linux. packets with a + * higher priority may be processed first depending on the selected device + * queueing discipline. Setting a priority outside the range 0 to 6 requires + * the CAP_NET_ADMIN capability (on Linux). + * + * 0:validate [boolean] + * If true, the connection setup will act as a dry-run without actually + * creating any connection but solely validating the provided parameters + * (default: false) + * + * **Connection Callback Parameters:** + * + * 0:remote-address [string] + * Contains the remote IP address. + * + * 0:remote-port [uint16] + * Contains the remote port. + * + * **Send Parameters:** + * + * No additional parameters for sending over an UDP connection defined. */ +UA_EXPORT UA_ConnectionManager * +UA_ConnectionManager_new_POSIX_UDP(const UA_String eventSourceName); + +#if defined(__linux__) /* Linux only so far */ +/** + * Ethernet Connection Manager + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Listens on the network and manages UDP connections. This should be available + * for all architectures. The configuration parameters have to set before + * calling _start to take effect. + * + * **Open Connection Parameters:** + * + * 0:listen [bool] + * The connection is either for sending or for listening (default: false). + * + * 0:interface [string] + * The name of the Ethernet interface to use (required). + * + * 0:address [string] + * MAC target address consisting of six groups of hexadecimal digits + * separated by hyphens such as 01-23-45-67-89-ab. For sending this is a + * required parameter. For listening this is a multicast address that the + * connections tries to register for. + * + * 0:ethertype [uint16] + * EtherType for sending and receiving frames (optional). For listening + * connections, this filters out all frames with different EtherTypes. + * + * 0:promiscuous [bool] + * Receive frames also for different target addresses. Defined only for + * listening connections (default: false). + * + * 0:vid [uint16] + * 12-bit VLAN identifier (optional for send connections). + * + * 0:pcp [byte] + * 3-bit priority code point (optional for send connections). + * + * 0:dei [bool] + * 1-bit drop eligible indicator (optional for seond connections). + * + * 0:validate [boolean] + * If true, the connection setup will act as a dry-run without actually + * creating any connection but solely validating the provided parameters + * (default: false) + * + * **Send Parameters:** + * + * No additional parameters for sending over an Ethernet connection defined. */ +UA_EXPORT UA_ConnectionManager * +UA_ConnectionManager_new_POSIX_Ethernet(const UA_String eventSourceName); +#endif + +/** + * MQTT Connection Manager + * ~~~~~~~~~~~~~~~~~~~~~~~ + * The MQTT ConnectionManager reuses the TCP ConnectionManager that is + * configured in the EventLoop. Hence the MQTT ConnectionManager is platform + * agnostic and does not require porting. An MQTT connection is for a + * combination of broker and topic. The MQTT ConnectionManager can group + * connections to the same broker in the background. Hence adding multiple + * connections for the same broker is "cheap". To have individual control, + * separate connections are created for each topic and for each direction + * (publishing / subscribing). + * + * **Open Connection Parameters:** + * + * 0:address [string] + * Hostname or IPv4/v6 address of the MQTT broker (required). + * + * 0:port [uint16] + * Port of the MQTT broker (default: 1883). + * + * 0:username [string] + * Username to use (default: none) + * + * 0:password [string] + * Password to use (default: none) + * + * 0:keep-alive [uint16] + * Number of seconds for the keep-alive (ping) (default: 400). + * + * 0:validate [boolean] + * If true, the connection setup will act as a dry-run without actually + * creating any connection but solely validating the provided parameters + * (default: false) + * + * 0:topic [string] + * Topic to which the connection is associated (required). + * + * 0:subscribe [bool] + * Subscribe to the topic (default: false). Otherwise it is only possible to + * publish on the topic. Subscribed topics can also be published to. + * + * **Connection Callback Parameters:** + * + * 0:topic [string] + * The value set during connect. + * + * 0:subscribe [bool] + * The value set during connect. + * + * **Send Parameters:** + * + * No additional parameters for sending over an Ethernet connection defined. */ +UA_EXPORT UA_ConnectionManager * +UA_ConnectionManager_new_MQTT(const UA_String eventSourceName); + +/** + * Signal Interrupt Manager + * ~~~~~~~~~~~~~~~~~~~~~~~~ + * Create an instance of the interrupt manager that handles POSX signals. This + * interrupt manager takes the numerical interrupt identifiers from + * for the interruptHandle. */ +UA_EXPORT UA_InterruptManager * +UA_InterruptManager_new_POSIX(const UA_String eventSourceName); + +#endif /* defined(UA_ARCHITECTURE_POSIX) || defined(UA_ARCHITECTURE_WIN32) */ + +_UA_END_DECLS + +#endif /* UA_EVENTLOOP_H_ */ diff --git a/product/src/fes/include/open62541/plugin/historydata/history_data_backend.h b/product/src/fes/include/open62541/plugin/historydata/history_data_backend.h new file mode 100644 index 00000000..e7722f3a --- /dev/null +++ b/product/src/fes/include/open62541/plugin/historydata/history_data_backend.h @@ -0,0 +1,291 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2018 (c) basysKom GmbH (Author: Peter Rustler) + */ + +#ifndef UA_PLUGIN_HISTORY_DATA_BACKEND_H_ +#define UA_PLUGIN_HISTORY_DATA_BACKEND_H_ + +#include + +_UA_BEGIN_DECLS + +typedef enum { + MATCH_EQUAL, /* Match with the exact timestamp. */ + MATCH_AFTER, /* Match the value with the timestamp in the + database that is the first later in time from the provided timestamp. */ + MATCH_EQUAL_OR_AFTER, /* Match exactly if possible, or the first timestamp + later in time from the provided timestamp. */ + MATCH_BEFORE, /* Match the first timestamp in the database that is earlier + in time from the provided timestamp. */ + MATCH_EQUAL_OR_BEFORE /* Match exactly if possible, or the first timestamp + that is earlier in time from the provided timestamp. */ +} MatchStrategy; + +typedef struct UA_HistoryDataBackend UA_HistoryDataBackend; + +struct UA_HistoryDataBackend { + void *context; + + void + (*deleteMembers)(UA_HistoryDataBackend *backend); + + /* This function sets a DataValue for a node in the historical data storage. + * + * server is the server the node lives in. + * hdbContext is the context of the UA_HistoryDataBackend. + * sessionId and sessionContext identify the session that wants to read historical data. + * nodeId is the node for which the value shall be stored. + * value is the value which shall be stored. + * historizing is the historizing flag of the node identified by nodeId. + * If sessionId is NULL, the historizing flag is invalid and must not be used. */ + UA_StatusCode + (*serverSetHistoryData)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + UA_Boolean historizing, + const UA_DataValue *value); + + /* This function is the high level interface for the ReadRaw operation. Set + * it to NULL if you use the low level API for your plugin. It should be + * used if the low level interface does not suite your database. It is more + * complex to implement the high level interface but it also provide more + * freedom. If you implement this, then set all low level api function + * pointer to NULL. + * + * server is the server the node lives in. + * hdbContext is the context of the UA_HistoryDataBackend. + * sessionId and sessionContext identify the session that wants to read historical data. + * backend is the HistoryDataBackend whose storage is to be queried. + * start is the start time of the HistoryRead request. + * end is the end time of the HistoryRead request. + * nodeId is the node id of the node for which historical data is requested. + * maxSizePerResponse is the maximum number of items per response the server can provide. + * numValuesPerNode is the maximum number of items per response the client wants to receive. + * returnBounds determines if the client wants to receive bounding values. + * timestampsToReturn contains the time stamps the client is interested in. + * range is the numeric range the client wants to read. + * releaseContinuationPoints determines if the continuation points shall be released. + * continuationPoint is the continuation point the client wants to release or start from. + * outContinuationPoint is the continuation point that gets passed to the + * client by the HistoryRead service. + * result contains the result histoy data that gets passed to the client. */ + UA_StatusCode + (*getHistoryData)(UA_Server *server, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_HistoryDataBackend *backend, + const UA_DateTime start, + const UA_DateTime end, + const UA_NodeId *nodeId, + size_t maxSizePerResponse, + UA_UInt32 numValuesPerNode, + UA_Boolean returnBounds, + UA_TimestampsToReturn timestampsToReturn, + UA_NumericRange range, + UA_Boolean releaseContinuationPoints, + const UA_ByteString *continuationPoint, + UA_ByteString *outContinuationPoint, + UA_HistoryData *result); + + /* This function is part of the low level HistoryRead API. It returns the + * index of a value in the database which matches certain criteria. + * + * server is the server the node lives in. + * hdbContext is the context of the UA_HistoryDataBackend. + * sessionId and sessionContext identify the session that wants to read historical data. + * nodeId is the node id of the node for which the matching value shall be found. + * timestamp is the timestamp of the requested index. + * strategy is the matching strategy which shall be applied in finding the index. */ + size_t + (*getDateTimeMatch)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + const UA_DateTime timestamp, + const MatchStrategy strategy); + + /* This function is part of the low level HistoryRead API. It returns the + * index of the element after the last valid entry in the database for a + * node. + * + * server is the server the node lives in. + * hdbContext is the context of the UA_HistoryDataBackend. + * sessionId and sessionContext identify the session that wants to read historical data. + * nodeId is the node id of the node for which the end of storage shall be returned. */ + size_t + (*getEnd)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId); + + /* This function is part of the low level HistoryRead API. It returns the + * index of the last element in the database for a node. + * + * server is the server the node lives in. + * hdbContext is the context of the UA_HistoryDataBackend. + * sessionId and sessionContext identify the session that wants to read historical data. + * nodeId is the node id of the node for which the index of the last element + * shall be returned. */ + size_t + (*lastIndex)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId); + + /* This function is part of the low level HistoryRead API. It returns the + * index of the first element in the database for a node. + * + * server is the server the node lives in. + * hdbContext is the context of the UA_HistoryDataBackend. + * sessionId and sessionContext identify the session that wants to read historical data. + * nodeId is the node id of the node for which the index of the first + * element shall be returned. */ + size_t + (*firstIndex)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId); + + /* This function is part of the low level HistoryRead API. It returns the + * number of elements between startIndex and endIndex including both. + * + * server is the server the node lives in. + * hdbContext is the context of the UA_HistoryDataBackend. + * sessionId and sessionContext identify the session that wants to read historical data. + * nodeId is the node id of the node for which the number of elements shall be returned. + * startIndex is the index of the first element in the range. + * endIndex is the index of the last element in the range. */ + size_t + (*resultSize)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + size_t startIndex, + size_t endIndex); + + /* This function is part of the low level HistoryRead API. It copies data + * values inside a certain range into a buffer. + * + * server is the server the node lives in. + * hdbContext is the context of the UA_HistoryDataBackend. + * sessionId and sessionContext identify the session that wants to read historical data. + * nodeId is the node id of the node for which the data values shall be copied. + * startIndex is the index of the first value in the range. + * endIndex is the index of the last value in the range. + * reverse determines if the values shall be copied in reverse order. + * valueSize is the maximal number of data values to copy. + * range is the numeric range which shall be copied for every data value. + * releaseContinuationPoints determines if the continuation points shall be released. + * continuationPoint is a continuation point the client wants to release or start from. + * outContinuationPoint is a continuation point which will be passed to the client. + * providedValues contains the number of values that were copied. + * values contains the values that have been copied from the database. */ + UA_StatusCode + (*copyDataValues)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + size_t startIndex, + size_t endIndex, + UA_Boolean reverse, + size_t valueSize, + UA_NumericRange range, + UA_Boolean releaseContinuationPoints, + const UA_ByteString *continuationPoint, + UA_ByteString *outContinuationPoint, + size_t *providedValues, + UA_DataValue *values); + + /* This function is part of the low level HistoryRead API. It returns the + * data value stored at a certain index in the database. + * + * server is the server the node lives in. + * hdbContext is the context of the UA_HistoryDataBackend. + * sessionId and sessionContext identify the session that wants to read historical data. + * nodeId is the node id of the node for which the data value shall be returned. + * index is the index in the database for which the data value is requested. */ + const UA_DataValue* + (*getDataValue)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + size_t index); + + /* This function returns UA_TRUE if the backend supports returning bounding + * values for a node. This function is mandatory. + * + * server is the server the node lives in. + * hdbContext is the context of the UA_HistoryDataBackend. + * sessionId and sessionContext identify the session that wants to read + * historical data. + * nodeId is the node id of the node for which the capability to return + * bounds shall be queried. */ + UA_Boolean + (*boundSupported)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId); + + /* This function returns UA_TRUE if the backend supports returning the + * requested timestamps for a node. This function is mandatory. + * + * server is the server the node lives in. + * hdbContext is the context of the UA_HistoryDataBackend. + * sessionId and sessionContext identify the session that wants to read historical data. + * nodeId is the node id of the node for which the capability to return + * certain timestamps shall be queried. */ + UA_Boolean + (*timestampsToReturnSupported)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + const UA_TimestampsToReturn timestampsToReturn); + + UA_StatusCode + (*insertDataValue)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + const UA_DataValue *value); + UA_StatusCode + (*replaceDataValue)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + const UA_DataValue *value); + UA_StatusCode + (*updateDataValue)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + const UA_DataValue *value); + UA_StatusCode + (*removeDataValue)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + UA_DateTime startTimestamp, + UA_DateTime endTimestamp); +}; + +_UA_END_DECLS + +#endif /* UA_PLUGIN_HISTORY_DATA_BACKEND_H_ */ diff --git a/product/src/fes/include/open62541/plugin/historydata/history_data_backend_memory.h b/product/src/fes/include/open62541/plugin/historydata/history_data_backend_memory.h new file mode 100644 index 00000000..17f1b87c --- /dev/null +++ b/product/src/fes/include/open62541/plugin/historydata/history_data_backend_memory.h @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2018 (c) basysKom GmbH (Author: Peter Rustler) + * Copyright 2021 (c) luibass92 (Author: Luigi Bassetta) + */ + +#ifndef UA_HISTORYDATABACKEND_MEMORY_H_ +#define UA_HISTORYDATABACKEND_MEMORY_H_ + +#include "history_data_backend.h" + +_UA_BEGIN_DECLS + +#define INITIAL_MEMORY_STORE_SIZE 1000 + +UA_HistoryDataBackend UA_EXPORT +UA_HistoryDataBackend_Memory(size_t initialNodeIdStoreSize, size_t initialDataStoreSize); + +/* This function construct a UA_HistoryDataBackend which implements a circular buffer in memory. + * + * initialNodeIdStoreSize is the maximum number of NodeIds that will be historized. This number cannot be overcomed. + * initialDataStoreSize is the maximum number of UA_DataValueMemoryStoreItem that will be saved in the circular buffer for a particular NodeId. + * Subsequent UA_DataValueMemoryStoreItem will be saved replacing the oldest ones following the logic of circular buffers. + */ +UA_HistoryDataBackend UA_EXPORT +UA_HistoryDataBackend_Memory_Circular(size_t initialNodeIdStoreSize, size_t initialDataStoreSize); + +void UA_EXPORT +UA_HistoryDataBackend_Memory_clear(UA_HistoryDataBackend *backend); + +_UA_END_DECLS + +#endif /* UA_HISTORYDATABACKEND_MEMORY_H_ */ diff --git a/product/src/fes/include/open62541/plugin/historydata/history_data_gathering.h b/product/src/fes/include/open62541/plugin/historydata/history_data_gathering.h new file mode 100644 index 00000000..6ecf6591 --- /dev/null +++ b/product/src/fes/include/open62541/plugin/historydata/history_data_gathering.h @@ -0,0 +1,120 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2018 (c) basysKom GmbH (Author: Peter Rustler) + */ + +#ifndef UA_PLUGIN_HISTORY_DATA_GATHERING_H_ +#define UA_PLUGIN_HISTORY_DATA_GATHERING_H_ + +#include "history_data_backend.h" + +_UA_BEGIN_DECLS + +typedef enum { + UA_HISTORIZINGUPDATESTRATEGY_USER = 0x00, /* The user of the api stores the values to the database himself. + The api will not store any value to the database. */ + UA_HISTORIZINGUPDATESTRATEGY_VALUESET = 0x01, /* Values will be stored when a node's value is set. + The values will be stored when a node is updated via write service.*/ + UA_HISTORIZINGUPDATESTRATEGY_POLL = 0x02 /* The value of the node will be read periodically. + This is mainly relevant for datasource nodes which do + not use the write service. + Values will not be stored if the value is + equal to the old value. */ +} UA_HistorizingUpdateStrategy; + +typedef struct { + UA_HistoryDataBackend historizingBackend; /* The database backend used for this node. */ + size_t maxHistoryDataResponseSize; /* The maximum number of values returned by the server in one response. + If the result has more values, continuation points will be used. */ + UA_HistorizingUpdateStrategy historizingUpdateStrategy; /* Defines how the values in the database will be updated. + See UA_HistorizingUpdateStrategy for details. */ + size_t pollingInterval; /* The polling interval for UA_HISTORIZINGUPDATESTRATEGY_POLL. */ + void *userContext; /* A pointer to store your own settings. */ +} UA_HistorizingNodeIdSettings; + +typedef struct UA_HistoryDataGathering UA_HistoryDataGathering; +struct UA_HistoryDataGathering { + void *context; + + void + (*deleteMembers)(UA_HistoryDataGathering *gathering); + + /* This function registers a node for the gathering of historical data. + * + * server is the server the node lives in. + * hdgContext is the context of the UA_HistoryDataGathering. + * nodeId is the node id of the node to register. + * setting contains the gatering settings for the node to register. */ + UA_StatusCode + (*registerNodeId)(UA_Server *server, + void *hdgContext, + const UA_NodeId *nodeId, + const UA_HistorizingNodeIdSettings setting); + + /* This function stops polling a node for value changes. + * + * server is the server the node lives in. + * hdgContext is the context of the UA_HistoryDataGathering. + * nodeId is id of the node for which polling shall be stopped. + * setting contains the gatering settings for the node. */ + UA_StatusCode + (*stopPoll)(UA_Server *server, + void *hdgContext, + const UA_NodeId *nodeId); + + /* This function starts polling a node for value changes. + * + * server is the server the node lives in. + * hdgContext is the context of the UA_HistoryDataGathering. + * nodeId is the id of the node for which polling shall be started. */ + UA_StatusCode + (*startPoll)(UA_Server *server, + void *hdgContext, + const UA_NodeId *nodeId); + + /* This function modifies the gathering settings for a node. + * + * server is the server the node lives in. + * hdgContext is the context of the UA_HistoryDataGathering. + * nodeId is the node id of the node for which gathering shall be modified. + * setting contains the new gatering settings for the node. */ + UA_Boolean + (*updateNodeIdSetting)(UA_Server *server, + void *hdgContext, + const UA_NodeId *nodeId, + const UA_HistorizingNodeIdSettings setting); + + /* Returns the gathering settings for a node. + * + * server is the server the node lives in. + * hdgContext is the context of the UA_HistoryDataGathering. + * nodeId is the node id of the node for which the gathering settings shall + * be retrieved. */ + const UA_HistorizingNodeIdSettings* + (*getHistorizingSetting)(UA_Server *server, + void *hdgContext, + const UA_NodeId *nodeId); + + /* Sets a DataValue for a node in the historical data storage. + * + * server is the server the node lives in. + * hdgContext is the context of the UA_HistoryDataGathering. + * sessionId and sessionContext identify the session which wants to set this value. + * nodeId is the node id of the node for which a value shall be set. + * historizing is the historizing flag of the node identified by nodeId. + * value is the value to set in the history data storage. */ + void + (*setValue)(UA_Server *server, + void *hdgContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + UA_Boolean historizing, + const UA_DataValue *value); +}; + +_UA_END_DECLS + +#endif /* UA_PLUGIN_HISTORY_DATA_GATHERING_H_ */ diff --git a/product/src/fes/include/open62541/plugin/historydata/history_data_gathering_default.h b/product/src/fes/include/open62541/plugin/historydata/history_data_gathering_default.h new file mode 100644 index 00000000..7985bc76 --- /dev/null +++ b/product/src/fes/include/open62541/plugin/historydata/history_data_gathering_default.h @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2018 (c) basysKom GmbH (Author: Peter Rustler) + * Copyright 2021 (c) luibass92 (Author: Luigi Bassetta) + */ + +#ifndef UA_HISTORYDATAGATHERING_DEFAULT_H_ +#define UA_HISTORYDATAGATHERING_DEFAULT_H_ + +#include "history_data_gathering.h" + +_UA_BEGIN_DECLS + +UA_HistoryDataGathering UA_EXPORT +UA_HistoryDataGathering_Default(size_t initialNodeIdStoreSize); + +/* This function construct a UA_HistoryDataGathering which implements a circular buffer in memory. + * + * initialNodeIdStoreSize is the maximum number of NodeIds for which the data will be gathered. This number cannot be overcomed. + */ +UA_HistoryDataGathering UA_EXPORT +UA_HistoryDataGathering_Circular(size_t initialNodeIdStoreSize); + +_UA_END_DECLS + +#endif /* UA_HISTORYDATAGATHERING_DEFAULT_H_ */ diff --git a/product/src/fes/include/open62541/plugin/historydata/history_database_default.h b/product/src/fes/include/open62541/plugin/historydata/history_database_default.h new file mode 100644 index 00000000..7445fdda --- /dev/null +++ b/product/src/fes/include/open62541/plugin/historydata/history_database_default.h @@ -0,0 +1,22 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2018 (c) basysKom GmbH (Author: Peter Rustler) + */ + +#ifndef UA_HISTORYDATASERVICE_DEFAULT_H_ +#define UA_HISTORYDATASERVICE_DEFAULT_H_ + +#include + +#include "history_data_gathering.h" + +_UA_BEGIN_DECLS + +UA_HistoryDatabase UA_EXPORT +UA_HistoryDatabase_default(UA_HistoryDataGathering gathering); + +_UA_END_DECLS + +#endif /* UA_HISTORYDATASERVICE_DEFAULT_H_ */ diff --git a/product/src/fes/include/open62541/plugin/historydatabase.h b/product/src/fes/include/open62541/plugin/historydatabase.h new file mode 100644 index 00000000..f9cee330 --- /dev/null +++ b/product/src/fes/include/open62541/plugin/historydatabase.h @@ -0,0 +1,187 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2018 (c) basysKom GmbH (Author: Peter Rustler) + */ + +#ifndef UA_PLUGIN_HISTORYDATABASE_H_ +#define UA_PLUGIN_HISTORYDATABASE_H_ + +#include + +_UA_BEGIN_DECLS + +typedef struct UA_HistoryDatabase UA_HistoryDatabase; + +struct UA_HistoryDatabase { + void *context; + + void (*clear)(UA_HistoryDatabase *hdb); + + /* This function will be called when a nodes value is set. + * Use this to insert data into your database(s) if polling is not suitable + * and you need to get all data changes. + * Set it to NULL if you do not need it. + * + * server is the server this node lives in. + * hdbContext is the context of the UA_HistoryDatabase. + * sessionId and sessionContext identify the session which set this value. + * nodeId is the node id for which data was set. + * historizing is the nodes boolean flag for historizing + * value is the new value. */ + void + (*setValue)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + UA_Boolean historizing, + const UA_DataValue *value); + + /* This function will be called when an event is triggered. + * Use it to insert data into your event database. + * No default implementation is provided by UA_HistoryDatabase_default. + * + * server is the server this node lives in. + * hdbContext is the context of the UA_HistoryDatabase. + * originId is the node id of the event's origin. + * emitterId is the node id of the event emitter. + * historicalEventFilter is the value of the HistoricalEventFilter property of + * the emitter (OPC UA Part 11, 5.3.2), it is NULL if + * the property does not exist or is not set. + * fieldList is the event field list returned after application of + * historicalEventFilter to the event node. */ + void + (*setEvent)(UA_Server *server, + void *hdbContext, + const UA_NodeId *originId, + const UA_NodeId *emitterId, + const UA_EventFilter *historicalEventFilter, + UA_EventFieldList *fieldList); + + /* This function is called if a history read is requested with + * isRawReadModified set to false. Setting it to NULL will result in a + * response with statuscode UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED. + * + * server is the server this node lives in. + * hdbContext is the context of the UA_HistoryDatabase. + * sessionId and sessionContext identify the session which set this value. + * requestHeader, historyReadDetails, timestampsToReturn, releaseContinuationPoints + * nodesToReadSize and nodesToRead is the requested data from the client. It + * is from the request object. + * response the response to fill for the client. If the request is ok, there + * is no need to use it. Use this to set status codes other than + * "Good" or other data. You find an already allocated + * UA_HistoryReadResult array with an UA_HistoryData object in the + * extension object in the size of nodesToReadSize. If you are not + * willing to return data, you have to delete the results array, + * set it to NULL and set the resultsSize to 0. Do not access + * historyData after that. + * historyData is a proper typed pointer array pointing in the + * UA_HistoryReadResult extension object. use this to provide + * result data to the client. Index in the array is the same as + * in nodesToRead and the UA_HistoryReadResult array. */ + void + (*readRaw)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_RequestHeader *requestHeader, + const UA_ReadRawModifiedDetails *historyReadDetails, + UA_TimestampsToReturn timestampsToReturn, + UA_Boolean releaseContinuationPoints, + size_t nodesToReadSize, + const UA_HistoryReadValueId *nodesToRead, + UA_HistoryReadResponse *response, + UA_HistoryData * const * const historyData); + + /* No default implementation is provided by UA_HistoryDatabase_default + * for the following function */ + void + (*readModified)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_RequestHeader *requestHeader, + const UA_ReadRawModifiedDetails *historyReadDetails, + UA_TimestampsToReturn timestampsToReturn, + UA_Boolean releaseContinuationPoints, + size_t nodesToReadSize, + const UA_HistoryReadValueId *nodesToRead, + UA_HistoryReadResponse *response, + UA_HistoryModifiedData * const * const historyData); + + /* No default implementation is provided by UA_HistoryDatabase_default + * for the following function */ + void + (*readEvent)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_RequestHeader *requestHeader, + const UA_ReadEventDetails *historyReadDetails, + UA_TimestampsToReturn timestampsToReturn, + UA_Boolean releaseContinuationPoints, + size_t nodesToReadSize, + const UA_HistoryReadValueId *nodesToRead, + UA_HistoryReadResponse *response, + UA_HistoryEvent * const * const historyData); + + /* No default implementation is provided by UA_HistoryDatabase_default + * for the following function */ + void + (*readProcessed)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_RequestHeader *requestHeader, + const UA_ReadProcessedDetails *historyReadDetails, + UA_TimestampsToReturn timestampsToReturn, + UA_Boolean releaseContinuationPoints, + size_t nodesToReadSize, + const UA_HistoryReadValueId *nodesToRead, + UA_HistoryReadResponse *response, + UA_HistoryData * const * const historyData); + + /* No default implementation is provided by UA_HistoryDatabase_default + * for the following function */ + void + (*readAtTime)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_RequestHeader *requestHeader, + const UA_ReadAtTimeDetails *historyReadDetails, + UA_TimestampsToReturn timestampsToReturn, + UA_Boolean releaseContinuationPoints, + size_t nodesToReadSize, + const UA_HistoryReadValueId *nodesToRead, + UA_HistoryReadResponse *response, + UA_HistoryData * const * const historyData); + + void + (*updateData)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_RequestHeader *requestHeader, + const UA_UpdateDataDetails *details, + UA_HistoryUpdateResult *result); + + void + (*deleteRawModified)(UA_Server *server, + void *hdbContext, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_RequestHeader *requestHeader, + const UA_DeleteRawModifiedDetails *details, + UA_HistoryUpdateResult *result); + + /* Add more function pointer here. + * For example for read_event, read_annotation, update_details */ +}; + +_UA_END_DECLS + +#endif /* UA_PLUGIN_HISTORYDATABASE_H_ */ diff --git a/product/src/fes/include/open62541/plugin/log.h b/product/src/fes/include/open62541/plugin/log.h new file mode 100644 index 00000000..e4fef3e4 --- /dev/null +++ b/product/src/fes/include/open62541/plugin/log.h @@ -0,0 +1,162 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + */ + +#ifndef UA_PLUGIN_LOG_H_ +#define UA_PLUGIN_LOG_H_ + +#include + +#include + +_UA_BEGIN_DECLS + +/** + * .. _logging: + * + * Logging Plugin API + * ================== + * + * Servers and clients define a logger in their configuration. The logger is a + * plugin. A default plugin that logs to ``stdout`` is provided as an example. + * The logger plugin is stateful and can point to custom data. So it is possible + * to keep open file handlers in the logger context. + * + * Every log message consists of a log level, a log category and a string + * message content. The timestamp of the log message is created within the + * logger. */ + +typedef enum { + UA_LOGLEVEL_TRACE = 100, + UA_LOGLEVEL_DEBUG = 200, + UA_LOGLEVEL_INFO = 300, + UA_LOGLEVEL_WARNING = 400, + UA_LOGLEVEL_ERROR = 500, + UA_LOGLEVEL_FATAL = 600 +} UA_LogLevel; + +#define UA_LOGCATEGORIES 10 + +typedef enum { + UA_LOGCATEGORY_NETWORK = 0, + UA_LOGCATEGORY_SECURECHANNEL, + UA_LOGCATEGORY_SESSION, + UA_LOGCATEGORY_SERVER, + UA_LOGCATEGORY_CLIENT, + UA_LOGCATEGORY_USERLAND, + UA_LOGCATEGORY_SECURITYPOLICY, + UA_LOGCATEGORY_EVENTLOOP, + UA_LOGCATEGORY_PUBSUB, + UA_LOGCATEGORY_DISCOVERY +} UA_LogCategory; + +typedef struct UA_Logger { + /* Log a message. The message string and following varargs are formatted + * according to the rules of the printf command. Use the convenience macros + * below that take the minimum log level defined in ua_config.h into + * account. */ + void (*log)(void *logContext, UA_LogLevel level, UA_LogCategory category, + const char *msg, va_list args); + + void *context; /* Logger state */ + + void (*clear)(struct UA_Logger *logger); /* Clean up the logger plugin */ +} UA_Logger; + +static UA_INLINE UA_FORMAT(3,4) void +UA_LOG_TRACE(const UA_Logger *logger, UA_LogCategory category, const char *msg, ...) { +#if UA_LOGLEVEL <= 100 + if(!logger || !logger->log) + return; + va_list args; va_start(args, msg); + logger->log(logger->context, UA_LOGLEVEL_TRACE, category, msg, args); + va_end(args); +#else + (void) logger; + (void) category; + (void) msg; +#endif +} + +static UA_INLINE UA_FORMAT(3,4) void +UA_LOG_DEBUG(const UA_Logger *logger, UA_LogCategory category, const char *msg, ...) { +#if UA_LOGLEVEL <= 200 + if(!logger || !logger->log) + return; + va_list args; va_start(args, msg); + logger->log(logger->context, UA_LOGLEVEL_DEBUG, category, msg, args); + va_end(args); +#else + (void) logger; + (void) category; + (void) msg; +#endif +} + +static UA_INLINE UA_FORMAT(3,4) void +UA_LOG_INFO(const UA_Logger *logger, UA_LogCategory category, const char *msg, ...) { +#if UA_LOGLEVEL <= 300 + if(!logger || !logger->log) + return; + va_list args; va_start(args, msg); + logger->log(logger->context, UA_LOGLEVEL_INFO, category, msg, args); + va_end(args); +#else + (void) logger; + (void) category; + (void) msg; +#endif +} + +static UA_INLINE UA_FORMAT(3,4) void +UA_LOG_WARNING(const UA_Logger *logger, UA_LogCategory category, const char *msg, ...) { +#if UA_LOGLEVEL <= 400 + if(!logger || !logger->log) + return; + va_list args; va_start(args, msg); + logger->log(logger->context, UA_LOGLEVEL_WARNING, category, msg, args); + va_end(args); +#else + (void) logger; + (void) category; + (void) msg; +#endif +} + +static UA_INLINE UA_FORMAT(3,4) void +UA_LOG_ERROR(const UA_Logger *logger, UA_LogCategory category, const char *msg, ...) { +#if UA_LOGLEVEL <= 500 + if(!logger || !logger->log) + return; + va_list args; va_start(args, msg); + logger->log(logger->context, UA_LOGLEVEL_ERROR, category, msg, args); + va_end(args); +#else + (void) logger; + (void) category; + (void) msg; +#endif +} + +static UA_INLINE UA_FORMAT(3,4) void +UA_LOG_FATAL(const UA_Logger *logger, UA_LogCategory category, const char *msg, ...) { +#if UA_LOGLEVEL <= 600 + if(!logger || !logger->log) + return; + va_list args; va_start(args, msg); + logger->log(logger->context, UA_LOGLEVEL_FATAL, category, msg, args); + va_end(args); +#else + (void) logger; + (void) category; + (void) msg; +#endif +} + +_UA_END_DECLS + +#endif /* UA_PLUGIN_LOG_H_ */ diff --git a/product/src/fes/include/open62541/plugin/log_stdout.h b/product/src/fes/include/open62541/plugin/log_stdout.h new file mode 100644 index 00000000..6d06df46 --- /dev/null +++ b/product/src/fes/include/open62541/plugin/log_stdout.h @@ -0,0 +1,27 @@ +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2016, 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + */ + +#ifndef UA_LOG_STDOUT_H_ +#define UA_LOG_STDOUT_H_ + +#include + +_UA_BEGIN_DECLS + +extern UA_EXPORT const UA_Logger UA_Log_Stdout_; /* Logger structure */ +extern UA_EXPORT const UA_Logger *UA_Log_Stdout; /* Shorthand pointer */ + +/* Returns a logger for messages up to the specified level */ +UA_EXPORT UA_Logger +UA_Log_Stdout_withLevel(UA_LogLevel minlevel); + +/* Allocates memory for the logger. Automatically cleared up via _clear. */ +UA_EXPORT UA_Logger * +UA_Log_Stdout_new(UA_LogLevel minlevel); + +_UA_END_DECLS + +#endif /* UA_LOG_STDOUT_H_ */ diff --git a/product/src/fes/include/open62541/plugin/log_syslog.h b/product/src/fes/include/open62541/plugin/log_syslog.h new file mode 100644 index 00000000..765a242c --- /dev/null +++ b/product/src/fes/include/open62541/plugin/log_syslog.h @@ -0,0 +1,46 @@ +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2020 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + */ + +#ifndef UA_LOG_SYSLOG_H_ +#define UA_LOG_SYSLOG_H_ + +#include + +_UA_BEGIN_DECLS + +/* Syslog-logging is available only for Linux/Unices. + * + * open62541 log levels are translated to syslog levels as follows: + * + * UA_LOGLEVEL_TRACE => not available for syslog + * UA_LOGLEVEL_DEBUG => LOG_DEBUG + * UA_LOGLEVEL_INFO => LOG_INFO + * UA_LOGLEVEL_WARNING => LOG_WARNING + * UA_LOGLEVEL_ERROR => LOG_ERR + * UA_LOGLEVEL_FATAL => LOG_CRIT + */ + +#if defined(__linux__) || defined(__unix__) + +/* Returns a syslog-logger for messages up to the specified level. + * The programm must call openlog(3) before using this logger. */ +UA_EXPORT UA_Logger +UA_Log_Syslog_withLevel(UA_LogLevel minlevel); + +/* Allocates memory for the logger. Automatically cleared up via _clear. */ +UA_EXPORT UA_Logger * +UA_Log_Syslog_new(UA_LogLevel minlevel); + +/* Log all warning levels supported by syslog (no trace-warnings). + * The programm must call openlog(3) before using this logger. */ +UA_EXPORT UA_Logger +UA_Log_Syslog(void); + +#endif + +_UA_END_DECLS + +#endif /* UA_LOG_SYSLOG_H_ */ diff --git a/product/src/fes/include/open62541/plugin/nodesetloader.h b/product/src/fes/include/open62541/plugin/nodesetloader.h new file mode 100644 index 00000000..a6416e24 --- /dev/null +++ b/product/src/fes/include/open62541/plugin/nodesetloader.h @@ -0,0 +1,24 @@ +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2019 (c) Julius Pfrommer, Fraunhofer IOSB + */ + +#ifndef UA_NODESET_LOADER_DEFAULT_H_ +#define UA_NODESET_LOADER_DEFAULT_H_ + +#include + +_UA_BEGIN_DECLS + +typedef void UA_NodeSetLoaderOptions; + +/* Load the typemodel at runtime, without the need to statically compile the model. + * This is an alternative to the Python nodeset compiler approach. */ +UA_EXPORT UA_StatusCode +UA_Server_loadNodeset(UA_Server *server, const char *nodeset2XmlFilePath, + UA_NodeSetLoaderOptions *options); + +_UA_END_DECLS + +#endif /* UA_NODESET_LOADER_DEFAULT_H_ */ diff --git a/product/src/fes/include/open62541/plugin/nodestore.h b/product/src/fes/include/open62541/plugin/nodestore.h new file mode 100644 index 00000000..f3272f64 --- /dev/null +++ b/product/src/fes/include/open62541/plugin/nodestore.h @@ -0,0 +1,871 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2017, 2021 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2017 (c) Julian Grothoff + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + */ + +#ifndef UA_NODESTORE_H_ +#define UA_NODESTORE_H_ + +/* !!! Warning !!! + * + * If you are not developing a nodestore plugin, then you should not work with + * the definitions from this file directly. The underlying node structures are + * not meant to be used directly by end users. Please use the public server API + * / OPC UA services to interact with the information model. */ + +#include + +_UA_BEGIN_DECLS + +/* Forward declaration */ +#ifdef UA_ENABLE_SUBSCRIPTIONS +struct UA_MonitoredItem; +typedef struct UA_MonitoredItem UA_MonitoredItem; +#endif + +/** + * Node Store Plugin API + * ===================== + * + * **Warning!!** The structures defined in this section are only relevant for + * the developers of custom Nodestores. The interaction with the information + * model is possible only via the OPC UA :ref:`services`. So the following + * sections are purely informational so that users may have a clear mental + * model of the underlying representation. + * + * .. _node-lifecycle: + * + * Node Lifecycle: Constructors, Destructors and Node Contexts + * ----------------------------------------------------------- + * + * To finalize the instantiation of a node, a (user-defined) constructor + * callback is executed. There can be both a global constructor for all nodes + * and node-type constructor specific to the TypeDefinition of the new node + * (attached to an ObjectTypeNode or VariableTypeNode). + * + * In the hierarchy of ObjectTypes and VariableTypes, only the constructor of + * the (lowest) type defined for the new node is executed. Note that every + * Object and Variable can have only one ``isTypeOf`` reference. But type-nodes + * can technically have several ``hasSubType`` references to implement multiple + * inheritance. Issues of (multiple) inheritance in the constructor need to be + * solved by the user. + * + * When a node is destroyed, the node-type destructor is called before the + * global destructor. So the overall node lifecycle is as follows: + * + * 1. Global Constructor (set in the server config) + * 2. Node-Type Constructor (for VariableType or ObjectTypes) + * 3. (Usage-period of the Node) + * 4. Node-Type Destructor + * 5. Global Destructor + * + * The constructor and destructor callbacks can be set to ``NULL`` and are not + * used in that case. If the node-type constructor fails, the global destructor + * will be called before removing the node. The destructors are assumed to never + * fail. + * + * Every node carries a user-context and a constructor-context pointer. The + * user-context is used to attach custom data to a node. But the (user-defined) + * constructors and destructors may replace the user-context pointer if they + * wish to do so. The initial value for the constructor-context is ``NULL``. + * When the ``AddNodes`` service is used over the network, the user-context + * pointer of the new node is also initially set to ``NULL``. + * + * Global Node Lifecycle + * ~~~~~~~~~~~~~~~~~~~~~~ + * Global constructor and destructor callbacks used for every node type. + * To be set in the server config. + */ + +typedef struct { + /* Can be NULL. May replace the nodeContext */ + UA_StatusCode (*constructor)(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeId, void **nodeContext); + + /* Can be NULL. The context cannot be replaced since the node is destroyed + * immediately afterwards anyway. */ + void (*destructor)(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeId, void *nodeContext); + + /* Can be NULL. Called during recursive node instantiation. While mandatory + * child nodes are automatically created if not already present, optional child + * nodes are not. This callback can be used to define whether an optional child + * node should be created. + * + * @param server The server executing the callback + * @param sessionId The identifier of the session + * @param sessionContext Additional data attached to the session in the + * access control layer + * @param sourceNodeId Source node from the type definition. If the new node + * shall be created, it will be a copy of this node. + * @param targetParentNodeId Parent of the potential new child node + * @param referenceTypeId Identifies the reference type which that the parent + * node has to the new node. + * @return Return UA_TRUE if the child node shall be instantiated, + * UA_FALSE otherwise. */ + UA_Boolean (*createOptionalChild)(UA_Server *server, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *sourceNodeId, + const UA_NodeId *targetParentNodeId, + const UA_NodeId *referenceTypeId); + + /* Can be NULL. Called when a node is to be copied during recursive + * node instantiation. Allows definition of the NodeId for the new node. + * If the callback is set to NULL or the resulting NodeId is UA_NODEID_NUMERIC(X,0) + * an unused nodeid in namespace X will be used. E.g. passing UA_NODEID_NULL will + * result in a NodeId in namespace 0. + * + * @param server The server executing the callback + * @param sessionId The identifier of the session + * @param sessionContext Additional data attached to the session in the + * access control layer + * @param sourceNodeId Source node of the copy operation + * @param targetParentNodeId Parent node of the new node + * @param referenceTypeId Identifies the reference type which that the parent + * node has to the new node. */ + UA_StatusCode (*generateChildNodeId)(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *sourceNodeId, + const UA_NodeId *targetParentNodeId, + const UA_NodeId *referenceTypeId, + UA_NodeId *targetNodeId); +} UA_GlobalNodeLifecycle; + +/** + * Node Type Lifecycle + * ~~~~~~~~~~~~~~~~~~~ + * Constructor and destructors for specific object and variable types. */ +typedef struct { + /* Can be NULL. May replace the nodeContext */ + UA_StatusCode (*constructor)(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *typeNodeId, void *typeNodeContext, + const UA_NodeId *nodeId, void **nodeContext); + + /* Can be NULL. May replace the nodeContext. */ + void (*destructor)(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *typeNodeId, void *typeNodeContext, + const UA_NodeId *nodeId, void **nodeContext); +} UA_NodeTypeLifecycle; + +/** + * ReferenceType Bitfield Representation + * ------------------------------------- + * ReferenceTypes have an alternative represention as an index into a bitfield + * for fast comparison. The index is generated when the corresponding + * ReferenceTypeNode is added. By bounding the number of ReferenceTypes that can + * exist in the server, the bitfield can represent a set of an combination of + * ReferenceTypes. + * + * Every ReferenceTypeNode contains a bitfield with the set of all its subtypes. + * This speeds up the Browse services substantially. + * + * The following ReferenceTypes have a fixed index. The NS0 bootstrapping + * creates these ReferenceTypes in-order. */ +#define UA_REFERENCETYPEINDEX_REFERENCES 0 +#define UA_REFERENCETYPEINDEX_HASSUBTYPE 1 +#define UA_REFERENCETYPEINDEX_AGGREGATES 2 +#define UA_REFERENCETYPEINDEX_HIERARCHICALREFERENCES 3 +#define UA_REFERENCETYPEINDEX_NONHIERARCHICALREFERENCES 4 +#define UA_REFERENCETYPEINDEX_HASCHILD 5 +#define UA_REFERENCETYPEINDEX_ORGANIZES 6 +#define UA_REFERENCETYPEINDEX_HASEVENTSOURCE 7 +#define UA_REFERENCETYPEINDEX_HASMODELLINGRULE 8 +#define UA_REFERENCETYPEINDEX_HASENCODING 9 +#define UA_REFERENCETYPEINDEX_HASDESCRIPTION 10 +#define UA_REFERENCETYPEINDEX_HASTYPEDEFINITION 11 +#define UA_REFERENCETYPEINDEX_GENERATESEVENT 12 +#define UA_REFERENCETYPEINDEX_HASPROPERTY 13 +#define UA_REFERENCETYPEINDEX_HASCOMPONENT 14 +#define UA_REFERENCETYPEINDEX_HASNOTIFIER 15 +#define UA_REFERENCETYPEINDEX_HASORDEREDCOMPONENT 16 +#define UA_REFERENCETYPEINDEX_HASINTERFACE 17 + +/* The maximum number of ReferrenceTypes. Must be a multiple of 32. */ +#define UA_REFERENCETYPESET_MAX 128 +typedef struct { + UA_UInt32 bits[UA_REFERENCETYPESET_MAX / 32]; +} UA_ReferenceTypeSet; + +UA_EXPORT extern const UA_ReferenceTypeSet UA_REFERENCETYPESET_NONE; +UA_EXPORT extern const UA_ReferenceTypeSet UA_REFERENCETYPESET_ALL; + +static UA_INLINE void +UA_ReferenceTypeSet_init(UA_ReferenceTypeSet *set) { + memset(set, 0, sizeof(UA_ReferenceTypeSet)); +} + +static UA_INLINE UA_ReferenceTypeSet +UA_REFTYPESET(UA_Byte index) { + UA_Byte i = index / 32, j = index % 32; + UA_ReferenceTypeSet set; + UA_ReferenceTypeSet_init(&set); + set.bits[i] |= ((UA_UInt32)1) << j; + return set; +} + +static UA_INLINE UA_ReferenceTypeSet +UA_ReferenceTypeSet_union(const UA_ReferenceTypeSet setA, + const UA_ReferenceTypeSet setB) { + UA_ReferenceTypeSet set; + for(size_t i = 0; i < UA_REFERENCETYPESET_MAX / 32; i++) + set.bits[i] = setA.bits[i] | setB.bits[i]; + return set; +} + +static UA_INLINE UA_Boolean +UA_ReferenceTypeSet_contains(const UA_ReferenceTypeSet *set, UA_Byte index) { + UA_Byte i = index / 32, j = index % 32; + return !!(set->bits[i] & (((UA_UInt32)1) << j)); +} + +/** + * Node Pointer + * ------------ + * + * The "native" format for reference between nodes is the ExpandedNodeId. That + * is, references can also point to external servers. In practice, most + * references point to local nodes using numerical NodeIds from the + * standard-defined namespace zero. In order to save space (and time), + * pointer-tagging is used for compressed "NodePointer" representations. + * Numerical NodeIds are immediately contained in the pointer. Full NodeIds and + * ExpandedNodeIds are behind a pointer indirection. If the Nodestore supports + * it, a NodePointer can also be an actual pointer to the target node. + * + * Depending on the processor architecture, some numerical NodeIds don't fit + * into an immediate encoding and are kept as pointers. ExpandedNodeIds may be + * internally translated to "normal" NodeIds. Use the provided functions to + * generate NodePointers that fit the assumptions for the local architecture. */ + +/* Forward declaration. All node structures begin with the NodeHead. */ +struct UA_NodeHead; +typedef struct UA_NodeHead UA_NodeHead; + +/* Tagged Pointer structure. */ +typedef union { + uintptr_t immediate; /* 00: Small numerical NodeId */ + const UA_NodeId *id; /* 01: Pointer to NodeId */ + const UA_ExpandedNodeId *expandedId; /* 10: Pointer to ExternalNodeId */ + const UA_NodeHead *node; /* 11: Pointer to a node */ +} UA_NodePointer; + +/* Sets the pointer to an immediate NodeId "ns=0;i=0" similar to a freshly + * initialized UA_NodeId */ +static UA_INLINE void +UA_NodePointer_init(UA_NodePointer *np) { np->immediate = 0; } + +/* NodeId and ExpandedNodeId targets are freed */ +void UA_EXPORT +UA_NodePointer_clear(UA_NodePointer *np); + +/* Makes a deep copy */ +UA_StatusCode UA_EXPORT +UA_NodePointer_copy(UA_NodePointer in, UA_NodePointer *out); + +/* Test if an ExpandedNodeId or a local NodeId */ +UA_Boolean UA_EXPORT +UA_NodePointer_isLocal(UA_NodePointer np); + +UA_Order UA_EXPORT +UA_NodePointer_order(UA_NodePointer p1, UA_NodePointer p2); + +static UA_INLINE UA_Boolean +UA_NodePointer_equal(UA_NodePointer p1, UA_NodePointer p2) { + return (UA_NodePointer_order(p1, p2) == UA_ORDER_EQ); +} + +/* Cannot fail. The resulting NodePointer can point to the memory from the + * NodeId. Make a deep copy if required. */ +UA_NodePointer UA_EXPORT +UA_NodePointer_fromNodeId(const UA_NodeId *id); + +/* Cannot fail. The resulting NodePointer can point to the memory from the + * ExpandedNodeId. Make a deep copy if required. */ +UA_NodePointer UA_EXPORT +UA_NodePointer_fromExpandedNodeId(const UA_ExpandedNodeId *id); + +/* Can point to the memory from the NodePointer */ +UA_ExpandedNodeId UA_EXPORT +UA_NodePointer_toExpandedNodeId(UA_NodePointer np); + +/* Can point to the memory from the NodePointer. Discards the ServerIndex and + * NamespaceUri of a potential ExpandedNodeId inside the NodePointer. Test + * before if the NodePointer is local. */ +UA_NodeId UA_EXPORT +UA_NodePointer_toNodeId(UA_NodePointer np); + +/** + * Base Node Attributes + * -------------------- + * + * Nodes contain attributes according to their node type. The base node + * attributes are common to all node types. In the OPC UA :ref:`services`, + * attributes are referred to via the :ref:`nodeid` of the containing node and + * an integer :ref:`attribute-id`. + * + * Internally, open62541 uses ``UA_Node`` in places where the exact node type is + * not known or not important. The ``nodeClass`` attribute is used to ensure the + * correctness of casting from ``UA_Node`` to a specific node type. */ + +typedef struct { + UA_NodePointer targetId; /* Has to be the first entry */ + UA_UInt32 targetNameHash; /* Hash of the target's BrowseName. Set to zero + * if the target is remote. */ +} UA_ReferenceTarget; + +typedef struct UA_ReferenceTargetTreeElem { + UA_ReferenceTarget target; /* Has to be the first entry */ + UA_UInt32 targetIdHash; /* Hash of the targetId */ + struct { + struct UA_ReferenceTargetTreeElem *left; + struct UA_ReferenceTargetTreeElem *right; + } idTreeEntry; + struct { + struct UA_ReferenceTargetTreeElem *left; + struct UA_ReferenceTargetTreeElem *right; + } nameTreeEntry; +} UA_ReferenceTargetTreeElem; + + +/* List of reference targets with the same reference type and direction. Uses + * either an array or a tree structure. The SDK will not change the type of + * reference target structure internally. The nodestore implementations may + * switch internally when a node is updated. + * + * The recommendation is to switch to a tree once the number of refs > 8. */ +typedef struct { + union { + /* Organize the references in an array. Uses less memory, but incurs + * lookups in linear time. Recommended if the number of references is + * known to be small. */ + UA_ReferenceTarget *array; + + /* Organize the references in a tree for fast lookup. Use + * UA_Node_addReference and UA_Node_deleteReference to modify the + * tree-structure. The binary tree implementation (and absolute ordering + * / duplicate browseNames are allowed) are not exposed otherwise in the + * public API. */ + struct { + UA_ReferenceTargetTreeElem *idRoot; /* Lookup based on target id */ + UA_ReferenceTargetTreeElem *nameRoot; /* Lookup based on browseName*/ + } tree; + } targets; + size_t targetsSize; + UA_Boolean hasRefTree; /* RefTree or RefArray? */ + UA_Byte referenceTypeIndex; + UA_Boolean isInverse; +} UA_NodeReferenceKind; + +/* Iterate over the references. Aborts when the first callback return a non-NULL + * pointer and returns that pointer. Do not modify the reference targets during + * the iteration. */ +typedef void * +(*UA_NodeReferenceKind_iterateCallback)(void *context, UA_ReferenceTarget *target); + +UA_EXPORT void * +UA_NodeReferenceKind_iterate(UA_NodeReferenceKind *rk, + UA_NodeReferenceKind_iterateCallback callback, + void *context); + +/* Returns the entry for the targetId or NULL if not found */ +UA_EXPORT const UA_ReferenceTarget * +UA_NodeReferenceKind_findTarget(const UA_NodeReferenceKind *rk, + const UA_ExpandedNodeId *targetId); + +/* Switch between array and tree representation. Does nothing upon error (e.g. + * out-of-memory). */ +UA_EXPORT UA_StatusCode +UA_NodeReferenceKind_switch(UA_NodeReferenceKind *rk); + +/* Singly-linked LocalizedText list */ +typedef struct UA_LocalizedTextListEntry { + struct UA_LocalizedTextListEntry *next; + UA_LocalizedText localizedText; +} UA_LocalizedTextListEntry; + +/* Every Node starts with these attributes */ +struct UA_NodeHead { + UA_NodeId nodeId; + UA_NodeClass nodeClass; + UA_QualifiedName browseName; + + /* A node can have different localizations for displayName and description. + * The server selects a suitable localization depending on the locale ids + * that are set for the current session. + * + * Locales are added simply by writing a LocalizedText value with a new + * locale. A locale can be removed by writing a LocalizedText value of the + * corresponding locale with an empty text field. */ + UA_LocalizedTextListEntry *displayName; + UA_LocalizedTextListEntry *description; + + UA_UInt32 writeMask; + size_t referencesSize; + UA_NodeReferenceKind *references; + + /* Members specific to open62541 */ + void *context; + UA_Boolean constructed; /* Constructors were called */ +#ifdef UA_ENABLE_SUBSCRIPTIONS + UA_MonitoredItem *monitoredItems; /* MonitoredItems for Events and immediate + * DataChanges (no sampling interval). */ +#endif +}; + +/** + * VariableNode + * ------------ */ + +/* Indicates whether a variable contains data inline or whether it points to an + * external data source */ +typedef enum { + UA_VALUESOURCE_DATA, + UA_VALUESOURCE_DATASOURCE +} UA_ValueSource; + +typedef struct { + /* Called before the value attribute is read. It is possible to write into the + * value attribute during onRead (using the write service). The node is + * re-opened afterwards so that changes are considered in the following read + * operation. + * + * @param handle Points to user-provided data for the callback. + * @param nodeid The identifier of the node. + * @param data Points to the current node value. + * @param range Points to the numeric range the client wants to read from + * (or NULL). */ + void (*onRead)(UA_Server *server, const UA_NodeId *sessionId, + void *sessionContext, const UA_NodeId *nodeid, + void *nodeContext, const UA_NumericRange *range, + const UA_DataValue *value); + + /* Called after writing the value attribute. The node is re-opened after + * writing so that the new value is visible in the callback. + * + * @param server The server executing the callback + * @sessionId The identifier of the session + * @sessionContext Additional data attached to the session + * in the access control layer + * @param nodeid The identifier of the node. + * @param nodeUserContext Additional data attached to the node by + * the user. + * @param nodeConstructorContext Additional data attached to the node + * by the type constructor(s). + * @param range Points to the numeric range the client wants to write to (or + * NULL). */ + void (*onWrite)(UA_Server *server, const UA_NodeId *sessionId, + void *sessionContext, const UA_NodeId *nodeId, + void *nodeContext, const UA_NumericRange *range, + const UA_DataValue *data); +} UA_ValueCallback; + +typedef struct { + /* Copies the data from the source into the provided value. + * + * !! ZERO-COPY OPERATIONS POSSIBLE !! + * It is not required to return a copy of the actual content data. You can + * return a pointer to memory owned by the user. Memory can be reused + * between read callbacks of a DataSource, as the result is already encoded + * on the network buffer between each read operation. + * + * To use zero-copy reads, set the value of the `value->value` Variant + * without copying, e.g. with `UA_Variant_setScalar`. Then, also set + * `value->value.storageType` to `UA_VARIANT_DATA_NODELETE` to prevent the + * memory being cleaned up. Don't forget to also set `value->hasValue` to + * true to indicate the presence of a value. + * + * @param server The server executing the callback + * @param sessionId The identifier of the session + * @param sessionContext Additional data attached to the session in the + * access control layer + * @param nodeId The identifier of the node being read from + * @param nodeContext Additional data attached to the node by the user + * @param includeSourceTimeStamp If true, then the datasource is expected to + * set the source timestamp in the returned value + * @param range If not null, then the datasource shall return only a + * selection of the (nonscalar) data. Set + * UA_STATUSCODE_BADINDEXRANGEINVALID in the value if this does not + * apply + * @param value The (non-null) DataValue that is returned to the client. The + * data source sets the read data, the result status and optionally a + * sourcetimestamp. + * @return Returns a status code for logging. Error codes intended for the + * original caller are set in the value. If an error is returned, + * then no releasing of the value is done + */ + UA_StatusCode (*read)(UA_Server *server, const UA_NodeId *sessionId, + void *sessionContext, const UA_NodeId *nodeId, + void *nodeContext, UA_Boolean includeSourceTimeStamp, + const UA_NumericRange *range, UA_DataValue *value); + + /* Write into a data source. This method pointer can be NULL if the + * operation is unsupported. + * + * @param server The server executing the callback + * @param sessionId The identifier of the session + * @param sessionContext Additional data attached to the session in the + * access control layer + * @param nodeId The identifier of the node being written to + * @param nodeContext Additional data attached to the node by the user + * @param range If not NULL, then the datasource shall return only a + * selection of the (nonscalar) data. Set + * UA_STATUSCODE_BADINDEXRANGEINVALID in the value if this does not + * apply + * @param value The (non-NULL) DataValue that has been written by the client. + * The data source contains the written data, the result status and + * optionally a sourcetimestamp + * @return Returns a status code for logging. Error codes intended for the + * original caller are set in the value. If an error is returned, + * then no releasing of the value is done + */ + UA_StatusCode (*write)(UA_Server *server, const UA_NodeId *sessionId, + void *sessionContext, const UA_NodeId *nodeId, + void *nodeContext, const UA_NumericRange *range, + const UA_DataValue *value); +} UA_DataSource; + +/** + * .. _value-callback: + * + * Value Callback + * ~~~~~~~~~~~~~~ + * Value Callbacks can be attached to variable and variable type nodes. If + * not ``NULL``, they are called before reading and after writing respectively. */ +typedef struct { + /* Called before the value attribute is read. The external value source can be + * be updated and/or locked during this notification call. After this function returns + * to the core, the external value source is readed immediately. + */ + UA_StatusCode (*notificationRead)(UA_Server *server, const UA_NodeId *sessionId, + void *sessionContext, const UA_NodeId *nodeid, + void *nodeContext, const UA_NumericRange *range); + + /* Called after writing the value attribute. The node is re-opened after + * writing so that the new value is visible in the callback. + * + * @param server The server executing the callback + * @sessionId The identifier of the session + * @sessionContext Additional data attached to the session + * in the access control layer + * @param nodeid The identifier of the node. + * @param nodeUserContext Additional data attached to the node by + * the user. + * @param nodeConstructorContext Additional data attached to the node + * by the type constructor(s). + * @param range Points to the numeric range the client wants to write to (or + * NULL). */ + UA_StatusCode (*userWrite)(UA_Server *server, const UA_NodeId *sessionId, + void *sessionContext, const UA_NodeId *nodeId, + void *nodeContext, const UA_NumericRange *range, + const UA_DataValue *data); +} UA_ExternalValueCallback; + +typedef enum { + UA_VALUEBACKENDTYPE_NONE, + UA_VALUEBACKENDTYPE_INTERNAL, + UA_VALUEBACKENDTYPE_DATA_SOURCE_CALLBACK, + UA_VALUEBACKENDTYPE_EXTERNAL +} UA_ValueBackendType; + +typedef struct { + UA_ValueBackendType backendType; + union { + struct { + UA_DataValue value; + UA_ValueCallback callback; + } internal; + UA_DataSource dataSource; + struct { + UA_DataValue **value; + UA_ExternalValueCallback callback; + } external; + } backend; +} UA_ValueBackend; + +#define UA_NODE_VARIABLEATTRIBUTES \ + /* Constraints on possible values */ \ + UA_NodeId dataType; \ + UA_Int32 valueRank; \ + size_t arrayDimensionsSize; \ + UA_UInt32 *arrayDimensions; \ + \ + UA_ValueBackend valueBackend; \ + \ + /* The current value */ \ + UA_ValueSource valueSource; \ + union { \ + struct { \ + UA_DataValue value; \ + UA_ValueCallback callback; \ + } data; \ + UA_DataSource dataSource; \ + } value; + +typedef struct { + UA_NodeHead head; + UA_NODE_VARIABLEATTRIBUTES + UA_Byte accessLevel; + UA_Double minimumSamplingInterval; + UA_Boolean historizing; + + /* Members specific to open62541 */ + UA_Boolean isDynamic; /* Some variables are "static" in the sense that they + * are not attached to a dynamic process in the + * background. Only dynamic variables conserve source + * and server timestamp for the value attribute. + * Static variables have timestamps of "now". */ +} UA_VariableNode; + +/** + * VariableTypeNode + * ---------------- */ + +typedef struct { + UA_NodeHead head; + UA_NODE_VARIABLEATTRIBUTES + UA_Boolean isAbstract; + + /* Members specific to open62541 */ + UA_NodeTypeLifecycle lifecycle; +} UA_VariableTypeNode; + +/** + * MethodNode + * ---------- */ + +typedef UA_StatusCode +(*UA_MethodCallback)(UA_Server *server, const UA_NodeId *sessionId, + void *sessionContext, const UA_NodeId *methodId, + void *methodContext, const UA_NodeId *objectId, + void *objectContext, size_t inputSize, + const UA_Variant *input, size_t outputSize, + UA_Variant *output); + +typedef struct { + UA_NodeHead head; + UA_Boolean executable; + + /* Members specific to open62541 */ + UA_MethodCallback method; +#if UA_MULTITHREADING >= 100 + UA_Boolean async; /* Indicates an async method call */ +#endif +} UA_MethodNode; + +/** + * ObjectNode + * ---------- */ + +typedef struct { + UA_NodeHead head; + UA_Byte eventNotifier; +} UA_ObjectNode; + +/** + * ObjectTypeNode + * -------------- */ + +typedef struct { + UA_NodeHead head; + UA_Boolean isAbstract; + + /* Members specific to open62541 */ + UA_NodeTypeLifecycle lifecycle; +} UA_ObjectTypeNode; + +/** + * ReferenceTypeNode + * ----------------- */ + +typedef struct { + UA_NodeHead head; + UA_Boolean isAbstract; + UA_Boolean symmetric; + UA_LocalizedText inverseName; + + /* Members specific to open62541 */ + UA_Byte referenceTypeIndex; + UA_ReferenceTypeSet subTypes; /* contains the type itself as well */ +} UA_ReferenceTypeNode; + +/** + * DataTypeNode + * ------------ */ + +typedef struct { + UA_NodeHead head; + UA_Boolean isAbstract; +} UA_DataTypeNode; + +/** + * ViewNode + * -------- */ + +typedef struct { + UA_NodeHead head; + UA_Byte eventNotifier; + UA_Boolean containsNoLoops; +} UA_ViewNode; + +/** + * Node Union + * ---------- + * + * A union that represents any kind of node. The node head can always be used. + * Check the NodeClass before accessing specific content. + */ + +typedef union { + UA_NodeHead head; + UA_VariableNode variableNode; + UA_VariableTypeNode variableTypeNode; + UA_MethodNode methodNode; + UA_ObjectNode objectNode; + UA_ObjectTypeNode objectTypeNode; + UA_ReferenceTypeNode referenceTypeNode; + UA_DataTypeNode dataTypeNode; + UA_ViewNode viewNode; +} UA_Node; + +/** + * Nodestore + * --------- + * + * The following definitions are used for implementing custom node storage + * backends. **Most users will want to use the default nodestore and don't need + * to work with the nodestore API**. + * + * Outside of custom nodestore implementations, users should not manually edit + * nodes. Please use the OPC UA services for that. Otherwise, all consistency + * checks are omitted. This can crash the application eventually. */ + +typedef void (*UA_NodestoreVisitor)(void *visitorCtx, const UA_Node *node); + +typedef struct { + /* Nodestore context and lifecycle */ + void *context; + void (*clear)(void *nsCtx); + + /* The following definitions are used to create empty nodes of the different + * node types. The memory is managed by the nodestore. Therefore, the node + * has to be removed via a special deleteNode function. (If the new node is + * not added to the nodestore.) */ + UA_Node * (*newNode)(void *nsCtx, UA_NodeClass nodeClass); + + void (*deleteNode)(void *nsCtx, UA_Node *node); + + /* ``Get`` returns a pointer to an immutable node. Call ``releaseNode`` to + * indicate when the pointer is no longer accessed. + * + * It can be indicated if only a subset of the attributes and referencs need + * to be accessed. That is relevant when the nodestore accesses a slow + * storage backend for the attributes. The attribute mask is a bitfield with + * ORed entries from UA_NodeAttributesMask. + * + * The returned node always contains the context-pointer and other fields + * specific to open626541 (not official attributes). + * + * The NodeStore does not complain if attributes and references that don't + * exist (for that node) are requested. Attributes and references in + * addition to those specified can be returned. For example, if the full + * node already is kept in memory by the Nodestore. */ + const UA_Node * (*getNode)(void *nsCtx, const UA_NodeId *nodeId, + UA_UInt32 attributeMask, + UA_ReferenceTypeSet references, + UA_BrowseDirection referenceDirections); + + /* Similar to the normal ``getNode``. But it can take advantage of the + * NodePointer structure, e.g. if it contains a direct pointer. */ + const UA_Node * (*getNodeFromPtr)(void *nsCtx, UA_NodePointer ptr, + UA_UInt32 attributeMask, + UA_ReferenceTypeSet references, + UA_BrowseDirection referenceDirections); + + /* Release a node that has been retrieved with ``getNode`` or + * ``getNodeFromPtr``. */ + void (*releaseNode)(void *nsCtx, const UA_Node *node); + + /* Returns an editable copy of a node (needs to be deleted with the + * deleteNode function or inserted / replaced into the nodestore). */ + UA_StatusCode (*getNodeCopy)(void *nsCtx, const UA_NodeId *nodeId, + UA_Node **outNode); + + /* Inserts a new node into the nodestore. If the NodeId is zero, then a + * fresh numeric NodeId is assigned. If insertion fails, the node is + * deleted. */ + UA_StatusCode (*insertNode)(void *nsCtx, UA_Node *node, + UA_NodeId *addedNodeId); + + /* To replace a node, get an editable copy of the node, edit and replace + * with this function. If the node was already replaced since the copy was + * made, UA_STATUSCODE_BADINTERNALERROR is returned. If the NodeId is not + * found, UA_STATUSCODE_BADNODEIDUNKNOWN is returned. In both error cases, + * the editable node is deleted. */ + UA_StatusCode (*replaceNode)(void *nsCtx, UA_Node *node); + + /* Removes a node from the nodestore. */ + UA_StatusCode (*removeNode)(void *nsCtx, const UA_NodeId *nodeId); + + /* Maps the ReferenceTypeIndex used for the references to the NodeId of the + * ReferenceType. The returned pointer is stable until the Nodestore is + * deleted. */ + const UA_NodeId * (*getReferenceTypeId)(void *nsCtx, UA_Byte refTypeIndex); + + /* Execute a callback for every node in the nodestore. */ + void (*iterate)(void *nsCtx, UA_NodestoreVisitor visitor, + void *visitorCtx); +} UA_Nodestore; + +/* Attributes must be of a matching type (VariableAttributes, ObjectAttributes, + * and so on). The attributes are copied. Note that the attributes structs do + * not contain NodeId, NodeClass and BrowseName. The NodeClass of the node needs + * to be correctly set before calling this method. UA_Node_clear is called on + * the node when an error occurs internally. */ +UA_StatusCode UA_EXPORT +UA_Node_setAttributes(UA_Node *node, const void *attributes, + const UA_DataType *attributeType); + +/* Reset the destination node and copy the content of the source */ +UA_StatusCode UA_EXPORT +UA_Node_copy(const UA_Node *src, UA_Node *dst); + +/* Allocate new node and copy the values from src */ +UA_EXPORT UA_Node * +UA_Node_copy_alloc(const UA_Node *src); + +/* Add a single reference to the node */ +UA_StatusCode UA_EXPORT +UA_Node_addReference(UA_Node *node, UA_Byte refTypeIndex, UA_Boolean isForward, + const UA_ExpandedNodeId *targetNodeId, + UA_UInt32 targetBrowseNameHash); + +/* Delete a single reference from the node */ +UA_StatusCode UA_EXPORT +UA_Node_deleteReference(UA_Node *node, UA_Byte refTypeIndex, UA_Boolean isForward, + const UA_ExpandedNodeId *targetNodeId); + +/* Deletes references from the node which are not matching any type in the given + * array. Could be used to e.g. delete all the references, except + * 'HASMODELINGRULE' */ +void UA_EXPORT +UA_Node_deleteReferencesSubset(UA_Node *node, const UA_ReferenceTypeSet *keepSet); + +/* Delete all references of the node */ +void UA_EXPORT +UA_Node_deleteReferences(UA_Node *node); + +/* Remove all malloc'ed members of the node and reset */ +void UA_EXPORT +UA_Node_clear(UA_Node *node); + +_UA_END_DECLS + +#endif /* UA_NODESTORE_H_ */ diff --git a/product/src/fes/include/open62541/plugin/nodestore_default.h b/product/src/fes/include/open62541/plugin/nodestore_default.h new file mode 100644 index 00000000..002c6221 --- /dev/null +++ b/product/src/fes/include/open62541/plugin/nodestore_default.h @@ -0,0 +1,32 @@ +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2019 (c) Julius Pfrommer, Fraunhofer IOSB + */ + +#ifndef UA_NODESTORE_DEFAULT_H_ +#define UA_NODESTORE_DEFAULT_H_ + +#include + +_UA_BEGIN_DECLS + +/* The HashMap Nodestore holds all nodes in RAM in single hash-map. Lookip is + * done based on hashing/comparison of the NodeId with close to O(1) lookup + * time. However, sometimes the underlying array has to be resized when nodes + * are added/removed. This can take O(n) time. */ +UA_EXPORT UA_StatusCode +UA_Nodestore_HashMap(UA_Nodestore *ns); + +/* The ZipTree Nodestore holds all nodes in RAM in a tree structure. The lookup + * time is about O(log n). Adding/removing nodes does not require resizing of + * the underlying array with the linear overhead. + * + * For most usage scenarios the hash-map Nodestore will be faster. + */ +UA_EXPORT UA_StatusCode +UA_Nodestore_ZipTree(UA_Nodestore *ns); + +_UA_END_DECLS + +#endif /* UA_NODESTORE_DEFAULT_H_ */ diff --git a/product/src/fes/include/open62541/plugin/pki.h b/product/src/fes/include/open62541/plugin/pki.h new file mode 100644 index 00000000..ce21872a --- /dev/null +++ b/product/src/fes/include/open62541/plugin/pki.h @@ -0,0 +1,77 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB + */ + +#ifndef UA_PLUGIN_PKI_H_ +#define UA_PLUGIN_PKI_H_ + +#include +#include +#include + +_UA_BEGIN_DECLS + +/** + * Public Key Infrastructure Integration + * ===================================== + * This file contains interface definitions for integration in a Public Key + * Infrastructure (PKI). Currently only one plugin interface is defined. + * + * Certificate Verification + * ------------------------ + * This plugin verifies that the origin of the certificate is trusted. It does + * not assign any access rights/roles to the holder of the certificate. + * + * Usually, implementations of the certificate verification plugin provide an + * initialization method that takes a trust-list and a revocation-list as input. + * The lifecycle of the plugin is attached to a server or client config. The + * ``clear`` method is called automatically when the config is destroyed. */ + +struct UA_CertificateVerification; +typedef struct UA_CertificateVerification UA_CertificateVerification; + +struct UA_CertificateVerification { + void *context; + + /* Verify the certificate against the configured policies and trust chain. */ + UA_StatusCode (*verifyCertificate)(const UA_CertificateVerification *cv, + const UA_ByteString *certificate); + + /* Verify that the certificate has the applicationURI in the subject name. */ + UA_StatusCode (*verifyApplicationURI)(const UA_CertificateVerification *cv, + const UA_ByteString *certificate, + const UA_String *applicationURI); + + /* Get the expire date from certificate */ + UA_StatusCode (*getExpirationDate)(UA_DateTime *expiryDateTime, + UA_ByteString *certificate); + + UA_StatusCode (*getSubjectName)(UA_String *subjectName, + UA_ByteString *certificate); + + /* Delete the certificate verification context */ + void (*clear)(UA_CertificateVerification *cv); + + /* Pointer to logging pointer in the server/client configuration. If the + * logging pointer is changed outside of the plugin, the new logger is used + * automatically*/ + const UA_Logger *logging; +}; + +/* Decrypt a private key in PEM format using a password. The output is the key + * in the binary DER format. Also succeeds if the PEM private key does not + * require a password or is already in the DER format. The outDerKey memory is + * allocated internally. + * + * Returns UA_STATUSCODE_BADSECURITYCHECKSFAILED if the password is wrong. */ +UA_EXPORT UA_StatusCode +UA_PKI_decryptPrivateKey(const UA_ByteString privateKey, + const UA_ByteString password, + UA_ByteString *outDerKey); + +_UA_END_DECLS + +#endif /* UA_PLUGIN_PKI_H_ */ diff --git a/product/src/fes/include/open62541/plugin/pki_default.h b/product/src/fes/include/open62541/plugin/pki_default.h new file mode 100644 index 00000000..a999fbbe --- /dev/null +++ b/product/src/fes/include/open62541/plugin/pki_default.h @@ -0,0 +1,54 @@ +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2019 (c) Kalycito Infotech Private Limited + */ + +#ifndef UA_PKI_CERTIFICATE_H_ +#define UA_PKI_CERTIFICATE_H_ + +#include + +_UA_BEGIN_DECLS + +/* Default implementation that accepts all certificates */ +UA_EXPORT void +UA_CertificateVerification_AcceptAll(UA_CertificateVerification *cv); + +#ifdef UA_ENABLE_ENCRYPTION + +/* Accept certificates based on a trust-list and a revocation-list. Based on + * mbedTLS. */ +UA_EXPORT UA_StatusCode +UA_CertificateVerification_Trustlist(UA_CertificateVerification *cv, + const UA_ByteString *certificateTrustList, + size_t certificateTrustListSize, + const UA_ByteString *certificateIssuerList, + size_t certificateIssuerListSize, + const UA_ByteString *certificateRevocationList, + size_t certificateRevocationListSize); + +#ifdef __linux__ /* Linux only so far */ + +#ifdef UA_ENABLE_CERT_REJECTED_DIR +UA_EXPORT UA_StatusCode +UA_CertificateVerification_CertFolders(UA_CertificateVerification *cv, + const char *trustListFolder, + const char *issuerListFolder, + const char *revocationListFolder, + const char *rejectedListFolder); +#else +UA_EXPORT UA_StatusCode +UA_CertificateVerification_CertFolders(UA_CertificateVerification *cv, + const char *trustListFolder, + const char *issuerListFolder, + const char *revocationListFolder); +#endif +#endif + +#endif + +_UA_END_DECLS + +#endif /* UA_PKI_CERTIFICATE_H_ */ diff --git a/product/src/fes/include/open62541/plugin/securitypolicy.h b/product/src/fes/include/open62541/plugin/securitypolicy.h new file mode 100644 index 00000000..1b9a32df --- /dev/null +++ b/product/src/fes/include/open62541/plugin/securitypolicy.h @@ -0,0 +1,381 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + */ + +#ifndef UA_PLUGIN_SECURITYPOLICY_H_ +#define UA_PLUGIN_SECURITYPOLICY_H_ + +#include +#include +#include + +_UA_BEGIN_DECLS + +extern UA_EXPORT const UA_String UA_SECURITY_POLICY_NONE_URI; + +struct UA_SecurityPolicy; +typedef struct UA_SecurityPolicy UA_SecurityPolicy; + +/** + * SecurityPolicy + * -------------- */ + +typedef struct { + UA_String uri; + + /* Verifies the signature of the message using the provided keys in the context. + * + * @param channelContext the channelContext that contains the key to verify + * the supplied message with. + * @param message the message to which the signature is supposed to belong. + * @param signature the signature of the message, that should be verified. */ + UA_StatusCode (*verify)(void *channelContext, const UA_ByteString *message, + const UA_ByteString *signature) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Signs the given message using this policys signing algorithm and the + * provided keys in the context. + * + * @param channelContext the channelContext that contains the key to sign + * the supplied message with. + * @param message the message to sign. + * @param signature an output buffer to which the signature is written. The + * buffer needs to be allocated by the caller. The + * necessary size can be acquired with the signatureSize + * attribute of this module. */ + UA_StatusCode (*sign)(void *channelContext, const UA_ByteString *message, + UA_ByteString *signature) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Gets the signature size that depends on the local (private) key. + * + * @param channelContext the channelContext that contains the + * certificate/key. + * @return the size of the local signature. Returns 0 if no local + * certificate was set. */ + size_t (*getLocalSignatureSize)(const void *channelContext); + + /* Gets the signature size that depends on the remote (public) key. + * + * @param channelContext the context to retrieve data from. + * @return the size of the remote signature. Returns 0 if no + * remote certificate was set previousely. */ + size_t (*getRemoteSignatureSize)(const void *channelContext); + + /* Gets the local signing key length. + * + * @param channelContext the context to retrieve data from. + * @return the length of the signing key in bytes. Returns 0 if no length can be found. + */ + size_t (*getLocalKeyLength)(const void *channelContext); + + /* Gets the local signing key length. + * + * @param channelContext the context to retrieve data from. + * @return the length of the signing key in bytes. Returns 0 if no length can be found. + */ + size_t (*getRemoteKeyLength)(const void *channelContext); +} UA_SecurityPolicySignatureAlgorithm; + +typedef struct { + UA_String uri; + + /* Encrypt the given data in place. For asymmetric encryption, the block + * size for plaintext and cypher depend on the remote key (certificate). + * + * @param channelContext the channelContext which contains information about + * the keys to encrypt data. + * @param data the data that is encrypted. The encrypted data will overwrite + * the data that was supplied. */ + UA_StatusCode (*encrypt)(void *channelContext, + UA_ByteString *data) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Decrypts the given ciphertext in place. For asymmetric encryption, the + * block size for plaintext and cypher depend on the local private key. + * + * @param channelContext the channelContext which contains information about + * the keys needed to decrypt the message. + * @param data the data to decrypt. The decryption is done in place. */ + UA_StatusCode (*decrypt)(void *channelContext, + UA_ByteString *data) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Returns the length of the key used to encrypt messages in bits. For + * asymmetric encryption the key length is for the local private key. + * + * @param channelContext the context to retrieve data from. + * @return the length of the local key. Returns 0 if no + * key length is known. */ + size_t (*getLocalKeyLength)(const void *channelContext); + + /* Returns the length of the key to encrypt messages in bits. Depends on the + * key (certificate) from the remote side. + * + * @param channelContext the context to retrieve data from. + * @return the length of the remote key. Returns 0 if no + * key length is known. */ + size_t (*getRemoteKeyLength)(const void *channelContext); + + /* Returns the size of encrypted blocks for sending. For asymmetric + * encryption this depends on the remote key (certificate). For symmetric + * encryption the local and remote encrypted block size are identical. + * + * @param channelContext the context to retrieve data from. + * @return the size of encrypted blocks in bytes. Returns 0 if no key length is known. + */ + size_t (*getRemoteBlockSize)(const void *channelContext); + + /* Returns the size of plaintext blocks for sending. For asymmetric + * encryption this depends on the remote key (certificate). For symmetric + * encryption the local and remote plaintext block size are identical. + * + * @param channelContext the context to retrieve data from. + * @return the size of plaintext blocks in bytes. Returns 0 if no key length is known. + */ + size_t (*getRemotePlainTextBlockSize)(const void *channelContext); +} UA_SecurityPolicyEncryptionAlgorithm; + +typedef struct { + /* The algorithm used to sign and verify certificates. */ + UA_SecurityPolicySignatureAlgorithm signatureAlgorithm; + + /* The algorithm used to encrypt and decrypt messages. */ + UA_SecurityPolicyEncryptionAlgorithm encryptionAlgorithm; + +} UA_SecurityPolicyCryptoModule; + +typedef struct { + /* Generates a thumbprint for the specified certificate. + * + * @param certificate the certificate to make a thumbprint of. + * @param thumbprint an output buffer for the resulting thumbprint. Always + * has the length specified in the thumbprintLength in the + * asymmetricModule. */ + UA_StatusCode (*makeCertificateThumbprint)(const UA_SecurityPolicy *securityPolicy, + const UA_ByteString *certificate, + UA_ByteString *thumbprint) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Compares the supplied certificate with the certificate in the endpoint context. + * + * @param securityPolicy the policy data that contains the certificate + * to compare to. + * @param certificateThumbprint the certificate thumbprint to compare to the + * one stored in the context. + * @return if the thumbprints match UA_STATUSCODE_GOOD is returned. If they + * don't match or an error occurred an error code is returned. */ + UA_StatusCode (*compareCertificateThumbprint)(const UA_SecurityPolicy *securityPolicy, + const UA_ByteString *certificateThumbprint) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + UA_SecurityPolicyCryptoModule cryptoModule; +} UA_SecurityPolicyAsymmetricModule; + +typedef struct { + /* Pseudo random function that is used to generate the symmetric keys. + * + * For information on what parameters this function receives in what situation, + * refer to the OPC UA specification 1.03 Part6 Table 33 + * + * @param policyContext The context of the policy instance + * @param secret + * @param seed + * @param out an output to write the data to. The length defines the maximum + * number of output bytes that are produced. */ + UA_StatusCode (*generateKey)(void *policyContext, const UA_ByteString *secret, + const UA_ByteString *seed, UA_ByteString *out) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Random generator for generating nonces. + * + * @param policyContext The context of the policy instance + * @param out pointer to a buffer to store the nonce in. Needs to be + * allocated by the caller. The buffer is filled with random + * data. */ + UA_StatusCode (*generateNonce)(void *policyContext, UA_ByteString *out) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* + * The length of the nonce used in the SecureChannel as specified in the standard. + */ + size_t secureChannelNonceLength; + + UA_SecurityPolicyCryptoModule cryptoModule; +} UA_SecurityPolicySymmetricModule; + +typedef struct { + /* This method creates a new context data object. + * + * The caller needs to call delete on the received object to free allocated + * memory. Memory is only allocated if the function succeeds so there is no + * need to manually free the memory pointed to by *channelContext or to + * call delete in case of failure. + * + * @param securityPolicy the policy context of the endpoint that is connected + * to. It will be stored in the channelContext for + * further access by the policy. + * @param remoteCertificate the remote certificate contains the remote + * asymmetric key. The certificate will be verified + * and then stored in the context so that its + * details may be accessed. + * @param channelContext the initialized channelContext that is passed to + * functions that work on a context. */ + UA_StatusCode (*newContext)(const UA_SecurityPolicy *securityPolicy, + const UA_ByteString *remoteCertificate, + void **channelContext) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Deletes the the security context. */ + void (*deleteContext)(void *channelContext); + + /* Sets the local encrypting key in the supplied context. + * + * @param channelContext the context to work on. + * @param key the local encrypting key to store in the context. */ + UA_StatusCode (*setLocalSymEncryptingKey)(void *channelContext, + const UA_ByteString *key) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Sets the local signing key in the supplied context. + * + * @param channelContext the context to work on. + * @param key the local signing key to store in the context. */ + UA_StatusCode (*setLocalSymSigningKey)(void *channelContext, + const UA_ByteString *key) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Sets the local initialization vector in the supplied context. + * + * @param channelContext the context to work on. + * @param iv the local initialization vector to store in the context. */ + UA_StatusCode (*setLocalSymIv)(void *channelContext, + const UA_ByteString *iv) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Sets the remote encrypting key in the supplied context. + * + * @param channelContext the context to work on. + * @param key the remote encrypting key to store in the context. */ + UA_StatusCode (*setRemoteSymEncryptingKey)(void *channelContext, + const UA_ByteString *key) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Sets the remote signing key in the supplied context. + * + * @param channelContext the context to work on. + * @param key the remote signing key to store in the context. */ + UA_StatusCode (*setRemoteSymSigningKey)(void *channelContext, + const UA_ByteString *key) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Sets the remote initialization vector in the supplied context. + * + * @param channelContext the context to work on. + * @param iv the remote initialization vector to store in the context. */ + UA_StatusCode (*setRemoteSymIv)(void *channelContext, + const UA_ByteString *iv) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* Compares the supplied certificate with the certificate in the channel + * context. + * + * @param channelContext the channel context data that contains the + * certificate to compare to. + * @param certificate the certificate to compare to the one stored in the context. + * @return if the certificates match UA_STATUSCODE_GOOD is returned. If they + * don't match or an errror occurred an error code is returned. */ + UA_StatusCode (*compareCertificate)(const void *channelContext, + const UA_ByteString *certificate) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; +} UA_SecurityPolicyChannelModule; + +struct UA_SecurityPolicy { + /* Additional data */ + void *policyContext; + + /* The policy uri that identifies the implemented algorithms */ + UA_String policyUri; + + /* The local certificate is specific for each SecurityPolicy since it + * depends on the used key length. */ + UA_ByteString localCertificate; + + /* Function pointers grouped into modules */ + UA_SecurityPolicyAsymmetricModule asymmetricModule; + UA_SecurityPolicySymmetricModule symmetricModule; + UA_SecurityPolicySignatureAlgorithm certificateSigningAlgorithm; + UA_SecurityPolicyChannelModule channelModule; + + const UA_Logger *logger; + + /* Updates the ApplicationInstanceCertificate and the corresponding private + * key at runtime. */ + UA_StatusCode (*updateCertificateAndPrivateKey)(UA_SecurityPolicy *policy, + const UA_ByteString newCertificate, + const UA_ByteString newPrivateKey); + + /* Deletes the dynamic content of the policy */ + void (*clear)(UA_SecurityPolicy *policy); +}; + +/** + * PubSub SecurityPolicy + * --------------------- + * + * For PubSub encryption, the message nonce is part of the (unencrypted) + * SecurityHeader. The nonce is required for the de- and encryption and has to + * be set in the channel context before de/encrypting. */ + +#ifdef UA_ENABLE_PUBSUB_ENCRYPTION +struct UA_PubSubSecurityPolicy; +typedef struct UA_PubSubSecurityPolicy UA_PubSubSecurityPolicy; + +struct UA_PubSubSecurityPolicy { + UA_String policyUri; /* The policy uri that identifies the implemented + * algorithms */ + UA_SecurityPolicySymmetricModule symmetricModule; + + /* Create the context for the WriterGroup. The keys and nonce can be NULL + * here. Then they have to be set before the first encryption or signing + * operation. */ + UA_StatusCode + (*newContext)(void *policyContext, + const UA_ByteString *signingKey, + const UA_ByteString *encryptingKey, + const UA_ByteString *keyNonce, + void **wgContext); + + /* Delete the WriterGroup SecurityPolicy context */ + void (*deleteContext)(void *wgContext); + + /* Set the keys and nonce for the WriterGroup. This is returned from the + * GetSecurityKeys method of a Security Key Service (SKS). Otherwise, set + * manually via out-of-band transmission of the keys. */ + UA_StatusCode + (*setSecurityKeys)(void *wgContext, + const UA_ByteString *signingKey, + const UA_ByteString *encryptingKey, + const UA_ByteString *keyNonce) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + /* The nonce is contained in the NetworkMessage SecurityHeader. Set before + * each en-/decryption step. */ + UA_StatusCode + (*setMessageNonce)(void *wgContext, + const UA_ByteString *nonce) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; + + const UA_Logger *logger; + + /* Deletes the dynamic content of the policy */ + void (*clear)(UA_PubSubSecurityPolicy *policy); + void *policyContext; +}; + +#endif + +_UA_END_DECLS + +#endif /* UA_PLUGIN_SECURITYPOLICY_H_ */ diff --git a/product/src/fes/include/open62541/plugin/securitypolicy_default.h b/product/src/fes/include/open62541/plugin/securitypolicy_default.h new file mode 100644 index 00000000..353a7405 --- /dev/null +++ b/product/src/fes/include/open62541/plugin/securitypolicy_default.h @@ -0,0 +1,79 @@ +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2018 (c) Daniel Feist, Precitec GmbH & Co. KG + */ + +#ifndef UA_SECURITYPOLICIES_H_ +#define UA_SECURITYPOLICIES_H_ + +#include + +_UA_BEGIN_DECLS + +UA_EXPORT UA_StatusCode +UA_SecurityPolicy_None(UA_SecurityPolicy *policy, + const UA_ByteString localCertificate, + const UA_Logger *logger); + +#ifdef UA_ENABLE_ENCRYPTION + +UA_EXPORT UA_StatusCode +UA_SecurityPolicy_Basic128Rsa15(UA_SecurityPolicy *policy, + const UA_ByteString localCertificate, + const UA_ByteString localPrivateKey, + const UA_Logger *logger); + +UA_EXPORT UA_StatusCode +UA_SecurityPolicy_Basic256(UA_SecurityPolicy *policy, + const UA_ByteString localCertificate, + const UA_ByteString localPrivateKey, + const UA_Logger *logger); + +UA_EXPORT UA_StatusCode +UA_SecurityPolicy_Basic256Sha256(UA_SecurityPolicy *policy, + const UA_ByteString localCertificate, + const UA_ByteString localPrivateKey, + const UA_Logger *logger); + +UA_EXPORT UA_StatusCode +UA_SecurityPolicy_Aes128Sha256RsaOaep(UA_SecurityPolicy *policy, + const UA_ByteString localCertificate, + const UA_ByteString localPrivateKey, + const UA_Logger *logger); + +UA_EXPORT UA_StatusCode +UA_SecurityPolicy_Aes256Sha256RsaPss(UA_SecurityPolicy *policy, + const UA_ByteString localCertificate, + const UA_ByteString localPrivateKey, + const UA_Logger *logger); + +#endif + +#ifdef UA_ENABLE_PUBSUB_ENCRYPTION + +UA_EXPORT UA_StatusCode +UA_PubSubSecurityPolicy_Aes128Ctr(UA_PubSubSecurityPolicy *policy, + const UA_Logger *logger); +UA_EXPORT UA_StatusCode +UA_PubSubSecurityPolicy_Aes256Ctr(UA_PubSubSecurityPolicy *policy, + const UA_Logger *logger); + +#endif + +#ifdef UA_ENABLE_TPM2_SECURITY + +UA_EXPORT UA_StatusCode +UA_PubSubSecurityPolicy_Aes128CtrTPM(UA_PubSubSecurityPolicy *policy, char *userpin, unsigned long slotId, + char *encryptionKeyLabel, char *signingKeyLabel, const UA_Logger *logger); +UA_EXPORT UA_StatusCode +UA_PubSubSecurityPolicy_Aes256CtrTPM(UA_PubSubSecurityPolicy *policy, char *userpin, unsigned long slotId, + char *encryptionKeyLabel, char *signingKeyLabel, const UA_Logger *logger); + +#endif + +_UA_END_DECLS + +#endif /* UA_SECURITYPOLICIES_H_ */ diff --git a/product/src/fes/include/open62541/server.h b/product/src/fes/include/open62541/server.h new file mode 100644 index 00000000..397663de --- /dev/null +++ b/product/src/fes/include/open62541/server.h @@ -0,0 +1,1977 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2014-2024 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2015-2016 (c) Sten Grüner + * Copyright 2014-2015, 2017 (c) Florian Palm + * Copyright 2015-2016 (c) Chris Iatrou + * Copyright 2015-2016 (c) Oleksiy Vasylyev + * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2017 (c) Henrik Norrman + * Copyright 2018 (c) Fabian Arndt, Root-Core + * Copyright 2017-2020 (c) HMS Industrial Networks AB (Author: Jonas Green) + * Copyright 2020-2022 (c) Christian von Arnim, ISW University of Stuttgart (for VDW and umati) + */ + +#ifndef UA_SERVER_H_ +#define UA_SERVER_H_ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef UA_ENABLE_PUBSUB +#include +#endif + +#ifdef UA_ENABLE_HISTORIZING +#include +#endif + +_UA_BEGIN_DECLS + +/* Forward declarations */ +struct UA_PubSubConfiguration; +typedef struct UA_PubSubConfiguration UA_PubSubConfiguration; +typedef void (*UA_Server_AsyncOperationNotifyCallback)(UA_Server *server); + +/** + * .. _server: + * + * Server + * ====== + * + * .. _server-configuration: + * + * Server Configuration + * -------------------- + * The configuration structure is passed to the server during initialization. + * The server expects that the configuration is not modified during runtime. + * Currently, only one server can use a configuration at a time. During + * shutdown, the server will clean up the parts of the configuration that are + * modified at runtime through the provided API. + * + * Examples for configurations are provided in the ``/plugins`` folder. + * The usual usage is as follows: + * + * 1. Create a server configuration with default settings as a starting point + * 2. Modifiy the configuration, e.g. by adding a server certificate + * 3. Instantiate a server with it + * 4. After shutdown of the server, clean up the configuration (free memory) + * + * The :ref:`tutorials` provide a good starting point for this. */ + +struct UA_ServerConfig { + void *context; /* Used to attach custom data to a server config. This can + * then be retrieved e.g. in a callback that forwards a + * pointer to the server. */ + UA_Logger *logging; /* Plugin for log output */ + + /** + * Server Description + * ^^^^^^^^^^^^^^^^^^ + * The description must be internally consistent. The ApplicationUri set in + * the ApplicationDescription must match the URI set in the server + * certificate. + * The applicationType is not just descriptive, it changes the actual + * functionality of the server. The RegisterServer service is available only + * if the server is a DiscoveryServer and the applicationType is set to the + * appropriate value.*/ + UA_BuildInfo buildInfo; + UA_ApplicationDescription applicationDescription; + + /** + * Server Lifecycle + * ^^^^^^^^^^^^^^^^ */ + /* Delay in ms from the shutdown signal (ctrl-c) until the actual shutdown. + * Clients need to be able to get a notification ahead of time. */ + UA_Double shutdownDelay; + + /* If an asynchronous server shutdown is used, this callback notifies about + * the current lifecycle state (notably the STOPPING -> STOPPED + * transition). */ + void (*notifyLifecycleState)(UA_Server *server, UA_LifecycleState state); + + /** + * Rule Handling + * ^^^^^^^^^^^^^ + * Override the handling of standard-defined behavior. These settings are + * used to balance the following contradicting requirements: + * + * - Strict conformance with the standard (for certification). + * - Ensure interoperability with old/non-conforming implementations + * encountered in the wild. + * + * The defaults are set for compatibility with the largest number of OPC UA + * vendors (with log warnings activated). Cf. Postel's Law "be conservative + * in what you send, be liberal in what you accept". + * + * See the section :ref:`rule-handling` for the possible settings. */ + + /* Verify that the server sends a timestamp in the request header */ + UA_RuleHandling verifyRequestTimestamp; + + /* Variables (that don't have a DataType of BaseDataType) must not have an + * empty variant value. The default behaviour is to auto-create a matching + * zeroed-out value for empty VariableNodes when they are added. */ + UA_RuleHandling allowEmptyVariables; + + /** + * Custom Data Types + * ^^^^^^^^^^^^^^^^^ + * The following is a linked list of arrays with custom data types. All data + * types that are accessible from here are automatically considered for the + * decoding of received messages. Custom data types are not cleaned up + * together with the configuration. So it is possible to allocate them on + * ROM. + * + * See the section on :ref:`generic-types`. Examples for working with custom + * data types are provided in ``/examples/custom_datatype/``. */ + const UA_DataTypeArray *customDataTypes; + + /** + * .. note:: See the section on :ref:`generic-types`. Examples for working + * with custom data types are provided in + * ``/examples/custom_datatype/``. */ + + /** + * EventLoop + * ^^^^^^^^^ + * The sever can be plugged into an external EventLoop. Otherwise the + * EventLoop is considered to be attached to the server's lifecycle and will + * be destroyed when the config is cleaned up. */ + UA_EventLoop *eventLoop; + UA_Boolean externalEventLoop; /* The EventLoop is not deleted with the config */ + + /** + * Networking + * ^^^^^^^^^^ + * The `severUrls` array contains the server URLs like + * `opc.tcp://my-server:4840` or `opc.wss://localhost:443`. The URLs are + * used both for discovery and to set up the server sockets based on the + * defined hostnames (and ports). + * + * - If the list is empty: Listen on all network interfaces with TCP port 4840. + * - If the hostname of a URL is empty: Use the define protocol and port and + * listen on all interfaces. */ + UA_String *serverUrls; + size_t serverUrlsSize; + + /** + * The following settings are specific to OPC UA with TCP transport. */ + UA_Boolean tcpEnabled; + UA_UInt32 tcpBufSize; /* Max length of sent and received chunks (packets) + * (default: 64kB) */ + UA_UInt32 tcpMaxMsgSize; /* Max length of messages + * (default: 0 -> unbounded) */ + UA_UInt32 tcpMaxChunks; /* Max number of chunks per message + * (default: 0 -> unbounded) */ + UA_Boolean tcpReuseAddr; + + /** + * Security and Encryption + * ^^^^^^^^^^^^^^^^^^^^^^^ */ + size_t securityPoliciesSize; + UA_SecurityPolicy* securityPolicies; + + /* Endpoints with combinations of SecurityPolicy and SecurityMode. If the + * UserIdentityToken array of the Endpoint is not set, then it will be + * filled by the server for all UserTokenPolicies that are configured in the + * AccessControl plugin. */ + size_t endpointsSize; + UA_EndpointDescription *endpoints; + + /* Only allow the following discovery services to be executed on a + * SecureChannel with SecurityPolicyNone: GetEndpointsRequest, + * FindServersRequest and FindServersOnNetworkRequest. + * + * Only enable this option if there is no endpoint with SecurityPolicy#None + * in the endpoints list. The SecurityPolicy#None must be present in the + * securityPolicies list. */ + UA_Boolean securityPolicyNoneDiscoveryOnly; + + /* Allow clients without encryption support to connect with username and password. + * This requires to transmit the password in plain text over the network which is + * why this option is disabled by default. + * Make sure you really need this before enabling plain text passwords. */ + UA_Boolean allowNonePolicyPassword; + + /* Different sets of certificates are trusted for SecureChannel / Session */ + UA_CertificateVerification secureChannelPKI; + UA_CertificateVerification sessionPKI; + + /** + * See the section for :ref:`access-control + * handling`. */ + UA_AccessControl accessControl; + + /** + * Nodes and Node Lifecycle + * ^^^^^^^^^^^^^^^^^^^^^^^^ + * See the section for :ref:`node lifecycle handling`. */ + UA_Nodestore nodestore; + UA_GlobalNodeLifecycle nodeLifecycle; + + /** + * Copy the HasModellingRule reference in instances from the type + * definition in UA_Server_addObjectNode and UA_Server_addVariableNode. + * + * Part 3 - 6.4.4: [...] it is not required that newly created or referenced + * instances based on InstanceDeclarations have a ModellingRule, however, it + * is allowed that they have any ModellingRule independent of the + * ModellingRule of their InstanceDeclaration */ + UA_Boolean modellingRulesOnInstances; + + /** + * Limits + * ^^^^^^ */ + /* Limits for SecureChannels */ + UA_UInt16 maxSecureChannels; + UA_UInt32 maxSecurityTokenLifetime; /* in ms */ + + /* Limits for Sessions */ + UA_UInt16 maxSessions; + UA_Double maxSessionTimeout; /* in ms */ + + /* Operation limits */ + UA_UInt32 maxNodesPerRead; + UA_UInt32 maxNodesPerWrite; + UA_UInt32 maxNodesPerMethodCall; + UA_UInt32 maxNodesPerBrowse; + UA_UInt32 maxNodesPerRegisterNodes; + UA_UInt32 maxNodesPerTranslateBrowsePathsToNodeIds; + UA_UInt32 maxNodesPerNodeManagement; + UA_UInt32 maxMonitoredItemsPerCall; + + /* Limits for Requests */ + UA_UInt32 maxReferencesPerNode; + + /** + * Async Operations + * ^^^^^^^^^^^^^^^^ + * See the section for :ref:`async operations`. */ +#if UA_MULTITHREADING >= 100 + UA_Double asyncOperationTimeout; /* in ms, 0 => unlimited */ + size_t maxAsyncOperationQueueSize; /* 0 => unlimited */ + /* Notify workers when an async operation was enqueued */ + UA_Server_AsyncOperationNotifyCallback asyncOperationNotifyCallback; +#endif + + /** + * Discovery + * ^^^^^^^^^ */ +#ifdef UA_ENABLE_DISCOVERY + /* Timeout in seconds when to automatically remove a registered server from + * the list, if it doesn't re-register within the given time frame. A value + * of 0 disables automatic removal. Default is 60 Minutes (60*60). Must be + * bigger than 10 seconds, because cleanup is only triggered approximately + * every 10 seconds. The server will still be removed depending on the + * state of the semaphore file. */ + UA_UInt32 discoveryCleanupTimeout; + +# ifdef UA_ENABLE_DISCOVERY_MULTICAST + UA_Boolean mdnsEnabled; + UA_MdnsDiscoveryConfiguration mdnsConfig; + UA_String mdnsInterfaceIP; +# if !defined(UA_HAS_GETIFADDR) + size_t mdnsIpAddressListSize; + UA_UInt32 *mdnsIpAddressList; +# endif +# endif +#endif + + /** + * Subscriptions + * ^^^^^^^^^^^^^ */ + UA_Boolean subscriptionsEnabled; +#ifdef UA_ENABLE_SUBSCRIPTIONS + /* Limits for Subscriptions */ + UA_UInt32 maxSubscriptions; + UA_UInt32 maxSubscriptionsPerSession; + UA_DurationRange publishingIntervalLimits; /* in ms (must not be less than 5) */ + UA_UInt32Range lifeTimeCountLimits; + UA_UInt32Range keepAliveCountLimits; + UA_UInt32 maxNotificationsPerPublish; + UA_Boolean enableRetransmissionQueue; + UA_UInt32 maxRetransmissionQueueSize; /* 0 -> unlimited size */ +# ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + UA_UInt32 maxEventsPerNode; /* 0 -> unlimited size */ +# endif + + /* Limits for MonitoredItems */ + UA_UInt32 maxMonitoredItems; + UA_UInt32 maxMonitoredItemsPerSubscription; + UA_DurationRange samplingIntervalLimits; /* in ms (must not be less than 5) */ + UA_UInt32Range queueSizeLimits; /* Negotiated with the client */ + + /* Limits for PublishRequests */ + UA_UInt32 maxPublishReqPerSession; + + /* Register MonitoredItem in Userland + * + * @param server Allows the access to the server object + * @param sessionId The session id, represented as an node id + * @param sessionContext An optional pointer to user-defined data for the + * specific data source + * @param nodeid Id of the node in question + * @param nodeidContext An optional pointer to user-defined data, associated + * with the node in the nodestore. Note that, if the node has already + * been removed, this value contains a NULL pointer. + * @param attributeId Identifies which attribute (value, data type etc.) is + * monitored + * @param removed Determines if the MonitoredItem was removed or created. */ + void (*monitoredItemRegisterCallback)(UA_Server *server, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeId, + void *nodeContext, + UA_UInt32 attibuteId, + UA_Boolean removed); +#endif + + /** + * PubSub + * ^^^^^^ */ + UA_Boolean pubsubEnabled; +#ifdef UA_ENABLE_PUBSUB + UA_PubSubConfiguration pubSubConfig; +#endif + + /** + * Historical Access + * ^^^^^^^^^^^^^^^^^ */ + UA_Boolean historizingEnabled; +#ifdef UA_ENABLE_HISTORIZING + UA_HistoryDatabase historyDatabase; + + UA_Boolean accessHistoryDataCapability; + UA_UInt32 maxReturnDataValues; /* 0 -> unlimited size */ + + UA_Boolean accessHistoryEventsCapability; + UA_UInt32 maxReturnEventValues; /* 0 -> unlimited size */ + + UA_Boolean insertDataCapability; + UA_Boolean insertEventCapability; + UA_Boolean insertAnnotationsCapability; + + UA_Boolean replaceDataCapability; + UA_Boolean replaceEventCapability; + + UA_Boolean updateDataCapability; + UA_Boolean updateEventCapability; + + UA_Boolean deleteRawCapability; + UA_Boolean deleteEventCapability; + UA_Boolean deleteAtTimeDataCapability; +#endif + + /** + * Reverse Connect + * ^^^^^^^^^^^^^^^ */ + UA_UInt32 reverseReconnectInterval; /* Default is 15000 ms */ + + /** + * Certificate Password Callback + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ +#ifdef UA_ENABLE_ENCRYPTION + /* If the private key is in PEM format and password protected, this callback + * is called during initialization to get the password to decrypt the + * private key. The memory containing the password is freed by the client + * after use. The callback should be set early, other parts of the client + * config setup may depend on it. */ + UA_StatusCode (*privateKeyPasswordCallback)(UA_ServerConfig *sc, + UA_ByteString *password); +#endif +}; + +void UA_EXPORT +UA_ServerConfig_clean(UA_ServerConfig *config); + +/** + * .. _server-lifecycle: + * + * Server Lifecycle + * ---------------- */ + +/* Create a new server with a default configuration that adds plugins for + * networking, security, logging and so on. See `server_config_default.h` for + * more detailed options. + * + * The default configuration can be used as the starting point to adjust the + * server configuration to individual needs. UA_Server_new is implemented in the + * /plugins folder under the CC0 license. Furthermore the server confiugration + * only uses the public server API. + * + * @return Returns the configured server or NULL if an error occurs. */ +UA_EXPORT UA_Server * +UA_Server_new(void); + +/* Creates a new server. Moves the config into the server with a shallow copy. + * The config content is cleared together with the server. */ +UA_EXPORT UA_Server * +UA_Server_newWithConfig(UA_ServerConfig *config); + +/* Delete the server. */ +UA_EXPORT UA_StatusCode +UA_Server_delete(UA_Server *server); + +/* Get the configuration. Always succeeds as this simplfy resolves a pointer. + * Attention! Do not adjust the configuration while the server is running! */ +UA_EXPORT UA_ServerConfig * +UA_Server_getConfig(UA_Server *server); + +/* Get the current server lifecycle state */ +UA_EXPORT UA_LifecycleState +UA_Server_getLifecycleState(UA_Server *server); + +/* Runs the server until interrupted. On Unix/Windows this registers an + * interrupt for SIGINT (ctrl-c). The method only returns after having received + * the interrupt. The logical sequence is as follows: + * + * - UA_Server_run_startup + * - Loop until interrupt: UA_Server_run_iterate + * - UA_Server_run_shutdown + * + * @param server The server object. + * @return Returns a bad statuscode if an error occurred internally. */ +UA_EXPORT UA_StatusCode +UA_Server_run(UA_Server *server, const volatile UA_Boolean *running); + +/* Runs the server until interrupted. On Unix/Windows this registers an + * interrupt for SIGINT (ctrl-c). The method only returns after having received + * the interrupt or upon an error condition. The logical sequence is as follows: + * + * - Register the interrupt + * - UA_Server_run_startup + * - Loop until interrupt: UA_Server_run_iterate + * - UA_Server_run_shutdown + * - Deregister the interrupt + * + * Attention! This method is implemented individually for the different + * platforms (POSIX/Win32/etc.). The default implementation is in + * /plugins/ua_config_default.c under the CC0 license. Adjust as needed. + * + * @param server The server object. + * @return Returns a bad statuscode if an error occurred internally. */ +UA_EXPORT UA_StatusCode +UA_Server_runUntilInterrupt(UA_Server *server); + +/* The prologue part of UA_Server_run (no need to use if you call + * UA_Server_run or UA_Server_runUntilInterrupt) */ +UA_EXPORT UA_StatusCode +UA_Server_run_startup(UA_Server *server); + +/* Executes a single iteration of the server's main loop. + * + * @param server The server object. + * @param waitInternal Should we wait for messages in the networklayer? + * Otherwise, the timouts for the networklayers are set to zero. + * The default max wait time is 200ms. + * @return Returns how long we can wait until the next scheduled + * callback (in ms) */ +UA_EXPORT UA_UInt16 +UA_Server_run_iterate(UA_Server *server, UA_Boolean waitInternal); + +/* The epilogue part of UA_Server_run (no need to use if you call + * UA_Server_run or UA_Server_runUntilInterrupt) */ +UA_EXPORT UA_StatusCode +UA_Server_run_shutdown(UA_Server *server); + +/** + * Timed Callbacks + * --------------- + * Add a callback to the server that is executed at a defined time. + * The callback can also be registered with a cyclic interval. */ + +/* Add a callback for execution at a specified time. If the indicated time lies + * in the past, then the callback is executed at the next iteration of the + * server's main loop. + * + * @param server The server object. + * @param callback The callback that shall be added. + * @param data Data that is forwarded to the callback. + * @param date The timestamp for the execution time. + * @param callbackId Set to the identifier of the repeated callback . This can + * be used to cancel the callback later on. If the pointer is null, the + * identifier is not set. + * @return Upon success, ``UA_STATUSCODE_GOOD`` is returned. An error code + * otherwise. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_addTimedCallback(UA_Server *server, UA_ServerCallback callback, + void *data, UA_DateTime date, UA_UInt64 *callbackId); + +/* Add a callback for cyclic repetition to the server. + * + * @param server The server object. + * @param callback The callback that shall be added. + * @param data Data that is forwarded to the callback. + * @param interval_ms The callback shall be repeatedly executed with the given + * interval (in ms). The interval must be positive. The first execution + * occurs at now() + interval at the latest. + * @param callbackId Set to the identifier of the repeated callback . This can + * be used to cancel the callback later on. If the pointer is null, the + * identifier is not set. + * @return Upon success, ``UA_STATUSCODE_GOOD`` is returned. An error code + * otherwise. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_addRepeatedCallback(UA_Server *server, UA_ServerCallback callback, + void *data, UA_Double interval_ms, + UA_UInt64 *callbackId); + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_changeRepeatedCallbackInterval(UA_Server *server, UA_UInt64 callbackId, + UA_Double interval_ms); + +/* Remove a repeated callback. Does nothing if the callback is not found. + * + * @param server The server object. + * @param callbackId The id of the callback */ +void UA_EXPORT UA_THREADSAFE +UA_Server_removeCallback(UA_Server *server, UA_UInt64 callbackId); + +#define UA_Server_removeRepeatedCallback(server, callbackId) \ + UA_Server_removeCallback(server, callbackId); + +/** + * Session Handling + * ---------------- + * A new session is announced via the AccessControl plugin. The session + * identifier is forwarded to the relevant callbacks back into userland. The + * following methods enable an interaction with a particular session. */ + +/* Manually close a session */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_closeSession(UA_Server *server, const UA_NodeId *sessionId); + +/** + * Session attributes: Besides the user-definable session context pointer (set + * by the AccessControl plugin when the Session is created), a session carries + * attributes in a key-value list. Some attributes are present in every session + * and shown in the list below. Additional attributes can be manually set as + * meta-data. + * + * Always present as session attributes are: + * + * - 0:localeIds [UA_String]: List of preferred languages (read-only) + * - 0:clientDescription [UA_ApplicationDescription]: Client description (read-only) + * - 0:sessionName [String] Client-defined name of the session (read-only) + * - 0:clientUserId [String] User identifier used to activate the session (read-only) */ + +/* Returns a shallow copy of the attribute. Don't _clear or _delete the value + * variant. Don't use the value once the Session could be already closed in the + * background or the attribute of the session replaced. Hence don't use this in a + * multi-threaded application. */ +UA_EXPORT UA_StatusCode +UA_Server_getSessionAttribute(UA_Server *server, const UA_NodeId *sessionId, + const UA_QualifiedName key, UA_Variant *outValue); + +/* Return a deep copy of the attribute */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_getSessionAttributeCopy(UA_Server *server, const UA_NodeId *sessionId, + const UA_QualifiedName key, UA_Variant *outValue); + +/* Returns NULL if the attribute is not defined or not a scalar or not of the + * right datatype. Otherwise a shallow copy of the scalar value is created at + * the target location of the void pointer. Hence don't use this in a + * multi-threaded application. */ +UA_EXPORT UA_StatusCode +UA_Server_getSessionAttribute_scalar(UA_Server *server, + const UA_NodeId *sessionId, + const UA_QualifiedName key, + const UA_DataType *type, + void *outValue); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_setSessionAttribute(UA_Server *server, const UA_NodeId *sessionId, + const UA_QualifiedName key, + const UA_Variant *value); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_deleteSessionAttribute(UA_Server *server, const UA_NodeId *sessionId, + const UA_QualifiedName key); + +/** + * Reading and Writing Node Attributes + * ----------------------------------- + * The functions for reading and writing node attributes call the regular read + * and write service in the background that are also used over the network. + * + * The following attributes cannot be read, since the local "admin" user always + * has full rights. + * + * - UserWriteMask + * - UserAccessLevel + * - UserExecutable */ + +/* Read an attribute of a node. The specialized functions below provide a more + * concise syntax. + * + * @param server The server object. + * @param item ReadValueIds contain the NodeId of the target node, the id of the + * attribute to read and (optionally) an index range to read parts + * of an array only. See the section on NumericRange for the format + * used for array ranges. + * @param timestamps Which timestamps to return for the attribute. + * @return Returns a DataValue that contains either an error code, or a variant + * with the attribute value and the timestamps. */ +UA_DataValue UA_EXPORT UA_THREADSAFE +UA_Server_read(UA_Server *server, const UA_ReadValueId *item, + UA_TimestampsToReturn timestamps); + +/* Don't use this function. There are typed versions for every supported + * attribute. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +__UA_Server_read(UA_Server *server, const UA_NodeId *nodeId, + UA_AttributeId attributeId, void *v); + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readNodeId(UA_Server *server, const UA_NodeId nodeId, + UA_NodeId *outNodeId) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_NODEID, outNodeId); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readNodeClass(UA_Server *server, const UA_NodeId nodeId, + UA_NodeClass *outNodeClass) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_NODECLASS, + outNodeClass); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readBrowseName(UA_Server *server, const UA_NodeId nodeId, + UA_QualifiedName *outBrowseName) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_BROWSENAME, + outBrowseName); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readDisplayName(UA_Server *server, const UA_NodeId nodeId, + UA_LocalizedText *outDisplayName) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_DISPLAYNAME, + outDisplayName); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readDescription(UA_Server *server, const UA_NodeId nodeId, + UA_LocalizedText *outDescription) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_DESCRIPTION, + outDescription); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readWriteMask(UA_Server *server, const UA_NodeId nodeId, + UA_UInt32 *outWriteMask) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_WRITEMASK, + outWriteMask); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readIsAbstract(UA_Server *server, const UA_NodeId nodeId, + UA_Boolean *outIsAbstract) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_ISABSTRACT, + outIsAbstract); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readSymmetric(UA_Server *server, const UA_NodeId nodeId, + UA_Boolean *outSymmetric) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_SYMMETRIC, + outSymmetric); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readInverseName(UA_Server *server, const UA_NodeId nodeId, + UA_LocalizedText *outInverseName) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_INVERSENAME, + outInverseName); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readContainsNoLoops(UA_Server *server, const UA_NodeId nodeId, + UA_Boolean *outContainsNoLoops) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_CONTAINSNOLOOPS, + outContainsNoLoops); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readEventNotifier(UA_Server *server, const UA_NodeId nodeId, + UA_Byte *outEventNotifier) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_EVENTNOTIFIER, + outEventNotifier); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readValue(UA_Server *server, const UA_NodeId nodeId, + UA_Variant *outValue) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_VALUE, outValue); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readDataType(UA_Server *server, const UA_NodeId nodeId, + UA_NodeId *outDataType) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_DATATYPE, + outDataType); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readValueRank(UA_Server *server, const UA_NodeId nodeId, + UA_Int32 *outValueRank) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_VALUERANK, + outValueRank); +} + +/* Returns a variant with an int32 array */ +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readArrayDimensions(UA_Server *server, const UA_NodeId nodeId, + UA_Variant *outArrayDimensions) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_ARRAYDIMENSIONS, + outArrayDimensions); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readAccessLevel(UA_Server *server, const UA_NodeId nodeId, + UA_Byte *outAccessLevel) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_ACCESSLEVEL, + outAccessLevel); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readAccessLevelEx(UA_Server *server, const UA_NodeId nodeId, + UA_UInt32 *outAccessLevelEx) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_ACCESSLEVELEX, + outAccessLevelEx); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readMinimumSamplingInterval(UA_Server *server, const UA_NodeId nodeId, + UA_Double *outMinimumSamplingInterval) { + return __UA_Server_read(server, &nodeId, + UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, + outMinimumSamplingInterval); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readHistorizing(UA_Server *server, const UA_NodeId nodeId, + UA_Boolean *outHistorizing) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_HISTORIZING, + outHistorizing); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_readExecutable(UA_Server *server, const UA_NodeId nodeId, + UA_Boolean *outExecutable) { + return __UA_Server_read(server, &nodeId, UA_ATTRIBUTEID_EXECUTABLE, + outExecutable); +} + +/** + * The following node attributes cannot be changed once a node has been created: + * + * - NodeClass + * - NodeId + * - Symmetric + * - ContainsNoLoops + * + * The following attributes cannot be written from the server, as they are + * specific to the different users and set by the access control callback: + * + * - UserWriteMask + * - UserAccessLevel + * - UserExecutable + */ + +/* Overwrite an attribute of a node. The specialized functions below provide a + * more concise syntax. + * + * @param server The server object. + * @param value WriteValues contain the NodeId of the target node, the id of the + * attribute to overwritten, the actual value and (optionally) an + * index range to replace parts of an array only. of an array only. + * See the section on NumericRange for the format used for array + * ranges. + * @return Returns a status code. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_write(UA_Server *server, const UA_WriteValue *value); + +/* Don't use this function. There are typed versions with no additional + * overhead. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +__UA_Server_write(UA_Server *server, const UA_NodeId *nodeId, + const UA_AttributeId attributeId, + const UA_DataType *attr_type, const void *attr); + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeBrowseName(UA_Server *server, const UA_NodeId nodeId, + const UA_QualifiedName browseName) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_BROWSENAME, + &UA_TYPES[UA_TYPES_QUALIFIEDNAME], &browseName); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeDisplayName(UA_Server *server, const UA_NodeId nodeId, + const UA_LocalizedText displayName) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_DISPLAYNAME, + &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &displayName); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeDescription(UA_Server *server, const UA_NodeId nodeId, + const UA_LocalizedText description) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_DESCRIPTION, + &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &description); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeWriteMask(UA_Server *server, const UA_NodeId nodeId, + const UA_UInt32 writeMask) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_WRITEMASK, + &UA_TYPES[UA_TYPES_UINT32], &writeMask); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeIsAbstract(UA_Server *server, const UA_NodeId nodeId, + const UA_Boolean isAbstract) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_ISABSTRACT, + &UA_TYPES[UA_TYPES_BOOLEAN], &isAbstract); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeInverseName(UA_Server *server, const UA_NodeId nodeId, + const UA_LocalizedText inverseName) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_INVERSENAME, + &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &inverseName); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeEventNotifier(UA_Server *server, const UA_NodeId nodeId, + const UA_Byte eventNotifier) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_EVENTNOTIFIER, + &UA_TYPES[UA_TYPES_BYTE], &eventNotifier); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeValue(UA_Server *server, const UA_NodeId nodeId, + const UA_Variant value) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_VALUE, + &UA_TYPES[UA_TYPES_VARIANT], &value); +} + +/* Writes an UA_DataValue to a variable/variableType node. In contrast to + * UA_Server_writeValue, this functions can also write SourceTimestamp, + * ServerTimestamp and StatusCode. */ +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeDataValue(UA_Server *server, const UA_NodeId nodeId, + const UA_DataValue value) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_VALUE, + &UA_TYPES[UA_TYPES_DATAVALUE], &value); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeDataType(UA_Server *server, const UA_NodeId nodeId, + const UA_NodeId dataType) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_DATATYPE, + &UA_TYPES[UA_TYPES_NODEID], &dataType); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeValueRank(UA_Server *server, const UA_NodeId nodeId, + const UA_Int32 valueRank) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_VALUERANK, + &UA_TYPES[UA_TYPES_INT32], &valueRank); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeArrayDimensions(UA_Server *server, const UA_NodeId nodeId, + const UA_Variant arrayDimensions) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_ARRAYDIMENSIONS, + &UA_TYPES[UA_TYPES_VARIANT], &arrayDimensions); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeAccessLevel(UA_Server *server, const UA_NodeId nodeId, + const UA_Byte accessLevel) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_ACCESSLEVEL, + &UA_TYPES[UA_TYPES_BYTE], &accessLevel); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeAccessLevelEx(UA_Server *server, const UA_NodeId nodeId, + const UA_UInt32 accessLevelEx) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_ACCESSLEVELEX, + &UA_TYPES[UA_TYPES_UINT32], &accessLevelEx); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeMinimumSamplingInterval(UA_Server *server, const UA_NodeId nodeId, + const UA_Double miniumSamplingInterval) { + return __UA_Server_write(server, &nodeId, + UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL, + &UA_TYPES[UA_TYPES_DOUBLE], + &miniumSamplingInterval); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeHistorizing(UA_Server *server, const UA_NodeId nodeId, + const UA_Boolean historizing) { + return __UA_Server_write(server, &nodeId, + UA_ATTRIBUTEID_HISTORIZING, + &UA_TYPES[UA_TYPES_BOOLEAN], + &historizing); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_writeExecutable(UA_Server *server, const UA_NodeId nodeId, + const UA_Boolean executable) { + return __UA_Server_write(server, &nodeId, UA_ATTRIBUTEID_EXECUTABLE, + &UA_TYPES[UA_TYPES_BOOLEAN], &executable); } + +/** + * Browsing + * -------- */ + +/* Browse the references of a particular node. See the definition of + * BrowseDescription structure for details. */ +UA_BrowseResult UA_EXPORT UA_THREADSAFE +UA_Server_browse(UA_Server *server, UA_UInt32 maxReferences, + const UA_BrowseDescription *bd); + +UA_BrowseResult UA_EXPORT UA_THREADSAFE +UA_Server_browseNext(UA_Server *server, UA_Boolean releaseContinuationPoint, + const UA_ByteString *continuationPoint); + +/* Non-standard version of the Browse service that recurses into child nodes. + * + * Possible loops (that can occur for non-hierarchical references) are handled + * internally. Every node is added at most once to the results array. + * + * Nodes are only added if they match the NodeClassMask in the + * BrowseDescription. However, child nodes are still recursed into if the + * NodeClass does not match. So it is possible, for example, to get all + * VariableNodes below a certain ObjectNode, with additional objects in the + * hierarchy below. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_browseRecursive(UA_Server *server, const UA_BrowseDescription *bd, + size_t *resultsSize, UA_ExpandedNodeId **results); + +UA_BrowsePathResult UA_EXPORT UA_THREADSAFE +UA_Server_translateBrowsePathToNodeIds(UA_Server *server, + const UA_BrowsePath *browsePath); + +/* A simplified TranslateBrowsePathsToNodeIds based on the + * SimpleAttributeOperand type (Part 4, 7.4.4.5). + * + * This specifies a relative path using a list of BrowseNames instead of the + * RelativePath structure. The list of BrowseNames is equivalent to a + * RelativePath that specifies forward references which are subtypes of the + * HierarchicalReferences ReferenceType. All Nodes followed by the browsePath + * shall be of the NodeClass Object or Variable. */ +UA_BrowsePathResult UA_EXPORT UA_THREADSAFE +UA_Server_browseSimplifiedBrowsePath(UA_Server *server, const UA_NodeId origin, + size_t browsePathSize, + const UA_QualifiedName *browsePath); + +#ifndef HAVE_NODEITER_CALLBACK +#define HAVE_NODEITER_CALLBACK +/* Iterate over all nodes referenced by parentNodeId by calling the callback + * function for each child node (in ifdef because GCC/CLANG handle include order + * differently) */ +typedef UA_StatusCode +(*UA_NodeIteratorCallback)(UA_NodeId childId, UA_Boolean isInverse, + UA_NodeId referenceTypeId, void *handle); +#endif + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId, + UA_NodeIteratorCallback callback, void *handle); + +#ifdef UA_ENABLE_DISCOVERY + +/** + * Discovery + * --------- + * + * Registering at a Discovery Server + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ + +/* Register the given server instance at the discovery server. This should be + * called periodically, for example every 10 minutes, depending on the + * configuration of the discovery server. You should also call + * _unregisterDiscovery when the server shuts down. + * + * The supplied client configuration is used to create a new client to connect + * to the discovery server. The client configuration is moved over to the server + * and eventually cleaned up internally. The structure pointed at by `cc` is + * zeroed to avoid accessing outdated information. + * + * The eventloop and logging plugins in the client configuration are replaced by + * those configured in the server. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_registerDiscovery(UA_Server *server, UA_ClientConfig *cc, + const UA_String discoveryServerUrl, + const UA_String semaphoreFilePath); + +/* Deregister the given server instance from the discovery server. + * This should be called when the server is shutting down. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_deregisterDiscovery(UA_Server *server, UA_ClientConfig *cc, + const UA_String discoveryServerUrl); + +/** + * Operating a Discovery Server + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ + +/* Callback for RegisterServer. Data is passed from the register call */ +typedef void +(*UA_Server_registerServerCallback)(const UA_RegisteredServer *registeredServer, + void* data); + +/* Set the callback which is called if another server registeres or unregisters + * with this instance. This callback is called every time the server gets a + * register call. This especially means that for every periodic server register + * the callback will be called. + * + * @param server + * @param cb the callback + * @param data data passed to the callback + * @return ``UA_STATUSCODE_SUCCESS`` on success */ +void UA_EXPORT UA_THREADSAFE +UA_Server_setRegisterServerCallback(UA_Server *server, + UA_Server_registerServerCallback cb, void* data); + +#ifdef UA_ENABLE_DISCOVERY_MULTICAST + +/* Callback for server detected through mDNS. Data is passed from the register + * call + * + * @param isServerAnnounce indicates if the server has just been detected. If + * set to false, this means the server is shutting down. + * @param isTxtReceived indicates if we already received the corresponding TXT + * record with the path and caps data */ +typedef void +(*UA_Server_serverOnNetworkCallback)(const UA_ServerOnNetwork *serverOnNetwork, + UA_Boolean isServerAnnounce, + UA_Boolean isTxtReceived, void* data); + +/* Set the callback which is called if another server is found through mDNS or + * deleted. It will be called for any mDNS message from the remote server, thus + * it may be called multiple times for the same instance. Also the SRV and TXT + * records may arrive later, therefore for the first call the server + * capabilities may not be set yet. If called multiple times, previous data will + * be overwritten. + * + * @param server + * @param cb the callback + * @param data data passed to the callback + * @return ``UA_STATUSCODE_SUCCESS`` on success */ +void UA_EXPORT UA_THREADSAFE +UA_Server_setServerOnNetworkCallback(UA_Server *server, + UA_Server_serverOnNetworkCallback cb, + void* data); + +#endif /* UA_ENABLE_DISCOVERY_MULTICAST */ + +#endif /* UA_ENABLE_DISCOVERY */ + +/** + * Information Model Callbacks + * --------------------------- + * There are three places where a callback from an information model to + * user-defined code can happen. + * + * - Custom node constructors and destructors + * - Linking VariableNodes with an external data source + * - MethodNode callbacks */ + +void UA_EXPORT +UA_Server_setAdminSessionContext(UA_Server *server, + void *context); + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_setNodeTypeLifecycle(UA_Server *server, UA_NodeId nodeId, + UA_NodeTypeLifecycle lifecycle); + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_getNodeContext(UA_Server *server, UA_NodeId nodeId, + void **nodeContext); + +/* Careful! The user has to ensure that the destructor callbacks still work. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_setNodeContext(UA_Server *server, UA_NodeId nodeId, + void *nodeContext); + +/** + * .. _datasource: + * + * Data Source Callback + * ^^^^^^^^^^^^^^^^^^^^ + * The server has a unique way of dealing with the content of variables. Instead + * of storing a variant attached to the variable node, the node can point to a + * function with a local data provider. Whenever the value attribute is read, + * the function will be called and asked to provide a UA_DataValue return value + * that contains the value content and additional timestamps. + * + * It is expected that the read callback is implemented. The write callback can + * be set to a null-pointer. */ + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_setVariableNode_dataSource(UA_Server *server, const UA_NodeId nodeId, + const UA_DataSource dataSource); + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_setVariableNode_valueCallback(UA_Server *server, + const UA_NodeId nodeId, + const UA_ValueCallback callback); + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_setVariableNode_valueBackend(UA_Server *server, + const UA_NodeId nodeId, + const UA_ValueBackend valueBackend); + +/** + * .. _local-monitoreditems: + * + * Local MonitoredItems + * ^^^^^^^^^^^^^^^^^^^^ + * MonitoredItems are used with the Subscription mechanism of OPC UA to + * transported notifications for data changes and events. MonitoredItems can + * also be registered locally. Notifications are then forwarded to a + * user-defined callback instead of a remote client. */ + +#ifdef UA_ENABLE_SUBSCRIPTIONS + +typedef void (*UA_Server_DataChangeNotificationCallback) + (UA_Server *server, UA_UInt32 monitoredItemId, void *monitoredItemContext, + const UA_NodeId *nodeId, void *nodeContext, UA_UInt32 attributeId, + const UA_DataValue *value); + +typedef void (*UA_Server_EventNotificationCallback) + (UA_Server *server, UA_UInt32 monId, void *monContext, + size_t nEventFields, const UA_Variant *eventFields); + +/* Create a local MonitoredItem with a sampling interval that detects data + * changes. + * + * @param server The server executing the MonitoredItem + * @timestampsToReturn Shall timestamps be added to the value for the callback? + * @item The parameters of the new MonitoredItem. Note that the attribute of the + * ReadValueId (the node that is monitored) can not be + * ``UA_ATTRIBUTEID_EVENTNOTIFIER``. A different callback type needs to be + * registered for event notifications. + * @monitoredItemContext A pointer that is forwarded with the callback + * @callback The callback that is executed on detected data changes + * + * @return Returns a description of the created MonitoredItem. The structure + * also contains a StatusCode (in case of an error) and the identifier of the + * new MonitoredItem. */ +UA_MonitoredItemCreateResult UA_EXPORT UA_THREADSAFE +UA_Server_createDataChangeMonitoredItem(UA_Server *server, + UA_TimestampsToReturn timestampsToReturn, + const UA_MonitoredItemCreateRequest item, + void *monitoredItemContext, + UA_Server_DataChangeNotificationCallback callback); + +/* UA_MonitoredItemCreateResult UA_EXPORT */ +/* UA_Server_createEventMonitoredItem(UA_Server *server, */ +/* UA_TimestampsToReturn timestampsToReturn, */ +/* const UA_MonitoredItemCreateRequest item, void *context, */ +/* UA_Server_EventNotificationCallback callback); */ + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_deleteMonitoredItem(UA_Server *server, UA_UInt32 monitoredItemId); + +#endif + +/** + * Method Callbacks + * ^^^^^^^^^^^^^^^^ + * Method callbacks are set to `NULL` (not executable) when a method node is + * added over the network. In theory, it is possible to add a callback via + * ``UA_Server_setMethodNode_callback`` within the global constructor when + * adding methods over the network is really wanted. See the Section + * :ref:`object-interaction` for calling methods on an object. */ + +#ifdef UA_ENABLE_METHODCALLS +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_setMethodNodeCallback(UA_Server *server, + const UA_NodeId methodNodeId, + UA_MethodCallback methodCallback); + +/* Backwards compatibility definition */ +#define UA_Server_setMethodNode_callback(server, methodNodeId, methodCallback) \ + UA_Server_setMethodNodeCallback(server, methodNodeId, methodCallback) + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_getMethodNodeCallback(UA_Server *server, + const UA_NodeId methodNodeId, + UA_MethodCallback *outMethodCallback); + +UA_CallMethodResult UA_EXPORT UA_THREADSAFE +UA_Server_call(UA_Server *server, const UA_CallMethodRequest *request); +#endif + +/** + * .. _object-interaction: + * + * Interacting with Objects + * ------------------------ + * Objects in the information model are represented as ObjectNodes. Some + * convenience functions are provided to simplify the interaction with objects. */ + +/* Write an object property. The property is represented as a VariableNode with + * a ``HasProperty`` reference from the ObjectNode. The VariableNode is + * identified by its BrowseName. Writing the property sets the value attribute + * of the VariableNode. + * + * @param server The server object + * @param objectId The identifier of the object (node) + * @param propertyName The name of the property + * @param value The value to be set for the event attribute + * @return The StatusCode for setting the event attribute */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_writeObjectProperty(UA_Server *server, const UA_NodeId objectId, + const UA_QualifiedName propertyName, + const UA_Variant value); + +/* Directly point to the scalar value instead of a variant */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_writeObjectProperty_scalar(UA_Server *server, const UA_NodeId objectId, + const UA_QualifiedName propertyName, + const void *value, const UA_DataType *type); + +/* Read an object property. + * + * @param server The server object + * @param objectId The identifier of the object (node) + * @param propertyName The name of the property + * @param value Contains the property value after reading. Must not be NULL. + * @return The StatusCode for setting the event attribute */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_readObjectProperty(UA_Server *server, const UA_NodeId objectId, + const UA_QualifiedName propertyName, + UA_Variant *value); + +/** + * .. _addnodes: + * + * Node Addition and Deletion + * -------------------------- + * When creating dynamic node instances at runtime, chances are that you will + * not care about the specific NodeId of the new node, as long as you can + * reference it later. When passing numeric NodeIds with a numeric identifier 0, + * the stack evaluates this as "select a random unassigned numeric NodeId in + * that namespace". To find out which NodeId was actually assigned to the new + * node, you may pass a pointer `outNewNodeId`, which will (after a successful + * node insertion) contain the nodeId of the new node. You may also pass a + * ``NULL`` pointer if this result is not needed. + * + * See the Section :ref:`node-lifecycle` on constructors and on attaching + * user-defined data to nodes. + * + * The Section :ref:`default-node-attributes` contains useful starting points + * for defining node attributes. Forgetting to set the ValueRank or the + * AccessLevel leads to errors that can be hard to track down for new users. The + * default attributes have a high likelihood to "do the right thing". + * + * The methods for node addition and deletion take mostly const arguments that + * are not modified. When creating a node, a deep copy of the node identifier, + * node attributes, etc. is created. Therefore, it is possible to call for + * example ``UA_Server_addVariablenode`` with a value attribute (a + * :ref:`variant`) pointing to a memory location on the stack. If you need + * changes to a variable value to manifest at a specific memory location, please + * use a :ref:`datasource` or a :ref:`value-callback`. */ + +/* Don't use this function. There are typed versions as inline functions. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +__UA_Server_addNode(UA_Server *server, const UA_NodeClass nodeClass, + const UA_NodeId *requestedNewNodeId, + const UA_NodeId *parentNodeId, + const UA_NodeId *referenceTypeId, + const UA_QualifiedName browseName, + const UA_NodeId *typeDefinition, + const UA_NodeAttributes *attr, + const UA_DataType *attributeType, + void *nodeContext, UA_NodeId *outNewNodeId); + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_addVariableNode(UA_Server *server, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_NodeId typeDefinition, + const UA_VariableAttributes attr, + void *nodeContext, UA_NodeId *outNewNodeId) { + return __UA_Server_addNode(server, UA_NODECLASS_VARIABLE, &requestedNewNodeId, + &parentNodeId, &referenceTypeId, browseName, + &typeDefinition, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], + nodeContext, outNewNodeId); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_addVariableTypeNode(UA_Server *server, + const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_NodeId typeDefinition, + const UA_VariableTypeAttributes attr, + void *nodeContext, UA_NodeId *outNewNodeId) { + return __UA_Server_addNode(server, UA_NODECLASS_VARIABLETYPE, + &requestedNewNodeId, &parentNodeId, &referenceTypeId, + browseName, &typeDefinition, + (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES], + nodeContext, outNewNodeId); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_addObjectNode(UA_Server *server, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_NodeId typeDefinition, + const UA_ObjectAttributes attr, + void *nodeContext, UA_NodeId *outNewNodeId) { + return __UA_Server_addNode(server, UA_NODECLASS_OBJECT, &requestedNewNodeId, + &parentNodeId, &referenceTypeId, browseName, + &typeDefinition, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], + nodeContext, outNewNodeId); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_addObjectTypeNode(UA_Server *server, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_ObjectTypeAttributes attr, + void *nodeContext, UA_NodeId *outNewNodeId) { + return __UA_Server_addNode(server, UA_NODECLASS_OBJECTTYPE, &requestedNewNodeId, + &parentNodeId, &referenceTypeId, browseName, + &UA_NODEID_NULL, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES], + nodeContext, outNewNodeId); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_addViewNode(UA_Server *server, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_ViewAttributes attr, + void *nodeContext, UA_NodeId *outNewNodeId) { + return __UA_Server_addNode(server, UA_NODECLASS_VIEW, &requestedNewNodeId, + &parentNodeId, &referenceTypeId, browseName, + &UA_NODEID_NULL, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_VIEWATTRIBUTES], + nodeContext, outNewNodeId); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_addReferenceTypeNode(UA_Server *server, + const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_ReferenceTypeAttributes attr, + void *nodeContext, UA_NodeId *outNewNodeId) { + return __UA_Server_addNode(server, UA_NODECLASS_REFERENCETYPE, + &requestedNewNodeId, &parentNodeId, &referenceTypeId, + browseName, &UA_NODEID_NULL, + (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES], + nodeContext, outNewNodeId); +} + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_addDataTypeNode(UA_Server *server, + const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_DataTypeAttributes attr, + void *nodeContext, UA_NodeId *outNewNodeId) { + return __UA_Server_addNode(server, UA_NODECLASS_DATATYPE, &requestedNewNodeId, + &parentNodeId, &referenceTypeId, browseName, + &UA_NODEID_NULL, (const UA_NodeAttributes*)&attr, + &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES], + nodeContext, outNewNodeId); +} + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_addDataSourceVariableNode(UA_Server *server, + const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_NodeId typeDefinition, + const UA_VariableAttributes attr, + const UA_DataSource dataSource, + void *nodeContext, UA_NodeId *outNewNodeId); + +/* VariableNodes that are "dynamic" (default for user-created variables) receive + * and store a SourceTimestamp. For non-dynamic VariableNodes the current time + * is used for the SourceTimestamp. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_setVariableNodeDynamic(UA_Server *server, const UA_NodeId nodeId, + UA_Boolean isDynamic); + +#ifdef UA_ENABLE_METHODCALLS + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_addMethodNodeEx(UA_Server *server, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_MethodAttributes attr, UA_MethodCallback method, + size_t inputArgumentsSize, const UA_Argument *inputArguments, + const UA_NodeId inputArgumentsRequestedNewNodeId, + UA_NodeId *inputArgumentsOutNewNodeId, + size_t outputArgumentsSize, const UA_Argument *outputArguments, + const UA_NodeId outputArgumentsRequestedNewNodeId, + UA_NodeId *outputArgumentsOutNewNodeId, + void *nodeContext, UA_NodeId *outNewNodeId); + +static UA_INLINE UA_THREADSAFE UA_StatusCode +UA_Server_addMethodNode(UA_Server *server, const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, const UA_MethodAttributes attr, + UA_MethodCallback method, + size_t inputArgumentsSize, const UA_Argument *inputArguments, + size_t outputArgumentsSize, const UA_Argument *outputArguments, + void *nodeContext, UA_NodeId *outNewNodeId) { + return UA_Server_addMethodNodeEx(server, requestedNewNodeId, parentNodeId, + referenceTypeId, browseName, attr, method, + inputArgumentsSize, inputArguments, + UA_NODEID_NULL, NULL, + outputArgumentsSize, outputArguments, + UA_NODEID_NULL, NULL, + nodeContext, outNewNodeId); +} + +#endif + + +/** + * The method pair UA_Server_addNode_begin and _finish splits the AddNodes + * service in two parts. This is useful if the node shall be modified before + * finish the instantiation. For example to add children with specific NodeIds. + * Otherwise, mandatory children (e.g. of an ObjectType) are added with + * pseudo-random unique NodeIds. Existing children are detected during the + * _finish part via their matching BrowseName. + * + * The _begin method: + * - prepares the node and adds it to the nodestore + * - copies some unassigned attributes from the TypeDefinition node internally + * - adds the references to the parent (and the TypeDefinition if applicable) + * - performs type-checking of variables. + * + * You can add an object node without a parent if you set the parentNodeId and + * referenceTypeId to UA_NODE_ID_NULL. Then you need to add the parent reference + * and hasTypeDef reference yourself before calling the _finish method. + * Not that this is only allowed for object nodes. + * + * The _finish method: + * - copies mandatory children + * - calls the node constructor(s) at the end + * - may remove the node if it encounters an error. + * + * The special UA_Server_addMethodNode_finish method needs to be used for method + * nodes, since there you need to explicitly specifiy the input and output + * arguments which are added in the finish step (if not yet already there) */ + +/* The ``attr`` argument must have a type according to the NodeClass. + * ``VariableAttributes`` for variables, ``ObjectAttributes`` for objects, and + * so on. Missing attributes are taken from the TypeDefinition node if + * applicable. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_addNode_begin(UA_Server *server, const UA_NodeClass nodeClass, + const UA_NodeId requestedNewNodeId, + const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, + const UA_QualifiedName browseName, + const UA_NodeId typeDefinition, + const void *attr, const UA_DataType *attributeType, + void *nodeContext, UA_NodeId *outNewNodeId); + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_addNode_finish(UA_Server *server, const UA_NodeId nodeId); + +#ifdef UA_ENABLE_METHODCALLS + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_addMethodNode_finish(UA_Server *server, const UA_NodeId nodeId, + UA_MethodCallback method, + size_t inputArgumentsSize, const UA_Argument *inputArguments, + size_t outputArgumentsSize, const UA_Argument *outputArguments); + +#endif + +/* Deletes a node and optionally all references leading to the node. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_deleteNode(UA_Server *server, const UA_NodeId nodeId, + UA_Boolean deleteReferences); + +/** + * Reference Management + * -------------------- */ + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_addReference(UA_Server *server, const UA_NodeId sourceId, + const UA_NodeId refTypeId, + const UA_ExpandedNodeId targetId, UA_Boolean isForward); + +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_deleteReference(UA_Server *server, const UA_NodeId sourceNodeId, + const UA_NodeId referenceTypeId, UA_Boolean isForward, + const UA_ExpandedNodeId targetNodeId, + UA_Boolean deleteBidirectional); + +/** + * .. _events: + * + * Events + * ------ + * The method ``UA_Server_createEvent`` creates an event and represents it as + * node. The node receives a unique `EventId` which is automatically added to + * the node. The method returns a `NodeId` to the object node which represents + * the event through ``outNodeId``. The `NodeId` can be used to set the + * attributes of the event. The generated `NodeId` is always numeric. + * ``outNodeId`` cannot be ``NULL``. + * + * Note: In order to see an event in UAExpert, the field `Time` must be given a + * value! + * + * The method ``UA_Server_triggerEvent`` "triggers" an event by adding it to all + * monitored items of the specified origin node and those of all its parents. + * Any filters specified by the monitored items are automatically applied. Using + * this method deletes the node generated by ``UA_Server_createEvent``. The + * `EventId` for the new event is generated automatically and is returned + * through ``outEventId``. ``NULL`` can be passed if the `EventId` is not + * needed. ``deleteEventNode`` specifies whether the node representation of the + * event should be deleted after invoking the method. This can be useful if + * events with the similar attributes are triggered frequently. ``UA_TRUE`` + * would cause the node to be deleted. */ + +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + +/* Creates a node representation of an event + * + * @param server The server object + * @param eventType The type of the event for which a node should be created + * @param outNodeId The NodeId of the newly created node for the event + * @return The StatusCode of the UA_Server_createEvent method */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_createEvent(UA_Server *server, const UA_NodeId eventType, + UA_NodeId *outNodeId); + +/* Triggers a node representation of an event by applying EventFilters and + * adding the event to the appropriate queues. + * + * @param server The server object + * @param eventNodeId The NodeId of the node representation of the event which + * should be triggered + * @param outEvent the EventId of the new event + * @param deleteEventNode Specifies whether the node representation of the event + * should be deleted + * @return The StatusCode of the UA_Server_triggerEvent method */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_triggerEvent(UA_Server *server, const UA_NodeId eventNodeId, + const UA_NodeId originId, UA_ByteString *outEventId, + const UA_Boolean deleteEventNode); + +#endif /* UA_ENABLE_SUBSCRIPTIONS_EVENTS */ + +/** + * Alarms & Conditions (Experimental) + * ---------------------------------- */ + +#ifdef UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS +typedef enum UA_TwoStateVariableCallbackType { + UA_ENTERING_ENABLEDSTATE, + UA_ENTERING_ACKEDSTATE, + UA_ENTERING_CONFIRMEDSTATE, + UA_ENTERING_ACTIVESTATE +} UA_TwoStateVariableCallbackType; + +/* Callback prototype to set user specific callbacks */ +typedef UA_StatusCode +(*UA_TwoStateVariableChangeCallback)(UA_Server *server, const UA_NodeId *condition); + +/* Create condition instance. The function checks first whether the passed + * conditionType is a subType of ConditionType. Then checks whether the + * condition source has HasEventSource reference to its parent. If not, a + * HasEventSource reference will be created between condition source and server + * object. To expose the condition in address space, a hierarchical + * ReferenceType should be passed to create the reference to condition source. + * Otherwise, UA_NODEID_NULL should be passed to make the condition not exposed. + * + * @param server The server object + * @param conditionId The NodeId of the requested Condition Object. When passing + * UA_NODEID_NUMERIC(X,0) an unused nodeid in namespace X will be used. + * E.g. passing UA_NODEID_NULL will result in a NodeId in namespace 0. + * @param conditionType The NodeId of the node representation of the ConditionType + * @param conditionName The name of the condition to be created + * @param conditionSource The NodeId of the Condition Source (Parent of the Condition) + * @param hierarchialReferenceType The NodeId of Hierarchical ReferenceType + * between Condition and its source + * @param outConditionId The NodeId of the created Condition + * @return The StatusCode of the UA_Server_createCondition method */ +UA_StatusCode UA_EXPORT +UA_Server_createCondition(UA_Server *server, + const UA_NodeId conditionId, + const UA_NodeId conditionType, + const UA_QualifiedName conditionName, + const UA_NodeId conditionSource, + const UA_NodeId hierarchialReferenceType, + UA_NodeId *outConditionId); + +/* The method pair UA_Server_addCondition_begin and _finish splits the + * UA_Server_createCondtion in two parts similiar to the + * UA_Server_addNode_begin / _finish pair. This is useful if the node shall be + * modified before finish the instantiation. For example to add children with + * specific NodeIds. + * For details refer to the UA_Server_addNode_begin / _finish methods. + * + * Additionally to UA_Server_addNode_begin UA_Server_addCondition_begin checks + * if the passed condition type is a subtype of the OPC UA ConditionType. + * + * @param server The server object + * @param conditionId The NodeId of the requested Condition Object. When passing + * UA_NODEID_NUMERIC(X,0) an unused nodeid in namespace X will be used. + * E.g. passing UA_NODEID_NULL will result in a NodeId in namespace 0. + * @param conditionType The NodeId of the node representation of the ConditionType + * @param conditionName The name of the condition to be added + * @param outConditionId The NodeId of the added Condition + * @return The StatusCode of the UA_Server_addCondition_begin method */ +UA_StatusCode UA_EXPORT +UA_Server_addCondition_begin(UA_Server *server, + const UA_NodeId conditionId, + const UA_NodeId conditionType, + const UA_QualifiedName conditionName, + UA_NodeId *outConditionId); + +/* Second call of the UA_Server_addCondition_begin and _finish pair. + * Additionally to UA_Server_addNode_finish UA_Server_addCondition_finish: + * - checks whether the condition source has HasEventSource reference to its + * parent. If not, a HasEventSource reference will be created between + * condition source and server object + * - exposes the condition in the address space if hierarchialReferenceType is + * not UA_NODEID_NULL by adding a reference of this type from the condition + * source to the condition instance + * - initializes the standard condition fields and callbacks + * + * @param server The server object + * @param conditionId The NodeId of the unfinished Condition Object + * @param conditionSource The NodeId of the Condition Source (Parent of the Condition) + * @param hierarchialReferenceType The NodeId of Hierarchical ReferenceType + * between Condition and its source + * @return The StatusCode of the UA_Server_addCondition_finish method */ + +UA_StatusCode UA_EXPORT +UA_Server_addCondition_finish(UA_Server *server, + const UA_NodeId conditionId, + const UA_NodeId conditionSource, + const UA_NodeId hierarchialReferenceType); + +/* Set the value of condition field. + * + * @param server The server object + * @param condition The NodeId of the node representation of the Condition Instance + * @param value Variant Value to be written to the Field + * @param fieldName Name of the Field in which the value should be written + * @return The StatusCode of the UA_Server_setConditionField method*/ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_setConditionField(UA_Server *server, + const UA_NodeId condition, + const UA_Variant *value, + const UA_QualifiedName fieldName); + +/* Set the value of property of condition field. + * + * @param server The server object + * @param condition The NodeId of the node representation of the Condition + * Instance + * @param value Variant Value to be written to the Field + * @param variableFieldName Name of the Field which has a property + * @param variablePropertyName Name of the Field Property in which the value + * should be written + * @return The StatusCode of the UA_Server_setConditionVariableFieldProperty*/ +UA_StatusCode UA_EXPORT +UA_Server_setConditionVariableFieldProperty(UA_Server *server, + const UA_NodeId condition, + const UA_Variant *value, + const UA_QualifiedName variableFieldName, + const UA_QualifiedName variablePropertyName); + +/* Triggers an event only for an enabled condition. The condition list is + * updated then with the last generated EventId. + * + * @param server The server object + * @param condition The NodeId of the node representation of the Condition Instance + * @param conditionSource The NodeId of the node representation of the Condition Source + * @param outEventId last generated EventId + * @return The StatusCode of the UA_Server_triggerConditionEvent method */ +UA_StatusCode UA_EXPORT +UA_Server_triggerConditionEvent(UA_Server *server, + const UA_NodeId condition, + const UA_NodeId conditionSource, + UA_ByteString *outEventId); + +/* Add an optional condition field using its name. (TODO Adding optional methods + * is not implemented yet) + * + * @param server The server object + * @param condition The NodeId of the node representation of the Condition Instance + * @param conditionType The NodeId of the node representation of the Condition Type + * from which the optional field comes + * @param fieldName Name of the optional field + * @param outOptionalVariable The NodeId of the created field (Variable Node) + * @return The StatusCode of the UA_Server_addConditionOptionalField method */ +UA_StatusCode UA_EXPORT +UA_Server_addConditionOptionalField(UA_Server *server, + const UA_NodeId condition, + const UA_NodeId conditionType, + const UA_QualifiedName fieldName, + UA_NodeId *outOptionalVariable); + +/* Function used to set a user specific callback to TwoStateVariable Fields of a + * condition. The callbacks will be called before triggering the events when + * transition to true State of EnabledState/Id, AckedState/Id, ConfirmedState/Id + * and ActiveState/Id occurs. + * + * @param server The server object + * @param condition The NodeId of the node representation of the Condition Instance + * @param conditionSource The NodeId of the node representation of the Condition Source + * @param removeBranch (Not Implemented yet) + * @param callback User specific callback function + * @param callbackType Callback function type, indicates where it should be called + * @return The StatusCode of the UA_Server_setConditionTwoStateVariableCallback method */ +UA_StatusCode UA_EXPORT +UA_Server_setConditionTwoStateVariableCallback(UA_Server *server, + const UA_NodeId condition, + const UA_NodeId conditionSource, + UA_Boolean removeBranch, + UA_TwoStateVariableChangeCallback callback, + UA_TwoStateVariableCallbackType callbackType); + +/* Delete a condition from the address space and the internal lists. + * + * @param server The server object + * @param condition The NodeId of the node representation of the Condition Instance + * @param conditionSource The NodeId of the node representation of the Condition Source + * @return ``UA_STATUSCODE_GOOD`` on success */ +UA_StatusCode UA_EXPORT +UA_Server_deleteCondition(UA_Server *server, + const UA_NodeId condition, + const UA_NodeId conditionSource); + +/* Set the LimitState of the LimitAlarmType + * + * @param server The server object + * @param conditionId NodeId of the node representation of the Condition Instance + * @param limitValue The value from the trigger node */ +UA_StatusCode UA_EXPORT +UA_Server_setLimitState(UA_Server *server, const UA_NodeId conditionId, + UA_Double limitValue); + +/* Parse the certifcate and set Expiration date + * + * @param server The server object + * @param conditionId NodeId of the node representation of the Condition Instance + * @param cert The certificate for parsing */ +UA_StatusCode UA_EXPORT +UA_Server_setExpirationDate(UA_Server *server, const UA_NodeId conditionId, + UA_ByteString cert); + +#endif /* UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS */ + +/** + * Update the Server Certificate at Runtime + * ---------------------------------------- */ + +UA_StatusCode UA_EXPORT +UA_Server_updateCertificate(UA_Server *server, + const UA_ByteString *oldCertificate, + const UA_ByteString *newCertificate, + const UA_ByteString *newPrivateKey, + UA_Boolean closeSessions, + UA_Boolean closeSecureChannels); + +/** + * Utility Functions + * ----------------- */ + +/* Lookup a datatype by its NodeId. Takes the custom types in the server + * configuration into account. Return NULL if none found. */ +UA_EXPORT const UA_DataType * +UA_Server_findDataType(UA_Server *server, const UA_NodeId *typeId); + +/* Add a new namespace to the server. Returns the index of the new namespace */ +UA_UInt16 UA_EXPORT UA_THREADSAFE +UA_Server_addNamespace(UA_Server *server, const char* name); + +/* Get namespace by name from the server. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_getNamespaceByName(UA_Server *server, const UA_String namespaceUri, + size_t* foundIndex); + +/* Get namespace by id from the server. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_getNamespaceByIndex(UA_Server *server, const size_t namespaceIndex, + UA_String *foundUri); + +/** + * .. _async-operations: + * + * Async Operations + * ---------------- + * Some operations (such as reading out a sensor that needs to warm up) can take + * quite some time. In order not to block the server during such an operation, it + * can be "outsourced" to a worker thread. + * + * Take the example of a CallRequest. It is split into the individual method call + * operations. If the method is marked as async, then the operation is put into a + * queue where it is be retrieved by a worker. The worker returns the result when + * ready. See the examples in ``/examples/tutorial_server_method_async.c`` for + * the usage. + * + * Note that the operation can time out (see the asyncOperationTimeout setting in + * the server config) also when it has been retrieved by the worker. */ + +#if UA_MULTITHREADING >= 100 + +/* Set the async flag in a method node */ +UA_StatusCode UA_EXPORT +UA_Server_setMethodNodeAsync(UA_Server *server, const UA_NodeId id, + UA_Boolean isAsync); + +typedef enum { + UA_ASYNCOPERATIONTYPE_INVALID, /* 0, the default */ + UA_ASYNCOPERATIONTYPE_CALL + /* UA_ASYNCOPERATIONTYPE_READ, */ + /* UA_ASYNCOPERATIONTYPE_WRITE, */ +} UA_AsyncOperationType; + +typedef union { + UA_CallMethodRequest callMethodRequest; + /* UA_ReadValueId readValueId; */ + /* UA_WriteValue writeValue; */ +} UA_AsyncOperationRequest; + +typedef union { + UA_CallMethodResult callMethodResult; + /* UA_DataValue readResult; */ + /* UA_StatusCode writeResult; */ +} UA_AsyncOperationResponse; + +/* Get the next async operation without blocking + * + * @param server The server object + * @param type The type of the async operation + * @param request Receives pointer to the operation + * @param context Receives the pointer to the operation context + * @param timeout The timestamp when the operation times out and can + * no longer be returned to the client. The response has to + * be set in UA_Server_setAsyncOperationResult in any case. + * @return false if queue is empty, true else */ +UA_Boolean UA_EXPORT +UA_Server_getAsyncOperationNonBlocking(UA_Server *server, + UA_AsyncOperationType *type, + const UA_AsyncOperationRequest **request, + void **context, UA_DateTime *timeout); + +/* UA_Boolean UA_EXPORT */ +/* UA_Server_getAsyncOperationBlocking(UA_Server *server, */ +/* UA_AsyncOperationType *type, */ +/* const UA_AsyncOperationRequest **request, */ +/* void **context, UA_DateTime *timeout); */ + +/* Submit an async operation result + * + * @param server The server object + * @param response Pointer to the operation result + * @param context Pointer to the operation context */ +void UA_EXPORT +UA_Server_setAsyncOperationResult(UA_Server *server, + const UA_AsyncOperationResponse *response, + void *context); + +#endif /* !UA_MULTITHREADING >= 100 */ + +/** + * Statistics + * ---------- + * Statistic counters keeping track of the current state of the stack. Counters + * are structured per OPC UA communication layer. */ + +typedef struct { + UA_SecureChannelStatistics scs; + UA_SessionStatistics ss; +} UA_ServerStatistics; + +UA_ServerStatistics UA_EXPORT +UA_Server_getStatistics(UA_Server *server); + +/** + * Reverse Connect + * --------------- + * The reverse connect feature of OPC UA permits the server instead of the + * client to establish the connection. The client must expose the listening port + * so the server is able to reach it. */ + +/* The reverse connect state change callback is called whenever the state of a + * reverse connect is changed by a connection attempt, a successful connection + * or a connection loss. + * + * The reverse connect states reflect the state of the secure channel currently + * associated with a reverse connect. The state will remain + * UA_SECURECHANNELSTATE_CONNECTING while the server attempts repeatedly to + * establish a connection. */ +typedef void (*UA_Server_ReverseConnectStateCallback)(UA_Server *server, + UA_UInt64 handle, + UA_SecureChannelState state, + void *context); + +/* Registers a reverse connect in the server. The server periodically attempts + * to establish a connection if the initial connect fails or if the connection + * breaks. + * + * @param server The server object + * @param url The URL of the remote client + * @param stateCallback The callback which will be called on state changes + * @param callbackContext The context for the state callback + * @param handle Is set to the handle of the reverse connect if not NULL + * @return Returns UA_STATUSCODE_GOOD if the reverse connect has been registered */ +UA_StatusCode UA_EXPORT +UA_Server_addReverseConnect(UA_Server *server, UA_String url, + UA_Server_ReverseConnectStateCallback stateCallback, + void *callbackContext, UA_UInt64 *handle); + +/* Removes a reverse connect from the server and closes the connection if it is + * currently open. + * + * @param server The server object + * @param handle The handle of the reverse connect to remove + * @return Returns UA_STATUSCODE_GOOD if the reverse connect has been + * successfully removed */ +UA_StatusCode UA_EXPORT +UA_Server_removeReverseConnect(UA_Server *server, UA_UInt64 handle); + +_UA_END_DECLS + +#ifdef UA_ENABLE_PUBSUB +#include +#endif + +#endif /* UA_SERVER_H_ */ diff --git a/product/src/fes/include/open62541/server_config_default.h b/product/src/fes/include/open62541/server_config_default.h new file mode 100644 index 00000000..d3828b30 --- /dev/null +++ b/product/src/fes/include/open62541/server_config_default.h @@ -0,0 +1,266 @@ +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2019 (c) Kalycito Infotech Private Limited + */ + +#ifndef UA_SERVER_CONFIG_DEFAULT_H_ +#define UA_SERVER_CONFIG_DEFAULT_H_ + +#include + +_UA_BEGIN_DECLS + +/**********************/ +/* Default Connection */ +/**********************/ + +extern const UA_EXPORT +UA_ConnectionConfig UA_ConnectionConfig_default; + +/*************************/ +/* Default Server Config */ +/*************************/ + +/* Creates a new server config with one endpoint and custom buffer size. + * + * The config will set the tcp network layer to the given port and adds a single + * endpoint with the security policy ``SecurityPolicy#None`` to the server. + * If the port is set to 0, it will be dynamically assigned. + * A server certificate may be supplied but is optional. + * Additionally you can define a custom buffer size for send and receive buffer. + * + * @param portNumber The port number for the tcp network layer + * @param certificate Optional certificate for the server endpoint. Can be + * ``NULL``. + * @param sendBufferSize The size in bytes for the network send buffer + * @param recvBufferSize The size in bytes for the network receive buffer + * + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_setMinimalCustomBuffer(UA_ServerConfig *config, + UA_UInt16 portNumber, + const UA_ByteString *certificate, + UA_UInt32 sendBufferSize, + UA_UInt32 recvBufferSize); + +/* Creates a new server config with one endpoint. + * + * The config will set the tcp network layer to the given port and adds a single + * endpoint with the security policy ``SecurityPolicy#None`` to the server. A + * server certificate may be supplied but is optional. */ +static UA_INLINE UA_StatusCode +UA_ServerConfig_setMinimal(UA_ServerConfig *config, UA_UInt16 portNumber, + const UA_ByteString *certificate) { + return UA_ServerConfig_setMinimalCustomBuffer(config, portNumber, + certificate, 0, 0); +} + +#ifdef UA_ENABLE_ENCRYPTION + +UA_EXPORT UA_StatusCode +UA_ServerConfig_setDefaultWithSecurityPolicies(UA_ServerConfig *conf, + UA_UInt16 portNumber, + const UA_ByteString *certificate, + const UA_ByteString *privateKey, + const UA_ByteString *trustList, + size_t trustListSize, + const UA_ByteString *issuerList, + size_t issuerListSize, + const UA_ByteString *revocationList, + size_t revocationListSize); + +UA_EXPORT UA_StatusCode +UA_ServerConfig_setDefaultWithSecureSecurityPolicies(UA_ServerConfig *conf, + UA_UInt16 portNumber, + const UA_ByteString *certificate, + const UA_ByteString *privateKey, + const UA_ByteString *trustList, + size_t trustListSize, + const UA_ByteString *issuerList, + size_t issuerListSize, + const UA_ByteString *revocationList, + size_t revocationListSize); + +#endif + +/* Creates a server config on the default port 4840 with no server + * certificate. */ +static UA_INLINE UA_StatusCode +UA_ServerConfig_setDefault(UA_ServerConfig *config) { + return UA_ServerConfig_setMinimal(config, 4840, NULL); +} + +/* Creates a new server config with no security policies and no endpoints. + * + * It initializes reasonable defaults for many things, but does not + * add any security policies and endpoints. + * Use the various UA_ServerConfig_addXxx functions to add them. + * The config will set the tcp network layer to the default port 4840 if the + * eventloop is not already set. + * + * @param conf The configuration to manipulate + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_setBasics(UA_ServerConfig *conf); + +/* Creates a new server config with no security policies and no endpoints. + * + * It initializes reasonable defaults for many things, but does not + * add any security policies and endpoints. + * Use the various UA_ServerConfig_addXxx functions to add them. + * The config will set the tcp network layer to the given port if the + * eventloop is not already set. + * If the port is set to 0, it will be dynamically assigned. + * + * @param conf The configuration to manipulate + * @param portNumber The port number for the tcp network layer + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_setBasics_withPort(UA_ServerConfig *conf, + UA_UInt16 portNumber); + +/* Adds the security policy ``SecurityPolicy#None`` to the server. A + * server certificate may be supplied but is optional. + * + * @param config The configuration to manipulate + * @param certificate The optional server certificate. + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_addSecurityPolicyNone(UA_ServerConfig *config, + const UA_ByteString *certificate); + +#ifdef UA_ENABLE_ENCRYPTION + +/* Adds the security policy ``SecurityPolicy#Basic128Rsa15`` to the server. A + * server certificate may be supplied but is optional. + * + * Certificate verification should be configured before calling this + * function. See PKI plugin. + * + * @param config The configuration to manipulate + * @param certificate The server certificate. + * @param privateKey The private key that corresponds to the certificate. + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_addSecurityPolicyBasic128Rsa15(UA_ServerConfig *config, + const UA_ByteString *certificate, + const UA_ByteString *privateKey); + +/* Adds the security policy ``SecurityPolicy#Basic256`` to the server. A + * server certificate may be supplied but is optional. + * + * Certificate verification should be configured before calling this + * function. See PKI plugin. + * + * @param config The configuration to manipulate + * @param certificate The server certificate. + * @param privateKey The private key that corresponds to the certificate. + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_addSecurityPolicyBasic256(UA_ServerConfig *config, + const UA_ByteString *certificate, + const UA_ByteString *privateKey); + +/* Adds the security policy ``SecurityPolicy#Basic256Sha256`` to the server. A + * server certificate may be supplied but is optional. + * + * Certificate verification should be configured before calling this + * function. See PKI plugin. + * + * @param config The configuration to manipulate + * @param certificate The server certificate. + * @param privateKey The private key that corresponds to the certificate. + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_addSecurityPolicyBasic256Sha256(UA_ServerConfig *config, + const UA_ByteString *certificate, + const UA_ByteString *privateKey); + +/* Adds the security policy ``SecurityPolicy#Aes128Sha256RsaOaep`` to the server. A + * server certificate may be supplied but is optional. + * + * Certificate verification should be configured before calling this + * function. See PKI plugin. + * + * @param config The configuration to manipulate + * @param certificate The server certificate. + * @param privateKey The private key that corresponds to the certificate. + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_addSecurityPolicyAes128Sha256RsaOaep(UA_ServerConfig *config, + const UA_ByteString *certificate, + const UA_ByteString *privateKey); + +/* Adds the security policy ``SecurityPolicy#Aes256Sha256RsaPss`` to the server. A + * server certificate may be supplied but is optional. + * + * Certificate verification should be configured before calling this + * function. See PKI plugin. + * + * @param config The configuration to manipulate + * @param certificate The server certificate. + * @param privateKey The private key that corresponds to the certificate. + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_addSecurityPolicyAes256Sha256RsaPss(UA_ServerConfig *config, + const UA_ByteString *certificate, + const UA_ByteString *privateKey); + +/* Adds all supported security policies and sets up certificate + * validation procedures. + * + * Certificate verification should be configured before calling this + * function. See PKI plugin. + * + * @param config The configuration to manipulate + * @param certificate The server certificate. + * @param privateKey The private key that corresponds to the certificate. + * @param trustList The trustList for client certificate validation. + * @param trustListSize The trustList size. + * @param revocationList The revocationList for client certificate validation. + * @param revocationListSize The revocationList size. + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_addAllSecurityPolicies(UA_ServerConfig *config, + const UA_ByteString *certificate, + const UA_ByteString *privateKey); + +UA_EXPORT UA_StatusCode +UA_ServerConfig_addAllSecureSecurityPolicies(UA_ServerConfig *config, + const UA_ByteString *certificate, + const UA_ByteString *privateKey); + +#endif + +/* Adds an endpoint for the given security policy and mode. The security + * policy has to be added already. See UA_ServerConfig_addXxx functions. + * + * @param config The configuration to manipulate + * @param securityPolicyUri The security policy for which to add the endpoint. + * @param securityMode The security mode for which to add the endpoint. + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_addEndpoint(UA_ServerConfig *config, const UA_String securityPolicyUri, + UA_MessageSecurityMode securityMode); + +/* Adds endpoints for all configured security policies in each mode. + * + * @param config The configuration to manipulate + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_addAllEndpoints(UA_ServerConfig *config); + +/* Adds endpoints for all secure configured security policies in each mode. + * + * @param config The configuration to manipulate + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_addAllSecureEndpoints(UA_ServerConfig *config); + +_UA_END_DECLS + +#endif /* UA_SERVER_CONFIG_DEFAULT_H_ */ diff --git a/product/src/fes/include/open62541/server_config_file_based.h b/product/src/fes/include/open62541/server_config_file_based.h new file mode 100644 index 00000000..c0f39a21 --- /dev/null +++ b/product/src/fes/include/open62541/server_config_file_based.h @@ -0,0 +1,33 @@ +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2023 (c) Fraunhofer IOSB (Author: Noel Graf) + */ + +#ifndef UA_SERVER_CONFIG_FILE_BASED_H +#define UA_SERVER_CONFIG_FILE_BASED_H + +#include +#include +#include + +_UA_BEGIN_DECLS + +/* Loads the server configuration from a Json5 file into the server. + * + * @param json The configuration in json5 format. + */ +UA_EXPORT UA_Server * +UA_Server_newFromFile(const UA_ByteString json_config); + +/* Loads the server configuration from a Json5 file into the server. + * + * @param config The server configuration. + * @param json The configuration in json5 format. + */ +UA_EXPORT UA_StatusCode +UA_ServerConfig_updateFromFile(UA_ServerConfig *config, const UA_ByteString json_config); + +_UA_END_DECLS + +#endif //UA_SERVER_CONFIG_FILE_BASED_H diff --git a/product/src/fes/include/open62541/server_pubsub.h b/product/src/fes/include/open62541/server_pubsub.h new file mode 100644 index 00000000..615b729d --- /dev/null +++ b/product/src/fes/include/open62541/server_pubsub.h @@ -0,0 +1,984 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2017-2022 Fraunhofer IOSB (Author: Andreas Ebner) + * Copyright (c) 2019 Kalycito Infotech Private Limited + * Copyright (c) 2021 Fraunhofer IOSB (Author: Jan Hermes) + * Copyright (c) 2022 Siemens AG (Author: Thomas Fischer) + * Copyright (c) 2022 Linutronix GmbH (Author: Muddasir Shakil) + */ + +#ifndef UA_SERVER_PUBSUB_H +#define UA_SERVER_PUBSUB_H + +#include +#include +#include +#include +#include + +_UA_BEGIN_DECLS + +#ifdef UA_ENABLE_PUBSUB + +/** + * .. _pubsub: + * + * PubSub + * ====== + * + * In PubSub the participating OPC UA Applications take their roles as + * Publishers and Subscribers. Publishers are the sources of data, while + * Subscribers consume that data. Communication in PubSub is message-based. + * Publishers send messages to a Message Oriented Middleware, without knowledge + * of what, if any, Subscribers there may be. Similarly, Subscribers express + * interest in specific types of data, and process messages that contain this + * data, without knowledge of what Publishers there are. + * + * Message Oriented Middleware is software or hardware infrastructure that + * supports sending and receiving messages between distributed systems. OPC UA + * PubSub supports two different Message Oriented Middleware variants, namely + * the broker-less form and broker-based form. A broker-less form is where the + * Message Oriented Middleware is the network infrastructure that is able to + * route datagram-based messages. Subscribers and Publishers use datagram + * protocols like UDP. In a broker-based form, the core component of the Message + * Oriented Middleware is a message Broker. Subscribers and Publishers use + * standard messaging protocols like AMQP or MQTT to communicate with the + * Broker. + * + * This makes PubSub suitable for applications where location independence + * and/or scalability are required. + * + * The Publish/Subscribe (PubSub) extension for OPC UA enables fast and + * efficient 1:m communication. The PubSub extension is protocol agnostic and + * can be used with broker based protocols like MQTT and AMQP or brokerless + * implementations like UDP-Multicasting. + * + * The configuration model for PubSub uses the following components: */ + +typedef enum { + UA_PUBSUB_COMPONENT_CONNECTION, + UA_PUBSUB_COMPONENT_WRITERGROUP, + UA_PUBSUB_COMPONENT_DATASETWRITER, + UA_PUBSUB_COMPONENT_READERGROUP, + UA_PUBSUB_COMPONENT_DATASETREADER +} UA_PubSubComponentEnumType; + +/** + * The open62541 PubSub API uses the following scheme: + * + * 1. Create a configuration for the needed PubSub element. + * + * 2. Call the add[element] function and pass in the configuration. + * + * 3. The add[element] function returns the unique nodeId of the internally created element. + * + * Take a look on the PubSub Tutorials for more details about the API usage:: + * + * +-----------+ + * | UA_Server | + * +-----------+ + * | | + * | | + * | | + * | | +----------------------+ + * | +--> UA_PubSubConnection | UA_Server_addPubSubConnection + * | +----------------------+ + * | | | + * | | | +----------------+ + * | | +----> UA_WriterGroup | UA_PubSubConnection_addWriterGroup + * | | +----------------+ + * | | | + * | | | +------------------+ + * | | +----> UA_DataSetWriter | UA_WriterGroup_addDataSetWriter +-+ + * | | +------------------+ | + * | | | + * | | +----------------+ | r + * | +---------> UA_ReaderGroup | UA_PubSubConnection_addReaderGroup | e + * | +----------------+ | f + * | | | + * | | +------------------+ | + * | +----> UA_DataSetReader | UA_ReaderGroup_addDataSetReader | + * | +------------------+ | + * | | | + * | | +----------------------+ | + * | +----> UA_SubscribedDataSet | | + * | +----------------------+ | + * | | | + * | | +----------------------------+ | + * | +----> UA_TargetVariablesDataType | | + * | | +----------------------------+ | + * | | | + * | | +------------------------------------+ | + * | +----> UA_SubscribedDataSetMirrorDataType | | + * | +------------------------------------+ | + * | | + * | +---------------------------+ | + * +-------> UA_PubSubPublishedDataSet | UA_Server_addPublishedDataSet <-+ + * +---------------------------+ + * | + * | +-----------------+ + * +----> UA_DataSetField | UA_PublishedDataSet_addDataSetField + * +-----------------+ + * + * PubSub Information Model Representation + * --------------------------------------- + * .. _pubsub_informationmodel: + * + * The complete PubSub configuration is available inside the information model. + * The entry point is the node 'PublishSubscribe', located under the Server + * node. + * The standard defines for PubSub no new Service set. The configuration can + * optionally be done over methods inside the information model. + * The information model representation of the current PubSub configuration is + * generated automatically. This feature can be enabled/disabled by changing the + * UA_ENABLE_PUBSUB_INFORMATIONMODEL option. + * + * Connections + * ----------- + * The PubSub connections are the abstraction between the concrete transport protocol + * and the PubSub functionality. It is possible to create multiple connections with + * different transport protocols at runtime. + */ + +/* Valid PublisherId types from Part 14 */ +typedef enum { + UA_PUBLISHERIDTYPE_BYTE = 0, + UA_PUBLISHERIDTYPE_UINT16 = 1, + UA_PUBLISHERIDTYPE_UINT32 = 2, + UA_PUBLISHERIDTYPE_UINT64 = 3, + UA_PUBLISHERIDTYPE_STRING = 4 +} UA_PublisherIdType; + +/* Publisher Id + Valid types are defined in Part 14, 7.2.2.2.2 NetworkMessage Layout: + + Bit range 0-2: PublisherId Type + 000 The PublisherId is of DataType Byte This is the default value if ExtendedFlags1 is omitted + 001 The PublisherId is of DataType UInt16 + 010 The PublisherId is of DataType UInt32 + 011 The PublisherId is of DataType UInt64 + 100 The PublisherId is of DataType String +*/ +typedef union { + UA_Byte byte; + UA_UInt16 uint16; + UA_UInt32 uint32; + UA_UInt64 uint64; + UA_String string; +} UA_PublisherId; + +typedef struct { + UA_String name; + UA_Boolean enabled; + UA_PublisherIdType publisherIdType; + UA_PublisherId publisherId; + UA_String transportProfileUri; + UA_Variant address; + UA_KeyValueMap connectionProperties; + UA_Variant connectionTransportSettings; + + UA_EventLoop *eventLoop; /* Use an external EventLoop (use the EventLoop of + * the server if this is NULL). Propagates to the + * ReaderGroup/WriterGroup attached to the + * Connection. */ +} UA_PubSubConnectionConfig; + +#ifdef UA_ENABLE_PUBSUB_MONITORING + +typedef enum { + UA_PUBSUB_MONITORING_MESSAGE_RECEIVE_TIMEOUT + // extend as needed +} UA_PubSubMonitoringType; + +/* PubSub monitoring interface */ +typedef struct { + UA_StatusCode (*createMonitoring)(UA_Server *server, UA_NodeId Id, + UA_PubSubComponentEnumType eComponentType, + UA_PubSubMonitoringType eMonitoringType, + void *data, UA_ServerCallback callback); + UA_StatusCode (*startMonitoring)(UA_Server *server, UA_NodeId Id, + UA_PubSubComponentEnumType eComponentType, + UA_PubSubMonitoringType eMonitoringType, void *data); + UA_StatusCode (*stopMonitoring)(UA_Server *server, UA_NodeId Id, + UA_PubSubComponentEnumType eComponentType, + UA_PubSubMonitoringType eMonitoringType, void *data); + UA_StatusCode (*updateMonitoringInterval)(UA_Server *server, UA_NodeId Id, + UA_PubSubComponentEnumType eComponentType, + UA_PubSubMonitoringType eMonitoringType, + void *data); + UA_StatusCode (*deleteMonitoring)(UA_Server *server, UA_NodeId Id, + UA_PubSubComponentEnumType eComponentType, + UA_PubSubMonitoringType eMonitoringType, void *data); +} UA_PubSubMonitoringInterface; + +#endif /* UA_ENABLE_PUBSUB_MONITORING */ + +/* General PubSub configuration */ +struct UA_PubSubConfiguration { + /* Callback for PubSub component state changes: If provided this callback + * informs the application about PubSub component state changes. E.g. state + * change from operational to error in case of a DataSetReader + * MessageReceiveTimeout. The status code provides additional + * information. */ + void (*stateChangeCallback)(UA_Server *server, UA_NodeId *id, + UA_PubSubState state, UA_StatusCode status); + + UA_Boolean enableDeltaFrames; + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + UA_Boolean enableInformationModelMethods; +#endif + +#ifdef UA_ENABLE_PUBSUB_ENCRYPTION + /* PubSub security policies */ + size_t securityPoliciesSize; + UA_PubSubSecurityPolicy *securityPolicies; +#endif + +#ifdef UA_ENABLE_PUBSUB_MONITORING + UA_PubSubMonitoringInterface monitoringInterface; +#endif +}; + +/* Add a new PubSub connection to the given server and open it. + * @param server The server to add the connection to. + * @param connectionConfig The configuration for the newly added connection. + * @param connectionIdentifier If not NULL will be set to the identifier of the + * newly added connection. + * @return UA_STATUSCODE_GOOD if connection was successfully added, otherwise an + * error code. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_addPubSubConnection(UA_Server *server, + const UA_PubSubConnectionConfig *connectionConfig, + UA_NodeId *connectionIdentifier); + +/* Returns a deep copy of the config */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_getPubSubConnectionConfig(UA_Server *server, + const UA_NodeId connection, + UA_PubSubConnectionConfig *config); + +/* Remove Connection, identified by the NodeId. Deletion of Connection + * removes all contained WriterGroups and Writers. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_removePubSubConnection(UA_Server *server, const UA_NodeId connection); + +/** + * PublishedDataSets + * ----------------- + * The PublishedDataSets (PDS) are containers for the published information. The + * PDS contain the published variables and meta information. The metadata is + * commonly autogenerated or given as constant argument as part of the template + * functions. The template functions are standard defined and intended for + * configuration tools. You should normally create an empty PDS and call the + * functions to add new fields. */ + +/* The UA_PUBSUB_DATASET_PUBLISHEDITEMS has currently no additional members and + * thus no dedicated config structure. */ + +typedef enum { + UA_PUBSUB_DATASET_PUBLISHEDITEMS, + UA_PUBSUB_DATASET_PUBLISHEDEVENTS, + UA_PUBSUB_DATASET_PUBLISHEDITEMS_TEMPLATE, + UA_PUBSUB_DATASET_PUBLISHEDEVENTS_TEMPLATE, +} UA_PublishedDataSetType; + +typedef struct { + UA_DataSetMetaDataType metaData; + size_t variablesToAddSize; + UA_PublishedVariableDataType *variablesToAdd; +} UA_PublishedDataItemsTemplateConfig; + +typedef struct { + UA_NodeId eventNotfier; + UA_ContentFilter filter; +} UA_PublishedEventConfig; + +typedef struct { + UA_DataSetMetaDataType metaData; + UA_NodeId eventNotfier; + size_t selectedFieldsSize; + UA_SimpleAttributeOperand *selectedFields; + UA_ContentFilter filter; +} UA_PublishedEventTemplateConfig; + +/* Configuration structure for PublishedDataSet */ +typedef struct { + UA_String name; + UA_PublishedDataSetType publishedDataSetType; + union { + /* The UA_PUBSUB_DATASET_PUBLISHEDITEMS has currently no additional members + * and thus no dedicated config structure.*/ + UA_PublishedDataItemsTemplateConfig itemsTemplate; + UA_PublishedEventConfig event; + UA_PublishedEventTemplateConfig eventTemplate; + } config; +} UA_PublishedDataSetConfig; + +void UA_EXPORT +UA_PublishedDataSetConfig_clear(UA_PublishedDataSetConfig *pdsConfig); + +typedef struct { + UA_StatusCode addResult; + size_t fieldAddResultsSize; + UA_StatusCode *fieldAddResults; + UA_ConfigurationVersionDataType configurationVersion; +} UA_AddPublishedDataSetResult; + +UA_EXPORT UA_AddPublishedDataSetResult UA_THREADSAFE +UA_Server_addPublishedDataSet(UA_Server *server, + const UA_PublishedDataSetConfig *publishedDataSetConfig, + UA_NodeId *pdsIdentifier); + +/* Returns a deep copy of the config */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_getPublishedDataSetConfig(UA_Server *server, const UA_NodeId pds, + UA_PublishedDataSetConfig *config); + +/* Returns a deep copy of the DataSetMetaData for an specific PDS */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_getPublishedDataSetMetaData(UA_Server *server, const UA_NodeId pds, + UA_DataSetMetaDataType *metaData); + +/* Remove PublishedDataSet, identified by the NodeId. Deletion of PDS removes + * all contained and linked PDS Fields. Connected WriterGroups will be also + * removed. */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_removePublishedDataSet(UA_Server *server, const UA_NodeId pds); + +/** + * DataSetFields + * ------------- + * The description of published variables is named DataSetField. Each + * DataSetField contains the selection of one information model node. The + * DataSetField has additional parameters for the publishing, sampling and error + * handling process. */ + +typedef struct{ + UA_ConfigurationVersionDataType configurationVersion; + UA_String fieldNameAlias; + UA_Boolean promotedField; + UA_PublishedVariableDataType publishParameters; + + /* non std. field */ + struct { + UA_Boolean rtFieldSourceEnabled; + /* If the rtInformationModelNode is set, the nodeid in publishParameter must point + * to a node with external data source backend defined + * */ + UA_Boolean rtInformationModelNode; + //TODO -> decide if suppress C++ warnings and use 'UA_DataValue * * const staticValueSource;' + UA_DataValue ** staticValueSource; + } rtValueSource; + UA_UInt32 maxStringLength; + +} UA_DataSetVariableConfig; + +typedef enum { + UA_PUBSUB_DATASETFIELD_VARIABLE, + UA_PUBSUB_DATASETFIELD_EVENT +} UA_DataSetFieldType; + +typedef struct { + UA_DataSetFieldType dataSetFieldType; + union { + /* events need other config later */ + UA_DataSetVariableConfig variable; + } field; +} UA_DataSetFieldConfig; + +void UA_EXPORT +UA_DataSetFieldConfig_clear(UA_DataSetFieldConfig *dataSetFieldConfig); + +typedef struct { + UA_StatusCode result; + UA_ConfigurationVersionDataType configurationVersion; +} UA_DataSetFieldResult; + +UA_EXPORT UA_DataSetFieldResult UA_THREADSAFE +UA_Server_addDataSetField(UA_Server *server, + const UA_NodeId publishedDataSet, + const UA_DataSetFieldConfig *fieldConfig, + UA_NodeId *fieldIdentifier); + +/* Returns a deep copy of the config */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_getDataSetFieldConfig(UA_Server *server, const UA_NodeId dsf, + UA_DataSetFieldConfig *config); + +UA_EXPORT UA_DataSetFieldResult UA_THREADSAFE +UA_Server_removeDataSetField(UA_Server *server, const UA_NodeId dsf); + +/** + * Custom Callback Implementation + * ------------------------------ + * The user can use his own callback implementation for publishing + * and subscribing. The user must take care of the callback to call for + * every publishing or subscibing interval */ + +typedef struct { + /* User's callback implementation. The user configured base time and timer policy + * will be provided as an argument to this callback so that the user can + * implement his callback (thread) considering base time and timer policies */ + UA_StatusCode (*addCustomCallback)(UA_Server *server, UA_NodeId identifier, + UA_ServerCallback callback, + void *data, UA_Double interval_ms, + UA_DateTime *baseTime, UA_TimerPolicy timerPolicy, + UA_UInt64 *callbackId); + + UA_StatusCode (*changeCustomCallback)(UA_Server *server, UA_NodeId identifier, + UA_UInt64 callbackId, UA_Double interval_ms, + UA_DateTime *baseTime, UA_TimerPolicy timerPolicy); + + void (*removeCustomCallback)(UA_Server *server, UA_NodeId identifier, UA_UInt64 callbackId); + +} UA_PubSub_CallbackLifecycle; + +/** + * WriterGroup + * ----------- + * All WriterGroups are created within a PubSubConnection and automatically + * deleted if the connection is removed. The WriterGroup is primary used as + * container for :ref:`dsw` and network message settings. The WriterGroup can be + * imagined as producer of the network messages. The creation of network + * messages is controlled by parameters like the publish interval, which is e.g. + * contained in the WriterGroup. */ + +typedef enum { + UA_PUBSUB_ENCODING_UADP = 0, + UA_PUBSUB_ENCODING_JSON = 1, + UA_PUBSUB_ENCODING_BINARY = 2 +} UA_PubSubEncodingType; + +/** + * WriterGroup + * ----------- + * The message publishing can be configured for realtime requirements. The RT-levels + * go along with different requirements. The below listed levels can be configured: + * + * UA_PUBSUB_RT_NONE + * No realtime-specific configuration. + * + * UA_PUBSUB_RT_DIRECT_VALUE_ACCESS + * All PublishedDataSets need to point to a variable with a + * ``UA_VALUEBACKENDTYPE_EXTERNAL`` value backend. The value backend gets + * cached when the configuration is frozen. No lookup of the variable from + * the information is performed afterwards. This enables also big data + * structures to be updated atomically with a compare-and-switch operation on + * the ``UA_DataValue`` double-pointer in the backend. + * + * UA_PUBSUB_RT_FIXED_SIZE + * Validate that the message constains only fields with a known size. + * Then the message fields have fixed offsets that are known ahead of time. + * + * UA_PUBSUB_RT_DETERMINISTIC + * Both direct-access and fixed-size is being used. The server pre-allocates + * buffers when the configuration is frozen and uses only memcpy operations + * to update the PubSub network messages for sending. + * + * WARNING! For hard real time requirements the underlying system must be + * RT-capable. Also note that each PubSubConnection can have a dedicated + * EventLoop. That way normal client/server operations can run independently + * from PubSub. The double-pointer in the ``UA_VALUEBACKENDTYPE_EXTERNAL`` value + * backend allows avoid race-condition with non-blocking atomic operations. */ + +typedef enum { + UA_PUBSUB_RT_NONE = 0, + UA_PUBSUB_RT_DIRECT_VALUE_ACCESS = 1, + UA_PUBSUB_RT_FIXED_SIZE = 2, + UA_PUBSUB_RT_DETERMINISTIC = 3, +} UA_PubSubRTLevel; + +typedef struct { + UA_String name; + UA_Boolean enabled; + UA_UInt16 writerGroupId; + UA_Duration publishingInterval; + UA_Double keepAliveTime; + UA_Byte priority; + UA_ExtensionObject transportSettings; + UA_ExtensionObject messageSettings; + UA_KeyValueMap groupProperties; + UA_PubSubEncodingType encodingMimeType; + /* PubSub Manager Callback */ + UA_PubSub_CallbackLifecycle pubsubManagerCallback; + /* non std. config parameter. maximum count of embedded DataSetMessage in + * one NetworkMessage */ + UA_UInt16 maxEncapsulatedDataSetMessageCount; + /* non std. field */ + UA_PubSubRTLevel rtLevel; + + /* Message are encrypted if a SecurityPolicy is configured and the + * securityMode set accordingly. The symmetric key is a runtime information + * and has to be set via UA_Server_setWriterGroupEncryptionKey. */ + UA_MessageSecurityMode securityMode; /* via the UA_WriterGroupDataType */ +#ifdef UA_ENABLE_PUBSUB_ENCRYPTION + UA_PubSubSecurityPolicy *securityPolicy; + UA_String securityGroupId; +#endif +} UA_WriterGroupConfig; + +void UA_EXPORT +UA_WriterGroupConfig_clear(UA_WriterGroupConfig *writerGroupConfig); + +/* Add a new WriterGroup to an existing Connection */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_addWriterGroup(UA_Server *server, const UA_NodeId connection, + const UA_WriterGroupConfig *writerGroupConfig, + UA_NodeId *writerGroupIdentifier); + +/* Returns a deep copy of the config */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_getWriterGroupConfig(UA_Server *server, const UA_NodeId writerGroup, + UA_WriterGroupConfig *config); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_updateWriterGroupConfig(UA_Server *server, UA_NodeId writerGroupIdentifier, + const UA_WriterGroupConfig *config); + +/* Get state of WriterGroup */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_WriterGroup_getState(UA_Server *server, UA_NodeId writerGroupIdentifier, + UA_PubSubState *state); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_WriterGroup_publish(UA_Server *server, const UA_NodeId writerGroupIdentifier); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_WriterGroup_lastPublishTimestamp(UA_Server *server, const UA_NodeId writerGroupId, + UA_DateTime *timestamp); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_removeWriterGroup(UA_Server *server, const UA_NodeId writerGroup); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_freezeWriterGroupConfiguration(UA_Server *server, const UA_NodeId writerGroup); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_unfreezeWriterGroupConfiguration(UA_Server *server, const UA_NodeId writerGroup); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_setWriterGroupOperational(UA_Server *server, const UA_NodeId writerGroup); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_setWriterGroupDisabled(UA_Server *server, const UA_NodeId writerGroup); + +#ifdef UA_ENABLE_PUBSUB_ENCRYPTION +/* Set the group key for the message encryption */ +UA_StatusCode UA_EXPORT UA_THREADSAFE +UA_Server_setWriterGroupEncryptionKeys(UA_Server *server, const UA_NodeId writerGroup, + UA_UInt32 securityTokenId, + const UA_ByteString signingKey, + const UA_ByteString encryptingKey, + const UA_ByteString keyNonce); +#endif + +/** + * .. _dsw: + * + * DataSetWriter + * ------------- + * The DataSetWriters are the glue between the WriterGroups and the + * PublishedDataSets. The DataSetWriter contain configuration parameters and + * flags which influence the creation of DataSet messages. These messages are + * encapsulated inside the network message. The DataSetWriter must be linked + * with an existing PublishedDataSet and be contained within a WriterGroup. */ + +typedef struct { + UA_String name; + UA_UInt16 dataSetWriterId; + UA_DataSetFieldContentMask dataSetFieldContentMask; + UA_UInt32 keyFrameCount; + UA_ExtensionObject messageSettings; + UA_ExtensionObject transportSettings; + UA_String dataSetName; + UA_KeyValueMap dataSetWriterProperties; +} UA_DataSetWriterConfig; + +void UA_EXPORT +UA_DataSetWriterConfig_clear(UA_DataSetWriterConfig *pdsConfig); + +/* Add a new DataSetWriter to an existing WriterGroup. The DataSetWriter must be + * coupled with a PublishedDataSet on creation. + * + * Part 14, 7.1.5.2.1 defines: The link between the PublishedDataSet and + * DataSetWriter shall be created when an instance of the DataSetWriterType is + * created. */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_addDataSetWriter(UA_Server *server, + const UA_NodeId writerGroup, const UA_NodeId dataSet, + const UA_DataSetWriterConfig *dataSetWriterConfig, + UA_NodeId *writerIdentifier); + +/* Returns a deep copy of the config */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_getDataSetWriterConfig(UA_Server *server, const UA_NodeId dsw, + UA_DataSetWriterConfig *config); + +/* Get state of DataSetWriter */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_DataSetWriter_getState(UA_Server *server, UA_NodeId dataSetWriterIdentifier, + UA_PubSubState *state); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_removeDataSetWriter(UA_Server *server, const UA_NodeId dsw); + +/** + * SubscribedDataSet + * ----------------- + * SubscribedDataSet describes the processing of the received DataSet. + * SubscribedDataSet defines which field in the DataSet is mapped to which + * Variable in the OPC UA Application. SubscribedDataSet has two sub-types + * called the TargetVariablesType and SubscribedDataSetMirrorType. + * SubscribedDataSetMirrorType is currently not supported. SubscribedDataSet is + * set to TargetVariablesType and then the list of target Variables are created + * in the Subscriber AddressSpace. TargetVariables are a list of variables that + * are to be added in the Subscriber AddressSpace. It defines a list of Variable + * mappings between received DataSet fields and added Variables in the + * Subscriber AddressSpace. */ + +/* SubscribedDataSetDataType Definition */ +typedef enum { + UA_PUBSUB_SDS_TARGET, + UA_PUBSUB_SDS_MIRROR +} UA_SubscribedDataSetEnumType; + +typedef struct { + /* Standard-defined FieldTargetDataType */ + UA_FieldTargetDataType targetVariable; + + /* If realtime-handling is required, set this pointer non-NULL and it will be used + * to memcpy the value instead of using the Write service. + * If the beforeWrite method pointer is set, it will be called before a memcpy update + * to the value. But param externalDataValue already contains the new value. + * If the afterWrite method pointer is set, it will be called after a memcpy update + * to the value. */ + UA_DataValue **externalDataValue; + void *targetVariableContext; /* user-defined pointer */ + void (*beforeWrite)(UA_Server *server, + const UA_NodeId *readerIdentifier, + const UA_NodeId *readerGroupIdentifier, + const UA_NodeId *targetVariableIdentifier, + void *targetVariableContext, + UA_DataValue **externalDataValue); + void (*afterWrite)(UA_Server *server, + const UA_NodeId *readerIdentifier, + const UA_NodeId *readerGroupIdentifier, + const UA_NodeId *targetVariableIdentifier, + void *targetVariableContext, + UA_DataValue **externalDataValue); +} UA_FieldTargetVariable; + +typedef struct { + size_t targetVariablesSize; + UA_FieldTargetVariable *targetVariables; +} UA_TargetVariables; + +/* Return Status Code after creating TargetVariables in Subscriber AddressSpace */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_DataSetReader_createTargetVariables(UA_Server *server, + UA_NodeId dataSetReaderIdentifier, + size_t targetVariablesSize, + const UA_FieldTargetVariable *targetVariables); + +/* To Do:Implementation of SubscribedDataSetMirrorType + * UA_StatusCode + * A_PubSubDataSetReader_createDataSetMirror(UA_Server *server, UA_NodeId dataSetReaderIdentifier, + * UA_SubscribedDataSetMirrorDataType* mirror) */ + +/** + * DataSetReader + * ------------- + * DataSetReader can receive NetworkMessages with the DataSetMessage + * of interest sent by the Publisher. DataSetReaders represent + * the configuration necessary to receive and process DataSetMessages + * on the Subscriber side. DataSetReader must be linked with a + * SubscribedDataSet and be contained within a ReaderGroup. */ + +typedef enum { + UA_PUBSUB_RT_UNKNOWN = 0, + UA_PUBSUB_RT_VARIANT = 1, + UA_PUBSUB_RT_DATA_VALUE = 2, + UA_PUBSUB_RT_RAW = 4, +} UA_PubSubRtEncoding; + +/* Parameters for PubSub DataSetReader Configuration */ +typedef struct { + UA_String name; + UA_Variant publisherId; + UA_UInt16 writerGroupId; + UA_UInt16 dataSetWriterId; + UA_DataSetMetaDataType dataSetMetaData; + UA_DataSetFieldContentMask dataSetFieldContentMask; + UA_Double messageReceiveTimeout; + UA_ExtensionObject messageSettings; + UA_ExtensionObject transportSettings; + UA_SubscribedDataSetEnumType subscribedDataSetType; + /* TODO UA_SubscribedDataSetMirrorDataType subscribedDataSetMirror */ + union { + UA_TargetVariables subscribedDataSetTarget; + // UA_SubscribedDataSetMirrorDataType subscribedDataSetMirror; + } subscribedDataSet; + /* non std. fields */ + UA_String linkedStandaloneSubscribedDataSetName; + UA_PubSubRtEncoding expectedEncoding; +} UA_DataSetReaderConfig; + +/* Copy the configuration of DataSetReader */ +UA_EXPORT UA_StatusCode +UA_DataSetReaderConfig_copy(const UA_DataSetReaderConfig *src, + UA_DataSetReaderConfig *dst); + +/* Clear the configuration of a DataSetReader */ +UA_EXPORT void +UA_DataSetReaderConfig_clear(UA_DataSetReaderConfig *cfg); + +/* Update configuration to the DataSetReader */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_DataSetReader_updateConfig(UA_Server *server, UA_NodeId dataSetReaderIdentifier, + UA_NodeId readerGroupIdentifier, + const UA_DataSetReaderConfig *config); + +/* Get the configuration (copy) of the DataSetReader */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_DataSetReader_getConfig(UA_Server *server, UA_NodeId dataSetReaderIdentifier, + UA_DataSetReaderConfig *config); + +/* Get state of DataSetReader */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_DataSetReader_getState(UA_Server *server, UA_NodeId dataSetReaderIdentifier, + UA_PubSubState *state); + +typedef struct { + UA_String name; + UA_SubscribedDataSetEnumType subscribedDataSetType; + union { + /* datasetmirror is currently not implemented */ + UA_TargetVariablesDataType target; + } subscribedDataSet; + UA_DataSetMetaDataType dataSetMetaData; + UA_Boolean isConnected; +} UA_StandaloneSubscribedDataSetConfig; + +void +UA_StandaloneSubscribedDataSetConfig_clear(UA_StandaloneSubscribedDataSetConfig *sdsConfig); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_addStandaloneSubscribedDataSet(UA_Server *server, + const UA_StandaloneSubscribedDataSetConfig *subscribedDataSetConfig, + UA_NodeId *sdsIdentifier); + +/* Remove StandaloneSubscribedDataSet, identified by the NodeId. */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_removeStandaloneSubscribedDataSet(UA_Server *server, const UA_NodeId sds); + +/** + * ReaderGroup + * ----------- + * + * ReaderGroup is used to group a list of DataSetReaders. All ReaderGroups are + * created within a PubSubConnection and automatically deleted if the connection + * is removed. All network message related filters are only available in the + * DataSetReader. + * + * The RT-levels go along with different requirements. The below listed levels + * can be configured for a ReaderGroup. + * + * - UA_PUBSUB_RT_NONE: RT applied to this level + * - PUBSUB_CONFIG_FASTPATH_FIXED_OFFSETS: Extends PubSub RT functionality and + * implements fast path message decoding in the Subscriber. Uses a buffered + * network message and only decodes the necessary offsets stored in an offset + * buffer. */ + +/* ReaderGroup configuration */ +typedef struct { + UA_String name; + + /* non std. field */ + UA_PubSubRTLevel rtLevel; + UA_KeyValueMap groupProperties; + UA_PubSubEncodingType encodingMimeType; + UA_ExtensionObject transportSettings; + + /* Messages are decrypted if a SecurityPolicy is configured and the + * securityMode set accordingly. The symmetric key is a runtime information + * and has to be set via UA_Server_setReaderGroupEncryptionKey. */ + UA_MessageSecurityMode securityMode; +#ifdef UA_ENABLE_PUBSUB_ENCRYPTION + UA_PubSubSecurityPolicy *securityPolicy; + UA_String securityGroupId; +#endif +} UA_ReaderGroupConfig; + +void UA_EXPORT +UA_ReaderGroupConfig_clear(UA_ReaderGroupConfig *readerGroupConfig); + +/* Add DataSetReader to the ReaderGroup */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_addDataSetReader(UA_Server *server, UA_NodeId readerGroupIdentifier, + const UA_DataSetReaderConfig *dataSetReaderConfig, + UA_NodeId *readerIdentifier); + +/* Remove DataSetReader from ReaderGroup */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_removeDataSetReader(UA_Server *server, UA_NodeId readerIdentifier); + +/* To Do: Update Configuration of ReaderGroup + * UA_StatusCode UA_EXPORT + * UA_Server_ReaderGroup_updateConfig(UA_Server *server, UA_NodeId readerGroupIdentifier, + * const UA_ReaderGroupConfig *config); + */ + +/* Get configuraiton of ReaderGroup */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_ReaderGroup_getConfig(UA_Server *server, UA_NodeId readerGroupIdentifier, + UA_ReaderGroupConfig *config); + +/* Get state of ReaderGroup */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_ReaderGroup_getState(UA_Server *server, UA_NodeId readerGroupIdentifier, + UA_PubSubState *state); + +/* Add ReaderGroup to the created connection */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_addReaderGroup(UA_Server *server, UA_NodeId connectionIdentifier, + const UA_ReaderGroupConfig *readerGroupConfig, + UA_NodeId *readerGroupIdentifier); + +/* Remove ReaderGroup from connection */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_removeReaderGroup(UA_Server *server, UA_NodeId groupIdentifier); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_freezeReaderGroupConfiguration(UA_Server *server, const UA_NodeId readerGroupId); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_unfreezeReaderGroupConfiguration(UA_Server *server, const UA_NodeId readerGroupId); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_setReaderGroupOperational(UA_Server *server, const UA_NodeId readerGroupId); + +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_setReaderGroupDisabled(UA_Server *server, const UA_NodeId readerGroupId); + +#ifdef UA_ENABLE_PUBSUB_ENCRYPTION +/* Set the group key for the message encryption */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_setReaderGroupEncryptionKeys(UA_Server *server, UA_NodeId readerGroup, + UA_UInt32 securityTokenId, + UA_ByteString signingKey, + UA_ByteString encryptingKey, + UA_ByteString keyNonce); +#endif + +#ifdef UA_ENABLE_PUBSUB_SKS + +/** + * SecurityGroup + * ------------- + * + * A SecurityGroup is an abstraction that represents the message security settings and + * security keys for a subset of NetworkMessages exchanged between Publishers and + * Subscribers. The SecurityGroup objects are created on a Security Key Service (SKS). The + * SKS manages the access to the keys based on the role permission for a user assigned to + * a SecurityGroup Object. A SecurityGroup is identified with a unique identifier called + * the SecurityGroupId. It is unique within the SKS. + * + * .. note:: The access to the SecurityGroup and therefore the securitykeys managed by SKS + * requires management of Roles and Permissions in the SKS. The Role Permission + * model is not supported at the time of writing. However, the access control plugin can + * be used to create and manage role permission on SecurityGroup object. + */ + +typedef struct { + UA_String securityGroupName; + UA_Duration keyLifeTime; + UA_String securityPolicyUri; + UA_UInt32 maxFutureKeyCount; + UA_UInt32 maxPastKeyCount; +} UA_SecurityGroupConfig; + +/** + * @brief Creates a SecurityGroup object and add it to the list in PubSub Manager. If the + * information model is enabled then the SecurityGroup object Node is also created in the + * server. A keyStorage with initial list of keys is created with a SecurityGroup. A + * callback is added to new SecurityGroup which updates the keys periodically at each + * KeyLifeTime expire. + * + * @param server The server instance + * @param securityGroupFolderNodeId The parent node of the SecurityGroup. It must be of + * SecurityGroupFolderType + * @param securityGroupConfig The security settings of a SecurityGroup + * @param securityGroupNodeId The output nodeId of the new SecurityGroup + * @return UA_StatusCode The return status code + */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_addSecurityGroup(UA_Server *server, UA_NodeId securityGroupFolderNodeId, + const UA_SecurityGroupConfig *securityGroupConfig, + UA_NodeId *securityGroupNodeId); + +/** + * @brief Removes the SecurityGroup from PubSub Manager. It removes the KeyStorage + * associated with the SecurityGroup from the server. + * + * @param server The server instance + * @param securityGroup The nodeId of the securityGroup to be removed + * @return UA_StatusCode The returned status code. + */ +UA_EXPORT UA_StatusCode UA_THREADSAFE +UA_Server_removeSecurityGroup(UA_Server *server, const UA_NodeId securityGroup); + +/** + * @brief This is a repeated callback which is triggered on each iteration of SKS Pull request. + * The server uses this callback to notify user about the status of current Pull request iteration. + * The period is calculated based on the KeylifeTime of specified in the SecurityGroup object node on + * the SKS server. + * + * @param server The server instance managing the publisher/subscriber. + * @param sksPullRequestStatus The current status of sks pull request. + * @param context The pointer to user defined data passed to this callback. + */ +typedef void +(*UA_Server_sksPullRequestCallback)(UA_Server *server, UA_StatusCode sksPullRequestStatus, void* context); + +/** + * @brief Sets the SKS client config used to call the GetSecurityKeys Method on SKS and get the + * initial set of keys for a SecurityGroupId and adds timedCallback for the next GetSecurityKeys + * method Call. This uses async Client API for SKS Pull request. The SKS Client instance is created and destroyed at + * runtime on each iteration of SKS Pull request by the server. The key Rollover mechanism will check if the new + * keys are needed then it will call the getSecurityKeys Method on SKS Server. At the end of SKS Pull request + * iteration, the sks client will be deleted by a delayed callback (in next server iteration). + * + * @note It is be called before setting Reader/Writer Group into Operational because this also allocates + * a channel context for the pubsub security policy. + * + * @note the stateCallback of sksClientConfig will be overwritten by an internal callback. + * + * @param server the server instance + * @param clientConfig holds the required configuration to make encrypted connection with + * SKS Server. The input client config takes the lifecycle as long as SKS request are made. + * It is deleted with its plugins when the server is deleted or the last Reader/Writer + * Group of the securityGroupId is deleted. The input config is copied to an internal + * config object and the content of input config object will be reset to zero. + * @param endpointUrl holds the endpointUrl of the SKS server + * @param securityGroupId the SecurityGroupId of the securityGroup on SKS and + * reader/writergroups + * @param callback the user defined callback to notify the user about the status of SKS + * Pull request. + * @param context passed to the callback function + * @return UA_StatusCode the retuned status + */ +UA_StatusCode UA_EXPORT +UA_Server_setSksClient(UA_Server *server, UA_String securityGroupId, + UA_ClientConfig *clientConfig, const char *endpointUrl, + UA_Server_sksPullRequestCallback callback, void *context); + +#endif /* UA_ENABLE_PUBSUB_SKS */ + +#endif /* UA_ENABLE_PUBSUB */ + +_UA_END_DECLS + +#endif /* UA_SERVER_PUBSUB_H */ diff --git a/product/src/fes/include/open62541/statuscodes.h b/product/src/fes/include/open62541/statuscodes.h new file mode 100644 index 00000000..c82217c0 --- /dev/null +++ b/product/src/fes/include/open62541/statuscodes.h @@ -0,0 +1,775 @@ +/** .. _statuscodes: + * + * StatusCodes + * =========== + * + * StatusCodes are extensively used in the OPC UA protocol and in the open62541 + * API. They are represented by the :ref:`statuscode` data type. The following + * definitions are autogenerated from the ``Opc.Ua.StatusCodes.csv`` file provided + * with the OPC UA standard. */ + +/* These StatusCodes are manually generated. */ +#define UA_STATUSCODE_INFOTYPE_DATAVALUE 0x00000400 +#define UA_STATUSCODE_INFOBITS_OVERFLOW 0x00000080 + +/* The operation succeeded. */ +#define UA_STATUSCODE_GOOD 0x00000000 + +/* The operation was uncertain. */ +#define UA_STATUSCODE_UNCERTAIN 0x40000000 + +/* The operation failed. */ +#define UA_STATUSCODE_BAD 0x80000000 + +/* An unexpected error occurred. */ +#define UA_STATUSCODE_BADUNEXPECTEDERROR 0x80010000 + +/* An internal error occurred as a result of a programming or configuration error. */ +#define UA_STATUSCODE_BADINTERNALERROR 0x80020000 + +/* Not enough memory to complete the operation. */ +#define UA_STATUSCODE_BADOUTOFMEMORY 0x80030000 + +/* An operating system resource is not available. */ +#define UA_STATUSCODE_BADRESOURCEUNAVAILABLE 0x80040000 + +/* A low level communication error occurred. */ +#define UA_STATUSCODE_BADCOMMUNICATIONERROR 0x80050000 + +/* Encoding halted because of invalid data in the objects being serialized. */ +#define UA_STATUSCODE_BADENCODINGERROR 0x80060000 + +/* Decoding halted because of invalid data in the stream. */ +#define UA_STATUSCODE_BADDECODINGERROR 0x80070000 + +/* The message encoding/decoding limits imposed by the stack have been exceeded. */ +#define UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED 0x80080000 + +/* The request message size exceeds limits set by the server. */ +#define UA_STATUSCODE_BADREQUESTTOOLARGE 0x80B80000 + +/* The response message size exceeds limits set by the client. */ +#define UA_STATUSCODE_BADRESPONSETOOLARGE 0x80B90000 + +/* An unrecognized response was received from the server. */ +#define UA_STATUSCODE_BADUNKNOWNRESPONSE 0x80090000 + +/* The operation timed out. */ +#define UA_STATUSCODE_BADTIMEOUT 0x800A0000 + +/* The server does not support the requested service. */ +#define UA_STATUSCODE_BADSERVICEUNSUPPORTED 0x800B0000 + +/* The operation was cancelled because the application is shutting down. */ +#define UA_STATUSCODE_BADSHUTDOWN 0x800C0000 + +/* The operation could not complete because the client is not connected to the server. */ +#define UA_STATUSCODE_BADSERVERNOTCONNECTED 0x800D0000 + +/* The server has stopped and cannot process any requests. */ +#define UA_STATUSCODE_BADSERVERHALTED 0x800E0000 + +/* There was nothing to do because the client passed a list of operations with no elements. */ +#define UA_STATUSCODE_BADNOTHINGTODO 0x800F0000 + +/* The request could not be processed because it specified too many operations. */ +#define UA_STATUSCODE_BADTOOMANYOPERATIONS 0x80100000 + +/* The request could not be processed because there are too many monitored items in the subscription. */ +#define UA_STATUSCODE_BADTOOMANYMONITOREDITEMS 0x80DB0000 + +/* The extension object cannot be (de)serialized because the data type id is not recognized. */ +#define UA_STATUSCODE_BADDATATYPEIDUNKNOWN 0x80110000 + +/* The certificate provided as a parameter is not valid. */ +#define UA_STATUSCODE_BADCERTIFICATEINVALID 0x80120000 + +/* An error occurred verifying security. */ +#define UA_STATUSCODE_BADSECURITYCHECKSFAILED 0x80130000 + +/* The certificate does not meet the requirements of the security policy. */ +#define UA_STATUSCODE_BADCERTIFICATEPOLICYCHECKFAILED 0x81140000 + +/* The certificate has expired or is not yet valid. */ +#define UA_STATUSCODE_BADCERTIFICATETIMEINVALID 0x80140000 + +/* An issuer certificate has expired or is not yet valid. */ +#define UA_STATUSCODE_BADCERTIFICATEISSUERTIMEINVALID 0x80150000 + +/* The HostName used to connect to a server does not match a HostName in the certificate. */ +#define UA_STATUSCODE_BADCERTIFICATEHOSTNAMEINVALID 0x80160000 + +/* The URI specified in the ApplicationDescription does not match the URI in the certificate. */ +#define UA_STATUSCODE_BADCERTIFICATEURIINVALID 0x80170000 + +/* The certificate may not be used for the requested operation. */ +#define UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED 0x80180000 + +/* The issuer certificate may not be used for the requested operation. */ +#define UA_STATUSCODE_BADCERTIFICATEISSUERUSENOTALLOWED 0x80190000 + +/* The certificate is not trusted. */ +#define UA_STATUSCODE_BADCERTIFICATEUNTRUSTED 0x801A0000 + +/* It was not possible to determine if the certificate has been revoked. */ +#define UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN 0x801B0000 + +/* It was not possible to determine if the issuer certificate has been revoked. */ +#define UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN 0x801C0000 + +/* The certificate has been revoked. */ +#define UA_STATUSCODE_BADCERTIFICATEREVOKED 0x801D0000 + +/* The issuer certificate has been revoked. */ +#define UA_STATUSCODE_BADCERTIFICATEISSUERREVOKED 0x801E0000 + +/* The certificate chain is incomplete. */ +#define UA_STATUSCODE_BADCERTIFICATECHAININCOMPLETE 0x810D0000 + +/* User does not have permission to perform the requested operation. */ +#define UA_STATUSCODE_BADUSERACCESSDENIED 0x801F0000 + +/* The user identity token is not valid. */ +#define UA_STATUSCODE_BADIDENTITYTOKENINVALID 0x80200000 + +/* The user identity token is valid but the server has rejected it. */ +#define UA_STATUSCODE_BADIDENTITYTOKENREJECTED 0x80210000 + +/* The specified secure channel is no longer valid. */ +#define UA_STATUSCODE_BADSECURECHANNELIDINVALID 0x80220000 + +/* The timestamp is outside the range allowed by the server. */ +#define UA_STATUSCODE_BADINVALIDTIMESTAMP 0x80230000 + +/* The nonce does appear to be not a random value or it is not the correct length. */ +#define UA_STATUSCODE_BADNONCEINVALID 0x80240000 + +/* The session id is not valid. */ +#define UA_STATUSCODE_BADSESSIONIDINVALID 0x80250000 + +/* The session was closed by the client. */ +#define UA_STATUSCODE_BADSESSIONCLOSED 0x80260000 + +/* The session cannot be used because ActivateSession has not been called. */ +#define UA_STATUSCODE_BADSESSIONNOTACTIVATED 0x80270000 + +/* The subscription id is not valid. */ +#define UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID 0x80280000 + +/* The header for the request is missing or invalid. */ +#define UA_STATUSCODE_BADREQUESTHEADERINVALID 0x802A0000 + +/* The timestamps to return parameter is invalid. */ +#define UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID 0x802B0000 + +/* The request was cancelled by the client. */ +#define UA_STATUSCODE_BADREQUESTCANCELLEDBYCLIENT 0x802C0000 + +/* Too many arguments were provided. */ +#define UA_STATUSCODE_BADTOOMANYARGUMENTS 0x80E50000 + +/* The server requires a license to operate in general or to perform a service or operatio */ +#define UA_STATUSCODE_BADLICENSEEXPIRED 0x810E0000 + +/* The server has limits on number of allowed operations / object */ +#define UA_STATUSCODE_BADLICENSELIMITSEXCEEDED 0x810F0000 + +/* The server does not have a license which is required to operate in general or to perform a service or operation. */ +#define UA_STATUSCODE_BADLICENSENOTAVAILABLE 0x81100000 + +/* The subscription was transferred to another session. */ +#define UA_STATUSCODE_GOODSUBSCRIPTIONTRANSFERRED 0x002D0000 + +/* The processing will complete asynchronously. */ +#define UA_STATUSCODE_GOODCOMPLETESASYNCHRONOUSLY 0x002E0000 + +/* Sampling has slowed down due to resource limitations. */ +#define UA_STATUSCODE_GOODOVERLOAD 0x002F0000 + +/* The value written was accepted but was clamped. */ +#define UA_STATUSCODE_GOODCLAMPED 0x00300000 + +/* Communication with the data source is define */ +#define UA_STATUSCODE_BADNOCOMMUNICATION 0x80310000 + +/* Waiting for the server to obtain values from the underlying data source. */ +#define UA_STATUSCODE_BADWAITINGFORINITIALDATA 0x80320000 + +/* The syntax of the node id is not valid. */ +#define UA_STATUSCODE_BADNODEIDINVALID 0x80330000 + +/* The node id refers to a node that does not exist in the server address space. */ +#define UA_STATUSCODE_BADNODEIDUNKNOWN 0x80340000 + +/* The attribute is not supported for the specified Node. */ +#define UA_STATUSCODE_BADATTRIBUTEIDINVALID 0x80350000 + +/* The syntax of the index range parameter is invalid. */ +#define UA_STATUSCODE_BADINDEXRANGEINVALID 0x80360000 + +/* No data exists within the range of indexes specified. */ +#define UA_STATUSCODE_BADINDEXRANGENODATA 0x80370000 + +/* The data encoding is invalid. */ +#define UA_STATUSCODE_BADDATAENCODINGINVALID 0x80380000 + +/* The server does not support the requested data encoding for the node. */ +#define UA_STATUSCODE_BADDATAENCODINGUNSUPPORTED 0x80390000 + +/* The access level does not allow reading or subscribing to the Node. */ +#define UA_STATUSCODE_BADNOTREADABLE 0x803A0000 + +/* The access level does not allow writing to the Node. */ +#define UA_STATUSCODE_BADNOTWRITABLE 0x803B0000 + +/* The value was out of range. */ +#define UA_STATUSCODE_BADOUTOFRANGE 0x803C0000 + +/* The requested operation is not supported. */ +#define UA_STATUSCODE_BADNOTSUPPORTED 0x803D0000 + +/* A requested item was not found or a search operation ended without success. */ +#define UA_STATUSCODE_BADNOTFOUND 0x803E0000 + +/* The object cannot be used because it has been deleted. */ +#define UA_STATUSCODE_BADOBJECTDELETED 0x803F0000 + +/* Requested operation is not implemented. */ +#define UA_STATUSCODE_BADNOTIMPLEMENTED 0x80400000 + +/* The monitoring mode is invalid. */ +#define UA_STATUSCODE_BADMONITORINGMODEINVALID 0x80410000 + +/* The monitoring item id does not refer to a valid monitored item. */ +#define UA_STATUSCODE_BADMONITOREDITEMIDINVALID 0x80420000 + +/* The monitored item filter parameter is not valid. */ +#define UA_STATUSCODE_BADMONITOREDITEMFILTERINVALID 0x80430000 + +/* The server does not support the requested monitored item filter. */ +#define UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED 0x80440000 + +/* A monitoring filter cannot be used in combination with the attribute specified. */ +#define UA_STATUSCODE_BADFILTERNOTALLOWED 0x80450000 + +/* A mandatory structured parameter was missing or null. */ +#define UA_STATUSCODE_BADSTRUCTUREMISSING 0x80460000 + +/* The event filter is not valid. */ +#define UA_STATUSCODE_BADEVENTFILTERINVALID 0x80470000 + +/* The content filter is not valid. */ +#define UA_STATUSCODE_BADCONTENTFILTERINVALID 0x80480000 + +/* An unrecognized operator was provided in a filter. */ +#define UA_STATUSCODE_BADFILTEROPERATORINVALID 0x80C10000 + +/* A valid operator was provide */ +#define UA_STATUSCODE_BADFILTEROPERATORUNSUPPORTED 0x80C20000 + +/* The number of operands provided for the filter operator was less then expected for the operand provided. */ +#define UA_STATUSCODE_BADFILTEROPERANDCOUNTMISMATCH 0x80C30000 + +/* The operand used in a content filter is not valid. */ +#define UA_STATUSCODE_BADFILTEROPERANDINVALID 0x80490000 + +/* The referenced element is not a valid element in the content filter. */ +#define UA_STATUSCODE_BADFILTERELEMENTINVALID 0x80C40000 + +/* The referenced literal is not a valid value. */ +#define UA_STATUSCODE_BADFILTERLITERALINVALID 0x80C50000 + +/* The continuation point provide is longer valid. */ +#define UA_STATUSCODE_BADCONTINUATIONPOINTINVALID 0x804A0000 + +/* The operation could not be processed because all continuation points have been allocated. */ +#define UA_STATUSCODE_BADNOCONTINUATIONPOINTS 0x804B0000 + +/* The reference type id does not refer to a valid reference type node. */ +#define UA_STATUSCODE_BADREFERENCETYPEIDINVALID 0x804C0000 + +/* The browse direction is not valid. */ +#define UA_STATUSCODE_BADBROWSEDIRECTIONINVALID 0x804D0000 + +/* The node is not part of the view. */ +#define UA_STATUSCODE_BADNODENOTINVIEW 0x804E0000 + +/* The number was not accepted because of a numeric overflow. */ +#define UA_STATUSCODE_BADNUMERICOVERFLOW 0x81120000 + +/* The ServerUri is not a valid URI. */ +#define UA_STATUSCODE_BADSERVERURIINVALID 0x804F0000 + +/* No ServerName was specified. */ +#define UA_STATUSCODE_BADSERVERNAMEMISSING 0x80500000 + +/* No DiscoveryUrl was specified. */ +#define UA_STATUSCODE_BADDISCOVERYURLMISSING 0x80510000 + +/* The semaphore file specified by the client is not valid. */ +#define UA_STATUSCODE_BADSEMPAHOREFILEMISSING 0x80520000 + +/* The security token request type is not valid. */ +#define UA_STATUSCODE_BADREQUESTTYPEINVALID 0x80530000 + +/* The security mode does not meet the requirements set by the server. */ +#define UA_STATUSCODE_BADSECURITYMODEREJECTED 0x80540000 + +/* The security policy does not meet the requirements set by the server. */ +#define UA_STATUSCODE_BADSECURITYPOLICYREJECTED 0x80550000 + +/* The server has reached its maximum number of sessions. */ +#define UA_STATUSCODE_BADTOOMANYSESSIONS 0x80560000 + +/* The user token signature is missing or invalid. */ +#define UA_STATUSCODE_BADUSERSIGNATUREINVALID 0x80570000 + +/* The signature generated with the client certificate is missing or invalid. */ +#define UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID 0x80580000 + +/* The client did not provide at least one software certificate that is valid and meets the profile requirements for the server. */ +#define UA_STATUSCODE_BADNOVALIDCERTIFICATES 0x80590000 + +/* The server does not support changing the user identity assigned to the session. */ +#define UA_STATUSCODE_BADIDENTITYCHANGENOTSUPPORTED 0x80C60000 + +/* The request was cancelled by the client with the Cancel service. */ +#define UA_STATUSCODE_BADREQUESTCANCELLEDBYREQUEST 0x805A0000 + +/* The parent node id does not to refer to a valid node. */ +#define UA_STATUSCODE_BADPARENTNODEIDINVALID 0x805B0000 + +/* The reference could not be created because it violates constraints imposed by the data model. */ +#define UA_STATUSCODE_BADREFERENCENOTALLOWED 0x805C0000 + +/* The requested node id was reject because it was either invalid or server does not allow node ids to be specified by the client. */ +#define UA_STATUSCODE_BADNODEIDREJECTED 0x805D0000 + +/* The requested node id is already used by another node. */ +#define UA_STATUSCODE_BADNODEIDEXISTS 0x805E0000 + +/* The node class is not valid. */ +#define UA_STATUSCODE_BADNODECLASSINVALID 0x805F0000 + +/* The browse name is invalid. */ +#define UA_STATUSCODE_BADBROWSENAMEINVALID 0x80600000 + +/* The browse name is not unique among nodes that share the same relationship with the parent. */ +#define UA_STATUSCODE_BADBROWSENAMEDUPLICATED 0x80610000 + +/* The node attributes are not valid for the node class. */ +#define UA_STATUSCODE_BADNODEATTRIBUTESINVALID 0x80620000 + +/* The type definition node id does not reference an appropriate type node. */ +#define UA_STATUSCODE_BADTYPEDEFINITIONINVALID 0x80630000 + +/* The source node id does not reference a valid node. */ +#define UA_STATUSCODE_BADSOURCENODEIDINVALID 0x80640000 + +/* The target node id does not reference a valid node. */ +#define UA_STATUSCODE_BADTARGETNODEIDINVALID 0x80650000 + +/* The reference type between the nodes is already defined. */ +#define UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED 0x80660000 + +/* The server does not allow this type of self reference on this node. */ +#define UA_STATUSCODE_BADINVALIDSELFREFERENCE 0x80670000 + +/* The reference type is not valid for a reference to a remote server. */ +#define UA_STATUSCODE_BADREFERENCELOCALONLY 0x80680000 + +/* The server will not allow the node to be deleted. */ +#define UA_STATUSCODE_BADNODELETERIGHTS 0x80690000 + +/* The server was not able to delete all target references. */ +#define UA_STATUSCODE_UNCERTAINREFERENCENOTDELETED 0x40BC0000 + +/* The server index is not valid. */ +#define UA_STATUSCODE_BADSERVERINDEXINVALID 0x806A0000 + +/* The view id does not refer to a valid view node. */ +#define UA_STATUSCODE_BADVIEWIDUNKNOWN 0x806B0000 + +/* The view timestamp is not available or not supported. */ +#define UA_STATUSCODE_BADVIEWTIMESTAMPINVALID 0x80C90000 + +/* The view parameters are not consistent with each other. */ +#define UA_STATUSCODE_BADVIEWPARAMETERMISMATCH 0x80CA0000 + +/* The view version is not available or not supported. */ +#define UA_STATUSCODE_BADVIEWVERSIONINVALID 0x80CB0000 + +/* The list of references may not be complete because the underlying system is not available. */ +#define UA_STATUSCODE_UNCERTAINNOTALLNODESAVAILABLE 0x40C00000 + +/* The server should have followed a reference to a node in a remote server but did not. The result set may be incomplete. */ +#define UA_STATUSCODE_GOODRESULTSMAYBEINCOMPLETE 0x00BA0000 + +/* The provided Nodeid was not a type definition nodeid. */ +#define UA_STATUSCODE_BADNOTTYPEDEFINITION 0x80C80000 + +/* One of the references to follow in the relative path references to a node in the address space in another server. */ +#define UA_STATUSCODE_UNCERTAINREFERENCEOUTOFSERVER 0x406C0000 + +/* The requested operation has too many matches to return. */ +#define UA_STATUSCODE_BADTOOMANYMATCHES 0x806D0000 + +/* The requested operation requires too many resources in the server. */ +#define UA_STATUSCODE_BADQUERYTOOCOMPLEX 0x806E0000 + +/* The requested operation has no match to return. */ +#define UA_STATUSCODE_BADNOMATCH 0x806F0000 + +/* The max age parameter is invalid. */ +#define UA_STATUSCODE_BADMAXAGEINVALID 0x80700000 + +/* The operation is not permitted over the current secure channel. */ +#define UA_STATUSCODE_BADSECURITYMODEINSUFFICIENT 0x80E60000 + +/* The history details parameter is not valid. */ +#define UA_STATUSCODE_BADHISTORYOPERATIONINVALID 0x80710000 + +/* The server does not support the requested operation. */ +#define UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED 0x80720000 + +/* The defined timestamp to return was invalid. */ +#define UA_STATUSCODE_BADINVALIDTIMESTAMPARGUMENT 0x80BD0000 + +/* The server does not support writing the combination of valu */ +#define UA_STATUSCODE_BADWRITENOTSUPPORTED 0x80730000 + +/* The value supplied for the attribute is not of the same type as the attribute's value. */ +#define UA_STATUSCODE_BADTYPEMISMATCH 0x80740000 + +/* The method id does not refer to a method for the specified object. */ +#define UA_STATUSCODE_BADMETHODINVALID 0x80750000 + +/* The client did not specify all of the input arguments for the method. */ +#define UA_STATUSCODE_BADARGUMENTSMISSING 0x80760000 + +/* The executable attribute does not allow the execution of the method. */ +#define UA_STATUSCODE_BADNOTEXECUTABLE 0x81110000 + +/* The server has reached its maximum number of subscriptions. */ +#define UA_STATUSCODE_BADTOOMANYSUBSCRIPTIONS 0x80770000 + +/* The server has reached the maximum number of queued publish requests. */ +#define UA_STATUSCODE_BADTOOMANYPUBLISHREQUESTS 0x80780000 + +/* There is no subscription available for this session. */ +#define UA_STATUSCODE_BADNOSUBSCRIPTION 0x80790000 + +/* The sequence number is unknown to the server. */ +#define UA_STATUSCODE_BADSEQUENCENUMBERUNKNOWN 0x807A0000 + +/* The Server does not support retransmission queue and acknowledgement of sequence numbers is not available. */ +#define UA_STATUSCODE_GOODRETRANSMISSIONQUEUENOTSUPPORTED 0x00DF0000 + +/* The requested notification message is no longer available. */ +#define UA_STATUSCODE_BADMESSAGENOTAVAILABLE 0x807B0000 + +/* The client of the current session does not support one or more Profiles that are necessary for the subscription. */ +#define UA_STATUSCODE_BADINSUFFICIENTCLIENTPROFILE 0x807C0000 + +/* The sub-state machine is not currently active. */ +#define UA_STATUSCODE_BADSTATENOTACTIVE 0x80BF0000 + +/* An equivalent rule already exists. */ +#define UA_STATUSCODE_BADALREADYEXISTS 0x81150000 + +/* The server cannot process the request because it is too busy. */ +#define UA_STATUSCODE_BADTCPSERVERTOOBUSY 0x807D0000 + +/* The type of the message specified in the header invalid. */ +#define UA_STATUSCODE_BADTCPMESSAGETYPEINVALID 0x807E0000 + +/* The SecureChannelId and/or TokenId are not currently in use. */ +#define UA_STATUSCODE_BADTCPSECURECHANNELUNKNOWN 0x807F0000 + +/* The size of the message chunk specified in the header is too large. */ +#define UA_STATUSCODE_BADTCPMESSAGETOOLARGE 0x80800000 + +/* There are not enough resources to process the request. */ +#define UA_STATUSCODE_BADTCPNOTENOUGHRESOURCES 0x80810000 + +/* An internal error occurred. */ +#define UA_STATUSCODE_BADTCPINTERNALERROR 0x80820000 + +/* The server does not recognize the QueryString specified. */ +#define UA_STATUSCODE_BADTCPENDPOINTURLINVALID 0x80830000 + +/* The request could not be sent because of a network interruption. */ +#define UA_STATUSCODE_BADREQUESTINTERRUPTED 0x80840000 + +/* Timeout occurred while processing the request. */ +#define UA_STATUSCODE_BADREQUESTTIMEOUT 0x80850000 + +/* The secure channel has been closed. */ +#define UA_STATUSCODE_BADSECURECHANNELCLOSED 0x80860000 + +/* The token has expired or is not recognized. */ +#define UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN 0x80870000 + +/* The sequence number is not valid. */ +#define UA_STATUSCODE_BADSEQUENCENUMBERINVALID 0x80880000 + +/* The applications do not have compatible protocol versions. */ +#define UA_STATUSCODE_BADPROTOCOLVERSIONUNSUPPORTED 0x80BE0000 + +/* There is a problem with the configuration that affects the usefulness of the value. */ +#define UA_STATUSCODE_BADCONFIGURATIONERROR 0x80890000 + +/* The variable should receive its value from another variabl */ +#define UA_STATUSCODE_BADNOTCONNECTED 0x808A0000 + +/* There has been a failure in the device/data source that generates the value that has affected the value. */ +#define UA_STATUSCODE_BADDEVICEFAILURE 0x808B0000 + +/* There has been a failure in the sensor from which the value is derived by the device/data source. */ +#define UA_STATUSCODE_BADSENSORFAILURE 0x808C0000 + +/* The source of the data is not operational. */ +#define UA_STATUSCODE_BADOUTOFSERVICE 0x808D0000 + +/* The deadband filter is not valid. */ +#define UA_STATUSCODE_BADDEADBANDFILTERINVALID 0x808E0000 + +/* Communication to the data source has failed. The variable value is the last value that had a good quality. */ +#define UA_STATUSCODE_UNCERTAINNOCOMMUNICATIONLASTUSABLEVALUE 0x408F0000 + +/* Whatever was updating this value has stopped doing so. */ +#define UA_STATUSCODE_UNCERTAINLASTUSABLEVALUE 0x40900000 + +/* The value is an operational value that was manually overwritten. */ +#define UA_STATUSCODE_UNCERTAINSUBSTITUTEVALUE 0x40910000 + +/* The value is an initial value for a variable that normally receives its value from another variable. */ +#define UA_STATUSCODE_UNCERTAININITIALVALUE 0x40920000 + +/* The value is at one of the sensor limits. */ +#define UA_STATUSCODE_UNCERTAINSENSORNOTACCURATE 0x40930000 + +/* The value is outside of the range of values defined for this parameter. */ +#define UA_STATUSCODE_UNCERTAINENGINEERINGUNITSEXCEEDED 0x40940000 + +/* The value is derived from multiple sources and has less than the required number of Good sources. */ +#define UA_STATUSCODE_UNCERTAINSUBNORMAL 0x40950000 + +/* The value has been overridden. */ +#define UA_STATUSCODE_GOODLOCALOVERRIDE 0x00960000 + +/* This Condition refresh faile */ +#define UA_STATUSCODE_BADREFRESHINPROGRESS 0x80970000 + +/* This condition has already been disabled. */ +#define UA_STATUSCODE_BADCONDITIONALREADYDISABLED 0x80980000 + +/* This condition has already been enabled. */ +#define UA_STATUSCODE_BADCONDITIONALREADYENABLED 0x80CC0000 + +/* Property not availabl */ +#define UA_STATUSCODE_BADCONDITIONDISABLED 0x80990000 + +/* The specified event id is not recognized. */ +#define UA_STATUSCODE_BADEVENTIDUNKNOWN 0x809A0000 + +/* The event cannot be acknowledged. */ +#define UA_STATUSCODE_BADEVENTNOTACKNOWLEDGEABLE 0x80BB0000 + +/* The dialog condition is not active. */ +#define UA_STATUSCODE_BADDIALOGNOTACTIVE 0x80CD0000 + +/* The response is not valid for the dialog. */ +#define UA_STATUSCODE_BADDIALOGRESPONSEINVALID 0x80CE0000 + +/* The condition branch has already been acknowledged. */ +#define UA_STATUSCODE_BADCONDITIONBRANCHALREADYACKED 0x80CF0000 + +/* The condition branch has already been confirmed. */ +#define UA_STATUSCODE_BADCONDITIONBRANCHALREADYCONFIRMED 0x80D00000 + +/* The condition has already been shelved. */ +#define UA_STATUSCODE_BADCONDITIONALREADYSHELVED 0x80D10000 + +/* The condition is not currently shelved. */ +#define UA_STATUSCODE_BADCONDITIONNOTSHELVED 0x80D20000 + +/* The shelving time not within an acceptable range. */ +#define UA_STATUSCODE_BADSHELVINGTIMEOUTOFRANGE 0x80D30000 + +/* No data exists for the requested time range or event filter. */ +#define UA_STATUSCODE_BADNODATA 0x809B0000 + +/* No data found to provide upper or lower bound value. */ +#define UA_STATUSCODE_BADBOUNDNOTFOUND 0x80D70000 + +/* The server cannot retrieve a bound for the variable. */ +#define UA_STATUSCODE_BADBOUNDNOTSUPPORTED 0x80D80000 + +/* Data is missing due to collection started/stopped/lost. */ +#define UA_STATUSCODE_BADDATALOST 0x809D0000 + +/* Expected data is unavailable for the requested time range due to an un-mounted volum */ +#define UA_STATUSCODE_BADDATAUNAVAILABLE 0x809E0000 + +/* The data or event was not successfully inserted because a matching entry exists. */ +#define UA_STATUSCODE_BADENTRYEXISTS 0x809F0000 + +/* The data or event was not successfully updated because no matching entry exists. */ +#define UA_STATUSCODE_BADNOENTRYEXISTS 0x80A00000 + +/* The client requested history using a timestamp format the server does not support (i.e requested ServerTimestamp when server only supports SourceTimestamp). */ +#define UA_STATUSCODE_BADTIMESTAMPNOTSUPPORTED 0x80A10000 + +/* The data or event was successfully inserted into the historical database. */ +#define UA_STATUSCODE_GOODENTRYINSERTED 0x00A20000 + +/* The data or event field was successfully replaced in the historical database. */ +#define UA_STATUSCODE_GOODENTRYREPLACED 0x00A30000 + +/* The value is derived from multiple values and has less than the required number of Good values. */ +#define UA_STATUSCODE_UNCERTAINDATASUBNORMAL 0x40A40000 + +/* No data exists for the requested time range or event filter. */ +#define UA_STATUSCODE_GOODNODATA 0x00A50000 + +/* The data or event field was successfully replaced in the historical database. */ +#define UA_STATUSCODE_GOODMOREDATA 0x00A60000 + +/* The requested number of Aggregates does not match the requested number of NodeIds. */ +#define UA_STATUSCODE_BADAGGREGATELISTMISMATCH 0x80D40000 + +/* The requested Aggregate is not support by the server. */ +#define UA_STATUSCODE_BADAGGREGATENOTSUPPORTED 0x80D50000 + +/* The aggregate value could not be derived due to invalid data inputs. */ +#define UA_STATUSCODE_BADAGGREGATEINVALIDINPUTS 0x80D60000 + +/* The aggregate configuration is not valid for specified node. */ +#define UA_STATUSCODE_BADAGGREGATECONFIGURATIONREJECTED 0x80DA0000 + +/* The request specifies fields which are not valid for the EventType or cannot be saved by the historian. */ +#define UA_STATUSCODE_GOODDATAIGNORED 0x00D90000 + +/* The request was rejected by the server because it did not meet the criteria set by the server. */ +#define UA_STATUSCODE_BADREQUESTNOTALLOWED 0x80E40000 + +/* The request has not been processed by the server yet. */ +#define UA_STATUSCODE_BADREQUESTNOTCOMPLETE 0x81130000 + +/* The device identity needs a ticket before it can be accepted. */ +#define UA_STATUSCODE_BADTICKETREQUIRED 0x811F0000 + +/* The device identity needs a ticket before it can be accepted. */ +#define UA_STATUSCODE_BADTICKETINVALID 0x81200000 + +/* The value does not come from the real source and has been edited by the server. */ +#define UA_STATUSCODE_GOODEDITED 0x00DC0000 + +/* There was an error in execution of these post-actions. */ +#define UA_STATUSCODE_GOODPOSTACTIONFAILED 0x00DD0000 + +/* The related EngineeringUnit has been changed but the Variable Value is still provided based on the previous unit. */ +#define UA_STATUSCODE_UNCERTAINDOMINANTVALUECHANGED 0x40DE0000 + +/* A dependent value has been changed but the change has not been applied to the device. */ +#define UA_STATUSCODE_GOODDEPENDENTVALUECHANGED 0x00E00000 + +/* The related EngineeringUnit has been changed but this change has not been applied to the device. The Variable Value is still dependent on the previous unit but its status is currently Bad. */ +#define UA_STATUSCODE_BADDOMINANTVALUECHANGED 0x80E10000 + +/* A dependent value has been changed but the change has not been applied to the device. The quality of the dominant variable is uncertain. */ +#define UA_STATUSCODE_UNCERTAINDEPENDENTVALUECHANGED 0x40E20000 + +/* A dependent value has been changed but the change has not been applied to the device. The quality of the dominant variable is Bad. */ +#define UA_STATUSCODE_BADDEPENDENTVALUECHANGED 0x80E30000 + +/* It is delivered with a dominant Variable value when a dependent Variable has changed but the change has not been applied. */ +#define UA_STATUSCODE_GOODEDITED_DEPENDENTVALUECHANGED 0x01160000 + +/* It is delivered with a dependent Variable value when a dominant Variable has changed but the change has not been applied. */ +#define UA_STATUSCODE_GOODEDITED_DOMINANTVALUECHANGED 0x01170000 + +/* It is delivered with a dependent Variable value when a dominant or dependent Variable has changed but change has not been applied. */ +#define UA_STATUSCODE_GOODEDITED_DOMINANTVALUECHANGED_DEPENDENTVALUECHANGED 0x01180000 + +/* It is delivered with a Variable value when Variable has changed but the value is not legal. */ +#define UA_STATUSCODE_BADEDITED_OUTOFRANGE 0x81190000 + +/* It is delivered with a Variable value when a source Variable has changed but the value is not legal. */ +#define UA_STATUSCODE_BADINITIALVALUE_OUTOFRANGE 0x811A0000 + +/* It is delivered with a dependent Variable value when a dominant Variable has changed and the value is not legal. */ +#define UA_STATUSCODE_BADOUTOFRANGE_DOMINANTVALUECHANGED 0x811B0000 + +/* It is delivered with a dependent Variable value when a dominant Variable has change */ +#define UA_STATUSCODE_BADEDITED_OUTOFRANGE_DOMINANTVALUECHANGED 0x811C0000 + +/* It is delivered with a dependent Variable value when a dominant or dependent Variable has changed and the value is not legal. */ +#define UA_STATUSCODE_BADOUTOFRANGE_DOMINANTVALUECHANGED_DEPENDENTVALUECHANGED 0x811D0000 + +/* It is delivered with a dependent Variable value when a dominant or dependent Variable has change */ +#define UA_STATUSCODE_BADEDITED_OUTOFRANGE_DOMINANTVALUECHANGED_DEPENDENTVALUECHANGED 0x811E0000 + +/* The communication layer has raised an event. */ +#define UA_STATUSCODE_GOODCOMMUNICATIONEVENT 0x00A70000 + +/* The system is shutting down. */ +#define UA_STATUSCODE_GOODSHUTDOWNEVENT 0x00A80000 + +/* The operation is not finished and needs to be called again. */ +#define UA_STATUSCODE_GOODCALLAGAIN 0x00A90000 + +/* A non-critical timeout occurred. */ +#define UA_STATUSCODE_GOODNONCRITICALTIMEOUT 0x00AA0000 + +/* One or more arguments are invalid. */ +#define UA_STATUSCODE_BADINVALIDARGUMENT 0x80AB0000 + +/* Could not establish a network connection to remote server. */ +#define UA_STATUSCODE_BADCONNECTIONREJECTED 0x80AC0000 + +/* The server has disconnected from the client. */ +#define UA_STATUSCODE_BADDISCONNECT 0x80AD0000 + +/* The network connection has been closed. */ +#define UA_STATUSCODE_BADCONNECTIONCLOSED 0x80AE0000 + +/* The operation cannot be completed because the object is close */ +#define UA_STATUSCODE_BADINVALIDSTATE 0x80AF0000 + +/* Cannot move beyond end of the stream. */ +#define UA_STATUSCODE_BADENDOFSTREAM 0x80B00000 + +/* No data is currently available for reading from a non-blocking stream. */ +#define UA_STATUSCODE_BADNODATAAVAILABLE 0x80B10000 + +/* The asynchronous operation is waiting for a response. */ +#define UA_STATUSCODE_BADWAITINGFORRESPONSE 0x80B20000 + +/* The asynchronous operation was abandoned by the caller. */ +#define UA_STATUSCODE_BADOPERATIONABANDONED 0x80B30000 + +/* The stream did not return all data requested (possibly because it is a non-blocking stream). */ +#define UA_STATUSCODE_BADEXPECTEDSTREAMTOBLOCK 0x80B40000 + +/* Non blocking behaviour is required and the operation would block. */ +#define UA_STATUSCODE_BADWOULDBLOCK 0x80B50000 + +/* A value had an invalid syntax. */ +#define UA_STATUSCODE_BADSYNTAXERROR 0x80B60000 + +/* The operation could not be finished because all available connections are in use. */ +#define UA_STATUSCODE_BADMAXCONNECTIONSREACHED 0x80B70000 + +/* Depending on the version of the schema, the following might be already defined: */ +#ifndef UA_STATUSCODE_GOOD +# define UA_STATUSCODE_GOOD 0x00000000 +#endif +#ifndef UA_STATUSCODE_UNCERTAIN +# define UA_STATUSCODE_UNCERTAIN 0x40000000 +#endif +#ifndef UA_STATUSCODE_BAD +# define UA_STATUSCODE_BAD 0x80000000 +#endif + diff --git a/product/src/fes/include/open62541/transport_generated.h b/product/src/fes/include/open62541/transport_generated.h new file mode 100644 index 00000000..9fa55a1d --- /dev/null +++ b/product/src/fes/include/open62541/transport_generated.h @@ -0,0 +1,122 @@ +/********************************** + * Autogenerated -- do not modify * + **********************************/ + +/* Must be before the include guards */ +#ifdef UA_ENABLE_AMALGAMATION +# include "open62541.h" +#else +# include +#endif + +#ifndef TRANSPORT_GENERATED_H_ +#define TRANSPORT_GENERATED_H_ + +#include "types_generated.h" + +_UA_BEGIN_DECLS + +/** + * Every type is assigned an index in an array containing the type descriptions. + * These descriptions are used during type handling (copying, deletion, + * binary encoding, ...). */ +#define UA_TRANSPORT_COUNT 9 +extern UA_EXPORT UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT]; + +/* MessageType: Message Type and whether the message contains an intermediate chunk */ +typedef enum { + UA_MESSAGETYPE_ACK = 0x4B4341, + UA_MESSAGETYPE_HEL = 0x4C4548, + UA_MESSAGETYPE_MSG = 0x47534D, + UA_MESSAGETYPE_OPN = 0x4E504F, + UA_MESSAGETYPE_CLO = 0x4F4C43, + UA_MESSAGETYPE_ERR = 0x525245, + UA_MESSAGETYPE_RHE = 0x454852, + UA_MESSAGETYPE_INVALID = 0x0, + __UA_MESSAGETYPE_FORCE32BIT = 0x7fffffff +} UA_MessageType; + +UA_STATIC_ASSERT(sizeof(UA_MessageType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TRANSPORT_MESSAGETYPE 0 + +/* ChunkType: Type of the chunk */ +typedef enum { + UA_CHUNKTYPE_FINAL = 0x46000000, + UA_CHUNKTYPE_INTERMEDIATE = 0x43000000, + UA_CHUNKTYPE_ABORT = 0x41000000, + __UA_CHUNKTYPE_FORCE32BIT = 0x7fffffff +} UA_ChunkType; + +UA_STATIC_ASSERT(sizeof(UA_ChunkType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TRANSPORT_CHUNKTYPE 1 + +/* TcpMessageHeader: TCP Header */ +typedef struct { + UA_UInt32 messageTypeAndChunkType; + UA_UInt32 messageSize; +} UA_TcpMessageHeader; + +#define UA_TRANSPORT_TCPMESSAGEHEADER 2 + +/* TcpHelloMessage: Hello Message */ +typedef struct { + UA_UInt32 protocolVersion; + UA_UInt32 receiveBufferSize; + UA_UInt32 sendBufferSize; + UA_UInt32 maxMessageSize; + UA_UInt32 maxChunkCount; + UA_String endpointUrl; +} UA_TcpHelloMessage; + +#define UA_TRANSPORT_TCPHELLOMESSAGE 3 + +/* TcpReverseHelloMessage */ +typedef struct { + UA_String serverUri; + UA_String endpointUrl; +} UA_TcpReverseHelloMessage; + +#define UA_TRANSPORT_TCPREVERSEHELLOMESSAGE 4 + +/* TcpAcknowledgeMessage: Acknowledge Message */ +typedef struct { + UA_UInt32 protocolVersion; + UA_UInt32 receiveBufferSize; + UA_UInt32 sendBufferSize; + UA_UInt32 maxMessageSize; + UA_UInt32 maxChunkCount; +} UA_TcpAcknowledgeMessage; + +#define UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE 5 + +/* TcpErrorMessage: Error Message */ +typedef struct { + UA_UInt32 error; + UA_String reason; +} UA_TcpErrorMessage; + +#define UA_TRANSPORT_TCPERRORMESSAGE 6 + +/* AsymmetricAlgorithmSecurityHeader: Asymmetric Security Header */ +typedef struct { + UA_ByteString securityPolicyUri; + UA_ByteString senderCertificate; + UA_ByteString receiverCertificateThumbprint; +} UA_AsymmetricAlgorithmSecurityHeader; + +#define UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER 7 + +/* SequenceHeader: Secure Layer Sequence Header */ +typedef struct { + UA_UInt32 sequenceNumber; + UA_UInt32 requestId; +} UA_SequenceHeader; + +#define UA_TRANSPORT_SEQUENCEHEADER 8 + + +_UA_END_DECLS + +#endif /* TRANSPORT_GENERATED_H_ */ diff --git a/product/src/fes/include/open62541/transport_generated_handling.h b/product/src/fes/include/open62541/transport_generated_handling.h new file mode 100644 index 00000000..abb71293 --- /dev/null +++ b/product/src/fes/include/open62541/transport_generated_handling.h @@ -0,0 +1,349 @@ +/********************************** + * Autogenerated -- do not modify * + **********************************/ + +#ifndef TRANSPORT_GENERATED_HANDLING_H_ +#define TRANSPORT_GENERATED_HANDLING_H_ + +#include "transport_generated.h" + +_UA_BEGIN_DECLS + +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +# pragma GCC diagnostic ignored "-Wmissing-braces" +#endif + + +/* MessageType */ +static UA_INLINE void +UA_MessageType_init(UA_MessageType *p) { + memset(p, 0, sizeof(UA_MessageType)); +} + +static UA_INLINE UA_MessageType * +UA_MessageType_new(void) { + return (UA_MessageType*)UA_new(&UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]); +} + +static UA_INLINE UA_StatusCode +UA_MessageType_copy(const UA_MessageType *src, UA_MessageType *dst) { + return UA_copy(src, dst, &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_MessageType_deleteMembers(UA_MessageType *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]); +} + +static UA_INLINE void +UA_MessageType_clear(UA_MessageType *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]); +} + +static UA_INLINE void +UA_MessageType_delete(UA_MessageType *p) { + UA_delete(p, &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]); +}static UA_INLINE UA_Boolean +UA_MessageType_equal(const UA_MessageType *p1, const UA_MessageType *p2) { + return (UA_order(p1, p2, &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]) == UA_ORDER_EQ); +} + + + +/* ChunkType */ +static UA_INLINE void +UA_ChunkType_init(UA_ChunkType *p) { + memset(p, 0, sizeof(UA_ChunkType)); +} + +static UA_INLINE UA_ChunkType * +UA_ChunkType_new(void) { + return (UA_ChunkType*)UA_new(&UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_ChunkType_copy(const UA_ChunkType *src, UA_ChunkType *dst) { + return UA_copy(src, dst, &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ChunkType_deleteMembers(UA_ChunkType *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]); +} + +static UA_INLINE void +UA_ChunkType_clear(UA_ChunkType *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]); +} + +static UA_INLINE void +UA_ChunkType_delete(UA_ChunkType *p) { + UA_delete(p, &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]); +}static UA_INLINE UA_Boolean +UA_ChunkType_equal(const UA_ChunkType *p1, const UA_ChunkType *p2) { + return (UA_order(p1, p2, &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]) == UA_ORDER_EQ); +} + + + +/* TcpMessageHeader */ +static UA_INLINE void +UA_TcpMessageHeader_init(UA_TcpMessageHeader *p) { + memset(p, 0, sizeof(UA_TcpMessageHeader)); +} + +static UA_INLINE UA_TcpMessageHeader * +UA_TcpMessageHeader_new(void) { + return (UA_TcpMessageHeader*)UA_new(&UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]); +} + +static UA_INLINE UA_StatusCode +UA_TcpMessageHeader_copy(const UA_TcpMessageHeader *src, UA_TcpMessageHeader *dst) { + return UA_copy(src, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TcpMessageHeader_deleteMembers(UA_TcpMessageHeader *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]); +} + +static UA_INLINE void +UA_TcpMessageHeader_clear(UA_TcpMessageHeader *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]); +} + +static UA_INLINE void +UA_TcpMessageHeader_delete(UA_TcpMessageHeader *p) { + UA_delete(p, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]); +}static UA_INLINE UA_Boolean +UA_TcpMessageHeader_equal(const UA_TcpMessageHeader *p1, const UA_TcpMessageHeader *p2) { + return (UA_order(p1, p2, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]) == UA_ORDER_EQ); +} + + + +/* TcpHelloMessage */ +static UA_INLINE void +UA_TcpHelloMessage_init(UA_TcpHelloMessage *p) { + memset(p, 0, sizeof(UA_TcpHelloMessage)); +} + +static UA_INLINE UA_TcpHelloMessage * +UA_TcpHelloMessage_new(void) { + return (UA_TcpHelloMessage*)UA_new(&UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]); +} + +static UA_INLINE UA_StatusCode +UA_TcpHelloMessage_copy(const UA_TcpHelloMessage *src, UA_TcpHelloMessage *dst) { + return UA_copy(src, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TcpHelloMessage_deleteMembers(UA_TcpHelloMessage *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]); +} + +static UA_INLINE void +UA_TcpHelloMessage_clear(UA_TcpHelloMessage *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]); +} + +static UA_INLINE void +UA_TcpHelloMessage_delete(UA_TcpHelloMessage *p) { + UA_delete(p, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]); +}static UA_INLINE UA_Boolean +UA_TcpHelloMessage_equal(const UA_TcpHelloMessage *p1, const UA_TcpHelloMessage *p2) { + return (UA_order(p1, p2, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]) == UA_ORDER_EQ); +} + + + +/* TcpReverseHelloMessage */ +static UA_INLINE void +UA_TcpReverseHelloMessage_init(UA_TcpReverseHelloMessage *p) { + memset(p, 0, sizeof(UA_TcpReverseHelloMessage)); +} + +static UA_INLINE UA_TcpReverseHelloMessage * +UA_TcpReverseHelloMessage_new(void) { + return (UA_TcpReverseHelloMessage*)UA_new(&UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE]); +} + +static UA_INLINE UA_StatusCode +UA_TcpReverseHelloMessage_copy(const UA_TcpReverseHelloMessage *src, UA_TcpReverseHelloMessage *dst) { + return UA_copy(src, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TcpReverseHelloMessage_deleteMembers(UA_TcpReverseHelloMessage *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE]); +} + +static UA_INLINE void +UA_TcpReverseHelloMessage_clear(UA_TcpReverseHelloMessage *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE]); +} + +static UA_INLINE void +UA_TcpReverseHelloMessage_delete(UA_TcpReverseHelloMessage *p) { + UA_delete(p, &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE]); +}static UA_INLINE UA_Boolean +UA_TcpReverseHelloMessage_equal(const UA_TcpReverseHelloMessage *p1, const UA_TcpReverseHelloMessage *p2) { + return (UA_order(p1, p2, &UA_TRANSPORT[UA_TRANSPORT_TCPREVERSEHELLOMESSAGE]) == UA_ORDER_EQ); +} + + + +/* TcpAcknowledgeMessage */ +static UA_INLINE void +UA_TcpAcknowledgeMessage_init(UA_TcpAcknowledgeMessage *p) { + memset(p, 0, sizeof(UA_TcpAcknowledgeMessage)); +} + +static UA_INLINE UA_TcpAcknowledgeMessage * +UA_TcpAcknowledgeMessage_new(void) { + return (UA_TcpAcknowledgeMessage*)UA_new(&UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]); +} + +static UA_INLINE UA_StatusCode +UA_TcpAcknowledgeMessage_copy(const UA_TcpAcknowledgeMessage *src, UA_TcpAcknowledgeMessage *dst) { + return UA_copy(src, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TcpAcknowledgeMessage_deleteMembers(UA_TcpAcknowledgeMessage *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]); +} + +static UA_INLINE void +UA_TcpAcknowledgeMessage_clear(UA_TcpAcknowledgeMessage *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]); +} + +static UA_INLINE void +UA_TcpAcknowledgeMessage_delete(UA_TcpAcknowledgeMessage *p) { + UA_delete(p, &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]); +}static UA_INLINE UA_Boolean +UA_TcpAcknowledgeMessage_equal(const UA_TcpAcknowledgeMessage *p1, const UA_TcpAcknowledgeMessage *p2) { + return (UA_order(p1, p2, &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]) == UA_ORDER_EQ); +} + + + +/* TcpErrorMessage */ +static UA_INLINE void +UA_TcpErrorMessage_init(UA_TcpErrorMessage *p) { + memset(p, 0, sizeof(UA_TcpErrorMessage)); +} + +static UA_INLINE UA_TcpErrorMessage * +UA_TcpErrorMessage_new(void) { + return (UA_TcpErrorMessage*)UA_new(&UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]); +} + +static UA_INLINE UA_StatusCode +UA_TcpErrorMessage_copy(const UA_TcpErrorMessage *src, UA_TcpErrorMessage *dst) { + return UA_copy(src, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TcpErrorMessage_deleteMembers(UA_TcpErrorMessage *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]); +} + +static UA_INLINE void +UA_TcpErrorMessage_clear(UA_TcpErrorMessage *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]); +} + +static UA_INLINE void +UA_TcpErrorMessage_delete(UA_TcpErrorMessage *p) { + UA_delete(p, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]); +}static UA_INLINE UA_Boolean +UA_TcpErrorMessage_equal(const UA_TcpErrorMessage *p1, const UA_TcpErrorMessage *p2) { + return (UA_order(p1, p2, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]) == UA_ORDER_EQ); +} + + + +/* AsymmetricAlgorithmSecurityHeader */ +static UA_INLINE void +UA_AsymmetricAlgorithmSecurityHeader_init(UA_AsymmetricAlgorithmSecurityHeader *p) { + memset(p, 0, sizeof(UA_AsymmetricAlgorithmSecurityHeader)); +} + +static UA_INLINE UA_AsymmetricAlgorithmSecurityHeader * +UA_AsymmetricAlgorithmSecurityHeader_new(void) { + return (UA_AsymmetricAlgorithmSecurityHeader*)UA_new(&UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]); +} + +static UA_INLINE UA_StatusCode +UA_AsymmetricAlgorithmSecurityHeader_copy(const UA_AsymmetricAlgorithmSecurityHeader *src, UA_AsymmetricAlgorithmSecurityHeader *dst) { + return UA_copy(src, dst, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(UA_AsymmetricAlgorithmSecurityHeader *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]); +} + +static UA_INLINE void +UA_AsymmetricAlgorithmSecurityHeader_clear(UA_AsymmetricAlgorithmSecurityHeader *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]); +} + +static UA_INLINE void +UA_AsymmetricAlgorithmSecurityHeader_delete(UA_AsymmetricAlgorithmSecurityHeader *p) { + UA_delete(p, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]); +}static UA_INLINE UA_Boolean +UA_AsymmetricAlgorithmSecurityHeader_equal(const UA_AsymmetricAlgorithmSecurityHeader *p1, const UA_AsymmetricAlgorithmSecurityHeader *p2) { + return (UA_order(p1, p2, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]) == UA_ORDER_EQ); +} + + + +/* SequenceHeader */ +static UA_INLINE void +UA_SequenceHeader_init(UA_SequenceHeader *p) { + memset(p, 0, sizeof(UA_SequenceHeader)); +} + +static UA_INLINE UA_SequenceHeader * +UA_SequenceHeader_new(void) { + return (UA_SequenceHeader*)UA_new(&UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]); +} + +static UA_INLINE UA_StatusCode +UA_SequenceHeader_copy(const UA_SequenceHeader *src, UA_SequenceHeader *dst) { + return UA_copy(src, dst, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SequenceHeader_deleteMembers(UA_SequenceHeader *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]); +} + +static UA_INLINE void +UA_SequenceHeader_clear(UA_SequenceHeader *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]); +} + +static UA_INLINE void +UA_SequenceHeader_delete(UA_SequenceHeader *p) { + UA_delete(p, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]); +}static UA_INLINE UA_Boolean +UA_SequenceHeader_equal(const UA_SequenceHeader *p1, const UA_SequenceHeader *p2) { + return (UA_order(p1, p2, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]) == UA_ORDER_EQ); +} + + + +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +# pragma GCC diagnostic pop +#endif + +_UA_END_DECLS + +#endif /* TRANSPORT_GENERATED_HANDLING_H_ */ diff --git a/product/src/fes/include/open62541/types.h b/product/src/fes/include/open62541/types.h new file mode 100644 index 00000000..82f64082 --- /dev/null +++ b/product/src/fes/include/open62541/types.h @@ -0,0 +1,1510 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2014 (c) Leon Urbas + * Copyright 2014, 2016-2017 (c) Florian Palm + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2015-2016 (c) Sten Grüner + * Copyright 2015-2016 (c) Chris Iatrou + * Copyright 2015 (c) Nick Goossens + * Copyright 2015-2016 (c) Oleksiy Vasylyev + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA + * Copyright 2023 (c) Fraunhofer IOSB (Author: Andreas Ebner) + */ + +#ifndef UA_TYPES_H_ +#define UA_TYPES_H_ + +#include +#include +#include + +_UA_BEGIN_DECLS + +/** + * .. _types: + * + * Data Types + * ========== + * + * The OPC UA protocol defines 25 builtin data types and three ways of combining + * them into higher-order types: arrays, structures and unions. In open62541, + * only the builtin data types are defined manually. All other data types are + * generated from standard XML definitions. Their exact definitions can be + * looked up at https://opcfoundation.org/UA/schemas/Opc.Ua.Types.bsd. + * + * For users that are new to open62541, take a look at the :ref:`tutorial for + * working with data types` before diving into the + * implementation details. + * + * Builtin Types + * ------------- + * + * Boolean + * ^^^^^^^ + * A two-state logical value (true or false). */ +typedef bool UA_Boolean; +#define UA_TRUE true UA_INTERNAL_DEPRECATED +#define UA_FALSE false UA_INTERNAL_DEPRECATED + +/** + * SByte + * ^^^^^ + * An integer value between -128 and 127. */ +typedef int8_t UA_SByte; +#define UA_SBYTE_MIN (-128) +#define UA_SBYTE_MAX 127 + +/** + * Byte + * ^^^^ + * An integer value between 0 and 255. */ +typedef uint8_t UA_Byte; +#define UA_BYTE_MIN 0 +#define UA_BYTE_MAX 255 + +/** + * Int16 + * ^^^^^ + * An integer value between -32 768 and 32 767. */ +typedef int16_t UA_Int16; +#define UA_INT16_MIN (-32768) +#define UA_INT16_MAX 32767 + +/** + * UInt16 + * ^^^^^^ + * An integer value between 0 and 65 535. */ +typedef uint16_t UA_UInt16; +#define UA_UINT16_MIN 0 +#define UA_UINT16_MAX 65535 + +/** + * Int32 + * ^^^^^ + * An integer value between -2 147 483 648 and 2 147 483 647. */ +typedef int32_t UA_Int32; +#define UA_INT32_MIN ((int32_t)-2147483648LL) +#define UA_INT32_MAX 2147483647L + +/** + * UInt32 + * ^^^^^^ + * An integer value between 0 and 4 294 967 295. */ +typedef uint32_t UA_UInt32; +#define UA_UINT32_MIN 0 +#define UA_UINT32_MAX 4294967295UL + +/** + * Int64 + * ^^^^^ + * An integer value between -9 223 372 036 854 775 808 and + * 9 223 372 036 854 775 807. */ +typedef int64_t UA_Int64; +#define UA_INT64_MAX (int64_t)9223372036854775807LL +#define UA_INT64_MIN ((int64_t)-UA_INT64_MAX-1LL) + +/** + * UInt64 + * ^^^^^^ + * An integer value between 0 and 18 446 744 073 709 551 615. */ +typedef uint64_t UA_UInt64; +#define UA_UINT64_MIN 0 +#define UA_UINT64_MAX (uint64_t)18446744073709551615ULL + +/** + * Float + * ^^^^^ + * An IEEE single precision (32 bit) floating point value. */ +typedef float UA_Float; +#define UA_FLOAT_MIN FLT_MIN +#define UA_FLOAT_MAX FLT_MAX + +/** + * Double + * ^^^^^^ + * An IEEE double precision (64 bit) floating point value. */ +typedef double UA_Double; +#define UA_DOUBLE_MIN DBL_MIN +#define UA_DOUBLE_MAX DBL_MAX + +/** + * .. _statuscode: + * + * StatusCode + * ^^^^^^^^^^ + * A numeric identifier for an error or condition that is associated with a + * value or an operation. See the section :ref:`statuscodes` for the meaning of + * a specific code. + * + * Each StatusCode has one of three "severity" bit-flags: + * Good, Uncertain, Bad. An additional reason is indicated by the SubCode + * bitfield. + * + * - A StatusCode with severity Good means that the value is of good quality. + * - A StatusCode with severity Uncertain means that the quality of the value is + * uncertain for reasons indicated by the SubCode. + * - A StatusCode with severity Bad means that the value is not usable for + * reasons indicated by the SubCode. */ +typedef uint32_t UA_StatusCode; + +/* Returns the human-readable name of the StatusCode. If no matching StatusCode + * is found, a default string for "Unknown" is returned. This feature might be + * disabled to create a smaller binary with the + * UA_ENABLE_STATUSCODE_DESCRIPTIONS build-flag. Then the function returns an + * empty string for every StatusCode. */ +UA_EXPORT const char * +UA_StatusCode_name(UA_StatusCode code); + +/* Extracts the severity from a StatusCode. See Part 4, Section 7.34 for + * details. */ +UA_INLINABLE(UA_Boolean + UA_StatusCode_isBad(UA_StatusCode code), { + return ((code >> 30) >= 0x02); +}) + +UA_INLINABLE(UA_Boolean + UA_StatusCode_isUncertain(UA_StatusCode code), { + return ((code >> 30) == 0x01); +}) + +UA_INLINABLE(UA_Boolean + UA_StatusCode_isGood(UA_StatusCode code), { + return ((code >> 30) == 0x00); +}) + +/* Compares the top 16 bits of two StatusCodes for equality. This should only + * be used when processing user-defined StatusCodes e.g when processing a ReadResponse. + * As a convention, the lower bits of StatusCodes should not be used internally, meaning + * can compare them without the use of this function. */ +UA_INLINABLE(UA_Boolean + UA_StatusCode_isEqualTop(UA_StatusCode s1, UA_StatusCode s2), { + return ((s1 & 0xFFFF0000) == (s2 & 0xFFFF0000)); +}) + +/** + * String + * ^^^^^^ + * A sequence of Unicode characters. Strings are just an array of UA_Byte. */ +typedef struct { + size_t length; /* The length of the string */ + UA_Byte *data; /* The content (not null-terminated) */ +} UA_String; + +/* Copies the content on the heap. Returns a null-string when alloc fails */ +UA_String UA_EXPORT +UA_String_fromChars(const char *src) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + +UA_Boolean UA_EXPORT +UA_String_isEmpty(const UA_String *s); + +UA_EXPORT extern const UA_String UA_STRING_NULL; + +/** + * ``UA_STRING`` returns a string pointing to the original char-array. + * ``UA_STRING_ALLOC`` is shorthand for ``UA_String_fromChars`` and makes a copy + * of the char-array. */ +UA_INLINABLE(UA_String + UA_STRING(char *chars), { + UA_String s; + memset(&s, 0, sizeof(s)); + if(!chars) + return s; + s.length = strlen(chars); s.data = (UA_Byte*)chars; + return s; +}) + +#define UA_STRING_ALLOC(CHARS) UA_String_fromChars(CHARS) + +/* Define strings at compile time (in ROM) */ +#define UA_STRING_STATIC(CHARS) {sizeof(CHARS)-1, (UA_Byte*)CHARS} + +/** + * .. _datetime: + * + * DateTime + * ^^^^^^^^ + * An instance in time. A DateTime value is encoded as a 64-bit signed integer + * which represents the number of 100 nanosecond intervals since January 1, 1601 + * (UTC). + * + * The methods providing an interface to the system clock are architecture- + * specific. Usually, they provide a UTC clock that includes leap seconds. The + * OPC UA standard allows the use of International Atomic Time (TAI) for the + * DateTime instead. But this is still unusual and not implemented for most + * SDKs. Currently (2019), UTC and TAI are 37 seconds apart due to leap + * seconds. */ + +typedef int64_t UA_DateTime; + +/* Multiples to convert durations to DateTime */ +#define UA_DATETIME_USEC 10LL +#define UA_DATETIME_MSEC (UA_DATETIME_USEC * 1000LL) +#define UA_DATETIME_SEC (UA_DATETIME_MSEC * 1000LL) + +/* The current time in UTC time */ +UA_DateTime UA_EXPORT UA_DateTime_now(void); + +/* Offset between local time and UTC time */ +UA_Int64 UA_EXPORT UA_DateTime_localTimeUtcOffset(void); + +/* CPU clock invariant to system time changes. Use only to measure durations, + * not absolute time. */ +UA_DateTime UA_EXPORT UA_DateTime_nowMonotonic(void); + +/* Represents a Datetime as a structure */ +typedef struct UA_DateTimeStruct { + UA_UInt16 nanoSec; + UA_UInt16 microSec; + UA_UInt16 milliSec; + UA_UInt16 sec; + UA_UInt16 min; + UA_UInt16 hour; + UA_UInt16 day; /* From 1 to 31 */ + UA_UInt16 month; /* From 1 to 12 */ + UA_Int16 year; /* Can be negative (BC) */ +} UA_DateTimeStruct; + +UA_DateTimeStruct UA_EXPORT UA_DateTime_toStruct(UA_DateTime t); +UA_DateTime UA_EXPORT UA_DateTime_fromStruct(UA_DateTimeStruct ts); + +/* The C99 standard (7.23.1) says: "The range and precision of times + * representable in clock_t and time_t are implementation-defined." On most + * systems, time_t is a 4 or 8 byte integer counting seconds since the UTC Unix + * epoch. The following methods are used for conversion. */ + +/* Datetime of 1 Jan 1970 00:00 */ +#define UA_DATETIME_UNIX_EPOCH (11644473600LL * UA_DATETIME_SEC) + +UA_INLINABLE(UA_Int64 + UA_DateTime_toUnixTime(UA_DateTime date), { + return (date - UA_DATETIME_UNIX_EPOCH) / UA_DATETIME_SEC; +}) + +UA_INLINABLE(UA_DateTime + UA_DateTime_fromUnixTime(UA_Int64 unixDate), { + return (unixDate * UA_DATETIME_SEC) + UA_DATETIME_UNIX_EPOCH; +}) + +/** + * Guid + * ^^^^ + * A 16 byte value that can be used as a globally unique identifier. */ +typedef struct { + UA_UInt32 data1; + UA_UInt16 data2; + UA_UInt16 data3; + UA_Byte data4[8]; +} UA_Guid; + +UA_EXPORT extern const UA_Guid UA_GUID_NULL; + +/* Print a Guid in the human-readable format defined in Part 6, 5.1.3 + * + * Format: C496578A-0DFE-4B8F-870A-745238C6AEAE + * | | | | | | + * 0 8 13 18 23 36 + * + * This allocates memory if the output argument is an empty string. Tries to use + * the given buffer otherwise. */ +UA_StatusCode UA_EXPORT +UA_Guid_print(const UA_Guid *guid, UA_String *output); + +/* Parse the humand-readable Guid format */ +#ifdef UA_ENABLE_PARSING +UA_StatusCode UA_EXPORT +UA_Guid_parse(UA_Guid *guid, const UA_String str); + +UA_INLINABLE(UA_Guid + UA_GUID(const char *chars), { + UA_Guid guid; + UA_Guid_parse(&guid, UA_STRING((char*)(uintptr_t)chars)); + return guid; +}) +#endif + +/** + * ByteString + * ^^^^^^^^^^ + * A sequence of octets. */ +typedef UA_String UA_ByteString; + +UA_EXPORT extern const UA_ByteString UA_BYTESTRING_NULL; + +/* Allocates memory of size length for the bytestring. + * The content is not set to zero. */ +UA_StatusCode UA_EXPORT +UA_ByteString_allocBuffer(UA_ByteString *bs, size_t length); + +/* Converts a ByteString to the corresponding + * base64 representation */ +UA_StatusCode UA_EXPORT +UA_ByteString_toBase64(const UA_ByteString *bs, UA_String *output); + +/* Parse a ByteString from a base64 representation */ +UA_StatusCode UA_EXPORT +UA_ByteString_fromBase64(UA_ByteString *bs, + const UA_String *input); + +#define UA_BYTESTRING(chars) UA_STRING(chars) +#define UA_BYTESTRING_ALLOC(chars) UA_STRING_ALLOC(chars) + +/* Returns a non-cryptographic hash of a bytestring */ +UA_UInt32 UA_EXPORT +UA_ByteString_hash(UA_UInt32 initialHashValue, + const UA_Byte *data, size_t size); + +/** + * XmlElement + * ^^^^^^^^^^ + * An XML element. */ +typedef UA_String UA_XmlElement; + +/** + * .. _nodeid: + * + * NodeId + * ^^^^^^ + * An identifier for a node in the address space of an OPC UA Server. */ +enum UA_NodeIdType { + UA_NODEIDTYPE_NUMERIC = 0, /* In the binary encoding, this can also + * become 1 or 2 (two-byte and four-byte + * encoding of small numeric nodeids) */ + UA_NODEIDTYPE_STRING = 3, + UA_NODEIDTYPE_GUID = 4, + UA_NODEIDTYPE_BYTESTRING = 5 +}; + +typedef struct { + UA_UInt16 namespaceIndex; + enum UA_NodeIdType identifierType; + union { + UA_UInt32 numeric; + UA_String string; + UA_Guid guid; + UA_ByteString byteString; + } identifier; +} UA_NodeId; + +UA_EXPORT extern const UA_NodeId UA_NODEID_NULL; + +UA_Boolean UA_EXPORT UA_NodeId_isNull(const UA_NodeId *p); + +/* Print the NodeId in the human-readable format defined in Part 6, + * 5.3.1.10. + * + * Examples: + * UA_NODEID("i=13") + * UA_NODEID("ns=10;i=1") + * UA_NODEID("ns=10;s=Hello:World") + * UA_NODEID("g=09087e75-8e5e-499b-954f-f2a9603db28a") + * UA_NODEID("ns=1;b=b3BlbjYyNTQxIQ==") // base64 + * + * The method can either use a pre-allocated string buffer or allocates memory + * internally if called with an empty output string. */ +UA_StatusCode UA_EXPORT +UA_NodeId_print(const UA_NodeId *id, UA_String *output); + +/* Parse the human-readable NodeId format. Attention! String and + * ByteString NodeIds have their identifier malloc'ed and need to be + * cleaned up. */ +#ifdef UA_ENABLE_PARSING +UA_StatusCode UA_EXPORT +UA_NodeId_parse(UA_NodeId *id, const UA_String str); + +UA_INLINABLE(UA_NodeId + UA_NODEID(const char *chars), { + UA_NodeId id; + UA_NodeId_parse(&id, UA_STRING((char*)(uintptr_t)chars)); + return id; +}) +#endif + +/** The following methods are a shorthand for creating NodeIds. */ +UA_INLINABLE(UA_NodeId + UA_NODEID_NUMERIC(UA_UInt16 nsIndex, + UA_UInt32 identifier), { + UA_NodeId id; + memset(&id, 0, sizeof(UA_NodeId)); + id.namespaceIndex = nsIndex; + id.identifierType = UA_NODEIDTYPE_NUMERIC; + id.identifier.numeric = identifier; + return id; +}) + +UA_INLINABLE(UA_NodeId + UA_NODEID_STRING(UA_UInt16 nsIndex, char *chars), { + UA_NodeId id; + memset(&id, 0, sizeof(UA_NodeId)); + id.namespaceIndex = nsIndex; + id.identifierType = UA_NODEIDTYPE_STRING; + id.identifier.string = UA_STRING(chars); + return id; +}) + +UA_INLINABLE(UA_NodeId + UA_NODEID_STRING_ALLOC(UA_UInt16 nsIndex, + const char *chars), { + UA_NodeId id; + memset(&id, 0, sizeof(UA_NodeId)); + id.namespaceIndex = nsIndex; + id.identifierType = UA_NODEIDTYPE_STRING; + id.identifier.string = UA_STRING_ALLOC(chars); + return id; +}) + +UA_INLINABLE(UA_NodeId + UA_NODEID_GUID(UA_UInt16 nsIndex, UA_Guid guid), { + UA_NodeId id; + memset(&id, 0, sizeof(UA_NodeId)); + id.namespaceIndex = nsIndex; + id.identifierType = UA_NODEIDTYPE_GUID; + id.identifier.guid = guid; + return id; +}) + +UA_INLINABLE(UA_NodeId + UA_NODEID_BYTESTRING(UA_UInt16 nsIndex, char *chars), { + UA_NodeId id; + memset(&id, 0, sizeof(UA_NodeId)); + id.namespaceIndex = nsIndex; + id.identifierType = UA_NODEIDTYPE_BYTESTRING; + id.identifier.byteString = UA_BYTESTRING(chars); + return id; +}) + +UA_INLINABLE(UA_NodeId + UA_NODEID_BYTESTRING_ALLOC(UA_UInt16 nsIndex, + const char *chars), { + UA_NodeId id; + memset(&id, 0, sizeof(UA_NodeId)); + id.namespaceIndex = nsIndex; + id.identifierType = UA_NODEIDTYPE_BYTESTRING; + id.identifier.byteString = UA_BYTESTRING_ALLOC(chars); + return id; +}) + +/* Total ordering of NodeId */ +UA_Order UA_EXPORT +UA_NodeId_order(const UA_NodeId *n1, const UA_NodeId *n2); + +/* Returns a non-cryptographic hash for NodeId */ +UA_UInt32 UA_EXPORT UA_NodeId_hash(const UA_NodeId *n); + +/** + * .. _expandednodeid: + * + * ExpandedNodeId + * ^^^^^^^^^^^^^^ + * A NodeId that allows the namespace URI to be specified instead of an index. */ +typedef struct { + UA_NodeId nodeId; + UA_String namespaceUri; + UA_UInt32 serverIndex; +} UA_ExpandedNodeId; + +UA_EXPORT extern const UA_ExpandedNodeId UA_EXPANDEDNODEID_NULL; + +/* Print the ExpandedNodeId in the humand-readable format defined in Part 6, + * 5.3.1.11: + * + * svr=;ns=;= + * or + * svr=;nsu=;= + * + * The definitions for svr, ns and nsu is omitted if zero / the empty string. + * + * The method can either use a pre-allocated string buffer or allocates memory + * internally if called with an empty output string. */ +UA_StatusCode UA_EXPORT +UA_ExpandedNodeId_print(const UA_ExpandedNodeId *id, UA_String *output); + +/* Parse the human-readable NodeId format. Attention! String and + * ByteString NodeIds have their identifier malloc'ed and need to be + * cleaned up. */ +#ifdef UA_ENABLE_PARSING +UA_StatusCode UA_EXPORT +UA_ExpandedNodeId_parse(UA_ExpandedNodeId *id, const UA_String str); + +UA_INLINABLE(UA_ExpandedNodeId + UA_EXPANDEDNODEID(const char *chars), { + UA_ExpandedNodeId id; + UA_ExpandedNodeId_parse(&id, UA_STRING((char*)(uintptr_t)chars)); + return id; +}) +#endif + +/** The following functions are shorthand for creating ExpandedNodeIds. */ +UA_INLINABLE(UA_ExpandedNodeId + UA_EXPANDEDNODEID_NUMERIC(UA_UInt16 nsIndex, UA_UInt32 identifier), { + UA_ExpandedNodeId id; id.nodeId = UA_NODEID_NUMERIC(nsIndex, identifier); + id.serverIndex = 0; id.namespaceUri = UA_STRING_NULL; return id; +}) + +UA_INLINABLE(UA_ExpandedNodeId + UA_EXPANDEDNODEID_STRING(UA_UInt16 nsIndex, char *chars), { + UA_ExpandedNodeId id; id.nodeId = UA_NODEID_STRING(nsIndex, chars); + id.serverIndex = 0; id.namespaceUri = UA_STRING_NULL; return id; +}) + +UA_INLINABLE(UA_ExpandedNodeId + UA_EXPANDEDNODEID_STRING_ALLOC(UA_UInt16 nsIndex, const char *chars), { + UA_ExpandedNodeId id; id.nodeId = UA_NODEID_STRING_ALLOC(nsIndex, chars); + id.serverIndex = 0; id.namespaceUri = UA_STRING_NULL; return id; +}) + +UA_INLINABLE(UA_ExpandedNodeId + UA_EXPANDEDNODEID_STRING_GUID(UA_UInt16 nsIndex, UA_Guid guid), { + UA_ExpandedNodeId id; id.nodeId = UA_NODEID_GUID(nsIndex, guid); + id.serverIndex = 0; id.namespaceUri = UA_STRING_NULL; return id; +}) + +UA_INLINABLE(UA_ExpandedNodeId + UA_EXPANDEDNODEID_BYTESTRING(UA_UInt16 nsIndex, char *chars), { + UA_ExpandedNodeId id; id.nodeId = UA_NODEID_BYTESTRING(nsIndex, chars); + id.serverIndex = 0; id.namespaceUri = UA_STRING_NULL; return id; +}) + +UA_INLINABLE(UA_ExpandedNodeId + UA_EXPANDEDNODEID_BYTESTRING_ALLOC(UA_UInt16 nsIndex, const char *chars), { + UA_ExpandedNodeId id; id.nodeId = UA_NODEID_BYTESTRING_ALLOC(nsIndex, chars); + id.serverIndex = 0; id.namespaceUri = UA_STRING_NULL; return id; +}) + +UA_INLINABLE(UA_ExpandedNodeId + UA_EXPANDEDNODEID_NODEID(UA_NodeId nodeId), { + UA_ExpandedNodeId id; memset(&id, 0, sizeof(UA_ExpandedNodeId)); + id.nodeId = nodeId; return id; +}) + +/* Does the ExpandedNodeId point to a local node? That is, are namespaceUri and + * serverIndex empty? */ +UA_Boolean UA_EXPORT +UA_ExpandedNodeId_isLocal(const UA_ExpandedNodeId *n); + +/* Total ordering of ExpandedNodeId */ +UA_Order UA_EXPORT +UA_ExpandedNodeId_order(const UA_ExpandedNodeId *n1, + const UA_ExpandedNodeId *n2); + +/* Returns a non-cryptographic hash for ExpandedNodeId. The hash of an + * ExpandedNodeId is identical to the hash of the embedded (simple) NodeId if + * the ServerIndex is zero and no NamespaceUri is set. */ +UA_UInt32 UA_EXPORT +UA_ExpandedNodeId_hash(const UA_ExpandedNodeId *n); + +/** + * .. _qualifiedname: + * + * QualifiedName + * ^^^^^^^^^^^^^ + * A name qualified by a namespace. */ +typedef struct { + UA_UInt16 namespaceIndex; + UA_String name; +} UA_QualifiedName; + +UA_INLINABLE(UA_Boolean + UA_QualifiedName_isNull(const UA_QualifiedName *q), { + return (q->namespaceIndex == 0 && q->name.length == 0); +}) + +/* Returns a non-cryptographic hash for QualifiedName */ +UA_UInt32 UA_EXPORT +UA_QualifiedName_hash(const UA_QualifiedName *q); + +UA_INLINABLE(UA_QualifiedName + UA_QUALIFIEDNAME(UA_UInt16 nsIndex, char *chars), { + UA_QualifiedName qn; + qn.namespaceIndex = nsIndex; + qn.name = UA_STRING(chars); + return qn; +}) + +UA_INLINABLE(UA_QualifiedName + UA_QUALIFIEDNAME_ALLOC(UA_UInt16 nsIndex, const char *chars), { + UA_QualifiedName qn; + qn.namespaceIndex = nsIndex; + qn.name = UA_STRING_ALLOC(chars); + return qn; +}) + +/** + * LocalizedText + * ^^^^^^^^^^^^^ + * Human readable text with an optional locale identifier. */ +typedef struct { + UA_String locale; + UA_String text; +} UA_LocalizedText; + +UA_INLINABLE(UA_LocalizedText + UA_LOCALIZEDTEXT(char *locale, char *text), { + UA_LocalizedText lt; + lt.locale = UA_STRING(locale); + lt.text = UA_STRING(text); + return lt; +}) + +UA_INLINABLE(UA_LocalizedText + UA_LOCALIZEDTEXT_ALLOC(const char *locale, const char *text), { + UA_LocalizedText lt; + lt.locale = UA_STRING_ALLOC(locale); + lt.text = UA_STRING_ALLOC(text); + return lt; +}) + +/** + * .. _numericrange: + * + * NumericRange + * ^^^^^^^^^^^^ + * + * NumericRanges are used to indicate subsets of a (multidimensional) array. + * They no official data type in the OPC UA standard and are transmitted only + * with a string encoding, such as "1:2,0:3,5". The colon separates min/max + * index and the comma separates dimensions. A single value indicates a range + * with a single element (min==max). */ +typedef struct { + UA_UInt32 min; + UA_UInt32 max; +} UA_NumericRangeDimension; + +typedef struct { + size_t dimensionsSize; + UA_NumericRangeDimension *dimensions; +} UA_NumericRange; + +UA_StatusCode UA_EXPORT +UA_NumericRange_parse(UA_NumericRange *range, const UA_String str); + +UA_INLINABLE(UA_NumericRange + UA_NUMERICRANGE(const char *s), { + UA_NumericRange nr; + memset(&nr, 0, sizeof(nr)); + UA_NumericRange_parse(&nr, UA_STRING((char*)(uintptr_t)s)); + return nr; +}) + +/** + * .. _variant: + * + * Variant + * ^^^^^^^ + * + * Variants may contain values of any type together with a description of the + * content. See the section on :ref:`generic-types` on how types are described. + * The standard mandates that variants contain built-in data types only. If the + * value is not of a builtin type, it is wrapped into an :ref:`extensionobject`. + * open62541 hides this wrapping transparently in the encoding layer. If the + * data type is unknown to the receiver, the variant contains the original + * ExtensionObject in binary or XML encoding. + * + * Variants may contain a scalar value or an array. For details on the handling + * of arrays, see the section on :ref:`array-handling`. Array variants can have + * an additional dimensionality (matrix, 3-tensor, ...) defined in an array of + * dimension lengths. The actual values are kept in an array of dimensions one. + * For users who work with higher-dimensions arrays directly, keep in mind that + * dimensions of higher rank are serialized first (the highest rank dimension + * has stride 1 and elements follow each other directly). Usually it is simplest + * to interact with higher-dimensional arrays via ``UA_NumericRange`` + * descriptions (see :ref:`array-handling`). + * + * To differentiate between scalar / array variants, the following definition is + * used. ``UA_Variant_isScalar`` provides simplified access to these checks. + * + * - ``arrayLength == 0 && data == NULL``: undefined array of length -1 + * - ``arrayLength == 0 && data == UA_EMPTY_ARRAY_SENTINEL``: array of length 0 + * - ``arrayLength == 0 && data > UA_EMPTY_ARRAY_SENTINEL``: scalar value + * - ``arrayLength > 0``: array of the given length + * + * Variants can also be *empty*. Then, the pointer to the type description is + * ``NULL``. */ +/* Forward declaration. See the section on Generic Type Handling */ +struct UA_DataType; +typedef struct UA_DataType UA_DataType; + +#define UA_EMPTY_ARRAY_SENTINEL ((void*)0x01) + +typedef enum { + UA_VARIANT_DATA, /* The data has the same lifecycle as the variant */ + UA_VARIANT_DATA_NODELETE /* The data is "borrowed" by the variant and is + * not deleted when the variant is cleared up. + * The array dimensions also borrowed. */ +} UA_VariantStorageType; + +typedef struct { + const UA_DataType *type; /* The data type description */ + UA_VariantStorageType storageType; + size_t arrayLength; /* The number of elements in the data array */ + void *data; /* Points to the scalar or array data */ + size_t arrayDimensionsSize; /* The number of dimensions */ + UA_UInt32 *arrayDimensions; /* The length of each dimension */ +} UA_Variant; + +/* Returns true if the variant has no value defined (contains neither an array + * nor a scalar value). + * + * @param v The variant + * @return Is the variant empty */ +UA_INLINABLE(UA_Boolean + UA_Variant_isEmpty(const UA_Variant *v), { + return v->type == NULL; +}) + +/* Returns true if the variant contains a scalar value. Note that empty variants + * contain an array of length -1 (undefined). + * + * @param v The variant + * @return Does the variant contain a scalar value */ +UA_INLINABLE(UA_Boolean + UA_Variant_isScalar(const UA_Variant *v), { + return (v->arrayLength == 0 && v->data > UA_EMPTY_ARRAY_SENTINEL); +}) + +/* Returns true if the variant contains a scalar value of the given type. + * + * @param v The variant + * @param type The data type + * @return Does the variant contain a scalar value of the given type */ +UA_INLINABLE(UA_Boolean + UA_Variant_hasScalarType(const UA_Variant *v, + const UA_DataType *type), { + return UA_Variant_isScalar(v) && type == v->type; +}) + +/* Returns true if the variant contains an array of the given type. + * + * @param v The variant + * @param type The data type + * @return Does the variant contain an array of the given type */ +UA_INLINABLE(UA_Boolean + UA_Variant_hasArrayType(const UA_Variant *v, + const UA_DataType *type), { + return (!UA_Variant_isScalar(v)) && type == v->type; +}) + +/* Set the variant to a scalar value that already resides in memory. The value + * takes on the lifecycle of the variant and is deleted with it. + * + * @param v The variant + * @param p A pointer to the value data + * @param type The datatype of the value in question */ +void UA_EXPORT +UA_Variant_setScalar(UA_Variant *v, void * UA_RESTRICT p, + const UA_DataType *type); + +/* Set the variant to a scalar value that is copied from an existing variable. + * @param v The variant + * @param p A pointer to the value data + * @param type The datatype of the value + * @return Indicates whether the operation succeeded or returns an error code */ +UA_StatusCode UA_EXPORT +UA_Variant_setScalarCopy(UA_Variant *v, const void * UA_RESTRICT p, + const UA_DataType *type); + +/* Set the variant to an array that already resides in memory. The array takes + * on the lifecycle of the variant and is deleted with it. + * + * @param v The variant + * @param array A pointer to the array data + * @param arraySize The size of the array + * @param type The datatype of the array */ +void UA_EXPORT +UA_Variant_setArray(UA_Variant *v, void * UA_RESTRICT array, + size_t arraySize, const UA_DataType *type); + +/* Set the variant to an array that is copied from an existing array. + * + * @param v The variant + * @param array A pointer to the array data + * @param arraySize The size of the array + * @param type The datatype of the array + * @return Indicates whether the operation succeeded or returns an error code */ +UA_StatusCode UA_EXPORT +UA_Variant_setArrayCopy(UA_Variant *v, const void * UA_RESTRICT array, + size_t arraySize, const UA_DataType *type); + +/* Copy the variant, but use only a subset of the (multidimensional) array into + * a variant. Returns an error code if the variant is not an array or if the + * indicated range does not fit. + * + * @param src The source variant + * @param dst The target variant + * @param range The range of the copied data + * @return Returns UA_STATUSCODE_GOOD or an error code */ +UA_StatusCode UA_EXPORT +UA_Variant_copyRange(const UA_Variant *src, UA_Variant * UA_RESTRICT dst, + const UA_NumericRange range); + +/* Insert a range of data into an existing variant. The data array cannot be + * reused afterwards if it contains types without a fixed size (e.g. strings) + * since the members are moved into the variant and take on its lifecycle. + * + * @param v The variant + * @param dataArray The data array. The type must match the variant + * @param dataArraySize The length of the data array. This is checked to match + * the range size. + * @param range The range of where the new data is inserted + * @return Returns UA_STATUSCODE_GOOD or an error code */ +UA_StatusCode UA_EXPORT +UA_Variant_setRange(UA_Variant *v, void * UA_RESTRICT array, + size_t arraySize, const UA_NumericRange range); + +/* Deep-copy a range of data into an existing variant. + * + * @param v The variant + * @param dataArray The data array. The type must match the variant + * @param dataArraySize The length of the data array. This is checked to match + * the range size. + * @param range The range of where the new data is inserted + * @return Returns UA_STATUSCODE_GOOD or an error code */ +UA_StatusCode UA_EXPORT +UA_Variant_setRangeCopy(UA_Variant *v, const void * UA_RESTRICT array, + size_t arraySize, const UA_NumericRange range); + +/** + * .. _extensionobject: + * + * ExtensionObject + * ^^^^^^^^^^^^^^^ + * + * ExtensionObjects may contain scalars of any data type. Even those that are + * unknown to the receiver. See the section on :ref:`generic-types` on how types + * are described. If the received data type is unknown, the encoded string and + * target NodeId is stored instead of the decoded value. */ +typedef enum { + UA_EXTENSIONOBJECT_ENCODED_NOBODY = 0, + UA_EXTENSIONOBJECT_ENCODED_BYTESTRING = 1, + UA_EXTENSIONOBJECT_ENCODED_XML = 2, + UA_EXTENSIONOBJECT_DECODED = 3, + UA_EXTENSIONOBJECT_DECODED_NODELETE = 4 /* Don't delete the content + together with the + ExtensionObject */ +} UA_ExtensionObjectEncoding; + +typedef struct { + UA_ExtensionObjectEncoding encoding; + union { + struct { + UA_NodeId typeId; /* The nodeid of the datatype */ + UA_ByteString body; /* The bytestring of the encoded data */ + } encoded; + struct { + const UA_DataType *type; + void *data; + } decoded; + } content; +} UA_ExtensionObject; + +/* Initialize the ExtensionObject and set the "decoded" value to the given + * pointer. The value will be deleted when the ExtensionObject is cleared. */ +void UA_EXPORT +UA_ExtensionObject_setValue(UA_ExtensionObject *eo, + void * UA_RESTRICT p, + const UA_DataType *type); + +/* Initialize the ExtensionObject and set the "decoded" value to the given + * pointer. The value will *not* be deleted when the ExtensionObject is + * cleared. */ +void UA_EXPORT +UA_ExtensionObject_setValueNoDelete(UA_ExtensionObject *eo, + void * UA_RESTRICT p, + const UA_DataType *type); + +/* Initialize the ExtensionObject and set the "decoded" value to a fresh copy of + * the given value pointer. The value will be deleted when the ExtensionObject + * is cleared. */ +UA_StatusCode UA_EXPORT +UA_ExtensionObject_setValueCopy(UA_ExtensionObject *eo, + void * UA_RESTRICT p, + const UA_DataType *type); + +/** + * .. _datavalue: + * + * DataValue + * ^^^^^^^^^ + * A data value with an associated status code and timestamps. */ +typedef struct { + UA_Variant value; + UA_DateTime sourceTimestamp; + UA_DateTime serverTimestamp; + UA_UInt16 sourcePicoseconds; + UA_UInt16 serverPicoseconds; + UA_StatusCode status; + UA_Boolean hasValue : 1; + UA_Boolean hasStatus : 1; + UA_Boolean hasSourceTimestamp : 1; + UA_Boolean hasServerTimestamp : 1; + UA_Boolean hasSourcePicoseconds : 1; + UA_Boolean hasServerPicoseconds : 1; +} UA_DataValue; + +/* Copy the DataValue, but use only a subset of the (multidimensional) array of + * of the variant of the source DataValue. Returns an error code if the variant + * of the DataValue is not an array or if the indicated range does not fit. + * + * @param src The source DataValue + * @param dst The target DataValue + * @param range The range of the variant of the DataValue to copy + * @return Returns UA_STATUSCODE_GOOD or an error code */ +UA_StatusCode UA_EXPORT +UA_DataValue_copyVariantRange(const UA_DataValue *src, UA_DataValue * UA_RESTRICT dst, + const UA_NumericRange range); + +/** + * DiagnosticInfo + * ^^^^^^^^^^^^^^ + * A structure that contains detailed error and diagnostic information + * associated with a StatusCode. */ +typedef struct UA_DiagnosticInfo { + UA_Boolean hasSymbolicId : 1; + UA_Boolean hasNamespaceUri : 1; + UA_Boolean hasLocalizedText : 1; + UA_Boolean hasLocale : 1; + UA_Boolean hasAdditionalInfo : 1; + UA_Boolean hasInnerStatusCode : 1; + UA_Boolean hasInnerDiagnosticInfo : 1; + UA_Int32 symbolicId; + UA_Int32 namespaceUri; + UA_Int32 localizedText; + UA_Int32 locale; + UA_String additionalInfo; + UA_StatusCode innerStatusCode; + struct UA_DiagnosticInfo *innerDiagnosticInfo; +} UA_DiagnosticInfo; + +/** + * .. _generic-types: + * + * Generic Type Handling + * --------------------- + * + * All information about a (builtin/structured) data type is stored in a + * ``UA_DataType``. The array ``UA_TYPES`` contains the description of all + * standard-defined types. This type description is used for the following + * generic operations that work on all types: + * + * - ``void T_init(T *ptr)``: Initialize the data type. This is synonymous with + * zeroing out the memory, i.e. ``memset(ptr, 0, sizeof(T))``. + * - ``T* T_new()``: Allocate and return the memory for the data type. The + * value is already initialized. + * - ``UA_StatusCode T_copy(const T *src, T *dst)``: Copy the content of the + * data type. Returns ``UA_STATUSCODE_GOOD`` or + * ``UA_STATUSCODE_BADOUTOFMEMORY``. + * - ``void T_clear(T *ptr)``: Delete the dynamically allocated content + * of the data type and perform a ``T_init`` to reset the type. + * - ``void T_delete(T *ptr)``: Delete the content of the data type and the + * memory for the data type itself. + * - ``void T_equal(T *p1, T *p2)``: Compare whether ``p1`` and ``p2`` have + * identical content. You can use ``UA_order`` if an absolute ordering + * is required. + * + * Specializations, such as ``UA_Int32_new()`` are derived from the generic + * type operations as static inline functions. */ + +typedef struct { +#ifdef UA_ENABLE_TYPEDESCRIPTION + const char *memberName; /* Human-readable member name */ +#endif + const UA_DataType *memberType;/* The member data type description */ + UA_Byte padding : 6; /* How much padding is there before this + member element? For arrays this is the + padding before the size_t length member. + (No padding between size_t and the + following ptr.) For unions, the padding + includes the size of the switchfield (the + offset from the start of the union + type). */ + UA_Byte isArray : 1; /* The member is an array */ + UA_Byte isOptional : 1; /* The member is an optional field */ +} UA_DataTypeMember; + +/* The DataType "kind" is an internal type classification. It is used to + * dispatch handling to the correct routines. */ +#define UA_DATATYPEKINDS 31 +typedef enum { + UA_DATATYPEKIND_BOOLEAN = 0, + UA_DATATYPEKIND_SBYTE = 1, + UA_DATATYPEKIND_BYTE = 2, + UA_DATATYPEKIND_INT16 = 3, + UA_DATATYPEKIND_UINT16 = 4, + UA_DATATYPEKIND_INT32 = 5, + UA_DATATYPEKIND_UINT32 = 6, + UA_DATATYPEKIND_INT64 = 7, + UA_DATATYPEKIND_UINT64 = 8, + UA_DATATYPEKIND_FLOAT = 9, + UA_DATATYPEKIND_DOUBLE = 10, + UA_DATATYPEKIND_STRING = 11, + UA_DATATYPEKIND_DATETIME = 12, + UA_DATATYPEKIND_GUID = 13, + UA_DATATYPEKIND_BYTESTRING = 14, + UA_DATATYPEKIND_XMLELEMENT = 15, + UA_DATATYPEKIND_NODEID = 16, + UA_DATATYPEKIND_EXPANDEDNODEID = 17, + UA_DATATYPEKIND_STATUSCODE = 18, + UA_DATATYPEKIND_QUALIFIEDNAME = 19, + UA_DATATYPEKIND_LOCALIZEDTEXT = 20, + UA_DATATYPEKIND_EXTENSIONOBJECT = 21, + UA_DATATYPEKIND_DATAVALUE = 22, + UA_DATATYPEKIND_VARIANT = 23, + UA_DATATYPEKIND_DIAGNOSTICINFO = 24, + UA_DATATYPEKIND_DECIMAL = 25, + UA_DATATYPEKIND_ENUM = 26, + UA_DATATYPEKIND_STRUCTURE = 27, + UA_DATATYPEKIND_OPTSTRUCT = 28, /* struct with optional fields */ + UA_DATATYPEKIND_UNION = 29, + UA_DATATYPEKIND_BITFIELDCLUSTER = 30 /* bitfields + padding */ +} UA_DataTypeKind; + +struct UA_DataType { +#ifdef UA_ENABLE_TYPEDESCRIPTION + const char *typeName; +#endif + UA_NodeId typeId; /* The nodeid of the type */ + UA_NodeId binaryEncodingId; /* NodeId of datatype when encoded as binary */ + //UA_NodeId xmlEncodingId; /* NodeId of datatype when encoded as XML */ + UA_UInt32 memSize : 16; /* Size of the struct in memory */ + UA_UInt32 typeKind : 6; /* Dispatch index for the handling routines */ + UA_UInt32 pointerFree : 1; /* The type (and its members) contains no + * pointers that need to be freed */ + UA_UInt32 overlayable : 1; /* The type has the identical memory layout + * in memory and on the binary stream. */ + UA_UInt32 membersSize : 8; /* How many members does the type have? */ + UA_DataTypeMember *members; +}; + +/* Datatype arrays with custom type definitions can be added in a linked list to + * the client or server configuration. */ +typedef struct UA_DataTypeArray { + const struct UA_DataTypeArray *next; + const size_t typesSize; + const UA_DataType *types; + UA_Boolean cleanup; /* Free the array structure and its content + when the client or server configuration + containing it is cleaned up */ +} UA_DataTypeArray; + +/* Returns the offset and type of a structure member. The return value is false + * if the member was not found. + * + * If the member is an array, the offset points to the (size_t) length field. + * (The array pointer comes after the length field without any padding.) */ +#ifdef UA_ENABLE_TYPEDESCRIPTION +UA_Boolean UA_EXPORT +UA_DataType_getStructMember(const UA_DataType *type, + const char *memberName, + size_t *outOffset, + const UA_DataType **outMemberType, + UA_Boolean *outIsArray); +#endif + +/* Test if the data type is a numeric builtin data type (via the typeKind field + * of UA_DataType). This includes integers and floating point numbers. Not + * included are Boolean, DateTime, StatusCode and Enums. */ +UA_Boolean UA_EXPORT +UA_DataType_isNumeric(const UA_DataType *type); + +/** + * Builtin data types can be accessed as UA_TYPES[UA_TYPES_XXX], where XXX is + * the name of the data type. If only the NodeId of a type is known, use the + * following method to retrieve the data type description. */ + +/* Returns the data type description for the type's identifier or NULL if no + * matching data type was found. */ +const UA_DataType UA_EXPORT * +UA_findDataType(const UA_NodeId *typeId); + +/* + * Add custom data types to the search scope of UA_findDataType. */ + +const UA_DataType UA_EXPORT * +UA_findDataTypeWithCustom(const UA_NodeId *typeId, + const UA_DataTypeArray *customTypes); + +/** The following functions are used for generic handling of data types. */ + +/* Allocates and initializes a variable of type dataType + * + * @param type The datatype description + * @return Returns the memory location of the variable or NULL if no + * memory could be allocated */ +void UA_EXPORT * UA_new(const UA_DataType *type) UA_FUNC_ATTR_MALLOC; + +/* Initializes a variable to default values + * + * @param p The memory location of the variable + * @param type The datatype description */ +UA_INLINABLE(void + UA_init(void *p, const UA_DataType *type), { + memset(p, 0, type->memSize); +}) + +/* Copies the content of two variables. If copying fails (e.g. because no memory + * was available for an array), then dst is emptied and initialized to prevent + * memory leaks. + * + * @param src The memory location of the source variable + * @param dst The memory location of the destination variable + * @param type The datatype description + * @return Indicates whether the operation succeeded or returns an error code */ +UA_StatusCode UA_EXPORT +UA_copy(const void *src, void *dst, const UA_DataType *type); + +/* Deletes the dynamically allocated content of a variable (e.g. resets all + * arrays to undefined arrays). Afterwards, the variable can be safely deleted + * without causing memory leaks. But the variable is not initialized and may + * contain old data that is not memory-relevant. + * + * @param p The memory location of the variable + * @param type The datatype description of the variable */ +void UA_EXPORT UA_clear(void *p, const UA_DataType *type); + +#define UA_deleteMembers(p, type) UA_clear(p, type) + +/* Frees a variable and all of its content. + * + * @param p The memory location of the variable + * @param type The datatype description of the variable */ +void UA_EXPORT UA_delete(void *p, const UA_DataType *type); + +/* Pretty-print the value from the datatype. The output is pretty-printed JSON5. + * Note that this format is non-standard and should not be sent over the + * network. It can however be read by our own JSON decoding. + * + * @param p The memory location of the variable + * @param type The datatype description of the variable + * @param output A string that is used for the pretty-printed output. If the + * memory for string is already allocated, we try to use the existing + * string (the length is adjusted). If the string is empty, memory + * is allocated for it. + * @return Indicates whether the operation succeeded */ +#ifdef UA_ENABLE_JSON_ENCODING +UA_StatusCode UA_EXPORT +UA_print(const void *p, const UA_DataType *type, UA_String *output); +#endif + +/* Compare two values and return their order. + * + * For numerical types (including StatusCodes and Enums), their natural order is + * used. NaN is the "smallest" value for floating point values. Different bit + * representations of NaN are considered identical. + * + * All other types have *some* absolute ordering so that a < b, b < c -> a < c. + * + * The ordering of arrays (also strings) is in "shortlex": A shorter array is + * always smaller than a longer array. Otherwise the first different element + * defines the order. + * + * When members of different types are permitted (in Variants and + * ExtensionObjects), the memory address in the "UA_DataType*" pointer + * determines which variable is smaller. + * + * @param p1 The memory location of the first value + * @param p2 The memory location of the first value + * @param type The datatype description of both values */ +UA_Order UA_EXPORT +UA_order(const void *p1, const void *p2, const UA_DataType *type); + +/* Compare if two values have identical content. */ +UA_INLINABLE(UA_Boolean + UA_equal(const void *p1, const void *p2, const UA_DataType *type), { + return (UA_order(p1, p2, type) == UA_ORDER_EQ); +}) + +/** + * Binary Encoding/Decoding + * ------------------------ + * + * Encoding and decoding routines for the binary format. For the binary decoding + * additional data types can be forwarded. */ + +/* Returns the number of bytes the value p takes in binary encoding. Returns + * zero if an error occurs. */ +UA_EXPORT size_t +UA_calcSizeBinary(const void *p, const UA_DataType *type); + +/* Encodes a data-structure in the binary format. If outBuf has a length of + * zero, a buffer of the required size is allocated. Otherwise, encoding into + * the existing outBuf is attempted (and may fail if the buffer is too + * small). */ +UA_EXPORT UA_StatusCode +UA_encodeBinary(const void *p, const UA_DataType *type, + UA_ByteString *outBuf); + +/* The structure with the decoding options may be extended in the future. + * Zero-out the entire structure initially to ensure code-compatibility when + * more fields are added in a later release. */ +typedef struct { + const UA_DataTypeArray *customTypes; /* Begin of a linked list with custom + * datatype definitions */ +} UA_DecodeBinaryOptions; + +/* Decodes a data structure from the input buffer in the binary format. It is + * assumed that `p` points to valid memory (not necessarily zeroed out). The + * options can be NULL and will be disregarded in that case. */ +UA_EXPORT UA_StatusCode +UA_decodeBinary(const UA_ByteString *inBuf, + void *p, const UA_DataType *type, + const UA_DecodeBinaryOptions *options); + +/** + * JSON En/Decoding + * ---------------- + * + * The JSON decoding can parse the official encoding from the OPC UA + * specification. It further allows the following extensions: + * + * - The strict JSON format is relaxed to also allow the JSON5 extensions + * (https://json5.org/). This allows for more human-readable encoding and adds + * convenience features such as trailing commas in arrays and comments within + * JSON documents. + * - Int64/UInt64 don't necessarily have to be wrapped into a string. + * - If `UA_ENABLE_PARSING` is set, NodeIds and ExpandedNodeIds can be given in + * the string encoding (e.g. "ns=1;i=42", see `UA_NodeId_parse`). The standard + * encoding is to express NodeIds as JSON objects. + * + * These extensions are not intended to be used for the OPC UA protocol on the + * network. They were rather added to allow more convenient configuration file + * formats that also include data in the OPC UA type system. + */ + +#ifdef UA_ENABLE_JSON_ENCODING + +typedef struct { + const UA_String *namespaces; + size_t namespacesSize; + const UA_String *serverUris; + size_t serverUrisSize; + UA_Boolean useReversible; + + UA_Boolean prettyPrint; /* Add newlines and spaces for legibility */ + + /* Enabling the following options leads to non-standard compatible JSON5 + * encoding! Use it for pretty-printing, but not for sending messages over + * the network. (Our own decoding can still parse it.) */ + + UA_Boolean unquotedKeys; /* Don't print quotes around object element keys */ + UA_Boolean stringNodeIds; /* String encoding for NodeIds, like "ns=1;i=42" */ +} UA_EncodeJsonOptions; + +/* Returns the number of bytes the value src takes in json encoding. Returns + * zero if an error occurs. */ +UA_EXPORT size_t +UA_calcSizeJson(const void *src, const UA_DataType *type, + const UA_EncodeJsonOptions *options); + +/* Encodes the scalar value described by type to json encoding. + * + * @param src The value. Must not be NULL. + * @param type The value type. Must not be NULL. + * @param outBuf Pointer to ByteString containing the result if the encoding + * was successful + * @return Returns a statuscode whether encoding succeeded. */ +UA_StatusCode UA_EXPORT +UA_encodeJson(const void *src, const UA_DataType *type, UA_ByteString *outBuf, + const UA_EncodeJsonOptions *options); + +/* The structure with the decoding options may be extended in the future. + * Zero-out the entire structure initially to ensure code-compatibility when + * more fields are added in a later release. */ +typedef struct { + const UA_String *namespaces; + size_t namespacesSize; + const UA_String *serverUris; + size_t serverUrisSize; + const UA_DataTypeArray *customTypes; /* Begin of a linked list with custom + * datatype definitions */ +} UA_DecodeJsonOptions; + +/* Decodes a scalar value described by type from json encoding. + * + * @param src The buffer with the json encoded value. Must not be NULL. + * @param dst The target value. Must not be NULL. The target is assumed to have + * size type->memSize. The value is reset to zero before decoding. If + * decoding fails, members are deleted and the value is reset (zeroed) + * again. + * @param type The value type. Must not be NULL. + * @param options The options struct for decoding, currently unused + * @return Returns a statuscode whether decoding succeeded. */ +UA_StatusCode UA_EXPORT +UA_decodeJson(const UA_ByteString *src, void *dst, const UA_DataType *type, + const UA_DecodeJsonOptions *options); + +#endif /* UA_ENABLE_JSON_ENCODING */ + +/** + * XML En/Decoding + * ---------------- + * + * The XML decoding can parse the official encoding from the OPC UA + * specification. + * + * These extensions are not intended to be used for the OPC UA protocol on the + * network. They were rather added to allow more convenient configuration file + * formats that also include data in the OPC UA type system. + */ + +#ifdef UA_ENABLE_XML_ENCODING + +typedef struct { + UA_Boolean prettyPrint; /* Add newlines and spaces for legibility */ +} UA_EncodeXmlOptions; + +/* Returns the number of bytes the value src takes in xml encoding. Returns + * zero if an error occurs. */ +UA_EXPORT size_t +UA_calcSizeXml(const void *src, const UA_DataType *type, + const UA_EncodeXmlOptions *options); + +/* Encodes the scalar value described by type to xml encoding. + * + * @param src The value. Must not be NULL. + * @param type The value type. Must not be NULL. + * @param outBuf Pointer to ByteString containing the result if the encoding + * was successful + * @return Returns a statuscode whether encoding succeeded. */ +UA_StatusCode UA_EXPORT +UA_encodeXml(const void *src, const UA_DataType *type, UA_ByteString *outBuf, + const UA_EncodeXmlOptions *options); + +/* The structure with the decoding options may be extended in the future. + * Zero-out the entire structure initially to ensure code-compatibility when + * more fields are added in a later release. */ +typedef struct { + const UA_DataTypeArray *customTypes; /* Begin of a linked list with custom + * datatype definitions */ +} UA_DecodeXmlOptions; + +/* Decodes a scalar value described by type from xml encoding. + * + * @param src The buffer with the xml encoded value. Must not be NULL. + * @param dst The target value. Must not be NULL. The target is assumed to have + * size type->memSize. The value is reset to zero before decoding. If + * decoding fails, members are deleted and the value is reset (zeroed) + * again. + * @param type The value type. Must not be NULL. + * @param options The options struct for decoding, currently unused + * @return Returns a statuscode whether decoding succeeded. */ +UA_StatusCode UA_EXPORT +UA_decodeXml(const UA_ByteString *src, void *dst, const UA_DataType *type, + const UA_DecodeXmlOptions *options); + +#endif /* UA_ENABLE_XML_ENCODING */ + +/** + * .. _array-handling: + * + * Array handling + * -------------- + * In OPC UA, arrays can have a length of zero or more with the usual meaning. + * In addition, arrays can be undefined. Then, they don't even have a length. In + * the binary encoding, this is indicated by an array of length -1. + * + * In open62541 however, we use ``size_t`` for array lengths. An undefined array + * has length 0 and the data pointer is ``NULL``. An array of length 0 also has + * length 0 but a data pointer ``UA_EMPTY_ARRAY_SENTINEL``. */ + +/* Allocates and initializes an array of variables of a specific type + * + * @param size The requested array length + * @param type The datatype description + * @return Returns the memory location of the variable or NULL if no memory + * could be allocated */ +void UA_EXPORT * +UA_Array_new(size_t size, const UA_DataType *type) UA_FUNC_ATTR_MALLOC; + +/* Allocates and copies an array + * + * @param src The memory location of the source array + * @param size The size of the array + * @param dst The location of the pointer to the new array + * @param type The datatype of the array members + * @return Returns UA_STATUSCODE_GOOD or UA_STATUSCODE_BADOUTOFMEMORY */ +UA_StatusCode UA_EXPORT +UA_Array_copy(const void *src, size_t size, void **dst, + const UA_DataType *type) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + +/* Resizes (and reallocates) an array. The last entries are initialized to zero + * if the array length is increased. If the array length is decreased, the last + * entries are removed if the size is decreased. + * + * @param p Double pointer to the array memory. Can be overwritten by the result + * of a realloc. + * @param size The current size of the array. Overwritten in case of success. + * @param newSize The new size of the array + * @param type The datatype of the array members + * @return Returns UA_STATUSCODE_GOOD or UA_STATUSCODE_BADOUTOFMEMORY. The + * original array is left untouched in the failure case. */ +UA_StatusCode UA_EXPORT +UA_Array_resize(void **p, size_t *size, size_t newSize, + const UA_DataType *type) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + +/* Append the given element at the end of the array. The content is moved + * (shallow copy) and the original memory is _init'ed if appending is + * successful. + * + * @param p Double pointer to the array memory. Can be overwritten by the result + * of a realloc. + * @param size The current size of the array. Overwritten in case of success. + * @param newElem The element to be appended. The memory is reset upon success. + * @param type The datatype of the array members + * @return Returns UA_STATUSCODE_GOOD or UA_STATUSCODE_BADOUTOFMEMORY. The + * original array is left untouched in the failure case. */ +UA_StatusCode UA_EXPORT +UA_Array_append(void **p, size_t *size, void *newElem, + const UA_DataType *type) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + +/* Append a copy of the given element at the end of the array. + * + * @param p Double pointer to the array memory. Can be overwritten by the result + * of a realloc. + * @param size The current size of the array. Overwritten in case of success. + * @param newElem The element to be appended. + * @param type The datatype of the array members + * @return Returns UA_STATUSCODE_GOOD or UA_STATUSCODE_BADOUTOFMEMORY. The + * original array is left untouched in the failure case. */ + +UA_StatusCode UA_EXPORT +UA_Array_appendCopy(void **p, size_t *size, const void *newElem, + const UA_DataType *type) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + +/* Deletes an array. + * + * @param p The memory location of the array + * @param size The size of the array + * @param type The datatype of the array members */ +void UA_EXPORT +UA_Array_delete(void *p, size_t size, const UA_DataType *type); + +/** + * .. _generated-types: + * + * Generated Data Type Definitions + * ------------------------------- + * + * The following standard-defined datatypes are auto-generated from XML files + * that are part of the OPC UA standard. All datatypes are built up from the 25 + * builtin-in datatypes from the :ref:`types` section. + * + * .. include:: types_generated.rst */ + +/* stop-doc-generation */ + +/* Helper used to exclude type names in the definition of UA_DataType structures + * if the feature is disabled. */ +#ifdef UA_ENABLE_TYPEDESCRIPTION +# define UA_TYPENAME(name) name, +#else +# define UA_TYPENAME(name) +#endif + +#include +#include + +_UA_END_DECLS + +#endif /* UA_TYPES_H_ */ diff --git a/product/src/fes/include/open62541/types_generated.h b/product/src/fes/include/open62541/types_generated.h new file mode 100644 index 00000000..bebe345f --- /dev/null +++ b/product/src/fes/include/open62541/types_generated.h @@ -0,0 +1,4134 @@ +/********************************** + * Autogenerated -- do not modify * + **********************************/ + +/* Must be before the include guards */ +#ifdef UA_ENABLE_AMALGAMATION +# include "open62541.h" +#else +# include +#endif + +#ifndef TYPES_GENERATED_H_ +#define TYPES_GENERATED_H_ + + +_UA_BEGIN_DECLS + +/** + * Every type is assigned an index in an array containing the type descriptions. + * These descriptions are used during type handling (copying, deletion, + * binary encoding, ...). */ +#define UA_TYPES_COUNT 388 +extern UA_EXPORT UA_DataType UA_TYPES[UA_TYPES_COUNT]; + +/* Boolean */ +#define UA_TYPES_BOOLEAN 0 + +/* SByte */ +#define UA_TYPES_SBYTE 1 + +/* Byte */ +#define UA_TYPES_BYTE 2 + +/* Int16 */ +#define UA_TYPES_INT16 3 + +/* UInt16 */ +#define UA_TYPES_UINT16 4 + +/* Int32 */ +#define UA_TYPES_INT32 5 + +/* UInt32 */ +#define UA_TYPES_UINT32 6 + +/* Int64 */ +#define UA_TYPES_INT64 7 + +/* UInt64 */ +#define UA_TYPES_UINT64 8 + +/* Float */ +#define UA_TYPES_FLOAT 9 + +/* Double */ +#define UA_TYPES_DOUBLE 10 + +/* String */ +#define UA_TYPES_STRING 11 + +/* DateTime */ +#define UA_TYPES_DATETIME 12 + +/* Guid */ +#define UA_TYPES_GUID 13 + +/* ByteString */ +#define UA_TYPES_BYTESTRING 14 + +/* XmlElement */ +#define UA_TYPES_XMLELEMENT 15 + +/* NodeId */ +#define UA_TYPES_NODEID 16 + +/* ExpandedNodeId */ +#define UA_TYPES_EXPANDEDNODEID 17 + +/* StatusCode */ +#define UA_TYPES_STATUSCODE 18 + +/* QualifiedName */ +#define UA_TYPES_QUALIFIEDNAME 19 + +/* LocalizedText */ +#define UA_TYPES_LOCALIZEDTEXT 20 + +/* ExtensionObject */ +#define UA_TYPES_EXTENSIONOBJECT 21 + +/* DataValue */ +#define UA_TYPES_DATAVALUE 22 + +/* Variant */ +#define UA_TYPES_VARIANT 23 + +/* DiagnosticInfo */ +#define UA_TYPES_DIAGNOSTICINFO 24 + +/* NamingRuleType */ +typedef enum { + UA_NAMINGRULETYPE_MANDATORY = 1, + UA_NAMINGRULETYPE_OPTIONAL = 2, + UA_NAMINGRULETYPE_CONSTRAINT = 3, + __UA_NAMINGRULETYPE_FORCE32BIT = 0x7fffffff +} UA_NamingRuleType; + +UA_STATIC_ASSERT(sizeof(UA_NamingRuleType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_NAMINGRULETYPE 25 + +/* Enumeration */ +typedef enum { + __UA_ENUMERATION_FORCE32BIT = 0x7fffffff +} UA_Enumeration; + +UA_STATIC_ASSERT(sizeof(UA_Enumeration) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_ENUMERATION 26 + +/* ImageBMP */ +typedef UA_ByteString UA_ImageBMP; + +#define UA_TYPES_IMAGEBMP 27 + +/* ImageGIF */ +typedef UA_ByteString UA_ImageGIF; + +#define UA_TYPES_IMAGEGIF 28 + +/* ImageJPG */ +typedef UA_ByteString UA_ImageJPG; + +#define UA_TYPES_IMAGEJPG 29 + +/* ImagePNG */ +typedef UA_ByteString UA_ImagePNG; + +#define UA_TYPES_IMAGEPNG 30 + +/* AudioDataType */ +typedef UA_ByteString UA_AudioDataType; + +#define UA_TYPES_AUDIODATATYPE 31 + +/* UriString */ +typedef UA_String UA_UriString; + +#define UA_TYPES_URISTRING 32 + +/* BitFieldMaskDataType */ +typedef UA_UInt64 UA_BitFieldMaskDataType; + +#define UA_TYPES_BITFIELDMASKDATATYPE 33 + +/* SemanticVersionString */ +typedef UA_String UA_SemanticVersionString; + +#define UA_TYPES_SEMANTICVERSIONSTRING 34 + +/* KeyValuePair */ +typedef struct { + UA_QualifiedName key; + UA_Variant value; +} UA_KeyValuePair; + +#define UA_TYPES_KEYVALUEPAIR 35 + +/* AdditionalParametersType */ +typedef struct { + size_t parametersSize; + UA_KeyValuePair *parameters; +} UA_AdditionalParametersType; + +#define UA_TYPES_ADDITIONALPARAMETERSTYPE 36 + +/* EphemeralKeyType */ +typedef struct { + UA_ByteString publicKey; + UA_ByteString signature; +} UA_EphemeralKeyType; + +#define UA_TYPES_EPHEMERALKEYTYPE 37 + +/* RationalNumber */ +typedef struct { + UA_Int32 numerator; + UA_UInt32 denominator; +} UA_RationalNumber; + +#define UA_TYPES_RATIONALNUMBER 38 + +/* ThreeDVector */ +typedef struct { + UA_Double x; + UA_Double y; + UA_Double z; +} UA_ThreeDVector; + +#define UA_TYPES_THREEDVECTOR 39 + +/* ThreeDCartesianCoordinates */ +typedef struct { + UA_Double x; + UA_Double y; + UA_Double z; +} UA_ThreeDCartesianCoordinates; + +#define UA_TYPES_THREEDCARTESIANCOORDINATES 40 + +/* ThreeDOrientation */ +typedef struct { + UA_Double a; + UA_Double b; + UA_Double c; +} UA_ThreeDOrientation; + +#define UA_TYPES_THREEDORIENTATION 41 + +/* ThreeDFrame */ +typedef struct { + UA_ThreeDCartesianCoordinates cartesianCoordinates; + UA_ThreeDOrientation orientation; +} UA_ThreeDFrame; + +#define UA_TYPES_THREEDFRAME 42 + +/* OpenFileMode */ +typedef enum { + UA_OPENFILEMODE_READ = 1, + UA_OPENFILEMODE_WRITE = 2, + UA_OPENFILEMODE_ERASEEXISTING = 4, + UA_OPENFILEMODE_APPEND = 8, + __UA_OPENFILEMODE_FORCE32BIT = 0x7fffffff +} UA_OpenFileMode; + +UA_STATIC_ASSERT(sizeof(UA_OpenFileMode) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_OPENFILEMODE 43 + +/* IdentityCriteriaType */ +typedef enum { + UA_IDENTITYCRITERIATYPE_USERNAME = 1, + UA_IDENTITYCRITERIATYPE_THUMBPRINT = 2, + UA_IDENTITYCRITERIATYPE_ROLE = 3, + UA_IDENTITYCRITERIATYPE_GROUPID = 4, + UA_IDENTITYCRITERIATYPE_ANONYMOUS = 5, + UA_IDENTITYCRITERIATYPE_AUTHENTICATEDUSER = 6, + UA_IDENTITYCRITERIATYPE_APPLICATION = 7, + UA_IDENTITYCRITERIATYPE_X509SUBJECT = 8, + __UA_IDENTITYCRITERIATYPE_FORCE32BIT = 0x7fffffff +} UA_IdentityCriteriaType; + +UA_STATIC_ASSERT(sizeof(UA_IdentityCriteriaType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_IDENTITYCRITERIATYPE 44 + +/* IdentityMappingRuleType */ +typedef struct { + UA_IdentityCriteriaType criteriaType; + UA_String criteria; +} UA_IdentityMappingRuleType; + +#define UA_TYPES_IDENTITYMAPPINGRULETYPE 45 + +/* CurrencyUnitType */ +typedef struct { + UA_Int16 numericCode; + UA_SByte exponent; + UA_String alphabeticCode; + UA_LocalizedText currency; +} UA_CurrencyUnitType; + +#define UA_TYPES_CURRENCYUNITTYPE 46 + +/* TrustListMasks */ +typedef enum { + UA_TRUSTLISTMASKS_NONE = 0, + UA_TRUSTLISTMASKS_TRUSTEDCERTIFICATES = 1, + UA_TRUSTLISTMASKS_TRUSTEDCRLS = 2, + UA_TRUSTLISTMASKS_ISSUERCERTIFICATES = 4, + UA_TRUSTLISTMASKS_ISSUERCRLS = 8, + UA_TRUSTLISTMASKS_ALL = 15, + __UA_TRUSTLISTMASKS_FORCE32BIT = 0x7fffffff +} UA_TrustListMasks; + +UA_STATIC_ASSERT(sizeof(UA_TrustListMasks) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_TRUSTLISTMASKS 47 + +/* TrustListDataType */ +typedef struct { + UA_UInt32 specifiedLists; + size_t trustedCertificatesSize; + UA_ByteString *trustedCertificates; + size_t trustedCrlsSize; + UA_ByteString *trustedCrls; + size_t issuerCertificatesSize; + UA_ByteString *issuerCertificates; + size_t issuerCrlsSize; + UA_ByteString *issuerCrls; +} UA_TrustListDataType; + +#define UA_TYPES_TRUSTLISTDATATYPE 48 + +/* DecimalDataType */ +typedef struct { + UA_Int16 scale; + UA_ByteString value; +} UA_DecimalDataType; + +#define UA_TYPES_DECIMALDATATYPE 49 + +/* DataTypeDescription */ +typedef struct { + UA_NodeId dataTypeId; + UA_QualifiedName name; +} UA_DataTypeDescription; + +#define UA_TYPES_DATATYPEDESCRIPTION 50 + +/* SimpleTypeDescription */ +typedef struct { + UA_NodeId dataTypeId; + UA_QualifiedName name; + UA_NodeId baseDataType; + UA_Byte builtInType; +} UA_SimpleTypeDescription; + +#define UA_TYPES_SIMPLETYPEDESCRIPTION 51 + +/* PortableQualifiedName */ +typedef struct { + UA_String namespaceUri; + UA_String name; +} UA_PortableQualifiedName; + +#define UA_TYPES_PORTABLEQUALIFIEDNAME 52 + +/* PortableNodeId */ +typedef struct { + UA_String namespaceUri; + UA_NodeId identifier; +} UA_PortableNodeId; + +#define UA_TYPES_PORTABLENODEID 53 + +/* UnsignedRationalNumber */ +typedef struct { + UA_UInt32 numerator; + UA_UInt32 denominator; +} UA_UnsignedRationalNumber; + +#define UA_TYPES_UNSIGNEDRATIONALNUMBER 54 + +/* PubSubState */ +typedef enum { + UA_PUBSUBSTATE_DISABLED = 0, + UA_PUBSUBSTATE_PAUSED = 1, + UA_PUBSUBSTATE_OPERATIONAL = 2, + UA_PUBSUBSTATE_ERROR = 3, + UA_PUBSUBSTATE_PREOPERATIONAL = 4, + __UA_PUBSUBSTATE_FORCE32BIT = 0x7fffffff +} UA_PubSubState; + +UA_STATIC_ASSERT(sizeof(UA_PubSubState) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_PUBSUBSTATE 55 + +/* DataSetFieldFlags */ +typedef UA_UInt16 UA_DataSetFieldFlags; + +#define UA_DATASETFIELDFLAGS_NONE 0 +#define UA_DATASETFIELDFLAGS_PROMOTEDFIELD 1 + +#define UA_TYPES_DATASETFIELDFLAGS 56 + +/* ConfigurationVersionDataType */ +typedef struct { + UA_UInt32 majorVersion; + UA_UInt32 minorVersion; +} UA_ConfigurationVersionDataType; + +#define UA_TYPES_CONFIGURATIONVERSIONDATATYPE 57 + +/* PublishedVariableDataType */ +typedef struct { + UA_NodeId publishedVariable; + UA_UInt32 attributeId; + UA_Double samplingIntervalHint; + UA_UInt32 deadbandType; + UA_Double deadbandValue; + UA_String indexRange; + UA_Variant substituteValue; + size_t metaDataPropertiesSize; + UA_QualifiedName *metaDataProperties; +} UA_PublishedVariableDataType; + +#define UA_TYPES_PUBLISHEDVARIABLEDATATYPE 58 + +/* PublishedDataItemsDataType */ +typedef struct { + size_t publishedDataSize; + UA_PublishedVariableDataType *publishedData; +} UA_PublishedDataItemsDataType; + +#define UA_TYPES_PUBLISHEDDATAITEMSDATATYPE 59 + +/* PublishedDataSetCustomSourceDataType */ +typedef struct { + UA_Boolean cyclicDataSet; +} UA_PublishedDataSetCustomSourceDataType; + +#define UA_TYPES_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE 60 + +/* DataSetFieldContentMask */ +typedef UA_UInt32 UA_DataSetFieldContentMask; + +#define UA_DATASETFIELDCONTENTMASK_NONE 0 +#define UA_DATASETFIELDCONTENTMASK_STATUSCODE 1 +#define UA_DATASETFIELDCONTENTMASK_SOURCETIMESTAMP 2 +#define UA_DATASETFIELDCONTENTMASK_SERVERTIMESTAMP 4 +#define UA_DATASETFIELDCONTENTMASK_SOURCEPICOSECONDS 8 +#define UA_DATASETFIELDCONTENTMASK_SERVERPICOSECONDS 16 +#define UA_DATASETFIELDCONTENTMASK_RAWDATA 32 + +#define UA_TYPES_DATASETFIELDCONTENTMASK 61 + +/* DataSetWriterDataType */ +typedef struct { + UA_String name; + UA_Boolean enabled; + UA_UInt16 dataSetWriterId; + UA_DataSetFieldContentMask dataSetFieldContentMask; + UA_UInt32 keyFrameCount; + UA_String dataSetName; + size_t dataSetWriterPropertiesSize; + UA_KeyValuePair *dataSetWriterProperties; + UA_ExtensionObject transportSettings; + UA_ExtensionObject messageSettings; +} UA_DataSetWriterDataType; + +#define UA_TYPES_DATASETWRITERDATATYPE 62 + +/* NetworkAddressDataType */ +typedef struct { + UA_String networkInterface; +} UA_NetworkAddressDataType; + +#define UA_TYPES_NETWORKADDRESSDATATYPE 63 + +/* NetworkAddressUrlDataType */ +typedef struct { + UA_String networkInterface; + UA_String url; +} UA_NetworkAddressUrlDataType; + +#define UA_TYPES_NETWORKADDRESSURLDATATYPE 64 + +/* OverrideValueHandling */ +typedef enum { + UA_OVERRIDEVALUEHANDLING_DISABLED = 0, + UA_OVERRIDEVALUEHANDLING_LASTUSABLEVALUE = 1, + UA_OVERRIDEVALUEHANDLING_OVERRIDEVALUE = 2, + __UA_OVERRIDEVALUEHANDLING_FORCE32BIT = 0x7fffffff +} UA_OverrideValueHandling; + +UA_STATIC_ASSERT(sizeof(UA_OverrideValueHandling) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_OVERRIDEVALUEHANDLING 65 + +/* StandaloneSubscribedDataSetRefDataType */ +typedef struct { + UA_String dataSetName; +} UA_StandaloneSubscribedDataSetRefDataType; + +#define UA_TYPES_STANDALONESUBSCRIBEDDATASETREFDATATYPE 66 + +/* DataSetOrderingType */ +typedef enum { + UA_DATASETORDERINGTYPE_UNDEFINED = 0, + UA_DATASETORDERINGTYPE_ASCENDINGWRITERID = 1, + UA_DATASETORDERINGTYPE_ASCENDINGWRITERIDSINGLE = 2, + __UA_DATASETORDERINGTYPE_FORCE32BIT = 0x7fffffff +} UA_DataSetOrderingType; + +UA_STATIC_ASSERT(sizeof(UA_DataSetOrderingType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_DATASETORDERINGTYPE 67 + +/* UadpNetworkMessageContentMask */ +typedef UA_UInt32 UA_UadpNetworkMessageContentMask; + +#define UA_UADPNETWORKMESSAGECONTENTMASK_NONE 0 +#define UA_UADPNETWORKMESSAGECONTENTMASK_PUBLISHERID 1 +#define UA_UADPNETWORKMESSAGECONTENTMASK_GROUPHEADER 2 +#define UA_UADPNETWORKMESSAGECONTENTMASK_WRITERGROUPID 4 +#define UA_UADPNETWORKMESSAGECONTENTMASK_GROUPVERSION 8 +#define UA_UADPNETWORKMESSAGECONTENTMASK_NETWORKMESSAGENUMBER 16 +#define UA_UADPNETWORKMESSAGECONTENTMASK_SEQUENCENUMBER 32 +#define UA_UADPNETWORKMESSAGECONTENTMASK_PAYLOADHEADER 64 +#define UA_UADPNETWORKMESSAGECONTENTMASK_TIMESTAMP 128 +#define UA_UADPNETWORKMESSAGECONTENTMASK_PICOSECONDS 256 +#define UA_UADPNETWORKMESSAGECONTENTMASK_DATASETCLASSID 512 +#define UA_UADPNETWORKMESSAGECONTENTMASK_PROMOTEDFIELDS 1024 + +#define UA_TYPES_UADPNETWORKMESSAGECONTENTMASK 68 + +/* UadpWriterGroupMessageDataType */ +typedef struct { + UA_UInt32 groupVersion; + UA_DataSetOrderingType dataSetOrdering; + UA_UadpNetworkMessageContentMask networkMessageContentMask; + UA_Double samplingOffset; + size_t publishingOffsetSize; + UA_Double *publishingOffset; +} UA_UadpWriterGroupMessageDataType; + +#define UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE 69 + +/* UadpDataSetMessageContentMask */ +typedef UA_UInt32 UA_UadpDataSetMessageContentMask; + +#define UA_UADPDATASETMESSAGECONTENTMASK_NONE 0 +#define UA_UADPDATASETMESSAGECONTENTMASK_TIMESTAMP 1 +#define UA_UADPDATASETMESSAGECONTENTMASK_PICOSECONDS 2 +#define UA_UADPDATASETMESSAGECONTENTMASK_STATUS 4 +#define UA_UADPDATASETMESSAGECONTENTMASK_MAJORVERSION 8 +#define UA_UADPDATASETMESSAGECONTENTMASK_MINORVERSION 16 +#define UA_UADPDATASETMESSAGECONTENTMASK_SEQUENCENUMBER 32 + +#define UA_TYPES_UADPDATASETMESSAGECONTENTMASK 70 + +/* UadpDataSetWriterMessageDataType */ +typedef struct { + UA_UadpDataSetMessageContentMask dataSetMessageContentMask; + UA_UInt16 configuredSize; + UA_UInt16 networkMessageNumber; + UA_UInt16 dataSetOffset; +} UA_UadpDataSetWriterMessageDataType; + +#define UA_TYPES_UADPDATASETWRITERMESSAGEDATATYPE 71 + +/* UadpDataSetReaderMessageDataType */ +typedef struct { + UA_UInt32 groupVersion; + UA_UInt16 networkMessageNumber; + UA_UInt16 dataSetOffset; + UA_Guid dataSetClassId; + UA_UadpNetworkMessageContentMask networkMessageContentMask; + UA_UadpDataSetMessageContentMask dataSetMessageContentMask; + UA_Double publishingInterval; + UA_Double receiveOffset; + UA_Double processingOffset; +} UA_UadpDataSetReaderMessageDataType; + +#define UA_TYPES_UADPDATASETREADERMESSAGEDATATYPE 72 + +/* JsonNetworkMessageContentMask */ +typedef UA_UInt32 UA_JsonNetworkMessageContentMask; + +#define UA_JSONNETWORKMESSAGECONTENTMASK_NONE 0 +#define UA_JSONNETWORKMESSAGECONTENTMASK_NETWORKMESSAGEHEADER 1 +#define UA_JSONNETWORKMESSAGECONTENTMASK_DATASETMESSAGEHEADER 2 +#define UA_JSONNETWORKMESSAGECONTENTMASK_SINGLEDATASETMESSAGE 4 +#define UA_JSONNETWORKMESSAGECONTENTMASK_PUBLISHERID 8 +#define UA_JSONNETWORKMESSAGECONTENTMASK_DATASETCLASSID 16 +#define UA_JSONNETWORKMESSAGECONTENTMASK_REPLYTO 32 + +#define UA_TYPES_JSONNETWORKMESSAGECONTENTMASK 73 + +/* JsonWriterGroupMessageDataType */ +typedef struct { + UA_JsonNetworkMessageContentMask networkMessageContentMask; +} UA_JsonWriterGroupMessageDataType; + +#define UA_TYPES_JSONWRITERGROUPMESSAGEDATATYPE 74 + +/* JsonDataSetMessageContentMask */ +typedef UA_UInt32 UA_JsonDataSetMessageContentMask; + +#define UA_JSONDATASETMESSAGECONTENTMASK_NONE 0 +#define UA_JSONDATASETMESSAGECONTENTMASK_DATASETWRITERID 1 +#define UA_JSONDATASETMESSAGECONTENTMASK_METADATAVERSION 2 +#define UA_JSONDATASETMESSAGECONTENTMASK_SEQUENCENUMBER 4 +#define UA_JSONDATASETMESSAGECONTENTMASK_TIMESTAMP 8 +#define UA_JSONDATASETMESSAGECONTENTMASK_STATUS 16 +#define UA_JSONDATASETMESSAGECONTENTMASK_MESSAGETYPE 32 +#define UA_JSONDATASETMESSAGECONTENTMASK_DATASETWRITERNAME 64 +#define UA_JSONDATASETMESSAGECONTENTMASK_REVERSIBLEFIELDENCODING 128 + +#define UA_TYPES_JSONDATASETMESSAGECONTENTMASK 75 + +/* JsonDataSetWriterMessageDataType */ +typedef struct { + UA_JsonDataSetMessageContentMask dataSetMessageContentMask; +} UA_JsonDataSetWriterMessageDataType; + +#define UA_TYPES_JSONDATASETWRITERMESSAGEDATATYPE 76 + +/* JsonDataSetReaderMessageDataType */ +typedef struct { + UA_JsonNetworkMessageContentMask networkMessageContentMask; + UA_JsonDataSetMessageContentMask dataSetMessageContentMask; +} UA_JsonDataSetReaderMessageDataType; + +#define UA_TYPES_JSONDATASETREADERMESSAGEDATATYPE 77 + +/* TransmitQosPriorityDataType */ +typedef struct { + UA_String priorityLabel; +} UA_TransmitQosPriorityDataType; + +#define UA_TYPES_TRANSMITQOSPRIORITYDATATYPE 78 + +/* ReceiveQosPriorityDataType */ +typedef struct { + UA_String priorityLabel; +} UA_ReceiveQosPriorityDataType; + +#define UA_TYPES_RECEIVEQOSPRIORITYDATATYPE 79 + +/* DatagramConnectionTransportDataType */ +typedef struct { + UA_ExtensionObject discoveryAddress; +} UA_DatagramConnectionTransportDataType; + +#define UA_TYPES_DATAGRAMCONNECTIONTRANSPORTDATATYPE 80 + +/* DatagramConnectionTransport2DataType */ +typedef struct { + UA_ExtensionObject discoveryAddress; + UA_UInt32 discoveryAnnounceRate; + UA_UInt32 discoveryMaxMessageSize; + UA_String qosCategory; + size_t datagramQosSize; + UA_ExtensionObject *datagramQos; +} UA_DatagramConnectionTransport2DataType; + +#define UA_TYPES_DATAGRAMCONNECTIONTRANSPORT2DATATYPE 81 + +/* DatagramWriterGroupTransportDataType */ +typedef struct { + UA_Byte messageRepeatCount; + UA_Double messageRepeatDelay; +} UA_DatagramWriterGroupTransportDataType; + +#define UA_TYPES_DATAGRAMWRITERGROUPTRANSPORTDATATYPE 82 + +/* DatagramWriterGroupTransport2DataType */ +typedef struct { + UA_Byte messageRepeatCount; + UA_Double messageRepeatDelay; + UA_ExtensionObject address; + UA_String qosCategory; + size_t datagramQosSize; + UA_ExtensionObject *datagramQos; + UA_UInt32 discoveryAnnounceRate; + UA_String topic; +} UA_DatagramWriterGroupTransport2DataType; + +#define UA_TYPES_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE 83 + +/* DatagramDataSetReaderTransportDataType */ +typedef struct { + UA_ExtensionObject address; + UA_String qosCategory; + size_t datagramQosSize; + UA_ExtensionObject *datagramQos; + UA_String topic; +} UA_DatagramDataSetReaderTransportDataType; + +#define UA_TYPES_DATAGRAMDATASETREADERTRANSPORTDATATYPE 84 + +/* BrokerConnectionTransportDataType */ +typedef struct { + UA_String resourceUri; + UA_String authenticationProfileUri; +} UA_BrokerConnectionTransportDataType; + +#define UA_TYPES_BROKERCONNECTIONTRANSPORTDATATYPE 85 + +/* BrokerTransportQualityOfService */ +typedef enum { + UA_BROKERTRANSPORTQUALITYOFSERVICE_NOTSPECIFIED = 0, + UA_BROKERTRANSPORTQUALITYOFSERVICE_BESTEFFORT = 1, + UA_BROKERTRANSPORTQUALITYOFSERVICE_ATLEASTONCE = 2, + UA_BROKERTRANSPORTQUALITYOFSERVICE_ATMOSTONCE = 3, + UA_BROKERTRANSPORTQUALITYOFSERVICE_EXACTLYONCE = 4, + __UA_BROKERTRANSPORTQUALITYOFSERVICE_FORCE32BIT = 0x7fffffff +} UA_BrokerTransportQualityOfService; + +UA_STATIC_ASSERT(sizeof(UA_BrokerTransportQualityOfService) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_BROKERTRANSPORTQUALITYOFSERVICE 86 + +/* BrokerWriterGroupTransportDataType */ +typedef struct { + UA_String queueName; + UA_String resourceUri; + UA_String authenticationProfileUri; + UA_BrokerTransportQualityOfService requestedDeliveryGuarantee; +} UA_BrokerWriterGroupTransportDataType; + +#define UA_TYPES_BROKERWRITERGROUPTRANSPORTDATATYPE 87 + +/* BrokerDataSetWriterTransportDataType */ +typedef struct { + UA_String queueName; + UA_String resourceUri; + UA_String authenticationProfileUri; + UA_BrokerTransportQualityOfService requestedDeliveryGuarantee; + UA_String metaDataQueueName; + UA_Double metaDataUpdateTime; +} UA_BrokerDataSetWriterTransportDataType; + +#define UA_TYPES_BROKERDATASETWRITERTRANSPORTDATATYPE 88 + +/* BrokerDataSetReaderTransportDataType */ +typedef struct { + UA_String queueName; + UA_String resourceUri; + UA_String authenticationProfileUri; + UA_BrokerTransportQualityOfService requestedDeliveryGuarantee; + UA_String metaDataQueueName; +} UA_BrokerDataSetReaderTransportDataType; + +#define UA_TYPES_BROKERDATASETREADERTRANSPORTDATATYPE 89 + +/* PubSubConfigurationRefMask */ +typedef UA_UInt32 UA_PubSubConfigurationRefMask; + +#define UA_PUBSUBCONFIGURATIONREFMASK_NONE 0 +#define UA_PUBSUBCONFIGURATIONREFMASK_ELEMENTADD 1 +#define UA_PUBSUBCONFIGURATIONREFMASK_ELEMENTMATCH 2 +#define UA_PUBSUBCONFIGURATIONREFMASK_ELEMENTMODIFY 4 +#define UA_PUBSUBCONFIGURATIONREFMASK_ELEMENTREMOVE 8 +#define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCEWRITER 16 +#define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCEREADER 32 +#define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCEWRITERGROUP 64 +#define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCEREADERGROUP 128 +#define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCECONNECTION 256 +#define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCEPUBDATASET 512 +#define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCESUBDATASET 1024 +#define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCESECURITYGROUP 2048 +#define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCEPUSHTARGET 4096 + +#define UA_TYPES_PUBSUBCONFIGURATIONREFMASK 90 + +/* PubSubConfigurationRefDataType */ +typedef struct { + UA_PubSubConfigurationRefMask configurationMask; + UA_UInt16 elementIndex; + UA_UInt16 connectionIndex; + UA_UInt16 groupIndex; +} UA_PubSubConfigurationRefDataType; + +#define UA_TYPES_PUBSUBCONFIGURATIONREFDATATYPE 91 + +/* PubSubConfigurationValueDataType */ +typedef struct { + UA_PubSubConfigurationRefDataType configurationElement; + UA_String name; + UA_Variant identifier; +} UA_PubSubConfigurationValueDataType; + +#define UA_TYPES_PUBSUBCONFIGURATIONVALUEDATATYPE 92 + +/* DiagnosticsLevel */ +typedef enum { + UA_DIAGNOSTICSLEVEL_BASIC = 0, + UA_DIAGNOSTICSLEVEL_ADVANCED = 1, + UA_DIAGNOSTICSLEVEL_INFO = 2, + UA_DIAGNOSTICSLEVEL_LOG = 3, + UA_DIAGNOSTICSLEVEL_DEBUG = 4, + __UA_DIAGNOSTICSLEVEL_FORCE32BIT = 0x7fffffff +} UA_DiagnosticsLevel; + +UA_STATIC_ASSERT(sizeof(UA_DiagnosticsLevel) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_DIAGNOSTICSLEVEL 93 + +/* PubSubDiagnosticsCounterClassification */ +typedef enum { + UA_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION_INFORMATION = 0, + UA_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION_ERROR = 1, + __UA_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION_FORCE32BIT = 0x7fffffff +} UA_PubSubDiagnosticsCounterClassification; + +UA_STATIC_ASSERT(sizeof(UA_PubSubDiagnosticsCounterClassification) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION 94 + +/* AliasNameDataType */ +typedef struct { + UA_QualifiedName aliasName; + size_t referencedNodesSize; + UA_ExpandedNodeId *referencedNodes; +} UA_AliasNameDataType; + +#define UA_TYPES_ALIASNAMEDATATYPE 95 + +/* PasswordOptionsMask */ +typedef UA_UInt32 UA_PasswordOptionsMask; + +#define UA_PASSWORDOPTIONSMASK_NONE 0 +#define UA_PASSWORDOPTIONSMASK_SUPPORTINITIALPASSWORDCHANGE 1 +#define UA_PASSWORDOPTIONSMASK_SUPPORTDISABLEUSER 2 +#define UA_PASSWORDOPTIONSMASK_SUPPORTDISABLEDELETEFORUSER 4 +#define UA_PASSWORDOPTIONSMASK_SUPPORTNOCHANGEFORUSER 8 +#define UA_PASSWORDOPTIONSMASK_SUPPORTDESCRIPTIONFORUSER 16 +#define UA_PASSWORDOPTIONSMASK_REQUIRESUPPERCASECHARACTERS 32 +#define UA_PASSWORDOPTIONSMASK_REQUIRESLOWERCASECHARACTERS 64 +#define UA_PASSWORDOPTIONSMASK_REQUIRESDIGITCHARACTERS 128 +#define UA_PASSWORDOPTIONSMASK_REQUIRESSPECIALCHARACTERS 256 + +#define UA_TYPES_PASSWORDOPTIONSMASK 96 + +/* UserConfigurationMask */ +typedef UA_UInt32 UA_UserConfigurationMask; + +#define UA_USERCONFIGURATIONMASK_NONE 0 +#define UA_USERCONFIGURATIONMASK_NODELETE 1 +#define UA_USERCONFIGURATIONMASK_DISABLED 2 +#define UA_USERCONFIGURATIONMASK_NOCHANGEBYUSER 4 +#define UA_USERCONFIGURATIONMASK_MUSTCHANGEPASSWORD 8 + +#define UA_TYPES_USERCONFIGURATIONMASK 97 + +/* UserManagementDataType */ +typedef struct { + UA_String userName; + UA_UserConfigurationMask userConfiguration; + UA_String description; +} UA_UserManagementDataType; + +#define UA_TYPES_USERMANAGEMENTDATATYPE 98 + +/* Duplex */ +typedef enum { + UA_DUPLEX_FULL = 0, + UA_DUPLEX_HALF = 1, + UA_DUPLEX_UNKNOWN = 2, + __UA_DUPLEX_FORCE32BIT = 0x7fffffff +} UA_Duplex; + +UA_STATIC_ASSERT(sizeof(UA_Duplex) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_DUPLEX 99 + +/* InterfaceAdminStatus */ +typedef enum { + UA_INTERFACEADMINSTATUS_UP = 0, + UA_INTERFACEADMINSTATUS_DOWN = 1, + UA_INTERFACEADMINSTATUS_TESTING = 2, + __UA_INTERFACEADMINSTATUS_FORCE32BIT = 0x7fffffff +} UA_InterfaceAdminStatus; + +UA_STATIC_ASSERT(sizeof(UA_InterfaceAdminStatus) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_INTERFACEADMINSTATUS 100 + +/* InterfaceOperStatus */ +typedef enum { + UA_INTERFACEOPERSTATUS_UP = 0, + UA_INTERFACEOPERSTATUS_DOWN = 1, + UA_INTERFACEOPERSTATUS_TESTING = 2, + UA_INTERFACEOPERSTATUS_UNKNOWN = 3, + UA_INTERFACEOPERSTATUS_DORMANT = 4, + UA_INTERFACEOPERSTATUS_NOTPRESENT = 5, + UA_INTERFACEOPERSTATUS_LOWERLAYERDOWN = 6, + __UA_INTERFACEOPERSTATUS_FORCE32BIT = 0x7fffffff +} UA_InterfaceOperStatus; + +UA_STATIC_ASSERT(sizeof(UA_InterfaceOperStatus) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_INTERFACEOPERSTATUS 101 + +/* NegotiationStatus */ +typedef enum { + UA_NEGOTIATIONSTATUS_INPROGRESS = 0, + UA_NEGOTIATIONSTATUS_COMPLETE = 1, + UA_NEGOTIATIONSTATUS_FAILED = 2, + UA_NEGOTIATIONSTATUS_UNKNOWN = 3, + UA_NEGOTIATIONSTATUS_NONEGOTIATION = 4, + __UA_NEGOTIATIONSTATUS_FORCE32BIT = 0x7fffffff +} UA_NegotiationStatus; + +UA_STATIC_ASSERT(sizeof(UA_NegotiationStatus) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_NEGOTIATIONSTATUS 102 + +/* TsnFailureCode */ +typedef enum { + UA_TSNFAILURECODE_NOFAILURE = 0, + UA_TSNFAILURECODE_INSUFFICIENTBANDWIDTH = 1, + UA_TSNFAILURECODE_INSUFFICIENTRESOURCES = 2, + UA_TSNFAILURECODE_INSUFFICIENTTRAFFICCLASSBANDWIDTH = 3, + UA_TSNFAILURECODE_STREAMIDINUSE = 4, + UA_TSNFAILURECODE_STREAMDESTINATIONADDRESSINUSE = 5, + UA_TSNFAILURECODE_STREAMPREEMPTEDBYHIGHERRANK = 6, + UA_TSNFAILURECODE_LATENCYHASCHANGED = 7, + UA_TSNFAILURECODE_EGRESSPORTNOTAVBCAPABLE = 8, + UA_TSNFAILURECODE_USEDIFFERENTDESTINATIONADDRESS = 9, + UA_TSNFAILURECODE_OUTOFMSRPRESOURCES = 10, + UA_TSNFAILURECODE_OUTOFMMRPRESOURCES = 11, + UA_TSNFAILURECODE_CANNOTSTOREDESTINATIONADDRESS = 12, + UA_TSNFAILURECODE_PRIORITYISNOTANSRCCLASS = 13, + UA_TSNFAILURECODE_MAXFRAMESIZETOOLARGE = 14, + UA_TSNFAILURECODE_MAXFANINPORTSLIMITREACHED = 15, + UA_TSNFAILURECODE_FIRSTVALUECHANGEDFORSTREAMID = 16, + UA_TSNFAILURECODE_VLANBLOCKEDONEGRESS = 17, + UA_TSNFAILURECODE_VLANTAGGINGDISABLEDONEGRESS = 18, + UA_TSNFAILURECODE_SRCLASSPRIORITYMISMATCH = 19, + UA_TSNFAILURECODE_FEATURENOTPROPAGATED = 20, + UA_TSNFAILURECODE_MAXLATENCYEXCEEDED = 21, + UA_TSNFAILURECODE_BRIDGEDOESNOTPROVIDENETWORKID = 22, + UA_TSNFAILURECODE_STREAMTRANSFORMNOTSUPPORTED = 23, + UA_TSNFAILURECODE_STREAMIDTYPENOTSUPPORTED = 24, + UA_TSNFAILURECODE_FEATURENOTSUPPORTED = 25, + __UA_TSNFAILURECODE_FORCE32BIT = 0x7fffffff +} UA_TsnFailureCode; + +UA_STATIC_ASSERT(sizeof(UA_TsnFailureCode) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_TSNFAILURECODE 103 + +/* TsnStreamState */ +typedef enum { + UA_TSNSTREAMSTATE_DISABLED = 0, + UA_TSNSTREAMSTATE_CONFIGURING = 1, + UA_TSNSTREAMSTATE_READY = 2, + UA_TSNSTREAMSTATE_OPERATIONAL = 3, + UA_TSNSTREAMSTATE_ERROR = 4, + __UA_TSNSTREAMSTATE_FORCE32BIT = 0x7fffffff +} UA_TsnStreamState; + +UA_STATIC_ASSERT(sizeof(UA_TsnStreamState) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_TSNSTREAMSTATE 104 + +/* TsnTalkerStatus */ +typedef enum { + UA_TSNTALKERSTATUS_NONE = 0, + UA_TSNTALKERSTATUS_READY = 1, + UA_TSNTALKERSTATUS_FAILED = 2, + __UA_TSNTALKERSTATUS_FORCE32BIT = 0x7fffffff +} UA_TsnTalkerStatus; + +UA_STATIC_ASSERT(sizeof(UA_TsnTalkerStatus) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_TSNTALKERSTATUS 105 + +/* TsnListenerStatus */ +typedef enum { + UA_TSNLISTENERSTATUS_NONE = 0, + UA_TSNLISTENERSTATUS_READY = 1, + UA_TSNLISTENERSTATUS_PARTIALFAILED = 2, + UA_TSNLISTENERSTATUS_FAILED = 3, + __UA_TSNLISTENERSTATUS_FORCE32BIT = 0x7fffffff +} UA_TsnListenerStatus; + +UA_STATIC_ASSERT(sizeof(UA_TsnListenerStatus) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_TSNLISTENERSTATUS 106 + +/* PriorityMappingEntryType */ +typedef struct { + UA_String mappingUri; + UA_String priorityLabel; + UA_Byte priorityValue_PCP; + UA_UInt32 priorityValue_DSCP; +} UA_PriorityMappingEntryType; + +#define UA_TYPES_PRIORITYMAPPINGENTRYTYPE 107 + +/* IdType */ +typedef enum { + UA_IDTYPE_NUMERIC = 0, + UA_IDTYPE_STRING = 1, + UA_IDTYPE_GUID = 2, + UA_IDTYPE_OPAQUE = 3, + __UA_IDTYPE_FORCE32BIT = 0x7fffffff +} UA_IdType; + +UA_STATIC_ASSERT(sizeof(UA_IdType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_IDTYPE 108 + +/* NodeClass */ +typedef enum { + UA_NODECLASS_UNSPECIFIED = 0, + UA_NODECLASS_OBJECT = 1, + UA_NODECLASS_VARIABLE = 2, + UA_NODECLASS_METHOD = 4, + UA_NODECLASS_OBJECTTYPE = 8, + UA_NODECLASS_VARIABLETYPE = 16, + UA_NODECLASS_REFERENCETYPE = 32, + UA_NODECLASS_DATATYPE = 64, + UA_NODECLASS_VIEW = 128, + __UA_NODECLASS_FORCE32BIT = 0x7fffffff +} UA_NodeClass; + +UA_STATIC_ASSERT(sizeof(UA_NodeClass) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_NODECLASS 109 + +/* PermissionType */ +typedef UA_UInt32 UA_PermissionType; + +#define UA_PERMISSIONTYPE_NONE 0 +#define UA_PERMISSIONTYPE_BROWSE 1 +#define UA_PERMISSIONTYPE_READROLEPERMISSIONS 2 +#define UA_PERMISSIONTYPE_WRITEATTRIBUTE 4 +#define UA_PERMISSIONTYPE_WRITEROLEPERMISSIONS 8 +#define UA_PERMISSIONTYPE_WRITEHISTORIZING 16 +#define UA_PERMISSIONTYPE_READ 32 +#define UA_PERMISSIONTYPE_WRITE 64 +#define UA_PERMISSIONTYPE_READHISTORY 128 +#define UA_PERMISSIONTYPE_INSERTHISTORY 256 +#define UA_PERMISSIONTYPE_MODIFYHISTORY 512 +#define UA_PERMISSIONTYPE_DELETEHISTORY 1024 +#define UA_PERMISSIONTYPE_RECEIVEEVENTS 2048 +#define UA_PERMISSIONTYPE_CALL 4096 +#define UA_PERMISSIONTYPE_ADDREFERENCE 8192 +#define UA_PERMISSIONTYPE_REMOVEREFERENCE 16384 +#define UA_PERMISSIONTYPE_DELETENODE 32768 +#define UA_PERMISSIONTYPE_ADDNODE 65536 + +#define UA_TYPES_PERMISSIONTYPE 110 + +/* AccessLevelType */ +typedef UA_Byte UA_AccessLevelType; + +#define UA_ACCESSLEVELTYPE_NONE 0 +#define UA_ACCESSLEVELTYPE_CURRENTREAD 1 +#define UA_ACCESSLEVELTYPE_CURRENTWRITE 2 +#define UA_ACCESSLEVELTYPE_HISTORYREAD 4 +#define UA_ACCESSLEVELTYPE_HISTORYWRITE 8 +#define UA_ACCESSLEVELTYPE_SEMANTICCHANGE 16 +#define UA_ACCESSLEVELTYPE_STATUSWRITE 32 +#define UA_ACCESSLEVELTYPE_TIMESTAMPWRITE 64 + +#define UA_TYPES_ACCESSLEVELTYPE 111 + +/* AccessLevelExType */ +typedef UA_UInt32 UA_AccessLevelExType; + +#define UA_ACCESSLEVELEXTYPE_NONE 0 +#define UA_ACCESSLEVELEXTYPE_CURRENTREAD 1 +#define UA_ACCESSLEVELEXTYPE_CURRENTWRITE 2 +#define UA_ACCESSLEVELEXTYPE_HISTORYREAD 4 +#define UA_ACCESSLEVELEXTYPE_HISTORYWRITE 8 +#define UA_ACCESSLEVELEXTYPE_SEMANTICCHANGE 16 +#define UA_ACCESSLEVELEXTYPE_STATUSWRITE 32 +#define UA_ACCESSLEVELEXTYPE_TIMESTAMPWRITE 64 +#define UA_ACCESSLEVELEXTYPE_NONATOMICREAD 256 +#define UA_ACCESSLEVELEXTYPE_NONATOMICWRITE 512 +#define UA_ACCESSLEVELEXTYPE_WRITEFULLARRAYONLY 1024 +#define UA_ACCESSLEVELEXTYPE_NOSUBDATATYPES 2048 +#define UA_ACCESSLEVELEXTYPE_NONVOLATILE 4096 +#define UA_ACCESSLEVELEXTYPE_CONSTANT 8192 + +#define UA_TYPES_ACCESSLEVELEXTYPE 112 + +/* EventNotifierType */ +typedef UA_Byte UA_EventNotifierType; + +#define UA_EVENTNOTIFIERTYPE_NONE 0 +#define UA_EVENTNOTIFIERTYPE_SUBSCRIBETOEVENTS 1 +#define UA_EVENTNOTIFIERTYPE_HISTORYREAD 4 +#define UA_EVENTNOTIFIERTYPE_HISTORYWRITE 8 + +#define UA_TYPES_EVENTNOTIFIERTYPE 113 + +/* AccessRestrictionType */ +typedef UA_UInt16 UA_AccessRestrictionType; + +#define UA_ACCESSRESTRICTIONTYPE_NONE 0 +#define UA_ACCESSRESTRICTIONTYPE_SIGNINGREQUIRED 1 +#define UA_ACCESSRESTRICTIONTYPE_ENCRYPTIONREQUIRED 2 +#define UA_ACCESSRESTRICTIONTYPE_SESSIONREQUIRED 4 +#define UA_ACCESSRESTRICTIONTYPE_APPLYRESTRICTIONSTOBROWSE 8 + +#define UA_TYPES_ACCESSRESTRICTIONTYPE 114 + +/* RolePermissionType */ +typedef struct { + UA_NodeId roleId; + UA_PermissionType permissions; +} UA_RolePermissionType; + +#define UA_TYPES_ROLEPERMISSIONTYPE 115 + +/* StructureType */ +typedef enum { + UA_STRUCTURETYPE_STRUCTURE = 0, + UA_STRUCTURETYPE_STRUCTUREWITHOPTIONALFIELDS = 1, + UA_STRUCTURETYPE_UNION = 2, + UA_STRUCTURETYPE_STRUCTUREWITHSUBTYPEDVALUES = 3, + UA_STRUCTURETYPE_UNIONWITHSUBTYPEDVALUES = 4, + __UA_STRUCTURETYPE_FORCE32BIT = 0x7fffffff +} UA_StructureType; + +UA_STATIC_ASSERT(sizeof(UA_StructureType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_STRUCTURETYPE 116 + +/* StructureField */ +typedef struct { + UA_String name; + UA_LocalizedText description; + UA_NodeId dataType; + UA_Int32 valueRank; + size_t arrayDimensionsSize; + UA_UInt32 *arrayDimensions; + UA_UInt32 maxStringLength; + UA_Boolean isOptional; +} UA_StructureField; + +#define UA_TYPES_STRUCTUREFIELD 117 + +/* StructureDefinition */ +typedef struct { + UA_NodeId defaultEncodingId; + UA_NodeId baseDataType; + UA_StructureType structureType; + size_t fieldsSize; + UA_StructureField *fields; +} UA_StructureDefinition; + +#define UA_TYPES_STRUCTUREDEFINITION 118 + +/* ReferenceNode */ +typedef struct { + UA_NodeId referenceTypeId; + UA_Boolean isInverse; + UA_ExpandedNodeId targetId; +} UA_ReferenceNode; + +#define UA_TYPES_REFERENCENODE 119 + +/* Argument */ +typedef struct { + UA_String name; + UA_NodeId dataType; + UA_Int32 valueRank; + size_t arrayDimensionsSize; + UA_UInt32 *arrayDimensions; + UA_LocalizedText description; +} UA_Argument; + +#define UA_TYPES_ARGUMENT 120 + +/* EnumValueType */ +typedef struct { + UA_Int64 value; + UA_LocalizedText displayName; + UA_LocalizedText description; +} UA_EnumValueType; + +#define UA_TYPES_ENUMVALUETYPE 121 + +/* EnumField */ +typedef struct { + UA_Int64 value; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_String name; +} UA_EnumField; + +#define UA_TYPES_ENUMFIELD 122 + +/* OptionSet */ +typedef struct { + UA_ByteString value; + UA_ByteString validBits; +} UA_OptionSet; + +#define UA_TYPES_OPTIONSET 123 + +/* NormalizedString */ +typedef UA_String UA_NormalizedString; + +#define UA_TYPES_NORMALIZEDSTRING 124 + +/* DecimalString */ +typedef UA_String UA_DecimalString; + +#define UA_TYPES_DECIMALSTRING 125 + +/* DurationString */ +typedef UA_String UA_DurationString; + +#define UA_TYPES_DURATIONSTRING 126 + +/* TimeString */ +typedef UA_String UA_TimeString; + +#define UA_TYPES_TIMESTRING 127 + +/* DateString */ +typedef UA_String UA_DateString; + +#define UA_TYPES_DATESTRING 128 + +/* Duration */ +typedef UA_Double UA_Duration; + +#define UA_TYPES_DURATION 129 + +/* UtcTime */ +typedef UA_DateTime UA_UtcTime; + +#define UA_TYPES_UTCTIME 130 + +/* LocaleId */ +typedef UA_String UA_LocaleId; + +#define UA_TYPES_LOCALEID 131 + +/* TimeZoneDataType */ +typedef struct { + UA_Int16 offset; + UA_Boolean daylightSavingInOffset; +} UA_TimeZoneDataType; + +#define UA_TYPES_TIMEZONEDATATYPE 132 + +/* Index */ +typedef UA_ByteString UA_Index; + +#define UA_TYPES_INDEX 133 + +/* IntegerId */ +typedef UA_UInt32 UA_IntegerId; + +#define UA_TYPES_INTEGERID 134 + +/* ApplicationType */ +typedef enum { + UA_APPLICATIONTYPE_SERVER = 0, + UA_APPLICATIONTYPE_CLIENT = 1, + UA_APPLICATIONTYPE_CLIENTANDSERVER = 2, + UA_APPLICATIONTYPE_DISCOVERYSERVER = 3, + __UA_APPLICATIONTYPE_FORCE32BIT = 0x7fffffff +} UA_ApplicationType; + +UA_STATIC_ASSERT(sizeof(UA_ApplicationType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_APPLICATIONTYPE 135 + +/* ApplicationDescription */ +typedef struct { + UA_String applicationUri; + UA_String productUri; + UA_LocalizedText applicationName; + UA_ApplicationType applicationType; + UA_String gatewayServerUri; + UA_String discoveryProfileUri; + size_t discoveryUrlsSize; + UA_String *discoveryUrls; +} UA_ApplicationDescription; + +#define UA_TYPES_APPLICATIONDESCRIPTION 136 + +/* RequestHeader */ +typedef struct { + UA_NodeId authenticationToken; + UA_DateTime timestamp; + UA_UInt32 requestHandle; + UA_UInt32 returnDiagnostics; + UA_String auditEntryId; + UA_UInt32 timeoutHint; + UA_ExtensionObject additionalHeader; +} UA_RequestHeader; + +#define UA_TYPES_REQUESTHEADER 137 + +/* ResponseHeader */ +typedef struct { + UA_DateTime timestamp; + UA_UInt32 requestHandle; + UA_StatusCode serviceResult; + UA_DiagnosticInfo serviceDiagnostics; + size_t stringTableSize; + UA_String *stringTable; + UA_ExtensionObject additionalHeader; +} UA_ResponseHeader; + +#define UA_TYPES_RESPONSEHEADER 138 + +/* VersionTime */ +typedef UA_ByteString UA_VersionTime; + +#define UA_TYPES_VERSIONTIME 139 + +/* ServiceFault */ +typedef struct { + UA_ResponseHeader responseHeader; +} UA_ServiceFault; + +#define UA_TYPES_SERVICEFAULT 140 + +/* SessionlessInvokeRequestType */ +typedef struct { + UA_UInt32 urisVersion; + size_t namespaceUrisSize; + UA_String *namespaceUris; + size_t serverUrisSize; + UA_String *serverUris; + size_t localeIdsSize; + UA_String *localeIds; + UA_UInt32 serviceId; +} UA_SessionlessInvokeRequestType; + +#define UA_TYPES_SESSIONLESSINVOKEREQUESTTYPE 141 + +/* SessionlessInvokeResponseType */ +typedef struct { + size_t namespaceUrisSize; + UA_String *namespaceUris; + size_t serverUrisSize; + UA_String *serverUris; + UA_UInt32 serviceId; +} UA_SessionlessInvokeResponseType; + +#define UA_TYPES_SESSIONLESSINVOKERESPONSETYPE 142 + +/* FindServersRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_String endpointUrl; + size_t localeIdsSize; + UA_String *localeIds; + size_t serverUrisSize; + UA_String *serverUris; +} UA_FindServersRequest; + +#define UA_TYPES_FINDSERVERSREQUEST 143 + +/* FindServersResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t serversSize; + UA_ApplicationDescription *servers; +} UA_FindServersResponse; + +#define UA_TYPES_FINDSERVERSRESPONSE 144 + +/* ServerOnNetwork */ +typedef struct { + UA_UInt32 recordId; + UA_String serverName; + UA_String discoveryUrl; + size_t serverCapabilitiesSize; + UA_String *serverCapabilities; +} UA_ServerOnNetwork; + +#define UA_TYPES_SERVERONNETWORK 145 + +/* FindServersOnNetworkRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 startingRecordId; + UA_UInt32 maxRecordsToReturn; + size_t serverCapabilityFilterSize; + UA_String *serverCapabilityFilter; +} UA_FindServersOnNetworkRequest; + +#define UA_TYPES_FINDSERVERSONNETWORKREQUEST 146 + +/* FindServersOnNetworkResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + UA_DateTime lastCounterResetTime; + size_t serversSize; + UA_ServerOnNetwork *servers; +} UA_FindServersOnNetworkResponse; + +#define UA_TYPES_FINDSERVERSONNETWORKRESPONSE 147 + +/* ApplicationInstanceCertificate */ +typedef UA_ByteString UA_ApplicationInstanceCertificate; + +#define UA_TYPES_APPLICATIONINSTANCECERTIFICATE 148 + +/* MessageSecurityMode */ +typedef enum { + UA_MESSAGESECURITYMODE_INVALID = 0, + UA_MESSAGESECURITYMODE_NONE = 1, + UA_MESSAGESECURITYMODE_SIGN = 2, + UA_MESSAGESECURITYMODE_SIGNANDENCRYPT = 3, + __UA_MESSAGESECURITYMODE_FORCE32BIT = 0x7fffffff +} UA_MessageSecurityMode; + +UA_STATIC_ASSERT(sizeof(UA_MessageSecurityMode) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_MESSAGESECURITYMODE 149 + +/* UserTokenType */ +typedef enum { + UA_USERTOKENTYPE_ANONYMOUS = 0, + UA_USERTOKENTYPE_USERNAME = 1, + UA_USERTOKENTYPE_CERTIFICATE = 2, + UA_USERTOKENTYPE_ISSUEDTOKEN = 3, + __UA_USERTOKENTYPE_FORCE32BIT = 0x7fffffff +} UA_UserTokenType; + +UA_STATIC_ASSERT(sizeof(UA_UserTokenType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_USERTOKENTYPE 150 + +/* UserTokenPolicy */ +typedef struct { + UA_String policyId; + UA_UserTokenType tokenType; + UA_String issuedTokenType; + UA_String issuerEndpointUrl; + UA_String securityPolicyUri; +} UA_UserTokenPolicy; + +#define UA_TYPES_USERTOKENPOLICY 151 + +/* EndpointDescription */ +typedef struct { + UA_String endpointUrl; + UA_ApplicationDescription server; + UA_ByteString serverCertificate; + UA_MessageSecurityMode securityMode; + UA_String securityPolicyUri; + size_t userIdentityTokensSize; + UA_UserTokenPolicy *userIdentityTokens; + UA_String transportProfileUri; + UA_Byte securityLevel; +} UA_EndpointDescription; + +#define UA_TYPES_ENDPOINTDESCRIPTION 152 + +/* GetEndpointsRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_String endpointUrl; + size_t localeIdsSize; + UA_String *localeIds; + size_t profileUrisSize; + UA_String *profileUris; +} UA_GetEndpointsRequest; + +#define UA_TYPES_GETENDPOINTSREQUEST 153 + +/* GetEndpointsResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t endpointsSize; + UA_EndpointDescription *endpoints; +} UA_GetEndpointsResponse; + +#define UA_TYPES_GETENDPOINTSRESPONSE 154 + +/* RegisteredServer */ +typedef struct { + UA_String serverUri; + UA_String productUri; + size_t serverNamesSize; + UA_LocalizedText *serverNames; + UA_ApplicationType serverType; + UA_String gatewayServerUri; + size_t discoveryUrlsSize; + UA_String *discoveryUrls; + UA_String semaphoreFilePath; + UA_Boolean isOnline; +} UA_RegisteredServer; + +#define UA_TYPES_REGISTEREDSERVER 155 + +/* RegisterServerRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_RegisteredServer server; +} UA_RegisterServerRequest; + +#define UA_TYPES_REGISTERSERVERREQUEST 156 + +/* RegisterServerResponse */ +typedef struct { + UA_ResponseHeader responseHeader; +} UA_RegisterServerResponse; + +#define UA_TYPES_REGISTERSERVERRESPONSE 157 + +/* MdnsDiscoveryConfiguration */ +typedef struct { + UA_String mdnsServerName; + size_t serverCapabilitiesSize; + UA_String *serverCapabilities; +} UA_MdnsDiscoveryConfiguration; + +#define UA_TYPES_MDNSDISCOVERYCONFIGURATION 158 + +/* RegisterServer2Request */ +typedef struct { + UA_RequestHeader requestHeader; + UA_RegisteredServer server; + size_t discoveryConfigurationSize; + UA_ExtensionObject *discoveryConfiguration; +} UA_RegisterServer2Request; + +#define UA_TYPES_REGISTERSERVER2REQUEST 159 + +/* RegisterServer2Response */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t configurationResultsSize; + UA_StatusCode *configurationResults; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_RegisterServer2Response; + +#define UA_TYPES_REGISTERSERVER2RESPONSE 160 + +/* SecurityTokenRequestType */ +typedef enum { + UA_SECURITYTOKENREQUESTTYPE_ISSUE = 0, + UA_SECURITYTOKENREQUESTTYPE_RENEW = 1, + __UA_SECURITYTOKENREQUESTTYPE_FORCE32BIT = 0x7fffffff +} UA_SecurityTokenRequestType; + +UA_STATIC_ASSERT(sizeof(UA_SecurityTokenRequestType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_SECURITYTOKENREQUESTTYPE 161 + +/* ChannelSecurityToken */ +typedef struct { + UA_UInt32 channelId; + UA_UInt32 tokenId; + UA_DateTime createdAt; + UA_UInt32 revisedLifetime; +} UA_ChannelSecurityToken; + +#define UA_TYPES_CHANNELSECURITYTOKEN 162 + +/* OpenSecureChannelRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 clientProtocolVersion; + UA_SecurityTokenRequestType requestType; + UA_MessageSecurityMode securityMode; + UA_ByteString clientNonce; + UA_UInt32 requestedLifetime; +} UA_OpenSecureChannelRequest; + +#define UA_TYPES_OPENSECURECHANNELREQUEST 163 + +/* OpenSecureChannelResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + UA_UInt32 serverProtocolVersion; + UA_ChannelSecurityToken securityToken; + UA_ByteString serverNonce; +} UA_OpenSecureChannelResponse; + +#define UA_TYPES_OPENSECURECHANNELRESPONSE 164 + +/* CloseSecureChannelRequest */ +typedef struct { + UA_RequestHeader requestHeader; +} UA_CloseSecureChannelRequest; + +#define UA_TYPES_CLOSESECURECHANNELREQUEST 165 + +/* CloseSecureChannelResponse */ +typedef struct { + UA_ResponseHeader responseHeader; +} UA_CloseSecureChannelResponse; + +#define UA_TYPES_CLOSESECURECHANNELRESPONSE 166 + +/* SignedSoftwareCertificate */ +typedef struct { + UA_ByteString certificateData; + UA_ByteString signature; +} UA_SignedSoftwareCertificate; + +#define UA_TYPES_SIGNEDSOFTWARECERTIFICATE 167 + +/* SessionAuthenticationToken */ +typedef UA_NodeId UA_SessionAuthenticationToken; + +#define UA_TYPES_SESSIONAUTHENTICATIONTOKEN 168 + +/* SignatureData */ +typedef struct { + UA_String algorithm; + UA_ByteString signature; +} UA_SignatureData; + +#define UA_TYPES_SIGNATUREDATA 169 + +/* CreateSessionRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_ApplicationDescription clientDescription; + UA_String serverUri; + UA_String endpointUrl; + UA_String sessionName; + UA_ByteString clientNonce; + UA_ByteString clientCertificate; + UA_Double requestedSessionTimeout; + UA_UInt32 maxResponseMessageSize; +} UA_CreateSessionRequest; + +#define UA_TYPES_CREATESESSIONREQUEST 170 + +/* CreateSessionResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + UA_NodeId sessionId; + UA_NodeId authenticationToken; + UA_Double revisedSessionTimeout; + UA_ByteString serverNonce; + UA_ByteString serverCertificate; + size_t serverEndpointsSize; + UA_EndpointDescription *serverEndpoints; + size_t serverSoftwareCertificatesSize; + UA_SignedSoftwareCertificate *serverSoftwareCertificates; + UA_SignatureData serverSignature; + UA_UInt32 maxRequestMessageSize; +} UA_CreateSessionResponse; + +#define UA_TYPES_CREATESESSIONRESPONSE 171 + +/* UserIdentityToken */ +typedef struct { + UA_String policyId; +} UA_UserIdentityToken; + +#define UA_TYPES_USERIDENTITYTOKEN 172 + +/* AnonymousIdentityToken */ +typedef struct { + UA_String policyId; +} UA_AnonymousIdentityToken; + +#define UA_TYPES_ANONYMOUSIDENTITYTOKEN 173 + +/* UserNameIdentityToken */ +typedef struct { + UA_String policyId; + UA_String userName; + UA_ByteString password; + UA_String encryptionAlgorithm; +} UA_UserNameIdentityToken; + +#define UA_TYPES_USERNAMEIDENTITYTOKEN 174 + +/* X509IdentityToken */ +typedef struct { + UA_String policyId; + UA_ByteString certificateData; +} UA_X509IdentityToken; + +#define UA_TYPES_X509IDENTITYTOKEN 175 + +/* IssuedIdentityToken */ +typedef struct { + UA_String policyId; + UA_ByteString tokenData; + UA_String encryptionAlgorithm; +} UA_IssuedIdentityToken; + +#define UA_TYPES_ISSUEDIDENTITYTOKEN 176 + +/* RsaEncryptedSecret */ +typedef UA_ByteString UA_RsaEncryptedSecret; + +#define UA_TYPES_RSAENCRYPTEDSECRET 177 + +/* EccEncryptedSecret */ +typedef UA_ByteString UA_EccEncryptedSecret; + +#define UA_TYPES_ECCENCRYPTEDSECRET 178 + +/* ActivateSessionRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_SignatureData clientSignature; + size_t clientSoftwareCertificatesSize; + UA_SignedSoftwareCertificate *clientSoftwareCertificates; + size_t localeIdsSize; + UA_String *localeIds; + UA_ExtensionObject userIdentityToken; + UA_SignatureData userTokenSignature; +} UA_ActivateSessionRequest; + +#define UA_TYPES_ACTIVATESESSIONREQUEST 179 + +/* ActivateSessionResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + UA_ByteString serverNonce; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_ActivateSessionResponse; + +#define UA_TYPES_ACTIVATESESSIONRESPONSE 180 + +/* CloseSessionRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_Boolean deleteSubscriptions; +} UA_CloseSessionRequest; + +#define UA_TYPES_CLOSESESSIONREQUEST 181 + +/* CloseSessionResponse */ +typedef struct { + UA_ResponseHeader responseHeader; +} UA_CloseSessionResponse; + +#define UA_TYPES_CLOSESESSIONRESPONSE 182 + +/* CancelRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 requestHandle; +} UA_CancelRequest; + +#define UA_TYPES_CANCELREQUEST 183 + +/* CancelResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + UA_UInt32 cancelCount; +} UA_CancelResponse; + +#define UA_TYPES_CANCELRESPONSE 184 + +/* NodeAttributesMask */ +typedef enum { + UA_NODEATTRIBUTESMASK_NONE = 0, + UA_NODEATTRIBUTESMASK_ACCESSLEVEL = 1, + UA_NODEATTRIBUTESMASK_ARRAYDIMENSIONS = 2, + UA_NODEATTRIBUTESMASK_BROWSENAME = 4, + UA_NODEATTRIBUTESMASK_CONTAINSNOLOOPS = 8, + UA_NODEATTRIBUTESMASK_DATATYPE = 16, + UA_NODEATTRIBUTESMASK_DESCRIPTION = 32, + UA_NODEATTRIBUTESMASK_DISPLAYNAME = 64, + UA_NODEATTRIBUTESMASK_EVENTNOTIFIER = 128, + UA_NODEATTRIBUTESMASK_EXECUTABLE = 256, + UA_NODEATTRIBUTESMASK_HISTORIZING = 512, + UA_NODEATTRIBUTESMASK_INVERSENAME = 1024, + UA_NODEATTRIBUTESMASK_ISABSTRACT = 2048, + UA_NODEATTRIBUTESMASK_MINIMUMSAMPLINGINTERVAL = 4096, + UA_NODEATTRIBUTESMASK_NODECLASS = 8192, + UA_NODEATTRIBUTESMASK_NODEID = 16384, + UA_NODEATTRIBUTESMASK_SYMMETRIC = 32768, + UA_NODEATTRIBUTESMASK_USERACCESSLEVEL = 65536, + UA_NODEATTRIBUTESMASK_USEREXECUTABLE = 131072, + UA_NODEATTRIBUTESMASK_USERWRITEMASK = 262144, + UA_NODEATTRIBUTESMASK_VALUERANK = 524288, + UA_NODEATTRIBUTESMASK_WRITEMASK = 1048576, + UA_NODEATTRIBUTESMASK_VALUE = 2097152, + UA_NODEATTRIBUTESMASK_DATATYPEDEFINITION = 4194304, + UA_NODEATTRIBUTESMASK_ROLEPERMISSIONS = 8388608, + UA_NODEATTRIBUTESMASK_ACCESSRESTRICTIONS = 16777216, + UA_NODEATTRIBUTESMASK_ALL = 33554431, + UA_NODEATTRIBUTESMASK_BASENODE = 26501220, + UA_NODEATTRIBUTESMASK_OBJECT = 26501348, + UA_NODEATTRIBUTESMASK_OBJECTTYPE = 26503268, + UA_NODEATTRIBUTESMASK_VARIABLE = 26571383, + UA_NODEATTRIBUTESMASK_VARIABLETYPE = 28600438, + UA_NODEATTRIBUTESMASK_METHOD = 26632548, + UA_NODEATTRIBUTESMASK_REFERENCETYPE = 26537060, + UA_NODEATTRIBUTESMASK_VIEW = 26501356, + __UA_NODEATTRIBUTESMASK_FORCE32BIT = 0x7fffffff +} UA_NodeAttributesMask; + +UA_STATIC_ASSERT(sizeof(UA_NodeAttributesMask) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_NODEATTRIBUTESMASK 185 + +/* NodeAttributes */ +typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; +} UA_NodeAttributes; + +#define UA_TYPES_NODEATTRIBUTES 186 + +/* ObjectAttributes */ +typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Byte eventNotifier; +} UA_ObjectAttributes; + +#define UA_TYPES_OBJECTATTRIBUTES 187 + +/* VariableAttributes */ +typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Variant value; + UA_NodeId dataType; + UA_Int32 valueRank; + size_t arrayDimensionsSize; + UA_UInt32 *arrayDimensions; + UA_Byte accessLevel; + UA_Byte userAccessLevel; + UA_Double minimumSamplingInterval; + UA_Boolean historizing; +} UA_VariableAttributes; + +#define UA_TYPES_VARIABLEATTRIBUTES 188 + +/* MethodAttributes */ +typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Boolean executable; + UA_Boolean userExecutable; +} UA_MethodAttributes; + +#define UA_TYPES_METHODATTRIBUTES 189 + +/* ObjectTypeAttributes */ +typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Boolean isAbstract; +} UA_ObjectTypeAttributes; + +#define UA_TYPES_OBJECTTYPEATTRIBUTES 190 + +/* VariableTypeAttributes */ +typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Variant value; + UA_NodeId dataType; + UA_Int32 valueRank; + size_t arrayDimensionsSize; + UA_UInt32 *arrayDimensions; + UA_Boolean isAbstract; +} UA_VariableTypeAttributes; + +#define UA_TYPES_VARIABLETYPEATTRIBUTES 191 + +/* ReferenceTypeAttributes */ +typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Boolean isAbstract; + UA_Boolean symmetric; + UA_LocalizedText inverseName; +} UA_ReferenceTypeAttributes; + +#define UA_TYPES_REFERENCETYPEATTRIBUTES 192 + +/* DataTypeAttributes */ +typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Boolean isAbstract; +} UA_DataTypeAttributes; + +#define UA_TYPES_DATATYPEATTRIBUTES 193 + +/* ViewAttributes */ +typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Boolean containsNoLoops; + UA_Byte eventNotifier; +} UA_ViewAttributes; + +#define UA_TYPES_VIEWATTRIBUTES 194 + +/* GenericAttributeValue */ +typedef struct { + UA_UInt32 attributeId; + UA_Variant value; +} UA_GenericAttributeValue; + +#define UA_TYPES_GENERICATTRIBUTEVALUE 195 + +/* GenericAttributes */ +typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + size_t attributeValuesSize; + UA_GenericAttributeValue *attributeValues; +} UA_GenericAttributes; + +#define UA_TYPES_GENERICATTRIBUTES 196 + +/* AddNodesItem */ +typedef struct { + UA_ExpandedNodeId parentNodeId; + UA_NodeId referenceTypeId; + UA_ExpandedNodeId requestedNewNodeId; + UA_QualifiedName browseName; + UA_NodeClass nodeClass; + UA_ExtensionObject nodeAttributes; + UA_ExpandedNodeId typeDefinition; +} UA_AddNodesItem; + +#define UA_TYPES_ADDNODESITEM 197 + +/* AddNodesResult */ +typedef struct { + UA_StatusCode statusCode; + UA_NodeId addedNodeId; +} UA_AddNodesResult; + +#define UA_TYPES_ADDNODESRESULT 198 + +/* AddNodesRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t nodesToAddSize; + UA_AddNodesItem *nodesToAdd; +} UA_AddNodesRequest; + +#define UA_TYPES_ADDNODESREQUEST 199 + +/* AddNodesResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_AddNodesResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_AddNodesResponse; + +#define UA_TYPES_ADDNODESRESPONSE 200 + +/* AddReferencesItem */ +typedef struct { + UA_NodeId sourceNodeId; + UA_NodeId referenceTypeId; + UA_Boolean isForward; + UA_String targetServerUri; + UA_ExpandedNodeId targetNodeId; + UA_NodeClass targetNodeClass; +} UA_AddReferencesItem; + +#define UA_TYPES_ADDREFERENCESITEM 201 + +/* AddReferencesRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t referencesToAddSize; + UA_AddReferencesItem *referencesToAdd; +} UA_AddReferencesRequest; + +#define UA_TYPES_ADDREFERENCESREQUEST 202 + +/* AddReferencesResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_AddReferencesResponse; + +#define UA_TYPES_ADDREFERENCESRESPONSE 203 + +/* DeleteNodesItem */ +typedef struct { + UA_NodeId nodeId; + UA_Boolean deleteTargetReferences; +} UA_DeleteNodesItem; + +#define UA_TYPES_DELETENODESITEM 204 + +/* DeleteNodesRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t nodesToDeleteSize; + UA_DeleteNodesItem *nodesToDelete; +} UA_DeleteNodesRequest; + +#define UA_TYPES_DELETENODESREQUEST 205 + +/* DeleteNodesResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_DeleteNodesResponse; + +#define UA_TYPES_DELETENODESRESPONSE 206 + +/* DeleteReferencesItem */ +typedef struct { + UA_NodeId sourceNodeId; + UA_NodeId referenceTypeId; + UA_Boolean isForward; + UA_ExpandedNodeId targetNodeId; + UA_Boolean deleteBidirectional; +} UA_DeleteReferencesItem; + +#define UA_TYPES_DELETEREFERENCESITEM 207 + +/* DeleteReferencesRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t referencesToDeleteSize; + UA_DeleteReferencesItem *referencesToDelete; +} UA_DeleteReferencesRequest; + +#define UA_TYPES_DELETEREFERENCESREQUEST 208 + +/* DeleteReferencesResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_DeleteReferencesResponse; + +#define UA_TYPES_DELETEREFERENCESRESPONSE 209 + +/* AttributeWriteMask */ +typedef UA_UInt32 UA_AttributeWriteMask; + +#define UA_ATTRIBUTEWRITEMASK_NONE 0 +#define UA_ATTRIBUTEWRITEMASK_ACCESSLEVEL 1 +#define UA_ATTRIBUTEWRITEMASK_ARRAYDIMENSIONS 2 +#define UA_ATTRIBUTEWRITEMASK_BROWSENAME 4 +#define UA_ATTRIBUTEWRITEMASK_CONTAINSNOLOOPS 8 +#define UA_ATTRIBUTEWRITEMASK_DATATYPE 16 +#define UA_ATTRIBUTEWRITEMASK_DESCRIPTION 32 +#define UA_ATTRIBUTEWRITEMASK_DISPLAYNAME 64 +#define UA_ATTRIBUTEWRITEMASK_EVENTNOTIFIER 128 +#define UA_ATTRIBUTEWRITEMASK_EXECUTABLE 256 +#define UA_ATTRIBUTEWRITEMASK_HISTORIZING 512 +#define UA_ATTRIBUTEWRITEMASK_INVERSENAME 1024 +#define UA_ATTRIBUTEWRITEMASK_ISABSTRACT 2048 +#define UA_ATTRIBUTEWRITEMASK_MINIMUMSAMPLINGINTERVAL 4096 +#define UA_ATTRIBUTEWRITEMASK_NODECLASS 8192 +#define UA_ATTRIBUTEWRITEMASK_NODEID 16384 +#define UA_ATTRIBUTEWRITEMASK_SYMMETRIC 32768 +#define UA_ATTRIBUTEWRITEMASK_USERACCESSLEVEL 65536 +#define UA_ATTRIBUTEWRITEMASK_USEREXECUTABLE 131072 +#define UA_ATTRIBUTEWRITEMASK_USERWRITEMASK 262144 +#define UA_ATTRIBUTEWRITEMASK_VALUERANK 524288 +#define UA_ATTRIBUTEWRITEMASK_WRITEMASK 1048576 +#define UA_ATTRIBUTEWRITEMASK_VALUEFORVARIABLETYPE 2097152 +#define UA_ATTRIBUTEWRITEMASK_DATATYPEDEFINITION 4194304 +#define UA_ATTRIBUTEWRITEMASK_ROLEPERMISSIONS 8388608 +#define UA_ATTRIBUTEWRITEMASK_ACCESSRESTRICTIONS 16777216 +#define UA_ATTRIBUTEWRITEMASK_ACCESSLEVELEX 33554432 + +#define UA_TYPES_ATTRIBUTEWRITEMASK 210 + +/* BrowseDirection */ +typedef enum { + UA_BROWSEDIRECTION_FORWARD = 0, + UA_BROWSEDIRECTION_INVERSE = 1, + UA_BROWSEDIRECTION_BOTH = 2, + UA_BROWSEDIRECTION_INVALID = 3, + __UA_BROWSEDIRECTION_FORCE32BIT = 0x7fffffff +} UA_BrowseDirection; + +UA_STATIC_ASSERT(sizeof(UA_BrowseDirection) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_BROWSEDIRECTION 211 + +/* ViewDescription */ +typedef struct { + UA_NodeId viewId; + UA_DateTime timestamp; + UA_UInt32 viewVersion; +} UA_ViewDescription; + +#define UA_TYPES_VIEWDESCRIPTION 212 + +/* BrowseDescription */ +typedef struct { + UA_NodeId nodeId; + UA_BrowseDirection browseDirection; + UA_NodeId referenceTypeId; + UA_Boolean includeSubtypes; + UA_UInt32 nodeClassMask; + UA_UInt32 resultMask; +} UA_BrowseDescription; + +#define UA_TYPES_BROWSEDESCRIPTION 213 + +/* BrowseResultMask */ +typedef enum { + UA_BROWSERESULTMASK_NONE = 0, + UA_BROWSERESULTMASK_REFERENCETYPEID = 1, + UA_BROWSERESULTMASK_ISFORWARD = 2, + UA_BROWSERESULTMASK_NODECLASS = 4, + UA_BROWSERESULTMASK_BROWSENAME = 8, + UA_BROWSERESULTMASK_DISPLAYNAME = 16, + UA_BROWSERESULTMASK_TYPEDEFINITION = 32, + UA_BROWSERESULTMASK_ALL = 63, + UA_BROWSERESULTMASK_REFERENCETYPEINFO = 3, + UA_BROWSERESULTMASK_TARGETINFO = 60, + __UA_BROWSERESULTMASK_FORCE32BIT = 0x7fffffff +} UA_BrowseResultMask; + +UA_STATIC_ASSERT(sizeof(UA_BrowseResultMask) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_BROWSERESULTMASK 214 + +/* ReferenceDescription */ +typedef struct { + UA_NodeId referenceTypeId; + UA_Boolean isForward; + UA_ExpandedNodeId nodeId; + UA_QualifiedName browseName; + UA_LocalizedText displayName; + UA_NodeClass nodeClass; + UA_ExpandedNodeId typeDefinition; +} UA_ReferenceDescription; + +#define UA_TYPES_REFERENCEDESCRIPTION 215 + +/* ContinuationPoint */ +typedef UA_ByteString UA_ContinuationPoint; + +#define UA_TYPES_CONTINUATIONPOINT 216 + +/* BrowseResult */ +typedef struct { + UA_StatusCode statusCode; + UA_ByteString continuationPoint; + size_t referencesSize; + UA_ReferenceDescription *references; +} UA_BrowseResult; + +#define UA_TYPES_BROWSERESULT 217 + +/* BrowseRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_ViewDescription view; + UA_UInt32 requestedMaxReferencesPerNode; + size_t nodesToBrowseSize; + UA_BrowseDescription *nodesToBrowse; +} UA_BrowseRequest; + +#define UA_TYPES_BROWSEREQUEST 218 + +/* BrowseResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_BrowseResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_BrowseResponse; + +#define UA_TYPES_BROWSERESPONSE 219 + +/* BrowseNextRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_Boolean releaseContinuationPoints; + size_t continuationPointsSize; + UA_ByteString *continuationPoints; +} UA_BrowseNextRequest; + +#define UA_TYPES_BROWSENEXTREQUEST 220 + +/* BrowseNextResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_BrowseResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_BrowseNextResponse; + +#define UA_TYPES_BROWSENEXTRESPONSE 221 + +/* RelativePathElement */ +typedef struct { + UA_NodeId referenceTypeId; + UA_Boolean isInverse; + UA_Boolean includeSubtypes; + UA_QualifiedName targetName; +} UA_RelativePathElement; + +#define UA_TYPES_RELATIVEPATHELEMENT 222 + +/* RelativePath */ +typedef struct { + size_t elementsSize; + UA_RelativePathElement *elements; +} UA_RelativePath; + +#define UA_TYPES_RELATIVEPATH 223 + +/* BrowsePath */ +typedef struct { + UA_NodeId startingNode; + UA_RelativePath relativePath; +} UA_BrowsePath; + +#define UA_TYPES_BROWSEPATH 224 + +/* BrowsePathTarget */ +typedef struct { + UA_ExpandedNodeId targetId; + UA_UInt32 remainingPathIndex; +} UA_BrowsePathTarget; + +#define UA_TYPES_BROWSEPATHTARGET 225 + +/* BrowsePathResult */ +typedef struct { + UA_StatusCode statusCode; + size_t targetsSize; + UA_BrowsePathTarget *targets; +} UA_BrowsePathResult; + +#define UA_TYPES_BROWSEPATHRESULT 226 + +/* TranslateBrowsePathsToNodeIdsRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t browsePathsSize; + UA_BrowsePath *browsePaths; +} UA_TranslateBrowsePathsToNodeIdsRequest; + +#define UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST 227 + +/* TranslateBrowsePathsToNodeIdsResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_BrowsePathResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_TranslateBrowsePathsToNodeIdsResponse; + +#define UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE 228 + +/* RegisterNodesRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t nodesToRegisterSize; + UA_NodeId *nodesToRegister; +} UA_RegisterNodesRequest; + +#define UA_TYPES_REGISTERNODESREQUEST 229 + +/* RegisterNodesResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t registeredNodeIdsSize; + UA_NodeId *registeredNodeIds; +} UA_RegisterNodesResponse; + +#define UA_TYPES_REGISTERNODESRESPONSE 230 + +/* UnregisterNodesRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t nodesToUnregisterSize; + UA_NodeId *nodesToUnregister; +} UA_UnregisterNodesRequest; + +#define UA_TYPES_UNREGISTERNODESREQUEST 231 + +/* UnregisterNodesResponse */ +typedef struct { + UA_ResponseHeader responseHeader; +} UA_UnregisterNodesResponse; + +#define UA_TYPES_UNREGISTERNODESRESPONSE 232 + +/* Counter */ +typedef UA_UInt32 UA_Counter; + +#define UA_TYPES_COUNTER 233 + +/* OpaqueNumericRange */ +typedef UA_String UA_OpaqueNumericRange; + +#define UA_TYPES_OPAQUENUMERICRANGE 234 + +/* EndpointConfiguration */ +typedef struct { + UA_Int32 operationTimeout; + UA_Boolean useBinaryEncoding; + UA_Int32 maxStringLength; + UA_Int32 maxByteStringLength; + UA_Int32 maxArrayLength; + UA_Int32 maxMessageSize; + UA_Int32 maxBufferSize; + UA_Int32 channelLifetime; + UA_Int32 securityTokenLifetime; +} UA_EndpointConfiguration; + +#define UA_TYPES_ENDPOINTCONFIGURATION 235 + +/* QueryDataDescription */ +typedef struct { + UA_RelativePath relativePath; + UA_UInt32 attributeId; + UA_String indexRange; +} UA_QueryDataDescription; + +#define UA_TYPES_QUERYDATADESCRIPTION 236 + +/* NodeTypeDescription */ +typedef struct { + UA_ExpandedNodeId typeDefinitionNode; + UA_Boolean includeSubTypes; + size_t dataToReturnSize; + UA_QueryDataDescription *dataToReturn; +} UA_NodeTypeDescription; + +#define UA_TYPES_NODETYPEDESCRIPTION 237 + +/* FilterOperator */ +typedef enum { + UA_FILTEROPERATOR_EQUALS = 0, + UA_FILTEROPERATOR_ISNULL = 1, + UA_FILTEROPERATOR_GREATERTHAN = 2, + UA_FILTEROPERATOR_LESSTHAN = 3, + UA_FILTEROPERATOR_GREATERTHANOREQUAL = 4, + UA_FILTEROPERATOR_LESSTHANOREQUAL = 5, + UA_FILTEROPERATOR_LIKE = 6, + UA_FILTEROPERATOR_NOT = 7, + UA_FILTEROPERATOR_BETWEEN = 8, + UA_FILTEROPERATOR_INLIST = 9, + UA_FILTEROPERATOR_AND = 10, + UA_FILTEROPERATOR_OR = 11, + UA_FILTEROPERATOR_CAST = 12, + UA_FILTEROPERATOR_INVIEW = 13, + UA_FILTEROPERATOR_OFTYPE = 14, + UA_FILTEROPERATOR_RELATEDTO = 15, + UA_FILTEROPERATOR_BITWISEAND = 16, + UA_FILTEROPERATOR_BITWISEOR = 17, + __UA_FILTEROPERATOR_FORCE32BIT = 0x7fffffff +} UA_FilterOperator; + +UA_STATIC_ASSERT(sizeof(UA_FilterOperator) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_FILTEROPERATOR 238 + +/* QueryDataSet */ +typedef struct { + UA_ExpandedNodeId nodeId; + UA_ExpandedNodeId typeDefinitionNode; + size_t valuesSize; + UA_Variant *values; +} UA_QueryDataSet; + +#define UA_TYPES_QUERYDATASET 239 + +/* NodeReference */ +typedef struct { + UA_NodeId nodeId; + UA_NodeId referenceTypeId; + UA_Boolean isForward; + size_t referencedNodeIdsSize; + UA_NodeId *referencedNodeIds; +} UA_NodeReference; + +#define UA_TYPES_NODEREFERENCE 240 + +/* ContentFilterElement */ +typedef struct { + UA_FilterOperator filterOperator; + size_t filterOperandsSize; + UA_ExtensionObject *filterOperands; +} UA_ContentFilterElement; + +#define UA_TYPES_CONTENTFILTERELEMENT 241 + +/* ContentFilter */ +typedef struct { + size_t elementsSize; + UA_ContentFilterElement *elements; +} UA_ContentFilter; + +#define UA_TYPES_CONTENTFILTER 242 + +/* ElementOperand */ +typedef struct { + UA_UInt32 index; +} UA_ElementOperand; + +#define UA_TYPES_ELEMENTOPERAND 243 + +/* LiteralOperand */ +typedef struct { + UA_Variant value; +} UA_LiteralOperand; + +#define UA_TYPES_LITERALOPERAND 244 + +/* AttributeOperand */ +typedef struct { + UA_NodeId nodeId; + UA_String alias; + UA_RelativePath browsePath; + UA_UInt32 attributeId; + UA_String indexRange; +} UA_AttributeOperand; + +#define UA_TYPES_ATTRIBUTEOPERAND 245 + +/* SimpleAttributeOperand */ +typedef struct { + UA_NodeId typeDefinitionId; + size_t browsePathSize; + UA_QualifiedName *browsePath; + UA_UInt32 attributeId; + UA_String indexRange; +} UA_SimpleAttributeOperand; + +#define UA_TYPES_SIMPLEATTRIBUTEOPERAND 246 + +/* ContentFilterElementResult */ +typedef struct { + UA_StatusCode statusCode; + size_t operandStatusCodesSize; + UA_StatusCode *operandStatusCodes; + size_t operandDiagnosticInfosSize; + UA_DiagnosticInfo *operandDiagnosticInfos; +} UA_ContentFilterElementResult; + +#define UA_TYPES_CONTENTFILTERELEMENTRESULT 247 + +/* ContentFilterResult */ +typedef struct { + size_t elementResultsSize; + UA_ContentFilterElementResult *elementResults; + size_t elementDiagnosticInfosSize; + UA_DiagnosticInfo *elementDiagnosticInfos; +} UA_ContentFilterResult; + +#define UA_TYPES_CONTENTFILTERRESULT 248 + +/* ParsingResult */ +typedef struct { + UA_StatusCode statusCode; + size_t dataStatusCodesSize; + UA_StatusCode *dataStatusCodes; + size_t dataDiagnosticInfosSize; + UA_DiagnosticInfo *dataDiagnosticInfos; +} UA_ParsingResult; + +#define UA_TYPES_PARSINGRESULT 249 + +/* QueryFirstRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_ViewDescription view; + size_t nodeTypesSize; + UA_NodeTypeDescription *nodeTypes; + UA_ContentFilter filter; + UA_UInt32 maxDataSetsToReturn; + UA_UInt32 maxReferencesToReturn; +} UA_QueryFirstRequest; + +#define UA_TYPES_QUERYFIRSTREQUEST 250 + +/* QueryFirstResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t queryDataSetsSize; + UA_QueryDataSet *queryDataSets; + UA_ByteString continuationPoint; + size_t parsingResultsSize; + UA_ParsingResult *parsingResults; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + UA_ContentFilterResult filterResult; +} UA_QueryFirstResponse; + +#define UA_TYPES_QUERYFIRSTRESPONSE 251 + +/* QueryNextRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_Boolean releaseContinuationPoint; + UA_ByteString continuationPoint; +} UA_QueryNextRequest; + +#define UA_TYPES_QUERYNEXTREQUEST 252 + +/* QueryNextResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t queryDataSetsSize; + UA_QueryDataSet *queryDataSets; + UA_ByteString revisedContinuationPoint; +} UA_QueryNextResponse; + +#define UA_TYPES_QUERYNEXTRESPONSE 253 + +/* TimestampsToReturn */ +typedef enum { + UA_TIMESTAMPSTORETURN_SOURCE = 0, + UA_TIMESTAMPSTORETURN_SERVER = 1, + UA_TIMESTAMPSTORETURN_BOTH = 2, + UA_TIMESTAMPSTORETURN_NEITHER = 3, + UA_TIMESTAMPSTORETURN_INVALID = 4, + __UA_TIMESTAMPSTORETURN_FORCE32BIT = 0x7fffffff +} UA_TimestampsToReturn; + +UA_STATIC_ASSERT(sizeof(UA_TimestampsToReturn) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_TIMESTAMPSTORETURN 254 + +/* ReadValueId */ +typedef struct { + UA_NodeId nodeId; + UA_UInt32 attributeId; + UA_String indexRange; + UA_QualifiedName dataEncoding; +} UA_ReadValueId; + +#define UA_TYPES_READVALUEID 255 + +/* ReadRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_Double maxAge; + UA_TimestampsToReturn timestampsToReturn; + size_t nodesToReadSize; + UA_ReadValueId *nodesToRead; +} UA_ReadRequest; + +#define UA_TYPES_READREQUEST 256 + +/* ReadResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_DataValue *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_ReadResponse; + +#define UA_TYPES_READRESPONSE 257 + +/* HistoryReadValueId */ +typedef struct { + UA_NodeId nodeId; + UA_String indexRange; + UA_QualifiedName dataEncoding; + UA_ByteString continuationPoint; +} UA_HistoryReadValueId; + +#define UA_TYPES_HISTORYREADVALUEID 258 + +/* HistoryReadResult */ +typedef struct { + UA_StatusCode statusCode; + UA_ByteString continuationPoint; + UA_ExtensionObject historyData; +} UA_HistoryReadResult; + +#define UA_TYPES_HISTORYREADRESULT 259 + +/* ReadRawModifiedDetails */ +typedef struct { + UA_Boolean isReadModified; + UA_DateTime startTime; + UA_DateTime endTime; + UA_UInt32 numValuesPerNode; + UA_Boolean returnBounds; +} UA_ReadRawModifiedDetails; + +#define UA_TYPES_READRAWMODIFIEDDETAILS 260 + +/* ReadAtTimeDetails */ +typedef struct { + size_t reqTimesSize; + UA_DateTime *reqTimes; + UA_Boolean useSimpleBounds; +} UA_ReadAtTimeDetails; + +#define UA_TYPES_READATTIMEDETAILS 261 + +/* ReadAnnotationDataDetails */ +typedef struct { + size_t reqTimesSize; + UA_DateTime *reqTimes; +} UA_ReadAnnotationDataDetails; + +#define UA_TYPES_READANNOTATIONDATADETAILS 262 + +/* HistoryData */ +typedef struct { + size_t dataValuesSize; + UA_DataValue *dataValues; +} UA_HistoryData; + +#define UA_TYPES_HISTORYDATA 263 + +/* HistoryReadRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_ExtensionObject historyReadDetails; + UA_TimestampsToReturn timestampsToReturn; + UA_Boolean releaseContinuationPoints; + size_t nodesToReadSize; + UA_HistoryReadValueId *nodesToRead; +} UA_HistoryReadRequest; + +#define UA_TYPES_HISTORYREADREQUEST 264 + +/* HistoryReadResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_HistoryReadResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_HistoryReadResponse; + +#define UA_TYPES_HISTORYREADRESPONSE 265 + +/* WriteValue */ +typedef struct { + UA_NodeId nodeId; + UA_UInt32 attributeId; + UA_String indexRange; + UA_DataValue value; +} UA_WriteValue; + +#define UA_TYPES_WRITEVALUE 266 + +/* WriteRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t nodesToWriteSize; + UA_WriteValue *nodesToWrite; +} UA_WriteRequest; + +#define UA_TYPES_WRITEREQUEST 267 + +/* WriteResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_WriteResponse; + +#define UA_TYPES_WRITERESPONSE 268 + +/* HistoryUpdateDetails */ +typedef struct { + UA_NodeId nodeId; +} UA_HistoryUpdateDetails; + +#define UA_TYPES_HISTORYUPDATEDETAILS 269 + +/* HistoryUpdateType */ +typedef enum { + UA_HISTORYUPDATETYPE_INSERT = 1, + UA_HISTORYUPDATETYPE_REPLACE = 2, + UA_HISTORYUPDATETYPE_UPDATE = 3, + UA_HISTORYUPDATETYPE_DELETE = 4, + __UA_HISTORYUPDATETYPE_FORCE32BIT = 0x7fffffff +} UA_HistoryUpdateType; + +UA_STATIC_ASSERT(sizeof(UA_HistoryUpdateType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_HISTORYUPDATETYPE 270 + +/* PerformUpdateType */ +typedef enum { + UA_PERFORMUPDATETYPE_INSERT = 1, + UA_PERFORMUPDATETYPE_REPLACE = 2, + UA_PERFORMUPDATETYPE_UPDATE = 3, + UA_PERFORMUPDATETYPE_REMOVE = 4, + __UA_PERFORMUPDATETYPE_FORCE32BIT = 0x7fffffff +} UA_PerformUpdateType; + +UA_STATIC_ASSERT(sizeof(UA_PerformUpdateType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_PERFORMUPDATETYPE 271 + +/* UpdateDataDetails */ +typedef struct { + UA_NodeId nodeId; + UA_PerformUpdateType performInsertReplace; + size_t updateValuesSize; + UA_DataValue *updateValues; +} UA_UpdateDataDetails; + +#define UA_TYPES_UPDATEDATADETAILS 272 + +/* UpdateStructureDataDetails */ +typedef struct { + UA_NodeId nodeId; + UA_PerformUpdateType performInsertReplace; + size_t updateValuesSize; + UA_DataValue *updateValues; +} UA_UpdateStructureDataDetails; + +#define UA_TYPES_UPDATESTRUCTUREDATADETAILS 273 + +/* DeleteRawModifiedDetails */ +typedef struct { + UA_NodeId nodeId; + UA_Boolean isDeleteModified; + UA_DateTime startTime; + UA_DateTime endTime; +} UA_DeleteRawModifiedDetails; + +#define UA_TYPES_DELETERAWMODIFIEDDETAILS 274 + +/* DeleteAtTimeDetails */ +typedef struct { + UA_NodeId nodeId; + size_t reqTimesSize; + UA_DateTime *reqTimes; +} UA_DeleteAtTimeDetails; + +#define UA_TYPES_DELETEATTIMEDETAILS 275 + +/* DeleteEventDetails */ +typedef struct { + UA_NodeId nodeId; + size_t eventIdsSize; + UA_ByteString *eventIds; +} UA_DeleteEventDetails; + +#define UA_TYPES_DELETEEVENTDETAILS 276 + +/* HistoryUpdateResult */ +typedef struct { + UA_StatusCode statusCode; + size_t operationResultsSize; + UA_StatusCode *operationResults; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_HistoryUpdateResult; + +#define UA_TYPES_HISTORYUPDATERESULT 277 + +/* HistoryUpdateRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t historyUpdateDetailsSize; + UA_ExtensionObject *historyUpdateDetails; +} UA_HistoryUpdateRequest; + +#define UA_TYPES_HISTORYUPDATEREQUEST 278 + +/* HistoryUpdateResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_HistoryUpdateResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_HistoryUpdateResponse; + +#define UA_TYPES_HISTORYUPDATERESPONSE 279 + +/* CallMethodRequest */ +typedef struct { + UA_NodeId objectId; + UA_NodeId methodId; + size_t inputArgumentsSize; + UA_Variant *inputArguments; +} UA_CallMethodRequest; + +#define UA_TYPES_CALLMETHODREQUEST 280 + +/* CallMethodResult */ +typedef struct { + UA_StatusCode statusCode; + size_t inputArgumentResultsSize; + UA_StatusCode *inputArgumentResults; + size_t inputArgumentDiagnosticInfosSize; + UA_DiagnosticInfo *inputArgumentDiagnosticInfos; + size_t outputArgumentsSize; + UA_Variant *outputArguments; +} UA_CallMethodResult; + +#define UA_TYPES_CALLMETHODRESULT 281 + +/* CallRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t methodsToCallSize; + UA_CallMethodRequest *methodsToCall; +} UA_CallRequest; + +#define UA_TYPES_CALLREQUEST 282 + +/* CallResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_CallMethodResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_CallResponse; + +#define UA_TYPES_CALLRESPONSE 283 + +/* MonitoringMode */ +typedef enum { + UA_MONITORINGMODE_DISABLED = 0, + UA_MONITORINGMODE_SAMPLING = 1, + UA_MONITORINGMODE_REPORTING = 2, + __UA_MONITORINGMODE_FORCE32BIT = 0x7fffffff +} UA_MonitoringMode; + +UA_STATIC_ASSERT(sizeof(UA_MonitoringMode) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_MONITORINGMODE 284 + +/* DataChangeTrigger */ +typedef enum { + UA_DATACHANGETRIGGER_STATUS = 0, + UA_DATACHANGETRIGGER_STATUSVALUE = 1, + UA_DATACHANGETRIGGER_STATUSVALUETIMESTAMP = 2, + __UA_DATACHANGETRIGGER_FORCE32BIT = 0x7fffffff +} UA_DataChangeTrigger; + +UA_STATIC_ASSERT(sizeof(UA_DataChangeTrigger) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_DATACHANGETRIGGER 285 + +/* DeadbandType */ +typedef enum { + UA_DEADBANDTYPE_NONE = 0, + UA_DEADBANDTYPE_ABSOLUTE = 1, + UA_DEADBANDTYPE_PERCENT = 2, + __UA_DEADBANDTYPE_FORCE32BIT = 0x7fffffff +} UA_DeadbandType; + +UA_STATIC_ASSERT(sizeof(UA_DeadbandType) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_DEADBANDTYPE 286 + +/* DataChangeFilter */ +typedef struct { + UA_DataChangeTrigger trigger; + UA_UInt32 deadbandType; + UA_Double deadbandValue; +} UA_DataChangeFilter; + +#define UA_TYPES_DATACHANGEFILTER 287 + +/* EventFilter */ +typedef struct { + size_t selectClausesSize; + UA_SimpleAttributeOperand *selectClauses; + UA_ContentFilter whereClause; +} UA_EventFilter; + +#define UA_TYPES_EVENTFILTER 288 + +/* AggregateConfiguration */ +typedef struct { + UA_Boolean useServerCapabilitiesDefaults; + UA_Boolean treatUncertainAsBad; + UA_Byte percentDataBad; + UA_Byte percentDataGood; + UA_Boolean useSlopedExtrapolation; +} UA_AggregateConfiguration; + +#define UA_TYPES_AGGREGATECONFIGURATION 289 + +/* AggregateFilter */ +typedef struct { + UA_DateTime startTime; + UA_NodeId aggregateType; + UA_Double processingInterval; + UA_AggregateConfiguration aggregateConfiguration; +} UA_AggregateFilter; + +#define UA_TYPES_AGGREGATEFILTER 290 + +/* EventFilterResult */ +typedef struct { + size_t selectClauseResultsSize; + UA_StatusCode *selectClauseResults; + size_t selectClauseDiagnosticInfosSize; + UA_DiagnosticInfo *selectClauseDiagnosticInfos; + UA_ContentFilterResult whereClauseResult; +} UA_EventFilterResult; + +#define UA_TYPES_EVENTFILTERRESULT 291 + +/* AggregateFilterResult */ +typedef struct { + UA_DateTime revisedStartTime; + UA_Double revisedProcessingInterval; + UA_AggregateConfiguration revisedAggregateConfiguration; +} UA_AggregateFilterResult; + +#define UA_TYPES_AGGREGATEFILTERRESULT 292 + +/* MonitoringParameters */ +typedef struct { + UA_UInt32 clientHandle; + UA_Double samplingInterval; + UA_ExtensionObject filter; + UA_UInt32 queueSize; + UA_Boolean discardOldest; +} UA_MonitoringParameters; + +#define UA_TYPES_MONITORINGPARAMETERS 293 + +/* MonitoredItemCreateRequest */ +typedef struct { + UA_ReadValueId itemToMonitor; + UA_MonitoringMode monitoringMode; + UA_MonitoringParameters requestedParameters; +} UA_MonitoredItemCreateRequest; + +#define UA_TYPES_MONITOREDITEMCREATEREQUEST 294 + +/* MonitoredItemCreateResult */ +typedef struct { + UA_StatusCode statusCode; + UA_UInt32 monitoredItemId; + UA_Double revisedSamplingInterval; + UA_UInt32 revisedQueueSize; + UA_ExtensionObject filterResult; +} UA_MonitoredItemCreateResult; + +#define UA_TYPES_MONITOREDITEMCREATERESULT 295 + +/* CreateMonitoredItemsRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + UA_TimestampsToReturn timestampsToReturn; + size_t itemsToCreateSize; + UA_MonitoredItemCreateRequest *itemsToCreate; +} UA_CreateMonitoredItemsRequest; + +#define UA_TYPES_CREATEMONITOREDITEMSREQUEST 296 + +/* CreateMonitoredItemsResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_MonitoredItemCreateResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_CreateMonitoredItemsResponse; + +#define UA_TYPES_CREATEMONITOREDITEMSRESPONSE 297 + +/* MonitoredItemModifyRequest */ +typedef struct { + UA_UInt32 monitoredItemId; + UA_MonitoringParameters requestedParameters; +} UA_MonitoredItemModifyRequest; + +#define UA_TYPES_MONITOREDITEMMODIFYREQUEST 298 + +/* MonitoredItemModifyResult */ +typedef struct { + UA_StatusCode statusCode; + UA_Double revisedSamplingInterval; + UA_UInt32 revisedQueueSize; + UA_ExtensionObject filterResult; +} UA_MonitoredItemModifyResult; + +#define UA_TYPES_MONITOREDITEMMODIFYRESULT 299 + +/* ModifyMonitoredItemsRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + UA_TimestampsToReturn timestampsToReturn; + size_t itemsToModifySize; + UA_MonitoredItemModifyRequest *itemsToModify; +} UA_ModifyMonitoredItemsRequest; + +#define UA_TYPES_MODIFYMONITOREDITEMSREQUEST 300 + +/* ModifyMonitoredItemsResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_MonitoredItemModifyResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_ModifyMonitoredItemsResponse; + +#define UA_TYPES_MODIFYMONITOREDITEMSRESPONSE 301 + +/* SetMonitoringModeRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + UA_MonitoringMode monitoringMode; + size_t monitoredItemIdsSize; + UA_UInt32 *monitoredItemIds; +} UA_SetMonitoringModeRequest; + +#define UA_TYPES_SETMONITORINGMODEREQUEST 302 + +/* SetMonitoringModeResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_SetMonitoringModeResponse; + +#define UA_TYPES_SETMONITORINGMODERESPONSE 303 + +/* SetTriggeringRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + UA_UInt32 triggeringItemId; + size_t linksToAddSize; + UA_UInt32 *linksToAdd; + size_t linksToRemoveSize; + UA_UInt32 *linksToRemove; +} UA_SetTriggeringRequest; + +#define UA_TYPES_SETTRIGGERINGREQUEST 304 + +/* SetTriggeringResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t addResultsSize; + UA_StatusCode *addResults; + size_t addDiagnosticInfosSize; + UA_DiagnosticInfo *addDiagnosticInfos; + size_t removeResultsSize; + UA_StatusCode *removeResults; + size_t removeDiagnosticInfosSize; + UA_DiagnosticInfo *removeDiagnosticInfos; +} UA_SetTriggeringResponse; + +#define UA_TYPES_SETTRIGGERINGRESPONSE 305 + +/* DeleteMonitoredItemsRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + size_t monitoredItemIdsSize; + UA_UInt32 *monitoredItemIds; +} UA_DeleteMonitoredItemsRequest; + +#define UA_TYPES_DELETEMONITOREDITEMSREQUEST 306 + +/* DeleteMonitoredItemsResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_DeleteMonitoredItemsResponse; + +#define UA_TYPES_DELETEMONITOREDITEMSRESPONSE 307 + +/* CreateSubscriptionRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_Double requestedPublishingInterval; + UA_UInt32 requestedLifetimeCount; + UA_UInt32 requestedMaxKeepAliveCount; + UA_UInt32 maxNotificationsPerPublish; + UA_Boolean publishingEnabled; + UA_Byte priority; +} UA_CreateSubscriptionRequest; + +#define UA_TYPES_CREATESUBSCRIPTIONREQUEST 308 + +/* CreateSubscriptionResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + UA_UInt32 subscriptionId; + UA_Double revisedPublishingInterval; + UA_UInt32 revisedLifetimeCount; + UA_UInt32 revisedMaxKeepAliveCount; +} UA_CreateSubscriptionResponse; + +#define UA_TYPES_CREATESUBSCRIPTIONRESPONSE 309 + +/* ModifySubscriptionRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + UA_Double requestedPublishingInterval; + UA_UInt32 requestedLifetimeCount; + UA_UInt32 requestedMaxKeepAliveCount; + UA_UInt32 maxNotificationsPerPublish; + UA_Byte priority; +} UA_ModifySubscriptionRequest; + +#define UA_TYPES_MODIFYSUBSCRIPTIONREQUEST 310 + +/* ModifySubscriptionResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + UA_Double revisedPublishingInterval; + UA_UInt32 revisedLifetimeCount; + UA_UInt32 revisedMaxKeepAliveCount; +} UA_ModifySubscriptionResponse; + +#define UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE 311 + +/* SetPublishingModeRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_Boolean publishingEnabled; + size_t subscriptionIdsSize; + UA_UInt32 *subscriptionIds; +} UA_SetPublishingModeRequest; + +#define UA_TYPES_SETPUBLISHINGMODEREQUEST 312 + +/* SetPublishingModeResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_SetPublishingModeResponse; + +#define UA_TYPES_SETPUBLISHINGMODERESPONSE 313 + +/* NotificationMessage */ +typedef struct { + UA_UInt32 sequenceNumber; + UA_DateTime publishTime; + size_t notificationDataSize; + UA_ExtensionObject *notificationData; +} UA_NotificationMessage; + +#define UA_TYPES_NOTIFICATIONMESSAGE 314 + +/* MonitoredItemNotification */ +typedef struct { + UA_UInt32 clientHandle; + UA_DataValue value; +} UA_MonitoredItemNotification; + +#define UA_TYPES_MONITOREDITEMNOTIFICATION 315 + +/* EventFieldList */ +typedef struct { + UA_UInt32 clientHandle; + size_t eventFieldsSize; + UA_Variant *eventFields; +} UA_EventFieldList; + +#define UA_TYPES_EVENTFIELDLIST 316 + +/* HistoryEventFieldList */ +typedef struct { + size_t eventFieldsSize; + UA_Variant *eventFields; +} UA_HistoryEventFieldList; + +#define UA_TYPES_HISTORYEVENTFIELDLIST 317 + +/* StatusChangeNotification */ +typedef struct { + UA_StatusCode status; + UA_DiagnosticInfo diagnosticInfo; +} UA_StatusChangeNotification; + +#define UA_TYPES_STATUSCHANGENOTIFICATION 318 + +/* SubscriptionAcknowledgement */ +typedef struct { + UA_UInt32 subscriptionId; + UA_UInt32 sequenceNumber; +} UA_SubscriptionAcknowledgement; + +#define UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT 319 + +/* PublishRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t subscriptionAcknowledgementsSize; + UA_SubscriptionAcknowledgement *subscriptionAcknowledgements; +} UA_PublishRequest; + +#define UA_TYPES_PUBLISHREQUEST 320 + +/* PublishResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + UA_UInt32 subscriptionId; + size_t availableSequenceNumbersSize; + UA_UInt32 *availableSequenceNumbers; + UA_Boolean moreNotifications; + UA_NotificationMessage notificationMessage; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_PublishResponse; + +#define UA_TYPES_PUBLISHRESPONSE 321 + +/* RepublishRequest */ +typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + UA_UInt32 retransmitSequenceNumber; +} UA_RepublishRequest; + +#define UA_TYPES_REPUBLISHREQUEST 322 + +/* RepublishResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + UA_NotificationMessage notificationMessage; +} UA_RepublishResponse; + +#define UA_TYPES_REPUBLISHRESPONSE 323 + +/* TransferResult */ +typedef struct { + UA_StatusCode statusCode; + size_t availableSequenceNumbersSize; + UA_UInt32 *availableSequenceNumbers; +} UA_TransferResult; + +#define UA_TYPES_TRANSFERRESULT 324 + +/* TransferSubscriptionsRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t subscriptionIdsSize; + UA_UInt32 *subscriptionIds; + UA_Boolean sendInitialValues; +} UA_TransferSubscriptionsRequest; + +#define UA_TYPES_TRANSFERSUBSCRIPTIONSREQUEST 325 + +/* TransferSubscriptionsResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_TransferResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_TransferSubscriptionsResponse; + +#define UA_TYPES_TRANSFERSUBSCRIPTIONSRESPONSE 326 + +/* DeleteSubscriptionsRequest */ +typedef struct { + UA_RequestHeader requestHeader; + size_t subscriptionIdsSize; + UA_UInt32 *subscriptionIds; +} UA_DeleteSubscriptionsRequest; + +#define UA_TYPES_DELETESUBSCRIPTIONSREQUEST 327 + +/* DeleteSubscriptionsResponse */ +typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_DeleteSubscriptionsResponse; + +#define UA_TYPES_DELETESUBSCRIPTIONSRESPONSE 328 + +/* BuildInfo */ +typedef struct { + UA_String productUri; + UA_String manufacturerName; + UA_String productName; + UA_String softwareVersion; + UA_String buildNumber; + UA_DateTime buildDate; +} UA_BuildInfo; + +#define UA_TYPES_BUILDINFO 329 + +/* RedundancySupport */ +typedef enum { + UA_REDUNDANCYSUPPORT_NONE = 0, + UA_REDUNDANCYSUPPORT_COLD = 1, + UA_REDUNDANCYSUPPORT_WARM = 2, + UA_REDUNDANCYSUPPORT_HOT = 3, + UA_REDUNDANCYSUPPORT_TRANSPARENT = 4, + UA_REDUNDANCYSUPPORT_HOTANDMIRRORED = 5, + __UA_REDUNDANCYSUPPORT_FORCE32BIT = 0x7fffffff +} UA_RedundancySupport; + +UA_STATIC_ASSERT(sizeof(UA_RedundancySupport) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_REDUNDANCYSUPPORT 330 + +/* ServerState */ +typedef enum { + UA_SERVERSTATE_RUNNING = 0, + UA_SERVERSTATE_FAILED = 1, + UA_SERVERSTATE_NOCONFIGURATION = 2, + UA_SERVERSTATE_SUSPENDED = 3, + UA_SERVERSTATE_SHUTDOWN = 4, + UA_SERVERSTATE_TEST = 5, + UA_SERVERSTATE_COMMUNICATIONFAULT = 6, + UA_SERVERSTATE_UNKNOWN = 7, + __UA_SERVERSTATE_FORCE32BIT = 0x7fffffff +} UA_ServerState; + +UA_STATIC_ASSERT(sizeof(UA_ServerState) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_SERVERSTATE 331 + +/* RedundantServerDataType */ +typedef struct { + UA_String serverId; + UA_Byte serviceLevel; + UA_ServerState serverState; +} UA_RedundantServerDataType; + +#define UA_TYPES_REDUNDANTSERVERDATATYPE 332 + +/* EndpointUrlListDataType */ +typedef struct { + size_t endpointUrlListSize; + UA_String *endpointUrlList; +} UA_EndpointUrlListDataType; + +#define UA_TYPES_ENDPOINTURLLISTDATATYPE 333 + +/* NetworkGroupDataType */ +typedef struct { + UA_String serverUri; + size_t networkPathsSize; + UA_EndpointUrlListDataType *networkPaths; +} UA_NetworkGroupDataType; + +#define UA_TYPES_NETWORKGROUPDATATYPE 334 + +/* SamplingIntervalDiagnosticsDataType */ +typedef struct { + UA_Double samplingInterval; + UA_UInt32 monitoredItemCount; + UA_UInt32 maxMonitoredItemCount; + UA_UInt32 disabledMonitoredItemCount; +} UA_SamplingIntervalDiagnosticsDataType; + +#define UA_TYPES_SAMPLINGINTERVALDIAGNOSTICSDATATYPE 335 + +/* ServerDiagnosticsSummaryDataType */ +typedef struct { + UA_UInt32 serverViewCount; + UA_UInt32 currentSessionCount; + UA_UInt32 cumulatedSessionCount; + UA_UInt32 securityRejectedSessionCount; + UA_UInt32 rejectedSessionCount; + UA_UInt32 sessionTimeoutCount; + UA_UInt32 sessionAbortCount; + UA_UInt32 currentSubscriptionCount; + UA_UInt32 cumulatedSubscriptionCount; + UA_UInt32 publishingIntervalCount; + UA_UInt32 securityRejectedRequestsCount; + UA_UInt32 rejectedRequestsCount; +} UA_ServerDiagnosticsSummaryDataType; + +#define UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE 336 + +/* ServerStatusDataType */ +typedef struct { + UA_DateTime startTime; + UA_DateTime currentTime; + UA_ServerState state; + UA_BuildInfo buildInfo; + UA_UInt32 secondsTillShutdown; + UA_LocalizedText shutdownReason; +} UA_ServerStatusDataType; + +#define UA_TYPES_SERVERSTATUSDATATYPE 337 + +/* SessionSecurityDiagnosticsDataType */ +typedef struct { + UA_NodeId sessionId; + UA_String clientUserIdOfSession; + size_t clientUserIdHistorySize; + UA_String *clientUserIdHistory; + UA_String authenticationMechanism; + UA_String encoding; + UA_String transportProtocol; + UA_MessageSecurityMode securityMode; + UA_String securityPolicyUri; + UA_ByteString clientCertificate; +} UA_SessionSecurityDiagnosticsDataType; + +#define UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE 338 + +/* ServiceCounterDataType */ +typedef struct { + UA_UInt32 totalCount; + UA_UInt32 errorCount; +} UA_ServiceCounterDataType; + +#define UA_TYPES_SERVICECOUNTERDATATYPE 339 + +/* StatusResult */ +typedef struct { + UA_StatusCode statusCode; + UA_DiagnosticInfo diagnosticInfo; +} UA_StatusResult; + +#define UA_TYPES_STATUSRESULT 340 + +/* SubscriptionDiagnosticsDataType */ +typedef struct { + UA_NodeId sessionId; + UA_UInt32 subscriptionId; + UA_Byte priority; + UA_Double publishingInterval; + UA_UInt32 maxKeepAliveCount; + UA_UInt32 maxLifetimeCount; + UA_UInt32 maxNotificationsPerPublish; + UA_Boolean publishingEnabled; + UA_UInt32 modifyCount; + UA_UInt32 enableCount; + UA_UInt32 disableCount; + UA_UInt32 republishRequestCount; + UA_UInt32 republishMessageRequestCount; + UA_UInt32 republishMessageCount; + UA_UInt32 transferRequestCount; + UA_UInt32 transferredToAltClientCount; + UA_UInt32 transferredToSameClientCount; + UA_UInt32 publishRequestCount; + UA_UInt32 dataChangeNotificationsCount; + UA_UInt32 eventNotificationsCount; + UA_UInt32 notificationsCount; + UA_UInt32 latePublishRequestCount; + UA_UInt32 currentKeepAliveCount; + UA_UInt32 currentLifetimeCount; + UA_UInt32 unacknowledgedMessageCount; + UA_UInt32 discardedMessageCount; + UA_UInt32 monitoredItemCount; + UA_UInt32 disabledMonitoredItemCount; + UA_UInt32 monitoringQueueOverflowCount; + UA_UInt32 nextSequenceNumber; + UA_UInt32 eventQueueOverFlowCount; +} UA_SubscriptionDiagnosticsDataType; + +#define UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE 341 + +/* ModelChangeStructureVerbMask */ +typedef enum { + UA_MODELCHANGESTRUCTUREVERBMASK_NODEADDED = 1, + UA_MODELCHANGESTRUCTUREVERBMASK_NODEDELETED = 2, + UA_MODELCHANGESTRUCTUREVERBMASK_REFERENCEADDED = 4, + UA_MODELCHANGESTRUCTUREVERBMASK_REFERENCEDELETED = 8, + UA_MODELCHANGESTRUCTUREVERBMASK_DATATYPECHANGED = 16, + __UA_MODELCHANGESTRUCTUREVERBMASK_FORCE32BIT = 0x7fffffff +} UA_ModelChangeStructureVerbMask; + +UA_STATIC_ASSERT(sizeof(UA_ModelChangeStructureVerbMask) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_MODELCHANGESTRUCTUREVERBMASK 342 + +/* ModelChangeStructureDataType */ +typedef struct { + UA_NodeId affected; + UA_NodeId affectedType; + UA_Byte verb; +} UA_ModelChangeStructureDataType; + +#define UA_TYPES_MODELCHANGESTRUCTUREDATATYPE 343 + +/* SemanticChangeStructureDataType */ +typedef struct { + UA_NodeId affected; + UA_NodeId affectedType; +} UA_SemanticChangeStructureDataType; + +#define UA_TYPES_SEMANTICCHANGESTRUCTUREDATATYPE 344 + +/* Range */ +typedef struct { + UA_Double low; + UA_Double high; +} UA_Range; + +#define UA_TYPES_RANGE 345 + +/* EUInformation */ +typedef struct { + UA_String namespaceUri; + UA_Int32 unitId; + UA_LocalizedText displayName; + UA_LocalizedText description; +} UA_EUInformation; + +#define UA_TYPES_EUINFORMATION 346 + +/* AxisScaleEnumeration */ +typedef enum { + UA_AXISSCALEENUMERATION_LINEAR = 0, + UA_AXISSCALEENUMERATION_LOG = 1, + UA_AXISSCALEENUMERATION_LN = 2, + __UA_AXISSCALEENUMERATION_FORCE32BIT = 0x7fffffff +} UA_AxisScaleEnumeration; + +UA_STATIC_ASSERT(sizeof(UA_AxisScaleEnumeration) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_AXISSCALEENUMERATION 347 + +/* ComplexNumberType */ +typedef struct { + UA_Float real; + UA_Float imaginary; +} UA_ComplexNumberType; + +#define UA_TYPES_COMPLEXNUMBERTYPE 348 + +/* DoubleComplexNumberType */ +typedef struct { + UA_Double real; + UA_Double imaginary; +} UA_DoubleComplexNumberType; + +#define UA_TYPES_DOUBLECOMPLEXNUMBERTYPE 349 + +/* AxisInformation */ +typedef struct { + UA_EUInformation engineeringUnits; + UA_Range eURange; + UA_LocalizedText title; + UA_AxisScaleEnumeration axisScaleType; + size_t axisStepsSize; + UA_Double *axisSteps; +} UA_AxisInformation; + +#define UA_TYPES_AXISINFORMATION 350 + +/* XVType */ +typedef struct { + UA_Double x; + UA_Float value; +} UA_XVType; + +#define UA_TYPES_XVTYPE 351 + +/* ProgramDiagnosticDataType */ +typedef struct { + UA_NodeId createSessionId; + UA_String createClientName; + UA_DateTime invocationCreationTime; + UA_DateTime lastTransitionTime; + UA_String lastMethodCall; + UA_NodeId lastMethodSessionId; + size_t lastMethodInputArgumentsSize; + UA_Argument *lastMethodInputArguments; + size_t lastMethodOutputArgumentsSize; + UA_Argument *lastMethodOutputArguments; + UA_DateTime lastMethodCallTime; + UA_StatusResult lastMethodReturnStatus; +} UA_ProgramDiagnosticDataType; + +#define UA_TYPES_PROGRAMDIAGNOSTICDATATYPE 352 + +/* ProgramDiagnostic2DataType */ +typedef struct { + UA_NodeId createSessionId; + UA_String createClientName; + UA_DateTime invocationCreationTime; + UA_DateTime lastTransitionTime; + UA_String lastMethodCall; + UA_NodeId lastMethodSessionId; + size_t lastMethodInputArgumentsSize; + UA_Argument *lastMethodInputArguments; + size_t lastMethodOutputArgumentsSize; + UA_Argument *lastMethodOutputArguments; + size_t lastMethodInputValuesSize; + UA_Variant *lastMethodInputValues; + size_t lastMethodOutputValuesSize; + UA_Variant *lastMethodOutputValues; + UA_DateTime lastMethodCallTime; + UA_StatusCode lastMethodReturnStatus; +} UA_ProgramDiagnostic2DataType; + +#define UA_TYPES_PROGRAMDIAGNOSTIC2DATATYPE 353 + +/* Annotation */ +typedef struct { + UA_String message; + UA_String userName; + UA_DateTime annotationTime; +} UA_Annotation; + +#define UA_TYPES_ANNOTATION 354 + +/* ExceptionDeviationFormat */ +typedef enum { + UA_EXCEPTIONDEVIATIONFORMAT_ABSOLUTEVALUE = 0, + UA_EXCEPTIONDEVIATIONFORMAT_PERCENTOFVALUE = 1, + UA_EXCEPTIONDEVIATIONFORMAT_PERCENTOFRANGE = 2, + UA_EXCEPTIONDEVIATIONFORMAT_PERCENTOFEURANGE = 3, + UA_EXCEPTIONDEVIATIONFORMAT_UNKNOWN = 4, + __UA_EXCEPTIONDEVIATIONFORMAT_FORCE32BIT = 0x7fffffff +} UA_ExceptionDeviationFormat; + +UA_STATIC_ASSERT(sizeof(UA_ExceptionDeviationFormat) == sizeof(UA_Int32), enum_must_be_32bit); + +#define UA_TYPES_EXCEPTIONDEVIATIONFORMAT 355 + +/* EndpointType */ +typedef struct { + UA_String endpointUrl; + UA_MessageSecurityMode securityMode; + UA_String securityPolicyUri; + UA_String transportProfileUri; +} UA_EndpointType; + +#define UA_TYPES_ENDPOINTTYPE 356 + +/* StructureDescription */ +typedef struct { + UA_NodeId dataTypeId; + UA_QualifiedName name; + UA_StructureDefinition structureDefinition; +} UA_StructureDescription; + +#define UA_TYPES_STRUCTUREDESCRIPTION 357 + +/* FieldMetaData */ +typedef struct { + UA_String name; + UA_LocalizedText description; + UA_DataSetFieldFlags fieldFlags; + UA_Byte builtInType; + UA_NodeId dataType; + UA_Int32 valueRank; + size_t arrayDimensionsSize; + UA_UInt32 *arrayDimensions; + UA_UInt32 maxStringLength; + UA_Guid dataSetFieldId; + size_t propertiesSize; + UA_KeyValuePair *properties; +} UA_FieldMetaData; + +#define UA_TYPES_FIELDMETADATA 358 + +/* PublishedEventsDataType */ +typedef struct { + UA_NodeId eventNotifier; + size_t selectedFieldsSize; + UA_SimpleAttributeOperand *selectedFields; + UA_ContentFilter filter; +} UA_PublishedEventsDataType; + +#define UA_TYPES_PUBLISHEDEVENTSDATATYPE 359 + +/* PubSubGroupDataType */ +typedef struct { + UA_String name; + UA_Boolean enabled; + UA_MessageSecurityMode securityMode; + UA_String securityGroupId; + size_t securityKeyServicesSize; + UA_EndpointDescription *securityKeyServices; + UA_UInt32 maxNetworkMessageSize; + size_t groupPropertiesSize; + UA_KeyValuePair *groupProperties; +} UA_PubSubGroupDataType; + +#define UA_TYPES_PUBSUBGROUPDATATYPE 360 + +/* WriterGroupDataType */ +typedef struct { + UA_String name; + UA_Boolean enabled; + UA_MessageSecurityMode securityMode; + UA_String securityGroupId; + size_t securityKeyServicesSize; + UA_EndpointDescription *securityKeyServices; + UA_UInt32 maxNetworkMessageSize; + size_t groupPropertiesSize; + UA_KeyValuePair *groupProperties; + UA_UInt16 writerGroupId; + UA_Double publishingInterval; + UA_Double keepAliveTime; + UA_Byte priority; + size_t localeIdsSize; + UA_String *localeIds; + UA_String headerLayoutUri; + UA_ExtensionObject transportSettings; + UA_ExtensionObject messageSettings; + size_t dataSetWritersSize; + UA_DataSetWriterDataType *dataSetWriters; +} UA_WriterGroupDataType; + +#define UA_TYPES_WRITERGROUPDATATYPE 361 + +/* FieldTargetDataType */ +typedef struct { + UA_Guid dataSetFieldId; + UA_String receiverIndexRange; + UA_NodeId targetNodeId; + UA_UInt32 attributeId; + UA_String writeIndexRange; + UA_OverrideValueHandling overrideValueHandling; + UA_Variant overrideValue; +} UA_FieldTargetDataType; + +#define UA_TYPES_FIELDTARGETDATATYPE 362 + +/* SubscribedDataSetMirrorDataType */ +typedef struct { + UA_String parentNodeName; + size_t rolePermissionsSize; + UA_RolePermissionType *rolePermissions; +} UA_SubscribedDataSetMirrorDataType; + +#define UA_TYPES_SUBSCRIBEDDATASETMIRRORDATATYPE 363 + +/* SecurityGroupDataType */ +typedef struct { + UA_String name; + size_t securityGroupFolderSize; + UA_String *securityGroupFolder; + UA_Double keyLifetime; + UA_String securityPolicyUri; + UA_UInt32 maxFutureKeyCount; + UA_UInt32 maxPastKeyCount; + UA_String securityGroupId; + size_t rolePermissionsSize; + UA_RolePermissionType *rolePermissions; + size_t groupPropertiesSize; + UA_KeyValuePair *groupProperties; +} UA_SecurityGroupDataType; + +#define UA_TYPES_SECURITYGROUPDATATYPE 364 + +/* PubSubKeyPushTargetDataType */ +typedef struct { + UA_String applicationUri; + size_t pushTargetFolderSize; + UA_String *pushTargetFolder; + UA_String endpointUrl; + UA_String securityPolicyUri; + UA_UserTokenPolicy userTokenType; + UA_UInt16 requestedKeyCount; + UA_Double retryInterval; + size_t pushTargetPropertiesSize; + UA_KeyValuePair *pushTargetProperties; + size_t securityGroupsSize; + UA_String *securityGroups; +} UA_PubSubKeyPushTargetDataType; + +#define UA_TYPES_PUBSUBKEYPUSHTARGETDATATYPE 365 + +/* EnumDefinition */ +typedef struct { + size_t fieldsSize; + UA_EnumField *fields; +} UA_EnumDefinition; + +#define UA_TYPES_ENUMDEFINITION 366 + +/* ReadEventDetails */ +typedef struct { + UA_UInt32 numValuesPerNode; + UA_DateTime startTime; + UA_DateTime endTime; + UA_EventFilter filter; +} UA_ReadEventDetails; + +#define UA_TYPES_READEVENTDETAILS 367 + +/* ReadProcessedDetails */ +typedef struct { + UA_DateTime startTime; + UA_DateTime endTime; + UA_Double processingInterval; + size_t aggregateTypeSize; + UA_NodeId *aggregateType; + UA_AggregateConfiguration aggregateConfiguration; +} UA_ReadProcessedDetails; + +#define UA_TYPES_READPROCESSEDDETAILS 368 + +/* ModificationInfo */ +typedef struct { + UA_DateTime modificationTime; + UA_HistoryUpdateType updateType; + UA_String userName; +} UA_ModificationInfo; + +#define UA_TYPES_MODIFICATIONINFO 369 + +/* HistoryModifiedData */ +typedef struct { + size_t dataValuesSize; + UA_DataValue *dataValues; + size_t modificationInfosSize; + UA_ModificationInfo *modificationInfos; +} UA_HistoryModifiedData; + +#define UA_TYPES_HISTORYMODIFIEDDATA 370 + +/* HistoryEvent */ +typedef struct { + size_t eventsSize; + UA_HistoryEventFieldList *events; +} UA_HistoryEvent; + +#define UA_TYPES_HISTORYEVENT 371 + +/* UpdateEventDetails */ +typedef struct { + UA_NodeId nodeId; + UA_PerformUpdateType performInsertReplace; + UA_EventFilter filter; + size_t eventDataSize; + UA_HistoryEventFieldList *eventData; +} UA_UpdateEventDetails; + +#define UA_TYPES_UPDATEEVENTDETAILS 372 + +/* DataChangeNotification */ +typedef struct { + size_t monitoredItemsSize; + UA_MonitoredItemNotification *monitoredItems; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; +} UA_DataChangeNotification; + +#define UA_TYPES_DATACHANGENOTIFICATION 373 + +/* EventNotificationList */ +typedef struct { + size_t eventsSize; + UA_EventFieldList *events; +} UA_EventNotificationList; + +#define UA_TYPES_EVENTNOTIFICATIONLIST 374 + +/* SessionDiagnosticsDataType */ +typedef struct { + UA_NodeId sessionId; + UA_String sessionName; + UA_ApplicationDescription clientDescription; + UA_String serverUri; + UA_String endpointUrl; + size_t localeIdsSize; + UA_String *localeIds; + UA_Double actualSessionTimeout; + UA_UInt32 maxResponseMessageSize; + UA_DateTime clientConnectionTime; + UA_DateTime clientLastContactTime; + UA_UInt32 currentSubscriptionsCount; + UA_UInt32 currentMonitoredItemsCount; + UA_UInt32 currentPublishRequestsInQueue; + UA_ServiceCounterDataType totalRequestCount; + UA_UInt32 unauthorizedRequestCount; + UA_ServiceCounterDataType readCount; + UA_ServiceCounterDataType historyReadCount; + UA_ServiceCounterDataType writeCount; + UA_ServiceCounterDataType historyUpdateCount; + UA_ServiceCounterDataType callCount; + UA_ServiceCounterDataType createMonitoredItemsCount; + UA_ServiceCounterDataType modifyMonitoredItemsCount; + UA_ServiceCounterDataType setMonitoringModeCount; + UA_ServiceCounterDataType setTriggeringCount; + UA_ServiceCounterDataType deleteMonitoredItemsCount; + UA_ServiceCounterDataType createSubscriptionCount; + UA_ServiceCounterDataType modifySubscriptionCount; + UA_ServiceCounterDataType setPublishingModeCount; + UA_ServiceCounterDataType publishCount; + UA_ServiceCounterDataType republishCount; + UA_ServiceCounterDataType transferSubscriptionsCount; + UA_ServiceCounterDataType deleteSubscriptionsCount; + UA_ServiceCounterDataType addNodesCount; + UA_ServiceCounterDataType addReferencesCount; + UA_ServiceCounterDataType deleteNodesCount; + UA_ServiceCounterDataType deleteReferencesCount; + UA_ServiceCounterDataType browseCount; + UA_ServiceCounterDataType browseNextCount; + UA_ServiceCounterDataType translateBrowsePathsToNodeIdsCount; + UA_ServiceCounterDataType queryFirstCount; + UA_ServiceCounterDataType queryNextCount; + UA_ServiceCounterDataType registerNodesCount; + UA_ServiceCounterDataType unregisterNodesCount; +} UA_SessionDiagnosticsDataType; + +#define UA_TYPES_SESSIONDIAGNOSTICSDATATYPE 375 + +/* EnumDescription */ +typedef struct { + UA_NodeId dataTypeId; + UA_QualifiedName name; + UA_EnumDefinition enumDefinition; + UA_Byte builtInType; +} UA_EnumDescription; + +#define UA_TYPES_ENUMDESCRIPTION 376 + +/* UABinaryFileDataType */ +typedef struct { + size_t namespacesSize; + UA_String *namespaces; + size_t structureDataTypesSize; + UA_StructureDescription *structureDataTypes; + size_t enumDataTypesSize; + UA_EnumDescription *enumDataTypes; + size_t simpleDataTypesSize; + UA_SimpleTypeDescription *simpleDataTypes; + UA_String schemaLocation; + size_t fileHeaderSize; + UA_KeyValuePair *fileHeader; + UA_Variant body; +} UA_UABinaryFileDataType; + +#define UA_TYPES_UABINARYFILEDATATYPE 377 + +/* DataSetMetaDataType */ +typedef struct { + size_t namespacesSize; + UA_String *namespaces; + size_t structureDataTypesSize; + UA_StructureDescription *structureDataTypes; + size_t enumDataTypesSize; + UA_EnumDescription *enumDataTypes; + size_t simpleDataTypesSize; + UA_SimpleTypeDescription *simpleDataTypes; + UA_String name; + UA_LocalizedText description; + size_t fieldsSize; + UA_FieldMetaData *fields; + UA_Guid dataSetClassId; + UA_ConfigurationVersionDataType configurationVersion; +} UA_DataSetMetaDataType; + +#define UA_TYPES_DATASETMETADATATYPE 378 + +/* PublishedDataSetDataType */ +typedef struct { + UA_String name; + size_t dataSetFolderSize; + UA_String *dataSetFolder; + UA_DataSetMetaDataType dataSetMetaData; + size_t extensionFieldsSize; + UA_KeyValuePair *extensionFields; + UA_ExtensionObject dataSetSource; +} UA_PublishedDataSetDataType; + +#define UA_TYPES_PUBLISHEDDATASETDATATYPE 379 + +/* DataSetReaderDataType */ +typedef struct { + UA_String name; + UA_Boolean enabled; + UA_Variant publisherId; + UA_UInt16 writerGroupId; + UA_UInt16 dataSetWriterId; + UA_DataSetMetaDataType dataSetMetaData; + UA_DataSetFieldContentMask dataSetFieldContentMask; + UA_Double messageReceiveTimeout; + UA_UInt32 keyFrameCount; + UA_String headerLayoutUri; + UA_MessageSecurityMode securityMode; + UA_String securityGroupId; + size_t securityKeyServicesSize; + UA_EndpointDescription *securityKeyServices; + size_t dataSetReaderPropertiesSize; + UA_KeyValuePair *dataSetReaderProperties; + UA_ExtensionObject transportSettings; + UA_ExtensionObject messageSettings; + UA_ExtensionObject subscribedDataSet; +} UA_DataSetReaderDataType; + +#define UA_TYPES_DATASETREADERDATATYPE 380 + +/* TargetVariablesDataType */ +typedef struct { + size_t targetVariablesSize; + UA_FieldTargetDataType *targetVariables; +} UA_TargetVariablesDataType; + +#define UA_TYPES_TARGETVARIABLESDATATYPE 381 + +/* StandaloneSubscribedDataSetDataType */ +typedef struct { + UA_String name; + size_t dataSetFolderSize; + UA_String *dataSetFolder; + UA_DataSetMetaDataType dataSetMetaData; + UA_ExtensionObject subscribedDataSet; +} UA_StandaloneSubscribedDataSetDataType; + +#define UA_TYPES_STANDALONESUBSCRIBEDDATASETDATATYPE 382 + +/* DataTypeSchemaHeader */ +typedef struct { + size_t namespacesSize; + UA_String *namespaces; + size_t structureDataTypesSize; + UA_StructureDescription *structureDataTypes; + size_t enumDataTypesSize; + UA_EnumDescription *enumDataTypes; + size_t simpleDataTypesSize; + UA_SimpleTypeDescription *simpleDataTypes; +} UA_DataTypeSchemaHeader; + +#define UA_TYPES_DATATYPESCHEMAHEADER 383 + +/* ReaderGroupDataType */ +typedef struct { + UA_String name; + UA_Boolean enabled; + UA_MessageSecurityMode securityMode; + UA_String securityGroupId; + size_t securityKeyServicesSize; + UA_EndpointDescription *securityKeyServices; + UA_UInt32 maxNetworkMessageSize; + size_t groupPropertiesSize; + UA_KeyValuePair *groupProperties; + UA_ExtensionObject transportSettings; + UA_ExtensionObject messageSettings; + size_t dataSetReadersSize; + UA_DataSetReaderDataType *dataSetReaders; +} UA_ReaderGroupDataType; + +#define UA_TYPES_READERGROUPDATATYPE 384 + +/* PubSubConnectionDataType */ +typedef struct { + UA_String name; + UA_Boolean enabled; + UA_Variant publisherId; + UA_String transportProfileUri; + UA_ExtensionObject address; + size_t connectionPropertiesSize; + UA_KeyValuePair *connectionProperties; + UA_ExtensionObject transportSettings; + size_t writerGroupsSize; + UA_WriterGroupDataType *writerGroups; + size_t readerGroupsSize; + UA_ReaderGroupDataType *readerGroups; +} UA_PubSubConnectionDataType; + +#define UA_TYPES_PUBSUBCONNECTIONDATATYPE 385 + +/* PubSubConfigurationDataType */ +typedef struct { + size_t publishedDataSetsSize; + UA_PublishedDataSetDataType *publishedDataSets; + size_t connectionsSize; + UA_PubSubConnectionDataType *connections; + UA_Boolean enabled; +} UA_PubSubConfigurationDataType; + +#define UA_TYPES_PUBSUBCONFIGURATIONDATATYPE 386 + +/* PubSubConfiguration2DataType */ +typedef struct { + size_t publishedDataSetsSize; + UA_PublishedDataSetDataType *publishedDataSets; + size_t connectionsSize; + UA_PubSubConnectionDataType *connections; + UA_Boolean enabled; + size_t subscribedDataSetsSize; + UA_StandaloneSubscribedDataSetDataType *subscribedDataSets; + size_t dataSetClassesSize; + UA_DataSetMetaDataType *dataSetClasses; + size_t defaultSecurityKeyServicesSize; + UA_EndpointDescription *defaultSecurityKeyServices; + size_t securityGroupsSize; + UA_SecurityGroupDataType *securityGroups; + size_t pubSubKeyPushTargetsSize; + UA_PubSubKeyPushTargetDataType *pubSubKeyPushTargets; + UA_UInt32 configurationVersion; + size_t configurationPropertiesSize; + UA_KeyValuePair *configurationProperties; +} UA_PubSubConfiguration2DataType; + +#define UA_TYPES_PUBSUBCONFIGURATION2DATATYPE 387 + + +_UA_END_DECLS + +#endif /* TYPES_GENERATED_H_ */ diff --git a/product/src/fes/include/open62541/types_generated.rst b/product/src/fes/include/open62541/types_generated.rst new file mode 100644 index 00000000..7a8e7982 --- /dev/null +++ b/product/src/fes/include/open62541/types_generated.rst @@ -0,0 +1,4634 @@ +NamingRuleType +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_NAMINGRULETYPE_MANDATORY = 1, + UA_NAMINGRULETYPE_OPTIONAL = 2, + UA_NAMINGRULETYPE_CONSTRAINT = 3 + } UA_NamingRuleType; + +Enumeration +^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + } UA_Enumeration; + +ImageBMP +^^^^^^^^ + +.. code-block:: c + + typedef UA_ByteString UA_ImageBMP; + +ImageGIF +^^^^^^^^ + +.. code-block:: c + + typedef UA_ByteString UA_ImageGIF; + +ImageJPG +^^^^^^^^ + +.. code-block:: c + + typedef UA_ByteString UA_ImageJPG; + +ImagePNG +^^^^^^^^ + +.. code-block:: c + + typedef UA_ByteString UA_ImagePNG; + +AudioDataType +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_ByteString UA_AudioDataType; + +UriString +^^^^^^^^^ + +.. code-block:: c + + typedef UA_String UA_UriString; + +BitFieldMaskDataType +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt64 UA_BitFieldMaskDataType; + +SemanticVersionString +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_String UA_SemanticVersionString; + +KeyValuePair +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_QualifiedName key; + UA_Variant value; + } UA_KeyValuePair; + +AdditionalParametersType +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t parametersSize; + UA_KeyValuePair *parameters; + } UA_AdditionalParametersType; + +EphemeralKeyType +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ByteString publicKey; + UA_ByteString signature; + } UA_EphemeralKeyType; + +RationalNumber +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Int32 numerator; + UA_UInt32 denominator; + } UA_RationalNumber; + +ThreeDVector +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Double x; + UA_Double y; + UA_Double z; + } UA_ThreeDVector; + +ThreeDCartesianCoordinates +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Double x; + UA_Double y; + UA_Double z; + } UA_ThreeDCartesianCoordinates; + +ThreeDOrientation +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Double a; + UA_Double b; + UA_Double c; + } UA_ThreeDOrientation; + +ThreeDFrame +^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ThreeDCartesianCoordinates cartesianCoordinates; + UA_ThreeDOrientation orientation; + } UA_ThreeDFrame; + +OpenFileMode +^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_OPENFILEMODE_READ = 1, + UA_OPENFILEMODE_WRITE = 2, + UA_OPENFILEMODE_ERASEEXISTING = 4, + UA_OPENFILEMODE_APPEND = 8 + } UA_OpenFileMode; + +IdentityCriteriaType +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_IDENTITYCRITERIATYPE_USERNAME = 1, + UA_IDENTITYCRITERIATYPE_THUMBPRINT = 2, + UA_IDENTITYCRITERIATYPE_ROLE = 3, + UA_IDENTITYCRITERIATYPE_GROUPID = 4, + UA_IDENTITYCRITERIATYPE_ANONYMOUS = 5, + UA_IDENTITYCRITERIATYPE_AUTHENTICATEDUSER = 6, + UA_IDENTITYCRITERIATYPE_APPLICATION = 7, + UA_IDENTITYCRITERIATYPE_X509SUBJECT = 8 + } UA_IdentityCriteriaType; + +IdentityMappingRuleType +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_IdentityCriteriaType criteriaType; + UA_String criteria; + } UA_IdentityMappingRuleType; + +CurrencyUnitType +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Int16 numericCode; + UA_SByte exponent; + UA_String alphabeticCode; + UA_LocalizedText currency; + } UA_CurrencyUnitType; + +TrustListMasks +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_TRUSTLISTMASKS_NONE = 0, + UA_TRUSTLISTMASKS_TRUSTEDCERTIFICATES = 1, + UA_TRUSTLISTMASKS_TRUSTEDCRLS = 2, + UA_TRUSTLISTMASKS_ISSUERCERTIFICATES = 4, + UA_TRUSTLISTMASKS_ISSUERCRLS = 8, + UA_TRUSTLISTMASKS_ALL = 15 + } UA_TrustListMasks; + +TrustListDataType +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 specifiedLists; + size_t trustedCertificatesSize; + UA_ByteString *trustedCertificates; + size_t trustedCrlsSize; + UA_ByteString *trustedCrls; + size_t issuerCertificatesSize; + UA_ByteString *issuerCertificates; + size_t issuerCrlsSize; + UA_ByteString *issuerCrls; + } UA_TrustListDataType; + +DecimalDataType +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Int16 scale; + UA_ByteString value; + } UA_DecimalDataType; + +DataTypeDescription +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId dataTypeId; + UA_QualifiedName name; + } UA_DataTypeDescription; + +SimpleTypeDescription +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId dataTypeId; + UA_QualifiedName name; + UA_NodeId baseDataType; + UA_Byte builtInType; + } UA_SimpleTypeDescription; + +PortableQualifiedName +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String namespaceUri; + UA_String name; + } UA_PortableQualifiedName; + +PortableNodeId +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String namespaceUri; + UA_NodeId identifier; + } UA_PortableNodeId; + +UnsignedRationalNumber +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 numerator; + UA_UInt32 denominator; + } UA_UnsignedRationalNumber; + +PubSubState +^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_PUBSUBSTATE_DISABLED = 0, + UA_PUBSUBSTATE_PAUSED = 1, + UA_PUBSUBSTATE_OPERATIONAL = 2, + UA_PUBSUBSTATE_ERROR = 3, + UA_PUBSUBSTATE_PREOPERATIONAL = 4 + } UA_PubSubState; + +DataSetFieldFlags +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt16 UA_DataSetFieldFlags; + + #define UA_DATASETFIELDFLAGS_NONE 0 + #define UA_DATASETFIELDFLAGS_PROMOTEDFIELD 1 + +ConfigurationVersionDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 majorVersion; + UA_UInt32 minorVersion; + } UA_ConfigurationVersionDataType; + +PublishedVariableDataType +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId publishedVariable; + UA_UInt32 attributeId; + UA_Double samplingIntervalHint; + UA_UInt32 deadbandType; + UA_Double deadbandValue; + UA_String indexRange; + UA_Variant substituteValue; + size_t metaDataPropertiesSize; + UA_QualifiedName *metaDataProperties; + } UA_PublishedVariableDataType; + +PublishedDataItemsDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t publishedDataSize; + UA_PublishedVariableDataType *publishedData; + } UA_PublishedDataItemsDataType; + +PublishedDataSetCustomSourceDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Boolean cyclicDataSet; + } UA_PublishedDataSetCustomSourceDataType; + +DataSetFieldContentMask +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_DataSetFieldContentMask; + + #define UA_DATASETFIELDCONTENTMASK_NONE 0 + #define UA_DATASETFIELDCONTENTMASK_STATUSCODE 1 + #define UA_DATASETFIELDCONTENTMASK_SOURCETIMESTAMP 2 + #define UA_DATASETFIELDCONTENTMASK_SERVERTIMESTAMP 4 + #define UA_DATASETFIELDCONTENTMASK_SOURCEPICOSECONDS 8 + #define UA_DATASETFIELDCONTENTMASK_SERVERPICOSECONDS 16 + #define UA_DATASETFIELDCONTENTMASK_RAWDATA 32 + +DataSetWriterDataType +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String name; + UA_Boolean enabled; + UA_UInt16 dataSetWriterId; + UA_DataSetFieldContentMask dataSetFieldContentMask; + UA_UInt32 keyFrameCount; + UA_String dataSetName; + size_t dataSetWriterPropertiesSize; + UA_KeyValuePair *dataSetWriterProperties; + UA_ExtensionObject transportSettings; + UA_ExtensionObject messageSettings; + } UA_DataSetWriterDataType; + +NetworkAddressDataType +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String networkInterface; + } UA_NetworkAddressDataType; + +NetworkAddressUrlDataType +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String networkInterface; + UA_String url; + } UA_NetworkAddressUrlDataType; + +OverrideValueHandling +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_OVERRIDEVALUEHANDLING_DISABLED = 0, + UA_OVERRIDEVALUEHANDLING_LASTUSABLEVALUE = 1, + UA_OVERRIDEVALUEHANDLING_OVERRIDEVALUE = 2 + } UA_OverrideValueHandling; + +StandaloneSubscribedDataSetRefDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String dataSetName; + } UA_StandaloneSubscribedDataSetRefDataType; + +DataSetOrderingType +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_DATASETORDERINGTYPE_UNDEFINED = 0, + UA_DATASETORDERINGTYPE_ASCENDINGWRITERID = 1, + UA_DATASETORDERINGTYPE_ASCENDINGWRITERIDSINGLE = 2 + } UA_DataSetOrderingType; + +UadpNetworkMessageContentMask +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_UadpNetworkMessageContentMask; + + #define UA_UADPNETWORKMESSAGECONTENTMASK_NONE 0 + #define UA_UADPNETWORKMESSAGECONTENTMASK_PUBLISHERID 1 + #define UA_UADPNETWORKMESSAGECONTENTMASK_GROUPHEADER 2 + #define UA_UADPNETWORKMESSAGECONTENTMASK_WRITERGROUPID 4 + #define UA_UADPNETWORKMESSAGECONTENTMASK_GROUPVERSION 8 + #define UA_UADPNETWORKMESSAGECONTENTMASK_NETWORKMESSAGENUMBER 16 + #define UA_UADPNETWORKMESSAGECONTENTMASK_SEQUENCENUMBER 32 + #define UA_UADPNETWORKMESSAGECONTENTMASK_PAYLOADHEADER 64 + #define UA_UADPNETWORKMESSAGECONTENTMASK_TIMESTAMP 128 + #define UA_UADPNETWORKMESSAGECONTENTMASK_PICOSECONDS 256 + #define UA_UADPNETWORKMESSAGECONTENTMASK_DATASETCLASSID 512 + #define UA_UADPNETWORKMESSAGECONTENTMASK_PROMOTEDFIELDS 1024 + +UadpWriterGroupMessageDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 groupVersion; + UA_DataSetOrderingType dataSetOrdering; + UA_UadpNetworkMessageContentMask networkMessageContentMask; + UA_Double samplingOffset; + size_t publishingOffsetSize; + UA_Double *publishingOffset; + } UA_UadpWriterGroupMessageDataType; + +UadpDataSetMessageContentMask +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_UadpDataSetMessageContentMask; + + #define UA_UADPDATASETMESSAGECONTENTMASK_NONE 0 + #define UA_UADPDATASETMESSAGECONTENTMASK_TIMESTAMP 1 + #define UA_UADPDATASETMESSAGECONTENTMASK_PICOSECONDS 2 + #define UA_UADPDATASETMESSAGECONTENTMASK_STATUS 4 + #define UA_UADPDATASETMESSAGECONTENTMASK_MAJORVERSION 8 + #define UA_UADPDATASETMESSAGECONTENTMASK_MINORVERSION 16 + #define UA_UADPDATASETMESSAGECONTENTMASK_SEQUENCENUMBER 32 + +UadpDataSetWriterMessageDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UadpDataSetMessageContentMask dataSetMessageContentMask; + UA_UInt16 configuredSize; + UA_UInt16 networkMessageNumber; + UA_UInt16 dataSetOffset; + } UA_UadpDataSetWriterMessageDataType; + +UadpDataSetReaderMessageDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 groupVersion; + UA_UInt16 networkMessageNumber; + UA_UInt16 dataSetOffset; + UA_Guid dataSetClassId; + UA_UadpNetworkMessageContentMask networkMessageContentMask; + UA_UadpDataSetMessageContentMask dataSetMessageContentMask; + UA_Double publishingInterval; + UA_Double receiveOffset; + UA_Double processingOffset; + } UA_UadpDataSetReaderMessageDataType; + +JsonNetworkMessageContentMask +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_JsonNetworkMessageContentMask; + + #define UA_JSONNETWORKMESSAGECONTENTMASK_NONE 0 + #define UA_JSONNETWORKMESSAGECONTENTMASK_NETWORKMESSAGEHEADER 1 + #define UA_JSONNETWORKMESSAGECONTENTMASK_DATASETMESSAGEHEADER 2 + #define UA_JSONNETWORKMESSAGECONTENTMASK_SINGLEDATASETMESSAGE 4 + #define UA_JSONNETWORKMESSAGECONTENTMASK_PUBLISHERID 8 + #define UA_JSONNETWORKMESSAGECONTENTMASK_DATASETCLASSID 16 + #define UA_JSONNETWORKMESSAGECONTENTMASK_REPLYTO 32 + +JsonWriterGroupMessageDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_JsonNetworkMessageContentMask networkMessageContentMask; + } UA_JsonWriterGroupMessageDataType; + +JsonDataSetMessageContentMask +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_JsonDataSetMessageContentMask; + + #define UA_JSONDATASETMESSAGECONTENTMASK_NONE 0 + #define UA_JSONDATASETMESSAGECONTENTMASK_DATASETWRITERID 1 + #define UA_JSONDATASETMESSAGECONTENTMASK_METADATAVERSION 2 + #define UA_JSONDATASETMESSAGECONTENTMASK_SEQUENCENUMBER 4 + #define UA_JSONDATASETMESSAGECONTENTMASK_TIMESTAMP 8 + #define UA_JSONDATASETMESSAGECONTENTMASK_STATUS 16 + #define UA_JSONDATASETMESSAGECONTENTMASK_MESSAGETYPE 32 + #define UA_JSONDATASETMESSAGECONTENTMASK_DATASETWRITERNAME 64 + #define UA_JSONDATASETMESSAGECONTENTMASK_REVERSIBLEFIELDENCODING 128 + +JsonDataSetWriterMessageDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_JsonDataSetMessageContentMask dataSetMessageContentMask; + } UA_JsonDataSetWriterMessageDataType; + +JsonDataSetReaderMessageDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_JsonNetworkMessageContentMask networkMessageContentMask; + UA_JsonDataSetMessageContentMask dataSetMessageContentMask; + } UA_JsonDataSetReaderMessageDataType; + +TransmitQosPriorityDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String priorityLabel; + } UA_TransmitQosPriorityDataType; + +ReceiveQosPriorityDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String priorityLabel; + } UA_ReceiveQosPriorityDataType; + +DatagramConnectionTransportDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ExtensionObject discoveryAddress; + } UA_DatagramConnectionTransportDataType; + +DatagramConnectionTransport2DataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ExtensionObject discoveryAddress; + UA_UInt32 discoveryAnnounceRate; + UA_UInt32 discoveryMaxMessageSize; + UA_String qosCategory; + size_t datagramQosSize; + UA_ExtensionObject *datagramQos; + } UA_DatagramConnectionTransport2DataType; + +DatagramWriterGroupTransportDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Byte messageRepeatCount; + UA_Double messageRepeatDelay; + } UA_DatagramWriterGroupTransportDataType; + +DatagramWriterGroupTransport2DataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Byte messageRepeatCount; + UA_Double messageRepeatDelay; + UA_ExtensionObject address; + UA_String qosCategory; + size_t datagramQosSize; + UA_ExtensionObject *datagramQos; + UA_UInt32 discoveryAnnounceRate; + UA_String topic; + } UA_DatagramWriterGroupTransport2DataType; + +DatagramDataSetReaderTransportDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ExtensionObject address; + UA_String qosCategory; + size_t datagramQosSize; + UA_ExtensionObject *datagramQos; + UA_String topic; + } UA_DatagramDataSetReaderTransportDataType; + +BrokerConnectionTransportDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String resourceUri; + UA_String authenticationProfileUri; + } UA_BrokerConnectionTransportDataType; + +BrokerTransportQualityOfService +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_BROKERTRANSPORTQUALITYOFSERVICE_NOTSPECIFIED = 0, + UA_BROKERTRANSPORTQUALITYOFSERVICE_BESTEFFORT = 1, + UA_BROKERTRANSPORTQUALITYOFSERVICE_ATLEASTONCE = 2, + UA_BROKERTRANSPORTQUALITYOFSERVICE_ATMOSTONCE = 3, + UA_BROKERTRANSPORTQUALITYOFSERVICE_EXACTLYONCE = 4 + } UA_BrokerTransportQualityOfService; + +BrokerWriterGroupTransportDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String queueName; + UA_String resourceUri; + UA_String authenticationProfileUri; + UA_BrokerTransportQualityOfService requestedDeliveryGuarantee; + } UA_BrokerWriterGroupTransportDataType; + +BrokerDataSetWriterTransportDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String queueName; + UA_String resourceUri; + UA_String authenticationProfileUri; + UA_BrokerTransportQualityOfService requestedDeliveryGuarantee; + UA_String metaDataQueueName; + UA_Double metaDataUpdateTime; + } UA_BrokerDataSetWriterTransportDataType; + +BrokerDataSetReaderTransportDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String queueName; + UA_String resourceUri; + UA_String authenticationProfileUri; + UA_BrokerTransportQualityOfService requestedDeliveryGuarantee; + UA_String metaDataQueueName; + } UA_BrokerDataSetReaderTransportDataType; + +PubSubConfigurationRefMask +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_PubSubConfigurationRefMask; + + #define UA_PUBSUBCONFIGURATIONREFMASK_NONE 0 + #define UA_PUBSUBCONFIGURATIONREFMASK_ELEMENTADD 1 + #define UA_PUBSUBCONFIGURATIONREFMASK_ELEMENTMATCH 2 + #define UA_PUBSUBCONFIGURATIONREFMASK_ELEMENTMODIFY 4 + #define UA_PUBSUBCONFIGURATIONREFMASK_ELEMENTREMOVE 8 + #define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCEWRITER 16 + #define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCEREADER 32 + #define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCEWRITERGROUP 64 + #define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCEREADERGROUP 128 + #define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCECONNECTION 256 + #define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCEPUBDATASET 512 + #define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCESUBDATASET 1024 + #define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCESECURITYGROUP 2048 + #define UA_PUBSUBCONFIGURATIONREFMASK_REFERENCEPUSHTARGET 4096 + +PubSubConfigurationRefDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_PubSubConfigurationRefMask configurationMask; + UA_UInt16 elementIndex; + UA_UInt16 connectionIndex; + UA_UInt16 groupIndex; + } UA_PubSubConfigurationRefDataType; + +PubSubConfigurationValueDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_PubSubConfigurationRefDataType configurationElement; + UA_String name; + UA_Variant identifier; + } UA_PubSubConfigurationValueDataType; + +DiagnosticsLevel +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_DIAGNOSTICSLEVEL_BASIC = 0, + UA_DIAGNOSTICSLEVEL_ADVANCED = 1, + UA_DIAGNOSTICSLEVEL_INFO = 2, + UA_DIAGNOSTICSLEVEL_LOG = 3, + UA_DIAGNOSTICSLEVEL_DEBUG = 4 + } UA_DiagnosticsLevel; + +PubSubDiagnosticsCounterClassification +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION_INFORMATION = 0, + UA_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION_ERROR = 1 + } UA_PubSubDiagnosticsCounterClassification; + +AliasNameDataType +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_QualifiedName aliasName; + size_t referencedNodesSize; + UA_ExpandedNodeId *referencedNodes; + } UA_AliasNameDataType; + +PasswordOptionsMask +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_PasswordOptionsMask; + + #define UA_PASSWORDOPTIONSMASK_NONE 0 + #define UA_PASSWORDOPTIONSMASK_SUPPORTINITIALPASSWORDCHANGE 1 + #define UA_PASSWORDOPTIONSMASK_SUPPORTDISABLEUSER 2 + #define UA_PASSWORDOPTIONSMASK_SUPPORTDISABLEDELETEFORUSER 4 + #define UA_PASSWORDOPTIONSMASK_SUPPORTNOCHANGEFORUSER 8 + #define UA_PASSWORDOPTIONSMASK_SUPPORTDESCRIPTIONFORUSER 16 + #define UA_PASSWORDOPTIONSMASK_REQUIRESUPPERCASECHARACTERS 32 + #define UA_PASSWORDOPTIONSMASK_REQUIRESLOWERCASECHARACTERS 64 + #define UA_PASSWORDOPTIONSMASK_REQUIRESDIGITCHARACTERS 128 + #define UA_PASSWORDOPTIONSMASK_REQUIRESSPECIALCHARACTERS 256 + +UserConfigurationMask +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_UserConfigurationMask; + + #define UA_USERCONFIGURATIONMASK_NONE 0 + #define UA_USERCONFIGURATIONMASK_NODELETE 1 + #define UA_USERCONFIGURATIONMASK_DISABLED 2 + #define UA_USERCONFIGURATIONMASK_NOCHANGEBYUSER 4 + #define UA_USERCONFIGURATIONMASK_MUSTCHANGEPASSWORD 8 + +UserManagementDataType +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String userName; + UA_UserConfigurationMask userConfiguration; + UA_String description; + } UA_UserManagementDataType; + +Duplex +^^^^^^ + +.. code-block:: c + + typedef enum { + UA_DUPLEX_FULL = 0, + UA_DUPLEX_HALF = 1, + UA_DUPLEX_UNKNOWN = 2 + } UA_Duplex; + +InterfaceAdminStatus +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_INTERFACEADMINSTATUS_UP = 0, + UA_INTERFACEADMINSTATUS_DOWN = 1, + UA_INTERFACEADMINSTATUS_TESTING = 2 + } UA_InterfaceAdminStatus; + +InterfaceOperStatus +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_INTERFACEOPERSTATUS_UP = 0, + UA_INTERFACEOPERSTATUS_DOWN = 1, + UA_INTERFACEOPERSTATUS_TESTING = 2, + UA_INTERFACEOPERSTATUS_UNKNOWN = 3, + UA_INTERFACEOPERSTATUS_DORMANT = 4, + UA_INTERFACEOPERSTATUS_NOTPRESENT = 5, + UA_INTERFACEOPERSTATUS_LOWERLAYERDOWN = 6 + } UA_InterfaceOperStatus; + +NegotiationStatus +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_NEGOTIATIONSTATUS_INPROGRESS = 0, + UA_NEGOTIATIONSTATUS_COMPLETE = 1, + UA_NEGOTIATIONSTATUS_FAILED = 2, + UA_NEGOTIATIONSTATUS_UNKNOWN = 3, + UA_NEGOTIATIONSTATUS_NONEGOTIATION = 4 + } UA_NegotiationStatus; + +TsnFailureCode +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_TSNFAILURECODE_NOFAILURE = 0, + UA_TSNFAILURECODE_INSUFFICIENTBANDWIDTH = 1, + UA_TSNFAILURECODE_INSUFFICIENTRESOURCES = 2, + UA_TSNFAILURECODE_INSUFFICIENTTRAFFICCLASSBANDWIDTH = 3, + UA_TSNFAILURECODE_STREAMIDINUSE = 4, + UA_TSNFAILURECODE_STREAMDESTINATIONADDRESSINUSE = 5, + UA_TSNFAILURECODE_STREAMPREEMPTEDBYHIGHERRANK = 6, + UA_TSNFAILURECODE_LATENCYHASCHANGED = 7, + UA_TSNFAILURECODE_EGRESSPORTNOTAVBCAPABLE = 8, + UA_TSNFAILURECODE_USEDIFFERENTDESTINATIONADDRESS = 9, + UA_TSNFAILURECODE_OUTOFMSRPRESOURCES = 10, + UA_TSNFAILURECODE_OUTOFMMRPRESOURCES = 11, + UA_TSNFAILURECODE_CANNOTSTOREDESTINATIONADDRESS = 12, + UA_TSNFAILURECODE_PRIORITYISNOTANSRCCLASS = 13, + UA_TSNFAILURECODE_MAXFRAMESIZETOOLARGE = 14, + UA_TSNFAILURECODE_MAXFANINPORTSLIMITREACHED = 15, + UA_TSNFAILURECODE_FIRSTVALUECHANGEDFORSTREAMID = 16, + UA_TSNFAILURECODE_VLANBLOCKEDONEGRESS = 17, + UA_TSNFAILURECODE_VLANTAGGINGDISABLEDONEGRESS = 18, + UA_TSNFAILURECODE_SRCLASSPRIORITYMISMATCH = 19, + UA_TSNFAILURECODE_FEATURENOTPROPAGATED = 20, + UA_TSNFAILURECODE_MAXLATENCYEXCEEDED = 21, + UA_TSNFAILURECODE_BRIDGEDOESNOTPROVIDENETWORKID = 22, + UA_TSNFAILURECODE_STREAMTRANSFORMNOTSUPPORTED = 23, + UA_TSNFAILURECODE_STREAMIDTYPENOTSUPPORTED = 24, + UA_TSNFAILURECODE_FEATURENOTSUPPORTED = 25 + } UA_TsnFailureCode; + +TsnStreamState +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_TSNSTREAMSTATE_DISABLED = 0, + UA_TSNSTREAMSTATE_CONFIGURING = 1, + UA_TSNSTREAMSTATE_READY = 2, + UA_TSNSTREAMSTATE_OPERATIONAL = 3, + UA_TSNSTREAMSTATE_ERROR = 4 + } UA_TsnStreamState; + +TsnTalkerStatus +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_TSNTALKERSTATUS_NONE = 0, + UA_TSNTALKERSTATUS_READY = 1, + UA_TSNTALKERSTATUS_FAILED = 2 + } UA_TsnTalkerStatus; + +TsnListenerStatus +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_TSNLISTENERSTATUS_NONE = 0, + UA_TSNLISTENERSTATUS_READY = 1, + UA_TSNLISTENERSTATUS_PARTIALFAILED = 2, + UA_TSNLISTENERSTATUS_FAILED = 3 + } UA_TsnListenerStatus; + +PriorityMappingEntryType +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String mappingUri; + UA_String priorityLabel; + UA_Byte priorityValue_PCP; + UA_UInt32 priorityValue_DSCP; + } UA_PriorityMappingEntryType; + +IdType +^^^^^^ + +.. code-block:: c + + typedef enum { + UA_IDTYPE_NUMERIC = 0, + UA_IDTYPE_STRING = 1, + UA_IDTYPE_GUID = 2, + UA_IDTYPE_OPAQUE = 3 + } UA_IdType; + +NodeClass +^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_NODECLASS_UNSPECIFIED = 0, + UA_NODECLASS_OBJECT = 1, + UA_NODECLASS_VARIABLE = 2, + UA_NODECLASS_METHOD = 4, + UA_NODECLASS_OBJECTTYPE = 8, + UA_NODECLASS_VARIABLETYPE = 16, + UA_NODECLASS_REFERENCETYPE = 32, + UA_NODECLASS_DATATYPE = 64, + UA_NODECLASS_VIEW = 128 + } UA_NodeClass; + +PermissionType +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_PermissionType; + + #define UA_PERMISSIONTYPE_NONE 0 + #define UA_PERMISSIONTYPE_BROWSE 1 + #define UA_PERMISSIONTYPE_READROLEPERMISSIONS 2 + #define UA_PERMISSIONTYPE_WRITEATTRIBUTE 4 + #define UA_PERMISSIONTYPE_WRITEROLEPERMISSIONS 8 + #define UA_PERMISSIONTYPE_WRITEHISTORIZING 16 + #define UA_PERMISSIONTYPE_READ 32 + #define UA_PERMISSIONTYPE_WRITE 64 + #define UA_PERMISSIONTYPE_READHISTORY 128 + #define UA_PERMISSIONTYPE_INSERTHISTORY 256 + #define UA_PERMISSIONTYPE_MODIFYHISTORY 512 + #define UA_PERMISSIONTYPE_DELETEHISTORY 1024 + #define UA_PERMISSIONTYPE_RECEIVEEVENTS 2048 + #define UA_PERMISSIONTYPE_CALL 4096 + #define UA_PERMISSIONTYPE_ADDREFERENCE 8192 + #define UA_PERMISSIONTYPE_REMOVEREFERENCE 16384 + #define UA_PERMISSIONTYPE_DELETENODE 32768 + #define UA_PERMISSIONTYPE_ADDNODE 65536 + +AccessLevelType +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_Byte UA_AccessLevelType; + + #define UA_ACCESSLEVELTYPE_NONE 0 + #define UA_ACCESSLEVELTYPE_CURRENTREAD 1 + #define UA_ACCESSLEVELTYPE_CURRENTWRITE 2 + #define UA_ACCESSLEVELTYPE_HISTORYREAD 4 + #define UA_ACCESSLEVELTYPE_HISTORYWRITE 8 + #define UA_ACCESSLEVELTYPE_SEMANTICCHANGE 16 + #define UA_ACCESSLEVELTYPE_STATUSWRITE 32 + #define UA_ACCESSLEVELTYPE_TIMESTAMPWRITE 64 + +AccessLevelExType +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_AccessLevelExType; + + #define UA_ACCESSLEVELEXTYPE_NONE 0 + #define UA_ACCESSLEVELEXTYPE_CURRENTREAD 1 + #define UA_ACCESSLEVELEXTYPE_CURRENTWRITE 2 + #define UA_ACCESSLEVELEXTYPE_HISTORYREAD 4 + #define UA_ACCESSLEVELEXTYPE_HISTORYWRITE 8 + #define UA_ACCESSLEVELEXTYPE_SEMANTICCHANGE 16 + #define UA_ACCESSLEVELEXTYPE_STATUSWRITE 32 + #define UA_ACCESSLEVELEXTYPE_TIMESTAMPWRITE 64 + #define UA_ACCESSLEVELEXTYPE_NONATOMICREAD 256 + #define UA_ACCESSLEVELEXTYPE_NONATOMICWRITE 512 + #define UA_ACCESSLEVELEXTYPE_WRITEFULLARRAYONLY 1024 + #define UA_ACCESSLEVELEXTYPE_NOSUBDATATYPES 2048 + #define UA_ACCESSLEVELEXTYPE_NONVOLATILE 4096 + #define UA_ACCESSLEVELEXTYPE_CONSTANT 8192 + +EventNotifierType +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_Byte UA_EventNotifierType; + + #define UA_EVENTNOTIFIERTYPE_NONE 0 + #define UA_EVENTNOTIFIERTYPE_SUBSCRIBETOEVENTS 1 + #define UA_EVENTNOTIFIERTYPE_HISTORYREAD 4 + #define UA_EVENTNOTIFIERTYPE_HISTORYWRITE 8 + +AccessRestrictionType +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt16 UA_AccessRestrictionType; + + #define UA_ACCESSRESTRICTIONTYPE_NONE 0 + #define UA_ACCESSRESTRICTIONTYPE_SIGNINGREQUIRED 1 + #define UA_ACCESSRESTRICTIONTYPE_ENCRYPTIONREQUIRED 2 + #define UA_ACCESSRESTRICTIONTYPE_SESSIONREQUIRED 4 + #define UA_ACCESSRESTRICTIONTYPE_APPLYRESTRICTIONSTOBROWSE 8 + +RolePermissionType +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId roleId; + UA_PermissionType permissions; + } UA_RolePermissionType; + +StructureType +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_STRUCTURETYPE_STRUCTURE = 0, + UA_STRUCTURETYPE_STRUCTUREWITHOPTIONALFIELDS = 1, + UA_STRUCTURETYPE_UNION = 2, + UA_STRUCTURETYPE_STRUCTUREWITHSUBTYPEDVALUES = 3, + UA_STRUCTURETYPE_UNIONWITHSUBTYPEDVALUES = 4 + } UA_StructureType; + +StructureField +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String name; + UA_LocalizedText description; + UA_NodeId dataType; + UA_Int32 valueRank; + size_t arrayDimensionsSize; + UA_UInt32 *arrayDimensions; + UA_UInt32 maxStringLength; + UA_Boolean isOptional; + } UA_StructureField; + +StructureDefinition +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId defaultEncodingId; + UA_NodeId baseDataType; + UA_StructureType structureType; + size_t fieldsSize; + UA_StructureField *fields; + } UA_StructureDefinition; + +ReferenceNode +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId referenceTypeId; + UA_Boolean isInverse; + UA_ExpandedNodeId targetId; + } UA_ReferenceNode; + +Argument +^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String name; + UA_NodeId dataType; + UA_Int32 valueRank; + size_t arrayDimensionsSize; + UA_UInt32 *arrayDimensions; + UA_LocalizedText description; + } UA_Argument; + +EnumValueType +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Int64 value; + UA_LocalizedText displayName; + UA_LocalizedText description; + } UA_EnumValueType; + +EnumField +^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Int64 value; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_String name; + } UA_EnumField; + +OptionSet +^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ByteString value; + UA_ByteString validBits; + } UA_OptionSet; + +NormalizedString +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_String UA_NormalizedString; + +DecimalString +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_String UA_DecimalString; + +DurationString +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_String UA_DurationString; + +TimeString +^^^^^^^^^^ + +.. code-block:: c + + typedef UA_String UA_TimeString; + +DateString +^^^^^^^^^^ + +.. code-block:: c + + typedef UA_String UA_DateString; + +Duration +^^^^^^^^ + +.. code-block:: c + + typedef UA_Double UA_Duration; + +UtcTime +^^^^^^^ + +.. code-block:: c + + typedef UA_DateTime UA_UtcTime; + +LocaleId +^^^^^^^^ + +.. code-block:: c + + typedef UA_String UA_LocaleId; + +TimeZoneDataType +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Int16 offset; + UA_Boolean daylightSavingInOffset; + } UA_TimeZoneDataType; + +Index +^^^^^ + +.. code-block:: c + + typedef UA_ByteString UA_Index; + +IntegerId +^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_IntegerId; + +ApplicationType +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_APPLICATIONTYPE_SERVER = 0, + UA_APPLICATIONTYPE_CLIENT = 1, + UA_APPLICATIONTYPE_CLIENTANDSERVER = 2, + UA_APPLICATIONTYPE_DISCOVERYSERVER = 3 + } UA_ApplicationType; + +ApplicationDescription +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String applicationUri; + UA_String productUri; + UA_LocalizedText applicationName; + UA_ApplicationType applicationType; + UA_String gatewayServerUri; + UA_String discoveryProfileUri; + size_t discoveryUrlsSize; + UA_String *discoveryUrls; + } UA_ApplicationDescription; + +RequestHeader +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId authenticationToken; + UA_DateTime timestamp; + UA_UInt32 requestHandle; + UA_UInt32 returnDiagnostics; + UA_String auditEntryId; + UA_UInt32 timeoutHint; + UA_ExtensionObject additionalHeader; + } UA_RequestHeader; + +ResponseHeader +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_DateTime timestamp; + UA_UInt32 requestHandle; + UA_StatusCode serviceResult; + UA_DiagnosticInfo serviceDiagnostics; + size_t stringTableSize; + UA_String *stringTable; + UA_ExtensionObject additionalHeader; + } UA_ResponseHeader; + +VersionTime +^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_ByteString UA_VersionTime; + +ServiceFault +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + } UA_ServiceFault; + +SessionlessInvokeRequestType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 urisVersion; + size_t namespaceUrisSize; + UA_String *namespaceUris; + size_t serverUrisSize; + UA_String *serverUris; + size_t localeIdsSize; + UA_String *localeIds; + UA_UInt32 serviceId; + } UA_SessionlessInvokeRequestType; + +SessionlessInvokeResponseType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t namespaceUrisSize; + UA_String *namespaceUris; + size_t serverUrisSize; + UA_String *serverUris; + UA_UInt32 serviceId; + } UA_SessionlessInvokeResponseType; + +FindServersRequest +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_String endpointUrl; + size_t localeIdsSize; + UA_String *localeIds; + size_t serverUrisSize; + UA_String *serverUris; + } UA_FindServersRequest; + +FindServersResponse +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t serversSize; + UA_ApplicationDescription *servers; + } UA_FindServersResponse; + +ServerOnNetwork +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 recordId; + UA_String serverName; + UA_String discoveryUrl; + size_t serverCapabilitiesSize; + UA_String *serverCapabilities; + } UA_ServerOnNetwork; + +FindServersOnNetworkRequest +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 startingRecordId; + UA_UInt32 maxRecordsToReturn; + size_t serverCapabilityFilterSize; + UA_String *serverCapabilityFilter; + } UA_FindServersOnNetworkRequest; + +FindServersOnNetworkResponse +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + UA_DateTime lastCounterResetTime; + size_t serversSize; + UA_ServerOnNetwork *servers; + } UA_FindServersOnNetworkResponse; + +ApplicationInstanceCertificate +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_ByteString UA_ApplicationInstanceCertificate; + +MessageSecurityMode +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_MESSAGESECURITYMODE_INVALID = 0, + UA_MESSAGESECURITYMODE_NONE = 1, + UA_MESSAGESECURITYMODE_SIGN = 2, + UA_MESSAGESECURITYMODE_SIGNANDENCRYPT = 3 + } UA_MessageSecurityMode; + +UserTokenType +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_USERTOKENTYPE_ANONYMOUS = 0, + UA_USERTOKENTYPE_USERNAME = 1, + UA_USERTOKENTYPE_CERTIFICATE = 2, + UA_USERTOKENTYPE_ISSUEDTOKEN = 3 + } UA_UserTokenType; + +UserTokenPolicy +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String policyId; + UA_UserTokenType tokenType; + UA_String issuedTokenType; + UA_String issuerEndpointUrl; + UA_String securityPolicyUri; + } UA_UserTokenPolicy; + +EndpointDescription +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String endpointUrl; + UA_ApplicationDescription server; + UA_ByteString serverCertificate; + UA_MessageSecurityMode securityMode; + UA_String securityPolicyUri; + size_t userIdentityTokensSize; + UA_UserTokenPolicy *userIdentityTokens; + UA_String transportProfileUri; + UA_Byte securityLevel; + } UA_EndpointDescription; + +GetEndpointsRequest +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_String endpointUrl; + size_t localeIdsSize; + UA_String *localeIds; + size_t profileUrisSize; + UA_String *profileUris; + } UA_GetEndpointsRequest; + +GetEndpointsResponse +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t endpointsSize; + UA_EndpointDescription *endpoints; + } UA_GetEndpointsResponse; + +RegisteredServer +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String serverUri; + UA_String productUri; + size_t serverNamesSize; + UA_LocalizedText *serverNames; + UA_ApplicationType serverType; + UA_String gatewayServerUri; + size_t discoveryUrlsSize; + UA_String *discoveryUrls; + UA_String semaphoreFilePath; + UA_Boolean isOnline; + } UA_RegisteredServer; + +RegisterServerRequest +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_RegisteredServer server; + } UA_RegisterServerRequest; + +RegisterServerResponse +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + } UA_RegisterServerResponse; + +MdnsDiscoveryConfiguration +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String mdnsServerName; + size_t serverCapabilitiesSize; + UA_String *serverCapabilities; + } UA_MdnsDiscoveryConfiguration; + +RegisterServer2Request +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_RegisteredServer server; + size_t discoveryConfigurationSize; + UA_ExtensionObject *discoveryConfiguration; + } UA_RegisterServer2Request; + +RegisterServer2Response +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t configurationResultsSize; + UA_StatusCode *configurationResults; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_RegisterServer2Response; + +SecurityTokenRequestType +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_SECURITYTOKENREQUESTTYPE_ISSUE = 0, + UA_SECURITYTOKENREQUESTTYPE_RENEW = 1 + } UA_SecurityTokenRequestType; + +ChannelSecurityToken +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 channelId; + UA_UInt32 tokenId; + UA_DateTime createdAt; + UA_UInt32 revisedLifetime; + } UA_ChannelSecurityToken; + +OpenSecureChannelRequest +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 clientProtocolVersion; + UA_SecurityTokenRequestType requestType; + UA_MessageSecurityMode securityMode; + UA_ByteString clientNonce; + UA_UInt32 requestedLifetime; + } UA_OpenSecureChannelRequest; + +OpenSecureChannelResponse +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + UA_UInt32 serverProtocolVersion; + UA_ChannelSecurityToken securityToken; + UA_ByteString serverNonce; + } UA_OpenSecureChannelResponse; + +CloseSecureChannelRequest +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + } UA_CloseSecureChannelRequest; + +CloseSecureChannelResponse +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + } UA_CloseSecureChannelResponse; + +SignedSoftwareCertificate +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ByteString certificateData; + UA_ByteString signature; + } UA_SignedSoftwareCertificate; + +SessionAuthenticationToken +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_NodeId UA_SessionAuthenticationToken; + +SignatureData +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String algorithm; + UA_ByteString signature; + } UA_SignatureData; + +CreateSessionRequest +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_ApplicationDescription clientDescription; + UA_String serverUri; + UA_String endpointUrl; + UA_String sessionName; + UA_ByteString clientNonce; + UA_ByteString clientCertificate; + UA_Double requestedSessionTimeout; + UA_UInt32 maxResponseMessageSize; + } UA_CreateSessionRequest; + +CreateSessionResponse +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + UA_NodeId sessionId; + UA_NodeId authenticationToken; + UA_Double revisedSessionTimeout; + UA_ByteString serverNonce; + UA_ByteString serverCertificate; + size_t serverEndpointsSize; + UA_EndpointDescription *serverEndpoints; + size_t serverSoftwareCertificatesSize; + UA_SignedSoftwareCertificate *serverSoftwareCertificates; + UA_SignatureData serverSignature; + UA_UInt32 maxRequestMessageSize; + } UA_CreateSessionResponse; + +UserIdentityToken +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String policyId; + } UA_UserIdentityToken; + +AnonymousIdentityToken +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String policyId; + } UA_AnonymousIdentityToken; + +UserNameIdentityToken +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String policyId; + UA_String userName; + UA_ByteString password; + UA_String encryptionAlgorithm; + } UA_UserNameIdentityToken; + +X509IdentityToken +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String policyId; + UA_ByteString certificateData; + } UA_X509IdentityToken; + +IssuedIdentityToken +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String policyId; + UA_ByteString tokenData; + UA_String encryptionAlgorithm; + } UA_IssuedIdentityToken; + +RsaEncryptedSecret +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_ByteString UA_RsaEncryptedSecret; + +EccEncryptedSecret +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_ByteString UA_EccEncryptedSecret; + +ActivateSessionRequest +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_SignatureData clientSignature; + size_t clientSoftwareCertificatesSize; + UA_SignedSoftwareCertificate *clientSoftwareCertificates; + size_t localeIdsSize; + UA_String *localeIds; + UA_ExtensionObject userIdentityToken; + UA_SignatureData userTokenSignature; + } UA_ActivateSessionRequest; + +ActivateSessionResponse +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + UA_ByteString serverNonce; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_ActivateSessionResponse; + +CloseSessionRequest +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_Boolean deleteSubscriptions; + } UA_CloseSessionRequest; + +CloseSessionResponse +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + } UA_CloseSessionResponse; + +CancelRequest +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 requestHandle; + } UA_CancelRequest; + +CancelResponse +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + UA_UInt32 cancelCount; + } UA_CancelResponse; + +NodeAttributesMask +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_NODEATTRIBUTESMASK_NONE = 0, + UA_NODEATTRIBUTESMASK_ACCESSLEVEL = 1, + UA_NODEATTRIBUTESMASK_ARRAYDIMENSIONS = 2, + UA_NODEATTRIBUTESMASK_BROWSENAME = 4, + UA_NODEATTRIBUTESMASK_CONTAINSNOLOOPS = 8, + UA_NODEATTRIBUTESMASK_DATATYPE = 16, + UA_NODEATTRIBUTESMASK_DESCRIPTION = 32, + UA_NODEATTRIBUTESMASK_DISPLAYNAME = 64, + UA_NODEATTRIBUTESMASK_EVENTNOTIFIER = 128, + UA_NODEATTRIBUTESMASK_EXECUTABLE = 256, + UA_NODEATTRIBUTESMASK_HISTORIZING = 512, + UA_NODEATTRIBUTESMASK_INVERSENAME = 1024, + UA_NODEATTRIBUTESMASK_ISABSTRACT = 2048, + UA_NODEATTRIBUTESMASK_MINIMUMSAMPLINGINTERVAL = 4096, + UA_NODEATTRIBUTESMASK_NODECLASS = 8192, + UA_NODEATTRIBUTESMASK_NODEID = 16384, + UA_NODEATTRIBUTESMASK_SYMMETRIC = 32768, + UA_NODEATTRIBUTESMASK_USERACCESSLEVEL = 65536, + UA_NODEATTRIBUTESMASK_USEREXECUTABLE = 131072, + UA_NODEATTRIBUTESMASK_USERWRITEMASK = 262144, + UA_NODEATTRIBUTESMASK_VALUERANK = 524288, + UA_NODEATTRIBUTESMASK_WRITEMASK = 1048576, + UA_NODEATTRIBUTESMASK_VALUE = 2097152, + UA_NODEATTRIBUTESMASK_DATATYPEDEFINITION = 4194304, + UA_NODEATTRIBUTESMASK_ROLEPERMISSIONS = 8388608, + UA_NODEATTRIBUTESMASK_ACCESSRESTRICTIONS = 16777216, + UA_NODEATTRIBUTESMASK_ALL = 33554431, + UA_NODEATTRIBUTESMASK_BASENODE = 26501220, + UA_NODEATTRIBUTESMASK_OBJECT = 26501348, + UA_NODEATTRIBUTESMASK_OBJECTTYPE = 26503268, + UA_NODEATTRIBUTESMASK_VARIABLE = 26571383, + UA_NODEATTRIBUTESMASK_VARIABLETYPE = 28600438, + UA_NODEATTRIBUTESMASK_METHOD = 26632548, + UA_NODEATTRIBUTESMASK_REFERENCETYPE = 26537060, + UA_NODEATTRIBUTESMASK_VIEW = 26501356 + } UA_NodeAttributesMask; + +NodeAttributes +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + } UA_NodeAttributes; + +ObjectAttributes +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Byte eventNotifier; + } UA_ObjectAttributes; + +VariableAttributes +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Variant value; + UA_NodeId dataType; + UA_Int32 valueRank; + size_t arrayDimensionsSize; + UA_UInt32 *arrayDimensions; + UA_Byte accessLevel; + UA_Byte userAccessLevel; + UA_Double minimumSamplingInterval; + UA_Boolean historizing; + } UA_VariableAttributes; + +MethodAttributes +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Boolean executable; + UA_Boolean userExecutable; + } UA_MethodAttributes; + +ObjectTypeAttributes +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Boolean isAbstract; + } UA_ObjectTypeAttributes; + +VariableTypeAttributes +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Variant value; + UA_NodeId dataType; + UA_Int32 valueRank; + size_t arrayDimensionsSize; + UA_UInt32 *arrayDimensions; + UA_Boolean isAbstract; + } UA_VariableTypeAttributes; + +ReferenceTypeAttributes +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Boolean isAbstract; + UA_Boolean symmetric; + UA_LocalizedText inverseName; + } UA_ReferenceTypeAttributes; + +DataTypeAttributes +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Boolean isAbstract; + } UA_DataTypeAttributes; + +ViewAttributes +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + UA_Boolean containsNoLoops; + UA_Byte eventNotifier; + } UA_ViewAttributes; + +GenericAttributeValue +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 attributeId; + UA_Variant value; + } UA_GenericAttributeValue; + +GenericAttributes +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 specifiedAttributes; + UA_LocalizedText displayName; + UA_LocalizedText description; + UA_UInt32 writeMask; + UA_UInt32 userWriteMask; + size_t attributeValuesSize; + UA_GenericAttributeValue *attributeValues; + } UA_GenericAttributes; + +AddNodesItem +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ExpandedNodeId parentNodeId; + UA_NodeId referenceTypeId; + UA_ExpandedNodeId requestedNewNodeId; + UA_QualifiedName browseName; + UA_NodeClass nodeClass; + UA_ExtensionObject nodeAttributes; + UA_ExpandedNodeId typeDefinition; + } UA_AddNodesItem; + +AddNodesResult +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode statusCode; + UA_NodeId addedNodeId; + } UA_AddNodesResult; + +AddNodesRequest +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t nodesToAddSize; + UA_AddNodesItem *nodesToAdd; + } UA_AddNodesRequest; + +AddNodesResponse +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_AddNodesResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_AddNodesResponse; + +AddReferencesItem +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId sourceNodeId; + UA_NodeId referenceTypeId; + UA_Boolean isForward; + UA_String targetServerUri; + UA_ExpandedNodeId targetNodeId; + UA_NodeClass targetNodeClass; + } UA_AddReferencesItem; + +AddReferencesRequest +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t referencesToAddSize; + UA_AddReferencesItem *referencesToAdd; + } UA_AddReferencesRequest; + +AddReferencesResponse +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_AddReferencesResponse; + +DeleteNodesItem +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + UA_Boolean deleteTargetReferences; + } UA_DeleteNodesItem; + +DeleteNodesRequest +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t nodesToDeleteSize; + UA_DeleteNodesItem *nodesToDelete; + } UA_DeleteNodesRequest; + +DeleteNodesResponse +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_DeleteNodesResponse; + +DeleteReferencesItem +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId sourceNodeId; + UA_NodeId referenceTypeId; + UA_Boolean isForward; + UA_ExpandedNodeId targetNodeId; + UA_Boolean deleteBidirectional; + } UA_DeleteReferencesItem; + +DeleteReferencesRequest +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t referencesToDeleteSize; + UA_DeleteReferencesItem *referencesToDelete; + } UA_DeleteReferencesRequest; + +DeleteReferencesResponse +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_DeleteReferencesResponse; + +AttributeWriteMask +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_AttributeWriteMask; + + #define UA_ATTRIBUTEWRITEMASK_NONE 0 + #define UA_ATTRIBUTEWRITEMASK_ACCESSLEVEL 1 + #define UA_ATTRIBUTEWRITEMASK_ARRAYDIMENSIONS 2 + #define UA_ATTRIBUTEWRITEMASK_BROWSENAME 4 + #define UA_ATTRIBUTEWRITEMASK_CONTAINSNOLOOPS 8 + #define UA_ATTRIBUTEWRITEMASK_DATATYPE 16 + #define UA_ATTRIBUTEWRITEMASK_DESCRIPTION 32 + #define UA_ATTRIBUTEWRITEMASK_DISPLAYNAME 64 + #define UA_ATTRIBUTEWRITEMASK_EVENTNOTIFIER 128 + #define UA_ATTRIBUTEWRITEMASK_EXECUTABLE 256 + #define UA_ATTRIBUTEWRITEMASK_HISTORIZING 512 + #define UA_ATTRIBUTEWRITEMASK_INVERSENAME 1024 + #define UA_ATTRIBUTEWRITEMASK_ISABSTRACT 2048 + #define UA_ATTRIBUTEWRITEMASK_MINIMUMSAMPLINGINTERVAL 4096 + #define UA_ATTRIBUTEWRITEMASK_NODECLASS 8192 + #define UA_ATTRIBUTEWRITEMASK_NODEID 16384 + #define UA_ATTRIBUTEWRITEMASK_SYMMETRIC 32768 + #define UA_ATTRIBUTEWRITEMASK_USERACCESSLEVEL 65536 + #define UA_ATTRIBUTEWRITEMASK_USEREXECUTABLE 131072 + #define UA_ATTRIBUTEWRITEMASK_USERWRITEMASK 262144 + #define UA_ATTRIBUTEWRITEMASK_VALUERANK 524288 + #define UA_ATTRIBUTEWRITEMASK_WRITEMASK 1048576 + #define UA_ATTRIBUTEWRITEMASK_VALUEFORVARIABLETYPE 2097152 + #define UA_ATTRIBUTEWRITEMASK_DATATYPEDEFINITION 4194304 + #define UA_ATTRIBUTEWRITEMASK_ROLEPERMISSIONS 8388608 + #define UA_ATTRIBUTEWRITEMASK_ACCESSRESTRICTIONS 16777216 + #define UA_ATTRIBUTEWRITEMASK_ACCESSLEVELEX 33554432 + +BrowseDirection +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_BROWSEDIRECTION_FORWARD = 0, + UA_BROWSEDIRECTION_INVERSE = 1, + UA_BROWSEDIRECTION_BOTH = 2, + UA_BROWSEDIRECTION_INVALID = 3 + } UA_BrowseDirection; + +ViewDescription +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId viewId; + UA_DateTime timestamp; + UA_UInt32 viewVersion; + } UA_ViewDescription; + +BrowseDescription +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + UA_BrowseDirection browseDirection; + UA_NodeId referenceTypeId; + UA_Boolean includeSubtypes; + UA_UInt32 nodeClassMask; + UA_UInt32 resultMask; + } UA_BrowseDescription; + +BrowseResultMask +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_BROWSERESULTMASK_NONE = 0, + UA_BROWSERESULTMASK_REFERENCETYPEID = 1, + UA_BROWSERESULTMASK_ISFORWARD = 2, + UA_BROWSERESULTMASK_NODECLASS = 4, + UA_BROWSERESULTMASK_BROWSENAME = 8, + UA_BROWSERESULTMASK_DISPLAYNAME = 16, + UA_BROWSERESULTMASK_TYPEDEFINITION = 32, + UA_BROWSERESULTMASK_ALL = 63, + UA_BROWSERESULTMASK_REFERENCETYPEINFO = 3, + UA_BROWSERESULTMASK_TARGETINFO = 60 + } UA_BrowseResultMask; + +ReferenceDescription +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId referenceTypeId; + UA_Boolean isForward; + UA_ExpandedNodeId nodeId; + UA_QualifiedName browseName; + UA_LocalizedText displayName; + UA_NodeClass nodeClass; + UA_ExpandedNodeId typeDefinition; + } UA_ReferenceDescription; + +ContinuationPoint +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_ByteString UA_ContinuationPoint; + +BrowseResult +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode statusCode; + UA_ByteString continuationPoint; + size_t referencesSize; + UA_ReferenceDescription *references; + } UA_BrowseResult; + +BrowseRequest +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_ViewDescription view; + UA_UInt32 requestedMaxReferencesPerNode; + size_t nodesToBrowseSize; + UA_BrowseDescription *nodesToBrowse; + } UA_BrowseRequest; + +BrowseResponse +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_BrowseResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_BrowseResponse; + +BrowseNextRequest +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_Boolean releaseContinuationPoints; + size_t continuationPointsSize; + UA_ByteString *continuationPoints; + } UA_BrowseNextRequest; + +BrowseNextResponse +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_BrowseResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_BrowseNextResponse; + +RelativePathElement +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId referenceTypeId; + UA_Boolean isInverse; + UA_Boolean includeSubtypes; + UA_QualifiedName targetName; + } UA_RelativePathElement; + +RelativePath +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t elementsSize; + UA_RelativePathElement *elements; + } UA_RelativePath; + +BrowsePath +^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId startingNode; + UA_RelativePath relativePath; + } UA_BrowsePath; + +BrowsePathTarget +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ExpandedNodeId targetId; + UA_UInt32 remainingPathIndex; + } UA_BrowsePathTarget; + +BrowsePathResult +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode statusCode; + size_t targetsSize; + UA_BrowsePathTarget *targets; + } UA_BrowsePathResult; + +TranslateBrowsePathsToNodeIdsRequest +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t browsePathsSize; + UA_BrowsePath *browsePaths; + } UA_TranslateBrowsePathsToNodeIdsRequest; + +TranslateBrowsePathsToNodeIdsResponse +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_BrowsePathResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_TranslateBrowsePathsToNodeIdsResponse; + +RegisterNodesRequest +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t nodesToRegisterSize; + UA_NodeId *nodesToRegister; + } UA_RegisterNodesRequest; + +RegisterNodesResponse +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t registeredNodeIdsSize; + UA_NodeId *registeredNodeIds; + } UA_RegisterNodesResponse; + +UnregisterNodesRequest +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t nodesToUnregisterSize; + UA_NodeId *nodesToUnregister; + } UA_UnregisterNodesRequest; + +UnregisterNodesResponse +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + } UA_UnregisterNodesResponse; + +Counter +^^^^^^^ + +.. code-block:: c + + typedef UA_UInt32 UA_Counter; + +OpaqueNumericRange +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef UA_String UA_OpaqueNumericRange; + +EndpointConfiguration +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Int32 operationTimeout; + UA_Boolean useBinaryEncoding; + UA_Int32 maxStringLength; + UA_Int32 maxByteStringLength; + UA_Int32 maxArrayLength; + UA_Int32 maxMessageSize; + UA_Int32 maxBufferSize; + UA_Int32 channelLifetime; + UA_Int32 securityTokenLifetime; + } UA_EndpointConfiguration; + +QueryDataDescription +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RelativePath relativePath; + UA_UInt32 attributeId; + UA_String indexRange; + } UA_QueryDataDescription; + +NodeTypeDescription +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ExpandedNodeId typeDefinitionNode; + UA_Boolean includeSubTypes; + size_t dataToReturnSize; + UA_QueryDataDescription *dataToReturn; + } UA_NodeTypeDescription; + +FilterOperator +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_FILTEROPERATOR_EQUALS = 0, + UA_FILTEROPERATOR_ISNULL = 1, + UA_FILTEROPERATOR_GREATERTHAN = 2, + UA_FILTEROPERATOR_LESSTHAN = 3, + UA_FILTEROPERATOR_GREATERTHANOREQUAL = 4, + UA_FILTEROPERATOR_LESSTHANOREQUAL = 5, + UA_FILTEROPERATOR_LIKE = 6, + UA_FILTEROPERATOR_NOT = 7, + UA_FILTEROPERATOR_BETWEEN = 8, + UA_FILTEROPERATOR_INLIST = 9, + UA_FILTEROPERATOR_AND = 10, + UA_FILTEROPERATOR_OR = 11, + UA_FILTEROPERATOR_CAST = 12, + UA_FILTEROPERATOR_INVIEW = 13, + UA_FILTEROPERATOR_OFTYPE = 14, + UA_FILTEROPERATOR_RELATEDTO = 15, + UA_FILTEROPERATOR_BITWISEAND = 16, + UA_FILTEROPERATOR_BITWISEOR = 17 + } UA_FilterOperator; + +QueryDataSet +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ExpandedNodeId nodeId; + UA_ExpandedNodeId typeDefinitionNode; + size_t valuesSize; + UA_Variant *values; + } UA_QueryDataSet; + +NodeReference +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + UA_NodeId referenceTypeId; + UA_Boolean isForward; + size_t referencedNodeIdsSize; + UA_NodeId *referencedNodeIds; + } UA_NodeReference; + +ContentFilterElement +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_FilterOperator filterOperator; + size_t filterOperandsSize; + UA_ExtensionObject *filterOperands; + } UA_ContentFilterElement; + +ContentFilter +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t elementsSize; + UA_ContentFilterElement *elements; + } UA_ContentFilter; + +ElementOperand +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 index; + } UA_ElementOperand; + +LiteralOperand +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Variant value; + } UA_LiteralOperand; + +AttributeOperand +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + UA_String alias; + UA_RelativePath browsePath; + UA_UInt32 attributeId; + UA_String indexRange; + } UA_AttributeOperand; + +SimpleAttributeOperand +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId typeDefinitionId; + size_t browsePathSize; + UA_QualifiedName *browsePath; + UA_UInt32 attributeId; + UA_String indexRange; + } UA_SimpleAttributeOperand; + +ContentFilterElementResult +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode statusCode; + size_t operandStatusCodesSize; + UA_StatusCode *operandStatusCodes; + size_t operandDiagnosticInfosSize; + UA_DiagnosticInfo *operandDiagnosticInfos; + } UA_ContentFilterElementResult; + +ContentFilterResult +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t elementResultsSize; + UA_ContentFilterElementResult *elementResults; + size_t elementDiagnosticInfosSize; + UA_DiagnosticInfo *elementDiagnosticInfos; + } UA_ContentFilterResult; + +ParsingResult +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode statusCode; + size_t dataStatusCodesSize; + UA_StatusCode *dataStatusCodes; + size_t dataDiagnosticInfosSize; + UA_DiagnosticInfo *dataDiagnosticInfos; + } UA_ParsingResult; + +QueryFirstRequest +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_ViewDescription view; + size_t nodeTypesSize; + UA_NodeTypeDescription *nodeTypes; + UA_ContentFilter filter; + UA_UInt32 maxDataSetsToReturn; + UA_UInt32 maxReferencesToReturn; + } UA_QueryFirstRequest; + +QueryFirstResponse +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t queryDataSetsSize; + UA_QueryDataSet *queryDataSets; + UA_ByteString continuationPoint; + size_t parsingResultsSize; + UA_ParsingResult *parsingResults; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + UA_ContentFilterResult filterResult; + } UA_QueryFirstResponse; + +QueryNextRequest +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_Boolean releaseContinuationPoint; + UA_ByteString continuationPoint; + } UA_QueryNextRequest; + +QueryNextResponse +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t queryDataSetsSize; + UA_QueryDataSet *queryDataSets; + UA_ByteString revisedContinuationPoint; + } UA_QueryNextResponse; + +TimestampsToReturn +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_TIMESTAMPSTORETURN_SOURCE = 0, + UA_TIMESTAMPSTORETURN_SERVER = 1, + UA_TIMESTAMPSTORETURN_BOTH = 2, + UA_TIMESTAMPSTORETURN_NEITHER = 3, + UA_TIMESTAMPSTORETURN_INVALID = 4 + } UA_TimestampsToReturn; + +ReadValueId +^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + UA_UInt32 attributeId; + UA_String indexRange; + UA_QualifiedName dataEncoding; + } UA_ReadValueId; + +ReadRequest +^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_Double maxAge; + UA_TimestampsToReturn timestampsToReturn; + size_t nodesToReadSize; + UA_ReadValueId *nodesToRead; + } UA_ReadRequest; + +ReadResponse +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_DataValue *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_ReadResponse; + +HistoryReadValueId +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + UA_String indexRange; + UA_QualifiedName dataEncoding; + UA_ByteString continuationPoint; + } UA_HistoryReadValueId; + +HistoryReadResult +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode statusCode; + UA_ByteString continuationPoint; + UA_ExtensionObject historyData; + } UA_HistoryReadResult; + +ReadRawModifiedDetails +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Boolean isReadModified; + UA_DateTime startTime; + UA_DateTime endTime; + UA_UInt32 numValuesPerNode; + UA_Boolean returnBounds; + } UA_ReadRawModifiedDetails; + +ReadAtTimeDetails +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t reqTimesSize; + UA_DateTime *reqTimes; + UA_Boolean useSimpleBounds; + } UA_ReadAtTimeDetails; + +ReadAnnotationDataDetails +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t reqTimesSize; + UA_DateTime *reqTimes; + } UA_ReadAnnotationDataDetails; + +HistoryData +^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t dataValuesSize; + UA_DataValue *dataValues; + } UA_HistoryData; + +HistoryReadRequest +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_ExtensionObject historyReadDetails; + UA_TimestampsToReturn timestampsToReturn; + UA_Boolean releaseContinuationPoints; + size_t nodesToReadSize; + UA_HistoryReadValueId *nodesToRead; + } UA_HistoryReadRequest; + +HistoryReadResponse +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_HistoryReadResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_HistoryReadResponse; + +WriteValue +^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + UA_UInt32 attributeId; + UA_String indexRange; + UA_DataValue value; + } UA_WriteValue; + +WriteRequest +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t nodesToWriteSize; + UA_WriteValue *nodesToWrite; + } UA_WriteRequest; + +WriteResponse +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_WriteResponse; + +HistoryUpdateDetails +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + } UA_HistoryUpdateDetails; + +HistoryUpdateType +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_HISTORYUPDATETYPE_INSERT = 1, + UA_HISTORYUPDATETYPE_REPLACE = 2, + UA_HISTORYUPDATETYPE_UPDATE = 3, + UA_HISTORYUPDATETYPE_DELETE = 4 + } UA_HistoryUpdateType; + +PerformUpdateType +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_PERFORMUPDATETYPE_INSERT = 1, + UA_PERFORMUPDATETYPE_REPLACE = 2, + UA_PERFORMUPDATETYPE_UPDATE = 3, + UA_PERFORMUPDATETYPE_REMOVE = 4 + } UA_PerformUpdateType; + +UpdateDataDetails +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + UA_PerformUpdateType performInsertReplace; + size_t updateValuesSize; + UA_DataValue *updateValues; + } UA_UpdateDataDetails; + +UpdateStructureDataDetails +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + UA_PerformUpdateType performInsertReplace; + size_t updateValuesSize; + UA_DataValue *updateValues; + } UA_UpdateStructureDataDetails; + +DeleteRawModifiedDetails +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + UA_Boolean isDeleteModified; + UA_DateTime startTime; + UA_DateTime endTime; + } UA_DeleteRawModifiedDetails; + +DeleteAtTimeDetails +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + size_t reqTimesSize; + UA_DateTime *reqTimes; + } UA_DeleteAtTimeDetails; + +DeleteEventDetails +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + size_t eventIdsSize; + UA_ByteString *eventIds; + } UA_DeleteEventDetails; + +HistoryUpdateResult +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode statusCode; + size_t operationResultsSize; + UA_StatusCode *operationResults; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_HistoryUpdateResult; + +HistoryUpdateRequest +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t historyUpdateDetailsSize; + UA_ExtensionObject *historyUpdateDetails; + } UA_HistoryUpdateRequest; + +HistoryUpdateResponse +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_HistoryUpdateResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_HistoryUpdateResponse; + +CallMethodRequest +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId objectId; + UA_NodeId methodId; + size_t inputArgumentsSize; + UA_Variant *inputArguments; + } UA_CallMethodRequest; + +CallMethodResult +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode statusCode; + size_t inputArgumentResultsSize; + UA_StatusCode *inputArgumentResults; + size_t inputArgumentDiagnosticInfosSize; + UA_DiagnosticInfo *inputArgumentDiagnosticInfos; + size_t outputArgumentsSize; + UA_Variant *outputArguments; + } UA_CallMethodResult; + +CallRequest +^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t methodsToCallSize; + UA_CallMethodRequest *methodsToCall; + } UA_CallRequest; + +CallResponse +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_CallMethodResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_CallResponse; + +MonitoringMode +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_MONITORINGMODE_DISABLED = 0, + UA_MONITORINGMODE_SAMPLING = 1, + UA_MONITORINGMODE_REPORTING = 2 + } UA_MonitoringMode; + +DataChangeTrigger +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_DATACHANGETRIGGER_STATUS = 0, + UA_DATACHANGETRIGGER_STATUSVALUE = 1, + UA_DATACHANGETRIGGER_STATUSVALUETIMESTAMP = 2 + } UA_DataChangeTrigger; + +DeadbandType +^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_DEADBANDTYPE_NONE = 0, + UA_DEADBANDTYPE_ABSOLUTE = 1, + UA_DEADBANDTYPE_PERCENT = 2 + } UA_DeadbandType; + +DataChangeFilter +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_DataChangeTrigger trigger; + UA_UInt32 deadbandType; + UA_Double deadbandValue; + } UA_DataChangeFilter; + +EventFilter +^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t selectClausesSize; + UA_SimpleAttributeOperand *selectClauses; + UA_ContentFilter whereClause; + } UA_EventFilter; + +AggregateConfiguration +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Boolean useServerCapabilitiesDefaults; + UA_Boolean treatUncertainAsBad; + UA_Byte percentDataBad; + UA_Byte percentDataGood; + UA_Boolean useSlopedExtrapolation; + } UA_AggregateConfiguration; + +AggregateFilter +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_DateTime startTime; + UA_NodeId aggregateType; + UA_Double processingInterval; + UA_AggregateConfiguration aggregateConfiguration; + } UA_AggregateFilter; + +EventFilterResult +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t selectClauseResultsSize; + UA_StatusCode *selectClauseResults; + size_t selectClauseDiagnosticInfosSize; + UA_DiagnosticInfo *selectClauseDiagnosticInfos; + UA_ContentFilterResult whereClauseResult; + } UA_EventFilterResult; + +AggregateFilterResult +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_DateTime revisedStartTime; + UA_Double revisedProcessingInterval; + UA_AggregateConfiguration revisedAggregateConfiguration; + } UA_AggregateFilterResult; + +MonitoringParameters +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 clientHandle; + UA_Double samplingInterval; + UA_ExtensionObject filter; + UA_UInt32 queueSize; + UA_Boolean discardOldest; + } UA_MonitoringParameters; + +MonitoredItemCreateRequest +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ReadValueId itemToMonitor; + UA_MonitoringMode monitoringMode; + UA_MonitoringParameters requestedParameters; + } UA_MonitoredItemCreateRequest; + +MonitoredItemCreateResult +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode statusCode; + UA_UInt32 monitoredItemId; + UA_Double revisedSamplingInterval; + UA_UInt32 revisedQueueSize; + UA_ExtensionObject filterResult; + } UA_MonitoredItemCreateResult; + +CreateMonitoredItemsRequest +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + UA_TimestampsToReturn timestampsToReturn; + size_t itemsToCreateSize; + UA_MonitoredItemCreateRequest *itemsToCreate; + } UA_CreateMonitoredItemsRequest; + +CreateMonitoredItemsResponse +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_MonitoredItemCreateResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_CreateMonitoredItemsResponse; + +MonitoredItemModifyRequest +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 monitoredItemId; + UA_MonitoringParameters requestedParameters; + } UA_MonitoredItemModifyRequest; + +MonitoredItemModifyResult +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode statusCode; + UA_Double revisedSamplingInterval; + UA_UInt32 revisedQueueSize; + UA_ExtensionObject filterResult; + } UA_MonitoredItemModifyResult; + +ModifyMonitoredItemsRequest +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + UA_TimestampsToReturn timestampsToReturn; + size_t itemsToModifySize; + UA_MonitoredItemModifyRequest *itemsToModify; + } UA_ModifyMonitoredItemsRequest; + +ModifyMonitoredItemsResponse +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_MonitoredItemModifyResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_ModifyMonitoredItemsResponse; + +SetMonitoringModeRequest +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + UA_MonitoringMode monitoringMode; + size_t monitoredItemIdsSize; + UA_UInt32 *monitoredItemIds; + } UA_SetMonitoringModeRequest; + +SetMonitoringModeResponse +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_SetMonitoringModeResponse; + +SetTriggeringRequest +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + UA_UInt32 triggeringItemId; + size_t linksToAddSize; + UA_UInt32 *linksToAdd; + size_t linksToRemoveSize; + UA_UInt32 *linksToRemove; + } UA_SetTriggeringRequest; + +SetTriggeringResponse +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t addResultsSize; + UA_StatusCode *addResults; + size_t addDiagnosticInfosSize; + UA_DiagnosticInfo *addDiagnosticInfos; + size_t removeResultsSize; + UA_StatusCode *removeResults; + size_t removeDiagnosticInfosSize; + UA_DiagnosticInfo *removeDiagnosticInfos; + } UA_SetTriggeringResponse; + +DeleteMonitoredItemsRequest +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + size_t monitoredItemIdsSize; + UA_UInt32 *monitoredItemIds; + } UA_DeleteMonitoredItemsRequest; + +DeleteMonitoredItemsResponse +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_DeleteMonitoredItemsResponse; + +CreateSubscriptionRequest +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_Double requestedPublishingInterval; + UA_UInt32 requestedLifetimeCount; + UA_UInt32 requestedMaxKeepAliveCount; + UA_UInt32 maxNotificationsPerPublish; + UA_Boolean publishingEnabled; + UA_Byte priority; + } UA_CreateSubscriptionRequest; + +CreateSubscriptionResponse +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + UA_UInt32 subscriptionId; + UA_Double revisedPublishingInterval; + UA_UInt32 revisedLifetimeCount; + UA_UInt32 revisedMaxKeepAliveCount; + } UA_CreateSubscriptionResponse; + +ModifySubscriptionRequest +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + UA_Double requestedPublishingInterval; + UA_UInt32 requestedLifetimeCount; + UA_UInt32 requestedMaxKeepAliveCount; + UA_UInt32 maxNotificationsPerPublish; + UA_Byte priority; + } UA_ModifySubscriptionRequest; + +ModifySubscriptionResponse +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + UA_Double revisedPublishingInterval; + UA_UInt32 revisedLifetimeCount; + UA_UInt32 revisedMaxKeepAliveCount; + } UA_ModifySubscriptionResponse; + +SetPublishingModeRequest +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_Boolean publishingEnabled; + size_t subscriptionIdsSize; + UA_UInt32 *subscriptionIds; + } UA_SetPublishingModeRequest; + +SetPublishingModeResponse +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_SetPublishingModeResponse; + +NotificationMessage +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 sequenceNumber; + UA_DateTime publishTime; + size_t notificationDataSize; + UA_ExtensionObject *notificationData; + } UA_NotificationMessage; + +MonitoredItemNotification +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 clientHandle; + UA_DataValue value; + } UA_MonitoredItemNotification; + +EventFieldList +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 clientHandle; + size_t eventFieldsSize; + UA_Variant *eventFields; + } UA_EventFieldList; + +HistoryEventFieldList +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t eventFieldsSize; + UA_Variant *eventFields; + } UA_HistoryEventFieldList; + +StatusChangeNotification +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode status; + UA_DiagnosticInfo diagnosticInfo; + } UA_StatusChangeNotification; + +SubscriptionAcknowledgement +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 subscriptionId; + UA_UInt32 sequenceNumber; + } UA_SubscriptionAcknowledgement; + +PublishRequest +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t subscriptionAcknowledgementsSize; + UA_SubscriptionAcknowledgement *subscriptionAcknowledgements; + } UA_PublishRequest; + +PublishResponse +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + UA_UInt32 subscriptionId; + size_t availableSequenceNumbersSize; + UA_UInt32 *availableSequenceNumbers; + UA_Boolean moreNotifications; + UA_NotificationMessage notificationMessage; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_PublishResponse; + +RepublishRequest +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + UA_UInt32 subscriptionId; + UA_UInt32 retransmitSequenceNumber; + } UA_RepublishRequest; + +RepublishResponse +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + UA_NotificationMessage notificationMessage; + } UA_RepublishResponse; + +TransferResult +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode statusCode; + size_t availableSequenceNumbersSize; + UA_UInt32 *availableSequenceNumbers; + } UA_TransferResult; + +TransferSubscriptionsRequest +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t subscriptionIdsSize; + UA_UInt32 *subscriptionIds; + UA_Boolean sendInitialValues; + } UA_TransferSubscriptionsRequest; + +TransferSubscriptionsResponse +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_TransferResult *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_TransferSubscriptionsResponse; + +DeleteSubscriptionsRequest +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_RequestHeader requestHeader; + size_t subscriptionIdsSize; + UA_UInt32 *subscriptionIds; + } UA_DeleteSubscriptionsRequest; + +DeleteSubscriptionsResponse +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_ResponseHeader responseHeader; + size_t resultsSize; + UA_StatusCode *results; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_DeleteSubscriptionsResponse; + +BuildInfo +^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String productUri; + UA_String manufacturerName; + UA_String productName; + UA_String softwareVersion; + UA_String buildNumber; + UA_DateTime buildDate; + } UA_BuildInfo; + +RedundancySupport +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_REDUNDANCYSUPPORT_NONE = 0, + UA_REDUNDANCYSUPPORT_COLD = 1, + UA_REDUNDANCYSUPPORT_WARM = 2, + UA_REDUNDANCYSUPPORT_HOT = 3, + UA_REDUNDANCYSUPPORT_TRANSPARENT = 4, + UA_REDUNDANCYSUPPORT_HOTANDMIRRORED = 5 + } UA_RedundancySupport; + +ServerState +^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_SERVERSTATE_RUNNING = 0, + UA_SERVERSTATE_FAILED = 1, + UA_SERVERSTATE_NOCONFIGURATION = 2, + UA_SERVERSTATE_SUSPENDED = 3, + UA_SERVERSTATE_SHUTDOWN = 4, + UA_SERVERSTATE_TEST = 5, + UA_SERVERSTATE_COMMUNICATIONFAULT = 6, + UA_SERVERSTATE_UNKNOWN = 7 + } UA_ServerState; + +RedundantServerDataType +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String serverId; + UA_Byte serviceLevel; + UA_ServerState serverState; + } UA_RedundantServerDataType; + +EndpointUrlListDataType +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t endpointUrlListSize; + UA_String *endpointUrlList; + } UA_EndpointUrlListDataType; + +NetworkGroupDataType +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String serverUri; + size_t networkPathsSize; + UA_EndpointUrlListDataType *networkPaths; + } UA_NetworkGroupDataType; + +SamplingIntervalDiagnosticsDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Double samplingInterval; + UA_UInt32 monitoredItemCount; + UA_UInt32 maxMonitoredItemCount; + UA_UInt32 disabledMonitoredItemCount; + } UA_SamplingIntervalDiagnosticsDataType; + +ServerDiagnosticsSummaryDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 serverViewCount; + UA_UInt32 currentSessionCount; + UA_UInt32 cumulatedSessionCount; + UA_UInt32 securityRejectedSessionCount; + UA_UInt32 rejectedSessionCount; + UA_UInt32 sessionTimeoutCount; + UA_UInt32 sessionAbortCount; + UA_UInt32 currentSubscriptionCount; + UA_UInt32 cumulatedSubscriptionCount; + UA_UInt32 publishingIntervalCount; + UA_UInt32 securityRejectedRequestsCount; + UA_UInt32 rejectedRequestsCount; + } UA_ServerDiagnosticsSummaryDataType; + +ServerStatusDataType +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_DateTime startTime; + UA_DateTime currentTime; + UA_ServerState state; + UA_BuildInfo buildInfo; + UA_UInt32 secondsTillShutdown; + UA_LocalizedText shutdownReason; + } UA_ServerStatusDataType; + +SessionSecurityDiagnosticsDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId sessionId; + UA_String clientUserIdOfSession; + size_t clientUserIdHistorySize; + UA_String *clientUserIdHistory; + UA_String authenticationMechanism; + UA_String encoding; + UA_String transportProtocol; + UA_MessageSecurityMode securityMode; + UA_String securityPolicyUri; + UA_ByteString clientCertificate; + } UA_SessionSecurityDiagnosticsDataType; + +ServiceCounterDataType +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 totalCount; + UA_UInt32 errorCount; + } UA_ServiceCounterDataType; + +StatusResult +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_StatusCode statusCode; + UA_DiagnosticInfo diagnosticInfo; + } UA_StatusResult; + +SubscriptionDiagnosticsDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId sessionId; + UA_UInt32 subscriptionId; + UA_Byte priority; + UA_Double publishingInterval; + UA_UInt32 maxKeepAliveCount; + UA_UInt32 maxLifetimeCount; + UA_UInt32 maxNotificationsPerPublish; + UA_Boolean publishingEnabled; + UA_UInt32 modifyCount; + UA_UInt32 enableCount; + UA_UInt32 disableCount; + UA_UInt32 republishRequestCount; + UA_UInt32 republishMessageRequestCount; + UA_UInt32 republishMessageCount; + UA_UInt32 transferRequestCount; + UA_UInt32 transferredToAltClientCount; + UA_UInt32 transferredToSameClientCount; + UA_UInt32 publishRequestCount; + UA_UInt32 dataChangeNotificationsCount; + UA_UInt32 eventNotificationsCount; + UA_UInt32 notificationsCount; + UA_UInt32 latePublishRequestCount; + UA_UInt32 currentKeepAliveCount; + UA_UInt32 currentLifetimeCount; + UA_UInt32 unacknowledgedMessageCount; + UA_UInt32 discardedMessageCount; + UA_UInt32 monitoredItemCount; + UA_UInt32 disabledMonitoredItemCount; + UA_UInt32 monitoringQueueOverflowCount; + UA_UInt32 nextSequenceNumber; + UA_UInt32 eventQueueOverFlowCount; + } UA_SubscriptionDiagnosticsDataType; + +ModelChangeStructureVerbMask +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_MODELCHANGESTRUCTUREVERBMASK_NODEADDED = 1, + UA_MODELCHANGESTRUCTUREVERBMASK_NODEDELETED = 2, + UA_MODELCHANGESTRUCTUREVERBMASK_REFERENCEADDED = 4, + UA_MODELCHANGESTRUCTUREVERBMASK_REFERENCEDELETED = 8, + UA_MODELCHANGESTRUCTUREVERBMASK_DATATYPECHANGED = 16 + } UA_ModelChangeStructureVerbMask; + +ModelChangeStructureDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId affected; + UA_NodeId affectedType; + UA_Byte verb; + } UA_ModelChangeStructureDataType; + +SemanticChangeStructureDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId affected; + UA_NodeId affectedType; + } UA_SemanticChangeStructureDataType; + +Range +^^^^^ + +.. code-block:: c + + typedef struct { + UA_Double low; + UA_Double high; + } UA_Range; + +EUInformation +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String namespaceUri; + UA_Int32 unitId; + UA_LocalizedText displayName; + UA_LocalizedText description; + } UA_EUInformation; + +AxisScaleEnumeration +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_AXISSCALEENUMERATION_LINEAR = 0, + UA_AXISSCALEENUMERATION_LOG = 1, + UA_AXISSCALEENUMERATION_LN = 2 + } UA_AxisScaleEnumeration; + +ComplexNumberType +^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Float real; + UA_Float imaginary; + } UA_ComplexNumberType; + +DoubleComplexNumberType +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Double real; + UA_Double imaginary; + } UA_DoubleComplexNumberType; + +AxisInformation +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_EUInformation engineeringUnits; + UA_Range eURange; + UA_LocalizedText title; + UA_AxisScaleEnumeration axisScaleType; + size_t axisStepsSize; + UA_Double *axisSteps; + } UA_AxisInformation; + +XVType +^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Double x; + UA_Float value; + } UA_XVType; + +ProgramDiagnosticDataType +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId createSessionId; + UA_String createClientName; + UA_DateTime invocationCreationTime; + UA_DateTime lastTransitionTime; + UA_String lastMethodCall; + UA_NodeId lastMethodSessionId; + size_t lastMethodInputArgumentsSize; + UA_Argument *lastMethodInputArguments; + size_t lastMethodOutputArgumentsSize; + UA_Argument *lastMethodOutputArguments; + UA_DateTime lastMethodCallTime; + UA_StatusResult lastMethodReturnStatus; + } UA_ProgramDiagnosticDataType; + +ProgramDiagnostic2DataType +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId createSessionId; + UA_String createClientName; + UA_DateTime invocationCreationTime; + UA_DateTime lastTransitionTime; + UA_String lastMethodCall; + UA_NodeId lastMethodSessionId; + size_t lastMethodInputArgumentsSize; + UA_Argument *lastMethodInputArguments; + size_t lastMethodOutputArgumentsSize; + UA_Argument *lastMethodOutputArguments; + size_t lastMethodInputValuesSize; + UA_Variant *lastMethodInputValues; + size_t lastMethodOutputValuesSize; + UA_Variant *lastMethodOutputValues; + UA_DateTime lastMethodCallTime; + UA_StatusCode lastMethodReturnStatus; + } UA_ProgramDiagnostic2DataType; + +Annotation +^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String message; + UA_String userName; + UA_DateTime annotationTime; + } UA_Annotation; + +ExceptionDeviationFormat +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef enum { + UA_EXCEPTIONDEVIATIONFORMAT_ABSOLUTEVALUE = 0, + UA_EXCEPTIONDEVIATIONFORMAT_PERCENTOFVALUE = 1, + UA_EXCEPTIONDEVIATIONFORMAT_PERCENTOFRANGE = 2, + UA_EXCEPTIONDEVIATIONFORMAT_PERCENTOFEURANGE = 3, + UA_EXCEPTIONDEVIATIONFORMAT_UNKNOWN = 4 + } UA_ExceptionDeviationFormat; + +EndpointType +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String endpointUrl; + UA_MessageSecurityMode securityMode; + UA_String securityPolicyUri; + UA_String transportProfileUri; + } UA_EndpointType; + +StructureDescription +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId dataTypeId; + UA_QualifiedName name; + UA_StructureDefinition structureDefinition; + } UA_StructureDescription; + +FieldMetaData +^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String name; + UA_LocalizedText description; + UA_DataSetFieldFlags fieldFlags; + UA_Byte builtInType; + UA_NodeId dataType; + UA_Int32 valueRank; + size_t arrayDimensionsSize; + UA_UInt32 *arrayDimensions; + UA_UInt32 maxStringLength; + UA_Guid dataSetFieldId; + size_t propertiesSize; + UA_KeyValuePair *properties; + } UA_FieldMetaData; + +PublishedEventsDataType +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId eventNotifier; + size_t selectedFieldsSize; + UA_SimpleAttributeOperand *selectedFields; + UA_ContentFilter filter; + } UA_PublishedEventsDataType; + +PubSubGroupDataType +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String name; + UA_Boolean enabled; + UA_MessageSecurityMode securityMode; + UA_String securityGroupId; + size_t securityKeyServicesSize; + UA_EndpointDescription *securityKeyServices; + UA_UInt32 maxNetworkMessageSize; + size_t groupPropertiesSize; + UA_KeyValuePair *groupProperties; + } UA_PubSubGroupDataType; + +WriterGroupDataType +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String name; + UA_Boolean enabled; + UA_MessageSecurityMode securityMode; + UA_String securityGroupId; + size_t securityKeyServicesSize; + UA_EndpointDescription *securityKeyServices; + UA_UInt32 maxNetworkMessageSize; + size_t groupPropertiesSize; + UA_KeyValuePair *groupProperties; + UA_UInt16 writerGroupId; + UA_Double publishingInterval; + UA_Double keepAliveTime; + UA_Byte priority; + size_t localeIdsSize; + UA_String *localeIds; + UA_String headerLayoutUri; + UA_ExtensionObject transportSettings; + UA_ExtensionObject messageSettings; + size_t dataSetWritersSize; + UA_DataSetWriterDataType *dataSetWriters; + } UA_WriterGroupDataType; + +FieldTargetDataType +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_Guid dataSetFieldId; + UA_String receiverIndexRange; + UA_NodeId targetNodeId; + UA_UInt32 attributeId; + UA_String writeIndexRange; + UA_OverrideValueHandling overrideValueHandling; + UA_Variant overrideValue; + } UA_FieldTargetDataType; + +SubscribedDataSetMirrorDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String parentNodeName; + size_t rolePermissionsSize; + UA_RolePermissionType *rolePermissions; + } UA_SubscribedDataSetMirrorDataType; + +SecurityGroupDataType +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String name; + size_t securityGroupFolderSize; + UA_String *securityGroupFolder; + UA_Double keyLifetime; + UA_String securityPolicyUri; + UA_UInt32 maxFutureKeyCount; + UA_UInt32 maxPastKeyCount; + UA_String securityGroupId; + size_t rolePermissionsSize; + UA_RolePermissionType *rolePermissions; + size_t groupPropertiesSize; + UA_KeyValuePair *groupProperties; + } UA_SecurityGroupDataType; + +PubSubKeyPushTargetDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String applicationUri; + size_t pushTargetFolderSize; + UA_String *pushTargetFolder; + UA_String endpointUrl; + UA_String securityPolicyUri; + UA_UserTokenPolicy userTokenType; + UA_UInt16 requestedKeyCount; + UA_Double retryInterval; + size_t pushTargetPropertiesSize; + UA_KeyValuePair *pushTargetProperties; + size_t securityGroupsSize; + UA_String *securityGroups; + } UA_PubSubKeyPushTargetDataType; + +EnumDefinition +^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t fieldsSize; + UA_EnumField *fields; + } UA_EnumDefinition; + +ReadEventDetails +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_UInt32 numValuesPerNode; + UA_DateTime startTime; + UA_DateTime endTime; + UA_EventFilter filter; + } UA_ReadEventDetails; + +ReadProcessedDetails +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_DateTime startTime; + UA_DateTime endTime; + UA_Double processingInterval; + size_t aggregateTypeSize; + UA_NodeId *aggregateType; + UA_AggregateConfiguration aggregateConfiguration; + } UA_ReadProcessedDetails; + +ModificationInfo +^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_DateTime modificationTime; + UA_HistoryUpdateType updateType; + UA_String userName; + } UA_ModificationInfo; + +HistoryModifiedData +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t dataValuesSize; + UA_DataValue *dataValues; + size_t modificationInfosSize; + UA_ModificationInfo *modificationInfos; + } UA_HistoryModifiedData; + +HistoryEvent +^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t eventsSize; + UA_HistoryEventFieldList *events; + } UA_HistoryEvent; + +UpdateEventDetails +^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId nodeId; + UA_PerformUpdateType performInsertReplace; + UA_EventFilter filter; + size_t eventDataSize; + UA_HistoryEventFieldList *eventData; + } UA_UpdateEventDetails; + +DataChangeNotification +^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t monitoredItemsSize; + UA_MonitoredItemNotification *monitoredItems; + size_t diagnosticInfosSize; + UA_DiagnosticInfo *diagnosticInfos; + } UA_DataChangeNotification; + +EventNotificationList +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t eventsSize; + UA_EventFieldList *events; + } UA_EventNotificationList; + +SessionDiagnosticsDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId sessionId; + UA_String sessionName; + UA_ApplicationDescription clientDescription; + UA_String serverUri; + UA_String endpointUrl; + size_t localeIdsSize; + UA_String *localeIds; + UA_Double actualSessionTimeout; + UA_UInt32 maxResponseMessageSize; + UA_DateTime clientConnectionTime; + UA_DateTime clientLastContactTime; + UA_UInt32 currentSubscriptionsCount; + UA_UInt32 currentMonitoredItemsCount; + UA_UInt32 currentPublishRequestsInQueue; + UA_ServiceCounterDataType totalRequestCount; + UA_UInt32 unauthorizedRequestCount; + UA_ServiceCounterDataType readCount; + UA_ServiceCounterDataType historyReadCount; + UA_ServiceCounterDataType writeCount; + UA_ServiceCounterDataType historyUpdateCount; + UA_ServiceCounterDataType callCount; + UA_ServiceCounterDataType createMonitoredItemsCount; + UA_ServiceCounterDataType modifyMonitoredItemsCount; + UA_ServiceCounterDataType setMonitoringModeCount; + UA_ServiceCounterDataType setTriggeringCount; + UA_ServiceCounterDataType deleteMonitoredItemsCount; + UA_ServiceCounterDataType createSubscriptionCount; + UA_ServiceCounterDataType modifySubscriptionCount; + UA_ServiceCounterDataType setPublishingModeCount; + UA_ServiceCounterDataType publishCount; + UA_ServiceCounterDataType republishCount; + UA_ServiceCounterDataType transferSubscriptionsCount; + UA_ServiceCounterDataType deleteSubscriptionsCount; + UA_ServiceCounterDataType addNodesCount; + UA_ServiceCounterDataType addReferencesCount; + UA_ServiceCounterDataType deleteNodesCount; + UA_ServiceCounterDataType deleteReferencesCount; + UA_ServiceCounterDataType browseCount; + UA_ServiceCounterDataType browseNextCount; + UA_ServiceCounterDataType translateBrowsePathsToNodeIdsCount; + UA_ServiceCounterDataType queryFirstCount; + UA_ServiceCounterDataType queryNextCount; + UA_ServiceCounterDataType registerNodesCount; + UA_ServiceCounterDataType unregisterNodesCount; + } UA_SessionDiagnosticsDataType; + +EnumDescription +^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_NodeId dataTypeId; + UA_QualifiedName name; + UA_EnumDefinition enumDefinition; + UA_Byte builtInType; + } UA_EnumDescription; + +UABinaryFileDataType +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t namespacesSize; + UA_String *namespaces; + size_t structureDataTypesSize; + UA_StructureDescription *structureDataTypes; + size_t enumDataTypesSize; + UA_EnumDescription *enumDataTypes; + size_t simpleDataTypesSize; + UA_SimpleTypeDescription *simpleDataTypes; + UA_String schemaLocation; + size_t fileHeaderSize; + UA_KeyValuePair *fileHeader; + UA_Variant body; + } UA_UABinaryFileDataType; + +DataSetMetaDataType +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t namespacesSize; + UA_String *namespaces; + size_t structureDataTypesSize; + UA_StructureDescription *structureDataTypes; + size_t enumDataTypesSize; + UA_EnumDescription *enumDataTypes; + size_t simpleDataTypesSize; + UA_SimpleTypeDescription *simpleDataTypes; + UA_String name; + UA_LocalizedText description; + size_t fieldsSize; + UA_FieldMetaData *fields; + UA_Guid dataSetClassId; + UA_ConfigurationVersionDataType configurationVersion; + } UA_DataSetMetaDataType; + +PublishedDataSetDataType +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String name; + size_t dataSetFolderSize; + UA_String *dataSetFolder; + UA_DataSetMetaDataType dataSetMetaData; + size_t extensionFieldsSize; + UA_KeyValuePair *extensionFields; + UA_ExtensionObject dataSetSource; + } UA_PublishedDataSetDataType; + +DataSetReaderDataType +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String name; + UA_Boolean enabled; + UA_Variant publisherId; + UA_UInt16 writerGroupId; + UA_UInt16 dataSetWriterId; + UA_DataSetMetaDataType dataSetMetaData; + UA_DataSetFieldContentMask dataSetFieldContentMask; + UA_Double messageReceiveTimeout; + UA_UInt32 keyFrameCount; + UA_String headerLayoutUri; + UA_MessageSecurityMode securityMode; + UA_String securityGroupId; + size_t securityKeyServicesSize; + UA_EndpointDescription *securityKeyServices; + size_t dataSetReaderPropertiesSize; + UA_KeyValuePair *dataSetReaderProperties; + UA_ExtensionObject transportSettings; + UA_ExtensionObject messageSettings; + UA_ExtensionObject subscribedDataSet; + } UA_DataSetReaderDataType; + +TargetVariablesDataType +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t targetVariablesSize; + UA_FieldTargetDataType *targetVariables; + } UA_TargetVariablesDataType; + +StandaloneSubscribedDataSetDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String name; + size_t dataSetFolderSize; + UA_String *dataSetFolder; + UA_DataSetMetaDataType dataSetMetaData; + UA_ExtensionObject subscribedDataSet; + } UA_StandaloneSubscribedDataSetDataType; + +DataTypeSchemaHeader +^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t namespacesSize; + UA_String *namespaces; + size_t structureDataTypesSize; + UA_StructureDescription *structureDataTypes; + size_t enumDataTypesSize; + UA_EnumDescription *enumDataTypes; + size_t simpleDataTypesSize; + UA_SimpleTypeDescription *simpleDataTypes; + } UA_DataTypeSchemaHeader; + +ReaderGroupDataType +^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String name; + UA_Boolean enabled; + UA_MessageSecurityMode securityMode; + UA_String securityGroupId; + size_t securityKeyServicesSize; + UA_EndpointDescription *securityKeyServices; + UA_UInt32 maxNetworkMessageSize; + size_t groupPropertiesSize; + UA_KeyValuePair *groupProperties; + UA_ExtensionObject transportSettings; + UA_ExtensionObject messageSettings; + size_t dataSetReadersSize; + UA_DataSetReaderDataType *dataSetReaders; + } UA_ReaderGroupDataType; + +PubSubConnectionDataType +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + UA_String name; + UA_Boolean enabled; + UA_Variant publisherId; + UA_String transportProfileUri; + UA_ExtensionObject address; + size_t connectionPropertiesSize; + UA_KeyValuePair *connectionProperties; + UA_ExtensionObject transportSettings; + size_t writerGroupsSize; + UA_WriterGroupDataType *writerGroups; + size_t readerGroupsSize; + UA_ReaderGroupDataType *readerGroups; + } UA_PubSubConnectionDataType; + +PubSubConfigurationDataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t publishedDataSetsSize; + UA_PublishedDataSetDataType *publishedDataSets; + size_t connectionsSize; + UA_PubSubConnectionDataType *connections; + UA_Boolean enabled; + } UA_PubSubConfigurationDataType; + +PubSubConfiguration2DataType +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: c + + typedef struct { + size_t publishedDataSetsSize; + UA_PublishedDataSetDataType *publishedDataSets; + size_t connectionsSize; + UA_PubSubConnectionDataType *connections; + UA_Boolean enabled; + size_t subscribedDataSetsSize; + UA_StandaloneSubscribedDataSetDataType *subscribedDataSets; + size_t dataSetClassesSize; + UA_DataSetMetaDataType *dataSetClasses; + size_t defaultSecurityKeyServicesSize; + UA_EndpointDescription *defaultSecurityKeyServices; + size_t securityGroupsSize; + UA_SecurityGroupDataType *securityGroups; + size_t pubSubKeyPushTargetsSize; + UA_PubSubKeyPushTargetDataType *pubSubKeyPushTargets; + UA_UInt32 configurationVersion; + size_t configurationPropertiesSize; + UA_KeyValuePair *configurationProperties; + } UA_PubSubConfiguration2DataType; + diff --git a/product/src/fes/include/open62541/types_generated_handling.h b/product/src/fes/include/open62541/types_generated_handling.h new file mode 100644 index 00000000..cf4b4533 --- /dev/null +++ b/product/src/fes/include/open62541/types_generated_handling.h @@ -0,0 +1,13993 @@ +/********************************** + * Autogenerated -- do not modify * + **********************************/ + +#ifndef TYPES_GENERATED_HANDLING_H_ +#define TYPES_GENERATED_HANDLING_H_ + +#include "types_generated.h" + +_UA_BEGIN_DECLS + +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +# pragma GCC diagnostic ignored "-Wmissing-braces" +#endif + + +/* Boolean */ +static UA_INLINE void +UA_Boolean_init(UA_Boolean *p) { + memset(p, 0, sizeof(UA_Boolean)); +} + +static UA_INLINE UA_Boolean * +UA_Boolean_new(void) { + return (UA_Boolean*)UA_new(&UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE UA_StatusCode +UA_Boolean_copy(const UA_Boolean *src, UA_Boolean *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Boolean_deleteMembers(UA_Boolean *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE void +UA_Boolean_clear(UA_Boolean *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BOOLEAN]); +} + +static UA_INLINE void +UA_Boolean_delete(UA_Boolean *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BOOLEAN]); +}static UA_INLINE UA_Boolean +UA_Boolean_equal(const UA_Boolean *p1, const UA_Boolean *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BOOLEAN]) == UA_ORDER_EQ); +} + + + +/* SByte */ +static UA_INLINE void +UA_SByte_init(UA_SByte *p) { + memset(p, 0, sizeof(UA_SByte)); +} + +static UA_INLINE UA_SByte * +UA_SByte_new(void) { + return (UA_SByte*)UA_new(&UA_TYPES[UA_TYPES_SBYTE]); +} + +static UA_INLINE UA_StatusCode +UA_SByte_copy(const UA_SByte *src, UA_SByte *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SBYTE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SByte_deleteMembers(UA_SByte *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SBYTE]); +} + +static UA_INLINE void +UA_SByte_clear(UA_SByte *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SBYTE]); +} + +static UA_INLINE void +UA_SByte_delete(UA_SByte *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SBYTE]); +}static UA_INLINE UA_Boolean +UA_SByte_equal(const UA_SByte *p1, const UA_SByte *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SBYTE]) == UA_ORDER_EQ); +} + + + +/* Byte */ +static UA_INLINE void +UA_Byte_init(UA_Byte *p) { + memset(p, 0, sizeof(UA_Byte)); +} + +static UA_INLINE UA_Byte * +UA_Byte_new(void) { + return (UA_Byte*)UA_new(&UA_TYPES[UA_TYPES_BYTE]); +} + +static UA_INLINE UA_StatusCode +UA_Byte_copy(const UA_Byte *src, UA_Byte *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BYTE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Byte_deleteMembers(UA_Byte *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BYTE]); +} + +static UA_INLINE void +UA_Byte_clear(UA_Byte *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BYTE]); +} + +static UA_INLINE void +UA_Byte_delete(UA_Byte *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BYTE]); +}static UA_INLINE UA_Boolean +UA_Byte_equal(const UA_Byte *p1, const UA_Byte *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BYTE]) == UA_ORDER_EQ); +} + + + +/* Int16 */ +static UA_INLINE void +UA_Int16_init(UA_Int16 *p) { + memset(p, 0, sizeof(UA_Int16)); +} + +static UA_INLINE UA_Int16 * +UA_Int16_new(void) { + return (UA_Int16*)UA_new(&UA_TYPES[UA_TYPES_INT16]); +} + +static UA_INLINE UA_StatusCode +UA_Int16_copy(const UA_Int16 *src, UA_Int16 *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_INT16]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Int16_deleteMembers(UA_Int16 *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INT16]); +} + +static UA_INLINE void +UA_Int16_clear(UA_Int16 *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INT16]); +} + +static UA_INLINE void +UA_Int16_delete(UA_Int16 *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_INT16]); +}static UA_INLINE UA_Boolean +UA_Int16_equal(const UA_Int16 *p1, const UA_Int16 *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_INT16]) == UA_ORDER_EQ); +} + + + +/* UInt16 */ +static UA_INLINE void +UA_UInt16_init(UA_UInt16 *p) { + memset(p, 0, sizeof(UA_UInt16)); +} + +static UA_INLINE UA_UInt16 * +UA_UInt16_new(void) { + return (UA_UInt16*)UA_new(&UA_TYPES[UA_TYPES_UINT16]); +} + +static UA_INLINE UA_StatusCode +UA_UInt16_copy(const UA_UInt16 *src, UA_UInt16 *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UINT16]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UInt16_deleteMembers(UA_UInt16 *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UINT16]); +} + +static UA_INLINE void +UA_UInt16_clear(UA_UInt16 *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UINT16]); +} + +static UA_INLINE void +UA_UInt16_delete(UA_UInt16 *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UINT16]); +}static UA_INLINE UA_Boolean +UA_UInt16_equal(const UA_UInt16 *p1, const UA_UInt16 *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UINT16]) == UA_ORDER_EQ); +} + + + +/* Int32 */ +static UA_INLINE void +UA_Int32_init(UA_Int32 *p) { + memset(p, 0, sizeof(UA_Int32)); +} + +static UA_INLINE UA_Int32 * +UA_Int32_new(void) { + return (UA_Int32*)UA_new(&UA_TYPES[UA_TYPES_INT32]); +} + +static UA_INLINE UA_StatusCode +UA_Int32_copy(const UA_Int32 *src, UA_Int32 *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_INT32]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Int32_deleteMembers(UA_Int32 *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INT32]); +} + +static UA_INLINE void +UA_Int32_clear(UA_Int32 *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INT32]); +} + +static UA_INLINE void +UA_Int32_delete(UA_Int32 *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_INT32]); +}static UA_INLINE UA_Boolean +UA_Int32_equal(const UA_Int32 *p1, const UA_Int32 *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_INT32]) == UA_ORDER_EQ); +} + + + +/* UInt32 */ +static UA_INLINE void +UA_UInt32_init(UA_UInt32 *p) { + memset(p, 0, sizeof(UA_UInt32)); +} + +static UA_INLINE UA_UInt32 * +UA_UInt32_new(void) { + return (UA_UInt32*)UA_new(&UA_TYPES[UA_TYPES_UINT32]); +} + +static UA_INLINE UA_StatusCode +UA_UInt32_copy(const UA_UInt32 *src, UA_UInt32 *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UINT32]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UInt32_deleteMembers(UA_UInt32 *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UINT32]); +} + +static UA_INLINE void +UA_UInt32_clear(UA_UInt32 *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UINT32]); +} + +static UA_INLINE void +UA_UInt32_delete(UA_UInt32 *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UINT32]); +}static UA_INLINE UA_Boolean +UA_UInt32_equal(const UA_UInt32 *p1, const UA_UInt32 *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UINT32]) == UA_ORDER_EQ); +} + + + +/* Int64 */ +static UA_INLINE void +UA_Int64_init(UA_Int64 *p) { + memset(p, 0, sizeof(UA_Int64)); +} + +static UA_INLINE UA_Int64 * +UA_Int64_new(void) { + return (UA_Int64*)UA_new(&UA_TYPES[UA_TYPES_INT64]); +} + +static UA_INLINE UA_StatusCode +UA_Int64_copy(const UA_Int64 *src, UA_Int64 *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_INT64]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Int64_deleteMembers(UA_Int64 *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INT64]); +} + +static UA_INLINE void +UA_Int64_clear(UA_Int64 *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INT64]); +} + +static UA_INLINE void +UA_Int64_delete(UA_Int64 *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_INT64]); +}static UA_INLINE UA_Boolean +UA_Int64_equal(const UA_Int64 *p1, const UA_Int64 *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_INT64]) == UA_ORDER_EQ); +} + + + +/* UInt64 */ +static UA_INLINE void +UA_UInt64_init(UA_UInt64 *p) { + memset(p, 0, sizeof(UA_UInt64)); +} + +static UA_INLINE UA_UInt64 * +UA_UInt64_new(void) { + return (UA_UInt64*)UA_new(&UA_TYPES[UA_TYPES_UINT64]); +} + +static UA_INLINE UA_StatusCode +UA_UInt64_copy(const UA_UInt64 *src, UA_UInt64 *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UINT64]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UInt64_deleteMembers(UA_UInt64 *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UINT64]); +} + +static UA_INLINE void +UA_UInt64_clear(UA_UInt64 *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UINT64]); +} + +static UA_INLINE void +UA_UInt64_delete(UA_UInt64 *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UINT64]); +}static UA_INLINE UA_Boolean +UA_UInt64_equal(const UA_UInt64 *p1, const UA_UInt64 *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UINT64]) == UA_ORDER_EQ); +} + + + +/* Float */ +static UA_INLINE void +UA_Float_init(UA_Float *p) { + memset(p, 0, sizeof(UA_Float)); +} + +static UA_INLINE UA_Float * +UA_Float_new(void) { + return (UA_Float*)UA_new(&UA_TYPES[UA_TYPES_FLOAT]); +} + +static UA_INLINE UA_StatusCode +UA_Float_copy(const UA_Float *src, UA_Float *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_FLOAT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Float_deleteMembers(UA_Float *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FLOAT]); +} + +static UA_INLINE void +UA_Float_clear(UA_Float *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FLOAT]); +} + +static UA_INLINE void +UA_Float_delete(UA_Float *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_FLOAT]); +}static UA_INLINE UA_Boolean +UA_Float_equal(const UA_Float *p1, const UA_Float *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_FLOAT]) == UA_ORDER_EQ); +} + + + +/* Double */ +static UA_INLINE void +UA_Double_init(UA_Double *p) { + memset(p, 0, sizeof(UA_Double)); +} + +static UA_INLINE UA_Double * +UA_Double_new(void) { + return (UA_Double*)UA_new(&UA_TYPES[UA_TYPES_DOUBLE]); +} + +static UA_INLINE UA_StatusCode +UA_Double_copy(const UA_Double *src, UA_Double *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DOUBLE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Double_deleteMembers(UA_Double *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DOUBLE]); +} + +static UA_INLINE void +UA_Double_clear(UA_Double *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DOUBLE]); +} + +static UA_INLINE void +UA_Double_delete(UA_Double *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DOUBLE]); +}static UA_INLINE UA_Boolean +UA_Double_equal(const UA_Double *p1, const UA_Double *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DOUBLE]) == UA_ORDER_EQ); +} + + + +/* String */ +static UA_INLINE void +UA_String_init(UA_String *p) { + memset(p, 0, sizeof(UA_String)); +} + +static UA_INLINE UA_String * +UA_String_new(void) { + return (UA_String*)UA_new(&UA_TYPES[UA_TYPES_STRING]); +} + +static UA_INLINE UA_StatusCode +UA_String_copy(const UA_String *src, UA_String *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_STRING]); +} + +UA_DEPRECATED static UA_INLINE void +UA_String_deleteMembers(UA_String *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STRING]); +} + +static UA_INLINE void +UA_String_clear(UA_String *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STRING]); +} + +static UA_INLINE void +UA_String_delete(UA_String *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_STRING]); +}static UA_INLINE UA_Boolean +UA_String_equal(const UA_String *p1, const UA_String *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_STRING]) == UA_ORDER_EQ); +} + + + +/* DateTime */ +static UA_INLINE void +UA_DateTime_init(UA_DateTime *p) { + memset(p, 0, sizeof(UA_DateTime)); +} + +static UA_INLINE UA_DateTime * +UA_DateTime_new(void) { + return (UA_DateTime*)UA_new(&UA_TYPES[UA_TYPES_DATETIME]); +} + +static UA_INLINE UA_StatusCode +UA_DateTime_copy(const UA_DateTime *src, UA_DateTime *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATETIME]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DateTime_deleteMembers(UA_DateTime *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATETIME]); +} + +static UA_INLINE void +UA_DateTime_clear(UA_DateTime *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATETIME]); +} + +static UA_INLINE void +UA_DateTime_delete(UA_DateTime *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATETIME]); +}static UA_INLINE UA_Boolean +UA_DateTime_equal(const UA_DateTime *p1, const UA_DateTime *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATETIME]) == UA_ORDER_EQ); +} + + + +/* Guid */ +static UA_INLINE void +UA_Guid_init(UA_Guid *p) { + memset(p, 0, sizeof(UA_Guid)); +} + +static UA_INLINE UA_Guid * +UA_Guid_new(void) { + return (UA_Guid*)UA_new(&UA_TYPES[UA_TYPES_GUID]); +} + +static UA_INLINE UA_StatusCode +UA_Guid_copy(const UA_Guid *src, UA_Guid *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_GUID]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Guid_deleteMembers(UA_Guid *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_GUID]); +} + +static UA_INLINE void +UA_Guid_clear(UA_Guid *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_GUID]); +} + +static UA_INLINE void +UA_Guid_delete(UA_Guid *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_GUID]); +}static UA_INLINE UA_Boolean +UA_Guid_equal(const UA_Guid *p1, const UA_Guid *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_GUID]) == UA_ORDER_EQ); +} + + + +/* ByteString */ +static UA_INLINE void +UA_ByteString_init(UA_ByteString *p) { + memset(p, 0, sizeof(UA_ByteString)); +} + +static UA_INLINE UA_ByteString * +UA_ByteString_new(void) { + return (UA_ByteString*)UA_new(&UA_TYPES[UA_TYPES_BYTESTRING]); +} + +static UA_INLINE UA_StatusCode +UA_ByteString_copy(const UA_ByteString *src, UA_ByteString *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BYTESTRING]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ByteString_deleteMembers(UA_ByteString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BYTESTRING]); +} + +static UA_INLINE void +UA_ByteString_clear(UA_ByteString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BYTESTRING]); +} + +static UA_INLINE void +UA_ByteString_delete(UA_ByteString *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BYTESTRING]); +}static UA_INLINE UA_Boolean +UA_ByteString_equal(const UA_ByteString *p1, const UA_ByteString *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BYTESTRING]) == UA_ORDER_EQ); +} + + + +/* XmlElement */ +static UA_INLINE void +UA_XmlElement_init(UA_XmlElement *p) { + memset(p, 0, sizeof(UA_XmlElement)); +} + +static UA_INLINE UA_XmlElement * +UA_XmlElement_new(void) { + return (UA_XmlElement*)UA_new(&UA_TYPES[UA_TYPES_XMLELEMENT]); +} + +static UA_INLINE UA_StatusCode +UA_XmlElement_copy(const UA_XmlElement *src, UA_XmlElement *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_XMLELEMENT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_XmlElement_deleteMembers(UA_XmlElement *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_XMLELEMENT]); +} + +static UA_INLINE void +UA_XmlElement_clear(UA_XmlElement *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_XMLELEMENT]); +} + +static UA_INLINE void +UA_XmlElement_delete(UA_XmlElement *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_XMLELEMENT]); +}static UA_INLINE UA_Boolean +UA_XmlElement_equal(const UA_XmlElement *p1, const UA_XmlElement *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_XMLELEMENT]) == UA_ORDER_EQ); +} + + + +/* NodeId */ +static UA_INLINE void +UA_NodeId_init(UA_NodeId *p) { + memset(p, 0, sizeof(UA_NodeId)); +} + +static UA_INLINE UA_NodeId * +UA_NodeId_new(void) { + return (UA_NodeId*)UA_new(&UA_TYPES[UA_TYPES_NODEID]); +} + +static UA_INLINE UA_StatusCode +UA_NodeId_copy(const UA_NodeId *src, UA_NodeId *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NODEID]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NodeId_deleteMembers(UA_NodeId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NODEID]); +} + +static UA_INLINE void +UA_NodeId_clear(UA_NodeId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NODEID]); +} + +static UA_INLINE void +UA_NodeId_delete(UA_NodeId *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NODEID]); +}static UA_INLINE UA_Boolean +UA_NodeId_equal(const UA_NodeId *p1, const UA_NodeId *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NODEID]) == UA_ORDER_EQ); +} + + + +/* ExpandedNodeId */ +static UA_INLINE void +UA_ExpandedNodeId_init(UA_ExpandedNodeId *p) { + memset(p, 0, sizeof(UA_ExpandedNodeId)); +} + +static UA_INLINE UA_ExpandedNodeId * +UA_ExpandedNodeId_new(void) { + return (UA_ExpandedNodeId*)UA_new(&UA_TYPES[UA_TYPES_EXPANDEDNODEID]); +} + +static UA_INLINE UA_StatusCode +UA_ExpandedNodeId_copy(const UA_ExpandedNodeId *src, UA_ExpandedNodeId *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ExpandedNodeId_deleteMembers(UA_ExpandedNodeId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); +} + +static UA_INLINE void +UA_ExpandedNodeId_clear(UA_ExpandedNodeId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); +} + +static UA_INLINE void +UA_ExpandedNodeId_delete(UA_ExpandedNodeId *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); +}static UA_INLINE UA_Boolean +UA_ExpandedNodeId_equal(const UA_ExpandedNodeId *p1, const UA_ExpandedNodeId *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]) == UA_ORDER_EQ); +} + + + +/* StatusCode */ +static UA_INLINE void +UA_StatusCode_init(UA_StatusCode *p) { + memset(p, 0, sizeof(UA_StatusCode)); +} + +static UA_INLINE UA_StatusCode * +UA_StatusCode_new(void) { + return (UA_StatusCode*)UA_new(&UA_TYPES[UA_TYPES_STATUSCODE]); +} + +static UA_INLINE UA_StatusCode +UA_StatusCode_copy(const UA_StatusCode *src, UA_StatusCode *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_STATUSCODE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_StatusCode_deleteMembers(UA_StatusCode *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STATUSCODE]); +} + +static UA_INLINE void +UA_StatusCode_clear(UA_StatusCode *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STATUSCODE]); +} + +static UA_INLINE void +UA_StatusCode_delete(UA_StatusCode *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_STATUSCODE]); +}static UA_INLINE UA_Boolean +UA_StatusCode_equal(const UA_StatusCode *p1, const UA_StatusCode *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_STATUSCODE]) == UA_ORDER_EQ); +} + + + +/* QualifiedName */ +static UA_INLINE void +UA_QualifiedName_init(UA_QualifiedName *p) { + memset(p, 0, sizeof(UA_QualifiedName)); +} + +static UA_INLINE UA_QualifiedName * +UA_QualifiedName_new(void) { + return (UA_QualifiedName*)UA_new(&UA_TYPES[UA_TYPES_QUALIFIEDNAME]); +} + +static UA_INLINE UA_StatusCode +UA_QualifiedName_copy(const UA_QualifiedName *src, UA_QualifiedName *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_QUALIFIEDNAME]); +} + +UA_DEPRECATED static UA_INLINE void +UA_QualifiedName_deleteMembers(UA_QualifiedName *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUALIFIEDNAME]); +} + +static UA_INLINE void +UA_QualifiedName_clear(UA_QualifiedName *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUALIFIEDNAME]); +} + +static UA_INLINE void +UA_QualifiedName_delete(UA_QualifiedName *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_QUALIFIEDNAME]); +}static UA_INLINE UA_Boolean +UA_QualifiedName_equal(const UA_QualifiedName *p1, const UA_QualifiedName *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_QUALIFIEDNAME]) == UA_ORDER_EQ); +} + + + +/* LocalizedText */ +static UA_INLINE void +UA_LocalizedText_init(UA_LocalizedText *p) { + memset(p, 0, sizeof(UA_LocalizedText)); +} + +static UA_INLINE UA_LocalizedText * +UA_LocalizedText_new(void) { + return (UA_LocalizedText*)UA_new(&UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +} + +static UA_INLINE UA_StatusCode +UA_LocalizedText_copy(const UA_LocalizedText *src, UA_LocalizedText *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_LocalizedText_deleteMembers(UA_LocalizedText *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +} + +static UA_INLINE void +UA_LocalizedText_clear(UA_LocalizedText *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +} + +static UA_INLINE void +UA_LocalizedText_delete(UA_LocalizedText *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +}static UA_INLINE UA_Boolean +UA_LocalizedText_equal(const UA_LocalizedText *p1, const UA_LocalizedText *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]) == UA_ORDER_EQ); +} + + + +/* ExtensionObject */ +static UA_INLINE void +UA_ExtensionObject_init(UA_ExtensionObject *p) { + memset(p, 0, sizeof(UA_ExtensionObject)); +} + +static UA_INLINE UA_ExtensionObject * +UA_ExtensionObject_new(void) { + return (UA_ExtensionObject*)UA_new(&UA_TYPES[UA_TYPES_EXTENSIONOBJECT]); +} + +static UA_INLINE UA_StatusCode +UA_ExtensionObject_copy(const UA_ExtensionObject *src, UA_ExtensionObject *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ExtensionObject_deleteMembers(UA_ExtensionObject *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]); +} + +static UA_INLINE void +UA_ExtensionObject_clear(UA_ExtensionObject *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]); +} + +static UA_INLINE void +UA_ExtensionObject_delete(UA_ExtensionObject *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]); +}static UA_INLINE UA_Boolean +UA_ExtensionObject_equal(const UA_ExtensionObject *p1, const UA_ExtensionObject *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]) == UA_ORDER_EQ); +} + + + +/* DataValue */ +static UA_INLINE void +UA_DataValue_init(UA_DataValue *p) { + memset(p, 0, sizeof(UA_DataValue)); +} + +static UA_INLINE UA_DataValue * +UA_DataValue_new(void) { + return (UA_DataValue*)UA_new(&UA_TYPES[UA_TYPES_DATAVALUE]); +} + +static UA_INLINE UA_StatusCode +UA_DataValue_copy(const UA_DataValue *src, UA_DataValue *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATAVALUE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataValue_deleteMembers(UA_DataValue *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATAVALUE]); +} + +static UA_INLINE void +UA_DataValue_clear(UA_DataValue *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATAVALUE]); +} + +static UA_INLINE void +UA_DataValue_delete(UA_DataValue *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATAVALUE]); +}static UA_INLINE UA_Boolean +UA_DataValue_equal(const UA_DataValue *p1, const UA_DataValue *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATAVALUE]) == UA_ORDER_EQ); +} + + + +/* Variant */ +static UA_INLINE void +UA_Variant_init(UA_Variant *p) { + memset(p, 0, sizeof(UA_Variant)); +} + +static UA_INLINE UA_Variant * +UA_Variant_new(void) { + return (UA_Variant*)UA_new(&UA_TYPES[UA_TYPES_VARIANT]); +} + +static UA_INLINE UA_StatusCode +UA_Variant_copy(const UA_Variant *src, UA_Variant *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_VARIANT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Variant_deleteMembers(UA_Variant *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_VARIANT]); +} + +static UA_INLINE void +UA_Variant_clear(UA_Variant *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_VARIANT]); +} + +static UA_INLINE void +UA_Variant_delete(UA_Variant *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_VARIANT]); +}static UA_INLINE UA_Boolean +UA_Variant_equal(const UA_Variant *p1, const UA_Variant *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_VARIANT]) == UA_ORDER_EQ); +} + + + +/* DiagnosticInfo */ +static UA_INLINE void +UA_DiagnosticInfo_init(UA_DiagnosticInfo *p) { + memset(p, 0, sizeof(UA_DiagnosticInfo)); +} + +static UA_INLINE UA_DiagnosticInfo * +UA_DiagnosticInfo_new(void) { + return (UA_DiagnosticInfo*)UA_new(&UA_TYPES[UA_TYPES_DIAGNOSTICINFO]); +} + +static UA_INLINE UA_StatusCode +UA_DiagnosticInfo_copy(const UA_DiagnosticInfo *src, UA_DiagnosticInfo *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DIAGNOSTICINFO]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DiagnosticInfo_deleteMembers(UA_DiagnosticInfo *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DIAGNOSTICINFO]); +} + +static UA_INLINE void +UA_DiagnosticInfo_clear(UA_DiagnosticInfo *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DIAGNOSTICINFO]); +} + +static UA_INLINE void +UA_DiagnosticInfo_delete(UA_DiagnosticInfo *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DIAGNOSTICINFO]); +}static UA_INLINE UA_Boolean +UA_DiagnosticInfo_equal(const UA_DiagnosticInfo *p1, const UA_DiagnosticInfo *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DIAGNOSTICINFO]) == UA_ORDER_EQ); +} + + + +/* NamingRuleType */ +static UA_INLINE void +UA_NamingRuleType_init(UA_NamingRuleType *p) { + memset(p, 0, sizeof(UA_NamingRuleType)); +} + +static UA_INLINE UA_NamingRuleType * +UA_NamingRuleType_new(void) { + return (UA_NamingRuleType*)UA_new(&UA_TYPES[UA_TYPES_NAMINGRULETYPE]); +} + +static UA_INLINE UA_StatusCode +UA_NamingRuleType_copy(const UA_NamingRuleType *src, UA_NamingRuleType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NAMINGRULETYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NamingRuleType_deleteMembers(UA_NamingRuleType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NAMINGRULETYPE]); +} + +static UA_INLINE void +UA_NamingRuleType_clear(UA_NamingRuleType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NAMINGRULETYPE]); +} + +static UA_INLINE void +UA_NamingRuleType_delete(UA_NamingRuleType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NAMINGRULETYPE]); +}static UA_INLINE UA_Boolean +UA_NamingRuleType_equal(const UA_NamingRuleType *p1, const UA_NamingRuleType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NAMINGRULETYPE]) == UA_ORDER_EQ); +} + + + +/* Enumeration */ +static UA_INLINE void +UA_Enumeration_init(UA_Enumeration *p) { + memset(p, 0, sizeof(UA_Enumeration)); +} + +static UA_INLINE UA_Enumeration * +UA_Enumeration_new(void) { + return (UA_Enumeration*)UA_new(&UA_TYPES[UA_TYPES_ENUMERATION]); +} + +static UA_INLINE UA_StatusCode +UA_Enumeration_copy(const UA_Enumeration *src, UA_Enumeration *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ENUMERATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Enumeration_deleteMembers(UA_Enumeration *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENUMERATION]); +} + +static UA_INLINE void +UA_Enumeration_clear(UA_Enumeration *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENUMERATION]); +} + +static UA_INLINE void +UA_Enumeration_delete(UA_Enumeration *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ENUMERATION]); +}static UA_INLINE UA_Boolean +UA_Enumeration_equal(const UA_Enumeration *p1, const UA_Enumeration *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ENUMERATION]) == UA_ORDER_EQ); +} + + + +/* ImageBMP */ +static UA_INLINE void +UA_ImageBMP_init(UA_ImageBMP *p) { + memset(p, 0, sizeof(UA_ImageBMP)); +} + +static UA_INLINE UA_ImageBMP * +UA_ImageBMP_new(void) { + return (UA_ImageBMP*)UA_new(&UA_TYPES[UA_TYPES_IMAGEBMP]); +} + +static UA_INLINE UA_StatusCode +UA_ImageBMP_copy(const UA_ImageBMP *src, UA_ImageBMP *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_IMAGEBMP]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ImageBMP_deleteMembers(UA_ImageBMP *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IMAGEBMP]); +} + +static UA_INLINE void +UA_ImageBMP_clear(UA_ImageBMP *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IMAGEBMP]); +} + +static UA_INLINE void +UA_ImageBMP_delete(UA_ImageBMP *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_IMAGEBMP]); +}static UA_INLINE UA_Boolean +UA_ImageBMP_equal(const UA_ImageBMP *p1, const UA_ImageBMP *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_IMAGEBMP]) == UA_ORDER_EQ); +} + + + +/* ImageGIF */ +static UA_INLINE void +UA_ImageGIF_init(UA_ImageGIF *p) { + memset(p, 0, sizeof(UA_ImageGIF)); +} + +static UA_INLINE UA_ImageGIF * +UA_ImageGIF_new(void) { + return (UA_ImageGIF*)UA_new(&UA_TYPES[UA_TYPES_IMAGEGIF]); +} + +static UA_INLINE UA_StatusCode +UA_ImageGIF_copy(const UA_ImageGIF *src, UA_ImageGIF *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_IMAGEGIF]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ImageGIF_deleteMembers(UA_ImageGIF *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IMAGEGIF]); +} + +static UA_INLINE void +UA_ImageGIF_clear(UA_ImageGIF *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IMAGEGIF]); +} + +static UA_INLINE void +UA_ImageGIF_delete(UA_ImageGIF *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_IMAGEGIF]); +}static UA_INLINE UA_Boolean +UA_ImageGIF_equal(const UA_ImageGIF *p1, const UA_ImageGIF *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_IMAGEGIF]) == UA_ORDER_EQ); +} + + + +/* ImageJPG */ +static UA_INLINE void +UA_ImageJPG_init(UA_ImageJPG *p) { + memset(p, 0, sizeof(UA_ImageJPG)); +} + +static UA_INLINE UA_ImageJPG * +UA_ImageJPG_new(void) { + return (UA_ImageJPG*)UA_new(&UA_TYPES[UA_TYPES_IMAGEJPG]); +} + +static UA_INLINE UA_StatusCode +UA_ImageJPG_copy(const UA_ImageJPG *src, UA_ImageJPG *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_IMAGEJPG]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ImageJPG_deleteMembers(UA_ImageJPG *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IMAGEJPG]); +} + +static UA_INLINE void +UA_ImageJPG_clear(UA_ImageJPG *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IMAGEJPG]); +} + +static UA_INLINE void +UA_ImageJPG_delete(UA_ImageJPG *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_IMAGEJPG]); +}static UA_INLINE UA_Boolean +UA_ImageJPG_equal(const UA_ImageJPG *p1, const UA_ImageJPG *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_IMAGEJPG]) == UA_ORDER_EQ); +} + + + +/* ImagePNG */ +static UA_INLINE void +UA_ImagePNG_init(UA_ImagePNG *p) { + memset(p, 0, sizeof(UA_ImagePNG)); +} + +static UA_INLINE UA_ImagePNG * +UA_ImagePNG_new(void) { + return (UA_ImagePNG*)UA_new(&UA_TYPES[UA_TYPES_IMAGEPNG]); +} + +static UA_INLINE UA_StatusCode +UA_ImagePNG_copy(const UA_ImagePNG *src, UA_ImagePNG *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_IMAGEPNG]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ImagePNG_deleteMembers(UA_ImagePNG *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IMAGEPNG]); +} + +static UA_INLINE void +UA_ImagePNG_clear(UA_ImagePNG *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IMAGEPNG]); +} + +static UA_INLINE void +UA_ImagePNG_delete(UA_ImagePNG *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_IMAGEPNG]); +}static UA_INLINE UA_Boolean +UA_ImagePNG_equal(const UA_ImagePNG *p1, const UA_ImagePNG *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_IMAGEPNG]) == UA_ORDER_EQ); +} + + + +/* AudioDataType */ +static UA_INLINE void +UA_AudioDataType_init(UA_AudioDataType *p) { + memset(p, 0, sizeof(UA_AudioDataType)); +} + +static UA_INLINE UA_AudioDataType * +UA_AudioDataType_new(void) { + return (UA_AudioDataType*)UA_new(&UA_TYPES[UA_TYPES_AUDIODATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_AudioDataType_copy(const UA_AudioDataType *src, UA_AudioDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_AUDIODATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AudioDataType_deleteMembers(UA_AudioDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_AUDIODATATYPE]); +} + +static UA_INLINE void +UA_AudioDataType_clear(UA_AudioDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_AUDIODATATYPE]); +} + +static UA_INLINE void +UA_AudioDataType_delete(UA_AudioDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_AUDIODATATYPE]); +}static UA_INLINE UA_Boolean +UA_AudioDataType_equal(const UA_AudioDataType *p1, const UA_AudioDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_AUDIODATATYPE]) == UA_ORDER_EQ); +} + + + +/* UriString */ +static UA_INLINE void +UA_UriString_init(UA_UriString *p) { + memset(p, 0, sizeof(UA_UriString)); +} + +static UA_INLINE UA_UriString * +UA_UriString_new(void) { + return (UA_UriString*)UA_new(&UA_TYPES[UA_TYPES_URISTRING]); +} + +static UA_INLINE UA_StatusCode +UA_UriString_copy(const UA_UriString *src, UA_UriString *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_URISTRING]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UriString_deleteMembers(UA_UriString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_URISTRING]); +} + +static UA_INLINE void +UA_UriString_clear(UA_UriString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_URISTRING]); +} + +static UA_INLINE void +UA_UriString_delete(UA_UriString *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_URISTRING]); +}static UA_INLINE UA_Boolean +UA_UriString_equal(const UA_UriString *p1, const UA_UriString *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_URISTRING]) == UA_ORDER_EQ); +} + + + +/* BitFieldMaskDataType */ +static UA_INLINE void +UA_BitFieldMaskDataType_init(UA_BitFieldMaskDataType *p) { + memset(p, 0, sizeof(UA_BitFieldMaskDataType)); +} + +static UA_INLINE UA_BitFieldMaskDataType * +UA_BitFieldMaskDataType_new(void) { + return (UA_BitFieldMaskDataType*)UA_new(&UA_TYPES[UA_TYPES_BITFIELDMASKDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_BitFieldMaskDataType_copy(const UA_BitFieldMaskDataType *src, UA_BitFieldMaskDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BITFIELDMASKDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BitFieldMaskDataType_deleteMembers(UA_BitFieldMaskDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BITFIELDMASKDATATYPE]); +} + +static UA_INLINE void +UA_BitFieldMaskDataType_clear(UA_BitFieldMaskDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BITFIELDMASKDATATYPE]); +} + +static UA_INLINE void +UA_BitFieldMaskDataType_delete(UA_BitFieldMaskDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BITFIELDMASKDATATYPE]); +}static UA_INLINE UA_Boolean +UA_BitFieldMaskDataType_equal(const UA_BitFieldMaskDataType *p1, const UA_BitFieldMaskDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BITFIELDMASKDATATYPE]) == UA_ORDER_EQ); +} + + + +/* SemanticVersionString */ +static UA_INLINE void +UA_SemanticVersionString_init(UA_SemanticVersionString *p) { + memset(p, 0, sizeof(UA_SemanticVersionString)); +} + +static UA_INLINE UA_SemanticVersionString * +UA_SemanticVersionString_new(void) { + return (UA_SemanticVersionString*)UA_new(&UA_TYPES[UA_TYPES_SEMANTICVERSIONSTRING]); +} + +static UA_INLINE UA_StatusCode +UA_SemanticVersionString_copy(const UA_SemanticVersionString *src, UA_SemanticVersionString *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SEMANTICVERSIONSTRING]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SemanticVersionString_deleteMembers(UA_SemanticVersionString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SEMANTICVERSIONSTRING]); +} + +static UA_INLINE void +UA_SemanticVersionString_clear(UA_SemanticVersionString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SEMANTICVERSIONSTRING]); +} + +static UA_INLINE void +UA_SemanticVersionString_delete(UA_SemanticVersionString *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SEMANTICVERSIONSTRING]); +}static UA_INLINE UA_Boolean +UA_SemanticVersionString_equal(const UA_SemanticVersionString *p1, const UA_SemanticVersionString *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SEMANTICVERSIONSTRING]) == UA_ORDER_EQ); +} + + + +/* KeyValuePair */ +static UA_INLINE void +UA_KeyValuePair_init(UA_KeyValuePair *p) { + memset(p, 0, sizeof(UA_KeyValuePair)); +} + +static UA_INLINE UA_KeyValuePair * +UA_KeyValuePair_new(void) { + return (UA_KeyValuePair*)UA_new(&UA_TYPES[UA_TYPES_KEYVALUEPAIR]); +} + +static UA_INLINE UA_StatusCode +UA_KeyValuePair_copy(const UA_KeyValuePair *src, UA_KeyValuePair *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_KEYVALUEPAIR]); +} + +UA_DEPRECATED static UA_INLINE void +UA_KeyValuePair_deleteMembers(UA_KeyValuePair *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_KEYVALUEPAIR]); +} + +static UA_INLINE void +UA_KeyValuePair_clear(UA_KeyValuePair *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_KEYVALUEPAIR]); +} + +static UA_INLINE void +UA_KeyValuePair_delete(UA_KeyValuePair *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_KEYVALUEPAIR]); +}static UA_INLINE UA_Boolean +UA_KeyValuePair_equal(const UA_KeyValuePair *p1, const UA_KeyValuePair *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_KEYVALUEPAIR]) == UA_ORDER_EQ); +} + + + +/* AdditionalParametersType */ +static UA_INLINE void +UA_AdditionalParametersType_init(UA_AdditionalParametersType *p) { + memset(p, 0, sizeof(UA_AdditionalParametersType)); +} + +static UA_INLINE UA_AdditionalParametersType * +UA_AdditionalParametersType_new(void) { + return (UA_AdditionalParametersType*)UA_new(&UA_TYPES[UA_TYPES_ADDITIONALPARAMETERSTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_AdditionalParametersType_copy(const UA_AdditionalParametersType *src, UA_AdditionalParametersType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ADDITIONALPARAMETERSTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AdditionalParametersType_deleteMembers(UA_AdditionalParametersType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDITIONALPARAMETERSTYPE]); +} + +static UA_INLINE void +UA_AdditionalParametersType_clear(UA_AdditionalParametersType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDITIONALPARAMETERSTYPE]); +} + +static UA_INLINE void +UA_AdditionalParametersType_delete(UA_AdditionalParametersType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ADDITIONALPARAMETERSTYPE]); +}static UA_INLINE UA_Boolean +UA_AdditionalParametersType_equal(const UA_AdditionalParametersType *p1, const UA_AdditionalParametersType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ADDITIONALPARAMETERSTYPE]) == UA_ORDER_EQ); +} + + + +/* EphemeralKeyType */ +static UA_INLINE void +UA_EphemeralKeyType_init(UA_EphemeralKeyType *p) { + memset(p, 0, sizeof(UA_EphemeralKeyType)); +} + +static UA_INLINE UA_EphemeralKeyType * +UA_EphemeralKeyType_new(void) { + return (UA_EphemeralKeyType*)UA_new(&UA_TYPES[UA_TYPES_EPHEMERALKEYTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_EphemeralKeyType_copy(const UA_EphemeralKeyType *src, UA_EphemeralKeyType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_EPHEMERALKEYTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EphemeralKeyType_deleteMembers(UA_EphemeralKeyType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EPHEMERALKEYTYPE]); +} + +static UA_INLINE void +UA_EphemeralKeyType_clear(UA_EphemeralKeyType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EPHEMERALKEYTYPE]); +} + +static UA_INLINE void +UA_EphemeralKeyType_delete(UA_EphemeralKeyType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_EPHEMERALKEYTYPE]); +}static UA_INLINE UA_Boolean +UA_EphemeralKeyType_equal(const UA_EphemeralKeyType *p1, const UA_EphemeralKeyType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_EPHEMERALKEYTYPE]) == UA_ORDER_EQ); +} + + + +/* RationalNumber */ +static UA_INLINE void +UA_RationalNumber_init(UA_RationalNumber *p) { + memset(p, 0, sizeof(UA_RationalNumber)); +} + +static UA_INLINE UA_RationalNumber * +UA_RationalNumber_new(void) { + return (UA_RationalNumber*)UA_new(&UA_TYPES[UA_TYPES_RATIONALNUMBER]); +} + +static UA_INLINE UA_StatusCode +UA_RationalNumber_copy(const UA_RationalNumber *src, UA_RationalNumber *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_RATIONALNUMBER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RationalNumber_deleteMembers(UA_RationalNumber *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RATIONALNUMBER]); +} + +static UA_INLINE void +UA_RationalNumber_clear(UA_RationalNumber *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RATIONALNUMBER]); +} + +static UA_INLINE void +UA_RationalNumber_delete(UA_RationalNumber *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_RATIONALNUMBER]); +}static UA_INLINE UA_Boolean +UA_RationalNumber_equal(const UA_RationalNumber *p1, const UA_RationalNumber *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_RATIONALNUMBER]) == UA_ORDER_EQ); +} + + + +/* ThreeDVector */ +static UA_INLINE void +UA_ThreeDVector_init(UA_ThreeDVector *p) { + memset(p, 0, sizeof(UA_ThreeDVector)); +} + +static UA_INLINE UA_ThreeDVector * +UA_ThreeDVector_new(void) { + return (UA_ThreeDVector*)UA_new(&UA_TYPES[UA_TYPES_THREEDVECTOR]); +} + +static UA_INLINE UA_StatusCode +UA_ThreeDVector_copy(const UA_ThreeDVector *src, UA_ThreeDVector *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_THREEDVECTOR]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ThreeDVector_deleteMembers(UA_ThreeDVector *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_THREEDVECTOR]); +} + +static UA_INLINE void +UA_ThreeDVector_clear(UA_ThreeDVector *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_THREEDVECTOR]); +} + +static UA_INLINE void +UA_ThreeDVector_delete(UA_ThreeDVector *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_THREEDVECTOR]); +}static UA_INLINE UA_Boolean +UA_ThreeDVector_equal(const UA_ThreeDVector *p1, const UA_ThreeDVector *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_THREEDVECTOR]) == UA_ORDER_EQ); +} + + + +/* ThreeDCartesianCoordinates */ +static UA_INLINE void +UA_ThreeDCartesianCoordinates_init(UA_ThreeDCartesianCoordinates *p) { + memset(p, 0, sizeof(UA_ThreeDCartesianCoordinates)); +} + +static UA_INLINE UA_ThreeDCartesianCoordinates * +UA_ThreeDCartesianCoordinates_new(void) { + return (UA_ThreeDCartesianCoordinates*)UA_new(&UA_TYPES[UA_TYPES_THREEDCARTESIANCOORDINATES]); +} + +static UA_INLINE UA_StatusCode +UA_ThreeDCartesianCoordinates_copy(const UA_ThreeDCartesianCoordinates *src, UA_ThreeDCartesianCoordinates *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_THREEDCARTESIANCOORDINATES]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ThreeDCartesianCoordinates_deleteMembers(UA_ThreeDCartesianCoordinates *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_THREEDCARTESIANCOORDINATES]); +} + +static UA_INLINE void +UA_ThreeDCartesianCoordinates_clear(UA_ThreeDCartesianCoordinates *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_THREEDCARTESIANCOORDINATES]); +} + +static UA_INLINE void +UA_ThreeDCartesianCoordinates_delete(UA_ThreeDCartesianCoordinates *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_THREEDCARTESIANCOORDINATES]); +}static UA_INLINE UA_Boolean +UA_ThreeDCartesianCoordinates_equal(const UA_ThreeDCartesianCoordinates *p1, const UA_ThreeDCartesianCoordinates *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_THREEDCARTESIANCOORDINATES]) == UA_ORDER_EQ); +} + + + +/* ThreeDOrientation */ +static UA_INLINE void +UA_ThreeDOrientation_init(UA_ThreeDOrientation *p) { + memset(p, 0, sizeof(UA_ThreeDOrientation)); +} + +static UA_INLINE UA_ThreeDOrientation * +UA_ThreeDOrientation_new(void) { + return (UA_ThreeDOrientation*)UA_new(&UA_TYPES[UA_TYPES_THREEDORIENTATION]); +} + +static UA_INLINE UA_StatusCode +UA_ThreeDOrientation_copy(const UA_ThreeDOrientation *src, UA_ThreeDOrientation *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_THREEDORIENTATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ThreeDOrientation_deleteMembers(UA_ThreeDOrientation *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_THREEDORIENTATION]); +} + +static UA_INLINE void +UA_ThreeDOrientation_clear(UA_ThreeDOrientation *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_THREEDORIENTATION]); +} + +static UA_INLINE void +UA_ThreeDOrientation_delete(UA_ThreeDOrientation *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_THREEDORIENTATION]); +}static UA_INLINE UA_Boolean +UA_ThreeDOrientation_equal(const UA_ThreeDOrientation *p1, const UA_ThreeDOrientation *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_THREEDORIENTATION]) == UA_ORDER_EQ); +} + + + +/* ThreeDFrame */ +static UA_INLINE void +UA_ThreeDFrame_init(UA_ThreeDFrame *p) { + memset(p, 0, sizeof(UA_ThreeDFrame)); +} + +static UA_INLINE UA_ThreeDFrame * +UA_ThreeDFrame_new(void) { + return (UA_ThreeDFrame*)UA_new(&UA_TYPES[UA_TYPES_THREEDFRAME]); +} + +static UA_INLINE UA_StatusCode +UA_ThreeDFrame_copy(const UA_ThreeDFrame *src, UA_ThreeDFrame *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_THREEDFRAME]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ThreeDFrame_deleteMembers(UA_ThreeDFrame *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_THREEDFRAME]); +} + +static UA_INLINE void +UA_ThreeDFrame_clear(UA_ThreeDFrame *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_THREEDFRAME]); +} + +static UA_INLINE void +UA_ThreeDFrame_delete(UA_ThreeDFrame *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_THREEDFRAME]); +}static UA_INLINE UA_Boolean +UA_ThreeDFrame_equal(const UA_ThreeDFrame *p1, const UA_ThreeDFrame *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_THREEDFRAME]) == UA_ORDER_EQ); +} + + + +/* OpenFileMode */ +static UA_INLINE void +UA_OpenFileMode_init(UA_OpenFileMode *p) { + memset(p, 0, sizeof(UA_OpenFileMode)); +} + +static UA_INLINE UA_OpenFileMode * +UA_OpenFileMode_new(void) { + return (UA_OpenFileMode*)UA_new(&UA_TYPES[UA_TYPES_OPENFILEMODE]); +} + +static UA_INLINE UA_StatusCode +UA_OpenFileMode_copy(const UA_OpenFileMode *src, UA_OpenFileMode *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_OPENFILEMODE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_OpenFileMode_deleteMembers(UA_OpenFileMode *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OPENFILEMODE]); +} + +static UA_INLINE void +UA_OpenFileMode_clear(UA_OpenFileMode *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OPENFILEMODE]); +} + +static UA_INLINE void +UA_OpenFileMode_delete(UA_OpenFileMode *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_OPENFILEMODE]); +}static UA_INLINE UA_Boolean +UA_OpenFileMode_equal(const UA_OpenFileMode *p1, const UA_OpenFileMode *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_OPENFILEMODE]) == UA_ORDER_EQ); +} + + + +/* IdentityCriteriaType */ +static UA_INLINE void +UA_IdentityCriteriaType_init(UA_IdentityCriteriaType *p) { + memset(p, 0, sizeof(UA_IdentityCriteriaType)); +} + +static UA_INLINE UA_IdentityCriteriaType * +UA_IdentityCriteriaType_new(void) { + return (UA_IdentityCriteriaType*)UA_new(&UA_TYPES[UA_TYPES_IDENTITYCRITERIATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_IdentityCriteriaType_copy(const UA_IdentityCriteriaType *src, UA_IdentityCriteriaType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_IDENTITYCRITERIATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_IdentityCriteriaType_deleteMembers(UA_IdentityCriteriaType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IDENTITYCRITERIATYPE]); +} + +static UA_INLINE void +UA_IdentityCriteriaType_clear(UA_IdentityCriteriaType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IDENTITYCRITERIATYPE]); +} + +static UA_INLINE void +UA_IdentityCriteriaType_delete(UA_IdentityCriteriaType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_IDENTITYCRITERIATYPE]); +}static UA_INLINE UA_Boolean +UA_IdentityCriteriaType_equal(const UA_IdentityCriteriaType *p1, const UA_IdentityCriteriaType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_IDENTITYCRITERIATYPE]) == UA_ORDER_EQ); +} + + + +/* IdentityMappingRuleType */ +static UA_INLINE void +UA_IdentityMappingRuleType_init(UA_IdentityMappingRuleType *p) { + memset(p, 0, sizeof(UA_IdentityMappingRuleType)); +} + +static UA_INLINE UA_IdentityMappingRuleType * +UA_IdentityMappingRuleType_new(void) { + return (UA_IdentityMappingRuleType*)UA_new(&UA_TYPES[UA_TYPES_IDENTITYMAPPINGRULETYPE]); +} + +static UA_INLINE UA_StatusCode +UA_IdentityMappingRuleType_copy(const UA_IdentityMappingRuleType *src, UA_IdentityMappingRuleType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_IDENTITYMAPPINGRULETYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_IdentityMappingRuleType_deleteMembers(UA_IdentityMappingRuleType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IDENTITYMAPPINGRULETYPE]); +} + +static UA_INLINE void +UA_IdentityMappingRuleType_clear(UA_IdentityMappingRuleType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IDENTITYMAPPINGRULETYPE]); +} + +static UA_INLINE void +UA_IdentityMappingRuleType_delete(UA_IdentityMappingRuleType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_IDENTITYMAPPINGRULETYPE]); +}static UA_INLINE UA_Boolean +UA_IdentityMappingRuleType_equal(const UA_IdentityMappingRuleType *p1, const UA_IdentityMappingRuleType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_IDENTITYMAPPINGRULETYPE]) == UA_ORDER_EQ); +} + + + +/* CurrencyUnitType */ +static UA_INLINE void +UA_CurrencyUnitType_init(UA_CurrencyUnitType *p) { + memset(p, 0, sizeof(UA_CurrencyUnitType)); +} + +static UA_INLINE UA_CurrencyUnitType * +UA_CurrencyUnitType_new(void) { + return (UA_CurrencyUnitType*)UA_new(&UA_TYPES[UA_TYPES_CURRENCYUNITTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_CurrencyUnitType_copy(const UA_CurrencyUnitType *src, UA_CurrencyUnitType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CURRENCYUNITTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CurrencyUnitType_deleteMembers(UA_CurrencyUnitType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CURRENCYUNITTYPE]); +} + +static UA_INLINE void +UA_CurrencyUnitType_clear(UA_CurrencyUnitType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CURRENCYUNITTYPE]); +} + +static UA_INLINE void +UA_CurrencyUnitType_delete(UA_CurrencyUnitType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CURRENCYUNITTYPE]); +}static UA_INLINE UA_Boolean +UA_CurrencyUnitType_equal(const UA_CurrencyUnitType *p1, const UA_CurrencyUnitType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CURRENCYUNITTYPE]) == UA_ORDER_EQ); +} + + + +/* TrustListMasks */ +static UA_INLINE void +UA_TrustListMasks_init(UA_TrustListMasks *p) { + memset(p, 0, sizeof(UA_TrustListMasks)); +} + +static UA_INLINE UA_TrustListMasks * +UA_TrustListMasks_new(void) { + return (UA_TrustListMasks*)UA_new(&UA_TYPES[UA_TYPES_TRUSTLISTMASKS]); +} + +static UA_INLINE UA_StatusCode +UA_TrustListMasks_copy(const UA_TrustListMasks *src, UA_TrustListMasks *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TRUSTLISTMASKS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TrustListMasks_deleteMembers(UA_TrustListMasks *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRUSTLISTMASKS]); +} + +static UA_INLINE void +UA_TrustListMasks_clear(UA_TrustListMasks *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRUSTLISTMASKS]); +} + +static UA_INLINE void +UA_TrustListMasks_delete(UA_TrustListMasks *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TRUSTLISTMASKS]); +}static UA_INLINE UA_Boolean +UA_TrustListMasks_equal(const UA_TrustListMasks *p1, const UA_TrustListMasks *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TRUSTLISTMASKS]) == UA_ORDER_EQ); +} + + + +/* TrustListDataType */ +static UA_INLINE void +UA_TrustListDataType_init(UA_TrustListDataType *p) { + memset(p, 0, sizeof(UA_TrustListDataType)); +} + +static UA_INLINE UA_TrustListDataType * +UA_TrustListDataType_new(void) { + return (UA_TrustListDataType*)UA_new(&UA_TYPES[UA_TYPES_TRUSTLISTDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_TrustListDataType_copy(const UA_TrustListDataType *src, UA_TrustListDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TRUSTLISTDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TrustListDataType_deleteMembers(UA_TrustListDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRUSTLISTDATATYPE]); +} + +static UA_INLINE void +UA_TrustListDataType_clear(UA_TrustListDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRUSTLISTDATATYPE]); +} + +static UA_INLINE void +UA_TrustListDataType_delete(UA_TrustListDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TRUSTLISTDATATYPE]); +}static UA_INLINE UA_Boolean +UA_TrustListDataType_equal(const UA_TrustListDataType *p1, const UA_TrustListDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TRUSTLISTDATATYPE]) == UA_ORDER_EQ); +} + + + +/* DecimalDataType */ +static UA_INLINE void +UA_DecimalDataType_init(UA_DecimalDataType *p) { + memset(p, 0, sizeof(UA_DecimalDataType)); +} + +static UA_INLINE UA_DecimalDataType * +UA_DecimalDataType_new(void) { + return (UA_DecimalDataType*)UA_new(&UA_TYPES[UA_TYPES_DECIMALDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_DecimalDataType_copy(const UA_DecimalDataType *src, UA_DecimalDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DECIMALDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DecimalDataType_deleteMembers(UA_DecimalDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DECIMALDATATYPE]); +} + +static UA_INLINE void +UA_DecimalDataType_clear(UA_DecimalDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DECIMALDATATYPE]); +} + +static UA_INLINE void +UA_DecimalDataType_delete(UA_DecimalDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DECIMALDATATYPE]); +}static UA_INLINE UA_Boolean +UA_DecimalDataType_equal(const UA_DecimalDataType *p1, const UA_DecimalDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DECIMALDATATYPE]) == UA_ORDER_EQ); +} + + + +/* DataTypeDescription */ +static UA_INLINE void +UA_DataTypeDescription_init(UA_DataTypeDescription *p) { + memset(p, 0, sizeof(UA_DataTypeDescription)); +} + +static UA_INLINE UA_DataTypeDescription * +UA_DataTypeDescription_new(void) { + return (UA_DataTypeDescription*)UA_new(&UA_TYPES[UA_TYPES_DATATYPEDESCRIPTION]); +} + +static UA_INLINE UA_StatusCode +UA_DataTypeDescription_copy(const UA_DataTypeDescription *src, UA_DataTypeDescription *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATATYPEDESCRIPTION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataTypeDescription_deleteMembers(UA_DataTypeDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATATYPEDESCRIPTION]); +} + +static UA_INLINE void +UA_DataTypeDescription_clear(UA_DataTypeDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATATYPEDESCRIPTION]); +} + +static UA_INLINE void +UA_DataTypeDescription_delete(UA_DataTypeDescription *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATATYPEDESCRIPTION]); +}static UA_INLINE UA_Boolean +UA_DataTypeDescription_equal(const UA_DataTypeDescription *p1, const UA_DataTypeDescription *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATATYPEDESCRIPTION]) == UA_ORDER_EQ); +} + + + +/* SimpleTypeDescription */ +static UA_INLINE void +UA_SimpleTypeDescription_init(UA_SimpleTypeDescription *p) { + memset(p, 0, sizeof(UA_SimpleTypeDescription)); +} + +static UA_INLINE UA_SimpleTypeDescription * +UA_SimpleTypeDescription_new(void) { + return (UA_SimpleTypeDescription*)UA_new(&UA_TYPES[UA_TYPES_SIMPLETYPEDESCRIPTION]); +} + +static UA_INLINE UA_StatusCode +UA_SimpleTypeDescription_copy(const UA_SimpleTypeDescription *src, UA_SimpleTypeDescription *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SIMPLETYPEDESCRIPTION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SimpleTypeDescription_deleteMembers(UA_SimpleTypeDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SIMPLETYPEDESCRIPTION]); +} + +static UA_INLINE void +UA_SimpleTypeDescription_clear(UA_SimpleTypeDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SIMPLETYPEDESCRIPTION]); +} + +static UA_INLINE void +UA_SimpleTypeDescription_delete(UA_SimpleTypeDescription *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SIMPLETYPEDESCRIPTION]); +}static UA_INLINE UA_Boolean +UA_SimpleTypeDescription_equal(const UA_SimpleTypeDescription *p1, const UA_SimpleTypeDescription *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SIMPLETYPEDESCRIPTION]) == UA_ORDER_EQ); +} + + + +/* PortableQualifiedName */ +static UA_INLINE void +UA_PortableQualifiedName_init(UA_PortableQualifiedName *p) { + memset(p, 0, sizeof(UA_PortableQualifiedName)); +} + +static UA_INLINE UA_PortableQualifiedName * +UA_PortableQualifiedName_new(void) { + return (UA_PortableQualifiedName*)UA_new(&UA_TYPES[UA_TYPES_PORTABLEQUALIFIEDNAME]); +} + +static UA_INLINE UA_StatusCode +UA_PortableQualifiedName_copy(const UA_PortableQualifiedName *src, UA_PortableQualifiedName *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PORTABLEQUALIFIEDNAME]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PortableQualifiedName_deleteMembers(UA_PortableQualifiedName *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PORTABLEQUALIFIEDNAME]); +} + +static UA_INLINE void +UA_PortableQualifiedName_clear(UA_PortableQualifiedName *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PORTABLEQUALIFIEDNAME]); +} + +static UA_INLINE void +UA_PortableQualifiedName_delete(UA_PortableQualifiedName *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PORTABLEQUALIFIEDNAME]); +}static UA_INLINE UA_Boolean +UA_PortableQualifiedName_equal(const UA_PortableQualifiedName *p1, const UA_PortableQualifiedName *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PORTABLEQUALIFIEDNAME]) == UA_ORDER_EQ); +} + + + +/* PortableNodeId */ +static UA_INLINE void +UA_PortableNodeId_init(UA_PortableNodeId *p) { + memset(p, 0, sizeof(UA_PortableNodeId)); +} + +static UA_INLINE UA_PortableNodeId * +UA_PortableNodeId_new(void) { + return (UA_PortableNodeId*)UA_new(&UA_TYPES[UA_TYPES_PORTABLENODEID]); +} + +static UA_INLINE UA_StatusCode +UA_PortableNodeId_copy(const UA_PortableNodeId *src, UA_PortableNodeId *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PORTABLENODEID]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PortableNodeId_deleteMembers(UA_PortableNodeId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PORTABLENODEID]); +} + +static UA_INLINE void +UA_PortableNodeId_clear(UA_PortableNodeId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PORTABLENODEID]); +} + +static UA_INLINE void +UA_PortableNodeId_delete(UA_PortableNodeId *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PORTABLENODEID]); +}static UA_INLINE UA_Boolean +UA_PortableNodeId_equal(const UA_PortableNodeId *p1, const UA_PortableNodeId *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PORTABLENODEID]) == UA_ORDER_EQ); +} + + + +/* UnsignedRationalNumber */ +static UA_INLINE void +UA_UnsignedRationalNumber_init(UA_UnsignedRationalNumber *p) { + memset(p, 0, sizeof(UA_UnsignedRationalNumber)); +} + +static UA_INLINE UA_UnsignedRationalNumber * +UA_UnsignedRationalNumber_new(void) { + return (UA_UnsignedRationalNumber*)UA_new(&UA_TYPES[UA_TYPES_UNSIGNEDRATIONALNUMBER]); +} + +static UA_INLINE UA_StatusCode +UA_UnsignedRationalNumber_copy(const UA_UnsignedRationalNumber *src, UA_UnsignedRationalNumber *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UNSIGNEDRATIONALNUMBER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UnsignedRationalNumber_deleteMembers(UA_UnsignedRationalNumber *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UNSIGNEDRATIONALNUMBER]); +} + +static UA_INLINE void +UA_UnsignedRationalNumber_clear(UA_UnsignedRationalNumber *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UNSIGNEDRATIONALNUMBER]); +} + +static UA_INLINE void +UA_UnsignedRationalNumber_delete(UA_UnsignedRationalNumber *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UNSIGNEDRATIONALNUMBER]); +}static UA_INLINE UA_Boolean +UA_UnsignedRationalNumber_equal(const UA_UnsignedRationalNumber *p1, const UA_UnsignedRationalNumber *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UNSIGNEDRATIONALNUMBER]) == UA_ORDER_EQ); +} + + + +/* PubSubState */ +static UA_INLINE void +UA_PubSubState_init(UA_PubSubState *p) { + memset(p, 0, sizeof(UA_PubSubState)); +} + +static UA_INLINE UA_PubSubState * +UA_PubSubState_new(void) { + return (UA_PubSubState*)UA_new(&UA_TYPES[UA_TYPES_PUBSUBSTATE]); +} + +static UA_INLINE UA_StatusCode +UA_PubSubState_copy(const UA_PubSubState *src, UA_PubSubState *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBSUBSTATE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PubSubState_deleteMembers(UA_PubSubState *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBSTATE]); +} + +static UA_INLINE void +UA_PubSubState_clear(UA_PubSubState *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBSTATE]); +} + +static UA_INLINE void +UA_PubSubState_delete(UA_PubSubState *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBSUBSTATE]); +}static UA_INLINE UA_Boolean +UA_PubSubState_equal(const UA_PubSubState *p1, const UA_PubSubState *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBSUBSTATE]) == UA_ORDER_EQ); +} + + + +/* DataSetFieldFlags */ +static UA_INLINE void +UA_DataSetFieldFlags_init(UA_DataSetFieldFlags *p) { + memset(p, 0, sizeof(UA_DataSetFieldFlags)); +} + +static UA_INLINE UA_DataSetFieldFlags * +UA_DataSetFieldFlags_new(void) { + return (UA_DataSetFieldFlags*)UA_new(&UA_TYPES[UA_TYPES_DATASETFIELDFLAGS]); +} + +static UA_INLINE UA_StatusCode +UA_DataSetFieldFlags_copy(const UA_DataSetFieldFlags *src, UA_DataSetFieldFlags *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATASETFIELDFLAGS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataSetFieldFlags_deleteMembers(UA_DataSetFieldFlags *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATASETFIELDFLAGS]); +} + +static UA_INLINE void +UA_DataSetFieldFlags_clear(UA_DataSetFieldFlags *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATASETFIELDFLAGS]); +} + +static UA_INLINE void +UA_DataSetFieldFlags_delete(UA_DataSetFieldFlags *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATASETFIELDFLAGS]); +}static UA_INLINE UA_Boolean +UA_DataSetFieldFlags_equal(const UA_DataSetFieldFlags *p1, const UA_DataSetFieldFlags *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATASETFIELDFLAGS]) == UA_ORDER_EQ); +} + + + +/* ConfigurationVersionDataType */ +static UA_INLINE void +UA_ConfigurationVersionDataType_init(UA_ConfigurationVersionDataType *p) { + memset(p, 0, sizeof(UA_ConfigurationVersionDataType)); +} + +static UA_INLINE UA_ConfigurationVersionDataType * +UA_ConfigurationVersionDataType_new(void) { + return (UA_ConfigurationVersionDataType*)UA_new(&UA_TYPES[UA_TYPES_CONFIGURATIONVERSIONDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_ConfigurationVersionDataType_copy(const UA_ConfigurationVersionDataType *src, UA_ConfigurationVersionDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CONFIGURATIONVERSIONDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ConfigurationVersionDataType_deleteMembers(UA_ConfigurationVersionDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CONFIGURATIONVERSIONDATATYPE]); +} + +static UA_INLINE void +UA_ConfigurationVersionDataType_clear(UA_ConfigurationVersionDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CONFIGURATIONVERSIONDATATYPE]); +} + +static UA_INLINE void +UA_ConfigurationVersionDataType_delete(UA_ConfigurationVersionDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CONFIGURATIONVERSIONDATATYPE]); +}static UA_INLINE UA_Boolean +UA_ConfigurationVersionDataType_equal(const UA_ConfigurationVersionDataType *p1, const UA_ConfigurationVersionDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CONFIGURATIONVERSIONDATATYPE]) == UA_ORDER_EQ); +} + + + +/* PublishedVariableDataType */ +static UA_INLINE void +UA_PublishedVariableDataType_init(UA_PublishedVariableDataType *p) { + memset(p, 0, sizeof(UA_PublishedVariableDataType)); +} + +static UA_INLINE UA_PublishedVariableDataType * +UA_PublishedVariableDataType_new(void) { + return (UA_PublishedVariableDataType*)UA_new(&UA_TYPES[UA_TYPES_PUBLISHEDVARIABLEDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PublishedVariableDataType_copy(const UA_PublishedVariableDataType *src, UA_PublishedVariableDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBLISHEDVARIABLEDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PublishedVariableDataType_deleteMembers(UA_PublishedVariableDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHEDVARIABLEDATATYPE]); +} + +static UA_INLINE void +UA_PublishedVariableDataType_clear(UA_PublishedVariableDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHEDVARIABLEDATATYPE]); +} + +static UA_INLINE void +UA_PublishedVariableDataType_delete(UA_PublishedVariableDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBLISHEDVARIABLEDATATYPE]); +}static UA_INLINE UA_Boolean +UA_PublishedVariableDataType_equal(const UA_PublishedVariableDataType *p1, const UA_PublishedVariableDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBLISHEDVARIABLEDATATYPE]) == UA_ORDER_EQ); +} + + + +/* PublishedDataItemsDataType */ +static UA_INLINE void +UA_PublishedDataItemsDataType_init(UA_PublishedDataItemsDataType *p) { + memset(p, 0, sizeof(UA_PublishedDataItemsDataType)); +} + +static UA_INLINE UA_PublishedDataItemsDataType * +UA_PublishedDataItemsDataType_new(void) { + return (UA_PublishedDataItemsDataType*)UA_new(&UA_TYPES[UA_TYPES_PUBLISHEDDATAITEMSDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PublishedDataItemsDataType_copy(const UA_PublishedDataItemsDataType *src, UA_PublishedDataItemsDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBLISHEDDATAITEMSDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PublishedDataItemsDataType_deleteMembers(UA_PublishedDataItemsDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHEDDATAITEMSDATATYPE]); +} + +static UA_INLINE void +UA_PublishedDataItemsDataType_clear(UA_PublishedDataItemsDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHEDDATAITEMSDATATYPE]); +} + +static UA_INLINE void +UA_PublishedDataItemsDataType_delete(UA_PublishedDataItemsDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBLISHEDDATAITEMSDATATYPE]); +}static UA_INLINE UA_Boolean +UA_PublishedDataItemsDataType_equal(const UA_PublishedDataItemsDataType *p1, const UA_PublishedDataItemsDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBLISHEDDATAITEMSDATATYPE]) == UA_ORDER_EQ); +} + + + +/* PublishedDataSetCustomSourceDataType */ +static UA_INLINE void +UA_PublishedDataSetCustomSourceDataType_init(UA_PublishedDataSetCustomSourceDataType *p) { + memset(p, 0, sizeof(UA_PublishedDataSetCustomSourceDataType)); +} + +static UA_INLINE UA_PublishedDataSetCustomSourceDataType * +UA_PublishedDataSetCustomSourceDataType_new(void) { + return (UA_PublishedDataSetCustomSourceDataType*)UA_new(&UA_TYPES[UA_TYPES_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PublishedDataSetCustomSourceDataType_copy(const UA_PublishedDataSetCustomSourceDataType *src, UA_PublishedDataSetCustomSourceDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PublishedDataSetCustomSourceDataType_deleteMembers(UA_PublishedDataSetCustomSourceDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE]); +} + +static UA_INLINE void +UA_PublishedDataSetCustomSourceDataType_clear(UA_PublishedDataSetCustomSourceDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE]); +} + +static UA_INLINE void +UA_PublishedDataSetCustomSourceDataType_delete(UA_PublishedDataSetCustomSourceDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE]); +}static UA_INLINE UA_Boolean +UA_PublishedDataSetCustomSourceDataType_equal(const UA_PublishedDataSetCustomSourceDataType *p1, const UA_PublishedDataSetCustomSourceDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBLISHEDDATASETCUSTOMSOURCEDATATYPE]) == UA_ORDER_EQ); +} + + + +/* DataSetFieldContentMask */ +static UA_INLINE void +UA_DataSetFieldContentMask_init(UA_DataSetFieldContentMask *p) { + memset(p, 0, sizeof(UA_DataSetFieldContentMask)); +} + +static UA_INLINE UA_DataSetFieldContentMask * +UA_DataSetFieldContentMask_new(void) { + return (UA_DataSetFieldContentMask*)UA_new(&UA_TYPES[UA_TYPES_DATASETFIELDCONTENTMASK]); +} + +static UA_INLINE UA_StatusCode +UA_DataSetFieldContentMask_copy(const UA_DataSetFieldContentMask *src, UA_DataSetFieldContentMask *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATASETFIELDCONTENTMASK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataSetFieldContentMask_deleteMembers(UA_DataSetFieldContentMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATASETFIELDCONTENTMASK]); +} + +static UA_INLINE void +UA_DataSetFieldContentMask_clear(UA_DataSetFieldContentMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATASETFIELDCONTENTMASK]); +} + +static UA_INLINE void +UA_DataSetFieldContentMask_delete(UA_DataSetFieldContentMask *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATASETFIELDCONTENTMASK]); +}static UA_INLINE UA_Boolean +UA_DataSetFieldContentMask_equal(const UA_DataSetFieldContentMask *p1, const UA_DataSetFieldContentMask *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATASETFIELDCONTENTMASK]) == UA_ORDER_EQ); +} + + + +/* DataSetWriterDataType */ +static UA_INLINE void +UA_DataSetWriterDataType_init(UA_DataSetWriterDataType *p) { + memset(p, 0, sizeof(UA_DataSetWriterDataType)); +} + +static UA_INLINE UA_DataSetWriterDataType * +UA_DataSetWriterDataType_new(void) { + return (UA_DataSetWriterDataType*)UA_new(&UA_TYPES[UA_TYPES_DATASETWRITERDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_DataSetWriterDataType_copy(const UA_DataSetWriterDataType *src, UA_DataSetWriterDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATASETWRITERDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataSetWriterDataType_deleteMembers(UA_DataSetWriterDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATASETWRITERDATATYPE]); +} + +static UA_INLINE void +UA_DataSetWriterDataType_clear(UA_DataSetWriterDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATASETWRITERDATATYPE]); +} + +static UA_INLINE void +UA_DataSetWriterDataType_delete(UA_DataSetWriterDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATASETWRITERDATATYPE]); +}static UA_INLINE UA_Boolean +UA_DataSetWriterDataType_equal(const UA_DataSetWriterDataType *p1, const UA_DataSetWriterDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATASETWRITERDATATYPE]) == UA_ORDER_EQ); +} + + + +/* NetworkAddressDataType */ +static UA_INLINE void +UA_NetworkAddressDataType_init(UA_NetworkAddressDataType *p) { + memset(p, 0, sizeof(UA_NetworkAddressDataType)); +} + +static UA_INLINE UA_NetworkAddressDataType * +UA_NetworkAddressDataType_new(void) { + return (UA_NetworkAddressDataType*)UA_new(&UA_TYPES[UA_TYPES_NETWORKADDRESSDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_NetworkAddressDataType_copy(const UA_NetworkAddressDataType *src, UA_NetworkAddressDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NETWORKADDRESSDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NetworkAddressDataType_deleteMembers(UA_NetworkAddressDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NETWORKADDRESSDATATYPE]); +} + +static UA_INLINE void +UA_NetworkAddressDataType_clear(UA_NetworkAddressDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NETWORKADDRESSDATATYPE]); +} + +static UA_INLINE void +UA_NetworkAddressDataType_delete(UA_NetworkAddressDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NETWORKADDRESSDATATYPE]); +}static UA_INLINE UA_Boolean +UA_NetworkAddressDataType_equal(const UA_NetworkAddressDataType *p1, const UA_NetworkAddressDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NETWORKADDRESSDATATYPE]) == UA_ORDER_EQ); +} + + + +/* NetworkAddressUrlDataType */ +static UA_INLINE void +UA_NetworkAddressUrlDataType_init(UA_NetworkAddressUrlDataType *p) { + memset(p, 0, sizeof(UA_NetworkAddressUrlDataType)); +} + +static UA_INLINE UA_NetworkAddressUrlDataType * +UA_NetworkAddressUrlDataType_new(void) { + return (UA_NetworkAddressUrlDataType*)UA_new(&UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_NetworkAddressUrlDataType_copy(const UA_NetworkAddressUrlDataType *src, UA_NetworkAddressUrlDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NetworkAddressUrlDataType_deleteMembers(UA_NetworkAddressUrlDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]); +} + +static UA_INLINE void +UA_NetworkAddressUrlDataType_clear(UA_NetworkAddressUrlDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]); +} + +static UA_INLINE void +UA_NetworkAddressUrlDataType_delete(UA_NetworkAddressUrlDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]); +}static UA_INLINE UA_Boolean +UA_NetworkAddressUrlDataType_equal(const UA_NetworkAddressUrlDataType *p1, const UA_NetworkAddressUrlDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]) == UA_ORDER_EQ); +} + + + +/* OverrideValueHandling */ +static UA_INLINE void +UA_OverrideValueHandling_init(UA_OverrideValueHandling *p) { + memset(p, 0, sizeof(UA_OverrideValueHandling)); +} + +static UA_INLINE UA_OverrideValueHandling * +UA_OverrideValueHandling_new(void) { + return (UA_OverrideValueHandling*)UA_new(&UA_TYPES[UA_TYPES_OVERRIDEVALUEHANDLING]); +} + +static UA_INLINE UA_StatusCode +UA_OverrideValueHandling_copy(const UA_OverrideValueHandling *src, UA_OverrideValueHandling *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_OVERRIDEVALUEHANDLING]); +} + +UA_DEPRECATED static UA_INLINE void +UA_OverrideValueHandling_deleteMembers(UA_OverrideValueHandling *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OVERRIDEVALUEHANDLING]); +} + +static UA_INLINE void +UA_OverrideValueHandling_clear(UA_OverrideValueHandling *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OVERRIDEVALUEHANDLING]); +} + +static UA_INLINE void +UA_OverrideValueHandling_delete(UA_OverrideValueHandling *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_OVERRIDEVALUEHANDLING]); +}static UA_INLINE UA_Boolean +UA_OverrideValueHandling_equal(const UA_OverrideValueHandling *p1, const UA_OverrideValueHandling *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_OVERRIDEVALUEHANDLING]) == UA_ORDER_EQ); +} + + + +/* StandaloneSubscribedDataSetRefDataType */ +static UA_INLINE void +UA_StandaloneSubscribedDataSetRefDataType_init(UA_StandaloneSubscribedDataSetRefDataType *p) { + memset(p, 0, sizeof(UA_StandaloneSubscribedDataSetRefDataType)); +} + +static UA_INLINE UA_StandaloneSubscribedDataSetRefDataType * +UA_StandaloneSubscribedDataSetRefDataType_new(void) { + return (UA_StandaloneSubscribedDataSetRefDataType*)UA_new(&UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETREFDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_StandaloneSubscribedDataSetRefDataType_copy(const UA_StandaloneSubscribedDataSetRefDataType *src, UA_StandaloneSubscribedDataSetRefDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETREFDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_StandaloneSubscribedDataSetRefDataType_deleteMembers(UA_StandaloneSubscribedDataSetRefDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETREFDATATYPE]); +} + +static UA_INLINE void +UA_StandaloneSubscribedDataSetRefDataType_clear(UA_StandaloneSubscribedDataSetRefDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETREFDATATYPE]); +} + +static UA_INLINE void +UA_StandaloneSubscribedDataSetRefDataType_delete(UA_StandaloneSubscribedDataSetRefDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETREFDATATYPE]); +}static UA_INLINE UA_Boolean +UA_StandaloneSubscribedDataSetRefDataType_equal(const UA_StandaloneSubscribedDataSetRefDataType *p1, const UA_StandaloneSubscribedDataSetRefDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETREFDATATYPE]) == UA_ORDER_EQ); +} + + + +/* DataSetOrderingType */ +static UA_INLINE void +UA_DataSetOrderingType_init(UA_DataSetOrderingType *p) { + memset(p, 0, sizeof(UA_DataSetOrderingType)); +} + +static UA_INLINE UA_DataSetOrderingType * +UA_DataSetOrderingType_new(void) { + return (UA_DataSetOrderingType*)UA_new(&UA_TYPES[UA_TYPES_DATASETORDERINGTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_DataSetOrderingType_copy(const UA_DataSetOrderingType *src, UA_DataSetOrderingType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATASETORDERINGTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataSetOrderingType_deleteMembers(UA_DataSetOrderingType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATASETORDERINGTYPE]); +} + +static UA_INLINE void +UA_DataSetOrderingType_clear(UA_DataSetOrderingType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATASETORDERINGTYPE]); +} + +static UA_INLINE void +UA_DataSetOrderingType_delete(UA_DataSetOrderingType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATASETORDERINGTYPE]); +}static UA_INLINE UA_Boolean +UA_DataSetOrderingType_equal(const UA_DataSetOrderingType *p1, const UA_DataSetOrderingType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATASETORDERINGTYPE]) == UA_ORDER_EQ); +} + + + +/* UadpNetworkMessageContentMask */ +static UA_INLINE void +UA_UadpNetworkMessageContentMask_init(UA_UadpNetworkMessageContentMask *p) { + memset(p, 0, sizeof(UA_UadpNetworkMessageContentMask)); +} + +static UA_INLINE UA_UadpNetworkMessageContentMask * +UA_UadpNetworkMessageContentMask_new(void) { + return (UA_UadpNetworkMessageContentMask*)UA_new(&UA_TYPES[UA_TYPES_UADPNETWORKMESSAGECONTENTMASK]); +} + +static UA_INLINE UA_StatusCode +UA_UadpNetworkMessageContentMask_copy(const UA_UadpNetworkMessageContentMask *src, UA_UadpNetworkMessageContentMask *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UADPNETWORKMESSAGECONTENTMASK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UadpNetworkMessageContentMask_deleteMembers(UA_UadpNetworkMessageContentMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UADPNETWORKMESSAGECONTENTMASK]); +} + +static UA_INLINE void +UA_UadpNetworkMessageContentMask_clear(UA_UadpNetworkMessageContentMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UADPNETWORKMESSAGECONTENTMASK]); +} + +static UA_INLINE void +UA_UadpNetworkMessageContentMask_delete(UA_UadpNetworkMessageContentMask *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UADPNETWORKMESSAGECONTENTMASK]); +}static UA_INLINE UA_Boolean +UA_UadpNetworkMessageContentMask_equal(const UA_UadpNetworkMessageContentMask *p1, const UA_UadpNetworkMessageContentMask *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UADPNETWORKMESSAGECONTENTMASK]) == UA_ORDER_EQ); +} + + + +/* UadpWriterGroupMessageDataType */ +static UA_INLINE void +UA_UadpWriterGroupMessageDataType_init(UA_UadpWriterGroupMessageDataType *p) { + memset(p, 0, sizeof(UA_UadpWriterGroupMessageDataType)); +} + +static UA_INLINE UA_UadpWriterGroupMessageDataType * +UA_UadpWriterGroupMessageDataType_new(void) { + return (UA_UadpWriterGroupMessageDataType*)UA_new(&UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_UadpWriterGroupMessageDataType_copy(const UA_UadpWriterGroupMessageDataType *src, UA_UadpWriterGroupMessageDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UadpWriterGroupMessageDataType_deleteMembers(UA_UadpWriterGroupMessageDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE]); +} + +static UA_INLINE void +UA_UadpWriterGroupMessageDataType_clear(UA_UadpWriterGroupMessageDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE]); +} + +static UA_INLINE void +UA_UadpWriterGroupMessageDataType_delete(UA_UadpWriterGroupMessageDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE]); +}static UA_INLINE UA_Boolean +UA_UadpWriterGroupMessageDataType_equal(const UA_UadpWriterGroupMessageDataType *p1, const UA_UadpWriterGroupMessageDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE]) == UA_ORDER_EQ); +} + + + +/* UadpDataSetMessageContentMask */ +static UA_INLINE void +UA_UadpDataSetMessageContentMask_init(UA_UadpDataSetMessageContentMask *p) { + memset(p, 0, sizeof(UA_UadpDataSetMessageContentMask)); +} + +static UA_INLINE UA_UadpDataSetMessageContentMask * +UA_UadpDataSetMessageContentMask_new(void) { + return (UA_UadpDataSetMessageContentMask*)UA_new(&UA_TYPES[UA_TYPES_UADPDATASETMESSAGECONTENTMASK]); +} + +static UA_INLINE UA_StatusCode +UA_UadpDataSetMessageContentMask_copy(const UA_UadpDataSetMessageContentMask *src, UA_UadpDataSetMessageContentMask *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UADPDATASETMESSAGECONTENTMASK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UadpDataSetMessageContentMask_deleteMembers(UA_UadpDataSetMessageContentMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UADPDATASETMESSAGECONTENTMASK]); +} + +static UA_INLINE void +UA_UadpDataSetMessageContentMask_clear(UA_UadpDataSetMessageContentMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UADPDATASETMESSAGECONTENTMASK]); +} + +static UA_INLINE void +UA_UadpDataSetMessageContentMask_delete(UA_UadpDataSetMessageContentMask *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UADPDATASETMESSAGECONTENTMASK]); +}static UA_INLINE UA_Boolean +UA_UadpDataSetMessageContentMask_equal(const UA_UadpDataSetMessageContentMask *p1, const UA_UadpDataSetMessageContentMask *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UADPDATASETMESSAGECONTENTMASK]) == UA_ORDER_EQ); +} + + + +/* UadpDataSetWriterMessageDataType */ +static UA_INLINE void +UA_UadpDataSetWriterMessageDataType_init(UA_UadpDataSetWriterMessageDataType *p) { + memset(p, 0, sizeof(UA_UadpDataSetWriterMessageDataType)); +} + +static UA_INLINE UA_UadpDataSetWriterMessageDataType * +UA_UadpDataSetWriterMessageDataType_new(void) { + return (UA_UadpDataSetWriterMessageDataType*)UA_new(&UA_TYPES[UA_TYPES_UADPDATASETWRITERMESSAGEDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_UadpDataSetWriterMessageDataType_copy(const UA_UadpDataSetWriterMessageDataType *src, UA_UadpDataSetWriterMessageDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UADPDATASETWRITERMESSAGEDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UadpDataSetWriterMessageDataType_deleteMembers(UA_UadpDataSetWriterMessageDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UADPDATASETWRITERMESSAGEDATATYPE]); +} + +static UA_INLINE void +UA_UadpDataSetWriterMessageDataType_clear(UA_UadpDataSetWriterMessageDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UADPDATASETWRITERMESSAGEDATATYPE]); +} + +static UA_INLINE void +UA_UadpDataSetWriterMessageDataType_delete(UA_UadpDataSetWriterMessageDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UADPDATASETWRITERMESSAGEDATATYPE]); +}static UA_INLINE UA_Boolean +UA_UadpDataSetWriterMessageDataType_equal(const UA_UadpDataSetWriterMessageDataType *p1, const UA_UadpDataSetWriterMessageDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UADPDATASETWRITERMESSAGEDATATYPE]) == UA_ORDER_EQ); +} + + + +/* UadpDataSetReaderMessageDataType */ +static UA_INLINE void +UA_UadpDataSetReaderMessageDataType_init(UA_UadpDataSetReaderMessageDataType *p) { + memset(p, 0, sizeof(UA_UadpDataSetReaderMessageDataType)); +} + +static UA_INLINE UA_UadpDataSetReaderMessageDataType * +UA_UadpDataSetReaderMessageDataType_new(void) { + return (UA_UadpDataSetReaderMessageDataType*)UA_new(&UA_TYPES[UA_TYPES_UADPDATASETREADERMESSAGEDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_UadpDataSetReaderMessageDataType_copy(const UA_UadpDataSetReaderMessageDataType *src, UA_UadpDataSetReaderMessageDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UADPDATASETREADERMESSAGEDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UadpDataSetReaderMessageDataType_deleteMembers(UA_UadpDataSetReaderMessageDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UADPDATASETREADERMESSAGEDATATYPE]); +} + +static UA_INLINE void +UA_UadpDataSetReaderMessageDataType_clear(UA_UadpDataSetReaderMessageDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UADPDATASETREADERMESSAGEDATATYPE]); +} + +static UA_INLINE void +UA_UadpDataSetReaderMessageDataType_delete(UA_UadpDataSetReaderMessageDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UADPDATASETREADERMESSAGEDATATYPE]); +}static UA_INLINE UA_Boolean +UA_UadpDataSetReaderMessageDataType_equal(const UA_UadpDataSetReaderMessageDataType *p1, const UA_UadpDataSetReaderMessageDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UADPDATASETREADERMESSAGEDATATYPE]) == UA_ORDER_EQ); +} + + + +/* JsonNetworkMessageContentMask */ +static UA_INLINE void +UA_JsonNetworkMessageContentMask_init(UA_JsonNetworkMessageContentMask *p) { + memset(p, 0, sizeof(UA_JsonNetworkMessageContentMask)); +} + +static UA_INLINE UA_JsonNetworkMessageContentMask * +UA_JsonNetworkMessageContentMask_new(void) { + return (UA_JsonNetworkMessageContentMask*)UA_new(&UA_TYPES[UA_TYPES_JSONNETWORKMESSAGECONTENTMASK]); +} + +static UA_INLINE UA_StatusCode +UA_JsonNetworkMessageContentMask_copy(const UA_JsonNetworkMessageContentMask *src, UA_JsonNetworkMessageContentMask *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_JSONNETWORKMESSAGECONTENTMASK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_JsonNetworkMessageContentMask_deleteMembers(UA_JsonNetworkMessageContentMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_JSONNETWORKMESSAGECONTENTMASK]); +} + +static UA_INLINE void +UA_JsonNetworkMessageContentMask_clear(UA_JsonNetworkMessageContentMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_JSONNETWORKMESSAGECONTENTMASK]); +} + +static UA_INLINE void +UA_JsonNetworkMessageContentMask_delete(UA_JsonNetworkMessageContentMask *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_JSONNETWORKMESSAGECONTENTMASK]); +}static UA_INLINE UA_Boolean +UA_JsonNetworkMessageContentMask_equal(const UA_JsonNetworkMessageContentMask *p1, const UA_JsonNetworkMessageContentMask *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_JSONNETWORKMESSAGECONTENTMASK]) == UA_ORDER_EQ); +} + + + +/* JsonWriterGroupMessageDataType */ +static UA_INLINE void +UA_JsonWriterGroupMessageDataType_init(UA_JsonWriterGroupMessageDataType *p) { + memset(p, 0, sizeof(UA_JsonWriterGroupMessageDataType)); +} + +static UA_INLINE UA_JsonWriterGroupMessageDataType * +UA_JsonWriterGroupMessageDataType_new(void) { + return (UA_JsonWriterGroupMessageDataType*)UA_new(&UA_TYPES[UA_TYPES_JSONWRITERGROUPMESSAGEDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_JsonWriterGroupMessageDataType_copy(const UA_JsonWriterGroupMessageDataType *src, UA_JsonWriterGroupMessageDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_JSONWRITERGROUPMESSAGEDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_JsonWriterGroupMessageDataType_deleteMembers(UA_JsonWriterGroupMessageDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_JSONWRITERGROUPMESSAGEDATATYPE]); +} + +static UA_INLINE void +UA_JsonWriterGroupMessageDataType_clear(UA_JsonWriterGroupMessageDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_JSONWRITERGROUPMESSAGEDATATYPE]); +} + +static UA_INLINE void +UA_JsonWriterGroupMessageDataType_delete(UA_JsonWriterGroupMessageDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_JSONWRITERGROUPMESSAGEDATATYPE]); +}static UA_INLINE UA_Boolean +UA_JsonWriterGroupMessageDataType_equal(const UA_JsonWriterGroupMessageDataType *p1, const UA_JsonWriterGroupMessageDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_JSONWRITERGROUPMESSAGEDATATYPE]) == UA_ORDER_EQ); +} + + + +/* JsonDataSetMessageContentMask */ +static UA_INLINE void +UA_JsonDataSetMessageContentMask_init(UA_JsonDataSetMessageContentMask *p) { + memset(p, 0, sizeof(UA_JsonDataSetMessageContentMask)); +} + +static UA_INLINE UA_JsonDataSetMessageContentMask * +UA_JsonDataSetMessageContentMask_new(void) { + return (UA_JsonDataSetMessageContentMask*)UA_new(&UA_TYPES[UA_TYPES_JSONDATASETMESSAGECONTENTMASK]); +} + +static UA_INLINE UA_StatusCode +UA_JsonDataSetMessageContentMask_copy(const UA_JsonDataSetMessageContentMask *src, UA_JsonDataSetMessageContentMask *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_JSONDATASETMESSAGECONTENTMASK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_JsonDataSetMessageContentMask_deleteMembers(UA_JsonDataSetMessageContentMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_JSONDATASETMESSAGECONTENTMASK]); +} + +static UA_INLINE void +UA_JsonDataSetMessageContentMask_clear(UA_JsonDataSetMessageContentMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_JSONDATASETMESSAGECONTENTMASK]); +} + +static UA_INLINE void +UA_JsonDataSetMessageContentMask_delete(UA_JsonDataSetMessageContentMask *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_JSONDATASETMESSAGECONTENTMASK]); +}static UA_INLINE UA_Boolean +UA_JsonDataSetMessageContentMask_equal(const UA_JsonDataSetMessageContentMask *p1, const UA_JsonDataSetMessageContentMask *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_JSONDATASETMESSAGECONTENTMASK]) == UA_ORDER_EQ); +} + + + +/* JsonDataSetWriterMessageDataType */ +static UA_INLINE void +UA_JsonDataSetWriterMessageDataType_init(UA_JsonDataSetWriterMessageDataType *p) { + memset(p, 0, sizeof(UA_JsonDataSetWriterMessageDataType)); +} + +static UA_INLINE UA_JsonDataSetWriterMessageDataType * +UA_JsonDataSetWriterMessageDataType_new(void) { + return (UA_JsonDataSetWriterMessageDataType*)UA_new(&UA_TYPES[UA_TYPES_JSONDATASETWRITERMESSAGEDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_JsonDataSetWriterMessageDataType_copy(const UA_JsonDataSetWriterMessageDataType *src, UA_JsonDataSetWriterMessageDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_JSONDATASETWRITERMESSAGEDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_JsonDataSetWriterMessageDataType_deleteMembers(UA_JsonDataSetWriterMessageDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_JSONDATASETWRITERMESSAGEDATATYPE]); +} + +static UA_INLINE void +UA_JsonDataSetWriterMessageDataType_clear(UA_JsonDataSetWriterMessageDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_JSONDATASETWRITERMESSAGEDATATYPE]); +} + +static UA_INLINE void +UA_JsonDataSetWriterMessageDataType_delete(UA_JsonDataSetWriterMessageDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_JSONDATASETWRITERMESSAGEDATATYPE]); +}static UA_INLINE UA_Boolean +UA_JsonDataSetWriterMessageDataType_equal(const UA_JsonDataSetWriterMessageDataType *p1, const UA_JsonDataSetWriterMessageDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_JSONDATASETWRITERMESSAGEDATATYPE]) == UA_ORDER_EQ); +} + + + +/* JsonDataSetReaderMessageDataType */ +static UA_INLINE void +UA_JsonDataSetReaderMessageDataType_init(UA_JsonDataSetReaderMessageDataType *p) { + memset(p, 0, sizeof(UA_JsonDataSetReaderMessageDataType)); +} + +static UA_INLINE UA_JsonDataSetReaderMessageDataType * +UA_JsonDataSetReaderMessageDataType_new(void) { + return (UA_JsonDataSetReaderMessageDataType*)UA_new(&UA_TYPES[UA_TYPES_JSONDATASETREADERMESSAGEDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_JsonDataSetReaderMessageDataType_copy(const UA_JsonDataSetReaderMessageDataType *src, UA_JsonDataSetReaderMessageDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_JSONDATASETREADERMESSAGEDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_JsonDataSetReaderMessageDataType_deleteMembers(UA_JsonDataSetReaderMessageDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_JSONDATASETREADERMESSAGEDATATYPE]); +} + +static UA_INLINE void +UA_JsonDataSetReaderMessageDataType_clear(UA_JsonDataSetReaderMessageDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_JSONDATASETREADERMESSAGEDATATYPE]); +} + +static UA_INLINE void +UA_JsonDataSetReaderMessageDataType_delete(UA_JsonDataSetReaderMessageDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_JSONDATASETREADERMESSAGEDATATYPE]); +}static UA_INLINE UA_Boolean +UA_JsonDataSetReaderMessageDataType_equal(const UA_JsonDataSetReaderMessageDataType *p1, const UA_JsonDataSetReaderMessageDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_JSONDATASETREADERMESSAGEDATATYPE]) == UA_ORDER_EQ); +} + + + +/* TransmitQosPriorityDataType */ +static UA_INLINE void +UA_TransmitQosPriorityDataType_init(UA_TransmitQosPriorityDataType *p) { + memset(p, 0, sizeof(UA_TransmitQosPriorityDataType)); +} + +static UA_INLINE UA_TransmitQosPriorityDataType * +UA_TransmitQosPriorityDataType_new(void) { + return (UA_TransmitQosPriorityDataType*)UA_new(&UA_TYPES[UA_TYPES_TRANSMITQOSPRIORITYDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_TransmitQosPriorityDataType_copy(const UA_TransmitQosPriorityDataType *src, UA_TransmitQosPriorityDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TRANSMITQOSPRIORITYDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TransmitQosPriorityDataType_deleteMembers(UA_TransmitQosPriorityDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRANSMITQOSPRIORITYDATATYPE]); +} + +static UA_INLINE void +UA_TransmitQosPriorityDataType_clear(UA_TransmitQosPriorityDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRANSMITQOSPRIORITYDATATYPE]); +} + +static UA_INLINE void +UA_TransmitQosPriorityDataType_delete(UA_TransmitQosPriorityDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TRANSMITQOSPRIORITYDATATYPE]); +}static UA_INLINE UA_Boolean +UA_TransmitQosPriorityDataType_equal(const UA_TransmitQosPriorityDataType *p1, const UA_TransmitQosPriorityDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TRANSMITQOSPRIORITYDATATYPE]) == UA_ORDER_EQ); +} + + + +/* ReceiveQosPriorityDataType */ +static UA_INLINE void +UA_ReceiveQosPriorityDataType_init(UA_ReceiveQosPriorityDataType *p) { + memset(p, 0, sizeof(UA_ReceiveQosPriorityDataType)); +} + +static UA_INLINE UA_ReceiveQosPriorityDataType * +UA_ReceiveQosPriorityDataType_new(void) { + return (UA_ReceiveQosPriorityDataType*)UA_new(&UA_TYPES[UA_TYPES_RECEIVEQOSPRIORITYDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_ReceiveQosPriorityDataType_copy(const UA_ReceiveQosPriorityDataType *src, UA_ReceiveQosPriorityDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_RECEIVEQOSPRIORITYDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReceiveQosPriorityDataType_deleteMembers(UA_ReceiveQosPriorityDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RECEIVEQOSPRIORITYDATATYPE]); +} + +static UA_INLINE void +UA_ReceiveQosPriorityDataType_clear(UA_ReceiveQosPriorityDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RECEIVEQOSPRIORITYDATATYPE]); +} + +static UA_INLINE void +UA_ReceiveQosPriorityDataType_delete(UA_ReceiveQosPriorityDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_RECEIVEQOSPRIORITYDATATYPE]); +}static UA_INLINE UA_Boolean +UA_ReceiveQosPriorityDataType_equal(const UA_ReceiveQosPriorityDataType *p1, const UA_ReceiveQosPriorityDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_RECEIVEQOSPRIORITYDATATYPE]) == UA_ORDER_EQ); +} + + + +/* DatagramConnectionTransportDataType */ +static UA_INLINE void +UA_DatagramConnectionTransportDataType_init(UA_DatagramConnectionTransportDataType *p) { + memset(p, 0, sizeof(UA_DatagramConnectionTransportDataType)); +} + +static UA_INLINE UA_DatagramConnectionTransportDataType * +UA_DatagramConnectionTransportDataType_new(void) { + return (UA_DatagramConnectionTransportDataType*)UA_new(&UA_TYPES[UA_TYPES_DATAGRAMCONNECTIONTRANSPORTDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_DatagramConnectionTransportDataType_copy(const UA_DatagramConnectionTransportDataType *src, UA_DatagramConnectionTransportDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATAGRAMCONNECTIONTRANSPORTDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DatagramConnectionTransportDataType_deleteMembers(UA_DatagramConnectionTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATAGRAMCONNECTIONTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_DatagramConnectionTransportDataType_clear(UA_DatagramConnectionTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATAGRAMCONNECTIONTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_DatagramConnectionTransportDataType_delete(UA_DatagramConnectionTransportDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATAGRAMCONNECTIONTRANSPORTDATATYPE]); +}static UA_INLINE UA_Boolean +UA_DatagramConnectionTransportDataType_equal(const UA_DatagramConnectionTransportDataType *p1, const UA_DatagramConnectionTransportDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATAGRAMCONNECTIONTRANSPORTDATATYPE]) == UA_ORDER_EQ); +} + + + +/* DatagramConnectionTransport2DataType */ +static UA_INLINE void +UA_DatagramConnectionTransport2DataType_init(UA_DatagramConnectionTransport2DataType *p) { + memset(p, 0, sizeof(UA_DatagramConnectionTransport2DataType)); +} + +static UA_INLINE UA_DatagramConnectionTransport2DataType * +UA_DatagramConnectionTransport2DataType_new(void) { + return (UA_DatagramConnectionTransport2DataType*)UA_new(&UA_TYPES[UA_TYPES_DATAGRAMCONNECTIONTRANSPORT2DATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_DatagramConnectionTransport2DataType_copy(const UA_DatagramConnectionTransport2DataType *src, UA_DatagramConnectionTransport2DataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATAGRAMCONNECTIONTRANSPORT2DATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DatagramConnectionTransport2DataType_deleteMembers(UA_DatagramConnectionTransport2DataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATAGRAMCONNECTIONTRANSPORT2DATATYPE]); +} + +static UA_INLINE void +UA_DatagramConnectionTransport2DataType_clear(UA_DatagramConnectionTransport2DataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATAGRAMCONNECTIONTRANSPORT2DATATYPE]); +} + +static UA_INLINE void +UA_DatagramConnectionTransport2DataType_delete(UA_DatagramConnectionTransport2DataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATAGRAMCONNECTIONTRANSPORT2DATATYPE]); +}static UA_INLINE UA_Boolean +UA_DatagramConnectionTransport2DataType_equal(const UA_DatagramConnectionTransport2DataType *p1, const UA_DatagramConnectionTransport2DataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATAGRAMCONNECTIONTRANSPORT2DATATYPE]) == UA_ORDER_EQ); +} + + + +/* DatagramWriterGroupTransportDataType */ +static UA_INLINE void +UA_DatagramWriterGroupTransportDataType_init(UA_DatagramWriterGroupTransportDataType *p) { + memset(p, 0, sizeof(UA_DatagramWriterGroupTransportDataType)); +} + +static UA_INLINE UA_DatagramWriterGroupTransportDataType * +UA_DatagramWriterGroupTransportDataType_new(void) { + return (UA_DatagramWriterGroupTransportDataType*)UA_new(&UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORTDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_DatagramWriterGroupTransportDataType_copy(const UA_DatagramWriterGroupTransportDataType *src, UA_DatagramWriterGroupTransportDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORTDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DatagramWriterGroupTransportDataType_deleteMembers(UA_DatagramWriterGroupTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_DatagramWriterGroupTransportDataType_clear(UA_DatagramWriterGroupTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_DatagramWriterGroupTransportDataType_delete(UA_DatagramWriterGroupTransportDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORTDATATYPE]); +}static UA_INLINE UA_Boolean +UA_DatagramWriterGroupTransportDataType_equal(const UA_DatagramWriterGroupTransportDataType *p1, const UA_DatagramWriterGroupTransportDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORTDATATYPE]) == UA_ORDER_EQ); +} + + + +/* DatagramWriterGroupTransport2DataType */ +static UA_INLINE void +UA_DatagramWriterGroupTransport2DataType_init(UA_DatagramWriterGroupTransport2DataType *p) { + memset(p, 0, sizeof(UA_DatagramWriterGroupTransport2DataType)); +} + +static UA_INLINE UA_DatagramWriterGroupTransport2DataType * +UA_DatagramWriterGroupTransport2DataType_new(void) { + return (UA_DatagramWriterGroupTransport2DataType*)UA_new(&UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_DatagramWriterGroupTransport2DataType_copy(const UA_DatagramWriterGroupTransport2DataType *src, UA_DatagramWriterGroupTransport2DataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DatagramWriterGroupTransport2DataType_deleteMembers(UA_DatagramWriterGroupTransport2DataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE]); +} + +static UA_INLINE void +UA_DatagramWriterGroupTransport2DataType_clear(UA_DatagramWriterGroupTransport2DataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE]); +} + +static UA_INLINE void +UA_DatagramWriterGroupTransport2DataType_delete(UA_DatagramWriterGroupTransport2DataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE]); +}static UA_INLINE UA_Boolean +UA_DatagramWriterGroupTransport2DataType_equal(const UA_DatagramWriterGroupTransport2DataType *p1, const UA_DatagramWriterGroupTransport2DataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATAGRAMWRITERGROUPTRANSPORT2DATATYPE]) == UA_ORDER_EQ); +} + + + +/* DatagramDataSetReaderTransportDataType */ +static UA_INLINE void +UA_DatagramDataSetReaderTransportDataType_init(UA_DatagramDataSetReaderTransportDataType *p) { + memset(p, 0, sizeof(UA_DatagramDataSetReaderTransportDataType)); +} + +static UA_INLINE UA_DatagramDataSetReaderTransportDataType * +UA_DatagramDataSetReaderTransportDataType_new(void) { + return (UA_DatagramDataSetReaderTransportDataType*)UA_new(&UA_TYPES[UA_TYPES_DATAGRAMDATASETREADERTRANSPORTDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_DatagramDataSetReaderTransportDataType_copy(const UA_DatagramDataSetReaderTransportDataType *src, UA_DatagramDataSetReaderTransportDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATAGRAMDATASETREADERTRANSPORTDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DatagramDataSetReaderTransportDataType_deleteMembers(UA_DatagramDataSetReaderTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATAGRAMDATASETREADERTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_DatagramDataSetReaderTransportDataType_clear(UA_DatagramDataSetReaderTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATAGRAMDATASETREADERTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_DatagramDataSetReaderTransportDataType_delete(UA_DatagramDataSetReaderTransportDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATAGRAMDATASETREADERTRANSPORTDATATYPE]); +}static UA_INLINE UA_Boolean +UA_DatagramDataSetReaderTransportDataType_equal(const UA_DatagramDataSetReaderTransportDataType *p1, const UA_DatagramDataSetReaderTransportDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATAGRAMDATASETREADERTRANSPORTDATATYPE]) == UA_ORDER_EQ); +} + + + +/* BrokerConnectionTransportDataType */ +static UA_INLINE void +UA_BrokerConnectionTransportDataType_init(UA_BrokerConnectionTransportDataType *p) { + memset(p, 0, sizeof(UA_BrokerConnectionTransportDataType)); +} + +static UA_INLINE UA_BrokerConnectionTransportDataType * +UA_BrokerConnectionTransportDataType_new(void) { + return (UA_BrokerConnectionTransportDataType*)UA_new(&UA_TYPES[UA_TYPES_BROKERCONNECTIONTRANSPORTDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_BrokerConnectionTransportDataType_copy(const UA_BrokerConnectionTransportDataType *src, UA_BrokerConnectionTransportDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROKERCONNECTIONTRANSPORTDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrokerConnectionTransportDataType_deleteMembers(UA_BrokerConnectionTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROKERCONNECTIONTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_BrokerConnectionTransportDataType_clear(UA_BrokerConnectionTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROKERCONNECTIONTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_BrokerConnectionTransportDataType_delete(UA_BrokerConnectionTransportDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROKERCONNECTIONTRANSPORTDATATYPE]); +}static UA_INLINE UA_Boolean +UA_BrokerConnectionTransportDataType_equal(const UA_BrokerConnectionTransportDataType *p1, const UA_BrokerConnectionTransportDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROKERCONNECTIONTRANSPORTDATATYPE]) == UA_ORDER_EQ); +} + + + +/* BrokerTransportQualityOfService */ +static UA_INLINE void +UA_BrokerTransportQualityOfService_init(UA_BrokerTransportQualityOfService *p) { + memset(p, 0, sizeof(UA_BrokerTransportQualityOfService)); +} + +static UA_INLINE UA_BrokerTransportQualityOfService * +UA_BrokerTransportQualityOfService_new(void) { + return (UA_BrokerTransportQualityOfService*)UA_new(&UA_TYPES[UA_TYPES_BROKERTRANSPORTQUALITYOFSERVICE]); +} + +static UA_INLINE UA_StatusCode +UA_BrokerTransportQualityOfService_copy(const UA_BrokerTransportQualityOfService *src, UA_BrokerTransportQualityOfService *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROKERTRANSPORTQUALITYOFSERVICE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrokerTransportQualityOfService_deleteMembers(UA_BrokerTransportQualityOfService *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROKERTRANSPORTQUALITYOFSERVICE]); +} + +static UA_INLINE void +UA_BrokerTransportQualityOfService_clear(UA_BrokerTransportQualityOfService *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROKERTRANSPORTQUALITYOFSERVICE]); +} + +static UA_INLINE void +UA_BrokerTransportQualityOfService_delete(UA_BrokerTransportQualityOfService *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROKERTRANSPORTQUALITYOFSERVICE]); +}static UA_INLINE UA_Boolean +UA_BrokerTransportQualityOfService_equal(const UA_BrokerTransportQualityOfService *p1, const UA_BrokerTransportQualityOfService *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROKERTRANSPORTQUALITYOFSERVICE]) == UA_ORDER_EQ); +} + + + +/* BrokerWriterGroupTransportDataType */ +static UA_INLINE void +UA_BrokerWriterGroupTransportDataType_init(UA_BrokerWriterGroupTransportDataType *p) { + memset(p, 0, sizeof(UA_BrokerWriterGroupTransportDataType)); +} + +static UA_INLINE UA_BrokerWriterGroupTransportDataType * +UA_BrokerWriterGroupTransportDataType_new(void) { + return (UA_BrokerWriterGroupTransportDataType*)UA_new(&UA_TYPES[UA_TYPES_BROKERWRITERGROUPTRANSPORTDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_BrokerWriterGroupTransportDataType_copy(const UA_BrokerWriterGroupTransportDataType *src, UA_BrokerWriterGroupTransportDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROKERWRITERGROUPTRANSPORTDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrokerWriterGroupTransportDataType_deleteMembers(UA_BrokerWriterGroupTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROKERWRITERGROUPTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_BrokerWriterGroupTransportDataType_clear(UA_BrokerWriterGroupTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROKERWRITERGROUPTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_BrokerWriterGroupTransportDataType_delete(UA_BrokerWriterGroupTransportDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROKERWRITERGROUPTRANSPORTDATATYPE]); +}static UA_INLINE UA_Boolean +UA_BrokerWriterGroupTransportDataType_equal(const UA_BrokerWriterGroupTransportDataType *p1, const UA_BrokerWriterGroupTransportDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROKERWRITERGROUPTRANSPORTDATATYPE]) == UA_ORDER_EQ); +} + + + +/* BrokerDataSetWriterTransportDataType */ +static UA_INLINE void +UA_BrokerDataSetWriterTransportDataType_init(UA_BrokerDataSetWriterTransportDataType *p) { + memset(p, 0, sizeof(UA_BrokerDataSetWriterTransportDataType)); +} + +static UA_INLINE UA_BrokerDataSetWriterTransportDataType * +UA_BrokerDataSetWriterTransportDataType_new(void) { + return (UA_BrokerDataSetWriterTransportDataType*)UA_new(&UA_TYPES[UA_TYPES_BROKERDATASETWRITERTRANSPORTDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_BrokerDataSetWriterTransportDataType_copy(const UA_BrokerDataSetWriterTransportDataType *src, UA_BrokerDataSetWriterTransportDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROKERDATASETWRITERTRANSPORTDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrokerDataSetWriterTransportDataType_deleteMembers(UA_BrokerDataSetWriterTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROKERDATASETWRITERTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_BrokerDataSetWriterTransportDataType_clear(UA_BrokerDataSetWriterTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROKERDATASETWRITERTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_BrokerDataSetWriterTransportDataType_delete(UA_BrokerDataSetWriterTransportDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROKERDATASETWRITERTRANSPORTDATATYPE]); +}static UA_INLINE UA_Boolean +UA_BrokerDataSetWriterTransportDataType_equal(const UA_BrokerDataSetWriterTransportDataType *p1, const UA_BrokerDataSetWriterTransportDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROKERDATASETWRITERTRANSPORTDATATYPE]) == UA_ORDER_EQ); +} + + + +/* BrokerDataSetReaderTransportDataType */ +static UA_INLINE void +UA_BrokerDataSetReaderTransportDataType_init(UA_BrokerDataSetReaderTransportDataType *p) { + memset(p, 0, sizeof(UA_BrokerDataSetReaderTransportDataType)); +} + +static UA_INLINE UA_BrokerDataSetReaderTransportDataType * +UA_BrokerDataSetReaderTransportDataType_new(void) { + return (UA_BrokerDataSetReaderTransportDataType*)UA_new(&UA_TYPES[UA_TYPES_BROKERDATASETREADERTRANSPORTDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_BrokerDataSetReaderTransportDataType_copy(const UA_BrokerDataSetReaderTransportDataType *src, UA_BrokerDataSetReaderTransportDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROKERDATASETREADERTRANSPORTDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrokerDataSetReaderTransportDataType_deleteMembers(UA_BrokerDataSetReaderTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROKERDATASETREADERTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_BrokerDataSetReaderTransportDataType_clear(UA_BrokerDataSetReaderTransportDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROKERDATASETREADERTRANSPORTDATATYPE]); +} + +static UA_INLINE void +UA_BrokerDataSetReaderTransportDataType_delete(UA_BrokerDataSetReaderTransportDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROKERDATASETREADERTRANSPORTDATATYPE]); +}static UA_INLINE UA_Boolean +UA_BrokerDataSetReaderTransportDataType_equal(const UA_BrokerDataSetReaderTransportDataType *p1, const UA_BrokerDataSetReaderTransportDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROKERDATASETREADERTRANSPORTDATATYPE]) == UA_ORDER_EQ); +} + + + +/* PubSubConfigurationRefMask */ +static UA_INLINE void +UA_PubSubConfigurationRefMask_init(UA_PubSubConfigurationRefMask *p) { + memset(p, 0, sizeof(UA_PubSubConfigurationRefMask)); +} + +static UA_INLINE UA_PubSubConfigurationRefMask * +UA_PubSubConfigurationRefMask_new(void) { + return (UA_PubSubConfigurationRefMask*)UA_new(&UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFMASK]); +} + +static UA_INLINE UA_StatusCode +UA_PubSubConfigurationRefMask_copy(const UA_PubSubConfigurationRefMask *src, UA_PubSubConfigurationRefMask *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFMASK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PubSubConfigurationRefMask_deleteMembers(UA_PubSubConfigurationRefMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFMASK]); +} + +static UA_INLINE void +UA_PubSubConfigurationRefMask_clear(UA_PubSubConfigurationRefMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFMASK]); +} + +static UA_INLINE void +UA_PubSubConfigurationRefMask_delete(UA_PubSubConfigurationRefMask *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFMASK]); +}static UA_INLINE UA_Boolean +UA_PubSubConfigurationRefMask_equal(const UA_PubSubConfigurationRefMask *p1, const UA_PubSubConfigurationRefMask *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFMASK]) == UA_ORDER_EQ); +} + + + +/* PubSubConfigurationRefDataType */ +static UA_INLINE void +UA_PubSubConfigurationRefDataType_init(UA_PubSubConfigurationRefDataType *p) { + memset(p, 0, sizeof(UA_PubSubConfigurationRefDataType)); +} + +static UA_INLINE UA_PubSubConfigurationRefDataType * +UA_PubSubConfigurationRefDataType_new(void) { + return (UA_PubSubConfigurationRefDataType*)UA_new(&UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PubSubConfigurationRefDataType_copy(const UA_PubSubConfigurationRefDataType *src, UA_PubSubConfigurationRefDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PubSubConfigurationRefDataType_deleteMembers(UA_PubSubConfigurationRefDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFDATATYPE]); +} + +static UA_INLINE void +UA_PubSubConfigurationRefDataType_clear(UA_PubSubConfigurationRefDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFDATATYPE]); +} + +static UA_INLINE void +UA_PubSubConfigurationRefDataType_delete(UA_PubSubConfigurationRefDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFDATATYPE]); +}static UA_INLINE UA_Boolean +UA_PubSubConfigurationRefDataType_equal(const UA_PubSubConfigurationRefDataType *p1, const UA_PubSubConfigurationRefDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONREFDATATYPE]) == UA_ORDER_EQ); +} + + + +/* PubSubConfigurationValueDataType */ +static UA_INLINE void +UA_PubSubConfigurationValueDataType_init(UA_PubSubConfigurationValueDataType *p) { + memset(p, 0, sizeof(UA_PubSubConfigurationValueDataType)); +} + +static UA_INLINE UA_PubSubConfigurationValueDataType * +UA_PubSubConfigurationValueDataType_new(void) { + return (UA_PubSubConfigurationValueDataType*)UA_new(&UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONVALUEDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PubSubConfigurationValueDataType_copy(const UA_PubSubConfigurationValueDataType *src, UA_PubSubConfigurationValueDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONVALUEDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PubSubConfigurationValueDataType_deleteMembers(UA_PubSubConfigurationValueDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONVALUEDATATYPE]); +} + +static UA_INLINE void +UA_PubSubConfigurationValueDataType_clear(UA_PubSubConfigurationValueDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONVALUEDATATYPE]); +} + +static UA_INLINE void +UA_PubSubConfigurationValueDataType_delete(UA_PubSubConfigurationValueDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONVALUEDATATYPE]); +}static UA_INLINE UA_Boolean +UA_PubSubConfigurationValueDataType_equal(const UA_PubSubConfigurationValueDataType *p1, const UA_PubSubConfigurationValueDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONVALUEDATATYPE]) == UA_ORDER_EQ); +} + + + +/* DiagnosticsLevel */ +static UA_INLINE void +UA_DiagnosticsLevel_init(UA_DiagnosticsLevel *p) { + memset(p, 0, sizeof(UA_DiagnosticsLevel)); +} + +static UA_INLINE UA_DiagnosticsLevel * +UA_DiagnosticsLevel_new(void) { + return (UA_DiagnosticsLevel*)UA_new(&UA_TYPES[UA_TYPES_DIAGNOSTICSLEVEL]); +} + +static UA_INLINE UA_StatusCode +UA_DiagnosticsLevel_copy(const UA_DiagnosticsLevel *src, UA_DiagnosticsLevel *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DIAGNOSTICSLEVEL]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DiagnosticsLevel_deleteMembers(UA_DiagnosticsLevel *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DIAGNOSTICSLEVEL]); +} + +static UA_INLINE void +UA_DiagnosticsLevel_clear(UA_DiagnosticsLevel *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DIAGNOSTICSLEVEL]); +} + +static UA_INLINE void +UA_DiagnosticsLevel_delete(UA_DiagnosticsLevel *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DIAGNOSTICSLEVEL]); +}static UA_INLINE UA_Boolean +UA_DiagnosticsLevel_equal(const UA_DiagnosticsLevel *p1, const UA_DiagnosticsLevel *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DIAGNOSTICSLEVEL]) == UA_ORDER_EQ); +} + + + +/* PubSubDiagnosticsCounterClassification */ +static UA_INLINE void +UA_PubSubDiagnosticsCounterClassification_init(UA_PubSubDiagnosticsCounterClassification *p) { + memset(p, 0, sizeof(UA_PubSubDiagnosticsCounterClassification)); +} + +static UA_INLINE UA_PubSubDiagnosticsCounterClassification * +UA_PubSubDiagnosticsCounterClassification_new(void) { + return (UA_PubSubDiagnosticsCounterClassification*)UA_new(&UA_TYPES[UA_TYPES_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION]); +} + +static UA_INLINE UA_StatusCode +UA_PubSubDiagnosticsCounterClassification_copy(const UA_PubSubDiagnosticsCounterClassification *src, UA_PubSubDiagnosticsCounterClassification *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PubSubDiagnosticsCounterClassification_deleteMembers(UA_PubSubDiagnosticsCounterClassification *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION]); +} + +static UA_INLINE void +UA_PubSubDiagnosticsCounterClassification_clear(UA_PubSubDiagnosticsCounterClassification *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION]); +} + +static UA_INLINE void +UA_PubSubDiagnosticsCounterClassification_delete(UA_PubSubDiagnosticsCounterClassification *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION]); +}static UA_INLINE UA_Boolean +UA_PubSubDiagnosticsCounterClassification_equal(const UA_PubSubDiagnosticsCounterClassification *p1, const UA_PubSubDiagnosticsCounterClassification *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBSUBDIAGNOSTICSCOUNTERCLASSIFICATION]) == UA_ORDER_EQ); +} + + + +/* AliasNameDataType */ +static UA_INLINE void +UA_AliasNameDataType_init(UA_AliasNameDataType *p) { + memset(p, 0, sizeof(UA_AliasNameDataType)); +} + +static UA_INLINE UA_AliasNameDataType * +UA_AliasNameDataType_new(void) { + return (UA_AliasNameDataType*)UA_new(&UA_TYPES[UA_TYPES_ALIASNAMEDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_AliasNameDataType_copy(const UA_AliasNameDataType *src, UA_AliasNameDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ALIASNAMEDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AliasNameDataType_deleteMembers(UA_AliasNameDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ALIASNAMEDATATYPE]); +} + +static UA_INLINE void +UA_AliasNameDataType_clear(UA_AliasNameDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ALIASNAMEDATATYPE]); +} + +static UA_INLINE void +UA_AliasNameDataType_delete(UA_AliasNameDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ALIASNAMEDATATYPE]); +}static UA_INLINE UA_Boolean +UA_AliasNameDataType_equal(const UA_AliasNameDataType *p1, const UA_AliasNameDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ALIASNAMEDATATYPE]) == UA_ORDER_EQ); +} + + + +/* PasswordOptionsMask */ +static UA_INLINE void +UA_PasswordOptionsMask_init(UA_PasswordOptionsMask *p) { + memset(p, 0, sizeof(UA_PasswordOptionsMask)); +} + +static UA_INLINE UA_PasswordOptionsMask * +UA_PasswordOptionsMask_new(void) { + return (UA_PasswordOptionsMask*)UA_new(&UA_TYPES[UA_TYPES_PASSWORDOPTIONSMASK]); +} + +static UA_INLINE UA_StatusCode +UA_PasswordOptionsMask_copy(const UA_PasswordOptionsMask *src, UA_PasswordOptionsMask *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PASSWORDOPTIONSMASK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PasswordOptionsMask_deleteMembers(UA_PasswordOptionsMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PASSWORDOPTIONSMASK]); +} + +static UA_INLINE void +UA_PasswordOptionsMask_clear(UA_PasswordOptionsMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PASSWORDOPTIONSMASK]); +} + +static UA_INLINE void +UA_PasswordOptionsMask_delete(UA_PasswordOptionsMask *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PASSWORDOPTIONSMASK]); +}static UA_INLINE UA_Boolean +UA_PasswordOptionsMask_equal(const UA_PasswordOptionsMask *p1, const UA_PasswordOptionsMask *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PASSWORDOPTIONSMASK]) == UA_ORDER_EQ); +} + + + +/* UserConfigurationMask */ +static UA_INLINE void +UA_UserConfigurationMask_init(UA_UserConfigurationMask *p) { + memset(p, 0, sizeof(UA_UserConfigurationMask)); +} + +static UA_INLINE UA_UserConfigurationMask * +UA_UserConfigurationMask_new(void) { + return (UA_UserConfigurationMask*)UA_new(&UA_TYPES[UA_TYPES_USERCONFIGURATIONMASK]); +} + +static UA_INLINE UA_StatusCode +UA_UserConfigurationMask_copy(const UA_UserConfigurationMask *src, UA_UserConfigurationMask *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_USERCONFIGURATIONMASK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UserConfigurationMask_deleteMembers(UA_UserConfigurationMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_USERCONFIGURATIONMASK]); +} + +static UA_INLINE void +UA_UserConfigurationMask_clear(UA_UserConfigurationMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_USERCONFIGURATIONMASK]); +} + +static UA_INLINE void +UA_UserConfigurationMask_delete(UA_UserConfigurationMask *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_USERCONFIGURATIONMASK]); +}static UA_INLINE UA_Boolean +UA_UserConfigurationMask_equal(const UA_UserConfigurationMask *p1, const UA_UserConfigurationMask *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_USERCONFIGURATIONMASK]) == UA_ORDER_EQ); +} + + + +/* UserManagementDataType */ +static UA_INLINE void +UA_UserManagementDataType_init(UA_UserManagementDataType *p) { + memset(p, 0, sizeof(UA_UserManagementDataType)); +} + +static UA_INLINE UA_UserManagementDataType * +UA_UserManagementDataType_new(void) { + return (UA_UserManagementDataType*)UA_new(&UA_TYPES[UA_TYPES_USERMANAGEMENTDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_UserManagementDataType_copy(const UA_UserManagementDataType *src, UA_UserManagementDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_USERMANAGEMENTDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UserManagementDataType_deleteMembers(UA_UserManagementDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_USERMANAGEMENTDATATYPE]); +} + +static UA_INLINE void +UA_UserManagementDataType_clear(UA_UserManagementDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_USERMANAGEMENTDATATYPE]); +} + +static UA_INLINE void +UA_UserManagementDataType_delete(UA_UserManagementDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_USERMANAGEMENTDATATYPE]); +}static UA_INLINE UA_Boolean +UA_UserManagementDataType_equal(const UA_UserManagementDataType *p1, const UA_UserManagementDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_USERMANAGEMENTDATATYPE]) == UA_ORDER_EQ); +} + + + +/* Duplex */ +static UA_INLINE void +UA_Duplex_init(UA_Duplex *p) { + memset(p, 0, sizeof(UA_Duplex)); +} + +static UA_INLINE UA_Duplex * +UA_Duplex_new(void) { + return (UA_Duplex*)UA_new(&UA_TYPES[UA_TYPES_DUPLEX]); +} + +static UA_INLINE UA_StatusCode +UA_Duplex_copy(const UA_Duplex *src, UA_Duplex *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DUPLEX]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Duplex_deleteMembers(UA_Duplex *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DUPLEX]); +} + +static UA_INLINE void +UA_Duplex_clear(UA_Duplex *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DUPLEX]); +} + +static UA_INLINE void +UA_Duplex_delete(UA_Duplex *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DUPLEX]); +}static UA_INLINE UA_Boolean +UA_Duplex_equal(const UA_Duplex *p1, const UA_Duplex *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DUPLEX]) == UA_ORDER_EQ); +} + + + +/* InterfaceAdminStatus */ +static UA_INLINE void +UA_InterfaceAdminStatus_init(UA_InterfaceAdminStatus *p) { + memset(p, 0, sizeof(UA_InterfaceAdminStatus)); +} + +static UA_INLINE UA_InterfaceAdminStatus * +UA_InterfaceAdminStatus_new(void) { + return (UA_InterfaceAdminStatus*)UA_new(&UA_TYPES[UA_TYPES_INTERFACEADMINSTATUS]); +} + +static UA_INLINE UA_StatusCode +UA_InterfaceAdminStatus_copy(const UA_InterfaceAdminStatus *src, UA_InterfaceAdminStatus *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_INTERFACEADMINSTATUS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_InterfaceAdminStatus_deleteMembers(UA_InterfaceAdminStatus *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INTERFACEADMINSTATUS]); +} + +static UA_INLINE void +UA_InterfaceAdminStatus_clear(UA_InterfaceAdminStatus *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INTERFACEADMINSTATUS]); +} + +static UA_INLINE void +UA_InterfaceAdminStatus_delete(UA_InterfaceAdminStatus *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_INTERFACEADMINSTATUS]); +}static UA_INLINE UA_Boolean +UA_InterfaceAdminStatus_equal(const UA_InterfaceAdminStatus *p1, const UA_InterfaceAdminStatus *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_INTERFACEADMINSTATUS]) == UA_ORDER_EQ); +} + + + +/* InterfaceOperStatus */ +static UA_INLINE void +UA_InterfaceOperStatus_init(UA_InterfaceOperStatus *p) { + memset(p, 0, sizeof(UA_InterfaceOperStatus)); +} + +static UA_INLINE UA_InterfaceOperStatus * +UA_InterfaceOperStatus_new(void) { + return (UA_InterfaceOperStatus*)UA_new(&UA_TYPES[UA_TYPES_INTERFACEOPERSTATUS]); +} + +static UA_INLINE UA_StatusCode +UA_InterfaceOperStatus_copy(const UA_InterfaceOperStatus *src, UA_InterfaceOperStatus *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_INTERFACEOPERSTATUS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_InterfaceOperStatus_deleteMembers(UA_InterfaceOperStatus *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INTERFACEOPERSTATUS]); +} + +static UA_INLINE void +UA_InterfaceOperStatus_clear(UA_InterfaceOperStatus *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INTERFACEOPERSTATUS]); +} + +static UA_INLINE void +UA_InterfaceOperStatus_delete(UA_InterfaceOperStatus *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_INTERFACEOPERSTATUS]); +}static UA_INLINE UA_Boolean +UA_InterfaceOperStatus_equal(const UA_InterfaceOperStatus *p1, const UA_InterfaceOperStatus *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_INTERFACEOPERSTATUS]) == UA_ORDER_EQ); +} + + + +/* NegotiationStatus */ +static UA_INLINE void +UA_NegotiationStatus_init(UA_NegotiationStatus *p) { + memset(p, 0, sizeof(UA_NegotiationStatus)); +} + +static UA_INLINE UA_NegotiationStatus * +UA_NegotiationStatus_new(void) { + return (UA_NegotiationStatus*)UA_new(&UA_TYPES[UA_TYPES_NEGOTIATIONSTATUS]); +} + +static UA_INLINE UA_StatusCode +UA_NegotiationStatus_copy(const UA_NegotiationStatus *src, UA_NegotiationStatus *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NEGOTIATIONSTATUS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NegotiationStatus_deleteMembers(UA_NegotiationStatus *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NEGOTIATIONSTATUS]); +} + +static UA_INLINE void +UA_NegotiationStatus_clear(UA_NegotiationStatus *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NEGOTIATIONSTATUS]); +} + +static UA_INLINE void +UA_NegotiationStatus_delete(UA_NegotiationStatus *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NEGOTIATIONSTATUS]); +}static UA_INLINE UA_Boolean +UA_NegotiationStatus_equal(const UA_NegotiationStatus *p1, const UA_NegotiationStatus *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NEGOTIATIONSTATUS]) == UA_ORDER_EQ); +} + + + +/* TsnFailureCode */ +static UA_INLINE void +UA_TsnFailureCode_init(UA_TsnFailureCode *p) { + memset(p, 0, sizeof(UA_TsnFailureCode)); +} + +static UA_INLINE UA_TsnFailureCode * +UA_TsnFailureCode_new(void) { + return (UA_TsnFailureCode*)UA_new(&UA_TYPES[UA_TYPES_TSNFAILURECODE]); +} + +static UA_INLINE UA_StatusCode +UA_TsnFailureCode_copy(const UA_TsnFailureCode *src, UA_TsnFailureCode *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TSNFAILURECODE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TsnFailureCode_deleteMembers(UA_TsnFailureCode *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TSNFAILURECODE]); +} + +static UA_INLINE void +UA_TsnFailureCode_clear(UA_TsnFailureCode *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TSNFAILURECODE]); +} + +static UA_INLINE void +UA_TsnFailureCode_delete(UA_TsnFailureCode *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TSNFAILURECODE]); +}static UA_INLINE UA_Boolean +UA_TsnFailureCode_equal(const UA_TsnFailureCode *p1, const UA_TsnFailureCode *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TSNFAILURECODE]) == UA_ORDER_EQ); +} + + + +/* TsnStreamState */ +static UA_INLINE void +UA_TsnStreamState_init(UA_TsnStreamState *p) { + memset(p, 0, sizeof(UA_TsnStreamState)); +} + +static UA_INLINE UA_TsnStreamState * +UA_TsnStreamState_new(void) { + return (UA_TsnStreamState*)UA_new(&UA_TYPES[UA_TYPES_TSNSTREAMSTATE]); +} + +static UA_INLINE UA_StatusCode +UA_TsnStreamState_copy(const UA_TsnStreamState *src, UA_TsnStreamState *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TSNSTREAMSTATE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TsnStreamState_deleteMembers(UA_TsnStreamState *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TSNSTREAMSTATE]); +} + +static UA_INLINE void +UA_TsnStreamState_clear(UA_TsnStreamState *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TSNSTREAMSTATE]); +} + +static UA_INLINE void +UA_TsnStreamState_delete(UA_TsnStreamState *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TSNSTREAMSTATE]); +}static UA_INLINE UA_Boolean +UA_TsnStreamState_equal(const UA_TsnStreamState *p1, const UA_TsnStreamState *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TSNSTREAMSTATE]) == UA_ORDER_EQ); +} + + + +/* TsnTalkerStatus */ +static UA_INLINE void +UA_TsnTalkerStatus_init(UA_TsnTalkerStatus *p) { + memset(p, 0, sizeof(UA_TsnTalkerStatus)); +} + +static UA_INLINE UA_TsnTalkerStatus * +UA_TsnTalkerStatus_new(void) { + return (UA_TsnTalkerStatus*)UA_new(&UA_TYPES[UA_TYPES_TSNTALKERSTATUS]); +} + +static UA_INLINE UA_StatusCode +UA_TsnTalkerStatus_copy(const UA_TsnTalkerStatus *src, UA_TsnTalkerStatus *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TSNTALKERSTATUS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TsnTalkerStatus_deleteMembers(UA_TsnTalkerStatus *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TSNTALKERSTATUS]); +} + +static UA_INLINE void +UA_TsnTalkerStatus_clear(UA_TsnTalkerStatus *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TSNTALKERSTATUS]); +} + +static UA_INLINE void +UA_TsnTalkerStatus_delete(UA_TsnTalkerStatus *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TSNTALKERSTATUS]); +}static UA_INLINE UA_Boolean +UA_TsnTalkerStatus_equal(const UA_TsnTalkerStatus *p1, const UA_TsnTalkerStatus *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TSNTALKERSTATUS]) == UA_ORDER_EQ); +} + + + +/* TsnListenerStatus */ +static UA_INLINE void +UA_TsnListenerStatus_init(UA_TsnListenerStatus *p) { + memset(p, 0, sizeof(UA_TsnListenerStatus)); +} + +static UA_INLINE UA_TsnListenerStatus * +UA_TsnListenerStatus_new(void) { + return (UA_TsnListenerStatus*)UA_new(&UA_TYPES[UA_TYPES_TSNLISTENERSTATUS]); +} + +static UA_INLINE UA_StatusCode +UA_TsnListenerStatus_copy(const UA_TsnListenerStatus *src, UA_TsnListenerStatus *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TSNLISTENERSTATUS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TsnListenerStatus_deleteMembers(UA_TsnListenerStatus *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TSNLISTENERSTATUS]); +} + +static UA_INLINE void +UA_TsnListenerStatus_clear(UA_TsnListenerStatus *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TSNLISTENERSTATUS]); +} + +static UA_INLINE void +UA_TsnListenerStatus_delete(UA_TsnListenerStatus *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TSNLISTENERSTATUS]); +}static UA_INLINE UA_Boolean +UA_TsnListenerStatus_equal(const UA_TsnListenerStatus *p1, const UA_TsnListenerStatus *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TSNLISTENERSTATUS]) == UA_ORDER_EQ); +} + + + +/* PriorityMappingEntryType */ +static UA_INLINE void +UA_PriorityMappingEntryType_init(UA_PriorityMappingEntryType *p) { + memset(p, 0, sizeof(UA_PriorityMappingEntryType)); +} + +static UA_INLINE UA_PriorityMappingEntryType * +UA_PriorityMappingEntryType_new(void) { + return (UA_PriorityMappingEntryType*)UA_new(&UA_TYPES[UA_TYPES_PRIORITYMAPPINGENTRYTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PriorityMappingEntryType_copy(const UA_PriorityMappingEntryType *src, UA_PriorityMappingEntryType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PRIORITYMAPPINGENTRYTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PriorityMappingEntryType_deleteMembers(UA_PriorityMappingEntryType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PRIORITYMAPPINGENTRYTYPE]); +} + +static UA_INLINE void +UA_PriorityMappingEntryType_clear(UA_PriorityMappingEntryType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PRIORITYMAPPINGENTRYTYPE]); +} + +static UA_INLINE void +UA_PriorityMappingEntryType_delete(UA_PriorityMappingEntryType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PRIORITYMAPPINGENTRYTYPE]); +}static UA_INLINE UA_Boolean +UA_PriorityMappingEntryType_equal(const UA_PriorityMappingEntryType *p1, const UA_PriorityMappingEntryType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PRIORITYMAPPINGENTRYTYPE]) == UA_ORDER_EQ); +} + + + +/* IdType */ +static UA_INLINE void +UA_IdType_init(UA_IdType *p) { + memset(p, 0, sizeof(UA_IdType)); +} + +static UA_INLINE UA_IdType * +UA_IdType_new(void) { + return (UA_IdType*)UA_new(&UA_TYPES[UA_TYPES_IDTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_IdType_copy(const UA_IdType *src, UA_IdType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_IDTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_IdType_deleteMembers(UA_IdType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IDTYPE]); +} + +static UA_INLINE void +UA_IdType_clear(UA_IdType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_IDTYPE]); +} + +static UA_INLINE void +UA_IdType_delete(UA_IdType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_IDTYPE]); +}static UA_INLINE UA_Boolean +UA_IdType_equal(const UA_IdType *p1, const UA_IdType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_IDTYPE]) == UA_ORDER_EQ); +} + + + +/* NodeClass */ +static UA_INLINE void +UA_NodeClass_init(UA_NodeClass *p) { + memset(p, 0, sizeof(UA_NodeClass)); +} + +static UA_INLINE UA_NodeClass * +UA_NodeClass_new(void) { + return (UA_NodeClass*)UA_new(&UA_TYPES[UA_TYPES_NODECLASS]); +} + +static UA_INLINE UA_StatusCode +UA_NodeClass_copy(const UA_NodeClass *src, UA_NodeClass *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NODECLASS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NodeClass_deleteMembers(UA_NodeClass *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NODECLASS]); +} + +static UA_INLINE void +UA_NodeClass_clear(UA_NodeClass *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NODECLASS]); +} + +static UA_INLINE void +UA_NodeClass_delete(UA_NodeClass *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NODECLASS]); +}static UA_INLINE UA_Boolean +UA_NodeClass_equal(const UA_NodeClass *p1, const UA_NodeClass *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NODECLASS]) == UA_ORDER_EQ); +} + + + +/* PermissionType */ +static UA_INLINE void +UA_PermissionType_init(UA_PermissionType *p) { + memset(p, 0, sizeof(UA_PermissionType)); +} + +static UA_INLINE UA_PermissionType * +UA_PermissionType_new(void) { + return (UA_PermissionType*)UA_new(&UA_TYPES[UA_TYPES_PERMISSIONTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PermissionType_copy(const UA_PermissionType *src, UA_PermissionType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PERMISSIONTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PermissionType_deleteMembers(UA_PermissionType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PERMISSIONTYPE]); +} + +static UA_INLINE void +UA_PermissionType_clear(UA_PermissionType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PERMISSIONTYPE]); +} + +static UA_INLINE void +UA_PermissionType_delete(UA_PermissionType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PERMISSIONTYPE]); +}static UA_INLINE UA_Boolean +UA_PermissionType_equal(const UA_PermissionType *p1, const UA_PermissionType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PERMISSIONTYPE]) == UA_ORDER_EQ); +} + + + +/* AccessLevelType */ +static UA_INLINE void +UA_AccessLevelType_init(UA_AccessLevelType *p) { + memset(p, 0, sizeof(UA_AccessLevelType)); +} + +static UA_INLINE UA_AccessLevelType * +UA_AccessLevelType_new(void) { + return (UA_AccessLevelType*)UA_new(&UA_TYPES[UA_TYPES_ACCESSLEVELTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_AccessLevelType_copy(const UA_AccessLevelType *src, UA_AccessLevelType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ACCESSLEVELTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AccessLevelType_deleteMembers(UA_AccessLevelType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ACCESSLEVELTYPE]); +} + +static UA_INLINE void +UA_AccessLevelType_clear(UA_AccessLevelType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ACCESSLEVELTYPE]); +} + +static UA_INLINE void +UA_AccessLevelType_delete(UA_AccessLevelType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ACCESSLEVELTYPE]); +}static UA_INLINE UA_Boolean +UA_AccessLevelType_equal(const UA_AccessLevelType *p1, const UA_AccessLevelType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ACCESSLEVELTYPE]) == UA_ORDER_EQ); +} + + + +/* AccessLevelExType */ +static UA_INLINE void +UA_AccessLevelExType_init(UA_AccessLevelExType *p) { + memset(p, 0, sizeof(UA_AccessLevelExType)); +} + +static UA_INLINE UA_AccessLevelExType * +UA_AccessLevelExType_new(void) { + return (UA_AccessLevelExType*)UA_new(&UA_TYPES[UA_TYPES_ACCESSLEVELEXTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_AccessLevelExType_copy(const UA_AccessLevelExType *src, UA_AccessLevelExType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ACCESSLEVELEXTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AccessLevelExType_deleteMembers(UA_AccessLevelExType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ACCESSLEVELEXTYPE]); +} + +static UA_INLINE void +UA_AccessLevelExType_clear(UA_AccessLevelExType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ACCESSLEVELEXTYPE]); +} + +static UA_INLINE void +UA_AccessLevelExType_delete(UA_AccessLevelExType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ACCESSLEVELEXTYPE]); +}static UA_INLINE UA_Boolean +UA_AccessLevelExType_equal(const UA_AccessLevelExType *p1, const UA_AccessLevelExType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ACCESSLEVELEXTYPE]) == UA_ORDER_EQ); +} + + + +/* EventNotifierType */ +static UA_INLINE void +UA_EventNotifierType_init(UA_EventNotifierType *p) { + memset(p, 0, sizeof(UA_EventNotifierType)); +} + +static UA_INLINE UA_EventNotifierType * +UA_EventNotifierType_new(void) { + return (UA_EventNotifierType*)UA_new(&UA_TYPES[UA_TYPES_EVENTNOTIFIERTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_EventNotifierType_copy(const UA_EventNotifierType *src, UA_EventNotifierType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_EVENTNOTIFIERTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EventNotifierType_deleteMembers(UA_EventNotifierType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EVENTNOTIFIERTYPE]); +} + +static UA_INLINE void +UA_EventNotifierType_clear(UA_EventNotifierType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EVENTNOTIFIERTYPE]); +} + +static UA_INLINE void +UA_EventNotifierType_delete(UA_EventNotifierType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_EVENTNOTIFIERTYPE]); +}static UA_INLINE UA_Boolean +UA_EventNotifierType_equal(const UA_EventNotifierType *p1, const UA_EventNotifierType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_EVENTNOTIFIERTYPE]) == UA_ORDER_EQ); +} + + + +/* AccessRestrictionType */ +static UA_INLINE void +UA_AccessRestrictionType_init(UA_AccessRestrictionType *p) { + memset(p, 0, sizeof(UA_AccessRestrictionType)); +} + +static UA_INLINE UA_AccessRestrictionType * +UA_AccessRestrictionType_new(void) { + return (UA_AccessRestrictionType*)UA_new(&UA_TYPES[UA_TYPES_ACCESSRESTRICTIONTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_AccessRestrictionType_copy(const UA_AccessRestrictionType *src, UA_AccessRestrictionType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ACCESSRESTRICTIONTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AccessRestrictionType_deleteMembers(UA_AccessRestrictionType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ACCESSRESTRICTIONTYPE]); +} + +static UA_INLINE void +UA_AccessRestrictionType_clear(UA_AccessRestrictionType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ACCESSRESTRICTIONTYPE]); +} + +static UA_INLINE void +UA_AccessRestrictionType_delete(UA_AccessRestrictionType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ACCESSRESTRICTIONTYPE]); +}static UA_INLINE UA_Boolean +UA_AccessRestrictionType_equal(const UA_AccessRestrictionType *p1, const UA_AccessRestrictionType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ACCESSRESTRICTIONTYPE]) == UA_ORDER_EQ); +} + + + +/* RolePermissionType */ +static UA_INLINE void +UA_RolePermissionType_init(UA_RolePermissionType *p) { + memset(p, 0, sizeof(UA_RolePermissionType)); +} + +static UA_INLINE UA_RolePermissionType * +UA_RolePermissionType_new(void) { + return (UA_RolePermissionType*)UA_new(&UA_TYPES[UA_TYPES_ROLEPERMISSIONTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_RolePermissionType_copy(const UA_RolePermissionType *src, UA_RolePermissionType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ROLEPERMISSIONTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RolePermissionType_deleteMembers(UA_RolePermissionType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ROLEPERMISSIONTYPE]); +} + +static UA_INLINE void +UA_RolePermissionType_clear(UA_RolePermissionType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ROLEPERMISSIONTYPE]); +} + +static UA_INLINE void +UA_RolePermissionType_delete(UA_RolePermissionType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ROLEPERMISSIONTYPE]); +}static UA_INLINE UA_Boolean +UA_RolePermissionType_equal(const UA_RolePermissionType *p1, const UA_RolePermissionType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ROLEPERMISSIONTYPE]) == UA_ORDER_EQ); +} + + + +/* StructureType */ +static UA_INLINE void +UA_StructureType_init(UA_StructureType *p) { + memset(p, 0, sizeof(UA_StructureType)); +} + +static UA_INLINE UA_StructureType * +UA_StructureType_new(void) { + return (UA_StructureType*)UA_new(&UA_TYPES[UA_TYPES_STRUCTURETYPE]); +} + +static UA_INLINE UA_StatusCode +UA_StructureType_copy(const UA_StructureType *src, UA_StructureType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_STRUCTURETYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_StructureType_deleteMembers(UA_StructureType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STRUCTURETYPE]); +} + +static UA_INLINE void +UA_StructureType_clear(UA_StructureType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STRUCTURETYPE]); +} + +static UA_INLINE void +UA_StructureType_delete(UA_StructureType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_STRUCTURETYPE]); +}static UA_INLINE UA_Boolean +UA_StructureType_equal(const UA_StructureType *p1, const UA_StructureType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_STRUCTURETYPE]) == UA_ORDER_EQ); +} + + + +/* StructureField */ +static UA_INLINE void +UA_StructureField_init(UA_StructureField *p) { + memset(p, 0, sizeof(UA_StructureField)); +} + +static UA_INLINE UA_StructureField * +UA_StructureField_new(void) { + return (UA_StructureField*)UA_new(&UA_TYPES[UA_TYPES_STRUCTUREFIELD]); +} + +static UA_INLINE UA_StatusCode +UA_StructureField_copy(const UA_StructureField *src, UA_StructureField *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_STRUCTUREFIELD]); +} + +UA_DEPRECATED static UA_INLINE void +UA_StructureField_deleteMembers(UA_StructureField *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STRUCTUREFIELD]); +} + +static UA_INLINE void +UA_StructureField_clear(UA_StructureField *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STRUCTUREFIELD]); +} + +static UA_INLINE void +UA_StructureField_delete(UA_StructureField *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_STRUCTUREFIELD]); +}static UA_INLINE UA_Boolean +UA_StructureField_equal(const UA_StructureField *p1, const UA_StructureField *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_STRUCTUREFIELD]) == UA_ORDER_EQ); +} + + + +/* StructureDefinition */ +static UA_INLINE void +UA_StructureDefinition_init(UA_StructureDefinition *p) { + memset(p, 0, sizeof(UA_StructureDefinition)); +} + +static UA_INLINE UA_StructureDefinition * +UA_StructureDefinition_new(void) { + return (UA_StructureDefinition*)UA_new(&UA_TYPES[UA_TYPES_STRUCTUREDEFINITION]); +} + +static UA_INLINE UA_StatusCode +UA_StructureDefinition_copy(const UA_StructureDefinition *src, UA_StructureDefinition *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_STRUCTUREDEFINITION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_StructureDefinition_deleteMembers(UA_StructureDefinition *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STRUCTUREDEFINITION]); +} + +static UA_INLINE void +UA_StructureDefinition_clear(UA_StructureDefinition *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STRUCTUREDEFINITION]); +} + +static UA_INLINE void +UA_StructureDefinition_delete(UA_StructureDefinition *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_STRUCTUREDEFINITION]); +}static UA_INLINE UA_Boolean +UA_StructureDefinition_equal(const UA_StructureDefinition *p1, const UA_StructureDefinition *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_STRUCTUREDEFINITION]) == UA_ORDER_EQ); +} + + + +/* ReferenceNode */ +static UA_INLINE void +UA_ReferenceNode_init(UA_ReferenceNode *p) { + memset(p, 0, sizeof(UA_ReferenceNode)); +} + +static UA_INLINE UA_ReferenceNode * +UA_ReferenceNode_new(void) { + return (UA_ReferenceNode*)UA_new(&UA_TYPES[UA_TYPES_REFERENCENODE]); +} + +static UA_INLINE UA_StatusCode +UA_ReferenceNode_copy(const UA_ReferenceNode *src, UA_ReferenceNode *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REFERENCENODE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReferenceNode_deleteMembers(UA_ReferenceNode *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REFERENCENODE]); +} + +static UA_INLINE void +UA_ReferenceNode_clear(UA_ReferenceNode *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REFERENCENODE]); +} + +static UA_INLINE void +UA_ReferenceNode_delete(UA_ReferenceNode *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REFERENCENODE]); +}static UA_INLINE UA_Boolean +UA_ReferenceNode_equal(const UA_ReferenceNode *p1, const UA_ReferenceNode *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REFERENCENODE]) == UA_ORDER_EQ); +} + + + +/* Argument */ +static UA_INLINE void +UA_Argument_init(UA_Argument *p) { + memset(p, 0, sizeof(UA_Argument)); +} + +static UA_INLINE UA_Argument * +UA_Argument_new(void) { + return (UA_Argument*)UA_new(&UA_TYPES[UA_TYPES_ARGUMENT]); +} + +static UA_INLINE UA_StatusCode +UA_Argument_copy(const UA_Argument *src, UA_Argument *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ARGUMENT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Argument_deleteMembers(UA_Argument *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ARGUMENT]); +} + +static UA_INLINE void +UA_Argument_clear(UA_Argument *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ARGUMENT]); +} + +static UA_INLINE void +UA_Argument_delete(UA_Argument *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ARGUMENT]); +}static UA_INLINE UA_Boolean +UA_Argument_equal(const UA_Argument *p1, const UA_Argument *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ARGUMENT]) == UA_ORDER_EQ); +} + + + +/* EnumValueType */ +static UA_INLINE void +UA_EnumValueType_init(UA_EnumValueType *p) { + memset(p, 0, sizeof(UA_EnumValueType)); +} + +static UA_INLINE UA_EnumValueType * +UA_EnumValueType_new(void) { + return (UA_EnumValueType*)UA_new(&UA_TYPES[UA_TYPES_ENUMVALUETYPE]); +} + +static UA_INLINE UA_StatusCode +UA_EnumValueType_copy(const UA_EnumValueType *src, UA_EnumValueType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ENUMVALUETYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EnumValueType_deleteMembers(UA_EnumValueType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENUMVALUETYPE]); +} + +static UA_INLINE void +UA_EnumValueType_clear(UA_EnumValueType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENUMVALUETYPE]); +} + +static UA_INLINE void +UA_EnumValueType_delete(UA_EnumValueType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ENUMVALUETYPE]); +}static UA_INLINE UA_Boolean +UA_EnumValueType_equal(const UA_EnumValueType *p1, const UA_EnumValueType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ENUMVALUETYPE]) == UA_ORDER_EQ); +} + + + +/* EnumField */ +static UA_INLINE void +UA_EnumField_init(UA_EnumField *p) { + memset(p, 0, sizeof(UA_EnumField)); +} + +static UA_INLINE UA_EnumField * +UA_EnumField_new(void) { + return (UA_EnumField*)UA_new(&UA_TYPES[UA_TYPES_ENUMFIELD]); +} + +static UA_INLINE UA_StatusCode +UA_EnumField_copy(const UA_EnumField *src, UA_EnumField *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ENUMFIELD]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EnumField_deleteMembers(UA_EnumField *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENUMFIELD]); +} + +static UA_INLINE void +UA_EnumField_clear(UA_EnumField *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENUMFIELD]); +} + +static UA_INLINE void +UA_EnumField_delete(UA_EnumField *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ENUMFIELD]); +}static UA_INLINE UA_Boolean +UA_EnumField_equal(const UA_EnumField *p1, const UA_EnumField *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ENUMFIELD]) == UA_ORDER_EQ); +} + + + +/* OptionSet */ +static UA_INLINE void +UA_OptionSet_init(UA_OptionSet *p) { + memset(p, 0, sizeof(UA_OptionSet)); +} + +static UA_INLINE UA_OptionSet * +UA_OptionSet_new(void) { + return (UA_OptionSet*)UA_new(&UA_TYPES[UA_TYPES_OPTIONSET]); +} + +static UA_INLINE UA_StatusCode +UA_OptionSet_copy(const UA_OptionSet *src, UA_OptionSet *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_OPTIONSET]); +} + +UA_DEPRECATED static UA_INLINE void +UA_OptionSet_deleteMembers(UA_OptionSet *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OPTIONSET]); +} + +static UA_INLINE void +UA_OptionSet_clear(UA_OptionSet *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OPTIONSET]); +} + +static UA_INLINE void +UA_OptionSet_delete(UA_OptionSet *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_OPTIONSET]); +}static UA_INLINE UA_Boolean +UA_OptionSet_equal(const UA_OptionSet *p1, const UA_OptionSet *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_OPTIONSET]) == UA_ORDER_EQ); +} + + + +/* NormalizedString */ +static UA_INLINE void +UA_NormalizedString_init(UA_NormalizedString *p) { + memset(p, 0, sizeof(UA_NormalizedString)); +} + +static UA_INLINE UA_NormalizedString * +UA_NormalizedString_new(void) { + return (UA_NormalizedString*)UA_new(&UA_TYPES[UA_TYPES_NORMALIZEDSTRING]); +} + +static UA_INLINE UA_StatusCode +UA_NormalizedString_copy(const UA_NormalizedString *src, UA_NormalizedString *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NORMALIZEDSTRING]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NormalizedString_deleteMembers(UA_NormalizedString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NORMALIZEDSTRING]); +} + +static UA_INLINE void +UA_NormalizedString_clear(UA_NormalizedString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NORMALIZEDSTRING]); +} + +static UA_INLINE void +UA_NormalizedString_delete(UA_NormalizedString *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NORMALIZEDSTRING]); +}static UA_INLINE UA_Boolean +UA_NormalizedString_equal(const UA_NormalizedString *p1, const UA_NormalizedString *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NORMALIZEDSTRING]) == UA_ORDER_EQ); +} + + + +/* DecimalString */ +static UA_INLINE void +UA_DecimalString_init(UA_DecimalString *p) { + memset(p, 0, sizeof(UA_DecimalString)); +} + +static UA_INLINE UA_DecimalString * +UA_DecimalString_new(void) { + return (UA_DecimalString*)UA_new(&UA_TYPES[UA_TYPES_DECIMALSTRING]); +} + +static UA_INLINE UA_StatusCode +UA_DecimalString_copy(const UA_DecimalString *src, UA_DecimalString *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DECIMALSTRING]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DecimalString_deleteMembers(UA_DecimalString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DECIMALSTRING]); +} + +static UA_INLINE void +UA_DecimalString_clear(UA_DecimalString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DECIMALSTRING]); +} + +static UA_INLINE void +UA_DecimalString_delete(UA_DecimalString *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DECIMALSTRING]); +}static UA_INLINE UA_Boolean +UA_DecimalString_equal(const UA_DecimalString *p1, const UA_DecimalString *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DECIMALSTRING]) == UA_ORDER_EQ); +} + + + +/* DurationString */ +static UA_INLINE void +UA_DurationString_init(UA_DurationString *p) { + memset(p, 0, sizeof(UA_DurationString)); +} + +static UA_INLINE UA_DurationString * +UA_DurationString_new(void) { + return (UA_DurationString*)UA_new(&UA_TYPES[UA_TYPES_DURATIONSTRING]); +} + +static UA_INLINE UA_StatusCode +UA_DurationString_copy(const UA_DurationString *src, UA_DurationString *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DURATIONSTRING]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DurationString_deleteMembers(UA_DurationString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DURATIONSTRING]); +} + +static UA_INLINE void +UA_DurationString_clear(UA_DurationString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DURATIONSTRING]); +} + +static UA_INLINE void +UA_DurationString_delete(UA_DurationString *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DURATIONSTRING]); +}static UA_INLINE UA_Boolean +UA_DurationString_equal(const UA_DurationString *p1, const UA_DurationString *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DURATIONSTRING]) == UA_ORDER_EQ); +} + + + +/* TimeString */ +static UA_INLINE void +UA_TimeString_init(UA_TimeString *p) { + memset(p, 0, sizeof(UA_TimeString)); +} + +static UA_INLINE UA_TimeString * +UA_TimeString_new(void) { + return (UA_TimeString*)UA_new(&UA_TYPES[UA_TYPES_TIMESTRING]); +} + +static UA_INLINE UA_StatusCode +UA_TimeString_copy(const UA_TimeString *src, UA_TimeString *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TIMESTRING]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TimeString_deleteMembers(UA_TimeString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TIMESTRING]); +} + +static UA_INLINE void +UA_TimeString_clear(UA_TimeString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TIMESTRING]); +} + +static UA_INLINE void +UA_TimeString_delete(UA_TimeString *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TIMESTRING]); +}static UA_INLINE UA_Boolean +UA_TimeString_equal(const UA_TimeString *p1, const UA_TimeString *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TIMESTRING]) == UA_ORDER_EQ); +} + + + +/* DateString */ +static UA_INLINE void +UA_DateString_init(UA_DateString *p) { + memset(p, 0, sizeof(UA_DateString)); +} + +static UA_INLINE UA_DateString * +UA_DateString_new(void) { + return (UA_DateString*)UA_new(&UA_TYPES[UA_TYPES_DATESTRING]); +} + +static UA_INLINE UA_StatusCode +UA_DateString_copy(const UA_DateString *src, UA_DateString *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATESTRING]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DateString_deleteMembers(UA_DateString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATESTRING]); +} + +static UA_INLINE void +UA_DateString_clear(UA_DateString *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATESTRING]); +} + +static UA_INLINE void +UA_DateString_delete(UA_DateString *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATESTRING]); +}static UA_INLINE UA_Boolean +UA_DateString_equal(const UA_DateString *p1, const UA_DateString *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATESTRING]) == UA_ORDER_EQ); +} + + + +/* Duration */ +static UA_INLINE void +UA_Duration_init(UA_Duration *p) { + memset(p, 0, sizeof(UA_Duration)); +} + +static UA_INLINE UA_Duration * +UA_Duration_new(void) { + return (UA_Duration*)UA_new(&UA_TYPES[UA_TYPES_DURATION]); +} + +static UA_INLINE UA_StatusCode +UA_Duration_copy(const UA_Duration *src, UA_Duration *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DURATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Duration_deleteMembers(UA_Duration *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DURATION]); +} + +static UA_INLINE void +UA_Duration_clear(UA_Duration *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DURATION]); +} + +static UA_INLINE void +UA_Duration_delete(UA_Duration *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DURATION]); +}static UA_INLINE UA_Boolean +UA_Duration_equal(const UA_Duration *p1, const UA_Duration *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DURATION]) == UA_ORDER_EQ); +} + + + +/* UtcTime */ +static UA_INLINE void +UA_UtcTime_init(UA_UtcTime *p) { + memset(p, 0, sizeof(UA_UtcTime)); +} + +static UA_INLINE UA_UtcTime * +UA_UtcTime_new(void) { + return (UA_UtcTime*)UA_new(&UA_TYPES[UA_TYPES_UTCTIME]); +} + +static UA_INLINE UA_StatusCode +UA_UtcTime_copy(const UA_UtcTime *src, UA_UtcTime *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UTCTIME]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UtcTime_deleteMembers(UA_UtcTime *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UTCTIME]); +} + +static UA_INLINE void +UA_UtcTime_clear(UA_UtcTime *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UTCTIME]); +} + +static UA_INLINE void +UA_UtcTime_delete(UA_UtcTime *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UTCTIME]); +}static UA_INLINE UA_Boolean +UA_UtcTime_equal(const UA_UtcTime *p1, const UA_UtcTime *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UTCTIME]) == UA_ORDER_EQ); +} + + + +/* LocaleId */ +static UA_INLINE void +UA_LocaleId_init(UA_LocaleId *p) { + memset(p, 0, sizeof(UA_LocaleId)); +} + +static UA_INLINE UA_LocaleId * +UA_LocaleId_new(void) { + return (UA_LocaleId*)UA_new(&UA_TYPES[UA_TYPES_LOCALEID]); +} + +static UA_INLINE UA_StatusCode +UA_LocaleId_copy(const UA_LocaleId *src, UA_LocaleId *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_LOCALEID]); +} + +UA_DEPRECATED static UA_INLINE void +UA_LocaleId_deleteMembers(UA_LocaleId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_LOCALEID]); +} + +static UA_INLINE void +UA_LocaleId_clear(UA_LocaleId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_LOCALEID]); +} + +static UA_INLINE void +UA_LocaleId_delete(UA_LocaleId *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_LOCALEID]); +}static UA_INLINE UA_Boolean +UA_LocaleId_equal(const UA_LocaleId *p1, const UA_LocaleId *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_LOCALEID]) == UA_ORDER_EQ); +} + + + +/* TimeZoneDataType */ +static UA_INLINE void +UA_TimeZoneDataType_init(UA_TimeZoneDataType *p) { + memset(p, 0, sizeof(UA_TimeZoneDataType)); +} + +static UA_INLINE UA_TimeZoneDataType * +UA_TimeZoneDataType_new(void) { + return (UA_TimeZoneDataType*)UA_new(&UA_TYPES[UA_TYPES_TIMEZONEDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_TimeZoneDataType_copy(const UA_TimeZoneDataType *src, UA_TimeZoneDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TIMEZONEDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TimeZoneDataType_deleteMembers(UA_TimeZoneDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TIMEZONEDATATYPE]); +} + +static UA_INLINE void +UA_TimeZoneDataType_clear(UA_TimeZoneDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TIMEZONEDATATYPE]); +} + +static UA_INLINE void +UA_TimeZoneDataType_delete(UA_TimeZoneDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TIMEZONEDATATYPE]); +}static UA_INLINE UA_Boolean +UA_TimeZoneDataType_equal(const UA_TimeZoneDataType *p1, const UA_TimeZoneDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TIMEZONEDATATYPE]) == UA_ORDER_EQ); +} + + + +/* Index */ +static UA_INLINE void +UA_Index_init(UA_Index *p) { + memset(p, 0, sizeof(UA_Index)); +} + +static UA_INLINE UA_Index * +UA_Index_new(void) { + return (UA_Index*)UA_new(&UA_TYPES[UA_TYPES_INDEX]); +} + +static UA_INLINE UA_StatusCode +UA_Index_copy(const UA_Index *src, UA_Index *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_INDEX]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Index_deleteMembers(UA_Index *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INDEX]); +} + +static UA_INLINE void +UA_Index_clear(UA_Index *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INDEX]); +} + +static UA_INLINE void +UA_Index_delete(UA_Index *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_INDEX]); +}static UA_INLINE UA_Boolean +UA_Index_equal(const UA_Index *p1, const UA_Index *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_INDEX]) == UA_ORDER_EQ); +} + + + +/* IntegerId */ +static UA_INLINE void +UA_IntegerId_init(UA_IntegerId *p) { + memset(p, 0, sizeof(UA_IntegerId)); +} + +static UA_INLINE UA_IntegerId * +UA_IntegerId_new(void) { + return (UA_IntegerId*)UA_new(&UA_TYPES[UA_TYPES_INTEGERID]); +} + +static UA_INLINE UA_StatusCode +UA_IntegerId_copy(const UA_IntegerId *src, UA_IntegerId *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_INTEGERID]); +} + +UA_DEPRECATED static UA_INLINE void +UA_IntegerId_deleteMembers(UA_IntegerId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INTEGERID]); +} + +static UA_INLINE void +UA_IntegerId_clear(UA_IntegerId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_INTEGERID]); +} + +static UA_INLINE void +UA_IntegerId_delete(UA_IntegerId *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_INTEGERID]); +}static UA_INLINE UA_Boolean +UA_IntegerId_equal(const UA_IntegerId *p1, const UA_IntegerId *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_INTEGERID]) == UA_ORDER_EQ); +} + + + +/* ApplicationType */ +static UA_INLINE void +UA_ApplicationType_init(UA_ApplicationType *p) { + memset(p, 0, sizeof(UA_ApplicationType)); +} + +static UA_INLINE UA_ApplicationType * +UA_ApplicationType_new(void) { + return (UA_ApplicationType*)UA_new(&UA_TYPES[UA_TYPES_APPLICATIONTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_ApplicationType_copy(const UA_ApplicationType *src, UA_ApplicationType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_APPLICATIONTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ApplicationType_deleteMembers(UA_ApplicationType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_APPLICATIONTYPE]); +} + +static UA_INLINE void +UA_ApplicationType_clear(UA_ApplicationType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_APPLICATIONTYPE]); +} + +static UA_INLINE void +UA_ApplicationType_delete(UA_ApplicationType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_APPLICATIONTYPE]); +}static UA_INLINE UA_Boolean +UA_ApplicationType_equal(const UA_ApplicationType *p1, const UA_ApplicationType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_APPLICATIONTYPE]) == UA_ORDER_EQ); +} + + + +/* ApplicationDescription */ +static UA_INLINE void +UA_ApplicationDescription_init(UA_ApplicationDescription *p) { + memset(p, 0, sizeof(UA_ApplicationDescription)); +} + +static UA_INLINE UA_ApplicationDescription * +UA_ApplicationDescription_new(void) { + return (UA_ApplicationDescription*)UA_new(&UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]); +} + +static UA_INLINE UA_StatusCode +UA_ApplicationDescription_copy(const UA_ApplicationDescription *src, UA_ApplicationDescription *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ApplicationDescription_deleteMembers(UA_ApplicationDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]); +} + +static UA_INLINE void +UA_ApplicationDescription_clear(UA_ApplicationDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]); +} + +static UA_INLINE void +UA_ApplicationDescription_delete(UA_ApplicationDescription *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]); +}static UA_INLINE UA_Boolean +UA_ApplicationDescription_equal(const UA_ApplicationDescription *p1, const UA_ApplicationDescription *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]) == UA_ORDER_EQ); +} + + + +/* RequestHeader */ +static UA_INLINE void +UA_RequestHeader_init(UA_RequestHeader *p) { + memset(p, 0, sizeof(UA_RequestHeader)); +} + +static UA_INLINE UA_RequestHeader * +UA_RequestHeader_new(void) { + return (UA_RequestHeader*)UA_new(&UA_TYPES[UA_TYPES_REQUESTHEADER]); +} + +static UA_INLINE UA_StatusCode +UA_RequestHeader_copy(const UA_RequestHeader *src, UA_RequestHeader *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REQUESTHEADER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RequestHeader_deleteMembers(UA_RequestHeader *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REQUESTHEADER]); +} + +static UA_INLINE void +UA_RequestHeader_clear(UA_RequestHeader *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REQUESTHEADER]); +} + +static UA_INLINE void +UA_RequestHeader_delete(UA_RequestHeader *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REQUESTHEADER]); +}static UA_INLINE UA_Boolean +UA_RequestHeader_equal(const UA_RequestHeader *p1, const UA_RequestHeader *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REQUESTHEADER]) == UA_ORDER_EQ); +} + + + +/* ResponseHeader */ +static UA_INLINE void +UA_ResponseHeader_init(UA_ResponseHeader *p) { + memset(p, 0, sizeof(UA_ResponseHeader)); +} + +static UA_INLINE UA_ResponseHeader * +UA_ResponseHeader_new(void) { + return (UA_ResponseHeader*)UA_new(&UA_TYPES[UA_TYPES_RESPONSEHEADER]); +} + +static UA_INLINE UA_StatusCode +UA_ResponseHeader_copy(const UA_ResponseHeader *src, UA_ResponseHeader *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_RESPONSEHEADER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ResponseHeader_deleteMembers(UA_ResponseHeader *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RESPONSEHEADER]); +} + +static UA_INLINE void +UA_ResponseHeader_clear(UA_ResponseHeader *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RESPONSEHEADER]); +} + +static UA_INLINE void +UA_ResponseHeader_delete(UA_ResponseHeader *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_RESPONSEHEADER]); +}static UA_INLINE UA_Boolean +UA_ResponseHeader_equal(const UA_ResponseHeader *p1, const UA_ResponseHeader *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_RESPONSEHEADER]) == UA_ORDER_EQ); +} + + + +/* VersionTime */ +static UA_INLINE void +UA_VersionTime_init(UA_VersionTime *p) { + memset(p, 0, sizeof(UA_VersionTime)); +} + +static UA_INLINE UA_VersionTime * +UA_VersionTime_new(void) { + return (UA_VersionTime*)UA_new(&UA_TYPES[UA_TYPES_VERSIONTIME]); +} + +static UA_INLINE UA_StatusCode +UA_VersionTime_copy(const UA_VersionTime *src, UA_VersionTime *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_VERSIONTIME]); +} + +UA_DEPRECATED static UA_INLINE void +UA_VersionTime_deleteMembers(UA_VersionTime *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_VERSIONTIME]); +} + +static UA_INLINE void +UA_VersionTime_clear(UA_VersionTime *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_VERSIONTIME]); +} + +static UA_INLINE void +UA_VersionTime_delete(UA_VersionTime *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_VERSIONTIME]); +}static UA_INLINE UA_Boolean +UA_VersionTime_equal(const UA_VersionTime *p1, const UA_VersionTime *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_VERSIONTIME]) == UA_ORDER_EQ); +} + + + +/* ServiceFault */ +static UA_INLINE void +UA_ServiceFault_init(UA_ServiceFault *p) { + memset(p, 0, sizeof(UA_ServiceFault)); +} + +static UA_INLINE UA_ServiceFault * +UA_ServiceFault_new(void) { + return (UA_ServiceFault*)UA_new(&UA_TYPES[UA_TYPES_SERVICEFAULT]); +} + +static UA_INLINE UA_StatusCode +UA_ServiceFault_copy(const UA_ServiceFault *src, UA_ServiceFault *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SERVICEFAULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ServiceFault_deleteMembers(UA_ServiceFault *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SERVICEFAULT]); +} + +static UA_INLINE void +UA_ServiceFault_clear(UA_ServiceFault *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SERVICEFAULT]); +} + +static UA_INLINE void +UA_ServiceFault_delete(UA_ServiceFault *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SERVICEFAULT]); +}static UA_INLINE UA_Boolean +UA_ServiceFault_equal(const UA_ServiceFault *p1, const UA_ServiceFault *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SERVICEFAULT]) == UA_ORDER_EQ); +} + + + +/* SessionlessInvokeRequestType */ +static UA_INLINE void +UA_SessionlessInvokeRequestType_init(UA_SessionlessInvokeRequestType *p) { + memset(p, 0, sizeof(UA_SessionlessInvokeRequestType)); +} + +static UA_INLINE UA_SessionlessInvokeRequestType * +UA_SessionlessInvokeRequestType_new(void) { + return (UA_SessionlessInvokeRequestType*)UA_new(&UA_TYPES[UA_TYPES_SESSIONLESSINVOKEREQUESTTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_SessionlessInvokeRequestType_copy(const UA_SessionlessInvokeRequestType *src, UA_SessionlessInvokeRequestType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SESSIONLESSINVOKEREQUESTTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SessionlessInvokeRequestType_deleteMembers(UA_SessionlessInvokeRequestType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SESSIONLESSINVOKEREQUESTTYPE]); +} + +static UA_INLINE void +UA_SessionlessInvokeRequestType_clear(UA_SessionlessInvokeRequestType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SESSIONLESSINVOKEREQUESTTYPE]); +} + +static UA_INLINE void +UA_SessionlessInvokeRequestType_delete(UA_SessionlessInvokeRequestType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SESSIONLESSINVOKEREQUESTTYPE]); +}static UA_INLINE UA_Boolean +UA_SessionlessInvokeRequestType_equal(const UA_SessionlessInvokeRequestType *p1, const UA_SessionlessInvokeRequestType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SESSIONLESSINVOKEREQUESTTYPE]) == UA_ORDER_EQ); +} + + + +/* SessionlessInvokeResponseType */ +static UA_INLINE void +UA_SessionlessInvokeResponseType_init(UA_SessionlessInvokeResponseType *p) { + memset(p, 0, sizeof(UA_SessionlessInvokeResponseType)); +} + +static UA_INLINE UA_SessionlessInvokeResponseType * +UA_SessionlessInvokeResponseType_new(void) { + return (UA_SessionlessInvokeResponseType*)UA_new(&UA_TYPES[UA_TYPES_SESSIONLESSINVOKERESPONSETYPE]); +} + +static UA_INLINE UA_StatusCode +UA_SessionlessInvokeResponseType_copy(const UA_SessionlessInvokeResponseType *src, UA_SessionlessInvokeResponseType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SESSIONLESSINVOKERESPONSETYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SessionlessInvokeResponseType_deleteMembers(UA_SessionlessInvokeResponseType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SESSIONLESSINVOKERESPONSETYPE]); +} + +static UA_INLINE void +UA_SessionlessInvokeResponseType_clear(UA_SessionlessInvokeResponseType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SESSIONLESSINVOKERESPONSETYPE]); +} + +static UA_INLINE void +UA_SessionlessInvokeResponseType_delete(UA_SessionlessInvokeResponseType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SESSIONLESSINVOKERESPONSETYPE]); +}static UA_INLINE UA_Boolean +UA_SessionlessInvokeResponseType_equal(const UA_SessionlessInvokeResponseType *p1, const UA_SessionlessInvokeResponseType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SESSIONLESSINVOKERESPONSETYPE]) == UA_ORDER_EQ); +} + + + +/* FindServersRequest */ +static UA_INLINE void +UA_FindServersRequest_init(UA_FindServersRequest *p) { + memset(p, 0, sizeof(UA_FindServersRequest)); +} + +static UA_INLINE UA_FindServersRequest * +UA_FindServersRequest_new(void) { + return (UA_FindServersRequest*)UA_new(&UA_TYPES[UA_TYPES_FINDSERVERSREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_FindServersRequest_copy(const UA_FindServersRequest *src, UA_FindServersRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_FindServersRequest_deleteMembers(UA_FindServersRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST]); +} + +static UA_INLINE void +UA_FindServersRequest_clear(UA_FindServersRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST]); +} + +static UA_INLINE void +UA_FindServersRequest_delete(UA_FindServersRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST]); +}static UA_INLINE UA_Boolean +UA_FindServersRequest_equal(const UA_FindServersRequest *p1, const UA_FindServersRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST]) == UA_ORDER_EQ); +} + + + +/* FindServersResponse */ +static UA_INLINE void +UA_FindServersResponse_init(UA_FindServersResponse *p) { + memset(p, 0, sizeof(UA_FindServersResponse)); +} + +static UA_INLINE UA_FindServersResponse * +UA_FindServersResponse_new(void) { + return (UA_FindServersResponse*)UA_new(&UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_FindServersResponse_copy(const UA_FindServersResponse *src, UA_FindServersResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_FindServersResponse_deleteMembers(UA_FindServersResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]); +} + +static UA_INLINE void +UA_FindServersResponse_clear(UA_FindServersResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]); +} + +static UA_INLINE void +UA_FindServersResponse_delete(UA_FindServersResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]); +}static UA_INLINE UA_Boolean +UA_FindServersResponse_equal(const UA_FindServersResponse *p1, const UA_FindServersResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]) == UA_ORDER_EQ); +} + + + +/* ServerOnNetwork */ +static UA_INLINE void +UA_ServerOnNetwork_init(UA_ServerOnNetwork *p) { + memset(p, 0, sizeof(UA_ServerOnNetwork)); +} + +static UA_INLINE UA_ServerOnNetwork * +UA_ServerOnNetwork_new(void) { + return (UA_ServerOnNetwork*)UA_new(&UA_TYPES[UA_TYPES_SERVERONNETWORK]); +} + +static UA_INLINE UA_StatusCode +UA_ServerOnNetwork_copy(const UA_ServerOnNetwork *src, UA_ServerOnNetwork *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SERVERONNETWORK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ServerOnNetwork_deleteMembers(UA_ServerOnNetwork *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SERVERONNETWORK]); +} + +static UA_INLINE void +UA_ServerOnNetwork_clear(UA_ServerOnNetwork *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SERVERONNETWORK]); +} + +static UA_INLINE void +UA_ServerOnNetwork_delete(UA_ServerOnNetwork *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SERVERONNETWORK]); +}static UA_INLINE UA_Boolean +UA_ServerOnNetwork_equal(const UA_ServerOnNetwork *p1, const UA_ServerOnNetwork *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SERVERONNETWORK]) == UA_ORDER_EQ); +} + + + +/* FindServersOnNetworkRequest */ +static UA_INLINE void +UA_FindServersOnNetworkRequest_init(UA_FindServersOnNetworkRequest *p) { + memset(p, 0, sizeof(UA_FindServersOnNetworkRequest)); +} + +static UA_INLINE UA_FindServersOnNetworkRequest * +UA_FindServersOnNetworkRequest_new(void) { + return (UA_FindServersOnNetworkRequest*)UA_new(&UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_FindServersOnNetworkRequest_copy(const UA_FindServersOnNetworkRequest *src, UA_FindServersOnNetworkRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_FindServersOnNetworkRequest_deleteMembers(UA_FindServersOnNetworkRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST]); +} + +static UA_INLINE void +UA_FindServersOnNetworkRequest_clear(UA_FindServersOnNetworkRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST]); +} + +static UA_INLINE void +UA_FindServersOnNetworkRequest_delete(UA_FindServersOnNetworkRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST]); +}static UA_INLINE UA_Boolean +UA_FindServersOnNetworkRequest_equal(const UA_FindServersOnNetworkRequest *p1, const UA_FindServersOnNetworkRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST]) == UA_ORDER_EQ); +} + + + +/* FindServersOnNetworkResponse */ +static UA_INLINE void +UA_FindServersOnNetworkResponse_init(UA_FindServersOnNetworkResponse *p) { + memset(p, 0, sizeof(UA_FindServersOnNetworkResponse)); +} + +static UA_INLINE UA_FindServersOnNetworkResponse * +UA_FindServersOnNetworkResponse_new(void) { + return (UA_FindServersOnNetworkResponse*)UA_new(&UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_FindServersOnNetworkResponse_copy(const UA_FindServersOnNetworkResponse *src, UA_FindServersOnNetworkResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_FindServersOnNetworkResponse_deleteMembers(UA_FindServersOnNetworkResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE]); +} + +static UA_INLINE void +UA_FindServersOnNetworkResponse_clear(UA_FindServersOnNetworkResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE]); +} + +static UA_INLINE void +UA_FindServersOnNetworkResponse_delete(UA_FindServersOnNetworkResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE]); +}static UA_INLINE UA_Boolean +UA_FindServersOnNetworkResponse_equal(const UA_FindServersOnNetworkResponse *p1, const UA_FindServersOnNetworkResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE]) == UA_ORDER_EQ); +} + + + +/* ApplicationInstanceCertificate */ +static UA_INLINE void +UA_ApplicationInstanceCertificate_init(UA_ApplicationInstanceCertificate *p) { + memset(p, 0, sizeof(UA_ApplicationInstanceCertificate)); +} + +static UA_INLINE UA_ApplicationInstanceCertificate * +UA_ApplicationInstanceCertificate_new(void) { + return (UA_ApplicationInstanceCertificate*)UA_new(&UA_TYPES[UA_TYPES_APPLICATIONINSTANCECERTIFICATE]); +} + +static UA_INLINE UA_StatusCode +UA_ApplicationInstanceCertificate_copy(const UA_ApplicationInstanceCertificate *src, UA_ApplicationInstanceCertificate *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_APPLICATIONINSTANCECERTIFICATE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ApplicationInstanceCertificate_deleteMembers(UA_ApplicationInstanceCertificate *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_APPLICATIONINSTANCECERTIFICATE]); +} + +static UA_INLINE void +UA_ApplicationInstanceCertificate_clear(UA_ApplicationInstanceCertificate *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_APPLICATIONINSTANCECERTIFICATE]); +} + +static UA_INLINE void +UA_ApplicationInstanceCertificate_delete(UA_ApplicationInstanceCertificate *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_APPLICATIONINSTANCECERTIFICATE]); +}static UA_INLINE UA_Boolean +UA_ApplicationInstanceCertificate_equal(const UA_ApplicationInstanceCertificate *p1, const UA_ApplicationInstanceCertificate *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_APPLICATIONINSTANCECERTIFICATE]) == UA_ORDER_EQ); +} + + + +/* MessageSecurityMode */ +static UA_INLINE void +UA_MessageSecurityMode_init(UA_MessageSecurityMode *p) { + memset(p, 0, sizeof(UA_MessageSecurityMode)); +} + +static UA_INLINE UA_MessageSecurityMode * +UA_MessageSecurityMode_new(void) { + return (UA_MessageSecurityMode*)UA_new(&UA_TYPES[UA_TYPES_MESSAGESECURITYMODE]); +} + +static UA_INLINE UA_StatusCode +UA_MessageSecurityMode_copy(const UA_MessageSecurityMode *src, UA_MessageSecurityMode *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_MessageSecurityMode_deleteMembers(UA_MessageSecurityMode *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE]); +} + +static UA_INLINE void +UA_MessageSecurityMode_clear(UA_MessageSecurityMode *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE]); +} + +static UA_INLINE void +UA_MessageSecurityMode_delete(UA_MessageSecurityMode *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE]); +}static UA_INLINE UA_Boolean +UA_MessageSecurityMode_equal(const UA_MessageSecurityMode *p1, const UA_MessageSecurityMode *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE]) == UA_ORDER_EQ); +} + + + +/* UserTokenType */ +static UA_INLINE void +UA_UserTokenType_init(UA_UserTokenType *p) { + memset(p, 0, sizeof(UA_UserTokenType)); +} + +static UA_INLINE UA_UserTokenType * +UA_UserTokenType_new(void) { + return (UA_UserTokenType*)UA_new(&UA_TYPES[UA_TYPES_USERTOKENTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_UserTokenType_copy(const UA_UserTokenType *src, UA_UserTokenType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_USERTOKENTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UserTokenType_deleteMembers(UA_UserTokenType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_USERTOKENTYPE]); +} + +static UA_INLINE void +UA_UserTokenType_clear(UA_UserTokenType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_USERTOKENTYPE]); +} + +static UA_INLINE void +UA_UserTokenType_delete(UA_UserTokenType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_USERTOKENTYPE]); +}static UA_INLINE UA_Boolean +UA_UserTokenType_equal(const UA_UserTokenType *p1, const UA_UserTokenType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_USERTOKENTYPE]) == UA_ORDER_EQ); +} + + + +/* UserTokenPolicy */ +static UA_INLINE void +UA_UserTokenPolicy_init(UA_UserTokenPolicy *p) { + memset(p, 0, sizeof(UA_UserTokenPolicy)); +} + +static UA_INLINE UA_UserTokenPolicy * +UA_UserTokenPolicy_new(void) { + return (UA_UserTokenPolicy*)UA_new(&UA_TYPES[UA_TYPES_USERTOKENPOLICY]); +} + +static UA_INLINE UA_StatusCode +UA_UserTokenPolicy_copy(const UA_UserTokenPolicy *src, UA_UserTokenPolicy *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_USERTOKENPOLICY]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UserTokenPolicy_deleteMembers(UA_UserTokenPolicy *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_USERTOKENPOLICY]); +} + +static UA_INLINE void +UA_UserTokenPolicy_clear(UA_UserTokenPolicy *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_USERTOKENPOLICY]); +} + +static UA_INLINE void +UA_UserTokenPolicy_delete(UA_UserTokenPolicy *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_USERTOKENPOLICY]); +}static UA_INLINE UA_Boolean +UA_UserTokenPolicy_equal(const UA_UserTokenPolicy *p1, const UA_UserTokenPolicy *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_USERTOKENPOLICY]) == UA_ORDER_EQ); +} + + + +/* EndpointDescription */ +static UA_INLINE void +UA_EndpointDescription_init(UA_EndpointDescription *p) { + memset(p, 0, sizeof(UA_EndpointDescription)); +} + +static UA_INLINE UA_EndpointDescription * +UA_EndpointDescription_new(void) { + return (UA_EndpointDescription*)UA_new(&UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); +} + +static UA_INLINE UA_StatusCode +UA_EndpointDescription_copy(const UA_EndpointDescription *src, UA_EndpointDescription *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EndpointDescription_deleteMembers(UA_EndpointDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); +} + +static UA_INLINE void +UA_EndpointDescription_clear(UA_EndpointDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); +} + +static UA_INLINE void +UA_EndpointDescription_delete(UA_EndpointDescription *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); +}static UA_INLINE UA_Boolean +UA_EndpointDescription_equal(const UA_EndpointDescription *p1, const UA_EndpointDescription *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]) == UA_ORDER_EQ); +} + + + +/* GetEndpointsRequest */ +static UA_INLINE void +UA_GetEndpointsRequest_init(UA_GetEndpointsRequest *p) { + memset(p, 0, sizeof(UA_GetEndpointsRequest)); +} + +static UA_INLINE UA_GetEndpointsRequest * +UA_GetEndpointsRequest_new(void) { + return (UA_GetEndpointsRequest*)UA_new(&UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_GetEndpointsRequest_copy(const UA_GetEndpointsRequest *src, UA_GetEndpointsRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_GetEndpointsRequest_deleteMembers(UA_GetEndpointsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST]); +} + +static UA_INLINE void +UA_GetEndpointsRequest_clear(UA_GetEndpointsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST]); +} + +static UA_INLINE void +UA_GetEndpointsRequest_delete(UA_GetEndpointsRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST]); +}static UA_INLINE UA_Boolean +UA_GetEndpointsRequest_equal(const UA_GetEndpointsRequest *p1, const UA_GetEndpointsRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST]) == UA_ORDER_EQ); +} + + + +/* GetEndpointsResponse */ +static UA_INLINE void +UA_GetEndpointsResponse_init(UA_GetEndpointsResponse *p) { + memset(p, 0, sizeof(UA_GetEndpointsResponse)); +} + +static UA_INLINE UA_GetEndpointsResponse * +UA_GetEndpointsResponse_new(void) { + return (UA_GetEndpointsResponse*)UA_new(&UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_GetEndpointsResponse_copy(const UA_GetEndpointsResponse *src, UA_GetEndpointsResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_GetEndpointsResponse_deleteMembers(UA_GetEndpointsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]); +} + +static UA_INLINE void +UA_GetEndpointsResponse_clear(UA_GetEndpointsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]); +} + +static UA_INLINE void +UA_GetEndpointsResponse_delete(UA_GetEndpointsResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]); +}static UA_INLINE UA_Boolean +UA_GetEndpointsResponse_equal(const UA_GetEndpointsResponse *p1, const UA_GetEndpointsResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]) == UA_ORDER_EQ); +} + + + +/* RegisteredServer */ +static UA_INLINE void +UA_RegisteredServer_init(UA_RegisteredServer *p) { + memset(p, 0, sizeof(UA_RegisteredServer)); +} + +static UA_INLINE UA_RegisteredServer * +UA_RegisteredServer_new(void) { + return (UA_RegisteredServer*)UA_new(&UA_TYPES[UA_TYPES_REGISTEREDSERVER]); +} + +static UA_INLINE UA_StatusCode +UA_RegisteredServer_copy(const UA_RegisteredServer *src, UA_RegisteredServer *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REGISTEREDSERVER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RegisteredServer_deleteMembers(UA_RegisteredServer *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTEREDSERVER]); +} + +static UA_INLINE void +UA_RegisteredServer_clear(UA_RegisteredServer *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTEREDSERVER]); +} + +static UA_INLINE void +UA_RegisteredServer_delete(UA_RegisteredServer *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REGISTEREDSERVER]); +}static UA_INLINE UA_Boolean +UA_RegisteredServer_equal(const UA_RegisteredServer *p1, const UA_RegisteredServer *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REGISTEREDSERVER]) == UA_ORDER_EQ); +} + + + +/* RegisterServerRequest */ +static UA_INLINE void +UA_RegisterServerRequest_init(UA_RegisterServerRequest *p) { + memset(p, 0, sizeof(UA_RegisterServerRequest)); +} + +static UA_INLINE UA_RegisterServerRequest * +UA_RegisterServerRequest_new(void) { + return (UA_RegisterServerRequest*)UA_new(&UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_RegisterServerRequest_copy(const UA_RegisterServerRequest *src, UA_RegisterServerRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RegisterServerRequest_deleteMembers(UA_RegisterServerRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST]); +} + +static UA_INLINE void +UA_RegisterServerRequest_clear(UA_RegisterServerRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST]); +} + +static UA_INLINE void +UA_RegisterServerRequest_delete(UA_RegisterServerRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST]); +}static UA_INLINE UA_Boolean +UA_RegisterServerRequest_equal(const UA_RegisterServerRequest *p1, const UA_RegisterServerRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST]) == UA_ORDER_EQ); +} + + + +/* RegisterServerResponse */ +static UA_INLINE void +UA_RegisterServerResponse_init(UA_RegisterServerResponse *p) { + memset(p, 0, sizeof(UA_RegisterServerResponse)); +} + +static UA_INLINE UA_RegisterServerResponse * +UA_RegisterServerResponse_new(void) { + return (UA_RegisterServerResponse*)UA_new(&UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_RegisterServerResponse_copy(const UA_RegisterServerResponse *src, UA_RegisterServerResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RegisterServerResponse_deleteMembers(UA_RegisterServerResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE]); +} + +static UA_INLINE void +UA_RegisterServerResponse_clear(UA_RegisterServerResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE]); +} + +static UA_INLINE void +UA_RegisterServerResponse_delete(UA_RegisterServerResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE]); +}static UA_INLINE UA_Boolean +UA_RegisterServerResponse_equal(const UA_RegisterServerResponse *p1, const UA_RegisterServerResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE]) == UA_ORDER_EQ); +} + + + +/* MdnsDiscoveryConfiguration */ +static UA_INLINE void +UA_MdnsDiscoveryConfiguration_init(UA_MdnsDiscoveryConfiguration *p) { + memset(p, 0, sizeof(UA_MdnsDiscoveryConfiguration)); +} + +static UA_INLINE UA_MdnsDiscoveryConfiguration * +UA_MdnsDiscoveryConfiguration_new(void) { + return (UA_MdnsDiscoveryConfiguration*)UA_new(&UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION]); +} + +static UA_INLINE UA_StatusCode +UA_MdnsDiscoveryConfiguration_copy(const UA_MdnsDiscoveryConfiguration *src, UA_MdnsDiscoveryConfiguration *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_MdnsDiscoveryConfiguration_deleteMembers(UA_MdnsDiscoveryConfiguration *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION]); +} + +static UA_INLINE void +UA_MdnsDiscoveryConfiguration_clear(UA_MdnsDiscoveryConfiguration *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION]); +} + +static UA_INLINE void +UA_MdnsDiscoveryConfiguration_delete(UA_MdnsDiscoveryConfiguration *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION]); +}static UA_INLINE UA_Boolean +UA_MdnsDiscoveryConfiguration_equal(const UA_MdnsDiscoveryConfiguration *p1, const UA_MdnsDiscoveryConfiguration *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION]) == UA_ORDER_EQ); +} + + + +/* RegisterServer2Request */ +static UA_INLINE void +UA_RegisterServer2Request_init(UA_RegisterServer2Request *p) { + memset(p, 0, sizeof(UA_RegisterServer2Request)); +} + +static UA_INLINE UA_RegisterServer2Request * +UA_RegisterServer2Request_new(void) { + return (UA_RegisterServer2Request*)UA_new(&UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_RegisterServer2Request_copy(const UA_RegisterServer2Request *src, UA_RegisterServer2Request *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RegisterServer2Request_deleteMembers(UA_RegisterServer2Request *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST]); +} + +static UA_INLINE void +UA_RegisterServer2Request_clear(UA_RegisterServer2Request *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST]); +} + +static UA_INLINE void +UA_RegisterServer2Request_delete(UA_RegisterServer2Request *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST]); +}static UA_INLINE UA_Boolean +UA_RegisterServer2Request_equal(const UA_RegisterServer2Request *p1, const UA_RegisterServer2Request *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST]) == UA_ORDER_EQ); +} + + + +/* RegisterServer2Response */ +static UA_INLINE void +UA_RegisterServer2Response_init(UA_RegisterServer2Response *p) { + memset(p, 0, sizeof(UA_RegisterServer2Response)); +} + +static UA_INLINE UA_RegisterServer2Response * +UA_RegisterServer2Response_new(void) { + return (UA_RegisterServer2Response*)UA_new(&UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_RegisterServer2Response_copy(const UA_RegisterServer2Response *src, UA_RegisterServer2Response *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RegisterServer2Response_deleteMembers(UA_RegisterServer2Response *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE]); +} + +static UA_INLINE void +UA_RegisterServer2Response_clear(UA_RegisterServer2Response *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE]); +} + +static UA_INLINE void +UA_RegisterServer2Response_delete(UA_RegisterServer2Response *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE]); +}static UA_INLINE UA_Boolean +UA_RegisterServer2Response_equal(const UA_RegisterServer2Response *p1, const UA_RegisterServer2Response *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE]) == UA_ORDER_EQ); +} + + + +/* SecurityTokenRequestType */ +static UA_INLINE void +UA_SecurityTokenRequestType_init(UA_SecurityTokenRequestType *p) { + memset(p, 0, sizeof(UA_SecurityTokenRequestType)); +} + +static UA_INLINE UA_SecurityTokenRequestType * +UA_SecurityTokenRequestType_new(void) { + return (UA_SecurityTokenRequestType*)UA_new(&UA_TYPES[UA_TYPES_SECURITYTOKENREQUESTTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_SecurityTokenRequestType_copy(const UA_SecurityTokenRequestType *src, UA_SecurityTokenRequestType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SECURITYTOKENREQUESTTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SecurityTokenRequestType_deleteMembers(UA_SecurityTokenRequestType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SECURITYTOKENREQUESTTYPE]); +} + +static UA_INLINE void +UA_SecurityTokenRequestType_clear(UA_SecurityTokenRequestType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SECURITYTOKENREQUESTTYPE]); +} + +static UA_INLINE void +UA_SecurityTokenRequestType_delete(UA_SecurityTokenRequestType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SECURITYTOKENREQUESTTYPE]); +}static UA_INLINE UA_Boolean +UA_SecurityTokenRequestType_equal(const UA_SecurityTokenRequestType *p1, const UA_SecurityTokenRequestType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SECURITYTOKENREQUESTTYPE]) == UA_ORDER_EQ); +} + + + +/* ChannelSecurityToken */ +static UA_INLINE void +UA_ChannelSecurityToken_init(UA_ChannelSecurityToken *p) { + memset(p, 0, sizeof(UA_ChannelSecurityToken)); +} + +static UA_INLINE UA_ChannelSecurityToken * +UA_ChannelSecurityToken_new(void) { + return (UA_ChannelSecurityToken*)UA_new(&UA_TYPES[UA_TYPES_CHANNELSECURITYTOKEN]); +} + +static UA_INLINE UA_StatusCode +UA_ChannelSecurityToken_copy(const UA_ChannelSecurityToken *src, UA_ChannelSecurityToken *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CHANNELSECURITYTOKEN]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ChannelSecurityToken_deleteMembers(UA_ChannelSecurityToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CHANNELSECURITYTOKEN]); +} + +static UA_INLINE void +UA_ChannelSecurityToken_clear(UA_ChannelSecurityToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CHANNELSECURITYTOKEN]); +} + +static UA_INLINE void +UA_ChannelSecurityToken_delete(UA_ChannelSecurityToken *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CHANNELSECURITYTOKEN]); +}static UA_INLINE UA_Boolean +UA_ChannelSecurityToken_equal(const UA_ChannelSecurityToken *p1, const UA_ChannelSecurityToken *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CHANNELSECURITYTOKEN]) == UA_ORDER_EQ); +} + + + +/* OpenSecureChannelRequest */ +static UA_INLINE void +UA_OpenSecureChannelRequest_init(UA_OpenSecureChannelRequest *p) { + memset(p, 0, sizeof(UA_OpenSecureChannelRequest)); +} + +static UA_INLINE UA_OpenSecureChannelRequest * +UA_OpenSecureChannelRequest_new(void) { + return (UA_OpenSecureChannelRequest*)UA_new(&UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_OpenSecureChannelRequest_copy(const UA_OpenSecureChannelRequest *src, UA_OpenSecureChannelRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_OpenSecureChannelRequest_deleteMembers(UA_OpenSecureChannelRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST]); +} + +static UA_INLINE void +UA_OpenSecureChannelRequest_clear(UA_OpenSecureChannelRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST]); +} + +static UA_INLINE void +UA_OpenSecureChannelRequest_delete(UA_OpenSecureChannelRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST]); +}static UA_INLINE UA_Boolean +UA_OpenSecureChannelRequest_equal(const UA_OpenSecureChannelRequest *p1, const UA_OpenSecureChannelRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST]) == UA_ORDER_EQ); +} + + + +/* OpenSecureChannelResponse */ +static UA_INLINE void +UA_OpenSecureChannelResponse_init(UA_OpenSecureChannelResponse *p) { + memset(p, 0, sizeof(UA_OpenSecureChannelResponse)); +} + +static UA_INLINE UA_OpenSecureChannelResponse * +UA_OpenSecureChannelResponse_new(void) { + return (UA_OpenSecureChannelResponse*)UA_new(&UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_OpenSecureChannelResponse_copy(const UA_OpenSecureChannelResponse *src, UA_OpenSecureChannelResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_OpenSecureChannelResponse_deleteMembers(UA_OpenSecureChannelResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE]); +} + +static UA_INLINE void +UA_OpenSecureChannelResponse_clear(UA_OpenSecureChannelResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE]); +} + +static UA_INLINE void +UA_OpenSecureChannelResponse_delete(UA_OpenSecureChannelResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE]); +}static UA_INLINE UA_Boolean +UA_OpenSecureChannelResponse_equal(const UA_OpenSecureChannelResponse *p1, const UA_OpenSecureChannelResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE]) == UA_ORDER_EQ); +} + + + +/* CloseSecureChannelRequest */ +static UA_INLINE void +UA_CloseSecureChannelRequest_init(UA_CloseSecureChannelRequest *p) { + memset(p, 0, sizeof(UA_CloseSecureChannelRequest)); +} + +static UA_INLINE UA_CloseSecureChannelRequest * +UA_CloseSecureChannelRequest_new(void) { + return (UA_CloseSecureChannelRequest*)UA_new(&UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_CloseSecureChannelRequest_copy(const UA_CloseSecureChannelRequest *src, UA_CloseSecureChannelRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CloseSecureChannelRequest_deleteMembers(UA_CloseSecureChannelRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]); +} + +static UA_INLINE void +UA_CloseSecureChannelRequest_clear(UA_CloseSecureChannelRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]); +} + +static UA_INLINE void +UA_CloseSecureChannelRequest_delete(UA_CloseSecureChannelRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]); +}static UA_INLINE UA_Boolean +UA_CloseSecureChannelRequest_equal(const UA_CloseSecureChannelRequest *p1, const UA_CloseSecureChannelRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]) == UA_ORDER_EQ); +} + + + +/* CloseSecureChannelResponse */ +static UA_INLINE void +UA_CloseSecureChannelResponse_init(UA_CloseSecureChannelResponse *p) { + memset(p, 0, sizeof(UA_CloseSecureChannelResponse)); +} + +static UA_INLINE UA_CloseSecureChannelResponse * +UA_CloseSecureChannelResponse_new(void) { + return (UA_CloseSecureChannelResponse*)UA_new(&UA_TYPES[UA_TYPES_CLOSESECURECHANNELRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_CloseSecureChannelResponse_copy(const UA_CloseSecureChannelResponse *src, UA_CloseSecureChannelResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CloseSecureChannelResponse_deleteMembers(UA_CloseSecureChannelResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELRESPONSE]); +} + +static UA_INLINE void +UA_CloseSecureChannelResponse_clear(UA_CloseSecureChannelResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELRESPONSE]); +} + +static UA_INLINE void +UA_CloseSecureChannelResponse_delete(UA_CloseSecureChannelResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELRESPONSE]); +}static UA_INLINE UA_Boolean +UA_CloseSecureChannelResponse_equal(const UA_CloseSecureChannelResponse *p1, const UA_CloseSecureChannelResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELRESPONSE]) == UA_ORDER_EQ); +} + + + +/* SignedSoftwareCertificate */ +static UA_INLINE void +UA_SignedSoftwareCertificate_init(UA_SignedSoftwareCertificate *p) { + memset(p, 0, sizeof(UA_SignedSoftwareCertificate)); +} + +static UA_INLINE UA_SignedSoftwareCertificate * +UA_SignedSoftwareCertificate_new(void) { + return (UA_SignedSoftwareCertificate*)UA_new(&UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE]); +} + +static UA_INLINE UA_StatusCode +UA_SignedSoftwareCertificate_copy(const UA_SignedSoftwareCertificate *src, UA_SignedSoftwareCertificate *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SignedSoftwareCertificate_deleteMembers(UA_SignedSoftwareCertificate *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE]); +} + +static UA_INLINE void +UA_SignedSoftwareCertificate_clear(UA_SignedSoftwareCertificate *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE]); +} + +static UA_INLINE void +UA_SignedSoftwareCertificate_delete(UA_SignedSoftwareCertificate *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE]); +}static UA_INLINE UA_Boolean +UA_SignedSoftwareCertificate_equal(const UA_SignedSoftwareCertificate *p1, const UA_SignedSoftwareCertificate *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE]) == UA_ORDER_EQ); +} + + + +/* SessionAuthenticationToken */ +static UA_INLINE void +UA_SessionAuthenticationToken_init(UA_SessionAuthenticationToken *p) { + memset(p, 0, sizeof(UA_SessionAuthenticationToken)); +} + +static UA_INLINE UA_SessionAuthenticationToken * +UA_SessionAuthenticationToken_new(void) { + return (UA_SessionAuthenticationToken*)UA_new(&UA_TYPES[UA_TYPES_SESSIONAUTHENTICATIONTOKEN]); +} + +static UA_INLINE UA_StatusCode +UA_SessionAuthenticationToken_copy(const UA_SessionAuthenticationToken *src, UA_SessionAuthenticationToken *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SESSIONAUTHENTICATIONTOKEN]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SessionAuthenticationToken_deleteMembers(UA_SessionAuthenticationToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SESSIONAUTHENTICATIONTOKEN]); +} + +static UA_INLINE void +UA_SessionAuthenticationToken_clear(UA_SessionAuthenticationToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SESSIONAUTHENTICATIONTOKEN]); +} + +static UA_INLINE void +UA_SessionAuthenticationToken_delete(UA_SessionAuthenticationToken *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SESSIONAUTHENTICATIONTOKEN]); +}static UA_INLINE UA_Boolean +UA_SessionAuthenticationToken_equal(const UA_SessionAuthenticationToken *p1, const UA_SessionAuthenticationToken *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SESSIONAUTHENTICATIONTOKEN]) == UA_ORDER_EQ); +} + + + +/* SignatureData */ +static UA_INLINE void +UA_SignatureData_init(UA_SignatureData *p) { + memset(p, 0, sizeof(UA_SignatureData)); +} + +static UA_INLINE UA_SignatureData * +UA_SignatureData_new(void) { + return (UA_SignatureData*)UA_new(&UA_TYPES[UA_TYPES_SIGNATUREDATA]); +} + +static UA_INLINE UA_StatusCode +UA_SignatureData_copy(const UA_SignatureData *src, UA_SignatureData *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SIGNATUREDATA]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SignatureData_deleteMembers(UA_SignatureData *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SIGNATUREDATA]); +} + +static UA_INLINE void +UA_SignatureData_clear(UA_SignatureData *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SIGNATUREDATA]); +} + +static UA_INLINE void +UA_SignatureData_delete(UA_SignatureData *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SIGNATUREDATA]); +}static UA_INLINE UA_Boolean +UA_SignatureData_equal(const UA_SignatureData *p1, const UA_SignatureData *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SIGNATUREDATA]) == UA_ORDER_EQ); +} + + + +/* CreateSessionRequest */ +static UA_INLINE void +UA_CreateSessionRequest_init(UA_CreateSessionRequest *p) { + memset(p, 0, sizeof(UA_CreateSessionRequest)); +} + +static UA_INLINE UA_CreateSessionRequest * +UA_CreateSessionRequest_new(void) { + return (UA_CreateSessionRequest*)UA_new(&UA_TYPES[UA_TYPES_CREATESESSIONREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_CreateSessionRequest_copy(const UA_CreateSessionRequest *src, UA_CreateSessionRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CreateSessionRequest_deleteMembers(UA_CreateSessionRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST]); +} + +static UA_INLINE void +UA_CreateSessionRequest_clear(UA_CreateSessionRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST]); +} + +static UA_INLINE void +UA_CreateSessionRequest_delete(UA_CreateSessionRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST]); +}static UA_INLINE UA_Boolean +UA_CreateSessionRequest_equal(const UA_CreateSessionRequest *p1, const UA_CreateSessionRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST]) == UA_ORDER_EQ); +} + + + +/* CreateSessionResponse */ +static UA_INLINE void +UA_CreateSessionResponse_init(UA_CreateSessionResponse *p) { + memset(p, 0, sizeof(UA_CreateSessionResponse)); +} + +static UA_INLINE UA_CreateSessionResponse * +UA_CreateSessionResponse_new(void) { + return (UA_CreateSessionResponse*)UA_new(&UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_CreateSessionResponse_copy(const UA_CreateSessionResponse *src, UA_CreateSessionResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CreateSessionResponse_deleteMembers(UA_CreateSessionResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]); +} + +static UA_INLINE void +UA_CreateSessionResponse_clear(UA_CreateSessionResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]); +} + +static UA_INLINE void +UA_CreateSessionResponse_delete(UA_CreateSessionResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]); +}static UA_INLINE UA_Boolean +UA_CreateSessionResponse_equal(const UA_CreateSessionResponse *p1, const UA_CreateSessionResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]) == UA_ORDER_EQ); +} + + + +/* UserIdentityToken */ +static UA_INLINE void +UA_UserIdentityToken_init(UA_UserIdentityToken *p) { + memset(p, 0, sizeof(UA_UserIdentityToken)); +} + +static UA_INLINE UA_UserIdentityToken * +UA_UserIdentityToken_new(void) { + return (UA_UserIdentityToken*)UA_new(&UA_TYPES[UA_TYPES_USERIDENTITYTOKEN]); +} + +static UA_INLINE UA_StatusCode +UA_UserIdentityToken_copy(const UA_UserIdentityToken *src, UA_UserIdentityToken *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_USERIDENTITYTOKEN]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UserIdentityToken_deleteMembers(UA_UserIdentityToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_USERIDENTITYTOKEN]); +} + +static UA_INLINE void +UA_UserIdentityToken_clear(UA_UserIdentityToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_USERIDENTITYTOKEN]); +} + +static UA_INLINE void +UA_UserIdentityToken_delete(UA_UserIdentityToken *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_USERIDENTITYTOKEN]); +}static UA_INLINE UA_Boolean +UA_UserIdentityToken_equal(const UA_UserIdentityToken *p1, const UA_UserIdentityToken *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_USERIDENTITYTOKEN]) == UA_ORDER_EQ); +} + + + +/* AnonymousIdentityToken */ +static UA_INLINE void +UA_AnonymousIdentityToken_init(UA_AnonymousIdentityToken *p) { + memset(p, 0, sizeof(UA_AnonymousIdentityToken)); +} + +static UA_INLINE UA_AnonymousIdentityToken * +UA_AnonymousIdentityToken_new(void) { + return (UA_AnonymousIdentityToken*)UA_new(&UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]); +} + +static UA_INLINE UA_StatusCode +UA_AnonymousIdentityToken_copy(const UA_AnonymousIdentityToken *src, UA_AnonymousIdentityToken *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AnonymousIdentityToken_deleteMembers(UA_AnonymousIdentityToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]); +} + +static UA_INLINE void +UA_AnonymousIdentityToken_clear(UA_AnonymousIdentityToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]); +} + +static UA_INLINE void +UA_AnonymousIdentityToken_delete(UA_AnonymousIdentityToken *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]); +}static UA_INLINE UA_Boolean +UA_AnonymousIdentityToken_equal(const UA_AnonymousIdentityToken *p1, const UA_AnonymousIdentityToken *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]) == UA_ORDER_EQ); +} + + + +/* UserNameIdentityToken */ +static UA_INLINE void +UA_UserNameIdentityToken_init(UA_UserNameIdentityToken *p) { + memset(p, 0, sizeof(UA_UserNameIdentityToken)); +} + +static UA_INLINE UA_UserNameIdentityToken * +UA_UserNameIdentityToken_new(void) { + return (UA_UserNameIdentityToken*)UA_new(&UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]); +} + +static UA_INLINE UA_StatusCode +UA_UserNameIdentityToken_copy(const UA_UserNameIdentityToken *src, UA_UserNameIdentityToken *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UserNameIdentityToken_deleteMembers(UA_UserNameIdentityToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]); +} + +static UA_INLINE void +UA_UserNameIdentityToken_clear(UA_UserNameIdentityToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]); +} + +static UA_INLINE void +UA_UserNameIdentityToken_delete(UA_UserNameIdentityToken *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]); +}static UA_INLINE UA_Boolean +UA_UserNameIdentityToken_equal(const UA_UserNameIdentityToken *p1, const UA_UserNameIdentityToken *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]) == UA_ORDER_EQ); +} + + + +/* X509IdentityToken */ +static UA_INLINE void +UA_X509IdentityToken_init(UA_X509IdentityToken *p) { + memset(p, 0, sizeof(UA_X509IdentityToken)); +} + +static UA_INLINE UA_X509IdentityToken * +UA_X509IdentityToken_new(void) { + return (UA_X509IdentityToken*)UA_new(&UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]); +} + +static UA_INLINE UA_StatusCode +UA_X509IdentityToken_copy(const UA_X509IdentityToken *src, UA_X509IdentityToken *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]); +} + +UA_DEPRECATED static UA_INLINE void +UA_X509IdentityToken_deleteMembers(UA_X509IdentityToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]); +} + +static UA_INLINE void +UA_X509IdentityToken_clear(UA_X509IdentityToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]); +} + +static UA_INLINE void +UA_X509IdentityToken_delete(UA_X509IdentityToken *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]); +}static UA_INLINE UA_Boolean +UA_X509IdentityToken_equal(const UA_X509IdentityToken *p1, const UA_X509IdentityToken *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]) == UA_ORDER_EQ); +} + + + +/* IssuedIdentityToken */ +static UA_INLINE void +UA_IssuedIdentityToken_init(UA_IssuedIdentityToken *p) { + memset(p, 0, sizeof(UA_IssuedIdentityToken)); +} + +static UA_INLINE UA_IssuedIdentityToken * +UA_IssuedIdentityToken_new(void) { + return (UA_IssuedIdentityToken*)UA_new(&UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN]); +} + +static UA_INLINE UA_StatusCode +UA_IssuedIdentityToken_copy(const UA_IssuedIdentityToken *src, UA_IssuedIdentityToken *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN]); +} + +UA_DEPRECATED static UA_INLINE void +UA_IssuedIdentityToken_deleteMembers(UA_IssuedIdentityToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN]); +} + +static UA_INLINE void +UA_IssuedIdentityToken_clear(UA_IssuedIdentityToken *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN]); +} + +static UA_INLINE void +UA_IssuedIdentityToken_delete(UA_IssuedIdentityToken *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN]); +}static UA_INLINE UA_Boolean +UA_IssuedIdentityToken_equal(const UA_IssuedIdentityToken *p1, const UA_IssuedIdentityToken *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN]) == UA_ORDER_EQ); +} + + + +/* RsaEncryptedSecret */ +static UA_INLINE void +UA_RsaEncryptedSecret_init(UA_RsaEncryptedSecret *p) { + memset(p, 0, sizeof(UA_RsaEncryptedSecret)); +} + +static UA_INLINE UA_RsaEncryptedSecret * +UA_RsaEncryptedSecret_new(void) { + return (UA_RsaEncryptedSecret*)UA_new(&UA_TYPES[UA_TYPES_RSAENCRYPTEDSECRET]); +} + +static UA_INLINE UA_StatusCode +UA_RsaEncryptedSecret_copy(const UA_RsaEncryptedSecret *src, UA_RsaEncryptedSecret *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_RSAENCRYPTEDSECRET]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RsaEncryptedSecret_deleteMembers(UA_RsaEncryptedSecret *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RSAENCRYPTEDSECRET]); +} + +static UA_INLINE void +UA_RsaEncryptedSecret_clear(UA_RsaEncryptedSecret *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RSAENCRYPTEDSECRET]); +} + +static UA_INLINE void +UA_RsaEncryptedSecret_delete(UA_RsaEncryptedSecret *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_RSAENCRYPTEDSECRET]); +}static UA_INLINE UA_Boolean +UA_RsaEncryptedSecret_equal(const UA_RsaEncryptedSecret *p1, const UA_RsaEncryptedSecret *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_RSAENCRYPTEDSECRET]) == UA_ORDER_EQ); +} + + + +/* EccEncryptedSecret */ +static UA_INLINE void +UA_EccEncryptedSecret_init(UA_EccEncryptedSecret *p) { + memset(p, 0, sizeof(UA_EccEncryptedSecret)); +} + +static UA_INLINE UA_EccEncryptedSecret * +UA_EccEncryptedSecret_new(void) { + return (UA_EccEncryptedSecret*)UA_new(&UA_TYPES[UA_TYPES_ECCENCRYPTEDSECRET]); +} + +static UA_INLINE UA_StatusCode +UA_EccEncryptedSecret_copy(const UA_EccEncryptedSecret *src, UA_EccEncryptedSecret *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ECCENCRYPTEDSECRET]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EccEncryptedSecret_deleteMembers(UA_EccEncryptedSecret *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ECCENCRYPTEDSECRET]); +} + +static UA_INLINE void +UA_EccEncryptedSecret_clear(UA_EccEncryptedSecret *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ECCENCRYPTEDSECRET]); +} + +static UA_INLINE void +UA_EccEncryptedSecret_delete(UA_EccEncryptedSecret *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ECCENCRYPTEDSECRET]); +}static UA_INLINE UA_Boolean +UA_EccEncryptedSecret_equal(const UA_EccEncryptedSecret *p1, const UA_EccEncryptedSecret *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ECCENCRYPTEDSECRET]) == UA_ORDER_EQ); +} + + + +/* ActivateSessionRequest */ +static UA_INLINE void +UA_ActivateSessionRequest_init(UA_ActivateSessionRequest *p) { + memset(p, 0, sizeof(UA_ActivateSessionRequest)); +} + +static UA_INLINE UA_ActivateSessionRequest * +UA_ActivateSessionRequest_new(void) { + return (UA_ActivateSessionRequest*)UA_new(&UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_ActivateSessionRequest_copy(const UA_ActivateSessionRequest *src, UA_ActivateSessionRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ActivateSessionRequest_deleteMembers(UA_ActivateSessionRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST]); +} + +static UA_INLINE void +UA_ActivateSessionRequest_clear(UA_ActivateSessionRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST]); +} + +static UA_INLINE void +UA_ActivateSessionRequest_delete(UA_ActivateSessionRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST]); +}static UA_INLINE UA_Boolean +UA_ActivateSessionRequest_equal(const UA_ActivateSessionRequest *p1, const UA_ActivateSessionRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST]) == UA_ORDER_EQ); +} + + + +/* ActivateSessionResponse */ +static UA_INLINE void +UA_ActivateSessionResponse_init(UA_ActivateSessionResponse *p) { + memset(p, 0, sizeof(UA_ActivateSessionResponse)); +} + +static UA_INLINE UA_ActivateSessionResponse * +UA_ActivateSessionResponse_new(void) { + return (UA_ActivateSessionResponse*)UA_new(&UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_ActivateSessionResponse_copy(const UA_ActivateSessionResponse *src, UA_ActivateSessionResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ActivateSessionResponse_deleteMembers(UA_ActivateSessionResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]); +} + +static UA_INLINE void +UA_ActivateSessionResponse_clear(UA_ActivateSessionResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]); +} + +static UA_INLINE void +UA_ActivateSessionResponse_delete(UA_ActivateSessionResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]); +}static UA_INLINE UA_Boolean +UA_ActivateSessionResponse_equal(const UA_ActivateSessionResponse *p1, const UA_ActivateSessionResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]) == UA_ORDER_EQ); +} + + + +/* CloseSessionRequest */ +static UA_INLINE void +UA_CloseSessionRequest_init(UA_CloseSessionRequest *p) { + memset(p, 0, sizeof(UA_CloseSessionRequest)); +} + +static UA_INLINE UA_CloseSessionRequest * +UA_CloseSessionRequest_new(void) { + return (UA_CloseSessionRequest*)UA_new(&UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_CloseSessionRequest_copy(const UA_CloseSessionRequest *src, UA_CloseSessionRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CloseSessionRequest_deleteMembers(UA_CloseSessionRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST]); +} + +static UA_INLINE void +UA_CloseSessionRequest_clear(UA_CloseSessionRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST]); +} + +static UA_INLINE void +UA_CloseSessionRequest_delete(UA_CloseSessionRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST]); +}static UA_INLINE UA_Boolean +UA_CloseSessionRequest_equal(const UA_CloseSessionRequest *p1, const UA_CloseSessionRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST]) == UA_ORDER_EQ); +} + + + +/* CloseSessionResponse */ +static UA_INLINE void +UA_CloseSessionResponse_init(UA_CloseSessionResponse *p) { + memset(p, 0, sizeof(UA_CloseSessionResponse)); +} + +static UA_INLINE UA_CloseSessionResponse * +UA_CloseSessionResponse_new(void) { + return (UA_CloseSessionResponse*)UA_new(&UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_CloseSessionResponse_copy(const UA_CloseSessionResponse *src, UA_CloseSessionResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CloseSessionResponse_deleteMembers(UA_CloseSessionResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE]); +} + +static UA_INLINE void +UA_CloseSessionResponse_clear(UA_CloseSessionResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE]); +} + +static UA_INLINE void +UA_CloseSessionResponse_delete(UA_CloseSessionResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE]); +}static UA_INLINE UA_Boolean +UA_CloseSessionResponse_equal(const UA_CloseSessionResponse *p1, const UA_CloseSessionResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE]) == UA_ORDER_EQ); +} + + + +/* CancelRequest */ +static UA_INLINE void +UA_CancelRequest_init(UA_CancelRequest *p) { + memset(p, 0, sizeof(UA_CancelRequest)); +} + +static UA_INLINE UA_CancelRequest * +UA_CancelRequest_new(void) { + return (UA_CancelRequest*)UA_new(&UA_TYPES[UA_TYPES_CANCELREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_CancelRequest_copy(const UA_CancelRequest *src, UA_CancelRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CANCELREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CancelRequest_deleteMembers(UA_CancelRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CANCELREQUEST]); +} + +static UA_INLINE void +UA_CancelRequest_clear(UA_CancelRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CANCELREQUEST]); +} + +static UA_INLINE void +UA_CancelRequest_delete(UA_CancelRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CANCELREQUEST]); +}static UA_INLINE UA_Boolean +UA_CancelRequest_equal(const UA_CancelRequest *p1, const UA_CancelRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CANCELREQUEST]) == UA_ORDER_EQ); +} + + + +/* CancelResponse */ +static UA_INLINE void +UA_CancelResponse_init(UA_CancelResponse *p) { + memset(p, 0, sizeof(UA_CancelResponse)); +} + +static UA_INLINE UA_CancelResponse * +UA_CancelResponse_new(void) { + return (UA_CancelResponse*)UA_new(&UA_TYPES[UA_TYPES_CANCELRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_CancelResponse_copy(const UA_CancelResponse *src, UA_CancelResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CANCELRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CancelResponse_deleteMembers(UA_CancelResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CANCELRESPONSE]); +} + +static UA_INLINE void +UA_CancelResponse_clear(UA_CancelResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CANCELRESPONSE]); +} + +static UA_INLINE void +UA_CancelResponse_delete(UA_CancelResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CANCELRESPONSE]); +}static UA_INLINE UA_Boolean +UA_CancelResponse_equal(const UA_CancelResponse *p1, const UA_CancelResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CANCELRESPONSE]) == UA_ORDER_EQ); +} + + + +/* NodeAttributesMask */ +static UA_INLINE void +UA_NodeAttributesMask_init(UA_NodeAttributesMask *p) { + memset(p, 0, sizeof(UA_NodeAttributesMask)); +} + +static UA_INLINE UA_NodeAttributesMask * +UA_NodeAttributesMask_new(void) { + return (UA_NodeAttributesMask*)UA_new(&UA_TYPES[UA_TYPES_NODEATTRIBUTESMASK]); +} + +static UA_INLINE UA_StatusCode +UA_NodeAttributesMask_copy(const UA_NodeAttributesMask *src, UA_NodeAttributesMask *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NODEATTRIBUTESMASK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NodeAttributesMask_deleteMembers(UA_NodeAttributesMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NODEATTRIBUTESMASK]); +} + +static UA_INLINE void +UA_NodeAttributesMask_clear(UA_NodeAttributesMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NODEATTRIBUTESMASK]); +} + +static UA_INLINE void +UA_NodeAttributesMask_delete(UA_NodeAttributesMask *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NODEATTRIBUTESMASK]); +}static UA_INLINE UA_Boolean +UA_NodeAttributesMask_equal(const UA_NodeAttributesMask *p1, const UA_NodeAttributesMask *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NODEATTRIBUTESMASK]) == UA_ORDER_EQ); +} + + + +/* NodeAttributes */ +static UA_INLINE void +UA_NodeAttributes_init(UA_NodeAttributes *p) { + memset(p, 0, sizeof(UA_NodeAttributes)); +} + +static UA_INLINE UA_NodeAttributes * +UA_NodeAttributes_new(void) { + return (UA_NodeAttributes*)UA_new(&UA_TYPES[UA_TYPES_NODEATTRIBUTES]); +} + +static UA_INLINE UA_StatusCode +UA_NodeAttributes_copy(const UA_NodeAttributes *src, UA_NodeAttributes *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NODEATTRIBUTES]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NodeAttributes_deleteMembers(UA_NodeAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NODEATTRIBUTES]); +} + +static UA_INLINE void +UA_NodeAttributes_clear(UA_NodeAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NODEATTRIBUTES]); +} + +static UA_INLINE void +UA_NodeAttributes_delete(UA_NodeAttributes *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NODEATTRIBUTES]); +}static UA_INLINE UA_Boolean +UA_NodeAttributes_equal(const UA_NodeAttributes *p1, const UA_NodeAttributes *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NODEATTRIBUTES]) == UA_ORDER_EQ); +} + + + +/* ObjectAttributes */ +static UA_INLINE void +UA_ObjectAttributes_init(UA_ObjectAttributes *p) { + memset(p, 0, sizeof(UA_ObjectAttributes)); +} + +static UA_INLINE UA_ObjectAttributes * +UA_ObjectAttributes_new(void) { + return (UA_ObjectAttributes*)UA_new(&UA_TYPES[UA_TYPES_OBJECTATTRIBUTES]); +} + +static UA_INLINE UA_StatusCode +UA_ObjectAttributes_copy(const UA_ObjectAttributes *src, UA_ObjectAttributes *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ObjectAttributes_deleteMembers(UA_ObjectAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES]); +} + +static UA_INLINE void +UA_ObjectAttributes_clear(UA_ObjectAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES]); +} + +static UA_INLINE void +UA_ObjectAttributes_delete(UA_ObjectAttributes *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES]); +}static UA_INLINE UA_Boolean +UA_ObjectAttributes_equal(const UA_ObjectAttributes *p1, const UA_ObjectAttributes *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES]) == UA_ORDER_EQ); +} + + + +/* VariableAttributes */ +static UA_INLINE void +UA_VariableAttributes_init(UA_VariableAttributes *p) { + memset(p, 0, sizeof(UA_VariableAttributes)); +} + +static UA_INLINE UA_VariableAttributes * +UA_VariableAttributes_new(void) { + return (UA_VariableAttributes*)UA_new(&UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES]); +} + +static UA_INLINE UA_StatusCode +UA_VariableAttributes_copy(const UA_VariableAttributes *src, UA_VariableAttributes *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES]); +} + +UA_DEPRECATED static UA_INLINE void +UA_VariableAttributes_deleteMembers(UA_VariableAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES]); +} + +static UA_INLINE void +UA_VariableAttributes_clear(UA_VariableAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES]); +} + +static UA_INLINE void +UA_VariableAttributes_delete(UA_VariableAttributes *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES]); +}static UA_INLINE UA_Boolean +UA_VariableAttributes_equal(const UA_VariableAttributes *p1, const UA_VariableAttributes *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES]) == UA_ORDER_EQ); +} + + + +/* MethodAttributes */ +static UA_INLINE void +UA_MethodAttributes_init(UA_MethodAttributes *p) { + memset(p, 0, sizeof(UA_MethodAttributes)); +} + +static UA_INLINE UA_MethodAttributes * +UA_MethodAttributes_new(void) { + return (UA_MethodAttributes*)UA_new(&UA_TYPES[UA_TYPES_METHODATTRIBUTES]); +} + +static UA_INLINE UA_StatusCode +UA_MethodAttributes_copy(const UA_MethodAttributes *src, UA_MethodAttributes *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_METHODATTRIBUTES]); +} + +UA_DEPRECATED static UA_INLINE void +UA_MethodAttributes_deleteMembers(UA_MethodAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_METHODATTRIBUTES]); +} + +static UA_INLINE void +UA_MethodAttributes_clear(UA_MethodAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_METHODATTRIBUTES]); +} + +static UA_INLINE void +UA_MethodAttributes_delete(UA_MethodAttributes *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_METHODATTRIBUTES]); +}static UA_INLINE UA_Boolean +UA_MethodAttributes_equal(const UA_MethodAttributes *p1, const UA_MethodAttributes *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_METHODATTRIBUTES]) == UA_ORDER_EQ); +} + + + +/* ObjectTypeAttributes */ +static UA_INLINE void +UA_ObjectTypeAttributes_init(UA_ObjectTypeAttributes *p) { + memset(p, 0, sizeof(UA_ObjectTypeAttributes)); +} + +static UA_INLINE UA_ObjectTypeAttributes * +UA_ObjectTypeAttributes_new(void) { + return (UA_ObjectTypeAttributes*)UA_new(&UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES]); +} + +static UA_INLINE UA_StatusCode +UA_ObjectTypeAttributes_copy(const UA_ObjectTypeAttributes *src, UA_ObjectTypeAttributes *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ObjectTypeAttributes_deleteMembers(UA_ObjectTypeAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES]); +} + +static UA_INLINE void +UA_ObjectTypeAttributes_clear(UA_ObjectTypeAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES]); +} + +static UA_INLINE void +UA_ObjectTypeAttributes_delete(UA_ObjectTypeAttributes *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES]); +}static UA_INLINE UA_Boolean +UA_ObjectTypeAttributes_equal(const UA_ObjectTypeAttributes *p1, const UA_ObjectTypeAttributes *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES]) == UA_ORDER_EQ); +} + + + +/* VariableTypeAttributes */ +static UA_INLINE void +UA_VariableTypeAttributes_init(UA_VariableTypeAttributes *p) { + memset(p, 0, sizeof(UA_VariableTypeAttributes)); +} + +static UA_INLINE UA_VariableTypeAttributes * +UA_VariableTypeAttributes_new(void) { + return (UA_VariableTypeAttributes*)UA_new(&UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES]); +} + +static UA_INLINE UA_StatusCode +UA_VariableTypeAttributes_copy(const UA_VariableTypeAttributes *src, UA_VariableTypeAttributes *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES]); +} + +UA_DEPRECATED static UA_INLINE void +UA_VariableTypeAttributes_deleteMembers(UA_VariableTypeAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES]); +} + +static UA_INLINE void +UA_VariableTypeAttributes_clear(UA_VariableTypeAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES]); +} + +static UA_INLINE void +UA_VariableTypeAttributes_delete(UA_VariableTypeAttributes *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES]); +}static UA_INLINE UA_Boolean +UA_VariableTypeAttributes_equal(const UA_VariableTypeAttributes *p1, const UA_VariableTypeAttributes *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES]) == UA_ORDER_EQ); +} + + + +/* ReferenceTypeAttributes */ +static UA_INLINE void +UA_ReferenceTypeAttributes_init(UA_ReferenceTypeAttributes *p) { + memset(p, 0, sizeof(UA_ReferenceTypeAttributes)); +} + +static UA_INLINE UA_ReferenceTypeAttributes * +UA_ReferenceTypeAttributes_new(void) { + return (UA_ReferenceTypeAttributes*)UA_new(&UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]); +} + +static UA_INLINE UA_StatusCode +UA_ReferenceTypeAttributes_copy(const UA_ReferenceTypeAttributes *src, UA_ReferenceTypeAttributes *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReferenceTypeAttributes_deleteMembers(UA_ReferenceTypeAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]); +} + +static UA_INLINE void +UA_ReferenceTypeAttributes_clear(UA_ReferenceTypeAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]); +} + +static UA_INLINE void +UA_ReferenceTypeAttributes_delete(UA_ReferenceTypeAttributes *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]); +}static UA_INLINE UA_Boolean +UA_ReferenceTypeAttributes_equal(const UA_ReferenceTypeAttributes *p1, const UA_ReferenceTypeAttributes *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]) == UA_ORDER_EQ); +} + + + +/* DataTypeAttributes */ +static UA_INLINE void +UA_DataTypeAttributes_init(UA_DataTypeAttributes *p) { + memset(p, 0, sizeof(UA_DataTypeAttributes)); +} + +static UA_INLINE UA_DataTypeAttributes * +UA_DataTypeAttributes_new(void) { + return (UA_DataTypeAttributes*)UA_new(&UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES]); +} + +static UA_INLINE UA_StatusCode +UA_DataTypeAttributes_copy(const UA_DataTypeAttributes *src, UA_DataTypeAttributes *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataTypeAttributes_deleteMembers(UA_DataTypeAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES]); +} + +static UA_INLINE void +UA_DataTypeAttributes_clear(UA_DataTypeAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES]); +} + +static UA_INLINE void +UA_DataTypeAttributes_delete(UA_DataTypeAttributes *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES]); +}static UA_INLINE UA_Boolean +UA_DataTypeAttributes_equal(const UA_DataTypeAttributes *p1, const UA_DataTypeAttributes *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES]) == UA_ORDER_EQ); +} + + + +/* ViewAttributes */ +static UA_INLINE void +UA_ViewAttributes_init(UA_ViewAttributes *p) { + memset(p, 0, sizeof(UA_ViewAttributes)); +} + +static UA_INLINE UA_ViewAttributes * +UA_ViewAttributes_new(void) { + return (UA_ViewAttributes*)UA_new(&UA_TYPES[UA_TYPES_VIEWATTRIBUTES]); +} + +static UA_INLINE UA_StatusCode +UA_ViewAttributes_copy(const UA_ViewAttributes *src, UA_ViewAttributes *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_VIEWATTRIBUTES]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ViewAttributes_deleteMembers(UA_ViewAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_VIEWATTRIBUTES]); +} + +static UA_INLINE void +UA_ViewAttributes_clear(UA_ViewAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_VIEWATTRIBUTES]); +} + +static UA_INLINE void +UA_ViewAttributes_delete(UA_ViewAttributes *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_VIEWATTRIBUTES]); +}static UA_INLINE UA_Boolean +UA_ViewAttributes_equal(const UA_ViewAttributes *p1, const UA_ViewAttributes *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_VIEWATTRIBUTES]) == UA_ORDER_EQ); +} + + + +/* GenericAttributeValue */ +static UA_INLINE void +UA_GenericAttributeValue_init(UA_GenericAttributeValue *p) { + memset(p, 0, sizeof(UA_GenericAttributeValue)); +} + +static UA_INLINE UA_GenericAttributeValue * +UA_GenericAttributeValue_new(void) { + return (UA_GenericAttributeValue*)UA_new(&UA_TYPES[UA_TYPES_GENERICATTRIBUTEVALUE]); +} + +static UA_INLINE UA_StatusCode +UA_GenericAttributeValue_copy(const UA_GenericAttributeValue *src, UA_GenericAttributeValue *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_GENERICATTRIBUTEVALUE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_GenericAttributeValue_deleteMembers(UA_GenericAttributeValue *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_GENERICATTRIBUTEVALUE]); +} + +static UA_INLINE void +UA_GenericAttributeValue_clear(UA_GenericAttributeValue *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_GENERICATTRIBUTEVALUE]); +} + +static UA_INLINE void +UA_GenericAttributeValue_delete(UA_GenericAttributeValue *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_GENERICATTRIBUTEVALUE]); +}static UA_INLINE UA_Boolean +UA_GenericAttributeValue_equal(const UA_GenericAttributeValue *p1, const UA_GenericAttributeValue *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_GENERICATTRIBUTEVALUE]) == UA_ORDER_EQ); +} + + + +/* GenericAttributes */ +static UA_INLINE void +UA_GenericAttributes_init(UA_GenericAttributes *p) { + memset(p, 0, sizeof(UA_GenericAttributes)); +} + +static UA_INLINE UA_GenericAttributes * +UA_GenericAttributes_new(void) { + return (UA_GenericAttributes*)UA_new(&UA_TYPES[UA_TYPES_GENERICATTRIBUTES]); +} + +static UA_INLINE UA_StatusCode +UA_GenericAttributes_copy(const UA_GenericAttributes *src, UA_GenericAttributes *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_GENERICATTRIBUTES]); +} + +UA_DEPRECATED static UA_INLINE void +UA_GenericAttributes_deleteMembers(UA_GenericAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_GENERICATTRIBUTES]); +} + +static UA_INLINE void +UA_GenericAttributes_clear(UA_GenericAttributes *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_GENERICATTRIBUTES]); +} + +static UA_INLINE void +UA_GenericAttributes_delete(UA_GenericAttributes *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_GENERICATTRIBUTES]); +}static UA_INLINE UA_Boolean +UA_GenericAttributes_equal(const UA_GenericAttributes *p1, const UA_GenericAttributes *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_GENERICATTRIBUTES]) == UA_ORDER_EQ); +} + + + +/* AddNodesItem */ +static UA_INLINE void +UA_AddNodesItem_init(UA_AddNodesItem *p) { + memset(p, 0, sizeof(UA_AddNodesItem)); +} + +static UA_INLINE UA_AddNodesItem * +UA_AddNodesItem_new(void) { + return (UA_AddNodesItem*)UA_new(&UA_TYPES[UA_TYPES_ADDNODESITEM]); +} + +static UA_INLINE UA_StatusCode +UA_AddNodesItem_copy(const UA_AddNodesItem *src, UA_AddNodesItem *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ADDNODESITEM]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AddNodesItem_deleteMembers(UA_AddNodesItem *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDNODESITEM]); +} + +static UA_INLINE void +UA_AddNodesItem_clear(UA_AddNodesItem *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDNODESITEM]); +} + +static UA_INLINE void +UA_AddNodesItem_delete(UA_AddNodesItem *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ADDNODESITEM]); +}static UA_INLINE UA_Boolean +UA_AddNodesItem_equal(const UA_AddNodesItem *p1, const UA_AddNodesItem *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ADDNODESITEM]) == UA_ORDER_EQ); +} + + + +/* AddNodesResult */ +static UA_INLINE void +UA_AddNodesResult_init(UA_AddNodesResult *p) { + memset(p, 0, sizeof(UA_AddNodesResult)); +} + +static UA_INLINE UA_AddNodesResult * +UA_AddNodesResult_new(void) { + return (UA_AddNodesResult*)UA_new(&UA_TYPES[UA_TYPES_ADDNODESRESULT]); +} + +static UA_INLINE UA_StatusCode +UA_AddNodesResult_copy(const UA_AddNodesResult *src, UA_AddNodesResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ADDNODESRESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AddNodesResult_deleteMembers(UA_AddNodesResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDNODESRESULT]); +} + +static UA_INLINE void +UA_AddNodesResult_clear(UA_AddNodesResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDNODESRESULT]); +} + +static UA_INLINE void +UA_AddNodesResult_delete(UA_AddNodesResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ADDNODESRESULT]); +}static UA_INLINE UA_Boolean +UA_AddNodesResult_equal(const UA_AddNodesResult *p1, const UA_AddNodesResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ADDNODESRESULT]) == UA_ORDER_EQ); +} + + + +/* AddNodesRequest */ +static UA_INLINE void +UA_AddNodesRequest_init(UA_AddNodesRequest *p) { + memset(p, 0, sizeof(UA_AddNodesRequest)); +} + +static UA_INLINE UA_AddNodesRequest * +UA_AddNodesRequest_new(void) { + return (UA_AddNodesRequest*)UA_new(&UA_TYPES[UA_TYPES_ADDNODESREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_AddNodesRequest_copy(const UA_AddNodesRequest *src, UA_AddNodesRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ADDNODESREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AddNodesRequest_deleteMembers(UA_AddNodesRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDNODESREQUEST]); +} + +static UA_INLINE void +UA_AddNodesRequest_clear(UA_AddNodesRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDNODESREQUEST]); +} + +static UA_INLINE void +UA_AddNodesRequest_delete(UA_AddNodesRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ADDNODESREQUEST]); +}static UA_INLINE UA_Boolean +UA_AddNodesRequest_equal(const UA_AddNodesRequest *p1, const UA_AddNodesRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ADDNODESREQUEST]) == UA_ORDER_EQ); +} + + + +/* AddNodesResponse */ +static UA_INLINE void +UA_AddNodesResponse_init(UA_AddNodesResponse *p) { + memset(p, 0, sizeof(UA_AddNodesResponse)); +} + +static UA_INLINE UA_AddNodesResponse * +UA_AddNodesResponse_new(void) { + return (UA_AddNodesResponse*)UA_new(&UA_TYPES[UA_TYPES_ADDNODESRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_AddNodesResponse_copy(const UA_AddNodesResponse *src, UA_AddNodesResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ADDNODESRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AddNodesResponse_deleteMembers(UA_AddNodesResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDNODESRESPONSE]); +} + +static UA_INLINE void +UA_AddNodesResponse_clear(UA_AddNodesResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDNODESRESPONSE]); +} + +static UA_INLINE void +UA_AddNodesResponse_delete(UA_AddNodesResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ADDNODESRESPONSE]); +}static UA_INLINE UA_Boolean +UA_AddNodesResponse_equal(const UA_AddNodesResponse *p1, const UA_AddNodesResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ADDNODESRESPONSE]) == UA_ORDER_EQ); +} + + + +/* AddReferencesItem */ +static UA_INLINE void +UA_AddReferencesItem_init(UA_AddReferencesItem *p) { + memset(p, 0, sizeof(UA_AddReferencesItem)); +} + +static UA_INLINE UA_AddReferencesItem * +UA_AddReferencesItem_new(void) { + return (UA_AddReferencesItem*)UA_new(&UA_TYPES[UA_TYPES_ADDREFERENCESITEM]); +} + +static UA_INLINE UA_StatusCode +UA_AddReferencesItem_copy(const UA_AddReferencesItem *src, UA_AddReferencesItem *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ADDREFERENCESITEM]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AddReferencesItem_deleteMembers(UA_AddReferencesItem *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDREFERENCESITEM]); +} + +static UA_INLINE void +UA_AddReferencesItem_clear(UA_AddReferencesItem *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDREFERENCESITEM]); +} + +static UA_INLINE void +UA_AddReferencesItem_delete(UA_AddReferencesItem *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ADDREFERENCESITEM]); +}static UA_INLINE UA_Boolean +UA_AddReferencesItem_equal(const UA_AddReferencesItem *p1, const UA_AddReferencesItem *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ADDREFERENCESITEM]) == UA_ORDER_EQ); +} + + + +/* AddReferencesRequest */ +static UA_INLINE void +UA_AddReferencesRequest_init(UA_AddReferencesRequest *p) { + memset(p, 0, sizeof(UA_AddReferencesRequest)); +} + +static UA_INLINE UA_AddReferencesRequest * +UA_AddReferencesRequest_new(void) { + return (UA_AddReferencesRequest*)UA_new(&UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_AddReferencesRequest_copy(const UA_AddReferencesRequest *src, UA_AddReferencesRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AddReferencesRequest_deleteMembers(UA_AddReferencesRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST]); +} + +static UA_INLINE void +UA_AddReferencesRequest_clear(UA_AddReferencesRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST]); +} + +static UA_INLINE void +UA_AddReferencesRequest_delete(UA_AddReferencesRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST]); +}static UA_INLINE UA_Boolean +UA_AddReferencesRequest_equal(const UA_AddReferencesRequest *p1, const UA_AddReferencesRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST]) == UA_ORDER_EQ); +} + + + +/* AddReferencesResponse */ +static UA_INLINE void +UA_AddReferencesResponse_init(UA_AddReferencesResponse *p) { + memset(p, 0, sizeof(UA_AddReferencesResponse)); +} + +static UA_INLINE UA_AddReferencesResponse * +UA_AddReferencesResponse_new(void) { + return (UA_AddReferencesResponse*)UA_new(&UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_AddReferencesResponse_copy(const UA_AddReferencesResponse *src, UA_AddReferencesResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AddReferencesResponse_deleteMembers(UA_AddReferencesResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE]); +} + +static UA_INLINE void +UA_AddReferencesResponse_clear(UA_AddReferencesResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE]); +} + +static UA_INLINE void +UA_AddReferencesResponse_delete(UA_AddReferencesResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE]); +}static UA_INLINE UA_Boolean +UA_AddReferencesResponse_equal(const UA_AddReferencesResponse *p1, const UA_AddReferencesResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE]) == UA_ORDER_EQ); +} + + + +/* DeleteNodesItem */ +static UA_INLINE void +UA_DeleteNodesItem_init(UA_DeleteNodesItem *p) { + memset(p, 0, sizeof(UA_DeleteNodesItem)); +} + +static UA_INLINE UA_DeleteNodesItem * +UA_DeleteNodesItem_new(void) { + return (UA_DeleteNodesItem*)UA_new(&UA_TYPES[UA_TYPES_DELETENODESITEM]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteNodesItem_copy(const UA_DeleteNodesItem *src, UA_DeleteNodesItem *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETENODESITEM]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteNodesItem_deleteMembers(UA_DeleteNodesItem *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETENODESITEM]); +} + +static UA_INLINE void +UA_DeleteNodesItem_clear(UA_DeleteNodesItem *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETENODESITEM]); +} + +static UA_INLINE void +UA_DeleteNodesItem_delete(UA_DeleteNodesItem *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETENODESITEM]); +}static UA_INLINE UA_Boolean +UA_DeleteNodesItem_equal(const UA_DeleteNodesItem *p1, const UA_DeleteNodesItem *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETENODESITEM]) == UA_ORDER_EQ); +} + + + +/* DeleteNodesRequest */ +static UA_INLINE void +UA_DeleteNodesRequest_init(UA_DeleteNodesRequest *p) { + memset(p, 0, sizeof(UA_DeleteNodesRequest)); +} + +static UA_INLINE UA_DeleteNodesRequest * +UA_DeleteNodesRequest_new(void) { + return (UA_DeleteNodesRequest*)UA_new(&UA_TYPES[UA_TYPES_DELETENODESREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteNodesRequest_copy(const UA_DeleteNodesRequest *src, UA_DeleteNodesRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETENODESREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteNodesRequest_deleteMembers(UA_DeleteNodesRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETENODESREQUEST]); +} + +static UA_INLINE void +UA_DeleteNodesRequest_clear(UA_DeleteNodesRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETENODESREQUEST]); +} + +static UA_INLINE void +UA_DeleteNodesRequest_delete(UA_DeleteNodesRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETENODESREQUEST]); +}static UA_INLINE UA_Boolean +UA_DeleteNodesRequest_equal(const UA_DeleteNodesRequest *p1, const UA_DeleteNodesRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETENODESREQUEST]) == UA_ORDER_EQ); +} + + + +/* DeleteNodesResponse */ +static UA_INLINE void +UA_DeleteNodesResponse_init(UA_DeleteNodesResponse *p) { + memset(p, 0, sizeof(UA_DeleteNodesResponse)); +} + +static UA_INLINE UA_DeleteNodesResponse * +UA_DeleteNodesResponse_new(void) { + return (UA_DeleteNodesResponse*)UA_new(&UA_TYPES[UA_TYPES_DELETENODESRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteNodesResponse_copy(const UA_DeleteNodesResponse *src, UA_DeleteNodesResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETENODESRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteNodesResponse_deleteMembers(UA_DeleteNodesResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETENODESRESPONSE]); +} + +static UA_INLINE void +UA_DeleteNodesResponse_clear(UA_DeleteNodesResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETENODESRESPONSE]); +} + +static UA_INLINE void +UA_DeleteNodesResponse_delete(UA_DeleteNodesResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETENODESRESPONSE]); +}static UA_INLINE UA_Boolean +UA_DeleteNodesResponse_equal(const UA_DeleteNodesResponse *p1, const UA_DeleteNodesResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETENODESRESPONSE]) == UA_ORDER_EQ); +} + + + +/* DeleteReferencesItem */ +static UA_INLINE void +UA_DeleteReferencesItem_init(UA_DeleteReferencesItem *p) { + memset(p, 0, sizeof(UA_DeleteReferencesItem)); +} + +static UA_INLINE UA_DeleteReferencesItem * +UA_DeleteReferencesItem_new(void) { + return (UA_DeleteReferencesItem*)UA_new(&UA_TYPES[UA_TYPES_DELETEREFERENCESITEM]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteReferencesItem_copy(const UA_DeleteReferencesItem *src, UA_DeleteReferencesItem *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteReferencesItem_deleteMembers(UA_DeleteReferencesItem *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM]); +} + +static UA_INLINE void +UA_DeleteReferencesItem_clear(UA_DeleteReferencesItem *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM]); +} + +static UA_INLINE void +UA_DeleteReferencesItem_delete(UA_DeleteReferencesItem *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM]); +}static UA_INLINE UA_Boolean +UA_DeleteReferencesItem_equal(const UA_DeleteReferencesItem *p1, const UA_DeleteReferencesItem *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM]) == UA_ORDER_EQ); +} + + + +/* DeleteReferencesRequest */ +static UA_INLINE void +UA_DeleteReferencesRequest_init(UA_DeleteReferencesRequest *p) { + memset(p, 0, sizeof(UA_DeleteReferencesRequest)); +} + +static UA_INLINE UA_DeleteReferencesRequest * +UA_DeleteReferencesRequest_new(void) { + return (UA_DeleteReferencesRequest*)UA_new(&UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteReferencesRequest_copy(const UA_DeleteReferencesRequest *src, UA_DeleteReferencesRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteReferencesRequest_deleteMembers(UA_DeleteReferencesRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST]); +} + +static UA_INLINE void +UA_DeleteReferencesRequest_clear(UA_DeleteReferencesRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST]); +} + +static UA_INLINE void +UA_DeleteReferencesRequest_delete(UA_DeleteReferencesRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST]); +}static UA_INLINE UA_Boolean +UA_DeleteReferencesRequest_equal(const UA_DeleteReferencesRequest *p1, const UA_DeleteReferencesRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST]) == UA_ORDER_EQ); +} + + + +/* DeleteReferencesResponse */ +static UA_INLINE void +UA_DeleteReferencesResponse_init(UA_DeleteReferencesResponse *p) { + memset(p, 0, sizeof(UA_DeleteReferencesResponse)); +} + +static UA_INLINE UA_DeleteReferencesResponse * +UA_DeleteReferencesResponse_new(void) { + return (UA_DeleteReferencesResponse*)UA_new(&UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteReferencesResponse_copy(const UA_DeleteReferencesResponse *src, UA_DeleteReferencesResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteReferencesResponse_deleteMembers(UA_DeleteReferencesResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE]); +} + +static UA_INLINE void +UA_DeleteReferencesResponse_clear(UA_DeleteReferencesResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE]); +} + +static UA_INLINE void +UA_DeleteReferencesResponse_delete(UA_DeleteReferencesResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE]); +}static UA_INLINE UA_Boolean +UA_DeleteReferencesResponse_equal(const UA_DeleteReferencesResponse *p1, const UA_DeleteReferencesResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE]) == UA_ORDER_EQ); +} + + + +/* AttributeWriteMask */ +static UA_INLINE void +UA_AttributeWriteMask_init(UA_AttributeWriteMask *p) { + memset(p, 0, sizeof(UA_AttributeWriteMask)); +} + +static UA_INLINE UA_AttributeWriteMask * +UA_AttributeWriteMask_new(void) { + return (UA_AttributeWriteMask*)UA_new(&UA_TYPES[UA_TYPES_ATTRIBUTEWRITEMASK]); +} + +static UA_INLINE UA_StatusCode +UA_AttributeWriteMask_copy(const UA_AttributeWriteMask *src, UA_AttributeWriteMask *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ATTRIBUTEWRITEMASK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AttributeWriteMask_deleteMembers(UA_AttributeWriteMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ATTRIBUTEWRITEMASK]); +} + +static UA_INLINE void +UA_AttributeWriteMask_clear(UA_AttributeWriteMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ATTRIBUTEWRITEMASK]); +} + +static UA_INLINE void +UA_AttributeWriteMask_delete(UA_AttributeWriteMask *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ATTRIBUTEWRITEMASK]); +}static UA_INLINE UA_Boolean +UA_AttributeWriteMask_equal(const UA_AttributeWriteMask *p1, const UA_AttributeWriteMask *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ATTRIBUTEWRITEMASK]) == UA_ORDER_EQ); +} + + + +/* BrowseDirection */ +static UA_INLINE void +UA_BrowseDirection_init(UA_BrowseDirection *p) { + memset(p, 0, sizeof(UA_BrowseDirection)); +} + +static UA_INLINE UA_BrowseDirection * +UA_BrowseDirection_new(void) { + return (UA_BrowseDirection*)UA_new(&UA_TYPES[UA_TYPES_BROWSEDIRECTION]); +} + +static UA_INLINE UA_StatusCode +UA_BrowseDirection_copy(const UA_BrowseDirection *src, UA_BrowseDirection *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROWSEDIRECTION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrowseDirection_deleteMembers(UA_BrowseDirection *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSEDIRECTION]); +} + +static UA_INLINE void +UA_BrowseDirection_clear(UA_BrowseDirection *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSEDIRECTION]); +} + +static UA_INLINE void +UA_BrowseDirection_delete(UA_BrowseDirection *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROWSEDIRECTION]); +}static UA_INLINE UA_Boolean +UA_BrowseDirection_equal(const UA_BrowseDirection *p1, const UA_BrowseDirection *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROWSEDIRECTION]) == UA_ORDER_EQ); +} + + + +/* ViewDescription */ +static UA_INLINE void +UA_ViewDescription_init(UA_ViewDescription *p) { + memset(p, 0, sizeof(UA_ViewDescription)); +} + +static UA_INLINE UA_ViewDescription * +UA_ViewDescription_new(void) { + return (UA_ViewDescription*)UA_new(&UA_TYPES[UA_TYPES_VIEWDESCRIPTION]); +} + +static UA_INLINE UA_StatusCode +UA_ViewDescription_copy(const UA_ViewDescription *src, UA_ViewDescription *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_VIEWDESCRIPTION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ViewDescription_deleteMembers(UA_ViewDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_VIEWDESCRIPTION]); +} + +static UA_INLINE void +UA_ViewDescription_clear(UA_ViewDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_VIEWDESCRIPTION]); +} + +static UA_INLINE void +UA_ViewDescription_delete(UA_ViewDescription *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_VIEWDESCRIPTION]); +}static UA_INLINE UA_Boolean +UA_ViewDescription_equal(const UA_ViewDescription *p1, const UA_ViewDescription *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_VIEWDESCRIPTION]) == UA_ORDER_EQ); +} + + + +/* BrowseDescription */ +static UA_INLINE void +UA_BrowseDescription_init(UA_BrowseDescription *p) { + memset(p, 0, sizeof(UA_BrowseDescription)); +} + +static UA_INLINE UA_BrowseDescription * +UA_BrowseDescription_new(void) { + return (UA_BrowseDescription*)UA_new(&UA_TYPES[UA_TYPES_BROWSEDESCRIPTION]); +} + +static UA_INLINE UA_StatusCode +UA_BrowseDescription_copy(const UA_BrowseDescription *src, UA_BrowseDescription *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrowseDescription_deleteMembers(UA_BrowseDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION]); +} + +static UA_INLINE void +UA_BrowseDescription_clear(UA_BrowseDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION]); +} + +static UA_INLINE void +UA_BrowseDescription_delete(UA_BrowseDescription *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION]); +}static UA_INLINE UA_Boolean +UA_BrowseDescription_equal(const UA_BrowseDescription *p1, const UA_BrowseDescription *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION]) == UA_ORDER_EQ); +} + + + +/* BrowseResultMask */ +static UA_INLINE void +UA_BrowseResultMask_init(UA_BrowseResultMask *p) { + memset(p, 0, sizeof(UA_BrowseResultMask)); +} + +static UA_INLINE UA_BrowseResultMask * +UA_BrowseResultMask_new(void) { + return (UA_BrowseResultMask*)UA_new(&UA_TYPES[UA_TYPES_BROWSERESULTMASK]); +} + +static UA_INLINE UA_StatusCode +UA_BrowseResultMask_copy(const UA_BrowseResultMask *src, UA_BrowseResultMask *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROWSERESULTMASK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrowseResultMask_deleteMembers(UA_BrowseResultMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSERESULTMASK]); +} + +static UA_INLINE void +UA_BrowseResultMask_clear(UA_BrowseResultMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSERESULTMASK]); +} + +static UA_INLINE void +UA_BrowseResultMask_delete(UA_BrowseResultMask *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROWSERESULTMASK]); +}static UA_INLINE UA_Boolean +UA_BrowseResultMask_equal(const UA_BrowseResultMask *p1, const UA_BrowseResultMask *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROWSERESULTMASK]) == UA_ORDER_EQ); +} + + + +/* ReferenceDescription */ +static UA_INLINE void +UA_ReferenceDescription_init(UA_ReferenceDescription *p) { + memset(p, 0, sizeof(UA_ReferenceDescription)); +} + +static UA_INLINE UA_ReferenceDescription * +UA_ReferenceDescription_new(void) { + return (UA_ReferenceDescription*)UA_new(&UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION]); +} + +static UA_INLINE UA_StatusCode +UA_ReferenceDescription_copy(const UA_ReferenceDescription *src, UA_ReferenceDescription *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReferenceDescription_deleteMembers(UA_ReferenceDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION]); +} + +static UA_INLINE void +UA_ReferenceDescription_clear(UA_ReferenceDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION]); +} + +static UA_INLINE void +UA_ReferenceDescription_delete(UA_ReferenceDescription *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION]); +}static UA_INLINE UA_Boolean +UA_ReferenceDescription_equal(const UA_ReferenceDescription *p1, const UA_ReferenceDescription *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION]) == UA_ORDER_EQ); +} + + + +/* ContinuationPoint */ +static UA_INLINE void +UA_ContinuationPoint_init(UA_ContinuationPoint *p) { + memset(p, 0, sizeof(UA_ContinuationPoint)); +} + +static UA_INLINE UA_ContinuationPoint * +UA_ContinuationPoint_new(void) { + return (UA_ContinuationPoint*)UA_new(&UA_TYPES[UA_TYPES_CONTINUATIONPOINT]); +} + +static UA_INLINE UA_StatusCode +UA_ContinuationPoint_copy(const UA_ContinuationPoint *src, UA_ContinuationPoint *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CONTINUATIONPOINT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ContinuationPoint_deleteMembers(UA_ContinuationPoint *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CONTINUATIONPOINT]); +} + +static UA_INLINE void +UA_ContinuationPoint_clear(UA_ContinuationPoint *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CONTINUATIONPOINT]); +} + +static UA_INLINE void +UA_ContinuationPoint_delete(UA_ContinuationPoint *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CONTINUATIONPOINT]); +}static UA_INLINE UA_Boolean +UA_ContinuationPoint_equal(const UA_ContinuationPoint *p1, const UA_ContinuationPoint *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CONTINUATIONPOINT]) == UA_ORDER_EQ); +} + + + +/* BrowseResult */ +static UA_INLINE void +UA_BrowseResult_init(UA_BrowseResult *p) { + memset(p, 0, sizeof(UA_BrowseResult)); +} + +static UA_INLINE UA_BrowseResult * +UA_BrowseResult_new(void) { + return (UA_BrowseResult*)UA_new(&UA_TYPES[UA_TYPES_BROWSERESULT]); +} + +static UA_INLINE UA_StatusCode +UA_BrowseResult_copy(const UA_BrowseResult *src, UA_BrowseResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROWSERESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrowseResult_deleteMembers(UA_BrowseResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSERESULT]); +} + +static UA_INLINE void +UA_BrowseResult_clear(UA_BrowseResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSERESULT]); +} + +static UA_INLINE void +UA_BrowseResult_delete(UA_BrowseResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROWSERESULT]); +}static UA_INLINE UA_Boolean +UA_BrowseResult_equal(const UA_BrowseResult *p1, const UA_BrowseResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROWSERESULT]) == UA_ORDER_EQ); +} + + + +/* BrowseRequest */ +static UA_INLINE void +UA_BrowseRequest_init(UA_BrowseRequest *p) { + memset(p, 0, sizeof(UA_BrowseRequest)); +} + +static UA_INLINE UA_BrowseRequest * +UA_BrowseRequest_new(void) { + return (UA_BrowseRequest*)UA_new(&UA_TYPES[UA_TYPES_BROWSEREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_BrowseRequest_copy(const UA_BrowseRequest *src, UA_BrowseRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROWSEREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrowseRequest_deleteMembers(UA_BrowseRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSEREQUEST]); +} + +static UA_INLINE void +UA_BrowseRequest_clear(UA_BrowseRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSEREQUEST]); +} + +static UA_INLINE void +UA_BrowseRequest_delete(UA_BrowseRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROWSEREQUEST]); +}static UA_INLINE UA_Boolean +UA_BrowseRequest_equal(const UA_BrowseRequest *p1, const UA_BrowseRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROWSEREQUEST]) == UA_ORDER_EQ); +} + + + +/* BrowseResponse */ +static UA_INLINE void +UA_BrowseResponse_init(UA_BrowseResponse *p) { + memset(p, 0, sizeof(UA_BrowseResponse)); +} + +static UA_INLINE UA_BrowseResponse * +UA_BrowseResponse_new(void) { + return (UA_BrowseResponse*)UA_new(&UA_TYPES[UA_TYPES_BROWSERESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_BrowseResponse_copy(const UA_BrowseResponse *src, UA_BrowseResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROWSERESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrowseResponse_deleteMembers(UA_BrowseResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSERESPONSE]); +} + +static UA_INLINE void +UA_BrowseResponse_clear(UA_BrowseResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSERESPONSE]); +} + +static UA_INLINE void +UA_BrowseResponse_delete(UA_BrowseResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROWSERESPONSE]); +}static UA_INLINE UA_Boolean +UA_BrowseResponse_equal(const UA_BrowseResponse *p1, const UA_BrowseResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROWSERESPONSE]) == UA_ORDER_EQ); +} + + + +/* BrowseNextRequest */ +static UA_INLINE void +UA_BrowseNextRequest_init(UA_BrowseNextRequest *p) { + memset(p, 0, sizeof(UA_BrowseNextRequest)); +} + +static UA_INLINE UA_BrowseNextRequest * +UA_BrowseNextRequest_new(void) { + return (UA_BrowseNextRequest*)UA_new(&UA_TYPES[UA_TYPES_BROWSENEXTREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_BrowseNextRequest_copy(const UA_BrowseNextRequest *src, UA_BrowseNextRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrowseNextRequest_deleteMembers(UA_BrowseNextRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST]); +} + +static UA_INLINE void +UA_BrowseNextRequest_clear(UA_BrowseNextRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST]); +} + +static UA_INLINE void +UA_BrowseNextRequest_delete(UA_BrowseNextRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST]); +}static UA_INLINE UA_Boolean +UA_BrowseNextRequest_equal(const UA_BrowseNextRequest *p1, const UA_BrowseNextRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST]) == UA_ORDER_EQ); +} + + + +/* BrowseNextResponse */ +static UA_INLINE void +UA_BrowseNextResponse_init(UA_BrowseNextResponse *p) { + memset(p, 0, sizeof(UA_BrowseNextResponse)); +} + +static UA_INLINE UA_BrowseNextResponse * +UA_BrowseNextResponse_new(void) { + return (UA_BrowseNextResponse*)UA_new(&UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_BrowseNextResponse_copy(const UA_BrowseNextResponse *src, UA_BrowseNextResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrowseNextResponse_deleteMembers(UA_BrowseNextResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE]); +} + +static UA_INLINE void +UA_BrowseNextResponse_clear(UA_BrowseNextResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE]); +} + +static UA_INLINE void +UA_BrowseNextResponse_delete(UA_BrowseNextResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE]); +}static UA_INLINE UA_Boolean +UA_BrowseNextResponse_equal(const UA_BrowseNextResponse *p1, const UA_BrowseNextResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE]) == UA_ORDER_EQ); +} + + + +/* RelativePathElement */ +static UA_INLINE void +UA_RelativePathElement_init(UA_RelativePathElement *p) { + memset(p, 0, sizeof(UA_RelativePathElement)); +} + +static UA_INLINE UA_RelativePathElement * +UA_RelativePathElement_new(void) { + return (UA_RelativePathElement*)UA_new(&UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]); +} + +static UA_INLINE UA_StatusCode +UA_RelativePathElement_copy(const UA_RelativePathElement *src, UA_RelativePathElement *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RelativePathElement_deleteMembers(UA_RelativePathElement *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]); +} + +static UA_INLINE void +UA_RelativePathElement_clear(UA_RelativePathElement *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]); +} + +static UA_INLINE void +UA_RelativePathElement_delete(UA_RelativePathElement *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]); +}static UA_INLINE UA_Boolean +UA_RelativePathElement_equal(const UA_RelativePathElement *p1, const UA_RelativePathElement *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]) == UA_ORDER_EQ); +} + + + +/* RelativePath */ +static UA_INLINE void +UA_RelativePath_init(UA_RelativePath *p) { + memset(p, 0, sizeof(UA_RelativePath)); +} + +static UA_INLINE UA_RelativePath * +UA_RelativePath_new(void) { + return (UA_RelativePath*)UA_new(&UA_TYPES[UA_TYPES_RELATIVEPATH]); +} + +static UA_INLINE UA_StatusCode +UA_RelativePath_copy(const UA_RelativePath *src, UA_RelativePath *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_RELATIVEPATH]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RelativePath_deleteMembers(UA_RelativePath *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RELATIVEPATH]); +} + +static UA_INLINE void +UA_RelativePath_clear(UA_RelativePath *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RELATIVEPATH]); +} + +static UA_INLINE void +UA_RelativePath_delete(UA_RelativePath *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_RELATIVEPATH]); +}static UA_INLINE UA_Boolean +UA_RelativePath_equal(const UA_RelativePath *p1, const UA_RelativePath *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_RELATIVEPATH]) == UA_ORDER_EQ); +} + + + +/* BrowsePath */ +static UA_INLINE void +UA_BrowsePath_init(UA_BrowsePath *p) { + memset(p, 0, sizeof(UA_BrowsePath)); +} + +static UA_INLINE UA_BrowsePath * +UA_BrowsePath_new(void) { + return (UA_BrowsePath*)UA_new(&UA_TYPES[UA_TYPES_BROWSEPATH]); +} + +static UA_INLINE UA_StatusCode +UA_BrowsePath_copy(const UA_BrowsePath *src, UA_BrowsePath *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROWSEPATH]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrowsePath_deleteMembers(UA_BrowsePath *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSEPATH]); +} + +static UA_INLINE void +UA_BrowsePath_clear(UA_BrowsePath *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSEPATH]); +} + +static UA_INLINE void +UA_BrowsePath_delete(UA_BrowsePath *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROWSEPATH]); +}static UA_INLINE UA_Boolean +UA_BrowsePath_equal(const UA_BrowsePath *p1, const UA_BrowsePath *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROWSEPATH]) == UA_ORDER_EQ); +} + + + +/* BrowsePathTarget */ +static UA_INLINE void +UA_BrowsePathTarget_init(UA_BrowsePathTarget *p) { + memset(p, 0, sizeof(UA_BrowsePathTarget)); +} + +static UA_INLINE UA_BrowsePathTarget * +UA_BrowsePathTarget_new(void) { + return (UA_BrowsePathTarget*)UA_new(&UA_TYPES[UA_TYPES_BROWSEPATHTARGET]); +} + +static UA_INLINE UA_StatusCode +UA_BrowsePathTarget_copy(const UA_BrowsePathTarget *src, UA_BrowsePathTarget *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROWSEPATHTARGET]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrowsePathTarget_deleteMembers(UA_BrowsePathTarget *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSEPATHTARGET]); +} + +static UA_INLINE void +UA_BrowsePathTarget_clear(UA_BrowsePathTarget *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSEPATHTARGET]); +} + +static UA_INLINE void +UA_BrowsePathTarget_delete(UA_BrowsePathTarget *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROWSEPATHTARGET]); +}static UA_INLINE UA_Boolean +UA_BrowsePathTarget_equal(const UA_BrowsePathTarget *p1, const UA_BrowsePathTarget *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROWSEPATHTARGET]) == UA_ORDER_EQ); +} + + + +/* BrowsePathResult */ +static UA_INLINE void +UA_BrowsePathResult_init(UA_BrowsePathResult *p) { + memset(p, 0, sizeof(UA_BrowsePathResult)); +} + +static UA_INLINE UA_BrowsePathResult * +UA_BrowsePathResult_new(void) { + return (UA_BrowsePathResult*)UA_new(&UA_TYPES[UA_TYPES_BROWSEPATHRESULT]); +} + +static UA_INLINE UA_StatusCode +UA_BrowsePathResult_copy(const UA_BrowsePathResult *src, UA_BrowsePathResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BROWSEPATHRESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BrowsePathResult_deleteMembers(UA_BrowsePathResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSEPATHRESULT]); +} + +static UA_INLINE void +UA_BrowsePathResult_clear(UA_BrowsePathResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BROWSEPATHRESULT]); +} + +static UA_INLINE void +UA_BrowsePathResult_delete(UA_BrowsePathResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BROWSEPATHRESULT]); +}static UA_INLINE UA_Boolean +UA_BrowsePathResult_equal(const UA_BrowsePathResult *p1, const UA_BrowsePathResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BROWSEPATHRESULT]) == UA_ORDER_EQ); +} + + + +/* TranslateBrowsePathsToNodeIdsRequest */ +static UA_INLINE void +UA_TranslateBrowsePathsToNodeIdsRequest_init(UA_TranslateBrowsePathsToNodeIdsRequest *p) { + memset(p, 0, sizeof(UA_TranslateBrowsePathsToNodeIdsRequest)); +} + +static UA_INLINE UA_TranslateBrowsePathsToNodeIdsRequest * +UA_TranslateBrowsePathsToNodeIdsRequest_new(void) { + return (UA_TranslateBrowsePathsToNodeIdsRequest*)UA_new(&UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_TranslateBrowsePathsToNodeIdsRequest_copy(const UA_TranslateBrowsePathsToNodeIdsRequest *src, UA_TranslateBrowsePathsToNodeIdsRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TranslateBrowsePathsToNodeIdsRequest_deleteMembers(UA_TranslateBrowsePathsToNodeIdsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST]); +} + +static UA_INLINE void +UA_TranslateBrowsePathsToNodeIdsRequest_clear(UA_TranslateBrowsePathsToNodeIdsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST]); +} + +static UA_INLINE void +UA_TranslateBrowsePathsToNodeIdsRequest_delete(UA_TranslateBrowsePathsToNodeIdsRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST]); +}static UA_INLINE UA_Boolean +UA_TranslateBrowsePathsToNodeIdsRequest_equal(const UA_TranslateBrowsePathsToNodeIdsRequest *p1, const UA_TranslateBrowsePathsToNodeIdsRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST]) == UA_ORDER_EQ); +} + + + +/* TranslateBrowsePathsToNodeIdsResponse */ +static UA_INLINE void +UA_TranslateBrowsePathsToNodeIdsResponse_init(UA_TranslateBrowsePathsToNodeIdsResponse *p) { + memset(p, 0, sizeof(UA_TranslateBrowsePathsToNodeIdsResponse)); +} + +static UA_INLINE UA_TranslateBrowsePathsToNodeIdsResponse * +UA_TranslateBrowsePathsToNodeIdsResponse_new(void) { + return (UA_TranslateBrowsePathsToNodeIdsResponse*)UA_new(&UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_TranslateBrowsePathsToNodeIdsResponse_copy(const UA_TranslateBrowsePathsToNodeIdsResponse *src, UA_TranslateBrowsePathsToNodeIdsResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TranslateBrowsePathsToNodeIdsResponse_deleteMembers(UA_TranslateBrowsePathsToNodeIdsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE]); +} + +static UA_INLINE void +UA_TranslateBrowsePathsToNodeIdsResponse_clear(UA_TranslateBrowsePathsToNodeIdsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE]); +} + +static UA_INLINE void +UA_TranslateBrowsePathsToNodeIdsResponse_delete(UA_TranslateBrowsePathsToNodeIdsResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE]); +}static UA_INLINE UA_Boolean +UA_TranslateBrowsePathsToNodeIdsResponse_equal(const UA_TranslateBrowsePathsToNodeIdsResponse *p1, const UA_TranslateBrowsePathsToNodeIdsResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE]) == UA_ORDER_EQ); +} + + + +/* RegisterNodesRequest */ +static UA_INLINE void +UA_RegisterNodesRequest_init(UA_RegisterNodesRequest *p) { + memset(p, 0, sizeof(UA_RegisterNodesRequest)); +} + +static UA_INLINE UA_RegisterNodesRequest * +UA_RegisterNodesRequest_new(void) { + return (UA_RegisterNodesRequest*)UA_new(&UA_TYPES[UA_TYPES_REGISTERNODESREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_RegisterNodesRequest_copy(const UA_RegisterNodesRequest *src, UA_RegisterNodesRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RegisterNodesRequest_deleteMembers(UA_RegisterNodesRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST]); +} + +static UA_INLINE void +UA_RegisterNodesRequest_clear(UA_RegisterNodesRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST]); +} + +static UA_INLINE void +UA_RegisterNodesRequest_delete(UA_RegisterNodesRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST]); +}static UA_INLINE UA_Boolean +UA_RegisterNodesRequest_equal(const UA_RegisterNodesRequest *p1, const UA_RegisterNodesRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST]) == UA_ORDER_EQ); +} + + + +/* RegisterNodesResponse */ +static UA_INLINE void +UA_RegisterNodesResponse_init(UA_RegisterNodesResponse *p) { + memset(p, 0, sizeof(UA_RegisterNodesResponse)); +} + +static UA_INLINE UA_RegisterNodesResponse * +UA_RegisterNodesResponse_new(void) { + return (UA_RegisterNodesResponse*)UA_new(&UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_RegisterNodesResponse_copy(const UA_RegisterNodesResponse *src, UA_RegisterNodesResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RegisterNodesResponse_deleteMembers(UA_RegisterNodesResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE]); +} + +static UA_INLINE void +UA_RegisterNodesResponse_clear(UA_RegisterNodesResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE]); +} + +static UA_INLINE void +UA_RegisterNodesResponse_delete(UA_RegisterNodesResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE]); +}static UA_INLINE UA_Boolean +UA_RegisterNodesResponse_equal(const UA_RegisterNodesResponse *p1, const UA_RegisterNodesResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE]) == UA_ORDER_EQ); +} + + + +/* UnregisterNodesRequest */ +static UA_INLINE void +UA_UnregisterNodesRequest_init(UA_UnregisterNodesRequest *p) { + memset(p, 0, sizeof(UA_UnregisterNodesRequest)); +} + +static UA_INLINE UA_UnregisterNodesRequest * +UA_UnregisterNodesRequest_new(void) { + return (UA_UnregisterNodesRequest*)UA_new(&UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_UnregisterNodesRequest_copy(const UA_UnregisterNodesRequest *src, UA_UnregisterNodesRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UnregisterNodesRequest_deleteMembers(UA_UnregisterNodesRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST]); +} + +static UA_INLINE void +UA_UnregisterNodesRequest_clear(UA_UnregisterNodesRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST]); +} + +static UA_INLINE void +UA_UnregisterNodesRequest_delete(UA_UnregisterNodesRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST]); +}static UA_INLINE UA_Boolean +UA_UnregisterNodesRequest_equal(const UA_UnregisterNodesRequest *p1, const UA_UnregisterNodesRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST]) == UA_ORDER_EQ); +} + + + +/* UnregisterNodesResponse */ +static UA_INLINE void +UA_UnregisterNodesResponse_init(UA_UnregisterNodesResponse *p) { + memset(p, 0, sizeof(UA_UnregisterNodesResponse)); +} + +static UA_INLINE UA_UnregisterNodesResponse * +UA_UnregisterNodesResponse_new(void) { + return (UA_UnregisterNodesResponse*)UA_new(&UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_UnregisterNodesResponse_copy(const UA_UnregisterNodesResponse *src, UA_UnregisterNodesResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UnregisterNodesResponse_deleteMembers(UA_UnregisterNodesResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE]); +} + +static UA_INLINE void +UA_UnregisterNodesResponse_clear(UA_UnregisterNodesResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE]); +} + +static UA_INLINE void +UA_UnregisterNodesResponse_delete(UA_UnregisterNodesResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE]); +}static UA_INLINE UA_Boolean +UA_UnregisterNodesResponse_equal(const UA_UnregisterNodesResponse *p1, const UA_UnregisterNodesResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE]) == UA_ORDER_EQ); +} + + + +/* Counter */ +static UA_INLINE void +UA_Counter_init(UA_Counter *p) { + memset(p, 0, sizeof(UA_Counter)); +} + +static UA_INLINE UA_Counter * +UA_Counter_new(void) { + return (UA_Counter*)UA_new(&UA_TYPES[UA_TYPES_COUNTER]); +} + +static UA_INLINE UA_StatusCode +UA_Counter_copy(const UA_Counter *src, UA_Counter *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_COUNTER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Counter_deleteMembers(UA_Counter *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_COUNTER]); +} + +static UA_INLINE void +UA_Counter_clear(UA_Counter *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_COUNTER]); +} + +static UA_INLINE void +UA_Counter_delete(UA_Counter *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_COUNTER]); +}static UA_INLINE UA_Boolean +UA_Counter_equal(const UA_Counter *p1, const UA_Counter *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_COUNTER]) == UA_ORDER_EQ); +} + + + +/* OpaqueNumericRange */ +static UA_INLINE void +UA_OpaqueNumericRange_init(UA_OpaqueNumericRange *p) { + memset(p, 0, sizeof(UA_OpaqueNumericRange)); +} + +static UA_INLINE UA_OpaqueNumericRange * +UA_OpaqueNumericRange_new(void) { + return (UA_OpaqueNumericRange*)UA_new(&UA_TYPES[UA_TYPES_OPAQUENUMERICRANGE]); +} + +static UA_INLINE UA_StatusCode +UA_OpaqueNumericRange_copy(const UA_OpaqueNumericRange *src, UA_OpaqueNumericRange *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_OPAQUENUMERICRANGE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_OpaqueNumericRange_deleteMembers(UA_OpaqueNumericRange *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OPAQUENUMERICRANGE]); +} + +static UA_INLINE void +UA_OpaqueNumericRange_clear(UA_OpaqueNumericRange *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_OPAQUENUMERICRANGE]); +} + +static UA_INLINE void +UA_OpaqueNumericRange_delete(UA_OpaqueNumericRange *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_OPAQUENUMERICRANGE]); +}static UA_INLINE UA_Boolean +UA_OpaqueNumericRange_equal(const UA_OpaqueNumericRange *p1, const UA_OpaqueNumericRange *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_OPAQUENUMERICRANGE]) == UA_ORDER_EQ); +} + + + +/* EndpointConfiguration */ +static UA_INLINE void +UA_EndpointConfiguration_init(UA_EndpointConfiguration *p) { + memset(p, 0, sizeof(UA_EndpointConfiguration)); +} + +static UA_INLINE UA_EndpointConfiguration * +UA_EndpointConfiguration_new(void) { + return (UA_EndpointConfiguration*)UA_new(&UA_TYPES[UA_TYPES_ENDPOINTCONFIGURATION]); +} + +static UA_INLINE UA_StatusCode +UA_EndpointConfiguration_copy(const UA_EndpointConfiguration *src, UA_EndpointConfiguration *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ENDPOINTCONFIGURATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EndpointConfiguration_deleteMembers(UA_EndpointConfiguration *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENDPOINTCONFIGURATION]); +} + +static UA_INLINE void +UA_EndpointConfiguration_clear(UA_EndpointConfiguration *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENDPOINTCONFIGURATION]); +} + +static UA_INLINE void +UA_EndpointConfiguration_delete(UA_EndpointConfiguration *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ENDPOINTCONFIGURATION]); +}static UA_INLINE UA_Boolean +UA_EndpointConfiguration_equal(const UA_EndpointConfiguration *p1, const UA_EndpointConfiguration *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ENDPOINTCONFIGURATION]) == UA_ORDER_EQ); +} + + + +/* QueryDataDescription */ +static UA_INLINE void +UA_QueryDataDescription_init(UA_QueryDataDescription *p) { + memset(p, 0, sizeof(UA_QueryDataDescription)); +} + +static UA_INLINE UA_QueryDataDescription * +UA_QueryDataDescription_new(void) { + return (UA_QueryDataDescription*)UA_new(&UA_TYPES[UA_TYPES_QUERYDATADESCRIPTION]); +} + +static UA_INLINE UA_StatusCode +UA_QueryDataDescription_copy(const UA_QueryDataDescription *src, UA_QueryDataDescription *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_QUERYDATADESCRIPTION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_QueryDataDescription_deleteMembers(UA_QueryDataDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUERYDATADESCRIPTION]); +} + +static UA_INLINE void +UA_QueryDataDescription_clear(UA_QueryDataDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUERYDATADESCRIPTION]); +} + +static UA_INLINE void +UA_QueryDataDescription_delete(UA_QueryDataDescription *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_QUERYDATADESCRIPTION]); +}static UA_INLINE UA_Boolean +UA_QueryDataDescription_equal(const UA_QueryDataDescription *p1, const UA_QueryDataDescription *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_QUERYDATADESCRIPTION]) == UA_ORDER_EQ); +} + + + +/* NodeTypeDescription */ +static UA_INLINE void +UA_NodeTypeDescription_init(UA_NodeTypeDescription *p) { + memset(p, 0, sizeof(UA_NodeTypeDescription)); +} + +static UA_INLINE UA_NodeTypeDescription * +UA_NodeTypeDescription_new(void) { + return (UA_NodeTypeDescription*)UA_new(&UA_TYPES[UA_TYPES_NODETYPEDESCRIPTION]); +} + +static UA_INLINE UA_StatusCode +UA_NodeTypeDescription_copy(const UA_NodeTypeDescription *src, UA_NodeTypeDescription *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NODETYPEDESCRIPTION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NodeTypeDescription_deleteMembers(UA_NodeTypeDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NODETYPEDESCRIPTION]); +} + +static UA_INLINE void +UA_NodeTypeDescription_clear(UA_NodeTypeDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NODETYPEDESCRIPTION]); +} + +static UA_INLINE void +UA_NodeTypeDescription_delete(UA_NodeTypeDescription *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NODETYPEDESCRIPTION]); +}static UA_INLINE UA_Boolean +UA_NodeTypeDescription_equal(const UA_NodeTypeDescription *p1, const UA_NodeTypeDescription *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NODETYPEDESCRIPTION]) == UA_ORDER_EQ); +} + + + +/* FilterOperator */ +static UA_INLINE void +UA_FilterOperator_init(UA_FilterOperator *p) { + memset(p, 0, sizeof(UA_FilterOperator)); +} + +static UA_INLINE UA_FilterOperator * +UA_FilterOperator_new(void) { + return (UA_FilterOperator*)UA_new(&UA_TYPES[UA_TYPES_FILTEROPERATOR]); +} + +static UA_INLINE UA_StatusCode +UA_FilterOperator_copy(const UA_FilterOperator *src, UA_FilterOperator *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_FILTEROPERATOR]); +} + +UA_DEPRECATED static UA_INLINE void +UA_FilterOperator_deleteMembers(UA_FilterOperator *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FILTEROPERATOR]); +} + +static UA_INLINE void +UA_FilterOperator_clear(UA_FilterOperator *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FILTEROPERATOR]); +} + +static UA_INLINE void +UA_FilterOperator_delete(UA_FilterOperator *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_FILTEROPERATOR]); +}static UA_INLINE UA_Boolean +UA_FilterOperator_equal(const UA_FilterOperator *p1, const UA_FilterOperator *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_FILTEROPERATOR]) == UA_ORDER_EQ); +} + + + +/* QueryDataSet */ +static UA_INLINE void +UA_QueryDataSet_init(UA_QueryDataSet *p) { + memset(p, 0, sizeof(UA_QueryDataSet)); +} + +static UA_INLINE UA_QueryDataSet * +UA_QueryDataSet_new(void) { + return (UA_QueryDataSet*)UA_new(&UA_TYPES[UA_TYPES_QUERYDATASET]); +} + +static UA_INLINE UA_StatusCode +UA_QueryDataSet_copy(const UA_QueryDataSet *src, UA_QueryDataSet *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_QUERYDATASET]); +} + +UA_DEPRECATED static UA_INLINE void +UA_QueryDataSet_deleteMembers(UA_QueryDataSet *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUERYDATASET]); +} + +static UA_INLINE void +UA_QueryDataSet_clear(UA_QueryDataSet *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUERYDATASET]); +} + +static UA_INLINE void +UA_QueryDataSet_delete(UA_QueryDataSet *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_QUERYDATASET]); +}static UA_INLINE UA_Boolean +UA_QueryDataSet_equal(const UA_QueryDataSet *p1, const UA_QueryDataSet *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_QUERYDATASET]) == UA_ORDER_EQ); +} + + + +/* NodeReference */ +static UA_INLINE void +UA_NodeReference_init(UA_NodeReference *p) { + memset(p, 0, sizeof(UA_NodeReference)); +} + +static UA_INLINE UA_NodeReference * +UA_NodeReference_new(void) { + return (UA_NodeReference*)UA_new(&UA_TYPES[UA_TYPES_NODEREFERENCE]); +} + +static UA_INLINE UA_StatusCode +UA_NodeReference_copy(const UA_NodeReference *src, UA_NodeReference *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NODEREFERENCE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NodeReference_deleteMembers(UA_NodeReference *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NODEREFERENCE]); +} + +static UA_INLINE void +UA_NodeReference_clear(UA_NodeReference *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NODEREFERENCE]); +} + +static UA_INLINE void +UA_NodeReference_delete(UA_NodeReference *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NODEREFERENCE]); +}static UA_INLINE UA_Boolean +UA_NodeReference_equal(const UA_NodeReference *p1, const UA_NodeReference *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NODEREFERENCE]) == UA_ORDER_EQ); +} + + + +/* ContentFilterElement */ +static UA_INLINE void +UA_ContentFilterElement_init(UA_ContentFilterElement *p) { + memset(p, 0, sizeof(UA_ContentFilterElement)); +} + +static UA_INLINE UA_ContentFilterElement * +UA_ContentFilterElement_new(void) { + return (UA_ContentFilterElement*)UA_new(&UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT]); +} + +static UA_INLINE UA_StatusCode +UA_ContentFilterElement_copy(const UA_ContentFilterElement *src, UA_ContentFilterElement *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ContentFilterElement_deleteMembers(UA_ContentFilterElement *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT]); +} + +static UA_INLINE void +UA_ContentFilterElement_clear(UA_ContentFilterElement *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT]); +} + +static UA_INLINE void +UA_ContentFilterElement_delete(UA_ContentFilterElement *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT]); +}static UA_INLINE UA_Boolean +UA_ContentFilterElement_equal(const UA_ContentFilterElement *p1, const UA_ContentFilterElement *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT]) == UA_ORDER_EQ); +} + + + +/* ContentFilter */ +static UA_INLINE void +UA_ContentFilter_init(UA_ContentFilter *p) { + memset(p, 0, sizeof(UA_ContentFilter)); +} + +static UA_INLINE UA_ContentFilter * +UA_ContentFilter_new(void) { + return (UA_ContentFilter*)UA_new(&UA_TYPES[UA_TYPES_CONTENTFILTER]); +} + +static UA_INLINE UA_StatusCode +UA_ContentFilter_copy(const UA_ContentFilter *src, UA_ContentFilter *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CONTENTFILTER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ContentFilter_deleteMembers(UA_ContentFilter *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CONTENTFILTER]); +} + +static UA_INLINE void +UA_ContentFilter_clear(UA_ContentFilter *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CONTENTFILTER]); +} + +static UA_INLINE void +UA_ContentFilter_delete(UA_ContentFilter *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CONTENTFILTER]); +}static UA_INLINE UA_Boolean +UA_ContentFilter_equal(const UA_ContentFilter *p1, const UA_ContentFilter *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CONTENTFILTER]) == UA_ORDER_EQ); +} + + + +/* ElementOperand */ +static UA_INLINE void +UA_ElementOperand_init(UA_ElementOperand *p) { + memset(p, 0, sizeof(UA_ElementOperand)); +} + +static UA_INLINE UA_ElementOperand * +UA_ElementOperand_new(void) { + return (UA_ElementOperand*)UA_new(&UA_TYPES[UA_TYPES_ELEMENTOPERAND]); +} + +static UA_INLINE UA_StatusCode +UA_ElementOperand_copy(const UA_ElementOperand *src, UA_ElementOperand *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ELEMENTOPERAND]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ElementOperand_deleteMembers(UA_ElementOperand *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ELEMENTOPERAND]); +} + +static UA_INLINE void +UA_ElementOperand_clear(UA_ElementOperand *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ELEMENTOPERAND]); +} + +static UA_INLINE void +UA_ElementOperand_delete(UA_ElementOperand *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ELEMENTOPERAND]); +}static UA_INLINE UA_Boolean +UA_ElementOperand_equal(const UA_ElementOperand *p1, const UA_ElementOperand *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ELEMENTOPERAND]) == UA_ORDER_EQ); +} + + + +/* LiteralOperand */ +static UA_INLINE void +UA_LiteralOperand_init(UA_LiteralOperand *p) { + memset(p, 0, sizeof(UA_LiteralOperand)); +} + +static UA_INLINE UA_LiteralOperand * +UA_LiteralOperand_new(void) { + return (UA_LiteralOperand*)UA_new(&UA_TYPES[UA_TYPES_LITERALOPERAND]); +} + +static UA_INLINE UA_StatusCode +UA_LiteralOperand_copy(const UA_LiteralOperand *src, UA_LiteralOperand *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_LITERALOPERAND]); +} + +UA_DEPRECATED static UA_INLINE void +UA_LiteralOperand_deleteMembers(UA_LiteralOperand *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_LITERALOPERAND]); +} + +static UA_INLINE void +UA_LiteralOperand_clear(UA_LiteralOperand *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_LITERALOPERAND]); +} + +static UA_INLINE void +UA_LiteralOperand_delete(UA_LiteralOperand *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_LITERALOPERAND]); +}static UA_INLINE UA_Boolean +UA_LiteralOperand_equal(const UA_LiteralOperand *p1, const UA_LiteralOperand *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_LITERALOPERAND]) == UA_ORDER_EQ); +} + + + +/* AttributeOperand */ +static UA_INLINE void +UA_AttributeOperand_init(UA_AttributeOperand *p) { + memset(p, 0, sizeof(UA_AttributeOperand)); +} + +static UA_INLINE UA_AttributeOperand * +UA_AttributeOperand_new(void) { + return (UA_AttributeOperand*)UA_new(&UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]); +} + +static UA_INLINE UA_StatusCode +UA_AttributeOperand_copy(const UA_AttributeOperand *src, UA_AttributeOperand *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AttributeOperand_deleteMembers(UA_AttributeOperand *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]); +} + +static UA_INLINE void +UA_AttributeOperand_clear(UA_AttributeOperand *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]); +} + +static UA_INLINE void +UA_AttributeOperand_delete(UA_AttributeOperand *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]); +}static UA_INLINE UA_Boolean +UA_AttributeOperand_equal(const UA_AttributeOperand *p1, const UA_AttributeOperand *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]) == UA_ORDER_EQ); +} + + + +/* SimpleAttributeOperand */ +static UA_INLINE void +UA_SimpleAttributeOperand_init(UA_SimpleAttributeOperand *p) { + memset(p, 0, sizeof(UA_SimpleAttributeOperand)); +} + +static UA_INLINE UA_SimpleAttributeOperand * +UA_SimpleAttributeOperand_new(void) { + return (UA_SimpleAttributeOperand*)UA_new(&UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]); +} + +static UA_INLINE UA_StatusCode +UA_SimpleAttributeOperand_copy(const UA_SimpleAttributeOperand *src, UA_SimpleAttributeOperand *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SimpleAttributeOperand_deleteMembers(UA_SimpleAttributeOperand *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]); +} + +static UA_INLINE void +UA_SimpleAttributeOperand_clear(UA_SimpleAttributeOperand *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]); +} + +static UA_INLINE void +UA_SimpleAttributeOperand_delete(UA_SimpleAttributeOperand *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]); +}static UA_INLINE UA_Boolean +UA_SimpleAttributeOperand_equal(const UA_SimpleAttributeOperand *p1, const UA_SimpleAttributeOperand *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]) == UA_ORDER_EQ); +} + + + +/* ContentFilterElementResult */ +static UA_INLINE void +UA_ContentFilterElementResult_init(UA_ContentFilterElementResult *p) { + memset(p, 0, sizeof(UA_ContentFilterElementResult)); +} + +static UA_INLINE UA_ContentFilterElementResult * +UA_ContentFilterElementResult_new(void) { + return (UA_ContentFilterElementResult*)UA_new(&UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT]); +} + +static UA_INLINE UA_StatusCode +UA_ContentFilterElementResult_copy(const UA_ContentFilterElementResult *src, UA_ContentFilterElementResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ContentFilterElementResult_deleteMembers(UA_ContentFilterElementResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT]); +} + +static UA_INLINE void +UA_ContentFilterElementResult_clear(UA_ContentFilterElementResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT]); +} + +static UA_INLINE void +UA_ContentFilterElementResult_delete(UA_ContentFilterElementResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT]); +}static UA_INLINE UA_Boolean +UA_ContentFilterElementResult_equal(const UA_ContentFilterElementResult *p1, const UA_ContentFilterElementResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT]) == UA_ORDER_EQ); +} + + + +/* ContentFilterResult */ +static UA_INLINE void +UA_ContentFilterResult_init(UA_ContentFilterResult *p) { + memset(p, 0, sizeof(UA_ContentFilterResult)); +} + +static UA_INLINE UA_ContentFilterResult * +UA_ContentFilterResult_new(void) { + return (UA_ContentFilterResult*)UA_new(&UA_TYPES[UA_TYPES_CONTENTFILTERRESULT]); +} + +static UA_INLINE UA_StatusCode +UA_ContentFilterResult_copy(const UA_ContentFilterResult *src, UA_ContentFilterResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CONTENTFILTERRESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ContentFilterResult_deleteMembers(UA_ContentFilterResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CONTENTFILTERRESULT]); +} + +static UA_INLINE void +UA_ContentFilterResult_clear(UA_ContentFilterResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CONTENTFILTERRESULT]); +} + +static UA_INLINE void +UA_ContentFilterResult_delete(UA_ContentFilterResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CONTENTFILTERRESULT]); +}static UA_INLINE UA_Boolean +UA_ContentFilterResult_equal(const UA_ContentFilterResult *p1, const UA_ContentFilterResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CONTENTFILTERRESULT]) == UA_ORDER_EQ); +} + + + +/* ParsingResult */ +static UA_INLINE void +UA_ParsingResult_init(UA_ParsingResult *p) { + memset(p, 0, sizeof(UA_ParsingResult)); +} + +static UA_INLINE UA_ParsingResult * +UA_ParsingResult_new(void) { + return (UA_ParsingResult*)UA_new(&UA_TYPES[UA_TYPES_PARSINGRESULT]); +} + +static UA_INLINE UA_StatusCode +UA_ParsingResult_copy(const UA_ParsingResult *src, UA_ParsingResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PARSINGRESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ParsingResult_deleteMembers(UA_ParsingResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PARSINGRESULT]); +} + +static UA_INLINE void +UA_ParsingResult_clear(UA_ParsingResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PARSINGRESULT]); +} + +static UA_INLINE void +UA_ParsingResult_delete(UA_ParsingResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PARSINGRESULT]); +}static UA_INLINE UA_Boolean +UA_ParsingResult_equal(const UA_ParsingResult *p1, const UA_ParsingResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PARSINGRESULT]) == UA_ORDER_EQ); +} + + + +/* QueryFirstRequest */ +static UA_INLINE void +UA_QueryFirstRequest_init(UA_QueryFirstRequest *p) { + memset(p, 0, sizeof(UA_QueryFirstRequest)); +} + +static UA_INLINE UA_QueryFirstRequest * +UA_QueryFirstRequest_new(void) { + return (UA_QueryFirstRequest*)UA_new(&UA_TYPES[UA_TYPES_QUERYFIRSTREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_QueryFirstRequest_copy(const UA_QueryFirstRequest *src, UA_QueryFirstRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_QUERYFIRSTREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_QueryFirstRequest_deleteMembers(UA_QueryFirstRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUERYFIRSTREQUEST]); +} + +static UA_INLINE void +UA_QueryFirstRequest_clear(UA_QueryFirstRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUERYFIRSTREQUEST]); +} + +static UA_INLINE void +UA_QueryFirstRequest_delete(UA_QueryFirstRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_QUERYFIRSTREQUEST]); +}static UA_INLINE UA_Boolean +UA_QueryFirstRequest_equal(const UA_QueryFirstRequest *p1, const UA_QueryFirstRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_QUERYFIRSTREQUEST]) == UA_ORDER_EQ); +} + + + +/* QueryFirstResponse */ +static UA_INLINE void +UA_QueryFirstResponse_init(UA_QueryFirstResponse *p) { + memset(p, 0, sizeof(UA_QueryFirstResponse)); +} + +static UA_INLINE UA_QueryFirstResponse * +UA_QueryFirstResponse_new(void) { + return (UA_QueryFirstResponse*)UA_new(&UA_TYPES[UA_TYPES_QUERYFIRSTRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_QueryFirstResponse_copy(const UA_QueryFirstResponse *src, UA_QueryFirstResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_QUERYFIRSTRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_QueryFirstResponse_deleteMembers(UA_QueryFirstResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUERYFIRSTRESPONSE]); +} + +static UA_INLINE void +UA_QueryFirstResponse_clear(UA_QueryFirstResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUERYFIRSTRESPONSE]); +} + +static UA_INLINE void +UA_QueryFirstResponse_delete(UA_QueryFirstResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_QUERYFIRSTRESPONSE]); +}static UA_INLINE UA_Boolean +UA_QueryFirstResponse_equal(const UA_QueryFirstResponse *p1, const UA_QueryFirstResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_QUERYFIRSTRESPONSE]) == UA_ORDER_EQ); +} + + + +/* QueryNextRequest */ +static UA_INLINE void +UA_QueryNextRequest_init(UA_QueryNextRequest *p) { + memset(p, 0, sizeof(UA_QueryNextRequest)); +} + +static UA_INLINE UA_QueryNextRequest * +UA_QueryNextRequest_new(void) { + return (UA_QueryNextRequest*)UA_new(&UA_TYPES[UA_TYPES_QUERYNEXTREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_QueryNextRequest_copy(const UA_QueryNextRequest *src, UA_QueryNextRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_QUERYNEXTREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_QueryNextRequest_deleteMembers(UA_QueryNextRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUERYNEXTREQUEST]); +} + +static UA_INLINE void +UA_QueryNextRequest_clear(UA_QueryNextRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUERYNEXTREQUEST]); +} + +static UA_INLINE void +UA_QueryNextRequest_delete(UA_QueryNextRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_QUERYNEXTREQUEST]); +}static UA_INLINE UA_Boolean +UA_QueryNextRequest_equal(const UA_QueryNextRequest *p1, const UA_QueryNextRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_QUERYNEXTREQUEST]) == UA_ORDER_EQ); +} + + + +/* QueryNextResponse */ +static UA_INLINE void +UA_QueryNextResponse_init(UA_QueryNextResponse *p) { + memset(p, 0, sizeof(UA_QueryNextResponse)); +} + +static UA_INLINE UA_QueryNextResponse * +UA_QueryNextResponse_new(void) { + return (UA_QueryNextResponse*)UA_new(&UA_TYPES[UA_TYPES_QUERYNEXTRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_QueryNextResponse_copy(const UA_QueryNextResponse *src, UA_QueryNextResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_QUERYNEXTRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_QueryNextResponse_deleteMembers(UA_QueryNextResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUERYNEXTRESPONSE]); +} + +static UA_INLINE void +UA_QueryNextResponse_clear(UA_QueryNextResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_QUERYNEXTRESPONSE]); +} + +static UA_INLINE void +UA_QueryNextResponse_delete(UA_QueryNextResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_QUERYNEXTRESPONSE]); +}static UA_INLINE UA_Boolean +UA_QueryNextResponse_equal(const UA_QueryNextResponse *p1, const UA_QueryNextResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_QUERYNEXTRESPONSE]) == UA_ORDER_EQ); +} + + + +/* TimestampsToReturn */ +static UA_INLINE void +UA_TimestampsToReturn_init(UA_TimestampsToReturn *p) { + memset(p, 0, sizeof(UA_TimestampsToReturn)); +} + +static UA_INLINE UA_TimestampsToReturn * +UA_TimestampsToReturn_new(void) { + return (UA_TimestampsToReturn*)UA_new(&UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN]); +} + +static UA_INLINE UA_StatusCode +UA_TimestampsToReturn_copy(const UA_TimestampsToReturn *src, UA_TimestampsToReturn *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TimestampsToReturn_deleteMembers(UA_TimestampsToReturn *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN]); +} + +static UA_INLINE void +UA_TimestampsToReturn_clear(UA_TimestampsToReturn *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN]); +} + +static UA_INLINE void +UA_TimestampsToReturn_delete(UA_TimestampsToReturn *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN]); +}static UA_INLINE UA_Boolean +UA_TimestampsToReturn_equal(const UA_TimestampsToReturn *p1, const UA_TimestampsToReturn *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN]) == UA_ORDER_EQ); +} + + + +/* ReadValueId */ +static UA_INLINE void +UA_ReadValueId_init(UA_ReadValueId *p) { + memset(p, 0, sizeof(UA_ReadValueId)); +} + +static UA_INLINE UA_ReadValueId * +UA_ReadValueId_new(void) { + return (UA_ReadValueId*)UA_new(&UA_TYPES[UA_TYPES_READVALUEID]); +} + +static UA_INLINE UA_StatusCode +UA_ReadValueId_copy(const UA_ReadValueId *src, UA_ReadValueId *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_READVALUEID]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReadValueId_deleteMembers(UA_ReadValueId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READVALUEID]); +} + +static UA_INLINE void +UA_ReadValueId_clear(UA_ReadValueId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READVALUEID]); +} + +static UA_INLINE void +UA_ReadValueId_delete(UA_ReadValueId *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_READVALUEID]); +}static UA_INLINE UA_Boolean +UA_ReadValueId_equal(const UA_ReadValueId *p1, const UA_ReadValueId *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_READVALUEID]) == UA_ORDER_EQ); +} + + + +/* ReadRequest */ +static UA_INLINE void +UA_ReadRequest_init(UA_ReadRequest *p) { + memset(p, 0, sizeof(UA_ReadRequest)); +} + +static UA_INLINE UA_ReadRequest * +UA_ReadRequest_new(void) { + return (UA_ReadRequest*)UA_new(&UA_TYPES[UA_TYPES_READREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_ReadRequest_copy(const UA_ReadRequest *src, UA_ReadRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_READREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReadRequest_deleteMembers(UA_ReadRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READREQUEST]); +} + +static UA_INLINE void +UA_ReadRequest_clear(UA_ReadRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READREQUEST]); +} + +static UA_INLINE void +UA_ReadRequest_delete(UA_ReadRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_READREQUEST]); +}static UA_INLINE UA_Boolean +UA_ReadRequest_equal(const UA_ReadRequest *p1, const UA_ReadRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_READREQUEST]) == UA_ORDER_EQ); +} + + + +/* ReadResponse */ +static UA_INLINE void +UA_ReadResponse_init(UA_ReadResponse *p) { + memset(p, 0, sizeof(UA_ReadResponse)); +} + +static UA_INLINE UA_ReadResponse * +UA_ReadResponse_new(void) { + return (UA_ReadResponse*)UA_new(&UA_TYPES[UA_TYPES_READRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_ReadResponse_copy(const UA_ReadResponse *src, UA_ReadResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_READRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReadResponse_deleteMembers(UA_ReadResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READRESPONSE]); +} + +static UA_INLINE void +UA_ReadResponse_clear(UA_ReadResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READRESPONSE]); +} + +static UA_INLINE void +UA_ReadResponse_delete(UA_ReadResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_READRESPONSE]); +}static UA_INLINE UA_Boolean +UA_ReadResponse_equal(const UA_ReadResponse *p1, const UA_ReadResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_READRESPONSE]) == UA_ORDER_EQ); +} + + + +/* HistoryReadValueId */ +static UA_INLINE void +UA_HistoryReadValueId_init(UA_HistoryReadValueId *p) { + memset(p, 0, sizeof(UA_HistoryReadValueId)); +} + +static UA_INLINE UA_HistoryReadValueId * +UA_HistoryReadValueId_new(void) { + return (UA_HistoryReadValueId*)UA_new(&UA_TYPES[UA_TYPES_HISTORYREADVALUEID]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryReadValueId_copy(const UA_HistoryReadValueId *src, UA_HistoryReadValueId *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYREADVALUEID]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryReadValueId_deleteMembers(UA_HistoryReadValueId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYREADVALUEID]); +} + +static UA_INLINE void +UA_HistoryReadValueId_clear(UA_HistoryReadValueId *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYREADVALUEID]); +} + +static UA_INLINE void +UA_HistoryReadValueId_delete(UA_HistoryReadValueId *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYREADVALUEID]); +}static UA_INLINE UA_Boolean +UA_HistoryReadValueId_equal(const UA_HistoryReadValueId *p1, const UA_HistoryReadValueId *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYREADVALUEID]) == UA_ORDER_EQ); +} + + + +/* HistoryReadResult */ +static UA_INLINE void +UA_HistoryReadResult_init(UA_HistoryReadResult *p) { + memset(p, 0, sizeof(UA_HistoryReadResult)); +} + +static UA_INLINE UA_HistoryReadResult * +UA_HistoryReadResult_new(void) { + return (UA_HistoryReadResult*)UA_new(&UA_TYPES[UA_TYPES_HISTORYREADRESULT]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryReadResult_copy(const UA_HistoryReadResult *src, UA_HistoryReadResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYREADRESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryReadResult_deleteMembers(UA_HistoryReadResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYREADRESULT]); +} + +static UA_INLINE void +UA_HistoryReadResult_clear(UA_HistoryReadResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYREADRESULT]); +} + +static UA_INLINE void +UA_HistoryReadResult_delete(UA_HistoryReadResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYREADRESULT]); +}static UA_INLINE UA_Boolean +UA_HistoryReadResult_equal(const UA_HistoryReadResult *p1, const UA_HistoryReadResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYREADRESULT]) == UA_ORDER_EQ); +} + + + +/* ReadRawModifiedDetails */ +static UA_INLINE void +UA_ReadRawModifiedDetails_init(UA_ReadRawModifiedDetails *p) { + memset(p, 0, sizeof(UA_ReadRawModifiedDetails)); +} + +static UA_INLINE UA_ReadRawModifiedDetails * +UA_ReadRawModifiedDetails_new(void) { + return (UA_ReadRawModifiedDetails*)UA_new(&UA_TYPES[UA_TYPES_READRAWMODIFIEDDETAILS]); +} + +static UA_INLINE UA_StatusCode +UA_ReadRawModifiedDetails_copy(const UA_ReadRawModifiedDetails *src, UA_ReadRawModifiedDetails *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_READRAWMODIFIEDDETAILS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReadRawModifiedDetails_deleteMembers(UA_ReadRawModifiedDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READRAWMODIFIEDDETAILS]); +} + +static UA_INLINE void +UA_ReadRawModifiedDetails_clear(UA_ReadRawModifiedDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READRAWMODIFIEDDETAILS]); +} + +static UA_INLINE void +UA_ReadRawModifiedDetails_delete(UA_ReadRawModifiedDetails *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_READRAWMODIFIEDDETAILS]); +}static UA_INLINE UA_Boolean +UA_ReadRawModifiedDetails_equal(const UA_ReadRawModifiedDetails *p1, const UA_ReadRawModifiedDetails *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_READRAWMODIFIEDDETAILS]) == UA_ORDER_EQ); +} + + + +/* ReadAtTimeDetails */ +static UA_INLINE void +UA_ReadAtTimeDetails_init(UA_ReadAtTimeDetails *p) { + memset(p, 0, sizeof(UA_ReadAtTimeDetails)); +} + +static UA_INLINE UA_ReadAtTimeDetails * +UA_ReadAtTimeDetails_new(void) { + return (UA_ReadAtTimeDetails*)UA_new(&UA_TYPES[UA_TYPES_READATTIMEDETAILS]); +} + +static UA_INLINE UA_StatusCode +UA_ReadAtTimeDetails_copy(const UA_ReadAtTimeDetails *src, UA_ReadAtTimeDetails *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_READATTIMEDETAILS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReadAtTimeDetails_deleteMembers(UA_ReadAtTimeDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READATTIMEDETAILS]); +} + +static UA_INLINE void +UA_ReadAtTimeDetails_clear(UA_ReadAtTimeDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READATTIMEDETAILS]); +} + +static UA_INLINE void +UA_ReadAtTimeDetails_delete(UA_ReadAtTimeDetails *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_READATTIMEDETAILS]); +}static UA_INLINE UA_Boolean +UA_ReadAtTimeDetails_equal(const UA_ReadAtTimeDetails *p1, const UA_ReadAtTimeDetails *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_READATTIMEDETAILS]) == UA_ORDER_EQ); +} + + + +/* ReadAnnotationDataDetails */ +static UA_INLINE void +UA_ReadAnnotationDataDetails_init(UA_ReadAnnotationDataDetails *p) { + memset(p, 0, sizeof(UA_ReadAnnotationDataDetails)); +} + +static UA_INLINE UA_ReadAnnotationDataDetails * +UA_ReadAnnotationDataDetails_new(void) { + return (UA_ReadAnnotationDataDetails*)UA_new(&UA_TYPES[UA_TYPES_READANNOTATIONDATADETAILS]); +} + +static UA_INLINE UA_StatusCode +UA_ReadAnnotationDataDetails_copy(const UA_ReadAnnotationDataDetails *src, UA_ReadAnnotationDataDetails *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_READANNOTATIONDATADETAILS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReadAnnotationDataDetails_deleteMembers(UA_ReadAnnotationDataDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READANNOTATIONDATADETAILS]); +} + +static UA_INLINE void +UA_ReadAnnotationDataDetails_clear(UA_ReadAnnotationDataDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READANNOTATIONDATADETAILS]); +} + +static UA_INLINE void +UA_ReadAnnotationDataDetails_delete(UA_ReadAnnotationDataDetails *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_READANNOTATIONDATADETAILS]); +}static UA_INLINE UA_Boolean +UA_ReadAnnotationDataDetails_equal(const UA_ReadAnnotationDataDetails *p1, const UA_ReadAnnotationDataDetails *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_READANNOTATIONDATADETAILS]) == UA_ORDER_EQ); +} + + + +/* HistoryData */ +static UA_INLINE void +UA_HistoryData_init(UA_HistoryData *p) { + memset(p, 0, sizeof(UA_HistoryData)); +} + +static UA_INLINE UA_HistoryData * +UA_HistoryData_new(void) { + return (UA_HistoryData*)UA_new(&UA_TYPES[UA_TYPES_HISTORYDATA]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryData_copy(const UA_HistoryData *src, UA_HistoryData *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYDATA]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryData_deleteMembers(UA_HistoryData *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYDATA]); +} + +static UA_INLINE void +UA_HistoryData_clear(UA_HistoryData *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYDATA]); +} + +static UA_INLINE void +UA_HistoryData_delete(UA_HistoryData *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYDATA]); +}static UA_INLINE UA_Boolean +UA_HistoryData_equal(const UA_HistoryData *p1, const UA_HistoryData *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYDATA]) == UA_ORDER_EQ); +} + + + +/* HistoryReadRequest */ +static UA_INLINE void +UA_HistoryReadRequest_init(UA_HistoryReadRequest *p) { + memset(p, 0, sizeof(UA_HistoryReadRequest)); +} + +static UA_INLINE UA_HistoryReadRequest * +UA_HistoryReadRequest_new(void) { + return (UA_HistoryReadRequest*)UA_new(&UA_TYPES[UA_TYPES_HISTORYREADREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryReadRequest_copy(const UA_HistoryReadRequest *src, UA_HistoryReadRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYREADREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryReadRequest_deleteMembers(UA_HistoryReadRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYREADREQUEST]); +} + +static UA_INLINE void +UA_HistoryReadRequest_clear(UA_HistoryReadRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYREADREQUEST]); +} + +static UA_INLINE void +UA_HistoryReadRequest_delete(UA_HistoryReadRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYREADREQUEST]); +}static UA_INLINE UA_Boolean +UA_HistoryReadRequest_equal(const UA_HistoryReadRequest *p1, const UA_HistoryReadRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYREADREQUEST]) == UA_ORDER_EQ); +} + + + +/* HistoryReadResponse */ +static UA_INLINE void +UA_HistoryReadResponse_init(UA_HistoryReadResponse *p) { + memset(p, 0, sizeof(UA_HistoryReadResponse)); +} + +static UA_INLINE UA_HistoryReadResponse * +UA_HistoryReadResponse_new(void) { + return (UA_HistoryReadResponse*)UA_new(&UA_TYPES[UA_TYPES_HISTORYREADRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryReadResponse_copy(const UA_HistoryReadResponse *src, UA_HistoryReadResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYREADRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryReadResponse_deleteMembers(UA_HistoryReadResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYREADRESPONSE]); +} + +static UA_INLINE void +UA_HistoryReadResponse_clear(UA_HistoryReadResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYREADRESPONSE]); +} + +static UA_INLINE void +UA_HistoryReadResponse_delete(UA_HistoryReadResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYREADRESPONSE]); +}static UA_INLINE UA_Boolean +UA_HistoryReadResponse_equal(const UA_HistoryReadResponse *p1, const UA_HistoryReadResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYREADRESPONSE]) == UA_ORDER_EQ); +} + + + +/* WriteValue */ +static UA_INLINE void +UA_WriteValue_init(UA_WriteValue *p) { + memset(p, 0, sizeof(UA_WriteValue)); +} + +static UA_INLINE UA_WriteValue * +UA_WriteValue_new(void) { + return (UA_WriteValue*)UA_new(&UA_TYPES[UA_TYPES_WRITEVALUE]); +} + +static UA_INLINE UA_StatusCode +UA_WriteValue_copy(const UA_WriteValue *src, UA_WriteValue *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_WRITEVALUE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_WriteValue_deleteMembers(UA_WriteValue *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_WRITEVALUE]); +} + +static UA_INLINE void +UA_WriteValue_clear(UA_WriteValue *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_WRITEVALUE]); +} + +static UA_INLINE void +UA_WriteValue_delete(UA_WriteValue *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_WRITEVALUE]); +}static UA_INLINE UA_Boolean +UA_WriteValue_equal(const UA_WriteValue *p1, const UA_WriteValue *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_WRITEVALUE]) == UA_ORDER_EQ); +} + + + +/* WriteRequest */ +static UA_INLINE void +UA_WriteRequest_init(UA_WriteRequest *p) { + memset(p, 0, sizeof(UA_WriteRequest)); +} + +static UA_INLINE UA_WriteRequest * +UA_WriteRequest_new(void) { + return (UA_WriteRequest*)UA_new(&UA_TYPES[UA_TYPES_WRITEREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_WriteRequest_copy(const UA_WriteRequest *src, UA_WriteRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_WRITEREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_WriteRequest_deleteMembers(UA_WriteRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_WRITEREQUEST]); +} + +static UA_INLINE void +UA_WriteRequest_clear(UA_WriteRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_WRITEREQUEST]); +} + +static UA_INLINE void +UA_WriteRequest_delete(UA_WriteRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_WRITEREQUEST]); +}static UA_INLINE UA_Boolean +UA_WriteRequest_equal(const UA_WriteRequest *p1, const UA_WriteRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_WRITEREQUEST]) == UA_ORDER_EQ); +} + + + +/* WriteResponse */ +static UA_INLINE void +UA_WriteResponse_init(UA_WriteResponse *p) { + memset(p, 0, sizeof(UA_WriteResponse)); +} + +static UA_INLINE UA_WriteResponse * +UA_WriteResponse_new(void) { + return (UA_WriteResponse*)UA_new(&UA_TYPES[UA_TYPES_WRITERESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_WriteResponse_copy(const UA_WriteResponse *src, UA_WriteResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_WRITERESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_WriteResponse_deleteMembers(UA_WriteResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_WRITERESPONSE]); +} + +static UA_INLINE void +UA_WriteResponse_clear(UA_WriteResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_WRITERESPONSE]); +} + +static UA_INLINE void +UA_WriteResponse_delete(UA_WriteResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_WRITERESPONSE]); +}static UA_INLINE UA_Boolean +UA_WriteResponse_equal(const UA_WriteResponse *p1, const UA_WriteResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_WRITERESPONSE]) == UA_ORDER_EQ); +} + + + +/* HistoryUpdateDetails */ +static UA_INLINE void +UA_HistoryUpdateDetails_init(UA_HistoryUpdateDetails *p) { + memset(p, 0, sizeof(UA_HistoryUpdateDetails)); +} + +static UA_INLINE UA_HistoryUpdateDetails * +UA_HistoryUpdateDetails_new(void) { + return (UA_HistoryUpdateDetails*)UA_new(&UA_TYPES[UA_TYPES_HISTORYUPDATEDETAILS]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryUpdateDetails_copy(const UA_HistoryUpdateDetails *src, UA_HistoryUpdateDetails *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYUPDATEDETAILS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryUpdateDetails_deleteMembers(UA_HistoryUpdateDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYUPDATEDETAILS]); +} + +static UA_INLINE void +UA_HistoryUpdateDetails_clear(UA_HistoryUpdateDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYUPDATEDETAILS]); +} + +static UA_INLINE void +UA_HistoryUpdateDetails_delete(UA_HistoryUpdateDetails *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYUPDATEDETAILS]); +}static UA_INLINE UA_Boolean +UA_HistoryUpdateDetails_equal(const UA_HistoryUpdateDetails *p1, const UA_HistoryUpdateDetails *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYUPDATEDETAILS]) == UA_ORDER_EQ); +} + + + +/* HistoryUpdateType */ +static UA_INLINE void +UA_HistoryUpdateType_init(UA_HistoryUpdateType *p) { + memset(p, 0, sizeof(UA_HistoryUpdateType)); +} + +static UA_INLINE UA_HistoryUpdateType * +UA_HistoryUpdateType_new(void) { + return (UA_HistoryUpdateType*)UA_new(&UA_TYPES[UA_TYPES_HISTORYUPDATETYPE]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryUpdateType_copy(const UA_HistoryUpdateType *src, UA_HistoryUpdateType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYUPDATETYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryUpdateType_deleteMembers(UA_HistoryUpdateType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYUPDATETYPE]); +} + +static UA_INLINE void +UA_HistoryUpdateType_clear(UA_HistoryUpdateType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYUPDATETYPE]); +} + +static UA_INLINE void +UA_HistoryUpdateType_delete(UA_HistoryUpdateType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYUPDATETYPE]); +}static UA_INLINE UA_Boolean +UA_HistoryUpdateType_equal(const UA_HistoryUpdateType *p1, const UA_HistoryUpdateType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYUPDATETYPE]) == UA_ORDER_EQ); +} + + + +/* PerformUpdateType */ +static UA_INLINE void +UA_PerformUpdateType_init(UA_PerformUpdateType *p) { + memset(p, 0, sizeof(UA_PerformUpdateType)); +} + +static UA_INLINE UA_PerformUpdateType * +UA_PerformUpdateType_new(void) { + return (UA_PerformUpdateType*)UA_new(&UA_TYPES[UA_TYPES_PERFORMUPDATETYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PerformUpdateType_copy(const UA_PerformUpdateType *src, UA_PerformUpdateType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PERFORMUPDATETYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PerformUpdateType_deleteMembers(UA_PerformUpdateType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PERFORMUPDATETYPE]); +} + +static UA_INLINE void +UA_PerformUpdateType_clear(UA_PerformUpdateType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PERFORMUPDATETYPE]); +} + +static UA_INLINE void +UA_PerformUpdateType_delete(UA_PerformUpdateType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PERFORMUPDATETYPE]); +}static UA_INLINE UA_Boolean +UA_PerformUpdateType_equal(const UA_PerformUpdateType *p1, const UA_PerformUpdateType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PERFORMUPDATETYPE]) == UA_ORDER_EQ); +} + + + +/* UpdateDataDetails */ +static UA_INLINE void +UA_UpdateDataDetails_init(UA_UpdateDataDetails *p) { + memset(p, 0, sizeof(UA_UpdateDataDetails)); +} + +static UA_INLINE UA_UpdateDataDetails * +UA_UpdateDataDetails_new(void) { + return (UA_UpdateDataDetails*)UA_new(&UA_TYPES[UA_TYPES_UPDATEDATADETAILS]); +} + +static UA_INLINE UA_StatusCode +UA_UpdateDataDetails_copy(const UA_UpdateDataDetails *src, UA_UpdateDataDetails *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UPDATEDATADETAILS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UpdateDataDetails_deleteMembers(UA_UpdateDataDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UPDATEDATADETAILS]); +} + +static UA_INLINE void +UA_UpdateDataDetails_clear(UA_UpdateDataDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UPDATEDATADETAILS]); +} + +static UA_INLINE void +UA_UpdateDataDetails_delete(UA_UpdateDataDetails *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UPDATEDATADETAILS]); +}static UA_INLINE UA_Boolean +UA_UpdateDataDetails_equal(const UA_UpdateDataDetails *p1, const UA_UpdateDataDetails *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UPDATEDATADETAILS]) == UA_ORDER_EQ); +} + + + +/* UpdateStructureDataDetails */ +static UA_INLINE void +UA_UpdateStructureDataDetails_init(UA_UpdateStructureDataDetails *p) { + memset(p, 0, sizeof(UA_UpdateStructureDataDetails)); +} + +static UA_INLINE UA_UpdateStructureDataDetails * +UA_UpdateStructureDataDetails_new(void) { + return (UA_UpdateStructureDataDetails*)UA_new(&UA_TYPES[UA_TYPES_UPDATESTRUCTUREDATADETAILS]); +} + +static UA_INLINE UA_StatusCode +UA_UpdateStructureDataDetails_copy(const UA_UpdateStructureDataDetails *src, UA_UpdateStructureDataDetails *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UPDATESTRUCTUREDATADETAILS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UpdateStructureDataDetails_deleteMembers(UA_UpdateStructureDataDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UPDATESTRUCTUREDATADETAILS]); +} + +static UA_INLINE void +UA_UpdateStructureDataDetails_clear(UA_UpdateStructureDataDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UPDATESTRUCTUREDATADETAILS]); +} + +static UA_INLINE void +UA_UpdateStructureDataDetails_delete(UA_UpdateStructureDataDetails *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UPDATESTRUCTUREDATADETAILS]); +}static UA_INLINE UA_Boolean +UA_UpdateStructureDataDetails_equal(const UA_UpdateStructureDataDetails *p1, const UA_UpdateStructureDataDetails *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UPDATESTRUCTUREDATADETAILS]) == UA_ORDER_EQ); +} + + + +/* DeleteRawModifiedDetails */ +static UA_INLINE void +UA_DeleteRawModifiedDetails_init(UA_DeleteRawModifiedDetails *p) { + memset(p, 0, sizeof(UA_DeleteRawModifiedDetails)); +} + +static UA_INLINE UA_DeleteRawModifiedDetails * +UA_DeleteRawModifiedDetails_new(void) { + return (UA_DeleteRawModifiedDetails*)UA_new(&UA_TYPES[UA_TYPES_DELETERAWMODIFIEDDETAILS]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteRawModifiedDetails_copy(const UA_DeleteRawModifiedDetails *src, UA_DeleteRawModifiedDetails *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETERAWMODIFIEDDETAILS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteRawModifiedDetails_deleteMembers(UA_DeleteRawModifiedDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETERAWMODIFIEDDETAILS]); +} + +static UA_INLINE void +UA_DeleteRawModifiedDetails_clear(UA_DeleteRawModifiedDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETERAWMODIFIEDDETAILS]); +} + +static UA_INLINE void +UA_DeleteRawModifiedDetails_delete(UA_DeleteRawModifiedDetails *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETERAWMODIFIEDDETAILS]); +}static UA_INLINE UA_Boolean +UA_DeleteRawModifiedDetails_equal(const UA_DeleteRawModifiedDetails *p1, const UA_DeleteRawModifiedDetails *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETERAWMODIFIEDDETAILS]) == UA_ORDER_EQ); +} + + + +/* DeleteAtTimeDetails */ +static UA_INLINE void +UA_DeleteAtTimeDetails_init(UA_DeleteAtTimeDetails *p) { + memset(p, 0, sizeof(UA_DeleteAtTimeDetails)); +} + +static UA_INLINE UA_DeleteAtTimeDetails * +UA_DeleteAtTimeDetails_new(void) { + return (UA_DeleteAtTimeDetails*)UA_new(&UA_TYPES[UA_TYPES_DELETEATTIMEDETAILS]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteAtTimeDetails_copy(const UA_DeleteAtTimeDetails *src, UA_DeleteAtTimeDetails *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETEATTIMEDETAILS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteAtTimeDetails_deleteMembers(UA_DeleteAtTimeDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEATTIMEDETAILS]); +} + +static UA_INLINE void +UA_DeleteAtTimeDetails_clear(UA_DeleteAtTimeDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEATTIMEDETAILS]); +} + +static UA_INLINE void +UA_DeleteAtTimeDetails_delete(UA_DeleteAtTimeDetails *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETEATTIMEDETAILS]); +}static UA_INLINE UA_Boolean +UA_DeleteAtTimeDetails_equal(const UA_DeleteAtTimeDetails *p1, const UA_DeleteAtTimeDetails *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETEATTIMEDETAILS]) == UA_ORDER_EQ); +} + + + +/* DeleteEventDetails */ +static UA_INLINE void +UA_DeleteEventDetails_init(UA_DeleteEventDetails *p) { + memset(p, 0, sizeof(UA_DeleteEventDetails)); +} + +static UA_INLINE UA_DeleteEventDetails * +UA_DeleteEventDetails_new(void) { + return (UA_DeleteEventDetails*)UA_new(&UA_TYPES[UA_TYPES_DELETEEVENTDETAILS]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteEventDetails_copy(const UA_DeleteEventDetails *src, UA_DeleteEventDetails *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETEEVENTDETAILS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteEventDetails_deleteMembers(UA_DeleteEventDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEEVENTDETAILS]); +} + +static UA_INLINE void +UA_DeleteEventDetails_clear(UA_DeleteEventDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEEVENTDETAILS]); +} + +static UA_INLINE void +UA_DeleteEventDetails_delete(UA_DeleteEventDetails *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETEEVENTDETAILS]); +}static UA_INLINE UA_Boolean +UA_DeleteEventDetails_equal(const UA_DeleteEventDetails *p1, const UA_DeleteEventDetails *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETEEVENTDETAILS]) == UA_ORDER_EQ); +} + + + +/* HistoryUpdateResult */ +static UA_INLINE void +UA_HistoryUpdateResult_init(UA_HistoryUpdateResult *p) { + memset(p, 0, sizeof(UA_HistoryUpdateResult)); +} + +static UA_INLINE UA_HistoryUpdateResult * +UA_HistoryUpdateResult_new(void) { + return (UA_HistoryUpdateResult*)UA_new(&UA_TYPES[UA_TYPES_HISTORYUPDATERESULT]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryUpdateResult_copy(const UA_HistoryUpdateResult *src, UA_HistoryUpdateResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYUPDATERESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryUpdateResult_deleteMembers(UA_HistoryUpdateResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYUPDATERESULT]); +} + +static UA_INLINE void +UA_HistoryUpdateResult_clear(UA_HistoryUpdateResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYUPDATERESULT]); +} + +static UA_INLINE void +UA_HistoryUpdateResult_delete(UA_HistoryUpdateResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYUPDATERESULT]); +}static UA_INLINE UA_Boolean +UA_HistoryUpdateResult_equal(const UA_HistoryUpdateResult *p1, const UA_HistoryUpdateResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYUPDATERESULT]) == UA_ORDER_EQ); +} + + + +/* HistoryUpdateRequest */ +static UA_INLINE void +UA_HistoryUpdateRequest_init(UA_HistoryUpdateRequest *p) { + memset(p, 0, sizeof(UA_HistoryUpdateRequest)); +} + +static UA_INLINE UA_HistoryUpdateRequest * +UA_HistoryUpdateRequest_new(void) { + return (UA_HistoryUpdateRequest*)UA_new(&UA_TYPES[UA_TYPES_HISTORYUPDATEREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryUpdateRequest_copy(const UA_HistoryUpdateRequest *src, UA_HistoryUpdateRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYUPDATEREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryUpdateRequest_deleteMembers(UA_HistoryUpdateRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYUPDATEREQUEST]); +} + +static UA_INLINE void +UA_HistoryUpdateRequest_clear(UA_HistoryUpdateRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYUPDATEREQUEST]); +} + +static UA_INLINE void +UA_HistoryUpdateRequest_delete(UA_HistoryUpdateRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYUPDATEREQUEST]); +}static UA_INLINE UA_Boolean +UA_HistoryUpdateRequest_equal(const UA_HistoryUpdateRequest *p1, const UA_HistoryUpdateRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYUPDATEREQUEST]) == UA_ORDER_EQ); +} + + + +/* HistoryUpdateResponse */ +static UA_INLINE void +UA_HistoryUpdateResponse_init(UA_HistoryUpdateResponse *p) { + memset(p, 0, sizeof(UA_HistoryUpdateResponse)); +} + +static UA_INLINE UA_HistoryUpdateResponse * +UA_HistoryUpdateResponse_new(void) { + return (UA_HistoryUpdateResponse*)UA_new(&UA_TYPES[UA_TYPES_HISTORYUPDATERESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryUpdateResponse_copy(const UA_HistoryUpdateResponse *src, UA_HistoryUpdateResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYUPDATERESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryUpdateResponse_deleteMembers(UA_HistoryUpdateResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYUPDATERESPONSE]); +} + +static UA_INLINE void +UA_HistoryUpdateResponse_clear(UA_HistoryUpdateResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYUPDATERESPONSE]); +} + +static UA_INLINE void +UA_HistoryUpdateResponse_delete(UA_HistoryUpdateResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYUPDATERESPONSE]); +}static UA_INLINE UA_Boolean +UA_HistoryUpdateResponse_equal(const UA_HistoryUpdateResponse *p1, const UA_HistoryUpdateResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYUPDATERESPONSE]) == UA_ORDER_EQ); +} + + + +/* CallMethodRequest */ +static UA_INLINE void +UA_CallMethodRequest_init(UA_CallMethodRequest *p) { + memset(p, 0, sizeof(UA_CallMethodRequest)); +} + +static UA_INLINE UA_CallMethodRequest * +UA_CallMethodRequest_new(void) { + return (UA_CallMethodRequest*)UA_new(&UA_TYPES[UA_TYPES_CALLMETHODREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_CallMethodRequest_copy(const UA_CallMethodRequest *src, UA_CallMethodRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CALLMETHODREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CallMethodRequest_deleteMembers(UA_CallMethodRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CALLMETHODREQUEST]); +} + +static UA_INLINE void +UA_CallMethodRequest_clear(UA_CallMethodRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CALLMETHODREQUEST]); +} + +static UA_INLINE void +UA_CallMethodRequest_delete(UA_CallMethodRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CALLMETHODREQUEST]); +}static UA_INLINE UA_Boolean +UA_CallMethodRequest_equal(const UA_CallMethodRequest *p1, const UA_CallMethodRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CALLMETHODREQUEST]) == UA_ORDER_EQ); +} + + + +/* CallMethodResult */ +static UA_INLINE void +UA_CallMethodResult_init(UA_CallMethodResult *p) { + memset(p, 0, sizeof(UA_CallMethodResult)); +} + +static UA_INLINE UA_CallMethodResult * +UA_CallMethodResult_new(void) { + return (UA_CallMethodResult*)UA_new(&UA_TYPES[UA_TYPES_CALLMETHODRESULT]); +} + +static UA_INLINE UA_StatusCode +UA_CallMethodResult_copy(const UA_CallMethodResult *src, UA_CallMethodResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CALLMETHODRESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CallMethodResult_deleteMembers(UA_CallMethodResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CALLMETHODRESULT]); +} + +static UA_INLINE void +UA_CallMethodResult_clear(UA_CallMethodResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CALLMETHODRESULT]); +} + +static UA_INLINE void +UA_CallMethodResult_delete(UA_CallMethodResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CALLMETHODRESULT]); +}static UA_INLINE UA_Boolean +UA_CallMethodResult_equal(const UA_CallMethodResult *p1, const UA_CallMethodResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CALLMETHODRESULT]) == UA_ORDER_EQ); +} + + + +/* CallRequest */ +static UA_INLINE void +UA_CallRequest_init(UA_CallRequest *p) { + memset(p, 0, sizeof(UA_CallRequest)); +} + +static UA_INLINE UA_CallRequest * +UA_CallRequest_new(void) { + return (UA_CallRequest*)UA_new(&UA_TYPES[UA_TYPES_CALLREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_CallRequest_copy(const UA_CallRequest *src, UA_CallRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CALLREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CallRequest_deleteMembers(UA_CallRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CALLREQUEST]); +} + +static UA_INLINE void +UA_CallRequest_clear(UA_CallRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CALLREQUEST]); +} + +static UA_INLINE void +UA_CallRequest_delete(UA_CallRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CALLREQUEST]); +}static UA_INLINE UA_Boolean +UA_CallRequest_equal(const UA_CallRequest *p1, const UA_CallRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CALLREQUEST]) == UA_ORDER_EQ); +} + + + +/* CallResponse */ +static UA_INLINE void +UA_CallResponse_init(UA_CallResponse *p) { + memset(p, 0, sizeof(UA_CallResponse)); +} + +static UA_INLINE UA_CallResponse * +UA_CallResponse_new(void) { + return (UA_CallResponse*)UA_new(&UA_TYPES[UA_TYPES_CALLRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_CallResponse_copy(const UA_CallResponse *src, UA_CallResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CALLRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CallResponse_deleteMembers(UA_CallResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CALLRESPONSE]); +} + +static UA_INLINE void +UA_CallResponse_clear(UA_CallResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CALLRESPONSE]); +} + +static UA_INLINE void +UA_CallResponse_delete(UA_CallResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CALLRESPONSE]); +}static UA_INLINE UA_Boolean +UA_CallResponse_equal(const UA_CallResponse *p1, const UA_CallResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CALLRESPONSE]) == UA_ORDER_EQ); +} + + + +/* MonitoringMode */ +static UA_INLINE void +UA_MonitoringMode_init(UA_MonitoringMode *p) { + memset(p, 0, sizeof(UA_MonitoringMode)); +} + +static UA_INLINE UA_MonitoringMode * +UA_MonitoringMode_new(void) { + return (UA_MonitoringMode*)UA_new(&UA_TYPES[UA_TYPES_MONITORINGMODE]); +} + +static UA_INLINE UA_StatusCode +UA_MonitoringMode_copy(const UA_MonitoringMode *src, UA_MonitoringMode *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MONITORINGMODE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_MonitoringMode_deleteMembers(UA_MonitoringMode *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITORINGMODE]); +} + +static UA_INLINE void +UA_MonitoringMode_clear(UA_MonitoringMode *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITORINGMODE]); +} + +static UA_INLINE void +UA_MonitoringMode_delete(UA_MonitoringMode *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MONITORINGMODE]); +}static UA_INLINE UA_Boolean +UA_MonitoringMode_equal(const UA_MonitoringMode *p1, const UA_MonitoringMode *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MONITORINGMODE]) == UA_ORDER_EQ); +} + + + +/* DataChangeTrigger */ +static UA_INLINE void +UA_DataChangeTrigger_init(UA_DataChangeTrigger *p) { + memset(p, 0, sizeof(UA_DataChangeTrigger)); +} + +static UA_INLINE UA_DataChangeTrigger * +UA_DataChangeTrigger_new(void) { + return (UA_DataChangeTrigger*)UA_new(&UA_TYPES[UA_TYPES_DATACHANGETRIGGER]); +} + +static UA_INLINE UA_StatusCode +UA_DataChangeTrigger_copy(const UA_DataChangeTrigger *src, UA_DataChangeTrigger *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATACHANGETRIGGER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataChangeTrigger_deleteMembers(UA_DataChangeTrigger *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATACHANGETRIGGER]); +} + +static UA_INLINE void +UA_DataChangeTrigger_clear(UA_DataChangeTrigger *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATACHANGETRIGGER]); +} + +static UA_INLINE void +UA_DataChangeTrigger_delete(UA_DataChangeTrigger *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATACHANGETRIGGER]); +}static UA_INLINE UA_Boolean +UA_DataChangeTrigger_equal(const UA_DataChangeTrigger *p1, const UA_DataChangeTrigger *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATACHANGETRIGGER]) == UA_ORDER_EQ); +} + + + +/* DeadbandType */ +static UA_INLINE void +UA_DeadbandType_init(UA_DeadbandType *p) { + memset(p, 0, sizeof(UA_DeadbandType)); +} + +static UA_INLINE UA_DeadbandType * +UA_DeadbandType_new(void) { + return (UA_DeadbandType*)UA_new(&UA_TYPES[UA_TYPES_DEADBANDTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_DeadbandType_copy(const UA_DeadbandType *src, UA_DeadbandType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DEADBANDTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeadbandType_deleteMembers(UA_DeadbandType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DEADBANDTYPE]); +} + +static UA_INLINE void +UA_DeadbandType_clear(UA_DeadbandType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DEADBANDTYPE]); +} + +static UA_INLINE void +UA_DeadbandType_delete(UA_DeadbandType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DEADBANDTYPE]); +}static UA_INLINE UA_Boolean +UA_DeadbandType_equal(const UA_DeadbandType *p1, const UA_DeadbandType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DEADBANDTYPE]) == UA_ORDER_EQ); +} + + + +/* DataChangeFilter */ +static UA_INLINE void +UA_DataChangeFilter_init(UA_DataChangeFilter *p) { + memset(p, 0, sizeof(UA_DataChangeFilter)); +} + +static UA_INLINE UA_DataChangeFilter * +UA_DataChangeFilter_new(void) { + return (UA_DataChangeFilter*)UA_new(&UA_TYPES[UA_TYPES_DATACHANGEFILTER]); +} + +static UA_INLINE UA_StatusCode +UA_DataChangeFilter_copy(const UA_DataChangeFilter *src, UA_DataChangeFilter *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATACHANGEFILTER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataChangeFilter_deleteMembers(UA_DataChangeFilter *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATACHANGEFILTER]); +} + +static UA_INLINE void +UA_DataChangeFilter_clear(UA_DataChangeFilter *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATACHANGEFILTER]); +} + +static UA_INLINE void +UA_DataChangeFilter_delete(UA_DataChangeFilter *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATACHANGEFILTER]); +}static UA_INLINE UA_Boolean +UA_DataChangeFilter_equal(const UA_DataChangeFilter *p1, const UA_DataChangeFilter *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATACHANGEFILTER]) == UA_ORDER_EQ); +} + + + +/* EventFilter */ +static UA_INLINE void +UA_EventFilter_init(UA_EventFilter *p) { + memset(p, 0, sizeof(UA_EventFilter)); +} + +static UA_INLINE UA_EventFilter * +UA_EventFilter_new(void) { + return (UA_EventFilter*)UA_new(&UA_TYPES[UA_TYPES_EVENTFILTER]); +} + +static UA_INLINE UA_StatusCode +UA_EventFilter_copy(const UA_EventFilter *src, UA_EventFilter *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_EVENTFILTER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EventFilter_deleteMembers(UA_EventFilter *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EVENTFILTER]); +} + +static UA_INLINE void +UA_EventFilter_clear(UA_EventFilter *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EVENTFILTER]); +} + +static UA_INLINE void +UA_EventFilter_delete(UA_EventFilter *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_EVENTFILTER]); +}static UA_INLINE UA_Boolean +UA_EventFilter_equal(const UA_EventFilter *p1, const UA_EventFilter *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_EVENTFILTER]) == UA_ORDER_EQ); +} + + + +/* AggregateConfiguration */ +static UA_INLINE void +UA_AggregateConfiguration_init(UA_AggregateConfiguration *p) { + memset(p, 0, sizeof(UA_AggregateConfiguration)); +} + +static UA_INLINE UA_AggregateConfiguration * +UA_AggregateConfiguration_new(void) { + return (UA_AggregateConfiguration*)UA_new(&UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION]); +} + +static UA_INLINE UA_StatusCode +UA_AggregateConfiguration_copy(const UA_AggregateConfiguration *src, UA_AggregateConfiguration *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AggregateConfiguration_deleteMembers(UA_AggregateConfiguration *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION]); +} + +static UA_INLINE void +UA_AggregateConfiguration_clear(UA_AggregateConfiguration *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION]); +} + +static UA_INLINE void +UA_AggregateConfiguration_delete(UA_AggregateConfiguration *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION]); +}static UA_INLINE UA_Boolean +UA_AggregateConfiguration_equal(const UA_AggregateConfiguration *p1, const UA_AggregateConfiguration *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION]) == UA_ORDER_EQ); +} + + + +/* AggregateFilter */ +static UA_INLINE void +UA_AggregateFilter_init(UA_AggregateFilter *p) { + memset(p, 0, sizeof(UA_AggregateFilter)); +} + +static UA_INLINE UA_AggregateFilter * +UA_AggregateFilter_new(void) { + return (UA_AggregateFilter*)UA_new(&UA_TYPES[UA_TYPES_AGGREGATEFILTER]); +} + +static UA_INLINE UA_StatusCode +UA_AggregateFilter_copy(const UA_AggregateFilter *src, UA_AggregateFilter *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_AGGREGATEFILTER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AggregateFilter_deleteMembers(UA_AggregateFilter *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_AGGREGATEFILTER]); +} + +static UA_INLINE void +UA_AggregateFilter_clear(UA_AggregateFilter *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_AGGREGATEFILTER]); +} + +static UA_INLINE void +UA_AggregateFilter_delete(UA_AggregateFilter *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_AGGREGATEFILTER]); +}static UA_INLINE UA_Boolean +UA_AggregateFilter_equal(const UA_AggregateFilter *p1, const UA_AggregateFilter *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_AGGREGATEFILTER]) == UA_ORDER_EQ); +} + + + +/* EventFilterResult */ +static UA_INLINE void +UA_EventFilterResult_init(UA_EventFilterResult *p) { + memset(p, 0, sizeof(UA_EventFilterResult)); +} + +static UA_INLINE UA_EventFilterResult * +UA_EventFilterResult_new(void) { + return (UA_EventFilterResult*)UA_new(&UA_TYPES[UA_TYPES_EVENTFILTERRESULT]); +} + +static UA_INLINE UA_StatusCode +UA_EventFilterResult_copy(const UA_EventFilterResult *src, UA_EventFilterResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_EVENTFILTERRESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EventFilterResult_deleteMembers(UA_EventFilterResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EVENTFILTERRESULT]); +} + +static UA_INLINE void +UA_EventFilterResult_clear(UA_EventFilterResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EVENTFILTERRESULT]); +} + +static UA_INLINE void +UA_EventFilterResult_delete(UA_EventFilterResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_EVENTFILTERRESULT]); +}static UA_INLINE UA_Boolean +UA_EventFilterResult_equal(const UA_EventFilterResult *p1, const UA_EventFilterResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_EVENTFILTERRESULT]) == UA_ORDER_EQ); +} + + + +/* AggregateFilterResult */ +static UA_INLINE void +UA_AggregateFilterResult_init(UA_AggregateFilterResult *p) { + memset(p, 0, sizeof(UA_AggregateFilterResult)); +} + +static UA_INLINE UA_AggregateFilterResult * +UA_AggregateFilterResult_new(void) { + return (UA_AggregateFilterResult*)UA_new(&UA_TYPES[UA_TYPES_AGGREGATEFILTERRESULT]); +} + +static UA_INLINE UA_StatusCode +UA_AggregateFilterResult_copy(const UA_AggregateFilterResult *src, UA_AggregateFilterResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_AGGREGATEFILTERRESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AggregateFilterResult_deleteMembers(UA_AggregateFilterResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_AGGREGATEFILTERRESULT]); +} + +static UA_INLINE void +UA_AggregateFilterResult_clear(UA_AggregateFilterResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_AGGREGATEFILTERRESULT]); +} + +static UA_INLINE void +UA_AggregateFilterResult_delete(UA_AggregateFilterResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_AGGREGATEFILTERRESULT]); +}static UA_INLINE UA_Boolean +UA_AggregateFilterResult_equal(const UA_AggregateFilterResult *p1, const UA_AggregateFilterResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_AGGREGATEFILTERRESULT]) == UA_ORDER_EQ); +} + + + +/* MonitoringParameters */ +static UA_INLINE void +UA_MonitoringParameters_init(UA_MonitoringParameters *p) { + memset(p, 0, sizeof(UA_MonitoringParameters)); +} + +static UA_INLINE UA_MonitoringParameters * +UA_MonitoringParameters_new(void) { + return (UA_MonitoringParameters*)UA_new(&UA_TYPES[UA_TYPES_MONITORINGPARAMETERS]); +} + +static UA_INLINE UA_StatusCode +UA_MonitoringParameters_copy(const UA_MonitoringParameters *src, UA_MonitoringParameters *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MONITORINGPARAMETERS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_MonitoringParameters_deleteMembers(UA_MonitoringParameters *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITORINGPARAMETERS]); +} + +static UA_INLINE void +UA_MonitoringParameters_clear(UA_MonitoringParameters *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITORINGPARAMETERS]); +} + +static UA_INLINE void +UA_MonitoringParameters_delete(UA_MonitoringParameters *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MONITORINGPARAMETERS]); +}static UA_INLINE UA_Boolean +UA_MonitoringParameters_equal(const UA_MonitoringParameters *p1, const UA_MonitoringParameters *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MONITORINGPARAMETERS]) == UA_ORDER_EQ); +} + + + +/* MonitoredItemCreateRequest */ +static UA_INLINE void +UA_MonitoredItemCreateRequest_init(UA_MonitoredItemCreateRequest *p) { + memset(p, 0, sizeof(UA_MonitoredItemCreateRequest)); +} + +static UA_INLINE UA_MonitoredItemCreateRequest * +UA_MonitoredItemCreateRequest_new(void) { + return (UA_MonitoredItemCreateRequest*)UA_new(&UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_MonitoredItemCreateRequest_copy(const UA_MonitoredItemCreateRequest *src, UA_MonitoredItemCreateRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_MonitoredItemCreateRequest_deleteMembers(UA_MonitoredItemCreateRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST]); +} + +static UA_INLINE void +UA_MonitoredItemCreateRequest_clear(UA_MonitoredItemCreateRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST]); +} + +static UA_INLINE void +UA_MonitoredItemCreateRequest_delete(UA_MonitoredItemCreateRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST]); +}static UA_INLINE UA_Boolean +UA_MonitoredItemCreateRequest_equal(const UA_MonitoredItemCreateRequest *p1, const UA_MonitoredItemCreateRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST]) == UA_ORDER_EQ); +} + + + +/* MonitoredItemCreateResult */ +static UA_INLINE void +UA_MonitoredItemCreateResult_init(UA_MonitoredItemCreateResult *p) { + memset(p, 0, sizeof(UA_MonitoredItemCreateResult)); +} + +static UA_INLINE UA_MonitoredItemCreateResult * +UA_MonitoredItemCreateResult_new(void) { + return (UA_MonitoredItemCreateResult*)UA_new(&UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT]); +} + +static UA_INLINE UA_StatusCode +UA_MonitoredItemCreateResult_copy(const UA_MonitoredItemCreateResult *src, UA_MonitoredItemCreateResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_MonitoredItemCreateResult_deleteMembers(UA_MonitoredItemCreateResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT]); +} + +static UA_INLINE void +UA_MonitoredItemCreateResult_clear(UA_MonitoredItemCreateResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT]); +} + +static UA_INLINE void +UA_MonitoredItemCreateResult_delete(UA_MonitoredItemCreateResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT]); +}static UA_INLINE UA_Boolean +UA_MonitoredItemCreateResult_equal(const UA_MonitoredItemCreateResult *p1, const UA_MonitoredItemCreateResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT]) == UA_ORDER_EQ); +} + + + +/* CreateMonitoredItemsRequest */ +static UA_INLINE void +UA_CreateMonitoredItemsRequest_init(UA_CreateMonitoredItemsRequest *p) { + memset(p, 0, sizeof(UA_CreateMonitoredItemsRequest)); +} + +static UA_INLINE UA_CreateMonitoredItemsRequest * +UA_CreateMonitoredItemsRequest_new(void) { + return (UA_CreateMonitoredItemsRequest*)UA_new(&UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_CreateMonitoredItemsRequest_copy(const UA_CreateMonitoredItemsRequest *src, UA_CreateMonitoredItemsRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CreateMonitoredItemsRequest_deleteMembers(UA_CreateMonitoredItemsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST]); +} + +static UA_INLINE void +UA_CreateMonitoredItemsRequest_clear(UA_CreateMonitoredItemsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST]); +} + +static UA_INLINE void +UA_CreateMonitoredItemsRequest_delete(UA_CreateMonitoredItemsRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST]); +}static UA_INLINE UA_Boolean +UA_CreateMonitoredItemsRequest_equal(const UA_CreateMonitoredItemsRequest *p1, const UA_CreateMonitoredItemsRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST]) == UA_ORDER_EQ); +} + + + +/* CreateMonitoredItemsResponse */ +static UA_INLINE void +UA_CreateMonitoredItemsResponse_init(UA_CreateMonitoredItemsResponse *p) { + memset(p, 0, sizeof(UA_CreateMonitoredItemsResponse)); +} + +static UA_INLINE UA_CreateMonitoredItemsResponse * +UA_CreateMonitoredItemsResponse_new(void) { + return (UA_CreateMonitoredItemsResponse*)UA_new(&UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_CreateMonitoredItemsResponse_copy(const UA_CreateMonitoredItemsResponse *src, UA_CreateMonitoredItemsResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CreateMonitoredItemsResponse_deleteMembers(UA_CreateMonitoredItemsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE]); +} + +static UA_INLINE void +UA_CreateMonitoredItemsResponse_clear(UA_CreateMonitoredItemsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE]); +} + +static UA_INLINE void +UA_CreateMonitoredItemsResponse_delete(UA_CreateMonitoredItemsResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE]); +}static UA_INLINE UA_Boolean +UA_CreateMonitoredItemsResponse_equal(const UA_CreateMonitoredItemsResponse *p1, const UA_CreateMonitoredItemsResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE]) == UA_ORDER_EQ); +} + + + +/* MonitoredItemModifyRequest */ +static UA_INLINE void +UA_MonitoredItemModifyRequest_init(UA_MonitoredItemModifyRequest *p) { + memset(p, 0, sizeof(UA_MonitoredItemModifyRequest)); +} + +static UA_INLINE UA_MonitoredItemModifyRequest * +UA_MonitoredItemModifyRequest_new(void) { + return (UA_MonitoredItemModifyRequest*)UA_new(&UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_MonitoredItemModifyRequest_copy(const UA_MonitoredItemModifyRequest *src, UA_MonitoredItemModifyRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_MonitoredItemModifyRequest_deleteMembers(UA_MonitoredItemModifyRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST]); +} + +static UA_INLINE void +UA_MonitoredItemModifyRequest_clear(UA_MonitoredItemModifyRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST]); +} + +static UA_INLINE void +UA_MonitoredItemModifyRequest_delete(UA_MonitoredItemModifyRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST]); +}static UA_INLINE UA_Boolean +UA_MonitoredItemModifyRequest_equal(const UA_MonitoredItemModifyRequest *p1, const UA_MonitoredItemModifyRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST]) == UA_ORDER_EQ); +} + + + +/* MonitoredItemModifyResult */ +static UA_INLINE void +UA_MonitoredItemModifyResult_init(UA_MonitoredItemModifyResult *p) { + memset(p, 0, sizeof(UA_MonitoredItemModifyResult)); +} + +static UA_INLINE UA_MonitoredItemModifyResult * +UA_MonitoredItemModifyResult_new(void) { + return (UA_MonitoredItemModifyResult*)UA_new(&UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT]); +} + +static UA_INLINE UA_StatusCode +UA_MonitoredItemModifyResult_copy(const UA_MonitoredItemModifyResult *src, UA_MonitoredItemModifyResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_MonitoredItemModifyResult_deleteMembers(UA_MonitoredItemModifyResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT]); +} + +static UA_INLINE void +UA_MonitoredItemModifyResult_clear(UA_MonitoredItemModifyResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT]); +} + +static UA_INLINE void +UA_MonitoredItemModifyResult_delete(UA_MonitoredItemModifyResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT]); +}static UA_INLINE UA_Boolean +UA_MonitoredItemModifyResult_equal(const UA_MonitoredItemModifyResult *p1, const UA_MonitoredItemModifyResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT]) == UA_ORDER_EQ); +} + + + +/* ModifyMonitoredItemsRequest */ +static UA_INLINE void +UA_ModifyMonitoredItemsRequest_init(UA_ModifyMonitoredItemsRequest *p) { + memset(p, 0, sizeof(UA_ModifyMonitoredItemsRequest)); +} + +static UA_INLINE UA_ModifyMonitoredItemsRequest * +UA_ModifyMonitoredItemsRequest_new(void) { + return (UA_ModifyMonitoredItemsRequest*)UA_new(&UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_ModifyMonitoredItemsRequest_copy(const UA_ModifyMonitoredItemsRequest *src, UA_ModifyMonitoredItemsRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ModifyMonitoredItemsRequest_deleteMembers(UA_ModifyMonitoredItemsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST]); +} + +static UA_INLINE void +UA_ModifyMonitoredItemsRequest_clear(UA_ModifyMonitoredItemsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST]); +} + +static UA_INLINE void +UA_ModifyMonitoredItemsRequest_delete(UA_ModifyMonitoredItemsRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST]); +}static UA_INLINE UA_Boolean +UA_ModifyMonitoredItemsRequest_equal(const UA_ModifyMonitoredItemsRequest *p1, const UA_ModifyMonitoredItemsRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST]) == UA_ORDER_EQ); +} + + + +/* ModifyMonitoredItemsResponse */ +static UA_INLINE void +UA_ModifyMonitoredItemsResponse_init(UA_ModifyMonitoredItemsResponse *p) { + memset(p, 0, sizeof(UA_ModifyMonitoredItemsResponse)); +} + +static UA_INLINE UA_ModifyMonitoredItemsResponse * +UA_ModifyMonitoredItemsResponse_new(void) { + return (UA_ModifyMonitoredItemsResponse*)UA_new(&UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_ModifyMonitoredItemsResponse_copy(const UA_ModifyMonitoredItemsResponse *src, UA_ModifyMonitoredItemsResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ModifyMonitoredItemsResponse_deleteMembers(UA_ModifyMonitoredItemsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE]); +} + +static UA_INLINE void +UA_ModifyMonitoredItemsResponse_clear(UA_ModifyMonitoredItemsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE]); +} + +static UA_INLINE void +UA_ModifyMonitoredItemsResponse_delete(UA_ModifyMonitoredItemsResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE]); +}static UA_INLINE UA_Boolean +UA_ModifyMonitoredItemsResponse_equal(const UA_ModifyMonitoredItemsResponse *p1, const UA_ModifyMonitoredItemsResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE]) == UA_ORDER_EQ); +} + + + +/* SetMonitoringModeRequest */ +static UA_INLINE void +UA_SetMonitoringModeRequest_init(UA_SetMonitoringModeRequest *p) { + memset(p, 0, sizeof(UA_SetMonitoringModeRequest)); +} + +static UA_INLINE UA_SetMonitoringModeRequest * +UA_SetMonitoringModeRequest_new(void) { + return (UA_SetMonitoringModeRequest*)UA_new(&UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_SetMonitoringModeRequest_copy(const UA_SetMonitoringModeRequest *src, UA_SetMonitoringModeRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SetMonitoringModeRequest_deleteMembers(UA_SetMonitoringModeRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST]); +} + +static UA_INLINE void +UA_SetMonitoringModeRequest_clear(UA_SetMonitoringModeRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST]); +} + +static UA_INLINE void +UA_SetMonitoringModeRequest_delete(UA_SetMonitoringModeRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST]); +}static UA_INLINE UA_Boolean +UA_SetMonitoringModeRequest_equal(const UA_SetMonitoringModeRequest *p1, const UA_SetMonitoringModeRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST]) == UA_ORDER_EQ); +} + + + +/* SetMonitoringModeResponse */ +static UA_INLINE void +UA_SetMonitoringModeResponse_init(UA_SetMonitoringModeResponse *p) { + memset(p, 0, sizeof(UA_SetMonitoringModeResponse)); +} + +static UA_INLINE UA_SetMonitoringModeResponse * +UA_SetMonitoringModeResponse_new(void) { + return (UA_SetMonitoringModeResponse*)UA_new(&UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_SetMonitoringModeResponse_copy(const UA_SetMonitoringModeResponse *src, UA_SetMonitoringModeResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SetMonitoringModeResponse_deleteMembers(UA_SetMonitoringModeResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE]); +} + +static UA_INLINE void +UA_SetMonitoringModeResponse_clear(UA_SetMonitoringModeResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE]); +} + +static UA_INLINE void +UA_SetMonitoringModeResponse_delete(UA_SetMonitoringModeResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE]); +}static UA_INLINE UA_Boolean +UA_SetMonitoringModeResponse_equal(const UA_SetMonitoringModeResponse *p1, const UA_SetMonitoringModeResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE]) == UA_ORDER_EQ); +} + + + +/* SetTriggeringRequest */ +static UA_INLINE void +UA_SetTriggeringRequest_init(UA_SetTriggeringRequest *p) { + memset(p, 0, sizeof(UA_SetTriggeringRequest)); +} + +static UA_INLINE UA_SetTriggeringRequest * +UA_SetTriggeringRequest_new(void) { + return (UA_SetTriggeringRequest*)UA_new(&UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_SetTriggeringRequest_copy(const UA_SetTriggeringRequest *src, UA_SetTriggeringRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SetTriggeringRequest_deleteMembers(UA_SetTriggeringRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST]); +} + +static UA_INLINE void +UA_SetTriggeringRequest_clear(UA_SetTriggeringRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST]); +} + +static UA_INLINE void +UA_SetTriggeringRequest_delete(UA_SetTriggeringRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST]); +}static UA_INLINE UA_Boolean +UA_SetTriggeringRequest_equal(const UA_SetTriggeringRequest *p1, const UA_SetTriggeringRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST]) == UA_ORDER_EQ); +} + + + +/* SetTriggeringResponse */ +static UA_INLINE void +UA_SetTriggeringResponse_init(UA_SetTriggeringResponse *p) { + memset(p, 0, sizeof(UA_SetTriggeringResponse)); +} + +static UA_INLINE UA_SetTriggeringResponse * +UA_SetTriggeringResponse_new(void) { + return (UA_SetTriggeringResponse*)UA_new(&UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_SetTriggeringResponse_copy(const UA_SetTriggeringResponse *src, UA_SetTriggeringResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SetTriggeringResponse_deleteMembers(UA_SetTriggeringResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE]); +} + +static UA_INLINE void +UA_SetTriggeringResponse_clear(UA_SetTriggeringResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE]); +} + +static UA_INLINE void +UA_SetTriggeringResponse_delete(UA_SetTriggeringResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE]); +}static UA_INLINE UA_Boolean +UA_SetTriggeringResponse_equal(const UA_SetTriggeringResponse *p1, const UA_SetTriggeringResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE]) == UA_ORDER_EQ); +} + + + +/* DeleteMonitoredItemsRequest */ +static UA_INLINE void +UA_DeleteMonitoredItemsRequest_init(UA_DeleteMonitoredItemsRequest *p) { + memset(p, 0, sizeof(UA_DeleteMonitoredItemsRequest)); +} + +static UA_INLINE UA_DeleteMonitoredItemsRequest * +UA_DeleteMonitoredItemsRequest_new(void) { + return (UA_DeleteMonitoredItemsRequest*)UA_new(&UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteMonitoredItemsRequest_copy(const UA_DeleteMonitoredItemsRequest *src, UA_DeleteMonitoredItemsRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteMonitoredItemsRequest_deleteMembers(UA_DeleteMonitoredItemsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST]); +} + +static UA_INLINE void +UA_DeleteMonitoredItemsRequest_clear(UA_DeleteMonitoredItemsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST]); +} + +static UA_INLINE void +UA_DeleteMonitoredItemsRequest_delete(UA_DeleteMonitoredItemsRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST]); +}static UA_INLINE UA_Boolean +UA_DeleteMonitoredItemsRequest_equal(const UA_DeleteMonitoredItemsRequest *p1, const UA_DeleteMonitoredItemsRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST]) == UA_ORDER_EQ); +} + + + +/* DeleteMonitoredItemsResponse */ +static UA_INLINE void +UA_DeleteMonitoredItemsResponse_init(UA_DeleteMonitoredItemsResponse *p) { + memset(p, 0, sizeof(UA_DeleteMonitoredItemsResponse)); +} + +static UA_INLINE UA_DeleteMonitoredItemsResponse * +UA_DeleteMonitoredItemsResponse_new(void) { + return (UA_DeleteMonitoredItemsResponse*)UA_new(&UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteMonitoredItemsResponse_copy(const UA_DeleteMonitoredItemsResponse *src, UA_DeleteMonitoredItemsResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteMonitoredItemsResponse_deleteMembers(UA_DeleteMonitoredItemsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE]); +} + +static UA_INLINE void +UA_DeleteMonitoredItemsResponse_clear(UA_DeleteMonitoredItemsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE]); +} + +static UA_INLINE void +UA_DeleteMonitoredItemsResponse_delete(UA_DeleteMonitoredItemsResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE]); +}static UA_INLINE UA_Boolean +UA_DeleteMonitoredItemsResponse_equal(const UA_DeleteMonitoredItemsResponse *p1, const UA_DeleteMonitoredItemsResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE]) == UA_ORDER_EQ); +} + + + +/* CreateSubscriptionRequest */ +static UA_INLINE void +UA_CreateSubscriptionRequest_init(UA_CreateSubscriptionRequest *p) { + memset(p, 0, sizeof(UA_CreateSubscriptionRequest)); +} + +static UA_INLINE UA_CreateSubscriptionRequest * +UA_CreateSubscriptionRequest_new(void) { + return (UA_CreateSubscriptionRequest*)UA_new(&UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_CreateSubscriptionRequest_copy(const UA_CreateSubscriptionRequest *src, UA_CreateSubscriptionRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CreateSubscriptionRequest_deleteMembers(UA_CreateSubscriptionRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST]); +} + +static UA_INLINE void +UA_CreateSubscriptionRequest_clear(UA_CreateSubscriptionRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST]); +} + +static UA_INLINE void +UA_CreateSubscriptionRequest_delete(UA_CreateSubscriptionRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST]); +}static UA_INLINE UA_Boolean +UA_CreateSubscriptionRequest_equal(const UA_CreateSubscriptionRequest *p1, const UA_CreateSubscriptionRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST]) == UA_ORDER_EQ); +} + + + +/* CreateSubscriptionResponse */ +static UA_INLINE void +UA_CreateSubscriptionResponse_init(UA_CreateSubscriptionResponse *p) { + memset(p, 0, sizeof(UA_CreateSubscriptionResponse)); +} + +static UA_INLINE UA_CreateSubscriptionResponse * +UA_CreateSubscriptionResponse_new(void) { + return (UA_CreateSubscriptionResponse*)UA_new(&UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_CreateSubscriptionResponse_copy(const UA_CreateSubscriptionResponse *src, UA_CreateSubscriptionResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_CreateSubscriptionResponse_deleteMembers(UA_CreateSubscriptionResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE]); +} + +static UA_INLINE void +UA_CreateSubscriptionResponse_clear(UA_CreateSubscriptionResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE]); +} + +static UA_INLINE void +UA_CreateSubscriptionResponse_delete(UA_CreateSubscriptionResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE]); +}static UA_INLINE UA_Boolean +UA_CreateSubscriptionResponse_equal(const UA_CreateSubscriptionResponse *p1, const UA_CreateSubscriptionResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE]) == UA_ORDER_EQ); +} + + + +/* ModifySubscriptionRequest */ +static UA_INLINE void +UA_ModifySubscriptionRequest_init(UA_ModifySubscriptionRequest *p) { + memset(p, 0, sizeof(UA_ModifySubscriptionRequest)); +} + +static UA_INLINE UA_ModifySubscriptionRequest * +UA_ModifySubscriptionRequest_new(void) { + return (UA_ModifySubscriptionRequest*)UA_new(&UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_ModifySubscriptionRequest_copy(const UA_ModifySubscriptionRequest *src, UA_ModifySubscriptionRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ModifySubscriptionRequest_deleteMembers(UA_ModifySubscriptionRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST]); +} + +static UA_INLINE void +UA_ModifySubscriptionRequest_clear(UA_ModifySubscriptionRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST]); +} + +static UA_INLINE void +UA_ModifySubscriptionRequest_delete(UA_ModifySubscriptionRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST]); +}static UA_INLINE UA_Boolean +UA_ModifySubscriptionRequest_equal(const UA_ModifySubscriptionRequest *p1, const UA_ModifySubscriptionRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST]) == UA_ORDER_EQ); +} + + + +/* ModifySubscriptionResponse */ +static UA_INLINE void +UA_ModifySubscriptionResponse_init(UA_ModifySubscriptionResponse *p) { + memset(p, 0, sizeof(UA_ModifySubscriptionResponse)); +} + +static UA_INLINE UA_ModifySubscriptionResponse * +UA_ModifySubscriptionResponse_new(void) { + return (UA_ModifySubscriptionResponse*)UA_new(&UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_ModifySubscriptionResponse_copy(const UA_ModifySubscriptionResponse *src, UA_ModifySubscriptionResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ModifySubscriptionResponse_deleteMembers(UA_ModifySubscriptionResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE]); +} + +static UA_INLINE void +UA_ModifySubscriptionResponse_clear(UA_ModifySubscriptionResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE]); +} + +static UA_INLINE void +UA_ModifySubscriptionResponse_delete(UA_ModifySubscriptionResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE]); +}static UA_INLINE UA_Boolean +UA_ModifySubscriptionResponse_equal(const UA_ModifySubscriptionResponse *p1, const UA_ModifySubscriptionResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE]) == UA_ORDER_EQ); +} + + + +/* SetPublishingModeRequest */ +static UA_INLINE void +UA_SetPublishingModeRequest_init(UA_SetPublishingModeRequest *p) { + memset(p, 0, sizeof(UA_SetPublishingModeRequest)); +} + +static UA_INLINE UA_SetPublishingModeRequest * +UA_SetPublishingModeRequest_new(void) { + return (UA_SetPublishingModeRequest*)UA_new(&UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_SetPublishingModeRequest_copy(const UA_SetPublishingModeRequest *src, UA_SetPublishingModeRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SetPublishingModeRequest_deleteMembers(UA_SetPublishingModeRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST]); +} + +static UA_INLINE void +UA_SetPublishingModeRequest_clear(UA_SetPublishingModeRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST]); +} + +static UA_INLINE void +UA_SetPublishingModeRequest_delete(UA_SetPublishingModeRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST]); +}static UA_INLINE UA_Boolean +UA_SetPublishingModeRequest_equal(const UA_SetPublishingModeRequest *p1, const UA_SetPublishingModeRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST]) == UA_ORDER_EQ); +} + + + +/* SetPublishingModeResponse */ +static UA_INLINE void +UA_SetPublishingModeResponse_init(UA_SetPublishingModeResponse *p) { + memset(p, 0, sizeof(UA_SetPublishingModeResponse)); +} + +static UA_INLINE UA_SetPublishingModeResponse * +UA_SetPublishingModeResponse_new(void) { + return (UA_SetPublishingModeResponse*)UA_new(&UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_SetPublishingModeResponse_copy(const UA_SetPublishingModeResponse *src, UA_SetPublishingModeResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SetPublishingModeResponse_deleteMembers(UA_SetPublishingModeResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE]); +} + +static UA_INLINE void +UA_SetPublishingModeResponse_clear(UA_SetPublishingModeResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE]); +} + +static UA_INLINE void +UA_SetPublishingModeResponse_delete(UA_SetPublishingModeResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE]); +}static UA_INLINE UA_Boolean +UA_SetPublishingModeResponse_equal(const UA_SetPublishingModeResponse *p1, const UA_SetPublishingModeResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE]) == UA_ORDER_EQ); +} + + + +/* NotificationMessage */ +static UA_INLINE void +UA_NotificationMessage_init(UA_NotificationMessage *p) { + memset(p, 0, sizeof(UA_NotificationMessage)); +} + +static UA_INLINE UA_NotificationMessage * +UA_NotificationMessage_new(void) { + return (UA_NotificationMessage*)UA_new(&UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE]); +} + +static UA_INLINE UA_StatusCode +UA_NotificationMessage_copy(const UA_NotificationMessage *src, UA_NotificationMessage *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NotificationMessage_deleteMembers(UA_NotificationMessage *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE]); +} + +static UA_INLINE void +UA_NotificationMessage_clear(UA_NotificationMessage *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE]); +} + +static UA_INLINE void +UA_NotificationMessage_delete(UA_NotificationMessage *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE]); +}static UA_INLINE UA_Boolean +UA_NotificationMessage_equal(const UA_NotificationMessage *p1, const UA_NotificationMessage *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE]) == UA_ORDER_EQ); +} + + + +/* MonitoredItemNotification */ +static UA_INLINE void +UA_MonitoredItemNotification_init(UA_MonitoredItemNotification *p) { + memset(p, 0, sizeof(UA_MonitoredItemNotification)); +} + +static UA_INLINE UA_MonitoredItemNotification * +UA_MonitoredItemNotification_new(void) { + return (UA_MonitoredItemNotification*)UA_new(&UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION]); +} + +static UA_INLINE UA_StatusCode +UA_MonitoredItemNotification_copy(const UA_MonitoredItemNotification *src, UA_MonitoredItemNotification *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_MonitoredItemNotification_deleteMembers(UA_MonitoredItemNotification *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION]); +} + +static UA_INLINE void +UA_MonitoredItemNotification_clear(UA_MonitoredItemNotification *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION]); +} + +static UA_INLINE void +UA_MonitoredItemNotification_delete(UA_MonitoredItemNotification *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION]); +}static UA_INLINE UA_Boolean +UA_MonitoredItemNotification_equal(const UA_MonitoredItemNotification *p1, const UA_MonitoredItemNotification *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION]) == UA_ORDER_EQ); +} + + + +/* EventFieldList */ +static UA_INLINE void +UA_EventFieldList_init(UA_EventFieldList *p) { + memset(p, 0, sizeof(UA_EventFieldList)); +} + +static UA_INLINE UA_EventFieldList * +UA_EventFieldList_new(void) { + return (UA_EventFieldList*)UA_new(&UA_TYPES[UA_TYPES_EVENTFIELDLIST]); +} + +static UA_INLINE UA_StatusCode +UA_EventFieldList_copy(const UA_EventFieldList *src, UA_EventFieldList *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_EVENTFIELDLIST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EventFieldList_deleteMembers(UA_EventFieldList *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EVENTFIELDLIST]); +} + +static UA_INLINE void +UA_EventFieldList_clear(UA_EventFieldList *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EVENTFIELDLIST]); +} + +static UA_INLINE void +UA_EventFieldList_delete(UA_EventFieldList *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_EVENTFIELDLIST]); +}static UA_INLINE UA_Boolean +UA_EventFieldList_equal(const UA_EventFieldList *p1, const UA_EventFieldList *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_EVENTFIELDLIST]) == UA_ORDER_EQ); +} + + + +/* HistoryEventFieldList */ +static UA_INLINE void +UA_HistoryEventFieldList_init(UA_HistoryEventFieldList *p) { + memset(p, 0, sizeof(UA_HistoryEventFieldList)); +} + +static UA_INLINE UA_HistoryEventFieldList * +UA_HistoryEventFieldList_new(void) { + return (UA_HistoryEventFieldList*)UA_new(&UA_TYPES[UA_TYPES_HISTORYEVENTFIELDLIST]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryEventFieldList_copy(const UA_HistoryEventFieldList *src, UA_HistoryEventFieldList *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYEVENTFIELDLIST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryEventFieldList_deleteMembers(UA_HistoryEventFieldList *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYEVENTFIELDLIST]); +} + +static UA_INLINE void +UA_HistoryEventFieldList_clear(UA_HistoryEventFieldList *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYEVENTFIELDLIST]); +} + +static UA_INLINE void +UA_HistoryEventFieldList_delete(UA_HistoryEventFieldList *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYEVENTFIELDLIST]); +}static UA_INLINE UA_Boolean +UA_HistoryEventFieldList_equal(const UA_HistoryEventFieldList *p1, const UA_HistoryEventFieldList *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYEVENTFIELDLIST]) == UA_ORDER_EQ); +} + + + +/* StatusChangeNotification */ +static UA_INLINE void +UA_StatusChangeNotification_init(UA_StatusChangeNotification *p) { + memset(p, 0, sizeof(UA_StatusChangeNotification)); +} + +static UA_INLINE UA_StatusChangeNotification * +UA_StatusChangeNotification_new(void) { + return (UA_StatusChangeNotification*)UA_new(&UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION]); +} + +static UA_INLINE UA_StatusCode +UA_StatusChangeNotification_copy(const UA_StatusChangeNotification *src, UA_StatusChangeNotification *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_StatusChangeNotification_deleteMembers(UA_StatusChangeNotification *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION]); +} + +static UA_INLINE void +UA_StatusChangeNotification_clear(UA_StatusChangeNotification *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION]); +} + +static UA_INLINE void +UA_StatusChangeNotification_delete(UA_StatusChangeNotification *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION]); +}static UA_INLINE UA_Boolean +UA_StatusChangeNotification_equal(const UA_StatusChangeNotification *p1, const UA_StatusChangeNotification *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION]) == UA_ORDER_EQ); +} + + + +/* SubscriptionAcknowledgement */ +static UA_INLINE void +UA_SubscriptionAcknowledgement_init(UA_SubscriptionAcknowledgement *p) { + memset(p, 0, sizeof(UA_SubscriptionAcknowledgement)); +} + +static UA_INLINE UA_SubscriptionAcknowledgement * +UA_SubscriptionAcknowledgement_new(void) { + return (UA_SubscriptionAcknowledgement*)UA_new(&UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT]); +} + +static UA_INLINE UA_StatusCode +UA_SubscriptionAcknowledgement_copy(const UA_SubscriptionAcknowledgement *src, UA_SubscriptionAcknowledgement *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SubscriptionAcknowledgement_deleteMembers(UA_SubscriptionAcknowledgement *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT]); +} + +static UA_INLINE void +UA_SubscriptionAcknowledgement_clear(UA_SubscriptionAcknowledgement *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT]); +} + +static UA_INLINE void +UA_SubscriptionAcknowledgement_delete(UA_SubscriptionAcknowledgement *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT]); +}static UA_INLINE UA_Boolean +UA_SubscriptionAcknowledgement_equal(const UA_SubscriptionAcknowledgement *p1, const UA_SubscriptionAcknowledgement *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT]) == UA_ORDER_EQ); +} + + + +/* PublishRequest */ +static UA_INLINE void +UA_PublishRequest_init(UA_PublishRequest *p) { + memset(p, 0, sizeof(UA_PublishRequest)); +} + +static UA_INLINE UA_PublishRequest * +UA_PublishRequest_new(void) { + return (UA_PublishRequest*)UA_new(&UA_TYPES[UA_TYPES_PUBLISHREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_PublishRequest_copy(const UA_PublishRequest *src, UA_PublishRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBLISHREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PublishRequest_deleteMembers(UA_PublishRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHREQUEST]); +} + +static UA_INLINE void +UA_PublishRequest_clear(UA_PublishRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHREQUEST]); +} + +static UA_INLINE void +UA_PublishRequest_delete(UA_PublishRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBLISHREQUEST]); +}static UA_INLINE UA_Boolean +UA_PublishRequest_equal(const UA_PublishRequest *p1, const UA_PublishRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBLISHREQUEST]) == UA_ORDER_EQ); +} + + + +/* PublishResponse */ +static UA_INLINE void +UA_PublishResponse_init(UA_PublishResponse *p) { + memset(p, 0, sizeof(UA_PublishResponse)); +} + +static UA_INLINE UA_PublishResponse * +UA_PublishResponse_new(void) { + return (UA_PublishResponse*)UA_new(&UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_PublishResponse_copy(const UA_PublishResponse *src, UA_PublishResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PublishResponse_deleteMembers(UA_PublishResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); +} + +static UA_INLINE void +UA_PublishResponse_clear(UA_PublishResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); +} + +static UA_INLINE void +UA_PublishResponse_delete(UA_PublishResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); +}static UA_INLINE UA_Boolean +UA_PublishResponse_equal(const UA_PublishResponse *p1, const UA_PublishResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]) == UA_ORDER_EQ); +} + + + +/* RepublishRequest */ +static UA_INLINE void +UA_RepublishRequest_init(UA_RepublishRequest *p) { + memset(p, 0, sizeof(UA_RepublishRequest)); +} + +static UA_INLINE UA_RepublishRequest * +UA_RepublishRequest_new(void) { + return (UA_RepublishRequest*)UA_new(&UA_TYPES[UA_TYPES_REPUBLISHREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_RepublishRequest_copy(const UA_RepublishRequest *src, UA_RepublishRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REPUBLISHREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RepublishRequest_deleteMembers(UA_RepublishRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REPUBLISHREQUEST]); +} + +static UA_INLINE void +UA_RepublishRequest_clear(UA_RepublishRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REPUBLISHREQUEST]); +} + +static UA_INLINE void +UA_RepublishRequest_delete(UA_RepublishRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REPUBLISHREQUEST]); +}static UA_INLINE UA_Boolean +UA_RepublishRequest_equal(const UA_RepublishRequest *p1, const UA_RepublishRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REPUBLISHREQUEST]) == UA_ORDER_EQ); +} + + + +/* RepublishResponse */ +static UA_INLINE void +UA_RepublishResponse_init(UA_RepublishResponse *p) { + memset(p, 0, sizeof(UA_RepublishResponse)); +} + +static UA_INLINE UA_RepublishResponse * +UA_RepublishResponse_new(void) { + return (UA_RepublishResponse*)UA_new(&UA_TYPES[UA_TYPES_REPUBLISHRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_RepublishResponse_copy(const UA_RepublishResponse *src, UA_RepublishResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REPUBLISHRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RepublishResponse_deleteMembers(UA_RepublishResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REPUBLISHRESPONSE]); +} + +static UA_INLINE void +UA_RepublishResponse_clear(UA_RepublishResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REPUBLISHRESPONSE]); +} + +static UA_INLINE void +UA_RepublishResponse_delete(UA_RepublishResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REPUBLISHRESPONSE]); +}static UA_INLINE UA_Boolean +UA_RepublishResponse_equal(const UA_RepublishResponse *p1, const UA_RepublishResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REPUBLISHRESPONSE]) == UA_ORDER_EQ); +} + + + +/* TransferResult */ +static UA_INLINE void +UA_TransferResult_init(UA_TransferResult *p) { + memset(p, 0, sizeof(UA_TransferResult)); +} + +static UA_INLINE UA_TransferResult * +UA_TransferResult_new(void) { + return (UA_TransferResult*)UA_new(&UA_TYPES[UA_TYPES_TRANSFERRESULT]); +} + +static UA_INLINE UA_StatusCode +UA_TransferResult_copy(const UA_TransferResult *src, UA_TransferResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TRANSFERRESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TransferResult_deleteMembers(UA_TransferResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRANSFERRESULT]); +} + +static UA_INLINE void +UA_TransferResult_clear(UA_TransferResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRANSFERRESULT]); +} + +static UA_INLINE void +UA_TransferResult_delete(UA_TransferResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TRANSFERRESULT]); +}static UA_INLINE UA_Boolean +UA_TransferResult_equal(const UA_TransferResult *p1, const UA_TransferResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TRANSFERRESULT]) == UA_ORDER_EQ); +} + + + +/* TransferSubscriptionsRequest */ +static UA_INLINE void +UA_TransferSubscriptionsRequest_init(UA_TransferSubscriptionsRequest *p) { + memset(p, 0, sizeof(UA_TransferSubscriptionsRequest)); +} + +static UA_INLINE UA_TransferSubscriptionsRequest * +UA_TransferSubscriptionsRequest_new(void) { + return (UA_TransferSubscriptionsRequest*)UA_new(&UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_TransferSubscriptionsRequest_copy(const UA_TransferSubscriptionsRequest *src, UA_TransferSubscriptionsRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TransferSubscriptionsRequest_deleteMembers(UA_TransferSubscriptionsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSREQUEST]); +} + +static UA_INLINE void +UA_TransferSubscriptionsRequest_clear(UA_TransferSubscriptionsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSREQUEST]); +} + +static UA_INLINE void +UA_TransferSubscriptionsRequest_delete(UA_TransferSubscriptionsRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSREQUEST]); +}static UA_INLINE UA_Boolean +UA_TransferSubscriptionsRequest_equal(const UA_TransferSubscriptionsRequest *p1, const UA_TransferSubscriptionsRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSREQUEST]) == UA_ORDER_EQ); +} + + + +/* TransferSubscriptionsResponse */ +static UA_INLINE void +UA_TransferSubscriptionsResponse_init(UA_TransferSubscriptionsResponse *p) { + memset(p, 0, sizeof(UA_TransferSubscriptionsResponse)); +} + +static UA_INLINE UA_TransferSubscriptionsResponse * +UA_TransferSubscriptionsResponse_new(void) { + return (UA_TransferSubscriptionsResponse*)UA_new(&UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_TransferSubscriptionsResponse_copy(const UA_TransferSubscriptionsResponse *src, UA_TransferSubscriptionsResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TransferSubscriptionsResponse_deleteMembers(UA_TransferSubscriptionsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSRESPONSE]); +} + +static UA_INLINE void +UA_TransferSubscriptionsResponse_clear(UA_TransferSubscriptionsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSRESPONSE]); +} + +static UA_INLINE void +UA_TransferSubscriptionsResponse_delete(UA_TransferSubscriptionsResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSRESPONSE]); +}static UA_INLINE UA_Boolean +UA_TransferSubscriptionsResponse_equal(const UA_TransferSubscriptionsResponse *p1, const UA_TransferSubscriptionsResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TRANSFERSUBSCRIPTIONSRESPONSE]) == UA_ORDER_EQ); +} + + + +/* DeleteSubscriptionsRequest */ +static UA_INLINE void +UA_DeleteSubscriptionsRequest_init(UA_DeleteSubscriptionsRequest *p) { + memset(p, 0, sizeof(UA_DeleteSubscriptionsRequest)); +} + +static UA_INLINE UA_DeleteSubscriptionsRequest * +UA_DeleteSubscriptionsRequest_new(void) { + return (UA_DeleteSubscriptionsRequest*)UA_new(&UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteSubscriptionsRequest_copy(const UA_DeleteSubscriptionsRequest *src, UA_DeleteSubscriptionsRequest *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteSubscriptionsRequest_deleteMembers(UA_DeleteSubscriptionsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST]); +} + +static UA_INLINE void +UA_DeleteSubscriptionsRequest_clear(UA_DeleteSubscriptionsRequest *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST]); +} + +static UA_INLINE void +UA_DeleteSubscriptionsRequest_delete(UA_DeleteSubscriptionsRequest *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST]); +}static UA_INLINE UA_Boolean +UA_DeleteSubscriptionsRequest_equal(const UA_DeleteSubscriptionsRequest *p1, const UA_DeleteSubscriptionsRequest *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST]) == UA_ORDER_EQ); +} + + + +/* DeleteSubscriptionsResponse */ +static UA_INLINE void +UA_DeleteSubscriptionsResponse_init(UA_DeleteSubscriptionsResponse *p) { + memset(p, 0, sizeof(UA_DeleteSubscriptionsResponse)); +} + +static UA_INLINE UA_DeleteSubscriptionsResponse * +UA_DeleteSubscriptionsResponse_new(void) { + return (UA_DeleteSubscriptionsResponse*)UA_new(&UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE]); +} + +static UA_INLINE UA_StatusCode +UA_DeleteSubscriptionsResponse_copy(const UA_DeleteSubscriptionsResponse *src, UA_DeleteSubscriptionsResponse *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DeleteSubscriptionsResponse_deleteMembers(UA_DeleteSubscriptionsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE]); +} + +static UA_INLINE void +UA_DeleteSubscriptionsResponse_clear(UA_DeleteSubscriptionsResponse *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE]); +} + +static UA_INLINE void +UA_DeleteSubscriptionsResponse_delete(UA_DeleteSubscriptionsResponse *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE]); +}static UA_INLINE UA_Boolean +UA_DeleteSubscriptionsResponse_equal(const UA_DeleteSubscriptionsResponse *p1, const UA_DeleteSubscriptionsResponse *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE]) == UA_ORDER_EQ); +} + + + +/* BuildInfo */ +static UA_INLINE void +UA_BuildInfo_init(UA_BuildInfo *p) { + memset(p, 0, sizeof(UA_BuildInfo)); +} + +static UA_INLINE UA_BuildInfo * +UA_BuildInfo_new(void) { + return (UA_BuildInfo*)UA_new(&UA_TYPES[UA_TYPES_BUILDINFO]); +} + +static UA_INLINE UA_StatusCode +UA_BuildInfo_copy(const UA_BuildInfo *src, UA_BuildInfo *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_BUILDINFO]); +} + +UA_DEPRECATED static UA_INLINE void +UA_BuildInfo_deleteMembers(UA_BuildInfo *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BUILDINFO]); +} + +static UA_INLINE void +UA_BuildInfo_clear(UA_BuildInfo *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_BUILDINFO]); +} + +static UA_INLINE void +UA_BuildInfo_delete(UA_BuildInfo *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_BUILDINFO]); +}static UA_INLINE UA_Boolean +UA_BuildInfo_equal(const UA_BuildInfo *p1, const UA_BuildInfo *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_BUILDINFO]) == UA_ORDER_EQ); +} + + + +/* RedundancySupport */ +static UA_INLINE void +UA_RedundancySupport_init(UA_RedundancySupport *p) { + memset(p, 0, sizeof(UA_RedundancySupport)); +} + +static UA_INLINE UA_RedundancySupport * +UA_RedundancySupport_new(void) { + return (UA_RedundancySupport*)UA_new(&UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]); +} + +static UA_INLINE UA_StatusCode +UA_RedundancySupport_copy(const UA_RedundancySupport *src, UA_RedundancySupport *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RedundancySupport_deleteMembers(UA_RedundancySupport *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]); +} + +static UA_INLINE void +UA_RedundancySupport_clear(UA_RedundancySupport *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]); +} + +static UA_INLINE void +UA_RedundancySupport_delete(UA_RedundancySupport *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]); +}static UA_INLINE UA_Boolean +UA_RedundancySupport_equal(const UA_RedundancySupport *p1, const UA_RedundancySupport *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]) == UA_ORDER_EQ); +} + + + +/* ServerState */ +static UA_INLINE void +UA_ServerState_init(UA_ServerState *p) { + memset(p, 0, sizeof(UA_ServerState)); +} + +static UA_INLINE UA_ServerState * +UA_ServerState_new(void) { + return (UA_ServerState*)UA_new(&UA_TYPES[UA_TYPES_SERVERSTATE]); +} + +static UA_INLINE UA_StatusCode +UA_ServerState_copy(const UA_ServerState *src, UA_ServerState *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SERVERSTATE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ServerState_deleteMembers(UA_ServerState *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SERVERSTATE]); +} + +static UA_INLINE void +UA_ServerState_clear(UA_ServerState *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SERVERSTATE]); +} + +static UA_INLINE void +UA_ServerState_delete(UA_ServerState *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SERVERSTATE]); +}static UA_INLINE UA_Boolean +UA_ServerState_equal(const UA_ServerState *p1, const UA_ServerState *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SERVERSTATE]) == UA_ORDER_EQ); +} + + + +/* RedundantServerDataType */ +static UA_INLINE void +UA_RedundantServerDataType_init(UA_RedundantServerDataType *p) { + memset(p, 0, sizeof(UA_RedundantServerDataType)); +} + +static UA_INLINE UA_RedundantServerDataType * +UA_RedundantServerDataType_new(void) { + return (UA_RedundantServerDataType*)UA_new(&UA_TYPES[UA_TYPES_REDUNDANTSERVERDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_RedundantServerDataType_copy(const UA_RedundantServerDataType *src, UA_RedundantServerDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_REDUNDANTSERVERDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_RedundantServerDataType_deleteMembers(UA_RedundantServerDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REDUNDANTSERVERDATATYPE]); +} + +static UA_INLINE void +UA_RedundantServerDataType_clear(UA_RedundantServerDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_REDUNDANTSERVERDATATYPE]); +} + +static UA_INLINE void +UA_RedundantServerDataType_delete(UA_RedundantServerDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_REDUNDANTSERVERDATATYPE]); +}static UA_INLINE UA_Boolean +UA_RedundantServerDataType_equal(const UA_RedundantServerDataType *p1, const UA_RedundantServerDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_REDUNDANTSERVERDATATYPE]) == UA_ORDER_EQ); +} + + + +/* EndpointUrlListDataType */ +static UA_INLINE void +UA_EndpointUrlListDataType_init(UA_EndpointUrlListDataType *p) { + memset(p, 0, sizeof(UA_EndpointUrlListDataType)); +} + +static UA_INLINE UA_EndpointUrlListDataType * +UA_EndpointUrlListDataType_new(void) { + return (UA_EndpointUrlListDataType*)UA_new(&UA_TYPES[UA_TYPES_ENDPOINTURLLISTDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_EndpointUrlListDataType_copy(const UA_EndpointUrlListDataType *src, UA_EndpointUrlListDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ENDPOINTURLLISTDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EndpointUrlListDataType_deleteMembers(UA_EndpointUrlListDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENDPOINTURLLISTDATATYPE]); +} + +static UA_INLINE void +UA_EndpointUrlListDataType_clear(UA_EndpointUrlListDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENDPOINTURLLISTDATATYPE]); +} + +static UA_INLINE void +UA_EndpointUrlListDataType_delete(UA_EndpointUrlListDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ENDPOINTURLLISTDATATYPE]); +}static UA_INLINE UA_Boolean +UA_EndpointUrlListDataType_equal(const UA_EndpointUrlListDataType *p1, const UA_EndpointUrlListDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ENDPOINTURLLISTDATATYPE]) == UA_ORDER_EQ); +} + + + +/* NetworkGroupDataType */ +static UA_INLINE void +UA_NetworkGroupDataType_init(UA_NetworkGroupDataType *p) { + memset(p, 0, sizeof(UA_NetworkGroupDataType)); +} + +static UA_INLINE UA_NetworkGroupDataType * +UA_NetworkGroupDataType_new(void) { + return (UA_NetworkGroupDataType*)UA_new(&UA_TYPES[UA_TYPES_NETWORKGROUPDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_NetworkGroupDataType_copy(const UA_NetworkGroupDataType *src, UA_NetworkGroupDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_NETWORKGROUPDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_NetworkGroupDataType_deleteMembers(UA_NetworkGroupDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NETWORKGROUPDATATYPE]); +} + +static UA_INLINE void +UA_NetworkGroupDataType_clear(UA_NetworkGroupDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_NETWORKGROUPDATATYPE]); +} + +static UA_INLINE void +UA_NetworkGroupDataType_delete(UA_NetworkGroupDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_NETWORKGROUPDATATYPE]); +}static UA_INLINE UA_Boolean +UA_NetworkGroupDataType_equal(const UA_NetworkGroupDataType *p1, const UA_NetworkGroupDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_NETWORKGROUPDATATYPE]) == UA_ORDER_EQ); +} + + + +/* SamplingIntervalDiagnosticsDataType */ +static UA_INLINE void +UA_SamplingIntervalDiagnosticsDataType_init(UA_SamplingIntervalDiagnosticsDataType *p) { + memset(p, 0, sizeof(UA_SamplingIntervalDiagnosticsDataType)); +} + +static UA_INLINE UA_SamplingIntervalDiagnosticsDataType * +UA_SamplingIntervalDiagnosticsDataType_new(void) { + return (UA_SamplingIntervalDiagnosticsDataType*)UA_new(&UA_TYPES[UA_TYPES_SAMPLINGINTERVALDIAGNOSTICSDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_SamplingIntervalDiagnosticsDataType_copy(const UA_SamplingIntervalDiagnosticsDataType *src, UA_SamplingIntervalDiagnosticsDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SAMPLINGINTERVALDIAGNOSTICSDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SamplingIntervalDiagnosticsDataType_deleteMembers(UA_SamplingIntervalDiagnosticsDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SAMPLINGINTERVALDIAGNOSTICSDATATYPE]); +} + +static UA_INLINE void +UA_SamplingIntervalDiagnosticsDataType_clear(UA_SamplingIntervalDiagnosticsDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SAMPLINGINTERVALDIAGNOSTICSDATATYPE]); +} + +static UA_INLINE void +UA_SamplingIntervalDiagnosticsDataType_delete(UA_SamplingIntervalDiagnosticsDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SAMPLINGINTERVALDIAGNOSTICSDATATYPE]); +}static UA_INLINE UA_Boolean +UA_SamplingIntervalDiagnosticsDataType_equal(const UA_SamplingIntervalDiagnosticsDataType *p1, const UA_SamplingIntervalDiagnosticsDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SAMPLINGINTERVALDIAGNOSTICSDATATYPE]) == UA_ORDER_EQ); +} + + + +/* ServerDiagnosticsSummaryDataType */ +static UA_INLINE void +UA_ServerDiagnosticsSummaryDataType_init(UA_ServerDiagnosticsSummaryDataType *p) { + memset(p, 0, sizeof(UA_ServerDiagnosticsSummaryDataType)); +} + +static UA_INLINE UA_ServerDiagnosticsSummaryDataType * +UA_ServerDiagnosticsSummaryDataType_new(void) { + return (UA_ServerDiagnosticsSummaryDataType*)UA_new(&UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_ServerDiagnosticsSummaryDataType_copy(const UA_ServerDiagnosticsSummaryDataType *src, UA_ServerDiagnosticsSummaryDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ServerDiagnosticsSummaryDataType_deleteMembers(UA_ServerDiagnosticsSummaryDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE]); +} + +static UA_INLINE void +UA_ServerDiagnosticsSummaryDataType_clear(UA_ServerDiagnosticsSummaryDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE]); +} + +static UA_INLINE void +UA_ServerDiagnosticsSummaryDataType_delete(UA_ServerDiagnosticsSummaryDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE]); +}static UA_INLINE UA_Boolean +UA_ServerDiagnosticsSummaryDataType_equal(const UA_ServerDiagnosticsSummaryDataType *p1, const UA_ServerDiagnosticsSummaryDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE]) == UA_ORDER_EQ); +} + + + +/* ServerStatusDataType */ +static UA_INLINE void +UA_ServerStatusDataType_init(UA_ServerStatusDataType *p) { + memset(p, 0, sizeof(UA_ServerStatusDataType)); +} + +static UA_INLINE UA_ServerStatusDataType * +UA_ServerStatusDataType_new(void) { + return (UA_ServerStatusDataType*)UA_new(&UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_ServerStatusDataType_copy(const UA_ServerStatusDataType *src, UA_ServerStatusDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ServerStatusDataType_deleteMembers(UA_ServerStatusDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE]); +} + +static UA_INLINE void +UA_ServerStatusDataType_clear(UA_ServerStatusDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE]); +} + +static UA_INLINE void +UA_ServerStatusDataType_delete(UA_ServerStatusDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE]); +}static UA_INLINE UA_Boolean +UA_ServerStatusDataType_equal(const UA_ServerStatusDataType *p1, const UA_ServerStatusDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE]) == UA_ORDER_EQ); +} + + + +/* SessionSecurityDiagnosticsDataType */ +static UA_INLINE void +UA_SessionSecurityDiagnosticsDataType_init(UA_SessionSecurityDiagnosticsDataType *p) { + memset(p, 0, sizeof(UA_SessionSecurityDiagnosticsDataType)); +} + +static UA_INLINE UA_SessionSecurityDiagnosticsDataType * +UA_SessionSecurityDiagnosticsDataType_new(void) { + return (UA_SessionSecurityDiagnosticsDataType*)UA_new(&UA_TYPES[UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_SessionSecurityDiagnosticsDataType_copy(const UA_SessionSecurityDiagnosticsDataType *src, UA_SessionSecurityDiagnosticsDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SessionSecurityDiagnosticsDataType_deleteMembers(UA_SessionSecurityDiagnosticsDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE]); +} + +static UA_INLINE void +UA_SessionSecurityDiagnosticsDataType_clear(UA_SessionSecurityDiagnosticsDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE]); +} + +static UA_INLINE void +UA_SessionSecurityDiagnosticsDataType_delete(UA_SessionSecurityDiagnosticsDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE]); +}static UA_INLINE UA_Boolean +UA_SessionSecurityDiagnosticsDataType_equal(const UA_SessionSecurityDiagnosticsDataType *p1, const UA_SessionSecurityDiagnosticsDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE]) == UA_ORDER_EQ); +} + + + +/* ServiceCounterDataType */ +static UA_INLINE void +UA_ServiceCounterDataType_init(UA_ServiceCounterDataType *p) { + memset(p, 0, sizeof(UA_ServiceCounterDataType)); +} + +static UA_INLINE UA_ServiceCounterDataType * +UA_ServiceCounterDataType_new(void) { + return (UA_ServiceCounterDataType*)UA_new(&UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_ServiceCounterDataType_copy(const UA_ServiceCounterDataType *src, UA_ServiceCounterDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ServiceCounterDataType_deleteMembers(UA_ServiceCounterDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE]); +} + +static UA_INLINE void +UA_ServiceCounterDataType_clear(UA_ServiceCounterDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE]); +} + +static UA_INLINE void +UA_ServiceCounterDataType_delete(UA_ServiceCounterDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE]); +}static UA_INLINE UA_Boolean +UA_ServiceCounterDataType_equal(const UA_ServiceCounterDataType *p1, const UA_ServiceCounterDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE]) == UA_ORDER_EQ); +} + + + +/* StatusResult */ +static UA_INLINE void +UA_StatusResult_init(UA_StatusResult *p) { + memset(p, 0, sizeof(UA_StatusResult)); +} + +static UA_INLINE UA_StatusResult * +UA_StatusResult_new(void) { + return (UA_StatusResult*)UA_new(&UA_TYPES[UA_TYPES_STATUSRESULT]); +} + +static UA_INLINE UA_StatusCode +UA_StatusResult_copy(const UA_StatusResult *src, UA_StatusResult *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_STATUSRESULT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_StatusResult_deleteMembers(UA_StatusResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STATUSRESULT]); +} + +static UA_INLINE void +UA_StatusResult_clear(UA_StatusResult *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STATUSRESULT]); +} + +static UA_INLINE void +UA_StatusResult_delete(UA_StatusResult *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_STATUSRESULT]); +}static UA_INLINE UA_Boolean +UA_StatusResult_equal(const UA_StatusResult *p1, const UA_StatusResult *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_STATUSRESULT]) == UA_ORDER_EQ); +} + + + +/* SubscriptionDiagnosticsDataType */ +static UA_INLINE void +UA_SubscriptionDiagnosticsDataType_init(UA_SubscriptionDiagnosticsDataType *p) { + memset(p, 0, sizeof(UA_SubscriptionDiagnosticsDataType)); +} + +static UA_INLINE UA_SubscriptionDiagnosticsDataType * +UA_SubscriptionDiagnosticsDataType_new(void) { + return (UA_SubscriptionDiagnosticsDataType*)UA_new(&UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_SubscriptionDiagnosticsDataType_copy(const UA_SubscriptionDiagnosticsDataType *src, UA_SubscriptionDiagnosticsDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SubscriptionDiagnosticsDataType_deleteMembers(UA_SubscriptionDiagnosticsDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE]); +} + +static UA_INLINE void +UA_SubscriptionDiagnosticsDataType_clear(UA_SubscriptionDiagnosticsDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE]); +} + +static UA_INLINE void +UA_SubscriptionDiagnosticsDataType_delete(UA_SubscriptionDiagnosticsDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE]); +}static UA_INLINE UA_Boolean +UA_SubscriptionDiagnosticsDataType_equal(const UA_SubscriptionDiagnosticsDataType *p1, const UA_SubscriptionDiagnosticsDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE]) == UA_ORDER_EQ); +} + + + +/* ModelChangeStructureVerbMask */ +static UA_INLINE void +UA_ModelChangeStructureVerbMask_init(UA_ModelChangeStructureVerbMask *p) { + memset(p, 0, sizeof(UA_ModelChangeStructureVerbMask)); +} + +static UA_INLINE UA_ModelChangeStructureVerbMask * +UA_ModelChangeStructureVerbMask_new(void) { + return (UA_ModelChangeStructureVerbMask*)UA_new(&UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREVERBMASK]); +} + +static UA_INLINE UA_StatusCode +UA_ModelChangeStructureVerbMask_copy(const UA_ModelChangeStructureVerbMask *src, UA_ModelChangeStructureVerbMask *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREVERBMASK]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ModelChangeStructureVerbMask_deleteMembers(UA_ModelChangeStructureVerbMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREVERBMASK]); +} + +static UA_INLINE void +UA_ModelChangeStructureVerbMask_clear(UA_ModelChangeStructureVerbMask *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREVERBMASK]); +} + +static UA_INLINE void +UA_ModelChangeStructureVerbMask_delete(UA_ModelChangeStructureVerbMask *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREVERBMASK]); +}static UA_INLINE UA_Boolean +UA_ModelChangeStructureVerbMask_equal(const UA_ModelChangeStructureVerbMask *p1, const UA_ModelChangeStructureVerbMask *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREVERBMASK]) == UA_ORDER_EQ); +} + + + +/* ModelChangeStructureDataType */ +static UA_INLINE void +UA_ModelChangeStructureDataType_init(UA_ModelChangeStructureDataType *p) { + memset(p, 0, sizeof(UA_ModelChangeStructureDataType)); +} + +static UA_INLINE UA_ModelChangeStructureDataType * +UA_ModelChangeStructureDataType_new(void) { + return (UA_ModelChangeStructureDataType*)UA_new(&UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_ModelChangeStructureDataType_copy(const UA_ModelChangeStructureDataType *src, UA_ModelChangeStructureDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ModelChangeStructureDataType_deleteMembers(UA_ModelChangeStructureDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREDATATYPE]); +} + +static UA_INLINE void +UA_ModelChangeStructureDataType_clear(UA_ModelChangeStructureDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREDATATYPE]); +} + +static UA_INLINE void +UA_ModelChangeStructureDataType_delete(UA_ModelChangeStructureDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREDATATYPE]); +}static UA_INLINE UA_Boolean +UA_ModelChangeStructureDataType_equal(const UA_ModelChangeStructureDataType *p1, const UA_ModelChangeStructureDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREDATATYPE]) == UA_ORDER_EQ); +} + + + +/* SemanticChangeStructureDataType */ +static UA_INLINE void +UA_SemanticChangeStructureDataType_init(UA_SemanticChangeStructureDataType *p) { + memset(p, 0, sizeof(UA_SemanticChangeStructureDataType)); +} + +static UA_INLINE UA_SemanticChangeStructureDataType * +UA_SemanticChangeStructureDataType_new(void) { + return (UA_SemanticChangeStructureDataType*)UA_new(&UA_TYPES[UA_TYPES_SEMANTICCHANGESTRUCTUREDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_SemanticChangeStructureDataType_copy(const UA_SemanticChangeStructureDataType *src, UA_SemanticChangeStructureDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SEMANTICCHANGESTRUCTUREDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SemanticChangeStructureDataType_deleteMembers(UA_SemanticChangeStructureDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SEMANTICCHANGESTRUCTUREDATATYPE]); +} + +static UA_INLINE void +UA_SemanticChangeStructureDataType_clear(UA_SemanticChangeStructureDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SEMANTICCHANGESTRUCTUREDATATYPE]); +} + +static UA_INLINE void +UA_SemanticChangeStructureDataType_delete(UA_SemanticChangeStructureDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SEMANTICCHANGESTRUCTUREDATATYPE]); +}static UA_INLINE UA_Boolean +UA_SemanticChangeStructureDataType_equal(const UA_SemanticChangeStructureDataType *p1, const UA_SemanticChangeStructureDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SEMANTICCHANGESTRUCTUREDATATYPE]) == UA_ORDER_EQ); +} + + + +/* Range */ +static UA_INLINE void +UA_Range_init(UA_Range *p) { + memset(p, 0, sizeof(UA_Range)); +} + +static UA_INLINE UA_Range * +UA_Range_new(void) { + return (UA_Range*)UA_new(&UA_TYPES[UA_TYPES_RANGE]); +} + +static UA_INLINE UA_StatusCode +UA_Range_copy(const UA_Range *src, UA_Range *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_RANGE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Range_deleteMembers(UA_Range *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RANGE]); +} + +static UA_INLINE void +UA_Range_clear(UA_Range *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_RANGE]); +} + +static UA_INLINE void +UA_Range_delete(UA_Range *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_RANGE]); +}static UA_INLINE UA_Boolean +UA_Range_equal(const UA_Range *p1, const UA_Range *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_RANGE]) == UA_ORDER_EQ); +} + + + +/* EUInformation */ +static UA_INLINE void +UA_EUInformation_init(UA_EUInformation *p) { + memset(p, 0, sizeof(UA_EUInformation)); +} + +static UA_INLINE UA_EUInformation * +UA_EUInformation_new(void) { + return (UA_EUInformation*)UA_new(&UA_TYPES[UA_TYPES_EUINFORMATION]); +} + +static UA_INLINE UA_StatusCode +UA_EUInformation_copy(const UA_EUInformation *src, UA_EUInformation *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_EUINFORMATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EUInformation_deleteMembers(UA_EUInformation *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EUINFORMATION]); +} + +static UA_INLINE void +UA_EUInformation_clear(UA_EUInformation *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EUINFORMATION]); +} + +static UA_INLINE void +UA_EUInformation_delete(UA_EUInformation *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_EUINFORMATION]); +}static UA_INLINE UA_Boolean +UA_EUInformation_equal(const UA_EUInformation *p1, const UA_EUInformation *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_EUINFORMATION]) == UA_ORDER_EQ); +} + + + +/* AxisScaleEnumeration */ +static UA_INLINE void +UA_AxisScaleEnumeration_init(UA_AxisScaleEnumeration *p) { + memset(p, 0, sizeof(UA_AxisScaleEnumeration)); +} + +static UA_INLINE UA_AxisScaleEnumeration * +UA_AxisScaleEnumeration_new(void) { + return (UA_AxisScaleEnumeration*)UA_new(&UA_TYPES[UA_TYPES_AXISSCALEENUMERATION]); +} + +static UA_INLINE UA_StatusCode +UA_AxisScaleEnumeration_copy(const UA_AxisScaleEnumeration *src, UA_AxisScaleEnumeration *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_AXISSCALEENUMERATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AxisScaleEnumeration_deleteMembers(UA_AxisScaleEnumeration *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_AXISSCALEENUMERATION]); +} + +static UA_INLINE void +UA_AxisScaleEnumeration_clear(UA_AxisScaleEnumeration *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_AXISSCALEENUMERATION]); +} + +static UA_INLINE void +UA_AxisScaleEnumeration_delete(UA_AxisScaleEnumeration *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_AXISSCALEENUMERATION]); +}static UA_INLINE UA_Boolean +UA_AxisScaleEnumeration_equal(const UA_AxisScaleEnumeration *p1, const UA_AxisScaleEnumeration *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_AXISSCALEENUMERATION]) == UA_ORDER_EQ); +} + + + +/* ComplexNumberType */ +static UA_INLINE void +UA_ComplexNumberType_init(UA_ComplexNumberType *p) { + memset(p, 0, sizeof(UA_ComplexNumberType)); +} + +static UA_INLINE UA_ComplexNumberType * +UA_ComplexNumberType_new(void) { + return (UA_ComplexNumberType*)UA_new(&UA_TYPES[UA_TYPES_COMPLEXNUMBERTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_ComplexNumberType_copy(const UA_ComplexNumberType *src, UA_ComplexNumberType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_COMPLEXNUMBERTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ComplexNumberType_deleteMembers(UA_ComplexNumberType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_COMPLEXNUMBERTYPE]); +} + +static UA_INLINE void +UA_ComplexNumberType_clear(UA_ComplexNumberType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_COMPLEXNUMBERTYPE]); +} + +static UA_INLINE void +UA_ComplexNumberType_delete(UA_ComplexNumberType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_COMPLEXNUMBERTYPE]); +}static UA_INLINE UA_Boolean +UA_ComplexNumberType_equal(const UA_ComplexNumberType *p1, const UA_ComplexNumberType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_COMPLEXNUMBERTYPE]) == UA_ORDER_EQ); +} + + + +/* DoubleComplexNumberType */ +static UA_INLINE void +UA_DoubleComplexNumberType_init(UA_DoubleComplexNumberType *p) { + memset(p, 0, sizeof(UA_DoubleComplexNumberType)); +} + +static UA_INLINE UA_DoubleComplexNumberType * +UA_DoubleComplexNumberType_new(void) { + return (UA_DoubleComplexNumberType*)UA_new(&UA_TYPES[UA_TYPES_DOUBLECOMPLEXNUMBERTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_DoubleComplexNumberType_copy(const UA_DoubleComplexNumberType *src, UA_DoubleComplexNumberType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DOUBLECOMPLEXNUMBERTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DoubleComplexNumberType_deleteMembers(UA_DoubleComplexNumberType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DOUBLECOMPLEXNUMBERTYPE]); +} + +static UA_INLINE void +UA_DoubleComplexNumberType_clear(UA_DoubleComplexNumberType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DOUBLECOMPLEXNUMBERTYPE]); +} + +static UA_INLINE void +UA_DoubleComplexNumberType_delete(UA_DoubleComplexNumberType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DOUBLECOMPLEXNUMBERTYPE]); +}static UA_INLINE UA_Boolean +UA_DoubleComplexNumberType_equal(const UA_DoubleComplexNumberType *p1, const UA_DoubleComplexNumberType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DOUBLECOMPLEXNUMBERTYPE]) == UA_ORDER_EQ); +} + + + +/* AxisInformation */ +static UA_INLINE void +UA_AxisInformation_init(UA_AxisInformation *p) { + memset(p, 0, sizeof(UA_AxisInformation)); +} + +static UA_INLINE UA_AxisInformation * +UA_AxisInformation_new(void) { + return (UA_AxisInformation*)UA_new(&UA_TYPES[UA_TYPES_AXISINFORMATION]); +} + +static UA_INLINE UA_StatusCode +UA_AxisInformation_copy(const UA_AxisInformation *src, UA_AxisInformation *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_AXISINFORMATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_AxisInformation_deleteMembers(UA_AxisInformation *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_AXISINFORMATION]); +} + +static UA_INLINE void +UA_AxisInformation_clear(UA_AxisInformation *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_AXISINFORMATION]); +} + +static UA_INLINE void +UA_AxisInformation_delete(UA_AxisInformation *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_AXISINFORMATION]); +}static UA_INLINE UA_Boolean +UA_AxisInformation_equal(const UA_AxisInformation *p1, const UA_AxisInformation *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_AXISINFORMATION]) == UA_ORDER_EQ); +} + + + +/* XVType */ +static UA_INLINE void +UA_XVType_init(UA_XVType *p) { + memset(p, 0, sizeof(UA_XVType)); +} + +static UA_INLINE UA_XVType * +UA_XVType_new(void) { + return (UA_XVType*)UA_new(&UA_TYPES[UA_TYPES_XVTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_XVType_copy(const UA_XVType *src, UA_XVType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_XVTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_XVType_deleteMembers(UA_XVType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_XVTYPE]); +} + +static UA_INLINE void +UA_XVType_clear(UA_XVType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_XVTYPE]); +} + +static UA_INLINE void +UA_XVType_delete(UA_XVType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_XVTYPE]); +}static UA_INLINE UA_Boolean +UA_XVType_equal(const UA_XVType *p1, const UA_XVType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_XVTYPE]) == UA_ORDER_EQ); +} + + + +/* ProgramDiagnosticDataType */ +static UA_INLINE void +UA_ProgramDiagnosticDataType_init(UA_ProgramDiagnosticDataType *p) { + memset(p, 0, sizeof(UA_ProgramDiagnosticDataType)); +} + +static UA_INLINE UA_ProgramDiagnosticDataType * +UA_ProgramDiagnosticDataType_new(void) { + return (UA_ProgramDiagnosticDataType*)UA_new(&UA_TYPES[UA_TYPES_PROGRAMDIAGNOSTICDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_ProgramDiagnosticDataType_copy(const UA_ProgramDiagnosticDataType *src, UA_ProgramDiagnosticDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PROGRAMDIAGNOSTICDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ProgramDiagnosticDataType_deleteMembers(UA_ProgramDiagnosticDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PROGRAMDIAGNOSTICDATATYPE]); +} + +static UA_INLINE void +UA_ProgramDiagnosticDataType_clear(UA_ProgramDiagnosticDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PROGRAMDIAGNOSTICDATATYPE]); +} + +static UA_INLINE void +UA_ProgramDiagnosticDataType_delete(UA_ProgramDiagnosticDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PROGRAMDIAGNOSTICDATATYPE]); +}static UA_INLINE UA_Boolean +UA_ProgramDiagnosticDataType_equal(const UA_ProgramDiagnosticDataType *p1, const UA_ProgramDiagnosticDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PROGRAMDIAGNOSTICDATATYPE]) == UA_ORDER_EQ); +} + + + +/* ProgramDiagnostic2DataType */ +static UA_INLINE void +UA_ProgramDiagnostic2DataType_init(UA_ProgramDiagnostic2DataType *p) { + memset(p, 0, sizeof(UA_ProgramDiagnostic2DataType)); +} + +static UA_INLINE UA_ProgramDiagnostic2DataType * +UA_ProgramDiagnostic2DataType_new(void) { + return (UA_ProgramDiagnostic2DataType*)UA_new(&UA_TYPES[UA_TYPES_PROGRAMDIAGNOSTIC2DATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_ProgramDiagnostic2DataType_copy(const UA_ProgramDiagnostic2DataType *src, UA_ProgramDiagnostic2DataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PROGRAMDIAGNOSTIC2DATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ProgramDiagnostic2DataType_deleteMembers(UA_ProgramDiagnostic2DataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PROGRAMDIAGNOSTIC2DATATYPE]); +} + +static UA_INLINE void +UA_ProgramDiagnostic2DataType_clear(UA_ProgramDiagnostic2DataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PROGRAMDIAGNOSTIC2DATATYPE]); +} + +static UA_INLINE void +UA_ProgramDiagnostic2DataType_delete(UA_ProgramDiagnostic2DataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PROGRAMDIAGNOSTIC2DATATYPE]); +}static UA_INLINE UA_Boolean +UA_ProgramDiagnostic2DataType_equal(const UA_ProgramDiagnostic2DataType *p1, const UA_ProgramDiagnostic2DataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PROGRAMDIAGNOSTIC2DATATYPE]) == UA_ORDER_EQ); +} + + + +/* Annotation */ +static UA_INLINE void +UA_Annotation_init(UA_Annotation *p) { + memset(p, 0, sizeof(UA_Annotation)); +} + +static UA_INLINE UA_Annotation * +UA_Annotation_new(void) { + return (UA_Annotation*)UA_new(&UA_TYPES[UA_TYPES_ANNOTATION]); +} + +static UA_INLINE UA_StatusCode +UA_Annotation_copy(const UA_Annotation *src, UA_Annotation *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ANNOTATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_Annotation_deleteMembers(UA_Annotation *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ANNOTATION]); +} + +static UA_INLINE void +UA_Annotation_clear(UA_Annotation *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ANNOTATION]); +} + +static UA_INLINE void +UA_Annotation_delete(UA_Annotation *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ANNOTATION]); +}static UA_INLINE UA_Boolean +UA_Annotation_equal(const UA_Annotation *p1, const UA_Annotation *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ANNOTATION]) == UA_ORDER_EQ); +} + + + +/* ExceptionDeviationFormat */ +static UA_INLINE void +UA_ExceptionDeviationFormat_init(UA_ExceptionDeviationFormat *p) { + memset(p, 0, sizeof(UA_ExceptionDeviationFormat)); +} + +static UA_INLINE UA_ExceptionDeviationFormat * +UA_ExceptionDeviationFormat_new(void) { + return (UA_ExceptionDeviationFormat*)UA_new(&UA_TYPES[UA_TYPES_EXCEPTIONDEVIATIONFORMAT]); +} + +static UA_INLINE UA_StatusCode +UA_ExceptionDeviationFormat_copy(const UA_ExceptionDeviationFormat *src, UA_ExceptionDeviationFormat *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_EXCEPTIONDEVIATIONFORMAT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ExceptionDeviationFormat_deleteMembers(UA_ExceptionDeviationFormat *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EXCEPTIONDEVIATIONFORMAT]); +} + +static UA_INLINE void +UA_ExceptionDeviationFormat_clear(UA_ExceptionDeviationFormat *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EXCEPTIONDEVIATIONFORMAT]); +} + +static UA_INLINE void +UA_ExceptionDeviationFormat_delete(UA_ExceptionDeviationFormat *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_EXCEPTIONDEVIATIONFORMAT]); +}static UA_INLINE UA_Boolean +UA_ExceptionDeviationFormat_equal(const UA_ExceptionDeviationFormat *p1, const UA_ExceptionDeviationFormat *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_EXCEPTIONDEVIATIONFORMAT]) == UA_ORDER_EQ); +} + + + +/* EndpointType */ +static UA_INLINE void +UA_EndpointType_init(UA_EndpointType *p) { + memset(p, 0, sizeof(UA_EndpointType)); +} + +static UA_INLINE UA_EndpointType * +UA_EndpointType_new(void) { + return (UA_EndpointType*)UA_new(&UA_TYPES[UA_TYPES_ENDPOINTTYPE]); +} + +static UA_INLINE UA_StatusCode +UA_EndpointType_copy(const UA_EndpointType *src, UA_EndpointType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ENDPOINTTYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EndpointType_deleteMembers(UA_EndpointType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENDPOINTTYPE]); +} + +static UA_INLINE void +UA_EndpointType_clear(UA_EndpointType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENDPOINTTYPE]); +} + +static UA_INLINE void +UA_EndpointType_delete(UA_EndpointType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ENDPOINTTYPE]); +}static UA_INLINE UA_Boolean +UA_EndpointType_equal(const UA_EndpointType *p1, const UA_EndpointType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ENDPOINTTYPE]) == UA_ORDER_EQ); +} + + + +/* StructureDescription */ +static UA_INLINE void +UA_StructureDescription_init(UA_StructureDescription *p) { + memset(p, 0, sizeof(UA_StructureDescription)); +} + +static UA_INLINE UA_StructureDescription * +UA_StructureDescription_new(void) { + return (UA_StructureDescription*)UA_new(&UA_TYPES[UA_TYPES_STRUCTUREDESCRIPTION]); +} + +static UA_INLINE UA_StatusCode +UA_StructureDescription_copy(const UA_StructureDescription *src, UA_StructureDescription *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_STRUCTUREDESCRIPTION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_StructureDescription_deleteMembers(UA_StructureDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STRUCTUREDESCRIPTION]); +} + +static UA_INLINE void +UA_StructureDescription_clear(UA_StructureDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STRUCTUREDESCRIPTION]); +} + +static UA_INLINE void +UA_StructureDescription_delete(UA_StructureDescription *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_STRUCTUREDESCRIPTION]); +}static UA_INLINE UA_Boolean +UA_StructureDescription_equal(const UA_StructureDescription *p1, const UA_StructureDescription *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_STRUCTUREDESCRIPTION]) == UA_ORDER_EQ); +} + + + +/* FieldMetaData */ +static UA_INLINE void +UA_FieldMetaData_init(UA_FieldMetaData *p) { + memset(p, 0, sizeof(UA_FieldMetaData)); +} + +static UA_INLINE UA_FieldMetaData * +UA_FieldMetaData_new(void) { + return (UA_FieldMetaData*)UA_new(&UA_TYPES[UA_TYPES_FIELDMETADATA]); +} + +static UA_INLINE UA_StatusCode +UA_FieldMetaData_copy(const UA_FieldMetaData *src, UA_FieldMetaData *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_FIELDMETADATA]); +} + +UA_DEPRECATED static UA_INLINE void +UA_FieldMetaData_deleteMembers(UA_FieldMetaData *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FIELDMETADATA]); +} + +static UA_INLINE void +UA_FieldMetaData_clear(UA_FieldMetaData *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FIELDMETADATA]); +} + +static UA_INLINE void +UA_FieldMetaData_delete(UA_FieldMetaData *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_FIELDMETADATA]); +}static UA_INLINE UA_Boolean +UA_FieldMetaData_equal(const UA_FieldMetaData *p1, const UA_FieldMetaData *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_FIELDMETADATA]) == UA_ORDER_EQ); +} + + + +/* PublishedEventsDataType */ +static UA_INLINE void +UA_PublishedEventsDataType_init(UA_PublishedEventsDataType *p) { + memset(p, 0, sizeof(UA_PublishedEventsDataType)); +} + +static UA_INLINE UA_PublishedEventsDataType * +UA_PublishedEventsDataType_new(void) { + return (UA_PublishedEventsDataType*)UA_new(&UA_TYPES[UA_TYPES_PUBLISHEDEVENTSDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PublishedEventsDataType_copy(const UA_PublishedEventsDataType *src, UA_PublishedEventsDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBLISHEDEVENTSDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PublishedEventsDataType_deleteMembers(UA_PublishedEventsDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHEDEVENTSDATATYPE]); +} + +static UA_INLINE void +UA_PublishedEventsDataType_clear(UA_PublishedEventsDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHEDEVENTSDATATYPE]); +} + +static UA_INLINE void +UA_PublishedEventsDataType_delete(UA_PublishedEventsDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBLISHEDEVENTSDATATYPE]); +}static UA_INLINE UA_Boolean +UA_PublishedEventsDataType_equal(const UA_PublishedEventsDataType *p1, const UA_PublishedEventsDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBLISHEDEVENTSDATATYPE]) == UA_ORDER_EQ); +} + + + +/* PubSubGroupDataType */ +static UA_INLINE void +UA_PubSubGroupDataType_init(UA_PubSubGroupDataType *p) { + memset(p, 0, sizeof(UA_PubSubGroupDataType)); +} + +static UA_INLINE UA_PubSubGroupDataType * +UA_PubSubGroupDataType_new(void) { + return (UA_PubSubGroupDataType*)UA_new(&UA_TYPES[UA_TYPES_PUBSUBGROUPDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PubSubGroupDataType_copy(const UA_PubSubGroupDataType *src, UA_PubSubGroupDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBSUBGROUPDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PubSubGroupDataType_deleteMembers(UA_PubSubGroupDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBGROUPDATATYPE]); +} + +static UA_INLINE void +UA_PubSubGroupDataType_clear(UA_PubSubGroupDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBGROUPDATATYPE]); +} + +static UA_INLINE void +UA_PubSubGroupDataType_delete(UA_PubSubGroupDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBSUBGROUPDATATYPE]); +}static UA_INLINE UA_Boolean +UA_PubSubGroupDataType_equal(const UA_PubSubGroupDataType *p1, const UA_PubSubGroupDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBSUBGROUPDATATYPE]) == UA_ORDER_EQ); +} + + + +/* WriterGroupDataType */ +static UA_INLINE void +UA_WriterGroupDataType_init(UA_WriterGroupDataType *p) { + memset(p, 0, sizeof(UA_WriterGroupDataType)); +} + +static UA_INLINE UA_WriterGroupDataType * +UA_WriterGroupDataType_new(void) { + return (UA_WriterGroupDataType*)UA_new(&UA_TYPES[UA_TYPES_WRITERGROUPDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_WriterGroupDataType_copy(const UA_WriterGroupDataType *src, UA_WriterGroupDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_WRITERGROUPDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_WriterGroupDataType_deleteMembers(UA_WriterGroupDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_WRITERGROUPDATATYPE]); +} + +static UA_INLINE void +UA_WriterGroupDataType_clear(UA_WriterGroupDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_WRITERGROUPDATATYPE]); +} + +static UA_INLINE void +UA_WriterGroupDataType_delete(UA_WriterGroupDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_WRITERGROUPDATATYPE]); +}static UA_INLINE UA_Boolean +UA_WriterGroupDataType_equal(const UA_WriterGroupDataType *p1, const UA_WriterGroupDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_WRITERGROUPDATATYPE]) == UA_ORDER_EQ); +} + + + +/* FieldTargetDataType */ +static UA_INLINE void +UA_FieldTargetDataType_init(UA_FieldTargetDataType *p) { + memset(p, 0, sizeof(UA_FieldTargetDataType)); +} + +static UA_INLINE UA_FieldTargetDataType * +UA_FieldTargetDataType_new(void) { + return (UA_FieldTargetDataType*)UA_new(&UA_TYPES[UA_TYPES_FIELDTARGETDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_FieldTargetDataType_copy(const UA_FieldTargetDataType *src, UA_FieldTargetDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_FIELDTARGETDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_FieldTargetDataType_deleteMembers(UA_FieldTargetDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FIELDTARGETDATATYPE]); +} + +static UA_INLINE void +UA_FieldTargetDataType_clear(UA_FieldTargetDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_FIELDTARGETDATATYPE]); +} + +static UA_INLINE void +UA_FieldTargetDataType_delete(UA_FieldTargetDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_FIELDTARGETDATATYPE]); +}static UA_INLINE UA_Boolean +UA_FieldTargetDataType_equal(const UA_FieldTargetDataType *p1, const UA_FieldTargetDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_FIELDTARGETDATATYPE]) == UA_ORDER_EQ); +} + + + +/* SubscribedDataSetMirrorDataType */ +static UA_INLINE void +UA_SubscribedDataSetMirrorDataType_init(UA_SubscribedDataSetMirrorDataType *p) { + memset(p, 0, sizeof(UA_SubscribedDataSetMirrorDataType)); +} + +static UA_INLINE UA_SubscribedDataSetMirrorDataType * +UA_SubscribedDataSetMirrorDataType_new(void) { + return (UA_SubscribedDataSetMirrorDataType*)UA_new(&UA_TYPES[UA_TYPES_SUBSCRIBEDDATASETMIRRORDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_SubscribedDataSetMirrorDataType_copy(const UA_SubscribedDataSetMirrorDataType *src, UA_SubscribedDataSetMirrorDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SUBSCRIBEDDATASETMIRRORDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SubscribedDataSetMirrorDataType_deleteMembers(UA_SubscribedDataSetMirrorDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SUBSCRIBEDDATASETMIRRORDATATYPE]); +} + +static UA_INLINE void +UA_SubscribedDataSetMirrorDataType_clear(UA_SubscribedDataSetMirrorDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SUBSCRIBEDDATASETMIRRORDATATYPE]); +} + +static UA_INLINE void +UA_SubscribedDataSetMirrorDataType_delete(UA_SubscribedDataSetMirrorDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SUBSCRIBEDDATASETMIRRORDATATYPE]); +}static UA_INLINE UA_Boolean +UA_SubscribedDataSetMirrorDataType_equal(const UA_SubscribedDataSetMirrorDataType *p1, const UA_SubscribedDataSetMirrorDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SUBSCRIBEDDATASETMIRRORDATATYPE]) == UA_ORDER_EQ); +} + + + +/* SecurityGroupDataType */ +static UA_INLINE void +UA_SecurityGroupDataType_init(UA_SecurityGroupDataType *p) { + memset(p, 0, sizeof(UA_SecurityGroupDataType)); +} + +static UA_INLINE UA_SecurityGroupDataType * +UA_SecurityGroupDataType_new(void) { + return (UA_SecurityGroupDataType*)UA_new(&UA_TYPES[UA_TYPES_SECURITYGROUPDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_SecurityGroupDataType_copy(const UA_SecurityGroupDataType *src, UA_SecurityGroupDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SECURITYGROUPDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SecurityGroupDataType_deleteMembers(UA_SecurityGroupDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SECURITYGROUPDATATYPE]); +} + +static UA_INLINE void +UA_SecurityGroupDataType_clear(UA_SecurityGroupDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SECURITYGROUPDATATYPE]); +} + +static UA_INLINE void +UA_SecurityGroupDataType_delete(UA_SecurityGroupDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SECURITYGROUPDATATYPE]); +}static UA_INLINE UA_Boolean +UA_SecurityGroupDataType_equal(const UA_SecurityGroupDataType *p1, const UA_SecurityGroupDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SECURITYGROUPDATATYPE]) == UA_ORDER_EQ); +} + + + +/* PubSubKeyPushTargetDataType */ +static UA_INLINE void +UA_PubSubKeyPushTargetDataType_init(UA_PubSubKeyPushTargetDataType *p) { + memset(p, 0, sizeof(UA_PubSubKeyPushTargetDataType)); +} + +static UA_INLINE UA_PubSubKeyPushTargetDataType * +UA_PubSubKeyPushTargetDataType_new(void) { + return (UA_PubSubKeyPushTargetDataType*)UA_new(&UA_TYPES[UA_TYPES_PUBSUBKEYPUSHTARGETDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PubSubKeyPushTargetDataType_copy(const UA_PubSubKeyPushTargetDataType *src, UA_PubSubKeyPushTargetDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBSUBKEYPUSHTARGETDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PubSubKeyPushTargetDataType_deleteMembers(UA_PubSubKeyPushTargetDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBKEYPUSHTARGETDATATYPE]); +} + +static UA_INLINE void +UA_PubSubKeyPushTargetDataType_clear(UA_PubSubKeyPushTargetDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBKEYPUSHTARGETDATATYPE]); +} + +static UA_INLINE void +UA_PubSubKeyPushTargetDataType_delete(UA_PubSubKeyPushTargetDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBSUBKEYPUSHTARGETDATATYPE]); +}static UA_INLINE UA_Boolean +UA_PubSubKeyPushTargetDataType_equal(const UA_PubSubKeyPushTargetDataType *p1, const UA_PubSubKeyPushTargetDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBSUBKEYPUSHTARGETDATATYPE]) == UA_ORDER_EQ); +} + + + +/* EnumDefinition */ +static UA_INLINE void +UA_EnumDefinition_init(UA_EnumDefinition *p) { + memset(p, 0, sizeof(UA_EnumDefinition)); +} + +static UA_INLINE UA_EnumDefinition * +UA_EnumDefinition_new(void) { + return (UA_EnumDefinition*)UA_new(&UA_TYPES[UA_TYPES_ENUMDEFINITION]); +} + +static UA_INLINE UA_StatusCode +UA_EnumDefinition_copy(const UA_EnumDefinition *src, UA_EnumDefinition *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ENUMDEFINITION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EnumDefinition_deleteMembers(UA_EnumDefinition *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENUMDEFINITION]); +} + +static UA_INLINE void +UA_EnumDefinition_clear(UA_EnumDefinition *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENUMDEFINITION]); +} + +static UA_INLINE void +UA_EnumDefinition_delete(UA_EnumDefinition *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ENUMDEFINITION]); +}static UA_INLINE UA_Boolean +UA_EnumDefinition_equal(const UA_EnumDefinition *p1, const UA_EnumDefinition *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ENUMDEFINITION]) == UA_ORDER_EQ); +} + + + +/* ReadEventDetails */ +static UA_INLINE void +UA_ReadEventDetails_init(UA_ReadEventDetails *p) { + memset(p, 0, sizeof(UA_ReadEventDetails)); +} + +static UA_INLINE UA_ReadEventDetails * +UA_ReadEventDetails_new(void) { + return (UA_ReadEventDetails*)UA_new(&UA_TYPES[UA_TYPES_READEVENTDETAILS]); +} + +static UA_INLINE UA_StatusCode +UA_ReadEventDetails_copy(const UA_ReadEventDetails *src, UA_ReadEventDetails *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_READEVENTDETAILS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReadEventDetails_deleteMembers(UA_ReadEventDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READEVENTDETAILS]); +} + +static UA_INLINE void +UA_ReadEventDetails_clear(UA_ReadEventDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READEVENTDETAILS]); +} + +static UA_INLINE void +UA_ReadEventDetails_delete(UA_ReadEventDetails *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_READEVENTDETAILS]); +}static UA_INLINE UA_Boolean +UA_ReadEventDetails_equal(const UA_ReadEventDetails *p1, const UA_ReadEventDetails *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_READEVENTDETAILS]) == UA_ORDER_EQ); +} + + + +/* ReadProcessedDetails */ +static UA_INLINE void +UA_ReadProcessedDetails_init(UA_ReadProcessedDetails *p) { + memset(p, 0, sizeof(UA_ReadProcessedDetails)); +} + +static UA_INLINE UA_ReadProcessedDetails * +UA_ReadProcessedDetails_new(void) { + return (UA_ReadProcessedDetails*)UA_new(&UA_TYPES[UA_TYPES_READPROCESSEDDETAILS]); +} + +static UA_INLINE UA_StatusCode +UA_ReadProcessedDetails_copy(const UA_ReadProcessedDetails *src, UA_ReadProcessedDetails *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_READPROCESSEDDETAILS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReadProcessedDetails_deleteMembers(UA_ReadProcessedDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READPROCESSEDDETAILS]); +} + +static UA_INLINE void +UA_ReadProcessedDetails_clear(UA_ReadProcessedDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READPROCESSEDDETAILS]); +} + +static UA_INLINE void +UA_ReadProcessedDetails_delete(UA_ReadProcessedDetails *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_READPROCESSEDDETAILS]); +}static UA_INLINE UA_Boolean +UA_ReadProcessedDetails_equal(const UA_ReadProcessedDetails *p1, const UA_ReadProcessedDetails *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_READPROCESSEDDETAILS]) == UA_ORDER_EQ); +} + + + +/* ModificationInfo */ +static UA_INLINE void +UA_ModificationInfo_init(UA_ModificationInfo *p) { + memset(p, 0, sizeof(UA_ModificationInfo)); +} + +static UA_INLINE UA_ModificationInfo * +UA_ModificationInfo_new(void) { + return (UA_ModificationInfo*)UA_new(&UA_TYPES[UA_TYPES_MODIFICATIONINFO]); +} + +static UA_INLINE UA_StatusCode +UA_ModificationInfo_copy(const UA_ModificationInfo *src, UA_ModificationInfo *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_MODIFICATIONINFO]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ModificationInfo_deleteMembers(UA_ModificationInfo *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODIFICATIONINFO]); +} + +static UA_INLINE void +UA_ModificationInfo_clear(UA_ModificationInfo *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_MODIFICATIONINFO]); +} + +static UA_INLINE void +UA_ModificationInfo_delete(UA_ModificationInfo *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_MODIFICATIONINFO]); +}static UA_INLINE UA_Boolean +UA_ModificationInfo_equal(const UA_ModificationInfo *p1, const UA_ModificationInfo *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_MODIFICATIONINFO]) == UA_ORDER_EQ); +} + + + +/* HistoryModifiedData */ +static UA_INLINE void +UA_HistoryModifiedData_init(UA_HistoryModifiedData *p) { + memset(p, 0, sizeof(UA_HistoryModifiedData)); +} + +static UA_INLINE UA_HistoryModifiedData * +UA_HistoryModifiedData_new(void) { + return (UA_HistoryModifiedData*)UA_new(&UA_TYPES[UA_TYPES_HISTORYMODIFIEDDATA]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryModifiedData_copy(const UA_HistoryModifiedData *src, UA_HistoryModifiedData *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYMODIFIEDDATA]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryModifiedData_deleteMembers(UA_HistoryModifiedData *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYMODIFIEDDATA]); +} + +static UA_INLINE void +UA_HistoryModifiedData_clear(UA_HistoryModifiedData *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYMODIFIEDDATA]); +} + +static UA_INLINE void +UA_HistoryModifiedData_delete(UA_HistoryModifiedData *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYMODIFIEDDATA]); +}static UA_INLINE UA_Boolean +UA_HistoryModifiedData_equal(const UA_HistoryModifiedData *p1, const UA_HistoryModifiedData *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYMODIFIEDDATA]) == UA_ORDER_EQ); +} + + + +/* HistoryEvent */ +static UA_INLINE void +UA_HistoryEvent_init(UA_HistoryEvent *p) { + memset(p, 0, sizeof(UA_HistoryEvent)); +} + +static UA_INLINE UA_HistoryEvent * +UA_HistoryEvent_new(void) { + return (UA_HistoryEvent*)UA_new(&UA_TYPES[UA_TYPES_HISTORYEVENT]); +} + +static UA_INLINE UA_StatusCode +UA_HistoryEvent_copy(const UA_HistoryEvent *src, UA_HistoryEvent *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_HISTORYEVENT]); +} + +UA_DEPRECATED static UA_INLINE void +UA_HistoryEvent_deleteMembers(UA_HistoryEvent *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYEVENT]); +} + +static UA_INLINE void +UA_HistoryEvent_clear(UA_HistoryEvent *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_HISTORYEVENT]); +} + +static UA_INLINE void +UA_HistoryEvent_delete(UA_HistoryEvent *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_HISTORYEVENT]); +}static UA_INLINE UA_Boolean +UA_HistoryEvent_equal(const UA_HistoryEvent *p1, const UA_HistoryEvent *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_HISTORYEVENT]) == UA_ORDER_EQ); +} + + + +/* UpdateEventDetails */ +static UA_INLINE void +UA_UpdateEventDetails_init(UA_UpdateEventDetails *p) { + memset(p, 0, sizeof(UA_UpdateEventDetails)); +} + +static UA_INLINE UA_UpdateEventDetails * +UA_UpdateEventDetails_new(void) { + return (UA_UpdateEventDetails*)UA_new(&UA_TYPES[UA_TYPES_UPDATEEVENTDETAILS]); +} + +static UA_INLINE UA_StatusCode +UA_UpdateEventDetails_copy(const UA_UpdateEventDetails *src, UA_UpdateEventDetails *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UPDATEEVENTDETAILS]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UpdateEventDetails_deleteMembers(UA_UpdateEventDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UPDATEEVENTDETAILS]); +} + +static UA_INLINE void +UA_UpdateEventDetails_clear(UA_UpdateEventDetails *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UPDATEEVENTDETAILS]); +} + +static UA_INLINE void +UA_UpdateEventDetails_delete(UA_UpdateEventDetails *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UPDATEEVENTDETAILS]); +}static UA_INLINE UA_Boolean +UA_UpdateEventDetails_equal(const UA_UpdateEventDetails *p1, const UA_UpdateEventDetails *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UPDATEEVENTDETAILS]) == UA_ORDER_EQ); +} + + + +/* DataChangeNotification */ +static UA_INLINE void +UA_DataChangeNotification_init(UA_DataChangeNotification *p) { + memset(p, 0, sizeof(UA_DataChangeNotification)); +} + +static UA_INLINE UA_DataChangeNotification * +UA_DataChangeNotification_new(void) { + return (UA_DataChangeNotification*)UA_new(&UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION]); +} + +static UA_INLINE UA_StatusCode +UA_DataChangeNotification_copy(const UA_DataChangeNotification *src, UA_DataChangeNotification *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataChangeNotification_deleteMembers(UA_DataChangeNotification *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION]); +} + +static UA_INLINE void +UA_DataChangeNotification_clear(UA_DataChangeNotification *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION]); +} + +static UA_INLINE void +UA_DataChangeNotification_delete(UA_DataChangeNotification *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION]); +}static UA_INLINE UA_Boolean +UA_DataChangeNotification_equal(const UA_DataChangeNotification *p1, const UA_DataChangeNotification *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION]) == UA_ORDER_EQ); +} + + + +/* EventNotificationList */ +static UA_INLINE void +UA_EventNotificationList_init(UA_EventNotificationList *p) { + memset(p, 0, sizeof(UA_EventNotificationList)); +} + +static UA_INLINE UA_EventNotificationList * +UA_EventNotificationList_new(void) { + return (UA_EventNotificationList*)UA_new(&UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST]); +} + +static UA_INLINE UA_StatusCode +UA_EventNotificationList_copy(const UA_EventNotificationList *src, UA_EventNotificationList *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EventNotificationList_deleteMembers(UA_EventNotificationList *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST]); +} + +static UA_INLINE void +UA_EventNotificationList_clear(UA_EventNotificationList *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST]); +} + +static UA_INLINE void +UA_EventNotificationList_delete(UA_EventNotificationList *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST]); +}static UA_INLINE UA_Boolean +UA_EventNotificationList_equal(const UA_EventNotificationList *p1, const UA_EventNotificationList *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST]) == UA_ORDER_EQ); +} + + + +/* SessionDiagnosticsDataType */ +static UA_INLINE void +UA_SessionDiagnosticsDataType_init(UA_SessionDiagnosticsDataType *p) { + memset(p, 0, sizeof(UA_SessionDiagnosticsDataType)); +} + +static UA_INLINE UA_SessionDiagnosticsDataType * +UA_SessionDiagnosticsDataType_new(void) { + return (UA_SessionDiagnosticsDataType*)UA_new(&UA_TYPES[UA_TYPES_SESSIONDIAGNOSTICSDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_SessionDiagnosticsDataType_copy(const UA_SessionDiagnosticsDataType *src, UA_SessionDiagnosticsDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_SESSIONDIAGNOSTICSDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_SessionDiagnosticsDataType_deleteMembers(UA_SessionDiagnosticsDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SESSIONDIAGNOSTICSDATATYPE]); +} + +static UA_INLINE void +UA_SessionDiagnosticsDataType_clear(UA_SessionDiagnosticsDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_SESSIONDIAGNOSTICSDATATYPE]); +} + +static UA_INLINE void +UA_SessionDiagnosticsDataType_delete(UA_SessionDiagnosticsDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_SESSIONDIAGNOSTICSDATATYPE]); +}static UA_INLINE UA_Boolean +UA_SessionDiagnosticsDataType_equal(const UA_SessionDiagnosticsDataType *p1, const UA_SessionDiagnosticsDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_SESSIONDIAGNOSTICSDATATYPE]) == UA_ORDER_EQ); +} + + + +/* EnumDescription */ +static UA_INLINE void +UA_EnumDescription_init(UA_EnumDescription *p) { + memset(p, 0, sizeof(UA_EnumDescription)); +} + +static UA_INLINE UA_EnumDescription * +UA_EnumDescription_new(void) { + return (UA_EnumDescription*)UA_new(&UA_TYPES[UA_TYPES_ENUMDESCRIPTION]); +} + +static UA_INLINE UA_StatusCode +UA_EnumDescription_copy(const UA_EnumDescription *src, UA_EnumDescription *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_ENUMDESCRIPTION]); +} + +UA_DEPRECATED static UA_INLINE void +UA_EnumDescription_deleteMembers(UA_EnumDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENUMDESCRIPTION]); +} + +static UA_INLINE void +UA_EnumDescription_clear(UA_EnumDescription *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_ENUMDESCRIPTION]); +} + +static UA_INLINE void +UA_EnumDescription_delete(UA_EnumDescription *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_ENUMDESCRIPTION]); +}static UA_INLINE UA_Boolean +UA_EnumDescription_equal(const UA_EnumDescription *p1, const UA_EnumDescription *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_ENUMDESCRIPTION]) == UA_ORDER_EQ); +} + + + +/* UABinaryFileDataType */ +static UA_INLINE void +UA_UABinaryFileDataType_init(UA_UABinaryFileDataType *p) { + memset(p, 0, sizeof(UA_UABinaryFileDataType)); +} + +static UA_INLINE UA_UABinaryFileDataType * +UA_UABinaryFileDataType_new(void) { + return (UA_UABinaryFileDataType*)UA_new(&UA_TYPES[UA_TYPES_UABINARYFILEDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_UABinaryFileDataType_copy(const UA_UABinaryFileDataType *src, UA_UABinaryFileDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_UABINARYFILEDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_UABinaryFileDataType_deleteMembers(UA_UABinaryFileDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UABINARYFILEDATATYPE]); +} + +static UA_INLINE void +UA_UABinaryFileDataType_clear(UA_UABinaryFileDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_UABINARYFILEDATATYPE]); +} + +static UA_INLINE void +UA_UABinaryFileDataType_delete(UA_UABinaryFileDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_UABINARYFILEDATATYPE]); +}static UA_INLINE UA_Boolean +UA_UABinaryFileDataType_equal(const UA_UABinaryFileDataType *p1, const UA_UABinaryFileDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_UABINARYFILEDATATYPE]) == UA_ORDER_EQ); +} + + + +/* DataSetMetaDataType */ +static UA_INLINE void +UA_DataSetMetaDataType_init(UA_DataSetMetaDataType *p) { + memset(p, 0, sizeof(UA_DataSetMetaDataType)); +} + +static UA_INLINE UA_DataSetMetaDataType * +UA_DataSetMetaDataType_new(void) { + return (UA_DataSetMetaDataType*)UA_new(&UA_TYPES[UA_TYPES_DATASETMETADATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_DataSetMetaDataType_copy(const UA_DataSetMetaDataType *src, UA_DataSetMetaDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATASETMETADATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataSetMetaDataType_deleteMembers(UA_DataSetMetaDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATASETMETADATATYPE]); +} + +static UA_INLINE void +UA_DataSetMetaDataType_clear(UA_DataSetMetaDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATASETMETADATATYPE]); +} + +static UA_INLINE void +UA_DataSetMetaDataType_delete(UA_DataSetMetaDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATASETMETADATATYPE]); +}static UA_INLINE UA_Boolean +UA_DataSetMetaDataType_equal(const UA_DataSetMetaDataType *p1, const UA_DataSetMetaDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATASETMETADATATYPE]) == UA_ORDER_EQ); +} + + + +/* PublishedDataSetDataType */ +static UA_INLINE void +UA_PublishedDataSetDataType_init(UA_PublishedDataSetDataType *p) { + memset(p, 0, sizeof(UA_PublishedDataSetDataType)); +} + +static UA_INLINE UA_PublishedDataSetDataType * +UA_PublishedDataSetDataType_new(void) { + return (UA_PublishedDataSetDataType*)UA_new(&UA_TYPES[UA_TYPES_PUBLISHEDDATASETDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PublishedDataSetDataType_copy(const UA_PublishedDataSetDataType *src, UA_PublishedDataSetDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBLISHEDDATASETDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PublishedDataSetDataType_deleteMembers(UA_PublishedDataSetDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHEDDATASETDATATYPE]); +} + +static UA_INLINE void +UA_PublishedDataSetDataType_clear(UA_PublishedDataSetDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBLISHEDDATASETDATATYPE]); +} + +static UA_INLINE void +UA_PublishedDataSetDataType_delete(UA_PublishedDataSetDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBLISHEDDATASETDATATYPE]); +}static UA_INLINE UA_Boolean +UA_PublishedDataSetDataType_equal(const UA_PublishedDataSetDataType *p1, const UA_PublishedDataSetDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBLISHEDDATASETDATATYPE]) == UA_ORDER_EQ); +} + + + +/* DataSetReaderDataType */ +static UA_INLINE void +UA_DataSetReaderDataType_init(UA_DataSetReaderDataType *p) { + memset(p, 0, sizeof(UA_DataSetReaderDataType)); +} + +static UA_INLINE UA_DataSetReaderDataType * +UA_DataSetReaderDataType_new(void) { + return (UA_DataSetReaderDataType*)UA_new(&UA_TYPES[UA_TYPES_DATASETREADERDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_DataSetReaderDataType_copy(const UA_DataSetReaderDataType *src, UA_DataSetReaderDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATASETREADERDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataSetReaderDataType_deleteMembers(UA_DataSetReaderDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATASETREADERDATATYPE]); +} + +static UA_INLINE void +UA_DataSetReaderDataType_clear(UA_DataSetReaderDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATASETREADERDATATYPE]); +} + +static UA_INLINE void +UA_DataSetReaderDataType_delete(UA_DataSetReaderDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATASETREADERDATATYPE]); +}static UA_INLINE UA_Boolean +UA_DataSetReaderDataType_equal(const UA_DataSetReaderDataType *p1, const UA_DataSetReaderDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATASETREADERDATATYPE]) == UA_ORDER_EQ); +} + + + +/* TargetVariablesDataType */ +static UA_INLINE void +UA_TargetVariablesDataType_init(UA_TargetVariablesDataType *p) { + memset(p, 0, sizeof(UA_TargetVariablesDataType)); +} + +static UA_INLINE UA_TargetVariablesDataType * +UA_TargetVariablesDataType_new(void) { + return (UA_TargetVariablesDataType*)UA_new(&UA_TYPES[UA_TYPES_TARGETVARIABLESDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_TargetVariablesDataType_copy(const UA_TargetVariablesDataType *src, UA_TargetVariablesDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_TARGETVARIABLESDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_TargetVariablesDataType_deleteMembers(UA_TargetVariablesDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TARGETVARIABLESDATATYPE]); +} + +static UA_INLINE void +UA_TargetVariablesDataType_clear(UA_TargetVariablesDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_TARGETVARIABLESDATATYPE]); +} + +static UA_INLINE void +UA_TargetVariablesDataType_delete(UA_TargetVariablesDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_TARGETVARIABLESDATATYPE]); +}static UA_INLINE UA_Boolean +UA_TargetVariablesDataType_equal(const UA_TargetVariablesDataType *p1, const UA_TargetVariablesDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_TARGETVARIABLESDATATYPE]) == UA_ORDER_EQ); +} + + + +/* StandaloneSubscribedDataSetDataType */ +static UA_INLINE void +UA_StandaloneSubscribedDataSetDataType_init(UA_StandaloneSubscribedDataSetDataType *p) { + memset(p, 0, sizeof(UA_StandaloneSubscribedDataSetDataType)); +} + +static UA_INLINE UA_StandaloneSubscribedDataSetDataType * +UA_StandaloneSubscribedDataSetDataType_new(void) { + return (UA_StandaloneSubscribedDataSetDataType*)UA_new(&UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_StandaloneSubscribedDataSetDataType_copy(const UA_StandaloneSubscribedDataSetDataType *src, UA_StandaloneSubscribedDataSetDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_StandaloneSubscribedDataSetDataType_deleteMembers(UA_StandaloneSubscribedDataSetDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETDATATYPE]); +} + +static UA_INLINE void +UA_StandaloneSubscribedDataSetDataType_clear(UA_StandaloneSubscribedDataSetDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETDATATYPE]); +} + +static UA_INLINE void +UA_StandaloneSubscribedDataSetDataType_delete(UA_StandaloneSubscribedDataSetDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETDATATYPE]); +}static UA_INLINE UA_Boolean +UA_StandaloneSubscribedDataSetDataType_equal(const UA_StandaloneSubscribedDataSetDataType *p1, const UA_StandaloneSubscribedDataSetDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_STANDALONESUBSCRIBEDDATASETDATATYPE]) == UA_ORDER_EQ); +} + + + +/* DataTypeSchemaHeader */ +static UA_INLINE void +UA_DataTypeSchemaHeader_init(UA_DataTypeSchemaHeader *p) { + memset(p, 0, sizeof(UA_DataTypeSchemaHeader)); +} + +static UA_INLINE UA_DataTypeSchemaHeader * +UA_DataTypeSchemaHeader_new(void) { + return (UA_DataTypeSchemaHeader*)UA_new(&UA_TYPES[UA_TYPES_DATATYPESCHEMAHEADER]); +} + +static UA_INLINE UA_StatusCode +UA_DataTypeSchemaHeader_copy(const UA_DataTypeSchemaHeader *src, UA_DataTypeSchemaHeader *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_DATATYPESCHEMAHEADER]); +} + +UA_DEPRECATED static UA_INLINE void +UA_DataTypeSchemaHeader_deleteMembers(UA_DataTypeSchemaHeader *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATATYPESCHEMAHEADER]); +} + +static UA_INLINE void +UA_DataTypeSchemaHeader_clear(UA_DataTypeSchemaHeader *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_DATATYPESCHEMAHEADER]); +} + +static UA_INLINE void +UA_DataTypeSchemaHeader_delete(UA_DataTypeSchemaHeader *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_DATATYPESCHEMAHEADER]); +}static UA_INLINE UA_Boolean +UA_DataTypeSchemaHeader_equal(const UA_DataTypeSchemaHeader *p1, const UA_DataTypeSchemaHeader *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_DATATYPESCHEMAHEADER]) == UA_ORDER_EQ); +} + + + +/* ReaderGroupDataType */ +static UA_INLINE void +UA_ReaderGroupDataType_init(UA_ReaderGroupDataType *p) { + memset(p, 0, sizeof(UA_ReaderGroupDataType)); +} + +static UA_INLINE UA_ReaderGroupDataType * +UA_ReaderGroupDataType_new(void) { + return (UA_ReaderGroupDataType*)UA_new(&UA_TYPES[UA_TYPES_READERGROUPDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_ReaderGroupDataType_copy(const UA_ReaderGroupDataType *src, UA_ReaderGroupDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_READERGROUPDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_ReaderGroupDataType_deleteMembers(UA_ReaderGroupDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READERGROUPDATATYPE]); +} + +static UA_INLINE void +UA_ReaderGroupDataType_clear(UA_ReaderGroupDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_READERGROUPDATATYPE]); +} + +static UA_INLINE void +UA_ReaderGroupDataType_delete(UA_ReaderGroupDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_READERGROUPDATATYPE]); +}static UA_INLINE UA_Boolean +UA_ReaderGroupDataType_equal(const UA_ReaderGroupDataType *p1, const UA_ReaderGroupDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_READERGROUPDATATYPE]) == UA_ORDER_EQ); +} + + + +/* PubSubConnectionDataType */ +static UA_INLINE void +UA_PubSubConnectionDataType_init(UA_PubSubConnectionDataType *p) { + memset(p, 0, sizeof(UA_PubSubConnectionDataType)); +} + +static UA_INLINE UA_PubSubConnectionDataType * +UA_PubSubConnectionDataType_new(void) { + return (UA_PubSubConnectionDataType*)UA_new(&UA_TYPES[UA_TYPES_PUBSUBCONNECTIONDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PubSubConnectionDataType_copy(const UA_PubSubConnectionDataType *src, UA_PubSubConnectionDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBSUBCONNECTIONDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PubSubConnectionDataType_deleteMembers(UA_PubSubConnectionDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBCONNECTIONDATATYPE]); +} + +static UA_INLINE void +UA_PubSubConnectionDataType_clear(UA_PubSubConnectionDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBCONNECTIONDATATYPE]); +} + +static UA_INLINE void +UA_PubSubConnectionDataType_delete(UA_PubSubConnectionDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBSUBCONNECTIONDATATYPE]); +}static UA_INLINE UA_Boolean +UA_PubSubConnectionDataType_equal(const UA_PubSubConnectionDataType *p1, const UA_PubSubConnectionDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBSUBCONNECTIONDATATYPE]) == UA_ORDER_EQ); +} + + + +/* PubSubConfigurationDataType */ +static UA_INLINE void +UA_PubSubConfigurationDataType_init(UA_PubSubConfigurationDataType *p) { + memset(p, 0, sizeof(UA_PubSubConfigurationDataType)); +} + +static UA_INLINE UA_PubSubConfigurationDataType * +UA_PubSubConfigurationDataType_new(void) { + return (UA_PubSubConfigurationDataType*)UA_new(&UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONDATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PubSubConfigurationDataType_copy(const UA_PubSubConfigurationDataType *src, UA_PubSubConfigurationDataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONDATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PubSubConfigurationDataType_deleteMembers(UA_PubSubConfigurationDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONDATATYPE]); +} + +static UA_INLINE void +UA_PubSubConfigurationDataType_clear(UA_PubSubConfigurationDataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONDATATYPE]); +} + +static UA_INLINE void +UA_PubSubConfigurationDataType_delete(UA_PubSubConfigurationDataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONDATATYPE]); +}static UA_INLINE UA_Boolean +UA_PubSubConfigurationDataType_equal(const UA_PubSubConfigurationDataType *p1, const UA_PubSubConfigurationDataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATIONDATATYPE]) == UA_ORDER_EQ); +} + + + +/* PubSubConfiguration2DataType */ +static UA_INLINE void +UA_PubSubConfiguration2DataType_init(UA_PubSubConfiguration2DataType *p) { + memset(p, 0, sizeof(UA_PubSubConfiguration2DataType)); +} + +static UA_INLINE UA_PubSubConfiguration2DataType * +UA_PubSubConfiguration2DataType_new(void) { + return (UA_PubSubConfiguration2DataType*)UA_new(&UA_TYPES[UA_TYPES_PUBSUBCONFIGURATION2DATATYPE]); +} + +static UA_INLINE UA_StatusCode +UA_PubSubConfiguration2DataType_copy(const UA_PubSubConfiguration2DataType *src, UA_PubSubConfiguration2DataType *dst) { + return UA_copy(src, dst, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATION2DATATYPE]); +} + +UA_DEPRECATED static UA_INLINE void +UA_PubSubConfiguration2DataType_deleteMembers(UA_PubSubConfiguration2DataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATION2DATATYPE]); +} + +static UA_INLINE void +UA_PubSubConfiguration2DataType_clear(UA_PubSubConfiguration2DataType *p) { + UA_clear(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATION2DATATYPE]); +} + +static UA_INLINE void +UA_PubSubConfiguration2DataType_delete(UA_PubSubConfiguration2DataType *p) { + UA_delete(p, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATION2DATATYPE]); +}static UA_INLINE UA_Boolean +UA_PubSubConfiguration2DataType_equal(const UA_PubSubConfiguration2DataType *p1, const UA_PubSubConfiguration2DataType *p2) { + return (UA_order(p1, p2, &UA_TYPES[UA_TYPES_PUBSUBCONFIGURATION2DATATYPE]) == UA_ORDER_EQ); +} + + + +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +# pragma GCC diagnostic pop +#endif + +_UA_END_DECLS + +#endif /* TYPES_GENERATED_HANDLING_H_ */ diff --git a/product/src/fes/include/open62541/util.h b/product/src/fes/include/open62541/util.h new file mode 100644 index 00000000..63a20880 --- /dev/null +++ b/product/src/fes/include/open62541/util.h @@ -0,0 +1,292 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2018 (c) Stefan Profanter, fortiss GmbH + */ + +#ifndef UA_HELPER_H_ +#define UA_HELPER_H_ + +#include +#include +#include + +_UA_BEGIN_DECLS + +/** + * Range Definition + * ---------------- */ + +typedef struct { + UA_UInt32 min; + UA_UInt32 max; +} UA_UInt32Range; + +typedef struct { + UA_Duration min; + UA_Duration max; +} UA_DurationRange; + +/** + * Random Number Generator + * ----------------------- + * If UA_MULTITHREADING is defined, then the seed is stored in thread + * local storage. The seed is initialized for every thread in the + * server/client. */ + +void UA_EXPORT +UA_random_seed(UA_UInt64 seed); + +UA_UInt32 UA_EXPORT +UA_UInt32_random(void); /* no cryptographic entropy */ + +UA_Guid UA_EXPORT +UA_Guid_random(void); /* no cryptographic entropy */ + +/** + * Key Value Map + * ------------- + * Helper functions to work with configuration parameters in an array of + * UA_KeyValuePair. Lookup is linear. So this is for small numbers of keys. The + * methods below that accept a `const UA_KeyValueMap` as an argument also accept + * NULL for that argument and treat it as an empty map. */ + +typedef struct { + size_t mapSize; + UA_KeyValuePair *map; +} UA_KeyValueMap; + +UA_EXPORT extern const UA_KeyValueMap UA_KEYVALUEMAP_NULL; + +UA_EXPORT UA_KeyValueMap * +UA_KeyValueMap_new(void); + +UA_EXPORT void +UA_KeyValueMap_clear(UA_KeyValueMap *map); + +UA_EXPORT void +UA_KeyValueMap_delete(UA_KeyValueMap *map); + +/* Is the map empty (or NULL)? */ +UA_EXPORT UA_Boolean +UA_KeyValueMap_isEmpty(const UA_KeyValueMap *map); + +/* Does the map contain an entry for the key? */ +UA_EXPORT UA_Boolean +UA_KeyValueMap_contains(const UA_KeyValueMap *map, const UA_QualifiedName key); + +/* Insert a copy of the value. Can reallocate the underlying array. This + * invalidates pointers into the previous array. If the key exists already, the + * value is overwritten (upsert semantics). */ +UA_EXPORT UA_StatusCode +UA_KeyValueMap_set(UA_KeyValueMap *map, + const UA_QualifiedName key, + const UA_Variant *value); + +/* Helper function for scalar insertion that internally calls + * `UA_KeyValueMap_set` */ +UA_EXPORT UA_StatusCode +UA_KeyValueMap_setScalar(UA_KeyValueMap *map, + const UA_QualifiedName key, + void * UA_RESTRICT p, + const UA_DataType *type); + +/* Returns a pointer to the value or NULL if the key is not found */ +UA_EXPORT const UA_Variant * +UA_KeyValueMap_get(const UA_KeyValueMap *map, + const UA_QualifiedName key); + +/* Returns NULL if the value for the key is not defined, not of the right + * datatype or not a scalar */ +UA_EXPORT const void * +UA_KeyValueMap_getScalar(const UA_KeyValueMap *map, + const UA_QualifiedName key, + const UA_DataType *type); + +/* Remove a single entry. To delete the entire map, use `UA_KeyValueMap_clear`. */ +UA_EXPORT UA_StatusCode +UA_KeyValueMap_remove(UA_KeyValueMap *map, + const UA_QualifiedName key); + +/* Create a deep copy of the given KeyValueMap */ +UA_EXPORT UA_StatusCode +UA_KeyValueMap_copy(const UA_KeyValueMap *src, UA_KeyValueMap *dst); + +/* Copy entries from the right-hand-side into the left-hand-size. Reallocates + * previous memory in the left-hand-side. If the operation fails, both maps are + * left untouched. */ +UA_EXPORT UA_StatusCode +UA_KeyValueMap_merge(UA_KeyValueMap *lhs, const UA_KeyValueMap *rhs); + +/** + * Binary Connection Config Parameters + * ----------------------------------- */ + +typedef struct { + UA_UInt32 protocolVersion; + UA_UInt32 recvBufferSize; + UA_UInt32 sendBufferSize; + UA_UInt32 localMaxMessageSize; /* (0 = unbounded) */ + UA_UInt32 remoteMaxMessageSize; /* (0 = unbounded) */ + UA_UInt32 localMaxChunkCount; /* (0 = unbounded) */ + UA_UInt32 remoteMaxChunkCount; /* (0 = unbounded) */ +} UA_ConnectionConfig; + +/** + * .. _default-node-attributes: + * + * Default Node Attributes + * ----------------------- + * Default node attributes to simplify the use of the AddNodes services. For + * example, Setting the ValueRank and AccessLevel to zero is often an unintended + * setting and leads to errors that are hard to track down. */ + +/* The default for variables is "BaseDataType" for the datatype, -2 for the + * valuerank and a read-accesslevel. */ +UA_EXPORT extern const UA_VariableAttributes UA_VariableAttributes_default; +UA_EXPORT extern const UA_VariableTypeAttributes UA_VariableTypeAttributes_default; + +/* Methods are executable by default */ +UA_EXPORT extern const UA_MethodAttributes UA_MethodAttributes_default; + +/* The remaining attribute definitions are currently all zeroed out */ +UA_EXPORT extern const UA_ObjectAttributes UA_ObjectAttributes_default; +UA_EXPORT extern const UA_ObjectTypeAttributes UA_ObjectTypeAttributes_default; +UA_EXPORT extern const UA_ReferenceTypeAttributes UA_ReferenceTypeAttributes_default; +UA_EXPORT extern const UA_DataTypeAttributes UA_DataTypeAttributes_default; +UA_EXPORT extern const UA_ViewAttributes UA_ViewAttributes_default; + +/** + * Endpoint URL Parser + * ------------------- + * The endpoint URL parser is generally useful for the implementation of network + * layer plugins. */ + +/* Split the given endpoint url into hostname, port and path. All arguments must + * be non-NULL. EndpointUrls have the form "opc.tcp://hostname:port/path", port + * and path may be omitted (together with the prefix colon and slash). + * + * @param endpointUrl The endpoint URL. + * @param outHostname Set to the parsed hostname. The string points into the + * original endpointUrl, so no memory is allocated. If an IPv6 address is + * given, hostname contains e.g. '[2001:0db8:85a3::8a2e:0370:7334]' + * @param outPort Set to the port of the url or left unchanged. + * @param outPath Set to the path if one is present in the endpointUrl. Can be + * NULL. Then not path is returned. Starting or trailing '/' are NOT + * included in the path. The string points into the original endpointUrl, + * so no memory is allocated. + * @return Returns UA_STATUSCODE_BADTCPENDPOINTURLINVALID if parsing failed. */ +UA_StatusCode UA_EXPORT +UA_parseEndpointUrl(const UA_String *endpointUrl, UA_String *outHostname, + UA_UInt16 *outPort, UA_String *outPath); + +/* Split the given endpoint url into hostname, vid and pcp. All arguments must + * be non-NULL. EndpointUrls have the form "opc.eth://[:[.PCP]]". + * The host is a MAC address, an IP address or a registered name like a + * hostname. The format of a MAC address is six groups of hexadecimal digits, + * separated by hyphens (e.g. 01-23-45-67-89-ab). A system may also accept + * hostnames and/or IP addresses if it provides means to resolve it to a MAC + * address (e.g. DNS and Reverse-ARP). + * + * Note: currently only parsing MAC address is supported. + * + * @param endpointUrl The endpoint URL. + * @param vid Set to VLAN ID. + * @param pcp Set to Priority Code Point. + * @return Returns UA_STATUSCODE_BADINTERNALERROR if parsing failed. */ +UA_StatusCode UA_EXPORT +UA_parseEndpointUrlEthernet(const UA_String *endpointUrl, UA_String *target, + UA_UInt16 *vid, UA_Byte *pcp); + +/* Convert given byte string to a positive number. Returns the number of valid + * digits. Stops if a non-digit char is found and returns the number of digits + * up to that point. */ +size_t UA_EXPORT +UA_readNumber(const UA_Byte *buf, size_t buflen, UA_UInt32 *number); + +/* Same as UA_ReadNumber but with a base parameter */ +size_t UA_EXPORT +UA_readNumberWithBase(const UA_Byte *buf, size_t buflen, + UA_UInt32 *number, UA_Byte base); + +#ifndef UA_MIN +#define UA_MIN(A, B) ((A) > (B) ? (B) : (A)) +#endif + +#ifndef UA_MAX +#define UA_MAX(A, B) ((A) > (B) ? (A) : (B)) +#endif + +/** + * Parse RelativePath Expressions + * ------------------------------ + * + * Parse a RelativePath according to the format defined in Part 4, A2. This is + * used e.g. for the BrowsePath structure. For now, only the standard + * ReferenceTypes from Namespace 0 are recognized (see Part 3). + * + * ``RelativePath := ( ReferenceType [BrowseName]? )*`` + * + * The ReferenceTypes have either of the following formats: + * + * - ``/``: *HierarchicalReferences* and subtypes + * - ``.``: *Aggregates* ReferenceTypesand subtypes + * - ``< [!#]* BrowseName >``: The ReferenceType is indicated by its BrowseName + * (a QualifiedName). Prefixed modifiers can be as follows: ``!`` switches to + * inverse References. ``#`` excludes subtypes of the ReferenceType. + * + * QualifiedNames consist of an optional NamespaceIndex and the nameitself: + * + * ``QualifiedName := ([0-9]+ ":")? Name`` + * + * The QualifiedName representation for RelativePaths uses ``&`` as the escape + * character. Occurences of the characters ``/.<>:#!&`` in a QualifiedName have + * to be escaped (prefixed with ``&``). + * + * Example RelativePaths + * ````````````````````` + * + * - ``/2:Block&.Output`` + * - ``/3:Truck.0:NodeVersion`` + * - ``<0:HasProperty>1:Boiler/1:HeatSensor`` + * - ``<0:HasChild>2:Wheel`` + * - ``<#Aggregates>1:Boiler/`` + * - ``Truck`` + * - ```` + */ +#ifdef UA_ENABLE_PARSING +UA_EXPORT UA_StatusCode +UA_RelativePath_parse(UA_RelativePath *rp, const UA_String str); +#endif + +/** + * Convenience macros for complex types + * ------------------------------------ */ +#define UA_PRINTF_GUID_FORMAT "%08" PRIx32 "-%04" PRIx16 "-%04" PRIx16 \ + "-%02" PRIx8 "%02" PRIx8 "-%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 +#define UA_PRINTF_GUID_DATA(GUID) (GUID).data1, (GUID).data2, (GUID).data3, \ + (GUID).data4[0], (GUID).data4[1], (GUID).data4[2], (GUID).data4[3], \ + (GUID).data4[4], (GUID).data4[5], (GUID).data4[6], (GUID).data4[7] + +#define UA_PRINTF_STRING_FORMAT "\"%.*s\"" +#define UA_PRINTF_STRING_DATA(STRING) (int)(STRING).length, (STRING).data + +/** + * Cryptography Helpers + * -------------------- */ + +/* Compare memory in constant time to mitigate timing attacks. + * Returns true if ptr1 and ptr2 are equal for length bytes. */ +UA_EXPORT UA_Boolean +UA_constantTimeEqual(const void *ptr1, const void *ptr2, size_t length); + +/* Zero-out memory in a way that is not removed by compiler-optimizations. Use + * this to ensure cryptographic secrets don't leave traces after the memory was + * freed. */ +UA_EXPORT void +UA_ByteString_memZero(UA_ByteString *bs); + +_UA_END_DECLS + +#endif /* UA_HELPER_H_ */ diff --git a/product/src/fes/protocol/cdts/CdtsDataProcThread.cpp b/product/src/fes/protocol/cdts/CdtsDataProcThread.cpp index 414efad6..528ba73a 100644 --- a/product/src/fes/protocol/cdts/CdtsDataProcThread.cpp +++ b/product/src/fes/protocol/cdts/CdtsDataProcThread.cpp @@ -667,6 +667,8 @@ void CCdtsDataProcThread::SendAccFrame() SFesFwAcc *pFwAcc; int writex; uint8 crc, wordLen, funCode; + double AccDoubleValue; + int64 shortAccValue; maxCount = 32; writex = 12; @@ -681,11 +683,17 @@ void CCdtsDataProcThread::SendAccFrame() { pFwAcc = m_ptrCFesRtu->m_pFwAcc + m_AppData.sendAccIndex; funCode = 0xA0 | m_AppData.sendAccIndex;//功能码 + AccDoubleValue = (double)(pFwAcc->Value*pFwAcc->Coeff + pFwAcc->Base); + shortAccValue = (int64)AccDoubleValue; m_AppData.sendData[writex++] = funCode; - m_AppData.sendData[writex++] = pFwAcc->Value & 0xff; - m_AppData.sendData[writex++] = (pFwAcc->Value >> 8) & 0xff; - m_AppData.sendData[writex++] = (pFwAcc->Value >> 16) & 0xff; - m_AppData.sendData[writex++] = (pFwAcc->Value >> 24) & 0xff; + // m_AppData.sendData[writex++] = pFwAcc->Value & 0xff; + // m_AppData.sendData[writex++] = (pFwAcc->Value >> 8) & 0xff; + // m_AppData.sendData[writex++] = (pFwAcc->Value >> 16) & 0xff; + // m_AppData.sendData[writex++] = (pFwAcc->Value >> 24) & 0xff; + m_AppData.sendData[writex++] = shortAccValue & 0xff; + m_AppData.sendData[writex++] = (shortAccValue >> 8) & 0xff; + m_AppData.sendData[writex++] = (shortAccValue >> 16) & 0xff; + m_AppData.sendData[writex++] = (shortAccValue >> 24) & 0xff; MakeBch(&m_AppData.sendData[writex - 5], &crc); m_AppData.sendData[writex++] = crc; m_AppData.sendAccIndex++; diff --git a/product/src/fes/protocol/combase/ComSerialPort.cpp b/product/src/fes/protocol/combase/ComSerialPort.cpp new file mode 100644 index 00000000..358ab5e7 --- /dev/null +++ b/product/src/fes/protocol/combase/ComSerialPort.cpp @@ -0,0 +1,830 @@ +/* + @file CComSerialPort.cpp + @brief + 串口驱动按照不同的操作系统,分别处理。 + WINDOWS系统下,COM17,COM18是按照R80X管理机的硬件处理,所以如果是台式电脑避免使用COM17,COM18 + + @author thxiao + @history + 2020-05-20 thxiao + 1、CComSerialPort 改为死锁超时5秒 + 2、增加应用重新打开串口功能,保证在某些异常情况下串口可以被从新初始化 + 2020-05-20 thxiao + LIUNX 串口驱动及P15,P16的RS232/RS485切换处理 + 2020-9-9 thxiao WIN系统增加P1~P24的配置方法 + 2021-07-08 thxiao 增加两种接收发送数据的模式, 0:在循环中接收发送数据 1:应用程序手动干预接收发送数据 + 2022-11-09 thxiao KBD511S 管理机串口分配 + + +*/ +#include "ComSerialPort.h" + +#ifdef WIN32 +#include "MPIO.h" +#else +#include +#include +#include +#include +#include +#include +#include +#include +#endif + + +using namespace iot_public; +using namespace iot_public; +const int g_SerialPortThreadTime = 10; + + +CComSerialPort::CComSerialPort(CFesChanPtr ptrCFesChan) +{ + m_ptrCFesChan = ptrCFesChan; + m_ptrCurrentChan = ptrCFesChan; + + m_timerCount = 0; + m_timerCountReset = 0; + m_devId = HINVALID; + m_comIndex = -1; + errSendCount = 0; + errRecvCount = 0; + openCount = 500; + +} + +CComSerialPort::~CComSerialPort() +{ + + LOGDEBUG("CComSerialPort::~CComSerialPort() chanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); +} + +#if 0 +void CComSerialPort::execute() +{ + + + if (!m_ThreadRunFlag) + return; + + if(m_devId!= HINVALID) + { + if (m_ThreadRunMode == 0) + { + RxComData(); + TxComData2(); + } + } + else + { + if (openCount++ > 500)//5秒重新打开 + { + openCount = 0; + OpenChan(); + SetChan(); + } + } + + //2020-05-20 thxiao 增加应用重新打开串口功能,保证在某些异常情况下串口可以被从新初始化 + SFesAppNetEvent event; + if (m_ptrCFesChan->ReadAppNetEvent(1, &event) > 0) + { + if (event.EventType == CN_FesAppNetEvent_ReopenChan) + { + OpenChan(); + SetChan(); + LOGDEBUG("CComSerialPort::execute() chanNo=%d 应用重新打开串口", m_ptrCFesChan->m_Param.ChanNo); + } + } + +} +#endif + +void CComSerialPort::RxComData(CFesChanPtr ptrCFesChan) +{ +#ifdef WIN32 + DWORD nBytesRead = 0; + DWORD dwError; + DWORD nBytes; + COMSTAT comstat; + BOOL bReadStat; +#else + int nBytesRead = 0; + int line; +#endif + int rtn; + uint8 inbuff[1024]; + +#ifdef WIN32 + ClearCommError(m_devId, &dwError, &comstat); + if (comstat.cbInQue > 512) + nBytes = 512; + else + nBytes = comstat.cbInQue; + bReadStat = ReadFile(m_devId, inbuff, nBytes, &nBytesRead, NULL); + if (!bReadStat) { + /*if (errRecvCount++ > 20) + { + LOGDEBUG("ChanNo=%d 读串口%s 失败!关闭通道", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + errRecvCount = 0; + CloseChan(ptrCFesChan); + }*/ + } + else + { + if (nBytesRead > 0) + { + if ((rtn = ptrCFesChan->WriteRxBufData(nBytesRead, inbuff)) < 0) + LOGDEBUG("SerialPortThread.cpp ChanNo:%d Error in WriteRxBufData!", ptrCFesChan->m_Param.ChanNo); + } + } +#else + fd_set rdfds; /* 先申明一个 fd_set 集合来保存我们要检测的 socket句柄 */ + struct timeval tv; /* 申明一个时间变量来保存时间 */ + int iRet; /* 保存返回值 */ + + FD_ZERO(&rdfds); /* 用select函数之前先把集合清零 */ + + FD_SET(m_devId, &rdfds); /* 把要检测的句柄socket加入到集合里 */ + tv.tv_sec = 0; + tv.tv_usec = 5000; /* 设置select等待的最大时间1秒加500000微秒 */ + + iRet = select(m_devId + 1, &rdfds, NULL, NULL, &tv); /* 检测我们上面设置到集合rdfds里的句柄是否有可读信息 */ + if(iRet < 0) + { + /*if (errRecvCount++ > 20) + { + LOGDEBUG("ChanNo=%d 读串口%s 失败!关闭通道", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + errRecvCount = 0; + CloseChan(ptrCFesChan); + }*/ + return ; + } + else if(iRet ==0) + { + return ; + } + else + { + if(FD_ISSET(m_devId,&rdfds)) + { + nBytesRead = read(m_devId, inbuff, 512); + if (nBytesRead < 1) + { + if (errRecvCount++ > 20) + { + LOGDEBUG("ChanNo=%d 读串口%s 失败!关闭通道", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + errRecvCount = 0; + CloseChan(ptrCFesChan); + } + return; + } + else + if (nBytesRead > 0) + { + //LOGERROR("SerialPortThread.cpp ChanNo:%d RxDataLen=%d!", ptrCFesChan->m_Param.ChanNo,nBytesRead); + if ((rtn = ptrCFesChan->WriteRxBufData(nBytesRead, inbuff)) < 0) + LOGDEBUG("SerialPortThread.cpp ChanNo:%d Error in WriteRxBufData!", ptrCFesChan->m_Param.ChanNo); + } + } + } + +#endif + +} + +void CComSerialPort::TxComData(CFesChanPtr ptrCFesChan,int dateLen, byte *pData) +{ +#ifdef WIN32 + DWORD nBytesWrite; + BOOL bWriteStat; +#else + int nBytesWrite; +#endif + + if (dateLen > 0) + { +#ifdef WIN32 + bWriteStat = WriteFile(m_devId, pData, dateLen, &nBytesWrite, NULL); + if (!bWriteStat) + { + errSendCount++; + if (errSendCount++ > 20) + { + LOGDEBUG("ChanNo:%d 发送错误%d次数,关闭通道!", ptrCFesChan->m_Param.ChanNo, errSendCount); + errSendCount = 0; + CloseChan(ptrCFesChan); + } + } + else + { + errSendCount = 0; + } + +#else + nBytesWrite = write(m_devId, pData, dateLen); + //LOGDEBUG("SerialPortThread.cpp ChanNo:%d write()", ptrCFesChan->m_Param.ChanNo); + if (nBytesWrite > 0) + ptrCFesChan->DeleteReadTxBufData(nBytesWrite); //删除已经发送的数据 + else + if (nBytesWrite < 0) + { + LOGERROR("SerialPortThread.cpp ChanNo:%d Error in write()", ptrCFesChan->m_Param.ChanNo); + } +#endif + + } +} + +bool CComSerialPort::OpenChan(CFesChanPtr ptrCFesChan) +{ +#ifdef WIN32 + if (m_devId != HINVALID) { + CloseHandle(m_devId); + m_devId = HINVALID; + Sleep(10); + } + std::string tempstr; + std::string tempComStr = ptrCFesChan->m_Param.NetRoute[0].NetDesc; + std::string tempPStr; + + tempPStr = tempComStr.substr(0, 1); + if (tempPStr == "P")//2020-9-9 thxiao WIN系统增加P1~P24的配置方法 + { + int namelen = (int)tempComStr.length(); + std::string strComNo1; + int index = -1; + if (namelen == 2) + strComNo1 = tempComStr.substr(1, 1); + else + if (namelen == 3) + strComNo1 = tempComStr.substr(1, 2); + + index = atoi(strComNo1.c_str()); + if ((index >= 1) && (index <= 24)) + { + char comname[20]; + sprintf(comname, "COM%d", index + 2); + tempstr = comname; + } + else + tempstr = ptrCFesChan->m_Param.NetRoute[0].NetDesc;//错误的描述 + + } + else//COM3 COM4...... + tempstr = ptrCFesChan->m_Param.NetRoute[0].NetDesc; + + + std::string nameStr; + int namelen = (int)tempstr.length(); + std::string strComNo; + if (namelen == 4) + strComNo = tempstr.substr(3, 1); + else + if (namelen >= 5) + strComNo = tempstr.substr(3, 2); + else + { + LOGERROR("ChanNo=%d 串口名字%s 错误,打开串口失败!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + return false; + } + //COM3->P1 COM4->P2 ...... + int index = atoi(strComNo.c_str()); + if (index >= 10)//PORT>=COM10 + { + char comname[100]; + sprintf(comname, "\\\\.\\%s", tempstr.c_str()); + nameStr = comname; + } + else + { + nameStr = tempstr;//2020-09-09 thxiao 取转换的串口名称值 + } + + int nDstLength; // UNICODE宽字符数目 + WCHAR wchar[64]; // UNICODE串缓冲区 + // 字符串-->UNICODE串 + memset(wchar, 0, sizeof(wchar)); + nDstLength = MultiByteToWideChar(CP_ACP, 0, nameStr.c_str(), (int)nameStr.length(), wchar, 64); + LPCWSTR strCommPath = wchar; + m_devId = CreateFile(strCommPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, 0, NULL); + if (m_devId == INVALID_HANDLE_VALUE) { + m_devId = HINVALID; + LOGERROR("ChanNo=%d 打开串口%s(%s) 失败!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc,nameStr.c_str()); + return false; + } + else + { + if ((index == 17) || (index == 18)) + { + //P15, P16为RS232/RS485可选串口 + if (ptrCFesChan->m_Param.ResParam1 == 232) + { + ComModeSet(m_devId, 0, index - 17); + LOGDEBUG("ChanNo=%d 打开串口%s RS232模式!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + } + else + { + ComModeSet(m_devId, 1, index - 17); + LOGDEBUG("ChanNo=%d 打开串口%s RS485模式!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + } + //ComReset(m_devId, 1, index - 17);//默认高电平输出 + } + + if (ptrCFesChan->GetLinkStatus() != CN_FesChanConnect) + { + ptrCFesChan->SetLinkStatus(CN_FesChanConnect); + //记录网络事件 + SFesNetEvent netEvent; + netEvent.Time = getUTCTimeMsec(); + netEvent.EventType = CN_FesChanConnect; + m_ptrCFesChan->WriteNetEvent(1, &netEvent); + } + SetChan(ptrCFesChan); + LOGDEBUG("ChanNo=%d 打开串口%s(%s) 成功!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc, nameStr.c_str()); + return true; + } +#else + //linux + if (m_devId != HINVALID) + { + close(m_devId); + m_devId = HINVALID; + Sleep(10); + } + std::string tempstr = ptrCFesChan->m_Param.NetRoute[0].NetDesc; + std::string nameStr; + int namelen = tempstr.length(); + std::string strComNo; + int index=-1; + if (namelen >= 2)//P1,P2.......or other + { + nameStr = tempstr.substr(0, 1); + if (nameStr == "P") + { + if (namelen == 2) + strComNo = tempstr.substr(1, 1); + else + if (namelen == 3) + strComNo = tempstr.substr(1, 2); + + index = atoi(strComNo.c_str()); +#if 0 + // X86管理机串口分配 + if ((index >= 1) && (index <= 24)) + { + char comname[100]; + sprintf(comname, "/dev/ttyXR%d", index - 1); + nameStr = comname; + m_comIndex = index; + } +#endif + // 2022-11-09 KBD511S 管理机串口分配 + if (index == 1) + { + char comname[100]; + sprintf(comname, "/dev/ttyS0"); + nameStr = comname; + m_comIndex = index; + } + else + if((index >= 2)&&(index <= 6)) + { + char comname[100]; + sprintf(comname, "/dev/ttyS%d", index + 1); + nameStr = comname; + m_comIndex = index; + } + else + { + LOGERROR("ChanNo=%d 串口名字%s 无法找到正确的串口,打开串口失败!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + m_comIndex = -1; + return false; + } + } + else + { + //直接就是LINUX串口名 + nameStr = tempstr; + } + //m_devId = open(nameStr.c_str(), O_RDWR | O_NOCTTY);//打开端口 + m_devId = open(nameStr.c_str(), O_RDWR,0);//打开端口 + if (m_devId<0) + { + m_devId = HINVALID; + LOGERROR("ChanNo=%d 串口%s %s 打开串口失败!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc, nameStr.c_str()); + return false; + } + } + else + { + LOGERROR("ChanNo=%d 串口%s 打开串口失败!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + return false; + } + + if (ptrCFesChan->GetLinkStatus() != CN_FesChanConnect) + { + ptrCFesChan->SetLinkStatus(CN_FesChanConnect); + //记录网络事件 + SFesNetEvent netEvent; + netEvent.Time = getUTCTimeMsec(); + netEvent.EventType = CN_FesChanConnect; + m_ptrCFesChan->WriteNetEvent(1, &netEvent); + } + SetChan(ptrCFesChan); + LOGINFO("ChanNo=%d 串口%s %s 打开成功!m_devId=%d", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc, nameStr.c_str(), m_devId); + return true; + +#endif + +} + + +void CComSerialPort::CloseChan(CFesChanPtr ptrCFesChan) +{ + if (m_devId == HINVALID) + return; + +#ifdef WIN32 + PurgeComm(m_devId, PURGE_RXCLEAR); + CloseHandle(m_devId); + m_devId = HINVALID; +#else + close(m_devId); + m_devId = HINVALID; +#endif + + if (ptrCFesChan->GetLinkStatus() != CN_FesChanDisconnect) + { + ptrCFesChan->SetLinkStatus(CN_FesChanDisconnect); + //记录网络事件 + SFesNetEvent netEvent; + netEvent.Time = getUTCTimeMsec(); + netEvent.EventType = CN_FesNetEvent_Disconnect; + ptrCFesChan->WriteNetEvent(1, &netEvent); + + LOGDEBUG("Chan%d Disconnect", ptrCFesChan->m_Param.ChanNo); + + } + ptrCFesChan->SetLinkStatus(CN_FesChanDisconnect); + +} + +void CComSerialPort::SetChan(CFesChanPtr ptrCFesChan) +{ +#ifdef WIN32 + DCB dcb; + COMMPROP commprop; + COMMTIMEOUTS timeouts; + + GetCommProperties(m_devId, &commprop); + GetCommState(m_devId, &dcb); + dcb.BaudRate = ptrCFesChan->m_Param.BaudRate; + dcb.ByteSize = ptrCFesChan->m_Param.DataBit; + dcb.StopBits = ptrCFesChan->m_Param.StopBit - 1;//ONESTOPBIT=0 TWOSTOPBITS=1 + dcb.Parity = 0; + dcb.fParity = 0; + if (ptrCFesChan->m_Param.Parity== COM_NOPARITY) + dcb.Parity = NOPARITY; + else + { + dcb.fParity = 1; + if(ptrCFesChan->m_Param.Parity == COM_ODDPARITY) + dcb.Parity = dcb.Parity | ODDPARITY; + else + if (ptrCFesChan->m_Param.Parity == COM_EVENPARITY) + dcb.Parity = dcb.Parity | EVENPARITY; + else + if (ptrCFesChan->m_Param.Parity == COM_SPACEPARITY) + dcb.Parity = dcb.Parity | SPACEPARITY; + else + if (ptrCFesChan->m_Param.Parity == COM_MARKPARITY) + dcb.Parity = dcb.Parity | MARKPARITY; + } + SetCommState(m_devId, &dcb); + GetCommTimeouts(m_devId, &timeouts); + memset(&timeouts, 0, sizeof(timeouts)); + timeouts.ReadIntervalTimeout = MAXDWORD; //如果读间隔超时被设置成MAXDWORD并且读时间系数和读时间常量都为0,那么在读一次输入缓冲区的内容后读操作就立即返回,而不管是否读入了要求的字符 + //timeouts.WriteTotalTimeoutConstant = 3000; //写该参数,串口写完会立刻返回,也不会等到超时才返回 + SetCommTimeouts(m_devId, &timeouts); + SetupComm(m_devId, 1024, 1024); //输入缓冲区和输出缓冲区的大小都是1024 +#else + int speed_arr[] = { B115200,B57600,B38400,B19200,B9600,B4800,B2400,B1800,B1200,B600,B300,B200 }; + int name_arr[] = { 115200,57600, 38400, 19200, 9600, 4800, 2400, 1800, 1200, 600, 300, 200 }; + + struct termios Opt; + int i; + fcntl(m_devId, F_SETFL, FNDELAY); /* Set nonblocking mode */ + tcgetattr(m_devId, &Opt); + Opt.c_lflag = 0; + Opt.c_iflag = 0; + Opt.c_oflag = 0; + Opt.c_iflag |= IGNBRK; + Opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + Opt.c_cflag |= (CLOCAL | CREAD); + Opt.c_cc[VMIN] = 1; + Opt.c_cc[VTIME] = 0; + tcsetattr(m_devId, TCSANOW, &Opt); + tcgetattr(m_devId, &Opt); + int found = 0; + for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++) + { + if (ptrCFesChan->m_Param.BaudRate == name_arr[i]) + { + cfsetispeed(&Opt, speed_arr[i]);/*设置波特率*/ + cfsetospeed(&Opt, speed_arr[i]); + found = 1; + break; + } + } + if (!found) + { + LOGERROR("ChanNo=%d 串口名字%s 设置BPS错误!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + return; + } + + + Opt.c_cflag &= ~CSIZE; + switch (ptrCFesChan->m_Param.DataBit) /*设置数据位数*/ + { + case 5: + Opt.c_cflag |= CS5; + break; + case 6: + Opt.c_cflag |= CS6; + break; + case 7: + Opt.c_cflag |= CS7; + break; + case 8: + Opt.c_cflag |= CS8; + break; + default: + Opt.c_cflag |= CS8; + break; + } + + /* 设置停止位*/ + + switch (ptrCFesChan->m_Param.StopBit) + { + case 1: + Opt.c_cflag &= ~CSTOPB; + break; + case 2: + Opt.c_cflag |= CSTOPB; + break; + default: + LOGERROR("ChanNo=%d 串口名字%s 设置停止位错误!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + return; + } + + Opt.c_cflag &= ~(PARENB | PARODD | CMSPAR); + switch (ptrCFesChan->m_Param.Parity) + { + case COM_EVENPARITY: + Opt.c_cflag |= PARENB; + Opt.c_cflag &= ~PARODD; + break; + case COM_ODDPARITY: + Opt.c_cflag |= PARENB; + Opt.c_cflag |= PARODD; + break; + case COM_SPACEPARITY: + Opt.c_cflag |= PARENB; + Opt.c_cflag &= ~PARODD; + Opt.c_cflag |= CMSPAR; + break; + case COM_MARKPARITY: + Opt.c_cflag |= PARENB; + Opt.c_cflag |= PARODD; + Opt.c_cflag |= CMSPAR; + break; + default: + Opt.c_cflag &= ~PARENB; + break; + } + + if (tcsetattr(m_devId, TCSANOW, &Opt) != 0) + { + LOGERROR("ChanNo=%d 串口名字%s 设置串口属性失败!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + return; + } + + tcgetattr(m_devId, &Opt); + Opt.c_cflag &= ~CRTSCTS; + Opt.c_iflag &= ~(IXON | IXOFF | IXANY); + tcsetattr(m_devId, TCSANOW, &Opt); + + + if ((m_comIndex == 15) || (m_comIndex == 16)) + { + //P15, P16为RS232/RS485可选串口 + if (ptrCFesChan->m_Param.ResParam1 == 232) + { + ComModeSet(m_devId, 0, m_comIndex - 15); + LOGDEBUG("ChanNo=%d 打开串口%s RS232模式!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + } + else + { + ComModeSet(m_devId, 1, m_comIndex - 15); + LOGDEBUG("ChanNo=%d 打开串口%s RS485模式!", ptrCFesChan->m_Param.ChanNo, ptrCFesChan->m_Param.NetRoute[0].NetDesc); + } + } + +#endif + +} +#ifdef WIN32 + + // 写配置 + BOOL CComSerialPort::cfgWrite(HANDLE hPortHandle, BYTE bReg, BYTE bValue) + { + BOOL Status; + DWORD cbReturned; + + CONFIG_WRITE cfgWrite; + + cfgWrite.bReg = bReg; // 寄存器 + cfgWrite.bData = bValue; // 值 + Status = DeviceIoControl(hPortHandle, //handle that you got from CreateFile() + (DWORD)IOCTL_XRPORT_WRITE_CONFIG_REG, + &cfgWrite, + sizeof(CONFIG_WRITE), + NULL, + 0, + &cbReturned, + 0); + if (!Status) + { + LOGERROR("cfgWrite() DeviceIoControl error."); + } + return Status; + } + + // 读配置 + BOOL CComSerialPort::cfgRead(HANDLE hPortHandle, BYTE bReg, BYTE *pbValue) + { + BOOL Status; + DWORD cbReturned; + + Status = DeviceIoControl(hPortHandle, //handle that you got from CreateFile + IOCTL_XRPORT_READ_CONFIG_REG, + &bReg, + sizeof(BYTE), + pbValue, + sizeof(BYTE), + &cbReturned, + 0); + if (!Status) + { + LOGERROR("cfgRead() DeviceIoControl error."); + } + return Status; + } + + //demo + /* 函数:ComModeSet + * 功能:配置COM15/16口为RS232/RS485模式 + * 参数:Mode, 0设置为RS232, 1设置为RS485 + * num, 0为COM15, 1为COM16 + */ + void CComSerialPort::ComModeSet( HANDLE hPortHandle, unsigned int Mode, unsigned int num) + { + BYTE v, x; + + cfgRead(hPortHandle, 0X19, &x); + cfgWrite(hPortHandle, 0x19, 0X24); + cfgRead(hPortHandle, 0x16, &v); + + if (0 == Mode) + { //设置RS232模式 + cfgWrite(hPortHandle, MPIOLVL[num], MPIOLVL232_VAL[num] & v); + } + else if (1 == Mode) + { //设置RS485模式 + cfgWrite(hPortHandle, MPIOLVL[num], MPIOLVL485_VAL[num] | v); + } + } + + /* 函数:ComReset + * 功能:配置COM15/16口进行Reset + * 参数:Mode, 0设置为低电平, 1设置为高电平 + * num, 0为COM15, 1为COM16 + */ + void CComSerialPort::ComReset(HANDLE hPortHandle, unsigned int Mode, unsigned int num) + { + BYTE v ,x; + + cfgRead(hPortHandle, 0X19, &x); + cfgWrite(hPortHandle, 0x19, 0X24); + + cfgRead(hPortHandle, MPIOLVL[num], &v); + if (0 == Mode) // 低电平 + { + //cfgWrite(0x16,MPIOLVL15_VAL[num]);//MPIOSET + //cfgWrite(num,0x16,MPIOLVL15_VAL[num] & v ); + cfgWrite(hPortHandle, 0x16, MPIOLVL15_VAL[num] & v); + } + else if (1 == Mode) // 高电平 + { + //cfgWrite(0x16,MPIOLVL15_VAL[num]); + cfgWrite(hPortHandle, 0x16, MPIOLVL16_VAL[num] | v); + } + + } +#else + +#define FIOQSIZE 0x5460 +#define EXAR_READ_REG (FIOQSIZE+1) +#define EXAR_WRITE_REG (FIOQSIZE+2) + +struct xrioctl_rw_reg +{ + unsigned char reg; + unsigned char regvalue; +}; + + + /****************************************************************************** + * NAME: + * ComModeset + * + * DESCRIPTION: + * RS232/RS485模式切换 + * + * PARAMETERS: + * fd:打开串口设备的文件句柄 + * Mode: 0 RS232 ; 1 RS485 + * num : 0 com15 ; 1 com16 + * RETURN: + * The flag + ******************************************************************************/ + int CComSerialPort::ComModeSet(int fd, unsigned int Mode,unsigned int num) + { + struct xrioctl_rw_reg input,Input; + int set_value=0; + //static int MPIOSEL[] = {0x99,0x99}; + //static int MPIOSEL_VAL[] = {0x6f,0xb7}; + //static int MPIOLVL[] = {0x96,0x96}; + static int MPIOLVL232_VAL[] = {0x6f,0xb7}; + static int MPIOLVL485_VAL[] = {0x96,0x48}; + + Input.reg = 0x99; + Input.regvalue = 0x24; + ioctl(fd, EXAR_WRITE_REG,&Input); + + if((Mode<0)&&(Mode>1)){ + printf("Input error, please input 0 or 1! \n"); + return 0; + } + + if((num<0)&&(num>1)){ + printf("Input error, please input 0 or 1! \n"); + return 0; + } + + + //Set Com RS232 + if(0 == Mode){ + + //Set MPIOLVL[15:8] + input.reg = 0x96; + //printf("reg is %d\n",input.reg); + ioctl(fd, EXAR_READ_REG,&input); + set_value=input.regvalue; + //printf("regvalue1 is %d\n",input.regvalue); + input.regvalue = MPIOLVL232_VAL[num] & set_value; + ioctl(fd, EXAR_WRITE_REG,&input); + //printf("regvalue2 is %d\n",input.regvalue); + + LOGDEBUG("打开串口 RS232模式! mode=%d num=%d", Mode,num); + } + + //Set Com RS485 + if(1 == Mode){ + + //Set MPIOLVL[15:8] + input.reg = 0x96; + ioctl(fd, EXAR_READ_REG,&input); + //printf("reg is %d\n",input.reg); + set_value = input.regvalue; + input.regvalue = MPIOLVL485_VAL[num] | set_value; + ioctl(fd, EXAR_WRITE_REG,&input); + //printf("regvalue is %d\n",input.regvalue); + LOGDEBUG("打开串口 RS485模式! mode=%d num=%d",Mode,num); + } + } + + +#endif + + int CComSerialPort::GetComStatus() + { + if (m_ptrCFesChan != NULL) + return m_ptrCFesChan->GetLinkStatus(); + else + return -1; + } + diff --git a/product/src/fes/protocol/combase/ComTcpClient.cpp b/product/src/fes/protocol/combase/ComTcpClient.cpp index dc282bb5..bbf55328 100644 --- a/product/src/fes/protocol/combase/ComTcpClient.cpp +++ b/product/src/fes/protocol/combase/ComTcpClient.cpp @@ -75,7 +75,7 @@ int CComTcpClient::TcpConnect(CFesChanPtr ptrCFesChan) strcpy(host, ptrCFesChan->m_Param.NetRoute[m_CurRoute].NetDesc); port = ptrCFesChan->m_Param.NetRoute[m_CurRoute].PortNo; - LOGDEBUG("ChanNo=%d Current Route is #%d<%s:%d> \n", ptrCFesChan->m_Param.ChanNo, m_CurRoute, host, port); + //LOGDEBUG("ChanNo=%d Current Route is #%d<%s:%d> \n", ptrCFesChan->m_Param.ChanNo, m_CurRoute, host, port); sin.sin_addr.s_addr = inet_addr(host); if ((int)sin.sin_addr.s_addr == (-1)) @@ -122,7 +122,7 @@ void CComTcpClient::TcpClose(CFesChanPtr ptrCFesChan) if (m_Socket == INVALID_SOCKET) return; - LOGDEBUG("ChanNo=%d TcpClose() m_Socket =%d", ptrCFesChan->m_Param.ChanNo, m_Socket); + //LOGDEBUG("ChanNo=%d TcpClose() m_Socket =%d", ptrCFesChan->m_Param.ChanNo, m_Socket); closesocket(m_Socket); m_Socket = INVALID_SOCKET; @@ -202,7 +202,7 @@ int CComTcpClient::ConnectNonb(CFesChanPtr ptrCFesChan,int sock, const struct so tval.tv_sec = 0; tval.tv_usec = 10 * 1000; readlen = select((int)sock + 1, &fdrSet, NULL, 0, &tval); - if (readlen < 0) + if (readlen < 0) { return -21; } @@ -237,7 +237,17 @@ int CComTcpClient::ConnectNonb(CFesChanPtr ptrCFesChan,int sock, const struct so } } else - LOGDEBUG(" LINUX ConnectNonb Succeed!!"); + { + if(0 == connect(sock, saptr, salen) || errno == EISCONN) //再次connect确认是否连接成功 + { + LOGDEBUG("TcpClientThread.cpp LINUX ConnectNonb Succeed!!"); + } + else + { + LOGDEBUG("TcpClientThread.cpp LINUX ConnectNonb Failed!! errno=%d",errno); + return (-25); + } + } } #endif } diff --git a/product/src/fes/protocol/combase/SerialPortThread.cpp b/product/src/fes/protocol/combase/SerialPortThread.cpp index 68bf4ae0..41fc50e3 100644 --- a/product/src/fes/protocol/combase/SerialPortThread.cpp +++ b/product/src/fes/protocol/combase/SerialPortThread.cpp @@ -542,8 +542,8 @@ void CSerialPortThread::SetChan() SetCommTimeouts(m_devId, &timeouts); SetupComm(m_devId, 1024, 1024); //输入缓冲区和输出缓冲区的大小都是1024 #else - int speed_arr[] = { B115200,B38400,B19200,B9600,B4800,B2400,B1800,B1200,B600,B300,B200 }; - int name_arr[] = { 115200, 38400, 19200, 9600, 4800, 2400, 1800, 1200, 600, 300, 200 }; + int speed_arr[] = { B115200,B57600,B38400,B19200,B9600,B4800,B2400,B1800,B1200,B600,B300,B200 }; + int name_arr[] = { 115200, 57600 ,38400, 19200, 9600, 4800, 2400, 1800, 1200, 600, 300, 200 }; struct termios Opt; int i; diff --git a/product/src/fes/protocol/combase/SnmpUdpClientThread.cpp b/product/src/fes/protocol/combase/SnmpUdpClientThread.cpp index 3c2c1306..5634f84b 100644 --- a/product/src/fes/protocol/combase/SnmpUdpClientThread.cpp +++ b/product/src/fes/protocol/combase/SnmpUdpClientThread.cpp @@ -396,9 +396,6 @@ void CUdpClientThread::RxTxData() void CUdpClientThread::TxData() { int rtn, len ; - fd_set fdwSet; - fd_set fdrSet; - struct timeval tv; unsigned char buff[1024]; int sinlen = sizeof(sockaddr_in); diff --git a/product/src/fes/protocol/combase/TcpClientThread.cpp b/product/src/fes/protocol/combase/TcpClientThread.cpp index 332005cc..db98a82c 100644 --- a/product/src/fes/protocol/combase/TcpClientThread.cpp +++ b/product/src/fes/protocol/combase/TcpClientThread.cpp @@ -267,21 +267,18 @@ int CTcpClientThread::ConnectNonb(int sock, const struct sockaddr *saptr, sockle struct timeval tval; int ret; - int rtn; - fd_set fdrSet; - unsigned char buff[8192]; - int readlen; - - //设置套接字为非阻塞模式 #ifdef OS_WINDOWS u_long argp = 1; if (ioctlsocket(sock, FIONBIO, &argp) == SOCKET_ERROR) #else + int rtn; + fd_set fdrSet; + unsigned char buff[8192]; + int readlen; int flags; flags = fcntl(sock, F_GETFL, 0); if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) //O_NDELAY - #endif { #ifdef OS_WINDOWS @@ -324,7 +321,7 @@ int CTcpClientThread::ConnectNonb(int sock, const struct sockaddr *saptr, sockle tval.tv_sec = 0; tval.tv_usec = 10 * 1000; readlen = select((int)sock + 1, &fdrSet, NULL, 0, &tval); - if (readlen < 0) + if (readlen < 0) { return -21; } @@ -358,8 +355,18 @@ int CTcpClientThread::ConnectNonb(int sock, const struct sockaddr *saptr, sockle return(-24); } } - else - LOGDEBUG("TcpClientThread.cpp LINUX ConnectNonb Succeed!!"); + else + { + if(0 == connect(sock, saptr, salen) || errno == EISCONN) //再次connect确认是否连接成功 + { + LOGDEBUG("TcpClientThread.cpp LINUX ConnectNonb Succeed!!"); + } + else + { + LOGDEBUG("TcpClientThread.cpp LINUX ConnectNonb Failed!! errno=%d",errno); + return (-25); + } + } } #endif } @@ -478,7 +485,7 @@ void CTcpClientThread::RxTxData() } else { - if (FD_ISSET(m_Socket, &fdwSet)) //可写 + if (INVALID_SOCKET != m_Socket && FD_ISSET(m_Socket, &fdwSet)) //可写 { //检测发送队列是否有数据,有则赋值buff,返回长度,不删除队列数据 len = m_ptrCFesChan->ReadTxBufData(8000,&buff[0]); @@ -515,7 +522,7 @@ void CTcpClientThread::RxTxData() } } - if (FD_ISSET(m_Socket, &fdrSet)) //可读 + if (INVALID_SOCKET != m_Socket && FD_ISSET(m_Socket, &fdrSet)) //可读 { len = ::recv(m_Socket , (char *)buff , 8000 , 0); if (len > 0) diff --git a/product/src/fes/protocol/dgls_mqttclient/Dglsmqtts.cpp b/product/src/fes/protocol/dgls_mqttclient/Dglsmqtts.cpp new file mode 100644 index 00000000..055ac9d7 --- /dev/null +++ b/product/src/fes/protocol/dgls_mqttclient/Dglsmqtts.cpp @@ -0,0 +1,486 @@ +/* + @file Dglsmqtts.cpp + @brief Dglsmqtts规约处理主程序 + @author zengrong + @date 2024-03-20 + @history + + */ + + +#include "Dglsmqtts.h" +#include "pub_utility_api/CommonConfigParse.h" + + +using namespace iot_public; + +CDglsmqtts Dglsmqtts; + +bool g_DglsmqttsIsMainFes=false; +bool g_DglsmqttsChanelRun=true; + +int EX_SetBaseAddr(void *address) +{ + Dglsmqtts.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + Dglsmqtts.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + Dglsmqtts.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + Dglsmqtts.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + Dglsmqtts.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + LOGDEBUG("Dgls_mqttclient_s EX_ExitSystem() start"); + g_DglsmqttsChanelRun=false;//使所有的线程退出。 + Dglsmqtts.ExitSystem(flag); + LOGDEBUG("Dgls_mqttclient_s EX_ExitSystem() end"); + return iotSuccess; +} + +CDglsmqtts::CDglsmqtts() +{ + m_ProtocolId = 0; + + + +} + + + +CDglsmqtts::~CDglsmqtts() +{ + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); +} + + +int CDglsmqtts::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + ReadConfigParam(); + } + return iotSuccess; +} + +int CDglsmqtts::SetProperty(int IsMainFes) +{ + g_DglsmqttsIsMainFes = (bool)IsMainFes; + LOGDEBUG("CDglsmqtts::SetProperty g_DglsmqttsIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief CDglsmqtts::OpenChan 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CDglsmqtts::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if ((OpenFlag == CN_FesChanThread_Flag) || (OpenFlag == CN_FesChanAndDataThread_Flag)) + { + switch (ptrFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + case CN_FesTcpServer: + break; + default: + LOGERROR("CDglsmqtts EX_OpenChan() ChanNo:%d CommType=%d is not TCP SERVER/Client!", ptrFesChan->m_Param.ChanNo, ptrFesChan->m_Param.CommType); + return iotFailed; + } + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + CDglsmqttsDataProcThreadPtr ptrCDataProc; + ptrCDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_vecAppParam); + if (ptrCDataProc == NULL) + { + LOGERROR("CDglsmqtts EX_OpenChan() ChanNo:%d create CDglsmqttsDataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + LOGERROR("CDglsmqtts EX_OpenChan() ChanNo:%d create CDglsmqttsDataProcThreadPtr ok!", ptrFesChan->m_Param.ChanNo); + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; +} + +/** + * @brief CDglsmqtts::CloseChan 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CDglsmqtts::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("CDglsmqtts::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + return iotSuccess; +} + +/** + * @brief CDglsmqtts::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int CDglsmqtts::ChanTimer(int MainChanNo) +{ + //把命令缓冲时间间隔到的命放到发送命令缓冲区 + return iotSuccess; +} + +int CDglsmqtts::ExitSystem(int flag) +{ + InformTcpThreadExit(); + return iotSuccess; +} + +void CDglsmqtts::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + CDglsmqttsDataProcThreadPtr ptrTcp; + + if ((tempNum = (int)m_CDataProcQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CDataProcQueue.erase(it);//会调用CDglsmqttsDataProcThread::~CDglsmqttsDataProcThread()退出线程 + LOGDEBUG("CDglsmqtts::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + +/** +* @brief CDglsmqtts::ReadConfigParam +* 读取Dglsmqtts配置文件 +* @return 成功返回iotSuccess,失败返回iotFailed +*/ +int CDglsmqtts::ReadConfigParam() +{ + CCommonConfigParse config; + int ivalue; + std::string strvalue; + char strRtuNo[48]; + SDglsmqttsAppConfigParam param; + int items,i,j; + CFesChanPtr ptrChan; //CHAN数据区 + CFesRtuPtr ptrRTU; + + //memset(¶m, 0, sizeof(SDglsmqttsAppConfigParam)); + + if (m_ptrCFesBase == NULL) + return iotFailed; + + m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"dgls_mqttclient"); + if (m_ProtocolId == -1) + { + LOGDEBUG("ReadConfigParam ProtoclID error"); + return iotFailed; + } + LOGINFO("dgls_mqttclient ProtoclID=%d", m_ProtocolId); + + if (config.load("../../data/fes/", "dgls_mqttclient.xml") == iotFailed) + { + LOGDEBUG("dgls_mqttclient load dgls_mqttclient.xml error"); + return iotSuccess; + } + LOGDEBUG("dgls_mqttclient load dgls_mqttclient.xml ok"); + + for (i = 0; i < m_ptrCFesBase->m_vectCFesChanPtr.size(); i++) + { + ptrChan = m_ptrCFesBase->m_vectCFesChanPtr[i]; + if ((ptrChan->m_Param.Used == 1) && (m_ProtocolId == ptrChan->m_Param.ProtocolId)) + { + //found RTU + for (j = 0; j < m_ptrCFesBase->m_vectCFesRtuPtr.size(); j++) + { + ptrRTU = m_ptrCFesBase->m_vectCFesRtuPtr[j]; + if (ptrRTU->m_Param.Used && (ptrRTU->m_Param.ChanNo == ptrChan->m_Param.ChanNo)) + { + memset(&strRtuNo[0], 0, sizeof(strRtuNo)); + sprintf(strRtuNo, "RTU%d", ptrRTU->m_Param.RtuNo); +// memset(¶m, 0, sizeof(param)); + param.RtuNo = ptrRTU->m_Param.RtuNo; + items = 0; + + if (config.getIntValue(strRtuNo, "startDelay", ivalue) == iotSuccess) + { + param.startDelay = ivalue; + items++; + } + else + param.startDelay = 30;//30s + + if (config.getIntValue(strRtuNo, "ymStartDelay", ivalue) == iotSuccess) + { + param.ymStartDelay = ivalue; + items++; + } + else + param.ymStartDelay = 350; //350s + + if (config.getIntValue(strRtuNo, "max_update_count", ivalue) == iotSuccess) + { + param.maxUpdateCount = ivalue; + items++; + } + else + param.maxUpdateCount = 18; //3MIN + + if (config.getIntValue(strRtuNo, "mqttDelayTime", ivalue) == iotSuccess) + { + param.mqttDelayTime = ivalue; + items++; + } + else + param.mqttDelayTime = 100; + + if (config.getIntValue(strRtuNo, "PasswordFlag", ivalue) == iotSuccess) + { + param.PasswordFlag = ivalue; + items++; + } + else + param.PasswordFlag = 0; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "ClientId", strvalue) == iotSuccess) + { + param.ClientId = strvalue; + items++; + } + else + param.ClientId = "KhMqttClient"; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "UserName", strvalue) == iotSuccess) + { + param.UserName = strvalue; + items++; + } + else + param.UserName.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "Password", strvalue) == iotSuccess) + { + param.Password = strvalue; + items++; + } + else + param.Password.clear(); + + if (config.getIntValue(strRtuNo, "KeepAlive", ivalue) == iotSuccess) + { + param.KeepAlive = ivalue; + items++; + } + else + param.KeepAlive = 180; //心跳检测时间间隔 + + if (config.getIntValue(strRtuNo, "Retain", ivalue) == iotSuccess) + { + param.Retain = (bool)(ivalue & 0x01); + items++; + } + else + param.Retain = false; //默认0 + + if (config.getIntValue(strRtuNo, "QoS", ivalue) == iotSuccess) + { + param.QoS = ivalue; + items++; + } + else + param.QoS = 1; + + if (config.getIntValue(strRtuNo, "WillFlag", ivalue) == iotSuccess) + { + param.WillFlag = ivalue; + items++; + } + else + param.WillFlag = 1; + + if (config.getIntValue(strRtuNo, "WillQos", ivalue) == iotSuccess) + { + param.WillQos = ivalue; + items++; + } + else + param.WillQos = 1; + + if (config.getIntValue(strRtuNo, "sslFlag", ivalue) == iotSuccess) + { + param.sslFlag = ivalue; + items++; + } + else + param.sslFlag = 0; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "tls_version", strvalue) == iotSuccess) + { + param.tls_version = strvalue; + items++; + } + else + param.tls_version = "tlsv1.1"; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "caPath", strvalue) == iotSuccess) + { + param.caPath = strvalue; + items++; + } + else + param.caPath = "../../data/fes/"; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "caFile", strvalue) == iotSuccess) + { + param.caFile = param.caPath + strvalue; + items++; + } + else + param.caFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "certFile", strvalue) == iotSuccess) + { + param.certFile = param.caPath + strvalue; + items++; + } + else + param.certFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "keyFile", strvalue) == iotSuccess) + { + param.keyFile = param.caPath + strvalue; + items++; + } + else + param.keyFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "keyPassword", strvalue) == iotSuccess) + { + param.keyPassword = strvalue; + items++; + } + else + param.keyPassword.clear(); + + if (config.getIntValue(strRtuNo, "CycReadFileTime", ivalue) == iotSuccess) + { + param.CycReadFileTime = ivalue; + items++; + } + else + param.CycReadFileTime = 300; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "AlarmProjectType", strvalue) == iotSuccess) + { + param.AlarmProjectType = strvalue; + items++; + } + else + param.AlarmProjectType.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "AlarmTopic", strvalue) == iotSuccess) + { + param.AlarmTopic = strvalue; + items++; + } + else + param.AlarmTopic.clear(); + + if (items > 0)//对应的RTU有配置项 + { + m_vecAppParam.push_back(param); + } + } + } + } + } + return iotSuccess; +} + +/** + * @brief CDglsmqtts::InformTcpThreadExit + * 设置线程退出标志,通知线程退出 + * @return + */ +void CDglsmqtts::InformTcpThreadExit() +{ + +} diff --git a/product/src/fes/protocol/dgls_mqttclient/Dglsmqtts.h b/product/src/fes/protocol/dgls_mqttclient/Dglsmqtts.h new file mode 100644 index 00000000..234382e5 --- /dev/null +++ b/product/src/fes/protocol/dgls_mqttclient/Dglsmqtts.h @@ -0,0 +1,48 @@ +/* + @file Dglsmqtts.h + @brief Dglsmqtts头文件 + @author zengrong + @date 2024-03-20 +*/ + +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "DglsmqttsDataProcThread.h" + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API CDglsmqtts : public CProtocolBase +{ + +public: + CDglsmqtts(); + ~CDglsmqtts(); + + + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + vector m_CDataProcQueue; + + vector m_vecAppParam; + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + int ExitSystem(int flag); + int ReadConfigParam(); + void InformTcpThreadExit(); +private: + int m_ProtocolId; + void ClearDataProcThreadByChanNo(int ChanNo); +}; + diff --git a/product/src/fes/protocol/dgls_mqttclient/DglsmqttsDataProcThread.cpp b/product/src/fes/protocol/dgls_mqttclient/DglsmqttsDataProcThread.cpp new file mode 100644 index 00000000..63429f23 --- /dev/null +++ b/product/src/fes/protocol/dgls_mqttclient/DglsmqttsDataProcThread.cpp @@ -0,0 +1,1181 @@ +/* + @file CDglsmqttsDataProcThread.cpp + @brief Dglsmqtts 数据处理线程类。 + @author zengrong + @date 2024-03-20 + @history + */ +#include +#include "DglsmqttsDataProcThread.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" +#include +#include + +using namespace iot_public; + +extern bool g_DglsmqttsIsMainFes; +extern bool g_DglsmqttsChanelRun; +const int gDglsmqttsThreadTime = 10; +std::string g_KeyPassword; //私钥密码 + +static int password_callback(char* buf, int size, int rwflag, void* userdata) +{ + memcpy(buf, g_KeyPassword.data(), size); + buf[size - 1] = '\0'; + + return (int)strlen(buf); +} + +CDglsmqttsDataProcThread::CDglsmqttsDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam): + CTimerThreadBase("DglsmqttsDataProcThread", gDglsmqttsThreadTime,0,true) +{ + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + m_pSoeData = NULL; + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + + m_timerCountReset = 10; + m_timerCount = 0; + + publishTime = 0; + memset(&mqttTime, 0, sizeof(MqttPublishTime)); + mqttTime.startTime = getMonotonicMsec() / 1000; + mqttTime.CycTime = getMonotonicMsec() / 1000; + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL)) + { + return; + } + m_ptrCFesChan->SetLinkStatus(CN_FesChanConnect); + m_ptrCFesChan->SetComThreadRunFlag(CN_FesRunFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + //2020-03-03 thxiao 不需要数据变化 + m_ptrCFesRtu->SetFwAiChgStop(1); + m_ptrCFesRtu->SetFwDiChgStop(1); + m_ptrCFesRtu->SetFwDDiChgStop(1); + m_ptrCFesRtu->SetFwMiChgStop(1); + m_ptrCFesRtu->SetFwAccChgStop(1); + + int found = 0; + if(vecAppParam.size()>0) + { + for (size_t i = 0; i < vecAppParam.size(); i++) + { + if(m_ptrCFesRtu->m_Param.RtuNo == vecAppParam[i].RtuNo) + { + //memset(&m_AppData,0,sizeof(SDglsmqttsAppData)); + //配置 + m_AppData.mqttDelayTime = vecAppParam[i].mqttDelayTime; + m_AppData.PasswordFlag = vecAppParam[i].PasswordFlag; + m_AppData.ClientId = vecAppParam[i].ClientId; + m_AppData.UserName = vecAppParam[i].UserName; + m_AppData.Password = vecAppParam[i].Password; + m_AppData.KeepAlive = vecAppParam[i].KeepAlive; + m_AppData.Retain = vecAppParam[i].Retain; + m_AppData.QoS = vecAppParam[i].QoS; + m_AppData.WillFlag = vecAppParam[i].WillFlag; + m_AppData.WillQos = vecAppParam[i].WillQos; + //SSL加密配置 + m_AppData.sslFlag = vecAppParam[i].sslFlag; + m_AppData.tls_version = vecAppParam[i].tls_version; + m_AppData.caPath = vecAppParam[i].caPath; + m_AppData.caFile = vecAppParam[i].caFile; + m_AppData.certFile = vecAppParam[i].certFile; + m_AppData.keyFile = vecAppParam[i].keyFile; + m_AppData.keyPassword = vecAppParam[i].keyPassword; + m_AppData.AlarmProjectType = vecAppParam[i].AlarmProjectType; + m_AppData.AlarmTopic = vecAppParam[i].AlarmTopic; + m_AppData.maxUpdateCount = vecAppParam[i].maxUpdateCount; + m_AppData.startDelay = vecAppParam[i].startDelay; + m_AppData.ymStartDelay = vecAppParam[i].ymStartDelay; + m_AppData.CycReadFileTime = vecAppParam[i].CycReadFileTime; + + found = 1; + break; + } + } + } + if(!found) + InitConfigParam();//配置文件读取失败,取默认配置 + + //读取mqtt_topic_cfg.csv文件,并更新参数 + GetTopicCfg(); + + m_AppData.mqttContFlag = false; + + //告警主题为空,则不发告警数据 + if (m_AppData.AlarmTopic.length() < 1) + { + m_ptrCFesRtu->SetFwSoeChgStop(1); + m_ptrCFesRtu->SetFwDSoeChgStop(1); + } + m_AppData.alarmList.clear(); + GetAlarmCfg(); + + //创建mqttclient对象 + mosqpp::lib_init(); + mqttClient = new mosqpp::mosquittopp(m_AppData.ClientId.data()); +} + +CDglsmqttsDataProcThread::~CDglsmqttsDataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + if(m_pSoeData != NULL) + free(m_pSoeData); + + if (m_AppData.mqttContFlag) + mqttClient->disconnect(); + + //删除MQTT对象 + if(mqttClient) + delete mqttClient; + + ClearTopicStr(); + + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + //LOGDEBUG("CDglsmqttsDataProcThread::~CDglsmqttsDataProcThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); + //LOGDEBUG("CDglsmqttsDataProcThread::~CDglsmqttsDataProcThread() ChanNo=%d 退出",m_ptrCFesChan->m_Param.ChanNo); + //释放mosqpp库 + mosqpp::lib_cleanup(); +} + +/** + * @brief CDglsmqttsDataProcThread::beforeExecute + * + */ + +int CDglsmqttsDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief CDglsmqttsDataProcThread::execute + + */ +void CDglsmqttsDataProcThread::execute() +{ + //读取网络事件 + if(!g_DglsmqttsChanelRun) //收到线程退出标志不再往下执行 + return; + + if (m_timerCount++ >= m_timerCountReset) + m_timerCount = 0;// 1sec is ready + + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + if(m_ptrCurrentChan== NULL) + return; + + //秒级判断流程 + TimerProcess(); + + //mqtt转发流程 + DglsmqttsProcess(); +} + +/* + @brief 执行quit函数前的处理 + */ +void CDglsmqttsDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetComThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetLinkStatus(CN_FesChanDisconnect); + + LOGDEBUG("CDglsmqttsDataProcThread::beforeQuit() "); +} + +/** + * @brief CDglsmqttsDataProcThread::InitConfigParam + * Dglsmqtts 初始化配置参数 + * @return 成功返回iotSuccess,失败返回iotFailed + */ +int CDglsmqttsDataProcThread::InitConfigParam() +{ + if((m_ptrCFesChan == NULL)||(m_ptrCFesRtu==NULL)) + return iotFailed; + + //memset(&m_AppData,0,sizeof(SDglsmqttsAppData)); + m_AppData.mqttDelayTime = 100; + m_AppData.PasswordFlag = 0; + m_AppData.ClientId = "KhMqttClient"; + m_AppData.KeepAlive = 180; + m_AppData.Retain = 0; + m_AppData.QoS = 0; + m_AppData.WillFlag = 0; + m_AppData.WillQos = 0; + + //SSL加密设置 + m_AppData.sslFlag = 0; + + m_AppData.maxUpdateCount = 18; + m_AppData.updateCount = 0; + m_AppData.startDelay = 30; + m_AppData.ymStartDelay = 350; + m_AppData.CycReadFileTime = 300; + + return iotSuccess; +} + +void CDglsmqttsDataProcThread::TimerProcess() +{ + if (m_timerCount == 0)//秒级判断,减少CPU负荷 + { + uint64 curmsec = getMonotonicMsec(); + + //定时更新本FES数据 + if (m_AppData.updateCount < m_AppData.maxUpdateCount) + { + if ((curmsec - m_AppData.lastUpdateTime) > CN_DglsmqttsStartUpateTime)//10s + { + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + m_AppData.updateCount++; + m_AppData.lastUpdateTime = curmsec; + } + } + else + { + if ((curmsec - m_AppData.lastUpdateTime) > CN_DglsmqttsNormalUpateTime)//60s + { + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + m_AppData.lastUpdateTime = curmsec; + } + } + //定时读取遥控命令响应缓冲区,及时清除队列释放空间,不对遥控成败作处理 + if (m_ptrCFesRtu->GetFwDoRespCmdNum() > 0) + { + SFesFwDoRespCmd retCmd; + m_ptrCFesRtu->ReadFwDoRespCmd(1, &retCmd); + } + + if (m_ptrCFesRtu->GetFwAoRespCmdNum() > 0) + { + SFesFwAoRespCmd retCmd; + m_ptrCFesRtu->ReadFwAoRespCmd(1, &retCmd); + } + + //启动主线程判断逻辑 + MainThread(); + } +} + +void CDglsmqttsDataProcThread::DglsmqttsProcess() +{ + //延迟启动MQTT上抛流程 + if (!mqttTime.mqttStartFlag) + return; + + //延时时间未到,不发送数据 + if ((getMonotonicMsec() - publishTime) < (m_AppData.mqttDelayTime/10)) + return; + + //上传SOE + if (m_AppData.AlarmTopic.length() > 0) + SendSoeDataFrame(); + + int i = 0; + for (i = mqttTime.topicIndex; i < m_AppData.sendTopicNum; i++) + { + if (m_AppData.sendTopicStr[i].TopicSendFlag) + { + SendTopicData(i); + m_AppData.sendTopicStr[i].TopicSendFlag = false; + break; + } + } + + //处理MQTT网络事件 + int ret = mqttClient->loop(); + char slog[256]; + memset(slog, 0, 256); + if (ret != MOSQ_ERR_SUCCESS) + { + m_AppData.mqttContFlag = false; + sprintf_s(slog,sizeof(slog),"MQTT %s:%d 连接异常,需要重连!错误代号[%d]", m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo, ret); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("DglsmqttsDataProcThread.cpp ChanNo:%d MQTT %s:%d连接异常,需要重连错误代号[%d]!", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo,ret); + } + + mqttTime.topicIndex = i; + if (mqttTime.topicIndex >= m_AppData.sendTopicNum) + {//一轮topic发送结束 + mqttTime.topicIndex = 0; + mqttTime.mqttSendEndFlag = true; + } + + +// char slog[256]; +// memset(slog, 0, 256); +// sprintf_s(slog, "**topicIndex=%d mqttSendEndFlag=%d mqttContFlag=%d!", mqttTime.topicIndex, mqttTime.mqttSendEndFlag, m_AppData.mqttContFlag); + //ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); +} + +//通过遥信远动号找告警点 +int CDglsmqttsDataProcThread::GetAlarmNo(const int RemoteNo) +{ + for (int i = 0; i < m_AppData.alarmList.size(); i++) + { + if (m_AppData.alarmList[i].yxNo == RemoteNo) + return i; + } + return -1; +} + +//上传SOE +void CDglsmqttsDataProcThread::SendSoeDataFrame() +{ + int i, DiValue; + LOCALTIME SysLocalTime; + SFesFwSoeEvent *pSoeEvent = NULL; + int count, retNum; + std::string jsonStr; + std::string DPTagName; + std::string pName; + std::string devId; + + count = m_ptrCFesRtu->GetFwSOEEventNum(); + if (count == 0) + return; + + //最多一次传100条事件 + if (count > 100) + count = 100; + + if (m_pSoeData == NULL) + m_pSoeData = (SFesFwSoeEvent*)malloc(count * sizeof(SFesFwSoeEvent)); + else + m_pSoeData = (SFesFwSoeEvent*)realloc(m_pSoeData, count * sizeof(SFesFwSoeEvent)); + + retNum = m_ptrCFesRtu->ReadFwSOEEvent(count, m_pSoeData); + jsonStr = "{\"DATATYPE\":\"ALARM_INFO\","; + if(m_AppData.AlarmProjectType.length() > 0) + jsonStr += "\"PROJECTTYPE\":\"" + m_AppData.AlarmProjectType + "\","; + jsonStr += "\"DATA\":["; + count = 0; + char vstr[50]; + int alarmNo = -1; + for (i = 0; i < retNum; i++) + { + pSoeEvent = m_pSoeData + i; + //LOGDEBUG("DglsmqttsDataProcThread.cpp ChanNo:%d SendSoeDataFrame RemoteNo=%d m_MaxFwDiPoints=%d!", m_ptrCFesChan->m_Param.ChanNo, pSoeEvent->RemoteNo, m_ptrCFesRtu->m_MaxFwDiPoints); + if (pSoeEvent->RemoteNo > m_ptrCFesRtu->m_MaxFwDiPoints) + continue; + + //取出告警列表索引 + alarmNo = GetAlarmNo(pSoeEvent->RemoteNo); + if(alarmNo == -1) + continue; + + DiValue = pSoeEvent->Value & 0x01; + SysLocalTime = convertUTCMsecToLocalTime(pSoeEvent->time); //把Soe时间戳转成本地时标 + + //第一个对象前不需要逗号 + if (count != 0) + jsonStr += ","; + jsonStr += "{\"deviceId\":" + to_string(m_AppData.alarmList[alarmNo].devId) + ",\"alarmId\":" + to_string(m_AppData.alarmList[alarmNo].alarmId) + ","; + //加上时标 + memset(vstr, 0, 50); + sprintf_s(vstr, sizeof(vstr),"\"generationDataTime\":\"%04d-%02d-%02d %02d:%02d:%02d\",", SysLocalTime.wYear, SysLocalTime.wMonth, + SysLocalTime.wDay, SysLocalTime.wHour, SysLocalTime.wMinute, SysLocalTime.wSecond); + jsonStr += vstr; + jsonStr += "\"message\":\"" + m_AppData.alarmList[alarmNo].alarmCode + "\","; + if(DiValue) + jsonStr += "\"status\":true}"; + else + jsonStr += "\"status\":false}"; + count++; + } + jsonStr += "]}"; + if (count > 0) + { + //LOGDEBUG("DglsmqttsDataProcThread.cpp ChanNo:%d SendSoeDataFrame AlarmTopic=%s !", m_ptrCFesChan->m_Param.ChanNo, m_AppData.AlarmTopic.data()); + + //将上抛信息传给通道报文显示 + char slog[256]; + memset(slog, 0, 256); + sprintf_s(slog, sizeof(slog),"MQTT Publish:%s, AlarmNum:%d", m_AppData.AlarmTopic.data(), count); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + //上抛数据 + if (MqttPublish(m_AppData.AlarmTopic, jsonStr) == false) + MqttPublish(m_AppData.AlarmTopic, jsonStr);//上抛失败,重新上抛一次 + SleepmSec(m_AppData.mqttDelayTime); + } +} + +void CDglsmqttsDataProcThread::MqttConnect() +{ + int ret = 0; + char slog[256]; + memset(slog, 0, 256); + //已结连接上则不需重连 + if (m_AppData.mqttContFlag) + return; + + //不判断服务器地址 + mqttClient->tls_insecure_set(1); + + //设置SSL加密 + if (m_AppData.sslFlag == 2) //双向加密 + { + //2022-9-21 lj tls_opt_set需要设置为0,即不验证服务器证书,山东海辰服务器的证书有问题,认证不过 + mqttClient->tls_opts_set(0, m_AppData.tls_version.data(), NULL); + if (m_AppData.keyPassword.length() < 1) + mqttClient->tls_set(m_AppData.caFile.data(), m_AppData.caPath.data(), m_AppData.certFile.data(), m_AppData.keyFile.data()); + else + { + //更新私钥的密码 + g_KeyPassword = m_AppData.keyPassword; + mqttClient->tls_set(m_AppData.caFile.data(), m_AppData.caPath.data(), m_AppData.certFile.data(), m_AppData.keyFile.data(), password_callback); + } + LOGDEBUG("DglsmqttsDataProcThread.cpp ChanNo:%d MqttConnect caFile=%s keyPassword=%d!", m_ptrCFesChan->m_Param.ChanNo, m_AppData.caFile.data(), m_AppData.keyPassword.length()); + } + else if (m_AppData.sslFlag == 1) //单向加密 + { + //2022-9-21 lj tls_opt_set需要设置为0,即不验证服务器证书,山东海辰服务器的证书有问题,认证不过 + mqttClient->tls_opts_set(0, m_AppData.tls_version.data(), NULL); + mqttClient->tls_set(m_AppData.caFile.data()); + } + + if (m_AppData.QoS) + mqttClient->message_retry_set(3); + + //设置用户名和密码 + if (m_AppData.PasswordFlag) + mqttClient->username_pw_set(m_AppData.UserName.data(), m_AppData.Password.data()); + + //连接Broker服务器 + //m_ptrCFesChan->m_Param.NetRoute[0].NetDesc localhost + char ServerIp[CN_FesMaxNetDescSize]; //通道IP + memset(ServerIp, 0, CN_FesMaxNetDescSize); + strcpy(ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc); + ret = mqttClient->connect(ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo, m_AppData.KeepAlive);//IP + if (ret != MOSQ_ERR_SUCCESS) + { + m_AppData.mqttContFlag = false; + sprintf_s(slog, sizeof(slog),"MQTT %s:%d 连接失败!", ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("DglsmqttsDataProcThread.cpp ChanNo:%d MQTT %s:%d连接失败!", m_ptrCFesChan->m_Param.ChanNo, ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); + return; + } + + m_AppData.mqttContFlag = true; + sprintf_s(slog, sizeof(slog),"MQTT %s:%d 连接成功!", ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog,CN_SFesSimComFrameTypeSend); + LOGDEBUG("DglsmqttsDataProcThread.cpp ChanNo:%d MQTT %s:%d连接成功!", m_ptrCFesChan->m_Param.ChanNo, ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); +} + +bool CDglsmqttsDataProcThread::MqttPublish(std::string mqttTopic, std::string mqttPayload) +{ + //连接MQTT服务器 + MqttConnect(); + if (!m_AppData.mqttContFlag) + return false; + + //主题和内容为空 + if ((mqttTopic.length() < 1) || (mqttPayload.length() < 1)) + return false; + + char slog[256]; + memset(slog, 0, 256); + + //发布主题数据 + int rc = mqttClient->publish(NULL, mqttTopic.data(), (int)mqttPayload.length(), mqttPayload.data(), m_AppData.QoS, m_AppData.Retain); + if (rc != MOSQ_ERR_SUCCESS) + { + sprintf_s(slog, sizeof(slog),"MQTT 上抛 %s 失败,断开连接!", mqttTopic.data()); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("DglsmqttsDataProcThread.cpp ChanNo:%d %s:%d %s", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo,slog); + mqttClient->disconnect(); + m_AppData.mqttContFlag = false; + return false; + } + + if (m_AppData.WillFlag > 0) + { + mqttClient->will_set(mqttTopic.data(), (int)mqttPayload.length(), mqttPayload.data(), m_AppData.WillQos, m_AppData.Retain); + } + //记下发送时间 单位毫秒 + publishTime = getMonotonicMsec(); + SleepmSec(m_AppData.mqttDelayTime); + return true; +} + +//获取文件MD5 +std::string CDglsmqttsDataProcThread::GetFileMd5(const std::string &file) +{ + ifstream in(file.c_str(), ios::binary); + if (!in) + return ""; + + MD5 md5; + std::streamsize length; + char buffer[1024]; + while (!in.eof()) + { + in.read(buffer, 1024); + length = in.gcount(); + if (length > 0) + md5.update(buffer, length); + } + in.close(); + return md5.toString(); +} + +//获取字符串MD5 +std::string CDglsmqttsDataProcThread::GetStringMd5(const std::string &src_str) +{ + if (src_str.size() < 1) + return ""; + + MD5 md5; + int rsaNum = ((int)src_str.size() + 1023) / 1024; + for (int i = 0; i 0) + md5.update(tmps.c_str(), tmps.size()); + } + return md5.toString(); +} + +//清空topic列表 +void CDglsmqttsDataProcThread::ClearTopicStr() +{ + for (int i = 0; i < MAX_TOPIC_NUM; i++) + { + m_AppData.sendTopicStr[i].jsonTimeList.clear(); + m_AppData.sendTopicStr[i].jsonValueList.clear(); + if (m_AppData.sendTopicStr[i].rootJson != NULL) + { + cJSON_Delete(m_AppData.sendTopicStr[i].rootJson); + m_AppData.sendTopicStr[i].rootJson = NULL; + } + } + //memset(m_AppData.sendTopicStr, 0, sizeof(SEND_TOPIC_STR)*MAX_TOPIC_NUM); +} + +void CDglsmqttsDataProcThread::GetAlarmCfg() +{ + char filename[100]; + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_alarm_cfg%d.csv", m_ptrCFesRtu->m_Param.RtuNo); + char line[1024]; + FILE *fpin; + if ((fpin = fopen(filename, "r")) == NULL) + { + LOGDEBUG("Dgls_mqttclient_s load mqtt_alarm_cfg.csv error"); + return; + } + LOGDEBUG("Dgls_mqttclient_s load mqtt_alarm_cfg.csv ok"); + + if (fgets(line, 1024, fpin) == NULL) + { + fclose(fpin); + return; + } + + //先清空原来的list + m_AppData.alarmList.clear(); + while (fgets(line, 1024, fpin) != NULL) + { + char *token; + token = strtok(line, ","); + int j = 0; + Alarm_Value_Str alarmValStr; + //memset(&alarmValStr,0,sizeof(Alarm_Value_Str)); + while (token != NULL) + { + if (0 == j)//设备ID + { + if (strlen(token) <= 0) + break; + alarmValStr.devId = atoi(token); + } + else if (1 == j)//告警ID + { + if (strlen(token) <= 0) + break; + alarmValStr.alarmId = atoi(token); + } + else if (2 == j)//遥信转发远动号 + { + if (strlen(token) <= 0) + break; + alarmValStr.yxNo = atoi(token); + } + else if (3 == j)//告警描述 + { + if (strlen(token) <= 0) + break; + alarmValStr.alarmCode = GbkToUtf8(token); + m_AppData.alarmList.push_back(alarmValStr); + } + else + break; + token = strtok(NULL, ","); + j++; + } + } + fclose(fpin); +} + +void CDglsmqttsDataProcThread::GetTopicCfg( ) +{ + char filename[100]; + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_topic_cfg%d.csv", m_ptrCFesRtu->m_Param.RtuNo); + char line[1024]; + FILE *fpin; + if ((fpin = fopen(filename, "r")) == NULL) + { + LOGDEBUG("Dgls_mqttclient_s load mqttconfig.csv error"); + return; + } + LOGDEBUG("Dgls_mqttclient_s load mqttconfig.csv ok"); + + if (fgets(line, 1024, fpin) == NULL) + { + fclose(fpin); + return; + } + + //先清空原来的list + ClearTopicStr(); + m_AppData.sendTopicNum = 0; + int topicNum = 0; + while (fgets(line, 1024, fpin) != NULL) + { + char *token; + token = strtok(line, ","); + int j = 0; + while (token != NULL) + { + if (0 == j)//主题 + { + if (strlen(token) <= 0) + break; + //m_AppData.sendTopicStr[topicNum].topic.assign(token); + m_AppData.sendTopicStr[topicNum].topic = token; + } + else if (1 == j)//关联JSON文件名 + { + if (strlen(token) <= 0) + break; + //m_AppData.sendTopicStr[topicNum].jsonFileName.assign(token); + m_AppData.sendTopicStr[topicNum].jsonFileName = token; + } + else if (2 == j)//上传周期 + { + if (strlen(token) <= 0) + break; + m_AppData.sendTopicStr[topicNum].sendTime = atoi(token); + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_topic_cfg%s.csv", m_AppData.sendTopicStr[topicNum].jsonFileName.c_str()); + m_AppData.sendTopicStr[topicNum].fileMd5 = GetFileMd5(filename); + topicNum ++; + } + else + break; + token = strtok(NULL, ","); + j++; + } + + //超过上限的不处理 + if (topicNum >= MAX_TOPIC_NUM) + { + topicNum = MAX_TOPIC_NUM; + break; + } + } + fclose(fpin); + m_AppData.sendTopicNum = topicNum; + + //读取Topic关联的JSON文件 + ReadTopic(); +} + +void CDglsmqttsDataProcThread::ReadTopic() +{ + std::string jsonStr; + char filename[100]; + for (int i = 0; i < m_AppData.sendTopicNum; i++) + { + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/%s", m_AppData.sendTopicStr[i].jsonFileName.c_str()); + + //计算文件MD5 + m_AppData.sendTopicStr[i].fileMd5 = GetFileMd5(filename); + + //读取JSON文件 + if (ReadJson(filename, jsonStr)) + { + //如果之前有读过JSON文件则释放内存空间 + if (m_AppData.sendTopicStr[i].rootJson != NULL) + { + cJSON_Delete(m_AppData.sendTopicStr[i].rootJson); + m_AppData.sendTopicStr[i].rootJson = NULL; + } + //这里会申请一片新的内存,用完记得释放 + m_AppData.sendTopicStr[i].rootJson = cJSON_Parse(jsonStr.c_str()); + m_AppData.sendTopicStr[i].JsonUpdataFlag = true; + m_AppData.sendTopicStr[i].TopicSendFlag = true; + } + } +} + +bool CDglsmqttsDataProcThread::ReadJson(const char *fileName, std::string &outStr) +{ + char slog[256]; + memset(slog, 0, 256); + ifstream ifile(fileName); + if (!ifile.is_open()) + { + sprintf_s(slog, sizeof(slog),"%s打开失败!请检查文件是否存在!", fileName); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + return false; + } + ostringstream buf; + char ch; + while (buf && ifile.get(ch)) + { + if ((ch != '\n') && (ch != '\t') && (ch != '\0')) + buf.put(ch); + } + outStr = buf.str(); + ifile.close(); + + int strLen = (int)outStr.size(); + if (strLen < 1) + return false; + + return true; +} + +//分割字符串 +int CDglsmqttsDataProcThread::StringSplit(std::vector &dst, const std::string &src, const std::string separator) +{ + if (src.empty() || separator.empty()) + return 0; + + int nCount = 0; + std::string temp; + size_t pos = 0, offset = 0; + + //分割第1~n-1个 + while ((pos = src.find_first_of(separator, offset)) != std::string::npos) + { + temp = src.substr(offset, pos - offset); + if (temp.length() > 0) + { + dst.push_back(temp); + nCount++; + } + offset = pos + 1; + } + + //分割第n个 + temp = src.substr(offset, src.length() - offset); + if (temp.length() > 0) + { + dst.push_back(temp); + nCount++; + } + return nCount; +} + +void CDglsmqttsDataProcThread::SendTopicData(const int topicNo) +{ + if (m_AppData.sendTopicStr[topicNo].rootJson != NULL) + { + //JSON文件有更新,重新解析JSON文件 + if (m_AppData.sendTopicStr[topicNo].JsonUpdataFlag) + { + m_AppData.sendTopicStr[topicNo].jsonValueList.clear(); + m_AppData.sendTopicStr[topicNo].jsonTimeList.clear(); + AnalyzeJson(m_AppData.sendTopicStr[topicNo].rootJson, m_AppData.sendTopicStr[topicNo].jsonValueList, m_AppData.sendTopicStr[topicNo].jsonTimeList); + m_AppData.sendTopicStr[topicNo].JsonUpdataFlag = false; + } + + //更新JSON中的值 + UpdataJsonValue(topicNo); + //更新JSON中的时间 + UpdataJsonTime(topicNo); + + //发送数据 + SendJsonData(topicNo, m_AppData.sendTopicStr[topicNo].rootJson); + } +} + +//解析JSON +void CDglsmqttsDataProcThread::AnalyzeJson(cJSON *root, Json_Value_List &jsonValList, Json_Time_List &jsonTimeList) +{ + int i; + for (i = 0; itype == cJSON_Object) //对象 + { + AnalyzeJson(item, jsonValList, jsonTimeList); + } + else if (item->type == cJSON_Array) //数组 + { + AnalyzeJson(item, jsonValList, jsonTimeList); + } + else + { + if (item->type != cJSON_String) + continue; + + if (strstr(item->valuestring, "Value")) + { + //取出点地址配置 + std::string paddr = item->valuestring; + std::vector paddrList; + int pNum = StringSplit(paddrList, paddr, ","); + //点地址格式"Data,数据类型,点类型,点号" + if (pNum == 4) + { + Json_Value_Str jsonValStr; + jsonValStr.item = item; + jsonValStr.DataType = paddrList[1].data(); + jsonValStr.pType = atoi(paddrList[2].data()); + jsonValStr.pNo = atoi(paddrList[3].data()); + + //类型正确 + if ((jsonValStr.pType > 0) && (jsonValStr.pType <= 4)) + jsonValList.push_back(jsonValStr); + else //取值地址配置错误时,该点置空值,避免上传错误的数据 + item->type = cJSON_NULL; + } + else //取值地址配置错误时,该点置空值,避免上传错误的数据 + item->type = cJSON_NULL; + } +// if(item->type == cJSON_Object) //对象 +// { +// AnalyzeJson(item, jsonValList, jsonTimeList); +// } + else if (strstr(item->valuestring, "Time")) + { + Json_Time_Str jsonTime; + jsonTime.item = item; + jsonTimeList.push_back(jsonTime); + } + } + } +} + +bool CDglsmqttsDataProcThread::UpdataJsonValue(const int topicNo) +{ + if (m_AppData.sendTopicStr[topicNo].jsonValueList.size() < 1) + return false; + + double fvalue; + int pNo, pType; + std::string DataType; + char vstr[50]; + unsigned char yxbit; + cJSON* item = NULL; //节点指针 + SFesFwAi *pFwAi; + SFesFwAcc *pFwAcc; + SFesFwDi *pFwDi; + SFesFwMi *pFwMi; + for (int i = 0; i < m_AppData.sendTopicStr[topicNo].jsonValueList.size(); i++) + { + Json_Value_Str jsonValStr = m_AppData.sendTopicStr[topicNo].jsonValueList[i]; + pType = jsonValStr.pType; + pNo = jsonValStr.pNo; + item = jsonValStr.item; + DataType = jsonValStr.DataType; + if (item == NULL) + continue; + switch (pType) + { + case 1://遥测 + pFwAi = m_ptrCFesRtu->m_pFwAi + pNo; + fvalue = pFwAi->Value*pFwAi->Coeff + pFwAi->Base; + //去掉多余的小数点位,只保留3位小数 + memset(vstr, 0, 50); + sprintf(vstr, "%.3f", fvalue); + fvalue = atof(vstr); + if (DataType == "string") + { + cJSON_free(item->valuestring); + item->valuestring = strdup(vstr); + } + else + { + item->type = cJSON_Number; + item->valuedouble = fvalue; + item->valueint = (int)fvalue; + } + break; + case 2://遥信 + pFwDi = m_ptrCFesRtu->m_pFwDi + pNo; + yxbit = pFwDi->Value & 0x01; + if (DataType == "string") + { + memset(vstr, 0, 50); + sprintf(vstr, "%d", yxbit); + cJSON_free(item->valuestring); + item->valuestring = strdup(vstr); + } + else if (DataType == "bool") + { + if (yxbit) + item->type = cJSON_True; + else + item->type = cJSON_False; + } + else + { + item->type = cJSON_Number; + item->valuedouble = yxbit; + item->valueint = yxbit; + } + break; + case 3://遥脉 + //遥脉5分钟才采集一次,未采集时遥脉值为0,避免上传0值给平台,需要延时上传 + if (!mqttTime.ymStartFlag) + { + item->type = cJSON_NULL; + break; + } + + pFwAcc = m_ptrCFesRtu->m_pFwAcc + pNo; + fvalue = pFwAcc->Value*pFwAcc->Coeff + pFwAcc->Base; + //去掉多余的小数点位,只保留3位小数 + memset(vstr, 0, 50); + sprintf(vstr, "%.3f", fvalue); + fvalue = atof(vstr); + if (DataType == "string") + { + cJSON_free(item->valuestring); + item->valuestring = strdup(vstr); + } + else + { + item->type = cJSON_Number; + item->valuedouble = fvalue; + item->valueint = (int)fvalue; + } + break; + case 4://混合 + pFwMi = m_ptrCFesRtu->m_pFwMi + pNo; + fvalue = pFwMi->Value*pFwMi->Coeff + pFwMi->Base; + memset(vstr, 0, 50); + sprintf(vstr, "%.3f", fvalue); + fvalue = atof(vstr); + if (DataType == "string") + { + cJSON_free(item->valuestring); + item->valuestring = strdup(vstr); + } + else + { + item->type = cJSON_Number; + item->valuedouble = fvalue; + item->valueint = (int)fvalue; + } + break; + default: + item->type = cJSON_NULL; + break; + } + } + return true; +} + +bool CDglsmqttsDataProcThread::UpdataJsonTime(const int topicNo) +{ + if (m_AppData.sendTopicStr[topicNo].jsonTimeList.size() < 1) + return false; + + cJSON* item = NULL; //节点指针 + //windows-api + //SYSTEMTIME st = { 0 }; + //GetLocalTime(&st); + time_t currentTime = time(nullptr); // 获取当前时间 + struct tm* st = localtime(¤tTime); // 转换为本地时间 + char time[40]; + memset(time, 0, 40); + //sprintf(time, "%04d-%02d-%02d %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + sprintf(time, "%04d-%02d-%02d %02d:%02d:%02d", st->tm_year+1900, st->tm_mon+1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec); + + for (int i = 0; i < m_AppData.sendTopicStr[topicNo].jsonTimeList.size(); i++) + { + Json_Time_Str jsonTimeStr = m_AppData.sendTopicStr[topicNo].jsonTimeList[i]; + item = jsonTimeStr.item; + if (item == NULL) + continue; + + cJSON_free(item->valuestring); + item->valuestring = strdup(time); + } + return true; +} + +void CDglsmqttsDataProcThread::MainThread() +{ + char fileName[100]; + std::string md5Str; + //系统启动后的运行的秒数 + int64 cursec = getMonotonicMsec() / 1000; + + if (m_AppData.startDelay > 0)//2021-05-06 thxiao 增加延时起动 + { + if ((cursec - mqttTime.startTime) < m_AppData.startDelay) + mqttTime.mqttStartFlag = false; + else + mqttTime.mqttStartFlag = true; + } + else + mqttTime.mqttStartFlag = true; + + if (m_AppData.ymStartDelay > 0) + { + if ((cursec - mqttTime.startTime) < m_AppData.ymStartDelay) + mqttTime.ymStartFlag = false; + else + mqttTime.ymStartFlag = true; + } + else + mqttTime.ymStartFlag = true; + + //周期检查文件是否修改 + if ((cursec - mqttTime.CycTime) > m_AppData.CycReadFileTime) + { + mqttTime.CycTime = cursec; + + //配置参数修改后,需要在线更新 + memset(fileName, 0, 100); + sprintf(fileName, "../../data/fes/mqtt_topic_cfg%d.csv", m_ptrCFesRtu->m_Param.RtuNo); + md5Str = GetFileMd5(fileName); + if (md5Str != m_AppData.TopicCfgMd5) + { + m_AppData.TopicCfgMd5 = md5Str; + //读取mqtt_topic_cfg.csv文件,并更新参数 + GetTopicCfg(); + } + } + //检查各个Topic的发送周期是否到了 + for (int i = 0; i < m_AppData.sendTopicNum; i++) + { + if (m_AppData.sendTopicStr[i].sendTime > 0) + { + //上传周期到,置上发送标志 + if (((cursec - m_AppData.sendTopicStr[i].TopicSendTime) >= m_AppData.sendTopicStr[i].sendTime) + && (m_AppData.sendTopicStr[i].rootJson != NULL)) + { + m_AppData.sendTopicStr[i].TopicSendTime = cursec; + m_AppData.sendTopicStr[i].TopicSendFlag = true; + } + } + } + + //一轮上抛完毕,关闭连接 + if (mqttTime.mqttSendEndFlag && m_AppData.mqttContFlag) + { + char slog[256]; + memset(slog, 0, 256); + //mqttClient->disconnect(); + //m_AppData.mqttContFlag = false; + mqttTime.mqttSendEndFlag = false; + sprintf_s(slog, sizeof(slog),"MQTT 一轮上抛完毕!"); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("DglsmqttsDataProcThread.cpp ChanNo:%d %s:%d %s", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo, slog); + } +} + +void CDglsmqttsDataProcThread::SendJsonData(const int topicNo,cJSON *rootJson) +{ + std::string jsonStr; + int i, j; + bool sendFlag = false; + //将JSON打印成字符串,此处会申请内存,使用完毕注意释放 + char* pStr = NULL; + pStr = cJSON_Print(rootJson); + if (pStr == NULL) + return; + + //去掉JSON中的TAB缩进符和换行符 + for (i = j = 0; im_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + +} + + + + + +//GBK转化为UTF8格式 +std::string CDglsmqttsDataProcThread::GbkToUtf8(std::string src_str) +{ + return boost::locale::conv::to_utf(src_str,std::string("gb2312")); +} + +// UTF-8转为GBK2312 +std::string CDglsmqttsDataProcThread::Utf8ToGbk(std::string src_str) +{ + return boost::locale::conv::from_utf(src_str,std::string("gb2312")); +} + + + + + diff --git a/product/src/fes/protocol/dgls_mqttclient/DglsmqttsDataProcThread.h b/product/src/fes/protocol/dgls_mqttclient/DglsmqttsDataProcThread.h new file mode 100644 index 00000000..44b547da --- /dev/null +++ b/product/src/fes/protocol/dgls_mqttclient/DglsmqttsDataProcThread.h @@ -0,0 +1,234 @@ +/* + @file CDglsmqttsDataProcThread.h + @brief Dglsmqtts 数据处理线程类。 + @author zengrong + @date 2024-03-20 +*/ +#pragma once + +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "mosquitto.h" +#include "mosquittopp.h" +#include "cJSON.h" +#include "Md5/Md5.h" +using namespace iot_public; + + +const int CN_DglsmqttsStartUpateTime = 10000;//10s +const int CN_DglsmqttsNormalUpateTime = 60000;//60s + + + +#define MAX_TOPIC_NUM 1000 + +typedef struct +{ + int devId; //设备ID + int alarmId; //告警ID + int yxNo; //遥信转发远动号 + std::string alarmCode; //告警描述 +}Alarm_Value_Str; + +typedef struct +{ + int pNo; //点号 + int pType; //点类型 1-YC 2-YX 3-YM 4-混合 + std::string DataType; //数据类型 + cJSON* item; //节点指针 +}Json_Value_Str; + +typedef struct +{ + cJSON* item; //节点指针 +}Json_Time_Str; + +typedef std::vector Json_Value_List; +typedef std::vector Json_Time_List; +typedef std::vector Alarm_Value_List; + +typedef struct +{ + cJSON *rootJson; //cJson指针,保存解析后的JSON文件内容 + int64 TopicSendTime; //主题发送时间,用于判断是否需要发送 + bool JsonUpdataFlag; //JSON文件更新标志 + bool TopicSendFlag; //发送标志 + + int sendTime; //上传周期,单位秒,0表示启动上传一次,后面变化上传,大于1的值表示间隔多少秒上传 + std::string topic; //topic + std::string jsonFileName; //JSON文件名 + std::string fileMd5; //文件MD5,用于判断文件内容是否改变 + + //值 + Json_Value_List jsonValueList; + //时标 + Json_Time_List jsonTimeList; +}SEND_TOPIC_STR; + + +typedef struct{ + int RtuNo; + int mqttDelayTime; //每个主题上抛延时,单位毫秒 + int CycReadFileTime; //周期检查文件的时间,单位秒 + + int PasswordFlag; //是否启用密码 0不启用 1启用 默认0 + std::string ClientId; //客户端ID + std::string UserName; //用户名 + std::string Password; //密码 + + int KeepAlive; //心跳检测时间间隔 + bool Retain; //MQTT服务器是否保持消息 默认0 + int QoS; //服务质量 默认1 + int WillFlag; //遗愿消息标志 默认1 + int WillQos; //遗愿消息服务质量 默认1 + + //SSL加密配置参数 + int sslFlag; //SSL加密标志 0不加密 1单向加密 2双向加密 + std::string tls_version; //加密协议版本 + std::string caPath; //加密文件路径 + std::string caFile; //CA文件名 + std::string certFile; //证书文件名 + std::string keyFile; //私钥文件名 + std::string keyPassword; //私钥密码 + + std::string AlarmProjectType; //告警数据项目类型 + std::string AlarmTopic; //告警数据主题 + + int maxUpdateCount; //系统启动前,本FES数据每10S跟新一次全数据,直到该值到到达最大值,变为60S跟新全数据。 + int startDelay; //系统启动延时,单位秒 + int ymStartDelay; //遥脉启动延时,单位秒 +}SDglsmqttsAppConfigParam; + +//Dglsmqtts 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct{ + //配置参数 + int RtuNo; + int64 startDelay; + int64 ymStartDelay; //遥脉启动延时,单位秒 + int CycReadFileTime; //周期检查文件的时间,单位秒 + int maxUpdateCount; + int updateCount; //系统启动前,本FES数据没10S跟新一次全数据,直到该值到到达最大值,变为60S跟新全数据。 + + uint64 updateTime; + uint64 lastUpdateTime; + bool mqttContFlag; + + int mqttDelayTime; //每个主题上抛延时,单位毫秒 + int PasswordFlag; //是否启用密码 0不启用 1启用 默认0 + std::string ClientId; //客户端ID + std::string UserName; //用户名 + std::string Password; //密码 + + std::string AlarmProjectType; //告警数据项目类型 + std::string AlarmTopic; //告警数据主题 + + int KeepAlive; //心跳检测时间间隔 + bool Retain; //MQTT服务器是否保持消息 默认0 + int QoS; //品质 默认1 + int WillFlag; //遗愿消息标志 默认1 + int WillQos; //遗愿消息品质 默认1 + + //SSL加密配置参数 + int sslFlag; //SSL加密标志 0不加密 1单向加密 2双向加密 + std::string tls_version; //加密协议版本 + std::string caPath; //文件路径 + std::string caFile; //CA文件名 + std::string certFile; //证书文件名 + std::string keyFile; //私钥文件名 + std::string keyPassword; //私钥密码 + + //mqtt_topic_cfg文件MD5 + std::string TopicCfgMd5; + + //主题列表 + SEND_TOPIC_STR sendTopicStr[MAX_TOPIC_NUM]; + int sendTopicNum; + + //告警列表 + Alarm_Value_List alarmList; +}SDglsmqttsAppData; + +typedef struct { + int64 startTime; //系统启动时间 + int64 CycTime; //周期检查文件时间 + int topicIndex; //已上抛主题索引 + bool mqttStartFlag; + bool ymStartFlag; //遥脉启动转发标志 + bool mqttSendEndFlag; //Mqtt发送结束标志 +}MqttPublishTime; + +class CDglsmqttsDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + CDglsmqttsDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam); + virtual ~CDglsmqttsDataProcThread(); + + + + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + CFesBase* m_ptrCFesBase; + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,Dglsmqtts tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SDglsmqttsAppData m_AppData; //内部应用数据结构 + SFesFwSoeEvent *m_pSoeData; + + MqttPublishTime mqttTime; //MQTT上抛时间管理 + mosqpp::mosquittopp *mqttClient; //MQTT句柄 +private: + int m_timerCount; + int m_timerCountReset; + + int InitConfigParam(); + + void TimerProcess(); + void DglsmqttsProcess(); + + void SendSoeDataFrame(); + int64 publishTime; + + void MqttConnect(); + bool MqttPublish(std::string mqttTopic, std::string mqttPayload); + void GetTopicCfg(); + void ReadTopic(); + //获取MD5 + std::string GetFileMd5(const std::string &file); + std::string GetStringMd5(const std::string &src_str); + + //分割字符串 + int StringSplit(std::vector &dst, const std::string &src, const std::string separator); + + //解析JSON + bool ReadJson(const char *fileName, std::string &outStr); + void AnalyzeJson(cJSON *root, Json_Value_List &jsonValList, Json_Time_List &jsonTimeList); + bool UpdataJsonValue(const int topicNo); + bool UpdataJsonTime(const int topicNo); + + void SendTopicData(const int topicNo); + void SendJsonData(const int topicNo, cJSON *rootJson); + + //主线程 + void MainThread(); + void ClearTopicStr(); + + //获取告警配置 + void GetAlarmCfg(); + int GetAlarmNo(const int RemoteNo); + + std::string GbkToUtf8(std::string src_str); + std::string Utf8ToGbk(std::string src_str); +}; + +typedef boost::shared_ptr CDglsmqttsDataProcThreadPtr; diff --git a/product/src/fes/protocol/dgls_mqttclient/Md5/Md5.cpp b/product/src/fes/protocol/dgls_mqttclient/Md5/Md5.cpp new file mode 100644 index 00000000..c6664c5e --- /dev/null +++ b/product/src/fes/protocol/dgls_mqttclient/Md5/Md5.cpp @@ -0,0 +1,372 @@ +#include "Md5.h" + +//using namespace std; + +/* Constants for MD5Transform routine. */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + + +/* F, G, H and I are basic MD5 functions. +*/ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. +*/ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. +*/ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} + + +const byte MD5::PADDING[64] = { 0x80 }; +const char MD5::HEX[16] = +{ + '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f' +}; + +/* Default construct. */ +MD5::MD5() +{ + + reset(); +} + +/* Construct a MD5 object with a input buffer. */ +MD5::MD5(const void *input, size_t length) +{ + reset(); + update(input, length); +} + +/* Construct a MD5 object with a string. */ +MD5::MD5(const string &str) +{ + reset(); + update(str); +} + +/* Construct a MD5 object with a file. */ +MD5::MD5(ifstream &in) +{ + reset(); + update(in); +} + +/* Return the message-digest */ +const byte *MD5::digest() +{ + if (!_finished) + { + _finished = true; + final(); + } + return _digest; +} + +/* Reset the calculate state */ +void MD5::reset() +{ + + _finished = false; + /* reset number of bits. */ + _count[0] = _count[1] = 0; + /* Load magic initialization constants. */ + _state[0] = 0x67452301; + _state[1] = 0xefcdab89; + _state[2] = 0x98badcfe; + _state[3] = 0x10325476; +} + +/* Updating the context with a input buffer. */ +void MD5::update(const void *input, size_t length) +{ + update((const byte *)input, length); +} + +/* Updating the context with a string. */ +void MD5::update(const string &str) +{ + update((const byte *)str.c_str(), str.length()); +} + +/* Updating the context with a file. */ +void MD5::update(ifstream &in) +{ + + if (!in) + { + return; + } + + const size_t BUFFER_SIZE = 1024; + std::streamsize length; + char buffer[BUFFER_SIZE]; + while (!in.eof()) + { + in.read(buffer, BUFFER_SIZE); + length = in.gcount(); + if (length > 0) + { + update(buffer, length); + } + } + in.close(); +} + +/* MD5 block update operation. Continues an MD5 message-digest +operation, processing another message block, and updating the +context. +*/ +void MD5::update(const byte *input, size_t length) +{ + + uint32 i, index, partLen; + + _finished = false; + + /* Compute number of bytes mod 64 */ + index = (uint32)((_count[0] >> 3) & 0x3f); + + /* update number of bits */ + if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) + { + _count[1]++; + } + _count[1] += ((uint32)length >> 29); + + partLen = 64 - index; + + /* transform as many times as possible. */ + if (length >= partLen) + { + + memcpy(&_buffer[index], input, partLen); + transform(_buffer); + + for (i = partLen; i + 63 < length; i += 64) + { + transform(&input[i]); + } + index = 0; + + } + else + { + i = 0; + } + + /* Buffer remaining input */ + memcpy(&_buffer[index], &input[i], length - i); +} + +/* MD5 finalization. Ends an MD5 message-_digest operation, writing the +the message _digest and zeroizing the context. +*/ +void MD5::final() +{ + + byte bits[8]; + uint32 oldState[4]; + uint32 oldCount[2]; + uint32 index, padLen; + + /* Save current state and count. */ + memcpy(oldState, _state, 16); + memcpy(oldCount, _count, 8); + + /* Save number of bits */ + encode(_count, bits, 8); + + /* Pad out to 56 mod 64. */ + index = (uint32)((_count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + update(PADDING, padLen); + + /* Append length (before padding) */ + update(bits, 8); + + /* Store state in digest */ + encode(_state, _digest, 16); + + /* Restore current state and count. */ + memcpy(_state, oldState, 16); + memcpy(_count, oldCount, 8); +} + +/* MD5 basic transformation. Transforms _state based on block. */ +void MD5::transform(const byte block[64]) +{ + + uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16]; + + decode(block, x, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + _state[0] += a; + _state[1] += b; + _state[2] += c; + _state[3] += d; +} + +/* Encodes input (ulong) into output (byte). Assumes length is +a multiple of 4. +*/ +void MD5::encode(const uint32 *input, byte *output, size_t length) +{ + + for (size_t i = 0, j = 0; j < length; i++, j += 4) + { + output[j] = (byte)(input[i] & 0xff); + output[j + 1] = (byte)((input[i] >> 8) & 0xff); + output[j + 2] = (byte)((input[i] >> 16) & 0xff); + output[j + 3] = (byte)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (byte) into output (ulong). Assumes length is +a multiple of 4. +*/ +void MD5::decode(const byte *input, uint32 *output, size_t length) +{ + + for (size_t i = 0, j = 0; j < length; i++, j += 4) + { + output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) | + (((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24); + } +} + +/* Convert byte array to hex string. */ +string MD5::bytesToHexString(const byte *input, size_t length) +{ + string str; + str.reserve(length << 1); + for (size_t i = 0; i < length; i++) + { + int t = input[i]; + int a = t / 16; + int b = t % 16; + str.append(1, HEX[a]); + str.append(1, HEX[b]); + } + return str; +} + +/* Convert digest to string value */ +string MD5::toString() +{ + return bytesToHexString(digest(), 16); +} diff --git a/product/src/fes/protocol/dgls_mqttclient/Md5/Md5.h b/product/src/fes/protocol/dgls_mqttclient/Md5/Md5.h new file mode 100644 index 00000000..826a9cf1 --- /dev/null +++ b/product/src/fes/protocol/dgls_mqttclient/Md5/Md5.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include + +/* Type define */ +typedef unsigned char byte; +typedef unsigned int uint32; + +using std::string; +using std::ifstream; + +/* MD5 declaration. */ +class MD5 +{ +public: + MD5(); + MD5(const void *input, size_t length); + MD5(const string &str); + MD5(ifstream &in); + void update(const void *input, size_t length); + void update(const string &str); + void update(ifstream &in); + const byte *digest(); + string toString(); + void reset(); +private: + void update(const byte *input, size_t length); + void final(); + void transform(const byte block[64]); + void encode(const uint32 *input, byte *output, size_t length); + void decode(const byte *input, uint32 *output, size_t length); + string bytesToHexString(const byte *input, size_t length); + + /* class uncopyable */ + MD5(const MD5 &); + MD5 &operator=(const MD5 &); +private: + uint32 _state[4]; /* state (ABCD) */ + uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */ + byte _buffer[64]; /* input buffer */ + byte _digest[16]; /* message digest */ + bool _finished; /* calculate finished ? */ + + static const byte PADDING[64]; /* padding for calculate */ + static const char HEX[16]; + static const size_t BUFFER_SIZE; + +}; diff --git a/product/src/fes/protocol/dgls_mqttclient/cJSON.c b/product/src/fes/protocol/dgls_mqttclient/cJSON.c new file mode 100644 index 00000000..ffe6d313 --- /dev/null +++ b/product/src/fes/protocol/dgls_mqttclient/cJSON.c @@ -0,0 +1,3100 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +/* disable warnings about old C89 functions in MSVC */ +#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +#define _CRT_SECURE_NO_DEPRECATE +#endif + +#ifdef __GNUC__ +#pragma GCC visibility push(default) +#endif +#if defined(_MSC_VER) +#pragma warning (push) +/* disable warning about single line comments in system headers */ +#pragma warning (disable : 4001) +#endif +#include +#include +#include +#include +#include +#include +#include + +#ifdef ENABLE_LOCALES +#include +#endif + +#if defined(_MSC_VER) +#pragma warning (pop) +#endif +#ifdef __GNUC__ +#pragma GCC visibility pop +#endif + +#include "cJSON.h" + +/* define our own boolean type */ +#ifdef true +#undef true +#endif +#define true ((cJSON_bool)1) + +#ifdef false +#undef false +#endif +#define false ((cJSON_bool)0) + +/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */ +#ifndef isinf +#define isinf(d) (isnan((d - d)) && !isnan(d)) +#endif +#ifndef isnan +#define isnan(d) (d != d) +#endif + +#ifndef _HUGE_ENUF + #define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow +#endif + +#define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) +#ifndef NAN +#define NAN ((float)(INFINITY * 0.0F))//sqrt(-1.0f)//0.0/0.0 +#endif + +typedef struct { + const unsigned char *json; + size_t position; +} error; +static error global_error = { NULL, 0 }; + +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) +{ + return (const char*) (global_error.json + global_error.position); +} + +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) +{ + if (!cJSON_IsString(item)) + { + return NULL; + } + + return item->valuestring; +} + +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) +{ + if (!cJSON_IsNumber(item)) + { + return (double) NAN; + } + + return item->valuedouble; +} + +/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ +#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 13) + #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. +#endif + +CJSON_PUBLIC(const char*) cJSON_Version(void) +{ + static char version[15]; + sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); + + return version; +} + +/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ +static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2) +{ + if ((string1 == NULL) || (string2 == NULL)) + { + return 1; + } + + if (string1 == string2) + { + return 0; + } + + for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) + { + if (*string1 == '\0') + { + return 0; + } + } + + return tolower(*string1) - tolower(*string2); +} + +typedef struct internal_hooks +{ + void *(CJSON_CDECL *allocate)(size_t size); + void (CJSON_CDECL *deallocate)(void *pointer); + void *(CJSON_CDECL *reallocate)(void *pointer, size_t size); +} internal_hooks; + +#if defined(_MSC_VER) +/* work around MSVC error C2322: '...' address of dllimport '...' is not static */ +static void * CJSON_CDECL internal_malloc(size_t size) +{ + return malloc(size); +} +static void CJSON_CDECL internal_free(void *pointer) +{ + free(pointer); +} +static void * CJSON_CDECL internal_realloc(void *pointer, size_t size) +{ + return realloc(pointer, size); +} +#else +#define internal_malloc malloc +#define internal_free free +#define internal_realloc realloc +#endif + +/* strlen of character literals resolved at compile time */ +#define static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) + +static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; + +static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks) +{ + size_t length = 0; + unsigned char *copy = NULL; + + if (string == NULL) + { + return NULL; + } + + length = strlen((const char*)string) + sizeof(""); + copy = (unsigned char*)hooks->allocate(length); + if (copy == NULL) + { + return NULL; + } + memcpy(copy, string, length); + + return copy; +} + +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (hooks == NULL) + { + /* Reset hooks */ + global_hooks.allocate = malloc; + global_hooks.deallocate = free; + global_hooks.reallocate = realloc; + return; + } + + global_hooks.allocate = malloc; + if (hooks->malloc_fn != NULL) + { + global_hooks.allocate = hooks->malloc_fn; + } + + global_hooks.deallocate = free; + if (hooks->free_fn != NULL) + { + global_hooks.deallocate = hooks->free_fn; + } + + /* use realloc only if both free and malloc are used */ + global_hooks.reallocate = NULL; + if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free)) + { + global_hooks.reallocate = realloc; + } +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(const internal_hooks * const hooks) +{ + cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON)); + if (node) + { + memset(node, '\0', sizeof(cJSON)); + } + + return node; +} + +/* Delete a cJSON structure. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) +{ + cJSON *next = NULL; + while (item != NULL) + { + next = item->next; + if (!(item->type & cJSON_IsReference) && (item->child != NULL)) + { + cJSON_Delete(item->child); + } + if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) + { + global_hooks.deallocate(item->valuestring); + } + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + global_hooks.deallocate(item->string); + } + global_hooks.deallocate(item); + item = next; + } +} + +/* get the decimal point character of the current locale */ +static unsigned char get_decimal_point(void) +{ +#ifdef ENABLE_LOCALES + struct lconv *lconv = localeconv(); + return (unsigned char) lconv->decimal_point[0]; +#else + return '.'; +#endif +} + +typedef struct +{ + const unsigned char *content; + size_t length; + size_t offset; + size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ + internal_hooks hooks; +} parse_buffer; + +/* check if the given size is left to read in a given parse buffer (starting with 1) */ +#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) +/* check if the buffer can be accessed at the given index (starting with 0) */ +#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) +#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) +/* get a pointer to the buffer at the position */ +#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) + +/* Parse the input text to generate a number, and populate the result into item. */ +static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer) +{ + double number = 0; + unsigned char *after_end = NULL; + unsigned char number_c_string[64]; + unsigned char decimal_point = get_decimal_point(); + size_t i = 0; + + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; + } + + /* copy the number into a temporary buffer and replace '.' with the decimal point + * of the current locale (for strtod) + * This also takes care of '\0' not necessarily being available for marking the end of the input */ + for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) + { + switch (buffer_at_offset(input_buffer)[i]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + case 'e': + case 'E': + number_c_string[i] = buffer_at_offset(input_buffer)[i]; + break; + + case '.': + number_c_string[i] = decimal_point; + break; + + default: + goto loop_end; + } + } +loop_end: + number_c_string[i] = '\0'; + + number = strtod((const char*)number_c_string, (char**)&after_end); + if (number_c_string == after_end) + { + return false; /* parse_error */ + } + + item->valuedouble = number; + + /* use saturation in case of overflow */ + if (number >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (number <= (double)INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)number; + } + + item->type = cJSON_Number; + + input_buffer->offset += (size_t)(after_end - number_c_string); + return true; +} + +/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) +{ + if (number >= INT_MAX) + { + object->valueint = INT_MAX; + } + else if (number <= (double)INT_MIN) + { + object->valueint = INT_MIN; + } + else + { + object->valueint = (int)number; + } + + return object->valuedouble = number; +} + +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring) +{ + char *copy = NULL; + /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */ + if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference)) + { + return NULL; + } + if (strlen(valuestring) <= strlen(object->valuestring)) + { + strcpy(object->valuestring, valuestring); + return object->valuestring; + } + copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks); + if (copy == NULL) + { + return NULL; + } + if (object->valuestring != NULL) + { + cJSON_free(object->valuestring); + } + object->valuestring = copy; + + return copy; +} + +typedef struct +{ + unsigned char *buffer; + size_t length; + size_t offset; + size_t depth; /* current nesting depth (for formatted printing) */ + cJSON_bool noalloc; + cJSON_bool format; /* is this print a formatted print */ + internal_hooks hooks; +} printbuffer; + +/* realloc printbuffer if necessary to have at least "needed" bytes more */ +static unsigned char* ensure(printbuffer * const p, size_t needed) +{ + unsigned char *newbuffer = NULL; + size_t newsize = 0; + + if ((p == NULL) || (p->buffer == NULL)) + { + return NULL; + } + + if ((p->length > 0) && (p->offset >= p->length)) + { + /* make sure that offset is valid */ + return NULL; + } + + if (needed > INT_MAX) + { + /* sizes bigger than INT_MAX are currently not supported */ + return NULL; + } + + needed += p->offset + 1; + if (needed <= p->length) + { + return p->buffer + p->offset; + } + + if (p->noalloc) { + return NULL; + } + + /* calculate new buffer size */ + if (needed > (INT_MAX / 2)) + { + /* overflow of int, use INT_MAX if possible */ + if (needed <= INT_MAX) + { + newsize = INT_MAX; + } + else + { + return NULL; + } + } + else + { + newsize = needed * 2; + } + + if (p->hooks.reallocate != NULL) + { + /* reallocate with realloc if available */ + newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize); + if (newbuffer == NULL) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + } + else + { + /* otherwise reallocate manually */ + newbuffer = (unsigned char*)p->hooks.allocate(newsize); + if (!newbuffer) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + if (newbuffer) + { + memcpy(newbuffer, p->buffer, p->offset + 1); + } + p->hooks.deallocate(p->buffer); + } + p->length = newsize; + p->buffer = newbuffer; + + return newbuffer + p->offset; +} + +/* calculate the new length of the string in a printbuffer and update the offset */ +static void update_offset(printbuffer * const buffer) +{ + const unsigned char *buffer_pointer = NULL; + if ((buffer == NULL) || (buffer->buffer == NULL)) + { + return; + } + buffer_pointer = buffer->buffer + buffer->offset; + + buffer->offset += strlen((const char*)buffer_pointer); +} + +/* securely comparison of floating-point variables */ +static cJSON_bool compare_double(double a, double b) +{ + double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b); + return (fabs(a - b) <= maxVal * DBL_EPSILON); +} + +/* Render the number nicely from the given item into a string. */ +static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + double d = item->valuedouble; + int length = 0; + size_t i = 0; + unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */ + unsigned char decimal_point = get_decimal_point(); + double test = 0.0; + + if (output_buffer == NULL) + { + return false; + } + + /* This checks for NaN and Infinity */ + if (isnan(d) || isinf(d)) + { + length = sprintf((char*)number_buffer, "null"); + } + else + { + /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ + length = sprintf((char*)number_buffer, "%1.15g", d); + + /* Check whether the original double can be recovered */ + if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d)) + { + /* If not, print with 17 decimal places of precision */ + length = sprintf((char*)number_buffer, "%1.17g", d); + } + } + + /* sprintf failed or buffer overrun occurred */ + if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) + { + return false; + } + + /* reserve appropriate space in the output */ + output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); + if (output_pointer == NULL) + { + return false; + } + + /* copy the printed number to the output and replace locale + * dependent decimal point with '.' */ + for (i = 0; i < ((size_t)length); i++) + { + if (number_buffer[i] == decimal_point) + { + output_pointer[i] = '.'; + continue; + } + + output_pointer[i] = number_buffer[i]; + } + output_pointer[i] = '\0'; + + output_buffer->offset += (size_t)length; + + return true; +} + +/* parse 4 digit hexadecimal number */ +static unsigned parse_hex4(const unsigned char * const input) +{ + unsigned int h = 0; + size_t i = 0; + + for (i = 0; i < 4; i++) + { + /* parse digit */ + if ((input[i] >= '0') && (input[i] <= '9')) + { + h += (unsigned int) input[i] - '0'; + } + else if ((input[i] >= 'A') && (input[i] <= 'F')) + { + h += (unsigned int) 10 + input[i] - 'A'; + } + else if ((input[i] >= 'a') && (input[i] <= 'f')) + { + h += (unsigned int) 10 + input[i] - 'a'; + } + else /* invalid */ + { + return 0; + } + + if (i < 3) + { + /* shift left to make place for the next nibble */ + h = h << 4; + } + } + + return h; +} + +/* converts a UTF-16 literal to UTF-8 + * A literal can be one or two sequences of the form \uXXXX */ +static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer) +{ + long unsigned int codepoint = 0; + unsigned int first_code = 0; + const unsigned char *first_sequence = input_pointer; + unsigned char utf8_length = 0; + unsigned char utf8_position = 0; + unsigned char sequence_length = 0; + unsigned char first_byte_mark = 0; + + if ((input_end - first_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + /* get the first utf16 sequence */ + first_code = parse_hex4(first_sequence + 2); + + /* check that the code is valid */ + if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) + { + goto fail; + } + + /* UTF16 surrogate pair */ + if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) + { + const unsigned char *second_sequence = first_sequence + 6; + unsigned int second_code = 0; + sequence_length = 12; /* \uXXXX\uXXXX */ + + if ((input_end - second_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) + { + /* missing second half of the surrogate pair */ + goto fail; + } + + /* get the second utf16 sequence */ + second_code = parse_hex4(second_sequence + 2); + /* check that the code is valid */ + if ((second_code < 0xDC00) || (second_code > 0xDFFF)) + { + /* invalid second half of the surrogate pair */ + goto fail; + } + + + /* calculate the unicode codepoint from the surrogate pair */ + codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); + } + else + { + sequence_length = 6; /* \uXXXX */ + codepoint = first_code; + } + + /* encode as UTF-8 + * takes at maximum 4 bytes to encode: + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (codepoint < 0x80) + { + /* normal ascii, encoding 0xxxxxxx */ + utf8_length = 1; + } + else if (codepoint < 0x800) + { + /* two bytes, encoding 110xxxxx 10xxxxxx */ + utf8_length = 2; + first_byte_mark = 0xC0; /* 11000000 */ + } + else if (codepoint < 0x10000) + { + /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ + utf8_length = 3; + first_byte_mark = 0xE0; /* 11100000 */ + } + else if (codepoint <= 0x10FFFF) + { + /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + utf8_length = 4; + first_byte_mark = 0xF0; /* 11110000 */ + } + else + { + /* invalid unicode codepoint */ + goto fail; + } + + /* encode as utf8 */ + for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--) + { + /* 10xxxxxx */ + (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF); + codepoint >>= 6; + } + /* encode first byte */ + if (utf8_length > 1) + { + (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF); + } + else + { + (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F); + } + + *output_pointer += utf8_length; + + return sequence_length; + +fail: + return 0; +} + +/* Parse the input text into an unescaped cinput, and populate item. */ +static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) +{ + const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; + const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; + unsigned char *output_pointer = NULL; + unsigned char *output = NULL; + + /* not a string */ + if (buffer_at_offset(input_buffer)[0] != '\"') + { + goto fail; + } + + { + /* calculate approximate size of the output (overestimate) */ + size_t allocation_length = 0; + size_t skipped_bytes = 0; + while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) + { + /* is escape sequence */ + if (input_end[0] == '\\') + { + if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) + { + /* prevent buffer overflow when last input character is a backslash */ + goto fail; + } + skipped_bytes++; + input_end++; + } + input_end++; + } + if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) + { + goto fail; /* string ended unexpectedly */ + } + + /* This is at most how much we need for the output */ + allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes; + output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); + if (output == NULL) + { + goto fail; /* allocation failure */ + } + } + + output_pointer = output; + /* loop through the string literal */ + while (input_pointer < input_end) + { + if (*input_pointer != '\\') + { + *output_pointer++ = *input_pointer++; + } + /* escape sequence */ + else + { + unsigned char sequence_length = 2; + if ((input_end - input_pointer) < 1) + { + goto fail; + } + + switch (input_pointer[1]) + { + case 'b': + *output_pointer++ = '\b'; + break; + case 'f': + *output_pointer++ = '\f'; + break; + case 'n': + *output_pointer++ = '\n'; + break; + case 'r': + *output_pointer++ = '\r'; + break; + case 't': + *output_pointer++ = '\t'; + break; + case '\"': + case '\\': + case '/': + *output_pointer++ = input_pointer[1]; + break; + + /* UTF-16 literal */ + case 'u': + sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); + if (sequence_length == 0) + { + /* failed to convert UTF16-literal to UTF-8 */ + goto fail; + } + break; + + default: + goto fail; + } + input_pointer += sequence_length; + } + } + + /* zero terminate the output */ + *output_pointer = '\0'; + + item->type = cJSON_String; + item->valuestring = (char*)output; + + input_buffer->offset = (size_t) (input_end - input_buffer->content); + input_buffer->offset++; + + return true; + +fail: + if (output != NULL) + { + input_buffer->hooks.deallocate(output); + } + + if (input_pointer != NULL) + { + input_buffer->offset = (size_t)(input_pointer - input_buffer->content); + } + + return false; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer) +{ + const unsigned char *input_pointer = NULL; + unsigned char *output = NULL; + unsigned char *output_pointer = NULL; + size_t output_length = 0; + /* numbers of additional characters needed for escaping */ + size_t escape_characters = 0; + + if (output_buffer == NULL) + { + return false; + } + + /* empty string */ + if (input == NULL) + { + output = ensure(output_buffer, sizeof("\"\"")); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "\"\""); + + return true; + } + + /* set "flag" to 1 if something needs to be escaped */ + for (input_pointer = input; *input_pointer; input_pointer++) + { + switch (*input_pointer) + { + case '\"': + case '\\': + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + /* one character escape sequence */ + escape_characters++; + break; + default: + if (*input_pointer < 32) + { + /* UTF-16 escape sequence uXXXX */ + escape_characters += 5; + } + break; + } + } + output_length = (size_t)(input_pointer - input) + escape_characters; + + output = ensure(output_buffer, output_length + sizeof("\"\"")); + if (output == NULL) + { + return false; + } + + /* no characters have to be escaped */ + if (escape_characters == 0) + { + output[0] = '\"'; + memcpy(output + 1, input, output_length); + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; + } + + output[0] = '\"'; + output_pointer = output + 1; + /* copy the string */ + for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) + { + if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) + { + /* normal character, copy */ + *output_pointer = *input_pointer; + } + else + { + /* character needs to be escaped */ + *output_pointer++ = '\\'; + switch (*input_pointer) + { + case '\\': + *output_pointer = '\\'; + break; + case '\"': + *output_pointer = '\"'; + break; + case '\b': + *output_pointer = 'b'; + break; + case '\f': + *output_pointer = 'f'; + break; + case '\n': + *output_pointer = 'n'; + break; + case '\r': + *output_pointer = 'r'; + break; + case '\t': + *output_pointer = 't'; + break; + default: + /* escape and print as unicode codepoint */ + sprintf((char*)output_pointer, "u%04x", *input_pointer); + output_pointer += 4; + break; + } + } + } + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; +} + +/* Invoke print_string_ptr (which is useful) on an item. */ +static cJSON_bool print_string(const cJSON * const item, printbuffer * const p) +{ + return print_string_ptr((unsigned char*)item->valuestring, p); +} + +/* Predeclare these prototypes. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer); + +/* Utility to jump whitespace and cr/lf */ +static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL)) + { + return NULL; + } + + if (cannot_access_at_index(buffer, 0)) + { + return buffer; + } + + while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) + { + buffer->offset++; + } + + if (buffer->offset == buffer->length) + { + buffer->offset--; + } + + return buffer; +} + +/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ +static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) + { + return NULL; + } + + if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) + { + buffer->offset += 3; + } + + return buffer; +} + +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + size_t buffer_length; + + if (NULL == value) + { + return NULL; + } + + /* Adding null character size due to require_null_terminated. */ + buffer_length = strlen(value) + sizeof(""); + + return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated); +} + +/* Parse an object - create a new root, and populate. */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; + cJSON *item = NULL; + + /* reset error position */ + global_error.json = NULL; + global_error.position = 0; + + if (value == NULL || 0 == buffer_length) + { + goto fail; + } + + buffer.content = (const unsigned char*)value; + buffer.length = buffer_length; + buffer.offset = 0; + buffer.hooks = global_hooks; + + item = cJSON_New_Item(&global_hooks); + if (item == NULL) /* memory fail */ + { + goto fail; + } + + if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) + { + /* parse failure. ep is set. */ + goto fail; + } + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) + { + buffer_skip_whitespace(&buffer); + if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0') + { + goto fail; + } + } + if (return_parse_end) + { + *return_parse_end = (const char*)buffer_at_offset(&buffer); + } + + return item; + +fail: + if (item != NULL) + { + cJSON_Delete(item); + } + + if (value != NULL) + { + error local_error; + local_error.json = (const unsigned char*)value; + local_error.position = 0; + + if (buffer.offset < buffer.length) + { + local_error.position = buffer.offset; + } + else if (buffer.length > 0) + { + local_error.position = buffer.length - 1; + } + + if (return_parse_end != NULL) + { + *return_parse_end = (const char*)local_error.json + local_error.position; + } + + global_error = local_error; + } + + return NULL; +} + +/* Default options for cJSON_Parse */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) +{ + return cJSON_ParseWithOpts(value, 0, 0); +} + +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length) +{ + return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0); +} + +#define cjson_min(a, b) (((a) < (b)) ? (a) : (b)) + +static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks) +{ + static const size_t default_buffer_size = 256; + printbuffer buffer[1]; + unsigned char *printed = NULL; + + memset(buffer, 0, sizeof(buffer)); + + /* create buffer */ + buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size); + buffer->length = default_buffer_size; + buffer->format = format; + buffer->hooks = *hooks; + if (buffer->buffer == NULL) + { + goto fail; + } + + /* print the value */ + if (!print_value(item, buffer)) + { + goto fail; + } + update_offset(buffer); + + /* check if reallocate is available */ + if (hooks->reallocate != NULL) + { + printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); + if (printed == NULL) { + goto fail; + } + buffer->buffer = NULL; + } + else /* otherwise copy the JSON over to a new buffer */ + { + printed = (unsigned char*) hooks->allocate(buffer->offset + 1); + if (printed == NULL) + { + goto fail; + } + memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); + printed[buffer->offset] = '\0'; /* just to be sure */ + + /* free the buffer */ + hooks->deallocate(buffer->buffer); + } + + return printed; + +fail: + if (buffer->buffer != NULL) + { + hooks->deallocate(buffer->buffer); + } + + if (printed != NULL) + { + hooks->deallocate(printed); + } + + return NULL; +} + +/* Render a cJSON item/entity/structure to text. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item) +{ + return (char*)print(item, true, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item) +{ + return (char*)print(item, false, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if (prebuffer < 0) + { + return NULL; + } + + p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer); + if (!p.buffer) + { + return NULL; + } + + p.length = (size_t)prebuffer; + p.offset = 0; + p.noalloc = false; + p.format = fmt; + p.hooks = global_hooks; + + if (!print_value(item, &p)) + { + global_hooks.deallocate(p.buffer); + return NULL; + } + + return (char*)p.buffer; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if ((length < 0) || (buffer == NULL)) + { + return false; + } + + p.buffer = (unsigned char*)buffer; + p.length = (size_t)length; + p.offset = 0; + p.noalloc = true; + p.format = format; + p.hooks = global_hooks; + + return print_value(item, &p); +} + +/* Parser core - when encountering text, process appropriately. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer) +{ + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; /* no input */ + } + + /* parse the different types of values */ + /* null */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0)) + { + item->type = cJSON_NULL; + input_buffer->offset += 4; + return true; + } + /* false */ + if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0)) + { + item->type = cJSON_False; + input_buffer->offset += 5; + return true; + } + /* true */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0)) + { + item->type = cJSON_True; + item->valueint = 1; + input_buffer->offset += 4; + return true; + } + /* string */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) + { + return parse_string(item, input_buffer); + } + /* number */ + if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) + { + return parse_number(item, input_buffer); + } + /* array */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) + { + return parse_array(item, input_buffer); + } + /* object */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) + { + return parse_object(item, input_buffer); + } + + return false; +} + +/* Render a value to text. */ +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output = NULL; + + if ((item == NULL) || (output_buffer == NULL)) + { + return false; + } + + switch ((item->type) & 0xFF) + { + case cJSON_NULL: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "null"); + return true; + + case cJSON_False: + output = ensure(output_buffer, 6); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "false"); + return true; + + case cJSON_True: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "true"); + return true; + + case cJSON_Number: + return print_number(item, output_buffer); + + case cJSON_Raw: + { + size_t raw_length = 0; + if (item->valuestring == NULL) + { + return false; + } + + raw_length = strlen(item->valuestring) + sizeof(""); + output = ensure(output_buffer, raw_length); + if (output == NULL) + { + return false; + } + memcpy(output, item->valuestring, raw_length); + return true; + } + + case cJSON_String: + return print_string(item, output_buffer); + + case cJSON_Array: + return print_array(item, output_buffer); + + case cJSON_Object: + return print_object(item, output_buffer); + + default: + return false; + } +} + +/* Build an array from input text. */ +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* head of the linked list */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (buffer_at_offset(input_buffer)[0] != '[') + { + /* not an array */ + goto fail; + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) + { + /* empty array */ + goto success; + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse next value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') + { + goto fail; /* expected end of array */ + } + +success: + input_buffer->depth--; + + if (head != NULL) { + head->prev = current_item; + } + + item->type = cJSON_Array; + item->child = head; + + input_buffer->offset++; + + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an array to text */ +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_element = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output array. */ + /* opening square bracket */ + output_pointer = ensure(output_buffer, 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer = '['; + output_buffer->offset++; + output_buffer->depth++; + + while (current_element != NULL) + { + if (!print_value(current_element, output_buffer)) + { + return false; + } + update_offset(output_buffer); + if (current_element->next) + { + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ','; + if(output_buffer->format) + { + *output_pointer++ = ' '; + } + *output_pointer = '\0'; + output_buffer->offset += length; + } + current_element = current_element->next; + } + + output_pointer = ensure(output_buffer, 2); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ']'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Build an object from the text. */ +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* linked list head */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) + { + goto fail; /* not an object */ + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) + { + goto success; /* empty object */ + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse the name of the child */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_string(current_item, input_buffer)) + { + goto fail; /* failed to parse name */ + } + buffer_skip_whitespace(input_buffer); + + /* swap valuestring and string, because we parsed the name */ + current_item->string = current_item->valuestring; + current_item->valuestring = NULL; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) + { + goto fail; /* invalid object */ + } + + /* parse the value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) + { + goto fail; /* expected end of object */ + } + +success: + input_buffer->depth--; + + if (head != NULL) { + head->prev = current_item; + } + + item->type = cJSON_Object; + item->child = head; + + input_buffer->offset++; + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an object to text. */ +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_item = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output: */ + length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */ + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer++ = '{'; + output_buffer->depth++; + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + output_buffer->offset += length; + + while (current_item) + { + if (output_buffer->format) + { + size_t i; + output_pointer = ensure(output_buffer, output_buffer->depth); + if (output_pointer == NULL) + { + return false; + } + for (i = 0; i < output_buffer->depth; i++) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += output_buffer->depth; + } + + /* print key */ + if (!print_string_ptr((unsigned char*)current_item->string, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ':'; + if (output_buffer->format) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += length; + + /* print value */ + if (!print_value(current_item, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + /* print comma if not last */ + length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0)); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + if (current_item->next) + { + *output_pointer++ = ','; + } + + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + *output_pointer = '\0'; + output_buffer->offset += length; + + current_item = current_item->next; + } + + output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); + if (output_pointer == NULL) + { + return false; + } + if (output_buffer->format) + { + size_t i; + for (i = 0; i < (output_buffer->depth - 1); i++) + { + *output_pointer++ = '\t'; + } + } + *output_pointer++ = '}'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Get Array size/item / object item. */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) +{ + cJSON *child = NULL; + size_t size = 0; + + if (array == NULL) + { + return 0; + } + + child = array->child; + + while(child != NULL) + { + size++; + child = child->next; + } + + /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ + + return (int)size; +} + +static cJSON* get_array_item(const cJSON *array, size_t index) +{ + cJSON *current_child = NULL; + + if (array == NULL) + { + return NULL; + } + + current_child = array->child; + while ((current_child != NULL) && (index > 0)) + { + index--; + current_child = current_child->next; + } + + return current_child; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) +{ + if (index < 0) + { + return NULL; + } + + return get_array_item(array, (size_t)index); +} + +static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) +{ + cJSON *current_element = NULL; + + if ((object == NULL) || (name == NULL)) + { + return NULL; + } + + current_element = object->child; + if (case_sensitive) + { + while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0)) + { + current_element = current_element->next; + } + } + else + { + while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) + { + current_element = current_element->next; + } + } + + if ((current_element == NULL) || (current_element->string == NULL)) { + return NULL; + } + + return current_element; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, false); +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) +{ + return cJSON_GetObjectItem(object, string) ? 1 : 0; +} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev, cJSON *item) +{ + prev->next = item; + item->prev = prev; +} + +/* Utility for handling references. */ +static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks) +{ + cJSON *reference = NULL; + if (item == NULL) + { + return NULL; + } + + reference = cJSON_New_Item(hooks); + if (reference == NULL) + { + return NULL; + } + + memcpy(reference, item, sizeof(cJSON)); + reference->string = NULL; + reference->type |= cJSON_IsReference; + reference->next = reference->prev = NULL; + return reference; +} + +static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) +{ + cJSON *child = NULL; + + if ((item == NULL) || (array == NULL) || (array == item)) + { + return false; + } + + child = array->child; + /* + * To find the last item in array quickly, we use prev in array + */ + if (child == NULL) + { + /* list is empty, start new one */ + array->child = item; + item->prev = item; + item->next = NULL; + } + else + { + /* append to the end */ + if (child->prev) + { + suffix_object(child->prev, item); + array->child->prev = item; + } + else + { + while (child->next) + { + child = child->next; + } + suffix_object(child, item); + array->child->prev = item; + } + } + + return true; +} + +/* Add item to array/object. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + return add_item_to_array(array, item); +} + +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic push +#endif +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif +/* helper function to cast away const */ +static void* cast_away_const(const void* string) +{ + return (void*)string; +} +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic pop +#endif + + +static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) +{ + char *new_key = NULL; + int new_type = cJSON_Invalid; + + if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item)) + { + return false; + } + + if (constant_key) + { + new_key = (char*)cast_away_const(string); + new_type = item->type | cJSON_StringIsConst; + } + else + { + new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks); + if (new_key == NULL) + { + return false; + } + + new_type = item->type & ~cJSON_StringIsConst; + } + + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + hooks->deallocate(item->string); + } + + item->string = new_key; + item->type = new_type; + + return add_item_to_array(object, item); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + return add_item_to_object(object, string, item, &global_hooks, false); +} + +/* Add an item to an object with constant string as key */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) +{ + return add_item_to_object(object, string, item, &global_hooks, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +{ + if (array == NULL) + { + return false; + } + + return add_item_to_array(array, create_reference(item, &global_hooks)); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +{ + if ((object == NULL) || (string == NULL)) + { + return false; + } + + return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) +{ + cJSON *null = cJSON_CreateNull(); + if (add_item_to_object(object, name, null, &global_hooks, false)) + { + return null; + } + + cJSON_Delete(null); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) +{ + cJSON *true_item = cJSON_CreateTrue(); + if (add_item_to_object(object, name, true_item, &global_hooks, false)) + { + return true_item; + } + + cJSON_Delete(true_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) +{ + cJSON *false_item = cJSON_CreateFalse(); + if (add_item_to_object(object, name, false_item, &global_hooks, false)) + { + return false_item; + } + + cJSON_Delete(false_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) +{ + cJSON *bool_item = cJSON_CreateBool(boolean); + if (add_item_to_object(object, name, bool_item, &global_hooks, false)) + { + return bool_item; + } + + cJSON_Delete(bool_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +{ + cJSON *number_item = cJSON_CreateNumber(number); + if (add_item_to_object(object, name, number_item, &global_hooks, false)) + { + return number_item; + } + + cJSON_Delete(number_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) +{ + cJSON *string_item = cJSON_CreateString(string); + if (add_item_to_object(object, name, string_item, &global_hooks, false)) + { + return string_item; + } + + cJSON_Delete(string_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) +{ + cJSON *raw_item = cJSON_CreateRaw(raw); + if (add_item_to_object(object, name, raw_item, &global_hooks, false)) + { + return raw_item; + } + + cJSON_Delete(raw_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) +{ + cJSON *object_item = cJSON_CreateObject(); + if (add_item_to_object(object, name, object_item, &global_hooks, false)) + { + return object_item; + } + + cJSON_Delete(object_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) +{ + cJSON *array = cJSON_CreateArray(); + if (add_item_to_object(object, name, array, &global_hooks, false)) + { + return array; + } + + cJSON_Delete(array); + return NULL; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) +{ + if ((parent == NULL) || (item == NULL)) + { + return NULL; + } + + if (item != parent->child) + { + /* not the first element */ + item->prev->next = item->next; + } + if (item->next != NULL) + { + /* not the last element */ + item->next->prev = item->prev; + } + + if (item == parent->child) + { + /* first element */ + parent->child = item->next; + } + else if (item->next == NULL) + { + /* last element */ + parent->child->prev = item->prev; + } + + /* make sure the detached item doesn't point anywhere anymore */ + item->prev = NULL; + item->next = NULL; + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) +{ + if (which < 0) + { + return NULL; + } + + return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which) +{ + cJSON_Delete(cJSON_DetachItemFromArray(array, which)); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItem(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObject(object, string)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); +} + +/* Replace array/object items with new ones. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +{ + cJSON *after_inserted = NULL; + + if (which < 0) + { + return false; + } + + after_inserted = get_array_item(array, (size_t)which); + if (after_inserted == NULL) + { + return add_item_to_array(array, newitem); + } + + newitem->next = after_inserted; + newitem->prev = after_inserted->prev; + after_inserted->prev = newitem; + if (after_inserted == array->child) + { + array->child = newitem; + } + else + { + newitem->prev->next = newitem; + } + return true; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) +{ + if ((parent == NULL) || (replacement == NULL) || (item == NULL)) + { + return false; + } + + if (replacement == item) + { + return true; + } + + replacement->next = item->next; + replacement->prev = item->prev; + + if (replacement->next != NULL) + { + replacement->next->prev = replacement; + } + if (parent->child == item) + { + if (parent->child->prev == parent->child) + { + replacement->prev = replacement; + } + parent->child = replacement; + } + else + { /* + * To find the last item in array quickly, we use prev in array. + * We can't modify the last item's next pointer where this item was the parent's child + */ + if (replacement->prev != NULL) + { + replacement->prev->next = replacement; + } + if (replacement->next == NULL) + { + parent->child->prev = replacement; + } + } + + item->next = NULL; + item->prev = NULL; + cJSON_Delete(item); + + return true; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + if (which < 0) + { + return false; + } + + return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); +} + +static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) +{ + if ((replacement == NULL) || (string == NULL)) + { + return false; + } + + /* replace the name in the replacement */ + if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) + { + cJSON_free(replacement->string); + } + replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + replacement->type &= ~cJSON_StringIsConst; + + return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +{ + return replace_item_in_object(object, string, newitem, false); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +{ + return replace_item_in_object(object, string, newitem, true); +} + +/* Create basic types: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_NULL; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_True; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = boolean ? cJSON_True : cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Number; + item->valuedouble = num; + + /* use saturation in case of overflow */ + if (num >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (num <= (double)INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)num; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_String; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) + { + item->type = cJSON_String | cJSON_IsReference; + item->valuestring = (char*)cast_away_const(string); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Object | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) { + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Array | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Raw; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type=cJSON_Array; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item) + { + item->type = cJSON_Object; + } + + return item; +} + +/* Create Arrays: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if (!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber((double)numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0;a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (strings == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for (i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateString(strings[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p,n); + } + p = n; + } + + return a; +} + +/* Duplication */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) +{ + cJSON *newitem = NULL; + cJSON *child = NULL; + cJSON *next = NULL; + cJSON *newchild = NULL; + + /* Bail on bad ptr */ + if (!item) + { + goto fail; + } + /* Create new item */ + newitem = cJSON_New_Item(&global_hooks); + if (!newitem) + { + goto fail; + } + /* Copy over all vars */ + newitem->type = item->type & (~cJSON_IsReference); + newitem->valueint = item->valueint; + newitem->valuedouble = item->valuedouble; + if (item->valuestring) + { + newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks); + if (!newitem->valuestring) + { + goto fail; + } + } + if (item->string) + { + newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); + if (!newitem->string) + { + goto fail; + } + } + /* If non-recursive, then we're done! */ + if (!recurse) + { + return newitem; + } + /* Walk the ->next chain for the child. */ + child = item->child; + while (child != NULL) + { + newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) + { + goto fail; + } + if (next != NULL) + { + /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + next->next = newchild; + newchild->prev = next; + next = newchild; + } + else + { + /* Set newitem->child and move to it */ + newitem->child = newchild; + next = newchild; + } + child = child->next; + } + + return newitem; + +fail: + if (newitem != NULL) + { + cJSON_Delete(newitem); + } + + return NULL; +} + +static void skip_oneline_comment(char **input) +{ + *input += static_strlen("//"); + + for (; (*input)[0] != '\0'; ++(*input)) + { + if ((*input)[0] == '\n') { + *input += static_strlen("\n"); + return; + } + } +} + +static void skip_multiline_comment(char **input) +{ + *input += static_strlen("/*"); + + for (; (*input)[0] != '\0'; ++(*input)) + { + if (((*input)[0] == '*') && ((*input)[1] == '/')) + { + *input += static_strlen("*/"); + return; + } + } +} + +static void minify_string(char **input, char **output) { + (*output)[0] = (*input)[0]; + *input += static_strlen("\""); + *output += static_strlen("\""); + + + for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) { + (*output)[0] = (*input)[0]; + + if ((*input)[0] == '\"') { + (*output)[0] = '\"'; + *input += static_strlen("\""); + *output += static_strlen("\""); + return; + } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) { + (*output)[1] = (*input)[1]; + *input += static_strlen("\""); + *output += static_strlen("\""); + } + } +} + +CJSON_PUBLIC(void) cJSON_Minify(char *json) +{ + char *into = json; + + if (json == NULL) + { + return; + } + + while (json[0] != '\0') + { + switch (json[0]) + { + case ' ': + case '\t': + case '\r': + case '\n': + json++; + break; + + case '/': + if (json[1] == '/') + { + skip_oneline_comment(&json); + } + else if (json[1] == '*') + { + skip_multiline_comment(&json); + } else { + json++; + } + break; + + case '\"': + minify_string(&json, (char**)&into); + break; + + default: + into[0] = json[0]; + json++; + into++; + } + } + + /* and null-terminate. */ + *into = '\0'; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Invalid; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_False; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xff) == cJSON_True; +} + + +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & (cJSON_True | cJSON_False)) != 0; +} +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_NULL; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Number; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_String; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Array; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Object; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Raw; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive) +{ + if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a)) + { + return false; + } + + /* check if type is valid */ + switch (a->type & 0xFF) + { + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + case cJSON_Number: + case cJSON_String: + case cJSON_Raw: + case cJSON_Array: + case cJSON_Object: + break; + + default: + return false; + } + + /* identical objects are equal */ + if (a == b) + { + return true; + } + + switch (a->type & 0xFF) + { + /* in these cases and equal type is enough */ + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + return true; + + case cJSON_Number: + if (compare_double(a->valuedouble, b->valuedouble)) + { + return true; + } + return false; + + case cJSON_String: + case cJSON_Raw: + if ((a->valuestring == NULL) || (b->valuestring == NULL)) + { + return false; + } + if (strcmp(a->valuestring, b->valuestring) == 0) + { + return true; + } + + return false; + + case cJSON_Array: + { + cJSON *a_element = a->child; + cJSON *b_element = b->child; + + for (; (a_element != NULL) && (b_element != NULL);) + { + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + + a_element = a_element->next; + b_element = b_element->next; + } + + /* one of the arrays is longer than the other */ + if (a_element != b_element) { + return false; + } + + return true; + } + + case cJSON_Object: + { + cJSON *a_element = NULL; + cJSON *b_element = NULL; + cJSON_ArrayForEach(a_element, a) + { + /* TODO This has O(n^2) runtime, which is horrible! */ + b_element = get_object_item(b, a_element->string, case_sensitive); + if (b_element == NULL) + { + return false; + } + + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + } + + /* doing this twice, once on a and b to prevent true comparison if a subset of b + * TODO: Do this the proper way, this is just a fix for now */ + cJSON_ArrayForEach(b_element, b) + { + a_element = get_object_item(a, b_element->string, case_sensitive); + if (a_element == NULL) + { + return false; + } + + if (!cJSON_Compare(b_element, a_element, case_sensitive)) + { + return false; + } + } + + return true; + } + + default: + return false; + } +} + +CJSON_PUBLIC(void *) cJSON_malloc(size_t size) +{ + return global_hooks.allocate(size); +} + +CJSON_PUBLIC(void) cJSON_free(void *object) +{ + global_hooks.deallocate(object); +} diff --git a/product/src/fes/protocol/dgls_mqttclient/cJSON.h b/product/src/fes/protocol/dgls_mqttclient/cJSON.h new file mode 100644 index 00000000..b5ceb290 --- /dev/null +++ b/product/src/fes/protocol/dgls_mqttclient/cJSON.h @@ -0,0 +1,293 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) +#define __WINDOWS__ +#endif + +#ifdef __WINDOWS__ + +/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options: + +CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols +CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) +CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol + +For *nix builds that support visibility attribute, you can define similar behavior by + +setting default visibility to hidden by adding +-fvisibility=hidden (for gcc) +or +-xldscope=hidden (for sun cc) +to CFLAGS + +then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does + +*/ + +#define CJSON_CDECL __cdecl +#define CJSON_STDCALL __stdcall + +/* export symbols by default, this is necessary for copy pasting the C and header file */ +#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_EXPORT_SYMBOLS +#endif + +#if defined(CJSON_HIDE_SYMBOLS) +#define CJSON_PUBLIC(type) type CJSON_STDCALL +#elif defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL +#elif defined(CJSON_IMPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL +#endif +#else /* !__WINDOWS__ */ +#define CJSON_CDECL +#define CJSON_STDCALL + +#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) +#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type +#else +#define CJSON_PUBLIC(type) type +#endif +#endif + +/* project version */ +#define CJSON_VERSION_MAJOR 1 +#define CJSON_VERSION_MINOR 7 +#define CJSON_VERSION_PATCH 13 + +#include + +/* cJSON Types: */ +#define cJSON_Invalid (0) +#define cJSON_False (1 << 0) +#define cJSON_True (1 << 1) +#define cJSON_NULL (1 << 2) +#define cJSON_Number (1 << 3) +#define cJSON_String (1 << 4) +#define cJSON_Array (1 << 5) +#define cJSON_Object (1 << 6) +#define cJSON_Raw (1 << 7) /* raw json */ + +#define cJSON_IsReference 256 +#define cJSON_StringIsConst 512 + +/* The cJSON structure: */ +typedef struct cJSON +{ + /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *next; + struct cJSON *prev; + /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + struct cJSON *child; + + /* The type of the item, as above. */ + int type; + + /* The item's string, if type==cJSON_String and type == cJSON_Raw */ + char *valuestring; + /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ + int valueint; + /* The item's number, if type==cJSON_Number */ + double valuedouble; + + /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + char *string; +} cJSON; + +typedef struct cJSON_Hooks +{ + /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */ + void *(CJSON_CDECL *malloc_fn)(size_t sz); + void (CJSON_CDECL *free_fn)(void *ptr); +} cJSON_Hooks; + +typedef int cJSON_bool; + +/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. + * This is to prevent stack overflows. */ +#ifndef CJSON_NESTING_LIMIT +#define CJSON_NESTING_LIMIT 1000 +#endif + +/* returns the version of cJSON as a string */ +CJSON_PUBLIC(const char*) cJSON_Version(void); + +/* Supply malloc, realloc and free functions to cJSON */ +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); + +/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length); +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated); + +/* Render a cJSON entity to text for transfer/storage. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. */ +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); +/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); +/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ +/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); +/* Delete a cJSON entity and all subentities. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); + +/* Returns the number of items in an array (or object). */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); +/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); +/* Get item "string" from object. Case insensitive. */ +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); + +/* Check item type and return its value */ +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item); +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item); + +/* These functions check the type of an item */ +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); + +/* These calls create a cJSON item of the appropriate type. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); +/* raw json */ +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); + +/* Create a string where valuestring references a string so + * it will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); +/* Create an object/array that only references it's elements so + * they will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); + +/* These utilities create an Array of count items. + * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); + +/* Append item to the specified array/object. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. + * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before + * writing to `item->string` */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); + +/* Remove/Detach items from Arrays/Objects. */ +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); + +/* Update array items. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will + * need to be released. With recurse!=0, it will duplicate any children connected to the item. + * The item->next and ->prev pointers are always zero on return from Duplicate. */ +/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. + * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); + +/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings. + * The input pointer json cannot point to a read-only address area, such as a string constant, + * but should point to a readable and writable adress area. */ +CJSON_PUBLIC(void) cJSON_Minify(char *json); + +/* Helper functions for creating and adding items to an object at the same time. + * They return the added item or NULL on failure. */ +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) +/* helper for the cJSON_SetNumberValue macro */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); +#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) +/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring); + +/* Macro for iterating over an array or object */ +#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) + +/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ +CJSON_PUBLIC(void *) cJSON_malloc(size_t size); +CJSON_PUBLIC(void) cJSON_free(void *object); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/dgls_mqttclient/dgls_mqttclient.pro b/product/src/fes/protocol/dgls_mqttclient/dgls_mqttclient.pro new file mode 100644 index 00000000..92b0ee5f --- /dev/null +++ b/product/src/fes/protocol/dgls_mqttclient/dgls_mqttclient.pro @@ -0,0 +1,59 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2024-03-20T09:35:51 +# +#------------------------------------------------- + +# ARM板上暂不支持mqtt,不编译 +message("Compile only in x86 environment") +# requires(contains(QMAKE_HOST.arch, x86_64)) +requires(!contains(QMAKE_HOST.arch, aarch64):!linux-aarch64*) + +QT -= core gui +CONFIG -= qt + +TARGET = dgls_mqttclient +TEMPLATE = lib + + +SOURCES += \ + Dglsmqtts.cpp \ + DglsmqttsDataProcThread.cpp \ + Md5/Md5.cpp \ + cJSON.c \ + +HEADERS += \ + Dglsmqtts.h \ + DglsmqttsDataProcThread.h \ + mosquitto.h \ + mosquitto_plugin.h \ + mosquittopp.h \ + Md5/Md5.h \ + cJSON.h \ + + +INCLUDEPATH += \ + ../../include/ \ + ../../../include/ \ + ../../../3rd/include/ + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase +LIBS += -lmosquitto -lmosquittopp + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + + +#unix { +# target.path = /usr/lib +# INSTALLS += target +#} diff --git a/product/src/fes/protocol/dgls_mqttclient/mosquitto.h b/product/src/fes/protocol/dgls_mqttclient/mosquitto.h new file mode 100644 index 00000000..879184dc --- /dev/null +++ b/product/src/fes/protocol/dgls_mqttclient/mosquitto.h @@ -0,0 +1,3084 @@ +/* +Copyright (c) 2010-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_H +#define MOSQUITTO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(WIN32) && !defined(WITH_BROKER) && !defined(LIBMOSQUITTO_STATIC) +# ifdef libmosquitto_EXPORTS +# define libmosq_EXPORT __declspec(dllexport) +# else +# define libmosq_EXPORT __declspec(dllimport) +# endif +#else +# define libmosq_EXPORT +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# ifndef __cplusplus +# define bool char +# define true 1 +# define false 0 +# endif +#else +# ifndef __cplusplus +# include +# endif +#endif + +#include +#include + +#define LIBMOSQUITTO_MAJOR 1 +#define LIBMOSQUITTO_MINOR 6 +#define LIBMOSQUITTO_REVISION 10 +/* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ +#define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION) + +/* Log types */ +#define MOSQ_LOG_NONE 0 +#define MOSQ_LOG_INFO (1<<0) +#define MOSQ_LOG_NOTICE (1<<1) +#define MOSQ_LOG_WARNING (1<<2) +#define MOSQ_LOG_ERR (1<<3) +#define MOSQ_LOG_DEBUG (1<<4) +#define MOSQ_LOG_SUBSCRIBE (1<<5) +#define MOSQ_LOG_UNSUBSCRIBE (1<<6) +#define MOSQ_LOG_WEBSOCKETS (1<<7) +#define MOSQ_LOG_INTERNAL 0x80000000U +#define MOSQ_LOG_ALL 0xFFFFFFFFU + +/* Error values */ +enum mosq_err_t { + MOSQ_ERR_AUTH_CONTINUE = -4, + MOSQ_ERR_NO_SUBSCRIBERS = -3, + MOSQ_ERR_SUB_EXISTS = -2, + MOSQ_ERR_CONN_PENDING = -1, + MOSQ_ERR_SUCCESS = 0, + MOSQ_ERR_NOMEM = 1, + MOSQ_ERR_PROTOCOL = 2, + MOSQ_ERR_INVAL = 3, + MOSQ_ERR_NO_CONN = 4, + MOSQ_ERR_CONN_REFUSED = 5, + MOSQ_ERR_NOT_FOUND = 6, + MOSQ_ERR_CONN_LOST = 7, + MOSQ_ERR_TLS = 8, + MOSQ_ERR_PAYLOAD_SIZE = 9, + MOSQ_ERR_NOT_SUPPORTED = 10, + MOSQ_ERR_AUTH = 11, + MOSQ_ERR_ACL_DENIED = 12, + MOSQ_ERR_UNKNOWN = 13, + MOSQ_ERR_ERRNO = 14, + MOSQ_ERR_EAI = 15, + MOSQ_ERR_PROXY = 16, + MOSQ_ERR_PLUGIN_DEFER = 17, + MOSQ_ERR_MALFORMED_UTF8 = 18, + MOSQ_ERR_KEEPALIVE = 19, + MOSQ_ERR_LOOKUP = 20, + MOSQ_ERR_MALFORMED_PACKET = 21, + MOSQ_ERR_DUPLICATE_PROPERTY = 22, + MOSQ_ERR_TLS_HANDSHAKE = 23, + MOSQ_ERR_QOS_NOT_SUPPORTED = 24, + MOSQ_ERR_OVERSIZE_PACKET = 25, + MOSQ_ERR_OCSP = 26, +}; + +/* Option values */ +enum mosq_opt_t { + MOSQ_OPT_PROTOCOL_VERSION = 1, + MOSQ_OPT_SSL_CTX = 2, + MOSQ_OPT_SSL_CTX_WITH_DEFAULTS = 3, + MOSQ_OPT_RECEIVE_MAXIMUM = 4, + MOSQ_OPT_SEND_MAXIMUM = 5, + MOSQ_OPT_TLS_KEYFORM = 6, + MOSQ_OPT_TLS_ENGINE = 7, + MOSQ_OPT_TLS_ENGINE_KPASS_SHA1 = 8, + MOSQ_OPT_TLS_OCSP_REQUIRED = 9, + MOSQ_OPT_TLS_ALPN = 10, +}; + + +/* MQTT specification restricts client ids to a maximum of 23 characters */ +#define MOSQ_MQTT_ID_MAX_LENGTH 23 + +#define MQTT_PROTOCOL_V31 3 +#define MQTT_PROTOCOL_V311 4 +#define MQTT_PROTOCOL_V5 5 + +struct mosquitto_message{ + int mid; + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct mosquitto; +typedef struct mqtt5__property mosquitto_property; + +/* + * Topic: Threads + * libmosquitto provides thread safe operation, with the exception of + * which is not thread safe. + * + * If your application uses threads you must use to + * tell the library this is the case, otherwise it makes some optimisations + * for the single threaded case that may result in unexpected behaviour for + * the multi threaded case. + */ +/*************************************************** + * Important note + * + * The following functions that deal with network operations will return + * MOSQ_ERR_SUCCESS on success, but this does not mean that the operation has + * taken place. An attempt will be made to write the network data, but if the + * socket is not available for writing at that time then the packet will not be + * sent. To ensure the packet is sent, call mosquitto_loop() (which must also + * be called to process incoming network data). + * This is especially important when disconnecting a client that has a will. If + * the broker does not receive the DISCONNECT command, it will assume that the + * client has disconnected unexpectedly and send the will. + * + * mosquitto_connect() + * mosquitto_disconnect() + * mosquitto_subscribe() + * mosquitto_unsubscribe() + * mosquitto_publish() + ***************************************************/ + + +/* ====================================================================== + * + * Section: Library version, init, and cleanup + * + * ====================================================================== */ +/* + * Function: mosquitto_lib_version + * + * Can be used to obtain version information for the mosquitto library. + * This allows the application to compare the library version against the + * version it was compiled against by using the LIBMOSQUITTO_MAJOR, + * LIBMOSQUITTO_MINOR and LIBMOSQUITTO_REVISION defines. + * + * Parameters: + * major - an integer pointer. If not NULL, the major version of the + * library will be returned in this variable. + * minor - an integer pointer. If not NULL, the minor version of the + * library will be returned in this variable. + * revision - an integer pointer. If not NULL, the revision of the library will + * be returned in this variable. + * + * Returns: + * LIBMOSQUITTO_VERSION_NUMBER, which is a unique number based on the major, + * minor and revision values. + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_version(int *major, int *minor, int *revision); + +/* + * Function: mosquitto_lib_init + * + * Must be called before any other mosquitto functions. + * + * This function is *not* thread safe. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_UNKNOWN - on Windows, if sockets couldn't be initialized. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_init(void); + +/* + * Function: mosquitto_lib_cleanup + * + * Call to free resources associated with the library. + * + * Returns: + * MOSQ_ERR_SUCCESS - always + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_cleanup(void); + + +/* ====================================================================== + * + * Section: Client creation, destruction, and reinitialisation + * + * ====================================================================== */ +/* + * Function: mosquitto_new + * + * Create a new mosquitto client instance. + * + * Parameters: + * id - String to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Note that a client will never discard its own outgoing + * messages on disconnect. Calling or + * will cause the messages to be resent. + * Use to reset a client to its + * original state. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * Pointer to a struct mosquitto on success. + * NULL on failure. Interrogate errno to determine the cause for the failure: + * - ENOMEM on out of memory. + * - EINVAL on invalid input parameters. + * + * See Also: + * , , + */ +libmosq_EXPORT struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj); + +/* + * Function: mosquitto_destroy + * + * Use to free memory associated with a mosquitto client instance. + * + * Parameters: + * mosq - a struct mosquitto pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_destroy(struct mosquitto *mosq); + +/* + * Function: mosquitto_reinitialise + * + * This function allows an existing mosquitto client to be reused. Call on a + * mosquitto instance to close any open network connections, free memory + * and reinitialise the client with the new parameters. The end result is the + * same as the output of . + * + * Parameters: + * mosq - a valid mosquitto instance. + * id - string to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *obj); + + +/* ====================================================================== + * + * Section: Will + * + * ====================================================================== */ +/* + * Function: mosquitto_will_set + * + * Configure will information for a mosquitto instance. By default, clients do + * not have a will. This must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + */ +libmosq_EXPORT int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + +/* + * Function: mosquitto_will_set_v5 + * + * Configure will information for a mosquitto instance, with attached + * properties. By default, clients do not have a will. This must be called + * before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * properties - list of MQTT 5 properties. Can be NULL. On success only, the + * property list becomes the property of libmosquitto once this + * function is called and will be freed by the library. The + * property list must be freed by the application on error. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + * MOSQ_ERR_NOT_SUPPORTED - if properties is not NULL and the client is not + * using MQTT v5 + * MOSQ_ERR_PROTOCOL - if a property is invalid for use with wills. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + */ +libmosq_EXPORT int mosquitto_will_set_v5(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties); + +/* + * Function: mosquitto_will_clear + * + * Remove a previously configured will. This must be called before calling + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_will_clear(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Username and password + * + * ====================================================================== */ +/* + * Function: mosquitto_username_pw_set + * + * Configure username and password for a mosquitto instance. By default, no + * username or password will be sent. For v3.1 and v3.1.1 clients, if username + * is NULL, the password argument is ignored. + * + * This is must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * username - the username to send as a string, or NULL to disable + * authentication. + * password - the password to send as a string. Set to NULL when username is + * valid in order to send just a username. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password); + + +/* ====================================================================== + * + * Section: Connecting, reconnecting, disconnecting + * + * ====================================================================== */ +/* + * Function: mosquitto_connect + * + * Connect to an MQTT broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter. Use this function + * if you need to restrict network communication over a particular interface. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_bind_v5 + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter and MQTT v5 + * properties. Use this function if you need to restrict network communication + * over a particular interface. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * properties - the MQTT 5 properties for the connect (not for the Will). + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with CONNECT. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_v5(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, const mosquitto_property *properties); + +/* + * Function: mosquitto_connect_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * This extends the functionality of by adding the + * bind_address parameter. Use this function if you need to restrict network + * communication over a particular interface. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_async(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_srv + * + * Connect to an MQTT broker. + * + * If you set `host` to `example.com`, then this call will attempt to retrieve + * the DNS SRV record for `_secure-mqtt._tcp.example.com` or + * `_mqtt._tcp.example.com` to discover which actual host to connect to. + * + * DNS SRV support is not usually compiled in to libmosquitto, use of this call + * is not recommended. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname to search for an SRV record. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_srv(struct mosquitto *mosq, const char *host, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_reconnect + * + * Reconnect to a broker. + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * call. It must not be called before + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_reconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_reconnect_async + * + * Reconnect to a broker. Non blocking version of . + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * or calls. It must not be + * called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reconnect_async(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect + * + * Disconnect from the broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + */ +libmosq_EXPORT int mosquitto_disconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect_v5 + * + * Disconnect from the broker, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * reason_code - the disconnect reason code. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with DISCONNECT. + */ +libmosq_EXPORT int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Publishing, subscribing, unsubscribing + * + * ====================================================================== */ +/* + * Function: mosquitto_publish + * + * Publish a message on a given topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + + +/* + * Function: mosquitto_publish_v5 + * + * Publish a message on a given topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Requires the mosquitto instance to be connected with MQTT 5. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with PUBLISH. + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_publish_v5( + struct mosquitto *mosq, + int *mid, + const char *topic, + int payloadlen, + const void *payload, + int qos, + bool retain, + const mosquitto_property *properties); + + +/* + * Function: mosquitto_subscribe + * + * Subscribe to a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos); + +/* + * Function: mosquitto_subscribe_v5 + * + * Subscribe to a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Requires the mosquitto instance to be connected with MQTT 5. + * + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * options - options to apply to this subscription, OR'd together. Set to 0 to + * use the default options, otherwise choose from the list: + * MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client + * publishes to a topic to which it is subscribed, the + * broker will not publish the message back to the + * client. + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages + * published for this subscription will keep the + * retain flag as was set by the publishing client. + * The default behaviour without this option set has + * the retain flag indicating whether a message is + * fresh/stale. + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set, + * pre-existing retained messages are sent as soon as + * the subscription is made, even if the subscription + * already exists. This is the default behaviour, so + * it is not necessary to set this option. + * MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing + * retained messages for this subscription will be + * sent when the subscription is made, but only if the + * subscription does not already exist. + * MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set, + * pre-existing retained messages will never be sent + * for this subscription. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with SUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_subscribe_multiple + * + * Subscribe to multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of subscriptions to be made + * sub - array of sub_count pointers, each pointing to a subscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * qos - the requested Quality of Service for each subscription. + * options - options to apply to this subscription, OR'd together. This + * argument is not used for MQTT v3 susbcriptions. Set to 0 to use + * the default options, otherwise choose from the list: + * MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client + * publishes to a topic to which it is subscribed, the + * broker will not publish the message back to the + * client. + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages + * published for this subscription will keep the + * retain flag as was set by the publishing client. + * The default behaviour without this option set has + * the retain flag indicating whether a message is + * fresh/stale. + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set, + * pre-existing retained messages are sent as soon as + * the subscription is made, even if the subscription + * already exists. This is the default behaviour, so + * it is not necessary to set this option. + * MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing + * retained messages for this subscription will be + * sent when the subscription is made, but only if the + * subscription does not already exist. + * MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set, + * pre-existing retained messages will never be sent + * for this subscription. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe + * + * Unsubscribe from a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub); + +/* + * Function: mosquitto_unsubscribe_v5 + * + * Unsubscribe from a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with UNSUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe_multiple + * + * Unsubscribe from multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of unsubscriptions to be made + * sub - array of sub_count pointers, each pointing to an unsubscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Struct mosquitto_message helper functions + * + * ====================================================================== */ +/* + * Function: mosquitto_message_copy + * + * Copy the contents of a mosquitto message to another message. + * Useful for preserving a message received in the on_message() callback. + * + * Parameters: + * dst - a pointer to a valid mosquitto_message struct to copy to. + * src - a pointer to a valid mosquitto_message struct to copy from. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src); + +/* + * Function: mosquitto_message_free + * + * Completely free a mosquitto_message struct. + * + * Parameters: + * message - pointer to a mosquitto_message pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_message_free(struct mosquitto_message **message); + +/* + * Function: mosquitto_message_free_contents + * + * Free a mosquitto_message struct contents, leaving the struct unaffected. + * + * Parameters: + * message - pointer to a mosquitto_message struct to free its contents. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_message_free_contents(struct mosquitto_message *message); + + +/* ====================================================================== + * + * Section: Network loop (managed by libmosquitto) + * + * The internal network loop must be called at a regular interval. The two + * recommended approaches are to use either or + * . is a blocking call and is + * suitable for the situation where you only want to handle incoming messages + * in callbacks. is a non-blocking call, it creates a + * separate thread to run the loop for you. Use this function when you have + * other tasks you need to run at the same time as the MQTT client, e.g. + * reading data from a sensor. + * + * ====================================================================== */ + +/* + * Function: mosquitto_loop_forever + * + * This function call loop() for you in an infinite blocking loop. It is useful + * for the case where you only want to run the MQTT client loop in your + * program. + * + * It handles reconnecting in case server connection is lost. If you call + * mosquitto_disconnect() in a callback it will return. + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets); + +/* + * Function: mosquitto_loop_start + * + * This is part of the threaded client interface. Call this once to start a new + * thread to process network traffic. This provides an alternative to + * repeatedly calling yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_start(struct mosquitto *mosq); + +/* + * Function: mosquitto_loop_stop + * + * This is part of the threaded client interface. Call this once to stop the + * network thread previously created with . This call + * will block until the network thread finishes. For the network thread to end, + * you must have previously called or have set the force + * parameter to true. + * + * Parameters: + * mosq - a valid mosquitto instance. + * force - set to true to force thread cancellation. If false, + * must have already been called. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_stop(struct mosquitto *mosq, bool force); + +/* + * Function: mosquitto_loop + * + * The main network loop for the client. This must be called frequently + * to keep communications between the client and broker working. This is + * carried out by and , which + * are the recommended ways of handling the network loop. You may also use this + * function if you wish. It must not be called inside a callback. + * + * If incoming data is present it will then be processed. Outgoing commands, + * from e.g. , are normally sent immediately that their + * function is called, but this is not always possible. will + * also attempt to send any remaining outgoing messages, which also includes + * commands that are part of the flow for messages with QoS>0. + * + * This calls select() to monitor the client network socket. If you want to + * integrate mosquitto client operation with your own select() call, use + * , , and + * . + * + * Threads: + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets); + +/* ====================================================================== + * + * Section: Network loop (for use in other event loops) + * + * ====================================================================== */ +/* + * Function: mosquitto_loop_read + * + * Carry out network read operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_read(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_write + * + * Carry out network write operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_write(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_misc + * + * Carry out miscellaneous operations required as part of the network loop. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * This function deals with handling PINGs and checking whether messages need + * to be retried, so should be called fairly frequently, around once per second + * is sufficient. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_misc(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Network loop (helper functions) + * + * ====================================================================== */ +/* + * Function: mosquitto_socket + * + * Return the socket handle for a mosquitto instance. Useful if you want to + * include a mosquitto client in your own select() calls. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * The socket for the mosquitto client or -1 on failure. + */ +libmosq_EXPORT int mosquitto_socket(struct mosquitto *mosq); + +/* + * Function: mosquitto_want_write + * + * Returns true if there is data ready to be written on the socket. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * See Also: + * , , + */ +libmosq_EXPORT bool mosquitto_want_write(struct mosquitto *mosq); + +/* + * Function: mosquitto_threaded_set + * + * Used to tell the library that your application is using threads, but not + * using . The library operates slightly differently when + * not in threaded mode in order to simplify its operation. If you are managing + * your own threads and do not use this function you will experience crashes + * due to race conditions. + * + * When using , this is set automatically. + * + * Parameters: + * mosq - a valid mosquitto instance. + * threaded - true if your application is using threads, false otherwise. + */ +libmosq_EXPORT int mosquitto_threaded_set(struct mosquitto *mosq, bool threaded); + + +/* ====================================================================== + * + * Section: Client options + * + * ====================================================================== */ +/* + * Function: mosquitto_opts_set + * + * Used to set options for the client. + * + * This function is deprecated, the replacement and + * functions should be used instead. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_PROTOCOL_VERSION + * Value must be an int, set to either MQTT_PROTOCOL_V31 or + * MQTT_PROTOCOL_V311. Must be set before the client connects. + * Defaults to MQTT_PROTOCOL_V31. + * + * MOSQ_OPT_SSL_CTX + * Pass an openssl SSL_CTX to be used when creating TLS connections + * rather than libmosquitto creating its own. This must be called + * before connecting to have any effect. If you use this option, the + * onus is on you to ensure that you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS + * Value must be an int set to 1 or 0. If set to 1, then the user + * specified SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the + * default options applied to it. This means that you only need to + * change the values that are relevant to you. If you use this + * option then you must configure the TLS options as normal, i.e. + * you should use to configure the cafile/capath + * as a minimum. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + +/* + * Function: mosquitto_int_option + * + * Used to set integer options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_PROTOCOL_VERSION - + * Value must be set to either MQTT_PROTOCOL_V31, + * MQTT_PROTOCOL_V311, or MQTT_PROTOCOL_V5. Must be set before the + * client connects. Defaults to MQTT_PROTOCOL_V311. + * + * MOSQ_OPT_RECEIVE_MAXIMUM - + * Value can be set between 1 and 65535 inclusive, and represents + * the maximum number of incoming QoS 1 and QoS 2 messages that this + * client wants to process at once. Defaults to 20. This option is + * not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the MQTT_PROP_RECEIVE_MAXIMUM property is in the + * proplist passed to mosquitto_connect_v5(), then that property + * will override this option. Using this option is the recommended + * method however. + * + * MOSQ_OPT_SEND_MAXIMUM - + * Value can be set between 1 and 65535 inclusive, and represents + * the maximum number of outgoing QoS 1 and QoS 2 messages that this + * client will attempt to have "in flight" at once. Defaults to 20. + * This option is not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the broker being connected to sends a + * MQTT_PROP_RECEIVE_MAXIMUM property that has a lower value than + * this option, then the broker provided value will be used. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS - + * If value is set to a non zero value, then the user specified + * SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the default + * options applied to it. This means that you only need to change + * the values that are relevant to you. If you use this option then + * you must configure the TLS options as normal, i.e. you should + * use to configure the cafile/capath as a + * minimum. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_TLS_OCSP_REQUIRED - + * Set whether OCSP checking on TLS connections is required. Set to + * 1 to enable checking, or 0 (the default) for no checking. + */ +libmosq_EXPORT int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t option, int value); + + +/* + * Function: mosquitto_void_option + * + * Used to set void* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_SSL_CTX - + * Pass an openssl SSL_CTX to be used when creating TLS connections + * rather than libmosquitto creating its own. This must be called + * before connecting to have any effect. If you use this option, the + * onus is on you to ensure that you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_void_option(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + +/* + * Function: mosquitto_max_inflight_messages_set + * + * This function is deprected. Use the function with the + * MOSQ_OPT_SEND_MAXIMUM option instead. + * + * Set the number of QoS 1 and 2 messages that can be "in flight" at one time. + * An in flight message is part way through its delivery flow. Attempts to send + * further messages with will result in the messages being + * queued until the number of in flight messages reduces. + * + * A higher number here results in greater message throughput, but if set + * higher than the maximum in flight messages on the broker may lead to + * delays in the messages being acknowledged. + * + * Set to 0 for no maximum. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_inflight_messages - the maximum number of inflight messages. Defaults + * to 20. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages); + +/* + * Function: mosquitto_message_retry_set + * + * This function now has no effect. + */ +libmosq_EXPORT void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry); + +/* + * Function: mosquitto_user_data_set + * + * When is called, the pointer given as the "obj" parameter + * will be passed to the callbacks as user data. The + * function allows this obj parameter to be updated at any time. This function + * will not modify the memory pointed to by the current user data pointer. If + * it is dynamically allocated memory you must free it yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * obj - A user pointer that will be passed as an argument to any callbacks + * that are specified. + */ +libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj); + +/* Function: mosquitto_userdata + * + * Retrieve the "userdata" variable for a mosquitto client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * A pointer to the userdata member variable. + */ +libmosq_EXPORT void *mosquitto_userdata(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: TLS support + * + * ====================================================================== */ +/* + * Function: mosquitto_tls_set + * + * Configure the client for certificate based SSL/TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Define the Certificate Authority certificates to be trusted (ie. the server + * certificate must be signed with one of these certificates) using cafile. + * + * If the server you are connecting to requires clients to provide a + * certificate, define certfile and keyfile with your client certificate and + * private key. If your private key is encrypted, provide a password callback + * function or you will have to enter the password at the command line. + * + * Parameters: + * mosq - a valid mosquitto instance. + * cafile - path to a file containing the PEM encoded trusted CA + * certificate files. Either cafile or capath must not be NULL. + * capath - path to a directory containing the PEM encoded trusted CA + * certificate files. See mosquitto.conf for more details on + * configuring this directory. Either cafile or capath must not + * be NULL. + * certfile - path to a file containing the PEM encoded certificate file + * for this client. If NULL, keyfile must also be NULL and no + * client certificate will be used. + * keyfile - path to a file containing the PEM encoded private key for + * this client. If NULL, certfile must also be NULL and no + * client certificate will be used. + * pw_callback - if keyfile is encrypted, set pw_callback to allow your client + * to pass the correct password for decryption. If set to NULL, + * the password must be entered on the command line. + * Your callback must write the password into "buf", which is + * "size" bytes long. The return value must be the length of the + * password. "userdata" will be set to the calling mosquitto + * instance. The mosquitto userdata member variable can be + * retrieved using . + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , , + * , + */ +libmosq_EXPORT int mosquitto_tls_set(struct mosquitto *mosq, + const char *cafile, const char *capath, + const char *certfile, const char *keyfile, + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)); + +/* + * Function: mosquitto_tls_insecure_set + * + * Configure verification of the server hostname in the server certificate. If + * value is set to true, it is impossible to guarantee that the host you are + * connecting to is not impersonating your server. This can be useful in + * initial server testing, but makes it possible for a malicious third party to + * impersonate your server through DNS spoofing, for example. + * Do not use this function in a real system. Setting value to true makes the + * connection encryption pointless. + * Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * value - if set to false, the default, certificate hostname checking is + * performed. If set to true, no hostname checking is performed and + * the connection is insecure. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_insecure_set(struct mosquitto *mosq, bool value); + +/* + * Function: mosquitto_tls_opts_set + * + * Set advanced SSL/TLS options. Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * cert_reqs - an integer defining the verification requirements the client + * will impose on the server. This can be one of: + * * SSL_VERIFY_NONE (0): the server will not be verified in any way. + * * SSL_VERIFY_PEER (1): the server certificate will be verified + * and the connection aborted if the verification fails. + * The default and recommended value is SSL_VERIFY_PEER. Using + * SSL_VERIFY_NONE provides no security. + * tls_version - the version of the SSL/TLS protocol to use as a string. If NULL, + * the default value is used. The default value and the + * available values depend on the version of openssl that the + * library was compiled against. For openssl >= 1.0.1, the + * available options are tlsv1.2, tlsv1.1 and tlsv1, with tlv1.2 + * as the default. For openssl < 1.0.1, only tlsv1 is available. + * ciphers - a string describing the ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tls_version, const char *ciphers); + +/* + * Function: mosquitto_tls_psk_set + * + * Configure the client for pre-shared-key based TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Parameters: + * mosq - a valid mosquitto instance. + * psk - the pre-shared-key in hex format with no leading "0x". + * identity - the identity of this client. May be used as the username + * depending on the server settings. + * ciphers - a string describing the PSK ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers); + + +/* ====================================================================== + * + * Section: Callbacks + * + * ====================================================================== */ +/* + * Function: mosquitto_connect_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_connect_with_flags_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * flags - the connect flags. + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int)); + +/* + * Function: mosquitto_connect_v5_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + * flags - the connect flags. + * props - list of MQTT 5 properties, or NULL + * + */ +libmosq_EXPORT void mosquitto_connect_v5_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int, const mosquitto_property *props)); + +/* + * Function: mosquitto_disconnect_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + */ +libmosq_EXPORT void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_disconnect_v5_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_disconnect_v5_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *)); + +/* + * Function: mosquitto_publish_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker successfully. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + */ +libmosq_EXPORT void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_publish_v5_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker. This callback will be + * called both if the message is sent successfully, or if the broker responded + * with an error, which will be reflected in the reason_code parameter. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + * reason_code - the MQTT 5 reason code + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_publish_v5_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int, int, const mosquitto_property *)); + +/* + * Function: mosquitto_message_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *)); + +/* + * Function: mosquitto_message_v5_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * props - list of MQTT 5 properties, or NULL + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_v5_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *, const mosquitto_property *)); + +/* + * Function: mosquitto_subscribe_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + */ +libmosq_EXPORT void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *)); + +/* + * Function: mosquitto_subscribe_v5_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_subscribe_v5_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *)); + +/* + * Function: mosquitto_unsubscribe_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + */ +libmosq_EXPORT void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_unsubscribe_v5_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, const mosquitto_property *)); + +/* + * Function: mosquitto_log_callback_set + * + * Set the logging callback. This should be used if you want event logging + * information from the client library. + * + * mosq - a valid mosquitto instance. + * on_log - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int level, const char *str) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * level - the log message level from the values: + * MOSQ_LOG_INFO + * MOSQ_LOG_NOTICE + * MOSQ_LOG_WARNING + * MOSQ_LOG_ERR + * MOSQ_LOG_DEBUG + * str - the message string. + */ +libmosq_EXPORT void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *)); + +/* + * Function: mosquitto_string_option + * + * Used to set const char* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_TLS_ENGINE + * Configure the client for TLS Engine support. Pass a TLS Engine ID + * to be used when creating TLS connections. + * Must be set before . + * MOSQ_OPT_TLS_KEYFORM + * Configure the client to treat the keyfile differently depending + * on its type. Must be set before . + * Set as either "pem" or "engine", to determine from where the + * private key for a TLS connection will be obtained. Defaults to + * "pem", a normal private key file. + * MOSQ_OPT_TLS_KPASS_SHA1 + * Where the TLS Engine requires the use of a password to be + * accessed, this option allows a hex encoded SHA1 hash of the + * private key password to be passed to the engine directly. + * Must be set before . + * MOSQ_OPT_TLS_ALPN + * If the broker being connected to has multiple services available + * on a single TLS port, such as both MQTT and WebSockets, use this + * option to configure the ALPN option for the connection. + */ +libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value); + + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + + +/* ============================================================================= + * + * Section: SOCKS5 proxy functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_socks5_set + * + * Configure the client to use a SOCKS5 proxy when connecting. Must be called + * before connecting. "None" and "username/password" authentication is + * supported. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the SOCKS5 proxy host to connect to. + * port - the SOCKS5 proxy port to use. + * username - if not NULL, use this username when authenticating with the proxy. + * password - if not NULL and username is not NULL, use this password when + * authenticating with the proxy. + */ +libmosq_EXPORT int mosquitto_socks5_set(struct mosquitto *mosq, const char *host, int port, const char *username, const char *password); + + +/* ============================================================================= + * + * Section: Utility functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_strerror + * + * Call to obtain a const string description of a mosquitto error number. + * + * Parameters: + * mosq_errno - a mosquitto error number. + * + * Returns: + * A constant string describing the error. + */ +libmosq_EXPORT const char *mosquitto_strerror(int mosq_errno); + +/* + * Function: mosquitto_connack_string + * + * Call to obtain a const string description of an MQTT connection result. + * + * Parameters: + * connack_code - an MQTT connection result. + * + * Returns: + * A constant string describing the result. + */ +libmosq_EXPORT const char *mosquitto_connack_string(int connack_code); + +/* + * Function: mosquitto_reason_string + * + * Call to obtain a const string description of an MQTT reason code. + * + * Parameters: + * reason_code - an MQTT reason code. + * + * Returns: + * A constant string describing the reason. + */ +libmosq_EXPORT const char *mosquitto_reason_string(int reason_code); + +/* Function: mosquitto_string_to_command + * + * Take a string input representing an MQTT command and convert it to the + * libmosquitto integer representation. + * + * Parameters: + * str - the string to parse. + * cmd - pointer to an int, for the result. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - on an invalid input. + * + * Example: + * mosquitto_string_to_command("CONNECT", &cmd); + * // cmd == CMD_CONNECT + */ +libmosq_EXPORT int mosquitto_string_to_command(const char *str, int *cmd); + +/* + * Function: mosquitto_sub_topic_tokenise + * + * Tokenise a topic or subscription string into an array of strings + * representing the topic hierarchy. + * + * For example: + * + * subtopic: "a/deep/topic/hierarchy" + * + * Would result in: + * + * topics[0] = "a" + * topics[1] = "deep" + * topics[2] = "topic" + * topics[3] = "hierarchy" + * + * and: + * + * subtopic: "/a/deep/topic/hierarchy/" + * + * Would result in: + * + * topics[0] = NULL + * topics[1] = "a" + * topics[2] = "deep" + * topics[3] = "topic" + * topics[4] = "hierarchy" + * + * Parameters: + * subtopic - the subscription/topic to tokenise + * topics - a pointer to store the array of strings + * count - an int pointer to store the number of items in the topics array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * + * Example: + * + * > char **topics; + * > int topic_count; + * > int i; + * > + * > mosquitto_sub_topic_tokenise("$SYS/broker/uptime", &topics, &topic_count); + * > + * > for(i=0; i printf("%d: %s\n", i, topics[i]); + * > } + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *count); + +/* + * Function: mosquitto_sub_topic_tokens_free + * + * Free memory that was allocated in . + * + * Parameters: + * topics - pointer to string array. + * count - count of items in string array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokens_free(char ***topics, int count); + +/* + * Function: mosquitto_topic_matches_sub + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * topic - topic to check. + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result); + + +/* + * Function: mosquitto_topic_matches_sub2 + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * sublen - length in bytes of sub string + * topic - topic to check. + * topiclen - length in bytes of topic string + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub2(const char *sub, size_t sublen, const char *topic, size_t topiclen, bool *result); + +/* + * Function: mosquitto_pub_topic_check + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check(const char *topic); + +/* + * Function: mosquitto_pub_topic_check2 + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - length of the topic in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check2(const char *topic, size_t topiclen); + +/* + * Function: mosquitto_sub_topic_check + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check(const char *topic); + +/* + * Function: mosquitto_sub_topic_check2 + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - the length in bytes of the topic + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check2(const char *topic, size_t topiclen); + + +/* + * Function: mosquitto_validate_utf8 + * + * Helper function to validate whether a UTF-8 string is valid, according to + * the UTF-8 spec and the MQTT additions. + * + * Parameters: + * str - a string to check + * len - the length of the string in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if str is NULL or len<0 or len>65536 + * MOSQ_ERR_MALFORMED_UTF8 - if str is not valid UTF-8 + */ +libmosq_EXPORT int mosquitto_validate_utf8(const char *str, int len); + + +/* ============================================================================= + * + * Section: One line client helper functions + * + * ============================================================================= + */ + +struct libmosquitto_will { + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct libmosquitto_auth { + char *username; + char *password; +}; + +struct libmosquitto_tls { + char *cafile; + char *capath; + char *certfile; + char *keyfile; + char *ciphers; + char *tls_version; + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata); + int cert_reqs; +}; + +/* + * Function: mosquitto_subscribe_simple + * + * Helper function to make subscribing to a topic and retrieving some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, waits for msg_count + * messages to be received, then returns after disconnecting cleanly. + * + * Parameters: + * messages - pointer to a "struct mosquitto_message *". The received + * messages will be returned here. On error, this will be set to + * NULL. + * msg_count - the number of messages to retrieve. + * want_retained - if set to true, stale retained messages will be treated as + * normal messages with regards to msg_count. If set to + * false, they will be ignored. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * >0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool want_retained, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* + * Function: mosquitto_subscribe_callback + * + * Helper function to make subscribing to a topic and processing some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, then passes received + * messages to a user provided callback. If the callback returns a 1, it then + * disconnects cleanly and returns. + * + * Parameters: + * callback - a callback function in the following form: + * int callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * Note that this is the same as the normal on_message callback, + * except that it returns an int. + * userdata - user provided pointer that will be passed to the callback. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * >0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* ============================================================================= + * + * Section: Properties + * + * ============================================================================= + */ + + +/* + * Function: mosquitto_property_add_byte + * + * Add a new byte property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_byte(&proplist, MQTT_PROP_PAYLOAD_FORMAT_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value); + +/* + * Function: mosquitto_property_add_int16 + * + * Add a new int16 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_RECEIVE_MAXIMUM) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_int16(&proplist, MQTT_PROP_RECEIVE_MAXIMUM, 1000); + */ +libmosq_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value); + +/* + * Function: mosquitto_property_add_int32 + * + * Add a new int32 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_MESSAGE_EXPIRY_INTERVAL) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_int32(&proplist, MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, 86400); + */ +libmosq_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_varint + * + * Add a new varint property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_SUBSCRIPTION_IDENTIFIER) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_varint(&proplist, MQTT_PROP_SUBSCRIPTION_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_binary + * + * Add a new binary property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to the property data + * len - length of property data in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_binary(&proplist, MQTT_PROP_AUTHENTICATION_DATA, auth_data, auth_data_len); + */ +libmosq_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len); + +/* + * Function: mosquitto_property_add_string + * + * Add a new string property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_CONTENT_TYPE) + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - value is not valid UTF-8. + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_string(&proplist, MQTT_PROP_CONTENT_TYPE, "application/json"); + */ +libmosq_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value); + +/* + * Function: mosquitto_property_add_string_pair + * + * Add a new string pair property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_USER_PROPERTY) + * name - string name for the new property, must be UTF-8 and zero terminated + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if name or value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - if name or value are not valid UTF-8. + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_string_pair(&proplist, MQTT_PROP_USER_PROPERTY, "client", "mosquitto_pub"); + */ +libmosq_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value); + +/* + * Function: mosquitto_property_read_byte + * + * Attempt to read a byte property matching an identifier, from a property list + * or single property. This function can search for multiple entries of the + * same identifier by using the returned value and skip_first. Note however + * that it is forbidden for most properties to be duplicated. + * + * If the property is not found, *value will not be modified, so it is safe to + * pass a variable with a default value to be potentially overwritten: + * + * uint16_t keepalive = 60; // default value + * // Get value from property list, or keep default if not found. + * mosquitto_property_read_int16(proplist, MQTT_PROP_SERVER_KEEP_ALIVE, &keepalive, false); + * + * Parameters: + * proplist - mosquitto_property pointer, the list of properties or single property + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * // proplist is obtained from a callback + * mosquitto_property *prop; + * prop = mosquitto_property_read_byte(proplist, identifier, &value, false); + * while(prop){ + * printf("value: %s\n", value); + * prop = mosquitto_property_read_byte(prop, identifier, &value); + * } + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_byte( + const mosquitto_property *proplist, + int identifier, + uint8_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int16 + * + * Read an int16 property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int16( + const mosquitto_property *proplist, + int identifier, + uint16_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int32 + * + * Read an int32 property value from a property. + * + * Parameters: + * property - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int32( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_varint + * + * Read a varint property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_varint( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_binary + * + * Read a binary property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_binary( + const mosquitto_property *proplist, + int identifier, + void **value, + uint16_t *len, + bool skip_first); + +/* + * Function: mosquitto_property_read_string + * + * Read a string property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string( + const mosquitto_property *proplist, + int identifier, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_read_string_pair + * + * Read a string pair property value pair from a property. + * + * On success, name and value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * name - pointer to char* for the name property data to be stored in, or NULL + * if the name is not required. + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string_pair( + const mosquitto_property *proplist, + int identifier, + char **name, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_free_all + * + * Free all properties from a list of properties. Frees the list and sets *properties to NULL. + * + * Parameters: + * properties - list of properties to free + * + * Example: + * mosquitto_properties *properties = NULL; + * // Add properties + * mosquitto_property_free_all(&properties); + */ +libmosq_EXPORT void mosquitto_property_free_all(mosquitto_property **properties); + +/* + * Function: mosquitto_property_copy_all + * + * Parameters: + * dest : pointer for new property list + * src : property list + * + * Returns: + * MOSQ_ERR_SUCCESS - on successful copy + * MOSQ_ERR_INVAL - if dest is NULL + * MOSQ_ERR_NOMEM - on out of memory (dest will be set to NULL) + */ +libmosq_EXPORT int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_property *src); + +/* + * Function: mosquitto_property_check_command + * + * Check whether a property identifier is valid for the given command. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * identifier - MQTT property (e.g. MQTT_PROP_USER_PROPERTY) + * + * Returns: + * MOSQ_ERR_SUCCESS - if the identifier is valid for command + * MOSQ_ERR_PROTOCOL - if the identifier is not valid for use with command. + */ +libmosq_EXPORT int mosquitto_property_check_command(int command, int identifier); + + +/* + * Function: mosquitto_property_check_all + * + * Check whether a list of properties are valid for a particular command, + * whether there are duplicates, and whether the values are valid where + * possible. + * + * Note that this function is used internally in the library whenever + * properties are passed to it, so in basic use this is not needed, but should + * be helpful to check property lists *before* the point of using them. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * properties - list of MQTT properties to check. + * + * Returns: + * MOSQ_ERR_SUCCESS - if all properties are valid + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid + */ +libmosq_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties); + +/* Function: mosquitto_string_to_property_info + * + * Parse a property name string and convert to a property identifier and data type. + * The property name is as defined in the MQTT specification, with - as a + * separator, for example: payload-format-indicator. + * + * Parameters: + * propname - the string to parse + * identifier - pointer to an int to receive the property identifier + * type - pointer to an int to receive the property type + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the string does not match a property + * + * Example: + * mosquitto_string_to_property_info("response-topic", &id, &type); + * // id == MQTT_PROP_RESPONSE_TOPIC + * // type == MQTT_PROP_TYPE_STRING + */ +libmosq_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/dgls_mqttclient/mosquitto_plugin.h b/product/src/fes/protocol/dgls_mqttclient/mosquitto_plugin.h new file mode 100644 index 00000000..99374bee --- /dev/null +++ b/product/src/fes/protocol/dgls_mqttclient/mosquitto_plugin.h @@ -0,0 +1,319 @@ +/* +Copyright (c) 2012-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_PLUGIN_H +#define MOSQUITTO_PLUGIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MOSQ_AUTH_PLUGIN_VERSION 4 + +#define MOSQ_ACL_NONE 0x00 +#define MOSQ_ACL_READ 0x01 +#define MOSQ_ACL_WRITE 0x02 +#define MOSQ_ACL_SUBSCRIBE 0x04 + +#include +#include + +struct mosquitto; + +struct mosquitto_opt { + char *key; + char *value; +}; + +struct mosquitto_auth_opt { + char *key; + char *value; +}; + +struct mosquitto_acl_msg { + const char *topic; + const void *payload; + long payloadlen; + int qos; + bool retain; +}; + +/* + * To create an authentication plugin you must include this file then implement + * the functions listed in the "Plugin Functions" section below. The resulting + * code should then be compiled as a shared library. Using gcc this can be + * achieved as follows: + * + * gcc -I -fPIC -shared plugin.c -o plugin.so + * + * On Mac OS X: + * + * gcc -I -fPIC -shared plugin.c -undefined dynamic_lookup -o plugin.so + * + * Authentication plugins can implement one or both of authentication and + * access control. If your plugin does not wish to handle either of + * authentication or access control it should return MOSQ_ERR_PLUGIN_DEFER. In + * this case, the next plugin will handle it. If all plugins return + * MOSQ_ERR_PLUGIN_DEFER, the request will be denied. + * + * For each check, the following flow happens: + * + * * The default password file and/or acl file checks are made. If either one + * of these is not defined, then they are considered to be deferred. If either + * one accepts the check, no further checks are made. If an error occurs, the + * check is denied + * * The first plugin does the check, if it returns anything other than + * MOSQ_ERR_PLUGIN_DEFER, then the check returns immediately. If the plugin + * returns MOSQ_ERR_PLUGIN_DEFER then the next plugin runs its check. + * * If the final plugin returns MOSQ_ERR_PLUGIN_DEFER, then access will be + * denied. + */ + +/* ========================================================================= + * + * Helper Functions + * + * ========================================================================= */ + +/* There are functions that are available for plugin developers to use in + * mosquitto_broker.h, including logging and accessor functions. + */ + + +/* ========================================================================= + * + * Plugin Functions + * + * You must implement these functions in your plugin. + * + * ========================================================================= */ + +/* + * Function: mosquitto_auth_plugin_version + * + * The broker will call this function immediately after loading the plugin to + * check it is a supported plugin version. Your code must simply return + * MOSQ_AUTH_PLUGIN_VERSION. + */ +int mosquitto_auth_plugin_version(void); + + +/* + * Function: mosquitto_auth_plugin_init + * + * Called after the plugin has been loaded and + * has been called. This will only ever be called once and can be used to + * initialise the plugin. + * + * Parameters: + * + * user_data : The pointer set here will be passed to the other plugin + * functions. Use to hold connection information for example. + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_plugin_cleanup + * + * Called when the broker is shutting down. This will only ever be called once + * per plugin. + * Note that will be called directly before + * this function. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_security_init + * + * This function is called in two scenarios: + * + * 1. When the broker starts up. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, will be called first, then + * this function will be called. In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_init(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_security_cleanup + * + * This function is called in two scenarios: + * + * 1. When the broker is shutting down. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, this function will be called, followed by + * . In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_acl_check + * + * Called by the broker when topic access must be checked. access will be one + * of: + * MOSQ_ACL_SUBSCRIBE when a client is asking to subscribe to a topic string. + * This differs from MOSQ_ACL_READ in that it allows you to + * deny access to topic strings rather than by pattern. For + * example, you may use MOSQ_ACL_SUBSCRIBE to deny + * subscriptions to '#', but allow all topics in + * MOSQ_ACL_READ. This allows clients to subscribe to any + * topic they want, but not discover what topics are in use + * on the server. + * MOSQ_ACL_READ when a message is about to be sent to a client (i.e. whether + * it can read that topic or not). + * MOSQ_ACL_WRITE when a message has been received from a client (i.e. whether + * it can write to that topic or not). + * + * Return: + * MOSQ_ERR_SUCCESS if access was granted. + * MOSQ_ERR_ACL_DENIED if access was not granted. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_acl_check(void *user_data, int access, struct mosquitto *client, const struct mosquitto_acl_msg *msg); + + +/* + * Function: mosquitto_auth_unpwd_check + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making basic username/password checks. + * + * Called by the broker when a username/password must be checked. + * + * Return: + * MOSQ_ERR_SUCCESS if the user is authenticated. + * MOSQ_ERR_AUTH if authentication failed. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_unpwd_check(void *user_data, struct mosquitto *client, const char *username, const char *password); + + +/* + * Function: mosquitto_psk_key_get + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making TLS-PSK checks. + * + * Called by the broker when a client connects to a listener using TLS/PSK. + * This is used to retrieve the pre-shared-key associated with a client + * identity. + * + * Examine hint and identity to determine the required PSK (which must be a + * hexadecimal string with no leading "0x") and copy this string into key. + * + * Parameters: + * user_data : the pointer provided in . + * hint : the psk_hint for the listener the client is connecting to. + * identity : the identity string provided by the client + * key : a string where the hex PSK should be copied + * max_key_len : the size of key + * + * Return value: + * Return 0 on success. + * Return >0 on failure. + * Return MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_psk_key_get(void *user_data, struct mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len); + +/* + * Function: mosquitto_auth_start + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making extended authentication checks. + * + * Parameters: + * user_data : the pointer provided in . + * method : the authentication method + * reauth : this is set to false if this is the first authentication attempt + * on a connection, set to true if the client is attempting to + * reauthenticate. + * data_in : pointer to authentication data, or NULL + * data_in_len : length of data_in, in bytes + * data_out : if your plugin wishes to send authentication data back to the + * client, allocate some memory using malloc or friends and set + * data_out. The broker will free the memory after use. + * data_out_len : Set the length of data_out in bytes. + * + * Return value: + * Return MOSQ_ERR_SUCCESS if authentication was successful. + * Return MOSQ_ERR_AUTH_CONTINUE if the authentication is a multi step process and can continue. + * Return MOSQ_ERR_AUTH if authentication was valid but did not succeed. + * Return any other relevant positive integer MOSQ_ERR_* to produce an error. + */ +int mosquitto_auth_start(void *user_data, struct mosquitto *client, const char *method, bool reauth, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + +int mosquitto_auth_continue(void *user_data, struct mosquitto *client, const char *method, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/dgls_mqttclient/mosquittopp.h b/product/src/fes/protocol/dgls_mqttclient/mosquittopp.h new file mode 100644 index 00000000..d3f388c0 --- /dev/null +++ b/product/src/fes/protocol/dgls_mqttclient/mosquittopp.h @@ -0,0 +1,146 @@ +/* +Copyright (c) 2010-2019 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTOPP_H +#define MOSQUITTOPP_H + +#if defined(_WIN32) && !defined(LIBMOSQUITTO_STATIC) +# ifdef mosquittopp_EXPORTS +# define mosqpp_EXPORT __declspec(dllexport) +# else +# define mosqpp_EXPORT __declspec(dllimport) +# endif +#else +# define mosqpp_EXPORT +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define DEPRECATED __attribute__ ((deprecated)) +#else +# define DEPRECATED +#endif + +#include +#include +#include + +namespace mosqpp { + + +mosqpp_EXPORT const char * DEPRECATED strerror(int mosq_errno); +mosqpp_EXPORT const char * DEPRECATED connack_string(int connack_code); +mosqpp_EXPORT int DEPRECATED sub_topic_tokenise(const char *subtopic, char ***topics, int *count); +mosqpp_EXPORT int DEPRECATED sub_topic_tokens_free(char ***topics, int count); +mosqpp_EXPORT int DEPRECATED lib_version(int *major, int *minor, int *revision); +mosqpp_EXPORT int DEPRECATED lib_init(); +mosqpp_EXPORT int DEPRECATED lib_cleanup(); +mosqpp_EXPORT int DEPRECATED topic_matches_sub(const char *sub, const char *topic, bool *result); +mosqpp_EXPORT int DEPRECATED validate_utf8(const char *str, int len); +mosqpp_EXPORT int DEPRECATED subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool retained, + const char *topic, + int qos=0, + const char *host="localhost", + int port=1883, + const char *client_id=NULL, + int keepalive=60, + bool clean_session=true, + const char *username=NULL, + const char *password=NULL, + const struct libmosquitto_will *will=NULL, + const struct libmosquitto_tls *tls=NULL); + +mosqpp_EXPORT int DEPRECATED subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos=0, + bool retained=true, + const char *host="localhost", + int port=1883, + const char *client_id=NULL, + int keepalive=60, + bool clean_session=true, + const char *username=NULL, + const char *password=NULL, + const struct libmosquitto_will *will=NULL, + const struct libmosquitto_tls *tls=NULL); + +/* + * Class: mosquittopp + * + * A mosquitto client class. This is a C++ wrapper class for the mosquitto C + * library. Please see mosquitto.h for details of the functions. + */ +class mosqpp_EXPORT DEPRECATED mosquittopp { + private: + struct mosquitto *m_mosq; + public: + DEPRECATED mosquittopp(const char *id=NULL, bool clean_session=true); + virtual ~mosquittopp(); + + int DEPRECATED reinitialise(const char *id, bool clean_session); + int DEPRECATED socket(); + int DEPRECATED will_set(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int DEPRECATED will_clear(); + int DEPRECATED username_pw_set(const char *username, const char *password=NULL); + int DEPRECATED connect(const char *host, int port=1883, int keepalive=60); + int DEPRECATED connect_async(const char *host, int port=1883, int keepalive=60); + int DEPRECATED connect(const char *host, int port, int keepalive, const char *bind_address); + int DEPRECATED connect_async(const char *host, int port, int keepalive, const char *bind_address); + int DEPRECATED reconnect(); + int DEPRECATED reconnect_async(); + int DEPRECATED disconnect(); + int DEPRECATED publish(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int DEPRECATED subscribe(int *mid, const char *sub, int qos=0); + int DEPRECATED unsubscribe(int *mid, const char *sub); + void DEPRECATED reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + int DEPRECATED max_inflight_messages_set(unsigned int max_inflight_messages); + void DEPRECATED message_retry_set(unsigned int message_retry); + void DEPRECATED user_data_set(void *userdata); + int DEPRECATED tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL); + int DEPRECATED tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL); + int DEPRECATED tls_insecure_set(bool value); + int DEPRECATED tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL); + int DEPRECATED opts_set(enum mosq_opt_t option, void *value); + + int DEPRECATED loop(int timeout=-1, int max_packets=1); + int DEPRECATED loop_misc(); + int DEPRECATED loop_read(int max_packets=1); + int DEPRECATED loop_write(int max_packets=1); + int DEPRECATED loop_forever(int timeout=-1, int max_packets=1); + int DEPRECATED loop_start(); + int DEPRECATED loop_stop(bool force=false); + bool DEPRECATED want_write(); + int DEPRECATED threaded_set(bool threaded=true); + int DEPRECATED socks5_set(const char *host, int port=1080, const char *username=NULL, const char *password=NULL); + + // names in the functions commented to prevent unused parameter warning + virtual void on_connect(int /*rc*/) {return;} + virtual void on_connect_with_flags(int /*rc*/, int /*flags*/) {return;} + virtual void on_disconnect(int /*rc*/) {return;} + virtual void on_publish(int /*mid*/) {return;} + virtual void on_message(const struct mosquitto_message * /*message*/) {return;} + virtual void on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/) {return;} + virtual void on_unsubscribe(int /*mid*/) {return;} + virtual void on_log(int /*level*/, const char * /*str*/) {return;} + virtual void on_error() {return;} +}; + +} +#endif diff --git a/product/src/fes/protocol/dlt645/DLT645.cpp b/product/src/fes/protocol/dlt645/DLT645.cpp index a1034a9b..cad04602 100644 --- a/product/src/fes/protocol/dlt645/DLT645.cpp +++ b/product/src/fes/protocol/dlt645/DLT645.cpp @@ -11,7 +11,19 @@ #include "pub_utility_api/I18N.h" #include + +//< 屏蔽xml_parser编译告警 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-copy" +#endif + #include "boost/property_tree/xml_parser.hpp" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "boost/typeof/typeof.hpp" #include "boost/filesystem.hpp" #include @@ -58,6 +70,8 @@ int EX_ChanTimer(int ChanNo) int EX_ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + g_DLT645ChanelRun=false;//使所有的线程退出。 DLT645.InformTcpThreadExit(); return iotSuccess; @@ -114,6 +128,7 @@ int CDLT645::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) CFesChanPtr ptrMainFesChan; CFesChanPtr ptrFesChan; + if (m_ptrCFesBase == NULL) return iotFailed; @@ -141,6 +156,21 @@ int CDLT645::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) ptrCSerialPort->resume(); //start SerialPort THREAD } break; + case CN_FesTcpClient: + if(ptrFesChan->m_ComThreadRun == CN_FesStopFlag) + { + //open chan thread + CTcpClientThreadPtr ptrCTcpClient; + ptrCTcpClient = boost::make_shared(ptrFesChan); + if (ptrCTcpClient == NULL) + { + LOGERROR("CIEC104 EX_OpenChan() ChanNo:%d create CTcpClientThread error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + m_CTcpClientQueue.push_back(ptrCTcpClient); + ptrCTcpClient->resume(); //start TCP CLIENT THREAD + } + break; default: return iotFailed; } @@ -203,6 +233,14 @@ int CDLT645::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) //ptrFesChan->m_ComThreadRun = CN_FesStopFlag; } break; + case CN_FesTcpClient: + if (ptrFesChan->m_ComThreadRun == CN_FesRunFlag) + { + //close chan thread + ClearTcpClientThreadByChanNo(ChanNo); + //ptrFesChan->m_ComThreadRun = CN_FesStopFlag; + } + break; default: return iotFailed; } @@ -253,6 +291,26 @@ void CDLT645::ClearSerialPortThreadByChanNo(int ChanNo) } } +void CDLT645::ClearTcpClientThreadByChanNo(int ChanNo) +{ + int tempNum; + CTcpClientThreadPtr ptrTcp; + + if ((tempNum = (int)m_CTcpClientQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CTcpClientQueue.begin();it!=m_CTcpClientQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CTcpClientQueue.erase(it);//会调用CTcpClientThread::~CTcpClientThreadPtr()退出线程 + LOGDEBUG("CDLT645::ClearTcpClientThreadByChanNo %d ok",ChanNo); + break; + } + } +} + void CDLT645::ClearDataProcThreadByChanNo(int ChanNo) { int tempNum; @@ -280,18 +338,39 @@ void CDLT645::ClearDataProcThreadByChanNo(int ChanNo) */ void CDLT645::InformTcpThreadExit() { - CSerialPortThreadPtr ptrSerial; + //CSerialPortThreadPtr ptrSerial; + CSerialPortThreadPtr ptrPort; + CTcpClientThreadPtr ptrTcp; LOGDEBUG("CDLT645::InformTcpThreadExit: 收到退出信号"); - if (m_CSerialPortQueue.size()<=0) - return; - vector::iterator it; - for (it = m_CSerialPortQueue.begin();it!=m_CSerialPortQueue.end();it++) +// if (m_CSerialPortQueue.size()<=0) +// return; + if (m_CSerialPortQueue.size() > 0) { - ptrSerial = *it; - ptrSerial->SetThreadRunFlag(0); + vector::iterator it; + for (it = m_CSerialPortQueue.begin(); it != m_CSerialPortQueue.end(); it++) + { + ptrPort = *it; + ptrPort->SetThreadRunFlag(0); + } } + + if (m_CTcpClientQueue.size() > 0) + { + vector::iterator it; + for (it = m_CTcpClientQueue.begin(); it != m_CTcpClientQueue.end(); it++) + { + ptrTcp = *it; + ptrTcp->SetThreadRunFlag(0); + } + } + //vector::iterator it; +// for (it = m_CSerialPortQueue.begin();it!=m_CSerialPortQueue.end();it++) +// { +// ptrSerial = *it; +// ptrSerial->SetThreadRunFlag(0); +// } LOGDEBUG("CDLT645::InformTcpThreadExit: 退出线程"); diff --git a/product/src/fes/protocol/dlt645/DLT645.h b/product/src/fes/protocol/dlt645/DLT645.h index c087a1ff..0a7ec936 100644 --- a/product/src/fes/protocol/dlt645/DLT645.h +++ b/product/src/fes/protocol/dlt645/DLT645.h @@ -5,6 +5,7 @@ #include "FesBase.h" #include "ProtocolBase.h" #include "SerialPortThread.h" +#include "TcpClientThread.h" #include "DLT645DataProcThread.h" #define CN_DLT645MaxRTUs 256 @@ -24,6 +25,7 @@ public: ~CDLT645(); vector m_CSerialPortQueue; + vector m_CTcpClientQueue; vector m_CDataProcQueue; CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 @@ -35,6 +37,7 @@ public: void InformTcpThreadExit(); private: void ClearSerialPortThreadByChanNo(int ChanNo); + void ClearTcpClientThreadByChanNo(int ChanNo); void ClearDataProcThreadByChanNo(int ChanNo); }; diff --git a/product/src/fes/protocol/dlt645/DLT645DataProcThread.cpp b/product/src/fes/protocol/dlt645/DLT645DataProcThread.cpp index 71557270..8b61c1fb 100644 --- a/product/src/fes/protocol/dlt645/DLT645DataProcThread.cpp +++ b/product/src/fes/protocol/dlt645/DLT645DataProcThread.cpp @@ -8,8 +8,8 @@ 2020-02-24 thxiao 创建时设置ThreadRun标识。 2020-04-02 Rong 1、修改数据RcvComData函数数据接收方式,2、修改遥测、遥脉数据解析方式。 2020-05-21 thxiao - RecvComData()当没有收到数据时,调用CFesBase::SetOfflineFlag(CFesRtuPtr ptrRtu, int flag),实现串口通信异常时能够重新打开串口。 - 其他地方还是使用原来的 CFesRtu::SetOfflineFlag(int flag)。 + RecvComData()当没有收到数据时,调用CFesBase::SetOfflineFlag(CFesRtuPtr ptrRtu, int flag),实现串口通信异常时能够重新打开串口。 + 其他地方还是使用原来的 CFesRtu::SetOfflineFlag(int flag)。 2020-08-18 thxiao 一个通道挂多个设备的规约,初始化时需要把标志置上在线状态,保证第一次每个设备都可以发送指令。 */ @@ -33,9 +33,9 @@ const int g_DLT645ThreadTime = 20; CDLT645DataProcThread::CDLT645DataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan): CTimerThreadBase("DLT645DataProcThread",g_DLT645ThreadTime,0,true) { - CFesRtuPtr pRtu; + CFesRtuPtr pRtu; - m_ptrCFesChan = ptrCFesChan; + m_ptrCFesChan = ptrCFesChan; m_ptrCFesBase = ptrCFesBase; m_ptrCurrentChan = ptrCFesChan; int RtuId = m_ptrCurrentChan->m_CurrentRtuIndex; @@ -44,14 +44,14 @@ CDLT645DataProcThread::CDLT645DataProcThread(CFesBase *ptrCFesBase,CFesChanPtr m_timerCountReset = 1000/g_DLT645ThreadTime; //1S COUNTER m_timerCount = 0; - //2020-02-24 thxiao 创建时设置ThreadRun标识。 - if (m_ptrCFesChan == NULL) - { - return; - } - m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); - //2020-08-18 thxiao 一个通道挂多个设备的规约,初始化时需要把标志置上在线状态,保证第一次每个设备都可以发送指令。 - m_ptrCFesBase->ClearRtuOfflineFlag(m_ptrCFesChan); + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if (m_ptrCFesChan == NULL) + { + return; + } + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + //2020-08-18 thxiao 一个通道挂多个设备的规约,初始化时需要把标志置上在线状态,保证第一次每个设备都可以发送指令。 + m_ptrCFesBase->ClearRtuOfflineFlag(m_ptrCFesChan); //memset(&m_AppData,0,sizeof(SDLT645AppData));//lww todo 声明结构进行初始化 //memset(&m_AppData.m_RtuData,0,sizeof(SDLT645RTUData)*CN_FesMaxRtuNumPerChan);//lww todo @@ -60,16 +60,16 @@ CDLT645DataProcThread::CDLT645DataProcThread(CFesBase *ptrCFesBase,CFesChanPtr { m_AppData.setCmdCount = 0; m_AppData.respTimeoutReset = m_ptrCFesChan->m_Param.RespTimeout; - for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) - { - RtuNo = m_ptrCFesChan->m_RtuNo[i]; - if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) - { - m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); - pRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); - pRtu->SetOfflineFlag(CN_FesRtuComDown); - } - } + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } InitConfigParam();//< 取默认配置 } } @@ -77,21 +77,21 @@ CDLT645DataProcThread::CDLT645DataProcThread(CFesBase *ptrCFesBase,CFesChanPtr CDLT645DataProcThread::~CDLT645DataProcThread() { - CFesRtuPtr pRtu; - int RtuNo; + CFesRtuPtr pRtu; + int RtuNo; - quit();//在调用quit()前,系统会调用beforeQuit(); + quit();//在调用quit()前,系统会调用beforeQuit(); - for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) - { - RtuNo = m_ptrCFesChan->m_RtuNo[i]; - if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) - { - m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); - pRtu->SetOfflineFlag(CN_FesRtuComDown); - } - } - LOGDEBUG("CDLT645DataProcThread::~CDLT645DataProcThread() ChanNo:%d 退出", m_ptrCFesChan->m_Param.ChanNo); + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } + LOGDEBUG("CDLT645DataProcThread::~CDLT645DataProcThread() ChanNo:%d 退出", m_ptrCFesChan->m_Param.ChanNo); } /** @@ -119,10 +119,10 @@ void CDLT645DataProcThread::execute() if(m_timerCount++>=m_timerCountReset) m_timerCount = 0;// 1sec is ready - if (m_timerCount == 0) - { - TimerProcess(); - } + if (m_timerCount == 0) + { + TimerProcess(); + } //< 处理数据块轮询 SetSendCmdFlag(); @@ -189,7 +189,7 @@ int CDLT645DataProcThread::InitConfigParam() m_AppData.m_RtuData[i].addHeadTypeDes = ""; } } - m_AppData.setTimeTimeoutReset = m_ptrCFesBase->m_gSetTimeReset; + m_AppData.setTimeTimeoutReset = m_ptrCFesBase->m_gSetTimeReset; return iotSuccess; } /** @@ -204,10 +204,10 @@ int CDLT645DataProcThread::GetPollingCmd(SModbusCmd *pCmd) int count = 0; - if (m_ptrCFesRtu == NULL) - return iotFailed; - - while (count < m_ptrCFesRtu->m_Param.ModbusCmdBuf.num) + if (m_ptrCFesRtu == NULL) + return iotFailed; + + while (count < m_ptrCFesRtu->m_Param.ModbusCmdBuf.num) { Cmd = m_ptrCFesRtu->m_Param.ModbusCmdBuf.pCmd + m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx; if (Cmd->CommandSendFlag == true) @@ -270,16 +270,16 @@ int CDLT645DataProcThread::PollingCmdProcess() int writex=0; int RtuNo, RtuIndex,len; - RtuNo = m_ptrCFesChan->m_RtuNo[m_ptrCurrentChan->m_CurrentRtuIndex]; - RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; - if ((m_ptrCFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) - { - NextRtuIndex(m_ptrCFesChan); - return 0; - } + RtuNo = m_ptrCFesChan->m_RtuNo[m_ptrCurrentChan->m_CurrentRtuIndex]; + RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; + if ((m_ptrCFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) + { + NextRtuIndex(m_ptrCFesChan); + return 0; + } - if (GetPollingCmd(&cmd) == iotFailed) - return 0; + if (GetPollingCmd(&cmd) == iotFailed) + return 0; memcpy(&m_AppData.m_RtuData[RtuIndex].lastCmd, &cmd, sizeof(SModbusCmd)); data[writex++] = 0xfe; @@ -346,10 +346,21 @@ int CDLT645DataProcThread::PollingCmdProcess() data[writex++] = CheckSum(&data[4],len); data[writex++] = 0x16; } - - if(m_AppData.m_RtuData[RtuIndex].addHeadTypeDes=="Head") //< 不发送头部帧 + if(m_AppData.m_RtuData[RtuIndex].addHeadTypeDes=="0") //< 不发送头部帧 SendDataToPort(&data[4],writex-4); - else + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes=="1") //发一个FE,东莞领尚 + { + SendDataToPort(&data[3],writex-3); + } + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes=="2") //发两个FE + { + SendDataToPort(&data[2],writex-2); + } + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes=="3") //发三个FE + { + SendDataToPort(&data[1],writex-1); + } + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes=="4")//默认发四个FE SendDataToPort(data,writex); m_AppData.m_RtuData[RtuIndex].state = CN_DLT645AppState_idle; @@ -398,121 +409,138 @@ void CDLT645DataProcThread::SetSendCmdFlag() int CDLT645DataProcThread::RecvComData() { - int RtuIndex, count = 20; + int RtuIndex, count = 20; int ExpectLen; - int recvLen, Len, i, frameError; - frameError = 0; + int recvLen, Len, i, frameError; + frameError = 0; - if (m_ptrCurrentChan == NULL) - return iotFailed; + if (m_ptrCurrentChan == NULL) + return iotFailed; - //int ChanNo = m_ptrCurrentChan->m_Param.ChanNo; - Len = 0; - recvLen = 0; - count = m_ptrCFesChan->m_Param.RespTimeout / 10; - RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; + //int ChanNo = m_ptrCurrentChan->m_Param.ChanNo; + Len = 0; + recvLen = 0; + count = m_ptrCFesChan->m_Param.RespTimeout / 10; + RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; + feNum = atoi(m_AppData.m_RtuData[RtuIndex].addHeadTypeDes.c_str()); - if (count <= 10) - count = 10;//最小响应超时为100毫秒 - ExpectLen = 0; - for (i = 0; i < count; i++) - { - SleepmSec(10);//以最快速度接收到数据 - recvLen = m_ptrCurrentChan->ReadRxBufData(256 - Len, &m_AppData.recvBuf[Len]); - if (recvLen <= 0) - continue; + if (count <= 10) + count = 10;//最小响应超时为100毫秒 + ExpectLen = 0; + for (i = 0; i < count; i++) + { + SleepmSec(10);//以最快速度接收到数据 + recvLen = m_ptrCurrentChan->ReadRxBufData(256 - Len, &m_AppData.recvBuf[Len]); + if (recvLen <= 0) + continue; - m_ptrCurrentChan->DeleteReadRxBufData(recvLen);//清除已读取的数据 - Len += recvLen; - if (Len > 14) - { - ExpectLen = m_AppData.recvBuf[13] + 16;//默认带4个fe + m_ptrCurrentChan->DeleteReadRxBufData(recvLen);//清除已读取的数据 + Len += recvLen; + if (Len > 14) + { - if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "Head")//不带4个fe - ExpectLen = m_AppData.recvBuf[9] + 12; - - ExpectLen = m_AppData.recvBuf[13]+16; - } - if ((Len >= ExpectLen) && (ExpectLen > 0)) - { - break; - } - } - - if (Len > 0) - ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, m_AppData.recvBuf, Len, CN_SFesSimComFrameTypeRecv); + if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "0")//不带4个fe + ExpectLen = m_AppData.recvBuf[9] + 12; + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "1") + ExpectLen = m_AppData.recvBuf[10] + 13; + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "2") + ExpectLen = m_AppData.recvBuf[11] + 14; + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "3") + ExpectLen = m_AppData.recvBuf[12] + 15; + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "4") + ExpectLen = m_AppData.recvBuf[13] + 16; + } + if ((Len >= ExpectLen) && (ExpectLen > 0)) + { + break; + } + } + if (Len > 0) + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, m_AppData.recvBuf, Len, CN_SFesSimComFrameTypeRecv); m_AppData.recvBufSize = ExpectLen; - //LOGDEBUG("===%d %d %d %d %d %d===", m_AppData.m_RtuData[RtuIndex].A0, m_AppData.m_RtuData[RtuIndex].A1, m_AppData.m_RtuData[RtuIndex].A2, - //m_AppData.m_RtuData[RtuIndex].A3, m_AppData.m_RtuData[RtuIndex].A4, m_AppData.m_RtuData[RtuIndex].A5); - //LOGDEBUG("===%d %d %d %d %d %d===", m_AppData.recvBuf[5], m_AppData.recvBuf[6], m_AppData.recvBuf[7], - //m_AppData.recvBuf[8], m_AppData.recvBuf[9], m_AppData.recvBuf[10]); + //LOGDEBUG("===%d %d %d %d %d %d===", m_AppData.m_RtuData[RtuIndex].A0, m_AppData.m_RtuData[RtuIndex].A1, m_AppData.m_RtuData[RtuIndex].A2, + //m_AppData.m_RtuData[RtuIndex].A3, m_AppData.m_RtuData[RtuIndex].A4, m_AppData.m_RtuData[RtuIndex].A5); + //LOGDEBUG("===%d %d %d %d %d %d===", m_AppData.recvBuf[5], m_AppData.recvBuf[6], m_AppData.recvBuf[7], + //m_AppData.recvBuf[8], m_AppData.recvBuf[9], m_AppData.recvBuf[10]); - if (Len == 0)//接收不完整,重发数据 - { - m_ptrCFesRtu->SetResendNum(1); - if (m_ptrCFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) - { - m_ptrCFesRtu->ResetResendNum(); //改为RTU下的resendNum - if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuNormal) - { - m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); - m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); - } - m_ptrCFesBase->SetOfflineFlag(m_ptrCFesRtu,CN_FesRtuComDown); - } - NextRtuIndex(m_ptrCFesChan); - - return iotFailed; - } - else//长度、A0-A5 都正确则认为数据正确。 - if ((Len == ExpectLen) && - (m_AppData.m_RtuData[RtuIndex].A0 == m_AppData.recvBuf[5]) && - (m_AppData.m_RtuData[RtuIndex].A1 == m_AppData.recvBuf[6]) && - (m_AppData.m_RtuData[RtuIndex].A2 == m_AppData.recvBuf[7]) && - (m_AppData.m_RtuData[RtuIndex].A3 == m_AppData.recvBuf[8]) && - (m_AppData.m_RtuData[RtuIndex].A4 == m_AppData.recvBuf[9]) && - (m_AppData.m_RtuData[RtuIndex].A5 == m_AppData.recvBuf[10])) - { - m_ptrCurrentChan->SetRxNum(1); - m_ptrCFesRtu->ResetResendNum(); - m_ptrCFesRtu->SetRxNum(1); - if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuComDown) - { - m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); - m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuNormal); - } + if (Len == 0)//接收不完整,重发数据 + { + m_ptrCFesRtu->SetResendNum(1); + if (m_ptrCFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCFesRtu->ResetResendNum(); //改为RTU下的resendNum + if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCFesRtu,CN_FesRtuComDown); + } + NextRtuIndex(m_ptrCFesChan); - if (m_AppData.m_RtuData[RtuIndex].protocolVers == 2007) //< 2007版本DLT645 - { - if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "Head")//不带4个fe - frameError = RecvDataProcess07(&m_AppData.recvBuf[4], m_AppData.recvBufSize); + return iotFailed; + } + else//长度、A0-A5 都正确则认为数据正确。 + // LOGINFO("ExpectLen = %d",ExpectLen); + // LOGINFO("[%d][%d][%d][%d][%d]",m_AppData.m_RtuData[RtuIndex].A0,m_AppData.m_RtuData[RtuIndex].A1,m_AppData.m_RtuData[RtuIndex].A2,m_AppData.m_RtuData[RtuIndex].A3,m_AppData.m_RtuData[RtuIndex].A4,m_AppData.m_RtuData[RtuIndex].A5); + // LOGINFO("[%d][%d][%d][%d][%d]",m_AppData.recvBuf[2],m_AppData.recvBuf[3],m_AppData.recvBuf[4],m_AppData.recvBuf[5],m_AppData.recvBuf[6],m_AppData.recvBuf[7]); + if ((Len == ExpectLen) && + (m_AppData.m_RtuData[RtuIndex].A0 == m_AppData.recvBuf[1+feNum]) && + (m_AppData.m_RtuData[RtuIndex].A1 == m_AppData.recvBuf[2+feNum]) && + (m_AppData.m_RtuData[RtuIndex].A2 == m_AppData.recvBuf[3+feNum]) && + (m_AppData.m_RtuData[RtuIndex].A3 == m_AppData.recvBuf[4+feNum]) && + (m_AppData.m_RtuData[RtuIndex].A4 == m_AppData.recvBuf[5+feNum]) && + (m_AppData.m_RtuData[RtuIndex].A5 == m_AppData.recvBuf[6+feNum])) + { + m_ptrCurrentChan->SetRxNum(1); + m_ptrCFesRtu->ResetResendNum(); + m_ptrCFesRtu->SetRxNum(1); + if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuComDown) + { + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuNormal); + } + if (m_AppData.m_RtuData[RtuIndex].protocolVers == 2007) //< 2007版本DLT645 + { + if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "0")//不带fe + frameError = RecvDataProcess07(&m_AppData.recvBuf[0], m_AppData.recvBufSize); + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "1")//带1个FE + frameError = RecvDataProcess07(&m_AppData.recvBuf[1],m_AppData.recvBufSize - 1); + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "2")//带2个FE + frameError = RecvDataProcess07(&m_AppData.recvBuf[2],m_AppData.recvBufSize - 2); + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "3")//带3个FE + frameError = RecvDataProcess07(&m_AppData.recvBuf[3],m_AppData.recvBufSize - 3); + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "4") + frameError = RecvDataProcess07(&m_AppData.recvBuf[4], m_AppData.recvBufSize - 4); - else - frameError = RecvDataProcess07(&m_AppData.recvBuf[4], m_AppData.recvBufSize - 4); + } + else + { + if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "0")//不带fe + frameError = RecvDataProcess97(&m_AppData.recvBuf[0], m_AppData.recvBufSize); + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "1")//带1个FE + frameError = RecvDataProcess97(&m_AppData.recvBuf[1],m_AppData.recvBufSize - 1); + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "2")//带2个FE + frameError = RecvDataProcess97(&m_AppData.recvBuf[2],m_AppData.recvBufSize - 2); + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "3")//带3个FE + frameError = RecvDataProcess97(&m_AppData.recvBuf[3],m_AppData.recvBufSize - 3); + else if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "4") + frameError = RecvDataProcess97(&m_AppData.recvBuf[4], m_AppData.recvBufSize - 4); - } - else - { - if (m_AppData.m_RtuData[RtuIndex].addHeadTypeDes == "Head")//不带4个fe - frameError = RecvDataProcess97(&m_AppData.recvBuf[4], m_AppData.recvBufSize); - - else - frameError = RecvDataProcess97(&m_AppData.recvBuf[4], m_AppData.recvBufSize - 4); - - } - //< 帧校验错误 - if (frameError) - { - m_ptrCurrentChan->SetErrNum(1); - m_ptrCFesRtu->SetErrNum(1); - NextRtuIndex(m_ptrCFesChan); - return 0; - } - NextRtuIndex(m_ptrCFesChan); - return m_AppData.recvBufSize; - } - return 0; + } + //< 帧校验错误 + if (frameError) + { + m_ptrCurrentChan->SetErrNum(1); + m_ptrCFesRtu->SetErrNum(1); + NextRtuIndex(m_ptrCFesChan); + return 0; + } + NextRtuIndex(m_ptrCFesChan); + return m_AppData.recvBufSize; + } + return 0; } @@ -533,21 +561,21 @@ int CDLT645DataProcThread::RecvComData() frameError = 0; count = m_ptrCFesChan->m_Param.RespTimeout / 10; m_AppData.recvBufSize = 0; - RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; - //LOGDEBUG("=============="); + RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; + //LOGDEBUG("=============="); for(i = 0; i < count; i++) { SleepmSec(10); //< 延时10ms - //LOGDEBUG("recvLen=%d ExpectLen=%d", recvLen, ExpectLen); + //LOGDEBUG("recvLen=%d ExpectLen=%d", recvLen, ExpectLen); recvLen = m_ptrCurrentChan->ReadRxBufData(CN_DLT645MaxRecvDataSize-m_AppData.recvBufSize, &m_AppData.recvBuf[m_AppData.recvBufSize]); if(recvLen <= 0) continue; - //LOGDEBUG("=============="); - //LOGDEBUG("recvLen=%d ExpectLen=%d", recvLen, ExpectLen); + //LOGDEBUG("=============="); + //LOGDEBUG("recvLen=%d ExpectLen=%d", recvLen, ExpectLen); m_AppData.recvBufSize += recvLen; m_ptrCurrentChan->DeleteReadRxBufData(recvLen); - //LOGDEBUG("=============="); + //LOGDEBUG("=============="); if(ExpectLen == -1) { @@ -556,37 +584,37 @@ int CDLT645DataProcThread::RecvComData() t=j; if((j+9)>=m_AppData.recvBufSize) break; //< 如果接收个数不够则继续接收 - //LOGDEBUG("recvLen=%d ExpectLen=%d", recvLen, ExpectLen); + //LOGDEBUG("recvLen=%d ExpectLen=%d", recvLen, ExpectLen); if( (m_AppData.recvBuf[j]==0x68)&&(m_AppData.recvBuf[j+7]==0x68) ) { - //LOGDEBUG("recvLen=%d ExpectLen=%d", recvLen, ExpectLen); + //LOGDEBUG("recvLen=%d ExpectLen=%d", recvLen, ExpectLen); ExpectLen = m_AppData.recvBuf[j+9]+12; break; } } } - //LOGDEBUG("=============="); + //LOGDEBUG("=============="); ExpectLen = ExpectLen+j; if(m_AppData.recvBufSize >= ExpectLen) break; } - LOGDEBUG("recvLen=%d ExpectLen=%d", recvLen, ExpectLen); + LOGDEBUG("recvLen=%d ExpectLen=%d", recvLen, ExpectLen); if((m_AppData.recvBufSize == 0) || (ExpectLen == -1)) { - m_ptrCFesRtu->SetResendNum(1); - if (m_ptrCFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) - { - m_ptrCFesRtu->ResetResendNum(); //改为RTU下的resendNum - if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuNormal) - { - m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); - m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); - } - m_ptrCFesRtu->SetOfflineFlag(CN_FesRtuComDown); - } + m_ptrCFesRtu->SetResendNum(1); + if (m_ptrCFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCFesRtu->ResetResendNum(); //改为RTU下的resendNum + if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + } + m_ptrCFesRtu->SetOfflineFlag(CN_FesRtuComDown); + } NextRtuIndex(m_ptrCFesChan); return 0; } @@ -609,7 +637,7 @@ int CDLT645DataProcThread::RecvComData() if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuComDown) { m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); - m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu,CN_FesRtuNormal); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu,CN_FesRtuNormal); } if(m_AppData.m_RtuData[RtuIndex].protocolVers == 2007) //< 2007版本DLT645 frameError = RecvDataProcess07(&m_AppData.recvBuf[j],m_AppData.recvBufSize-j); @@ -640,7 +668,7 @@ int CDLT645DataProcThread::SendProcess() if (m_ptrCurrentChan->m_LinkStatus != CN_FesChanConnect) return retLen; - if ((retLen = PollingCmdProcess())>0) + if ((retLen = PollingCmdProcess())>0) return retLen; return retLen; @@ -657,8 +685,8 @@ void CDLT645DataProcThread::SendClockSynchFrame97() LOCALTIME stTime; int writex=0; int len; - int RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; - getLocalSysTime(stTime); + int RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; + getLocalSysTime(stTime); if(m_AppData.m_RtuData[RtuIndex].deviceDes=="WEISHENG") //< 威胜电表校时 { @@ -740,11 +768,16 @@ void CDLT645DataProcThread::SendClockSynchFrame97() data[writex++] = 0x16; } - if(m_AppData.m_RtuData[RtuIndex].addHeadTypeDes=="Head") //< 不发送头部帧 + if(m_AppData.m_RtuData[RtuIndex].addHeadTypeDes=="0") //< 不发送头部帧 + SendDataToPort(&data[0],writex); + else if(m_AppData.m_RtuData[RtuIndex].addHeadTypeDes=="1")//发1个FE + SendDataToPort(&data[1],writex-1); + else if(m_AppData.m_RtuData[RtuIndex].addHeadTypeDes=="2")//发2个FE + SendDataToPort(&data[2],writex-2); + else if(m_AppData.m_RtuData[RtuIndex].addHeadTypeDes=="3")//发3个FE + SendDataToPort(&data[3],writex-3); + else if(m_AppData.m_RtuData[RtuIndex].addHeadTypeDes=="4") SendDataToPort(&data[4],writex-4); - else - SendDataToPort(data,writex); - } /** @@ -838,51 +871,51 @@ void CDLT645DataProcThread::SendDataToPort(byte *Data, int Size) void CDLT645DataProcThread::TimerProcess() { - SFesNetEvent netEvent; - CFesRtuPtr pRtu; - int RtuNo; + SFesNetEvent netEvent; + CFesRtuPtr pRtu; + int RtuNo; - uint64 curmsec = getMonotonicMsec(); //getUTCTimeMsec(); + uint64 curmsec = getMonotonicMsec(); //getUTCTimeMsec(); - if (m_ptrCurrentChan->ReadNetEvent(1, &netEvent) > 0) - { - switch (netEvent.EventType) - { - case CN_FesNetEvent_Connect: - LOGDEBUG("CDLT645DataProcThread::execute() Chan%d connect ok", m_ptrCurrentChan->m_Param.ChanNo); - break; - case CN_FesNetEvent_Disconnect: - LOGDEBUG("CDLT645DataProcThread::execute() Chan%d disconnect ok", m_ptrCurrentChan->m_Param.ChanNo); - for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) - { - RtuNo = m_ptrCFesChan->m_RtuNo[i]; - if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) - { - m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); - pRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); - pRtu->SetOfflineFlag(CN_FesRtuComDown); - } - m_AppData.m_RtuData[i].state = CN_DLT645AppState_init; - } - break; - default: - break; - } - } + if (m_ptrCurrentChan->ReadNetEvent(1, &netEvent) > 0) + { + switch (netEvent.EventType) + { + case CN_FesNetEvent_Connect: + LOGDEBUG("CDLT645DataProcThread::execute() Chan%d connect ok", m_ptrCurrentChan->m_Param.ChanNo); + break; + case CN_FesNetEvent_Disconnect: + LOGDEBUG("CDLT645DataProcThread::execute() Chan%d disconnect ok", m_ptrCurrentChan->m_Param.ChanNo); + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + m_AppData.m_RtuData[i].state = CN_DLT645AppState_init; + } + break; + default: + break; + } + } - if ((m_ptrCFesChan->m_Param.SetTimeEnable == 1) && (m_AppData.setTimeTimeoutReset > 0) && - ((curmsec - m_AppData.lastSetTimemSec) > m_AppData.setTimeTimeoutReset)) - { - m_AppData.setTimeFlag = 1; - m_AppData.lastSetTimemSec = curmsec; - //广播对时,同一通道为相同的版本类型 - if (m_AppData.m_RtuData[0].protocolVers == 2007) //< 2007版本DLT645 - SendClockSynchFrame07(); - else - SendClockSynchFrame97(); + if ((m_ptrCFesChan->m_Param.SetTimeEnable == 1) && (m_AppData.setTimeTimeoutReset > 0) && + ((curmsec - m_AppData.lastSetTimemSec) > m_AppData.setTimeTimeoutReset)) + { + m_AppData.setTimeFlag = 1; + m_AppData.lastSetTimemSec = curmsec; + //广播对时,同一通道为相同的版本类型 + if (m_AppData.m_RtuData[0].protocolVers == 2007) //< 2007版本DLT645 + SendClockSynchFrame07(); + else + SendClockSynchFrame97(); - Sleep(5000); - } + Sleep(5000); + } } @@ -896,7 +929,7 @@ int CDLT645DataProcThread::RecvDataProcess97(byte *recvBuff,int recvLen) int RtuIndex; int funCode,blockType,funType; - RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; + RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; //< 主从发送方向检查,PRM为0表示主->从报文,1表示从->主报文 PRM = recvBuff[8]&0x80; @@ -942,25 +975,29 @@ int CDLT645DataProcThread::RecvDataProcess07(byte *recvBuff,int recvLen) byte PRM,sum; int RtuIndex,parsEffective=0; int funCode,blockType,funType; - - RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; - parsEffective = recvBuff[8]; + //LOGINFO("recvBuff[8]=%d",recvBuff[8]); + // LOGINFO("recvLen = %d",recvLen); + RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; + parsEffective = recvBuff[8]; //< 主从发送方向检查,PRM为0表示主->从报文,1表示从->主报文 PRM = recvBuff[8]&0x80; if(PRM==0) return iotFailed; - //< 功能码类型,不是读数据的不解析 + + //< 功能码类型,不是读数据的不解析 funType = recvBuff[8]&0x0f; if(funType!=1) return iotFailed; - //< 和校验检查 + + //< 和校验检查 sum = (byte)CheckSum(&recvBuff[0],recvLen-2); if(sum!=recvBuff[recvLen-2]) return iotFailed; - //< 结束符检查 + + //< 结束符检查 if(recvBuff[recvLen-1]!=0x16) return iotFailed; @@ -969,7 +1006,7 @@ int CDLT645DataProcThread::RecvDataProcess07(byte *recvBuff,int recvLen) if((0x91==parsEffective)||(0xb1==parsEffective))//< 0xb1:表示有后续帧,0x91:表示无后续帧 { - //LOGDEBUG("====%d %d==========",m_AppData.m_RtuData[RtuIndex].lastCmd.StartAddr, m_AppData.m_RtuData[RtuIndex].lastCmd.DataLen); + //LOGDEBUG("====%d %d==========",m_AppData.m_RtuData[RtuIndex].lastCmd.StartAddr, m_AppData.m_RtuData[RtuIndex].lastCmd.DataLen); switch(funCode) { @@ -1011,8 +1048,8 @@ void CDLT645DataProcThread::RecvDiWithoutTimeProcess97(byte *recvBuff) ChgCount = 0; ValueCount = 0; SoeCount = 0; - RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; - dataByteLen = m_AppData.m_RtuData[RtuIndex].lastCmd.Param1; + RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; + dataByteLen = m_AppData.m_RtuData[RtuIndex].lastCmd.Param1; Di0 = *(recvBuff+10)-0x33; Di1 = *(recvBuff+11)-0x33; @@ -1064,9 +1101,9 @@ void CDLT645DataProcThread::RecvDiWithoutTimeProcess97(byte *recvBuff) ChgDi[ChgCount].Value = bitValue; ChgDi[ChgCount].Status = status; ChgDi[ChgCount].time = mSec; - ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - ChgDi[ChgCount].PointNo = pDi->PointNo; - ChgCount++; + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgCount++; } //Create Soe memset(&SoeEvent[SoeCount],0,sizeof(SFesSoeEvent)); @@ -1077,8 +1114,8 @@ void CDLT645DataProcThread::RecvDiWithoutTimeProcess97(byte *recvBuff) SoeEvent[SoeCount].Value = bitValue; SoeEvent[SoeCount].Status = status; SoeEvent[SoeCount].FaultNum =0; - SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; SoeCount++; } //更新点值 @@ -1092,12 +1129,12 @@ void CDLT645DataProcThread::RecvDiWithoutTimeProcess97(byte *recvBuff) } if(ChgCount>0) { - m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu,ChgCount,&ChgDi[0]); + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu,ChgCount,&ChgDi[0]); ChgCount = 0; } if(SoeCount>0) { - m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu,SoeCount,&SoeEvent[0]); + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu,SoeCount,&SoeEvent[0]); SoeCount = 0; //保存FesSim监视数据 m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount,&SoeEvent[0]); @@ -1118,6 +1155,8 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess97(byte *recvBuff) int i,j,k; int ChgCount,ValueCount; int status, RtuIndex,dataNum,dataByteLen; + int signedFlag = 0; + int signAllow = 0; int StartPointNo=0; int Di0,Di1,dataLen,aiByte; uint64 mSec; @@ -1125,13 +1164,15 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess97(byte *recvBuff) SFesAi *pAi; SFesRtuAiValue AiValue[100]; SFesChgAi ChgAi[100]; - int64 aiValue = 0, tempValue = 0; + int64 aiValue = 0, tempValue = 0; ChgCount = 0; ValueCount = 0; mSec = getUTCTimeMsec(); - RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; - dataByteLen = m_AppData.m_RtuData[RtuIndex].lastCmd.Param1; + RtuIndex = m_ptrCurrentChan->m_CurrentRtuIndex; + dataByteLen = m_AppData.m_RtuData[RtuIndex].lastCmd.Param1; + + signAllow = m_AppData.m_RtuData[RtuIndex].lastCmd.Param2; Di0 = *(recvBuff+10)-0x33; Di1 = *(recvBuff+11)-0x33; @@ -1149,18 +1190,28 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess97(byte *recvBuff) { aiStr = ""; aiStr1 = ""; - aiValue = 0; + aiValue = 0; for(j=0;j0) && (signedFlag == 1)) + { + aiValue = -aiValue; + signedFlag = 0; + } if((pAi=GetFesAiByParam23(m_ptrCFesRtu,StartPointNo,Di0+i,Di1))!=NULL) { @@ -1177,7 +1228,7 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess97(byte *recvBuff) ValueCount = 0; if((ChgCount>0)&&(g_DLT645IsMainFes==true))//主机才报告变化数据 { - m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); } } } @@ -1188,7 +1239,7 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess97(byte *recvBuff) ValueCount = 0; if((ChgCount>0)&&(g_DLT645IsMainFes==true))//主机才报告变化数据 { - m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); } } } @@ -1212,18 +1263,18 @@ void CDLT645DataProcThread::RecvAccWithoutTimeProcess97(byte *recvBuff) SFesAcc *pAcc; SFesChgAcc ChgAcc[100]; SFesRtuAccValue AccValue[100]; - int64 accValue = 0, tempValue = 0; + int64 accValue = 0, tempValue = 0; ChgCount = 0; ValueCount = 0; mSec = getUTCTimeMsec(); - RtuIndex = m_ptrCFesChan->m_CurrentRtuIndex; + RtuIndex = m_ptrCFesChan->m_CurrentRtuIndex; dataByteLen = m_AppData.m_RtuData[RtuIndex].lastCmd.Param1; Di0 = *(recvBuff+10)-0x33; Di1 = *(recvBuff+11)-0x33; //< 处理只读单个数据的情况 - if ((Di0 & 0x0f) == 0x0f)//正向有功电能数据块 + if ((Di0 & 0x0f) == 0x0f)//正向有功电能数据块 Di0=Di0 & 0xf0; dataLen = *(recvBuff+9); dataNum = (dataLen-2)/dataByteLen; @@ -1235,16 +1286,16 @@ void CDLT645DataProcThread::RecvAccWithoutTimeProcess97(byte *recvBuff) { accStr = ""; accStr1 = ""; - accValue = 0; + accValue = 0; for(j=0;jPointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = status; AccValue[ValueCount].time = mSec; ValueCount++; @@ -1262,7 +1313,7 @@ void CDLT645DataProcThread::RecvAccWithoutTimeProcess97(byte *recvBuff) ValueCount = 0; if((ChgCount>0)&&(g_DLT645IsMainFes==true))//主机才报告变化数据 { - m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu,ChgCount,&ChgAcc[0]); + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu,ChgCount,&ChgAcc[0]); } } } @@ -1273,7 +1324,7 @@ void CDLT645DataProcThread::RecvAccWithoutTimeProcess97(byte *recvBuff) ValueCount = 0; if((ChgCount>0)&&(g_DLT645IsMainFes==true))//主机才报告变化数据 { - m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu,ChgCount,&ChgAcc[0]); + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu,ChgCount,&ChgAcc[0]); } } } @@ -1301,8 +1352,8 @@ void CDLT645DataProcThread::RecvDiWithoutTimeProcess07(byte *recvBuff) ChgCount = 0; ValueCount = 0; SoeCount = 0; - RtuIndex = m_ptrCFesChan->m_CurrentRtuIndex; - dataByteLen = m_AppData.m_RtuData[RtuIndex].lastCmd.Param1; + RtuIndex = m_ptrCFesChan->m_CurrentRtuIndex; + dataByteLen = m_AppData.m_RtuData[RtuIndex].lastCmd.Param1; Di0 = *(recvBuff+10)-0x33; Di1 = *(recvBuff+11)-0x33; @@ -1359,9 +1410,9 @@ void CDLT645DataProcThread::RecvDiWithoutTimeProcess07(byte *recvBuff) ChgDi[ChgCount].Value = bitValue; ChgDi[ChgCount].Status = status; ChgDi[ChgCount].time = mSec; - ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - ChgDi[ChgCount].PointNo = pDi->PointNo; - ChgCount++; + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgCount++; } //Create Soe memset(&SoeEvent[SoeCount],0,sizeof(SFesSoeEvent)); @@ -1372,8 +1423,8 @@ void CDLT645DataProcThread::RecvDiWithoutTimeProcess07(byte *recvBuff) SoeEvent[SoeCount].Value = bitValue; SoeEvent[SoeCount].Status = status; SoeEvent[SoeCount].FaultNum =0; - SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; SoeCount++; } //更新点值 @@ -1425,9 +1476,9 @@ void CDLT645DataProcThread::RecvDiWithoutTimeProcess07(byte *recvBuff) ChgDi[ChgCount].Value = bitValue; ChgDi[ChgCount].Status = status; ChgDi[ChgCount].time = mSec; - ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - ChgDi[ChgCount].PointNo = pDi->PointNo; - ChgCount++; + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgCount++; } //Create Soe memset(&SoeEvent[SoeCount],0,sizeof(SFesSoeEvent)); @@ -1438,8 +1489,8 @@ void CDLT645DataProcThread::RecvDiWithoutTimeProcess07(byte *recvBuff) SoeEvent[SoeCount].Value = bitValue; SoeEvent[SoeCount].Status = status; SoeEvent[SoeCount].FaultNum =0; - SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; SoeCount++; } //更新点值 @@ -1455,12 +1506,12 @@ void CDLT645DataProcThread::RecvDiWithoutTimeProcess07(byte *recvBuff) if(ChgCount>0) { - m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu,ChgCount,&ChgDi[0]); + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu,ChgCount,&ChgDi[0]); ChgCount = 0; } if(SoeCount>0) { - m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu,SoeCount,&SoeEvent[0]); + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu,SoeCount,&SoeEvent[0]); SoeCount = 0; //保存FesSim监视数据 m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount,&SoeEvent[0]); @@ -1481,6 +1532,8 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess07(byte *recvBuff) int i,j,k; int ChgCount,ValueCount; int status, RtuIndex,dataNum,dataByteLen; + int signedFlag = 0; + int signAllow; int StartPointNo=0; int Di0,Di1,Di2,Di3,Di01,Di23,dataLen,aiByte; uint64 mSec; @@ -1489,13 +1542,15 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess07(byte *recvBuff) SFesRtuAiValue AiValue[100]; SFesChgAi ChgAi[100]; uint64 maxNeedValue[10]; - int64 aiValue = 0, tempValue = 0; + int64 aiValue = 0, tempValue = 0; ChgCount = 0; ValueCount = 0; mSec = getUTCTimeMsec(); - RtuIndex = m_ptrCFesChan->m_CurrentRtuIndex; - dataByteLen = m_AppData.m_RtuData[RtuIndex].lastCmd.Param1; + RtuIndex = m_ptrCFesChan->m_CurrentRtuIndex; + dataByteLen = m_AppData.m_RtuData[RtuIndex].lastCmd.Param1; + + signAllow = m_AppData.m_RtuData[RtuIndex].lastCmd.Param2; Di0 = *(recvBuff+10)-0x33; Di1 = *(recvBuff+11)-0x33; @@ -1509,8 +1564,8 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess07(byte *recvBuff) dataLen = *(recvBuff+9); dataNum = (dataLen-4)/dataByteLen; - //LOGDEBUG("==dataNum=%d==Di0=%d==Di1=%d==Di2=%d==Di3=%d=", dataNum, Di0, Di1, Di2, Di3); - //< 一个块最多256个ai + //LOGDEBUG("==dataNum=%d==Di0=%d==Di1=%d==Di2=%d==Di3=%d=", dataNum, Di0, Di1, Di2, Di3); + //< 一个块最多256个ai if(dataNum>256) return; @@ -1523,32 +1578,32 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess07(byte *recvBuff) { aiStr = ""; aiStr1 = ""; - aiValue = 0; - memset(maxNeedValue,0,sizeof(maxNeedValue)); + aiValue = 0; + memset(maxNeedValue,0,sizeof(maxNeedValue)); for(j=0;j0)&&(g_DLT645IsMainFes==true))//主机才报告变化数据 { - m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); } } } @@ -1576,27 +1631,50 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess07(byte *recvBuff) }//< 单个ai解析 else { - //LOGDEBUG("====%d %d==========", m_AppData.m_RtuData[RtuIndex].lastCmd.StartAddr, m_AppData.m_RtuData[RtuIndex].lastCmd.DataLen); + //LOGDEBUG("====%d %d==========", m_AppData.m_RtuData[RtuIndex].lastCmd.StartAddr, m_AppData.m_RtuData[RtuIndex].lastCmd.DataLen); aiStr = ""; aiStr1 = ""; - aiValue = 0; + aiValue = 0; for(j=0;j>4)&0x0f)*10; + tempValue = static_cast(tempValue*pow(100,dataByteLen-1-j)); + //tempValue = aiByte<<((dataByteLen-1-j)*8); + // LOGINFO("tempValue = %d",tempValue); + //tempValue += (aiByte % 16); + // for (k = 1; k < dataByteLen - j; k++) + // tempValue = tempValue * 100; + //LOGDEBUG("accValue=%lld", accValue); + aiValue += tempValue; //memset(aiData,0,sizeof(char)*256); //itoa(aiByte,aiData,10); //< int 转 char //aiStr1 = (string)aiData; //aiStr += aiStr1; } + if((signAllow>0) && (signedFlag == 1)) + { + aiValue = -aiValue; + signedFlag = 0; + } if((pAi=GetFesAiByParam23(m_ptrCFesRtu,StartPointNo,Di1,Di23))!=NULL) { @@ -1613,7 +1691,7 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess07(byte *recvBuff) ValueCount = 0; if((ChgCount>0)&&(g_DLT645IsMainFes==true))//主机才报告变化数据 { - m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); } } } @@ -1629,29 +1707,29 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess07(byte *recvBuff) { aiStr = ""; aiStr1 = ""; - aiValue = 0; - memset(maxNeedValue,0,sizeof(maxNeedValue)); + aiValue = 0; + memset(maxNeedValue,0,sizeof(maxNeedValue)); for(j=0;j0)&&(g_DLT645IsMainFes==true))//主机才报告变化数据 { - m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); } } } @@ -1681,22 +1759,40 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess07(byte *recvBuff) { aiStr = ""; aiStr1 = ""; - aiValue = 0; + aiValue = 0; for(j=0;j>4)&0x0f)*10; + tempValue = static_cast(tempValue*pow(100,dataByteLen-1-j)); + //tempValue = aiByte<<((dataByteLen-1-j)*8); + // LOGINFO("tempValue = %d",tempValue); + //tempValue += (aiByte % 16); + // for (k = 1; k < dataByteLen - j; k++) + // tempValue = tempValue * 100; + //LOGDEBUG("accValue=%lld", accValue); + aiValue += tempValue; //memset(aiData,0,sizeof(char)*256); //itoa(aiByte,aiData,10); //< int 转 char //aiStr1 = (string)aiData; //aiStr += aiStr1; } + if((signAllow>0) && (signedFlag == 1)) + { + aiValue = -aiValue; + signedFlag = 0; + } if((pAi=GetFesAiByParam23(m_ptrCFesRtu,StartPointNo,i,Di23))!=NULL) { @@ -1713,7 +1809,7 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess07(byte *recvBuff) ValueCount = 0; if((ChgCount>0)&&(g_DLT645IsMainFes==true))//主机才报告变化数据 { - m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); } } } @@ -1728,7 +1824,7 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess07(byte *recvBuff) ValueCount = 0; if((ChgCount>0)&&(g_DLT645IsMainFes==true))//主机才报告变化数据 { - m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu,ChgCount,&ChgAi[0]); } } } @@ -1740,7 +1836,7 @@ void CDLT645DataProcThread::RecvAiWithoutTimeProcess07(byte *recvBuff) void CDLT645DataProcThread::RecvAccWithoutTimeProcess07(byte *recvBuff) { int ChgCount,ValueCount; - int i, j, k, status; + int i, j, k, status; int RtuIndex,dataNum,dataByteLen; int StartPointNo=0; int Di0,Di1,Di2,Di3,Di01,Di23,dataLen,accByte; @@ -1749,12 +1845,12 @@ void CDLT645DataProcThread::RecvAccWithoutTimeProcess07(byte *recvBuff) SFesAcc *pAcc; SFesChgAcc ChgAcc[100]; SFesRtuAccValue AccValue[100]; - int64 accValue=0, tempValue=0; + int64 accValue=0, tempValue=0; ChgCount = 0; ValueCount = 0; mSec = getUTCTimeMsec(); - RtuIndex = m_ptrCFesChan->m_CurrentRtuIndex; - dataByteLen = m_AppData.m_RtuData[RtuIndex].lastCmd.Param1; + RtuIndex = m_ptrCFesChan->m_CurrentRtuIndex; + dataByteLen = m_AppData.m_RtuData[RtuIndex].lastCmd.Param1; Di0 = *(recvBuff+10)-0x33; Di1 = *(recvBuff+11)-0x33; @@ -1775,29 +1871,29 @@ void CDLT645DataProcThread::RecvAccWithoutTimeProcess07(byte *recvBuff) if(1==dataNum) { accStr = ""; - accStr1 = ""; - accValue = 0; + accStr1 = ""; + accValue = 0; for(j=0;jPointNo; - AccValue[ValueCount].Value = accValue;// _atoi64(accStr.c_str()); + AccValue[ValueCount].Value = static_cast(accValue);// _atoi64(accStr.c_str()); AccValue[ValueCount].Status = status; AccValue[ValueCount].time = mSec; ValueCount++; @@ -1807,7 +1903,7 @@ void CDLT645DataProcThread::RecvAccWithoutTimeProcess07(byte *recvBuff) ValueCount = 0; if((ChgCount>0)&&(g_DLT645IsMainFes==true))//主机才报告变化数据 { - m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu,ChgCount,&ChgAcc[0]); + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu,ChgCount,&ChgAcc[0]); } } } @@ -1818,29 +1914,31 @@ void CDLT645DataProcThread::RecvAccWithoutTimeProcess07(byte *recvBuff) { accStr = ""; accStr1 = ""; - accValue = 0; + accValue = 0; for(j=0;j>4)&0x0f)*10; + tempValue = static_cast(tempValue*pow(100,dataByteLen-1-j)); +// tempValue = (accByte / 16) * 10; +// tempValue += (accByte % 16); +// for (k = 1; k < dataByteLen - j; k++) +// tempValue = tempValue * 100; + //LOGDEBUG("accValue=%lld", accValue); + accValue += tempValue; + //memset(accData,0,sizeof(char)*256); //itoa(accByte,accData,10); //< int 转 char //accStr1 = (string)accData; // accStr += accStr1; } - //LOGDEBUG("accValue=%lld", accValue); + //LOGDEBUG("accValue=%lld", accValue); if((pAcc=GetFesAccByParam23(m_ptrCFesRtu,StartPointNo,i,Di23))!=NULL) { status = CN_FesValueUpdate; AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue;// _atoi64(accStr.c_str()); + AccValue[ValueCount].Value = static_cast(accValue);// _atoi64(accStr.c_str()); AccValue[ValueCount].Status = status; AccValue[ValueCount].time = mSec; ValueCount++; @@ -1850,7 +1948,7 @@ void CDLT645DataProcThread::RecvAccWithoutTimeProcess07(byte *recvBuff) ValueCount = 0; if((ChgCount>0)&&(g_DLT645IsMainFes==true))//主机才报告变化数据 { - m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu,ChgCount,&ChgAcc[0]); + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu,ChgCount,&ChgAcc[0]); } } } @@ -1862,7 +1960,7 @@ void CDLT645DataProcThread::RecvAccWithoutTimeProcess07(byte *recvBuff) ValueCount = 0; if((ChgCount>0)&&(g_DLT645IsMainFes==true))//主机才报告变化数据 { - m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu,ChgCount,&ChgAcc[0]); + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu,ChgCount,&ChgAcc[0]); } } } diff --git a/product/src/fes/protocol/dlt645/DLT645DataProcThread.h b/product/src/fes/protocol/dlt645/DLT645DataProcThread.h index f88fb37c..787439e0 100644 --- a/product/src/fes/protocol/dlt645/DLT645DataProcThread.h +++ b/product/src/fes/protocol/dlt645/DLT645DataProcThread.h @@ -121,6 +121,8 @@ public: int m_timerCount; int m_timerCountReset; + int feNum = 0; + CFesBase* m_ptrCFesBase; CFesChanPtr m_ptrCFesChan; //< 主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 CFesRtuPtr m_ptrCFesRtu; //< 当前使用RTU数据区,DLT645 每个通道对应一个RTU数据,所以不需要轮询处理。 diff --git a/product/src/fes/protocol/dlt645/dlt645.pro b/product/src/fes/protocol/dlt645/dlt645.pro index 5fc46bcd..ba63e5af 100644 --- a/product/src/fes/protocol/dlt645/dlt645.pro +++ b/product/src/fes/protocol/dlt645/dlt645.pro @@ -8,10 +8,12 @@ SOURCES += \ DLT645.cpp \ DLT645DataProcThread.cpp \ ../combase/SerialPortThread.cpp \ + ../combase/TcpClientThread.cpp \ HEADERS += \ DLT645.h \ DLT645DataProcThread.h \ + ../../include/TcpClientThread.h \ ../../include/SerialPortThread.h \ INCLUDEPATH += ../../include/ diff --git a/product/src/fes/protocol/dnp3_transmit/DNP3Transmit.cpp b/product/src/fes/protocol/dnp3_transmit/DNP3Transmit.cpp new file mode 100644 index 00000000..abb7f22a --- /dev/null +++ b/product/src/fes/protocol/dnp3_transmit/DNP3Transmit.cpp @@ -0,0 +1,320 @@ +#include "DNP3Transmit.h" +#include "pub_utility_api/I18N.h" +#include "pub_utility_api/CharUtil.h" + + +using namespace iot_public; + +DNP3Transmit g_dnp3transmit; +bool g_dnp3transmitIsMainFes = false; +bool g_dnp3transmitChanelRun = true; + + +int EX_SetBaseAddr(void *address) +{ + g_dnp3transmit.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + g_dnp3transmit.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + g_dnp3transmit.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + g_dnp3transmit.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + + +int EX_ChanTimer(int ChanNo) +{ + g_dnp3transmit.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + LOGDEBUG("g_dnp3transmit EX_ExitSystem() start"); + boost::ignore_unused_variable_warning(flag); + g_dnp3transmitChanelRun = false;//使所有的线程退出。 + return iotSuccess; +} + + + +DNP3Transmit::DNP3Transmit():m_ProtocolId(-1),m_ptrCFesBase(NULL) +{ + +} + +DNP3Transmit::~DNP3Transmit() +{ + +} + +int DNP3Transmit::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + } + + //规约映射表初始化 + if(m_ptrCFesBase != NULL) + { + m_ptrCFesBase->ProtocolRtuInitByParam1((char*)"dnp3_transmit"); + ReadConfigParam(); //加载配置文件中的RTU配置参数 + } + return iotSuccess; +} + +int DNP3Transmit::SetProperty(int IsMainFes) +{ + g_dnp3transmitIsMainFes = (IsMainFes == 1); + LOGDEBUG("DNP3Transmit::SetProperty g_dnp3transmitIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief DNP3Transmit::OpenChan 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return + */ +int DNP3Transmit::OpenChan(int MainChanNo, int ChanNo, int OpenFlag) +{ + CFesChanPtr ptrMainFesChan = GetChanDataByChanNo(MainChanNo); + CFesChanPtr ptrFesChan = GetChanDataByChanNo(ChanNo); + + if(ptrMainFesChan == NULL || ptrFesChan == NULL) + { + return iotFailed; + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //waitadd + //参数配置 + + SDNP3TransmitConfPara stRtuConfParam; + auto iterConfig = m_mapConfMap.find(ptrMainFesChan->m_Param.ChanNo); + if(iterConfig != m_mapConfMap.end()) + { + stRtuConfParam = iterConfig->second; + } + + //open chan thread + DNP3TransmitDataProcThreadPtr ptrThread = + boost::make_shared(m_ptrCFesBase,ptrMainFesChan,stRtuConfParam); + + if (ptrThread == NULL) + { + LOGERROR("dnp3_transmit EX_OpenChan() ChanNo:%d create DNP3MasterDataProcThread error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + + if(iotSuccess != ptrThread->init()) + { + LOGERROR("dnp3_transmit EX_OpenChan() ChanNo:%d init DNP3MasterDataProcThread error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + + m_vecDataThreadPtr.push_back(ptrThread); + ptrThread->resume(); //start Data THREAD + + + } + } + + //使用的是sdk连接 + ptrMainFesChan->SetComThreadRunFlag(CN_FesRunFlag); + + return iotSuccess; +} + +/** + * @brief DNP3Transmit::CloseChan 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param CloseFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int DNP3Transmit::CloseChan(int MainChanNo, int ChanNo, int CloseFlag) +{ + CFesChanPtr ptrMainFesChan = GetChanDataByChanNo(MainChanNo); + CFesChanPtr ptrFesChan = GetChanDataByChanNo(ChanNo); + + if(ptrMainFesChan == NULL || ptrFesChan == NULL) + { + return iotFailed; + } + + //虽然本协议使用sdk,不是自己管理连接,但是需要执行SetComThreadRunFlag(CN_FesStopFlag),否则冗余状态变化时,无法重新打开通道 + if ((CloseFlag == CN_FesChanThread_Flag) || (CloseFlag == CN_FesChanAndDataThread_Flag)) + { + ptrFesChan->SetComThreadRunFlag(CN_FesStopFlag); + LOGINFO("ChanNo=%d ptrFesChan->SetComThreadRunFlag(CN_FesStopFlag)", ptrFesChan->m_Param.ChanNo); + } + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + + return iotSuccess; +} + +/** + * @brief DNP3Transmit::ChanTimer 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int DNP3Transmit::ChanTimer(int MainChanNo) +{ + boost::ignore_unused_variable_warning(MainChanNo); + return iotSuccess; +} + +int DNP3Transmit::ReadConfigParam() +{ + if ( m_ptrCFesBase == NULL) + return iotFailed; + + m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"dnp3_transmit"); + if (m_ProtocolId == -1) + { + LOGERROR("ReadConfigParam() ProtoclID=dnp3_transmit error"); + return iotFailed; + } + LOGINFO("dnp3_transmit ProtoclID=%d",m_ProtocolId); + + CCommonConfigParse config; + SDNP3TransmitConfPara defaultRtuParam; + CFesChanPtr ptrChan = NULL; //CHAN数据区 + CFesRtuPtr ptrRTU = NULL; + + if (config.load("../../data/fes/", "dnp3_transmit.xml") == iotFailed) + { + LOGWARN("dnp3_transmit load dnp3_transmit.xml error"); + return iotSuccess; + } + + parseRtuConfig(config,"RTU?",defaultRtuParam); + + LOGDEBUG("dnp3_transmit nchanidx=%d",m_ptrCFesBase->m_vectCFesChanPtr.size()); + for (size_t nChanIdx = 0; nChanIdx < m_ptrCFesBase->m_vectCFesChanPtr.size(); nChanIdx++) + { + ptrChan = m_ptrCFesBase->m_vectCFesChanPtr[nChanIdx]; + if(ptrChan->m_Param.Used != 1 || m_ProtocolId != ptrChan->m_Param.ProtocolId) + { + continue; + } + + //found RTU + for (size_t nRtuIdx = 0; nRtuIdx < m_ptrCFesBase->m_vectCFesRtuPtr.size(); nRtuIdx++) + { + //LOGDEBUG("dnp3_transmit nRtuIdx=%d",nRtuIdx); + ptrRTU = m_ptrCFesBase->m_vectCFesRtuPtr[nRtuIdx]; + //LOGDEBUG("dnp3_transmit Used=%d ptrRTU->m_Param.ChanNo=%d ptrChan->m_Param.ChanNo=%d",ptrRTU->m_Param.Used , ptrRTU->m_Param.ChanNo , ptrChan->m_Param.ChanNo); + if (!ptrRTU->m_Param.Used || (ptrRTU->m_Param.ChanNo != ptrChan->m_Param.ChanNo)) + { + continue; + } + + SDNP3TransmitConfPara param = defaultRtuParam; + string strRtuName = "RTU" + IntToString(ptrRTU->m_Param.RtuNo); + parseRtuConfig(config,strRtuName,param); + + m_mapConfMap[ptrRTU->m_Param.ChanNo] = param; + } + + } + return iotSuccess; +} + +int DNP3Transmit::parseRtuConfig(CCommonConfigParse &configParse, const string &strRtuName, SDNP3TransmitConfPara &stParam) +{ + LOGDEBUG("dnp3_transmit:解析RTU参数,RTU=%s",strRtuName.c_str()); + + if(iotSuccess != configParse.getIntValue(strRtuName,"maxControlsPerRequest",stParam.maxControlsPerRequest)) + { + //采用默认配置 + return iotFailed; + } + + int values = 0; + + configParse.getIntValue(strRtuName,"selectTimeout",stParam.selectTimeout); + configParse.getIntValue(strRtuName,"solConfirmTimeout",stParam.solConfirmTimeout); + configParse.getIntValue(strRtuName,"unsolConfirmTimeout",stParam.unsolConfirmTimeout); + configParse.getIntValue(strRtuName,"numUnsolRetries",stParam.numUnsolRetries); + configParse.getBoolValue(strRtuName,"NullResponse",stParam.NullResponse); + configParse.getBoolValue(strRtuName,"allowUnsolicited",stParam.allowUnsolicited); + configParse.getBoolValue(strRtuName,"respondToAnyMaster",stParam.respondToAnyMaster); + configParse.getIntValue(strRtuName,"maxTxFragSize",stParam.maxTxFragSize); + configParse.getIntValue(strRtuName,"maxRxFragSize",stParam.maxRxFragSize); + configParse.getIntValue(strRtuName,"KeepAliveTimeout",stParam.KeepAliveTimeout); + configParse.getIntValue(strRtuName , "unsolClassMask" , values); + +// LOGERROR("value size %d" , values.size()); +// uint8_t mask = 0; +// for (const auto& value : values) { +// try { +// LOGERROR("value %s" , value); +// int classNum = std::stoi(value); +// switch (classNum) { +// case 0: mask |= opendnp3::ClassField::CLASS_0; LOGERROR("mask 0 : %d classNum :%d" , mask , classNum);break; +// case 1: mask |= opendnp3::ClassField::CLASS_1; LOGERROR("mask 1 : %d classNum :%d" , mask , classNum); break; +// case 2: mask |= opendnp3::ClassField::CLASS_2; LOGERROR("mask 2 : %d classNum :%d" , mask , classNum);break; +// case 3: mask |= opendnp3::ClassField::CLASS_3; LOGERROR("mask 3 : %d classNum :%d" , mask , classNum);break; +// default: +// break; +// } +// } catch (const std::exception& e) { +// LOGERROR("DNP3Transmit 参数解析错误! value:%s" , value); +// } +// } + + stParam.unsolClassMask = values ; + + configParse.getIntValue(strRtuName,"maxBinaryEvents",stParam.maxBinaryEvents); + configParse.getIntValue(strRtuName,"maxDoubleBinaryEvents",stParam.maxDoubleBinaryEvents); + configParse.getIntValue(strRtuName,"maxAnalogEvents",stParam.maxAnalogEvents); + configParse.getIntValue(strRtuName,"maxCounterEvents",stParam.maxCounterEvents); + configParse.getIntValue(strRtuName,"maxFrozenCounterEvents",stParam.maxFrozenCounterEvents); + configParse.getIntValue(strRtuName,"maxBinaryOutputStatusEvents",stParam.maxBinaryOutputStatusEvents); + configParse.getIntValue(strRtuName,"maxAnalogOutputStatusEvents",stParam.maxAnalogOutputStatusEvents); + configParse.getIntValue(strRtuName,"maxOctetStringEvents",stParam.maxOctetStringEvents); + + LOGDEBUG("dnp3_transmit:解析RTU参数,RTU=%s end",strRtuName.c_str()); +} + +void DNP3Transmit::ClearDataProcThreadByChanNo(int nChanNo) +{ + for(auto it = m_vecDataThreadPtr.begin(); it != m_vecDataThreadPtr.end();it++) + { + const DNP3TransmitDataProcThreadPtr &ptrThread = *it; + if( ptrThread->getChannelNo() == nChanNo) + { + m_vecDataThreadPtr.erase(it); + LOGINFO("dnp3_transmit::ClearDataProcThreadByChanNo %d ok",nChanNo); + break; + } + } +} diff --git a/product/src/fes/protocol/dnp3_transmit/DNP3Transmit.h b/product/src/fes/protocol/dnp3_transmit/DNP3Transmit.h new file mode 100644 index 00000000..e5e6eb3a --- /dev/null +++ b/product/src/fes/protocol/dnp3_transmit/DNP3Transmit.h @@ -0,0 +1,44 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "DNP3TransmitDataProcThread.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "DNP3TransmitComm.h" +#include + + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API DNP3Transmit : public CProtocolBase +{ +public: + DNP3Transmit(); + virtual ~DNP3Transmit(); + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + + +private: + + int ReadConfigParam(); + int parseRtuConfig(CCommonConfigParse &configParse, const std::string &strRtuName, SDNP3TransmitConfPara &stParam); + void ClearDataProcThreadByChanNo(int nChanNo); + +private: + int m_ProtocolId; //本协议的ID + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + DNP3TransmitDataProcThreadPtrSeq m_vecDataThreadPtr; //存放所有本协议的线程处理指针 + boost::unordered_map m_mapConfMap; //存储RTU对应的配置参数 +}; diff --git a/product/src/fes/protocol/dnp3_transmit/DNP3TransmitComm.h b/product/src/fes/protocol/dnp3_transmit/DNP3TransmitComm.h new file mode 100644 index 00000000..bc42b690 --- /dev/null +++ b/product/src/fes/protocol/dnp3_transmit/DNP3TransmitComm.h @@ -0,0 +1,70 @@ +#ifndef DNP3TRANSMITCOMM_H +#define DNP3TRANSMITCOMM_H + + +#include + + +#define DNP3_CLASS0 (0) +#define DNP3_CLASS1 (1) +#define DNP3_CLASS2 (2) +#define DNP3_CLASS3 (3) + + + + +const int CN_THREAD_SIZE_TRAN = 1; //DNP3管理器线程数 + + +//从站配置信息 +typedef struct _SDNP3TransmitConfPara +{ + int maxControlsPerRequest; //单个APDU能够处理的最大控制命令数量 + int selectTimeout; //针对SBO遥控类型从站收到“选择”命令后,允许“操作”命令执行的最长等待时间 + int solConfirmTimeout; //等待主站对“请求响应”的确认的超时时间 + int unsolConfirmTimeout; //等待主站对“未请求响应”的确认的超时时间(单位:秒) + int numUnsolRetries; //发送未请求响应后,如果未收到主站确认,尝试重传的次数 + bool NullResponse; //从站推迟处理 READ 请求,直到未请求的 NULL 响应完成 + bool allowUnsolicited; //启动非请求响应功能 + uint8_t unsolClassMask; //未请求响应中包含的事件类别 + bool respondToAnyMaster; //是否检查主站地址是否与预期一致 + int maxTxFragSize; //从站发送的数据分片的最大尺寸 + int maxRxFragSize; //从站能够接收的数据分片的最大尺寸 + int KeepAliveTimeout; //从站发送链路状态请求的间隔 + + int maxBinaryEvents; //二进制输入事件的最大数量 + int maxDoubleBinaryEvents; //双位二进制输入事件的最大数量 + int maxAnalogEvents; //模拟量输入事件的最大数量 + int maxCounterEvents; //计数器事件的最大数量 + int maxFrozenCounterEvents; //冻结计数器事件的最大数量 + int maxBinaryOutputStatusEvents; //二进制输出状态事件的最大数量 + int maxAnalogOutputStatusEvents; //模拟量输出状态事件的最大数量 + int maxOctetStringEvents; //八位字节串事件的最大数量 + + + _SDNP3TransmitConfPara() + { + maxControlsPerRequest = 10; + selectTimeout = 10; + solConfirmTimeout = 5; + unsolConfirmTimeout = 5; + numUnsolRetries = 5; + NullResponse = false; + allowUnsolicited = true; + respondToAnyMaster = false; + maxTxFragSize = 2048; + maxRxFragSize = 2048; + maxBinaryEvents = 100; + maxDoubleBinaryEvents = 100; + maxAnalogEvents = 100; + maxCounterEvents = 100; + maxFrozenCounterEvents = 20; + maxBinaryOutputStatusEvents = 100; + maxAnalogOutputStatusEvents = 100; + maxOctetStringEvents = 10; + KeepAliveTimeout = 60; + unsolClassMask = 0xF; + } +}SDNP3TransmitConfPara, *P_SDNP3TransmitConfPara; + +#endif // DNP3TRANSMITCOMM_H diff --git a/product/src/fes/protocol/dnp3_transmit/DNP3TransmitDataProcThread.cpp b/product/src/fes/protocol/dnp3_transmit/DNP3TransmitDataProcThread.cpp new file mode 100644 index 00000000..7684faa7 --- /dev/null +++ b/product/src/fes/protocol/dnp3_transmit/DNP3TransmitDataProcThread.cpp @@ -0,0 +1,514 @@ +#include "DNP3TransmitDataProcThread.h" +#include +#include +#include +#include + + + +extern bool g_dnp3transmitIsMainFes; +extern bool g_dnp3transmitChanelRun; +uint8_t ConvertToDNP3Flags(int fesStatus , bool type = false); + +DNP3TransmitDataProcThread::DNP3TransmitDataProcThread(CFesBase *ptrCFesBase, const CFesChanPtr &ptrChan, const SDNP3TransmitConfPara &stConfParam) + :CTimerThreadBase("DNP3TransmitDataProcThread",CN_RunPeriodMsec,0,true), + m_ptrCFesBase(ptrCFesBase), + m_ptrFesChan(ptrChan), + m_ptrCurChan(NULL), + m_ptrCurRtu(NULL), + m_pDnpManager(NULL), + m_stRtuParam(stConfParam), + m_curIP(0), + m_channelListener(std::make_shared()), + m_updateBuilder(std::make_shared()) +{ + +} + +DNP3TransmitDataProcThread::~DNP3TransmitDataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + //虽然本协议使用sdk,不是自己管理连接,但是需要执行SetComThreadRunFlag(CN_FesStopFlag),否则冗余状态变化时,无法重新打开通道 + m_ptrCurChan->SetLinkStatus(CN_FesChanDisconnect); + m_ptrFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + if(m_ptrCurRtu != NULL) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCurRtu, CN_FesRtuComDown); + } + + //waitadd + //需要处理dnp3连接的问题 + if (m_pDnpManager) + { + m_pDnpManager->Shutdown(); + delete m_pDnpManager; + } + m_pDnpManager = NULL; +} + +int DNP3TransmitDataProcThread::beforeExecute() +{ + return 0; +} + +void DNP3TransmitDataProcThread::execute() +{ + if (!m_channel || !m_outstation) + { + LOGWARN("DNP3 execute m_channel not exist! try init.."); + CreateConnection(); + return; + } + + //收到线程退出标志不再继续执行 + if( !g_dnp3transmitChanelRun ) + return; + + m_ptrCurChan = GetCurrentChanData(m_ptrFesChan); + + if(m_ptrCurChan== NULL) + return; + + if (m_channelListener->GetState() != ChannelState::OPEN) + { + m_ptrCurChan->SetLinkStatus(CN_FesChanConnect); + m_ptrCurRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + m_ptrCFesBase->WriteRtuSatus(m_ptrCurRtu, CN_FesRtuComDown); + LOGWARN("DNP3 channel disconnect... wait Reconnect"); + return; + + }else if( m_channelListener->GetState() == ChannelState::OPEN ) + { + m_ptrCurChan->SetLinkStatus(CN_FesChanConnect); + m_ptrCurRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); + m_ptrCFesBase->WriteRtuSatus(m_ptrCurRtu, CN_FesRtuNormal); + } + + updateAllPointValue(true); +} + +void DNP3TransmitDataProcThread::beforeQuit() +{ + +} + +int DNP3TransmitDataProcThread::getChannelNo() +{ + return m_ptrFesChan->m_Param.ChanNo; +} + +int DNP3TransmitDataProcThread::getRtuNo() +{ + return m_ptrCurRtu->m_Param.RtuNo; +} + +int DNP3TransmitDataProcThread::init() +{ + LOGDEBUG("DNP3Transmit init start!"); + m_ptrCurChan = m_ptrFesChan; + m_ptrCurRtu = GetRtuDataByChanData(m_ptrFesChan); + if ((m_ptrFesChan == NULL) || (m_ptrCurRtu == NULL)) + { + LOGERROR("DNP3Transmit m_ptrCurRtu or m_ptrFesChan is NULL"); + return iotFailed; + } + + //waitadd + //这里是否要像61850一样处理双IP和连接时间 后续处理 + m_curIP = 0; + + //设置通讯状态 + m_ptrFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + m_ptrCFesBase->WriteRtuSatus(m_ptrCurRtu, CN_FesRtuComDown); + + if(iotSuccess != initDNP3ConnPara()) + { + LOGWARN("m_pDnpManager init error! ChanNo=%d" , getChannelNo()); + return iotFailed; + } + + //配置数据点类别 + if(iotSuccess != configOpenDNP3Database()) + { + LOGWARN("config OpenDNP3Database error! ChanNo=%d" , getChannelNo()); + return iotFailed; + } + +} + +int DNP3TransmitDataProcThread::initDNP3ConnPara() +{ + //配置DNP管理器 + if( m_pDnpManager != NULL ) + { + LOGWARN("m_pDnpManager already init! ChanNo=%d" , getChannelNo()); + return iotSuccess; + } + m_pDnpManager = new DNP3Manager(CN_THREAD_SIZE_TRAN , DNP3TransmitLoggHandler::Create()); + + if( NULL == m_pDnpManager) + { + LOGERROR("m_pDnpManager new faliure!"); + return iotFailed; + } + + //配置dnp3相关参数 + m_outstationConf.outstation.params.maxControlsPerRequest = m_stRtuParam.maxControlsPerRequest; + m_outstationConf.outstation.params.selectTimeout = TimeDuration::Seconds(m_stRtuParam.selectTimeout); + m_outstationConf.outstation.params.solConfirmTimeout = TimeDuration::Seconds(m_stRtuParam.solConfirmTimeout); + m_outstationConf.outstation.params.unsolConfirmTimeout = TimeDuration::Seconds(m_stRtuParam.unsolConfirmTimeout); + m_outstationConf.outstation.params.numUnsolRetries = m_stRtuParam.numUnsolRetries < 0? NumRetries::Infinite():NumRetries::Fixed(m_stRtuParam.numUnsolRetries); + m_outstationConf.outstation.params.noDefferedReadDuringUnsolicitedNullResponse = m_stRtuParam.NullResponse; + m_outstationConf.outstation.params.maxTxFragSize = m_stRtuParam.maxTxFragSize; + m_outstationConf.outstation.params.maxRxFragSize = m_stRtuParam.maxRxFragSize; + m_outstationConf.outstation.params.allowUnsolicited = m_stRtuParam.allowUnsolicited; + m_outstationConf.outstation.params.respondToAnyMaster = m_stRtuParam.respondToAnyMaster; + m_outstationConf.outstation.params.unsolClassMask = opendnp3::ClassField(m_stRtuParam.unsolClassMask); + LOGDEBUG("ClassField bitfield:%d" ,static_cast(m_outstationConf.outstation.params.unsolClassMask.GetBitfield()) ); + + m_outstationConf.outstation.eventBufferConfig = EventBufferConfig(m_stRtuParam.maxBinaryEvents , + m_stRtuParam.maxDoubleBinaryEvents , + m_stRtuParam.maxAnalogEvents, + m_stRtuParam.maxCounterEvents, + m_stRtuParam.maxFrozenCounterEvents, + m_stRtuParam.maxBinaryOutputStatusEvents, + m_stRtuParam.maxAnalogOutputStatusEvents, + m_stRtuParam.maxOctetStringEvents); + + m_outstationConf.link.LocalAddr = m_ptrCurRtu->m_Param.ResParam1 <= 0?2: m_ptrCurRtu->m_Param.ResParam1; //从站地址若没配置默认2 + m_outstationConf.link.RemoteAddr = m_ptrCurRtu->m_Param.RtuAddr; + m_outstationConf.link.KeepAliveTimeout = m_stRtuParam.KeepAliveTimeout < 0 ? TimeDuration::Max():TimeDuration::Seconds(m_stRtuParam.KeepAliveTimeout); + + return iotSuccess; +} + +int DNP3TransmitDataProcThread::CreateConnection() +{ + if (!m_pDnpManager || !m_ptrFesChan) + { + LOGERROR("CreateConnection m_pDnpManager or m_ptrFesChan is NULL!"); + return iotFailed; + } + + if( m_channel) + { + m_channel->Shutdown(); + m_channel.reset(); + } + + if( m_outstation ) + { + m_outstation.reset(); + } + + LOGINFO("DNP3 Transmit CreateConnection!"); + + //设置日志等级 + const auto logLevels = levels::NORMAL | levels::ALL_APP_COMMS; + IPEndpoint IpAndPort(m_ptrFesChan->m_Param.NetRoute[m_curIP].NetDesc ,m_ptrFesChan->m_Param.NetRoute[m_curIP].PortNo); + + try{ + + m_channel = m_pDnpManager->AddTCPServer(m_ptrFesChan->m_Param.ChanName, + logLevels, + ServerAcceptMode::CloseExisting, + IpAndPort, + m_channelListener); + } + catch(const std::exception& e) + { + LOGERROR("AddTCPServer Failure! error: %s" , e.what()); + return iotFailed; + } + + + m_outstation = m_channel->AddOutstation(m_ptrCurRtu->m_Param.RtuName, + NotSupportCommandHandler::Create(), + DefaultOutstationApplication::Create(), + m_outstationConf); + + + //获取最新静态值更新值 + updateAllPointValue(); + m_outstation->Enable(); + + LOGINFO("DNP3 OUTSTATION ADD AND CONNECT SUCCESS!"); + + return iotSuccess; +} + +int DNP3TransmitDataProcThread::configOpenDNP3Database() +{ + + //配置dnp3数据库点 + if( m_ptrCurRtu == NULL) + { + LOGERROR("m_ptrCurRtu is NULL!"); + return iotFailed; + } + + DatabaseConfig config; + configAiPoint(config); + configDiPoint(config); + configAccPoint(config); + m_outstationConf.database = config; + return iotSuccess; + +} + +PointClass checkPointClass(int type) +{ + PointClass classType; + switch (type) { + case DNP3_CLASS0: + classType = PointClass::Class0; + break; + case DNP3_CLASS1: + classType = PointClass::Class1; + break; + case DNP3_CLASS2: + classType = PointClass::Class2; + break; + case DNP3_CLASS3: + classType = PointClass::Class3; + break; + default: + classType = PointClass::Class0; + break; + } + return classType; +} + +//在opendnp3中只有模拟量和累计量 状态有错误的选项 , type就是用来标志是否是这两个之一 +uint8_t ConvertToDNP3Flags(int fesStatus , bool type) +{ + uint8_t flags = 0; + + if( fesStatus & CN_FesValueUpdate) + { + flags |= 0x1; //ONLINE 由于多种点都定义值都相同 + } + + if( fesStatus & CN_FesValueComDown ) + { + flags |= 0x4; //COMM_LOST + } + + + if( type ) + { + //累计量和模拟量都是一样的值 + if( fesStatus & CN_FesValueExceed ) + { + flags |= 0x20; //OVERRANGE + } + + if( fesStatus & CN_FesValueInvaild ) + { + flags |= 0x40; //AnalogQuality::REFERENCE_ERR; + } + } + + return flags; +} + + +void DNP3TransmitDataProcThread::configAiPoint(DatabaseConfig &con) +{ + //模拟量输入 + con.analog_input.clear(); + for(int i = 0 ; i < m_ptrCurRtu->m_MaxFwAiPoints ; i ++ ) + { + SFesFwAi *pFwAi = m_ptrCurRtu->m_pFwAi+i; + AnalogConfig tmp; + tmp.clazz = checkPointClass(pFwAi->ResParam2); + tmp.svariation = StaticAnalogVariationSpec::from_type(pFwAi->ResParam3); + tmp.evariation = EventAnalogVariationSpec::from_type(pFwAi->ResParam4); + //tmp.deadband = 0; + con.analog_input[pFwAi->ResParam1] = tmp; + } + + //模拟量输出 + con.analog_output_status.clear(); + for(int j = 0 ; j < m_ptrCurRtu->m_MaxFwAoPoints ; j++) + { + SFesFwAo *pFwAo = m_ptrCurRtu->m_pFwAo + j; + AOStatusConfig tmpAO; + tmpAO.clazz = checkPointClass(pFwAo->ResParam2); + tmpAO.svariation = StaticAnalogOutputStatusVariationSpec::from_type(pFwAo->ResParam3); + tmpAO.evariation = EventAnalogOutputStatusVariationSpec::from_type(pFwAo->ResParam4); + con.analog_output_status[pFwAo->ResParam1] = tmpAO; + } +} + +void DNP3TransmitDataProcThread::configDiPoint(DatabaseConfig &con) +{ + //单点数字量输入 + con.binary_input.clear(); + for( int i = 0 ; i < m_ptrCurRtu->m_MaxFwDiPoints; i++) + { + SFesFwDi *pFwDi = m_ptrCurRtu->m_pFwDi + i; + BinaryConfig tmp; + tmp.clazz = checkPointClass(pFwDi->ResParam2); + tmp.svariation = StaticBinaryVariationSpec::from_type(pFwDi->ResParam3); + tmp.evariation = EventBinaryVariationSpec::from_type(pFwDi->ResParam4); + con.binary_input[pFwDi->ResParam1] = tmp; + } + + //单点数字量输出 + con.binary_output_status.clear(); + for( int j = 0 ; j < m_ptrCurRtu->m_MaxFwDoPoints ; j++) + { + SFesFwDo *pFwDo = m_ptrCurRtu->m_pFwDo + j; + BOStatusConfig tmpDO; + tmpDO.clazz = checkPointClass(pFwDo->ResParam2); + tmpDO.svariation = StaticBinaryOutputStatusVariationSpec::from_type(pFwDo->ResParam3); + tmpDO.evariation = EventBinaryOutputStatusVariationSpec::from_type(pFwDo->ResParam4); + con.binary_output_status[pFwDo->ResParam1] = tmpDO; + } + + + //双点数字量输入 + con.double_binary.clear(); + for( int t = 0 ; t < m_ptrCurRtu->m_MaxFwDDiPoints; t++) + { + SFesFwDi *pFwDDi = m_ptrCurRtu->m_pFwDDi + t; + DoubleBitBinaryConfig tmpDDi; + tmpDDi.clazz = checkPointClass(pFwDDi->ResParam2); + tmpDDi.svariation = StaticDoubleBinaryVariationSpec::from_type(pFwDDi->ResParam3); + tmpDDi.evariation = EventDoubleBinaryVariationSpec::from_type(pFwDDi->ResParam4); + con.double_binary[pFwDDi->ResParam1] = tmpDDi; + } +} + +void DNP3TransmitDataProcThread::configAccPoint(DatabaseConfig &con) +{ + con.counter.clear(); + for( int i = 0 ; i < m_ptrCurRtu->m_MaxFwAccPoints ; i ++) + { + SFesFwAcc *pFwAcc = m_ptrCurRtu->m_pFwAcc + i; + CounterConfig tmpAcc; + tmpAcc.clazz = checkPointClass(pFwAcc->ResParam2); + tmpAcc.svariation = StaticCounterVariationSpec::from_type(pFwAcc->ResParam3); + tmpAcc.evariation = EventCounterVariationSpec::from_type(pFwAcc->ResParam4); + con.counter[pFwAcc->ResParam1] = tmpAcc; + } +} + +void DNP3TransmitDataProcThread::updateAllPointValue(bool flag) +{ + //初始化所有点位的值 + opendnp3::EventMode modeType = flag?(opendnp3::EventMode::Detect):(opendnp3::EventMode::Suppress); + + //模拟量 + int i = 0 , count = m_outstationConf.database.analog_input.size(); + for(i = 0 ; i < count ; i++ ) + { + SFesFwAi *pFwAi = m_ptrCurRtu->m_pFwAi+i; + uint8_t dnp3Flag = ConvertToDNP3Flags(pFwAi->Status , true); + m_updateBuilder->Update(Analog(pFwAi->Value , opendnp3::Flags(dnp3Flag) , DNPTime(pFwAi->time)) , pFwAi->ResParam1 ,modeType); + } + + + //数字量 + count = m_outstationConf.database.binary_input.size(); + for( i = 0; i < count ; i++ ) + { + SFesFwDi *pFwDi = m_ptrCurRtu->m_pFwDi + i; + uint8_t dnp3Flag = ConvertToDNP3Flags(pFwDi->Status); + bool tmp = pFwDi->Value?true:false; + m_updateBuilder->Update(Binary(tmp,Flags(dnp3Flag) , DNPTime(pFwDi->time)) , pFwDi->ResParam1 , modeType); + } + + count = m_outstationConf.database.double_binary.size(); + for( i = 0 ; i < count ; i ++) + { + SFesFwDi *pFwDDi = m_ptrCurRtu->m_pFwDDi + i; + uint8_t dnp3FlagDDo = ConvertToDNP3Flags(pFwDDi->Status); + m_updateBuilder->Update(DoubleBitBinary(DoubleBitSpec::from_type(pFwDDi->Value) , opendnp3::Flags(dnp3FlagDDo) , DNPTime(pFwDDi->time)) , pFwDDi->ResParam1 , modeType); + } + + //累计量 + count = m_outstationConf.database.counter.size(); + for( i = 0 ; i < count ; i ++) + { + SFesFwAcc *pFwAcc = m_ptrCurRtu->m_pFwAcc + i; + uint8_t dnp3FlagAcc = ConvertToDNP3Flags(pFwAcc->Status); + m_updateBuilder->Update(Counter(pFwAcc->Value , opendnp3::Flags(dnp3FlagAcc) , DNPTime(pFwAcc->time)) , pFwAcc->ResParam1 , modeType); + } + + //后续冻结计数量、OctetString、time + + updateOutPointValue(flag); + + m_outstation->Apply(m_updateBuilder->Build()); + + LOGINFO("updateAllPointValue END!"); + + +} + +void DNP3TransmitDataProcThread::updateChangePointValue(bool flag) +{ +// int count = 0 , retNum = 0; +// opendnp3::EventMode modeType = flag?(opendnp3::EventMode::Detect):(opendnp3::EventMode::Suppress); +// //只更新变化的点位值 + +// //模拟量 +// SFesFwChgAi *pChgAi = NULL , pChgAiData = NULL; +// SFesFwAi *pFwAi = NULL; +// uint8_t dnp3Flag = 0; + +// count = m_ptrCurRtu->GetFwChgDDiNum(); +// pChgAiData = malloc(count * sizeof(SFesFwChgAi)); +// retNum = m_ptrCurRtu->ReadFwChgDi(count , pChgAiData); + +// for(int i = 0; i < retNum ; i++ ) +// { +// pChgAi = pChgAiData + i; +// if(pChgAi->RemoteNo >= m_ptrCurRtu->m_MaxFwAiPoints) +// { +// continue; +// } +// pFwAi = m_ptrCurRtu->m_pFwAi + pChgAi->RemoteNo; +// if( NULL != pFwAi ) +// { +// dnp3Flag = ConvertToDNP3Flags(pFwAi->Status); +// m_updateBuilder->Update(Analog(pFwAi->Value , opendnp3::Flags(dnp3Flag) , DNPTime(pFwAi->time)) , i ,modeType); +// } + +// } + + +// updateOutPointValue(flag); + + + +} + +void DNP3TransmitDataProcThread::updateOutPointValue(bool flag) +{ + opendnp3::EventMode modeType = flag?(opendnp3::EventMode::Detect):(opendnp3::EventMode::Suppress); + + int i , count = m_outstationConf.database.analog_output_status.size(); + for( i = 0 ; i < count ; i++ ) + { + SFesFwAo *pFwAo = m_ptrCurRtu->m_pFwAo+i; + uint8_t dnp3Flag = ConvertToDNP3Flags(pFwAo->Status , true); + m_updateBuilder->Update(AnalogOutputStatus(pFwAo->Value , opendnp3::Flags(dnp3Flag) , DNPTime(pFwAo->time)) , pFwAo->ResParam1 , modeType); //初始配值不产生变化 + } + + count = m_outstationConf.database.binary_output_status.size(); + for(i = 0; i < count ; i++) + { + SFesFwDo *pFwDo = m_ptrCurRtu->m_pFwDo + i; + uint8_t dnp3FlagDo = ConvertToDNP3Flags(pFwDo->Status); + bool tmpDo = pFwDo->Value?true:false; + m_updateBuilder->Update(BinaryOutputStatus(tmpDo ,opendnp3::Flags(dnp3FlagDo) , DNPTime(pFwDo->time) ) , pFwDo->ResParam1, modeType); + } + +} + + + diff --git a/product/src/fes/protocol/dnp3_transmit/DNP3TransmitDataProcThread.h b/product/src/fes/protocol/dnp3_transmit/DNP3TransmitDataProcThread.h new file mode 100644 index 00000000..e97bf21c --- /dev/null +++ b/product/src/fes/protocol/dnp3_transmit/DNP3TransmitDataProcThread.h @@ -0,0 +1,175 @@ +#ifndef DNP3TRANSMITDATAPROCTHREAD_H +#define DNP3TRANSMITDATAPROCTHREAD_H + +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include +#include +#include +#include "DNP3TransmitComm.h" +#include +#include + + +using namespace opendnp3; + +using namespace std; + +class DNP3TransmitChannelListener; + +class DNP3TransmitDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + DNP3TransmitDataProcThread(CFesBase *ptrCFesBase,const CFesChanPtr &ptrChan,const SDNP3TransmitConfPara &stConfParam); + virtual ~DNP3TransmitDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + int getChannelNo(); //获取当前通道号 + int getRtuNo(); //获取当前RTU号 + int init(); + int initDNP3ConnPara(); //配置dnp3的连接参数 + int CreateConnection(); //建立连接 + int configOpenDNP3Database(); + + void configAiPoint(DatabaseConfig &con); + void configDiPoint(DatabaseConfig &con); + void configAccPoint(DatabaseConfig &con); + + void updateAllPointValue(bool flag = false); //这个flag代表是否update时产生时间 + void updateChangePointValue(bool flag = false); + void updateOutPointValue(bool flag = false); //更新输出点数据 + +private: + CFesBase* m_ptrCFesBase; + CFesChanPtr m_ptrFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesChanPtr m_ptrCurChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCurRtu; //当前使用RTU数据区,本协议每个通道对应一个RTU数据,所以不需要轮询处理。 + DNP3Manager* m_pDnpManager; //dnp3库根管理器 管理主从站连接 + + std::shared_ptr m_channel; //dnp3通道 + std::shared_ptr m_outstation; //dnp3子站指针 + SDNP3TransmitConfPara m_stRtuParam; //Rtu配置参数 + OutstationStackConfig m_outstationConf; //dnp3子站配置 + std::shared_ptr m_channelListener; // 通道状态监听器 + std::shared_ptr m_updateBuilder; //数据更新器 + int m_curIP; //0=主通道 1=备通道 + +}; + +typedef boost::shared_ptr DNP3TransmitDataProcThreadPtr; +typedef std::vector DNP3TransmitDataProcThreadPtrSeq; + + + +//dnp3日志类实现 +class DNP3TransmitLoggHandler final : public ILogHandler, private Uncopyable +{ + public: + void log(ModuleId module, const char* id, LogLevel level, const char* location, const char* message) override { + // 输出日志信息到控制台 + std::stringstream sstream; + sstream << "Module: " << module.value + << ", ID: " << id + << ", Location: " << location + << ", Message: " << message; + std::string levelStr = levelToString(level); + + + // 检查 level 中的每个标志并调用对应的日志函数 + if (level.value & opendnp3::flags::ERR.value) { + LOGERROR("DNP3TransmitLoggHandler logtype:%s logContext:%s", + "ERROR", sstream.str().c_str()); + } + if (level.value & opendnp3::flags::WARN.value) { + LOGWARN("DNP3TransmitLoggHandler logtype:%s logContext:%s", + "WARNING", sstream.str().c_str()); + } + if (level.value & opendnp3::flags::INFO.value) { + LOGINFO("DNP3TransmitLoggHandler logtype:%s logContext:%s", + "INFO", sstream.str().c_str()); + } + if (level.value & opendnp3::flags::EVENT.value) { + LOGINFO("DNP3TransmitLoggHandler logtype:%s logContext:%s", + "EVENT", sstream.str().c_str()); // EVENT 可以映射到 INFO + } + // 调试级别:处理通信相关的日志(可选) + if (level.value & (opendnp3::flags::APP_HEX_RX.value | opendnp3::flags::APP_HEX_TX.value | + opendnp3::flags::LINK_RX.value | opendnp3::flags::LINK_TX.value)) { + LOGDEBUG("DNP3TransmitLoggHandler logtype:%s logContext:%s", + levelStr.c_str(), sstream.str().c_str()); + } + } + + static std::shared_ptr Create() + { + return std::make_shared(); + } + +private: + // 将 LogLevel 转换为字符串(可选,用于调试或显示) + std::string levelToString(opendnp3::LogLevel &level) { + std::string result; + if (level.value & opendnp3::flags::ERR.value) result += "ERROR "; + if (level.value & opendnp3::flags::WARN.value) result += "WARNING "; + if (level.value & opendnp3::flags::INFO.value) result += "INFO "; + if (level.value & opendnp3::flags::EVENT.value) result += "EVENT "; + if (level.value & opendnp3::flags::APP_HEX_RX.value) result += "APP_HEX_RX "; + if (level.value & opendnp3::flags::APP_HEX_TX.value) result += "APP_HEX_TX "; + if (level.value & opendnp3::flags::LINK_RX.value) result += "LINK_RX "; + return result.empty() ? "UNKNOWN" : result; + } +}; + +//dnp3通道监视器 +class DNP3TransmitChannelListener final : public opendnp3::IChannelListener +{ +public: + virtual void OnStateChange(ChannelState state) override + { + std::stringstream sstr; + sstr<< "channel state change: " << ChannelStateSpec::to_human_string(state); + LOGDEBUG("%s" , sstr.str().c_str()); + m_state = state; + } + + static std::shared_ptr Create() + { + return std::make_shared(); + } + + DNP3TransmitChannelListener() :m_state(opendnp3::ChannelState::CLOSED) {} + + opendnp3::ChannelState GetState() const { return m_state; } + +private: + opendnp3::ChannelState m_state; + +}; + + +//暂未实现遥控命令,全部回复状态不支持 +class NotSupportCommandHandler : public SimpleCommandHandler +{ +public: + static std::shared_ptr Create() + { + return std::make_shared(); + } + + NotSupportCommandHandler() : SimpleCommandHandler(CommandStatus::NOT_SUPPORTED) {} +}; + + + +#endif // DNP3TRANSMITDATAPROCTHREAD_H diff --git a/product/src/fes/protocol/dnp3_transmit/dnp3_transmit.pro b/product/src/fes/protocol/dnp3_transmit/dnp3_transmit.pro new file mode 100644 index 00000000..0202abf6 --- /dev/null +++ b/product/src/fes/protocol/dnp3_transmit/dnp3_transmit.pro @@ -0,0 +1,45 @@ +# ARM板上资源有限,不会与云平台混用,不编译 +message("Compile only in x86 environment") +# requires(contains(QMAKE_HOST.arch, x86_64)) +requires(!contains(QMAKE_HOST.arch, aarch64):!linux-aarch64*) + + +QT -= core gui sql +CONFIG -= qt + +TARGET = dnp3_transmit +TEMPLATE = lib + + + +INCLUDEPATH += ../../include/ +INCLUDEPATH += ../../include/libdnp3 + +HEADERS += \ + DNP3Transmit.h \ + DNP3TransmitDataProcThread.h \ + DNP3TransmitComm.h + +SOURCES += \ + DNP3Transmit.cpp \ + DNP3TransmitDataProcThread.cpp + + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase -lrdb_api +LIBS += -lopendnp3 + + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + + diff --git a/product/src/fes/protocol/fesdatarecv/fesdatarecv.cpp b/product/src/fes/protocol/fesdatarecv/fesdatarecv.cpp index 42fad38d..4e7f2df3 100644 --- a/product/src/fes/protocol/fesdatarecv/fesdatarecv.cpp +++ b/product/src/fes/protocol/fesdatarecv/fesdatarecv.cpp @@ -86,7 +86,7 @@ int CFesdatarecv::SetBaseAddr(void *address) int CFesdatarecv::SetProperty(int IsMainFes) { - g_fesdatarecvIsMainFes = IsMainFes; + g_fesdatarecvIsMainFes = (IsMainFes != 0); LOGDEBUG("CFesdatarecv::SetProperty g_fesdatarecvIsMainFes:%d",IsMainFes); return iotSuccess; } @@ -236,11 +236,15 @@ int CFesdatarecv::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) */ int CFesdatarecv::ChanTimer(int MainChanNo) { + boost::ignore_unused_variable_warning(MainChanNo); + return iotSuccess; } int CFesdatarecv::ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + InformComThreadExit(); return iotSuccess; diff --git a/product/src/fes/protocol/fesdatarecv/fesdatarecvDataProcThread.cpp b/product/src/fes/protocol/fesdatarecv/fesdatarecvDataProcThread.cpp index 3d26b515..7a62abbe 100644 --- a/product/src/fes/protocol/fesdatarecv/fesdatarecvDataProcThread.cpp +++ b/product/src/fes/protocol/fesdatarecv/fesdatarecvDataProcThread.cpp @@ -411,7 +411,7 @@ void CFesdatarecvDataProcThread::ProcessAccFrame() uValue64 = 0; for (n = 0; n < CN_INT64_SIZE; n++) uValue64 |= (uint64)m_AppData.recvBuf[readx++] << (n * 8); - AccValue[j].Value = (int64)uValue64; + AccValue[j].Value = static_cast((int64)uValue64); //解析状态 uValue32 = 0; diff --git a/product/src/fes/protocol/fesdatazf/fesdatazf.cpp b/product/src/fes/protocol/fesdatazf/fesdatazf.cpp index 4294f02a..54caae4f 100644 --- a/product/src/fes/protocol/fesdatazf/fesdatazf.cpp +++ b/product/src/fes/protocol/fesdatazf/fesdatazf.cpp @@ -85,7 +85,7 @@ int CFesdatazf::SetBaseAddr(void *address) int CFesdatazf::SetProperty(int IsMainFes) { - g_fesdatazfIsMainFes = IsMainFes; + g_fesdatazfIsMainFes = (IsMainFes != 0); LOGDEBUG("CFesdatazf::SetProperty g_fesdatazfIsMainFes:%d",IsMainFes); return iotSuccess; } @@ -222,11 +222,15 @@ int CFesdatazf::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) */ int CFesdatazf::ChanTimer(int MainChanNo) { + boost::ignore_unused_variable_warning(MainChanNo); + return iotSuccess; } int CFesdatazf::ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + InformComThreadExit(); return iotSuccess; diff --git a/product/src/fes/protocol/fesdatazf/fesdatazfDataProcThread.cpp b/product/src/fes/protocol/fesdatazf/fesdatazfDataProcThread.cpp index 9c43aa18..19d2d938 100644 --- a/product/src/fes/protocol/fesdatazf/fesdatazfDataProcThread.cpp +++ b/product/src/fes/protocol/fesdatazf/fesdatazfDataProcThread.cpp @@ -423,9 +423,8 @@ void CFesdatazfDataProcThread::SendAiFrame() memcpy(&DWordData, &AiFloatValue, sizeof(AiFloatValue)); for (n = 0; n < CN_FLOAT_SIZE; n++) m_AppData.sendData[writex++] = (byte)(DWordData >> (n * 8));//值 - for (n = 0; n < CN_INT_SIZE; n++) - m_AppData.sendData[writex++] = (byte)(pAi->Status >> (n * 8));//状态 + m_AppData.sendData[writex++] = (byte)(pAi->Status >> (n * 8));//状态 pNum++; dataCount ++; @@ -544,7 +543,7 @@ void CFesdatazfDataProcThread::SendDiFrame() m_AppData.sendData[writex++] = (byte)(pDi->Value >> (n * 8));//值 for (n = 0; n < CN_INT_SIZE; n++) - m_AppData.sendData[writex++] = (byte)(pDi->Status >> (n * 8));//状态 + m_AppData.sendData[writex++] = (byte)(pDi->Status >> (n * 8));//状态 pNum++; dataCount ++; @@ -611,6 +610,9 @@ void CFesdatazfDataProcThread::SendAccFrame() CFesRtuPtr pRtu = NULL; int writex, rtuNo, rtuNum; int pNum, pNumWritex; + double AccDoubleValue; + uint64 QWordData; + dataCount = 0; writex = 5; @@ -652,17 +654,20 @@ void CFesdatazfDataProcThread::SendAccFrame() return; pAcc = pRtu->m_pAcc + k; if (pAcc->Used != 1) - continue; + continue; + AccDoubleValue = pAcc->Value; //转发数据组帧 for (n = 0; n < CN_INT_SIZE; n++) m_AppData.sendData[writex++] = (byte)(pAcc->PointNo >> (n * 8));//点号 - + + memcpy(&QWordData, &AccDoubleValue, sizeof(AccDoubleValue)); for (n = 0; n < CN_INT64_SIZE; n++) - m_AppData.sendData[writex++] = (byte)(pAcc->Value >> (n * 8));//值 + //m_AppData.sendData[writex++] = (byte)(pAcc->Value >> (n * 8));//值 + m_AppData.sendData[writex++] = (byte)(QWordData >> (n * 8));//值 for (n = 0; n < CN_INT_SIZE; n++) - m_AppData.sendData[writex++] = (byte)(pAcc->Status >> (n * 8));//状态 + m_AppData.sendData[writex++] = (byte)(pAcc->Status >> (n * 8));//状态 pNum++; dataCount++; @@ -779,7 +784,7 @@ void CFesdatazfDataProcThread::SendMiFrame() m_AppData.sendData[writex++] = (byte)(pMi->Value >> (n * 8));//值 for (n = 0; n < CN_INT_SIZE; n++) - m_AppData.sendData[writex++] = (byte)(pMi->Status >> (n * 8));//状态 + m_AppData.sendData[writex++] = (byte)(pMi->Status >> (n * 8));//状态 pNum++; dataCount++; @@ -874,10 +879,10 @@ void CFesdatazfDataProcThread::SendSOEFrame() m_AppData.sendData[writex++] = (byte)(pSoeEvent->PointNo >> (n * 8));//点号 for (n = 0; n < CN_INT_SIZE; n++) - m_AppData.sendData[writex++] = (byte)(pSoeEvent->Value >> (n * 8));//值 + m_AppData.sendData[writex++] = (byte)(pSoeEvent->Status >> (n * 8));//值 for (n = 0; n < CN_INT_SIZE; n++) - m_AppData.sendData[writex++] = (byte)(pSoeEvent->Status >> (n * 8));//状态 + m_AppData.sendData[writex++] = (byte)(pSoeEvent->Status >> (n * 8));//状态 for (n = 0; n < CN_INT64_SIZE; n++) m_AppData.sendData[writex++] = (byte)(pSoeEvent->time >> (n * 8));//时间戳 @@ -953,7 +958,7 @@ void CFesdatazfDataProcThread::SendChgDiFrame() m_AppData.sendData[writex++] = (byte)(pChgDi->PointNo >> (n * 8));//点号 for (n = 0; n < CN_INT_SIZE; n++) - m_AppData.sendData[writex++] = (byte)(pChgDi->Value >> (n * 8));//值 + m_AppData.sendData[writex++] = (byte)(pChgDi->Status >> (n * 8));//值 for (n = 0; n < CN_INT_SIZE; n++) m_AppData.sendData[writex++] = (byte)(pChgDi->Status >> (n * 8));//状态 diff --git a/product/src/fes/protocol/fespartdatarecv/fespartdatarecv.cpp b/product/src/fes/protocol/fespartdatarecv/fespartdatarecv.cpp new file mode 100644 index 00000000..876df8df --- /dev/null +++ b/product/src/fes/protocol/fespartdatarecv/fespartdatarecv.cpp @@ -0,0 +1,392 @@ +/* + @file fespartdatarecv.cpp + @brief fespartdatarecv规约处理主程序。 + @author thxiao + @histroy + + + +*/ +#include "fespartdatarecv.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" + +using namespace iot_public; + +CFespartdatarecv fespartdatarecv; +bool g_fespartdatarecvIsMainFes=false; +bool g_fespartdatarecvChanelRun=true; + +int EX_SetBaseAddr(void *address) +{ + fespartdatarecv.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + fespartdatarecv.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + fespartdatarecv.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + fespartdatarecv.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + fespartdatarecv.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + g_fespartdatarecvChanelRun=false;//使所有的线程退出。 + return fespartdatarecv.ExitSystem(flag); +} +CFespartdatarecv::CFespartdatarecv() +{ + m_ProtocolId = 0; + m_ptrCFesBase = NULL; + m_TcpServerListenThreadFlag = true; + m_CTcpServerListenThread = NULL; +} + +CFespartdatarecv::~CFespartdatarecv() +{ + if (m_DataProcThreadQueue.size() > 0) + m_DataProcThreadQueue.clear(); + + if (m_UdpClientThreadQueue.size()>0) + m_UdpClientThreadQueue.clear(); + + if (m_CTcpServerRxTxQueue.size()>0) + m_CTcpServerRxTxQueue.clear(); + + LOGDEBUG("CFespartdatarecv::~CFespartdatarecv() 退出"); +} + + +int CFespartdatarecv::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + } + return iotSuccess; +} + +int CFespartdatarecv::SetProperty(int IsMainFes) +{ + g_fespartdatarecvIsMainFes = (IsMainFes != 0); + LOGDEBUG("CFespartdatarecv::SetProperty g_fespartdatarecvIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief CFespartdatarecv::OpenChan + * 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CFespartdatarecv::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if(m_TcpServerListenThreadFlag) + { + m_CTcpServerListenThread = boost::make_shared(m_CTcpServerRxTxQueue,m_ptrCFesBase, ptrMainFesChan->m_Param.ProtocolId); + if (m_CTcpServerListenThread == NULL) + { + LOGERROR("CFespartdatarecv EX_OpenChan() ChanNo:%d create CTcpServerListenThread error!"); + return iotFailed; + } + GetFespartdatarecvProtocolInfo((char*) "fespartdatarecv"); + m_CTcpServerListenThread->resume(); //start TCP ServerListen THREAD + m_TcpServerListenThreadFlag = false; + } + + if((OpenFlag==CN_FesChanThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + switch(ptrFesChan->m_Param.CommType) + { + case CN_FesUdpClient: + if(ptrFesChan->m_ComThreadRun == CN_FesStopFlag) + { + //open chan thread + CUdpClientThreadPtr ptrUdpClient; + ptrUdpClient = boost::make_shared(ptrFesChan); + if (ptrUdpClient == NULL) + { + LOGERROR("CFespartdatarecv EX_OpenChan() ChanNo:%d create CTcpServerRxTxThread error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + m_UdpClientThreadQueue.push_back(ptrUdpClient); + ptrUdpClient->resume(); //start THREAD + } + break; + + case CN_FesTcpServer: + if(ptrFesChan->m_ComThreadRun == CN_FesStopFlag) + { + //open chan thread + CTcpServerRxTxThreadPtr ptrCTcpServerRxTx; + ptrCTcpServerRxTx = boost::make_shared(ptrFesChan,m_CTcpServerListenThread); + if (ptrCTcpServerRxTx == NULL) + { + LOGERROR("CFespartdatarecv EX_OpenChan() ChanNo:%d create CTcpServerRxTxThread error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + m_CTcpServerRxTxQueue.push_back(ptrCTcpServerRxTx); + ptrCTcpServerRxTx->resume(); //start TCP Server THREAD + } + break; + default: + return iotFailed; + } + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + CFespartdatarecvDataProcThreadPtr ptrDataProc; + ptrDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan); + if (ptrDataProc == NULL) + { + LOGERROR("CFespartdatarecv EX_OpenChan() ChanNo:%d create CfespartdatarecvDataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + m_DataProcThreadQueue.push_back(ptrDataProc); + ptrDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; +} + +/** + * @brief CFespartdatarecv::CloseChan + * 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CFespartdatarecv::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("CFespartdatarecv::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + if((CloseFlag==CN_FesChanThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrFesChan->m_ComThreadRun == CN_FesRunFlag) + { + //close chan thread + ClearUdpClientThreadByChanNo(ChanNo); + ClearTcpServerRxTxThreadByChanNo(ChanNo); + } + } + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + + return iotSuccess; +} + +/** + * @brief CFespartdatarecv::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int CFespartdatarecv::ChanTimer(int MainChanNo) +{ + boost::ignore_unused_variable_warning(MainChanNo); + + return iotSuccess; +} + +int CFespartdatarecv::ExitSystem(int flag) +{ + boost::ignore_unused_variable_warning(flag); + + InformComThreadExit(); + + return iotSuccess; +} + +void CFespartdatarecv::ClearUdpClientThreadByChanNo(int ChanNo) +{ + int tempNum; + CUdpClientThreadPtr ptrTcp; + + if ((tempNum = (int)m_UdpClientThreadQueue.size())<=0) + return; + vector::iterator it; + for (it = m_UdpClientThreadQueue.begin();it!= m_UdpClientThreadQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_UdpClientThreadQueue.erase(it);//会调用CTcpServerRxTxThread::~CTcpServerRxTxThreadPtr()退出线程 + LOGDEBUG("CFespartdatarecv::ClearUdpClientThreadByChanNo %d ok",ChanNo); + break; + } + } +} + +void CFespartdatarecv::ClearTcpServerRxTxThreadByChanNo(int ChanNo) +{ + int tempNum; + CTcpServerRxTxThreadPtr ptrTcp; + + if ((tempNum = (int)m_CTcpServerRxTxQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CTcpServerRxTxQueue.begin();it!=m_CTcpServerRxTxQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CTcpServerRxTxQueue.erase(it);//会调用CTcpServerRxTxThread::~CTcpServerRxTxThreadPtr()退出线程 + LOGDEBUG("CFespartdatarecv::ClearTcpServerRxTxThreadByChanNo %d ok",ChanNo); + break; + } + } +} + +void CFespartdatarecv::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + CFespartdatarecvDataProcThreadPtr ptrTcp; + + if ((tempNum = (int)m_DataProcThreadQueue.size())<=0) + return; + vector::iterator it; + for (it = m_DataProcThreadQueue.begin();it!= m_DataProcThreadQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_DataProcThreadQueue.erase(it);//会调用CfespartdatarecvDataProcThread::~CfespartdatarecvDataProcThread()退出线程 + LOGDEBUG("CFespartdatarecv::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + +/** + * @brief CFespartdatarecv::InformComThreadExit + * 设置线程退出标志,通知线程退出 + * @return + */ +void CFespartdatarecv::InformComThreadExit() +{ + CUdpClientThreadPtr ptrCom; + CTcpServerRxTxThreadPtr ptrTcp; + + if (m_UdpClientThreadQueue.size() > 0) + { + vector::iterator it; + for (it = m_UdpClientThreadQueue.begin(); it != m_UdpClientThreadQueue.end(); it++) + { + ptrCom = *it; + ptrCom->SetThreadRunFlag(0); + } + } + + if (m_CTcpServerListenThread != NULL) + { + m_CTcpServerListenThread->SetThreadRunFlag(0); + m_CTcpServerListenThread->quit();//线程会退出 + m_CTcpServerListenThread.reset();//相当于把智能指针付NULL,在此处的m_CTcpServerListenThread已经失效,失去了控制权。 + //同时m_CTcpServerListenThread被TcpServerRxTxThread引用了,所以还不会被销毁,所有权在TcpServerRxTxThread中 + //当TcpServerRxTxThread都退出后,系统把m_CTcpServerListenThread销毁(进入析构函数)。 + } + + if (m_CTcpServerRxTxQueue.size() > 0) + { + vector::iterator it2; + for (it2 = m_CTcpServerRxTxQueue.begin(); it2 != m_CTcpServerRxTxQueue.end(); it2++) + { + ptrTcp = *it2; + ptrTcp->SetThreadRunFlag(0); + } + } + + LOGDEBUG("CFespartdatarecv::InformComThreadExit() "); +} + + +/** +* @brief CFespartdatarecv::CFespartdatarecvProtocolInfo +* 筛选协议端口号以及协议ID +* @return +*/ +int CFespartdatarecv::GetFespartdatarecvProtocolInfo(char* ProtocolName) +{ + int i, j; + int OK = 1; + + for (i = 0; i < CN_FesMaxProtocolNum; i++) + { + if (strstr(m_ptrCFesBase->m_protoclName[i].Name, ProtocolName) != NULL) + { + for (j = 0; j < m_ptrCFesBase->m_vectCFesChanPtr.size(); j++) + { + if ((m_ptrCFesBase->m_vectCFesChanPtr[j]->m_Param.Used) && + (m_ptrCFesBase->m_vectCFesChanPtr[j]->m_Param.ProtocolId == m_ptrCFesBase->m_protoclName[i].ProtocolId)) + { + //m_CTcpServerListenThread->addListenPort(m_ptrCFesBase->m_vectCFesChanPtr[j]->m_Param.NetRoute[0].PortNo); + //2020-02-18 thxiao GetProtocolInfo()通道的本地端口号固定为自定义参数4 + if (m_ptrCFesBase->m_vectCFesChanPtr[j]->m_Param.LocalPortNo == 0) + { + m_ptrCFesBase->m_vectCFesChanPtr[j]->ResetLocalPortNo(1234); + } + m_CTcpServerListenThread->addListenPort(m_ptrCFesBase->m_vectCFesChanPtr[j]->m_Param.LocalPortNo); + LOGDEBUG("GetFespartdatarecvProtocolInfo::LocalPortNo(%d) ", m_ptrCFesBase->m_vectCFesChanPtr[j]->m_Param.LocalPortNo); + } + } + break; + } + } + return OK; +} + + + diff --git a/product/src/fes/protocol/fespartdatarecv/fespartdatarecv.h b/product/src/fes/protocol/fespartdatarecv/fespartdatarecv.h new file mode 100644 index 00000000..8cdacea9 --- /dev/null +++ b/product/src/fes/protocol/fespartdatarecv/fespartdatarecv.h @@ -0,0 +1,59 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "UdpClientThread.h" +#include "TcpServerRxTxThread.h" +#include "TcpServerListenThread.h" +#include "fespartdatarecvDataProcThread.h" + +/* +#ifndef Fespartdatarecv_API_EXPORT +#ifdef OS_WINDOWS +#define Fespartdatarecv_API G_DECL_EXPORT +#else + //LINUX下 默认情况下会使用C++ API函数命名规则(函数名会增加字符),使用extern "C"修饰后变为C的函数名,便于使用。 +#define Fespartdatarecv_API extern "C" +#endif +#else +#define Fespartdatarecv_API G_DECL_IMPORT +#endif +*/ + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API CFespartdatarecv : public CProtocolBase +{ +public: + CFespartdatarecv(); + ~CFespartdatarecv(); + + CTcpServerListenThreadPtr m_CTcpServerListenThread; + vector m_CTcpServerRxTxQueue; + vector m_UdpClientThreadQueue; + vector m_DataProcThreadQueue; + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + int ExitSystem(int flag); + void InformComThreadExit(); + int GetFespartdatarecvProtocolInfo(char* ProtocolName); +private: + bool m_TcpServerListenThreadFlag; + int m_ProtocolId; + void ClearUdpClientThreadByChanNo(int ChanNo); + void ClearTcpServerRxTxThreadByChanNo(int ChanNo); + void ClearDataProcThreadByChanNo(int ChanNo); +}; + diff --git a/product/src/fes/protocol/fespartdatarecv/fespartdatarecv.pro b/product/src/fes/protocol/fespartdatarecv/fespartdatarecv.pro new file mode 100644 index 00000000..99780f38 --- /dev/null +++ b/product/src/fes/protocol/fespartdatarecv/fespartdatarecv.pro @@ -0,0 +1,37 @@ +QT -= core gui +CONFIG -= qt + +TARGET = fespartdatarecv +TEMPLATE = lib + +SOURCES += \ + fespartdatarecv.cpp \ + fespartdatarecvDataProcThread.cpp \ + ../combase/UdpClientThread.cpp \ + ../combase/TcpServerListenThread.cpp \ + ../combase/TcpServerRxTxThread.cpp + +HEADERS += \ + fespartdatarecv.h \ + fespartdatarecvDataProcThread.h \ + ../../include/UdpClientThread.h \ + ../../include/TcpServerListenThread.h \ + ../../include/TcpServerRxTxThread.h + +INCLUDEPATH += ../../include/ + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase +LIBS += -lprotobuf -lboost_regex + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/fes/protocol/fespartdatarecv/fespartdatarecvDataProcThread.cpp b/product/src/fes/protocol/fespartdatarecv/fespartdatarecvDataProcThread.cpp new file mode 100644 index 00000000..706ad014 --- /dev/null +++ b/product/src/fes/protocol/fespartdatarecv/fespartdatarecvDataProcThread.cpp @@ -0,0 +1,589 @@ +/* + @file CFespartdatarecvDataProcThread.cpp + @brief 与珠海优特的五防用UDP通讯,采用协议为UDP CDT转发规约。 + 遥测数据都为A帧,最大32个信息字。 + @author thxiao + @history + 2020-02-24 thxiao 创建时设置ThreadRun标识。 + +*/ +#include +#include "fespartdatarecvDataProcThread.h" +#include "TcpClientThread.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" + +using namespace iot_public; + +extern bool g_fespartdatarecvIsMainFes; +extern bool g_fespartdatarecvChanelRun; + +const int g_fespartdatarecvThreadTime = 20; + +CFespartdatarecvDataProcThread::CFespartdatarecvDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan): + CTimerThreadBase("fespartdatarecvDataProcThread", g_fespartdatarecvThreadTime,0,true) +{ + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + + memset(&m_AppData, 0, sizeof(SFespartdatarecvAppData)); + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL)) + { + return ; + } + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); +} + +CFespartdatarecvDataProcThread::~CFespartdatarecvDataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + LOGDEBUG("CFespartdatarecvDataProcThread::~CFespartdatarecvDataProcThread() ChanNo=%d 退出",m_ptrCFesChan->m_Param.ChanNo); +} + +/** + * @brief CFespartdatarecvDataProcThread::beforeExecute + * + */ +int CFespartdatarecvDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief CFespartdatarecvDataProcThread::execute + + */ +void CFespartdatarecvDataProcThread::execute() +{ + //读取网络事件 + SFesNetEvent netEvent; + + if(!g_fespartdatarecvChanelRun) //收到线程退出标志不再往下执行 + return; + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + + if(m_ptrCurrentChan== NULL) + return; + + if(m_ptrCurrentChan->ReadNetEvent(1,&netEvent)>0) + { + switch(netEvent.EventType) + { + case CN_FesNetEvent_Connect: + LOGDEBUG("ChanNo=%d connect", m_ptrCurrentChan->m_Param.ChanNo); + m_AppData.state = CN_FespartdatarecvAppState_idle; + m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuNormal); + break; + case CN_FesNetEvent_Disconnect: + LOGDEBUG("ChanNo=%d disconnect",m_ptrCurrentChan->m_Param.ChanNo); + m_AppData.state = CN_FespartdatarecvAppState_idle; + m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuComDown); + break; + default: + break; + } + } + + //接收数据 + if (RecvNetData()>0) + { + RecvDataProcess(); + } +} + +/* + @brief 执行quit函数前的处理 + */ +void CFespartdatarecvDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + + LOGDEBUG("CFespartdatarecvDataProcThread::beforeQuit() "); +} + +/** + * @brief CFespartdatarecvDataProcThread::RecvNetData + * fespartdatarecv 接收数据处理,返回数据去掉同步头 + * @return 接收长度。 + */ +int CFespartdatarecvDataProcThread::RecvNetData() +{ + int recvLen, ExpectLen; + recvLen = m_ptrCurrentChan->GetRxBufSize(); + if (recvLen <= 0) + return 0; + ExpectLen = 0; + while (recvLen>4) + { + m_ptrCurrentChan->ReadRxBufData(4, &m_AppData.recvBuf[0]); + if (m_AppData.recvBuf[0] != 0xAB) + { + //错误帧,放弃本字节 + m_ptrCurrentChan->DeleteReadRxBufData(1);//清除已读取的数据 + m_ptrCurrentChan->SetErrNum(1); + recvLen -= 1; + continue; + } + //计算出该帧报文的长度 + ExpectLen = m_AppData.recvBuf[3] * 256 + m_AppData.recvBuf[2] + 6; + if (recvLen >= ExpectLen) //接收完整的数据 + { + m_ptrCurrentChan->ReadRxBufData(ExpectLen, &m_AppData.recvBuf[0]); + + //接收正确 + if( (m_AppData.recvBuf[ExpectLen - 2] == 0xCD) && (m_AppData.recvBuf[ExpectLen - 1] == 0xEF) ) + { + m_ptrCurrentChan->DeleteReadRxBufData(ExpectLen);//清除已读取的数据 + m_AppData.recvBufSize = ExpectLen; + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, m_AppData.recvBuf, m_AppData.recvBufSize, CN_SFesSimComFrameTypeRecv); + m_ptrCurrentChan->SetRxNum(1); + return m_AppData.recvBufSize; + } + else + { + //错误帧,放弃本字节 + m_ptrCurrentChan->DeleteReadRxBufData(1);//清除已读取的数据 + m_ptrCurrentChan->SetErrNum(1); + recvLen -= 1; + continue; + } + } + else + return 0; + } + return 0; +} + +/** + * @brief CFespartdatarecvDataProcThread::SendDataToPort + * 数据发送到发送缓冲区。 + * 如是主通道,直接使用m_ptrCFesChan通道结构;如果是备用通道,需要获取当前使用通道,在发送数据。 + * @param Data 数据区 + * @param Size 数据区长度 + */ +void CFespartdatarecvDataProcThread::SendDataToPort(byte *Data, int Size) +{ + if (m_ptrCurrentChan == NULL) + return; + + m_ptrCurrentChan->WriteTxBufData(Size, Data); + + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, Data, Size, CN_SFesSimComFrameTypeSend); + m_ptrCurrentChan->SetTxNum(1); +} + +int CFespartdatarecvDataProcThread::RecvProcess() +{ + return 1; +} + +int CFespartdatarecvDataProcThread::RecvDataProcess() +{ + byte FrameType; + FrameType = m_AppData.recvBuf[1]; + + if (m_AppData.recvBufSize<7) + return iotFailed; + switch (FrameType) + { + case 0xC1://遥测 + ProcessAiFrame(); + break; + + case 0xC2://遥信 + ProcessDiFrame(); + break; + + case 0xC3://遥脉 + ProcessAccFrame(); + break; + + case 0xC4://混合量 + ProcessMiFrame(); + break; + + case 0xC5://SOE + ProcessSoeFrame(); + break; + + case 0xC6://遥信变位 + ProcessChgDiFrame(); + break; + + default: + break; + } + return 1; +} + +//解析遥测数据 +void CFespartdatarecvDataProcThread::ProcessAiFrame() +{ + SFesRtuAiValue AiValue[256]; + SFesChgAi ChgAi[256]; + //CFesRtuPtr pRtu = NULL; + int ChgCount; + int j, n; + float aiValue; + int readx,recvNum, pointNum; + uint32 uValue32; + uint64 mSec; + byte pNum; + + ChgCount = 0; + mSec = getUTCTimeMsec(); + readx = 5; + pNum = 0; + recvNum = m_AppData.recvBuf[4]; + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + pointNum = (int)uValue32; + + //当前帧点数量 + pNum = m_AppData.recvBuf[readx++]; + + + for (j = 0; j < pNum; j++) + { + //解析点号 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + AiValue[j].PointNo = (int)uValue32; + + //解析值 + uValue32 = 0; + for (n = 0; n < CN_FLOAT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + memcpy(&aiValue, &uValue32, sizeof(float)); + if (aiValue != aiValue) + aiValue = 0; + AiValue[j].Value = aiValue; + + //解析状态 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + AiValue[j].Status = uValue32; + AiValue[j].time = mSec; + } + + ChgCount = 0; + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(pNum, &AiValue[0], &ChgCount, &ChgAi[0]); + if ((ChgCount>0) && (g_fespartdatarecvIsMainFes == true))//主机才报告变化数据 + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); +} + +//解析遥信数据 +void CFespartdatarecvDataProcThread::ProcessDiFrame() +{ + SFesRtuDiValue DiValue[256]; + //CFesRtuPtr pRtu = NULL; + int j, n; + int readx, recvNum, pointNum; + uint32 uValue32; + uint64 mSec; + byte pNum; + + mSec = getUTCTimeMsec(); + readx = 5; + pNum = 0; + recvNum = m_AppData.recvBuf[4]; + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + pointNum = (int)uValue32; + + //当前帧点数量 + pNum = m_AppData.recvBuf[readx++]; + + + for (j = 0; j < pNum; j++) + { + //解析点号 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + DiValue[j].PointNo = (int)uValue32; + + //解析值 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + DiValue[j].Value = (int)uValue32; + + //解析状态 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + DiValue[j].Status = uValue32; + DiValue[j].time = mSec; + } + m_ptrCFesRtu->WriteRtuDiValue(pNum, &DiValue[0]); +} + +//解析遥脉数据 +void CFespartdatarecvDataProcThread::ProcessAccFrame() +{ + SFesRtuAccValue AccValue[256]; + SFesChgAcc ChgAcc[256]; + //CFesRtuPtr pRtu = NULL; + int ChgCount; + int j, n; + int readx, recvNum, pointNum; + uint32 uValue32; + uint64 mSec,uValue64; + double accValue; + byte pNum; + + ChgCount = 0; + mSec = getUTCTimeMsec(); + readx = 5; + pNum = 0; + recvNum = m_AppData.recvBuf[4]; + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + pointNum = (int)uValue32; + + //当前帧点数量 + pNum = m_AppData.recvBuf[readx++]; + + + for (j = 0; j < pNum; j++) + { + //解析点号 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + AccValue[j].PointNo = (int)uValue32; + + //解析值 + uValue64 = 0; + for (n = 0; n < CN_INT64_SIZE; n++) + uValue64 |= (uint64)m_AppData.recvBuf[readx++] << (n * 8); + //AccValue[j].Value = (int64)uValue64; + + memcpy(&accValue, &uValue64, sizeof(double)); + if (accValue != accValue) + accValue = 0; + AccValue[j].Value = accValue; + + //解析状态 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + AccValue[j].Status = uValue32; + AccValue[j].time = mSec; + } + + ChgCount = 0; + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(pNum, &AccValue[0], &ChgCount, &ChgAcc[0]); + if ((ChgCount>0) && (g_fespartdatarecvIsMainFes == true))//主机才报告变化数据 + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); +} + +//解析混合数据 +void CFespartdatarecvDataProcThread::ProcessMiFrame() +{ + SFesRtuMiValue MiValue[256]; + SFesChgMi ChgMi[256]; + //CFesRtuPtr pRtu = NULL; + int ChgCount; + int j, n; + int readx, recvNum, pointNum; + uint32 uValue32; + uint64 mSec; + byte pNum; + + ChgCount = 0; + mSec = getUTCTimeMsec(); + readx = 5; + pNum = 0; + recvNum = m_AppData.recvBuf[4]; + //解析RTU号 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + pointNum = (int)uValue32; + + //当前帧点数量 + pNum = m_AppData.recvBuf[readx++]; + +// pRtu = m_ptrCFesBase->GetRtuDataByRtuNo(rtuNo); + + for (j = 0; j < pNum; j++) + { + //解析点号 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + MiValue[j].PointNo = (int)uValue32; + + //解析值 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + MiValue[j].Value = (int)uValue32; + + //解析状态 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + MiValue[j].Status = uValue32; + MiValue[j].time = mSec; + } + + ChgCount = 0; + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(pNum, &MiValue[0], &ChgCount, &ChgMi[0]); + if ((ChgCount>0) && (g_fespartdatarecvIsMainFes == true))//主机才报告变化数据 + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); +} + +//解析SOE数据 +void CFespartdatarecvDataProcThread::ProcessSoeFrame() +{ + SFesSoeEvent SoeEvent; + //CFesRtuPtr pRtu = NULL; + int i, n,pNum; + int readx; + uint32 uValue32; + uint64 mSec=0; + SFesDi *pDi = NULL; + + readx = 5; + pNum = m_AppData.recvBuf[4]; + LOGDEBUG("ChanNo=%d recv SOE pNum=%d", m_ptrCurrentChan->m_Param.ChanNo,pNum); + for (i = 0; i < pNum; i++) + { + //解析RTU号 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); +// rtuNo = (int)uValue32; + +// //没找到对应RTU,则跳过该RTU +// pRtu = m_ptrCFesBase->GetRtuDataByRtuNo(rtuNo); +// if (pRtu == NULL) +// continue; + + memset(&SoeEvent, 0, sizeof(SFesSoeEvent)); + //RTU号 + SoeEvent.RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + + //解析点号 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + SoeEvent.PointNo = (int)uValue32; + + //解析值 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + SoeEvent.Value = (int)uValue32; + + //解析状态 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + SoeEvent.Status = uValue32; + + mSec = 0; + for (n = 0; n < CN_INT64_SIZE; n++) + mSec |= (uint64)m_AppData.recvBuf[readx++] << (n * 8); + SoeEvent.time = mSec; + + if((pDi=GetFesDiByPointNo(m_ptrCFesRtu,SoeEvent.PointNo))!=NULL) + { + memcpy(SoeEvent.TableName,pDi->TableName,CN_FesMaxTableNameSize); + memcpy(SoeEvent.ColumnName,pDi->ColumnName,CN_FesMaxColumnNameSize); + memcpy(SoeEvent.TagName,pDi->TagName,CN_FesMaxTagSize); + + if (g_fespartdatarecvIsMainFes == true)//主机才报告变化数据,更新过的点才能报告变化 + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, 1, &SoeEvent); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(1, &SoeEvent); + } + } + } +} + +//解析遥信变位数据 +void CFespartdatarecvDataProcThread::ProcessChgDiFrame() +{ + SFesChgDi ChgDi; + //CFesRtuPtr pRtu = NULL; + int i, n,pNum; + int readx; + uint32 uValue32; + uint64 mSec=0; + SFesDi *pDi = NULL; + + readx = 5; + pNum = m_AppData.recvBuf[4]; + LOGDEBUG("ChanNo=%d recv ChgDi pNum=%d", m_ptrCurrentChan->m_Param.ChanNo,pNum); + for (i = 0; i < pNum; i++) + { + //解析RTU号 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); +// rtuNo = (int)uValue32; + +// //没找到对应RTU,则跳过该RTU +// pRtu = m_ptrCFesBase->GetRtuDataByRtuNo(rtuNo); +// if (pRtu == NULL) +// continue; + + memset(&ChgDi, 0, sizeof(SFesChgDi)); + //RTU号 + ChgDi.RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + + //解析点号 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + ChgDi.PointNo = (int)uValue32; + + //解析值 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + ChgDi.Value = (int)uValue32; + + //解析状态 + uValue32 = 0; + for (n = 0; n < CN_INT_SIZE; n++) + uValue32 |= (uint32)m_AppData.recvBuf[readx++] << (n * 8); + ChgDi.Status = uValue32; + + mSec = 0; + for (n = 0; n < CN_INT64_SIZE; n++) + mSec |= (uint64)m_AppData.recvBuf[readx++] << (n * 8); + ChgDi.time = mSec; + + if((pDi=GetFesDiByPointNo(m_ptrCFesRtu,ChgDi.PointNo))!=NULL) + { + memcpy(ChgDi.TableName,pDi->TableName,CN_FesMaxTableNameSize); + memcpy(ChgDi.ColumnName,pDi->ColumnName,CN_FesMaxColumnNameSize); + memcpy(ChgDi.TagName,pDi->TagName,CN_FesMaxTagSize); + + if (g_fespartdatarecvIsMainFes == true)//主机才报告变化数据,更新过的点才能报告变化 + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, 1, &ChgDi); + } + } + } +} + diff --git a/product/src/fes/protocol/fespartdatarecv/fespartdatarecvDataProcThread.h b/product/src/fes/protocol/fespartdatarecv/fespartdatarecvDataProcThread.h new file mode 100644 index 00000000..b861c2ad --- /dev/null +++ b/product/src/fes/protocol/fespartdatarecv/fespartdatarecvDataProcThread.h @@ -0,0 +1,85 @@ +/* + @file CFespartdatarecvDataProcThread.h + @brief Fespartdatarecv 数据处理线程类 + @author thxiao +*/ +#pragma once + +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "TcpServerThread.h" +using namespace iot_public; + +#define CN_FespartdatarecvMaxRecvDataSize 5000 +#define CN_Fespartdatarecv_MAX_Point_NUM 100 +#define CN_Fespartdatarecv_MAX_CMD_LEN 256 +#define CN_Fespartdatarecv_MAX_SOE_LEN 80 + +#define CN_Fespartdatarecv_AI_STR_LEN 12 //遥测数据结构长度 +#define CN_Fespartdatarecv_DI_STR_LEN 12 //遥信数据结构长度 +#define CN_Fespartdatarecv_ACC_STR_LEN 16 //遥脉数据结构长度 +#define CN_Fespartdatarecv_MI_STR_LEN 12 //混合量数据结构长度 +#define CN_Fespartdatarecv_SOE_STR_LEN 20 //SOE数据结构长度 + +#define CN_INT_SIZE 4 +#define CN_FLOAT_SIZE 4 +#define CN_INT64_SIZE 8 + +const int CN_FespartdatarecvAppState_idle = 0; +const int CN_FespartdatarecvAppState_waitResp = 1; +const int CN_FespartdatarecvAppState_waitControlResp = 2; + +//本FES数据跟新间隔 +const int CN_FespartdatarecvStartUpateTime = 10000;//10s +const int CN_FespartdatarecvNormalUpateTime = 60000;//60s + +//Fespartdatarecv 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct{ + int state; //网络状态 + + int recvBufSize; + byte recvBuf[CN_FespartdatarecvMaxRecvDataSize]; +}SFespartdatarecvAppData; + + +class CFespartdatarecvDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + CFespartdatarecvDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan); + virtual ~CFespartdatarecvDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + CFesBase* m_ptrCFesBase; + + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,Fespartdatarecv tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SFespartdatarecvAppData m_AppData; //内部应用数据结构 + +private: + int RecvProcess(); + int RecvDataProcess(); + int RecvNetData(); + void SendDataToPort(byte *Data, int Size); + + void ProcessAiFrame(); + void ProcessDiFrame(); + void ProcessAccFrame(); + void ProcessMiFrame(); + void ProcessSoeFrame(); + void ProcessChgDiFrame(); +}; + +typedef boost::shared_ptr CFespartdatarecvDataProcThreadPtr; + diff --git a/product/src/fes/protocol/fespartdatazf/fespartdatazf.cpp b/product/src/fes/protocol/fespartdatazf/fespartdatazf.cpp new file mode 100644 index 00000000..bcd32b78 --- /dev/null +++ b/product/src/fes/protocol/fespartdatazf/fespartdatazf.cpp @@ -0,0 +1,462 @@ +/* + @file fespartdatazf.cpp + @brief fespartdatazf规约处理主程序。 + @author thxiao + @histroy + + + +*/ +#include "fespartdatazf.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" + +using namespace iot_public; + +CFespartdatazf fespartdatazf; +bool g_fespartdatazfIsMainFes=false; +bool g_fespartdatazfChanelRun=true; + +int EX_SetBaseAddr(void *address) +{ + fespartdatazf.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + fespartdatazf.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + fespartdatazf.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + fespartdatazf.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + fespartdatazf.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + g_fespartdatazfChanelRun=false;//使所有的线程退出。 + return fespartdatazf.ExitSystem(flag); +} +CFespartdatazf::CFespartdatazf() +{ + m_ProtocolId = 0; + m_ptrCFesBase = NULL; +} + +CFespartdatazf::~CFespartdatazf() +{ + if (m_UdpClientThreadQueue.size()>0 ) + m_UdpClientThreadQueue.clear(); + + if (m_CTcpClientQueue.size()>0) + m_CTcpClientQueue.clear(); + + if (m_DataProcThreadQueue.size() > 0) + m_DataProcThreadQueue.clear(); + LOGDEBUG("CFespartdatazf::~CFespartdatazf() 退出"); +} + + +int CFespartdatazf::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + ReadConfigParam(); + } + return iotSuccess; +} + +int CFespartdatazf::SetProperty(int IsMainFes) +{ + g_fespartdatazfIsMainFes = (IsMainFes != 0); + LOGDEBUG("CFespartdatazf::SetProperty g_fespartdatazfIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief CFespartdatazf::OpenChan + * 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CFespartdatazf::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if((OpenFlag==CN_FesChanThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + switch(ptrFesChan->m_Param.CommType) + { + case CN_FesUdpClient: + if(ptrFesChan->m_ComThreadRun == CN_FesStopFlag) + { + //open chan thread + CUdpClientThreadPtr ptrUdpClient; + ptrUdpClient = boost::make_shared(ptrFesChan); + if (ptrUdpClient == NULL) + { + LOGERROR("CFespartdatazf EX_OpenChan() ChanNo:%d create CTcpServerRxTxThread error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + m_UdpClientThreadQueue.push_back(ptrUdpClient); + ptrUdpClient->resume(); //start THREAD + } + break; + + case CN_FesTcpClient: + if (ptrFesChan->m_ComThreadRun == CN_FesStopFlag) + { + //open chan thread + CTcpClientThreadPtr ptrCTcpClient; + ptrCTcpClient = boost::make_shared(ptrFesChan); + if (ptrCTcpClient == NULL) + { + LOGERROR("CFespartdatazf EX_OpenChan() ChanNo:%d create CTcpClientThread error!", ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + m_CTcpClientQueue.push_back(ptrCTcpClient); + ptrCTcpClient->resume(); //start TCP CLIENT THREAD + } + break; + default: + return iotFailed; + } + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + CFespartdatazfDataProcThreadPtr ptrDataProc; + ptrDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_vecAppParam); + if (ptrDataProc == NULL) + { + LOGERROR("CFespartdatazf EX_OpenChan() ChanNo:%d create CfespartdatazfDataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + m_DataProcThreadQueue.push_back(ptrDataProc); + ptrDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; +} + +/** + * @brief CFespartdatazf::CloseChan + * 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CFespartdatazf::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("CFespartdatazf::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + if((CloseFlag==CN_FesChanThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrFesChan->m_ComThreadRun == CN_FesRunFlag) + { + //close chan thread + ClearUdpClientThreadByChanNo(ChanNo); + ClearTcpClientThreadByChanNo(ChanNo); + } + } + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + + return iotSuccess; +} + +/** + * @brief CFespartdatazf::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int CFespartdatazf::ChanTimer(int MainChanNo) +{ + boost::ignore_unused_variable_warning(MainChanNo); + + return iotSuccess; +} + +int CFespartdatazf::ExitSystem(int flag) +{ + boost::ignore_unused_variable_warning(flag); + + InformComThreadExit(); + + return iotSuccess; +} + +void CFespartdatazf::ClearUdpClientThreadByChanNo(int ChanNo) +{ + int tempNum; + CUdpClientThreadPtr ptrTcp; + + if ((tempNum = (int)m_UdpClientThreadQueue.size())<=0) + return; + vector::iterator it; + for (it = m_UdpClientThreadQueue.begin();it!= m_UdpClientThreadQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_UdpClientThreadQueue.erase(it);//会调用CTcpServerRxTxThread::~CTcpServerRxTxThreadPtr()退出线程 + LOGDEBUG("CFespartdatazf::ClearUdpClientThreadByChanNo %d ok",ChanNo); + break; + } + } +} + +void CFespartdatazf::ClearTcpClientThreadByChanNo(int ChanNo) +{ + int tempNum; + CTcpClientThreadPtr ptrTcp; + + if ((tempNum = (int)m_CTcpClientQueue.size()) <= 0) + return; + vector::iterator it; + for (it = m_CTcpClientQueue.begin(); it != m_CTcpClientQueue.end(); it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CTcpClientQueue.erase(it);//会调用CTcpClientThread::~CTcpClientThreadPtr()退出线程 + LOGDEBUG("CKBD104::ClearTcpClientThreadByChanNo %d ok", ChanNo); + break; + } + } +} + +void CFespartdatazf::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + CFespartdatazfDataProcThreadPtr ptrTcp; + + if ((tempNum = (int)m_DataProcThreadQueue.size())<=0) + return; + vector::iterator it; + for (it = m_DataProcThreadQueue.begin();it!= m_DataProcThreadQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_DataProcThreadQueue.erase(it);//会调用CfespartdatazfDataProcThread::~CfespartdatazfDataProcThread()退出线程 + LOGDEBUG("CFespartdatazf::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + + +/** + * @brief CFespartdatazf::ReadConfigParam + * 读取fespartdatazf配置文件 + * @return 成功返回iotSuccess,失败返回iotFailed + */ +int CFespartdatazf::ReadConfigParam() +{ + CCommonConfigParse config; + int ivalue; + char strRtuNo[48]; + SFespartdatazfAppConfigParam param; + int items,i,j; + CFesChanPtr ptrChan; //CHAN数据区 + CFesRtuPtr ptrRTU; + std::string svalue; + + memset(¶m,0,sizeof(SFespartdatazfAppConfigParam)); + + if (m_ptrCFesBase == NULL) + return iotFailed; + + m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"fespartdatazf"); + if (m_ProtocolId == -1) + { + LOGDEBUG("ReadConfigParam ProtoclID error"); + return iotFailed; + } + if(config.load("../../data/fes/","fespartdatazf.xml")==iotFailed) + return iotSuccess; + + for (i = 0; i < m_ptrCFesBase->m_vectCFesChanPtr.size(); i++) + { + ptrChan = m_ptrCFesBase->m_vectCFesChanPtr[i]; + if ((ptrChan->m_Param.Used == 1) && (m_ProtocolId == ptrChan->m_Param.ProtocolId)) + { + //found RTU + for (j = 0; j < m_ptrCFesBase->m_vectCFesRtuPtr.size(); j++) + { + ptrRTU = m_ptrCFesBase->m_vectCFesRtuPtr[j]; + if (ptrRTU->m_Param.Used && (ptrRTU->m_Param.ChanNo == ptrChan->m_Param.ChanNo)) + { + memset(&strRtuNo[0], 0, sizeof(strRtuNo)); + sprintf(strRtuNo, "RTU%d", ptrRTU->m_Param.RtuNo); + memset(¶m, 0, sizeof(param)); + param.RtuNo = ptrRTU->m_Param.RtuNo; + items = 0; + if (config.getIntValue(strRtuNo, "start_delay", ivalue) == iotSuccess) + { + param.startDelay = ivalue * 1000; + items++; + } + else + param.startDelay = 30 * 1000; + + if (config.getIntValue(strRtuNo, "DiFrame_Interval", ivalue) == iotSuccess) + { + param.DiFrameIntervalReset = ivalue*1000; + items++; + } + else + param.DiFrameIntervalReset = 1*1000; + + if (config.getIntValue(strRtuNo, "AiFrame_Interval", ivalue) == iotSuccess) + { + param.AiFrameIntervalReset = ivalue * 1000; + items++; + } + else + param.AiFrameIntervalReset = 5 * 1000; + + if (config.getIntValue(strRtuNo, "AccFrame_Interval", ivalue) == iotSuccess) + { + param.AccFrameIntervalReset = ivalue * 1000; + items++; + } + else + param.AccFrameIntervalReset = 300 * 1000; + + if (config.getIntValue(strRtuNo, "MiFrame_Interval", ivalue) == iotSuccess) + { + param.MiFrameIntervalReset = ivalue * 1000; + items++; + } + else + param.MiFrameIntervalReset = 120 * 1000; + + if (config.getIntValue(strRtuNo, "max_update_count", ivalue) == iotSuccess) + { + param.maxUpdateCount = ivalue; + items++; + } + else + param.maxUpdateCount = 18; + + if (config.getIntValue(strRtuNo, "send_Interval", ivalue) == iotSuccess) + { + param.sendIntervalReset = ivalue; + items++; + } + else + param.sendIntervalReset = 100; + + //起始通道号 + if (config.getIntValue(strRtuNo, "StartChNo", ivalue) == iotSuccess) + { + param.StartChNo = ivalue; + items++; + } + else + param.StartChNo = 0; + + //结束通道号 + if (config.getIntValue(strRtuNo, "EndChNo", ivalue) == iotSuccess) + { + param.EndChNo = ivalue; + items++; + } + else + param.EndChNo = m_ptrCFesBase->m_ChanNum; + + if (items > 0)//对应的RTU有配置项 + { + m_vecAppParam.push_back(param); + } + } + } + } + } + LOGDEBUG("CFespartdatazf::ReadConfigParam end"); + return iotSuccess; + +} + +/** + * @brief CFespartdatazf::InformComThreadExit + * 设置线程退出标志,通知线程退出 + * @return + */ +void CFespartdatazf::InformComThreadExit() +{ + CUdpClientThreadPtr ptrCom; + CTcpClientThreadPtr ptrTcp; + + if (m_UdpClientThreadQueue.size() > 0) + { + vector::iterator it; + for (it = m_UdpClientThreadQueue.begin();it!= m_UdpClientThreadQueue.end();it++) + { + ptrCom = *it; + ptrCom->SetThreadRunFlag(0); + } + } + + if (m_CTcpClientQueue.size() > 0) + { + vector::iterator it; + for (it = m_CTcpClientQueue.begin();it!=m_CTcpClientQueue.end();it++) + { + ptrTcp = *it; + ptrTcp->SetThreadRunFlag(0); + } + } +} + diff --git a/product/src/fes/protocol/fespartdatazf/fespartdatazf.h b/product/src/fes/protocol/fespartdatazf/fespartdatazf.h new file mode 100644 index 00000000..12fd8a24 --- /dev/null +++ b/product/src/fes/protocol/fespartdatazf/fespartdatazf.h @@ -0,0 +1,59 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "UdpClientThread.h" +#include "TcpClientThread.h" +#include "fespartdatazfDataProcThread.h" + +/* +#ifndef Fespartdatazf_API_EXPORT +#ifdef OS_WINDOWS +#define Fespartdatazf_API G_DECL_EXPORT +#else + //LINUX下 默认情况下会使用C++ API函数命名规则(函数名会增加字符),使用extern "C"修饰后变为C的函数名,便于使用。 +#define Fespartdatazf_API extern "C" +#endif +#else +#define Fespartdatazf_API G_DECL_IMPORT +#endif +*/ + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API CFespartdatazf : public CProtocolBase +{ +public: + CFespartdatazf(); + ~CFespartdatazf(); + + vector m_UdpClientThreadQueue; + vector m_CTcpClientQueue; + vector m_DataProcThreadQueue; + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + + vector m_vecAppParam; + + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + int ExitSystem(int flag); + int ReadConfigParam(); + void InformComThreadExit(); +private: + int m_ProtocolId; + void ClearUdpClientThreadByChanNo(int ChanNo); + void ClearTcpClientThreadByChanNo(int ChanNo); + void ClearDataProcThreadByChanNo(int ChanNo); +}; + diff --git a/product/src/fes/protocol/fespartdatazf/fespartdatazf.pro b/product/src/fes/protocol/fespartdatazf/fespartdatazf.pro new file mode 100644 index 00000000..5089f791 --- /dev/null +++ b/product/src/fes/protocol/fespartdatazf/fespartdatazf.pro @@ -0,0 +1,34 @@ +QT -= core gui +CONFIG -= qt + +TARGET = fespartdatazf +TEMPLATE = lib + +SOURCES += \ + fespartdatazf.cpp \ + fespartdatazfDataProcThread.cpp \ + ../combase/UdpClientThread.cpp \ + ../combase/TcpClientThread.cpp + +HEADERS += \ + fespartdatazf.h \ + fespartdatazfDataProcThread.h \ + ../../include/UdpClientThread.h \ + ../../include/TcpClientThread.h + +INCLUDEPATH += ../../include/ + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase +LIBS += -lprotobuf -lboost_regex + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/fes/protocol/fespartdatazf/fespartdatazfDataProcThread.cpp b/product/src/fes/protocol/fespartdatazf/fespartdatazfDataProcThread.cpp new file mode 100644 index 00000000..6abbeccf --- /dev/null +++ b/product/src/fes/protocol/fespartdatazf/fespartdatazfDataProcThread.cpp @@ -0,0 +1,904 @@ +/* + @file CFespartdatazfDataProcThread.cpp + @brief 与珠海优特的五防用UDP通讯,采用协议为UDP CDT转发规约。 + 遥测数据都为A帧,最大32个信息字。 + @author thxiao + @history + 2020-02-24 thxiao 创建时设置ThreadRun标识。 + +*/ +#include +#include "fespartdatazfDataProcThread.h" +#include "TcpClientThread.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" + +using namespace iot_public; + +extern bool g_fespartdatazfIsMainFes; +extern bool g_fespartdatazfChanelRun; + +const int g_fespartdatazfThreadTime = 10; + +CFespartdatazfDataProcThread::CFespartdatazfDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam): + CTimerThreadBase("fespartdatazfDataProcThread", g_fespartdatazfThreadTime,0,true) +{ + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + m_timerCountReset = 1000 / g_fespartdatazfThreadTime; //1S COUNTER + m_timerCount = 0; + m_pFwSoeData = NULL; + m_pChgDiData = NULL; + + m_ptrCFesRtu->SetFwAiChgStop(1); + m_ptrCFesRtu->SetFwAccChgStop(1); + m_ptrCFesRtu->SetFwMiChgStop(1); + //m_ptrCFesRtu->SetFwDiChgStop(1); + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL)) + { + return ; + } + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + + m_pFwSoeData = (SFesFwSoeEvent*)malloc(CN_Fespartdatazf_MAX_SOE_NUM * sizeof(SFesFwSoeEvent)); + m_pChgDiData = (SFesFwChgDi*)malloc(CN_Fespartdatazf_MAX_SOE_NUM * sizeof(SFesFwChgDi)); + + AppDataInit(vecAppParam); + //m_ptrCFesBase->SetFwDiData(m_ptrCFesRtu, -1, -1);//all chan + m_ptrCFesBase->SetFwDiData(m_ptrCFesRtu, m_AppData.StartChNo, m_AppData.EndChNo);//all chan + ThreadRunFlag = true; +} + +CFespartdatazfDataProcThread::~CFespartdatazfDataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + if (m_pFwSoeData != NULL) + free(m_pFwSoeData); + + if (m_pChgDiData != NULL) + free(m_pChgDiData); + + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + LOGDEBUG("CFespartdatazfDataProcThread::~CFespartdatazfDataProcThread() ChanNo=%d 退出",m_ptrCFesChan->m_Param.ChanNo); +} + +/** + * @brief CFespartdatazfDataProcThread::beforeExecute + * + */ +int CFespartdatazfDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief CFespartdatazfDataProcThread::execute + + */ +void CFespartdatazfDataProcThread::execute() +{ + //读取网络事件 + SFesNetEvent netEvent; + + if(!g_fespartdatazfChanelRun) //收到线程退出标志不再往下执行 + return; + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + if(m_ptrCurrentChan== NULL) + return; + + if(m_ptrCurrentChan->ReadNetEvent(1,&netEvent)>0) + { + switch(netEvent.EventType) + { + case CN_FesNetEvent_Connect: + LOGDEBUG("ChanNo=%d connect", m_ptrCurrentChan->m_Param.ChanNo); + m_AppData.state = CN_FespartdatazfAppState_idle; + m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuNormal); + break; + case CN_FesNetEvent_Disconnect: + LOGDEBUG("ChanNo=%d disconnect",m_ptrCurrentChan->m_Param.ChanNo); + m_AppData.state = CN_FespartdatazfAppState_init; + m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuComDown); + break; + default: + break; + } + } + + //接收数据 + RecvNetData(); + SendProcess(); + if (m_timerCount++ >= m_timerCountReset) + m_timerCount = 0;// 1sec is ready + + if (m_timerCount == 0)//1s timer + { + TimerProcess(); + } +} + +/* + @brief 执行quit函数前的处理 + */ +void CFespartdatazfDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + ThreadRunFlag = true; +} + +/** + * @brief CFespartdatazfDataProcThread::InitConfigParam + * fespartdatazf 初始化配置参数 + * @return 成功返回iotSuccess,失败返回iotFailed + */ +int CFespartdatazfDataProcThread::InitConfigParam() +{ + if((m_ptrCFesChan == NULL)||(m_ptrCFesRtu==NULL)) + return iotFailed; + + memset(&m_AppData,0,sizeof(SFespartdatazfAppData)); + m_AppData.sendIntervalReset = 100;//100ms + m_AppData.startDelayReset = 30;//30s + m_AppData.DiFrameIntervalReset = 10000; //10s + m_AppData.AiFrameIntervalReset = 60000; //60s + m_AppData.AccFrameIntervalReset = 300000; //300s + m_AppData.MiFrameIntervalReset = 60000; //60s + m_AppData.startDelay = 0; + m_AppData.maxUpdateCount = 18; + m_AppData.StartChNo = 0; + m_AppData.EndChNo = m_ptrCFesBase->m_ChanNum; + if (m_ptrCurrentChan->m_Param.CommType == CN_FesTcpClient) + m_AppData.state = CN_FespartdatazfAppState_init; + else + m_AppData.state = CN_FespartdatazfAppState_idle; + return iotSuccess; +} + +void CFespartdatazfDataProcThread::AppDataInit(vector vecAppParam) +{ + int found = 0; + if ((m_ptrCurrentChan != NULL) && (m_ptrCFesRtu != NULL) && (vecAppParam.size() > 0)) + { + for (size_t i = 0; i < vecAppParam.size(); i++) + { + if (m_ptrCFesRtu->m_Param.RtuNo == vecAppParam[i].RtuNo) + { + memset(&m_AppData, 0, sizeof(SFespartdatazfAppData)); + //配置 + m_AppData.startDelayReset = vecAppParam[i].startDelay; + m_AppData.sendIntervalReset = vecAppParam[i].sendIntervalReset; + m_AppData.DiFrameIntervalReset = vecAppParam[i].DiFrameIntervalReset; + m_AppData.AiFrameIntervalReset = vecAppParam[i].AiFrameIntervalReset; + m_AppData.AccFrameIntervalReset = vecAppParam[i].AccFrameIntervalReset; + m_AppData.MiFrameIntervalReset = vecAppParam[i].MiFrameIntervalReset; + m_AppData.StartChNo = vecAppParam[i].StartChNo; + m_AppData.EndChNo = vecAppParam[i].EndChNo; + + m_AppData.updateCount = 0; + m_AppData.sendInterval = 0; + m_AppData.startDelay = 0; + found = 1; + break; + } + } + } + if (!found) + InitConfigParam();//配置文件读取失败,取默认配置 + + uint64 msec = getMonotonicMsec(); + m_AppData.startDelay = msec; + m_AppData.sendInterval = msec; + m_AppData.DiFrameInterval = msec; + m_AppData.AiFrameInterval = msec; + m_AppData.AccFrameInterval = msec; + m_AppData.MiFrameInterval = msec; + m_AppData.lastUpdateTime = msec; +} + +/** + * @brief CFespartdatazfDataProcThread::RecvNetData + * fespartdatazf 接收数据处理,返回数据去掉同步头 + * @return 接收长度。 + */ +int CFespartdatazfDataProcThread::RecvNetData() +{ + int recvLen; + recvLen = m_ptrCurrentChan->GetRxBufSize(); + if (recvLen <= 0) + return 0; + byte data[10240]; + recvLen = m_ptrCurrentChan->GetRxBufSize(); + m_ptrCurrentChan->ReadRxBufData(recvLen, data); + m_ptrCurrentChan->DeleteReadRxBufData(recvLen);//清除清除已读取的数据 + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, data, recvLen, CN_SFesSimComFrameTypeRecv); + m_ptrCurrentChan->SetRxNum(1); + return recvLen; +} + +/** + * @brief CFespartdatazfDataProcThread::SendDataToPort + * 数据发送到发送缓冲区。 + * 如是主通道,直接使用m_ptrCFesChan通道结构;如果是备用通道,需要获取当前使用通道,在发送数据。 + * @param Data 数据区 + * @param Size 数据区长度 + */ +void CFespartdatazfDataProcThread::SendDataToPort(byte *Data, int Size) +{ + if (m_ptrCurrentChan == NULL) + return; + + m_ptrCurrentChan->WriteTxBufData(Size, Data); + + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, Data, Size, CN_SFesSimComFrameTypeSend); + m_ptrCurrentChan->SetTxNum(1); + + SleepmSec(m_AppData.sendIntervalReset); +} + +bool CFespartdatazfDataProcThread::isTimetoSend() +{ + int64 curmSec; + + if (!m_AppData.sendFlag) + return false; + + curmSec = getMonotonicMsec(); + if ((curmSec - m_AppData.sendInterval) < m_AppData.sendIntervalReset) + { + if (m_AppData.sendIntervalCount++ > 200)//2秒,纠错处理 + { + m_AppData.sendInterval = curmSec; + m_AppData.sendIntervalCount = 0; + return true; + } + else + return false; + } + else + { + m_AppData.sendInterval = curmSec; + m_AppData.sendIntervalCount = 0; + return true; + } +} +void CFespartdatazfDataProcThread::TimerProcess() +{ + uint64 curmsec = getMonotonicMsec(); + + //定时更新本FES数据 + if (m_AppData.updateCount < m_AppData.maxUpdateCount) + { + if ((curmsec - m_AppData.lastUpdateTime) > CN_FespartdatazfStartUpateTime)//10s + { + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + m_AppData.updateCount++; + m_AppData.lastUpdateTime = curmsec; + } + } + else + { + if ((curmsec - m_AppData.lastUpdateTime) > CN_FespartdatazfNormalUpateTime)//60s + { + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + m_AppData.lastUpdateTime = curmsec; + } + } + + if ((curmsec - m_AppData.DiFrameInterval) > m_AppData.DiFrameIntervalReset) + { + m_AppData.DiFrameInterval = curmsec; + m_AppData.DiFrameFlag = 1; + } + if ((curmsec - m_AppData.AiFrameInterval) > m_AppData.AiFrameIntervalReset) + { + m_AppData.AiFrameInterval = curmsec; + m_AppData.AiFrameFlag = 1; + } + if ((curmsec - m_AppData.AccFrameInterval) > m_AppData.AccFrameIntervalReset) + { + m_AppData.AccFrameInterval = curmsec; + m_AppData.AccFrameFlag = 1; + } + if ((curmsec - m_AppData.MiFrameInterval) > m_AppData.MiFrameIntervalReset) + { + m_AppData.MiFrameInterval = curmsec; + m_AppData.MiFrameFlag = 1; + } + if ((!m_AppData.sendFlag) && ((curmsec - m_AppData.startDelay) > m_AppData.startDelayReset)) + { + m_AppData.sendFlag = 1; + m_AppData.DiFrameFlag = 1; + m_AppData.AiFrameFlag = 1; + m_AppData.AccFrameFlag = 1; + m_AppData.MiFrameFlag = 1; + } +} + +/** +* @brief CFespartdatazfDataProcThread::SendProcess +* fespartdatazf 发送处理 +* @return null +*/ +void CFespartdatazfDataProcThread::SendProcess() +{ + if (!isTimetoSend()) + return; + + if (g_fespartdatazfIsMainFes == false)//备机不作任何操作 + return; + +// if (m_AppData.state == CN_FespartdatazfAppState_init) +// return; + + //转发遥信变位 + SendChgDiFrame(); + //转发SOE + SendSOEFrame(); + + if (m_AppData.DiFrameFlag) + SendDiFrame(); + + if (m_AppData.AiFrameFlag) + SendAiFrame(); + + if (m_AppData.AccFrameFlag) + SendAccFrame(); + + if (m_AppData.MiFrameFlag) + SendMiFrame(); +} + +/** + * @brief CFespartdatazfDataProcThread::SendAiFrame + * @describe 上送遥测 + */ +void CFespartdatazfDataProcThread::SendAiFrame() +{ + int k,n,dataCount; + float AiFloatValue; + //SFesAi *pAi; + SFesFwAi *pFwAi; + //CFesChanPtr pChan = NULL; + //CFesRtuPtr pRtu = NULL; + int writex, sendNum, pointNum; + int pNum, pNumWritex; + uint32 DWordData; + uint32 tempStatus; + + dataCount = 0; + writex = 5; + //当前所有点数量 + pointNum = 0; + m_AppData.sendData[0] = 0xAB; + m_AppData.sendData[1] = 0xC1; + + + sendNum = 1;//发送的第几帧 + pointNum = m_ptrCFesRtu->m_MaxFwAiPoints;//需要转发点的数量 + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pointNum >> (n * 8));//点的总数 + + //点数量 + pNumWritex = writex++; + pNum = 0; + //for (k = 0; k < pRtu->m_MaxAiPoints; k++) + for (k = 0; k < m_ptrCFesRtu->m_MaxFwAiPoints; k++)//m_FwAiPointsNum + { + if (!ThreadRunFlag) + return; + pFwAi = m_ptrCFesRtu->m_pFwAi + k; + if (pFwAi->Used != 1) + //if (pFwAi->Used != 1 || pFwAi->FesRtuNo!=rtuNo) + continue; + AiFloatValue = pFwAi->Value; + + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pFwAi->RemoteNo >> (n * 8));// + //m_AppData.sendData[writex++] = (byte)(pFwAi->FesPointNo >> (n * 8));// + + memcpy(&DWordData, &AiFloatValue, sizeof(AiFloatValue)); + for (n = 0; n < CN_FLOAT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(DWordData >> (n * 8));//值 + + tempStatus = pFwAi->Status; + + tempStatus = 0x01; + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(tempStatus >> (n * 8));//状态 + + pNum++; + dataCount ++; + //点数量超过单帧最大点数后,发送报文 + if (dataCount >= CN_Fespartdatazf_MAX_Point_NUM) + { + m_AppData.sendData[2] = writex - 4; //RTU数量(1字节),加RTU号(4字节),加数据区数量 + m_AppData.sendData[3] = (writex - 4) >> 8; + m_AppData.sendData[4] = sendNum; + //发送帧中的点数量 + m_AppData.sendData[pNumWritex] = pNum; + m_AppData.sendData[writex++] = 0xCD; + m_AppData.sendData[writex++] = 0xEF; + m_AppData.sendDataLen = writex; + SendDataToPort(m_AppData.sendData, m_AppData.sendDataLen); + + //发送一帧报文后,清空计数 + pNum = 0; + dataCount = 0; + sendNum++; + writex = 10; + } + } + //发送帧中该RTU的点数量 + m_AppData.sendData[pNumWritex] = pNum; + //判断是否还有点未发送 + if (dataCount > 0) + { + m_AppData.sendData[2] = writex - 4; + m_AppData.sendData[3] = (writex - 4) >> 8; + m_AppData.sendData[4] = sendNum; + m_AppData.sendData[writex++] = 0xCD; + m_AppData.sendData[writex++] = 0xEF; + m_AppData.sendDataLen = writex; + SendDataToPort(m_AppData.sendData, m_AppData.sendDataLen); + } + m_AppData.AiFrameFlag = 0; +} + +/** +* @brief CFespartdatazfDataProcThread::SendDiFrame +* @describe 上送遥信 +*/ +void CFespartdatazfDataProcThread::SendDiFrame() +{ + int k,n, dataCount; + //SFesDi *pDi; + SFesFwDi *pFwDi; +// CFesChanPtr pChan = NULL; +// CFesRtuPtr pRtu = NULL; + int writex,sendNum, pointNum; + int pNum, pNumWritex; + uint32 tempStatus; + + //初始化 + dataCount = 0; + writex = 5; + pointNum = 0; + m_AppData.sendData[0] = 0xAB; + m_AppData.sendData[1] = 0xC2; + sendNum = 1;//发送的第几帧 + pointNum = m_ptrCFesRtu->m_MaxFwDiPoints;//需要转发点的数量 + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pointNum >> (n * 8));//点的总数 + + //点数量 + pNumWritex = writex++; + pNum = 0; + for (k = 0; k < m_ptrCFesRtu->m_MaxFwDiPoints; k++) + { + if (!ThreadRunFlag) + return; + pFwDi = m_ptrCFesRtu->m_pFwDi + k; + //pDi = pRtu->m_pDi + k; + //if (pFwDi->Used != 1 || pFwDi->FesRtuNo!=rtuNo) + if (pFwDi->Used != 1) + continue; + + //转发数据组帧 + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pFwDi->RemoteNo >> (n * 8));//点号 + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pFwDi->Value >> (n * 8));//值 + + tempStatus = pFwDi->Status; + + tempStatus = 0x01; + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(tempStatus >> (n * 8));//状态 + + pNum++; + dataCount ++; + //点数量超过单帧最大点数后,发送报文 + if (dataCount >= CN_Fespartdatazf_MAX_Point_NUM) + { + m_AppData.sendData[2] = writex - 4; //RTU数量(1字节),加RTU号(4字节),加数据区数量 + m_AppData.sendData[3] = (writex - 4) >> 8; + m_AppData.sendData[4] = sendNum; + //发送帧中该RTU的点数量 + m_AppData.sendData[pNumWritex] = pNum; + m_AppData.sendData[writex++] = 0xCD; + m_AppData.sendData[writex++] = 0xEF; + m_AppData.sendDataLen = writex; + SendDataToPort(m_AppData.sendData, m_AppData.sendDataLen); + + //发送一帧报文后,清空计数 + pNum = 0; + dataCount = 0; + sendNum++; + writex = 10; + } + } + //发送帧中该RTU的点数量 + m_AppData.sendData[pNumWritex] = pNum; + //判断是否还有点未发送 + if (dataCount > 0) + { + m_AppData.sendData[2] = writex - 4; + m_AppData.sendData[3] = (writex - 4) >> 8; + m_AppData.sendData[4] = sendNum; + m_AppData.sendData[writex++] = 0xCD; + m_AppData.sendData[writex++] = 0xEF; + m_AppData.sendDataLen = writex; + SendDataToPort(m_AppData.sendData, m_AppData.sendDataLen); + } + m_AppData.DiFrameFlag = 0; +} + +/** +* @brief CFespartdatazfDataProcThread::SendAccFrame +* @describe 上送遥脉 +*/ +void CFespartdatazfDataProcThread::SendAccFrame() +{ + int k,n, dataCount; + //SFesAcc *pAcc; + SFesFwAcc *pFwAcc; +// CFesChanPtr pChan = NULL; +// CFesRtuPtr pRtu = NULL; + int writex, sendNum, pointNum; + int pNum, pNumWritex; + double AccDoubleValue; + uint64 QWordData; + uint32 tempStatus; + + dataCount = 0; + writex = 5; + //当前所有点数量 + pointNum = 0; + m_AppData.sendData[0] = 0xAB; + m_AppData.sendData[1] = 0xC3; + + sendNum = 1;//发送的第几帧 + pointNum = m_ptrCFesRtu->m_MaxFwAccPoints;//需要转发点的数量 + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pointNum >> (n * 8));//RTU号 + + //点数量下标先记下,后面再赋值 + pNumWritex = writex++; + pNum = 0; + for (k = 0; k < m_ptrCFesRtu->m_MaxFwAccPoints; k++) + { + if (!ThreadRunFlag) + return; + //pAcc = pRtu->m_pAcc + k; + pFwAcc = m_ptrCFesRtu->m_pFwAcc + k; +// if (pFwAcc->Used != 1 || pFwAcc->FesRtuNo!=rtuNo) + if (pFwAcc->Used != 1) + continue; + AccDoubleValue = pFwAcc->Value; + + //转发数据组帧 + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pFwAcc->RemoteNo >> (n * 8));//点号 + memcpy(&QWordData, &AccDoubleValue, sizeof(AccDoubleValue)); + for (n = 0; n < CN_INT64_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(QWordData >> (n * 8));//值 + + tempStatus = pFwAcc->Status; + + tempStatus = 0x01; + + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(tempStatus >> (n * 8));//状态 + + pNum++; + dataCount++; + //点数量超过单帧最大点数后,发送报文 + if (dataCount >= CN_Fespartdatazf_MAX_ACC_NUM) + { + m_AppData.sendData[2] = writex - 4; + m_AppData.sendData[3] = (writex - 4) >> 8; + m_AppData.sendData[4] = sendNum; + //发送帧中该RTU的点数量 + m_AppData.sendData[pNumWritex] = pNum; + m_AppData.sendData[writex++] = 0xCD; + m_AppData.sendData[writex++] = 0xEF; + m_AppData.sendDataLen = writex; + SendDataToPort(m_AppData.sendData, m_AppData.sendDataLen); + + //发送一帧报文后,清空计数 + pNum = 0; + dataCount = 0; + sendNum++; + writex = 10; + } + } + //发送帧中该RTU的点数量 + m_AppData.sendData[pNumWritex] = pNum; + + //判断是否还有点未发送 + if (dataCount > 0) + { + m_AppData.sendData[2] = writex - 4; + m_AppData.sendData[3] = (writex - 4) >> 8; + m_AppData.sendData[4] = sendNum; + m_AppData.sendData[writex++] = 0xCD; + m_AppData.sendData[writex++] = 0xEF; + m_AppData.sendDataLen = writex; + SendDataToPort(m_AppData.sendData, m_AppData.sendDataLen); + } + m_AppData.AccFrameFlag = 0; +} + +/** +* @brief CFespartdatazfDataProcThread::SendMiFrame +* @describe 上送混合量 +*/ +void CFespartdatazfDataProcThread::SendMiFrame() +{ + int k,n, dataCount; + //SFesMi *pMi; + SFesFwMi *pFwMi; +// CFesChanPtr pChan = NULL; +// CFesRtuPtr pRtu = NULL; + int writex, sendNum, pointNum; + int pNum, pNumWritex; + uint32 tempStatus; + + dataCount = 0; + writex = 5; + //当前所有点数量 + pointNum = 0; + m_AppData.sendData[0] = 0xAB; + m_AppData.sendData[1] = 0xC4; + + sendNum = 1;//发送的第几帧 + pointNum = m_ptrCFesRtu->m_MaxFwMiPoints;//需要转发点的数量 + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pointNum >> (n * 8));//点的总数 + + //点数量下标先记下,后面再赋值 + pNumWritex = writex++; + pNum = 0; + for (k = 0; k < m_ptrCFesRtu->m_MaxFwMiPoints; k++) + { + if (!ThreadRunFlag) + return; + //pMi = pRtu->m_pMi + k; + pFwMi = m_ptrCFesRtu->m_pFwMi + k; +// if (pFwMi->Used != 1 || pFwMi->FesRtuNo!=rtuNo) + if (pFwMi->Used != 1) + continue; + + //转发数据组帧 + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pFwMi->RemoteNo >> (n * 8));//点号 + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pFwMi->Value >> (n * 8));//值 + + tempStatus = pFwMi->Status; + + tempStatus = 0x01; + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(tempStatus >> (n * 8));//状态 + + pNum++; + dataCount++; + //点数量超过单帧最大点数后,发送报文 + if (dataCount >= CN_Fespartdatazf_MAX_Point_NUM) + { + m_AppData.sendData[2] = writex - 4; + m_AppData.sendData[3] = (writex - 4) >> 8; + m_AppData.sendData[4] = sendNum; + //发送帧中该RTU的点数量 + m_AppData.sendData[pNumWritex] = pNum; + m_AppData.sendData[writex++] = 0xCD; + m_AppData.sendData[writex++] = 0xEF; + m_AppData.sendDataLen = writex; + SendDataToPort(m_AppData.sendData, m_AppData.sendDataLen); + + //发送一帧报文后,清空计数 + pNum = 0; + dataCount = 0; + sendNum++; + writex = 10; + } + } + //发送帧中该RTU的点数量 + m_AppData.sendData[pNumWritex] = pNum; + //判断是否还有点未发送 + if (dataCount > 0) + { + m_AppData.sendData[2] = writex - 4; + m_AppData.sendData[3] = (writex - 4) >> 8; + m_AppData.sendData[4] = sendNum; + m_AppData.sendData[writex++] = 0xCD; + m_AppData.sendData[writex++] = 0xEF; + m_AppData.sendDataLen = writex; + SendDataToPort(m_AppData.sendData, m_AppData.sendDataLen); + } + m_AppData.MiFrameFlag = 0; +} + +/** +* @brief CFespartdatazfDataProcThread::SendSOEFrame +* @describe 上送SOE +*/ +void CFespartdatazfDataProcThread::SendSOEFrame() +{ + int i,n, dataCount; + SFesFwSoeEvent *pSoeEvent = NULL; + int writex,retNum, count; + uint32 tempStatus; + + dataCount = 0; + writex = 5; + m_AppData.sendData[0] = 0xAB; + m_AppData.sendData[1] = 0xC5; + + count = m_ptrCFesRtu->GetFwSOEEventNum(); + if (count < 1) + return; + + if (count > CN_Fespartdatazf_MAX_SOE_NUM) + count = CN_Fespartdatazf_MAX_SOE_NUM; + + //count可以设置为最大值,这样就不用动态分配空间 + retNum = m_ptrCFesRtu->ReadFwSOEEvent(count, m_pFwSoeData); + count = 0; + for (i = 0; i < retNum; i++) + { + pSoeEvent = m_pFwSoeData + i; + //LOGDEBUG("RtuNo=%d PointNo=%d Status=%d Value=%d", pSoeEvent->RtuNo, pSoeEvent->PointNo, pSoeEvent->Status, pSoeEvent->Value); + + if (!ThreadRunFlag) + return; + + //转发数据组帧 + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pSoeEvent->RtuNo >> (n * 8));//RTU号 + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pSoeEvent->PointNo >> (n * 8));//点号 + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pSoeEvent->Value >> (n * 8));//值 + + tempStatus = pSoeEvent->Status; + + tempStatus = 0x01; + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(tempStatus >> (n * 8));//状态 + + for (n = 0; n < CN_INT64_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pSoeEvent->time >> (n * 8));//时间戳 + + dataCount++; + //点数量超过单帧最大点数后,发送报文 + if (dataCount >= CN_Fespartdatazf_MAX_SOE_NUM) + { + m_AppData.sendData[2] = writex - 4; + m_AppData.sendData[3] = (writex - 4) >> 8; + m_AppData.sendData[4] = dataCount; + m_AppData.sendData[writex++] = 0xCD; + m_AppData.sendData[writex++] = 0xEF; + m_AppData.sendDataLen = writex; + SendDataToPort(m_AppData.sendData, m_AppData.sendDataLen); + + //发送一帧报文后,清空计数 + dataCount = 0; + writex = 10; + } + } + + //判断是否还有点未发送 + if (dataCount > 0) + { + m_AppData.sendData[2] = writex - 4; + m_AppData.sendData[3] = (writex - 4) >> 8; + m_AppData.sendData[4] = dataCount; + m_AppData.sendData[writex++] = 0xCD; + m_AppData.sendData[writex++] = 0xEF; + m_AppData.sendDataLen = writex; + SendDataToPort(m_AppData.sendData, m_AppData.sendDataLen); + } +} + + +/** +* @brief CFespartdatazfDataProcThread::SendChgDiFrame +* @describe 上送遥信变位 +*/ +void CFespartdatazfDataProcThread::SendChgDiFrame() +{ + int i, n, dataCount; + int writex, retNum, count; + SFesFwChgDi *pChgDi; + + dataCount = 0; + writex = 5; + m_AppData.sendData[0] = 0xAB; + m_AppData.sendData[1] = 0xC6; + + count = m_ptrCFesRtu->GetFwChgDiNum(); + if (count < 1) + return; + + if (count > CN_Fespartdatazf_MAX_SOE_NUM) + count = CN_Fespartdatazf_MAX_SOE_NUM; + + //count可以设置为最大值,这样就不用动态分配空间 + retNum = m_ptrCFesRtu->ReadFwChgDi(count, m_pChgDiData); + count = 0; + for (i = 0; i < retNum; i++) + { + if (!ThreadRunFlag) + return; + + pChgDi = m_pChgDiData + i; + //转发数据组帧 + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pChgDi->RtuNo >> (n * 8));//RTU号 + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pChgDi->PointNo >> (n * 8));//点号 + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pChgDi->Value >> (n * 8));//值 + + for (n = 0; n < CN_INT_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pChgDi->Status >> (n * 8));//状态 + + for (n = 0; n < CN_INT64_SIZE; n++) + m_AppData.sendData[writex++] = (byte)(pChgDi->time >> (n * 8));//时间戳 + + dataCount++; + //点数量超过单帧最大点数后,发送报文 + if (dataCount >= CN_Fespartdatazf_MAX_SOE_NUM) + { + m_AppData.sendData[2] = writex - 4; + m_AppData.sendData[3] = (writex - 4) >> 8; + m_AppData.sendData[4] = dataCount; + m_AppData.sendData[writex++] = 0xCD; + m_AppData.sendData[writex++] = 0xEF; + m_AppData.sendDataLen = writex; + SendDataToPort(m_AppData.sendData, m_AppData.sendDataLen); + + //发送一帧报文后,清空计数 + dataCount = 0; + writex = 10; + } + } + + //判断是否还有点未发送 + if (dataCount > 0) + { + m_AppData.sendData[2] = writex - 4; + m_AppData.sendData[3] = (writex - 4) >> 8; + m_AppData.sendData[4] = dataCount; + m_AppData.sendData[writex++] = 0xCD; + m_AppData.sendData[writex++] = 0xEF; + m_AppData.sendDataLen = writex; + SendDataToPort(m_AppData.sendData, m_AppData.sendDataLen); + } +} + diff --git a/product/src/fes/protocol/fespartdatazf/fespartdatazfDataProcThread.h b/product/src/fes/protocol/fespartdatazf/fespartdatazfDataProcThread.h new file mode 100644 index 00000000..c08c09a2 --- /dev/null +++ b/product/src/fes/protocol/fespartdatazf/fespartdatazfDataProcThread.h @@ -0,0 +1,125 @@ +/* + @file FespartdatazfDataProcThread.h + @brief Fespartdatazf 数据处理线程类 + @author thxiao +*/ +#pragma once + +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "TcpServerThread.h" +using namespace iot_public; + +#define CN_Fespartdatazf_MAX_Point_NUM 165 +#define CN_Fespartdatazf_MAX_ACC_NUM 125 +#define CN_Fespartdatazf_MAX_SOE_NUM 100 +#define CN_Fespartdatazf_MAX_Frame_LEN 3000 + +#define CN_INT_SIZE 4 +#define CN_FLOAT_SIZE 4 +#define CN_INT64_SIZE 8 +const int CN_FespartdatazfAppState_idle = 0; +const int CN_FespartdatazfAppState_waitResp = 1; +const int CN_FespartdatazfAppState_waitControlResp = 2; +const int CN_FespartdatazfAppState_init = 3; + +//本FES数据跟新间隔 +const int CN_FespartdatazfStartUpateTime = 10000;//10s +const int CN_FespartdatazfNormalUpateTime = 60000;//60s + +typedef struct{ + int RtuNo; + int startDelay; //系统启动延时,单位秒 + int sendIntervalReset; //报文发送间隔,单位毫秒 + + int DiFrameIntervalReset; //遥信帧发送间隔(单位:秒) + int AiFrameIntervalReset; //遥测帧发送间隔(单位:秒) + int AccFrameIntervalReset; //遥脉帧发送间隔(单位:秒) + int MiFrameIntervalReset; //混合量帧发送间隔(单位:秒) + + int StartChNo; //需要转发的起始通道号 + int EndChNo; //需要转发的结束通道号 + + int maxUpdateCount; //系统启动前,本FES数据每10S跟新一次全数据,直到该值到到达最大值,变为60S跟新全数据。 +}SFespartdatazfAppConfigParam; + +//Fespartdatazf 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct{ + int RtuNo; + uint64 startDelay; //系统启动延时,单位秒 + int startDelayReset; + int sendFlag; + uint64 sendInterval; //连续发送数据的时间间隔(单位:毫秒) + int sendIntervalReset; + uint64 DiFrameInterval; //遥信帧发送间隔(单位:秒) + int DiFrameIntervalReset; //遥信帧发送间隔(单位:秒) + uint64 AiFrameInterval; //遥测帧发送间隔(单位:秒) + int AiFrameIntervalReset; //遥测帧发送间隔(单位:秒) + uint64 AccFrameInterval; //遥脉帧发送间隔(单位:秒) + int AccFrameIntervalReset; //遥脉帧发送间隔(单位:秒) + uint64 MiFrameInterval; //混合量帧发送间隔(单位:秒) + int MiFrameIntervalReset; //混合量帧发送间隔(单位:秒) + + int maxUpdateCount; //系统启动前,本FES数据每10S跟新一次全数据,直到该值到到达最大值,变为60S跟新全数据。 + int updateCount; + int state; //网络状态 + + int StartChNo; //需要转发的起始通道号 + int EndChNo; //需要转发的结束通道号 + + uint8 DiFrameFlag; + uint8 AccFrameFlag; + uint8 AiFrameFlag; + uint8 MiFrameFlag; + uint64 lastUpdateTime; + uint8 sendData[CN_Fespartdatazf_MAX_Frame_LEN]; + int sendDataLen; + int sendIntervalCount; +}SFespartdatazfAppData; + +class CFespartdatazfDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + CFespartdatazfDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam); + virtual ~CFespartdatazfDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + virtual void beforeQuit(); + CFesBase* m_ptrCFesBase; + + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,Fespartdatazf tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SFespartdatazfAppData m_AppData; //内部应用数据结构 + bool ThreadRunFlag; //线程运行标志 + SFesFwSoeEvent *m_pFwSoeData; + SFesFwChgDi *m_pChgDiData; +private: + int m_timerCount; + int m_timerCountReset; + + void SendProcess(); + int RecvNetData(); + void SendDataToPort(byte *Data, int Size); + int InitConfigParam(); + void TimerProcess(); + bool isTimetoSend(); + void AppDataInit(vector vecAppParam); + void SendAiFrame(); + void SendDiFrame(); + void SendAccFrame(); + void SendMiFrame(); + void SendSOEFrame(); + void SendChgDiFrame(); +}; + +typedef boost::shared_ptr CFespartdatazfDataProcThreadPtr; + diff --git a/product/src/fes/protocol/gf104/GF104.cpp b/product/src/fes/protocol/gf104/GF104.cpp index 323753e2..aac5c807 100644 --- a/product/src/fes/protocol/gf104/GF104.cpp +++ b/product/src/fes/protocol/gf104/GF104.cpp @@ -54,6 +54,7 @@ int EX_ExitSystem(int flag) CGF104::CGF104() { + m_ProtocolId = 0; m_TcpServerListenThreadFlag = true; m_ptrCFesBase = NULL; m_CTcpServerListenThread = NULL; diff --git a/product/src/fes/protocol/gf104/GFTcpServerListenThread.cpp b/product/src/fes/protocol/gf104/GFTcpServerListenThread.cpp index 8eceecb1..62d27982 100644 --- a/product/src/fes/protocol/gf104/GFTcpServerListenThread.cpp +++ b/product/src/fes/protocol/gf104/GFTcpServerListenThread.cpp @@ -415,7 +415,7 @@ bool CGFTcpServerListenThread::GetStationId(char *recIp,int recvSock,int station TcpClose((int)m_AcceptSocket[ReNo]); LOGDEBUG("The ChanNo=%d RtuAddr=%d already connect! m_AcceptSocket[%d] = %d close\n", ptrTcp->m_ptrCFesChan->m_Param.ChanNo, stationId, ReNo, m_AcceptSocket[ReNo]); // SetDiscNetEvent(ptrTcp->m_ptrCFesChan); - m_AcceptSocket[ReNo] = INVALID_SOCKET; + //m_AcceptSocket[ReNo] = INVALID_SOCKET; m_AcceptSocket[ReNo] = recvSock; LOGDEBUG("Accept-1 The ChanNo=%d RtuAddr=%d %s new connect! m_AcceptSocket[%d] = %d accept\n", ptrTcp->m_ptrCFesChan->m_Param.ChanNo, stationId, recIp, ReNo, m_AcceptSocket[ReNo]); diff --git a/product/src/fes/protocol/hc_mqttclient_s/Hcmqtts.cpp b/product/src/fes/protocol/hc_mqttclient_s/Hcmqtts.cpp new file mode 100644 index 00000000..a53bee04 --- /dev/null +++ b/product/src/fes/protocol/hc_mqttclient_s/Hcmqtts.cpp @@ -0,0 +1,479 @@ +/* + @file Hcmqtts.cpp + @brief Hcmqtts规约处理主程序 + @author liujian + @date 2022-01-05 + @history + + */ +#include "Hcmqtts.h" +#include "pub_utility_api/CommonConfigParse.h" + +using namespace iot_public; + +CHcmqtts Hcmqtts; +bool g_HcmqttsIsMainFes=false; +bool g_HcmqttsChanelRun=true; + +int EX_SetBaseAddr(void *address) +{ + Hcmqtts.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + Hcmqtts.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + Hcmqtts.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + Hcmqtts.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + Hcmqtts.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + LOGDEBUG("hc_mqttclient_s EX_ExitSystem() start"); + g_HcmqttsChanelRun=false;//使所有的线程退出。 + Hcmqtts.ExitSystem(flag); + LOGDEBUG("hc_mqttclient_s EX_ExitSystem() end"); + return iotSuccess; +} +CHcmqtts::CHcmqtts() +{ + // 2020-02-13 thxiao ReadConfigParam()需要使用m_ptrCFesBase,所以改为SetBaseAddr()处调用 + //ReadConfigParam(); + m_ProtocolId = 0; +} + +CHcmqtts::~CHcmqtts() +{ + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); +} + + +int CHcmqtts::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + ReadConfigParam(); + } + return iotSuccess; +} + +int CHcmqtts::SetProperty(int IsMainFes) +{ + g_HcmqttsIsMainFes = (bool)IsMainFes; + LOGDEBUG("CHcmqtts::SetProperty g_HcmqttsIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief CHcmqtts::OpenChan 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CHcmqtts::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if ((OpenFlag == CN_FesChanThread_Flag) || (OpenFlag == CN_FesChanAndDataThread_Flag)) + { + switch (ptrFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + case CN_FesTcpServer: + break; + default: + LOGERROR("CHcmqtts EX_OpenChan() ChanNo:%d CommType=%d is not TCP SERVER/Client!", ptrFesChan->m_Param.ChanNo, ptrFesChan->m_Param.CommType); + return iotFailed; + } + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + CHcmqttsDataProcThreadPtr ptrCDataProc; + ptrCDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_vecAppParam); + if (ptrCDataProc == NULL) + { + LOGERROR("CHcmqtts EX_OpenChan() ChanNo:%d create CHcmqttsDataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + LOGERROR("CHcmqtts EX_OpenChan() ChanNo:%d create CHcmqttsDataProcThreadPtr ok!", ptrFesChan->m_Param.ChanNo); + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; +} + +/** + * @brief CHcmqtts::CloseChan 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CHcmqtts::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("CHcmqtts::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + return iotSuccess; +} + +/** + * @brief CHcmqtts::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int CHcmqtts::ChanTimer(int MainChanNo) +{ + //把命令缓冲时间间隔到的命放到发送命令缓冲区 + return iotSuccess; +} + +int CHcmqtts::ExitSystem(int flag) +{ + InformTcpThreadExit(); + return iotSuccess; +} + +void CHcmqtts::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + CHcmqttsDataProcThreadPtr ptrTcp; + + if ((tempNum = (int)m_CDataProcQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CDataProcQueue.erase(it);//会调用CHcmqttsDataProcThread::~CHcmqttsDataProcThread()退出线程 + LOGDEBUG("CHcmqtts::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + +/** +* @brief CHcmqtts::ReadConfigParam +* 读取Hcmqtts配置文件 +* @return 成功返回iotSuccess,失败返回iotFailed +*/ +int CHcmqtts::ReadConfigParam() +{ + CCommonConfigParse config; + int ivalue; + std::string strvalue; + char strRtuNo[48]; + SHcmqttsAppConfigParam param; + int items,i,j; + CFesChanPtr ptrChan; //CHAN数据区 + CFesRtuPtr ptrRTU; + + memset(¶m, 0, sizeof(SHcmqttsAppConfigParam)); + + if (m_ptrCFesBase == NULL) + return iotFailed; + + m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"hc_mqttclient_s"); + if (m_ProtocolId == -1) + { + LOGDEBUG("ReadConfigParam ProtoclID error"); + return iotFailed; + } + LOGINFO("hc_mqttclient_s ProtoclID=%d", m_ProtocolId); + + if (config.load("../../data/fes/", "hc_mqttclient_s.xml") == iotFailed) + { + LOGDEBUG("hc_mqttclient_s load hcmqttclients.xml error"); + return iotSuccess; + } + LOGDEBUG("hc_mqttclient_s load hcmqttclients.xml ok"); + + for (i = 0; i < m_ptrCFesBase->m_vectCFesChanPtr.size(); i++) + { + ptrChan = m_ptrCFesBase->m_vectCFesChanPtr[i]; + if ((ptrChan->m_Param.Used == 1) && (m_ProtocolId == ptrChan->m_Param.ProtocolId)) + { + //found RTU + for (j = 0; j < m_ptrCFesBase->m_vectCFesRtuPtr.size(); j++) + { + ptrRTU = m_ptrCFesBase->m_vectCFesRtuPtr[j]; + if (ptrRTU->m_Param.Used && (ptrRTU->m_Param.ChanNo == ptrChan->m_Param.ChanNo)) + { + memset(&strRtuNo[0], 0, sizeof(strRtuNo)); + sprintf(strRtuNo, "RTU%d", ptrRTU->m_Param.RtuNo); + memset(¶m, 0, sizeof(param)); + param.RtuNo = ptrRTU->m_Param.RtuNo; + items = 0; + + if (config.getIntValue(strRtuNo, "startDelay", ivalue) == iotSuccess) + { + param.startDelay = ivalue; + items++; + } + else + param.startDelay = 30;//30s + + if (config.getIntValue(strRtuNo, "ymStartDelay", ivalue) == iotSuccess) + { + param.ymStartDelay = ivalue; + items++; + } + else + param.ymStartDelay = 350; //350s + + if (config.getIntValue(strRtuNo, "max_update_count", ivalue) == iotSuccess) + { + param.maxUpdateCount = ivalue; + items++; + } + else + param.maxUpdateCount = 18; //3MIN + + if (config.getIntValue(strRtuNo, "mqttDelayTime", ivalue) == iotSuccess) + { + param.mqttDelayTime = ivalue; + items++; + } + else + param.mqttDelayTime = 100; + + if (config.getIntValue(strRtuNo, "PasswordFlag", ivalue) == iotSuccess) + { + param.PasswordFlag = ivalue; + items++; + } + else + param.PasswordFlag = 0; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "ClientId", strvalue) == iotSuccess) + { + param.ClientId = strvalue; + items++; + } + else + param.ClientId = "KhMqttClient"; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "UserName", strvalue) == iotSuccess) + { + param.UserName = strvalue; + items++; + } + else + param.UserName.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "Password", strvalue) == iotSuccess) + { + param.Password = strvalue; + items++; + } + else + param.Password.clear(); + + if (config.getIntValue(strRtuNo, "KeepAlive", ivalue) == iotSuccess) + { + param.KeepAlive = ivalue; + items++; + } + else + param.KeepAlive = 180; //心跳检测时间间隔 + + if (config.getIntValue(strRtuNo, "Retain", ivalue) == iotSuccess) + { + param.Retain = (bool)(ivalue & 0x01); + items++; + } + else + param.Retain = false; //默认0 + + if (config.getIntValue(strRtuNo, "QoS", ivalue) == iotSuccess) + { + param.QoS = ivalue; + items++; + } + else + param.QoS = 1; + + if (config.getIntValue(strRtuNo, "WillFlag", ivalue) == iotSuccess) + { + param.WillFlag = ivalue; + items++; + } + else + param.WillFlag = 1; + + if (config.getIntValue(strRtuNo, "WillQos", ivalue) == iotSuccess) + { + param.WillQos = ivalue; + items++; + } + else + param.WillQos = 1; + + if (config.getIntValue(strRtuNo, "sslFlag", ivalue) == iotSuccess) + { + param.sslFlag = ivalue; + items++; + } + else + param.sslFlag = 0; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "tls_version", strvalue) == iotSuccess) + { + param.tls_version = strvalue; + items++; + } + else + param.tls_version = "tlsv1.1"; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "caPath", strvalue) == iotSuccess) + { + param.caPath = strvalue; + items++; + } + else + param.caPath = "../../data/fes/"; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "caFile", strvalue) == iotSuccess) + { + param.caFile = param.caPath + strvalue; + items++; + } + else + param.caFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "certFile", strvalue) == iotSuccess) + { + param.certFile = param.caPath + strvalue; + items++; + } + else + param.certFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "keyFile", strvalue) == iotSuccess) + { + param.keyFile = param.caPath + strvalue; + items++; + } + else + param.keyFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "keyPassword", strvalue) == iotSuccess) + { + param.keyPassword = strvalue; + items++; + } + else + param.keyPassword.clear(); + + if (config.getIntValue(strRtuNo, "CycReadFileTime", ivalue) == iotSuccess) + { + param.CycReadFileTime = ivalue; + items++; + } + else + param.CycReadFileTime = 300; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "AlarmProjectType", strvalue) == iotSuccess) + { + param.AlarmProjectType = strvalue; + items++; + } + else + param.AlarmProjectType.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "AlarmTopic", strvalue) == iotSuccess) + { + param.AlarmTopic = strvalue; + items++; + } + else + param.AlarmTopic.clear(); + + if (items > 0)//对应的RTU有配置项 + { + m_vecAppParam.push_back(param); + } + } + } + } + } + return iotSuccess; +} + +/** + * @brief CHcmqtts::InformTcpThreadExit + * 设置线程退出标志,通知线程退出 + * @return + */ +void CHcmqtts::InformTcpThreadExit() +{ + +} + diff --git a/product/src/fes/protocol/hc_mqttclient_s/Hcmqtts.h b/product/src/fes/protocol/hc_mqttclient_s/Hcmqtts.h new file mode 100644 index 00000000..9ecd03a1 --- /dev/null +++ b/product/src/fes/protocol/hc_mqttclient_s/Hcmqtts.h @@ -0,0 +1,44 @@ +/* + @file Hcmqtts.h + @brief Hcmqtts头文件 + @author liujian + @date 2022-01-05 +*/ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "HcmqttsDataProcThread.h" + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API CHcmqtts : public CProtocolBase +{ +public: + CHcmqtts(); + ~CHcmqtts(); + + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + vector m_CDataProcQueue; + vector m_vecAppParam; + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + int ExitSystem(int flag); + int ReadConfigParam(); + void InformTcpThreadExit(); +private: + int m_ProtocolId; + void ClearDataProcThreadByChanNo(int ChanNo); +}; + diff --git a/product/src/fes/protocol/hc_mqttclient_s/HcmqttsDataProcThread.cpp b/product/src/fes/protocol/hc_mqttclient_s/HcmqttsDataProcThread.cpp new file mode 100644 index 00000000..e550cce4 --- /dev/null +++ b/product/src/fes/protocol/hc_mqttclient_s/HcmqttsDataProcThread.cpp @@ -0,0 +1,1148 @@ +/* + @file CHcmqttsDataProcThread.cpp + @brief Hcmqtts 数据处理线程类。 + @author liujian + @date 2022-01-05 + @history + */ +#include +#include "HcmqttsDataProcThread.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" + +using namespace iot_public; + +extern bool g_HcmqttsIsMainFes; +extern bool g_HcmqttsChanelRun; +const int gHcmqttsThreadTime = 10; +std::string g_KeyPassword; //私钥密码 + +static int password_callback(char* buf, int size, int rwflag, void* userdata) +{ + memcpy(buf, g_KeyPassword.data(), size); + buf[size - 1] = '\0'; + + return (int)strlen(buf); +} + +CHcmqttsDataProcThread::CHcmqttsDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam): + CTimerThreadBase("HcmqttsDataProcThread", gHcmqttsThreadTime,0,true) +{ + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + m_pSoeData = NULL; + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + + m_timerCountReset = 10; + m_timerCount = 0; + + publishTime = 0; + memset(&mqttTime, 0, sizeof(MqttPublishTime)); + mqttTime.startTime = getMonotonicMsec() / 1000; + mqttTime.CycTime = getMonotonicMsec() / 1000; + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL)) + { + return; + } + m_ptrCFesChan->SetLinkStatus(CN_FesChanConnect); + m_ptrCFesChan->SetComThreadRunFlag(CN_FesRunFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + //2020-03-03 thxiao 不需要数据变化 + m_ptrCFesRtu->SetFwAiChgStop(1); + m_ptrCFesRtu->SetFwDiChgStop(1); + m_ptrCFesRtu->SetFwDDiChgStop(1); + m_ptrCFesRtu->SetFwMiChgStop(1); + m_ptrCFesRtu->SetFwAccChgStop(1); + + int found = 0; + if(vecAppParam.size()>0) + { + for (size_t i = 0; i < vecAppParam.size(); i++) + { + if(m_ptrCFesRtu->m_Param.RtuNo == vecAppParam[i].RtuNo) + { + memset(&m_AppData,0,sizeof(SHcmqttsAppData)); + //配置 + m_AppData.mqttDelayTime = vecAppParam[i].mqttDelayTime; + m_AppData.PasswordFlag = vecAppParam[i].PasswordFlag; + m_AppData.ClientId = vecAppParam[i].ClientId; + m_AppData.UserName = vecAppParam[i].UserName; + m_AppData.Password = vecAppParam[i].Password; + m_AppData.KeepAlive = vecAppParam[i].KeepAlive; + m_AppData.Retain = vecAppParam[i].Retain; + m_AppData.QoS = vecAppParam[i].QoS; + m_AppData.WillFlag = vecAppParam[i].WillFlag; + m_AppData.WillQos = vecAppParam[i].WillQos; + //SSL加密配置 + m_AppData.sslFlag = vecAppParam[i].sslFlag; + m_AppData.tls_version = vecAppParam[i].tls_version; + m_AppData.caPath = vecAppParam[i].caPath; + m_AppData.caFile = vecAppParam[i].caFile; + m_AppData.certFile = vecAppParam[i].certFile; + m_AppData.keyFile = vecAppParam[i].keyFile; + m_AppData.keyPassword = vecAppParam[i].keyPassword; + m_AppData.AlarmProjectType = vecAppParam[i].AlarmProjectType; + m_AppData.AlarmTopic = vecAppParam[i].AlarmTopic; + m_AppData.maxUpdateCount = vecAppParam[i].maxUpdateCount; + m_AppData.startDelay = vecAppParam[i].startDelay; + m_AppData.ymStartDelay = vecAppParam[i].ymStartDelay; + m_AppData.CycReadFileTime = vecAppParam[i].CycReadFileTime; + + found = 1; + break; + } + } + } + if(!found) + InitConfigParam();//配置文件读取失败,取默认配置 + + //读取mqtt_topic_cfg.csv文件,并更新参数 + GetTopicCfg(); + + m_AppData.mqttContFlag = false; + + //告警主题为空,则不发告警数据 + if (m_AppData.AlarmTopic.length() < 1) + { + m_ptrCFesRtu->SetFwSoeChgStop(1); + m_ptrCFesRtu->SetFwDSoeChgStop(1); + } + m_AppData.alarmList.clear(); + GetAlarmCfg(); + + //创建mqttclient对象 + mosqpp::lib_init(); + mqttClient = new mosqpp::mosquittopp(m_AppData.ClientId.data()); +} + +CHcmqttsDataProcThread::~CHcmqttsDataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + if(m_pSoeData != NULL) + free(m_pSoeData); + + if (m_AppData.mqttContFlag) + mqttClient->disconnect(); + + //删除MQTT对象 + if(mqttClient) + delete mqttClient; + + ClearTopicStr(); + + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + LOGDEBUG("CHcmqttsDataProcThread::~CHcmqttsDataProcThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); + //释放mosqpp库 + mosqpp::lib_cleanup(); +} + +/** + * @brief CHcmqttsDataProcThread::beforeExecute + * + */ +int CHcmqttsDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief CHcmqttsDataProcThread::execute + + */ +void CHcmqttsDataProcThread::execute() +{ + //读取网络事件 + if(!g_HcmqttsChanelRun) //收到线程退出标志不再往下执行 + return; + + if (m_timerCount++ >= m_timerCountReset) + m_timerCount = 0;// 1sec is ready + + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + if(m_ptrCurrentChan== NULL) + return; + + //秒级判断流程 + TimerProcess(); + + //mqtt转发流程 + HcmqttsProcess(); +} + +/* + @brief 执行quit函数前的处理 + */ +void CHcmqttsDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetComThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetLinkStatus(CN_FesChanDisconnect); + + LOGDEBUG("CHcmqttsDataProcThread::beforeQuit() "); +} + +/** + * @brief CHcmqttsDataProcThread::InitConfigParam + * Hcmqtts 初始化配置参数 + * @return 成功返回iotSuccess,失败返回iotFailed + */ +int CHcmqttsDataProcThread::InitConfigParam() +{ + if((m_ptrCFesChan == NULL)||(m_ptrCFesRtu==NULL)) + return iotFailed; + + memset(&m_AppData,0,sizeof(SHcmqttsAppData)); + m_AppData.mqttDelayTime = 100; + m_AppData.PasswordFlag = 0; + m_AppData.ClientId = "KhMqttClient"; + m_AppData.KeepAlive = 180; + m_AppData.Retain = 0; + m_AppData.QoS = 0; + m_AppData.WillFlag = 0; + m_AppData.WillQos = 0; + + //SSL加密设置 + m_AppData.sslFlag = 0; + + m_AppData.maxUpdateCount = 18; + m_AppData.updateCount = 0; + m_AppData.startDelay = 30; + m_AppData.ymStartDelay = 350; + m_AppData.CycReadFileTime = 300; + + return iotSuccess; +} + +void CHcmqttsDataProcThread::TimerProcess() +{ + if (m_timerCount == 0)//秒级判断,减少CPU负荷 + { + uint64 curmsec = getMonotonicMsec(); + + //定时更新本FES数据 + if (m_AppData.updateCount < m_AppData.maxUpdateCount) + { + if ((curmsec - m_AppData.lastUpdateTime) > CN_HcmqttsStartUpateTime)//10s + { + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + m_AppData.updateCount++; + m_AppData.lastUpdateTime = curmsec; + } + } + else + { + if ((curmsec - m_AppData.lastUpdateTime) > CN_HcmqttsNormalUpateTime)//60s + { + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + m_AppData.lastUpdateTime = curmsec; + } + } + //定时读取遥控命令响应缓冲区,及时清除队列释放空间,不对遥控成败作处理 + if (m_ptrCFesRtu->GetFwDoRespCmdNum() > 0) + { + SFesFwDoRespCmd retCmd; + m_ptrCFesRtu->ReadFwDoRespCmd(1, &retCmd); + } + + if (m_ptrCFesRtu->GetFwAoRespCmdNum() > 0) + { + SFesFwAoRespCmd retCmd; + m_ptrCFesRtu->ReadFwAoRespCmd(1, &retCmd); + } + + //启动主线程判断逻辑 + MainThread(); + } +} + +void CHcmqttsDataProcThread::HcmqttsProcess() +{ + //延迟启动MQTT上抛流程 + if (!mqttTime.mqttStartFlag) + return; + + //延时时间未到,不发送数据 + if ((getMonotonicMsec() - publishTime) < (m_AppData.mqttDelayTime/10)) + return; + + //上传SOE + if (m_AppData.AlarmTopic.length() > 0) + SendSoeDataFrame(); + + int i = 0; + for (i = mqttTime.topicIndex; i < m_AppData.sendTopicNum; i++) + { + if (m_AppData.sendTopicStr[i].TopicSendFlag) + { + SendTopicData(i); + m_AppData.sendTopicStr[i].TopicSendFlag = false; + break; + } + } + + //处理MQTT网络事件 + mqttClient->loop(); + + mqttTime.topicIndex = i; + if (mqttTime.topicIndex >= m_AppData.sendTopicNum) + {//一轮topic发送结束 + mqttTime.topicIndex = 0; + mqttTime.mqttSendEndFlag = true; + } + +// char slog[256]; +// memset(slog, 0, 256); +// sprintf_s(slog, "**topicIndex=%d mqttSendEndFlag=%d mqttContFlag=%d!", mqttTime.topicIndex, mqttTime.mqttSendEndFlag, m_AppData.mqttContFlag); + //ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); +} + +//通过遥信远动号找告警点 +int CHcmqttsDataProcThread::GetAlarmNo(const int RemoteNo) +{ + for (int i = 0; i < m_AppData.alarmList.size(); i++) + { + if (m_AppData.alarmList[i].yxNo == RemoteNo) + return i; + } + return -1; +} + +//上传SOE +void CHcmqttsDataProcThread::SendSoeDataFrame() +{ + int i, DiValue; + LOCALTIME SysLocalTime; + SFesFwSoeEvent *pSoeEvent = NULL; + int count, retNum; + std::string jsonStr; + std::string DPTagName; + std::string pName; + std::string devId; + + count = m_ptrCFesRtu->GetFwSOEEventNum(); + if (count == 0) + return; + + //最多一次传100条事件 + if (count > 100) + count = 100; + + if (m_pSoeData == NULL) + m_pSoeData = (SFesFwSoeEvent*)malloc(count * sizeof(SFesFwSoeEvent)); + else + m_pSoeData = (SFesFwSoeEvent*)realloc(m_pSoeData, count * sizeof(SFesFwSoeEvent)); + + retNum = m_ptrCFesRtu->ReadFwSOEEvent(count, m_pSoeData); + jsonStr = "{\"DATATYPE\":\"ALARM_INFO\","; + if(m_AppData.AlarmProjectType.length() > 0) + jsonStr += "\"PROJECTTYPE\":\"" + m_AppData.AlarmProjectType + "\","; + jsonStr += "\"DATA\":["; + count = 0; + char vstr[50]; + int alarmNo = -1; + for (i = 0; i < retNum; i++) + { + pSoeEvent = m_pSoeData + i; + //LOGDEBUG("HcmqttsDataProcThread.cpp ChanNo:%d SendSoeDataFrame RemoteNo=%d m_MaxFwDiPoints=%d!", m_ptrCFesChan->m_Param.ChanNo, pSoeEvent->RemoteNo, m_ptrCFesRtu->m_MaxFwDiPoints); + if (pSoeEvent->RemoteNo > m_ptrCFesRtu->m_MaxFwDiPoints) + continue; + + //取出告警列表索引 + alarmNo = GetAlarmNo(pSoeEvent->RemoteNo); + if(alarmNo == -1) + continue; + + DiValue = pSoeEvent->Value & 0x01; + SysLocalTime = convertUTCMsecToLocalTime(pSoeEvent->time); //把Soe时间戳转成本地时标 + + //第一个对象前不需要逗号 + if (count != 0) + jsonStr += ","; + jsonStr += "{\"deviceId\":" + to_string(m_AppData.alarmList[alarmNo].devId) + ",\"alarmId\":" + to_string(m_AppData.alarmList[alarmNo].alarmId) + ","; + //加上时标 + memset(vstr, 0, 50); + sprintf_s(vstr, "\"generationDataTime\":\"%04d-%02d-%02d %02d:%02d:%02d\",", SysLocalTime.wYear, SysLocalTime.wMonth, + SysLocalTime.wDay, SysLocalTime.wHour, SysLocalTime.wMinute, SysLocalTime.wSecond); + jsonStr += vstr; + jsonStr += "\"message\":\"" + m_AppData.alarmList[alarmNo].alarmCode + "\","; + if(DiValue) + jsonStr += "\"status\":true}"; + else + jsonStr += "\"status\":false}"; + count++; + } + jsonStr += "]}"; + if (count > 0) + { + //LOGDEBUG("HcmqttsDataProcThread.cpp ChanNo:%d SendSoeDataFrame AlarmTopic=%s !", m_ptrCFesChan->m_Param.ChanNo, m_AppData.AlarmTopic.data()); + + //将上抛信息传给通道报文显示 + char slog[256]; + memset(slog, 0, 256); + sprintf_s(slog, "MQTT Publish:%s, AlarmNum:%d", m_AppData.AlarmTopic.data(), count); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + //上抛数据 + if (MqttPublish(m_AppData.AlarmTopic, jsonStr) == false) + MqttPublish(m_AppData.AlarmTopic, jsonStr);//上抛失败,重新上抛一次 + SleepmSec(m_AppData.mqttDelayTime); + } +} + +void CHcmqttsDataProcThread::MqttConnect() +{ + int ret = 0; + char slog[256]; + memset(slog, 0, 256); + //已结连接上则不需重连 + if (m_AppData.mqttContFlag) + return; + + //不判断服务器地址 + mqttClient->tls_insecure_set(1); + + //设置SSL加密 + if (m_AppData.sslFlag == 2) //双向加密 + { + //2022-9-21 lj tls_opt_set需要设置为0,即不验证服务器证书,山东海辰服务器的证书有问题,认证不过 + mqttClient->tls_opts_set(0, m_AppData.tls_version.data(), NULL); + if (m_AppData.keyPassword.length() < 1) + mqttClient->tls_set(m_AppData.caFile.data(), m_AppData.caPath.data(), m_AppData.certFile.data(), m_AppData.keyFile.data()); + else + { + //更新私钥的密码 + g_KeyPassword = m_AppData.keyPassword; + mqttClient->tls_set(m_AppData.caFile.data(), m_AppData.caPath.data(), m_AppData.certFile.data(), m_AppData.keyFile.data(), password_callback); + } + LOGDEBUG("HcmqttsDataProcThread.cpp ChanNo:%d MqttConnect caFile=%s keyPassword=%d!", m_ptrCFesChan->m_Param.ChanNo, m_AppData.caFile.data(), m_AppData.keyPassword.length()); + } + else if (m_AppData.sslFlag == 1) //单向加密 + { + //2022-9-21 lj tls_opt_set需要设置为0,即不验证服务器证书,山东海辰服务器的证书有问题,认证不过 + mqttClient->tls_opts_set(0, m_AppData.tls_version.data(), NULL); + mqttClient->tls_set(m_AppData.caFile.data()); + } + + if (m_AppData.QoS) + mqttClient->message_retry_set(3); + + //设置用户名和密码 + if (m_AppData.PasswordFlag) + mqttClient->username_pw_set(m_AppData.UserName.data(), m_AppData.Password.data()); + + //连接Broker服务器 + //m_ptrCFesChan->m_Param.NetRoute[0].NetDesc localhost + char ServerIp[CN_FesMaxNetDescSize]; //通道IP + memset(ServerIp, 0, CN_FesMaxNetDescSize); + strcpy(ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc); + ret = mqttClient->connect(ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo, m_AppData.KeepAlive);//IP + if (ret != MOSQ_ERR_SUCCESS) + { + sprintf_s(slog, "MQTT %s:%d 连接失败!", ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("HcmqttsDataProcThread.cpp ChanNo:%d MQTT %s:%d连接失败!", m_ptrCFesChan->m_Param.ChanNo, ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); + return; + } + else + m_AppData.mqttContFlag = true; + + sprintf_s(slog, "MQTT %s:%d 连接成功!", ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog,CN_SFesSimComFrameTypeSend); + LOGDEBUG("HcmqttsDataProcThread.cpp ChanNo:%d MQTT %s:%d连接成功!", m_ptrCFesChan->m_Param.ChanNo, ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); +} + +bool CHcmqttsDataProcThread::MqttPublish(std::string mqttTopic, std::string mqttPayload) +{ + //连接MQTT服务器 + MqttConnect(); + if (!m_AppData.mqttContFlag) + return false; + + //主题和内容为空 + if ((mqttTopic.length() < 1) || (mqttPayload.length() < 1)) + return true; + + char slog[256]; + memset(slog, 0, 256); + + //发布主题数据 + int rc = mqttClient->publish(NULL, mqttTopic.data(), (int)mqttPayload.length(), mqttPayload.data(), m_AppData.QoS, m_AppData.Retain); + if (rc != MOSQ_ERR_SUCCESS) + { + sprintf_s(slog, "MQTT 上抛 %s 失败,断开连接!", mqttTopic.data()); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("HcmqttsDataProcThread.cpp ChanNo:%d %s:%d %s", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo,slog); + mqttClient->disconnect(); + m_AppData.mqttContFlag = false; + return false; + } + + if (m_AppData.WillFlag > 0) + { + mqttClient->will_set(mqttTopic.data(), (int)mqttPayload.length(), mqttPayload.data(), m_AppData.WillQos, m_AppData.Retain); + } + //记下发送时间 单位毫秒 + publishTime = getMonotonicMsec(); + SleepmSec(m_AppData.mqttDelayTime); + return true; +} + +//获取文件MD5 +std::string CHcmqttsDataProcThread::GetFileMd5(const std::string &file) +{ + ifstream in(file.c_str(), ios::binary); + if (!in) + return ""; + + MD5 md5; + std::streamsize length; + char buffer[1024]; + while (!in.eof()) + { + in.read(buffer, 1024); + length = in.gcount(); + if (length > 0) + md5.update(buffer, length); + } + in.close(); + return md5.toString(); +} + +//获取字符串MD5 +std::string CHcmqttsDataProcThread::GetStringMd5(const std::string &src_str) +{ + if (src_str.size() < 1) + return ""; + + MD5 md5; + int rsaNum = ((int)src_str.size() + 1023) / 1024; + for (int i = 0; i 0) + md5.update(tmps.c_str(), tmps.size()); + } + return md5.toString(); +} + +//清空topic列表 +void CHcmqttsDataProcThread::ClearTopicStr() +{ + for (int i = 0; i < MAX_TOPIC_NUM; i++) + { + m_AppData.sendTopicStr[i].jsonTimeList.clear(); + m_AppData.sendTopicStr[i].jsonValueList.clear(); + if (m_AppData.sendTopicStr[i].rootJson != NULL) + { + cJSON_Delete(m_AppData.sendTopicStr[i].rootJson); + m_AppData.sendTopicStr[i].rootJson = NULL; + } + } + memset(m_AppData.sendTopicStr, 0, sizeof(SEND_TOPIC_STR)*MAX_TOPIC_NUM); +} + +void CHcmqttsDataProcThread::GetAlarmCfg() +{ + char filename[100]; + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_alarm_cfg%d.csv", m_ptrCFesRtu->m_Param.RtuNo); + char line[1024]; + FILE *fpin; + if ((fpin = fopen(filename, "r")) == NULL) + { + LOGDEBUG("hc_mqttclient_s load mqtt_alarm_cfg.csv error"); + return; + } + LOGDEBUG("hc_mqttclient_s load mqtt_alarm_cfg.csv ok"); + + if (fgets(line, 1024, fpin) == NULL) + { + fclose(fpin); + return; + } + + //先清空原来的list + m_AppData.alarmList.clear(); + while (fgets(line, 1024, fpin) != NULL) + { + char *token; + token = strtok(line, ","); + int j = 0; + Alarm_Value_Str alarmValStr; + memset(&alarmValStr,0,sizeof(Alarm_Value_Str)); + while (token != NULL) + { + if (0 == j)//设备ID + { + if (strlen(token) <= 0) + break; + alarmValStr.devId = atoi(token); + } + else if (1 == j)//告警ID + { + if (strlen(token) <= 0) + break; + alarmValStr.alarmId = atoi(token); + } + else if (2 == j)//遥信转发远动号 + { + if (strlen(token) <= 0) + break; + alarmValStr.yxNo = atoi(token); + } + else if (3 == j)//告警描述 + { + if (strlen(token) <= 0) + break; + alarmValStr.alarmCode = GbkToUtf8(token); + m_AppData.alarmList.push_back(alarmValStr); + } + else + break; + token = strtok(NULL, ","); + j++; + } + } + fclose(fpin); +} + +void CHcmqttsDataProcThread::GetTopicCfg( ) +{ + char filename[100]; + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_topic_cfg%d.csv", m_ptrCFesRtu->m_Param.RtuNo); + char line[1024]; + FILE *fpin; + if ((fpin = fopen(filename, "r")) == NULL) + { + LOGDEBUG("hc_mqttclient_s load mqttconfig.csv error"); + return; + } + LOGDEBUG("hc_mqttclient_s load mqttconfig.csv ok"); + + if (fgets(line, 1024, fpin) == NULL) + { + fclose(fpin); + return; + } + + //先清空原来的list + ClearTopicStr(); + m_AppData.sendTopicNum = 0; + int topicNum = 0; + while (fgets(line, 1024, fpin) != NULL) + { + char *token; + token = strtok(line, ","); + int j = 0; + while (token != NULL) + { + if (0 == j)//主题 + { + if (strlen(token) <= 0) + break; + m_AppData.sendTopicStr[topicNum].topic = token; + } + else if (1 == j)//关联JSON文件名 + { + if (strlen(token) <= 0) + break; + m_AppData.sendTopicStr[topicNum].jsonFileName = token; + } + else if (2 == j)//上传周期 + { + if (strlen(token) <= 0) + break; + m_AppData.sendTopicStr[topicNum].sendTime = atoi(token); + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_topic_cfg%s.csv", m_AppData.sendTopicStr[topicNum].jsonFileName.c_str()); + m_AppData.sendTopicStr[topicNum].fileMd5 = GetFileMd5(filename); + topicNum ++; + } + else + break; + token = strtok(NULL, ","); + j++; + } + + //超过上限的不处理 + if (topicNum >= MAX_TOPIC_NUM) + { + topicNum = MAX_TOPIC_NUM; + break; + } + } + fclose(fpin); + m_AppData.sendTopicNum = topicNum; + + //读取Topic关联的JSON文件 + ReadTopic(); +} + +void CHcmqttsDataProcThread::ReadTopic() +{ + std::string jsonStr; + char filename[100]; + for (int i = 0; i < m_AppData.sendTopicNum; i++) + { + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/%s", m_AppData.sendTopicStr[i].jsonFileName.c_str()); + + //计算文件MD5 + m_AppData.sendTopicStr[i].fileMd5 = GetFileMd5(filename); + + //读取JSON文件 + if (ReadJson(filename, jsonStr)) + { + //如果之前有读过JSON文件则释放内存空间 + if (m_AppData.sendTopicStr[i].rootJson != NULL) + { + cJSON_Delete(m_AppData.sendTopicStr[i].rootJson); + m_AppData.sendTopicStr[i].rootJson = NULL; + } + //这里会申请一片新的内存,用完记得释放 + m_AppData.sendTopicStr[i].rootJson = cJSON_Parse(jsonStr.c_str()); + m_AppData.sendTopicStr[i].JsonUpdataFlag = true; + m_AppData.sendTopicStr[i].TopicSendFlag = true; + } + } +} + +bool CHcmqttsDataProcThread::ReadJson(const char *fileName, std::string &outStr) +{ + char slog[256]; + memset(slog, 0, 256); + ifstream ifile(fileName); + if (!ifile.is_open()) + { + sprintf_s(slog, "%s打开失败!请检查文件是否存在!", fileName); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + return false; + } + ostringstream buf; + char ch; + while (buf && ifile.get(ch)) + { + if ((ch != '\n') && (ch != '\t') && (ch != '\0')) + buf.put(ch); + } + outStr = buf.str(); + ifile.close(); + + int strLen = (int)outStr.size(); + if (strLen < 1) + return false; + + return true; +} + +//分割字符串 +int CHcmqttsDataProcThread::StringSplit(std::vector &dst, const std::string &src, const std::string separator) +{ + if (src.empty() || separator.empty()) + return 0; + + int nCount = 0; + std::string temp; + size_t pos = 0, offset = 0; + + //分割第1~n-1个 + while ((pos = src.find_first_of(separator, offset)) != std::string::npos) + { + temp = src.substr(offset, pos - offset); + if (temp.length() > 0) + { + dst.push_back(temp); + nCount++; + } + offset = pos + 1; + } + + //分割第n个 + temp = src.substr(offset, src.length() - offset); + if (temp.length() > 0) + { + dst.push_back(temp); + nCount++; + } + return nCount; +} + +void CHcmqttsDataProcThread::SendTopicData(const int topicNo) +{ + if (m_AppData.sendTopicStr[topicNo].rootJson != NULL) + { + //JSON文件有更新,重新解析JSON文件 + if (m_AppData.sendTopicStr[topicNo].JsonUpdataFlag) + { + m_AppData.sendTopicStr[topicNo].jsonValueList.clear(); + m_AppData.sendTopicStr[topicNo].jsonTimeList.clear(); + AnalyzeJson(m_AppData.sendTopicStr[topicNo].rootJson, m_AppData.sendTopicStr[topicNo].jsonValueList, m_AppData.sendTopicStr[topicNo].jsonTimeList); + m_AppData.sendTopicStr[topicNo].JsonUpdataFlag = false; + } + + //更新JSON中的值 + UpdataJsonValue(topicNo); + //更新JSON中的时间 + UpdataJsonTime(topicNo); + + //发送数据 + SendJsonData(topicNo, m_AppData.sendTopicStr[topicNo].rootJson); + } +} + +//解析JSON +void CHcmqttsDataProcThread::AnalyzeJson(cJSON *root, Json_Value_List &jsonValList, Json_Time_List &jsonTimeList) +{ + int i; + for (i = 0; itype == cJSON_Object) //对象 + { + if (cJSON_IsNull(item)) + continue; + AnalyzeJson(item, jsonValList, jsonTimeList); + } + else if (item->type == cJSON_Array) //数组 + { + if (cJSON_IsNull(item)) + continue; + AnalyzeJson(item, jsonValList, jsonTimeList); + } + else + { + if (cJSON_IsNull(item)) + continue; + + if (item->type != cJSON_String) + continue; + + if (strstr(item->valuestring, "Value")) + { + //取出点地址配置 + std::string paddr = item->valuestring; + std::vector paddrList; + int pNum = StringSplit(paddrList, paddr, ","); + //点地址格式"Data,数据类型,点类型,点号" + if (pNum == 4) + { + Json_Value_Str jsonValStr; + jsonValStr.item = item; + jsonValStr.DataType = paddrList[1].data(); + jsonValStr.pType = atoi(paddrList[2].data()); + jsonValStr.pNo = atoi(paddrList[3].data()); + + //类型正确 + if ((jsonValStr.pType > 0) && (jsonValStr.pType < 4)) + jsonValList.push_back(jsonValStr); + else //取值地址配置错误时,该点置空值,避免上传错误的数据 + item->type = cJSON_NULL; + } + else //取值地址配置错误时,该点置空值,避免上传错误的数据 + item->type = cJSON_NULL; + } + else if (strstr(item->valuestring, "Time")) + { + Json_Time_Str jsonTime; + jsonTime.item = item; + jsonTimeList.push_back(jsonTime); + } + } + } +} + +bool CHcmqttsDataProcThread::UpdataJsonValue(const int topicNo) +{ + if (m_AppData.sendTopicStr[topicNo].jsonValueList.size() < 1) + return false; + + double fvalue; + int pNo, pType; + std::string DataType; + char vstr[50]; + BYTE yxbit; + cJSON* item = NULL; //节点指针 + SFesFwAi *pFwAi; + SFesFwAcc *pFwAcc; + SFesFwDi *pFwDi; + for (int i = 0; i < m_AppData.sendTopicStr[topicNo].jsonValueList.size(); i++) + { + Json_Value_Str jsonValStr = m_AppData.sendTopicStr[topicNo].jsonValueList[i]; + pType = jsonValStr.pType; + pNo = jsonValStr.pNo; + item = jsonValStr.item; + DataType = jsonValStr.DataType; + if (cJSON_IsNull(item)) + continue; + switch (pType) + { + case 1://遥测 + pFwAi = m_ptrCFesRtu->m_pFwAi + pNo; + fvalue = pFwAi->Value*pFwAi->Coeff + pFwAi->Base; + //去掉多余的小数点位,只保留3位小数 + memset(vstr, 0, 50); + sprintf(vstr, "%.3f", fvalue); + fvalue = atof(vstr); + if (DataType == "string") + { + cJSON_free(item->valuestring); + item->valuestring = strdup(vstr); + } + else + { + item->type = cJSON_Number; + item->valuedouble = fvalue; + item->valueint = (int)fvalue; + } + break; + case 2://遥信 + pFwDi = m_ptrCFesRtu->m_pFwDi + pNo; + yxbit = pFwDi->Value & 0x01; + if (DataType == "string") + { + memset(vstr, 0, 50); + sprintf(vstr, "%d", yxbit); + cJSON_free(item->valuestring); + item->valuestring = strdup(vstr); + } + else if (DataType == "bool") + { + if (yxbit) + item->type = cJSON_True; + else + item->type = cJSON_False; + } + else + { + item->type = cJSON_Number; + item->valuedouble = yxbit; + item->valueint = yxbit; + } + break; + case 3://遥脉 + //遥脉5分钟才采集一次,未采集时遥脉值为0,避免上传0值给平台,需要延时上传 + if (!mqttTime.ymStartFlag) + { + item->type = cJSON_NULL; + break; + } + + pFwAcc = m_ptrCFesRtu->m_pFwAcc + pNo; + fvalue = pFwAcc->Value*pFwAcc->Coeff + pFwAcc->Base; + //去掉多余的小数点位,只保留3位小数 + memset(vstr, 0, 50); + sprintf(vstr, "%.3f", fvalue); + fvalue = atof(vstr); + if (DataType == "string") + { + cJSON_free(item->valuestring); + item->valuestring = strdup(vstr); + } + else + { + item->type = cJSON_Number; + item->valuedouble = fvalue; + item->valueint = (int)fvalue; + } + break; + default: + item->type = cJSON_NULL; + break; + } + } + return true; +} + +bool CHcmqttsDataProcThread::UpdataJsonTime(const int topicNo) +{ + if (m_AppData.sendTopicStr[topicNo].jsonTimeList.size() < 1) + return false; + + cJSON* item = NULL; //节点指针 + SYSTEMTIME st = { 0 }; + GetLocalTime(&st); + char time[40]; + memset(time, 0, 40); + sprintf(time, "%04d-%02d-%02d %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + for (int i = 0; i < m_AppData.sendTopicStr[topicNo].jsonTimeList.size(); i++) + { + Json_Time_Str jsonTimeStr = m_AppData.sendTopicStr[topicNo].jsonTimeList[i]; + item = jsonTimeStr.item; + if (cJSON_IsNull(item)) + continue; + + cJSON_free(item->valuestring); + item->valuestring = strdup(time); + } + return true; +} + +void CHcmqttsDataProcThread::MainThread() +{ + char fileName[100]; + std::string md5Str; + //系统启动后的运行的秒数 + int64 cursec = getMonotonicMsec() / 1000; + + if (m_AppData.startDelay > 0)//2021-05-06 thxiao 增加延时起动 + { + if ((cursec - mqttTime.startTime) < m_AppData.startDelay) + mqttTime.mqttStartFlag = false; + else + mqttTime.mqttStartFlag = true; + } + else + mqttTime.mqttStartFlag = true; + + if (m_AppData.ymStartDelay > 0) + { + if ((cursec - mqttTime.startTime) < m_AppData.ymStartDelay) + mqttTime.ymStartFlag = false; + else + mqttTime.ymStartFlag = true; + } + else + mqttTime.ymStartFlag = true; + + //周期检查文件是否修改 + if ((cursec - mqttTime.CycTime) > m_AppData.CycReadFileTime) + { + mqttTime.CycTime = cursec; + + //配置参数修改后,需要在线更新 + memset(fileName, 0, 100); + sprintf(fileName, "../../data/fes/mqtt_topic_cfg%d.csv", m_ptrCFesRtu->m_Param.RtuNo); + md5Str = GetFileMd5(fileName); + if (md5Str != m_AppData.TopicCfgMd5) + { + m_AppData.TopicCfgMd5 = md5Str; + //读取mqtt_topic_cfg.csv文件,并更新参数 + GetTopicCfg(); + } + } + //检查各个Topic的发送周期是否到了 + for (int i = 0; i < m_AppData.sendTopicNum; i++) + { + if (m_AppData.sendTopicStr[i].sendTime > 0) + { + //上传周期到,置上发送标志 + if (((cursec - m_AppData.sendTopicStr[i].TopicSendTime) >= m_AppData.sendTopicStr[i].sendTime) + && (m_AppData.sendTopicStr[i].rootJson != NULL)) + { + m_AppData.sendTopicStr[i].TopicSendTime = cursec; + m_AppData.sendTopicStr[i].TopicSendFlag = true; + } + } + } + + //一轮上抛完毕,关闭连接 + if (mqttTime.mqttSendEndFlag && m_AppData.mqttContFlag) + { + char slog[256]; + memset(slog, 0, 256); + //mqttClient->disconnect(); + //m_AppData.mqttContFlag = false; + mqttTime.mqttSendEndFlag = false; + sprintf_s(slog, "MQTT 一轮上抛完毕,关闭连接!"); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("HcmqttsDataProcThread.cpp ChanNo:%d %s:%d %s", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo, slog); + } +} + +void CHcmqttsDataProcThread::SendJsonData(const int topicNo,cJSON *rootJson) +{ + std::string jsonStr; + int i, j; + //将JSON打印成字符串,此处会申请内存,使用完毕注意释放 + char* pStr = NULL; + pStr = cJSON_Print(rootJson); + if (pStr == NULL) + return; + + //去掉JSON中的TAB缩进符和换行符 + for (i = j = 0; im_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + //上抛数据 将处理过的JSON字符串发送 + if (MqttPublish(m_AppData.sendTopicStr[topicNo].topic, jsonStr) == false) + MqttPublish(m_AppData.sendTopicStr[topicNo].topic, jsonStr);//上抛失败,重新上抛一次 +} + +//GBK转化为UTF8格式 +std::string CHcmqttsDataProcThread::GbkToUtf8(std::string src_str) +{ + int len = MultiByteToWideChar(CP_ACP, 0, src_str.c_str(), -1, NULL, 0); + wchar_t* wstr = new wchar_t[len + 1]; + memset(wstr, 0, len + 1); + MultiByteToWideChar(CP_ACP, 0, src_str.c_str(), -1, wstr, len); + len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); + char* str = new char[len + 1]; + memset(str, 0, len + 1); + WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL); + string strTemp = str; + if (wstr) delete[] wstr; + if (str) delete[] str; + return strTemp; +} + +// UTF-8转为GBK2312 +std::string CHcmqttsDataProcThread::Utf8ToGbk(std::string src_str) +{ + int len = MultiByteToWideChar(CP_UTF8, 0, src_str.c_str(), -1, NULL, 0); + wchar_t* wszGBK = new wchar_t[len + 1]; + memset(wszGBK, 0, len * 2 + 2); + MultiByteToWideChar(CP_UTF8, 0, src_str.c_str(), -1, wszGBK, len); + len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); + char* szGBK = new char[len + 1]; + memset(szGBK, 0, len + 1); + WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL); + string strTemp(szGBK); + if (wszGBK) delete[] wszGBK; + if (szGBK) delete[] szGBK; + return strTemp; +} + diff --git a/product/src/fes/protocol/hc_mqttclient_s/HcmqttsDataProcThread.h b/product/src/fes/protocol/hc_mqttclient_s/HcmqttsDataProcThread.h new file mode 100644 index 00000000..d7f232e1 --- /dev/null +++ b/product/src/fes/protocol/hc_mqttclient_s/HcmqttsDataProcThread.h @@ -0,0 +1,229 @@ +/* + @file CHcmqttsDataProcThread.h + @brief Hcmqtts 数据处理线程类。 + @author liujian + @date 2022-01-05 +*/ +#pragma once + +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "mosquitto.h" +#include "mosquittopp.h" +#include "cJSON.h" +#include "Md5\Md5.h" +using namespace iot_public; + +//本FES数据跟新间隔 +const int CN_HcmqttsStartUpateTime = 10000;//10s +const int CN_HcmqttsNormalUpateTime = 60000;//60s + +#define MAX_TOPIC_NUM 1000 + +typedef struct +{ + int devId; //设备ID + int alarmId; //告警ID + int yxNo; //遥信转发远动号 + std::string alarmCode; //告警描述 +}Alarm_Value_Str; + +typedef struct +{ + int pNo; //点号 + int pType; //点类型 1-YC 2-YX 3-YM + std::string DataType; //数据类型 + cJSON* item; //节点指针 +}Json_Value_Str; + +typedef struct +{ + cJSON* item; //节点指针 +}Json_Time_Str; + +typedef std::vector Json_Value_List; +typedef std::vector Json_Time_List; +typedef std::vector Alarm_Value_List; + +typedef struct +{ + cJSON *rootJson; //cJson指针,保存解析后的JSON文件内容 + int64 TopicSendTime; //主题发送时间,用于判断是否需要发送 + bool JsonUpdataFlag; //JSON文件更新标志 + bool TopicSendFlag; //发送标志 + + int sendTime; //上传周期,单位秒,0表示启动上传一次,后面变化上传,大于1的值表示间隔多少秒上传 + std::string topic; //topic + std::string jsonFileName; //JSON文件名 + std::string fileMd5; //文件MD5,用于判断文件内容是否改变 + + //值 + Json_Value_List jsonValueList; + //时标 + Json_Time_List jsonTimeList; +}SEND_TOPIC_STR; + +typedef struct{ + int RtuNo; + int mqttDelayTime; //每个主题上抛延时,单位毫秒 + int CycReadFileTime; //周期检查文件的时间,单位秒 + + int PasswordFlag; //是否启用密码 0不启用 1启用 默认0 + std::string ClientId; //客户端ID + std::string UserName; //用户名 + std::string Password; //密码 + + int KeepAlive; //心跳检测时间间隔 + bool Retain; //MQTT服务器是否保持消息 默认0 + int QoS; //服务质量 默认1 + int WillFlag; //遗愿消息标志 默认1 + int WillQos; //遗愿消息服务质量 默认1 + + //SSL加密配置参数 + int sslFlag; //SSL加密标志 0不加密 1单向加密 2双向加密 + std::string tls_version; //加密协议版本 + std::string caPath; //加密文件路径 + std::string caFile; //CA文件名 + std::string certFile; //证书文件名 + std::string keyFile; //私钥文件名 + std::string keyPassword; //私钥密码 + + std::string AlarmProjectType; //告警数据项目类型 + std::string AlarmTopic; //告警数据主题 + + int maxUpdateCount; //系统启动前,本FES数据每10S跟新一次全数据,直到该值到到达最大值,变为60S跟新全数据。 + int startDelay; //系统启动延时,单位秒 + int ymStartDelay; //遥脉启动延时,单位秒 +}SHcmqttsAppConfigParam; + +//Hcmqtts 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct{ + //配置参数 + int RtuNo; + int64 startDelay; + int64 ymStartDelay; //遥脉启动延时,单位秒 + int CycReadFileTime; //周期检查文件的时间,单位秒 + int maxUpdateCount; + int updateCount; //系统启动前,本FES数据没10S跟新一次全数据,直到该值到到达最大值,变为60S跟新全数据。 + + uint64 updateTime; + uint64 lastUpdateTime; + bool mqttContFlag; + + int mqttDelayTime; //每个主题上抛延时,单位毫秒 + int PasswordFlag; //是否启用密码 0不启用 1启用 默认0 + std::string ClientId; //客户端ID + std::string UserName; //用户名 + std::string Password; //密码 + + std::string AlarmProjectType; //告警数据项目类型 + std::string AlarmTopic; //告警数据主题 + + int KeepAlive; //心跳检测时间间隔 + bool Retain; //MQTT服务器是否保持消息 默认0 + int QoS; //品质 默认1 + int WillFlag; //遗愿消息标志 默认1 + int WillQos; //遗愿消息品质 默认1 + + //SSL加密配置参数 + int sslFlag; //SSL加密标志 0不加密 1单向加密 2双向加密 + std::string tls_version; //加密协议版本 + std::string caPath; //文件路径 + std::string caFile; //CA文件名 + std::string certFile; //证书文件名 + std::string keyFile; //私钥文件名 + std::string keyPassword; //私钥密码 + + //mqtt_topic_cfg文件MD5 + std::string TopicCfgMd5; + + //主题列表 + SEND_TOPIC_STR sendTopicStr[MAX_TOPIC_NUM]; + int sendTopicNum; + + //告警列表 + Alarm_Value_List alarmList; +}SHcmqttsAppData; + +typedef struct { + int64 startTime; //系统启动时间 + int64 CycTime; //周期检查文件时间 + int topicIndex; //已上抛主题索引 + bool mqttStartFlag; + bool ymStartFlag; //遥脉启动转发标志 + bool mqttSendEndFlag; //Mqtt发送结束标志 +}MqttPublishTime; + +class CHcmqttsDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + CHcmqttsDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam); + virtual ~CHcmqttsDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + CFesBase* m_ptrCFesBase; + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,Hcmqtts tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SHcmqttsAppData m_AppData; //内部应用数据结构 + SFesFwSoeEvent *m_pSoeData; + + MqttPublishTime mqttTime; //MQTT上抛时间管理 + mosqpp::mosquittopp *mqttClient; //MQTT句柄 +private: + int m_timerCount; + int m_timerCountReset; + + int InitConfigParam(); + + void TimerProcess(); + void HcmqttsProcess(); + + void SendSoeDataFrame(); + int64 publishTime; + + void MqttConnect(); + bool MqttPublish(std::string mqttTopic, std::string mqttPayload); + void GetTopicCfg(); + void ReadTopic(); + //获取MD5 + std::string GetFileMd5(const std::string &file); + std::string GetStringMd5(const std::string &src_str); + + //分割字符串 + int StringSplit(std::vector &dst, const std::string &src, const std::string separator); + + //解析JSON + bool ReadJson(const char *fileName, std::string &outStr); + void AnalyzeJson(cJSON *root, Json_Value_List &jsonValList, Json_Time_List &jsonTimeList); + bool UpdataJsonValue(const int topicNo); + bool UpdataJsonTime(const int topicNo); + + void SendTopicData(const int topicNo); + void SendJsonData(const int topicNo, cJSON *rootJson); + + //主线程 + void MainThread(); + void ClearTopicStr(); + + //获取告警配置 + void GetAlarmCfg(); + int GetAlarmNo(const int RemoteNo); + + std::string GbkToUtf8(std::string src_str); + std::string Utf8ToGbk(std::string src_str); +}; + +typedef boost::shared_ptr CHcmqttsDataProcThreadPtr; + diff --git a/product/src/fes/protocol/hc_mqttclient_s/Md5/Md5.cpp b/product/src/fes/protocol/hc_mqttclient_s/Md5/Md5.cpp new file mode 100644 index 00000000..c6664c5e --- /dev/null +++ b/product/src/fes/protocol/hc_mqttclient_s/Md5/Md5.cpp @@ -0,0 +1,372 @@ +#include "Md5.h" + +//using namespace std; + +/* Constants for MD5Transform routine. */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + + +/* F, G, H and I are basic MD5 functions. +*/ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. +*/ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. +*/ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} + + +const byte MD5::PADDING[64] = { 0x80 }; +const char MD5::HEX[16] = +{ + '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f' +}; + +/* Default construct. */ +MD5::MD5() +{ + + reset(); +} + +/* Construct a MD5 object with a input buffer. */ +MD5::MD5(const void *input, size_t length) +{ + reset(); + update(input, length); +} + +/* Construct a MD5 object with a string. */ +MD5::MD5(const string &str) +{ + reset(); + update(str); +} + +/* Construct a MD5 object with a file. */ +MD5::MD5(ifstream &in) +{ + reset(); + update(in); +} + +/* Return the message-digest */ +const byte *MD5::digest() +{ + if (!_finished) + { + _finished = true; + final(); + } + return _digest; +} + +/* Reset the calculate state */ +void MD5::reset() +{ + + _finished = false; + /* reset number of bits. */ + _count[0] = _count[1] = 0; + /* Load magic initialization constants. */ + _state[0] = 0x67452301; + _state[1] = 0xefcdab89; + _state[2] = 0x98badcfe; + _state[3] = 0x10325476; +} + +/* Updating the context with a input buffer. */ +void MD5::update(const void *input, size_t length) +{ + update((const byte *)input, length); +} + +/* Updating the context with a string. */ +void MD5::update(const string &str) +{ + update((const byte *)str.c_str(), str.length()); +} + +/* Updating the context with a file. */ +void MD5::update(ifstream &in) +{ + + if (!in) + { + return; + } + + const size_t BUFFER_SIZE = 1024; + std::streamsize length; + char buffer[BUFFER_SIZE]; + while (!in.eof()) + { + in.read(buffer, BUFFER_SIZE); + length = in.gcount(); + if (length > 0) + { + update(buffer, length); + } + } + in.close(); +} + +/* MD5 block update operation. Continues an MD5 message-digest +operation, processing another message block, and updating the +context. +*/ +void MD5::update(const byte *input, size_t length) +{ + + uint32 i, index, partLen; + + _finished = false; + + /* Compute number of bytes mod 64 */ + index = (uint32)((_count[0] >> 3) & 0x3f); + + /* update number of bits */ + if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) + { + _count[1]++; + } + _count[1] += ((uint32)length >> 29); + + partLen = 64 - index; + + /* transform as many times as possible. */ + if (length >= partLen) + { + + memcpy(&_buffer[index], input, partLen); + transform(_buffer); + + for (i = partLen; i + 63 < length; i += 64) + { + transform(&input[i]); + } + index = 0; + + } + else + { + i = 0; + } + + /* Buffer remaining input */ + memcpy(&_buffer[index], &input[i], length - i); +} + +/* MD5 finalization. Ends an MD5 message-_digest operation, writing the +the message _digest and zeroizing the context. +*/ +void MD5::final() +{ + + byte bits[8]; + uint32 oldState[4]; + uint32 oldCount[2]; + uint32 index, padLen; + + /* Save current state and count. */ + memcpy(oldState, _state, 16); + memcpy(oldCount, _count, 8); + + /* Save number of bits */ + encode(_count, bits, 8); + + /* Pad out to 56 mod 64. */ + index = (uint32)((_count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + update(PADDING, padLen); + + /* Append length (before padding) */ + update(bits, 8); + + /* Store state in digest */ + encode(_state, _digest, 16); + + /* Restore current state and count. */ + memcpy(_state, oldState, 16); + memcpy(_count, oldCount, 8); +} + +/* MD5 basic transformation. Transforms _state based on block. */ +void MD5::transform(const byte block[64]) +{ + + uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16]; + + decode(block, x, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + _state[0] += a; + _state[1] += b; + _state[2] += c; + _state[3] += d; +} + +/* Encodes input (ulong) into output (byte). Assumes length is +a multiple of 4. +*/ +void MD5::encode(const uint32 *input, byte *output, size_t length) +{ + + for (size_t i = 0, j = 0; j < length; i++, j += 4) + { + output[j] = (byte)(input[i] & 0xff); + output[j + 1] = (byte)((input[i] >> 8) & 0xff); + output[j + 2] = (byte)((input[i] >> 16) & 0xff); + output[j + 3] = (byte)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (byte) into output (ulong). Assumes length is +a multiple of 4. +*/ +void MD5::decode(const byte *input, uint32 *output, size_t length) +{ + + for (size_t i = 0, j = 0; j < length; i++, j += 4) + { + output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) | + (((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24); + } +} + +/* Convert byte array to hex string. */ +string MD5::bytesToHexString(const byte *input, size_t length) +{ + string str; + str.reserve(length << 1); + for (size_t i = 0; i < length; i++) + { + int t = input[i]; + int a = t / 16; + int b = t % 16; + str.append(1, HEX[a]); + str.append(1, HEX[b]); + } + return str; +} + +/* Convert digest to string value */ +string MD5::toString() +{ + return bytesToHexString(digest(), 16); +} diff --git a/product/src/fes/protocol/hc_mqttclient_s/Md5/Md5.h b/product/src/fes/protocol/hc_mqttclient_s/Md5/Md5.h new file mode 100644 index 00000000..826a9cf1 --- /dev/null +++ b/product/src/fes/protocol/hc_mqttclient_s/Md5/Md5.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include + +/* Type define */ +typedef unsigned char byte; +typedef unsigned int uint32; + +using std::string; +using std::ifstream; + +/* MD5 declaration. */ +class MD5 +{ +public: + MD5(); + MD5(const void *input, size_t length); + MD5(const string &str); + MD5(ifstream &in); + void update(const void *input, size_t length); + void update(const string &str); + void update(ifstream &in); + const byte *digest(); + string toString(); + void reset(); +private: + void update(const byte *input, size_t length); + void final(); + void transform(const byte block[64]); + void encode(const uint32 *input, byte *output, size_t length); + void decode(const byte *input, uint32 *output, size_t length); + string bytesToHexString(const byte *input, size_t length); + + /* class uncopyable */ + MD5(const MD5 &); + MD5 &operator=(const MD5 &); +private: + uint32 _state[4]; /* state (ABCD) */ + uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */ + byte _buffer[64]; /* input buffer */ + byte _digest[16]; /* message digest */ + bool _finished; /* calculate finished ? */ + + static const byte PADDING[64]; /* padding for calculate */ + static const char HEX[16]; + static const size_t BUFFER_SIZE; + +}; diff --git a/product/src/fes/protocol/hc_mqttclient_s/cJSON.c b/product/src/fes/protocol/hc_mqttclient_s/cJSON.c new file mode 100644 index 00000000..ffe6d313 --- /dev/null +++ b/product/src/fes/protocol/hc_mqttclient_s/cJSON.c @@ -0,0 +1,3100 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +/* disable warnings about old C89 functions in MSVC */ +#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +#define _CRT_SECURE_NO_DEPRECATE +#endif + +#ifdef __GNUC__ +#pragma GCC visibility push(default) +#endif +#if defined(_MSC_VER) +#pragma warning (push) +/* disable warning about single line comments in system headers */ +#pragma warning (disable : 4001) +#endif +#include +#include +#include +#include +#include +#include +#include + +#ifdef ENABLE_LOCALES +#include +#endif + +#if defined(_MSC_VER) +#pragma warning (pop) +#endif +#ifdef __GNUC__ +#pragma GCC visibility pop +#endif + +#include "cJSON.h" + +/* define our own boolean type */ +#ifdef true +#undef true +#endif +#define true ((cJSON_bool)1) + +#ifdef false +#undef false +#endif +#define false ((cJSON_bool)0) + +/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */ +#ifndef isinf +#define isinf(d) (isnan((d - d)) && !isnan(d)) +#endif +#ifndef isnan +#define isnan(d) (d != d) +#endif + +#ifndef _HUGE_ENUF + #define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow +#endif + +#define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) +#ifndef NAN +#define NAN ((float)(INFINITY * 0.0F))//sqrt(-1.0f)//0.0/0.0 +#endif + +typedef struct { + const unsigned char *json; + size_t position; +} error; +static error global_error = { NULL, 0 }; + +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) +{ + return (const char*) (global_error.json + global_error.position); +} + +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) +{ + if (!cJSON_IsString(item)) + { + return NULL; + } + + return item->valuestring; +} + +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) +{ + if (!cJSON_IsNumber(item)) + { + return (double) NAN; + } + + return item->valuedouble; +} + +/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ +#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 13) + #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. +#endif + +CJSON_PUBLIC(const char*) cJSON_Version(void) +{ + static char version[15]; + sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); + + return version; +} + +/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ +static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2) +{ + if ((string1 == NULL) || (string2 == NULL)) + { + return 1; + } + + if (string1 == string2) + { + return 0; + } + + for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) + { + if (*string1 == '\0') + { + return 0; + } + } + + return tolower(*string1) - tolower(*string2); +} + +typedef struct internal_hooks +{ + void *(CJSON_CDECL *allocate)(size_t size); + void (CJSON_CDECL *deallocate)(void *pointer); + void *(CJSON_CDECL *reallocate)(void *pointer, size_t size); +} internal_hooks; + +#if defined(_MSC_VER) +/* work around MSVC error C2322: '...' address of dllimport '...' is not static */ +static void * CJSON_CDECL internal_malloc(size_t size) +{ + return malloc(size); +} +static void CJSON_CDECL internal_free(void *pointer) +{ + free(pointer); +} +static void * CJSON_CDECL internal_realloc(void *pointer, size_t size) +{ + return realloc(pointer, size); +} +#else +#define internal_malloc malloc +#define internal_free free +#define internal_realloc realloc +#endif + +/* strlen of character literals resolved at compile time */ +#define static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) + +static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; + +static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks) +{ + size_t length = 0; + unsigned char *copy = NULL; + + if (string == NULL) + { + return NULL; + } + + length = strlen((const char*)string) + sizeof(""); + copy = (unsigned char*)hooks->allocate(length); + if (copy == NULL) + { + return NULL; + } + memcpy(copy, string, length); + + return copy; +} + +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (hooks == NULL) + { + /* Reset hooks */ + global_hooks.allocate = malloc; + global_hooks.deallocate = free; + global_hooks.reallocate = realloc; + return; + } + + global_hooks.allocate = malloc; + if (hooks->malloc_fn != NULL) + { + global_hooks.allocate = hooks->malloc_fn; + } + + global_hooks.deallocate = free; + if (hooks->free_fn != NULL) + { + global_hooks.deallocate = hooks->free_fn; + } + + /* use realloc only if both free and malloc are used */ + global_hooks.reallocate = NULL; + if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free)) + { + global_hooks.reallocate = realloc; + } +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(const internal_hooks * const hooks) +{ + cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON)); + if (node) + { + memset(node, '\0', sizeof(cJSON)); + } + + return node; +} + +/* Delete a cJSON structure. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) +{ + cJSON *next = NULL; + while (item != NULL) + { + next = item->next; + if (!(item->type & cJSON_IsReference) && (item->child != NULL)) + { + cJSON_Delete(item->child); + } + if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) + { + global_hooks.deallocate(item->valuestring); + } + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + global_hooks.deallocate(item->string); + } + global_hooks.deallocate(item); + item = next; + } +} + +/* get the decimal point character of the current locale */ +static unsigned char get_decimal_point(void) +{ +#ifdef ENABLE_LOCALES + struct lconv *lconv = localeconv(); + return (unsigned char) lconv->decimal_point[0]; +#else + return '.'; +#endif +} + +typedef struct +{ + const unsigned char *content; + size_t length; + size_t offset; + size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ + internal_hooks hooks; +} parse_buffer; + +/* check if the given size is left to read in a given parse buffer (starting with 1) */ +#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) +/* check if the buffer can be accessed at the given index (starting with 0) */ +#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) +#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) +/* get a pointer to the buffer at the position */ +#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) + +/* Parse the input text to generate a number, and populate the result into item. */ +static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer) +{ + double number = 0; + unsigned char *after_end = NULL; + unsigned char number_c_string[64]; + unsigned char decimal_point = get_decimal_point(); + size_t i = 0; + + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; + } + + /* copy the number into a temporary buffer and replace '.' with the decimal point + * of the current locale (for strtod) + * This also takes care of '\0' not necessarily being available for marking the end of the input */ + for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) + { + switch (buffer_at_offset(input_buffer)[i]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + case 'e': + case 'E': + number_c_string[i] = buffer_at_offset(input_buffer)[i]; + break; + + case '.': + number_c_string[i] = decimal_point; + break; + + default: + goto loop_end; + } + } +loop_end: + number_c_string[i] = '\0'; + + number = strtod((const char*)number_c_string, (char**)&after_end); + if (number_c_string == after_end) + { + return false; /* parse_error */ + } + + item->valuedouble = number; + + /* use saturation in case of overflow */ + if (number >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (number <= (double)INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)number; + } + + item->type = cJSON_Number; + + input_buffer->offset += (size_t)(after_end - number_c_string); + return true; +} + +/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) +{ + if (number >= INT_MAX) + { + object->valueint = INT_MAX; + } + else if (number <= (double)INT_MIN) + { + object->valueint = INT_MIN; + } + else + { + object->valueint = (int)number; + } + + return object->valuedouble = number; +} + +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring) +{ + char *copy = NULL; + /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */ + if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference)) + { + return NULL; + } + if (strlen(valuestring) <= strlen(object->valuestring)) + { + strcpy(object->valuestring, valuestring); + return object->valuestring; + } + copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks); + if (copy == NULL) + { + return NULL; + } + if (object->valuestring != NULL) + { + cJSON_free(object->valuestring); + } + object->valuestring = copy; + + return copy; +} + +typedef struct +{ + unsigned char *buffer; + size_t length; + size_t offset; + size_t depth; /* current nesting depth (for formatted printing) */ + cJSON_bool noalloc; + cJSON_bool format; /* is this print a formatted print */ + internal_hooks hooks; +} printbuffer; + +/* realloc printbuffer if necessary to have at least "needed" bytes more */ +static unsigned char* ensure(printbuffer * const p, size_t needed) +{ + unsigned char *newbuffer = NULL; + size_t newsize = 0; + + if ((p == NULL) || (p->buffer == NULL)) + { + return NULL; + } + + if ((p->length > 0) && (p->offset >= p->length)) + { + /* make sure that offset is valid */ + return NULL; + } + + if (needed > INT_MAX) + { + /* sizes bigger than INT_MAX are currently not supported */ + return NULL; + } + + needed += p->offset + 1; + if (needed <= p->length) + { + return p->buffer + p->offset; + } + + if (p->noalloc) { + return NULL; + } + + /* calculate new buffer size */ + if (needed > (INT_MAX / 2)) + { + /* overflow of int, use INT_MAX if possible */ + if (needed <= INT_MAX) + { + newsize = INT_MAX; + } + else + { + return NULL; + } + } + else + { + newsize = needed * 2; + } + + if (p->hooks.reallocate != NULL) + { + /* reallocate with realloc if available */ + newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize); + if (newbuffer == NULL) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + } + else + { + /* otherwise reallocate manually */ + newbuffer = (unsigned char*)p->hooks.allocate(newsize); + if (!newbuffer) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + if (newbuffer) + { + memcpy(newbuffer, p->buffer, p->offset + 1); + } + p->hooks.deallocate(p->buffer); + } + p->length = newsize; + p->buffer = newbuffer; + + return newbuffer + p->offset; +} + +/* calculate the new length of the string in a printbuffer and update the offset */ +static void update_offset(printbuffer * const buffer) +{ + const unsigned char *buffer_pointer = NULL; + if ((buffer == NULL) || (buffer->buffer == NULL)) + { + return; + } + buffer_pointer = buffer->buffer + buffer->offset; + + buffer->offset += strlen((const char*)buffer_pointer); +} + +/* securely comparison of floating-point variables */ +static cJSON_bool compare_double(double a, double b) +{ + double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b); + return (fabs(a - b) <= maxVal * DBL_EPSILON); +} + +/* Render the number nicely from the given item into a string. */ +static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + double d = item->valuedouble; + int length = 0; + size_t i = 0; + unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */ + unsigned char decimal_point = get_decimal_point(); + double test = 0.0; + + if (output_buffer == NULL) + { + return false; + } + + /* This checks for NaN and Infinity */ + if (isnan(d) || isinf(d)) + { + length = sprintf((char*)number_buffer, "null"); + } + else + { + /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ + length = sprintf((char*)number_buffer, "%1.15g", d); + + /* Check whether the original double can be recovered */ + if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d)) + { + /* If not, print with 17 decimal places of precision */ + length = sprintf((char*)number_buffer, "%1.17g", d); + } + } + + /* sprintf failed or buffer overrun occurred */ + if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) + { + return false; + } + + /* reserve appropriate space in the output */ + output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); + if (output_pointer == NULL) + { + return false; + } + + /* copy the printed number to the output and replace locale + * dependent decimal point with '.' */ + for (i = 0; i < ((size_t)length); i++) + { + if (number_buffer[i] == decimal_point) + { + output_pointer[i] = '.'; + continue; + } + + output_pointer[i] = number_buffer[i]; + } + output_pointer[i] = '\0'; + + output_buffer->offset += (size_t)length; + + return true; +} + +/* parse 4 digit hexadecimal number */ +static unsigned parse_hex4(const unsigned char * const input) +{ + unsigned int h = 0; + size_t i = 0; + + for (i = 0; i < 4; i++) + { + /* parse digit */ + if ((input[i] >= '0') && (input[i] <= '9')) + { + h += (unsigned int) input[i] - '0'; + } + else if ((input[i] >= 'A') && (input[i] <= 'F')) + { + h += (unsigned int) 10 + input[i] - 'A'; + } + else if ((input[i] >= 'a') && (input[i] <= 'f')) + { + h += (unsigned int) 10 + input[i] - 'a'; + } + else /* invalid */ + { + return 0; + } + + if (i < 3) + { + /* shift left to make place for the next nibble */ + h = h << 4; + } + } + + return h; +} + +/* converts a UTF-16 literal to UTF-8 + * A literal can be one or two sequences of the form \uXXXX */ +static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer) +{ + long unsigned int codepoint = 0; + unsigned int first_code = 0; + const unsigned char *first_sequence = input_pointer; + unsigned char utf8_length = 0; + unsigned char utf8_position = 0; + unsigned char sequence_length = 0; + unsigned char first_byte_mark = 0; + + if ((input_end - first_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + /* get the first utf16 sequence */ + first_code = parse_hex4(first_sequence + 2); + + /* check that the code is valid */ + if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) + { + goto fail; + } + + /* UTF16 surrogate pair */ + if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) + { + const unsigned char *second_sequence = first_sequence + 6; + unsigned int second_code = 0; + sequence_length = 12; /* \uXXXX\uXXXX */ + + if ((input_end - second_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) + { + /* missing second half of the surrogate pair */ + goto fail; + } + + /* get the second utf16 sequence */ + second_code = parse_hex4(second_sequence + 2); + /* check that the code is valid */ + if ((second_code < 0xDC00) || (second_code > 0xDFFF)) + { + /* invalid second half of the surrogate pair */ + goto fail; + } + + + /* calculate the unicode codepoint from the surrogate pair */ + codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); + } + else + { + sequence_length = 6; /* \uXXXX */ + codepoint = first_code; + } + + /* encode as UTF-8 + * takes at maximum 4 bytes to encode: + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (codepoint < 0x80) + { + /* normal ascii, encoding 0xxxxxxx */ + utf8_length = 1; + } + else if (codepoint < 0x800) + { + /* two bytes, encoding 110xxxxx 10xxxxxx */ + utf8_length = 2; + first_byte_mark = 0xC0; /* 11000000 */ + } + else if (codepoint < 0x10000) + { + /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ + utf8_length = 3; + first_byte_mark = 0xE0; /* 11100000 */ + } + else if (codepoint <= 0x10FFFF) + { + /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + utf8_length = 4; + first_byte_mark = 0xF0; /* 11110000 */ + } + else + { + /* invalid unicode codepoint */ + goto fail; + } + + /* encode as utf8 */ + for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--) + { + /* 10xxxxxx */ + (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF); + codepoint >>= 6; + } + /* encode first byte */ + if (utf8_length > 1) + { + (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF); + } + else + { + (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F); + } + + *output_pointer += utf8_length; + + return sequence_length; + +fail: + return 0; +} + +/* Parse the input text into an unescaped cinput, and populate item. */ +static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) +{ + const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; + const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; + unsigned char *output_pointer = NULL; + unsigned char *output = NULL; + + /* not a string */ + if (buffer_at_offset(input_buffer)[0] != '\"') + { + goto fail; + } + + { + /* calculate approximate size of the output (overestimate) */ + size_t allocation_length = 0; + size_t skipped_bytes = 0; + while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) + { + /* is escape sequence */ + if (input_end[0] == '\\') + { + if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) + { + /* prevent buffer overflow when last input character is a backslash */ + goto fail; + } + skipped_bytes++; + input_end++; + } + input_end++; + } + if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) + { + goto fail; /* string ended unexpectedly */ + } + + /* This is at most how much we need for the output */ + allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes; + output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); + if (output == NULL) + { + goto fail; /* allocation failure */ + } + } + + output_pointer = output; + /* loop through the string literal */ + while (input_pointer < input_end) + { + if (*input_pointer != '\\') + { + *output_pointer++ = *input_pointer++; + } + /* escape sequence */ + else + { + unsigned char sequence_length = 2; + if ((input_end - input_pointer) < 1) + { + goto fail; + } + + switch (input_pointer[1]) + { + case 'b': + *output_pointer++ = '\b'; + break; + case 'f': + *output_pointer++ = '\f'; + break; + case 'n': + *output_pointer++ = '\n'; + break; + case 'r': + *output_pointer++ = '\r'; + break; + case 't': + *output_pointer++ = '\t'; + break; + case '\"': + case '\\': + case '/': + *output_pointer++ = input_pointer[1]; + break; + + /* UTF-16 literal */ + case 'u': + sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); + if (sequence_length == 0) + { + /* failed to convert UTF16-literal to UTF-8 */ + goto fail; + } + break; + + default: + goto fail; + } + input_pointer += sequence_length; + } + } + + /* zero terminate the output */ + *output_pointer = '\0'; + + item->type = cJSON_String; + item->valuestring = (char*)output; + + input_buffer->offset = (size_t) (input_end - input_buffer->content); + input_buffer->offset++; + + return true; + +fail: + if (output != NULL) + { + input_buffer->hooks.deallocate(output); + } + + if (input_pointer != NULL) + { + input_buffer->offset = (size_t)(input_pointer - input_buffer->content); + } + + return false; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer) +{ + const unsigned char *input_pointer = NULL; + unsigned char *output = NULL; + unsigned char *output_pointer = NULL; + size_t output_length = 0; + /* numbers of additional characters needed for escaping */ + size_t escape_characters = 0; + + if (output_buffer == NULL) + { + return false; + } + + /* empty string */ + if (input == NULL) + { + output = ensure(output_buffer, sizeof("\"\"")); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "\"\""); + + return true; + } + + /* set "flag" to 1 if something needs to be escaped */ + for (input_pointer = input; *input_pointer; input_pointer++) + { + switch (*input_pointer) + { + case '\"': + case '\\': + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + /* one character escape sequence */ + escape_characters++; + break; + default: + if (*input_pointer < 32) + { + /* UTF-16 escape sequence uXXXX */ + escape_characters += 5; + } + break; + } + } + output_length = (size_t)(input_pointer - input) + escape_characters; + + output = ensure(output_buffer, output_length + sizeof("\"\"")); + if (output == NULL) + { + return false; + } + + /* no characters have to be escaped */ + if (escape_characters == 0) + { + output[0] = '\"'; + memcpy(output + 1, input, output_length); + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; + } + + output[0] = '\"'; + output_pointer = output + 1; + /* copy the string */ + for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) + { + if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) + { + /* normal character, copy */ + *output_pointer = *input_pointer; + } + else + { + /* character needs to be escaped */ + *output_pointer++ = '\\'; + switch (*input_pointer) + { + case '\\': + *output_pointer = '\\'; + break; + case '\"': + *output_pointer = '\"'; + break; + case '\b': + *output_pointer = 'b'; + break; + case '\f': + *output_pointer = 'f'; + break; + case '\n': + *output_pointer = 'n'; + break; + case '\r': + *output_pointer = 'r'; + break; + case '\t': + *output_pointer = 't'; + break; + default: + /* escape and print as unicode codepoint */ + sprintf((char*)output_pointer, "u%04x", *input_pointer); + output_pointer += 4; + break; + } + } + } + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; +} + +/* Invoke print_string_ptr (which is useful) on an item. */ +static cJSON_bool print_string(const cJSON * const item, printbuffer * const p) +{ + return print_string_ptr((unsigned char*)item->valuestring, p); +} + +/* Predeclare these prototypes. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer); + +/* Utility to jump whitespace and cr/lf */ +static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL)) + { + return NULL; + } + + if (cannot_access_at_index(buffer, 0)) + { + return buffer; + } + + while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) + { + buffer->offset++; + } + + if (buffer->offset == buffer->length) + { + buffer->offset--; + } + + return buffer; +} + +/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ +static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) + { + return NULL; + } + + if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) + { + buffer->offset += 3; + } + + return buffer; +} + +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + size_t buffer_length; + + if (NULL == value) + { + return NULL; + } + + /* Adding null character size due to require_null_terminated. */ + buffer_length = strlen(value) + sizeof(""); + + return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated); +} + +/* Parse an object - create a new root, and populate. */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; + cJSON *item = NULL; + + /* reset error position */ + global_error.json = NULL; + global_error.position = 0; + + if (value == NULL || 0 == buffer_length) + { + goto fail; + } + + buffer.content = (const unsigned char*)value; + buffer.length = buffer_length; + buffer.offset = 0; + buffer.hooks = global_hooks; + + item = cJSON_New_Item(&global_hooks); + if (item == NULL) /* memory fail */ + { + goto fail; + } + + if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) + { + /* parse failure. ep is set. */ + goto fail; + } + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) + { + buffer_skip_whitespace(&buffer); + if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0') + { + goto fail; + } + } + if (return_parse_end) + { + *return_parse_end = (const char*)buffer_at_offset(&buffer); + } + + return item; + +fail: + if (item != NULL) + { + cJSON_Delete(item); + } + + if (value != NULL) + { + error local_error; + local_error.json = (const unsigned char*)value; + local_error.position = 0; + + if (buffer.offset < buffer.length) + { + local_error.position = buffer.offset; + } + else if (buffer.length > 0) + { + local_error.position = buffer.length - 1; + } + + if (return_parse_end != NULL) + { + *return_parse_end = (const char*)local_error.json + local_error.position; + } + + global_error = local_error; + } + + return NULL; +} + +/* Default options for cJSON_Parse */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) +{ + return cJSON_ParseWithOpts(value, 0, 0); +} + +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length) +{ + return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0); +} + +#define cjson_min(a, b) (((a) < (b)) ? (a) : (b)) + +static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks) +{ + static const size_t default_buffer_size = 256; + printbuffer buffer[1]; + unsigned char *printed = NULL; + + memset(buffer, 0, sizeof(buffer)); + + /* create buffer */ + buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size); + buffer->length = default_buffer_size; + buffer->format = format; + buffer->hooks = *hooks; + if (buffer->buffer == NULL) + { + goto fail; + } + + /* print the value */ + if (!print_value(item, buffer)) + { + goto fail; + } + update_offset(buffer); + + /* check if reallocate is available */ + if (hooks->reallocate != NULL) + { + printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); + if (printed == NULL) { + goto fail; + } + buffer->buffer = NULL; + } + else /* otherwise copy the JSON over to a new buffer */ + { + printed = (unsigned char*) hooks->allocate(buffer->offset + 1); + if (printed == NULL) + { + goto fail; + } + memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); + printed[buffer->offset] = '\0'; /* just to be sure */ + + /* free the buffer */ + hooks->deallocate(buffer->buffer); + } + + return printed; + +fail: + if (buffer->buffer != NULL) + { + hooks->deallocate(buffer->buffer); + } + + if (printed != NULL) + { + hooks->deallocate(printed); + } + + return NULL; +} + +/* Render a cJSON item/entity/structure to text. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item) +{ + return (char*)print(item, true, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item) +{ + return (char*)print(item, false, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if (prebuffer < 0) + { + return NULL; + } + + p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer); + if (!p.buffer) + { + return NULL; + } + + p.length = (size_t)prebuffer; + p.offset = 0; + p.noalloc = false; + p.format = fmt; + p.hooks = global_hooks; + + if (!print_value(item, &p)) + { + global_hooks.deallocate(p.buffer); + return NULL; + } + + return (char*)p.buffer; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if ((length < 0) || (buffer == NULL)) + { + return false; + } + + p.buffer = (unsigned char*)buffer; + p.length = (size_t)length; + p.offset = 0; + p.noalloc = true; + p.format = format; + p.hooks = global_hooks; + + return print_value(item, &p); +} + +/* Parser core - when encountering text, process appropriately. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer) +{ + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; /* no input */ + } + + /* parse the different types of values */ + /* null */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0)) + { + item->type = cJSON_NULL; + input_buffer->offset += 4; + return true; + } + /* false */ + if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0)) + { + item->type = cJSON_False; + input_buffer->offset += 5; + return true; + } + /* true */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0)) + { + item->type = cJSON_True; + item->valueint = 1; + input_buffer->offset += 4; + return true; + } + /* string */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) + { + return parse_string(item, input_buffer); + } + /* number */ + if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) + { + return parse_number(item, input_buffer); + } + /* array */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) + { + return parse_array(item, input_buffer); + } + /* object */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) + { + return parse_object(item, input_buffer); + } + + return false; +} + +/* Render a value to text. */ +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output = NULL; + + if ((item == NULL) || (output_buffer == NULL)) + { + return false; + } + + switch ((item->type) & 0xFF) + { + case cJSON_NULL: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "null"); + return true; + + case cJSON_False: + output = ensure(output_buffer, 6); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "false"); + return true; + + case cJSON_True: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "true"); + return true; + + case cJSON_Number: + return print_number(item, output_buffer); + + case cJSON_Raw: + { + size_t raw_length = 0; + if (item->valuestring == NULL) + { + return false; + } + + raw_length = strlen(item->valuestring) + sizeof(""); + output = ensure(output_buffer, raw_length); + if (output == NULL) + { + return false; + } + memcpy(output, item->valuestring, raw_length); + return true; + } + + case cJSON_String: + return print_string(item, output_buffer); + + case cJSON_Array: + return print_array(item, output_buffer); + + case cJSON_Object: + return print_object(item, output_buffer); + + default: + return false; + } +} + +/* Build an array from input text. */ +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* head of the linked list */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (buffer_at_offset(input_buffer)[0] != '[') + { + /* not an array */ + goto fail; + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) + { + /* empty array */ + goto success; + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse next value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') + { + goto fail; /* expected end of array */ + } + +success: + input_buffer->depth--; + + if (head != NULL) { + head->prev = current_item; + } + + item->type = cJSON_Array; + item->child = head; + + input_buffer->offset++; + + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an array to text */ +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_element = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output array. */ + /* opening square bracket */ + output_pointer = ensure(output_buffer, 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer = '['; + output_buffer->offset++; + output_buffer->depth++; + + while (current_element != NULL) + { + if (!print_value(current_element, output_buffer)) + { + return false; + } + update_offset(output_buffer); + if (current_element->next) + { + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ','; + if(output_buffer->format) + { + *output_pointer++ = ' '; + } + *output_pointer = '\0'; + output_buffer->offset += length; + } + current_element = current_element->next; + } + + output_pointer = ensure(output_buffer, 2); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ']'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Build an object from the text. */ +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* linked list head */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) + { + goto fail; /* not an object */ + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) + { + goto success; /* empty object */ + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse the name of the child */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_string(current_item, input_buffer)) + { + goto fail; /* failed to parse name */ + } + buffer_skip_whitespace(input_buffer); + + /* swap valuestring and string, because we parsed the name */ + current_item->string = current_item->valuestring; + current_item->valuestring = NULL; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) + { + goto fail; /* invalid object */ + } + + /* parse the value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) + { + goto fail; /* expected end of object */ + } + +success: + input_buffer->depth--; + + if (head != NULL) { + head->prev = current_item; + } + + item->type = cJSON_Object; + item->child = head; + + input_buffer->offset++; + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an object to text. */ +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_item = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output: */ + length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */ + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer++ = '{'; + output_buffer->depth++; + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + output_buffer->offset += length; + + while (current_item) + { + if (output_buffer->format) + { + size_t i; + output_pointer = ensure(output_buffer, output_buffer->depth); + if (output_pointer == NULL) + { + return false; + } + for (i = 0; i < output_buffer->depth; i++) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += output_buffer->depth; + } + + /* print key */ + if (!print_string_ptr((unsigned char*)current_item->string, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ':'; + if (output_buffer->format) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += length; + + /* print value */ + if (!print_value(current_item, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + /* print comma if not last */ + length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0)); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + if (current_item->next) + { + *output_pointer++ = ','; + } + + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + *output_pointer = '\0'; + output_buffer->offset += length; + + current_item = current_item->next; + } + + output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); + if (output_pointer == NULL) + { + return false; + } + if (output_buffer->format) + { + size_t i; + for (i = 0; i < (output_buffer->depth - 1); i++) + { + *output_pointer++ = '\t'; + } + } + *output_pointer++ = '}'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Get Array size/item / object item. */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) +{ + cJSON *child = NULL; + size_t size = 0; + + if (array == NULL) + { + return 0; + } + + child = array->child; + + while(child != NULL) + { + size++; + child = child->next; + } + + /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ + + return (int)size; +} + +static cJSON* get_array_item(const cJSON *array, size_t index) +{ + cJSON *current_child = NULL; + + if (array == NULL) + { + return NULL; + } + + current_child = array->child; + while ((current_child != NULL) && (index > 0)) + { + index--; + current_child = current_child->next; + } + + return current_child; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) +{ + if (index < 0) + { + return NULL; + } + + return get_array_item(array, (size_t)index); +} + +static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) +{ + cJSON *current_element = NULL; + + if ((object == NULL) || (name == NULL)) + { + return NULL; + } + + current_element = object->child; + if (case_sensitive) + { + while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0)) + { + current_element = current_element->next; + } + } + else + { + while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) + { + current_element = current_element->next; + } + } + + if ((current_element == NULL) || (current_element->string == NULL)) { + return NULL; + } + + return current_element; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, false); +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) +{ + return cJSON_GetObjectItem(object, string) ? 1 : 0; +} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev, cJSON *item) +{ + prev->next = item; + item->prev = prev; +} + +/* Utility for handling references. */ +static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks) +{ + cJSON *reference = NULL; + if (item == NULL) + { + return NULL; + } + + reference = cJSON_New_Item(hooks); + if (reference == NULL) + { + return NULL; + } + + memcpy(reference, item, sizeof(cJSON)); + reference->string = NULL; + reference->type |= cJSON_IsReference; + reference->next = reference->prev = NULL; + return reference; +} + +static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) +{ + cJSON *child = NULL; + + if ((item == NULL) || (array == NULL) || (array == item)) + { + return false; + } + + child = array->child; + /* + * To find the last item in array quickly, we use prev in array + */ + if (child == NULL) + { + /* list is empty, start new one */ + array->child = item; + item->prev = item; + item->next = NULL; + } + else + { + /* append to the end */ + if (child->prev) + { + suffix_object(child->prev, item); + array->child->prev = item; + } + else + { + while (child->next) + { + child = child->next; + } + suffix_object(child, item); + array->child->prev = item; + } + } + + return true; +} + +/* Add item to array/object. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + return add_item_to_array(array, item); +} + +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic push +#endif +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif +/* helper function to cast away const */ +static void* cast_away_const(const void* string) +{ + return (void*)string; +} +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic pop +#endif + + +static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) +{ + char *new_key = NULL; + int new_type = cJSON_Invalid; + + if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item)) + { + return false; + } + + if (constant_key) + { + new_key = (char*)cast_away_const(string); + new_type = item->type | cJSON_StringIsConst; + } + else + { + new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks); + if (new_key == NULL) + { + return false; + } + + new_type = item->type & ~cJSON_StringIsConst; + } + + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + hooks->deallocate(item->string); + } + + item->string = new_key; + item->type = new_type; + + return add_item_to_array(object, item); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + return add_item_to_object(object, string, item, &global_hooks, false); +} + +/* Add an item to an object with constant string as key */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) +{ + return add_item_to_object(object, string, item, &global_hooks, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +{ + if (array == NULL) + { + return false; + } + + return add_item_to_array(array, create_reference(item, &global_hooks)); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +{ + if ((object == NULL) || (string == NULL)) + { + return false; + } + + return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) +{ + cJSON *null = cJSON_CreateNull(); + if (add_item_to_object(object, name, null, &global_hooks, false)) + { + return null; + } + + cJSON_Delete(null); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) +{ + cJSON *true_item = cJSON_CreateTrue(); + if (add_item_to_object(object, name, true_item, &global_hooks, false)) + { + return true_item; + } + + cJSON_Delete(true_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) +{ + cJSON *false_item = cJSON_CreateFalse(); + if (add_item_to_object(object, name, false_item, &global_hooks, false)) + { + return false_item; + } + + cJSON_Delete(false_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) +{ + cJSON *bool_item = cJSON_CreateBool(boolean); + if (add_item_to_object(object, name, bool_item, &global_hooks, false)) + { + return bool_item; + } + + cJSON_Delete(bool_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +{ + cJSON *number_item = cJSON_CreateNumber(number); + if (add_item_to_object(object, name, number_item, &global_hooks, false)) + { + return number_item; + } + + cJSON_Delete(number_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) +{ + cJSON *string_item = cJSON_CreateString(string); + if (add_item_to_object(object, name, string_item, &global_hooks, false)) + { + return string_item; + } + + cJSON_Delete(string_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) +{ + cJSON *raw_item = cJSON_CreateRaw(raw); + if (add_item_to_object(object, name, raw_item, &global_hooks, false)) + { + return raw_item; + } + + cJSON_Delete(raw_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) +{ + cJSON *object_item = cJSON_CreateObject(); + if (add_item_to_object(object, name, object_item, &global_hooks, false)) + { + return object_item; + } + + cJSON_Delete(object_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) +{ + cJSON *array = cJSON_CreateArray(); + if (add_item_to_object(object, name, array, &global_hooks, false)) + { + return array; + } + + cJSON_Delete(array); + return NULL; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) +{ + if ((parent == NULL) || (item == NULL)) + { + return NULL; + } + + if (item != parent->child) + { + /* not the first element */ + item->prev->next = item->next; + } + if (item->next != NULL) + { + /* not the last element */ + item->next->prev = item->prev; + } + + if (item == parent->child) + { + /* first element */ + parent->child = item->next; + } + else if (item->next == NULL) + { + /* last element */ + parent->child->prev = item->prev; + } + + /* make sure the detached item doesn't point anywhere anymore */ + item->prev = NULL; + item->next = NULL; + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) +{ + if (which < 0) + { + return NULL; + } + + return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which) +{ + cJSON_Delete(cJSON_DetachItemFromArray(array, which)); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItem(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObject(object, string)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); +} + +/* Replace array/object items with new ones. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +{ + cJSON *after_inserted = NULL; + + if (which < 0) + { + return false; + } + + after_inserted = get_array_item(array, (size_t)which); + if (after_inserted == NULL) + { + return add_item_to_array(array, newitem); + } + + newitem->next = after_inserted; + newitem->prev = after_inserted->prev; + after_inserted->prev = newitem; + if (after_inserted == array->child) + { + array->child = newitem; + } + else + { + newitem->prev->next = newitem; + } + return true; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) +{ + if ((parent == NULL) || (replacement == NULL) || (item == NULL)) + { + return false; + } + + if (replacement == item) + { + return true; + } + + replacement->next = item->next; + replacement->prev = item->prev; + + if (replacement->next != NULL) + { + replacement->next->prev = replacement; + } + if (parent->child == item) + { + if (parent->child->prev == parent->child) + { + replacement->prev = replacement; + } + parent->child = replacement; + } + else + { /* + * To find the last item in array quickly, we use prev in array. + * We can't modify the last item's next pointer where this item was the parent's child + */ + if (replacement->prev != NULL) + { + replacement->prev->next = replacement; + } + if (replacement->next == NULL) + { + parent->child->prev = replacement; + } + } + + item->next = NULL; + item->prev = NULL; + cJSON_Delete(item); + + return true; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + if (which < 0) + { + return false; + } + + return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); +} + +static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) +{ + if ((replacement == NULL) || (string == NULL)) + { + return false; + } + + /* replace the name in the replacement */ + if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) + { + cJSON_free(replacement->string); + } + replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + replacement->type &= ~cJSON_StringIsConst; + + return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +{ + return replace_item_in_object(object, string, newitem, false); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +{ + return replace_item_in_object(object, string, newitem, true); +} + +/* Create basic types: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_NULL; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_True; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = boolean ? cJSON_True : cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Number; + item->valuedouble = num; + + /* use saturation in case of overflow */ + if (num >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (num <= (double)INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)num; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_String; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) + { + item->type = cJSON_String | cJSON_IsReference; + item->valuestring = (char*)cast_away_const(string); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Object | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) { + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Array | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Raw; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type=cJSON_Array; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item) + { + item->type = cJSON_Object; + } + + return item; +} + +/* Create Arrays: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if (!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber((double)numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0;a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (strings == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for (i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateString(strings[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p,n); + } + p = n; + } + + return a; +} + +/* Duplication */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) +{ + cJSON *newitem = NULL; + cJSON *child = NULL; + cJSON *next = NULL; + cJSON *newchild = NULL; + + /* Bail on bad ptr */ + if (!item) + { + goto fail; + } + /* Create new item */ + newitem = cJSON_New_Item(&global_hooks); + if (!newitem) + { + goto fail; + } + /* Copy over all vars */ + newitem->type = item->type & (~cJSON_IsReference); + newitem->valueint = item->valueint; + newitem->valuedouble = item->valuedouble; + if (item->valuestring) + { + newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks); + if (!newitem->valuestring) + { + goto fail; + } + } + if (item->string) + { + newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); + if (!newitem->string) + { + goto fail; + } + } + /* If non-recursive, then we're done! */ + if (!recurse) + { + return newitem; + } + /* Walk the ->next chain for the child. */ + child = item->child; + while (child != NULL) + { + newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) + { + goto fail; + } + if (next != NULL) + { + /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + next->next = newchild; + newchild->prev = next; + next = newchild; + } + else + { + /* Set newitem->child and move to it */ + newitem->child = newchild; + next = newchild; + } + child = child->next; + } + + return newitem; + +fail: + if (newitem != NULL) + { + cJSON_Delete(newitem); + } + + return NULL; +} + +static void skip_oneline_comment(char **input) +{ + *input += static_strlen("//"); + + for (; (*input)[0] != '\0'; ++(*input)) + { + if ((*input)[0] == '\n') { + *input += static_strlen("\n"); + return; + } + } +} + +static void skip_multiline_comment(char **input) +{ + *input += static_strlen("/*"); + + for (; (*input)[0] != '\0'; ++(*input)) + { + if (((*input)[0] == '*') && ((*input)[1] == '/')) + { + *input += static_strlen("*/"); + return; + } + } +} + +static void minify_string(char **input, char **output) { + (*output)[0] = (*input)[0]; + *input += static_strlen("\""); + *output += static_strlen("\""); + + + for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) { + (*output)[0] = (*input)[0]; + + if ((*input)[0] == '\"') { + (*output)[0] = '\"'; + *input += static_strlen("\""); + *output += static_strlen("\""); + return; + } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) { + (*output)[1] = (*input)[1]; + *input += static_strlen("\""); + *output += static_strlen("\""); + } + } +} + +CJSON_PUBLIC(void) cJSON_Minify(char *json) +{ + char *into = json; + + if (json == NULL) + { + return; + } + + while (json[0] != '\0') + { + switch (json[0]) + { + case ' ': + case '\t': + case '\r': + case '\n': + json++; + break; + + case '/': + if (json[1] == '/') + { + skip_oneline_comment(&json); + } + else if (json[1] == '*') + { + skip_multiline_comment(&json); + } else { + json++; + } + break; + + case '\"': + minify_string(&json, (char**)&into); + break; + + default: + into[0] = json[0]; + json++; + into++; + } + } + + /* and null-terminate. */ + *into = '\0'; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Invalid; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_False; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xff) == cJSON_True; +} + + +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & (cJSON_True | cJSON_False)) != 0; +} +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_NULL; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Number; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_String; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Array; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Object; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Raw; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive) +{ + if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a)) + { + return false; + } + + /* check if type is valid */ + switch (a->type & 0xFF) + { + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + case cJSON_Number: + case cJSON_String: + case cJSON_Raw: + case cJSON_Array: + case cJSON_Object: + break; + + default: + return false; + } + + /* identical objects are equal */ + if (a == b) + { + return true; + } + + switch (a->type & 0xFF) + { + /* in these cases and equal type is enough */ + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + return true; + + case cJSON_Number: + if (compare_double(a->valuedouble, b->valuedouble)) + { + return true; + } + return false; + + case cJSON_String: + case cJSON_Raw: + if ((a->valuestring == NULL) || (b->valuestring == NULL)) + { + return false; + } + if (strcmp(a->valuestring, b->valuestring) == 0) + { + return true; + } + + return false; + + case cJSON_Array: + { + cJSON *a_element = a->child; + cJSON *b_element = b->child; + + for (; (a_element != NULL) && (b_element != NULL);) + { + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + + a_element = a_element->next; + b_element = b_element->next; + } + + /* one of the arrays is longer than the other */ + if (a_element != b_element) { + return false; + } + + return true; + } + + case cJSON_Object: + { + cJSON *a_element = NULL; + cJSON *b_element = NULL; + cJSON_ArrayForEach(a_element, a) + { + /* TODO This has O(n^2) runtime, which is horrible! */ + b_element = get_object_item(b, a_element->string, case_sensitive); + if (b_element == NULL) + { + return false; + } + + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + } + + /* doing this twice, once on a and b to prevent true comparison if a subset of b + * TODO: Do this the proper way, this is just a fix for now */ + cJSON_ArrayForEach(b_element, b) + { + a_element = get_object_item(a, b_element->string, case_sensitive); + if (a_element == NULL) + { + return false; + } + + if (!cJSON_Compare(b_element, a_element, case_sensitive)) + { + return false; + } + } + + return true; + } + + default: + return false; + } +} + +CJSON_PUBLIC(void *) cJSON_malloc(size_t size) +{ + return global_hooks.allocate(size); +} + +CJSON_PUBLIC(void) cJSON_free(void *object) +{ + global_hooks.deallocate(object); +} diff --git a/product/src/fes/protocol/hc_mqttclient_s/cJSON.h b/product/src/fes/protocol/hc_mqttclient_s/cJSON.h new file mode 100644 index 00000000..b5ceb290 --- /dev/null +++ b/product/src/fes/protocol/hc_mqttclient_s/cJSON.h @@ -0,0 +1,293 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) +#define __WINDOWS__ +#endif + +#ifdef __WINDOWS__ + +/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options: + +CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols +CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) +CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol + +For *nix builds that support visibility attribute, you can define similar behavior by + +setting default visibility to hidden by adding +-fvisibility=hidden (for gcc) +or +-xldscope=hidden (for sun cc) +to CFLAGS + +then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does + +*/ + +#define CJSON_CDECL __cdecl +#define CJSON_STDCALL __stdcall + +/* export symbols by default, this is necessary for copy pasting the C and header file */ +#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_EXPORT_SYMBOLS +#endif + +#if defined(CJSON_HIDE_SYMBOLS) +#define CJSON_PUBLIC(type) type CJSON_STDCALL +#elif defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL +#elif defined(CJSON_IMPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL +#endif +#else /* !__WINDOWS__ */ +#define CJSON_CDECL +#define CJSON_STDCALL + +#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) +#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type +#else +#define CJSON_PUBLIC(type) type +#endif +#endif + +/* project version */ +#define CJSON_VERSION_MAJOR 1 +#define CJSON_VERSION_MINOR 7 +#define CJSON_VERSION_PATCH 13 + +#include + +/* cJSON Types: */ +#define cJSON_Invalid (0) +#define cJSON_False (1 << 0) +#define cJSON_True (1 << 1) +#define cJSON_NULL (1 << 2) +#define cJSON_Number (1 << 3) +#define cJSON_String (1 << 4) +#define cJSON_Array (1 << 5) +#define cJSON_Object (1 << 6) +#define cJSON_Raw (1 << 7) /* raw json */ + +#define cJSON_IsReference 256 +#define cJSON_StringIsConst 512 + +/* The cJSON structure: */ +typedef struct cJSON +{ + /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *next; + struct cJSON *prev; + /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + struct cJSON *child; + + /* The type of the item, as above. */ + int type; + + /* The item's string, if type==cJSON_String and type == cJSON_Raw */ + char *valuestring; + /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ + int valueint; + /* The item's number, if type==cJSON_Number */ + double valuedouble; + + /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + char *string; +} cJSON; + +typedef struct cJSON_Hooks +{ + /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */ + void *(CJSON_CDECL *malloc_fn)(size_t sz); + void (CJSON_CDECL *free_fn)(void *ptr); +} cJSON_Hooks; + +typedef int cJSON_bool; + +/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. + * This is to prevent stack overflows. */ +#ifndef CJSON_NESTING_LIMIT +#define CJSON_NESTING_LIMIT 1000 +#endif + +/* returns the version of cJSON as a string */ +CJSON_PUBLIC(const char*) cJSON_Version(void); + +/* Supply malloc, realloc and free functions to cJSON */ +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); + +/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length); +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated); + +/* Render a cJSON entity to text for transfer/storage. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. */ +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); +/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); +/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ +/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); +/* Delete a cJSON entity and all subentities. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); + +/* Returns the number of items in an array (or object). */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); +/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); +/* Get item "string" from object. Case insensitive. */ +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); + +/* Check item type and return its value */ +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item); +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item); + +/* These functions check the type of an item */ +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); + +/* These calls create a cJSON item of the appropriate type. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); +/* raw json */ +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); + +/* Create a string where valuestring references a string so + * it will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); +/* Create an object/array that only references it's elements so + * they will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); + +/* These utilities create an Array of count items. + * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); + +/* Append item to the specified array/object. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. + * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before + * writing to `item->string` */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); + +/* Remove/Detach items from Arrays/Objects. */ +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); + +/* Update array items. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will + * need to be released. With recurse!=0, it will duplicate any children connected to the item. + * The item->next and ->prev pointers are always zero on return from Duplicate. */ +/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. + * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); + +/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings. + * The input pointer json cannot point to a read-only address area, such as a string constant, + * but should point to a readable and writable adress area. */ +CJSON_PUBLIC(void) cJSON_Minify(char *json); + +/* Helper functions for creating and adding items to an object at the same time. + * They return the added item or NULL on failure. */ +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) +/* helper for the cJSON_SetNumberValue macro */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); +#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) +/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring); + +/* Macro for iterating over an array or object */ +#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) + +/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ +CJSON_PUBLIC(void *) cJSON_malloc(size_t size); +CJSON_PUBLIC(void) cJSON_free(void *object); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/hc_mqttclient_s/hc_mqttclient_s.pro b/product/src/fes/protocol/hc_mqttclient_s/hc_mqttclient_s.pro new file mode 100644 index 00000000..2a2784a8 --- /dev/null +++ b/product/src/fes/protocol/hc_mqttclient_s/hc_mqttclient_s.pro @@ -0,0 +1,42 @@ +QT -= core gui +CONFIG -= qt + +TARGET = hc_mqttclient_s +TEMPLATE = lib + +SOURCES += \ + Hcmqtts.cpp \ + HcmqttsDataProcThread.cpp \ + HcmqttsDataProcThread.cpp \ + Md5/Md5.cpp \ + cJSON.c \ + +HEADERS += \ + Hcmqtts.h \ + HcmqttsDataProcThread.h \ + mosquitto.h \ + mosquitto_plugin.h \ + mosquittopp.h \ + Md5/Md5.h \ + cJSON.h \ + +INCLUDEPATH += \ + ../../include/ \ + ../../../include/ \ + ../../../3rd/include/ + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase +LIBS += -lmosquitto -lmosquittopp + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/fes/protocol/hc_mqttclient_s/mosquitto.h b/product/src/fes/protocol/hc_mqttclient_s/mosquitto.h new file mode 100644 index 00000000..879184dc --- /dev/null +++ b/product/src/fes/protocol/hc_mqttclient_s/mosquitto.h @@ -0,0 +1,3084 @@ +/* +Copyright (c) 2010-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_H +#define MOSQUITTO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(WIN32) && !defined(WITH_BROKER) && !defined(LIBMOSQUITTO_STATIC) +# ifdef libmosquitto_EXPORTS +# define libmosq_EXPORT __declspec(dllexport) +# else +# define libmosq_EXPORT __declspec(dllimport) +# endif +#else +# define libmosq_EXPORT +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# ifndef __cplusplus +# define bool char +# define true 1 +# define false 0 +# endif +#else +# ifndef __cplusplus +# include +# endif +#endif + +#include +#include + +#define LIBMOSQUITTO_MAJOR 1 +#define LIBMOSQUITTO_MINOR 6 +#define LIBMOSQUITTO_REVISION 10 +/* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ +#define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION) + +/* Log types */ +#define MOSQ_LOG_NONE 0 +#define MOSQ_LOG_INFO (1<<0) +#define MOSQ_LOG_NOTICE (1<<1) +#define MOSQ_LOG_WARNING (1<<2) +#define MOSQ_LOG_ERR (1<<3) +#define MOSQ_LOG_DEBUG (1<<4) +#define MOSQ_LOG_SUBSCRIBE (1<<5) +#define MOSQ_LOG_UNSUBSCRIBE (1<<6) +#define MOSQ_LOG_WEBSOCKETS (1<<7) +#define MOSQ_LOG_INTERNAL 0x80000000U +#define MOSQ_LOG_ALL 0xFFFFFFFFU + +/* Error values */ +enum mosq_err_t { + MOSQ_ERR_AUTH_CONTINUE = -4, + MOSQ_ERR_NO_SUBSCRIBERS = -3, + MOSQ_ERR_SUB_EXISTS = -2, + MOSQ_ERR_CONN_PENDING = -1, + MOSQ_ERR_SUCCESS = 0, + MOSQ_ERR_NOMEM = 1, + MOSQ_ERR_PROTOCOL = 2, + MOSQ_ERR_INVAL = 3, + MOSQ_ERR_NO_CONN = 4, + MOSQ_ERR_CONN_REFUSED = 5, + MOSQ_ERR_NOT_FOUND = 6, + MOSQ_ERR_CONN_LOST = 7, + MOSQ_ERR_TLS = 8, + MOSQ_ERR_PAYLOAD_SIZE = 9, + MOSQ_ERR_NOT_SUPPORTED = 10, + MOSQ_ERR_AUTH = 11, + MOSQ_ERR_ACL_DENIED = 12, + MOSQ_ERR_UNKNOWN = 13, + MOSQ_ERR_ERRNO = 14, + MOSQ_ERR_EAI = 15, + MOSQ_ERR_PROXY = 16, + MOSQ_ERR_PLUGIN_DEFER = 17, + MOSQ_ERR_MALFORMED_UTF8 = 18, + MOSQ_ERR_KEEPALIVE = 19, + MOSQ_ERR_LOOKUP = 20, + MOSQ_ERR_MALFORMED_PACKET = 21, + MOSQ_ERR_DUPLICATE_PROPERTY = 22, + MOSQ_ERR_TLS_HANDSHAKE = 23, + MOSQ_ERR_QOS_NOT_SUPPORTED = 24, + MOSQ_ERR_OVERSIZE_PACKET = 25, + MOSQ_ERR_OCSP = 26, +}; + +/* Option values */ +enum mosq_opt_t { + MOSQ_OPT_PROTOCOL_VERSION = 1, + MOSQ_OPT_SSL_CTX = 2, + MOSQ_OPT_SSL_CTX_WITH_DEFAULTS = 3, + MOSQ_OPT_RECEIVE_MAXIMUM = 4, + MOSQ_OPT_SEND_MAXIMUM = 5, + MOSQ_OPT_TLS_KEYFORM = 6, + MOSQ_OPT_TLS_ENGINE = 7, + MOSQ_OPT_TLS_ENGINE_KPASS_SHA1 = 8, + MOSQ_OPT_TLS_OCSP_REQUIRED = 9, + MOSQ_OPT_TLS_ALPN = 10, +}; + + +/* MQTT specification restricts client ids to a maximum of 23 characters */ +#define MOSQ_MQTT_ID_MAX_LENGTH 23 + +#define MQTT_PROTOCOL_V31 3 +#define MQTT_PROTOCOL_V311 4 +#define MQTT_PROTOCOL_V5 5 + +struct mosquitto_message{ + int mid; + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct mosquitto; +typedef struct mqtt5__property mosquitto_property; + +/* + * Topic: Threads + * libmosquitto provides thread safe operation, with the exception of + * which is not thread safe. + * + * If your application uses threads you must use to + * tell the library this is the case, otherwise it makes some optimisations + * for the single threaded case that may result in unexpected behaviour for + * the multi threaded case. + */ +/*************************************************** + * Important note + * + * The following functions that deal with network operations will return + * MOSQ_ERR_SUCCESS on success, but this does not mean that the operation has + * taken place. An attempt will be made to write the network data, but if the + * socket is not available for writing at that time then the packet will not be + * sent. To ensure the packet is sent, call mosquitto_loop() (which must also + * be called to process incoming network data). + * This is especially important when disconnecting a client that has a will. If + * the broker does not receive the DISCONNECT command, it will assume that the + * client has disconnected unexpectedly and send the will. + * + * mosquitto_connect() + * mosquitto_disconnect() + * mosquitto_subscribe() + * mosquitto_unsubscribe() + * mosquitto_publish() + ***************************************************/ + + +/* ====================================================================== + * + * Section: Library version, init, and cleanup + * + * ====================================================================== */ +/* + * Function: mosquitto_lib_version + * + * Can be used to obtain version information for the mosquitto library. + * This allows the application to compare the library version against the + * version it was compiled against by using the LIBMOSQUITTO_MAJOR, + * LIBMOSQUITTO_MINOR and LIBMOSQUITTO_REVISION defines. + * + * Parameters: + * major - an integer pointer. If not NULL, the major version of the + * library will be returned in this variable. + * minor - an integer pointer. If not NULL, the minor version of the + * library will be returned in this variable. + * revision - an integer pointer. If not NULL, the revision of the library will + * be returned in this variable. + * + * Returns: + * LIBMOSQUITTO_VERSION_NUMBER, which is a unique number based on the major, + * minor and revision values. + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_version(int *major, int *minor, int *revision); + +/* + * Function: mosquitto_lib_init + * + * Must be called before any other mosquitto functions. + * + * This function is *not* thread safe. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_UNKNOWN - on Windows, if sockets couldn't be initialized. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_init(void); + +/* + * Function: mosquitto_lib_cleanup + * + * Call to free resources associated with the library. + * + * Returns: + * MOSQ_ERR_SUCCESS - always + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_cleanup(void); + + +/* ====================================================================== + * + * Section: Client creation, destruction, and reinitialisation + * + * ====================================================================== */ +/* + * Function: mosquitto_new + * + * Create a new mosquitto client instance. + * + * Parameters: + * id - String to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Note that a client will never discard its own outgoing + * messages on disconnect. Calling or + * will cause the messages to be resent. + * Use to reset a client to its + * original state. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * Pointer to a struct mosquitto on success. + * NULL on failure. Interrogate errno to determine the cause for the failure: + * - ENOMEM on out of memory. + * - EINVAL on invalid input parameters. + * + * See Also: + * , , + */ +libmosq_EXPORT struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj); + +/* + * Function: mosquitto_destroy + * + * Use to free memory associated with a mosquitto client instance. + * + * Parameters: + * mosq - a struct mosquitto pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_destroy(struct mosquitto *mosq); + +/* + * Function: mosquitto_reinitialise + * + * This function allows an existing mosquitto client to be reused. Call on a + * mosquitto instance to close any open network connections, free memory + * and reinitialise the client with the new parameters. The end result is the + * same as the output of . + * + * Parameters: + * mosq - a valid mosquitto instance. + * id - string to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *obj); + + +/* ====================================================================== + * + * Section: Will + * + * ====================================================================== */ +/* + * Function: mosquitto_will_set + * + * Configure will information for a mosquitto instance. By default, clients do + * not have a will. This must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + */ +libmosq_EXPORT int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + +/* + * Function: mosquitto_will_set_v5 + * + * Configure will information for a mosquitto instance, with attached + * properties. By default, clients do not have a will. This must be called + * before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * properties - list of MQTT 5 properties. Can be NULL. On success only, the + * property list becomes the property of libmosquitto once this + * function is called and will be freed by the library. The + * property list must be freed by the application on error. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + * MOSQ_ERR_NOT_SUPPORTED - if properties is not NULL and the client is not + * using MQTT v5 + * MOSQ_ERR_PROTOCOL - if a property is invalid for use with wills. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + */ +libmosq_EXPORT int mosquitto_will_set_v5(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties); + +/* + * Function: mosquitto_will_clear + * + * Remove a previously configured will. This must be called before calling + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_will_clear(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Username and password + * + * ====================================================================== */ +/* + * Function: mosquitto_username_pw_set + * + * Configure username and password for a mosquitto instance. By default, no + * username or password will be sent. For v3.1 and v3.1.1 clients, if username + * is NULL, the password argument is ignored. + * + * This is must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * username - the username to send as a string, or NULL to disable + * authentication. + * password - the password to send as a string. Set to NULL when username is + * valid in order to send just a username. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password); + + +/* ====================================================================== + * + * Section: Connecting, reconnecting, disconnecting + * + * ====================================================================== */ +/* + * Function: mosquitto_connect + * + * Connect to an MQTT broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter. Use this function + * if you need to restrict network communication over a particular interface. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_bind_v5 + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter and MQTT v5 + * properties. Use this function if you need to restrict network communication + * over a particular interface. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * properties - the MQTT 5 properties for the connect (not for the Will). + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with CONNECT. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_v5(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, const mosquitto_property *properties); + +/* + * Function: mosquitto_connect_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * This extends the functionality of by adding the + * bind_address parameter. Use this function if you need to restrict network + * communication over a particular interface. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_async(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_srv + * + * Connect to an MQTT broker. + * + * If you set `host` to `example.com`, then this call will attempt to retrieve + * the DNS SRV record for `_secure-mqtt._tcp.example.com` or + * `_mqtt._tcp.example.com` to discover which actual host to connect to. + * + * DNS SRV support is not usually compiled in to libmosquitto, use of this call + * is not recommended. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname to search for an SRV record. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_srv(struct mosquitto *mosq, const char *host, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_reconnect + * + * Reconnect to a broker. + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * call. It must not be called before + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_reconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_reconnect_async + * + * Reconnect to a broker. Non blocking version of . + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * or calls. It must not be + * called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reconnect_async(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect + * + * Disconnect from the broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + */ +libmosq_EXPORT int mosquitto_disconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect_v5 + * + * Disconnect from the broker, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * reason_code - the disconnect reason code. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with DISCONNECT. + */ +libmosq_EXPORT int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Publishing, subscribing, unsubscribing + * + * ====================================================================== */ +/* + * Function: mosquitto_publish + * + * Publish a message on a given topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + + +/* + * Function: mosquitto_publish_v5 + * + * Publish a message on a given topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Requires the mosquitto instance to be connected with MQTT 5. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with PUBLISH. + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_publish_v5( + struct mosquitto *mosq, + int *mid, + const char *topic, + int payloadlen, + const void *payload, + int qos, + bool retain, + const mosquitto_property *properties); + + +/* + * Function: mosquitto_subscribe + * + * Subscribe to a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos); + +/* + * Function: mosquitto_subscribe_v5 + * + * Subscribe to a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Requires the mosquitto instance to be connected with MQTT 5. + * + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * options - options to apply to this subscription, OR'd together. Set to 0 to + * use the default options, otherwise choose from the list: + * MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client + * publishes to a topic to which it is subscribed, the + * broker will not publish the message back to the + * client. + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages + * published for this subscription will keep the + * retain flag as was set by the publishing client. + * The default behaviour without this option set has + * the retain flag indicating whether a message is + * fresh/stale. + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set, + * pre-existing retained messages are sent as soon as + * the subscription is made, even if the subscription + * already exists. This is the default behaviour, so + * it is not necessary to set this option. + * MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing + * retained messages for this subscription will be + * sent when the subscription is made, but only if the + * subscription does not already exist. + * MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set, + * pre-existing retained messages will never be sent + * for this subscription. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with SUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_subscribe_multiple + * + * Subscribe to multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of subscriptions to be made + * sub - array of sub_count pointers, each pointing to a subscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * qos - the requested Quality of Service for each subscription. + * options - options to apply to this subscription, OR'd together. This + * argument is not used for MQTT v3 susbcriptions. Set to 0 to use + * the default options, otherwise choose from the list: + * MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client + * publishes to a topic to which it is subscribed, the + * broker will not publish the message back to the + * client. + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages + * published for this subscription will keep the + * retain flag as was set by the publishing client. + * The default behaviour without this option set has + * the retain flag indicating whether a message is + * fresh/stale. + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set, + * pre-existing retained messages are sent as soon as + * the subscription is made, even if the subscription + * already exists. This is the default behaviour, so + * it is not necessary to set this option. + * MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing + * retained messages for this subscription will be + * sent when the subscription is made, but only if the + * subscription does not already exist. + * MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set, + * pre-existing retained messages will never be sent + * for this subscription. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe + * + * Unsubscribe from a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub); + +/* + * Function: mosquitto_unsubscribe_v5 + * + * Unsubscribe from a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with UNSUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe_multiple + * + * Unsubscribe from multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of unsubscriptions to be made + * sub - array of sub_count pointers, each pointing to an unsubscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Struct mosquitto_message helper functions + * + * ====================================================================== */ +/* + * Function: mosquitto_message_copy + * + * Copy the contents of a mosquitto message to another message. + * Useful for preserving a message received in the on_message() callback. + * + * Parameters: + * dst - a pointer to a valid mosquitto_message struct to copy to. + * src - a pointer to a valid mosquitto_message struct to copy from. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src); + +/* + * Function: mosquitto_message_free + * + * Completely free a mosquitto_message struct. + * + * Parameters: + * message - pointer to a mosquitto_message pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_message_free(struct mosquitto_message **message); + +/* + * Function: mosquitto_message_free_contents + * + * Free a mosquitto_message struct contents, leaving the struct unaffected. + * + * Parameters: + * message - pointer to a mosquitto_message struct to free its contents. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_message_free_contents(struct mosquitto_message *message); + + +/* ====================================================================== + * + * Section: Network loop (managed by libmosquitto) + * + * The internal network loop must be called at a regular interval. The two + * recommended approaches are to use either or + * . is a blocking call and is + * suitable for the situation where you only want to handle incoming messages + * in callbacks. is a non-blocking call, it creates a + * separate thread to run the loop for you. Use this function when you have + * other tasks you need to run at the same time as the MQTT client, e.g. + * reading data from a sensor. + * + * ====================================================================== */ + +/* + * Function: mosquitto_loop_forever + * + * This function call loop() for you in an infinite blocking loop. It is useful + * for the case where you only want to run the MQTT client loop in your + * program. + * + * It handles reconnecting in case server connection is lost. If you call + * mosquitto_disconnect() in a callback it will return. + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets); + +/* + * Function: mosquitto_loop_start + * + * This is part of the threaded client interface. Call this once to start a new + * thread to process network traffic. This provides an alternative to + * repeatedly calling yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_start(struct mosquitto *mosq); + +/* + * Function: mosquitto_loop_stop + * + * This is part of the threaded client interface. Call this once to stop the + * network thread previously created with . This call + * will block until the network thread finishes. For the network thread to end, + * you must have previously called or have set the force + * parameter to true. + * + * Parameters: + * mosq - a valid mosquitto instance. + * force - set to true to force thread cancellation. If false, + * must have already been called. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_stop(struct mosquitto *mosq, bool force); + +/* + * Function: mosquitto_loop + * + * The main network loop for the client. This must be called frequently + * to keep communications between the client and broker working. This is + * carried out by and , which + * are the recommended ways of handling the network loop. You may also use this + * function if you wish. It must not be called inside a callback. + * + * If incoming data is present it will then be processed. Outgoing commands, + * from e.g. , are normally sent immediately that their + * function is called, but this is not always possible. will + * also attempt to send any remaining outgoing messages, which also includes + * commands that are part of the flow for messages with QoS>0. + * + * This calls select() to monitor the client network socket. If you want to + * integrate mosquitto client operation with your own select() call, use + * , , and + * . + * + * Threads: + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets); + +/* ====================================================================== + * + * Section: Network loop (for use in other event loops) + * + * ====================================================================== */ +/* + * Function: mosquitto_loop_read + * + * Carry out network read operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_read(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_write + * + * Carry out network write operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_write(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_misc + * + * Carry out miscellaneous operations required as part of the network loop. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * This function deals with handling PINGs and checking whether messages need + * to be retried, so should be called fairly frequently, around once per second + * is sufficient. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_misc(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Network loop (helper functions) + * + * ====================================================================== */ +/* + * Function: mosquitto_socket + * + * Return the socket handle for a mosquitto instance. Useful if you want to + * include a mosquitto client in your own select() calls. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * The socket for the mosquitto client or -1 on failure. + */ +libmosq_EXPORT int mosquitto_socket(struct mosquitto *mosq); + +/* + * Function: mosquitto_want_write + * + * Returns true if there is data ready to be written on the socket. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * See Also: + * , , + */ +libmosq_EXPORT bool mosquitto_want_write(struct mosquitto *mosq); + +/* + * Function: mosquitto_threaded_set + * + * Used to tell the library that your application is using threads, but not + * using . The library operates slightly differently when + * not in threaded mode in order to simplify its operation. If you are managing + * your own threads and do not use this function you will experience crashes + * due to race conditions. + * + * When using , this is set automatically. + * + * Parameters: + * mosq - a valid mosquitto instance. + * threaded - true if your application is using threads, false otherwise. + */ +libmosq_EXPORT int mosquitto_threaded_set(struct mosquitto *mosq, bool threaded); + + +/* ====================================================================== + * + * Section: Client options + * + * ====================================================================== */ +/* + * Function: mosquitto_opts_set + * + * Used to set options for the client. + * + * This function is deprecated, the replacement and + * functions should be used instead. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_PROTOCOL_VERSION + * Value must be an int, set to either MQTT_PROTOCOL_V31 or + * MQTT_PROTOCOL_V311. Must be set before the client connects. + * Defaults to MQTT_PROTOCOL_V31. + * + * MOSQ_OPT_SSL_CTX + * Pass an openssl SSL_CTX to be used when creating TLS connections + * rather than libmosquitto creating its own. This must be called + * before connecting to have any effect. If you use this option, the + * onus is on you to ensure that you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS + * Value must be an int set to 1 or 0. If set to 1, then the user + * specified SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the + * default options applied to it. This means that you only need to + * change the values that are relevant to you. If you use this + * option then you must configure the TLS options as normal, i.e. + * you should use to configure the cafile/capath + * as a minimum. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + +/* + * Function: mosquitto_int_option + * + * Used to set integer options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_PROTOCOL_VERSION - + * Value must be set to either MQTT_PROTOCOL_V31, + * MQTT_PROTOCOL_V311, or MQTT_PROTOCOL_V5. Must be set before the + * client connects. Defaults to MQTT_PROTOCOL_V311. + * + * MOSQ_OPT_RECEIVE_MAXIMUM - + * Value can be set between 1 and 65535 inclusive, and represents + * the maximum number of incoming QoS 1 and QoS 2 messages that this + * client wants to process at once. Defaults to 20. This option is + * not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the MQTT_PROP_RECEIVE_MAXIMUM property is in the + * proplist passed to mosquitto_connect_v5(), then that property + * will override this option. Using this option is the recommended + * method however. + * + * MOSQ_OPT_SEND_MAXIMUM - + * Value can be set between 1 and 65535 inclusive, and represents + * the maximum number of outgoing QoS 1 and QoS 2 messages that this + * client will attempt to have "in flight" at once. Defaults to 20. + * This option is not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the broker being connected to sends a + * MQTT_PROP_RECEIVE_MAXIMUM property that has a lower value than + * this option, then the broker provided value will be used. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS - + * If value is set to a non zero value, then the user specified + * SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the default + * options applied to it. This means that you only need to change + * the values that are relevant to you. If you use this option then + * you must configure the TLS options as normal, i.e. you should + * use to configure the cafile/capath as a + * minimum. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_TLS_OCSP_REQUIRED - + * Set whether OCSP checking on TLS connections is required. Set to + * 1 to enable checking, or 0 (the default) for no checking. + */ +libmosq_EXPORT int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t option, int value); + + +/* + * Function: mosquitto_void_option + * + * Used to set void* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_SSL_CTX - + * Pass an openssl SSL_CTX to be used when creating TLS connections + * rather than libmosquitto creating its own. This must be called + * before connecting to have any effect. If you use this option, the + * onus is on you to ensure that you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_void_option(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + +/* + * Function: mosquitto_max_inflight_messages_set + * + * This function is deprected. Use the function with the + * MOSQ_OPT_SEND_MAXIMUM option instead. + * + * Set the number of QoS 1 and 2 messages that can be "in flight" at one time. + * An in flight message is part way through its delivery flow. Attempts to send + * further messages with will result in the messages being + * queued until the number of in flight messages reduces. + * + * A higher number here results in greater message throughput, but if set + * higher than the maximum in flight messages on the broker may lead to + * delays in the messages being acknowledged. + * + * Set to 0 for no maximum. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_inflight_messages - the maximum number of inflight messages. Defaults + * to 20. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages); + +/* + * Function: mosquitto_message_retry_set + * + * This function now has no effect. + */ +libmosq_EXPORT void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry); + +/* + * Function: mosquitto_user_data_set + * + * When is called, the pointer given as the "obj" parameter + * will be passed to the callbacks as user data. The + * function allows this obj parameter to be updated at any time. This function + * will not modify the memory pointed to by the current user data pointer. If + * it is dynamically allocated memory you must free it yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * obj - A user pointer that will be passed as an argument to any callbacks + * that are specified. + */ +libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj); + +/* Function: mosquitto_userdata + * + * Retrieve the "userdata" variable for a mosquitto client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * A pointer to the userdata member variable. + */ +libmosq_EXPORT void *mosquitto_userdata(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: TLS support + * + * ====================================================================== */ +/* + * Function: mosquitto_tls_set + * + * Configure the client for certificate based SSL/TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Define the Certificate Authority certificates to be trusted (ie. the server + * certificate must be signed with one of these certificates) using cafile. + * + * If the server you are connecting to requires clients to provide a + * certificate, define certfile and keyfile with your client certificate and + * private key. If your private key is encrypted, provide a password callback + * function or you will have to enter the password at the command line. + * + * Parameters: + * mosq - a valid mosquitto instance. + * cafile - path to a file containing the PEM encoded trusted CA + * certificate files. Either cafile or capath must not be NULL. + * capath - path to a directory containing the PEM encoded trusted CA + * certificate files. See mosquitto.conf for more details on + * configuring this directory. Either cafile or capath must not + * be NULL. + * certfile - path to a file containing the PEM encoded certificate file + * for this client. If NULL, keyfile must also be NULL and no + * client certificate will be used. + * keyfile - path to a file containing the PEM encoded private key for + * this client. If NULL, certfile must also be NULL and no + * client certificate will be used. + * pw_callback - if keyfile is encrypted, set pw_callback to allow your client + * to pass the correct password for decryption. If set to NULL, + * the password must be entered on the command line. + * Your callback must write the password into "buf", which is + * "size" bytes long. The return value must be the length of the + * password. "userdata" will be set to the calling mosquitto + * instance. The mosquitto userdata member variable can be + * retrieved using . + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , , + * , + */ +libmosq_EXPORT int mosquitto_tls_set(struct mosquitto *mosq, + const char *cafile, const char *capath, + const char *certfile, const char *keyfile, + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)); + +/* + * Function: mosquitto_tls_insecure_set + * + * Configure verification of the server hostname in the server certificate. If + * value is set to true, it is impossible to guarantee that the host you are + * connecting to is not impersonating your server. This can be useful in + * initial server testing, but makes it possible for a malicious third party to + * impersonate your server through DNS spoofing, for example. + * Do not use this function in a real system. Setting value to true makes the + * connection encryption pointless. + * Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * value - if set to false, the default, certificate hostname checking is + * performed. If set to true, no hostname checking is performed and + * the connection is insecure. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_insecure_set(struct mosquitto *mosq, bool value); + +/* + * Function: mosquitto_tls_opts_set + * + * Set advanced SSL/TLS options. Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * cert_reqs - an integer defining the verification requirements the client + * will impose on the server. This can be one of: + * * SSL_VERIFY_NONE (0): the server will not be verified in any way. + * * SSL_VERIFY_PEER (1): the server certificate will be verified + * and the connection aborted if the verification fails. + * The default and recommended value is SSL_VERIFY_PEER. Using + * SSL_VERIFY_NONE provides no security. + * tls_version - the version of the SSL/TLS protocol to use as a string. If NULL, + * the default value is used. The default value and the + * available values depend on the version of openssl that the + * library was compiled against. For openssl >= 1.0.1, the + * available options are tlsv1.2, tlsv1.1 and tlsv1, with tlv1.2 + * as the default. For openssl < 1.0.1, only tlsv1 is available. + * ciphers - a string describing the ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tls_version, const char *ciphers); + +/* + * Function: mosquitto_tls_psk_set + * + * Configure the client for pre-shared-key based TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Parameters: + * mosq - a valid mosquitto instance. + * psk - the pre-shared-key in hex format with no leading "0x". + * identity - the identity of this client. May be used as the username + * depending on the server settings. + * ciphers - a string describing the PSK ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers); + + +/* ====================================================================== + * + * Section: Callbacks + * + * ====================================================================== */ +/* + * Function: mosquitto_connect_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_connect_with_flags_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * flags - the connect flags. + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int)); + +/* + * Function: mosquitto_connect_v5_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + * flags - the connect flags. + * props - list of MQTT 5 properties, or NULL + * + */ +libmosq_EXPORT void mosquitto_connect_v5_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int, const mosquitto_property *props)); + +/* + * Function: mosquitto_disconnect_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + */ +libmosq_EXPORT void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_disconnect_v5_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_disconnect_v5_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *)); + +/* + * Function: mosquitto_publish_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker successfully. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + */ +libmosq_EXPORT void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_publish_v5_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker. This callback will be + * called both if the message is sent successfully, or if the broker responded + * with an error, which will be reflected in the reason_code parameter. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + * reason_code - the MQTT 5 reason code + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_publish_v5_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int, int, const mosquitto_property *)); + +/* + * Function: mosquitto_message_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *)); + +/* + * Function: mosquitto_message_v5_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * props - list of MQTT 5 properties, or NULL + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_v5_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *, const mosquitto_property *)); + +/* + * Function: mosquitto_subscribe_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + */ +libmosq_EXPORT void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *)); + +/* + * Function: mosquitto_subscribe_v5_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_subscribe_v5_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *)); + +/* + * Function: mosquitto_unsubscribe_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + */ +libmosq_EXPORT void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_unsubscribe_v5_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, const mosquitto_property *)); + +/* + * Function: mosquitto_log_callback_set + * + * Set the logging callback. This should be used if you want event logging + * information from the client library. + * + * mosq - a valid mosquitto instance. + * on_log - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int level, const char *str) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * level - the log message level from the values: + * MOSQ_LOG_INFO + * MOSQ_LOG_NOTICE + * MOSQ_LOG_WARNING + * MOSQ_LOG_ERR + * MOSQ_LOG_DEBUG + * str - the message string. + */ +libmosq_EXPORT void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *)); + +/* + * Function: mosquitto_string_option + * + * Used to set const char* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_TLS_ENGINE + * Configure the client for TLS Engine support. Pass a TLS Engine ID + * to be used when creating TLS connections. + * Must be set before . + * MOSQ_OPT_TLS_KEYFORM + * Configure the client to treat the keyfile differently depending + * on its type. Must be set before . + * Set as either "pem" or "engine", to determine from where the + * private key for a TLS connection will be obtained. Defaults to + * "pem", a normal private key file. + * MOSQ_OPT_TLS_KPASS_SHA1 + * Where the TLS Engine requires the use of a password to be + * accessed, this option allows a hex encoded SHA1 hash of the + * private key password to be passed to the engine directly. + * Must be set before . + * MOSQ_OPT_TLS_ALPN + * If the broker being connected to has multiple services available + * on a single TLS port, such as both MQTT and WebSockets, use this + * option to configure the ALPN option for the connection. + */ +libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value); + + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + + +/* ============================================================================= + * + * Section: SOCKS5 proxy functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_socks5_set + * + * Configure the client to use a SOCKS5 proxy when connecting. Must be called + * before connecting. "None" and "username/password" authentication is + * supported. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the SOCKS5 proxy host to connect to. + * port - the SOCKS5 proxy port to use. + * username - if not NULL, use this username when authenticating with the proxy. + * password - if not NULL and username is not NULL, use this password when + * authenticating with the proxy. + */ +libmosq_EXPORT int mosquitto_socks5_set(struct mosquitto *mosq, const char *host, int port, const char *username, const char *password); + + +/* ============================================================================= + * + * Section: Utility functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_strerror + * + * Call to obtain a const string description of a mosquitto error number. + * + * Parameters: + * mosq_errno - a mosquitto error number. + * + * Returns: + * A constant string describing the error. + */ +libmosq_EXPORT const char *mosquitto_strerror(int mosq_errno); + +/* + * Function: mosquitto_connack_string + * + * Call to obtain a const string description of an MQTT connection result. + * + * Parameters: + * connack_code - an MQTT connection result. + * + * Returns: + * A constant string describing the result. + */ +libmosq_EXPORT const char *mosquitto_connack_string(int connack_code); + +/* + * Function: mosquitto_reason_string + * + * Call to obtain a const string description of an MQTT reason code. + * + * Parameters: + * reason_code - an MQTT reason code. + * + * Returns: + * A constant string describing the reason. + */ +libmosq_EXPORT const char *mosquitto_reason_string(int reason_code); + +/* Function: mosquitto_string_to_command + * + * Take a string input representing an MQTT command and convert it to the + * libmosquitto integer representation. + * + * Parameters: + * str - the string to parse. + * cmd - pointer to an int, for the result. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - on an invalid input. + * + * Example: + * mosquitto_string_to_command("CONNECT", &cmd); + * // cmd == CMD_CONNECT + */ +libmosq_EXPORT int mosquitto_string_to_command(const char *str, int *cmd); + +/* + * Function: mosquitto_sub_topic_tokenise + * + * Tokenise a topic or subscription string into an array of strings + * representing the topic hierarchy. + * + * For example: + * + * subtopic: "a/deep/topic/hierarchy" + * + * Would result in: + * + * topics[0] = "a" + * topics[1] = "deep" + * topics[2] = "topic" + * topics[3] = "hierarchy" + * + * and: + * + * subtopic: "/a/deep/topic/hierarchy/" + * + * Would result in: + * + * topics[0] = NULL + * topics[1] = "a" + * topics[2] = "deep" + * topics[3] = "topic" + * topics[4] = "hierarchy" + * + * Parameters: + * subtopic - the subscription/topic to tokenise + * topics - a pointer to store the array of strings + * count - an int pointer to store the number of items in the topics array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * + * Example: + * + * > char **topics; + * > int topic_count; + * > int i; + * > + * > mosquitto_sub_topic_tokenise("$SYS/broker/uptime", &topics, &topic_count); + * > + * > for(i=0; i printf("%d: %s\n", i, topics[i]); + * > } + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *count); + +/* + * Function: mosquitto_sub_topic_tokens_free + * + * Free memory that was allocated in . + * + * Parameters: + * topics - pointer to string array. + * count - count of items in string array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokens_free(char ***topics, int count); + +/* + * Function: mosquitto_topic_matches_sub + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * topic - topic to check. + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result); + + +/* + * Function: mosquitto_topic_matches_sub2 + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * sublen - length in bytes of sub string + * topic - topic to check. + * topiclen - length in bytes of topic string + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub2(const char *sub, size_t sublen, const char *topic, size_t topiclen, bool *result); + +/* + * Function: mosquitto_pub_topic_check + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check(const char *topic); + +/* + * Function: mosquitto_pub_topic_check2 + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - length of the topic in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check2(const char *topic, size_t topiclen); + +/* + * Function: mosquitto_sub_topic_check + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check(const char *topic); + +/* + * Function: mosquitto_sub_topic_check2 + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - the length in bytes of the topic + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check2(const char *topic, size_t topiclen); + + +/* + * Function: mosquitto_validate_utf8 + * + * Helper function to validate whether a UTF-8 string is valid, according to + * the UTF-8 spec and the MQTT additions. + * + * Parameters: + * str - a string to check + * len - the length of the string in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if str is NULL or len<0 or len>65536 + * MOSQ_ERR_MALFORMED_UTF8 - if str is not valid UTF-8 + */ +libmosq_EXPORT int mosquitto_validate_utf8(const char *str, int len); + + +/* ============================================================================= + * + * Section: One line client helper functions + * + * ============================================================================= + */ + +struct libmosquitto_will { + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct libmosquitto_auth { + char *username; + char *password; +}; + +struct libmosquitto_tls { + char *cafile; + char *capath; + char *certfile; + char *keyfile; + char *ciphers; + char *tls_version; + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata); + int cert_reqs; +}; + +/* + * Function: mosquitto_subscribe_simple + * + * Helper function to make subscribing to a topic and retrieving some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, waits for msg_count + * messages to be received, then returns after disconnecting cleanly. + * + * Parameters: + * messages - pointer to a "struct mosquitto_message *". The received + * messages will be returned here. On error, this will be set to + * NULL. + * msg_count - the number of messages to retrieve. + * want_retained - if set to true, stale retained messages will be treated as + * normal messages with regards to msg_count. If set to + * false, they will be ignored. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * >0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool want_retained, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* + * Function: mosquitto_subscribe_callback + * + * Helper function to make subscribing to a topic and processing some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, then passes received + * messages to a user provided callback. If the callback returns a 1, it then + * disconnects cleanly and returns. + * + * Parameters: + * callback - a callback function in the following form: + * int callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * Note that this is the same as the normal on_message callback, + * except that it returns an int. + * userdata - user provided pointer that will be passed to the callback. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * >0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* ============================================================================= + * + * Section: Properties + * + * ============================================================================= + */ + + +/* + * Function: mosquitto_property_add_byte + * + * Add a new byte property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_byte(&proplist, MQTT_PROP_PAYLOAD_FORMAT_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value); + +/* + * Function: mosquitto_property_add_int16 + * + * Add a new int16 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_RECEIVE_MAXIMUM) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_int16(&proplist, MQTT_PROP_RECEIVE_MAXIMUM, 1000); + */ +libmosq_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value); + +/* + * Function: mosquitto_property_add_int32 + * + * Add a new int32 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_MESSAGE_EXPIRY_INTERVAL) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_int32(&proplist, MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, 86400); + */ +libmosq_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_varint + * + * Add a new varint property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_SUBSCRIPTION_IDENTIFIER) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_varint(&proplist, MQTT_PROP_SUBSCRIPTION_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_binary + * + * Add a new binary property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to the property data + * len - length of property data in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_binary(&proplist, MQTT_PROP_AUTHENTICATION_DATA, auth_data, auth_data_len); + */ +libmosq_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len); + +/* + * Function: mosquitto_property_add_string + * + * Add a new string property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_CONTENT_TYPE) + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - value is not valid UTF-8. + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_string(&proplist, MQTT_PROP_CONTENT_TYPE, "application/json"); + */ +libmosq_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value); + +/* + * Function: mosquitto_property_add_string_pair + * + * Add a new string pair property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_USER_PROPERTY) + * name - string name for the new property, must be UTF-8 and zero terminated + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if name or value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - if name or value are not valid UTF-8. + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_string_pair(&proplist, MQTT_PROP_USER_PROPERTY, "client", "mosquitto_pub"); + */ +libmosq_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value); + +/* + * Function: mosquitto_property_read_byte + * + * Attempt to read a byte property matching an identifier, from a property list + * or single property. This function can search for multiple entries of the + * same identifier by using the returned value and skip_first. Note however + * that it is forbidden for most properties to be duplicated. + * + * If the property is not found, *value will not be modified, so it is safe to + * pass a variable with a default value to be potentially overwritten: + * + * uint16_t keepalive = 60; // default value + * // Get value from property list, or keep default if not found. + * mosquitto_property_read_int16(proplist, MQTT_PROP_SERVER_KEEP_ALIVE, &keepalive, false); + * + * Parameters: + * proplist - mosquitto_property pointer, the list of properties or single property + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * // proplist is obtained from a callback + * mosquitto_property *prop; + * prop = mosquitto_property_read_byte(proplist, identifier, &value, false); + * while(prop){ + * printf("value: %s\n", value); + * prop = mosquitto_property_read_byte(prop, identifier, &value); + * } + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_byte( + const mosquitto_property *proplist, + int identifier, + uint8_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int16 + * + * Read an int16 property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int16( + const mosquitto_property *proplist, + int identifier, + uint16_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int32 + * + * Read an int32 property value from a property. + * + * Parameters: + * property - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int32( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_varint + * + * Read a varint property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_varint( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_binary + * + * Read a binary property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_binary( + const mosquitto_property *proplist, + int identifier, + void **value, + uint16_t *len, + bool skip_first); + +/* + * Function: mosquitto_property_read_string + * + * Read a string property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string( + const mosquitto_property *proplist, + int identifier, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_read_string_pair + * + * Read a string pair property value pair from a property. + * + * On success, name and value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * name - pointer to char* for the name property data to be stored in, or NULL + * if the name is not required. + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string_pair( + const mosquitto_property *proplist, + int identifier, + char **name, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_free_all + * + * Free all properties from a list of properties. Frees the list and sets *properties to NULL. + * + * Parameters: + * properties - list of properties to free + * + * Example: + * mosquitto_properties *properties = NULL; + * // Add properties + * mosquitto_property_free_all(&properties); + */ +libmosq_EXPORT void mosquitto_property_free_all(mosquitto_property **properties); + +/* + * Function: mosquitto_property_copy_all + * + * Parameters: + * dest : pointer for new property list + * src : property list + * + * Returns: + * MOSQ_ERR_SUCCESS - on successful copy + * MOSQ_ERR_INVAL - if dest is NULL + * MOSQ_ERR_NOMEM - on out of memory (dest will be set to NULL) + */ +libmosq_EXPORT int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_property *src); + +/* + * Function: mosquitto_property_check_command + * + * Check whether a property identifier is valid for the given command. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * identifier - MQTT property (e.g. MQTT_PROP_USER_PROPERTY) + * + * Returns: + * MOSQ_ERR_SUCCESS - if the identifier is valid for command + * MOSQ_ERR_PROTOCOL - if the identifier is not valid for use with command. + */ +libmosq_EXPORT int mosquitto_property_check_command(int command, int identifier); + + +/* + * Function: mosquitto_property_check_all + * + * Check whether a list of properties are valid for a particular command, + * whether there are duplicates, and whether the values are valid where + * possible. + * + * Note that this function is used internally in the library whenever + * properties are passed to it, so in basic use this is not needed, but should + * be helpful to check property lists *before* the point of using them. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * properties - list of MQTT properties to check. + * + * Returns: + * MOSQ_ERR_SUCCESS - if all properties are valid + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid + */ +libmosq_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties); + +/* Function: mosquitto_string_to_property_info + * + * Parse a property name string and convert to a property identifier and data type. + * The property name is as defined in the MQTT specification, with - as a + * separator, for example: payload-format-indicator. + * + * Parameters: + * propname - the string to parse + * identifier - pointer to an int to receive the property identifier + * type - pointer to an int to receive the property type + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the string does not match a property + * + * Example: + * mosquitto_string_to_property_info("response-topic", &id, &type); + * // id == MQTT_PROP_RESPONSE_TOPIC + * // type == MQTT_PROP_TYPE_STRING + */ +libmosq_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/hc_mqttclient_s/mosquitto_plugin.h b/product/src/fes/protocol/hc_mqttclient_s/mosquitto_plugin.h new file mode 100644 index 00000000..99374bee --- /dev/null +++ b/product/src/fes/protocol/hc_mqttclient_s/mosquitto_plugin.h @@ -0,0 +1,319 @@ +/* +Copyright (c) 2012-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_PLUGIN_H +#define MOSQUITTO_PLUGIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MOSQ_AUTH_PLUGIN_VERSION 4 + +#define MOSQ_ACL_NONE 0x00 +#define MOSQ_ACL_READ 0x01 +#define MOSQ_ACL_WRITE 0x02 +#define MOSQ_ACL_SUBSCRIBE 0x04 + +#include +#include + +struct mosquitto; + +struct mosquitto_opt { + char *key; + char *value; +}; + +struct mosquitto_auth_opt { + char *key; + char *value; +}; + +struct mosquitto_acl_msg { + const char *topic; + const void *payload; + long payloadlen; + int qos; + bool retain; +}; + +/* + * To create an authentication plugin you must include this file then implement + * the functions listed in the "Plugin Functions" section below. The resulting + * code should then be compiled as a shared library. Using gcc this can be + * achieved as follows: + * + * gcc -I -fPIC -shared plugin.c -o plugin.so + * + * On Mac OS X: + * + * gcc -I -fPIC -shared plugin.c -undefined dynamic_lookup -o plugin.so + * + * Authentication plugins can implement one or both of authentication and + * access control. If your plugin does not wish to handle either of + * authentication or access control it should return MOSQ_ERR_PLUGIN_DEFER. In + * this case, the next plugin will handle it. If all plugins return + * MOSQ_ERR_PLUGIN_DEFER, the request will be denied. + * + * For each check, the following flow happens: + * + * * The default password file and/or acl file checks are made. If either one + * of these is not defined, then they are considered to be deferred. If either + * one accepts the check, no further checks are made. If an error occurs, the + * check is denied + * * The first plugin does the check, if it returns anything other than + * MOSQ_ERR_PLUGIN_DEFER, then the check returns immediately. If the plugin + * returns MOSQ_ERR_PLUGIN_DEFER then the next plugin runs its check. + * * If the final plugin returns MOSQ_ERR_PLUGIN_DEFER, then access will be + * denied. + */ + +/* ========================================================================= + * + * Helper Functions + * + * ========================================================================= */ + +/* There are functions that are available for plugin developers to use in + * mosquitto_broker.h, including logging and accessor functions. + */ + + +/* ========================================================================= + * + * Plugin Functions + * + * You must implement these functions in your plugin. + * + * ========================================================================= */ + +/* + * Function: mosquitto_auth_plugin_version + * + * The broker will call this function immediately after loading the plugin to + * check it is a supported plugin version. Your code must simply return + * MOSQ_AUTH_PLUGIN_VERSION. + */ +int mosquitto_auth_plugin_version(void); + + +/* + * Function: mosquitto_auth_plugin_init + * + * Called after the plugin has been loaded and + * has been called. This will only ever be called once and can be used to + * initialise the plugin. + * + * Parameters: + * + * user_data : The pointer set here will be passed to the other plugin + * functions. Use to hold connection information for example. + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_plugin_cleanup + * + * Called when the broker is shutting down. This will only ever be called once + * per plugin. + * Note that will be called directly before + * this function. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_security_init + * + * This function is called in two scenarios: + * + * 1. When the broker starts up. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, will be called first, then + * this function will be called. In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_init(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_security_cleanup + * + * This function is called in two scenarios: + * + * 1. When the broker is shutting down. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, this function will be called, followed by + * . In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_acl_check + * + * Called by the broker when topic access must be checked. access will be one + * of: + * MOSQ_ACL_SUBSCRIBE when a client is asking to subscribe to a topic string. + * This differs from MOSQ_ACL_READ in that it allows you to + * deny access to topic strings rather than by pattern. For + * example, you may use MOSQ_ACL_SUBSCRIBE to deny + * subscriptions to '#', but allow all topics in + * MOSQ_ACL_READ. This allows clients to subscribe to any + * topic they want, but not discover what topics are in use + * on the server. + * MOSQ_ACL_READ when a message is about to be sent to a client (i.e. whether + * it can read that topic or not). + * MOSQ_ACL_WRITE when a message has been received from a client (i.e. whether + * it can write to that topic or not). + * + * Return: + * MOSQ_ERR_SUCCESS if access was granted. + * MOSQ_ERR_ACL_DENIED if access was not granted. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_acl_check(void *user_data, int access, struct mosquitto *client, const struct mosquitto_acl_msg *msg); + + +/* + * Function: mosquitto_auth_unpwd_check + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making basic username/password checks. + * + * Called by the broker when a username/password must be checked. + * + * Return: + * MOSQ_ERR_SUCCESS if the user is authenticated. + * MOSQ_ERR_AUTH if authentication failed. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_unpwd_check(void *user_data, struct mosquitto *client, const char *username, const char *password); + + +/* + * Function: mosquitto_psk_key_get + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making TLS-PSK checks. + * + * Called by the broker when a client connects to a listener using TLS/PSK. + * This is used to retrieve the pre-shared-key associated with a client + * identity. + * + * Examine hint and identity to determine the required PSK (which must be a + * hexadecimal string with no leading "0x") and copy this string into key. + * + * Parameters: + * user_data : the pointer provided in . + * hint : the psk_hint for the listener the client is connecting to. + * identity : the identity string provided by the client + * key : a string where the hex PSK should be copied + * max_key_len : the size of key + * + * Return value: + * Return 0 on success. + * Return >0 on failure. + * Return MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_psk_key_get(void *user_data, struct mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len); + +/* + * Function: mosquitto_auth_start + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making extended authentication checks. + * + * Parameters: + * user_data : the pointer provided in . + * method : the authentication method + * reauth : this is set to false if this is the first authentication attempt + * on a connection, set to true if the client is attempting to + * reauthenticate. + * data_in : pointer to authentication data, or NULL + * data_in_len : length of data_in, in bytes + * data_out : if your plugin wishes to send authentication data back to the + * client, allocate some memory using malloc or friends and set + * data_out. The broker will free the memory after use. + * data_out_len : Set the length of data_out in bytes. + * + * Return value: + * Return MOSQ_ERR_SUCCESS if authentication was successful. + * Return MOSQ_ERR_AUTH_CONTINUE if the authentication is a multi step process and can continue. + * Return MOSQ_ERR_AUTH if authentication was valid but did not succeed. + * Return any other relevant positive integer MOSQ_ERR_* to produce an error. + */ +int mosquitto_auth_start(void *user_data, struct mosquitto *client, const char *method, bool reauth, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + +int mosquitto_auth_continue(void *user_data, struct mosquitto *client, const char *method, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/hc_mqttclient_s/mosquittopp.h b/product/src/fes/protocol/hc_mqttclient_s/mosquittopp.h new file mode 100644 index 00000000..d3f388c0 --- /dev/null +++ b/product/src/fes/protocol/hc_mqttclient_s/mosquittopp.h @@ -0,0 +1,146 @@ +/* +Copyright (c) 2010-2019 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTOPP_H +#define MOSQUITTOPP_H + +#if defined(_WIN32) && !defined(LIBMOSQUITTO_STATIC) +# ifdef mosquittopp_EXPORTS +# define mosqpp_EXPORT __declspec(dllexport) +# else +# define mosqpp_EXPORT __declspec(dllimport) +# endif +#else +# define mosqpp_EXPORT +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define DEPRECATED __attribute__ ((deprecated)) +#else +# define DEPRECATED +#endif + +#include +#include +#include + +namespace mosqpp { + + +mosqpp_EXPORT const char * DEPRECATED strerror(int mosq_errno); +mosqpp_EXPORT const char * DEPRECATED connack_string(int connack_code); +mosqpp_EXPORT int DEPRECATED sub_topic_tokenise(const char *subtopic, char ***topics, int *count); +mosqpp_EXPORT int DEPRECATED sub_topic_tokens_free(char ***topics, int count); +mosqpp_EXPORT int DEPRECATED lib_version(int *major, int *minor, int *revision); +mosqpp_EXPORT int DEPRECATED lib_init(); +mosqpp_EXPORT int DEPRECATED lib_cleanup(); +mosqpp_EXPORT int DEPRECATED topic_matches_sub(const char *sub, const char *topic, bool *result); +mosqpp_EXPORT int DEPRECATED validate_utf8(const char *str, int len); +mosqpp_EXPORT int DEPRECATED subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool retained, + const char *topic, + int qos=0, + const char *host="localhost", + int port=1883, + const char *client_id=NULL, + int keepalive=60, + bool clean_session=true, + const char *username=NULL, + const char *password=NULL, + const struct libmosquitto_will *will=NULL, + const struct libmosquitto_tls *tls=NULL); + +mosqpp_EXPORT int DEPRECATED subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos=0, + bool retained=true, + const char *host="localhost", + int port=1883, + const char *client_id=NULL, + int keepalive=60, + bool clean_session=true, + const char *username=NULL, + const char *password=NULL, + const struct libmosquitto_will *will=NULL, + const struct libmosquitto_tls *tls=NULL); + +/* + * Class: mosquittopp + * + * A mosquitto client class. This is a C++ wrapper class for the mosquitto C + * library. Please see mosquitto.h for details of the functions. + */ +class mosqpp_EXPORT DEPRECATED mosquittopp { + private: + struct mosquitto *m_mosq; + public: + DEPRECATED mosquittopp(const char *id=NULL, bool clean_session=true); + virtual ~mosquittopp(); + + int DEPRECATED reinitialise(const char *id, bool clean_session); + int DEPRECATED socket(); + int DEPRECATED will_set(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int DEPRECATED will_clear(); + int DEPRECATED username_pw_set(const char *username, const char *password=NULL); + int DEPRECATED connect(const char *host, int port=1883, int keepalive=60); + int DEPRECATED connect_async(const char *host, int port=1883, int keepalive=60); + int DEPRECATED connect(const char *host, int port, int keepalive, const char *bind_address); + int DEPRECATED connect_async(const char *host, int port, int keepalive, const char *bind_address); + int DEPRECATED reconnect(); + int DEPRECATED reconnect_async(); + int DEPRECATED disconnect(); + int DEPRECATED publish(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int DEPRECATED subscribe(int *mid, const char *sub, int qos=0); + int DEPRECATED unsubscribe(int *mid, const char *sub); + void DEPRECATED reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + int DEPRECATED max_inflight_messages_set(unsigned int max_inflight_messages); + void DEPRECATED message_retry_set(unsigned int message_retry); + void DEPRECATED user_data_set(void *userdata); + int DEPRECATED tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL); + int DEPRECATED tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL); + int DEPRECATED tls_insecure_set(bool value); + int DEPRECATED tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL); + int DEPRECATED opts_set(enum mosq_opt_t option, void *value); + + int DEPRECATED loop(int timeout=-1, int max_packets=1); + int DEPRECATED loop_misc(); + int DEPRECATED loop_read(int max_packets=1); + int DEPRECATED loop_write(int max_packets=1); + int DEPRECATED loop_forever(int timeout=-1, int max_packets=1); + int DEPRECATED loop_start(); + int DEPRECATED loop_stop(bool force=false); + bool DEPRECATED want_write(); + int DEPRECATED threaded_set(bool threaded=true); + int DEPRECATED socks5_set(const char *host, int port=1080, const char *username=NULL, const char *password=NULL); + + // names in the functions commented to prevent unused parameter warning + virtual void on_connect(int /*rc*/) {return;} + virtual void on_connect_with_flags(int /*rc*/, int /*flags*/) {return;} + virtual void on_disconnect(int /*rc*/) {return;} + virtual void on_publish(int /*mid*/) {return;} + virtual void on_message(const struct mosquitto_message * /*message*/) {return;} + virtual void on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/) {return;} + virtual void on_unsubscribe(int /*mid*/) {return;} + virtual void on_log(int /*level*/, const char * /*str*/) {return;} + virtual void on_error() {return;} +}; + +} +#endif diff --git a/product/src/fes/protocol/httpClient_szdt/HttpClient_szdt.cpp b/product/src/fes/protocol/httpClient_szdt/HttpClient_szdt.cpp index 2f8271a4..0ba054d2 100644 --- a/product/src/fes/protocol/httpClient_szdt/HttpClient_szdt.cpp +++ b/product/src/fes/protocol/httpClient_szdt/HttpClient_szdt.cpp @@ -186,7 +186,7 @@ int CHttpClient_szdt::SetBaseAddr(void *address) int CHttpClient_szdt::SetProperty(int IsMainFes) { - g_HttpClient_szdtIsMainFes = IsMainFes; + g_HttpClient_szdtIsMainFes = (IsMainFes != 0); LOGDEBUG("CHttpClient_szdt::SetProperty g_HttpClient_szdtIsMainFes:%d", IsMainFes); return iotSuccess; } @@ -318,11 +318,13 @@ int CHttpClient_szdt::CloseChan(int MainChanNo, int ChanNo, int CloseFlag) void CHttpClient_szdt::ClearDataProcThreadByChanNo(int ChanNo) { - int tempNum; + if(m_CDataProcQueue.empty()) + { + return; + } + CHttpClient_szdtDataProcThreadPtr ptrPort; - if ((tempNum = m_CDataProcQueue.size()) <= 0) - return; vector::iterator it; for (it = m_CDataProcQueue.begin(); it != m_CDataProcQueue.end(); it++) { @@ -338,10 +340,14 @@ void CHttpClient_szdt::ClearDataProcThreadByChanNo(int ChanNo) int CHttpClient_szdt::ChanTimer(int MainChanNo) { + boost::ignore_unused_variable_warning(MainChanNo); + return iotSuccess; } int CHttpClient_szdt::ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + return iotSuccess; } diff --git a/product/src/fes/protocol/httpClient_szdt/HttpClient_szdtDataProcThread.cpp b/product/src/fes/protocol/httpClient_szdt/HttpClient_szdtDataProcThread.cpp index 21efcfa4..86f5c482 100644 --- a/product/src/fes/protocol/httpClient_szdt/HttpClient_szdtDataProcThread.cpp +++ b/product/src/fes/protocol/httpClient_szdt/HttpClient_szdtDataProcThread.cpp @@ -14,7 +14,7 @@ std::vector split(std::string str, std::string pattern) std::string::size_type pos; std::vector result; str += pattern;//扩展字符串以方便操作 - int size = str.size(); + int size = static_cast(str.size()); for (int i = 0; i < size; i++) { @@ -23,7 +23,7 @@ std::vector split(std::string str, std::string pattern) { std::string s = str.substr(i, pos - i); result.push_back(s); - i = pos + pattern.size() - 1; + i = static_cast(pos + pattern.size() - 1); } } return result; @@ -169,7 +169,7 @@ void CHttpClient_szdtDataProcThread::GetDevRealTimeValue_SZDT(int devId) vector GetJsonDataByForm(string json, string form) { - int i, j, k; + size_t i, j; //LOGDEBUG("%s",json.data()); rapidjson::Document document; @@ -252,7 +252,7 @@ vector GetJsonDataByForm(string json, string form) if (!temp1.HasMember(rootSplits[0].c_str())) return vals; - for (k = 0; k devIdData, vector(atof(valueData[i].c_str())); AiValue[AiValueCount].PointNo = pAi->PointNo; AiValue[AiValueCount].Value = value; diff --git a/product/src/fes/protocol/httpClient_szdt/httpClient_szdt.pro b/product/src/fes/protocol/httpClient_szdt/httpClient_szdt.pro index 881ce06f..a4dc9693 100644 --- a/product/src/fes/protocol/httpClient_szdt/httpClient_szdt.pro +++ b/product/src/fes/protocol/httpClient_szdt/httpClient_szdt.pro @@ -23,11 +23,11 @@ INCLUDEPATH += \ ../../../3rd/include/ LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time -LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase -lcurl -ltinyxml - +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase -lcurl DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) #------------------------------------------------------------------- COMMON_PRI=$$PWD/../../../common.pri diff --git a/product/src/fes/protocol/httpsClient_bjjc/httpsClient_bjjc.pro b/product/src/fes/protocol/httpsClient_bjjc/httpsClient_bjjc.pro index 092f4d70..961543ef 100644 --- a/product/src/fes/protocol/httpsClient_bjjc/httpsClient_bjjc.pro +++ b/product/src/fes/protocol/httpsClient_bjjc/httpsClient_bjjc.pro @@ -23,10 +23,12 @@ INCLUDEPATH += \ LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase +#LIBS += -llibcurl -llibeay32 -lssleay32 -lzlibwapi DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) #------------------------------------------------------------------- COMMON_PRI=$$PWD/../../../common.pri diff --git a/product/src/fes/protocol/iec103/IEC103.cpp b/product/src/fes/protocol/iec103/IEC103.cpp index 38781cb3..25568ddd 100644 --- a/product/src/fes/protocol/iec103/IEC103.cpp +++ b/product/src/fes/protocol/iec103/IEC103.cpp @@ -14,7 +14,19 @@ #include "pub_utility_api/I18N.h" #include + +//< 屏蔽xml_parser编译告警 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-copy" +#endif + #include "boost/property_tree/xml_parser.hpp" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "boost/typeof/typeof.hpp" #include "boost/filesystem.hpp" #include diff --git a/product/src/fes/protocol/iec104/IEC104.cpp b/product/src/fes/protocol/iec104/IEC104.cpp index bb174683..ff2ad00b 100644 --- a/product/src/fes/protocol/iec104/IEC104.cpp +++ b/product/src/fes/protocol/iec104/IEC104.cpp @@ -53,6 +53,8 @@ int EX_ChanTimer(int ChanNo) int EX_ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + g_IEC104ChanelRun=false;//使所有的线程退出。 Iec104.InformTcpThreadExit(); return iotSuccess; @@ -94,7 +96,7 @@ int CIEC104::SetBaseAddr(void *address) int CIEC104::SetProperty(int IsMainFes) { - g_IEC104IsMainFes = IsMainFes; + g_IEC104IsMainFes = (IsMainFes != 0); LOGDEBUG("CIEC104::SetProperty g_IEC104IsMainFes:%d",IsMainFes); return iotSuccess; } @@ -440,14 +442,6 @@ int CIEC104::ReadConfigParam() else param.soeOnce = 0; - if (config.getIntValue(strRtuNo, "soe_check_di", ivalue) == iotSuccess) - { - param.soeCheckDi = ivalue; - items++; - } - else - param.soeCheckDi = 0; - if (config.getIntValue(strRtuNo, "ignore_invalid_data", ivalue) == iotSuccess) { param.ignoreInvalid = ivalue; diff --git a/product/src/fes/protocol/iec104/IEC104DataProcThread.cpp b/product/src/fes/protocol/iec104/IEC104DataProcThread.cpp index b5596908..6e6d76db 100644 --- a/product/src/fes/protocol/iec104/IEC104DataProcThread.cpp +++ b/product/src/fes/protocol/iec104/IEC104DataProcThread.cpp @@ -29,17 +29,21 @@ 再收到变位时,与当前值判断没有变位,不会报告变位告警,导致画面变位延后。此时需要设置soeOnce=1,收到SOE时也产生变位告警。 */ #include +#include #include "IEC104DataProcThread.h" #include "TcpClientThread.h" #include "pub_utility_api/CommonConfigParse.h" #include "pub_utility_api/I18N.h" +#include "FesMessage.pb.h" using namespace iot_public; +using namespace iot_idl; extern bool g_IEC104IsMainFes; extern bool g_IEC104ChanelRun; const int g_IEC104ThreadTime = 20; +const int CONST_PARAM2_SPLIT_BIT = 99; //按位拆分功能 CIEC104DataProcThread::CIEC104DataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam): CTimerThreadBase("IEC104DataProcThread",g_IEC104ThreadTime,0,true) @@ -75,12 +79,12 @@ CTimerThreadBase("IEC104DataProcThread",g_IEC104ThreadTime,0,true) m_AppData.address = m_ptrCFesRtu->m_Param.RtuAddr; m_AppData.respTimeoutReset = m_ptrCFesChan->m_Param.RespTimeout; //配置 - m_AppData.dataPollTimeoutReset = vecAppParam[i].dataPollTimeoutReset; + m_AppData.dataPollTimeoutReset =vecAppParam[i].dataPollTimeoutReset; m_AppData.accPollTimeoutReset = vecAppParam[i].accPollTimeoutReset; m_AppData.setTimeTimeoutReset = vecAppParam[i].setTimeTimeoutReset; m_AppData.t1Reset = vecAppParam[i].t1Reset; //帧确认超时 i frame & s frame */ - m_AppData.t2Reset = vecAppParam[i].t2Reset; //无捎带I帧超时发送S帧 - m_AppData.t3Reset = vecAppParam[i].t3Reset; //活跃检测超时 TEST帧 + m_AppData.t2Reset=vecAppParam[i].t2Reset; //无捎带I帧超时发送S帧 + m_AppData.t3Reset=vecAppParam[i].t3Reset; //活跃检测超时 TEST帧 m_AppData.IFrameFlag=0; //I帧确认标志 m_AppData.controlTimeoutReset = vecAppParam[i].controlTimeoutReset;//uint s m_AppData.n=vecAppParam[i].n; //滑动窗口个数 @@ -92,7 +96,6 @@ CTimerThreadBase("IEC104DataProcThread",g_IEC104ThreadTime,0,true) m_AppData.strictComMode=vecAppParam[i].strictComMode; //1:接收序号不对,断开网络。0:忽略 m_AppData.soeOnce = vecAppParam[i].soeOnce; //1:遥信变位只产生SOE;0:遥信变位只产生SOE和变位 m_AppData.createSoe=vecAppParam[i].createSoe; //1:对于不产生SOE的 IEC104 Server在遥信帧中产生SOE. 0: 忽略 - m_AppData.soeCheckDi = vecAppParam[i].soeCheckDi; //1:Soe判断状态; 0:Soe不判断状态 m_AppData.ignoreInvalid = vecAppParam[i].ignoreInvalid;//忽略数据无效位 1:忽略 0:不忽略 m_AppData.aoCmdMode = vecAppParam[i].aoCmdMode;//AO控制模式; 0:允许发送单AO命令处理 1:允许同时发送多AO命令处理 m_AppData.aoCmdType = vecAppParam[i].aoCmdType; @@ -116,7 +119,7 @@ CTimerThreadBase("IEC104DataProcThread",g_IEC104ThreadTime,0,true) if ((m_AppData.aoCmdType != C_SE_NA_1) && (m_AppData.aoCmdType != C_SE_NB_1) && (m_AppData.aoCmdType != C_SE_NC_1)) m_AppData.aoCmdType = C_SE_NC_1; - + InitBitMapping(); //缓存按位拆解地址映射 } @@ -167,6 +170,7 @@ void CIEC104DataProcThread::execute() while ((count < 20) && (retLen > 0)) { RecvDataProcess(); + HandleSplitBitCache(); retLen = RecvNetData(); count++; } @@ -216,8 +220,7 @@ void CIEC104DataProcThread::execute() DoCmdProcess(); return; } - else - if(m_ptrCFesRtu->GetRxAoCmdNum()>0) + else if(m_ptrCFesRtu->GetRxAoCmdNum()>0) { if (m_AppData.aoCmdMode == CN_IEC104AoSingleCmd) AoSingleCmdProcess(); @@ -225,6 +228,11 @@ void CIEC104DataProcThread::execute() AoManyCmdProcess(); return; } + else if(m_ptrCFesRtu->GetRxMoCmdNum() > 0) + { + MoCmdProcess(); + return; + } } } @@ -272,7 +280,6 @@ int CIEC104DataProcThread::InitConfigParam() m_AppData.infoAddrSize=3; //信息体地址长度 1\2\3 m_AppData.strictComMode=0; //1:接收序号不对,断开网络。0:忽略 m_AppData.createSoe=0; //1:对于不产生SOE的 IEC104 Server在遥信帧中产生SOE. 0: 忽略 - m_AppData.soeCheckDi = 0; //1:Soe判断状态; 0:Soe不判断状态 m_AppData.ignoreInvalid = 0;//忽略数据无效位 1:忽略 0:不忽略 m_AppData.diStartAddress = 0x0001; m_AppData.aiStartAddress = 0x0701; @@ -426,13 +433,6 @@ int CIEC104DataProcThread::ReadConfigParam() else m_AppData.soeOnce = 0; - if (config.getIntValue(strRtuNo, "soe_check_di", ivalue) == iotSuccess) - { - m_AppData.soeCheckDi = ivalue; - } - else - m_AppData.soeCheckDi = 0; - if(config.getIntValue(strRtuNo,"ignore_invalid_data",ivalue) == iotSuccess) { m_AppData.ignoreInvalid = ivalue; @@ -1077,6 +1077,7 @@ int CIEC104DataProcThread::RecvDataProcess() case M_ME_NC_1: case M_ME_ND_1: RecvAiWithoutTimeProcess(); + RecvMiWithoutTimeProcess(); break; case M_ME_TA_1: case M_ME_TB_1: @@ -1397,10 +1398,9 @@ void CIEC104DataProcThread::RecvDiWithoutTimeProcess() if(infoType==M_DP_NA_1) { - if((value&0x02)==0x01) + if((value&0x01)==0x01) bitValue = 0; - else - if((value&0x02)==0x02) + else if((value&0x02)==0x02) bitValue = 1; else status = CN_FesValueUpdate|CN_FesValueInvaild; @@ -1588,6 +1588,13 @@ void CIEC104DataProcThread::RecvDiPSNAProcess() SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; SoeEvent[SoeCount].PointNo = pDi->PointNo; SoeCount++; + if(SoeCount>=128) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount,&SoeEvent[0]); + SoeCount = 0; + } } } } @@ -1854,10 +1861,7 @@ void CIEC104DataProcThread::RecvDiWithTime24Process() ChgDi[ChgCount].PointNo = pDi->PointNo; ChgCount++; } - //鄂州机场SOE需要判断是否变位 - if (m_AppData.soeCheckDi && (bitValue == pDi->Value)) - continue; - //Create Soe + //Create Soe memset(&SoeEvent[SoeCount],0,sizeof(SFesSoeEvent)); SoeEvent[SoeCount].time = mSec; memcpy(SoeEvent[SoeCount].TableName,pDi->TableName,CN_FesMaxTableNameSize); @@ -2032,9 +2036,6 @@ void CIEC104DataProcThread::RecvDiWithTime56Process() ChgDi[ChgCount].PointNo = pDi->PointNo; ChgCount++; } - //鄂州机场SOE需要判断是否变位 - if (m_AppData.soeCheckDi && (bitValue == pDi->Value)) - continue; //Create Soe memset(&SoeEvent[SoeCount],0,sizeof(SFesSoeEvent)); SoeEvent[SoeCount].time = mSec; @@ -3409,6 +3410,268 @@ void CIEC104DataProcThread::RecvAccWithTime56Process() } } +void CIEC104DataProcThread::RecvMiWithoutTimeProcess() +{ + if(m_ptrCFesRtu->m_MaxMiPoints <= 0) + { + return; //如果无MI点,则直接返回 + } + + int trReason,infoAddr,publicAddr,PIndex,ChgCount,ValueCount; + int readx,i,status; + byte VSQ,infoType,count,QDS; + SFesMi *pMi; + SFesRtuMiValue MiValue[100]; + SFesChgMi ChgMi[100]; + short sValue16; + float fTempVal = 0.0f; + int miValue; + byte *pTemp; + uint64 mSec; + + infoType = m_AppData.recvBuf[6]; + VSQ = m_AppData.recvBuf[7]; + count = VSQ&0x7f; + readx = 8; + if(m_AppData.trReasonSize==1) + { + trReason = m_AppData.recvBuf[readx++]; + } + else + { + trReason = m_AppData.recvBuf[readx++]; + trReason |= (int)m_AppData.recvBuf[readx++]<<8; + } + + if(m_AppData.publicAddrSize==1) + { + publicAddr = m_AppData.recvBuf[readx++]; + } + else + { + publicAddr = m_AppData.recvBuf[readx++]; + publicAddr |= (int)m_AppData.recvBuf[readx++]<<8; + } + + if(publicAddr != m_ptrCFesRtu->m_Param.RtuAddr || count <= 0) + return; + + ChgCount = 0; + ValueCount = 0; + mSec = getUTCTimeMsec(); + if(VSQ&0x80) //连续地址 + { + if(m_AppData.infoAddrSize==1) + { + infoAddr = m_AppData.recvBuf[readx++]; + } + else if(m_AppData.infoAddrSize==2) + { + infoAddr = m_AppData.recvBuf[readx++]; + infoAddr |= (int)m_AppData.recvBuf[readx++]<<8; + } + else + { + infoAddr = m_AppData.recvBuf[readx++]; + infoAddr |= (int)m_AppData.recvBuf[readx++]<<8; + infoAddr |= (int)m_AppData.recvBuf[readx++]<<16; + } + PIndex = infoAddr- m_AppData.aiStartAddress; //本报文中的起始地址 + + if(PIndex >= m_ptrCFesRtu->m_MaxMiIndex || PIndex + count <= m_ptrCFesRtu->m_MinMiIndex) + { + //如果不在索引范围跳过即可: + return; + } + + for(i=0;i(fTempVal); + QDS = m_AppData.recvBuf[readx++]; + break; + case M_ME_ND_1: + sValue16 = (short)m_AppData.recvBuf[readx++]; + sValue16 |= (short)m_AppData.recvBuf[readx++]<<8; + miValue = sValue16; + QDS = 0; + break; + } + status = CN_FesValueUpdate; + if (!m_AppData.ignoreInvalid) + { + if (QDS & IEC104DI_SIQ_IV) + status |= CN_FesValueInvaild; + if (QDS & IEC104DI_SIQ_NT) + status |= CN_FesValueComDown; + } + MiValue[ValueCount].PointNo = pMi->PointNo; //远动号从点序号移植到规约参数1 + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = status; + MiValue[ValueCount].time = mSec; + if(pMi->Param2 == CONST_PARAM2_SPLIT_BIT) + { + CacheSplitBitByMi(PIndex,MiValue[ValueCount]); //配置了按位拆分 + } + + ValueCount++; + if(ValueCount>=100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount,&MiValue[0],&ChgCount,&ChgMi[0]); + ValueCount = 0; + if((ChgCount>0)&&(g_IEC104IsMainFes==true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + } + } + } + else + { + switch(infoType) + { + case M_ME_NA_1: + case M_ME_NB_1: + readx+=3; + break; + case M_ME_NC_1: + readx+=5; + break; + case M_ME_ND_1: + readx+=2; + break; + } + } + PIndex++; + } + } + else + { //非连续地址 + for(i=0;i(fTempVal); + QDS = m_AppData.recvBuf[readx++]; + break; + case M_ME_ND_1: + sValue16 = (short)m_AppData.recvBuf[readx++]; + sValue16 |= (short)m_AppData.recvBuf[readx++]<<8; + miValue = sValue16; + QDS = 0; + break; + } + + status = CN_FesValueUpdate; + if (!m_AppData.ignoreInvalid) + { + if (QDS & IEC104DI_SIQ_IV) + status |= CN_FesValueInvaild; + if (QDS & IEC104DI_SIQ_NT) + status |= CN_FesValueComDown; + } + + + MiValue[ValueCount].PointNo = pMi->PointNo; //远动号从点序号移植到规约参数1 + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = status; + MiValue[ValueCount].time = mSec; + if(pMi->Param2 == CONST_PARAM2_SPLIT_BIT) + { + CacheSplitBitByMi(PIndex,MiValue[ValueCount]); //配置了按位拆分 + } + + ValueCount++; + if(ValueCount>=100) + { + //MI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount,&MiValue[0],&ChgCount,&ChgMi[0]); + ValueCount = 0; + if((ChgCount>0)&&(g_IEC104IsMainFes==true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + } + } + } + else + { + switch(infoType) + { + case M_ME_NA_1: + case M_ME_NB_1: + readx+=3; + break; + case M_ME_NC_1: + readx+=5; + break; + case M_ME_ND_1: + readx+=2; + break; + } + } + } + } + + if(ValueCount>0) //前面循环每100个发送一次,本判断是把剩余的发送出去 + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount,&MiValue[0],&ChgCount,&ChgMi[0]); + ValueCount = 0; + if((ChgCount>0)&&(g_IEC104IsMainFes==true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + } + } +} + /** * @brief CIEC104DataProcThread::DoCmdProcess * 接收SCADA传来的DO控制命令,组织命令帧,并返回操作消息。 @@ -3447,7 +3710,7 @@ void CIEC104DataProcThread::DoCmdProcess() retCmd.retStatus = CN_ControlFailed; retCmd.CtrlActType = cmd.CtrlActType; //sprintf(retCmd.strParam,"IEC104 遥控失败!RtuNo:%d 通信中断",m_ptrCFesRtu->m_Param.RtuNo); - sprintf(retCmd.strParam,I18N("IEC104 遥控失败!RtuNo:%d 通信中断").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo); + sprintf(retCmd.strParam,I18N_C("IEC104 遥控失败!RtuNo:%d 通信中断"), m_ptrCFesRtu->m_Param.RtuNo); LOGDEBUG("IEC104 Do failed!RtuNo:%d comm disconnect",m_ptrCFesRtu->m_Param.RtuNo); //2019-02-21 thxiao 为适应转发规约 @@ -3465,7 +3728,7 @@ void CIEC104DataProcThread::DoCmdProcess() strcpy(retCmd.RtuName, cmd.RtuName); retCmd.retStatus = CN_ControlFailed; retCmd.CtrlActType = cmd.CtrlActType; - sprintf(retCmd.strParam, I18N("IEC104 遥控失败! RtuNo:%d DO:%d 闭锁!").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); + sprintf(retCmd.strParam, I18N_C("IEC104 遥控失败! RtuNo:%d DO:%d 闭锁!"), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); LOGDEBUG("IEC104 遥控失败! RtuNo:%d DO:%d 闭锁!", m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); //2019-02-21 thxiao 为适应转发规约 m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); @@ -3566,7 +3829,7 @@ void CIEC104DataProcThread::DoCmdProcess() retCmd.retStatus = CN_ControlPointErr; retCmd.CtrlActType = cmd.CtrlActType; //sprintf(retCmd.strParam,"IEC104 遥控失败!RtuNo:%d 找不到遥控点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); - sprintf(retCmd.strParam,I18N("IEC104 遥控失败!RtuNo:%d 找不到遥控点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + sprintf(retCmd.strParam,I18N_C("IEC104 遥控失败!RtuNo:%d 找不到遥控点:%d"), m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); LOGDEBUG("IEC104 Do failed!RtuNo:%d can not find PointNo:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); //2019-02-21 thxiao 为适应转发规约 m_ptrCFesBase->WritexDoRespCmdBuf(1,&retCmd); @@ -3609,20 +3872,21 @@ void CIEC104DataProcThread::AoSingleCmdProcess() retCmd.SubSystem = cmd.SubSystem; if (m_AppData.state < CN_IEC104AppState_idle)//通信中断 { - //return failed to scada - strcpy(retCmd.TableName,cmd.TableName); - strcpy(retCmd.ColumnName,cmd.ColumnName); - strcpy(retCmd.TagName,cmd.TagName); - strcpy(retCmd.RtuName,cmd.RtuName); - retCmd.retStatus = CN_ControlPointErr; - retCmd.CtrlActType = cmd.CtrlActType; - //sprintf(retCmd.strParam,"IEC104 遥调失败!RtuNo:%d 通信中断",m_ptrCFesRtu->m_Param.RtuNo); - sprintf(retCmd.strParam,I18N("IEC104 遥调失败!RtuNo:%d 通信中断").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo); - LOGDEBUG("IEC104 Ao Failed!RtuNo:%d disconnect",m_ptrCFesRtu->m_Param.RtuNo); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); + if(cmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N_C("IEC104 遥调失败!RtuNo:%d 通信中断"), m_ptrCFesRtu->m_Param.RtuNo); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); + } + LOGDEBUG("IEC104 Ao Failed!RtuNo:%d disconnect",m_ptrCFesRtu->m_Param.RtuNo); m_AppData.lastCotrolcmd = CN_IEC104NoCmd; return; } @@ -3644,19 +3908,22 @@ void CIEC104DataProcThread::AoSingleCmdProcess() if(failed == 1) { - //return failed to scada - strcpy(retCmd.TableName,cmd.TableName); - strcpy(retCmd.ColumnName,cmd.ColumnName); - strcpy(retCmd.TagName,cmd.TagName); - strcpy(retCmd.RtuName,cmd.RtuName); - retCmd.retStatus = CN_ControlPointErr; - retCmd.CtrlActType = cmd.CtrlActType; - //sprintf(retCmd.strParam,"IEC104 遥调失败!RtuNo:%d 遥调点:%d 范围超出",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); - sprintf(retCmd.strParam,I18N("IEC104 遥调失败!RtuNo:%d 遥调点:%d 范围超出").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + if(cmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N_C("IEC104 遥调失败!RtuNo:%d 遥调点:%d 范围超出"), m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); + } + LOGDEBUG("IEC104 Ao Failed!RtuNo:%d PointNo:%d exceed range",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); m_AppData.lastCotrolcmd = CN_IEC104NoCmd; m_AppData.state = CN_IEC104AppState_idle; } @@ -3756,24 +4023,26 @@ void CIEC104DataProcThread::AoSingleCmdProcess() } else { - //return failed to scada - strcpy(retCmd.TableName,cmd.TableName); - strcpy(retCmd.ColumnName,cmd.ColumnName); - strcpy(retCmd.TagName,cmd.TagName); - strcpy(retCmd.RtuName,cmd.RtuName); - retCmd.retStatus = CN_ControlPointErr; - retCmd.CtrlActType = cmd.CtrlActType; - //2019-03-18 thxiao 为适应转发规约增加 - retCmd.CtrlDir = cmd.CtrlDir; - retCmd.RtuNo = cmd.RtuNo; - retCmd.PointID = cmd.PointID; + if(cmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + sprintf(retCmd.strParam,I18N_C("IEC104 遥调失败!RtuNo:%d 找不到遥调点:%d"), m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); + } - //sprintf(retCmd.strParam,"IEC104 遥调失败!RtuNo:%d 找不到遥调点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); - sprintf(retCmd.strParam,I18N("IEC104 遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); LOGDEBUG("IEC104 Ao failed!RtuNo:%d Can not find the PointNo:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); m_AppData.lastCotrolcmd = CN_IEC104NoCmd; m_AppData.state = CN_IEC104AppState_idle; } @@ -3814,6 +4083,11 @@ void CIEC104DataProcThread::AoManyCmdProcess() //return failed to scada for (i = 0; i < retNum1; i++) { + LOGDEBUG("IEC104 Ao Failed!RtuNo:%d disconnect", m_ptrCFesRtu->m_Param.RtuNo); + if(cmd[i].TagtState == CTRL_TYPE_NWAIT_ACK) + { + continue; + } retCmd.CtrlDir = cmd[i].CtrlDir; retCmd.RtuNo = cmd[i].RtuNo; retCmd.PointID = cmd[i].PointID; @@ -3828,10 +4102,7 @@ void CIEC104DataProcThread::AoManyCmdProcess() retCmd.retStatus = CN_ControlPointErr; retCmd.CtrlActType = cmd[i].CtrlActType; - //sprintf(retCmd.strParam,"IEC104 遥调失败!RtuNo:%d 通信中断",m_ptrCFesRtu->m_Param.RtuNo); - sprintf(retCmd.strParam, I18N("IEC104 遥调失败!RtuNo:%d 通信中断").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo); - LOGDEBUG("IEC104 Ao Failed!RtuNo:%d disconnect", m_ptrCFesRtu->m_Param.RtuNo); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + sprintf(retCmd.strParam, I18N_C("IEC104 遥调失败!RtuNo:%d 通信中断"), m_ptrCFesRtu->m_Param.RtuNo); //2019-03-18 thxiao 为适应转发规约 m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); } @@ -3873,28 +4144,31 @@ void CIEC104DataProcThread::AoManyCmdProcess() if (failed == 1) { - //return failed to scada - retCmd.CtrlDir = cmd[i].CtrlDir; - retCmd.RtuNo = cmd[i].RtuNo; - retCmd.PointID = cmd[i].PointID; - retCmd.FwSubSystem = cmd[i].FwSubSystem; - retCmd.FwRtuNo = cmd[i].FwRtuNo; - retCmd.FwPointNo = cmd[i].FwPointNo; - retCmd.SubSystem = cmd[i].SubSystem; - strcpy(retCmd.TableName, cmd[i].TableName); - strcpy(retCmd.ColumnName, cmd[i].ColumnName); - strcpy(retCmd.TagName, cmd[i].TagName); - strcpy(retCmd.RtuName, cmd[i].RtuName); - retCmd.retStatus = CN_ControlPointErr; - retCmd.CtrlActType = cmd[i].CtrlActType; - //sprintf(retCmd.strParam,"IEC104 遥调失败!RtuNo:%d 遥调点:%d 范围超出",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); - sprintf(retCmd.strParam, I18N("IEC104 遥调失败!RtuNo:%d 遥调点:%d 范围超出").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID); - LOGDEBUG("IEC104 Ao Failed!RtuNo:%d PointNo:%d exceed range", m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); - //m_AppData.lastCotrolcmd = CN_IEC104NoCmd; - //m_AppData.state = CN_IEC104AppState_idle; + if(cmd[i].TagtState != CTRL_TYPE_NWAIT_ACK) + { + //return failed to scada + retCmd.CtrlDir = cmd[i].CtrlDir; + retCmd.RtuNo = cmd[i].RtuNo; + retCmd.PointID = cmd[i].PointID; + retCmd.FwSubSystem = cmd[i].FwSubSystem; + retCmd.FwRtuNo = cmd[i].FwRtuNo; + retCmd.FwPointNo = cmd[i].FwPointNo; + retCmd.SubSystem = cmd[i].SubSystem; + strcpy(retCmd.TableName, cmd[i].TableName); + strcpy(retCmd.ColumnName, cmd[i].ColumnName); + strcpy(retCmd.TagName, cmd[i].TagName); + strcpy(retCmd.RtuName, cmd[i].RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd[i].CtrlActType; + sprintf(retCmd.strParam, I18N_C("IEC104 遥调失败!RtuNo:%d 遥调点:%d 范围超出"), m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + //m_AppData.lastCotrolcmd = CN_IEC104NoCmd; + //m_AppData.state = CN_IEC104AppState_idle; + } + + LOGDEBUG("IEC104 Ao Failed!RtuNo:%d PointNo:%d exceed range", m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID); } else { @@ -3923,58 +4197,65 @@ void CIEC104DataProcThread::AoManyCmdProcess() data[writex++] = *(pTemp + 1); data[writex++] = *(pTemp + 2); data[writex++] = *(pTemp + 3); - sprintf(retCmd.strParam, I18N("IEC104 遥调成功!RtuNo:%d value=%f").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID, fValue); + sprintf(retCmd.strParam, I18N_C("IEC104 遥调成功!RtuNo:%d value=%f"), m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID, fValue); LOGDEBUG("IEC104 遥调成功!RtuNo:%d PointNo:%d value=%f", m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID, fValue); } else//CN_IEC104AoNaCmd { data[writex++] = setValue & 0xff; data[writex++] = (setValue >> 8) & 0xff; - sprintf(retCmd.strParam, I18N("IEC104 遥调成功!RtuNo:%d value=%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID, setValue); + sprintf(retCmd.strParam, I18N_C("IEC104 遥调成功!RtuNo:%d value=%d"), m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID, setValue); LOGDEBUG("IEC104 遥调成功!RtuNo:%d PointNo:%d value=%d", m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID, setValue); } - //2019-03-18 thxiao 为适应转发规约增加 - retCmd.CtrlDir = cmd[i].CtrlDir; - retCmd.RtuNo = cmd[i].RtuNo; - retCmd.PointID = cmd[i].PointID; - retCmd.FwSubSystem = cmd[i].FwSubSystem; - retCmd.FwRtuNo = cmd[i].FwRtuNo; - retCmd.FwPointNo = cmd[i].FwPointNo; - retCmd.SubSystem = cmd[i].SubSystem; - //return failed to scada - strcpy(retCmd.TableName, cmd[i].TableName); - strcpy(retCmd.ColumnName, cmd[i].ColumnName); - strcpy(retCmd.TagName, cmd[i].TagName); - strcpy(retCmd.RtuName, cmd[i].RtuName); - retCmd.retStatus = CN_ControlSuccess; - retCmd.CtrlActType = cmd[i].CtrlActType; - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + + if(cmd[i].TagtState != CTRL_TYPE_NWAIT_ACK) + { + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd[i].CtrlDir; + retCmd.RtuNo = cmd[i].RtuNo; + retCmd.PointID = cmd[i].PointID; + retCmd.FwSubSystem = cmd[i].FwSubSystem; + retCmd.FwRtuNo = cmd[i].FwRtuNo; + retCmd.FwPointNo = cmd[i].FwPointNo; + retCmd.SubSystem = cmd[i].SubSystem; + //return failed to scada + strcpy(retCmd.TableName, cmd[i].TableName); + strcpy(retCmd.ColumnName, cmd[i].ColumnName); + strcpy(retCmd.TagName, cmd[i].TagName); + strcpy(retCmd.RtuName, cmd[i].RtuName); + retCmd.retStatus = CN_ControlSuccess; + retCmd.CtrlActType = cmd[i].CtrlActType; + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } } } else { - //2019-03-18 thxiao 为适应转发规约增加 - retCmd.CtrlDir = cmd[i].CtrlDir; - retCmd.RtuNo = cmd[i].RtuNo; - retCmd.PointID = cmd[i].PointID; - retCmd.FwSubSystem = cmd[i].FwSubSystem; - retCmd.FwRtuNo = cmd[i].FwRtuNo; - retCmd.FwPointNo = cmd[i].FwPointNo; - retCmd.SubSystem = cmd[i].SubSystem; - //return failed to scada - strcpy(retCmd.TableName, cmd[i].TableName); - strcpy(retCmd.ColumnName, cmd[i].ColumnName); - strcpy(retCmd.TagName, cmd[i].TagName); - strcpy(retCmd.RtuName, cmd[i].RtuName); - retCmd.retStatus = CN_ControlPointErr; - retCmd.CtrlActType = cmd[i].CtrlActType; - sprintf(retCmd.strParam, I18N("IEC104 遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID); - LOGDEBUG("IEC104 Ao failed!RtuNo:%d Can not find the PointNo:%d", m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + if(cmd[i].TagtState != CTRL_TYPE_NWAIT_ACK) + { + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd[i].CtrlDir; + retCmd.RtuNo = cmd[i].RtuNo; + retCmd.PointID = cmd[i].PointID; + retCmd.FwSubSystem = cmd[i].FwSubSystem; + retCmd.FwRtuNo = cmd[i].FwRtuNo; + retCmd.FwPointNo = cmd[i].FwPointNo; + retCmd.SubSystem = cmd[i].SubSystem; + //return failed to scada + strcpy(retCmd.TableName, cmd[i].TableName); + strcpy(retCmd.ColumnName, cmd[i].ColumnName); + strcpy(retCmd.TagName, cmd[i].TagName); + strcpy(retCmd.RtuName, cmd[i].RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd[i].CtrlActType; + sprintf(retCmd.strParam, I18N_C("IEC104 遥调失败!RtuNo:%d 找不到遥调点:%d"), m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + + LOGDEBUG("IEC104 Ao failed!RtuNo:%d Can not find the PointNo:%d", m_ptrCFesRtu->m_Param.RtuNo, cmd[i].PointID); } } } @@ -3991,6 +4272,202 @@ void CIEC104DataProcThread::AoManyCmdProcess() } +void CIEC104DataProcThread::MoCmdProcess() +{ + byte data[100]; + SFesRxMoCmd cmd; + SFesTxMoCmd retCmd; + short setValue; + SFesMo *pMo=NULL; + int writex,infoAddr; + float fValue,tempValue; + int failed; + + m_AppData.controlTimeout = 0; + writex = 0; + if(m_ptrCFesRtu->ReadRxMoCmd(1,&cmd)==1) + { + //get the cmd ok + //LOGDEBUG("TableName:%s ColumnName:%s TagName:%s RtuName:%s",cmd.TableName,cmd.ColumnName,cmd.TagName,cmd.RtuName); + //memset(&retCmd,0,sizeof(retCmd)); + memcpy(&m_AppData.moCmd,&cmd,sizeof(cmd)); + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + if (m_AppData.state < CN_IEC104AppState_idle)//通信中断 + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N_C("IEC104 遥调失败!RtuNo:%d 通信中断"), m_ptrCFesRtu->m_Param.RtuNo); + LOGDEBUG("IEC104 Ao Failed!RtuNo:%d disconnect",m_ptrCFesRtu->m_Param.RtuNo); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_IEC104NoCmd; + return; + } + if((pMo = GetFesMoByPointNo(m_ptrCFesRtu,cmd.PointID))!=NULL) + { + tempValue = static_cast(cmd.iValue); + failed = 0; + if(pMo->Coeff!=0) + { + fValue=(tempValue-pMo->Base)/pMo->Coeff; + if(pMo->MaxRange>pMo->MinRange) + { + if((fValueMinRange)||(fValue>pMo->MaxRange)) + failed = 1; + } + } + else + { + failed = 1; + } + + if(failed == 1) + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N_C("IEC104 遥调失败!RtuNo:%d 遥调点:%d 范围超出"), m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG("IEC104 Ao Failed!RtuNo:%d PointNo:%d exceed range",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&retCmd); + m_AppData.lastCotrolcmd = CN_IEC104NoCmd; + m_AppData.state = CN_IEC104AppState_idle; + } + else + { + setValue = (short)fValue;//归一化值 + writex = 6; + if(pMo->Param2 ==CN_IEC104AoNbCmd)//command type + { + data[writex++] = C_SE_NB_1; + } + else if(pMo->Param2 ==CN_IEC104AoNcCmd)//command type + { + data[writex++] = C_SE_NC_1; + } + else + { + data[writex++] = C_SE_NA_1; + } + data[writex++] = 0x01;//可变结构限定词(VSQ) + if(m_AppData.trReasonSize ==1) + { + if(cmd.CtrlActType == CN_ControlAbort) + data[writex++] = DEACT; + else + data[writex++] = ACT; + } + else + { + if(cmd.CtrlActType == CN_ControlAbort) + { + data[writex++] = DEACT; + data[writex++] = 0x00; + } + else + { + data[writex++] = ACT; + data[writex++] = 0x00; + } + } + if(m_AppData.publicAddrSize ==1) + data[writex++] = m_AppData.address; + else + { + data[writex++] = m_AppData.address&0xff; + data[writex++] = (m_AppData.address>>8)&0xff; + } + infoAddr = pMo->Param1+m_AppData.aoStartAddress; //远动号从点序号移植到规约参数1 + if(m_AppData.infoAddrSize ==1) + data[writex++] = infoAddr; + else + if(m_AppData.infoAddrSize ==2) + { + data[writex++] = infoAddr&0xff; + data[writex++] = (infoAddr>>8)&0xff; + } + else + { + data[writex++] = infoAddr&0xff; + data[writex++] = (infoAddr>>8)&0xff; + data[writex++] = (infoAddr>>16)&0xff; + } + if(pMo->Param2 ==CN_IEC104AoNbCmd)//command type + { + data[writex++] = setValue&0xff; + data[writex++] = (setValue>>8)&0xff; + } + else if(pMo->Param2 ==CN_IEC104AoNcCmd)//command type + { + byte *pTemp; + pTemp = (byte*)&fValue; + data[writex++] = *pTemp; + data[writex++] = *(pTemp+1); + data[writex++] = *(pTemp+2); + data[writex++] = *(pTemp+3); + } + else//CN_IEC104AoNaCmd + { + data[writex++] = setValue&0xff; + data[writex++] = (setValue>>8)&0xff; + } + if(cmd.CtrlActType == CN_ControlSelect) + data[writex++] = 0x80; + else//abort or execute + data[writex++] = 0x00; + FillIFrameHeader(data,writex); + + SendDataToPort(data,writex); + + memcpy(&m_AppData.aoCmd,&cmd,sizeof(cmd)); + m_AppData.lastCotrolcmd = CN_IEC104MoCmd; + m_AppData.state = CN_IEC104AppState_waitControlResp; + m_AppData.controlTimeout = getMonotonicMsec();//getUTCTimeMsec();//需要处理控制超时,所以置上时间。 + } + } + else + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + sprintf(retCmd.strParam,I18N_C("IEC104 遥调失败!RtuNo:%d 找不到遥调点:%d"), m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG("IEC104 Ao failed!RtuNo:%d Can not find the PointNo:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&retCmd); + m_AppData.lastCotrolcmd = CN_IEC104NoCmd; + m_AppData.state = CN_IEC104AppState_idle; + } + } +} + /** * @brief CIEC104DataProcThread::CmdControlRespProcess @@ -4003,6 +4480,7 @@ bool CIEC104DataProcThread::CmdControlRespProcess(int okFlag) { SFesTxDoCmd retDoCmd; SFesTxAoCmd retAoCmd; + SFesTxMoCmd retMoCmd; if(m_AppData.state != CN_IEC104AppState_waitControlResp) return false; @@ -4015,15 +4493,13 @@ bool CIEC104DataProcThread::CmdControlRespProcess(int okFlag) if(okFlag) { retDoCmd.retStatus = CN_ControlSuccess; - //sprintf(retDoCmd.strParam,"遥控成功!RtuNo:%d 遥控点:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); - sprintf(retDoCmd.strParam,I18N("IEC104 遥控成功!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + sprintf(retDoCmd.strParam,I18N_C("IEC104 遥控成功!RtuNo:%d 遥控点:%d"), m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); LOGDEBUG("1 IEC104 Do succeed!RtuNo:%d PointNo:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); } else { retDoCmd.retStatus = CN_ControlFailed; - //sprintf(retDoCmd.strParam,"遥控失败!RtuNo:%d 遥控点:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); - sprintf(retDoCmd.strParam,I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + sprintf(retDoCmd.strParam,I18N_C("遥控失败!RtuNo:%d 遥控点:%d"),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); LOGDEBUG("2 IEC104 Do failed!RtuNo:%d PointNo:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); } strcpy(retDoCmd.TableName,m_AppData.doCmd.TableName); @@ -4054,34 +4530,71 @@ bool CIEC104DataProcThread::CmdControlRespProcess(int okFlag) if(okFlag) { retAoCmd.retStatus = CN_ControlSuccess; - //sprintf(retAoCmd.strParam,"遥调成功!RtuNo:%d 遥调点:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); - sprintf(retAoCmd.strParam,I18N("遥调成功!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); + sprintf(retAoCmd.strParam,I18N_C("遥调成功!RtuNo:%d 遥调点:%d"),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); LOGDEBUG("3 IEC104 Ao succeed!RtuNo:%d PointNo:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); } else { retAoCmd.retStatus = CN_ControlFailed; - //sprintf(retAoCmd.strParam,"遥调失败!RtuNo:%d 遥调点:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); - sprintf(retAoCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); + sprintf(retAoCmd.strParam,I18N_C("遥调失败!RtuNo:%d 遥调点:%d"),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); LOGDEBUG("4 IEC104 Ao failed!RtuNo:%d PointNo:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); } - strcpy(retAoCmd.TableName,m_AppData.aoCmd.TableName); - strcpy(retAoCmd.ColumnName,m_AppData.aoCmd.ColumnName); - strcpy(retAoCmd.TagName,m_AppData.aoCmd.TagName); - strcpy(retAoCmd.RtuName,m_AppData.aoCmd.RtuName); - retAoCmd.CtrlActType = m_AppData.aoCmd.CtrlActType; - //2019-03-18 thxiao 为适应转发规约增加 - retAoCmd.CtrlDir = m_AppData.aoCmd.CtrlDir; - retAoCmd.RtuNo = m_AppData.aoCmd.RtuNo; - retAoCmd.PointID = m_AppData.aoCmd.PointID; - retAoCmd.FwSubSystem = m_AppData.aoCmd.FwSubSystem; - retAoCmd.FwRtuNo = m_AppData.aoCmd.FwRtuNo; - retAoCmd.FwPointNo = m_AppData.aoCmd.FwPointNo; - retAoCmd.SubSystem = m_AppData.aoCmd.SubSystem; - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retAoCmd); + if(m_AppData.aoCmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + strcpy(retAoCmd.TableName,m_AppData.aoCmd.TableName); + strcpy(retAoCmd.ColumnName,m_AppData.aoCmd.ColumnName); + strcpy(retAoCmd.TagName,m_AppData.aoCmd.TagName); + strcpy(retAoCmd.RtuName,m_AppData.aoCmd.RtuName); + retAoCmd.CtrlActType = m_AppData.aoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retAoCmd.CtrlDir = m_AppData.aoCmd.CtrlDir; + retAoCmd.RtuNo = m_AppData.aoCmd.RtuNo; + retAoCmd.PointID = m_AppData.aoCmd.PointID; + retAoCmd.FwSubSystem = m_AppData.aoCmd.FwSubSystem; + retAoCmd.FwRtuNo = m_AppData.aoCmd.FwRtuNo; + retAoCmd.FwPointNo = m_AppData.aoCmd.FwPointNo; + retAoCmd.SubSystem = m_AppData.aoCmd.SubSystem; + + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retAoCmd); + } + + m_AppData.lastCotrolcmd = CN_IEC104NoCmd; + m_AppData.state = CN_IEC104AppState_idle; + m_AppData.controlTimeout = 0; + return true; + break; + case CN_IEC104MoCmd: + if(okFlag) + { + retMoCmd.retStatus = CN_ControlSuccess; + sprintf(retMoCmd.strParam,I18N_C("遥调成功!RtuNo:%d 遥调点:%d"),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.moCmd.PointID); + LOGDEBUG("3 IEC104 Ao succeed!RtuNo:%d PointNo:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.moCmd.PointID); + } + else + { + retMoCmd.retStatus = CN_ControlFailed; + sprintf(retMoCmd.strParam,I18N_C("遥调失败!RtuNo:%d 遥调点:%d"),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.moCmd.PointID); + LOGDEBUG("4 IEC104 Ao failed!RtuNo:%d PointNo:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.moCmd.PointID); + } + strcpy(retMoCmd.TableName,m_AppData.moCmd.TableName); + strcpy(retMoCmd.ColumnName,m_AppData.moCmd.ColumnName); + strcpy(retMoCmd.TagName,m_AppData.moCmd.TagName); + strcpy(retMoCmd.RtuName,m_AppData.moCmd.RtuName); + retMoCmd.CtrlActType = m_AppData.moCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retMoCmd.CtrlDir = m_AppData.moCmd.CtrlDir; + retMoCmd.RtuNo = m_AppData.moCmd.RtuNo; + retMoCmd.PointID = m_AppData.moCmd.PointID; + retMoCmd.FwSubSystem = m_AppData.moCmd.FwSubSystem; + retMoCmd.FwRtuNo = m_AppData.moCmd.FwRtuNo; + retMoCmd.FwPointNo = m_AppData.moCmd.FwPointNo; + retMoCmd.SubSystem = m_AppData.moCmd.SubSystem; + + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&retmoCmd); //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1,&retAoCmd); + m_ptrCFesBase->WritexMoRespCmdBuf(1,&retMoCmd); m_AppData.lastCotrolcmd = CN_IEC104NoCmd; m_AppData.state = CN_IEC104AppState_idle; m_AppData.controlTimeout = 0; @@ -4222,6 +4735,7 @@ void CIEC104DataProcThread::RecvAoControlProcess() CmdControlRespProcess(0); } } + /** * @brief CIEC104DataProcThread::getUTCTime24Sec * @param 短时标接口结构,转换为UTC毫秒数 @@ -4281,7 +4795,7 @@ void CIEC104DataProcThread::ErrorControlRespProcess() TxDoCmd.FwPointNo = RxDoCmd.FwPointNo; TxDoCmd.SubSystem = RxDoCmd.SubSystem; - sprintf(TxDoCmd.strParam,I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,RxDoCmd.PointID); + sprintf(TxDoCmd.strParam,I18N_C("遥控失败!RtuNo:%d 遥控点:%d"),m_ptrCFesRtu->m_Param.RtuNo,RxDoCmd.PointID); LOGDEBUG ("网络已断开 DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",RxDoCmd.CtrlActType,RxDoCmd.iValue,RxDoCmd.RtuName,RxDoCmd.PointID); //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&TxDoCmd); //2019-03-18 thxiao 为适应转发规约 @@ -4294,26 +4808,29 @@ void CIEC104DataProcThread::ErrorControlRespProcess() { if(m_ptrCFesRtu->ReadRxAoCmd(1,&RxAoCmd)==1) { - //memset(&TxAoCmd,0,sizeof(TxAoCmd)); - strcpy(TxAoCmd.TableName,RxAoCmd.TableName); - strcpy(TxAoCmd.ColumnName,RxAoCmd.ColumnName); - strcpy(TxAoCmd.TagName,RxAoCmd.TagName); - strcpy(TxAoCmd.RtuName,RxAoCmd.RtuName); - TxAoCmd.retStatus = CN_ControlFailed; - sprintf(TxAoCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,RxAoCmd.PointID); - TxAoCmd.CtrlActType = RxAoCmd.CtrlActType; - //2019-03-18 thxiao 为适应转发规约增加 - TxAoCmd.CtrlDir = RxAoCmd.CtrlDir; - TxAoCmd.RtuNo = RxAoCmd.RtuNo; - TxAoCmd.PointID = RxAoCmd.PointID; - TxAoCmd.FwSubSystem = RxAoCmd.FwSubSystem; - TxAoCmd.FwRtuNo = RxAoCmd.FwRtuNo; - TxAoCmd.FwPointNo = RxAoCmd.FwPointNo; - TxAoCmd.SubSystem = RxAoCmd.SubSystem; - LOGDEBUG("网络已断开 AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", RxAoCmd.CtrlActType, RxAoCmd.fValue, RxAoCmd.RtuName, RxAoCmd.PointID); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&TxAoCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1,&TxAoCmd); + if(RxAoCmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + strcpy(TxAoCmd.TableName,RxAoCmd.TableName); + strcpy(TxAoCmd.ColumnName,RxAoCmd.ColumnName); + strcpy(TxAoCmd.TagName,RxAoCmd.TagName); + strcpy(TxAoCmd.RtuName,RxAoCmd.RtuName); + TxAoCmd.retStatus = CN_ControlFailed; + sprintf(TxAoCmd.strParam,I18N_C("遥调失败!RtuNo:%d 遥调点:%d"),m_ptrCFesRtu->m_Param.RtuNo,RxAoCmd.PointID); + TxAoCmd.CtrlActType = RxAoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxAoCmd.CtrlDir = RxAoCmd.CtrlDir; + TxAoCmd.RtuNo = RxAoCmd.RtuNo; + TxAoCmd.PointID = RxAoCmd.PointID; + TxAoCmd.FwSubSystem = RxAoCmd.FwSubSystem; + TxAoCmd.FwRtuNo = RxAoCmd.FwRtuNo; + TxAoCmd.FwPointNo = RxAoCmd.FwPointNo; + TxAoCmd.SubSystem = RxAoCmd.SubSystem; + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&TxAoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&TxAoCmd); + } + + LOGDEBUG("网络已断开 AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", RxAoCmd.CtrlActType, RxAoCmd.fValue, RxAoCmd.RtuName, RxAoCmd.PointID); } } else @@ -4336,7 +4853,7 @@ void CIEC104DataProcThread::ErrorControlRespProcess() TxMoCmd.FwRtuNo = RxMoCmd.FwRtuNo; TxMoCmd.FwPointNo = RxMoCmd.FwPointNo; TxMoCmd.SubSystem = RxMoCmd.SubSystem; - sprintf(TxMoCmd.strParam, I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxMoCmd.PointID); + sprintf(TxMoCmd.strParam, I18N_C("混合量输出成功!RtuNo:%d 混合量输出点:%d"), m_ptrCFesRtu->m_Param.RtuNo, RxMoCmd.PointID); LOGDEBUG ("网络已断开 MO混合量执行失败 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",RxMoCmd.CtrlActType,RxMoCmd.iValue,RxMoCmd.RtuName,RxMoCmd.PointID); //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&TxMoCmd); @@ -4345,3 +4862,148 @@ void CIEC104DataProcThread::ErrorControlRespProcess() } } } + +/** + * @brief 建立通过遥测拆分bit的地址映射 + * @return + */ +void CIEC104DataProcThread::InitBitMapping() +{ + for(int i = 0; i < m_ptrCFesRtu->m_MaxDiPoints;++i) + { + SFesDi *pDi = GetFesDiByPointNo(m_ptrCFesRtu,i); + if(pDi == NULL) + { + continue; + } + //param2:表示是否是按位拆解值,param3表示遥测的规约参数1,param4表示第几位,从最低位开始,从0开始 + if(pDi->Param2 == CONST_PARAM2_SPLIT_BIT && pDi->Param4 >=0 && pDi->Param4 <= 32) //表示通过遥测值按位拆分 + { + m_mapYC2PntNo[pDi->Param3].push_back(pDi->PointNo); //遥测地址 -> 点号 + } + } +} + +void CIEC104DataProcThread::CacheSplitBitByMi(const int &nAddrIndex,const SFesRtuMiValue &stMiValue) +{ + //复用了一下SFesRtuMiValue结构,但是PointNo实际含义是规约参数1的值 + m_vecSplitBitMiValue.push_back(stMiValue); + m_vecSplitBitMiValue[m_vecSplitBitMiValue.size() - 1].PointNo = nAddrIndex; +} + +void CIEC104DataProcThread::HandleSplitBitCache() +{ + int ChgCount = 0; + int SoeCount = 0; + int ValueCount = 0; + int statusChg = 0; + byte bitValue = 0; + enum {DI_BUF_SIZE = 128}; + SFesRtuDiValue DiValue[DI_BUF_SIZE]; + SFesChgDi ChgDi[DI_BUF_SIZE]; + SFesSoeEvent SoeEvent[DI_BUF_SIZE]; + + for(int i = 0; i < m_vecSplitBitMiValue.size();++i) + { + const SFesRtuMiValue &stMiValue = m_vecSplitBitMiValue[i]; + //复用了SFesRtuAiValue结构,PointNo实际含义是遥测的规约参数1 + std::map >::const_iterator pIter = m_mapYC2PntNo.find(stMiValue.PointNo); + if(pIter == m_mapYC2PntNo.end()) + { + continue; + } + + //pDi->Param4表示第几个bit,初始化时已经判断了值的合法性,0~32 + std::bitset<32> bitsetValue(stMiValue.Value); + + const std::vector &vecPntNo = pIter->second; + for(int i = 0; i < vecPntNo.size();++i) + { + int nPntNo = vecPntNo[i]; + SFesDi *pDi = GetFesDiByPointNo(m_ptrCFesRtu,nPntNo); + if(pDi == NULL) + { + continue; + } + + bitValue = pDi->Revers ? (!bitsetValue.test(pDi->Param4)) : bitsetValue.test(pDi->Param4); + //2021-09-16 thxiao 通信状态位变化也需要报告,及时通知画面刷新 + if ((pDi->Status&CN_FesValueComDown) != (stMiValue.Status&CN_FesValueComDown)) + { + statusChg = 1; + } + else + { + statusChg = 0; + } + + //主机才报告变化数据,更新过的点才能报告变化 + if(((bitValue != pDi->Value) || (statusChg == 1)) && (g_IEC104IsMainFes==true) && (pDi->Status&CN_FesValueUpdate)) + { + memcpy(ChgDi[ChgCount].TableName,pDi->TableName,CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName,pDi->ColumnName,CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName,pDi->TagName,CN_FesMaxTagSize); + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = stMiValue.Status; + ChgDi[ChgCount].time = stMiValue.time; + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgCount++; + if(ChgCount >= DI_BUF_SIZE) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if((m_AppData.createSoe)&&(bitValue != pDi->Value)) + { + SoeEvent[SoeCount].time = stMiValue.time; + memcpy(SoeEvent[SoeCount].TableName,pDi->TableName,CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName,pDi->ColumnName,CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName,pDi->TagName,CN_FesMaxTagSize); + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].Status = stMiValue.Status; + SoeEvent[SoeCount].FaultNum =0; + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeCount++; + if(SoeCount >= DI_BUF_SIZE) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount,&SoeEvent[0]); + SoeCount = 0; + } + } + } + //更新点值 + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = stMiValue.Status; + DiValue[ValueCount].time = stMiValue.time; + ValueCount++; + if(ValueCount >= DI_BUF_SIZE) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount,&DiValue[0]); + } + } + } + + + if(ChgCount>0) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + } + if(SoeCount>0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount,&SoeEvent[0]); + } + if(ValueCount>0) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount,&DiValue[0]); + } + + m_vecSplitBitMiValue.clear(); +} diff --git a/product/src/fes/protocol/iec104/IEC104DataProcThread.h b/product/src/fes/protocol/iec104/IEC104DataProcThread.h index b7d14e26..7c5a421a 100644 --- a/product/src/fes/protocol/iec104/IEC104DataProcThread.h +++ b/product/src/fes/protocol/iec104/IEC104DataProcThread.h @@ -163,7 +163,6 @@ typedef struct{ byte strictComMode; //1:接收序号不对,断开网络。0:忽略 byte createSoe; //1:对于不产生SOE的 IEC104 Server在遥信帧中产生SOE. 0: 忽略 byte soeOnce; //1:装置DI变位只产生一次SOE; 0:装置DI变位产生SOE,及遥信变位 - byte soeCheckDi; //1:Soe判断状态; 0:Soe不判断状态 byte ignoreInvalid; //忽略数据无效位 1:忽略 0:不忽略 byte aoCmdMode; //2019-08-07 thxiao AO控制模式; 0:允许发送单AO命令处理 1:允许同时发送多AO命令处理 byte aoCmdType; //对于允许同时发送多AO命令处理,所有的AO命令使用同一种类型 @@ -203,6 +202,7 @@ typedef struct{ uint64 controlTimeout; SFesRxDoCmd doCmd; SFesRxAoCmd aoCmd; + SFesRxMoCmd moCmd; int lastCotrolcmd; int respTimeoutReset; //通道参数传递过来 @@ -224,7 +224,6 @@ typedef struct{ byte strictComMode; //1:接收序号不对,断开网络。0:忽略 byte createSoe; //1:对于不产生SOE的 IEC104 Server在遥信帧中产生SOE. 0: 忽略 byte soeOnce; //1:装置DI变位只产生一次SOE; 0:装置DI变位产生SOE,及遥信变位 - byte soeCheckDi; //1:Soe判断状态; 0:Soe不判断状态 byte ignoreInvalid; //忽略数据无效位 1:忽略 0:不忽略 byte aoCmdMode; //2019-08-07 thxiao AO控制模式; 0:允许发送单AO命令处理 1:允许同时发送多AO命令处理 byte aoCmdType; //对于允许同时发送多AO命令处理,所有的AO命令使用同一种类型 @@ -265,6 +264,8 @@ public: CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,IEC104 tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 SIEC104AppData m_AppData; //内部应用数据结构 + std::map > m_mapYC2PntNo; //用于遥测按位获取功能的地址映射表,主键为遥测地址,值为要拆分的遥信点的点号 + std::vector m_vecSplitBitMiValue; //缓存需要拆解的值 private: int SendProcess(); int RecvProcess(); @@ -296,9 +297,11 @@ private: void RecvAccWithoutTimeProcess(); void RecvAccWithTime24Process(); void RecvAccWithTime56Process(); + void RecvMiWithoutTimeProcess(); void DoCmdProcess(); void AoSingleCmdProcess(); void AoManyCmdProcess(); + void MoCmdProcess(); bool CmdControlRespProcess(int okFlag); void RecvDoControlProcess(); void RecvAoControlProcess(); @@ -306,6 +309,10 @@ private: void ErrorControlRespProcess(); /*短时标接口结构,转换为UTC毫秒数*/ __inline uint64 getUTCTime24Sec(int nMin, int nMsec); + + void InitBitMapping(); //建立通过遥测拆分bit的地址映射 + void CacheSplitBitByMi(const int &nAddrIndex,const SFesRtuMiValue &stMiValue); + void HandleSplitBitCache(); }; typedef boost::shared_ptr CIEC104DataProcThreadPtr; diff --git a/product/src/fes/protocol/iec104V2/IEC104V2.cpp b/product/src/fes/protocol/iec104V2/IEC104V2.cpp index 1c77977d..e9da427c 100644 --- a/product/src/fes/protocol/iec104V2/IEC104V2.cpp +++ b/product/src/fes/protocol/iec104V2/IEC104V2.cpp @@ -53,6 +53,8 @@ int EX_ChanTimer(int ChanNo) int EX_ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + g_IEC104V2ChanelRun=false;//使所有的线程退出。 Iec104.InformTcpThreadExit(); return iotSuccess; @@ -94,7 +96,7 @@ int CIEC104V2::SetBaseAddr(void *address) int CIEC104V2::SetProperty(int IsMainFes) { - g_IEC104V2IsMainFes = IsMainFes; + g_IEC104V2IsMainFes = (IsMainFes != 0); LOGDEBUG("CIEC104V2::SetProperty g_IEC104V2IsMainFes:%d",IsMainFes); return iotSuccess; } @@ -440,14 +442,6 @@ int CIEC104V2::ReadConfigParam() else param.soeOnce = 0; - if (config.getIntValue(strRtuNo, "soe_check_di", ivalue) == iotSuccess) - { - param.soeCheckDi = ivalue; - items++; - } - else - param.soeCheckDi = 0; - if (config.getIntValue(strRtuNo, "ignore_invalid_data", ivalue) == iotSuccess) { param.ignoreInvalid = ivalue; diff --git a/product/src/fes/protocol/iec104V2/IEC104V2DataProcThread.cpp b/product/src/fes/protocol/iec104V2/IEC104V2DataProcThread.cpp index 5c03c353..9dd28df1 100644 --- a/product/src/fes/protocol/iec104V2/IEC104V2DataProcThread.cpp +++ b/product/src/fes/protocol/iec104V2/IEC104V2DataProcThread.cpp @@ -12,8 +12,10 @@ #include "TcpClientThread.h" #include "pub_utility_api/CommonConfigParse.h" #include "pub_utility_api/I18N.h" +#include "FesMessage.pb.h" using namespace iot_public; +using namespace iot_idl; extern bool g_IEC104V2IsMainFes; extern bool g_IEC104V2ChanelRun; @@ -73,7 +75,6 @@ CTimerThreadBase("IEC104V2DataProcThread",g_IEC104V2ThreadTime,0,true) m_AppData.strictComMode=vecAppParam[i].strictComMode; //1:接收序号不对,断开网络。0:忽略 m_AppData.soeOnce = vecAppParam[i].soeOnce; //1:遥信变位只产生SOE;0:遥信变位只产生SOE和变位 m_AppData.createSoe=vecAppParam[i].createSoe; //1:对于不产生SOE的 IEC104V2 Server在遥信帧中产生SOE. 0: 忽略 - m_AppData.soeCheckDi = vecAppParam[i].soeCheckDi; //1:Soe判断状态; 0:Soe不判断状态 m_AppData.ignoreInvalid = vecAppParam[i].ignoreInvalid;//忽略数据无效位 1:忽略 0:不忽略 m_AppData.aoCmdMode = vecAppParam[i].aoCmdMode;//AO控制模式; 0:允许发送单AO命令处理 1:允许同时发送多AO命令处理 m_AppData.aoCmdType = vecAppParam[i].aoCmdType; @@ -254,7 +255,6 @@ int CIEC104V2DataProcThread::InitConfigParam() m_AppData.infoAddrSize=3; //信息体地址长度 1\2\3 m_AppData.strictComMode=0; //1:接收序号不对,断开网络。0:忽略 m_AppData.createSoe=0; //1:对于不产生SOE的 IEC104V2 Server在遥信帧中产生SOE. 0: 忽略 - m_AppData.soeCheckDi = 0; //1:Soe判断状态; 0:Soe不判断状态 m_AppData.ignoreInvalid = 0;//忽略数据无效位 1:忽略 0:不忽略 m_AppData.diStartAddress = 0x0001; m_AppData.aiStartAddress = 0x0701; @@ -408,13 +408,6 @@ int CIEC104V2DataProcThread::ReadConfigParam() else m_AppData.soeOnce = 0; - if (config.getIntValue(strRtuNo, "soe_check_di", ivalue) == iotSuccess) - { - m_AppData.soeCheckDi = ivalue; - } - else - m_AppData.soeCheckDi = 0; - if(config.getIntValue(strRtuNo,"ignore_invalid_data",ivalue) == iotSuccess) { m_AppData.ignoreInvalid = ivalue; @@ -1819,9 +1812,6 @@ void CIEC104V2DataProcThread::RecvDiWithTime24Process() m_ptrCFesBase->WriteChgDiValue(pCurrentRtu, ChgCount, &ChgDi[0]); ChgCount = 0; } - //鄂州机场SOE需要判断是否变位 - if (m_AppData.soeCheckDi && (bitValue == pDi->Value)) - continue; //Create Soe memset(&SoeEvent[SoeCount],0,sizeof(SFesSoeEvent)); SoeEvent[SoeCount].time = mSec; @@ -1987,9 +1977,6 @@ void CIEC104V2DataProcThread::RecvDiWithTime56Process() m_ptrCFesBase->WriteChgDiValue(pCurrentRtu, ChgCount, &ChgDi[0]); ChgCount = 0; } - //鄂州机场SOE需要判断是否变位 - if (m_AppData.soeCheckDi && (bitValue == pDi->Value)) - continue; //Create Soe memset(&SoeEvent[SoeCount],0,sizeof(SFesSoeEvent)); SoeEvent[SoeCount].time = mSec; @@ -3308,8 +3295,7 @@ void CIEC104V2DataProcThread::DoCmdProcess(CFesRtuPtr pRtu) strcpy(retCmd.RtuName, cmd.RtuName); retCmd.retStatus = CN_ControlFailed; retCmd.CtrlActType = cmd.CtrlActType; - //sprintf(retCmd.strParam,"IEC104V2 遥控失败!RtuNo:%d 通信中断",pRtu->m_Param.RtuNo); - sprintf(retCmd.strParam, I18N("IEC104V2 遥控失败!RtuNo:%d 通信中断").str().c_str(), pRtu->m_Param.RtuNo); + sprintf(retCmd.strParam, I18N_C("IEC104V2 遥控失败!RtuNo:%d 通信中断"), pRtu->m_Param.RtuNo); LOGDEBUG("IEC104V2 Do failed!RtuNo:%d comm disconnect", pRtu->m_Param.RtuNo); //2019-02-21 thxiao 为适应转发规约 @@ -3327,7 +3313,7 @@ void CIEC104V2DataProcThread::DoCmdProcess(CFesRtuPtr pRtu) strcpy(retCmd.RtuName, cmd.RtuName); retCmd.retStatus = CN_ControlFailed; retCmd.CtrlActType = cmd.CtrlActType; - sprintf(retCmd.strParam, I18N("IEC104V2 遥控失败! RtuNo:%d DO:%d 闭锁!").str().c_str(), pRtu->m_Param.RtuNo, cmd.PointID); + sprintf(retCmd.strParam, I18N_C("IEC104V2 遥控失败! RtuNo:%d DO:%d 闭锁!"), pRtu->m_Param.RtuNo, cmd.PointID); LOGDEBUG("IEC104V2 遥控失败! RtuNo:%d DO:%d 闭锁!", pRtu->m_Param.RtuNo, cmd.PointID); //2019-02-21 thxiao 为适应转发规约 m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); @@ -3427,8 +3413,7 @@ void CIEC104V2DataProcThread::DoCmdProcess(CFesRtuPtr pRtu) strcpy(retCmd.RtuName, cmd.RtuName); retCmd.retStatus = CN_ControlPointErr; retCmd.CtrlActType = cmd.CtrlActType; - //sprintf(retCmd.strParam,"IEC104V2 遥控失败!RtuNo:%d 找不到遥控点:%d",pRtu->m_Param.RtuNo,cmd.PointID); - sprintf(retCmd.strParam, I18N("IEC104V2 遥控失败!RtuNo:%d 找不到遥控点:%d").str().c_str(), pRtu->m_Param.RtuNo, cmd.PointID); + sprintf(retCmd.strParam, I18N_C("IEC104V2 遥控失败!RtuNo:%d 找不到遥控点:%d"), pRtu->m_Param.RtuNo, cmd.PointID); LOGDEBUG("IEC104V2 Do failed!RtuNo:%d can not find PointNo:%d", pRtu->m_Param.RtuNo, cmd.PointID); //2019-02-21 thxiao 为适应转发规约 m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); @@ -3471,22 +3456,25 @@ void CIEC104V2DataProcThread::AoSingleCmdProcess(CFesRtuPtr pRtu) retCmd.FwRtuNo = cmd.FwRtuNo; retCmd.FwPointNo = cmd.FwPointNo; retCmd.SubSystem = cmd.SubSystem; - if (m_AppData.state < CN_IEC104V2AppState_idle)//通信中断 - { - //return failed to scada - strcpy(retCmd.TableName, cmd.TableName); - strcpy(retCmd.ColumnName, cmd.ColumnName); - strcpy(retCmd.TagName, cmd.TagName); - strcpy(retCmd.RtuName, cmd.RtuName); - retCmd.retStatus = CN_ControlPointErr; - retCmd.CtrlActType = cmd.CtrlActType; - //sprintf(retCmd.strParam,"IEC104V2 遥调失败!RtuNo:%d 通信中断",pRtu->m_Param.RtuNo); - sprintf(retCmd.strParam, I18N("IEC104V2 遥调失败!RtuNo:%d 通信中断").str().c_str(), pRtu->m_Param.RtuNo); - LOGDEBUG("IEC104V2 Ao Failed!RtuNo:%d disconnect", pRtu->m_Param.RtuNo); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + if (m_AppData.state < CN_IEC104V2AppState_idle) //< 通信中断 + { + if(cmd.TagtState != CTRL_TYPE_NWAIT_ACK) //< 不需要等待遥控确认,则不发送反馈 + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N_C("IEC104V2 遥调失败!RtuNo:%d 通信中断"), pRtu->m_Param.RtuNo); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + + LOGDEBUG("IEC104V2 Ao Failed!RtuNo:%d disconnect", pRtu->m_Param.RtuNo); m_AppData.lastCotrolcmd = CN_IEC104V2NoCmd; return; } @@ -3508,20 +3496,23 @@ void CIEC104V2DataProcThread::AoSingleCmdProcess(CFesRtuPtr pRtu) if (failed == 1) { - //return failed to scada - strcpy(retCmd.TableName, cmd.TableName); - strcpy(retCmd.ColumnName, cmd.ColumnName); - strcpy(retCmd.TagName, cmd.TagName); - strcpy(retCmd.RtuName, cmd.RtuName); - retCmd.retStatus = CN_ControlPointErr; - retCmd.CtrlActType = cmd.CtrlActType; - //sprintf(retCmd.strParam,"IEC104V2 遥调失败!RtuNo:%d 遥调点:%d 范围超出",pRtu->m_Param.RtuNo,cmd.PointID); - sprintf(retCmd.strParam, I18N("IEC104V2 遥调失败!RtuNo:%d 遥调点:%d 范围超出").str().c_str(), pRtu->m_Param.RtuNo, cmd.PointID); - LOGDEBUG("IEC104V2 Ao Failed!RtuNo:%d PointNo:%d exceed range", pRtu->m_Param.RtuNo, cmd.PointID); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); - m_AppData.lastCotrolcmd = CN_IEC104V2NoCmd; + if(cmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N_C("IEC104V2 遥调失败!RtuNo:%d 遥调点:%d 范围超出"), pRtu->m_Param.RtuNo, cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + + LOGDEBUG("IEC104V2 Ao Failed!RtuNo:%d PointNo:%d exceed range", pRtu->m_Param.RtuNo, cmd.PointID); + m_AppData.lastCotrolcmd = CN_IEC104V2NoCmd; m_AppData.state = CN_IEC104V2AppState_idle; } else @@ -3620,24 +3611,27 @@ void CIEC104V2DataProcThread::AoSingleCmdProcess(CFesRtuPtr pRtu) } else { - //return failed to scada - strcpy(retCmd.TableName, cmd.TableName); - strcpy(retCmd.ColumnName, cmd.ColumnName); - strcpy(retCmd.TagName, cmd.TagName); - strcpy(retCmd.RtuName, cmd.RtuName); - retCmd.retStatus = CN_ControlPointErr; - retCmd.CtrlActType = cmd.CtrlActType; - //2019-03-18 thxiao 为适应转发规约增加 - retCmd.CtrlDir = cmd.CtrlDir; - retCmd.RtuNo = cmd.RtuNo; - retCmd.PointID = cmd.PointID; + if(cmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; - //sprintf(retCmd.strParam,"IEC104V2 遥调失败!RtuNo:%d 找不到遥调点:%d",pRtu->m_Param.RtuNo,cmd.PointID); - sprintf(retCmd.strParam, I18N("IEC104V2 遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(), pRtu->m_Param.RtuNo, cmd.PointID); - LOGDEBUG("IEC104V2 Ao failed!RtuNo:%d Can not find the PointNo:%d", pRtu->m_Param.RtuNo, cmd.PointID); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + sprintf(retCmd.strParam, I18N_C("IEC104V2 遥调失败!RtuNo:%d 找不到遥调点:%d"), pRtu->m_Param.RtuNo, cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + + LOGDEBUG("IEC104V2 Ao failed!RtuNo:%d Can not find the PointNo:%d", pRtu->m_Param.RtuNo, cmd.PointID); m_AppData.lastCotrolcmd = CN_IEC104V2NoCmd; m_AppData.state = CN_IEC104V2AppState_idle; } @@ -3680,6 +3674,11 @@ void CIEC104V2DataProcThread::AoManyCmdProcess(CFesRtuPtr pRtu) //return failed to scada for (i = 0; i < retNum1; i++) { + LOGDEBUG("IEC104V2 Ao Failed!RtuNo:%d disconnect", pRtu->m_Param.RtuNo); + if(cmd[i].TagtState == CTRL_TYPE_NWAIT_ACK) + { + continue; + } retCmd.CtrlDir = cmd[i].CtrlDir; retCmd.RtuNo = cmd[i].RtuNo; retCmd.PointID = cmd[i].PointID; @@ -3694,13 +3693,11 @@ void CIEC104V2DataProcThread::AoManyCmdProcess(CFesRtuPtr pRtu) retCmd.retStatus = CN_ControlPointErr; retCmd.CtrlActType = cmd[i].CtrlActType; - //sprintf(retCmd.strParam,"IEC104V2 遥调失败!RtuNo:%d 通信中断",pRtu->m_Param.RtuNo); - sprintf(retCmd.strParam, I18N("IEC104V2 遥调失败!RtuNo:%d 通信中断").str().c_str(), pRtu->m_Param.RtuNo); - LOGDEBUG("IEC104V2 Ao Failed!RtuNo:%d disconnect", pRtu->m_Param.RtuNo); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + sprintf(retCmd.strParam, I18N_C("IEC104V2 遥调失败!RtuNo:%d 通信中断"), pRtu->m_Param.RtuNo); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); //2019-03-18 thxiao 为适应转发规约 m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); - } + } m_AppData.lastCotrolcmd = CN_IEC104V2NoCmd; return; } @@ -3739,29 +3736,31 @@ void CIEC104V2DataProcThread::AoManyCmdProcess(CFesRtuPtr pRtu) if (failed == 1) { - //return failed to scada - retCmd.CtrlDir = cmd[i].CtrlDir; - retCmd.RtuNo = cmd[i].RtuNo; - retCmd.PointID = cmd[i].PointID; - retCmd.FwSubSystem = cmd[i].FwSubSystem; - retCmd.FwRtuNo = cmd[i].FwRtuNo; - retCmd.FwPointNo = cmd[i].FwPointNo; - retCmd.SubSystem = cmd[i].SubSystem; - strcpy(retCmd.TableName, cmd[i].TableName); - strcpy(retCmd.ColumnName, cmd[i].ColumnName); - strcpy(retCmd.TagName, cmd[i].TagName); - strcpy(retCmd.RtuName, cmd[i].RtuName); - retCmd.retStatus = CN_ControlPointErr; - retCmd.CtrlActType = cmd[i].CtrlActType; - //sprintf(retCmd.strParam,"IEC104V2 遥调失败!RtuNo:%d 遥调点:%d 范围超出",pRtu->m_Param.RtuNo,cmd.PointID); - sprintf(retCmd.strParam, I18N("IEC104V2 遥调失败!RtuNo:%d 遥调点:%d 范围超出").str().c_str(), pRtu->m_Param.RtuNo, cmd[i].PointID); - LOGDEBUG("IEC104V2 Ao Failed!RtuNo:%d PointNo:%d exceed range", pRtu->m_Param.RtuNo, cmd[i].PointID); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); - //m_AppData.lastCotrolcmd = CN_IEC104V2NoCmd; - //m_AppData.state = CN_IEC104V2AppState_idle; - } + if(cmd[i].TagtState != CTRL_TYPE_NWAIT_ACK) + { + //return failed to scada + retCmd.CtrlDir = cmd[i].CtrlDir; + retCmd.RtuNo = cmd[i].RtuNo; + retCmd.PointID = cmd[i].PointID; + retCmd.FwSubSystem = cmd[i].FwSubSystem; + retCmd.FwRtuNo = cmd[i].FwRtuNo; + retCmd.FwPointNo = cmd[i].FwPointNo; + retCmd.SubSystem = cmd[i].SubSystem; + strcpy(retCmd.TableName, cmd[i].TableName); + strcpy(retCmd.ColumnName, cmd[i].ColumnName); + strcpy(retCmd.TagName, cmd[i].TagName); + strcpy(retCmd.RtuName, cmd[i].RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd[i].CtrlActType; + sprintf(retCmd.strParam, I18N_C("IEC104V2 遥调失败!RtuNo:%d 遥调点:%d 范围超出"), pRtu->m_Param.RtuNo, cmd[i].PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + //m_AppData.lastCotrolcmd = CN_IEC104V2NoCmd; + //m_AppData.state = CN_IEC104V2AppState_idle; + } + LOGDEBUG("IEC104V2 Ao Failed!RtuNo:%d PointNo:%d exceed range", pRtu->m_Param.RtuNo, cmd[i].PointID); + } else { count++; @@ -3789,58 +3788,65 @@ void CIEC104V2DataProcThread::AoManyCmdProcess(CFesRtuPtr pRtu) data[writex++] = *(pTemp + 1); data[writex++] = *(pTemp + 2); data[writex++] = *(pTemp + 3); - sprintf(retCmd.strParam, I18N("IEC104V2 遥调成功!RtuNo:%d value=%f").str().c_str(), pRtu->m_Param.RtuNo, cmd[i].PointID, fValue); + sprintf(retCmd.strParam, I18N_C("IEC104V2 遥调成功!RtuNo:%d value=%f"), pRtu->m_Param.RtuNo, cmd[i].PointID, fValue); LOGDEBUG("IEC104V2 遥调成功!RtuNo:%d PointNo:%d value=%f", pRtu->m_Param.RtuNo, cmd[i].PointID, fValue); } else//CN_IEC104V2AoNaCmd { data[writex++] = setValue & 0xff; data[writex++] = (setValue >> 8) & 0xff; - sprintf(retCmd.strParam, I18N("IEC104V2 遥调成功!RtuNo:%d value=%d").str().c_str(), pRtu->m_Param.RtuNo, cmd[i].PointID, setValue); + sprintf(retCmd.strParam, I18N_C("IEC104V2 遥调成功!RtuNo:%d value=%d"), pRtu->m_Param.RtuNo, cmd[i].PointID, setValue); LOGDEBUG("IEC104V2 遥调成功!RtuNo:%d PointNo:%d value=%d", pRtu->m_Param.RtuNo, cmd[i].PointID, setValue); } - //2019-03-18 thxiao 为适应转发规约增加 - retCmd.CtrlDir = cmd[i].CtrlDir; - retCmd.RtuNo = cmd[i].RtuNo; - retCmd.PointID = cmd[i].PointID; - retCmd.FwSubSystem = cmd[i].FwSubSystem; - retCmd.FwRtuNo = cmd[i].FwRtuNo; - retCmd.FwPointNo = cmd[i].FwPointNo; - retCmd.SubSystem = cmd[i].SubSystem; - //return failed to scada - strcpy(retCmd.TableName, cmd[i].TableName); - strcpy(retCmd.ColumnName, cmd[i].ColumnName); - strcpy(retCmd.TagName, cmd[i].TagName); - strcpy(retCmd.RtuName, cmd[i].RtuName); - retCmd.retStatus = CN_ControlSuccess; - retCmd.CtrlActType = cmd[i].CtrlActType; - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + + if(cmd[i].TagtState != CTRL_TYPE_NWAIT_ACK) + { + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd[i].CtrlDir; + retCmd.RtuNo = cmd[i].RtuNo; + retCmd.PointID = cmd[i].PointID; + retCmd.FwSubSystem = cmd[i].FwSubSystem; + retCmd.FwRtuNo = cmd[i].FwRtuNo; + retCmd.FwPointNo = cmd[i].FwPointNo; + retCmd.SubSystem = cmd[i].SubSystem; + //return failed to scada + strcpy(retCmd.TableName, cmd[i].TableName); + strcpy(retCmd.ColumnName, cmd[i].ColumnName); + strcpy(retCmd.TagName, cmd[i].TagName); + strcpy(retCmd.RtuName, cmd[i].RtuName); + retCmd.retStatus = CN_ControlSuccess; + retCmd.CtrlActType = cmd[i].CtrlActType; + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } } } else { - //2019-03-18 thxiao 为适应转发规约增加 - retCmd.CtrlDir = cmd[i].CtrlDir; - retCmd.RtuNo = cmd[i].RtuNo; - retCmd.PointID = cmd[i].PointID; - retCmd.FwSubSystem = cmd[i].FwSubSystem; - retCmd.FwRtuNo = cmd[i].FwRtuNo; - retCmd.FwPointNo = cmd[i].FwPointNo; - retCmd.SubSystem = cmd[i].SubSystem; - //return failed to scada - strcpy(retCmd.TableName, cmd[i].TableName); - strcpy(retCmd.ColumnName, cmd[i].ColumnName); - strcpy(retCmd.TagName, cmd[i].TagName); - strcpy(retCmd.RtuName, cmd[i].RtuName); - retCmd.retStatus = CN_ControlPointErr; - retCmd.CtrlActType = cmd[i].CtrlActType; - sprintf(retCmd.strParam, I18N("IEC104V2 遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(), pRtu->m_Param.RtuNo, cmd[i].PointID); - LOGDEBUG("IEC104V2 Ao failed!RtuNo:%d Can not find the PointNo:%d", pRtu->m_Param.RtuNo, cmd[i].PointID); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + if(cmd[i].TagtState != CTRL_TYPE_NWAIT_ACK) + { + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd[i].CtrlDir; + retCmd.RtuNo = cmd[i].RtuNo; + retCmd.PointID = cmd[i].PointID; + retCmd.FwSubSystem = cmd[i].FwSubSystem; + retCmd.FwRtuNo = cmd[i].FwRtuNo; + retCmd.FwPointNo = cmd[i].FwPointNo; + retCmd.SubSystem = cmd[i].SubSystem; + //return failed to scada + strcpy(retCmd.TableName, cmd[i].TableName); + strcpy(retCmd.ColumnName, cmd[i].ColumnName); + strcpy(retCmd.TagName, cmd[i].TagName); + strcpy(retCmd.RtuName, cmd[i].RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd[i].CtrlActType; + sprintf(retCmd.strParam, I18N_C("IEC104V2 遥调失败!RtuNo:%d 找不到遥调点:%d"), pRtu->m_Param.RtuNo, cmd[i].PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + LOGDEBUG("IEC104V2 Ao failed!RtuNo:%d Can not find the PointNo:%d", pRtu->m_Param.RtuNo, cmd[i].PointID); } } } @@ -3880,15 +3886,13 @@ bool CIEC104V2DataProcThread::CmdControlRespProcess(int okFlag) if(okFlag) { retDoCmd.retStatus = CN_ControlSuccess; - //sprintf(retDoCmd.strParam,"遥控成功!RtuNo:%d 遥控点:%d",m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); - sprintf(retDoCmd.strParam,I18N("IEC104V2 遥控成功!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + sprintf(retDoCmd.strParam,I18N_C("IEC104V2 遥控成功!RtuNo:%d 遥控点:%d"), m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); LOGDEBUG("1 IEC104V2 Do succeed!RtuNo:%d PointNo:%d", m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); } else { retDoCmd.retStatus = CN_ControlFailed; - //sprintf(retDoCmd.strParam,"遥控失败!RtuNo:%d 遥控点:%d",m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); - sprintf(retDoCmd.strParam,I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + sprintf(retDoCmd.strParam,I18N_C("遥控失败!RtuNo:%d 遥控点:%d"), m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); LOGDEBUG("2 IEC104V2 Do failed!RtuNo:%d PointNo:%d", m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); } strcpy(retDoCmd.TableName,m_AppData.doCmd.TableName); @@ -3919,34 +3923,37 @@ bool CIEC104V2DataProcThread::CmdControlRespProcess(int okFlag) if(okFlag) { retAoCmd.retStatus = CN_ControlSuccess; - //sprintf(retAoCmd.strParam,"遥调成功!RtuNo:%d 遥调点:%d",m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); - sprintf(retAoCmd.strParam,I18N("遥调成功!RtuNo:%d 遥调点:%d").str().c_str(), m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); + sprintf(retAoCmd.strParam,I18N_C("遥调成功!RtuNo:%d 遥调点:%d"), m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); LOGDEBUG("3 IEC104V2 Ao succeed!RtuNo:%d PointNo:%d", m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); } else { retAoCmd.retStatus = CN_ControlFailed; - //sprintf(retAoCmd.strParam,"遥调失败!RtuNo:%d 遥调点:%d",m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); - sprintf(retAoCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(), m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); + sprintf(retAoCmd.strParam,I18N_C("遥调失败!RtuNo:%d 遥调点:%d"), m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); LOGDEBUG("4 IEC104V2 Ao failed!RtuNo:%d PointNo:%d", m_ptrCurrentControlRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); } - strcpy(retAoCmd.TableName,m_AppData.aoCmd.TableName); - strcpy(retAoCmd.ColumnName,m_AppData.aoCmd.ColumnName); - strcpy(retAoCmd.TagName,m_AppData.aoCmd.TagName); - strcpy(retAoCmd.RtuName,m_AppData.aoCmd.RtuName); - retAoCmd.CtrlActType = m_AppData.aoCmd.CtrlActType; - //2019-03-18 thxiao 为适应转发规约增加 - retAoCmd.CtrlDir = m_AppData.aoCmd.CtrlDir; - retAoCmd.RtuNo = m_AppData.aoCmd.RtuNo; - retAoCmd.PointID = m_AppData.aoCmd.PointID; - retAoCmd.FwSubSystem = m_AppData.aoCmd.FwSubSystem; - retAoCmd.FwRtuNo = m_AppData.aoCmd.FwRtuNo; - retAoCmd.FwPointNo = m_AppData.aoCmd.FwPointNo; - retAoCmd.SubSystem = m_AppData.aoCmd.SubSystem; - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retAoCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1,&retAoCmd); + if(m_AppData.aoCmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + strcpy(retAoCmd.TableName,m_AppData.aoCmd.TableName); + strcpy(retAoCmd.ColumnName,m_AppData.aoCmd.ColumnName); + strcpy(retAoCmd.TagName,m_AppData.aoCmd.TagName); + strcpy(retAoCmd.RtuName,m_AppData.aoCmd.RtuName); + retAoCmd.CtrlActType = m_AppData.aoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retAoCmd.CtrlDir = m_AppData.aoCmd.CtrlDir; + retAoCmd.RtuNo = m_AppData.aoCmd.RtuNo; + retAoCmd.PointID = m_AppData.aoCmd.PointID; + retAoCmd.FwSubSystem = m_AppData.aoCmd.FwSubSystem; + retAoCmd.FwRtuNo = m_AppData.aoCmd.FwRtuNo; + retAoCmd.FwPointNo = m_AppData.aoCmd.FwPointNo; + retAoCmd.SubSystem = m_AppData.aoCmd.SubSystem; + + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retAoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retAoCmd); + } + m_AppData.lastCotrolcmd = CN_IEC104V2NoCmd; m_AppData.state = CN_IEC104V2AppState_idle; m_AppData.controlTimeout = 0; @@ -4146,7 +4153,7 @@ void CIEC104V2DataProcThread::ErrorControlRespProcess() TxDoCmd.FwPointNo = RxDoCmd.FwPointNo; TxDoCmd.SubSystem = RxDoCmd.SubSystem; - sprintf(TxDoCmd.strParam,I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,RxDoCmd.PointID); + sprintf(TxDoCmd.strParam,I18N_C("遥控失败!RtuNo:%d 遥控点:%d"),m_ptrCFesRtu->m_Param.RtuNo,RxDoCmd.PointID); LOGDEBUG ("网络已断开 DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",RxDoCmd.CtrlActType,RxDoCmd.iValue,RxDoCmd.RtuName,RxDoCmd.PointID); //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&TxDoCmd); //2019-03-18 thxiao 为适应转发规约 @@ -4159,26 +4166,30 @@ void CIEC104V2DataProcThread::ErrorControlRespProcess() { if(m_ptrCFesRtu->ReadRxAoCmd(1,&RxAoCmd)==1) { - //memset(&TxAoCmd,0,sizeof(TxAoCmd)); - strcpy(TxAoCmd.TableName,RxAoCmd.TableName); - strcpy(TxAoCmd.ColumnName,RxAoCmd.ColumnName); - strcpy(TxAoCmd.TagName,RxAoCmd.TagName); - strcpy(TxAoCmd.RtuName,RxAoCmd.RtuName); - TxAoCmd.retStatus = CN_ControlFailed; - sprintf(TxAoCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,RxAoCmd.PointID); - TxAoCmd.CtrlActType = RxAoCmd.CtrlActType; - //2019-03-18 thxiao 为适应转发规约增加 - TxAoCmd.CtrlDir = RxAoCmd.CtrlDir; - TxAoCmd.RtuNo = RxAoCmd.RtuNo; - TxAoCmd.PointID = RxAoCmd.PointID; - TxAoCmd.FwSubSystem = RxAoCmd.FwSubSystem; - TxAoCmd.FwRtuNo = RxAoCmd.FwRtuNo; - TxAoCmd.FwPointNo = RxAoCmd.FwPointNo; - TxAoCmd.SubSystem = RxAoCmd.SubSystem; - LOGDEBUG("网络已断开 AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", RxAoCmd.CtrlActType, RxAoCmd.fValue, RxAoCmd.RtuName, RxAoCmd.PointID); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&TxAoCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1,&TxAoCmd); + if(RxAoCmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + //memset(&TxAoCmd,0,sizeof(TxAoCmd)); + strcpy(TxAoCmd.TableName,RxAoCmd.TableName); + strcpy(TxAoCmd.ColumnName,RxAoCmd.ColumnName); + strcpy(TxAoCmd.TagName,RxAoCmd.TagName); + strcpy(TxAoCmd.RtuName,RxAoCmd.RtuName); + TxAoCmd.retStatus = CN_ControlFailed; + sprintf(TxAoCmd.strParam,I18N_C("遥调失败!RtuNo:%d 遥调点:%d"),m_ptrCFesRtu->m_Param.RtuNo,RxAoCmd.PointID); + TxAoCmd.CtrlActType = RxAoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxAoCmd.CtrlDir = RxAoCmd.CtrlDir; + TxAoCmd.RtuNo = RxAoCmd.RtuNo; + TxAoCmd.PointID = RxAoCmd.PointID; + TxAoCmd.FwSubSystem = RxAoCmd.FwSubSystem; + TxAoCmd.FwRtuNo = RxAoCmd.FwRtuNo; + TxAoCmd.FwPointNo = RxAoCmd.FwPointNo; + TxAoCmd.SubSystem = RxAoCmd.SubSystem; + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&TxAoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&TxAoCmd); + } + + LOGDEBUG("网络已断开 AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", RxAoCmd.CtrlActType, RxAoCmd.fValue, RxAoCmd.RtuName, RxAoCmd.PointID); } } else @@ -4201,7 +4212,7 @@ void CIEC104V2DataProcThread::ErrorControlRespProcess() TxMoCmd.FwRtuNo = RxMoCmd.FwRtuNo; TxMoCmd.FwPointNo = RxMoCmd.FwPointNo; TxMoCmd.SubSystem = RxMoCmd.SubSystem; - sprintf(TxMoCmd.strParam, I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxMoCmd.PointID); + sprintf(TxMoCmd.strParam, I18N_C("混合量输出成功!RtuNo:%d 混合量输出点:%d"), m_ptrCFesRtu->m_Param.RtuNo, RxMoCmd.PointID); LOGDEBUG ("网络已断开 MO混合量执行失败 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",RxMoCmd.CtrlActType,RxMoCmd.iValue,RxMoCmd.RtuName,RxMoCmd.PointID); //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&TxMoCmd); diff --git a/product/src/fes/protocol/iec104V2/IEC104V2DataProcThread.h b/product/src/fes/protocol/iec104V2/IEC104V2DataProcThread.h index 05dd3c6d..008807bf 100644 --- a/product/src/fes/protocol/iec104V2/IEC104V2DataProcThread.h +++ b/product/src/fes/protocol/iec104V2/IEC104V2DataProcThread.h @@ -163,7 +163,6 @@ typedef struct{ byte strictComMode; //1:接收序号不对,断开网络。0:忽略 byte createSoe; //1:对于不产生SOE的 IEC104V2 Server在遥信帧中产生SOE. 0: 忽略 byte soeOnce; //1:装置DI变位只产生一次SOE; 0:装置DI变位产生SOE,及遥信变位 - byte soeCheckDi; //1:Soe判断状态; 0:Soe不判断状态 byte ignoreInvalid; //忽略数据无效位 1:忽略 0:不忽略 byte aoCmdMode; //2019-08-07 thxiao AO控制模式; 0:允许发送单AO命令处理 1:允许同时发送多AO命令处理 byte aoCmdType; //对于允许同时发送多AO命令处理,所有的AO命令使用同一种类型 @@ -224,7 +223,6 @@ typedef struct{ byte strictComMode; //1:接收序号不对,断开网络。0:忽略 byte createSoe; //1:对于不产生SOE的 IEC104V2 Server在遥信帧中产生SOE. 0: 忽略 byte soeOnce; //1:装置DI变位只产生一次SOE; 0:装置DI变位产生SOE,及遥信变位 - byte soeCheckDi; //1:Soe判断状态; 0:Soe不判断状态 byte ignoreInvalid; //忽略数据无效位 1:忽略 0:不忽略 byte aoCmdMode; //2019-08-07 thxiao AO控制模式; 0:允许发送单AO命令处理 1:允许同时发送多AO命令处理 byte aoCmdType; //对于允许同时发送多AO命令处理,所有的AO命令使用同一种类型 diff --git a/product/src/fes/protocol/iec104s/IEC104S.cpp b/product/src/fes/protocol/iec104s/IEC104S.cpp index c5c05169..9b6071d8 100644 --- a/product/src/fes/protocol/iec104s/IEC104S.cpp +++ b/product/src/fes/protocol/iec104s/IEC104S.cpp @@ -100,7 +100,7 @@ int CIEC104S::SetBaseAddr(void *address) int CIEC104S::SetProperty(int IsMainFes) { - g_IEC104SIsMainFes = IsMainFes; + g_IEC104SIsMainFes = (IsMainFes != 0); LOGDEBUG("CIEC104S::SetProperty g_IEC104SIsMainFes:%d",IsMainFes); return iotSuccess; } @@ -251,11 +251,15 @@ int CIEC104S::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) */ int CIEC104S::ChanTimer(int MainChanNo) { + boost::ignore_unused_variable_warning(MainChanNo); + return iotSuccess; } int CIEC104S::ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + InformTcpThreadExit(); return iotSuccess; } @@ -461,6 +465,15 @@ int CIEC104S::ReadConfigParam() } else param.aiUploadType = 13; + + if (config.getIntValue(strRtuNo, "acc_use_ai", ivalue) == iotSuccess) + { + param.bAccUseAi = (ivalue == 1); + items++; + } + else + param.bAccUseAi = false; + if (config.getIntValue(strRtuNo, "ai_start_info_address", ivalue) == iotSuccess) { param.aiStartAddress = ivalue; diff --git a/product/src/fes/protocol/iec104s/IEC104SDataProcThread.cpp b/product/src/fes/protocol/iec104s/IEC104SDataProcThread.cpp index 70ea371d..93e90825 100644 --- a/product/src/fes/protocol/iec104s/IEC104SDataProcThread.cpp +++ b/product/src/fes/protocol/iec104s/IEC104SDataProcThread.cpp @@ -52,8 +52,8 @@ CIEC104SDataProcThread::CIEC104SDataProcThread(CFesBase *ptrCFesBase,CFesChanPt m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); //2020-03-03 thxiao 不需要Acc及MI的变化 - m_ptrCFesRtu->SetFwAccChgStop(1); - m_ptrCFesRtu->SetFwMiChgStop(1); + //m_ptrCFesRtu->SetFwAccChgStop(1); + //m_ptrCFesRtu->SetFwMiChgStop(1); int found = 0; if((m_ptrCurrentChan!=NULL)&&(m_ptrCFesRtu!=NULL)&&(vecAppParam.size()>0)) @@ -106,6 +106,7 @@ CIEC104SDataProcThread::CIEC104SDataProcThread(CFesBase *ptrCFesBase,CFesChanPt m_AppData.qdsEnable = vecAppParam[i].qdsEnable; m_AppData.accSendYmTime = vecAppParam[i].accSendYmTime; m_AppData.aiUploadType = vecAppParam[i].aiUploadType; + m_AppData.bAccUseAi = vecAppParam[i].bAccUseAi; m_AppData.state = CN_IEC104SAppState_init; m_AppData.maxUpdateCount = vecAppParam[i].maxUpdateCount; m_AppData.updateCount = 0; @@ -124,7 +125,10 @@ CIEC104SDataProcThread::CIEC104SDataProcThread(CFesBase *ptrCFesBase,CFesChanPt InitConfigParam();//配置文件读取失败,取默认配置 m_AppData.startDelay = getMonotonicMsec(); - + if(!m_AppData.bAccUseAi) + { + m_ptrCFesRtu->SetFwAccChgStop(1); + } } @@ -521,7 +525,7 @@ void CIEC104SDataProcThread::TimerProcess() if(m_AppData.SEND_K_NO>=m_AppData.k) { m_AppData.K_STOP = true; - LOGINFO("CIEC104SDataProcThread::主站超出K=%d包未确认,子站停止发送!",m_AppData.k); + //LOGINFO("CIEC104SDataProcThread::主站超出K=%d包未确认,子站停止发送!",m_AppData.k); } if (m_timerCount == 0)//秒级判断,减少CPU负荷 @@ -580,264 +584,22 @@ void CIEC104SDataProcThread::TimerProcess() */ void CIEC104SDataProcThread::SendAllDataFrame() { - int i,j, count,maxAiCount; - int StartAddr,FrameLen; - int DiValue,SendAllDiNum,SendAllAiNum; - int AiValueLen,AIQDDES; - int AiValue,ShortAiValue; - float AiFloatValue; - int subLen; - SFesFwDi *pFwDi; - SFesFwAi *pFwAi; - byte data[256]; - - SendAllDiNum = 0; - SendAllAiNum = 0; - AiValueLen = 0; - AiValue = 0; - ShortAiValue = 0; - AiFloatValue = 0; - subLen = m_AppData.trReasonSize + m_AppData.publicAddrSize + m_AppData.infoAddrSize; - StartAddr = 0; FrameLen = 0; count = 0; - /****************--------****响应总召,上传Di数据***----------****************/ if((m_AppData.AllDiStartNom_MaxFwDiPoints)&&(m_ptrCFesRtu->m_MaxFwDiPoints>0)) { - if (!isTimetoSend()) - return; - - if((m_ptrCFesRtu->m_MaxFwDiPoints -m_AppData.AllDiStartNo)>SEND_DI_COUNT) - SendAllDiNum = SEND_DI_COUNT; - else - SendAllDiNum = m_ptrCFesRtu->m_MaxFwDiPoints -m_AppData.AllDiStartNo; - - count = 0; - for(i= m_AppData.AllDiStartNo;im_MaxFwDiPoints;i++) - { - pFwDi = m_ptrCFesRtu->m_pFwDi+i; - if (INTROGEN != m_AppData.AllQOI) //组召唤 - { - if ((m_AppData.AllQOI-20) != pFwDi->ResParam1) - { - if (count == 0) - continue;//找到对应的组号 - else - { - m_AppData.AllDiStartNo = m_ptrCFesRtu->m_MaxFwDiPoints;//强制结束 - break;//当前点和前面的点不在同一组,则将之前的点为一完整报文先发 - } - } - } - if (count == 0) - StartAddr = m_AppData.SingaldiStartAddress + i; - - DiValue = pFwDi->Value; - /********************品质描述*************************************/ - if (m_AppData.qdsEnable) - { - if (pFwDi->Status & CN_FesValueComDown)//数据非当前值(通讯中断) - DiValue |= 0x40; - if (pFwDi->Status & CN_FesValueInvaild)//数据无效 - DiValue |= 0x80; - } - data[8 + subLen + count] = DiValue; - - count++; - if (count >= SEND_DI_COUNT) - break; - } - m_AppData.AllDiStartNo = i+1; //记录下次发送的Di起始地址 - if(count>0) - { - data[6] = M_SP_NA_1; //单点yx类型标识 - data[7] = 0x80 | count;//vsq - for(j=0;j>(j*8)); - for(j=0;j>(j*8)); - for(j=0;j>(j*8)); - FrameLen = 8+subLen+ count; - FillIFrameHeader(data,FrameLen); - SendDataToPort(data,FrameLen); - } - return; + sendAllDi(); + return; } - else/****************--------****响应总召,上传Di数据***----------****************/ + else/****************--------****响应总召,上传DDi数据***----------****************/ if ((m_AppData.AllDDiStartNom_MaxFwDDiPoints) && (m_ptrCFesRtu->m_MaxFwDDiPoints>0)) { - if (!isTimetoSend()) - return; - - count = 0; - for (i = m_AppData.AllDDiStartNo; im_MaxFwDDiPoints; i++) - { - pFwDi = m_ptrCFesRtu->m_pFwDDi + i; - if (INTROGEN != m_AppData.AllQOI) //组召唤 - { - if ((m_AppData.AllQOI-20) != pFwDi->ResParam1) - { - if (count == 0) - continue;//找到对应的组号 - else - { - m_AppData.AllDDiStartNo = m_ptrCFesRtu->m_MaxFwDDiPoints;//强制结束 - break;//当前点和前面的点不在同一组,则将之前的点为一完整报文先发 - } - } - } - if (count == 0) - StartAddr = m_AppData.DoublediStartAddress + i; - - DiValue = pFwDi->Value; - /********************品质描述*************************************/ - if (m_AppData.qdsEnable) - { - if (pFwDi->Status & CN_FesValueComDown)//数据非当前值(通讯中断) - DiValue |= 0x40; - if (pFwDi->Status & CN_FesValueInvaild)//数据无效 - DiValue |= 0x80; - } - data[8 + subLen + count] = DiValue; - - count++; - if (count >= SEND_DI_COUNT) - break; - } - m_AppData.AllDDiStartNo = i+1; //记录下次发送的Di起始地址 - if (count>0) - { - data[6] = M_DP_NA_1; //双点类型标识 - data[7] = 0x80 | count;//vsq - for (j = 0; j> (j * 8)); - for (j = 0; j> (j * 8)); - for (j = 0; j> (j * 8)); - FrameLen = 8 + subLen + count; - FillIFrameHeader(data, FrameLen); - SendDataToPort(data, FrameLen); - } - return; + sendAllDDi(); + return; } else/****************--------****响应总召,上传Ai数据***----------****************/ if((m_AppData.AllAiStartNom_MaxFwAiPoints)&&(m_ptrCFesRtu->m_MaxFwAiPoints>0)) { - if (!isTimetoSend()) - return; - //2020-03-09 thxiao 总召前可以把变化AI清除 - if (m_AppData.AllAiStartNo == 0) - { - m_ptrCFesRtu->ClearFwAiBuf(); - } - /*********--------各种帧类型标识的Ai值字节个数-----*******************/ - data[6] = M_ME_NC_1; - if((m_AppData.aiUploadType== M_ME_NA_1)||(m_AppData.aiUploadType== M_ME_NB_1)) //带品质描述的归一化值和标度化值 - { - data[6] = m_AppData.aiUploadType; - AiValueLen = 3; - } - else if(m_AppData.aiUploadType== M_ME_ND_1)//analog message without quality - { - data[6] = M_ME_ND_1; - AiValueLen = 2; - } - else if(m_AppData.aiUploadType== M_ME_TD_1) //如果配置为带长时标的归一化值,在总召唤时按不带时标的带品质描述的归一化值上传 - { - data[6] = M_ME_NA_1; //如果配置为带长时标的归一化值,在总召唤时按不带时标的标度化值上传 - AiValueLen = 3; - } - else if(m_AppData.aiUploadType== M_ME_TE_1) //带长时标的标度化值 - { - data[6] = M_ME_NB_1; //如果配置为带长时标的归一化值,在总召唤时按不带时标的带品质描述的归一化值上传 - AiValueLen = 3; - } - else if (m_AppData.aiUploadType == M_ME_TF_1) //带CP56Time2a时标的测量值, 短浮点数 - { - data[6] = M_ME_NC_1; //如果配置为带长时标的归一化值,在总召唤时按不带时标的带品质描述的归一化值上传 - AiValueLen = 5; - } - else//默认短浮点数 - { - data[6] = M_ME_NC_1; - AiValueLen = 5; - } - maxAiCount = 230 / AiValueLen; - - for (i = m_AppData.AllAiStartNo; i < m_ptrCFesRtu->m_MaxFwAiPoints; i++) - { - pFwAi = m_ptrCFesRtu->m_pFwAi+i; - if (INTROGEN != m_AppData.AllQOI) //组召唤 - { - if ((m_AppData.AllQOI-20) != pFwAi->ResParam1) - { - if (count == 0) - continue; //找到对应的组号 - else - { - m_AppData.AllAiStartNo = m_ptrCFesRtu->m_MaxFwAiPoints;//强制结束 - break; //当前点和前面的点不在同一组,则将之前的点为一完整报文先发 - } - } - } - if(count == 0) - StartAddr = m_AppData.aiStartAddress + i; - - AiFloatValue = (float)(pFwAi->Value*pFwAi->Coeff+pFwAi->Base); - ShortAiValue = (int)AiFloatValue; - switch(data[6]) - { - case M_ME_NA_1: - case M_ME_NB_1: - case M_ME_NC_1: - /********************品质描述*************************************/ - AIQDDES=0; - if (m_AppData.qdsEnable) - { - if (pFwAi->Status & CN_FesValueExceed) - AIQDDES |= 0x01; //数据溢出 - if (pFwAi->Status & CN_FesValueComDown)//数据非当前值(通讯中断) - AIQDDES |= 0x40; - if (pFwAi->Status & CN_FesValueInvaild)//数据无效 - AIQDDES |= 0x80; - } - if (data[6] == M_ME_NC_1) //短浮点数 - { - memcpy(&AiValue, &AiFloatValue, sizeof(AiFloatValue)); - for (j = 0; j < 4; j++) - data[8 + subLen + count*AiValueLen+j] = (byte)(AiValue >> (j * 8)); - } - else //带品质描述的归一化值和标度化值 - { - for (j = 0; j < 2; j++) - data[8 + subLen + count*AiValueLen + j] = (byte)(ShortAiValue >> (j * 8)); - } - data[8+subLen+ count*AiValueLen+j] = AIQDDES; - break; - default://M_ME_ND_1 默认为不带品质描述的归一化值21 - for(j=0;j<2;j++) - data[8+subLen+i*AiValueLen+j] = (byte)(ShortAiValue>>(j*8)); - break; - } - count++; - if (count >= maxAiCount) - break; - } - m_AppData.AllAiStartNo=i+1; //记录下次发送的Ai起始地址 - if(count>0) - { - data[7] = 0x80 | count;//vsq - for(j=0;j>(j*8)); - for(j=0;j>(j*8)); - for(j=0;j>(j*8)); - FrameLen = count*AiValueLen+8+subLen; - FillIFrameHeader(data,FrameLen); - SendDataToPort(data,FrameLen); - } + sendAllAi(); return; } /*******************--------**************----------**********************/ @@ -921,7 +683,7 @@ void CIEC104SDataProcThread::SendAccDataFrame() } } } - ShortAccValue = (int)(pFwAcc->Value*pFwAcc->Coeff + pFwAcc->Base); + ShortAccValue = (int)(pFwAcc->Value); infoAddr = m_AppData.accStartAddress + i; for (j = 0; j < m_AppData.infoAddrSize; j++) //Acc信息体地址 data[8 + subLen + count*(m_AppData.infoAddrSize + 5) + j] = (byte)(infoAddr >> (j * 8)); @@ -995,167 +757,46 @@ void CIEC104SDataProcThread::SendAccOverFrame() */ void CIEC104SDataProcThread::SendChangeAiDataFrame() { - int i,j; - int StartAddr,FrameLen; - int AiValueLen,AiTimeLen,AIQDDES; - int AiValue,ShortAiValue; - float AiFloatValue; - LOCALTIME SysLocalTime; - int64 Msecond; - SFesFwAi *pFwAi; byte data[300]; - AiValueLen = 0; - AiTimeLen = 0; - AiValue = 0; - ShortAiValue = 0; - AiFloatValue = 0; - StartAddr = 0; FrameLen = 0; - int count, retNum,subLen,MaxCount; - SFesFwChgAi *pChgAi; - count = m_ptrCFesRtu->GetFwChgAiNum(); - if (count == 0) + int nAiCount = m_ptrCFesRtu->GetFwChgAiNum(); + int nMiCount = m_ptrCFesRtu->GetFwChgMiNum(); + int nAccCount = m_ptrCFesRtu->GetFwChgAccNum(); + + int nAllCount = nAiCount + nMiCount; + if(m_AppData.bAccUseAi) + { + nAllCount += nAccCount; + } + + if (nAllCount == 0) return; if (!isTimetoSend()) return; - subLen = 8+m_AppData.trReasonSize + m_AppData.publicAddrSize ; + int subLen = 8+m_AppData.trReasonSize + m_AppData.publicAddrSize ; /*********--------各种帧类型标识的Ai值字节个数-----*******************/ - switch (m_AppData.aiUploadType) - { - case M_ME_NA_1: - case M_ME_NB_1://带品质描述的归一化值和标度化值 - data[6] = m_AppData.aiUploadType; - AiValueLen = 3; - break; - case M_ME_TD_1://带长时标的归一化值 - case M_ME_TE_1://带长时标的标度化值 - data[6] = m_AppData.aiUploadType; - AiValueLen = 10; - break; - case M_ME_TF_1://带长时标的短浮点数 - data[6] = m_AppData.aiUploadType; - AiValueLen = 12; - break; - case M_ME_ND_1://为不带品质描述的遥测 - data[6] = M_ME_ND_1; - AiValueLen = 2; - break; - default: //默认短浮点数M_ME_NC_1 - data[6] = m_AppData.aiUploadType; - AiValueLen = 5; - break; - } - MaxCount = 235 / (AiValueLen+ m_AppData.infoAddrSize); + data[6] = m_AppData.aiUploadType; + int AiValueLen = getAiValueLen(m_AppData.aiUploadType); + int MaxCount = 235 / (AiValueLen+ m_AppData.infoAddrSize); - if (count > MaxCount) - count = MaxCount;//取每次最大能发送的点数 + //调用Ai处理函数 + int nRealCount = buildAiFrame(nAiCount,MaxCount,subLen,AiValueLen,data); + nRealCount += buildMiFrame(nMiCount,MaxCount - nRealCount,subLen,AiValueLen,data); + nRealCount += buildAccFrame(nAccCount,MaxCount - nRealCount,subLen,AiValueLen,data); - if (m_pChgAiData == NULL) - m_pChgAiData = (SFesFwChgAi*)malloc(count * sizeof(SFesFwChgAi)); - else - m_pChgAiData = (SFesFwChgAi*)realloc(m_pChgAiData, count * sizeof(SFesFwChgAi)); - - retNum = m_ptrCFesRtu->ReadFwChgAi(count, m_pChgAiData); - //fill data - count = 0; - for (i = 0; i < retNum; i++) - { - pChgAi = m_pChgAiData + i; - if(pChgAi->RemoteNo>= m_ptrCFesRtu->m_MaxFwAiPoints) - continue; - pFwAi = m_ptrCFesRtu->m_pFwAi + pChgAi->RemoteNo; - AiFloatValue = (float)(pChgAi->Value*pFwAi->Coeff + pFwAi->Base); - StartAddr = pChgAi->RemoteNo + m_AppData.aiStartAddress; - for(j=0;j>(j*8)); - if (pFwAi->DeadBandType != CN_FesDeadbandType_None) //启动死区值判断 - { - - } - /********************品质描述*************************************/ - //品质描述词 - AIQDDES = 0; - if (m_AppData.qdsEnable) - { - if (pChgAi->Status&CN_FesValueExceed) - AIQDDES |= IEC104SAI_QDS_OV;//数据溢出 - if (pChgAi->Status&CN_FesValueInvaild) - AIQDDES |= IEC104SAI_QDS_IV; //数据无效 - if (pChgAi->Status&CN_FesValueComDown) - AIQDDES |= IEC104SAI_QDS_NT; //数据非当前值(通讯中断) - } - ShortAiValue = (int)AiFloatValue; - switch(data[6]) - { - case M_ME_NA_1: - case M_ME_NB_1: - for (j = 0; j < 2; j++) - data[subLen + m_AppData.infoAddrSize+ count*(m_AppData.infoAddrSize + AiValueLen) + j] = (byte)(ShortAiValue >> (j * 8)); - data[subLen + m_AppData.infoAddrSize+ count*(m_AppData.infoAddrSize + AiValueLen) + 2] = AIQDDES; - break; - case M_ME_TD_1: //带长时标的归一化值 - case M_ME_TE_1: //带长时标的标度化值 - for(j=0;j<2;j++) - data[subLen + m_AppData.infoAddrSize + count*(m_AppData.infoAddrSize+AiValueLen)+j] = (byte)(ShortAiValue>>(j*8)); - data[subLen + m_AppData.infoAddrSize+ count*(m_AppData.infoAddrSize+AiValueLen)+2] = (byte)AIQDDES; //品质描述 - AiTimeLen = subLen + m_AppData.infoAddrSize + count*(m_AppData.infoAddrSize+AiValueLen)+3; - SysLocalTime = getLocalSystemTime(); - Msecond = SysLocalTime.wSecond*1000+SysLocalTime.wMilliseconds; - data[AiTimeLen+0] = Msecond & 0xff;//msl - data[AiTimeLen+1] = (Msecond>>8) & 0xff;//msh - data[AiTimeLen+2] = SysLocalTime.wMinute & 0xff;//minute - data[AiTimeLen+3] = SysLocalTime.wHour & 0xff;//hour - data[AiTimeLen+4] = SysLocalTime.wDay & 0xff;//day - data[AiTimeLen+5] = SysLocalTime.wMonth & 0xff;//month - data[AiTimeLen+6] = SysLocalTime.wYear%100;//year - break; - case M_ME_TF_1: //带长时标的短浮点数 - memcpy(&AiValue, &AiFloatValue, sizeof(AiFloatValue)); - for (j = 0; j < 4; j++) - data[subLen + m_AppData.infoAddrSize + count*(m_AppData.infoAddrSize + AiValueLen) + j] = (byte)(AiValue >> (j * 8)); - data[subLen + m_AppData.infoAddrSize + count*(m_AppData.infoAddrSize + AiValueLen) + 4] = (byte)AIQDDES; //品质描述 - AiTimeLen = subLen + m_AppData.infoAddrSize + count*(m_AppData.infoAddrSize + AiValueLen) + 5; - SysLocalTime = getLocalSystemTime(); - Msecond = SysLocalTime.wSecond * 1000 + SysLocalTime.wMilliseconds; - data[AiTimeLen + 0] = Msecond & 0xff;//msl - data[AiTimeLen + 1] = (Msecond >> 8) & 0xff;//msh - data[AiTimeLen + 2] = SysLocalTime.wMinute & 0xff;//minute - data[AiTimeLen + 3] = SysLocalTime.wHour & 0xff;//hour - data[AiTimeLen + 4] = SysLocalTime.wDay & 0xff;//day - data[AiTimeLen + 5] = SysLocalTime.wMonth & 0xff;//month - if (SysLocalTime.wYear >= 2000) - data[AiTimeLen + 6] = (SysLocalTime.wYear - 2000) & 0xff;//year - else - data[AiTimeLen + 6] = (2000 - SysLocalTime.wYear) & 0xff;//year - break; - case M_ME_ND_1: - //默认为不带品质描述的归一化值21 - for(j=0;j>(j*8)); - break; - default://M_ME_NC_1 - memcpy(&AiValue, &AiFloatValue, sizeof(AiFloatValue)); - for (j = 0; j < 4; j++) - data[subLen + m_AppData.infoAddrSize + count*(m_AppData.infoAddrSize + AiValueLen) + j] = (byte)(AiValue >> (j * 8)); - data[subLen + m_AppData.infoAddrSize + count*(m_AppData.infoAddrSize + AiValueLen) + j] = AIQDDES; - break; - } - count++; //实际准备上传的信息点个数 - } - - if(count>0) + if(nRealCount >0) { - data[7] = count;//vsq + data[7] = nRealCount;//vsq - for(j=0;j>(j*8)); - for(j=0;j>(j*8)); - FrameLen = subLen +count*(m_AppData.infoAddrSize+AiValueLen); + int FrameLen = subLen +nRealCount*(m_AppData.infoAddrSize+AiValueLen); FillIFrameHeader(data,FrameLen); SendDataToPort(data,FrameLen); @@ -1211,7 +852,7 @@ void CIEC104SDataProcThread::SendChangeDiDataFrame() { if (pChgDi->Status&CN_FesValueInvaild) DiValue |= IEC104SDI_SIQ_IV; //数据无效 - if (pChgDi->Status&CN_FesValueComDown) + if (pChgDi->Status&CN_FesValueComDown || pChgDi->Status == CN_FesValueNotUpdate) DiValue |= IEC104SDI_SIQ_NT; //数据非当前值(通讯中断) } data[subLen+count*DiValueLen+j] = (byte)DiValue; @@ -1283,7 +924,7 @@ void CIEC104SDataProcThread::SendChangeDDiDataFrame() { if (pChgDi->Status&CN_FesValueInvaild) DiValue |= IEC104SDI_SIQ_IV; //数据无效 - if (pChgDi->Status&CN_FesValueComDown) + if (pChgDi->Status&CN_FesValueComDown || pChgDi->Status == CN_FesValueNotUpdate) DiValue |= IEC104SDI_SIQ_NT; //数据非当前值(通讯中断) } data[subLen + count*DiValueLen + j] = (byte)DiValue; @@ -1353,7 +994,7 @@ void CIEC104SDataProcThread::SendSoeDataFrame() { if (pSoeEvent->Status&CN_FesValueInvaild) DiValue |= IEC104SDI_SIQ_IV; //数据无效 - if (pSoeEvent->Status&CN_FesValueComDown) + if (pSoeEvent->Status&CN_FesValueComDown || pSoeEvent->Status == CN_FesValueNotUpdate) DiValue |= IEC104SDI_SIQ_NT; //数据非当前值(通讯中断) } data[subLen + count*ValueLen + k] = (byte)DiValue; @@ -1433,7 +1074,7 @@ void CIEC104SDataProcThread::SendDSoeDataFrame() { if (pSoeEvent->Status&CN_FesValueInvaild) DiValue |= IEC104SDI_SIQ_IV; //数据无效 - if (pSoeEvent->Status&CN_FesValueComDown) + if (pSoeEvent->Status&CN_FesValueComDown || pSoeEvent->Status == CN_FesValueNotUpdate) DiValue |= IEC104SDI_SIQ_NT; //数据非当前值(通讯中断) } data[subLen + count*ValueLen + k] = (byte)DiValue; @@ -2196,6 +1837,8 @@ int CIEC104SDataProcThread::RecvDataProcess() SendStartAckFrame(); m_AppData.LinkOk = true; m_AppData.K_STOP = false; + m_AppData.recvNo = 0; + m_AppData.sendNo = 0; ClearAppData(); break; case IEC104S_U_STOP: @@ -2435,5 +2078,720 @@ bool CIEC104SDataProcThread::isTimetoSend() void CIEC104SDataProcThread::ClearAppData() { - m_ptrCFesRtu->ClearFwChangDataBuf(); + m_ptrCFesRtu->ClearFwChangDataBuf(); +} + +int CIEC104SDataProcThread::getAiValueLen(const int nAiUploadType) +{ + int nAiValueLen = 0; + switch (nAiUploadType) + { + case M_ME_NA_1: + case M_ME_NB_1://带品质描述的归一化值和标度化值 + nAiValueLen = 3; + break; + case M_ME_TD_1://带长时标的归一化值 + case M_ME_TE_1://带长时标的标度化值 + nAiValueLen = 10; + break; + case M_ME_TF_1://带长时标的短浮点数 + nAiValueLen = 12; + break; + case M_ME_ND_1://为不带品质描述的遥测 + nAiValueLen = 2; + break; + default: //默认短浮点数M_ME_NC_1 + nAiValueLen = 5; + break; + } + + return nAiValueLen; +} + +int CIEC104SDataProcThread::buildAiFrame(const int nAiCount,const int nRemainingCout,const int nHeadLen,const int nAiValueLen,byte data[]) +{ + if(nRemainingCout <= 0 || nAiCount <= 0) + { + return 0; //本次报文已经满了,不处理 + } + + LOCALTIME SysLocalTime = getLocalSystemTime(); + int nRetNum = 0; //实际准备上传的信息点个数 + SFesFwChgAi *pChgAi = NULL; + SFesFwAi *pFwAi = NULL; + int nOneValAndAddrLen = m_AppData.infoAddrSize + nAiValueLen; //一个测点值+地址的长度 + int AiValue = 0; + int j = 0; + int64 Msecond = 0; + int AiTimeLen = 0; + + int nCount = min(nAiCount,nRemainingCout); + + if (m_pChgAiData == NULL) + m_pChgAiData = (SFesFwChgAi*)malloc(nCount * sizeof(SFesFwChgAi)); + else + m_pChgAiData = (SFesFwChgAi*)realloc(m_pChgAiData, nCount * sizeof(SFesFwChgAi)); + + int nReadNum = m_ptrCFesRtu->ReadFwChgAi(nCount, m_pChgAiData); + + //fill data + for (int i = 0; i < nReadNum; i++) + { + pChgAi = m_pChgAiData + i; + if(pChgAi->RemoteNo >= m_ptrCFesRtu->m_MaxFwAiPoints) + { + continue; + } + pFwAi = m_ptrCFesRtu->m_pFwAi + pChgAi->RemoteNo; + float AiFloatValue = pChgAi->Value; + int StartAddr = pChgAi->RemoteNo + m_AppData.aiStartAddress; + for(int j=0;j>(j*8)); + } + + /********************品质描述*************************************/ + //品质描述词 + int AiQDDES = 0; + if (m_AppData.qdsEnable) + { + if (pChgAi->Status&CN_FesValueExceed) + AiQDDES |= IEC104SAI_QDS_OV;//数据溢出 + if (pChgAi->Status&CN_FesValueInvaild) + AiQDDES |= IEC104SAI_QDS_IV; //数据无效 + if (pChgAi->Status&CN_FesValueComDown || pChgAi->Status == CN_FesValueNotUpdate) + AiQDDES |= IEC104SAI_QDS_NT; //数据非当前值(通讯中断) + } + int ShortAiValue = static_cast(AiFloatValue); + switch(data[6]) + { + case M_ME_NA_1: + case M_ME_NB_1: + for (j = 0; j < 2; j++) + { + data[nHeadLen + m_AppData.infoAddrSize+ nRetNum*(nOneValAndAddrLen) + j] = (byte)(ShortAiValue >> (j * 8)); + } + data[nHeadLen + m_AppData.infoAddrSize+ nRetNum*(nOneValAndAddrLen) + 2] = AiQDDES; + break; + case M_ME_TD_1: //带长时标的归一化值 + case M_ME_TE_1: //带长时标的标度化值 + for(j=0;j<2;j++) + { + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen)+j] = (byte)(ShortAiValue>>(j*8)); + } + data[nHeadLen + m_AppData.infoAddrSize+ nRetNum*(nOneValAndAddrLen)+2] = (byte)AiQDDES; //品质描述 + AiTimeLen = nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen)+3; + //SysLocalTime = getLocalSystemTime(); + Msecond = SysLocalTime.wSecond*1000 + SysLocalTime.wMilliseconds; + data[AiTimeLen+0] = Msecond & 0xff;//msl + data[AiTimeLen+1] = (Msecond>>8) & 0xff;//msh + data[AiTimeLen+2] = SysLocalTime.wMinute & 0xff;//minute + data[AiTimeLen+3] = SysLocalTime.wHour & 0xff;//hour + data[AiTimeLen+4] = SysLocalTime.wDay & 0xff;//day + data[AiTimeLen+5] = SysLocalTime.wMonth & 0xff;//month + data[AiTimeLen+6] = SysLocalTime.wYear%100;//year + break; + case M_ME_TF_1: //带长时标的短浮点数 + memcpy(&AiValue, &AiFloatValue, sizeof(AiFloatValue)); + for (j = 0; j < 4; j++) + { + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + j] = (byte)(AiValue >> (j * 8)); + } + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + 4] = (byte)AiQDDES; //品质描述 + AiTimeLen = nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + 5; + //SysLocalTime = getLocalSystemTime(); + Msecond = SysLocalTime.wSecond * 1000 + SysLocalTime.wMilliseconds; + data[AiTimeLen + 0] = Msecond & 0xff;//msl + data[AiTimeLen + 1] = (Msecond >> 8) & 0xff;//msh + data[AiTimeLen + 2] = SysLocalTime.wMinute & 0xff;//minute + data[AiTimeLen + 3] = SysLocalTime.wHour & 0xff;//hour + data[AiTimeLen + 4] = SysLocalTime.wDay & 0xff;//day + data[AiTimeLen + 5] = SysLocalTime.wMonth & 0xff;//month + if (SysLocalTime.wYear >= 2000) + data[AiTimeLen + 6] = (SysLocalTime.wYear - 2000) & 0xff;//year + else + data[AiTimeLen + 6] = (2000 - SysLocalTime.wYear) & 0xff;//year + break; + case M_ME_ND_1: + //默认为不带品质描述的归一化值21 + for(j=0;j>(j*8)); + } + break; + default://M_ME_NC_1 + memcpy(&AiValue, &AiFloatValue, sizeof(AiFloatValue)); + for (j = 0; j < 4; j++) + { + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + j] = (byte)(AiValue >> (j * 8)); + } + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + j] = AiQDDES; + break; + } + nRetNum++; //实际准备上传的信息点个数 + } + + return nRetNum; +} + +int CIEC104SDataProcThread::buildMiFrame(const int nMiCount, const int nRemainingCout, const int nHeadLen, const int nAiValueLen, byte data[]) +{ + if(nRemainingCout <= 0 || nMiCount <= 0) + { + return 0; //本次报文已经满了,不处理 + } + + LOCALTIME SysLocalTime = getLocalSystemTime(); + int nRetNum = 0; //实际准备上传的信息点个数 + int nOneValAndAddrLen = m_AppData.infoAddrSize + nAiValueLen; //一个测点值+地址的长度 + int AiValue = 0; + int j = 0; + int64 Msecond = 0; + int AiTimeLen = 0; + + int nCount = min(nMiCount,nRemainingCout); + + if (m_pChgMiData == NULL) + m_pChgMiData = (SFesFwChgMi*)malloc(nCount * sizeof(SFesFwChgMi)); + else + m_pChgMiData = (SFesFwChgMi*)realloc(m_pChgMiData, nCount * sizeof(SFesFwChgMi)); + + int nReadNum = m_ptrCFesRtu->ReadFwChgMi(nCount, m_pChgMiData); + + //fill data + for (int i = 0; i < nReadNum; i++) + { + SFesFwChgMi *pChgMi = m_pChgMiData + i; + if(pChgMi->RemoteNo >= m_ptrCFesRtu->m_MaxFwMiPoints) + { + continue; + } +// SFesFwMi *pFwMi = m_ptrCFesRtu->m_pFwMi + pChgMi->RemoteNo; + float AiFloatValue = static_cast(pChgMi->Value); + int StartAddr = pChgMi->RemoteNo + m_AppData.aiStartAddress; + for(int j=0;j>(j*8)); + } + + /********************品质描述*************************************/ + //品质描述词 + int AiQDDES = 0; + if (m_AppData.qdsEnable) + { + if (pChgMi->Status&CN_FesValueExceed) + AiQDDES |= IEC104SAI_QDS_OV;//数据溢出 + if (pChgMi->Status&CN_FesValueInvaild) + AiQDDES |= IEC104SAI_QDS_IV; //数据无效 + if (pChgMi->Status&CN_FesValueComDown || pChgMi->Status == CN_FesValueNotUpdate) + AiQDDES |= IEC104SAI_QDS_NT; //数据非当前值(通讯中断) + } + int ShortAiValue = static_cast(AiFloatValue); + switch(data[6]) + { + case M_ME_NA_1: + case M_ME_NB_1: + for (j = 0; j < 2; j++) + { + data[nHeadLen + m_AppData.infoAddrSize+ nRetNum*(nOneValAndAddrLen) + j] = (byte)(ShortAiValue >> (j * 8)); + } + data[nHeadLen + m_AppData.infoAddrSize+ nRetNum*(nOneValAndAddrLen) + 2] = AiQDDES; + break; + case M_ME_TD_1: //带长时标的归一化值 + case M_ME_TE_1: //带长时标的标度化值 + for(j=0;j<2;j++) + { + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen)+j] = (byte)(ShortAiValue>>(j*8)); + } + data[nHeadLen + m_AppData.infoAddrSize+ nRetNum*(nOneValAndAddrLen)+2] = (byte)AiQDDES; //品质描述 + AiTimeLen = nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen)+3; + //SysLocalTime = getLocalSystemTime(); + Msecond = SysLocalTime.wSecond*1000 + SysLocalTime.wMilliseconds; + data[AiTimeLen+0] = Msecond & 0xff;//msl + data[AiTimeLen+1] = (Msecond>>8) & 0xff;//msh + data[AiTimeLen+2] = SysLocalTime.wMinute & 0xff;//minute + data[AiTimeLen+3] = SysLocalTime.wHour & 0xff;//hour + data[AiTimeLen+4] = SysLocalTime.wDay & 0xff;//day + data[AiTimeLen+5] = SysLocalTime.wMonth & 0xff;//month + data[AiTimeLen+6] = SysLocalTime.wYear%100;//year + break; + case M_ME_TF_1: //带长时标的短浮点数 + memcpy(&AiValue, &AiFloatValue, sizeof(AiFloatValue)); + for (j = 0; j < 4; j++) + { + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + j] = (byte)(AiValue >> (j * 8)); + } + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + 4] = (byte)AiQDDES; //品质描述 + AiTimeLen = nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + 5; + //SysLocalTime = getLocalSystemTime(); + Msecond = SysLocalTime.wSecond * 1000 + SysLocalTime.wMilliseconds; + data[AiTimeLen + 0] = Msecond & 0xff;//msl + data[AiTimeLen + 1] = (Msecond >> 8) & 0xff;//msh + data[AiTimeLen + 2] = SysLocalTime.wMinute & 0xff;//minute + data[AiTimeLen + 3] = SysLocalTime.wHour & 0xff;//hour + data[AiTimeLen + 4] = SysLocalTime.wDay & 0xff;//day + data[AiTimeLen + 5] = SysLocalTime.wMonth & 0xff;//month + if (SysLocalTime.wYear >= 2000) + data[AiTimeLen + 6] = (SysLocalTime.wYear - 2000) & 0xff;//year + else + data[AiTimeLen + 6] = (2000 - SysLocalTime.wYear) & 0xff;//year + break; + case M_ME_ND_1: + //默认为不带品质描述的归一化值21 + for(j=0;j>(j*8)); + } + break; + default://M_ME_NC_1 + memcpy(&AiValue, &AiFloatValue, sizeof(AiFloatValue)); + for (j = 0; j < 4; j++) + { + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + j] = (byte)(AiValue >> (j * 8)); + } + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + j] = AiQDDES; + break; + } + nRetNum++; //实际准备上传的信息点个数 + } + + return nRetNum; +} + +int CIEC104SDataProcThread::buildAccFrame(const int nAccCount, const int nRemainingCout, const int nHeadLen, const int nAiValueLen, byte data[]) +{ + if(nRemainingCout <= 0 || nAccCount <= 0) + { + return 0; //本次报文已经满了,不处理 + } + + LOCALTIME SysLocalTime = getLocalSystemTime(); + int nRetNum = 0; //实际准备上传的信息点个数 + int nOneValAndAddrLen = m_AppData.infoAddrSize + nAiValueLen; //一个测点值+地址的长度 + int AiValue = 0; + int j = 0; + int64 Msecond = 0; + int AiTimeLen = 0; + + int nCount = min(nAccCount,nRemainingCout); + + if (m_pChgAccData == NULL) + m_pChgAccData = (SFesFwChgAcc*)malloc(nCount * sizeof(SFesFwChgAcc)); + else + m_pChgAccData = (SFesFwChgAcc*)realloc(m_pChgAccData, nCount * sizeof(SFesFwChgAcc)); + + int nReadNum = m_ptrCFesRtu->ReadFwChgAcc(nCount, m_pChgAccData); + + //fill data + for (int i = 0; i < nReadNum; i++) + { + SFesFwChgAcc *pChgAcc = m_pChgAccData + i; + if(pChgAcc->RemoteNo >= m_ptrCFesRtu->m_MaxFwAccPoints) + { + continue; + } +// SFesFwAcc *pFwAcc = m_ptrCFesRtu->m_pFwAcc + pChgAcc->RemoteNo; + float AiFloatValue = static_cast(pChgAcc->Value); + int StartAddr = pChgAcc->RemoteNo + m_AppData.aiStartAddress; + for(int j=0;j>(j*8)); + } + + /********************品质描述*************************************/ + //品质描述词 + int AiQDDES = 0; + if (m_AppData.qdsEnable) + { + if (pChgAcc->Status&CN_FesValueExceed) + AiQDDES |= IEC104SAI_QDS_OV;//数据溢出 + if (pChgAcc->Status&CN_FesValueInvaild) + AiQDDES |= IEC104SAI_QDS_IV; //数据无效 + if (pChgAcc->Status&CN_FesValueComDown || pChgAcc->Status == CN_FesValueNotUpdate) + AiQDDES |= IEC104SAI_QDS_NT; //数据非当前值(通讯中断) + } + int ShortAiValue = static_cast(AiFloatValue); + switch(data[6]) + { + case M_ME_NA_1: + case M_ME_NB_1: + for (j = 0; j < 2; j++) + { + data[nHeadLen + m_AppData.infoAddrSize+ nRetNum*(nOneValAndAddrLen) + j] = (byte)(ShortAiValue >> (j * 8)); + } + data[nHeadLen + m_AppData.infoAddrSize+ nRetNum*(nOneValAndAddrLen) + 2] = AiQDDES; + break; + case M_ME_TD_1: //带长时标的归一化值 + case M_ME_TE_1: //带长时标的标度化值 + for(j=0;j<2;j++) + { + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen)+j] = (byte)(ShortAiValue>>(j*8)); + } + data[nHeadLen + m_AppData.infoAddrSize+ nRetNum*(nOneValAndAddrLen)+2] = (byte)AiQDDES; //品质描述 + AiTimeLen = nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen)+3; + //SysLocalTime = getLocalSystemTime(); + Msecond = SysLocalTime.wSecond*1000 + SysLocalTime.wMilliseconds; + data[AiTimeLen+0] = Msecond & 0xff;//msl + data[AiTimeLen+1] = (Msecond>>8) & 0xff;//msh + data[AiTimeLen+2] = SysLocalTime.wMinute & 0xff;//minute + data[AiTimeLen+3] = SysLocalTime.wHour & 0xff;//hour + data[AiTimeLen+4] = SysLocalTime.wDay & 0xff;//day + data[AiTimeLen+5] = SysLocalTime.wMonth & 0xff;//month + data[AiTimeLen+6] = SysLocalTime.wYear%100;//year + break; + case M_ME_TF_1: //带长时标的短浮点数 + memcpy(&AiValue, &AiFloatValue, sizeof(AiFloatValue)); + for (j = 0; j < 4; j++) + { + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + j] = (byte)(AiValue >> (j * 8)); + } + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + 4] = (byte)AiQDDES; //品质描述 + AiTimeLen = nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + 5; + //SysLocalTime = getLocalSystemTime(); + Msecond = SysLocalTime.wSecond * 1000 + SysLocalTime.wMilliseconds; + data[AiTimeLen + 0] = Msecond & 0xff;//msl + data[AiTimeLen + 1] = (Msecond >> 8) & 0xff;//msh + data[AiTimeLen + 2] = SysLocalTime.wMinute & 0xff;//minute + data[AiTimeLen + 3] = SysLocalTime.wHour & 0xff;//hour + data[AiTimeLen + 4] = SysLocalTime.wDay & 0xff;//day + data[AiTimeLen + 5] = SysLocalTime.wMonth & 0xff;//month + if (SysLocalTime.wYear >= 2000) + data[AiTimeLen + 6] = (SysLocalTime.wYear - 2000) & 0xff;//year + else + data[AiTimeLen + 6] = (2000 - SysLocalTime.wYear) & 0xff;//year + break; + case M_ME_ND_1: + //默认为不带品质描述的归一化值21 + for(j=0;j>(j*8)); + } + break; + default://M_ME_NC_1 + memcpy(&AiValue, &AiFloatValue, sizeof(AiFloatValue)); + for (j = 0; j < 4; j++) + { + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + j] = (byte)(AiValue >> (j * 8)); + } + data[nHeadLen + m_AppData.infoAddrSize + nRetNum*(nOneValAndAddrLen) + j] = AiQDDES; + break; + } + nRetNum++; //实际准备上传的信息点个数 + } + + return nRetNum; +} + +int CIEC104SDataProcThread::sendAllDi() +{ + if (!isTimetoSend()) + return 0; + + int SendAllDiNum = 0; + int StartAddr = 0; + int FrameLen = 0; + int i = 0; + int j = 0; + byte data[256]; + int subLen = m_AppData.trReasonSize + m_AppData.publicAddrSize + m_AppData.infoAddrSize; + + if((m_ptrCFesRtu->m_MaxFwDiPoints - m_AppData.AllDiStartNo) > SEND_DI_COUNT) + { + SendAllDiNum = SEND_DI_COUNT; + } + else + { + SendAllDiNum = m_ptrCFesRtu->m_MaxFwDiPoints - m_AppData.AllDiStartNo; + } + + int count = 0; + for(i= m_AppData.AllDiStartNo;im_MaxFwDiPoints;i++) + { + SFesFwDi *pFwDi = m_ptrCFesRtu->m_pFwDi+i; + if (INTROGEN != m_AppData.AllQOI) //组召唤 + { + if ((m_AppData.AllQOI-20) != pFwDi->ResParam1) + { + if (count == 0) + continue;//找到对应的组号 + else + { + m_AppData.AllDiStartNo = m_ptrCFesRtu->m_MaxFwDiPoints;//强制结束 + break;//当前点和前面的点不在同一组,则将之前的点为一完整报文先发 + } + } + } + if (count == 0) + StartAddr = m_AppData.SingaldiStartAddress + i; + + int DiValue = pFwDi->Value; + /********************品质描述*************************************/ + if (m_AppData.qdsEnable) + { + if (pFwDi->Status & CN_FesValueComDown || pFwDi->Status == CN_FesValueNotUpdate)//数据非当前值(通讯中断) + DiValue |= IEC104SDI_SIQ_NT; + if (pFwDi->Status & CN_FesValueInvaild)//数据无效 + DiValue |= IEC104SDI_SIQ_IV; + } + data[8 + subLen + count] = DiValue; + + count++; + if (count >= SEND_DI_COUNT) + break; + } + m_AppData.AllDiStartNo = i+1; //记录下次发送的Di起始地址 + if(count>0) + { + data[6] = M_SP_NA_1; //单点yx类型标识 + data[7] = 0x80 | count;//vsq + for(j=0;j>(j*8)); + for(j=0;j>(j*8)); + for(j=0;j>(j*8)); + FrameLen = 8+subLen+ count; + FillIFrameHeader(data,FrameLen); + SendDataToPort(data,FrameLen); + } + return count; +} + +int CIEC104SDataProcThread::sendAllDDi() +{ + if (!isTimetoSend()) + return 0; + + int StartAddr = 0; + int count = 0; + int FrameLen = 0; + int subLen = m_AppData.trReasonSize + m_AppData.publicAddrSize + m_AppData.infoAddrSize; + byte data[256]; + + int i = 0; + int j = 0; + for (i = m_AppData.AllDDiStartNo; im_MaxFwDDiPoints; i++) + { + SFesFwDi *pFwDi = m_ptrCFesRtu->m_pFwDDi + i; + if (INTROGEN != m_AppData.AllQOI) //组召唤 + { + if ((m_AppData.AllQOI-20) != pFwDi->ResParam1) + { + if (count == 0) + continue;//找到对应的组号 + else + { + m_AppData.AllDDiStartNo = m_ptrCFesRtu->m_MaxFwDDiPoints;//强制结束 + break;//当前点和前面的点不在同一组,则将之前的点为一完整报文先发 + } + } + } + if (count == 0) + StartAddr = m_AppData.DoublediStartAddress + i; + + int DiValue = pFwDi->Value; + /********************品质描述*************************************/ + if (m_AppData.qdsEnable) + { + if (pFwDi->Status & CN_FesValueComDown || pFwDi->Status == CN_FesValueNotUpdate)//数据非当前值(通讯中断) + DiValue |= IEC104SDI_SIQ_NT; + if (pFwDi->Status & CN_FesValueInvaild)//数据无效 + DiValue |= IEC104SDI_SIQ_IV; + } + data[8 + subLen + count] = DiValue; + + count++; + if (count >= SEND_DI_COUNT) + break; + } + m_AppData.AllDDiStartNo = i+1; //记录下次发送的Di起始地址 + if (count>0) + { + data[6] = M_DP_NA_1; //双点类型标识 + data[7] = 0x80 | count;//vsq + for (j = 0; j> (j * 8)); + for (j = 0; j> (j * 8)); + for (j = 0; j> (j * 8)); + FrameLen = 8 + subLen + count; + FillIFrameHeader(data, FrameLen); + SendDataToPort(data, FrameLen); + } + return count; +} + + +void CIEC104SDataProcThread::getAiFuncCodeAndLenWhenStationReq(const int nAiUploadType, int &nFuncCode, int &nLen) +{ + if((nAiUploadType == M_ME_NA_1)||(nAiUploadType == M_ME_NB_1)) //带品质描述的归一化值和标度化值 + { + nFuncCode = nAiUploadType; + nLen = 3; + } + else if(nAiUploadType == M_ME_ND_1)//analog message without quality + { + nFuncCode = nAiUploadType; + nLen = 2; + } + else if(nAiUploadType == M_ME_TD_1) //如果配置为带长时标的归一化值,在总召唤时按不带时标的带品质描述的归一化值上传 + { + nFuncCode = M_ME_NA_1; //如果配置为带长时标的归一化值,在总召唤时按不带时标的标度化值上传 + nLen = 3; + } + else if(nAiUploadType == M_ME_TE_1) //带长时标的标度化值 + { + nFuncCode = M_ME_NB_1; //如果配置为带长时标的归一化值,在总召唤时按不带时标的带品质描述的归一化值上传 + nLen = 3; + } + else if (nAiUploadType == M_ME_TF_1) //带CP56Time2a时标的测量值, 短浮点数 + { + nFuncCode = M_ME_NC_1; //如果配置为带长时标的归一化值,在总召唤时按不带时标的带品质描述的归一化值上传 + nLen = 5; + } + else//默认短浮点数 + { + nFuncCode = M_ME_NC_1; + nLen = 5; + } +} + +int CIEC104SDataProcThread::sendAllAi() +{ + if (!isTimetoSend()) + return 0; + + byte data[256]; + int i = 0; + int j = 0; + int AiValueLen = 0; + int count = 0; + int StartAddr = 0; + float AiFloatValue = 0; + int ShortAiValue = 0; + int AIQDDES = 0; + int AiValue = 0; + int subLen = m_AppData.trReasonSize + m_AppData.publicAddrSize + m_AppData.infoAddrSize; + int FrameLen = 0; + + //2020-03-09 thxiao 总召前可以把变化AI清除 + if (m_AppData.AllAiStartNo == 0) + { + m_ptrCFesRtu->ClearFwAiBuf(); + } + /*********--------各种帧类型标识的Ai值字节个数-----*******************/ + int nFuncCode = M_ME_NC_1; + getAiFuncCodeAndLenWhenStationReq(m_AppData.aiUploadType,nFuncCode,AiValueLen); + + data[6] = nFuncCode; + int maxAiCount = 230 / AiValueLen; + + for (i = m_AppData.AllAiStartNo; i < m_ptrCFesRtu->m_MaxFwAiPoints; i++) + { + SFesFwAi *pFwAi = m_ptrCFesRtu->m_pFwAi+i; + if (INTROGEN != m_AppData.AllQOI) //组召唤 + { + if ((m_AppData.AllQOI-20) != pFwAi->ResParam1) + { + if (count == 0) + continue; //找到对应的组号 + else + { + m_AppData.AllAiStartNo = m_ptrCFesRtu->m_MaxFwAiPoints;//强制结束 + break; //当前点和前面的点不在同一组,则将之前的点为一完整报文先发 + } + } + } + if(count == 0) + StartAddr = m_AppData.aiStartAddress + i; + + uint32 aiStatus = pFwAi->Status; + AiFloatValue = pFwAi->Value; + if(pFwAi->Used != 1) //表示该测点未使用,则尝试从Mi和Acc获取 + { + getMiOrAccValueAndSta(i,AiFloatValue,aiStatus);//获取不到,不会修改值 + } + + ShortAiValue = (int)AiFloatValue; + + switch(data[6]) + { + case M_ME_NA_1: + case M_ME_NB_1: + case M_ME_NC_1: + /********************品质描述*************************************/ + AIQDDES=0; + if (m_AppData.qdsEnable) + { + if (aiStatus & CN_FesValueExceed) + AIQDDES |= IEC104SAI_QDS_OV; //数据溢出 + if (aiStatus & CN_FesValueComDown || aiStatus == CN_FesValueNotUpdate)//数据非当前值(通讯中断) + AIQDDES |= IEC104SAI_QDS_NT; + if (aiStatus & CN_FesValueInvaild)//数据无效 + AIQDDES |= IEC104SAI_QDS_IV; + } + if (data[6] == M_ME_NC_1) //短浮点数 + { + memcpy(&AiValue, &AiFloatValue, sizeof(AiFloatValue)); + for (j = 0; j < 4; j++) + data[8 + subLen + count*AiValueLen+j] = (byte)(AiValue >> (j * 8)); + } + else //带品质描述的归一化值和标度化值 + { + for (j = 0; j < 2; j++) + data[8 + subLen + count*AiValueLen + j] = (byte)(ShortAiValue >> (j * 8)); + } + data[8+subLen+ count*AiValueLen+j] = AIQDDES; + break; + default://M_ME_ND_1 默认为不带品质描述的归一化值21 + for(j=0;j<2;j++) + data[8+subLen+i*AiValueLen+j] = (byte)(ShortAiValue>>(j*8)); + break; + } + count++; + if (count >= maxAiCount) + break; + } + m_AppData.AllAiStartNo=i+1; //记录下次发送的Ai起始地址 + if(count>0) + { + data[7] = 0x80 | count;//vsq + for(j=0;j>(j*8)); + for(j=0;j>(j*8)); + for(j=0;j>(j*8)); + FrameLen = count*AiValueLen+8+subLen; + FillIFrameHeader(data,FrameLen); + SendDataToPort(data,FrameLen); + } + + return count; +} + +void CIEC104SDataProcThread::getMiOrAccValueAndSta(const int nRemoteNo, float &fValue, uint32 &uStatus) +{ + if(nRemoteNo < m_ptrCFesRtu->m_MaxFwMiPoints) + { + SFesFwMi *pFwMi = m_ptrCFesRtu->m_pFwMi + nRemoteNo; + if(pFwMi->Used == 1) //有此测点 + { + fValue = static_cast(pFwMi->Value); + uStatus = pFwMi->Status; + return; + } + } + + if(m_AppData.bAccUseAi && nRemoteNo < m_ptrCFesRtu->m_MaxFwAccPoints) + { + SFesFwAcc *pFwAcc = m_ptrCFesRtu->m_pFwAcc + nRemoteNo; + if(pFwAcc->Used == 1) //有此测点 + { + fValue = static_cast(pFwAcc->Value); + uStatus = pFwAcc->Status; + return; + } + } } diff --git a/product/src/fes/protocol/iec104s/IEC104SDataProcThread.h b/product/src/fes/protocol/iec104s/IEC104SDataProcThread.h index 31c67192..f3ebb0bf 100644 --- a/product/src/fes/protocol/iec104s/IEC104SDataProcThread.h +++ b/product/src/fes/protocol/iec104s/IEC104SDataProcThread.h @@ -185,6 +185,7 @@ typedef struct{ byte ignoreInvalid; //忽略数据无效位 1:忽略 0:不忽略 int aiStartAddress; //遥测起始地址 int aiUploadType; //遥测上传类型 + bool bAccUseAi; //累计量采用遥测类型上传 int SingaldiStartAddress; //单点遥信起始地址 int DoublediStartAddress; //双点遥信起始地址 int accStartAddress; //电度起始地址 @@ -268,6 +269,7 @@ typedef struct{ byte infoAddrSize; //信息体地址长度 1\2\3 byte strictComMode; //1:接收序号不对,断开网络。0:忽略 int aiUploadType; //遥测上传类型 + bool bAccUseAi; //累计量采用遥测类型上传 int aiStartAddress; //遥测起始地址 int SingaldiStartAddress; //单点遥信起始地址 int DoublediStartAddress; //双点遥信起始地址 @@ -360,6 +362,33 @@ private: bool isTimetoSend(); void ClearAppData(); + //根据规约配置中遥测类型获取一个测点占用的字节长度 + int getAiValueLen(const int nAiUploadType); + //根据规约配置中遥测类型获取对应的功能码和一个测点占用的字节长度 + void getAiFuncCodeAndLenWhenStationReq(const int nAiUploadType,int &nFuncCode,int &nLen); + /* 获取mi或者acc对应的值,使用场景:为了实现mi和acc作为ai来上传 + * nRemoteNo:远动号,也就是104的遥测点号 + * fValue:返回的测点值,不存在不改变原值 + * uStatus:返回的测点状态 + */ + void getMiOrAccValueAndSta(const int nRemoteNo,float &fValue,uint32 &uStatus); + + /* 填充测点到缓冲区 + * nAiCount:本次需要处理的数量 + * nRemainingCout:最大还能塞入几个,返回实际处理的数量 + * nHeadLen:帧头长度 + * nAiValueLen:一个测点占用的长度 + * data:报文缓冲区 + */ + int buildAiFrame(const int nAiCount,const int nRemainingCout,const int nHeadLen,const int nAiValueLen,byte data[]); + int buildMiFrame(const int nMiCount,const int nRemainingCout,const int nHeadLen,const int nAiValueLen,byte data[]); + int buildAccFrame(const int nAccCount,const int nRemainingCout,const int nHeadLen,const int nAiValueLen,byte data[]); + + //总召时发送所有的测点数据 + int sendAllDi(); + int sendAllDDi(); + int sendAllAi(); + /*短时标接口结构,转换为UTC毫秒数*/ __inline uint64 getUTCTime24Sec(int nMin, int nMsec); }; diff --git a/product/src/fes/protocol/iec61850_clientV3/IEC61850.cpp b/product/src/fes/protocol/iec61850_clientV3/IEC61850.cpp new file mode 100644 index 00000000..d3479c13 --- /dev/null +++ b/product/src/fes/protocol/iec61850_clientV3/IEC61850.cpp @@ -0,0 +1,418 @@ +#include "IEC61850.h" +#include "pub_utility_api/I18N.h" +#include "pub_utility_api/CharUtil.h" + +using namespace iot_public; + +CIEC61850 g_iec61850; +bool g_IEC61850IsMainFes = false; +bool g_IEC61850ChanelRun = true; + +int EX_SetBaseAddr(void *address) +{ + g_iec61850.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + g_iec61850.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + g_iec61850.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + g_iec61850.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + + +int EX_ChanTimer(int ChanNo) +{ + g_iec61850.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + boost::ignore_unused_variable_warning(flag); + g_IEC61850ChanelRun = false;//使所有的线程退出。 + return iotSuccess; +} + +CIEC61850::CIEC61850():m_ProtocolId(-1),m_ptrCFesBase(NULL) +{ + +} + +CIEC61850::~CIEC61850() +{ + m_vecDataThreadPtr.clear(); +} + +int CIEC61850::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + } + + //规约映射表初始化 + if(m_ptrCFesBase != NULL) + { + m_ptrCFesBase->ProtocolRtuInitByParam1((char*)"iec61850_clientV3"); + ReadConfigParam(); //加载配置文件中的RTU配置参数 + } + return iotSuccess; +} + +int CIEC61850::SetProperty(int IsMainFes) +{ + g_IEC61850IsMainFes = (IsMainFes == 1); + LOGDEBUG("CIEC61850::SetProperty g_IEC61850IsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief CIEC61850::OpenChan + * 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CIEC61850::OpenChan(int MainChanNo, int ChanNo, int OpenFlag) +{ + CFesChanPtr ptrMainFesChan = GetChanDataByChanNo(MainChanNo); + CFesChanPtr ptrFesChan = GetChanDataByChanNo(ChanNo); + + if(ptrMainFesChan == NULL || ptrFesChan == NULL) + { + return iotFailed; + } + +// if((OpenFlag==CN_FesChanThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) +// { +// } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //找到就用配置文件中配置,找不到就用构造函数默认参数 + SIEC61850AppConfParam stRtuConfParam; + auto iterConfig = m_mapConfMap.find(ptrMainFesChan->m_Param.ChanNo); + if(iterConfig != m_mapConfMap.end()) + { + stRtuConfParam = iterConfig->second; + } + + //open chan thread + CIEC61850DataProcThreadPtr ptrThread = + boost::make_shared(m_ptrCFesBase,ptrMainFesChan,stRtuConfParam); + + if (ptrThread == NULL) + { + LOGERROR("CIEC61850 EX_OpenChan() ChanNo:%d create CIEC61850DataProcThread error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + + if(iotSuccess != ptrThread->init()) + { + LOGERROR("CIEC61850 EX_OpenChan() ChanNo:%d init CIEC61850DataProcThread error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + + m_vecDataThreadPtr.push_back(ptrThread); + ptrThread->resume(); //start Data THREAD + } + } + + // 因为使用的sdk的连接,所以直接将通信状态设置为run + ptrMainFesChan->SetComThreadRunFlag(CN_FesRunFlag); + + return iotSuccess; +} + +/** + * @brief CIEC61850::CloseChan + * 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CIEC61850::CloseChan(int MainChanNo, int ChanNo, int CloseFlag) +{ + CFesChanPtr ptrMainFesChan = GetChanDataByChanNo(MainChanNo); + CFesChanPtr ptrFesChan = GetChanDataByChanNo(ChanNo); + + if(ptrMainFesChan == NULL || ptrFesChan == NULL) + { + return iotFailed; + } + + //虽然本协议使用sdk,不是自己管理连接,但是需要执行SetComThreadRunFlag(CN_FesStopFlag),否则冗余状态变化时,无法重新打开通道 + if ((CloseFlag == CN_FesChanThread_Flag) || (CloseFlag == CN_FesChanAndDataThread_Flag)) + { + ptrFesChan->SetComThreadRunFlag(CN_FesStopFlag); + LOGINFO("ChanNo=%d ptrFesChan->SetComThreadRunFlag(CN_FesStopFlag)", ptrFesChan->m_Param.ChanNo); + } + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + + return iotSuccess; +} + +/** + * @brief CIEC61850::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int CIEC61850::ChanTimer(int MainChanNo) +{ + boost::ignore_unused_variable_warning(MainChanNo); + //把命令缓冲时间间隔到的命放到发送命令缓冲区 + return iotSuccess; +} + +int CIEC61850::ReadConfigParam() +{ + if (m_ptrCFesBase == NULL) + return iotFailed; + + m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"iec61850_clientV3"); + if (m_ProtocolId == -1) + { + LOGERROR("ReadConfigParam() ProtoclID=iec61850_clientV3 error"); + return iotFailed; + } + + LOGINFO("iec61850_clientV3 ProtoclID=%d",m_ProtocolId); + + CCommonConfigParse config; + SIEC61850AppConfParam defaultRtuParam; + CFesChanPtr ptrChan = NULL; //CHAN数据区 + CFesRtuPtr ptrRTU = NULL; + + if (config.load("../../data/fes/", "iec61850_clientV3.xml") == iotFailed) + { + LOGWARN("iec61850 load iec61850_clientV3.xml error"); + return iotSuccess; + } + + LOGINFO("iec61850 load iec61850_clientV3.xml ok"); + parseRtuConfig(config,"RTU?",defaultRtuParam); + + for (size_t nChanIdx = 0; nChanIdx < m_ptrCFesBase->m_vectCFesChanPtr.size(); nChanIdx++) + { + ptrChan = m_ptrCFesBase->m_vectCFesChanPtr[nChanIdx]; + if(ptrChan->m_Param.Used != 1 || m_ProtocolId != ptrChan->m_Param.ProtocolId) + { + continue; + } + + //found RTU + for (size_t nRtuIdx = 0; nRtuIdx < m_ptrCFesBase->m_vectCFesRtuPtr.size(); nRtuIdx++) + { + ptrRTU = m_ptrCFesBase->m_vectCFesRtuPtr[nRtuIdx]; + if (!ptrRTU->m_Param.Used || (ptrRTU->m_Param.ChanNo != ptrChan->m_Param.ChanNo)) + { + continue; + } + + SIEC61850AppConfParam param = defaultRtuParam; + string strRtuName = "RTU" + IntToString(ptrRTU->m_Param.RtuNo); + parseRtuConfig(config,strRtuName,param); + + m_mapConfMap[ptrRTU->m_Param.ChanNo] = param; + } + + } + return iotSuccess; +} + +int CIEC61850::parseRtuConfig(CCommonConfigParse &configParse,const std::string &strRtuName,SIEC61850AppConfParam &stParam) +{ + LOGDEBUG("CIEC61850:解析RTU参数,RTU=%s",strRtuName.c_str()); + //找到就用配置文件,找不到就用构造函数中的值 + if(iotSuccess == configParse.getIntValue(strRtuName,"enable_report_retry_period",stParam.nEnableRportRetryPeriod)) + { + stParam.nEnableRportRetryPeriod *= MSEC_PER_SEC; + } + else + { + return iotFailed; //如果找不到这个参数,认为本RTU没有配置,那就采用默认配置 + } + + configParse.getStringValue(strRtuName,"valid_path_suffix",stParam.strValidPathSuffix); + boost::trim_if(stParam.strValidPathSuffix,boost::is_any_of(";;")||boost::is_space()); + + configParse.getBoolValue(strRtuName,"enable_soe",stParam.bEnableSOE); + configParse.getBoolValue(strRtuName,"enable_remote_advanced_param",stParam.bEnableRemoteAdvancedParam); + configParse.getBoolValue(strRtuName,"enable_local_advanced_param",stParam.bEnableLocalAdvancedParam); + configParse.getIntValue(strRtuName,"Local_AE_Qualifier",stParam.nLocalAEQualifier); + string strRCBMask = configParse.getStringWithDefault(strRtuName,"RCB_MASK",""); + if(!strRCBMask.empty()) + { + stParam.dwRCBMask = boost::lexical_cast(strRCBMask); + } + + string strSetRealRCB = configParse.getStringWithDefault(strRtuName,"set_real_rcb",""); + if(!strSetRealRCB.empty()) + { + stParam.bSetRealRCB = boost::lexical_cast(strSetRealRCB); + } + + string strPSel; + string strSSel; + string strTSel; + if(stParam.bEnableRemoteAdvancedParam) + { + configParse.getIntValue(strRtuName,"Remote_AE_Qualifier",stParam.nRemoteAEQualifier); + + configParse.getStringValue(strRtuName,"Remote_Psel",strPSel); + configParse.getStringValue(strRtuName,"Remote_Ssel",strSSel); + configParse.getStringValue(strRtuName,"Remote_Tsel",strTSel); + + if(!convertToPsel(strPSel,stParam.stRemotePSel) || + !convertToSsel(strSSel,stParam.stRemoteSSel) || + !convertToTsel(strTSel,stParam.stRemoteTSel) ) + { + LOGWARN("CIEC61850:解析Remote相关参数失败.RtuName=%s",strRtuName.c_str()); + stParam.bEnableRemoteAdvancedParam = false; //有一个失败就禁用掉 + } + } + + if(stParam.bEnableLocalAdvancedParam) + { + configParse.getIntValue(strRtuName,"Local_AE_Qualifier",stParam.nRemoteAEQualifier); + + configParse.getStringValue(strRtuName,"Local_Psel",strPSel); + configParse.getStringValue(strRtuName,"Local_Ssel",strSSel); + configParse.getStringValue(strRtuName,"Local_Tsel",strTSel); + + if(!convertToPsel(strPSel,stParam.stLocalPSel) || + !convertToSsel(strSSel,stParam.stLocalSSel) || + !convertToTsel(strTSel,stParam.stLocalTSel) ) + { + LOGWARN("CIEC61850:解析Local相关参数失败.RtuName=%s",strRtuName.c_str()); + stParam.bEnableLocalAdvancedParam = false; //有一个失败就禁用掉 + } + } + + return iotSuccess; +} + +bool CIEC61850::convertToPsel(const string &strPsel, PSelector &stPsel) +{ + string strTempSel = boost::algorithm::trim_copy(strPsel); + if(strTempSel.empty()) + { + return false; + } + + std::vector vecRet; + boost::algorithm::split(vecRet, strTempSel, boost::algorithm::is_any_of(" "),boost::algorithm::token_compress_on); + if(vecRet.size() > 16 || vecRet.empty()) + { + return false; + } + + stPsel.size = static_cast(vecRet.size()); + for(size_t i = 0;i < vecRet.size();i++) + { + if(vecRet[i].empty()) + { + continue; + } + + stPsel.value[i] = StringToByte(vecRet[i]); + } + + return true; +} + +bool CIEC61850::convertToSsel(const string &strSsel, SSelector &stSsel) +{ + string strTempSel = boost::algorithm::trim_copy(strSsel); + if(strTempSel.empty()) + { + return false; + } + + std::vector vecRet; + boost::algorithm::split(vecRet, strTempSel, boost::algorithm::is_any_of(" "),boost::algorithm::token_compress_on); + if(vecRet.size() > 16 || vecRet.empty()) + { + return false; + } + + stSsel.size = static_cast(vecRet.size()); + for(size_t i = 0;i < vecRet.size();i++) + { + if(vecRet[i].empty()) + { + continue; + } + stSsel.value[i] = StringToByte(vecRet[i]); + } + + return true; +} + +bool CIEC61850::convertToTsel(const string &strTsel, TSelector &stTsel) +{ + string strTempSel = boost::algorithm::trim_copy(strTsel); + if(strTempSel.empty()) + { + return false; + } + + std::vector vecRet; + boost::algorithm::split(vecRet, strTempSel, boost::algorithm::is_any_of(" "),boost::algorithm::token_compress_on); + if(vecRet.size() > 4 || vecRet.empty()) + { + return false; + } + + stTsel.size = static_cast(vecRet.size()); + for(size_t i = 0;i < vecRet.size();i++) + { + if(vecRet[i].empty()) + { + continue; + } + stTsel.value[i] = StringToByte(vecRet[i]); + } + + return true; +} + +void CIEC61850::ClearDataProcThreadByChanNo(int nChanNo) +{ + for(auto it = m_vecDataThreadPtr.begin(); it != m_vecDataThreadPtr.end();it++) + { + const CIEC61850DataProcThreadPtr &ptrThread = *it; + if(ptrThread->getChannelNo() == nChanNo) + { + m_vecDataThreadPtr.erase(it); + LOGINFO("CIEC61850::ClearDataProcThreadByChanNo %d ok",nChanNo); + break; + } + } +} diff --git a/product/src/fes/protocol/iec61850_clientV3/IEC61850.h b/product/src/fes/protocol/iec61850_clientV3/IEC61850.h new file mode 100644 index 00000000..0d203f58 --- /dev/null +++ b/product/src/fes/protocol/iec61850_clientV3/IEC61850.h @@ -0,0 +1,101 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "IEC61850DataProcThread.h" +#include "pub_utility_api/CommonConfigParse.h" + +/* +#ifndef IEC104_API_EXPORT +#ifdef OS_WINDOWS +#define IEC104_API G_DECL_EXPORT +#else + //LINUX下 默认情况下会使用C++ API函数命名规则(函数名会增加字符),使用extern "C"修饰后变为C的函数名,便于使用。 +#define IEC104_API extern "C" +#endif +#else +#define IEC104_API G_DECL_IMPORT +#endif +*/ + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + + +class PROTOCOLBASE_API CIEC61850 : public CProtocolBase +{ +public: + CIEC61850(); + virtual ~CIEC61850(); + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + +private: + /** + * @brief 销毁指定通道资源 + * + * @param nChanNo 通道号 + */ + void ClearDataProcThreadByChanNo(int nChanNo); + + /** + * @brief 加载协议配置文件 data/fes/iec61850_clientV3 + * + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int ReadConfigParam(); + + /** + * @brief 解析RTU对应的参数,没有特殊配置时,使用默认参数 + * + * @param configParse 文件解析类,已经加载完了配置 + * @param strRtuName 要解析的RtuName,其实就是RTU+号 + * @param stParam 返回的参数 + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int parseRtuConfig(CCommonConfigParse &configParse,const std::string &strRtuName,SIEC61850AppConfParam &stParam); + + /** + * @brief 通过配置字符串解析成ISO 7层协议中Presentation表示层格式 + * + * @param strPsel 传入的字符串,以空格间隔 + * @param stPsel 返回的表示层结构 + * @return bool 成功返回true,失败返回false + */ + bool convertToPsel(const std::string &strPsel,PSelector &stPsel); + + /** + * @brief 通过配置字符串解析成ISO 7层协议中Session会话层格式 + * + * @param strSsel 传入的字符串,以空格间隔 + * @param stSsel 返回的表示层结构 + * @return bool 成功返回true,失败返回false + */ + bool convertToSsel(const std::string &strSsel,SSelector &stSsel); + + /** + * @brief 通过配置字符串解析成ISO 7层协议中Transport传输层格式 + * + * @param strTsel 传入的字符串,以空格间隔 + * @param stTsel 返回的表示层结构 + * @return bool 成功返回true,失败返回false + */ + bool convertToTsel(const std::string &strTsel,TSelector &stTsel); + +private: + int m_ProtocolId; //本协议的ID + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + CIEC61850DataProcThreadPtrSeq m_vecDataThreadPtr; //存放所有本协议的线程处理指针 + boost::unordered_map m_mapConfMap; //存储RTU对应的配置参数 +}; + diff --git a/product/src/fes/protocol/iec61850_clientV3/IEC61850Common.h b/product/src/fes/protocol/iec61850_clientV3/IEC61850Common.h new file mode 100644 index 00000000..7522a14d --- /dev/null +++ b/product/src/fes/protocol/iec61850_clientV3/IEC61850Common.h @@ -0,0 +1,277 @@ +#ifndef IEC61850COMMON_H +#define IEC61850COMMON_H +#include "FesDef.h" +#include "FesBase.h" +#include "iec61850_client.h" +#include + +class CIEC61850DataProcThread; + +//const std::string CN_Protocol_IEC61850V3 = "iec61850_clientV3"; //本协议标识 + +const int CN_IEC61850_MaxProcDataNum = 256; //报告控制块的最大数据缓冲区数目。当到达最大值时,批量修改系统数据值,提高效率 +const int CN_IEC61850_ContorlTimeout = 20 * MSEC_PER_SEC;//20s +const int CN_BLOCK_61850NameLen = 64; +const int CN_POINT_61850NameLen = 64; +const int CN_POINT_DO_61850NameLen = 128; +const int CN_POINT_RES_PARA_STR1_LEN = 64; //< 对应控制测点的保留字段RES_PARA_STR1 + +//对应测点值的数据结构,包含3个元素,0:值(可能struct嵌套) 1:品质 2:时间戳 +const int CN_IEC61850_Struct_Min_Size = 1; +const int CN_IEC61850_Struct_Value = 0; +const int CN_IEC61850_Struct_Quality = 1; +const int CN_IEC61850_Struct_Time = 2; + +//规约参数2对应的含义 +const int CN_IEC61850_Param2_int = 1; +const int CN_IEC61850_Param2_float = 2; +const int CN_IEC61850_Param2_int64 = 3; + +//暂时在遥控中使用,不确定不设置有没有问题。3这个是数字参考的iec61850client2,表示3远程控制.应该是规范中约定的 +const int CN_IEC61850_OrCat = 3; + +//测点上61850位置参数 +const int CN_IEC61850_Pos_Original = -1; //保持原样,也就是不对61850path进行后缀匹配 + +//IEC61850的RTU配置参数 +typedef struct _SIEC61850AppConfParam +{ + int nEnableRportRetryPeriod; //启用失败报告的重试时间 + std::string strValidPathSuffix; //合法的61850路径后缀 + uint32 dwRCBMask; //RCB掩码 + bool bEnableSOE; //是否产生SOE,默认不产生 + bool bSetRealRCB; //是否使用_S61850ReportParam.strRealRCB字段设置rtpId,因为索英厂商61850实现有问题,从rcb中获取的和report中的rtpid不一致 + bool bEnableRemoteAdvancedParam; //是否启用远程参数配置 + bool bEnableLocalAdvancedParam; //是否启用本地参数配置 + std::string strRemoteAPTitle; + int nRemoteAEQualifier; + PSelector stRemotePSel; + SSelector stRemoteSSel; + TSelector stRemoteTSel; + + std::string strLocalAPTitle; + int nLocalAEQualifier; + PSelector stLocalPSel; + SSelector stLocalSSel; + TSelector stLocalTSel; + + _SIEC61850AppConfParam() + :stRemotePSel({4,{0x00,0x00,0x00,0x01}}), + stRemoteSSel({2,{0x00,0x01}}), + stRemoteTSel({2,{0x00,0x01}}), + stLocalPSel({4,{0x00,0x00,0x00,0x01}}), + stLocalSSel({2,{0x00,0x01}}), + stLocalTSel({2,{0x00,0x01}}) + { + nEnableRportRetryPeriod = 300 * MSEC_PER_SEC; //默认5分钟 + bSetRealRCB = false; + bEnableSOE = false; + strValidPathSuffix = "$mag$f;$mag$i;$stVal;$setMag$f"; + dwRCBMask = RCB_ELEMENT_TRG_OPS | RCB_ELEMENT_OPT_FLDS | RCB_ELEMENT_RPT_ENA; + bEnableRemoteAdvancedParam = false; + bEnableLocalAdvancedParam = false; + strRemoteAPTitle = "1.1.1.999.1"; + nRemoteAEQualifier = 12; + + strLocalAPTitle = "1.1.1.999"; + nLocalAEQualifier = 12; + } +}SIEC61850AppConfParam,*P_SIEC61850AppConfParam; + + +//IEC61850 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct _SIEC61850AppData +{ + int comState; + int setCmdCount; + int controlTimeoutReset;//RTU自定义参数1为控制超时时间, 0:默认为20S,其他:N秒;有的保护修改定值需要较长的时间需要修改该参数 + int startConnenctDelayReset; //连接延迟,单位ms,对应通道配置:连接等待时间(秒) + int ConnectTimeout; //连接超时,单位ms,对应通道配置:连接超时时间(秒) + //int RecvTimeout; //请求超时,单位ms,对应通道配置:接收超时时间(秒), 此字段默认60秒,配置暂时没有放开 + int RespTimeout; //响应超时,单位ms,对应通道配置:响应超时时间(秒) + int enableReportRetryPeriod; //启用失败报告块间隔时间,单位ms + + bool bEnableRemoteAdvancedParam; //是否启用远程参数配置 + bool bEnableLocalAdvancedParam; //是否启用本地参数配置 + std::string strRemoteAPTitle; + int nRemoteAEQualifier; + PSelector stRemotePSel; + SSelector stRemoteSSel; + TSelector stRemoteTSel; + + std::string strLocalAPTitle; + int nLocalAEQualifier; + PSelector strLocalPSel; + SSelector strLocalSSel; + TSelector strLocalTSel; + + _SIEC61850AppData() + { + comState = CN_FesRtuComDown; + setCmdCount = 0; + controlTimeoutReset = CN_IEC61850_ContorlTimeout; + startConnenctDelayReset = 10 * MSEC_PER_SEC; + ConnectTimeout = 5 * MSEC_PER_SEC; + RespTimeout = 10 * MSEC_PER_SEC; + enableReportRetryPeriod = 300 * MSEC_PER_SEC; //默认5分钟 + bEnableRemoteAdvancedParam = false; + bEnableLocalAdvancedParam = false; + } +}SIEC61850AppData,*PSIEC61850AppData; + +//内存表fes_data_block +typedef struct _S61850RdbBlockParam +{ + int RtuNo; + int BlockNo; + int Used; //块使能 + char LDName[CN_BLOCK_61850NameLen]; //LD名 + int CallMode; //总召模式 + char DS[CN_BLOCK_61850NameLen]; //数据集(Ds),格式:不带IEDName,如:LD1/LLN0$dsRemoteSign + //int DsType; //数据集类型/定值设备ID + int DsCallTime; //数据集召唤时间(秒) + char RptID[CN_BLOCK_61850NameLen]; //报告控制块(RptID),格式:不带IEDName,如:LD1/LLN0$BR$brcbRelayDin.01,最后是实例号 + int Param1; //保留参数1,为1时表示此数据集中的包含了属性名 +}S61850RdbBlockParam,*PS61850RdbBlockParam; +typedef std::vector S61850RdbBlockParamSeq; + + +//测点内存表,主要用来读取61850参数 +typedef struct _S61850RdbPointParam{ + int rtuNo; + int pointNo;//Point号 + char path61850[CN_POINT_61850NameLen];//61850 Point路径 + int position61850;//61850位置 + char resStrPara1[CN_POINT_RES_PARA_STR1_LEN]; //< 对应规约参数9,RES_PARA_STR1 +}S61850RdbPointParam,*PS61850RdbPointParam; +typedef std::vector S61850RdbPointParamSeq; + +//DO测点内存表,主要用来读取61850参数,因为DO表的path61850长度与其它不一致,为了避免有修改不完整的地方,暂时在本协议中特例化处理DO表 +typedef struct _SDO61850RdbPointParam{ + int rtuNo; + int pointNo;//Point号 + char path61850[CN_POINT_DO_61850NameLen];//61850 Point路径 + int position61850;//61850位置 + char resStrPara1[CN_POINT_RES_PARA_STR1_LEN]; //< 对应规约参数9,RES_PARA_STR1 +}SDO61850RdbPointParam,*PSDO61850RdbPointParam; +typedef std::vector SDO61850RdbPointParamSeq; + +//测点参数相关 +typedef struct _S61850PointParam{ + std::string str61850path; + int nPntNo; + int nPntType; //对应FesDef.h中点类型 + std::vector v; + std::vector q; + std::vector t; + + _S61850PointParam() {} +}S61850PointParam,*P_S61850PointParam; +typedef std::vector S61850PointParamSeq; + +//<不带IEDName的61850路径,测点信息列表(为了实现数字量拆分位)> +typedef boost::unordered_map DataRef2PntInfoMAP; + +//<数据集名,<61850路径,测点信息>>,用来在收到report时先按数据集筛选,提高检索效率,相当于做了2层索引 +//typedef boost::unordered_map DataSet2PntInfoMAP; +typedef std::map DataSet2PntInfoMAP; +// 主键:测点点号*100 + 测点类型 +typedef boost::unordered_map CmdPntNo2InfoMAP; + +//< 用于保存处理批量写ao的所需参数 +typedef struct _SMultiAoCmdParam +{ + SFesAo *pAo; + std::string strDomainId; //不带iedname的DomainId,也就是/之前的部分 + std::string str61850Path; //不带着domainid的路径,也就是去除/之前的内容 + float fValue; + _SMultiAoCmdParam() + { + pAo = NULL; + fValue = 0; + } +}SMultiAoCmdParam,*PMultiAoCmdParam; + +typedef std::vector MultiAoCmdParamSeq; +//< 自定义参数9 RES_PARA_STR1对应AO点 +typedef boost::unordered_map StrPara1ToAoMAP; + +//< 自定义参数9 RES_PARA_STR1,控制值 +typedef std::vector > StrPara1ToValueSeq; + +typedef struct _S61850DataSetValue +{ + std::string strDataRef; + MmsValue *pValue; //测点值,是个结构体 + MmsValue *pReason; //bitstring 上传原因:数据变化(1)|品质变化(2)|数据更新(3)|定时上报(4)|总召(5) + + _S61850DataSetValue() { + pValue = NULL; + pReason = NULL; + } + + _S61850DataSetValue(const std::string &strRef,MmsValue *pVal,MmsValue *reason) { + strDataRef = strRef; + pValue = pVal; + pReason = reason; + } +}S61850DataSetValue,*PS61850DataSetValue; +typedef std::vector S61850DataSetValueSeq; + + +//报告回调函数传入参数 +typedef struct _SReportCallBackInParam +{ + CIEC61850DataProcThread* pDataProcThread; + LinkedList dataSetDirectory; + _SReportCallBackInParam() { + pDataProcThread = NULL; + dataSetDirectory = NULL; + } + _SReportCallBackInParam(CIEC61850DataProcThread* pProc,LinkedList pDs) { + pDataProcThread = pProc; + dataSetDirectory = pDs; + } +}SReportCallBackInParam,*PSReportCallBackInParam; + +enum class Enum61850CallMode{ + GI = 0, //总召 + PD = 1 //IntegerPd 周期上报 +}; + + +typedef struct _S61850ReportParam +{ + int nBlockId; //对应数据块序号 + bool bUsed; //是否启用,默认启用,如果数据集没有任何测点被使用就禁用掉 + std::string strIedName; + std::string strLDName; //逻辑设备名,不包括IEDNAME部分 + std::string strDataSetDir; //不带iedName MEAS/LLN0.dsAin + std::string strDataSetRef; //不带iedname MEAS/LLN0$dsAin + std::string strRCB; //不带iedname MEAS/LLN0.RP.brcbAin01 + std::string strRcbRef; //不带iedname MEAS/LLN0.RP.brcbAin + std::string strRealDataSetDir; //带iedName EMUMEAS/LLN0.dsAin + std::string strRealDataSetRef; //带iedname EMUMEAS/LLN0$dsAin + std::string strRealRCB; //带iedname EMUMEAS/LLN0.RP.brcbAin01 + std::string strRealRcbRef; //带iedname EMUMEAS/LLN0.RP.brcbAin + uint32 dwRCBMask; //用来定义报告中包含哪些信息 + int nCallMode; //总召方式 + int64 lDataSetCallPeriod; //总召周期,单位毫秒 + int64 lLastGITime; //最后一次总召时间 + int nParam1; //保留参数1,为1时表示此数据集中的包含了属性名 + SReportCallBackInParam stRptInParam; + + ClientReportControlBlock rcb; + + _S61850ReportParam() { + nBlockId = 0; + bUsed = true; + dwRCBMask = 0; + lLastGITime = 0L; + rcb = NULL; + } +}S61850ReportParam,*PS61850ReportParam; + +typedef std::vector S61850ReportParamSeq; + +#endif // IEC61850COMMON_H diff --git a/product/src/fes/protocol/iec61850_clientV3/IEC61850DataProcThread.cpp b/product/src/fes/protocol/iec61850_clientV3/IEC61850DataProcThread.cpp new file mode 100644 index 00000000..a1fc8f82 --- /dev/null +++ b/product/src/fes/protocol/iec61850_clientV3/IEC61850DataProcThread.cpp @@ -0,0 +1,2568 @@ +#include "IEC61850DataProcThread.h" +#include "dbms/rdb_api/CRdbAccessEx.h" +#include "pub_utility_api/I18N.h" +#include "pub_utility_api/CharUtil.h" +#include "boost/algorithm/string.hpp" +#include +#include "FesMessage.pb.h" +#include "pub_utility_api/RapidJsonHelper.h" + +using namespace iot_dbms; +using namespace iot_public; +using namespace iot_idl; + +#define JSON_KEY_TID "tid" +#define JSON_KEY_CreateTime "create_time" +#define JSON_KEY_ExpInterval "exp_interval" +#define JSON_KEY_CMD_NAME "cmd_name" +#define JSON_KEY_DATA "data" +#define JSON_CMD_TYPE_MultiAO "writeMultiAO" + +const int CN_DefaultVal_CmdExpInterval = 5000; //< json控制命令的默认有效时间,防止过期的命令被执行 + +extern bool g_IEC61850IsMainFes; +extern bool g_IEC61850ChanelRun; + +template +bool getValueByMmsValue(MmsValue *curValue,const std::vector vecIndex, T &retValue) +{ + if(curValue == NULL || vecIndex.empty()) // vecIndex为空,表示不包含此属性 + { + return false; + } + + MmsValue *tempValue = curValue; + + //先遍历到叶子节点 + if(MmsValue_getType(tempValue) == MMS_STRUCTURE) //结构体类型才会使用索引 + { + for(size_t i = 0; i < vecIndex.size();i++) + { + tempValue = MmsValue_getElement(tempValue,vecIndex[i]); + if(tempValue == NULL) + { + return false; + } + } + } + + if(tempValue == NULL) + { + return false; + } + + switch (MmsValue_getType(tempValue)) { + case MMS_BOOLEAN: + retValue = static_cast(MmsValue_getBoolean(tempValue)); + return true; + case MMS_INTEGER: //同时包含32位和64位 + retValue = static_cast(MmsValue_toInt64(tempValue)); + return true; + case MMS_UNSIGNED: + retValue = static_cast(MmsValue_toUint32(tempValue)); + return true; + case MMS_FLOAT://现在只解析了32位float,没有解析64位float + retValue = static_cast(MmsValue_toDouble(tempValue)); + return true; + case MMS_BIT_STRING: + retValue = static_cast(Quality_fromMmsValue(tempValue)); + return true; + case MMS_UTC_TIME: + retValue = static_cast(MmsValue_getUtcTimeInMs(tempValue)); + return true; + default: + break; + } + + return false; +} + + +bool isChangeReason(MmsValue *value) +{ + //ReasonForInclusion nReason = IEC61850_REASON_NOT_INCLUDED; + if(value == NULL || MmsValue_getType(value) != MMS_BIT_STRING) + { + return false; + } + + //上传原因:数据变化(1)|品质变化(2)|数据更新(3)|定时上报(4)|总召(5) + if(MmsValue_getBitStringBit(value,1)) + { + return true; + } + + return false; +} + +//todo:回调线程与主线程之间的消耗逻辑需要排查一下,是不是执行了closeied,就能保证回调已经结束了? +void reportCallbackFunction(void* parameter, ClientReport report) +{ + PSReportCallBackInParam pInParam = (PSReportCallBackInParam)parameter; + if(pInParam->pDataProcThread == NULL || report == NULL) + { + return; + } + + pInParam->pDataProcThread->handleReportInfo(report); +} + +CIEC61850DataProcThread::CIEC61850DataProcThread(CFesBase *ptrCFesBase,const CFesChanPtr &ptrChan,const SIEC61850AppConfParam &stConfParam) + :CTimerThreadBase("IEC61850DataProcThread",10,0,true), + m_ptrCFesBase(ptrCFesBase), + m_ptrFesChan(ptrChan), + m_ptrCurChan(NULL), + m_ptrCurRtu(NULL), + m_pCurCon(NULL), + m_curIP(0), + m_IPNum(0), + m_lLastEnableReportTime(0L), + m_stRtuParam(stConfParam) +{ +} + +CIEC61850DataProcThread::~CIEC61850DataProcThread() +{ + quit(); + + if(m_pCurCon != NULL) + { + closeIED(); + IedConnection_destroy(m_pCurCon); + m_pCurCon = NULL; + } + + //虽然本协议使用sdk,不是自己管理连接,但是需要执行SetComThreadRunFlag(CN_FesStopFlag),否则冗余状态变化时,无法重新打开通道 + m_ptrCurChan->SetLinkStatus(CN_FesChanDisconnect); + m_ptrFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + if(m_ptrCurRtu != NULL) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCurRtu, CN_FesRtuComDown); + } + + //销毁资源前将命令缓冲区清空,防止缓存引起的误操作 + ErrorControlRespProcess(); +} + +int CIEC61850DataProcThread::beforeExecute() +{ + return iotSuccess; +} + +void CIEC61850DataProcThread::execute() +{ + IedConnectionState conState = IedConnection_getState(m_pCurCon); + + if(IED_STATE_CONNECTED != conState) + { + //1.未连接,清空命令缓冲区 + ErrorControlRespProcess(); + + int64 lMinLastConnetTime = m_vecLastConnectTime[0]; //初始化时已经保证了最少一个IP + for(size_t nIpIdx = 1;nIpIdx < m_vecLastConnectTime.size();nIpIdx++) + { + lMinLastConnetTime = (std::min)(lMinLastConnetTime,m_vecLastConnectTime[nIpIdx]); + } + + if(getMonotonicMsec() - lMinLastConnetTime < m_AppData.startConnenctDelayReset) + { + return; //未到重连时间 + } + + //2.未连接状态,尝试连接,因为使用的同步连接方式,所以应该不会出现IED_STATE_CONNECTING和IED_STATE_CLOSING + //connectIED中会更换A/B网IP + if(iotSuccess == connectIED()) + { + setComState(CN_FesChanConnect); + } + else + { + setComState(CN_FesChanDisconnect); + } + + //记录本IP最后一次连接时间 + m_vecLastConnectTime[m_curIP] = getMonotonicMsec(); + return; //无论成功与否,结束本次循环,防止指令发送太快 + } + + //此处连接状态已经是IED_STATE_CONNECTED + int64 lCurTime = getMonotonicMsec(); + if(lCurTime - m_lLastEnableReportTime > m_stRtuParam.nEnableRportRetryPeriod) + { + installAllReportCallBack(); //可以重入,已经启用的Report不会重复执行 + m_lLastEnableReportTime = lCurTime; + } + + //处理 + handleCommand(); + + //周期性发送总召 + enableReportGI(); +} + +void CIEC61850DataProcThread::beforeQuit() +{ + +} + +void CIEC61850DataProcThread::setComState(int status) +{ + if (status == CN_FesChanConnect) + { + m_ptrCurChan->SetLinkStatus(CN_FesChanConnect); + if (m_AppData.comState == CN_FesRtuComDown) + { + m_AppData.comState = CN_FesRtuNormal; + m_ptrCurRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); + m_ptrCFesBase->WriteRtuSatus(m_ptrCurRtu, CN_FesRtuNormal); + } + } + else + { + m_ptrCurChan->SetLinkStatus(CN_FesChanDisconnect); + if (m_AppData.comState == CN_FesRtuNormal) + { + m_AppData.comState = CN_FesRtuComDown; + m_ptrCurRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + m_ptrCFesBase->WriteRtuSatus(m_ptrCurRtu, CN_FesRtuComDown); + } + } +} + +/** + * @brief CIEC61850DataProcThread::ErrorControlRespProcess + * @param + * @param + * @param 网络令来需要做异常处理断开时有控制命 + * @return + */ +void CIEC61850DataProcThread::ErrorControlRespProcess() +{ + SFesRxDoCmd RxDoCmd; + SFesTxDoCmd TxDoCmd; + SFesRxAoCmd RxAoCmd; + SFesTxAoCmd TxAoCmd; + SFesRxMoCmd RxMoCmd; + SFesTxMoCmd TxMoCmd; + + if(m_ptrCurRtu == NULL) + return; + + while(m_ptrCurRtu->GetRxDoCmdNum() > 0) + { + if(m_ptrCurRtu->ReadRxDoCmd(1,&RxDoCmd) != 1) + { + continue; + } + + if(!g_IEC61850IsMainFes) //备机不处理 + { + continue; + } + + strcpy(TxDoCmd.TableName,RxDoCmd.TableName); + strcpy(TxDoCmd.ColumnName,RxDoCmd.ColumnName); + strcpy(TxDoCmd.TagName,RxDoCmd.TagName); + strcpy(TxDoCmd.RtuName,RxDoCmd.RtuName); + TxDoCmd.retStatus = CN_ControlFailed; + TxDoCmd.CtrlActType = RxDoCmd.CtrlActType; + //为适应转发规约增加 + TxDoCmd.CtrlDir = RxDoCmd.CtrlDir; + TxDoCmd.RtuNo = RxDoCmd.RtuNo; + TxDoCmd.PointID = RxDoCmd.PointID; + TxDoCmd.FwSubSystem = RxDoCmd.FwSubSystem; + TxDoCmd.FwRtuNo = RxDoCmd.FwRtuNo; + TxDoCmd.FwPointNo = RxDoCmd.FwPointNo; + TxDoCmd.SubSystem = RxDoCmd.SubSystem; + + sprintf(TxDoCmd.strParam,I18N_C("遥控失败!RtuNo:%d 遥控点:%d"),getRtuNo(),RxDoCmd.PointID); + LOGINFO ("网络已断开 DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", + RxDoCmd.CtrlActType,RxDoCmd.iValue,RxDoCmd.RtuName,RxDoCmd.PointID); + //为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1,&TxDoCmd); + } + + while(m_ptrCurRtu->GetRxAoCmdNum() > 0) + { + if(m_ptrCurRtu->ReadRxAoCmd(1,&RxAoCmd) != 1) + { + continue; + } + + if(!g_IEC61850IsMainFes) //备机不处理 + { + continue; + } + + if(RxAoCmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + strcpy(TxAoCmd.TableName,RxAoCmd.TableName); + strcpy(TxAoCmd.ColumnName,RxAoCmd.ColumnName); + strcpy(TxAoCmd.TagName,RxAoCmd.TagName); + strcpy(TxAoCmd.RtuName,RxAoCmd.RtuName); + TxAoCmd.retStatus = CN_ControlFailed; + sprintf(TxAoCmd.strParam,I18N_C("遥调失败!RtuNo:%d 遥调点:%d"),getRtuNo(),RxAoCmd.PointID); + TxAoCmd.CtrlActType = RxAoCmd.CtrlActType; + //为适应转发规约增加 + TxAoCmd.CtrlDir = RxAoCmd.CtrlDir; + TxAoCmd.RtuNo = RxAoCmd.RtuNo; + TxAoCmd.PointID = RxAoCmd.PointID; + TxAoCmd.FwSubSystem = RxAoCmd.FwSubSystem; + TxAoCmd.FwRtuNo = RxAoCmd.FwRtuNo; + TxAoCmd.FwPointNo = RxAoCmd.FwPointNo; + TxAoCmd.SubSystem = RxAoCmd.SubSystem; + //为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&TxAoCmd); + } + + LOGINFO("网络已断开 AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", + RxAoCmd.CtrlActType, RxAoCmd.fValue, RxAoCmd.RtuName, RxAoCmd.PointID); + } + + while(m_ptrCurRtu->GetRxMoCmdNum() > 0) + { + if(m_ptrCurRtu->ReadRxMoCmd(1,&RxMoCmd) != 1) + { + continue; + } + + if(!g_IEC61850IsMainFes) //备机不处理 + { + continue; + } + + strcpy(TxMoCmd.TableName,RxMoCmd.TableName); + strcpy(TxMoCmd.ColumnName,RxMoCmd.ColumnName); + strcpy(TxMoCmd.TagName,RxMoCmd.TagName); + strcpy(TxMoCmd.RtuName,RxMoCmd.RtuName); + TxMoCmd.retStatus = CN_ControlFailed; + TxMoCmd.CtrlActType = RxMoCmd.CtrlActType; + //为适应转发规约增加 + TxMoCmd.CtrlDir = RxMoCmd.CtrlDir; + TxMoCmd.RtuNo = RxMoCmd.RtuNo; + TxMoCmd.PointID = RxMoCmd.PointID; + TxMoCmd.FwSubSystem = RxMoCmd.FwSubSystem; + TxMoCmd.FwRtuNo = RxMoCmd.FwRtuNo; + TxMoCmd.FwPointNo = RxMoCmd.FwPointNo; + TxMoCmd.SubSystem = RxMoCmd.SubSystem; + sprintf(TxMoCmd.strParam, I18N_C("混合量输出成功!RtuNo:%d 混合量输出点:%d"), getRtuNo(), RxMoCmd.PointID); + + LOGINFO("网络已断开 MO混合量执行失败 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", + RxMoCmd.CtrlActType,RxMoCmd.iValue,RxMoCmd.RtuName,RxMoCmd.PointID); + //为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&TxMoCmd); + } + + //< 暂时只清空json自定义命令,不做反馈 + m_ptrCurRtu->clearJsonFormatReqCmdBuf(); +} + +void CIEC61850DataProcThread::handleValueByDataRef(S61850DataSetValueSeq &vecDataSetValue, + const DataRef2PntInfoMAP &mapDataRef2PntInfo) +{ + SFesRtuDiValue DiValue[CN_IEC61850_MaxProcDataNum]; + SFesChgDi ChgDi[CN_IEC61850_MaxProcDataNum]; + SFesSoeEvent SoeEvent[CN_IEC61850_MaxProcDataNum]; + SFesChgAi ChgAi[CN_IEC61850_MaxProcDataNum]; + SFesChgMi ChgMi[CN_IEC61850_MaxProcDataNum]; + SFesChgAcc ChgAcc[CN_IEC61850_MaxProcDataNum]; + + int AiChgCount = 0; + int DiValueCount = 0; + int SoeCount = 0; + int DiChgCount = 0; + int AccChgCount = 0; + int MiChgCount = 0; + + for (size_t i = 0; i < vecDataSetValue.size(); i++) + { + const S61850DataSetValue &stDatasetValue = vecDataSetValue[i]; + +// int nArraySize = MmsValue_getArraySize(stDatasetValue.pValue); +// if(nArraySize < CN_IEC61850_Struct_Min_Size) +// { +// LOGWARN("CIEC61850:接收到测点值结构错误.预期size=%d,实际=%d",CN_IEC61850_Struct_Min_Size,nArraySize); +// continue; +// } + + auto iterPnt = mapDataRef2PntInfo.find(stDatasetValue.strDataRef); + if(iterPnt == mapDataRef2PntInfo.end()) + { + continue; + } + const S61850PointParamSeq &vecPntParam = iterPnt->second; + + for(size_t nPntIdx = 0; nPntIdx < vecPntParam.size();nPntIdx++) + { + const S61850PointParam &stPntParam = vecPntParam[nPntIdx]; + switch (stPntParam.nPntType) + { + case CN_Fes_DI: + procDiDataValue(stPntParam,stDatasetValue, &DiValue[0], &ChgDi[0], &SoeEvent[0], DiValueCount, DiChgCount, SoeCount); + break; + case CN_Fes_AI: + procAiDataValue(stPntParam,stDatasetValue, &ChgAi[0], AiChgCount); + break; + case CN_Fes_MI: + procMiProcess(stPntParam,stDatasetValue, &ChgMi[0], MiChgCount); + break; + case CN_Fes_ACC: + procAccProcess(stPntParam,stDatasetValue, &ChgAcc[0], AccChgCount); + break; + case CN_Fes_Setting: //定值 + break; + default: + break; + } + } + } + + if (DiChgCount > 0) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCurRtu, DiChgCount, &ChgDi[0]); + DiChgCount = 0; + } + if (DiValueCount > 0) + { + m_ptrCurRtu->WriteRtuDiValue(DiValueCount, &DiValue[0]); + DiValueCount = 0; + } + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCurRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + if (AiChgCount > 0) + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCurRtu, AiChgCount, &ChgAi[0]); + AiChgCount = 0; + } + + if(MiChgCount > 0) + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCurRtu,MiChgCount,&ChgMi[0]); + MiChgCount = 0; + } + + if(AccChgCount > 0) + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCurRtu, AccChgCount, &ChgAcc[0]); + AccChgCount = 0; + } +} + +void CIEC61850DataProcThread::procAiDataValue(const S61850PointParam &stPntParam, + const S61850DataSetValue &stDataSetValue, + SFesChgAi *pChgAi, int &ChgCount) +{ + //调用前判断了curValue结构的合法性 + MmsValue *curValue = stDataSetValue.pValue; + SFesAi *pAi; + SFesRtuAiValue AiValue; + SFesChgAi ChgAi; + int retCount; + + if ((pAi = GetFesAiByPointNo(m_ptrCurRtu, stPntParam.nPntNo)) == NULL) + return; + + AiValue.Status = CN_FesValueUpdate; + + float fval = 0.0f; + Quality nQulity = 0; + if(!getValueByMmsValue(curValue,stPntParam.v,fval)) + { + AiValue.Status |= CN_FesValueInvaild; + } + + if(getValueByMmsValue(curValue,stPntParam.q,nQulity) && + Quality_isFlagSet(&nQulity, QUALITY_VALIDITY_INVALID)) + { + //不存在或者失败认为数据是好的 + fval = 0.0f; //无效点值清零 + AiValue.Status |= CN_FesValueInvaild; + } + + uint64 lTime = 0; + if(!getValueByMmsValue(curValue,stPntParam.t,lTime)) + { + lTime = getUTCTimeMsec(); + } + + AiValue.PointNo = pAi->PointNo; //PointNo + AiValue.Value = fval; + AiValue.time = lTime; + + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCurRtu->WriteRtuAiValueAndRetChg(1, &AiValue, &retCount, &ChgAi); + if ((retCount > 0) && (g_IEC61850IsMainFes == true))//主机才报告变化数据 + { + memcpy(pChgAi + ChgCount, &ChgAi, sizeof(ChgAi)); + ChgCount++; + } + + if (ChgCount >= CN_IEC61850_MaxProcDataNum) + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCurRtu, ChgCount, pChgAi); + ChgCount = 0; + } + return; +} + +void CIEC61850DataProcThread::procDiDataValue(const S61850PointParam &stPntParam, + const S61850DataSetValue &stDataSetValue, + SFesRtuDiValue* pDiValue, SFesChgDi *pChgDi, SFesSoeEvent *pSoeEvent, + int &ValueCount, int &ChgCount, int &SoeCount) +{ + SFesDi *pDi; + SFesRtuDiValue *DiValuePtr; + SFesChgDi *ChgDiPtr; + SFesSoeEvent *SoeEventPtr; + byte status = CN_FesValueUpdate; + + if ((pDi = GetFesDiByPointNo(m_ptrCurRtu, stPntParam.nPntNo)) == NULL) + return; + + ChgDiPtr = pChgDi + ChgCount; + SoeEventPtr = pSoeEvent + SoeCount; + DiValuePtr = pDiValue + ValueCount; + + bool bIsChangeReason = isChangeReason(stDataSetValue.pReason); + + MmsValue *curValue = stDataSetValue.pValue; + + byte bitValue = 0; + int32 nValue = 0; + if(!getValueByMmsValue(curValue,stPntParam.v,nValue)) + { + status |= CN_FesValueInvaild; + } + else + { + std::bitset<32> bitsetValue(nValue); + bitValue = bitsetValue.test(pDi->Param4); + } + + Quality nQulity = 0; + if(getValueByMmsValue(curValue,stPntParam.q,nQulity) && + Quality_isFlagSet(&nQulity, QUALITY_VALIDITY_INVALID)) + { + status |= CN_FesValueInvaild; + } + + uint64 lTime = 0; + if(!getValueByMmsValue(curValue,stPntParam.t,lTime)) + { + lTime = getUTCTimeMsec(); + } + + if (pDi->Revers) + bitValue ^= 1; //这个取反逻辑有问题,双位开关取反不对 + + if ((bitValue != pDi->Value) && (g_IEC61850IsMainFes == true) && (pDi->Status & CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDiPtr->TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDiPtr->ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDiPtr->TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDiPtr->Value = bitValue; + ChgDiPtr->Status = status; + ChgDiPtr->time = lTime; + ChgDiPtr->RtuNo = getRtuNo(); + ChgDiPtr->PointNo = pDi->PointNo; + LOGTRACE("变化遥信 RtuNo:%d PointNo:%d %s value=%d status=%d ms=%" PRId64 , + getRtuNo(), pDi->PointNo, ChgDiPtr->TagName, ChgDiPtr->Value,ChgDiPtr->Status, ChgDiPtr->time); + ChgCount++; + } + //Create Soe + if (m_stRtuParam.bEnableSOE && bIsChangeReason && (g_IEC61850IsMainFes == true))//变化报告控制块 + { + SoeEventPtr->time = lTime; + memcpy(SoeEventPtr->TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEventPtr->ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEventPtr->TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEventPtr->Value = bitValue; + SoeEventPtr->Status = status; + SoeEventPtr->FaultNum = 0; + SoeEventPtr->RtuNo = getRtuNo(); + SoeEventPtr->PointNo = pDi->PointNo; + LOGDEBUG("SOE RtuNo:%d PointNo:%d %s value=%d status=%d ms=%" PRId64, getRtuNo(), + pDi->PointNo, SoeEventPtr->TagName, SoeEventPtr->Value,SoeEventPtr->Status,SoeEventPtr->time); + SoeCount++; + } + //更新点值 + DiValuePtr->PointNo = pDi->PointNo; + DiValuePtr->Value = bitValue; + DiValuePtr->Status = status; + DiValuePtr->time = lTime; + ValueCount++; + + if (ChgCount >= CN_IEC61850_MaxProcDataNum) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCurRtu, ChgCount, pChgDi); + ChgCount = 0; + } + if (ValueCount >= CN_IEC61850_MaxProcDataNum) + { + m_ptrCurRtu->WriteRtuDiValue(ValueCount, pDiValue); + ValueCount = 0; + } + if (SoeCount >= CN_IEC61850_MaxProcDataNum) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCurRtu, SoeCount, pSoeEvent); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, pSoeEvent); + SoeCount = 0; + } + + return; +} + +void CIEC61850DataProcThread::procMiProcess(const S61850PointParam &stPntParam, + const S61850DataSetValue &stDataSetValue, + SFesChgMi *pChgMi, int &ChgCount) +{ + //调用前判断了curValue结构的合法性 + MmsValue *curValue = stDataSetValue.pValue; + SFesMi *pMi; + SFesRtuMiValue MiValue; + SFesChgMi ChgMi; + int retCount; + + if ((pMi = GetFesMiByPointNo(m_ptrCurRtu, stPntParam.nPntNo)) == NULL) + return; + + MiValue.Status = CN_FesValueUpdate; + int32 nValue = 0; + Quality nQulity = 0; + + if(!getValueByMmsValue(curValue,stPntParam.v,nValue)) + { + MiValue.Status |= CN_FesValueInvaild; + } + + if(getValueByMmsValue(curValue,stPntParam.q,nQulity) && + Quality_isFlagSet(&nQulity, QUALITY_VALIDITY_INVALID)) + { + //不存在或者失败认为数据是好的 + nValue = 0; //无效点值清零 + MiValue.Status |= CN_FesValueInvaild; + } + + uint64 lTime = 0; + if(!getValueByMmsValue(curValue,stPntParam.t,lTime)) + { + lTime = getUTCTimeMsec(); + } + + MiValue.PointNo = pMi->PointNo; //PointNo + MiValue.Value = nValue; + MiValue.time = lTime; + + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCurRtu->WriteRtuMiValueAndRetChg(1, &MiValue, &retCount, &ChgMi); + if ((retCount > 0) && (g_IEC61850IsMainFes == true))//主机才报告变化数据 + { + memcpy(pChgMi + ChgCount, &ChgMi, sizeof(ChgMi)); + ChgCount++; + } + + if (ChgCount >= CN_IEC61850_MaxProcDataNum) + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCurRtu, ChgCount, pChgMi); + ChgCount = 0; + } + + return; +} + +void CIEC61850DataProcThread::procAccProcess(const S61850PointParam &stPntParam, + const S61850DataSetValue &stDataSetValue, + SFesChgAcc *pChgAcc, int &ChgCount) +{ + //调用前判断了curValue结构的合法性 + MmsValue *curValue = stDataSetValue.pValue; + SFesAcc *pAcc; + SFesRtuAccValue AccValue; + SFesChgAcc ChgAcc; + int retCount; + + if ((pAcc = GetFesAccByPointNo(m_ptrCurRtu, stPntParam.nPntNo)) == NULL) + return; + + AccValue.Status = CN_FesValueUpdate; + int64 iValue64 = 0; + Quality nQulity = 0; + if(!getValueByMmsValue(curValue,stPntParam.v,iValue64)) + { + AccValue.Status |= CN_FesValueInvaild; + } + + if(getValueByMmsValue(curValue,stPntParam.q,nQulity) && + Quality_isFlagSet(&nQulity, QUALITY_VALIDITY_INVALID)) + { + //不存在或者失败认为数据是好的 + AccValue.Status |= CN_FesValueInvaild; + } + + uint64 lTime = 0; + if(!getValueByMmsValue(curValue,stPntParam.t,lTime)) + { + lTime = getUTCTimeMsec(); + } + + AccValue.PointNo = pAcc->PointNo; //远动号从点序号移植到规约参数1 + AccValue.Value = static_cast(iValue64); + AccValue.time = lTime; + //Acc 需要判断的情况很多,所以“WriteRtuAccValueAndRetChg”内部进行判断 + m_ptrCurRtu->WriteRtuAccValueAndRetChg(1, &AccValue, &retCount, &ChgAcc); + if ((retCount > 0) && (g_IEC61850IsMainFes == true))//主机才报告变化数据 + { + memcpy(pChgAcc + ChgCount, &ChgAcc, sizeof(ChgAcc)); + ChgCount++; + } + + if (ChgCount >= CN_IEC61850_MaxProcDataNum) + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCurRtu, ChgCount, pChgAcc); + ChgCount = 0; + } + + return; +} + +void CIEC61850DataProcThread::handleCommand() +{ + if(m_ptrCurChan->m_LinkStatus != CN_FesChanConnect) + { + //此重新连接之前会清空所有命令缓存,所以此处就不处理了 + return; + } + + if(m_ptrCurRtu->GetRxDoCmdNum() > 0) + { + DoCmdProcess(); + } + else if(m_ptrCurRtu->GetRxMoCmdNum() > 0) + { + MoCmdProcess(); + } + else if(m_ptrCurRtu->GetRxAoCmdNum() > 0) + { + AoCmdProcess(); + } + else if(m_ptrCurRtu->getJsonFormatReqCmdSize() > 0) + { + handleJsonFormatCmd(); + } +} + +void CIEC61850DataProcThread::DoCmdProcess() +{ + SFesDo *pDo; + SFesRxDoCmd cmd; + SFesTxDoCmd retCmd; + + if(m_ptrCurRtu->ReadRxDoCmd(1,&cmd) != 1) + { + return; + } + + //get the cmd ok + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + retCmd.CtrlActType = cmd.CtrlActType; + int doValue = cmd.iValue; + + if (m_AppData.comState == CN_FesRtuComDown)//通信没有建立 + { + //return failed to scada + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N_C("通信没有建立遥控失败")); + LOGINFO("CIEC61850:通信没有建立遥控失败 RtuNo:%d", getRtuNo()); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + return; + } + //遥控增加五防闭锁检查 + if (m_ptrCurRtu->CheckWuFangDoStatus(cmd.PointID) == 0)//闭锁 + { + //return failed to scada + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N_C("遥控失败!RtuNo:%d 遥控点:%d 闭锁"), getRtuNo(), cmd.PointID); + LOGINFO("CIEC61850:遥控失败!RtuNo:%d 遥控点:%d 闭锁", getRtuNo(), cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + return; + } + + pDo = GetFesDoByPointNo(m_ptrCurRtu, cmd.PointID); + if(pDo == NULL) + { + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N_C("找不到遥控点遥控失败!")); + LOGINFO("CIEC61850:找不到遥控点遥控失败,RtuNo:%d,遥控点:%d 命令类型:%d", getRtuNo(), cmd.PointID, cmd.CtrlActType); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + return; + } + + S61850PointParam st61850Param; + if(!getCmdPntInfo(CN_Fes_DO,pDo->PointNo,st61850Param)) + { + //return failed to scada + retCmd.retStatus = CN_ControlPointErr; + sprintf(retCmd.strParam, I18N_C("遥控失败!找不到遥控点控制参数")); + LOGINFO("CIEC61850:遥控失败!RtuNo:%d 找不到遥控点控制参数:%d", getRtuNo(), cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + return; + } + + string strDataRef; + FunctionalConstraint fc = IEC61850_FC_NONE; + getDataRefBy61850Path(st61850Param.str61850path, strDataRef, fc); + MmsValue *ctrlVal = MmsValue_newBoolean(doValue == 1); + ControlObjectClient ctrlClient = NULL; + bool bCtrlSuccess = false; + IedClientError error = IED_ERROR_OK; + + switch (cmd.CtrlActType) + { + case CN_ControlSelect: + ctrlClient = getControlObjectClient(strDataRef.c_str(), fc); + if (ctrlClient != NULL) + { + switch (ControlObjectClient_getControlModel(ctrlClient)) { + case CONTROL_MODEL_DIRECT_NORMAL: //1.直控 + case CONTROL_MODEL_DIRECT_ENHANCED: //3.加强型直控 + bCtrlSuccess = true; + LOGINFO("CIEC61850:当前测点无需执行选择,直接返回成功 RtuNo:%d 遥控点:%d 值:%d", getRtuNo(), cmd.PointID, doValue); + break; + case CONTROL_MODEL_SBO_NORMAL: //2.选择型控制 + bCtrlSuccess = ControlObjectClient_select(ctrlClient,fc); + error = ControlObjectClient_getLastError(ctrlClient); + break; + case CONTROL_MODEL_SBO_ENHANCED: //4.加强型选择控制 + ControlObjectClient_setOrigin(ctrlClient, NULL, CN_IEC61850_OrCat); + bCtrlSuccess = ControlObjectClient_selectWithValue(ctrlClient, ctrlVal,fc); + error = ControlObjectClient_getLastError(ctrlClient); + break; + default: + LOGINFO("下发遥控选择命令失败.不支持的控制类型[%d] RtuNo:%d 遥控点:%d 值:%d", + ControlObjectClient_getControlModel(ctrlClient),getRtuNo(), cmd.PointID, doValue); + break; + } + } + else + { + LOGINFO("下发遥调命令,执行getControlObjectClient失败 RtuNo:%d 遥控点:%d 下发值:%d 接收命令值:%d", + getRtuNo(), cmd.PointID, doValue, cmd.iValue); + } + + if (bCtrlSuccess) + { + retCmd.retStatus = CN_ControlSuccess; + sprintf(retCmd.strParam, I18N_C("下发遥控选择命令,设备返回成功")); + LOGINFO("下发遥控选择命令,设备返回成功 RtuNo:%d 遥控点:%d 值:%d", getRtuNo(), cmd.PointID, doValue); + } + else + { + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N_C("下发遥控选择命令,设备返回失败")); + LOGINFO("下发遥控选择命令,设备返回失败 RtuNo:%d 遥控点:%d 值:%d 返回状态:%d", + getRtuNo(), cmd.PointID, doValue, error); + } + break; + case CN_ControlExecute: + ctrlClient = getControlObjectClient(strDataRef.c_str(), fc); + if (ctrlClient != NULL) + { + ControlObjectClient_setOrigin(ctrlClient, NULL, CN_IEC61850_OrCat); + bCtrlSuccess = ControlObjectClient_operate(ctrlClient, ctrlVal, 0, fc); + error = ControlObjectClient_getLastError(ctrlClient); + } + else + { + LOGINFO("下发遥控执行命令,执行getControlObjectClient失败 RtuNo:%d 遥控点:%d 下发值:%d 接收命令值:%d", + getRtuNo(), cmd.PointID, doValue, cmd.iValue); + } + + if (bCtrlSuccess) + { + retCmd.retStatus = CN_ControlSuccess; + sprintf(retCmd.strParam, I18N_C("下发遥控执行命令,设备返回成功")); + LOGINFO("下发遥控执行命令,设备返回成功 RtuNo:%d 遥控点:%d 值:%d", getRtuNo(), cmd.PointID, doValue); + } + else + { + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N_C("下发遥控执行命令,设备返回失败")); + LOGINFO("下发遥控执行命令,设备返回失败 RtuNo:%d 遥控点:%d 值:%d 返回状态:%d", + getRtuNo(), cmd.PointID, doValue, error); + } + break; + case CN_ControlAbort: + ctrlClient = getControlObjectClient(strDataRef.c_str(), fc); + if (ctrlClient != NULL) + { + ControlObjectClient_setOrigin(ctrlClient, NULL, CN_IEC61850_OrCat); + bCtrlSuccess = ControlObjectClient_cancel(ctrlClient,fc); + error = ControlObjectClient_getLastError(ctrlClient); + } + else + { + LOGINFO("下发遥控撤销命令,执行getControlObjectClient失败 RtuNo:%d 遥控点:%d 下发值:%d 接收命令值:%d", + getRtuNo(), cmd.PointID, doValue, cmd.iValue); + } + + if (bCtrlSuccess) + { + retCmd.retStatus = CN_ControlSuccess; + sprintf(retCmd.strParam, I18N_C("下发遥控撤销命令,设备返回成功")); + LOGINFO("下发遥控撤销命令,设备返回成功 RtuNo:%d 遥控点:%d 值:%d", getRtuNo(), cmd.PointID, doValue); + } + else + { + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N_C("下发遥控撤销命令,设备返回失败")); + LOGINFO("下发遥控撤销命令,设备返回失败 RtuNo:%d 遥控点:%d 值:%d 返回状态:%d", + getRtuNo(), cmd.PointID, doValue, error); + } + break; + default: + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N_C("遥控命令类型错误!")); + LOGINFO("CIEC61850:遥控命令类型错误,RtuNo:%d,遥控点:%d 命令类型:%d", getRtuNo(), cmd.PointID, cmd.CtrlActType); + break; + } + + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + + if(ctrlVal != NULL) + { + MmsValue_delete(ctrlVal); + ctrlVal = NULL; + } +} + +void CIEC61850DataProcThread::AoCmdProcess() +{ + enum {BUF_SIZE = 20}; + SFesRxAoCmd cmd[BUF_SIZE]; + int nCmdCount = m_ptrCurRtu->ReadRxAoCmd(BUF_SIZE,&cmd[0]); //为了让缓冲区指令尽快执行 + + for(int i = 0; i < nCmdCount; i++) + { + AoCmdProcess(cmd[i]); + } +} + +void CIEC61850DataProcThread::AoCmdProcess(const SFesRxAoCmd &cmd) +{ + SFesTxAoCmd retCmd; + SFesAo *pAo = NULL; + //同步调用 + //为适应转发规约增加 + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + retCmd.CtrlActType = cmd.CtrlActType; + + //通信没有建立,直接返回错误 + if (m_AppData.comState == CN_FesRtuComDown) + { + if(cmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N_C("通信没有建立遥调失败")); + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + + LOGINFO("CIEC61850:通信没有建立遥调失败.ChanNo=%d", getChannelNo()); + return; + } + + pAo = GetFesAoByPointNo(m_ptrCurRtu, cmd.PointID); + if(pAo == NULL) + { + if(cmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + //return failed to scada + retCmd.retStatus = CN_ControlPointErr; + sprintf(retCmd.strParam, I18N_C("遥调失败!找不到遥调点")); + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + + LOGINFO("CIEC61850:遥调失败!RtuNo:%d 找不到遥调点:%d", getRtuNo(), cmd.PointID); + return; + } + + if (cmd.CtrlActType != CN_ControlExecute) + { + if(cmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N_C("遥调控制命令错误!")); + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + + LOGINFO("CIEC61850:遥调控制命令错误! RtuNo:%d 遥调点:%d CtrlActType=%d", getRtuNo(), cmd.PointID,cmd.CtrlActType); + return; + } + + //< 系数和量程的合法性在初始化时已经校验 + float fValue = (cmd.fValue - pAo->Base) / pAo->Coeff; + if((fValue < pAo->MinRange) || (fValue > pAo->MaxRange)) + { + if(cmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + retCmd.retStatus = CN_ControlPointErr; //return failed to scada + sprintf(retCmd.strParam, I18N_C("遥调失败!设置值超出量程")); + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + + LOGINFO("CIEC61850:遥调失败,设置值超出量程!RtuNo:%d 遥调点:%d",getRtuNo(), cmd.PointID); + return; + } + + S61850PointParam st61850Param; + if(!getCmdPntInfo(CN_Fes_AO,pAo->PointNo,st61850Param)) + { + if(cmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + //return failed to scada + retCmd.retStatus = CN_ControlPointErr; + sprintf(retCmd.strParam, I18N_C("遥调失败!找不到遥调点控制参数")); + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + + LOGINFO("CIEC61850:遥调失败!RtuNo:%d 找不到遥调点控制参数:%d", getRtuNo(), cmd.PointID); + return; + } + + //开始真正的控制逻辑处理 + MmsValue *ctrlValue = NULL; + switch (pAo->Param2) + { + case CN_IEC61850_Param2_float: + ctrlValue = MmsValue_newFloat(fValue); + break; + case CN_IEC61850_Param2_int: + ctrlValue = MmsValue_newIntegerFromInt32(static_cast(fValue)); + break; + case CN_IEC61850_Param2_int64: + ctrlValue = MmsValue_newIntegerFromInt64(static_cast(fValue)); + break; + default: + ctrlValue = MmsValue_newFloat(fValue);//默认使用float类型 + break; + } + + IedClientError error = IED_ERROR_OK; + ControlObjectClient ctrlClient = NULL; + bool bCtrlSuccess = true; + string strDataRef; + FunctionalConstraint fc = IEC61850_FC_NONE; + getDataRefBy61850Path(st61850Param.str61850path,strDataRef,fc); + + //下面不要提前return,要注意销毁ctrlValue和ctrlClient + if(pAo->Param3 == 1) //0:值控制,1:对象控制 + { + try{ + ctrlClient = getControlObjectClient(strDataRef.c_str(),fc); + if(ctrlClient != NULL) + { + ControlObjectClient_setOrigin(ctrlClient, NULL, CN_IEC61850_OrCat); + bCtrlSuccess = ControlObjectClient_operate(ctrlClient, ctrlValue, 0 /* operate now */,fc); + error = ControlObjectClient_getLastError(ctrlClient); + } + else + { + LOGINFO("下发遥调命令,执行getControlObjectClient失败 RtuNo:%d 遥调点:%d 下发值:%.2f 接收命令值:%.2f", + getRtuNo(), cmd.PointID, fValue, cmd.fValue); + bCtrlSuccess = false; + } + }catch(...) + { + //注意 该61850开源库对于控制路径好像是有要求的 类似只能配置到 CTRL/setGGIO1$CO$APCS1 要不然会崩溃 + LOGERROR(" getControlObjectClient Unknow error ! check ref: %s " , strDataRef.c_str()); + } + } + else + { + IedConnection_writeObject(m_pCurCon,&error,strDataRef.c_str(),fc,ctrlValue); + } + + if(bCtrlSuccess && error == IED_ERROR_OK) + { + sprintf(retCmd.strParam, I18N_C("下发遥调命令,设备返回成功")); + LOGINFO("下发遥调命令,设备返回成功 RtuNo:%d 遥调点:%d 下发值:%.2f 接收命令值:%.2f", + getRtuNo(), cmd.PointID, fValue, cmd.fValue); + retCmd.retStatus = CN_ControlSuccess; + } + else + { + sprintf(retCmd.strParam, I18N_C("下发遥调命令,设备返回失败")); + LOGINFO("下发遥调命令,设备返回失败 RtuNo:%d 遥调点:%d 下发值:%.2f 接收命令值:%.2f 返回状态:%d", + getRtuNo(), cmd.PointID, fValue, cmd.fValue, error); + retCmd.retStatus = CN_ControlFailed; + } + + if(cmd.TagtState != CTRL_TYPE_NWAIT_ACK) + { + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + + if(ctrlValue != NULL) + { + MmsValue_delete(ctrlValue); + ctrlValue = NULL; + } +} + +void CIEC61850DataProcThread::MoCmdProcess() +{ + SFesRxMoCmd cmd; + SFesTxMoCmd retCmd; + SFesMo *pMo = NULL; + + if (m_ptrCurRtu->ReadRxMoCmd(1, &cmd) != 1) + { + return; + } + + //get the cmd ok + //为适应转发规约增加 + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + retCmd.CtrlActType = cmd.CtrlActType; + if (m_AppData.comState == CN_FesRtuComDown)//通信没有建立 + { + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N_C("通信没有建立遥调失败")); + LOGINFO("通信没有建立遥调失败 RtuNo:%d", getRtuNo()); + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retCmd); + return; + } + + if ((pMo = GetFesMoByPointNo(m_ptrCurRtu, cmd.PointID)) == NULL) + { + //return failed to scada + retCmd.retStatus = CN_ControlPointErr; + sprintf(retCmd.strParam, I18N_C("遥调失败!找不到遥调点")); + LOGINFO("遥调失败!RtuNo:%d 找不到遥调点:%d", getRtuNo(), cmd.PointID); + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retCmd); + return; + } + + if (cmd.CtrlActType != CN_ControlExecute) + { + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N_C("遥调控制命令错误!")); + retCmd.CtrlActType = cmd.CtrlActType; + LOGINFO("遥调控制命令错误! RtuNo:%d 遥调点:%d CtrlActType=%d ", getRtuNo(), cmd.PointID,cmd.CtrlActType); + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retCmd); + return; + } + + bool bCheckSuccess = true; + if(static_cast(pMo->Coeff) == 0) + { + sprintf(retCmd.strParam, I18N_C("遥调失败!测点系数为0")); + bCheckSuccess = false; + } + else if(pMo->MaxRange < pMo->MinRange) + { + sprintf(retCmd.strParam, I18N_C("遥调失败!量程配置错误,最大量程<=最小量程!")); + bCheckSuccess = false; + } + + if(!bCheckSuccess) + { + //return failed to scada + retCmd.retStatus = CN_ControlPointErr; + LOGINFO("CIEC61850:遥调失败,点系数为0或者量程配置错误!RtuNo:%d 遥调点:%d",getRtuNo(), cmd.PointID); + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retCmd); + return; + } + + int nCtrlValue = (cmd.iValue - pMo->Base) / pMo->Coeff; + if((nCtrlValue < pMo->MinRange) || (nCtrlValue > pMo->MaxRange)) + { + retCmd.retStatus = CN_ControlPointErr; //return failed to scada + sprintf(retCmd.strParam, I18N_C("遥调失败!设置值超出量程")); + LOGINFO("CIEC61850:遥调失败,设置值超出量程!RtuNo:%d 遥调点:%d",getRtuNo(), cmd.PointID); + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retCmd); + return; + } + + S61850PointParam st61850Param; + if(!getCmdPntInfo(CN_Fes_MO,pMo->PointNo,st61850Param)) + { + //return failed to scada + retCmd.retStatus = CN_ControlPointErr; + sprintf(retCmd.strParam, I18N_C("遥调失败!找不到遥调点控制参数")); + LOGINFO("CIEC61850:遥调失败!RtuNo:%d 找不到遥调点控制参数:%d", getRtuNo(), cmd.PointID); + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retCmd); + return; + } + + //开始真正的控制逻辑处理 + MmsValue *ctrlValue = NULL; + switch (pMo->Param2) + { + case CN_IEC61850_Param2_float: + ctrlValue = MmsValue_newFloat(static_cast(nCtrlValue)); + break; + case CN_IEC61850_Param2_int: + ctrlValue = MmsValue_newIntegerFromInt32(nCtrlValue); + break; + case CN_IEC61850_Param2_int64: + ctrlValue = MmsValue_newIntegerFromInt64(static_cast(nCtrlValue)); + break; + default: + ctrlValue = MmsValue_newFloat(static_cast(nCtrlValue));//默认使用float类型 + break; + } + + IedClientError error = IED_ERROR_OK; + ControlObjectClient ctrlClient = NULL; + bool bCtrlSuccess = true; + string strDataRef; + FunctionalConstraint fc = IEC61850_FC_NONE; + getDataRefBy61850Path(st61850Param.str61850path,strDataRef,fc); + + //下面不要提前return,要注意销毁ctrlValue和ctrlClient + if(pMo->Param3 == 1) //0:值控制,1:对象控制 + { + ctrlClient = getControlObjectClient(strDataRef.c_str(),fc); + if(ctrlClient != NULL) + { + ControlObjectClient_setOrigin(ctrlClient, NULL, CN_IEC61850_OrCat); + bCtrlSuccess = ControlObjectClient_operate(ctrlClient, ctrlValue, 0 /* operate now */,fc); + error = ControlObjectClient_getLastError(ctrlClient); + } + else + { + LOGINFO("下发遥调命令,执行getControlObjectClient失败 RtuNo:%d 遥调点:%d 下发值:%d 接收命令值:%d", + getRtuNo(), cmd.PointID, nCtrlValue, cmd.iValue); + bCtrlSuccess = false; + } + } + else + { + IedConnection_writeObject(m_pCurCon,&error,strDataRef.c_str(),fc,ctrlValue); + } + + if(bCtrlSuccess && error == IED_ERROR_OK) + { + sprintf(retCmd.strParam, I18N_C("下发遥调命令,设备返回成功")); + LOGINFO("下发遥调命令,设备返回成功 RtuNo:%d 遥调点:%d 下发值:%d 接收命令值:%d", + getRtuNo(), cmd.PointID, nCtrlValue, cmd.iValue); + retCmd.retStatus = CN_ControlSuccess; + } + else + { + sprintf(retCmd.strParam, I18N_C("下发遥调命令,设备返回失败")); + LOGINFO("下发遥调命令,设备返回失败 RtuNo:%d 遥调点:%d 下发值:%d 接收命令值:%d 返回状态:%d", + getRtuNo(), cmd.PointID, nCtrlValue, cmd.iValue, error); + retCmd.retStatus = CN_ControlFailed; + } + + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retCmd); + + if(ctrlValue != NULL) + { + MmsValue_delete(ctrlValue); + ctrlValue = NULL; + } +} + +int CIEC61850DataProcThread::makePntCtrlIndexByStrPara1(const int nPntType, const S61850RdbPointParam &stRdbParam) +{ + string strPara = stRdbParam.resStrPara1; + if(strPara.empty()) + { + return iotSuccess; + } + + if(nPntType == CN_Fes_AO) + { + SFesAo* pAo = GetFesAoByPointNo(m_ptrCurRtu, stRdbParam.pointNo); + if(pAo == NULL) + { + LOGERROR("get AO object failed,RtuNo=%d, PntNo=%d",getRtuNo(),stRdbParam.pointNo); + return iotFailed; + } + + if(m_mapStrPara1ToAo.count(strPara) > 0) + { + LOGERROR("res_str_para1 of ao is duplicate,RtuNo=%d, PntNo=%d",getRtuNo(),stRdbParam.pointNo); + return iotFailed; + } + + std::vector vecParam; + boost::split(vecParam,stRdbParam.path61850, boost::is_any_of("/"), boost::token_compress_on); + if(vecParam.size() != 2) + { + LOGERROR("61850 path is not invalid. RtuNo:%d PntNo:%d",getRtuNo(),stRdbParam.pointNo); + return iotFailed; + } + + m_mapStrPara1ToAo[strPara].pAo = pAo; + m_mapStrPara1ToAo[strPara].strDomainId = vecParam[0]; //< 不带iedname + m_mapStrPara1ToAo[strPara].str61850Path = vecParam[1]; + } + + return iotSuccess; +} + +void CIEC61850DataProcThread::handleJsonFormatCmd() +{ + std::queue dequeJsonCmd; + m_ptrCurRtu->readJsonFormatReqCmd(dequeJsonCmd); + + while(!dequeJsonCmd.empty()) + { + RapidJsonDocPtr ptrDoc = dequeJsonCmd.front(); + dequeJsonCmd.pop(); + + rapidjson::Document *pDoc = ptrDoc.get(); + int64 lCreateTime = 0L; + int nExpInterval = CN_DefaultVal_CmdExpInterval; + string strCmdName; + + try + { + lCreateTime = RapidJsonHelper::getInt64(*pDoc,JSON_KEY_CreateTime); + nExpInterval = RapidJsonHelper::getInt(*pDoc,JSON_KEY_CreateTime,CN_DefaultVal_CmdExpInterval); + strCmdName = RapidJsonHelper::getString(*pDoc,JSON_KEY_CMD_NAME); + } + catch(std::exception &ex) + { + LOGERROR("handleJsonFormatCmd: json cmd is invalid.RtuNo:%d. exception=%s",getRtuNo(),ex.what()); + continue; + } + + if((lCreateTime + nExpInterval) < getUTCTimeMsec()) + { + LOGERROR("handleJsonFormatCmd: json cmd has expired.RtuNo:%d",getRtuNo()); + continue; + } + + if(strCmdName == JSON_CMD_TYPE_MultiAO) //< 一次写入多个AO测点 + { + handleMultiAoJsonFormatCmd(ptrDoc); + } + else + { + LOGERROR("handleJsonFormatCmd: json cmd is not supported,cmd_type=%s.RtuNo:%d",strCmdName.c_str(),getRtuNo()); + } + } +} + +void CIEC61850DataProcThread::handleMultiAoJsonFormatCmd(const RapidJsonDocPtr ptrDoc) +{ + //通信没有建立,直接返回错误 + if (m_AppData.comState == CN_FesRtuComDown) + { + LOGINFO("CIEC61850:通信没有建立遥调失败.RtuNo=%d", getRtuNo()); + return; + } + + rapidjson::Value::ConstMemberIterator iter = ptrDoc->FindMember(JSON_KEY_TID); + if(iter == ptrDoc->MemberEnd()) + { + LOGERROR("handleMultiAoJsonFormatCmd: json cmd has not tid or tid is not numberic,RtuNo:%d",getRtuNo()); + return; + } + + iter = ptrDoc->FindMember(JSON_KEY_DATA); + if(iter == ptrDoc->MemberEnd() || (!iter->value.IsObject())) + { + LOGERROR("handleMultiAoJsonFormatCmd: json cmd has not data or data is not object,RtuNo:%d",getRtuNo()); + return; + } + + StrPara1ToValueSeq vecCtrlVal; + const rapidjson::Value &objData = iter->value; + for(iter = objData.MemberBegin();iter != objData.MemberEnd();iter++) + { + string strKey = iter->name.GetString(); + const rapidjson::Value &val = iter->value; + if(!val.IsDouble()) + { + LOGERROR("handleMultiAoJsonFormatCmd: json cmd element of data is invalid.key=%s,RtuNo:%d", + strKey.c_str(),getRtuNo()); + return; + } + + vecCtrlVal.push_back(std::make_pair(strKey,val.GetDouble())); + } + + std::map mapDomainId2Val; + if(iotSuccess != buildMultiAoParamByResStrPara1(vecCtrlVal,mapDomainId2Val)) + { + return; + } + + for(auto pDomain = mapDomainId2Val.begin(); pDomain != mapDomainId2Val.end();pDomain++) + { + if(iotSuccess != sendMultiAoByResStrPara1(pDomain->first,pDomain->second)) + { + return; + } + } + + LOGDEBUG("handleMultiAoJsonFormatCmd: json cmd success,RtuNo:%d",getRtuNo()); +} + +int CIEC61850DataProcThread::buildMultiAoParamByResStrPara1(const StrPara1ToValueSeq &vecCtrlValue, + std::map &mapPathToVal) +{ + for(size_t i = 0; i < vecCtrlValue.size();i++) + { + auto iter = m_mapStrPara1ToAo.find(vecCtrlValue[i].first); + if(iter == m_mapStrPara1ToAo.end()) + { + LOGERROR("writeMultiAoByResStrPara1: json cmd has not data or data is not object,RtuNo:%d",getRtuNo()); + return iotFailed; + } + + const SMultiAoCmdParam &stAoParam = iter->second; + SFesAo *pAo = stAoParam.pAo; + if(pAo->Param3 != 0) //< 0:普通值控制 1:对象控制 + { + LOGERROR("writeMultiAoByResStrPara1: json cmd param3 !=0,RtuNo:%d PntNo:%d",getRtuNo(),pAo->PointNo); + return iotFailed; + } + + float fValue = static_cast((vecCtrlValue[i].second - pAo->Base) / pAo->Coeff); + if((fValue < pAo->MinRange) || (fValue > pAo->MaxRange)) + { + LOGERROR("writeMultiAoByResStrPara1: set value is over range. RtuNo:%d PntNo:%d",getRtuNo(),pAo->PointNo); + return iotFailed; + } + + SMultiAoCmdParam stCtrlInfo; + stCtrlInfo.pAo = pAo; + stCtrlInfo.fValue = fValue; + stCtrlInfo.strDomainId = m_strIedName + stAoParam.strDomainId; + stCtrlInfo.str61850Path = stAoParam.str61850Path; + + mapPathToVal[stCtrlInfo.strDomainId].push_back(stCtrlInfo); + } + + return iotSuccess; +} + +int CIEC61850DataProcThread::sendMultiAoByResStrPara1(const std::string &strDomainId, + const MultiAoCmdParamSeq &vecAo) +{ + LinkedList itemIds = LinkedList_create(); + LinkedList values = LinkedList_create(); + + MmsValue *ctrlValue = NULL; + for(size_t i = 0; i < vecAo.size();i++) + { + const SMultiAoCmdParam &stParam = vecAo[i]; + switch (stParam.pAo->Param2) + { + case CN_IEC61850_Param2_int: + ctrlValue = MmsValue_newIntegerFromInt32(static_cast(stParam.fValue)); + break; + case CN_IEC61850_Param2_int64: + ctrlValue = MmsValue_newIntegerFromInt64(static_cast(stParam.fValue)); + break; + case CN_IEC61850_Param2_float: + default: + ctrlValue = MmsValue_newFloat(stParam.fValue);//默认使用float类型 + break; + } + LinkedList_add(itemIds, (char*)stParam.str61850Path.c_str()); //< 一定要注意string的生命周期大于itemIds + LinkedList_add(values, ctrlValue); + } + + LinkedList accessResults = NULL; + MmsError mmsError = MMS_ERROR_NONE; + MmsConnection_writeMultipleVariables(IedConnection_getMmsConnection(m_pCurCon), &mmsError, strDomainId.c_str(), itemIds, values, &accessResults); + if(accessResults != NULL) + { + //todo:没处理返回值 + LinkedList_destroyDeep(accessResults, (LinkedListValueDeleteFunction)MmsValue_delete); + } + + //< itemIds中字符串是vecAo中的,所以仅用LinkedList_destroyStatic销毁链表,不销毁内部对象 + LinkedList_destroyStatic(itemIds); + LinkedList_destroyDeep(values, (LinkedListValueDeleteFunction)MmsValue_delete); + + return iotSuccess; +} + +int CIEC61850DataProcThread::getKeybyPntNoAndType(const int &nPntType, const int &nPntNo) +{ + return nPntNo * 100 + nPntType; +} + +bool CIEC61850DataProcThread::getCmdPntInfo(const int &nPntType, const int &nPntNo, S61850PointParam &stParam) +{ + int nPntKey = getKeybyPntNoAndType(nPntType,nPntNo); + auto iter61850Info = m_mapCmdPntNo2Info.find(nPntKey); + if(iter61850Info != m_mapCmdPntNo2Info.end()) + { + stParam = iter61850Info->second; + return true; + } + + return false; +} + +void CIEC61850DataProcThread::getDataRefBy61850Path(const string &str61850Path, string &strDataRef, FunctionalConstraint &fc) +{ + if(boost::algorithm::contains(str61850Path,"$SP$")) + { + fc = IEC61850_FC_SP; + strDataRef = boost::algorithm::replace_first_copy(str61850Path,"$SP$","$"); + strDataRef = m_strIedName + boost::algorithm::replace_all_copy(strDataRef,"$","."); + + } + else if(boost::algorithm::contains(str61850Path,"$CO$")) + { + fc = IEC61850_FC_CO; + strDataRef = boost::algorithm::replace_first_copy(str61850Path,"$CO$","$"); + strDataRef = m_strIedName + boost::algorithm::replace_all_copy(strDataRef,"$","."); + } + else + { + fc = IEC61850_FC_NONE; + strDataRef = m_strIedName + str61850Path; + } +} + +int CIEC61850DataProcThread::getChannelNo() +{ + return m_ptrFesChan->m_Param.ChanNo; +} + +int CIEC61850DataProcThread::getRtuNo() +{ + return m_ptrCurRtu->m_Param.RtuNo; +} + +ControlObjectClient CIEC61850DataProcThread::getControlObjectClient(const string &strDataRef, const FunctionalConstraint FC) +{ + auto it = m_mapCtrlObjClient.find(strDataRef); + if(it != m_mapCtrlObjClient.end()) + { + return it->second; + } + + ControlObjectClient ctrlClient = ControlObjectClient_create(strDataRef.c_str(), m_pCurCon, FC); + if(ctrlClient == NULL) + { + LOGERROR("CIEC61850:执行ControlObjectClient_create失败,RtuNo:%d dataRef:%s",getRtuNo(),strDataRef.c_str()); + return NULL; + } + + m_mapCtrlObjClient[strDataRef] = ctrlClient; + return ctrlClient; +} + +void CIEC61850DataProcThread::destoryControlOjbectClients() +{ + for(auto it = m_mapCtrlObjClient.begin(); it != m_mapCtrlObjClient.end(); it++) + { + ControlObjectClient_destroy(it->second); + } + + m_mapCtrlObjClient.clear(); +} + +int CIEC61850DataProcThread::init() +{ + m_ptrCurChan = m_ptrFesChan; //暂时没有实现主备通道的逻辑 + m_ptrCurRtu = GetRtuDataByChanData(m_ptrFesChan); + if ((m_ptrFesChan == NULL) || (m_ptrCurRtu == NULL)) + { + LOGERROR("CIEC61850 m_ptrCurRtu或m_ptrFesChan为空"); + return iotFailed; + } + m_ptrFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + m_ptrCFesBase->WriteRtuSatus(m_ptrCurRtu, CN_FesRtuComDown); + + if (m_ptrCurRtu->m_Param.ResParam1 > 0) + { + m_AppData.controlTimeoutReset = m_ptrCurRtu->m_Param.ResParam1 * MSEC_PER_SEC; + } + + if(m_ptrCurChan->m_Param.ConnectTimeout > 0) + { + m_AppData.ConnectTimeout = m_ptrCurChan->m_Param.ConnectTimeout * MSEC_PER_SEC; + } + + if(m_ptrCurChan->m_Param.ConnectWaitSec > 0) + { + m_AppData.startConnenctDelayReset = m_ptrCurChan->m_Param.ConnectWaitSec * MSEC_PER_SEC; + } + + if(m_ptrCurChan->m_Param.RespTimeout > 0) + { + m_AppData.RespTimeout = m_ptrCurChan->m_Param.RespTimeout; + } + + m_curIP = 0; //双IP处理,初始化为1,在每次连接时会使用下一个IP,这样第一次就使用下标0 + m_IPNum = 0; + if (strlen(m_ptrFesChan->m_Param.NetRoute[0].NetDesc) > 4) + { + m_IPNum = 1; + if (strlen(m_ptrFesChan->m_Param.NetRoute[1].NetDesc) > 4) + { + m_curIP = 1; + m_IPNum = 2; + } + } + + if(m_IPNum <= 0) + { + LOGERROR("CIEC61850:ChanNo=%d IP配置错误",m_ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + + //每个IP的上一次连接时间都设置为0 + m_vecLastConnectTime.resize(m_IPNum,0L); + + if(iotSuccess != init61850ConParam()) + { + return iotFailed; + } + + if(iotSuccess != loadBlockInfo()) + { + return iotFailed; + } + + if(iotSuccess != loadPointInfo()) + { + return iotFailed; + } + + if(iotSuccess != loadCmdPointInfo()) + { + return iotFailed; + } + + //< 用来校验控制参数的合法性(比如系数、量程) + if(iotSuccess != verifyCtrlPointParam()) + { + return iotFailed; + } + + return iotSuccess; +} + +void CIEC61850DataProcThread::handleReportInfo(ClientReport clientReport) +{ + if (g_IEC61850ChanelRun == false)//已收到系统退出命令,不处理数据。 + return; + + if(ClientReport_getRcbReference(clientReport) == NULL) + { + LOGTRACE("received report but ClientReport_getRcbReference is NULL.ChanNo=%d",getChannelNo()); + } + else + { + LOGTRACE("received report for %s.ChanNo=%d", ClientReport_getRcbReference(clientReport),getChannelNo()); + } + + if(ClientReport_getRptId(clientReport) == NULL) + { + LOGTRACE("received report with rptId is NULL.ChanNo=%d",getChannelNo()); + } + else + { + LOGTRACE("received report with rptId %s .ChanNo=%d",ClientReport_getRptId(clientReport),getChannelNo()); + } + + if(ClientReport_getDataSetName(clientReport) == NULL) + { + LOGWARN("当前报告块中数据集名称为空. ChanNo=%d",getChannelNo()); + return; + } + + string strDataSetName = ClientReport_getDataSetName(clientReport); //数据集名称 + LOGTRACE("received dataset %s . ChanNo=%d",strDataSetName.c_str(),getChannelNo()); + auto iterDataSet = m_mapDataSet2PntInfo.find(strDataSetName); + if(iterDataSet == m_mapDataSet2PntInfo.end()) + { + LOGWARN("当前数据集[%s]没有使用,跳过. ChanNo=%d",strDataSetName.c_str(),getChannelNo()); + return; + } + + DataRef2PntInfoMAP &mapDataRef2PntInfo = iterDataSet->second; + + MmsValue* dataSetValues = ClientReport_getDataValues(clientReport); + MmsValue* inclusion = ClientReport_getInclusion(clientReport); + if(dataSetValues == NULL || inclusion == NULL) + { + LOGWARN("received empty report for %s with rptId %s .ChanNo=%d", ClientReport_getRcbReference(clientReport), + ClientReport_getRptId(clientReport),getChannelNo()); + return; + } + + if (!ClientReport_hasDataReference(clientReport)) + { + LOGWARN("%s report has not dataReference,skip. ChanNo=%d",ClientReport_getRcbReference(clientReport),getChannelNo()); + return; + } + + S61850DataSetValueSeq vecDataSetValues; + int nValueIdx = ClientReport_getValueIndex(clientReport); //值的起始地址,第1段是测点标识、第2段是值,第3段是原因 + int nElementNum = MmsValue_getNumberOfSetBits(inclusion); + + //校验一下总长度,防止越界 + int nTotalLen = MmsValue_getArraySize(dataSetValues); + bool bHasReason = ClientReport_hasReasonForInclusion(clientReport); + int nExpectMinLen = nValueIdx + nElementNum * (2 + static_cast(bHasReason)); + if(nTotalLen < nExpectMinLen) + { + LOGWARN("%s report length error. Actual length=%d , expect length=%d .ChanNo=%d", + ClientReport_getRcbReference(clientReport),nTotalLen,nExpectMinLen,getChannelNo()); + return; + } + + for (int i = 0;i < nElementNum;i++) + { + int nElementIndex = nValueIdx + i; + MmsValue *curDSRef = MmsValue_getElement(dataSetValues, nElementIndex); + if ((curDSRef == NULL) || (MmsValue_getType(curDSRef) != MMS_VISIBLE_STRING)) + { + LOGERROR("IED_CLIENT: %s report contains invalid data reference,skip the report. ChanNo=%d",ClientReport_getRcbReference(clientReport),getChannelNo()); + return; + } + + string strDataRef = MmsValue_toString(curDSRef); + MmsValue *curValue = MmsValue_getElement(dataSetValues,nElementIndex + nElementNum); + MmsValue *curReason = NULL; + if(bHasReason) + { + curReason = MmsValue_getElement(dataSetValues,nElementIndex + 2*nElementNum); + } + + vecDataSetValues.push_back(S61850DataSetValue(strDataRef,curValue,curReason)); + } + + handleValueByDataRef(vecDataSetValues,mapDataRef2PntInfo); +} + +int CIEC61850DataProcThread::init61850ConParam() +{ + if(m_pCurCon != NULL) + { + LOGWARN("CIEC61850:init61850ConParam已经初始化过.ChanNo=%d",getChannelNo()); + return iotSuccess; + } + + m_pCurCon = IedConnection_create(); + if(NULL == m_pCurCon) + { + LOGERROR("CIEC61850: IedConnection_create 失败. ChanNo=%d",getChannelNo()); + return iotFailed; + } + + //要设置连接超时、ap title等参数 + /* To change MMS parameters you need to get access to the underlying MmsConnection */ + MmsConnection mmsConnection = IedConnection_getMmsConnection(m_pCurCon); + + /* Get the container for the parameters */ + IsoConnectionParameters parameters = MmsConnection_getIsoConnectionParameters(mmsConnection); + if(m_stRtuParam.bEnableRemoteAdvancedParam) + { + IsoConnectionParameters_setRemoteApTitle(parameters, m_stRtuParam.strRemoteAPTitle.c_str(), m_stRtuParam.nRemoteAEQualifier); + IsoConnectionParameters_setRemoteAddresses(parameters, m_stRtuParam.stRemotePSel, m_stRtuParam.stRemoteSSel, m_stRtuParam.stRemoteTSel); + } + + if(m_stRtuParam.bEnableLocalAdvancedParam) + { + IsoConnectionParameters_setLocalApTitle(parameters, m_stRtuParam.strLocalAPTitle.c_str(), m_stRtuParam.nLocalAEQualifier); + IsoConnectionParameters_setLocalAddresses(parameters, m_stRtuParam.stLocalPSel, m_stRtuParam.stLocalSSel, m_stRtuParam.stLocalTSel); + } + + IedConnection_setConnectTimeout(m_pCurCon,m_AppData.ConnectTimeout); //连接超时 + IedConnection_setRequestTimeout(m_pCurCon,m_AppData.RespTimeout); //会影响发送的命令超时,比如启用报告、控制命令等 + + return iotSuccess; +} + +int CIEC61850DataProcThread::loadBlockInfo() +{ + iot_dbms::CRdbAccessEx RdbDataBlockTable; + S61850RdbBlockParamSeq vecBlockInfo; + //条件判断 + CONDINFO con; + con.relationop = ATTRCOND_EQU; + con.conditionval = getRtuNo(); + strcpy(con.name, "rtu_no"); + + std::vector vecBlockCol; + vecBlockCol.push_back("rtu_no"); + vecBlockCol.push_back("block_id"); + vecBlockCol.push_back("is_enable"); + vecBlockCol.push_back("ld"); + vecBlockCol.push_back("call_mode"); + vecBlockCol.push_back("data_set"); + //vecBlockCol.push_back("data_set_type"); + vecBlockCol.push_back("data_set_call_time"); + vecBlockCol.push_back("report_ctrl"); + vecBlockCol.push_back("para_int1"); + bool bRet = RdbDataBlockTable.open(m_ptrCFesBase->m_strAppLabel.c_str(),RT_FES_DATA_BLOCK_TBL); + if(!bRet) + { + LOGERROR("RdbDataBlockTable::Open error"); + return iotFailed; + } + + bRet = RdbDataBlockTable.selectOneOrder(con,vecBlockInfo, vecBlockCol, "block_id");//默认顺序 + if (!bRet) + { + LOGERROR("RdbDataBlockTable.selectOneCondition error!"); + return iotFailed; + } + + bRet = RdbDataBlockTable.close(); + if (!bRet) + { + LOGERROR("RdbDataBlockTable.close error!"); + return iotFailed; + } + + S61850ReportParam stReportParam; + for(size_t i = 0; i < vecBlockInfo.size();i++) + { + const S61850RdbBlockParam ¶m = vecBlockInfo[i]; + if(param.Used == 0) + { + continue; //禁用跳过 + } + stReportParam.nParam1 = param.Param1; + stReportParam.nBlockId = param.BlockNo; + stReportParam.strLDName = param.LDName; + if(stReportParam.strLDName.empty()) + { + LOGERROR("CIEC61850:数据块[%d]的逻辑设备名为空,ChanNo=%d",stReportParam.nBlockId,getChannelNo()); + return iotFailed; + } + stReportParam.nCallMode = param.CallMode; + stReportParam.lDataSetCallPeriod = param.DsCallTime * MSEC_PER_SEC; + + //数据集,不带IEDName,以点分割,如:LD1/LLN0.dsRemoteSign + stReportParam.strDataSetDir = param.DS; + boost::algorithm::replace_all(stReportParam.strDataSetDir,"$","."); + + //数据集引用,不带IEDName,如:LD1/LLN0$dsRemoteSign + stReportParam.strDataSetRef = param.DS; + + string strRCB = param.RptID; //格式:LD1/LLN0$BR$brcbRelayDin.01,最后是实例号 + stReportParam.strRCB = boost::algorithm::erase_last_copy(strRCB,"."); + stReportParam.strRcbRef = strRCB.substr(0,strRCB.find_last_of('.')); + + //RCB_ELEMENT_GI单独发送总召命令,所以不加入此处 + //南瑞的设备设置RCB_ELEMENT_DATSET会返回失败 + //stReportParam.dwRCBMask = RCB_ELEMENT_DATSET | RCB_ELEMENT_TRG_OPS| RCB_ELEMENT_OPT_FLDS | RCB_ELEMENT_RPT_ENA; + stReportParam.dwRCBMask = m_stRtuParam.dwRCBMask; + if(boost::algorithm::contains(stReportParam.strRcbRef,".RP.")) //无buffer + { + stReportParam.dwRCBMask = stReportParam.dwRCBMask | RCB_ELEMENT_RESV; + } + else if(boost::algorithm::contains(stReportParam.strRcbRef,".BR.")) //有buffer,清空buffer + { + stReportParam.dwRCBMask = stReportParam.dwRCBMask | RCB_ELEMENT_PURGE_BUF; + } + + stReportParam.stRptInParam.pDataProcThread = this; + + m_vecBlockInfo.push_back(stReportParam); + } + + return iotSuccess; +} + +bool CIEC61850DataProcThread::parse61850Path(const std::string &strOld61850Path, + std::string &strNew61850Path, + bool &bContainIndex, + std::vector &vecV, + std::vector &vecQ, + std::vector &vecT) +{ + bContainIndex = false; + + std::vector vecParam; + boost::split(vecParam, strOld61850Path, boost::is_any_of(":"), boost::token_compress_on); + if(vecParam.empty()) + { + return false; + } + if(vecParam.size() > 1) + { + bContainIndex = true; + } + + strNew61850Path = vecParam[0]; //去除结构体索引的61850路径 + + for(size_t i = 1; i < vecParam.size(); i++) + { + vector* pIndex = NULL; + if(boost::starts_with(vecParam[i],"v=")) //值对应的结构路径,从0开始 + { + pIndex = &vecV; + } + else if(boost::starts_with(vecParam[i],"q=")) + { + pIndex = &vecQ; + } + else if(boost::starts_with(vecParam[i],"t=")) + { + pIndex = &vecT; + } + + if(pIndex == NULL) + { + continue; + } + + std::vector vecIndex; + //因为现在会固定长度,所以直接写了2 + string strParam2Split = vecParam[i].substr(2); + boost::split(vecIndex, strParam2Split, boost::is_any_of("."), boost::token_compress_on); + for(size_t nIdx = 0; nIdx < vecIndex.size(); nIdx++) + { + pIndex->push_back(StringToInt(vecIndex[nIdx])); + } + } + + return true; +} + + +void CIEC61850DataProcThread::build61850Path(const int &nPntType, + const S61850RdbPointParam &stRdbParam, + const std::vector &vecSuffix, + const std::vector > &valIndexSeq, + const std::vector > &qualityIndexSeq, + const std::vector > &timeIndexSeq) +{ + //可能格式:"PROT/PMMXU1$MX$PPV$phsAB:v=0.0.0:q=1:t=2" + S61850PointParam stParam; + stParam.nPntType = nPntType; + stParam.nPntNo = stRdbParam.pointNo; + + bool bContainIndex = false; + if(!parse61850Path(stRdbParam.path61850,stParam.str61850path,bContainIndex,stParam.v,stParam.q,stParam.t)) + { + LOGWARN("CIEC61850:当前测点61850参数格式错误.PointNo=%d,61850path=%s,ChanNo=%d", + stRdbParam.pointNo,stRdbParam.path61850,getChannelNo()); + return; + } + + if(!bContainIndex) //没有结构体索引则判断后缀 + { + if(stRdbParam.position61850 == CN_IEC61850_Pos_Original) //保持原样 + { + stParam.v.push_back(CN_IEC61850_Struct_Value); //特殊处理,用与只有属性上报时获取值 + } + else + { + //下面用来保存去除后缀的测点信息 + for(size_t nSuffixIdx = 0; nSuffixIdx < vecSuffix.size(); nSuffixIdx++) + { + if(boost::algorithm::ends_with(stParam.str61850path,vecSuffix[nSuffixIdx])) + { + stParam.v = valIndexSeq[nSuffixIdx]; + stParam.q = qualityIndexSeq[nSuffixIdx]; + stParam.t = timeIndexSeq[nSuffixIdx]; + + boost::algorithm::erase_last(stParam.str61850path,vecSuffix[nSuffixIdx]); + break; + } + } + } + } + + LOGTRACE("CIEC61850:加载测点61850 path=%s ChanNo=%d",stParam.str61850path.c_str(),getChannelNo()); + m_mapDataRef2PntInfo[stParam.str61850path].push_back(stParam); //保存没有去除后缀的测点 +} + +int CIEC61850DataProcThread::loadPointInfo() +{ + //合法的后缀 + std::vector vecSuffix; + std::vector > valIndexSeq; + std::vector > qualityIndexSeq; + std::vector > timeIndexSeq; + boost::split(vecSuffix, m_stRtuParam.strValidPathSuffix, boost::is_any_of(";;"), boost::token_compress_on); + + //计算出val在struct的索引顺序 + for(size_t nSuf = 0; nSuf < vecSuffix.size(); nSuf++) + { + string strNewPath; + bool bContainIndex = false; + std::vector vecV,vecQ,vecT; + if(!parse61850Path(vecSuffix[nSuf],strNewPath,bContainIndex,vecV,vecQ,vecT)) + { + LOGWARN("CIEC61850:61850后缀参数格式错误.suffix_path=%s,ChanNo=%d",vecSuffix[nSuf].c_str(),getChannelNo()); + } + + if(!bContainIndex) //不包含结构体索引,就用默认 + { + std::vector vecTemp; + string strNewPath2Split = strNewPath.substr(1); + boost::split(vecTemp, strNewPath2Split, boost::is_any_of("$"), boost::token_compress_on); + + std::vector vecIndexTemp(vecTemp.size(),0); + vecV = vecIndexTemp; + vecQ.push_back(CN_IEC61850_Struct_Quality); + vecT.push_back(CN_IEC61850_Struct_Time); + } + + valIndexSeq.push_back(vecV); + qualityIndexSeq.push_back(vecQ); + timeIndexSeq.push_back(vecT); + vecSuffix[nSuf] = strNewPath; //更新后缀索引,也就是去除结构体索引参数 + } + + //因为DO表中61850path在内存库的长度跟其它表不一样,为了避免出现问题,所以暂时将DO表单独加载 + map mapTableName2PntType = { + {RT_FES_AI_TBL,CN_Fes_AI},{RT_FES_DI_TBL,CN_Fes_DI}, + {RT_FES_ACC_TBL,CN_Fes_ACC},{RT_FES_MI_TBL,CN_Fes_MI} + }; + + for(auto it = mapTableName2PntType.begin();it != mapTableName2PntType.end();it++) + { + S61850RdbPointParamSeq vec61850PntParam; + SDO61850RdbPointParamSeq vecDO61850PntParam; + if(iotSuccess != loadPointParamFromRtdbTable(it->first,vec61850PntParam,vecDO61850PntParam)) + { + return iotFailed; + } + + for(size_t i = 0;i < vec61850PntParam.size();i++) + { + build61850Path(it->second,vec61850PntParam[i],vecSuffix,valIndexSeq,qualityIndexSeq,timeIndexSeq); + } + } + + LOGINFO("CIEC61850:加载采集测点61850参数成功. ChanNo=%d",getChannelNo()); + return iotSuccess; +} + +int CIEC61850DataProcThread::loadCmdPointInfo() +{ + //因为DO表中61850path在内存库的长度跟其它表不一样,为了避免出现问题,所以暂时将DO表单独加载 + map mapTableName2PntType = { + {RT_FES_AO_TBL,CN_Fes_AO},{RT_FES_MO_TBL,CN_Fes_MO},{RT_FES_DO_TBL,CN_Fes_DO} + }; + + for(auto it = mapTableName2PntType.begin();it != mapTableName2PntType.end();it++) + { + S61850RdbPointParamSeq vec61850PntParam; + SDO61850RdbPointParamSeq vecDO61850PntParam; + if(iotSuccess != loadPointParamFromRtdbTable(it->first,vec61850PntParam,vecDO61850PntParam)) + { + return iotFailed; + } + + for(size_t i = 0;i < vec61850PntParam.size();i++) + { + const S61850RdbPointParam &stRdbParam = vec61850PntParam[i]; + S61850PointParam stParam; + stParam.nPntType = it->second; + stParam.nPntNo = stRdbParam.pointNo; + stParam.str61850path = stRdbParam.path61850; + + int nKey = getKeybyPntNoAndType(stParam.nPntType,stParam.nPntNo); + m_mapCmdPntNo2Info[nKey] = stParam; + + if(iotSuccess != makePntCtrlIndexByStrPara1(stParam.nPntType,stRdbParam)) + { + return iotFailed; + } + } + + for(size_t i = 0;i < vecDO61850PntParam.size();i++) + { + const SDO61850RdbPointParam &stRdbParam = vecDO61850PntParam[i]; + S61850PointParam stParam; + stParam.nPntType = it->second; + stParam.nPntNo = stRdbParam.pointNo; + stParam.str61850path = stRdbParam.path61850; + + int nKey = getKeybyPntNoAndType(stParam.nPntType,stParam.nPntNo); + m_mapCmdPntNo2Info[nKey] = stParam; + } + } + + LOGINFO("CIEC61850:加载控制测点61850参数成功. ChanNo=%d",getChannelNo()); + return iotSuccess; +} + +int CIEC61850DataProcThread::loadPointParamFromRtdbTable(const string &strTableName, + S61850RdbPointParamSeq &vecRet, + SDO61850RdbPointParamSeq &vecDORet) +{ + iot_dbms::CRdbAccessEx rdbTable; + //条件判断 + CONDINFO con; + con.relationop = ATTRCOND_EQU; + con.conditionval = getRtuNo(); + strcpy(con.name, "rtu_no"); + + std::vector vecPntCol; + vecPntCol.push_back("rtu_no"); + vecPntCol.push_back("dot_no"); + vecPntCol.push_back("path61850"); + vecPntCol.push_back("position61850"); + vecPntCol.push_back("res_para_str1"); + + if(!rdbTable.open(m_ptrCFesBase->m_strAppLabel.c_str(),strTableName.c_str())) + { + LOGERROR("RdbTable::Open error.tableName=%s",strTableName.c_str()); + return iotFailed; + } + + //特例化DO表处理 + bool bRet = false; + if(strTableName == RT_FES_DO_TBL) + { + bRet = rdbTable.selectOneOrder(con,vecDORet,vecPntCol,"dot_no"); + } + else + { + bRet = rdbTable.selectOneOrder(con,vecRet,vecPntCol,"dot_no"); + } + + if (!bRet) + { + LOGERROR("RdbTable.selectNoCondition error! tableName=%s",strTableName.c_str()); + return iotFailed; + } + + if(!rdbTable.close()) + { + LOGERROR("RdbTable::Close error. tableName=%s",strTableName.c_str()); + return iotFailed; + } + + return iotSuccess; +} + +int CIEC61850DataProcThread::verifyCtrlPointParam() +{ + for (int i = 0; i < m_ptrCurRtu->m_MaxAoPoints; i++) + { + SFesAo *pAo = m_ptrCurRtu->m_pAo + i; + if (pAo->Used == 0) + { + continue; + } + + if(static_cast(pAo->Coeff) == 0) + { + LOGERROR("CIEC61850:ao ctrl param:coeff is invalid.PntNo=%d,RtuNo=%d",i,getRtuNo()); + return iotFailed; + } + else if(pAo->MaxRange <= pAo->MinRange) + { + LOGERROR("CIEC61850:ao ctrl param:range is invalid.PntNo=%d,RtuNo=%d",i,getRtuNo()); + return iotFailed; + } + } + + return iotSuccess; +} + +int CIEC61850DataProcThread::connectIED() +{ + //先关闭一下释放资源,防止上一次连接后中途断开 + closeIED(); + + //每次重连换IP尝试 + m_curIP = (m_curIP + 1) % m_IPNum; + IedClientError error; + IedConnection_connect(m_pCurCon,&error, + m_ptrFesChan->m_Param.NetRoute[m_curIP].NetDesc, + m_ptrFesChan->m_Param.NetRoute[m_curIP].PortNo); + + if(error != IED_ERROR_OK) + { + closeIED(); + return iotFailed; + } + + LOGINFO("CIEC61850:连接成功.IP=%s Port=%d ChanNo=%d", + m_ptrCurChan->m_Param.NetRoute[m_curIP].NetDesc, + m_ptrFesChan->m_Param.NetRoute[m_curIP].PortNo, + getChannelNo()); + + //如果获取失败,就断开连接,因为继续下去也没法正确解析 + if(iotSuccess != getIedNameFromServer()) + { + closeIED(); + return iotFailed; + } + + //如果获取失败,认为模型不一致,暂处理为重连 + if(iotSuccess != getDataRefFromServer()) + { + closeIED(); + return iotFailed; + } + + return iotSuccess; +} + +int CIEC61850DataProcThread::closeIED() +{ + //1.没有初始化连接,后面的资源也不会创建 + if(m_pCurCon == NULL) + { + return iotSuccess; + } + + //2.禁用report,同时销毁report相关资源 + uninstallAllReportCallBack(); + + //3.销毁控制对象 + destoryControlOjbectClients(); + + //4.关闭连接 + IedConnection_close(m_pCurCon); + + return iotSuccess; +} + +//通过设备中的逻辑设备名和数据块中的逻辑设备名比较得到IEDNAME +int CIEC61850DataProcThread::getIedNameFromServer() +{ + if(m_vecBlockInfo.empty()) + { + LOGWARN("CIEC61850:getIedNameFromServer 未配置数据块,不获取IedName. ChanNo=%d",getChannelNo()); + return iotSuccess; + } + + MmsConnection mmsConnection = IedConnection_getMmsConnection(m_pCurCon); + if(mmsConnection == NULL) + { + LOGERROR("CIEC61850:IedConnection_getMmsConnection 失败.ChanNo=%d",getChannelNo()); + return iotFailed; + } + + //获取设备服务中的逻辑设备列表 + MmsError mmsErr = MMS_ERROR_NONE; + LinkedList listDevNames = MmsConnection_getDomainNames(mmsConnection, &mmsErr); + if(mmsErr != MMS_ERROR_NONE || listDevNames == NULL) + { + LOGERROR("CIEC61850:MmsConnection_getDomainNames 失败.ChanNo=%d",getChannelNo()); + return iotFailed; + } + + vector vecDevName; + for (int i = 0; i < LinkedList_size(listDevNames);i++) + { + LinkedList curList = LinkedList_get(listDevNames, i); + if(curList == NULL) + { + continue; + } + string strCurLDName = (char*)curList->data; + vecDevName.push_back(strCurLDName); + LOGINFO("CIEC61850:当前服务器中包含逻辑设备:%s", strCurLDName.c_str()); + } + + LinkedList_destroy(listDevNames); + listDevNames = NULL; + + //找到数据块中配置的其中一个逻辑设备名,1.最开始已经判断是否为空,2.加载数据块时已经判断了逻辑设备名是否为空 + string strBlockLDName = m_vecBlockInfo[0].strLDName; + + string strSvrLDName; + for(size_t i = 0;i < vecDevName.size();i++) + { + if(boost::algorithm::ends_with(vecDevName[i],strBlockLDName)) + { + strSvrLDName = vecDevName[i]; + break; + } + } + + if(strSvrLDName.empty()) + { + LOGERROR("CIEC61850:当前服务器中不包含逻辑设备:%s.ChanNo=%d", strBlockLDName.c_str(),getChannelNo()); + return iotFailed; + } + + m_strIedName = boost::algorithm::erase_last_copy(strSvrLDName,strBlockLDName); + if(m_strIedName.empty()) + { + LOGERROR("CIEC61850:获取IedName失败.ChanNo=%d", getChannelNo()); + return iotFailed; + } + + //更新数据块中参数,因为配置时报告和数据集不包括IEDNAME,在此更新上 + for(size_t i = 0; i < m_vecBlockInfo.size();i++) + { + S61850ReportParam ¶m = m_vecBlockInfo[i]; + param.strIedName = m_strIedName; + param.strRealDataSetDir = m_strIedName + param.strDataSetDir; + param.strRealDataSetRef = m_strIedName + param.strDataSetRef; + param.strRealRCB = m_strIedName + param.strRCB; + param.strRealRcbRef = m_strIedName + param.strRcbRef; + } + + LOGINFO("CIEC61850:获取IedName成功.IedName=%s.ChanNo=%d", m_strIedName.c_str(),getChannelNo()); + return iotSuccess; +} + +int CIEC61850DataProcThread::getDataRefFromServer() +{ + m_mapDataSet2PntInfo.clear(); + + IedClientError error = IED_ERROR_UNKNOWN; + for(size_t nBlkIdx = 0;nBlkIdx < m_vecBlockInfo.size();nBlkIdx++) + { + S61850ReportParam &stRptParam = m_vecBlockInfo[nBlkIdx]; + /* read data set directory */ + LinkedList dataSetDirectory = IedConnection_getDataSetDirectory(m_pCurCon, &error, + stRptParam.strRealDataSetDir.c_str(), + NULL); + + if (error != IED_ERROR_OK || dataSetDirectory == NULL) + { + LOGERROR("CIEC61850: IedConnection_getDataSetDirectory失败,dataset=%s,error=%d. ChanNo=%d", + stRptParam.strRealDataSetDir.c_str(), error, getChannelNo()); + LinkedList_destroy(dataSetDirectory); //内部实现已经处理了为NULL的情况 + dataSetDirectory = NULL; + return iotFailed; + } + + for(int nIdx = 0; nIdx < LinkedList_size(dataSetDirectory);nIdx++) + { + LinkedList entry = LinkedList_get(dataSetDirectory, nIdx); + string strDataRef = (char*)entry->data; //strDataRef中IEDNAME了 + string strDataRefWithoutIedName = strDataRef.substr(m_strIedName.size()); + + auto iter = m_mapDataRef2PntInfo.find(strDataRefWithoutIedName); + if(iter != m_mapDataRef2PntInfo.end()) + { + m_mapDataSet2PntInfo[stRptParam.strRealDataSetRef][strDataRef] = iter->second; + LOGTRACE("CIEC61850:dataset=%s dataRef=%s ChanNo=%d",stRptParam.strRealDataSetRef.c_str(),strDataRef.c_str(),getChannelNo()); + } + else + { + LOGDEBUG("CIEC61850:找不到,忽略 dataset=%s dataRef=%s ChanNo=%d",stRptParam.strRealDataSetRef.c_str(),strDataRef.c_str(),getChannelNo()); + } + } + + LinkedList_destroy(dataSetDirectory); + dataSetDirectory = NULL; + } + + LOGINFO("CIEC61850:建立数据集与采集测点参数之间映射关系成功.ChanNo=%d",getChannelNo()); + + return iotSuccess; +} + +int CIEC61850DataProcThread::installAllReportCallBack() +{ + for(size_t i = 0;i < m_vecBlockInfo.size();i++) + { + S61850ReportParam &stReportParam = m_vecBlockInfo[i]; + //为NULL表示没有enable,所以要保证关闭连接时都置为NULL + if(!stReportParam.bUsed || NULL != stReportParam.rcb) + { + continue; + } + + if(m_mapDataSet2PntInfo.count(stReportParam.strRealDataSetRef) == 0) + { + //没有使用本数据集,不启用本数据集 + stReportParam.bUsed = false; + LOGINFO("CIEC61850:数据集[%s]没有使用,禁用掉本报告块",stReportParam.strRealDataSetRef.c_str()); + continue; + } + + if(iotSuccess != installOneReportCallBack(stReportParam)) + { + //启用服务失败的情况下,后面会定时重试,此处仅记录日志 + LOGINFO("CIEC61850:启用report失败.report=%s real_report=%s ChanNo=%d", + stReportParam.strRCB.c_str(),stReportParam.strRealRCB.c_str(),getChannelNo()); + uninstallOneReportCallBack(stReportParam); + } + } + + return iotSuccess; +} + +void CIEC61850DataProcThread::destoryReportResource(S61850ReportParam &stParam) +{ + if(stParam.rcb != NULL) + { + IedConnection_uninstallReportHandler(m_pCurCon,stParam.strRealRcbRef.c_str()); + ClientReportControlBlock_destroy(stParam.rcb); + stParam.rcb = NULL; + } +} + +int CIEC61850DataProcThread::installOneReportCallBack(S61850ReportParam &stReportParam) +{ + IedClientError error = IED_ERROR_UNKNOWN; + ClientReportControlBlock &rcb = stReportParam.rcb; + + /* Read RCB values */ + rcb = IedConnection_getRCBValues(m_pCurCon, &error, stReportParam.strRealRCB.c_str(), NULL); + if(error != IED_ERROR_OK || rcb == NULL) + { + LOGERROR("CIEC61850: IedConnection_getRCBValues失败,error=%d. ChanNo=%d",error,getChannelNo()); + destoryReportResource(stReportParam); + return iotFailed; + } + + /* prepare the parameters of the RCP */ + ClientReportControlBlock_setResv(rcb, true); + ClientReportControlBlock_setTrgOps(rcb, TRG_OPT_DATA_CHANGED | TRG_OPT_QUALITY_CHANGED | TRG_OPT_GI); + ClientReportControlBlock_setOptFlds(rcb,RPT_OPT_TIME_STAMP|RPT_OPT_REASON_FOR_INCLUSION|RPT_OPT_DATA_SET|RPT_OPT_DATA_REFERENCE|RPT_OPT_ENTRY_ID); + ClientReportControlBlock_setPurgeBuf(rcb, true);//清除缓冲区内容,直接总召获取最新数据 + ClientReportControlBlock_setDataSetReference(rcb, stReportParam.strRealDataSetRef.c_str()); /* NOTE the "$" instead of "." ! */ + if(m_stRtuParam.bSetRealRCB) + { + ClientReportControlBlock_setRptId(rcb,stReportParam.strRealRCB.c_str()); + } + + ClientReportControlBlock_setRptEna(rcb, true); + //总召指令单独发送,所以此处就不赋值了 + //ClientReportControlBlock_setGI(rcb, true); + + /* Configure the report receiver */ + IedConnection_installReportHandler(m_pCurCon, stReportParam.strRealRcbRef.c_str(), + ClientReportControlBlock_getRptId(rcb), + reportCallbackFunction,(void*)(&stReportParam.stRptInParam)); + + + + /* Write RCB parameters and enable report */ + IedConnection_setRCBValues(m_pCurCon, &error, rcb,stReportParam.dwRCBMask, true); + if(error != IED_ERROR_OK) + { + LOGERROR("CIEC61850: IedConnection_setRCBValues失败,rcb=%s error=%d. ChanNo=%d",stReportParam.strRealRcbRef.c_str(),error,getChannelNo()); + IedConnection_uninstallReportHandler(m_pCurCon,stReportParam.strRealRcbRef.c_str()); + destoryReportResource(stReportParam); + return iotFailed; + } + + LOGINFO("CIEC61850:启用report成功.report=%s real_report=%s ChanNo=%d", + stReportParam.strRCB.c_str(),stReportParam.strRealRCB.c_str(),getChannelNo()); + + return iotSuccess; +} + +int CIEC61850DataProcThread::enableReportGI() +{ + int64 lCurTime = getMonotonicMsec(); + for(size_t i = 0;i < m_vecBlockInfo.size();i++) + { + S61850ReportParam &stReportParam = m_vecBlockInfo[i]; + if(lCurTime - stReportParam.lLastGITime < stReportParam.lDataSetCallPeriod) + { + continue; + } + + enableOneReportGI(stReportParam); + //不管成功与否都更新一下时间戳 + stReportParam.lLastGITime = lCurTime; + } + + return iotSuccess; +} + +int CIEC61850DataProcThread::enableOneReportGI(S61850ReportParam &stReportParam) +{ + if(NULL == stReportParam.rcb) + { + return iotSuccess; + } + + IedClientError error = IED_ERROR_OK; + /* 总召 */ + ClientReportControlBlock_setGI(stReportParam.rcb, true); + IedConnection_setRCBValues(m_pCurCon, &error, stReportParam.rcb, RCB_ELEMENT_GI, true); + if(error != IED_ERROR_OK) + { + LOGINFO("CIEC61850:发送总召失败.dataset=%s real_dataset=%s ChanNo=%d", + stReportParam.strDataSetRef.c_str(),stReportParam.strRealDataSetRef.c_str(),getChannelNo()); + } + else + { + LOGTRACE("CIEC61850:发送总召成功.dataset=%s real_dataset=%s ChanNo=%d", + stReportParam.strDataSetRef.c_str(),stReportParam.strRealDataSetRef.c_str(),getChannelNo()); + } + + + return iotSuccess; +} + +int CIEC61850DataProcThread::uninstallAllReportCallBack() +{ + for(size_t i = 0;i < m_vecBlockInfo.size();i++) + { + uninstallOneReportCallBack(m_vecBlockInfo[i]); + } + + m_lLastEnableReportTime = 0; + return iotSuccess; +} + +int CIEC61850DataProcThread::uninstallOneReportCallBack(S61850ReportParam &stReportParam) +{ + if(NULL == stReportParam.rcb) + { + return iotSuccess; + } + + IedClientError error = IED_ERROR_OK; + + /* disable reporting */ + ClientReportControlBlock_setRptEna(stReportParam.rcb, false); + IedConnection_setRCBValues(m_pCurCon, &error, stReportParam.rcb, RCB_ELEMENT_RPT_ENA, true); + if(error != IED_ERROR_OK) + { + LOGINFO("CIEC61850:禁用report失败.report=%s real_report=%s ChanNo=%d", + stReportParam.strRCB.c_str(),stReportParam.strRealRCB.c_str(),getChannelNo()); + } + + destoryReportResource(stReportParam); + stReportParam.lLastGITime = 0; //复位时间,以便重连后立即总召 + + return iotSuccess; +} + diff --git a/product/src/fes/protocol/iec61850_clientV3/IEC61850DataProcThread.h b/product/src/fes/protocol/iec61850_clientV3/IEC61850DataProcThread.h new file mode 100644 index 00000000..cc10f59d --- /dev/null +++ b/product/src/fes/protocol/iec61850_clientV3/IEC61850DataProcThread.h @@ -0,0 +1,399 @@ +#ifndef IEC61850DATAPROCTHREAD_H +#define IEC61850DATAPROCTHREAD_H + +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "IEC61850Common.h" + +class CIEC61850DataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + CIEC61850DataProcThread(CFesBase *ptrCFesBase,const CFesChanPtr &ptrChan,const SIEC61850AppConfParam &stConfParam); + virtual ~CIEC61850DataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + /** + * @brief 获取当前通道号 + * + * @return 返回通道号 + */ + int getChannelNo(); + + /** + * @brief 初始化 + * + * @return 成功返回iotSuccess + */ + int init(); + + /** + * @brief 处理当前报告报文 + * + * @param clientReport + */ + void handleReportInfo(ClientReport clientReport); + +private: + + /** + * @brief 初始化61850连接参数(只是初始化参数,没有真正连接) + * + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int init61850ConParam(); + + /** + * @brief 从内存表加载数据块参数 + * + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int loadBlockInfo(); + + /** + * @brief 从内存库加载测点信息,主要是加载61850参数 + * + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int loadPointInfo(); + + /** + * @brief 从内存库加载控制测点信息 + * + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int loadCmdPointInfo(); + + /** + * @brief 从内存表加载测点参数,主要是61850相关的参数配置 + * + * @param strTableName 内存表表名 + * @param vecRet 返回的测点参数信息 + * @param vecDORet 返回的DO控制测点参数信息,此参数特例化是因为DO表跟其它表格式不一样,所以单独特例化一下 + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int loadPointParamFromRtdbTable(const std::string &strTableName,S61850RdbPointParamSeq &vecRet,SDO61850RdbPointParamSeq &vecDORet); + + //< 用来校验控制参数的合法性(比如系数、量程) + int verifyCtrlPointParam(); + + /** + * @brief 销毁指定的报告块资源 + * + * @param stParam 要销毁的报告块 + */ + void destoryReportResource(S61850ReportParam &stParam); + + /** + * @brief 连接IED Server,主要做:1、连接服务器;2、获取IEDName;3、从服务器获取数据集,与fes的测点建立映射关系 + * + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int connectIED(); + + /** + * @brief 关闭与IED Server的连接。主要实现:1、禁用报告,销毁报告资源;2、关闭连接 + * + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int closeIED(); + + /** + * @brief 从设备动态获取IEDName + * + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int getIedNameFromServer(); + + /** + * @brief 从服务器获取数据集中的测点信息,并与FES测点建立映射关系 + * + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int getDataRefFromServer(); + + /** + * @brief 初始化所有的报告块,并设置回调 + * + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int installAllReportCallBack(); + + /** + * @brief 根据指定的数据块配置初始化报告,并设置回调 + * + * @param stReportParam 要初始化的报告块 + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int installOneReportCallBack(S61850ReportParam &stReportParam); + + /** + * @brief 遍历所有的报告块,发送总召命令 + * + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int enableReportGI(); + + /** + * @brief 发送指定报告块的总召指令 + * + * @param stReportParam 要总召的报告块 + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int enableOneReportGI(S61850ReportParam &stReportParam); + + /** + * @brief 禁用报告,取消回调、并销毁资源 + * + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int uninstallAllReportCallBack(); + + /** + * @brief 禁用指定报告,取消回调、并销毁资源 + * + * @param stReportParam 要卸载的报告块 + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int uninstallOneReportCallBack(S61850ReportParam &stReportParam); + + /** + * @brief 设置通信状态 + * + * @param status 状态:CN_FesChanConnect、CN_FesChanConnecting、CN_FesChanDisconnect + */ + void setComState(int status); + + /** + * @brief 根据Report上报的DataRef更新测点值 + * + * @param vecDataSetValue 报告块中提取出来的61850数据集包含的测点信息 + * @param mapDataRef2PntInfo 本数据集对应的fes测点信息 + */ + void handleValueByDataRef(S61850DataSetValueSeq &vecDataSetValue, + const DataRef2PntInfoMAP &mapDataRef2PntInfo); + + /** + * @brief 处理单个模拟量测点 + * + * @param stPntParam 测点61850相关参数 + * @param stDataSetValue 报告中对应的测点值信息 + * @param pChgAi 处理后的结果存入的缓存地址起始地址,会跟ChgCount配合存入对应的地址中 + * @param ChgCount 已经处理过的数量 + */ + void procAiDataValue(const S61850PointParam &stPntParam,const S61850DataSetValue &stDataSetValue, + SFesChgAi *pChgAi, int &ChgCount); + + /** + * @brief 处理单个数字量测点 + * + * @param stPntParam 测点61850相关参数 + * @param stDataSetValue 报告中对应的测点值信息 + * @param pDiValue FES缓存中对应的DI起始指针,与ValueCount配合找到地址 + * @param pChgDi DI变化缓存起始地址,与ChgCount配合找到地址 + * @param pSoeEvent DI变化缓存SOE起始地址,与SoeCount配合找到地址 + * @param ValueCount 已经处理的数量,也就是缓存中偏移 + * @param ChgCount 已经处理的数量,也就是缓存中偏移 + * @param SoeCount 已经处理的数量,也就是缓存中偏移 + */ + void procDiDataValue(const S61850PointParam &stPntParam,const S61850DataSetValue &stDataSetValue, + SFesRtuDiValue* pDiValue, SFesChgDi *pChgDi, SFesSoeEvent *pSoeEvent, + int &ValueCount, int &ChgCount, int &SoeCount); + + /** + * @brief 处理单个混合量测点 + * + * @param stPntParam 测点61850相关参数 + * @param stDataSetValue 报告中对应的测点值信息 + * @param pChgMi 处理后的结果存入的缓存地址起始地址,会跟ChgCount配合存入对应的地址中 + * @param ChgCount 已经处理过的数量 + */ + void procMiProcess(const S61850PointParam &stPntParam,const S61850DataSetValue &stDataSetValue, + SFesChgMi *pChgMi, int &ChgCount); + + /** + * @brief 处理单个累计量测点 + * + * @param stPntParam 测点61850相关参数 + * @param stDataSetValue 报告中对应的测点值信息 + * @param pChgAcc 处理后的结果存入的缓存地址起始地址,会跟ChgCount配合存入对应的地址中 + * @param ChgCount 已经处理过的数量 + */ + void procAccProcess(const S61850PointParam &stPntParam,const S61850DataSetValue &stDataSetValue, + SFesChgAcc *pChgAcc, int &ChgCount); + + + /** + * @brief 处理控制命令 + * + */ + void handleCommand(); + + + /** + * @brief 处理单个数字量测点控制命令 + * + */ + void DoCmdProcess(); + + /** + * @brief 处理单个模拟量测点控制命令 + * + */ + void AoCmdProcess(); + void AoCmdProcess(const SFesRxAoCmd &cmd); + + /** + * @brief 处理单个混合量测点控制命令 + * + */ + void MoCmdProcess(); + + //< 构建基于自定义参数9实现的批量控制缓存 + int makePntCtrlIndexByStrPara1(const int nPntType, const S61850RdbPointParam &stRdbParam); + //< 处理json格式的自定义命令 + void handleJsonFormatCmd(); + + //< 处理一次写入多个模拟量变量 + void handleMultiAoJsonFormatCmd(const RapidJsonDocPtr ptrDoc); + + //< 获取控制相关参数(包括61850路径,基值.K值变换等) + int buildMultiAoParamByResStrPara1(const StrPara1ToValueSeq &vecCtrlValue, + std::map &mapPathToVal); + + //< 发送批量写AO指令 + int sendMultiAoByResStrPara1(const std::string &strDomainId, const MultiAoCmdParamSeq &vecAo); + + /** + * @brief 根据测点类型和PointNo生成主键,对应m_mapCmdPntNo2Info的key,用来通过命令服务下发指令获取61850控制相关参数 + * + * @param nPntType 测点类型 + * @param nPntNo 点号 + * @return 成功返回iotSuccess,失败返回iotFailed + */ + int getKeybyPntNoAndType(const int &nPntType,const int &nPntNo); + + /** + * @brief 通过测点类型、测点号获取61850相关参数 + * + * @param nPntType 测点类型 + * @param nPntNo 点号 + * @param stParam 返回的测点61850相关参数 + * @return 成功返回true,失败返回false + */ + bool getCmdPntInfo(const int &nPntType,const int &nPntNo,S61850PointParam &stParam); + + /** + * @brief 用来转换61850路径,不同的控制方式61850路径格式不一致,主要识别SP和CO这2种 + * + * @param str61850Path 61850路径 + * @param strDataRef 返回的处理后的61850路径 + * @param fc 返回的fc,后续控制命令会用到 + */ + void getDataRefBy61850Path(const std::string &str61850Path,std::string &strDataRef,FunctionalConstraint &fc); + + /** + * @brief 当网络异常时,清空掉所有已经收到的指令 + * + */ + void ErrorControlRespProcess(); + + /** + * @brief 获取RTU号 + * + * @return 返回的RTU号 + */ + int getRtuNo(); + + /** + * @brief 根据路径获取控制对象 + * + * @param strDataRef 返回的处理后的61850路径 + * @param fc 返回的fc,后续控制命令会用到 + * + * @return 返回控制对象,不存在或者错误返回空 + */ + ControlObjectClient getControlObjectClient(const std::string &strDataRef,const FunctionalConstraint FC); + + /** + * @brief 销毁控制对象 + * + */ + void destoryControlOjbectClients(); + + /** + * @brief 解析61850路径中的结构体索引,主要用来生成v/q/t的结构索引 + * + * @param strOld61850Path 原始的61850path + * @param strNew61850Path 去除结构体索引的61850path + * @param bContainIndex 是否包含结构体索引 + * @param vecV 值对应的结构体索引 + * @param vecQ 质量戳对应的结构体索引 + * @param vecT 时间戳对应的结构体索引 + * + */ + bool parse61850Path(const std::string &strOld61850Path, + std::string &strNew61850Path, + bool &bContainIndex, + std::vector &vecV, + std::vector &vecQ, + std::vector &vecT); + + /** + * @brief 解析61850路径,主要用来生成v/q/t的结构索引 + * + * @param nPntType 测点类型 + * @param stRdbParam 前置测点61850相关参数 + * @param vecSuffix 分割后的合法后缀 + * @param valIndexSeq 值对应的结构体索引 + * @param qualityIndexSeq 质量戳对应的结构体索引 + * @param timeIndexSeq 时间戳对应的结构体索引 + * + */ + void build61850Path(const int &nPntType, + const S61850RdbPointParam &stRdbParam, + const std::vector &vecSuffix, + const std::vector > &valIndexSeq, + const std::vector > &qualityIndexSeq, + const std::vector > &timeIndexSeq); + +private: + CFesBase* m_ptrCFesBase; + CFesChanPtr m_ptrFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesChanPtr m_ptrCurChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCurRtu; //当前使用RTU数据区,本协议每个通道对应一个RTU数据,所以不需要轮询处理。 + IedConnection m_pCurCon; //当前连接,本变量是个指针 + + int m_curIP; //0=主通道 1=备通道 + int m_IPNum; //1 OR 2,IP数量 + int64 m_lLastEnableReportTime; //上一次启用报告时间 + + std::string m_strIedName; //设备IEDName + + SIEC61850AppData m_AppData; //协议内部数据结构 + SIEC61850AppConfParam m_stRtuParam; //Rtu配置参数 + + S61850ReportParamSeq m_vecBlockInfo; //数据块信息 + DataRef2PntInfoMAP m_mapDataRef2PntInfoWithoutSuffix; //去除了合法的后缀,<61850路径,测点信息> 主键没有带IEDNAME,在连上服务器时动态构建m_mapDataSet2PntInfo + DataRef2PntInfoMAP m_mapDataRef2PntInfo; //原始测点的路径,没有去除后缀 <61850路径,测点信息> 主键没有带IEDNAME,在连上服务器时动态构建m_mapDataSet2PntInfo + DataSet2PntInfoMAP m_mapDataSet2PntInfo; //<数据集名,<61850路径,测点信息> >,用来在收到report时先按数据集筛选,提高检索效率 + CmdPntNo2InfoMAP m_mapCmdPntNo2Info; //控制测点信息,61850path中没有带IEDName + std::vector m_vecLastConnectTime; //记录每个IP地址对应的上一次连接时间,用来防止网络异常时连接太频繁 + std::map m_mapCtrlObjClient; //存储控制对象 + StrPara1ToAoMAP m_mapStrPara1ToAo; //主键:自定义参数9,用于实现批量AO控制 +}; + +typedef boost::shared_ptr CIEC61850DataProcThreadPtr; +typedef std::vector CIEC61850DataProcThreadPtrSeq; + +#endif // IEC61850DATAPROCTHREAD_H diff --git a/product/src/fes/protocol/iec61850_clientV3/iec61850_clientV3.pro b/product/src/fes/protocol/iec61850_clientV3/iec61850_clientV3.pro new file mode 100644 index 00000000..fb1af3b3 --- /dev/null +++ b/product/src/fes/protocol/iec61850_clientV3/iec61850_clientV3.pro @@ -0,0 +1,41 @@ + +# ARM板上资源有限,不会与云平台混用,不编译 +message("Compile only in x86 environment") +# requires(contains(QMAKE_HOST.arch, x86_64)) +requires(!contains(QMAKE_HOST.arch, aarch64):!linux-aarch64*) + +QT -= core gui +CONFIG -= qt + +TARGET = iec61850_clientV3 +TEMPLATE = lib + +SOURCES += \ + IEC61850.cpp \ + IEC61850DataProcThread.cpp + + +HEADERS += \ + IEC61850.h \ + IEC61850DataProcThread.h \ + IEC61850Common.h + + +INCLUDEPATH += ../../include/ +INCLUDEPATH += ../../include/libiec61850 + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase -lrdb_api +LIBS += -liec61850 -lhal-shared + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/fes/protocol/iec61850client2/IEC61850cDataProcThread.cpp b/product/src/fes/protocol/iec61850client2/IEC61850cDataProcThread.cpp index 028ede96..ca16ec53 100644 --- a/product/src/fes/protocol/iec61850client2/IEC61850cDataProcThread.cpp +++ b/product/src/fes/protocol/iec61850client2/IEC61850cDataProcThread.cpp @@ -11,22 +11,20 @@ 2022-04-14 thxiao 1、ReportAccProcess() 华星光电T9 GE 电度是非标模型,浮点值,所以需要乘系数。 但是WriteRtuAccValueAndRetChg也会乘以系数,相当于乘两次,后台还需要处理系数。 - 2023-05-08 thxiao - 1、ReportDiProcess() 防止误报,N小时前的数据不处理,N可通过iec61850client2.xml配置,不配置为0,不判断。 - 2、ReportDiProcess() DI时标取系统时间, SOE的时标取事件时标。 */ #include "IEC61850cDataProcThread.h" #include "pub_utility_api/I18N.h" #include "KBD_dll.h" #include "IEC61850dll.h" +#include using namespace iot_public; extern bool g_IEC61850cIsMainFes; extern bool g_IEC61850cChanelRun; -CIEC61850cDataProcThread::CIEC61850cDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan, IEC61850cRTUPtr ptrRtu) +CIEC61850cDataProcThread::CIEC61850cDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan, IEC61850cRTUPtr ptrRtu,const iot_fes::CPingInterfacePtr &ptrPingMng) { m_ptrCFesChan = ptrCFesChan; m_ptrCFesBase = ptrCFesBase; @@ -48,10 +46,6 @@ CIEC61850cDataProcThread::CIEC61850cDataProcThread(CFesBase *ptrCFesBase,CFesCh else m_AppData.controlTimeoutReset = m_ptrCFesRtu->m_Param.ResParam1 * 1000; - m_SOEvalidmSec = ptrRtu->m_SOEvalidSec * 1000; - - LOGINFO("iec61850client2 m_SOEvalidmSec=%lld ms ", m_SOEvalidmSec); - if (m_ptrCFesRtu->m_DevInfo.DevNum > 0) { m_AppData.DevId = m_ptrCFesRtu->m_DevInfo.pDev->DevId; @@ -73,6 +67,8 @@ CIEC61850cDataProcThread::CIEC61850cDataProcThread(CFesBase *ptrCFesBase,CFesCh else m_IPNum = 1; m_AppData.startConnenctDelayReset = m_ptrCFesChan->m_Param.ConnectWaitSec * 1000; + + m_ptrPingMng = ptrPingMng; } @@ -91,6 +87,7 @@ CIEC61850cDataProcThread::~CIEC61850cDataProcThread() m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); LOGDEBUG("CIEC61850cDataProcThread::~CIEC61850cDataProcThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); + m_ptrPingMng.reset(); } /** @@ -173,8 +170,9 @@ void CIEC61850cDataProcThread::ReportCallback(const SIEC61850InfoReport &InfoR SFesChgDi ChgDi[CN_IEC61850cMaxProcessDataNum]; SFesSoeEvent SoeEvent[CN_IEC61850cMaxProcessDataNum]; SFesChgAi ChgAi[CN_IEC61850cMaxProcessDataNum]; + SFesChgMi ChgMi[CN_IEC61850cMaxProcessDataNum]; SFesChgAcc ChgAcc[CN_IEC61850cMaxProcessDataNum]; - int AiChgCount, DiValueCount, SoeCount, AccChgCount, DiChgCount; + int AiChgCount, DiValueCount, SoeCount, AccChgCount, DiChgCount,MiChgCount; int iType,num; unsigned char ReasonCode; @@ -190,6 +188,7 @@ void CIEC61850cDataProcThread::ReportCallback(const SIEC61850InfoReport &InfoR SoeCount = 0; DiChgCount = 0; AccChgCount = 0; + MiChgCount = 0; for (i = 0; i < num; i++) { @@ -210,8 +209,11 @@ void CIEC61850cDataProcThread::ReportCallback(const SIEC61850InfoReport &InfoR ReportDiProcess(InfoReport.dataInfo[i], iType, &DiValue[0], &ChgDi[0], &SoeEvent[0], DiValueCount, DiChgCount, SoeCount); break; case CN_IEC61850c_AI: - ReportAiProcess(InfoReport.dataInfo[i], &ChgAi[0], AiChgCount); + ReportAiProcess(InfoReport.dataInfo[i], &ChgAi[0], AiChgCount); break; + case CN_IEC61850c_MI: + ReportMiProcess(InfoReport.dataInfo[i], &ChgMi[0], MiChgCount); + break; case CN_IEC61850c_ACC: ReportAccProcess(InfoReport.dataInfo[i], &ChgAcc[0], AccChgCount); break; @@ -244,6 +246,18 @@ void CIEC61850cDataProcThread::ReportCallback(const SIEC61850InfoReport &InfoR m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, AiChgCount, &ChgAi[0]); AiChgCount = 0; } + + if(MiChgCount > 0) + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu,MiChgCount,&ChgMi[0]); + MiChgCount = 0; + } + + if(AccChgCount > 0) + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, AccChgCount, &ChgAcc[0]); + AccChgCount = 0; + } } } @@ -747,93 +761,98 @@ void CIEC61850cDataProcThread::WriteParameterValueResp(std::vector bitSetVal(DataInfo.Value.iValue); + bitValue = bitSetVal.test(pDi->Param4); - //2023-05-06 thxiao 防止误报,N小时前的数据不处理 - if ((1 == iType)&&(m_SOEvalidmSec>0)) - { - tempSec = curmSec-m_SOEvalidmSec; - if (DataInfo.t < tempSec) - { - LOGDEBUG("变位时间不在有效时间内,放弃处理 RtuNo:%d PointNo:%d %s ms=%lld curmSec=%lld", m_ptrCFesRtu->m_Param.RtuNo, pDi->PointNo, pDi->TagName, DataInfo.t, curmSec); - return true; - } - } - bitValue = DataInfo.Value.iValue & 0x03; - status = CN_FesValueUpdate; - if (pDi->Revers) - bitValue ^= 1; - if ((1 == iType) && (bitValue != pDi->Value) && (g_IEC61850cIsMainFes == true) && (pDi->Status & CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 - { - memcpy(ChgDiPtr->TableName, pDi->TableName, CN_FesMaxTableNameSize); - memcpy(ChgDiPtr->ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); - memcpy(ChgDiPtr->TagName, pDi->TagName, CN_FesMaxTagSize); - ChgDiPtr->Value = bitValue; - ChgDiPtr->Status = status; - //ChgDiPtr->time = DataInfo.t; - ChgDiPtr->time = curmSec;//2023-05-08 thxiao 当前 - ChgDiPtr->RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - ChgDiPtr->PointNo = pDi->PointNo; - LOGDEBUG("变化遥信 RtuNo:%d PointNo:%d %s value=%d 原因:%d ms=%lld", m_ptrCFesRtu->m_Param.RtuNo, pDi->PointNo, ChgDiPtr->TagName, ChgDiPtr->Value, iType, ChgDiPtr->time); - ChgCount++; - } - //Create Soe - if ((1 == iType) && (g_IEC61850cIsMainFes == true))//变化报告控制块 - { - SoeEventPtr->time = DataInfo.t; - memcpy(SoeEventPtr->TableName, pDi->TableName, CN_FesMaxTableNameSize); - memcpy(SoeEventPtr->ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); - memcpy(SoeEventPtr->TagName, pDi->TagName, CN_FesMaxTagSize); - SoeEventPtr->Value = bitValue; - SoeEventPtr->Status = CN_FesValueUpdate; - SoeEventPtr->FaultNum = 0; - SoeEventPtr->RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - SoeEventPtr->PointNo = pDi->PointNo; - LOGDEBUG("SOE RtuNo:%d PointNo:%d %s value=%d 原因:%d ms=%lld", m_ptrCFesRtu->m_Param.RtuNo, pDi->PointNo, SoeEventPtr->TagName, SoeEventPtr->Value, iType, SoeEventPtr->time); - SoeCount++; - } - //更新点值 - DiValuePtr->PointNo = pDi->PointNo; - DiValuePtr->Value = bitValue; - DiValuePtr->Status = status; - DiValuePtr->time = DataInfo.t; - ValueCount++; + //bitValue = DataInfo.Value.iValue & 0x03; + status = CN_FesValueUpdate; + if (pDi->Revers) + bitValue ^= 1; + if ((bitValue != pDi->Value) && (g_IEC61850cIsMainFes == true) && (pDi->Status & CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDiPtr->TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDiPtr->ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDiPtr->TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDiPtr->Value = bitValue; + ChgDiPtr->Status = status; + ChgDiPtr->time = DataInfo.t; + ChgDiPtr->RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDiPtr->PointNo = pDi->PointNo; + LOGDEBUG("变化遥信 RtuNo:%d PointNo:%d %s value=%d 原因:%d ms=%lld", m_ptrCFesRtu->m_Param.RtuNo, pDi->PointNo, ChgDiPtr->TagName, ChgDiPtr->Value, iType, ChgDiPtr->time); + ChgCount++; + } + //Create Soe + if ((1 == iType) && (g_IEC61850cIsMainFes == true))//变化报告控制块 + { + SoeEventPtr->time = DataInfo.t; + memcpy(SoeEventPtr->TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEventPtr->ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEventPtr->TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEventPtr->Value = bitValue; + SoeEventPtr->Status = CN_FesValueUpdate; + SoeEventPtr->FaultNum = 0; + SoeEventPtr->RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEventPtr->PointNo = pDi->PointNo; + LOGDEBUG("SOE RtuNo:%d PointNo:%d %s value=%d 原因:%d ms=%lld", m_ptrCFesRtu->m_Param.RtuNo, pDi->PointNo, SoeEventPtr->TagName, SoeEventPtr->Value, iType, SoeEventPtr->time); + SoeCount++; + } + //更新点值 + DiValuePtr->PointNo = pDi->PointNo; + DiValuePtr->Value = bitValue; + DiValuePtr->Status = status; + DiValuePtr->time = DataInfo.t; + ValueCount++; - if (ChgCount >= CN_IEC61850cMaxProcessDataNum) - { - m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, pChgDi); - ChgCount = 0; - } - if (ValueCount >= CN_IEC61850cMaxProcessDataNum) - { - m_ptrCFesRtu->WriteRtuDiValue(ValueCount, pDiValue); - ValueCount = 0; - } - if (SoeCount >= CN_IEC61850cMaxProcessDataNum) - { - m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, pSoeEvent); - //保存FesSim监视数据 - m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, pSoeEvent); - SoeCount = 0; - } - return true; + if (ChgCount >= CN_IEC61850cMaxProcessDataNum) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, pChgDi); + ChgCount = 0; + } + if (ValueCount >= CN_IEC61850cMaxProcessDataNum) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, pDiValue); + ValueCount = 0; + } + if (SoeCount >= CN_IEC61850cMaxProcessDataNum) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, pSoeEvent); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, pSoeEvent); + SoeCount = 0; + } + return true; +} + +bool CIEC61850cDataProcThread::ReportDiProcess(const SIEC61850DataInfo &DataInfo,int iType,SFesRtuDiValue* pDiValue, SFesChgDi *pChgDi, SFesSoeEvent *pSoeEvent, int &ValueCount, int &ChgCount, int &SoeCount) +{ + auto pPntIter = m_ptrRtu->mapDi.find(DataInfo.strPntRef); + if(pPntIter == m_ptrRtu->mapDi.end()) + { + return ReportDiProcessByBit(DataInfo.PointId,DataInfo,iType, pDiValue, pChgDi, pSoeEvent, ValueCount, ChgCount, SoeCount); + } + + const IEC61850C_DATA_SEQ &vecPnt = pPntIter->second; + for(size_t i = 0; i < vecPnt.size();i++) + { + ReportDiProcessByBit(vecPnt[i].Index,DataInfo,iType, pDiValue, pChgDi, pSoeEvent, ValueCount, ChgCount, SoeCount); + } + + return true; } @@ -886,7 +905,54 @@ bool CIEC61850cDataProcThread::ReportAiProcess(SIEC61850DataInfo DataInfo, SFesC m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, pChgAi); ChgCount = 0; } - return true; + return true; +} + +bool CIEC61850cDataProcThread::ReportMiProcess(SIEC61850DataInfo DataInfo, SFesChgMi *pChgMi, int &ChgCount) +{ + SFesMi *pMi; + SFesRtuMiValue MiValue; + SFesChgMi ChgMi; + int32 nValue = 0; + int retCount; + + if ((pMi = GetFesMiByPIndex(m_ptrCFesRtu, DataInfo.PointId)) == NULL) + return false; + switch (DataInfo.ValueType) + { + case CN_IEC61850c_int: + nValue = DataInfo.Value.iValue; + break; + case CN_IEC61850c_int64: + nValue = static_cast(DataInfo.Value.iValue64); + break; + default: + nValue = static_cast(DataInfo.Value.fValue); + break; + } + + //无效点值清零 + if (DataInfo.q[0] & 0x42) + nValue = 0; + MiValue.PointNo = pMi->PointNo; //PointNo + MiValue.Value = nValue; + MiValue.Status = CN_FesValueUpdate; + MiValue.time = DataInfo.t; + + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(1, &MiValue, &retCount, &ChgMi); + if ((retCount > 0) && (g_IEC61850cIsMainFes == true))//主机才报告变化数据 + { + memcpy(pChgMi + ChgCount, &ChgMi, sizeof(ChgMi)); + ChgCount++; + } + + if (ChgCount >= CN_IEC61850cMaxProcessDataNum) + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, pChgMi); + ChgCount = 0; + } + return true; } bool CIEC61850cDataProcThread::ReportAccProcess(SIEC61850DataInfo DataInfo, SFesChgAcc *pChgAcc, int &ChgCount) @@ -1244,6 +1310,9 @@ void CIEC61850cDataProcThread::AoCmdProcess() CtrlReq.Value.fValue = fValue; } CtrlReq.PointId = pAo->Param1; + //对应IEC850C_Resource.h中的eCtrlObjType,0:值控制,1:对象控制,原工程未引用IEC850C_Resource.h,所以直接传递到后面 + CtrlReq.CtrlObjType = pAo->Param3; + std::vector Req; std::vector Resp; Req.push_back(CtrlReq); @@ -1303,7 +1372,165 @@ void CIEC61850cDataProcThread::AoCmdProcess() m_AppData.state = CN_IEC61850cAppState_idle; } } - } + } +} + +void CIEC61850cDataProcThread::MoCmdProcess() +{ + SFesRxMoCmd cmd; + SFesTxMoCmd retCmd; + SFesMo *pMo = NULL; + SIEC61850CtrlReq CtrlReq; + char dispstr[200]; + int ret; + + if (m_AppData.controlTimeout) + return; + if (m_ptrCFesRtu->ReadRxMoCmd(1, &cmd) == 1) + { + //get the cmd ok + memcpy(&m_AppData.moCmd, &cmd, sizeof(cmd)); + //为适应转发规约增加 + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + retCmd.CtrlActType = cmd.CtrlActType; + if (m_AppData.comState == CN_FesRtuComDown)//通信没有建立 + { + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N("通信没有建立遥调失败").str().c_str()); + sprintf(dispstr, I18N("通信没有建立遥调失败 RtuNo:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, dispstr, CN_SFesSimComFrameTypeSend); + LOGINFO(dispstr); + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_IEC61850cNoCmd; + return; + } + else + { + if ((pMo = GetFesMoByPointNo(m_ptrCFesRtu, cmd.PointID)) != NULL) + { + if (cmd.CtrlActType == CN_ControlExecute) + { +// nValue = cmd.iValue; + + //todo:此处为什么只有AO判断了,DO没有判断,直接放行后面判断可以吗?待验证 +// IEC61850C_DATA aoPoint; +// if (GetAoByPointNo(pAo->PointNo, &aoPoint) == false) +// { +// //return failed to scada +// retCmd.retStatus = CN_ControlPointErr; +// sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 找不到遥调点路径:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); +// LOGDEBUG(I18N("遥调失败!RtuNo:%d 找不到遥调点路径:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); +// m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); +// m_AppData.lastCotrolcmd = CN_IEC61850cNoCmd; +// m_AppData.state = CN_IEC61850cAppState_idle; +// return; +// } + memset(&CtrlReq, 0, sizeof(CtrlReq)); + CtrlReq.CtrlActType = CN_ControlExecute; + CtrlReq.PointType = CN_IEC61850c_MO; + CtrlReq.ValueType = (pMo->Param2 == 0) ? CN_IEC61850c_int : pMo->Param2; + + //合法取值:1:CN_IEC61850c_int 2:CN_IEC61850c_float 3:CN_IEC61850c_int64 + if(CtrlReq.ValueType >= CN_IEC61850c_int && pMo->Param2 <= CN_IEC61850c_int64) + { + switch (CtrlReq.ValueType) { + case CN_IEC61850c_int: + CtrlReq.Value.iValue = cmd.iValue; + break; + case CN_IEC61850c_float: + CtrlReq.Value.fValue = cmd.iValue; + break; + case CN_IEC61850c_int64: + CtrlReq.Value.iValue64 = cmd.iValue; + break; + default: + break; + } + + CtrlReq.PointId = pMo->Param1; + //对应IEC850C_Resource.h中的eCtrlObjType,0:值控制,1:对象控制,原工程未引用IEC850C_Resource.h,所以直接传递到后面 + CtrlReq.CtrlObjType = pMo->Param3; + + std::vector Req; + std::vector Resp; + Req.push_back(CtrlReq); + ret = iec61850dll.FES_Control(m_ptrCFesChan->m_Param.ChanNo, m_AppData.controlTimeoutReset, Req, Resp); + if (Resp.size() > 0) + { + int retstatus; + retstatus = Resp[0].retStatus; + if (Resp[0].retStatus == 0) + { + sprintf(retCmd.strParam, I18N("下发遥调命令,设备返回成功").str().c_str()); + sprintf(dispstr, I18N("下发遥调命令,设备返回成功 RtuNo:%d 遥调点:%d 下发值:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID, cmd.iValue); + retCmd.retStatus = CN_ControlSuccess; + } + else + { + sprintf(retCmd.strParam, I18N("下发遥调命令,设备返回失败").str().c_str()); + sprintf(dispstr, I18N("下发遥调命令,设备返回失败 RtuNo:%d 遥调点:%d 下发值:%d 返回状态:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID, cmd.iValue, retstatus); + retCmd.retStatus = CN_ControlFailed; + } + } + else + { + sprintf(retCmd.strParam, I18N("下发遥调命令,设备返回失败").str().c_str()); + sprintf(dispstr, I18N("下发遥调命令,设备返回失败 RtuNo:%d 遥调点:%d 下发值:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID, cmd.iValue); + retCmd.retStatus = CN_ControlFailed; + } + } + else + { //数据类型配置错误 + sprintf(retCmd.strParam, I18N("下发遥调命令失败,数据类型错误").str().c_str()); + sprintf(dispstr, I18N("下发遥调命令失败 RtuNo:%d 遥调点:%d 下发值:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID, cmd.iValue); + retCmd.retStatus = CN_ControlFailed; + } + + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, dispstr, CN_SFesSimComFrameTypeSend); + LOGINFO(dispstr); + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_IEC61850cNoCmd; + m_AppData.state = CN_IEC61850cAppState_idle; + m_AppData.controlTimeout = 0; + } + else + { + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N("遥调控制命令错误!").str().c_str()); + retCmd.CtrlActType = cmd.CtrlActType; + LOGDEBUG(I18N("遥调控制命令错误! RtuNo:%d 遥调点:%d CtrlActType=%d ").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID,cmd.CtrlActType); + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_IEC61850cNoCmd; + m_AppData.state = CN_IEC61850cAppState_idle; + } + } + else + { + //return failed to scada + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥调失败!找不到遥调点").str().c_str()); + LOGDEBUG(I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_IEC61850cNoCmd; + m_AppData.state = CN_IEC61850cAppState_idle; + } + } + } } // 控制超时处理函数 @@ -1700,9 +1927,10 @@ void CIEC61850cDataProcThread::SettingCmdProcess() void CIEC61850cDataProcThread::SetComState(int status) { - if (status == CN_FesChanConnect) { + m_ptrPingMng->disablePing(m_ptrCFesChan->m_Param.ChanNo); + m_ptrCFesChan->SetLinkStatus(CN_FesChanConnect); if (m_AppData.comState == CN_FesRtuComDown) { @@ -1713,6 +1941,8 @@ void CIEC61850cDataProcThread::SetComState(int status) } else { + m_ptrPingMng->enablePing(m_ptrCFesChan->m_Param.ChanNo); + m_ptrCFesChan->SetLinkStatus(CN_FesChanDisconnect); if (m_AppData.comState == CN_FesRtuNormal) { @@ -1737,7 +1967,7 @@ bool CIEC61850cDataProcThread::GetAoByPointNo(int PointNo, IEC61850C_DATA* retP return true; } } - return false; + return false; } void CIEC61850cDataProcThread::IsMainFes(int IsMainFes) @@ -1753,7 +1983,7 @@ void CIEC61850cDataProcThread::IsMainFes(int IsMainFes) m_StatusCallbackFlag = 0; LOGDEBUG("Fes_Connect()..............IP=%s ChanNo=%d 变为备机,禁止报告控制块", m_ptrCFesChan->m_Param.NetRoute[m_curIP].NetDesc, m_ptrCFesRtu->m_Param.ChanNo); iec61850dll.FES_Connect(m_ptrCFesRtu->m_Param.ChanNo, m_curIP, 0); - } + } } //录波文件回调函数 diff --git a/product/src/fes/protocol/iec61850client2/IEC61850cDataProcThread.h b/product/src/fes/protocol/iec61850client2/IEC61850cDataProcThread.h index c7949e53..2fb27fb0 100644 --- a/product/src/fes/protocol/iec61850client2/IEC61850cDataProcThread.h +++ b/product/src/fes/protocol/iec61850client2/IEC61850cDataProcThread.h @@ -10,6 +10,7 @@ #include "ProtocolBase.h" #include "KBD_dll.h" #include "IEC61850cRtu.h" +#include "fes_ping_api/PingInterface.h" using namespace iot_public; @@ -53,12 +54,15 @@ const int CN_IEC61850cContorlTimeout = 20000;//20s const int CN_IEC61850cMaxProcessDataNum = 50; //报告控制块的最大数据缓冲区数目。当到达最大值时,批量修改系统数据值,提高效率 +//此定义要与IEC61850C_RESOURCE.h中的ePointType对应 const int CN_IEC61850c_AI = 1; const int CN_IEC61850c_DI = 2; const int CN_IEC61850c_ACC = 3; const int CN_IEC61850c_DZ = 4; const int CN_IEC61850c_DO = 5; const int CN_IEC61850c_AO = 6; +const int CN_IEC61850c_MO = 7; +const int CN_IEC61850c_MI = 8; const int CN_IEC61850c_int = 1; const int CN_IEC61850c_float = 2; @@ -155,7 +159,7 @@ vector editValue; //修改值容器 class CIEC61850cDataProcThread : public CProtocolBase { public: - CIEC61850cDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,IEC61850cRTUPtr ptrRtu); + CIEC61850cDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,IEC61850cRTUPtr ptrRtu,const iot_fes::CPingInterfacePtr &ptrPingMng); virtual ~CIEC61850cDataProcThread(); CFesBase* m_ptrCFesBase; @@ -163,11 +167,12 @@ public: CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,modbus tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 SIEC61850cAppData m_AppData; //内部应用数据结构 IEC61850cRTUPtr m_ptrRtu; + iot_fes::CPingInterfacePtr m_ptrPingMng; int m_curIP;//0=主通道 1=备通道 int m_IPNum;//1 OR 2 int m_StatusCallbackFlag;//0:connect 1:disconnent int m_ConnectDelay; //通信中断后,延时N毫秒后再发起连接。 - int m_SOEvalidmSec; //2023-05-08 thxiao 离当前时间范围内的SOE才认为是有效的事件。0不判断 + void ConnectStatusCallback(const int retStatus, const int flag); void RptStatusCallback(const std::vector& RetStatus); @@ -181,11 +186,18 @@ public: void WriteParameterValueResp(std::vector&Resp); void IsMainFes(int IsMainFes); - bool ReportDiProcess(SIEC61850DataInfo DataInfo, int iType, SFesRtuDiValue* pDiValue, SFesChgDi *pChgDi, SFesSoeEvent *pSoeEvent, int &ValueCount, int &ChgCount, int &SoeCount); + //用来实现按位拆分功能,DataInfo中的PointID不能使用,要用PointId替换掉 + bool ReportDiProcessByBit(int PointId, const SIEC61850DataInfo &DataInfo, int iType, SFesRtuDiValue* pDiValue, + SFesChgDi *pChgDi, SFesSoeEvent *pSoeEvent, int &ValueCount, + int &ChgCount, int &SoeCount); + + bool ReportDiProcess(const SIEC61850DataInfo &DataInfo, int iType, SFesRtuDiValue* pDiValue, SFesChgDi *pChgDi, SFesSoeEvent *pSoeEvent, int &ValueCount, int &ChgCount, int &SoeCount); bool ReportAiProcess(SIEC61850DataInfo DataInfo, SFesChgAi *pChgAi, int &ChgCount); + bool ReportMiProcess(SIEC61850DataInfo DataInfo, SFesChgMi *pChgMi, int &ChgCount); bool ReportAccProcess(SIEC61850DataInfo DataInfo, SFesChgAcc *pChgAcc, int &ChgCount); void DoCmdProcess(); void AoCmdProcess(); + void MoCmdProcess(); void ControlTimeout(); void SettingCmdProcess(); void SetComState(int status); diff --git a/product/src/fes/protocol/iec61850client2/IEC61850cRtu.h b/product/src/fes/protocol/iec61850client2/IEC61850cRtu.h index 605bbae7..1a08b4c3 100644 --- a/product/src/fes/protocol/iec61850client2/IEC61850cRtu.h +++ b/product/src/fes/protocol/iec61850client2/IEC61850cRtu.h @@ -6,28 +6,31 @@ const int CN_IEC61850CPointPathLen = 64; typedef struct { int PointNo;//Point号 int Index;//param1 + int BitIndex; //param4,按位拆分功能使用 char PathName[CN_IEC61850CPointPathLen];//61850YX路径 }IEC61850C_DATA; +typedef std::vector IEC61850C_DATA_SEQ; + typedef struct{ int RtuNo; int PointNo;//Point号 - int Param1; - char PathName[CN_IEC61850CPointPathLen];//61850 Point路径 + int Param1; + int Param4; + char PathName[CN_IEC61850CPointPathLen];//61850 Point路径 }SIEC61850CRdbPointParam; class CIEC61850cRTU { public: - CIEC61850cRTU(void) {}; - ~CIEC61850cRTU(void) {}; + CIEC61850cRTU(void) {}; + ~CIEC61850cRTU(void) {}; short iChanNo;//通道号 - short iRtuNo; //RTU序号 - int m_SOEvalidSec; //2023-05-08 thxiao 离当前时间范围内的SOE才认为是有效的事件。0不判断 - - vector aoPoint; + short iRtuNo; //RTU序号 + IEC61850C_DATA_SEQ aoPoint; + std::map mapDi; //需要按位拆分的测点 private: }; diff --git a/product/src/fes/protocol/iec61850client2/IEC61850cThread.cpp b/product/src/fes/protocol/iec61850client2/IEC61850cThread.cpp index 93d43a0f..13300759 100644 --- a/product/src/fes/protocol/iec61850client2/IEC61850cThread.cpp +++ b/product/src/fes/protocol/iec61850client2/IEC61850cThread.cpp @@ -8,14 +8,12 @@ */ #include "dbms/rdb_api/CRdbAccessEx.h" #include "dbms/rdb_api/CRdbAccess.h" -#include "pub_utility_api/CommonConfigParse.h" -#include "pub_utility_api/FileUtil.h" -#include "pub_utility_api/I18N.h" #include "KBD_dll.h" #include "IEC61850dll.h" #include "IEC61850cThread.h" using namespace iot_dbms; +using namespace iot_fes; extern bool g_IEC61850cIsMainFes; extern bool g_IEC61850cChanelRun; @@ -29,6 +27,8 @@ CIEC61850cThread::CIEC61850cThread(CFesBase *ptrCFesBase) : { m_ptrCFesBase = ptrCFesBase; m_lastChanIndex = 0; + m_ptrPingMng = NULL; + m_bEnablePing = false; } @@ -42,6 +42,13 @@ CIEC61850cThread::~CIEC61850cThread() m_CDataProcQueue.clear(); } LOGDEBUG("CIEC61850cThread::~CIEC61850cThread 退出 4"); + + if(m_ptrPingMng != NULL) + { + m_ptrPingMng->stop(); + m_ptrPingMng.reset(); + } + LOGDEBUG("CIEC61850cThread::~CIEC61850cThread 退出"); } /** @@ -60,169 +67,187 @@ int CIEC61850cThread::beforeExecute() */ void CIEC61850cThread::execute() { - CIEC61850cDataProcThreadPtr ProcThreadPtr; - int i, ProcCount,ChanNo; - uint64 tempmsec; - int k,tempReportEnable; - - - if (!g_IEC61850cChanelRun) - { - //LOGDEBUG("CIEC61850cThread::execute() 退出1 "); - return; - } - if (g_IEC61850cReportEnable != -1) - { - ReportEnable(g_IEC61850cReportEnable); - g_IEC61850cReportEnable = -1; - } - - if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 - return; - - ProcCount = m_VecChan.size(); - //控制命令每次都需要循环 - for (i = 0; i < ProcCount; i++) - { - if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 - break; - - ChanNo = m_VecChan[i]->m_Param.ChanNo; - ProcThreadPtr = NULL; - { - boost::mutex::scoped_lock lock(m_DataMutex); - if ((ProcThreadPtr = GetDataProcThreadPtrByChan(ChanNo)) == NULL) - { - // LOGDEBUG("CIEC61850cThread::execute can not found CIEC61850cDataProcThreadPtr! "); - } - } - if (ProcThreadPtr == NULL) - continue; - - if(ProcThreadPtr->m_AppData.state== CN_IEC61850cAppState_idle) - { - if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 - break; - - if (ProcThreadPtr->m_ptrCFesRtu->GetRxDoCmdNum() > 0) - { - ProcThreadPtr->DoCmdProcess(); - } - else - if (ProcThreadPtr->m_ptrCFesRtu->GetRxAoCmdNum() > 0) - { - ProcThreadPtr->AoCmdProcess(); - } - else - if (ProcThreadPtr->m_ptrCFesRtu->GetRxDefCmdNum() > 0) - { - ProcThreadPtr->SettingCmdProcess(); - } - } - } - if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 - return; - - k = 0; - for (i = m_lastChanIndex; i < ProcCount; i++) - { - if (k++ > 10) - { - m_lastChanIndex = i; - break; - } - - if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 - break; - - if (g_IEC61850cReportEnable != -1) - { - tempReportEnable = g_IEC61850cReportEnable; - ReportEnable(tempReportEnable); - if(tempReportEnable == g_IEC61850cReportEnable)//ReportEnable()返回的时间很长,在等待返回的过程中存在g_IEC61850cReportEnable变化的情况,如果前后状态不一致,就还需要继续切换。 - g_IEC61850cReportEnable = -1; - break; - } - - ChanNo = m_VecChan[i]->m_Param.ChanNo; - ProcThreadPtr = NULL; - { - boost::mutex::scoped_lock lock(m_DataMutex); - if ((ProcThreadPtr = GetDataProcThreadPtrByChan(ChanNo)) == NULL) - { - // LOGDEBUG("CIEC61850cThread::execute can not found CIEC61850cDataProcThreadPtr! "); - } - } - if (ProcThreadPtr == NULL) - continue; - - if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 - break; - switch (ProcThreadPtr->m_AppData.state) - { - case CN_IEC61850cAppState_disConnect: - if (g_IEC61850cIsMainFes == true) - { - if (ProcThreadPtr->m_IPNum == 2) - { - LOGDEBUG("FES_Disconnect().................IP=%s ChanNo=%d 开始", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); - ProcThreadPtr->m_StatusCallbackFlag = 1; - iec61850dll.FES_Disconnect(ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); - LOGDEBUG("FES_Disconnect().................IP=%s ChanNo=%d 结束", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); - ProcThreadPtr->m_curIP = (ProcThreadPtr->m_curIP + 1) % 2; - } - } - ProcThreadPtr->m_AppData.state = CN_IEC61850cAppState_init; - break; - case CN_IEC61850cAppState_init: - if (ProcThreadPtr->m_AppData.startConnenctDelayReset > 0) - { - int64 temp; - - temp = getMonotonicMsec() - ProcThreadPtr->m_AppData.startConnenctDelay; - if (temp < ProcThreadPtr->m_AppData.startConnenctDelayReset) - break; - } - - ProcThreadPtr->m_AppData.state = CN_IEC61850cAppState_waitConnectResp; - if (g_IEC61850cIsMainFes == true) - { - /*if (ProcThreadPtr->m_IPNum == 2) - { - LOGDEBUG("FES_Disconnect().................IP=%s ChanNo=%d 开始", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); - ProcThreadPtr->m_StatusCallbackFlag = 1; - iec61850dll.FES_Disconnect(ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); - LOGDEBUG("FES_Disconnect().................IP=%s ChanNo=%d 结束", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); - ProcThreadPtr->m_curIP = (ProcThreadPtr->m_curIP + 1) % 2; - }*/ - - - - LOGDEBUG("Fes_Connect()..............IP=%s ChanNo=%d m_curIP=%d 使能报告控制块开始", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc,ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo, ProcThreadPtr->m_curIP); - ProcThreadPtr->m_StatusCallbackFlag = 0; - iec61850dll.FES_Connect(ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo, ProcThreadPtr->m_curIP,1); - LOGDEBUG("Fes_Connect()..............ChanNo=%d 使能报告控制块结束", ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo); - } - else - { - LOGDEBUG("Fes_Connect()..............IP=%s ChanNo=%d m_curIP=%d 禁止报告控制块开始", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo,ProcThreadPtr->m_curIP); - ProcThreadPtr->m_StatusCallbackFlag = 0; - iec61850dll.FES_Connect(ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo, ProcThreadPtr->m_curIP, 0); - LOGDEBUG("Fes_Connect()..............ChanNo=%d 禁止报告控制块结束", ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo); - } - ProcThreadPtr->m_AppData.state = CN_IEC61850cAppState_idle; - break; - default: - break; - } - } - if (i >= ProcCount) - m_lastChanIndex = 0; - else - m_lastChanIndex = i; + // 有通道启用了Ping功能,就执行新逻辑,都没有启用就执行原有逻辑,防止新逻辑有漏洞,可以用原逻辑暂时顶替 + if(m_bEnablePing) + { + execute_new(); + } + else + { + execute_old(); + } } +void CIEC61850cThread::execute_old() +{ + CIEC61850cDataProcThreadPtr ProcThreadPtr; + int i, ProcCount,ChanNo; + int k,tempReportEnable; + + if (!g_IEC61850cChanelRun) + { + //LOGDEBUG("CIEC61850cThread::execute() 退出1 "); + return; + } + if (g_IEC61850cReportEnable != -1) + { + ReportEnable(g_IEC61850cReportEnable); + g_IEC61850cReportEnable = -1; + } + + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + return; + + ProcCount = m_VecChan.size(); + //控制命令每次都需要循环 + for (i = 0; i < ProcCount; i++) + { + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + break; + + ChanNo = m_VecChan[i]->m_Param.ChanNo; + ProcThreadPtr = NULL; + { + boost::mutex::scoped_lock lock(m_DataMutex); + if ((ProcThreadPtr = GetDataProcThreadPtrByChan(ChanNo)) == NULL) + { + // LOGDEBUG("CIEC61850cThread::execute can not found CIEC61850cDataProcThreadPtr! "); + } + } + if (ProcThreadPtr == NULL) + continue; + + if(ProcThreadPtr->m_AppData.state== CN_IEC61850cAppState_idle) + { + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + break; + + if (ProcThreadPtr->m_ptrCFesRtu->GetRxDoCmdNum() > 0) + { + ProcThreadPtr->DoCmdProcess(); + } + else if (ProcThreadPtr->m_ptrCFesRtu->GetRxAoCmdNum() > 0) + { + ProcThreadPtr->AoCmdProcess(); + } + else if (ProcThreadPtr->m_ptrCFesRtu->GetRxDefCmdNum() > 0) + { + ProcThreadPtr->SettingCmdProcess(); + } + else if(ProcThreadPtr->m_ptrCFesRtu->GetRxMoCmdNum() > 0) + { + ProcThreadPtr->MoCmdProcess(); + } + } + } + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + return; + + k = 0; + for (i = m_lastChanIndex; i < ProcCount; i++) + { + if (k++ > 10) + { + m_lastChanIndex = i; + break; + } + + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + break; + + if (g_IEC61850cReportEnable != -1) + { + tempReportEnable = g_IEC61850cReportEnable; + ReportEnable(tempReportEnable); + if(tempReportEnable == g_IEC61850cReportEnable)//ReportEnable()返回的时间很长,在等待返回的过程中存在g_IEC61850cReportEnable变化的情况,如果前后状态不一致,就还需要继续切换。 + g_IEC61850cReportEnable = -1; + break; + } + + ChanNo = m_VecChan[i]->m_Param.ChanNo; + ProcThreadPtr = NULL; + { + boost::mutex::scoped_lock lock(m_DataMutex); + if ((ProcThreadPtr = GetDataProcThreadPtrByChan(ChanNo)) == NULL) + { + // LOGDEBUG("CIEC61850cThread::execute can not found CIEC61850cDataProcThreadPtr! "); + } + } + if (ProcThreadPtr == NULL) + continue; + + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + break; + switch (ProcThreadPtr->m_AppData.state) + { + case CN_IEC61850cAppState_disConnect: + if (g_IEC61850cIsMainFes == true) + { + if (ProcThreadPtr->m_IPNum == 2) + { + LOGDEBUG("FES_Disconnect().................IP=%s ChanNo=%d 开始", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); + ProcThreadPtr->m_StatusCallbackFlag = 1; + iec61850dll.FES_Disconnect(ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); + LOGDEBUG("FES_Disconnect().................IP=%s ChanNo=%d 结束", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); + ProcThreadPtr->m_curIP = (ProcThreadPtr->m_curIP + 1) % 2; + } + } + ProcThreadPtr->m_AppData.state = CN_IEC61850cAppState_init; + break; + case CN_IEC61850cAppState_init: + if (ProcThreadPtr->m_AppData.startConnenctDelayReset > 0) + { + int64 temp; + + temp = getMonotonicMsec() - ProcThreadPtr->m_AppData.startConnenctDelay; + if (temp < ProcThreadPtr->m_AppData.startConnenctDelayReset) + break; + } + + ProcThreadPtr->m_AppData.state = CN_IEC61850cAppState_waitConnectResp; + if (g_IEC61850cIsMainFes == true) + { + /*if (ProcThreadPtr->m_IPNum == 2) + { + LOGDEBUG("FES_Disconnect().................IP=%s ChanNo=%d 开始", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); + ProcThreadPtr->m_StatusCallbackFlag = 1; + iec61850dll.FES_Disconnect(ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); + LOGDEBUG("FES_Disconnect().................IP=%s ChanNo=%d 结束", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); + ProcThreadPtr->m_curIP = (ProcThreadPtr->m_curIP + 1) % 2; + }*/ + + + + LOGDEBUG("Fes_Connect()..............IP=%s ChanNo=%d m_curIP=%d 使能报告控制块开始", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc,ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo, ProcThreadPtr->m_curIP); + ProcThreadPtr->m_StatusCallbackFlag = 0; + iec61850dll.FES_Connect(ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo, ProcThreadPtr->m_curIP,1); + LOGDEBUG("Fes_Connect()..............ChanNo=%d 使能报告控制块结束", ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo); + } + else + { + LOGDEBUG("Fes_Connect()..............IP=%s ChanNo=%d m_curIP=%d 禁止报告控制块开始", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo,ProcThreadPtr->m_curIP); + ProcThreadPtr->m_StatusCallbackFlag = 0; + iec61850dll.FES_Connect(ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo, ProcThreadPtr->m_curIP, 0); + LOGDEBUG("Fes_Connect()..............ChanNo=%d 禁止报告控制块结束", ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo); + } + ProcThreadPtr->m_AppData.state = CN_IEC61850cAppState_idle; + break; + default: + break; + } + } + if (i >= ProcCount) + { + m_lastChanIndex = 0; + } + else + { + m_lastChanIndex = i; + } +} + + /* @brief 执行quit函数前的处理 */ @@ -235,6 +260,8 @@ void CIEC61850cThread::Init() { InitRTUData(); InitChan(); + InitPingMng(); + loadDiPointInfo(); } void CIEC61850cThread::ClearDataProcThreadByChanNo(int ChanNo) @@ -278,13 +305,7 @@ CIEC61850cDataProcThreadPtr CIEC61850cThread::GetDataProcThreadPtrByChan(int Cha void CIEC61850cThread::InitRTUData() { int RtuCount, ret, i, j, RtuNo, ProtocolId, ChanNo; - iot_dbms::CRdbAccessEx RdbRtuTable; - iot_dbms::CRdbAccessEx RdbProtocolTable; iot_dbms::CRdbAccessEx RdbAoTable; - char str1[48]; - int iValue,iSoeSec; - CCommonConfigParse config; - int PointCount; @@ -307,28 +328,6 @@ void CIEC61850cThread::InitRTUData() LOGERROR("InitRTUData() can't found iec61850client2 ProtocolId."); return; } - - - iSoeSec = 0; - if (config.load("../../data/fes/", "iec61850client2.xml") == iotFailed) - { - LOGDEBUG("iec61850client2 load iec61850client2.xml error"); - } - else - { - LOGDEBUG("iec61850client2 load iec61850client2.xml ok"); - - sprintf(str1, "SYS"); - if (config.getIntValue(str1, "SOE_valid_Sec", iValue) == iotSuccess) - { - iSoeSec = iValue; - } - else - iSoeSec = 86400;//24 hour - } - LOGINFO("iec61850client2 SOE_valid_Sec=%d s ", iSoeSec); - - RtuCount = m_ptrCFesBase->m_vectCFesRtuPtr.size(); for (i = 0; i < RtuCount; i++) { @@ -346,7 +345,7 @@ void CIEC61850cThread::InitRTUData() } RtuPtr->iRtuNo = RtuNo; RtuPtr->iChanNo = ChanNo; - RtuPtr->m_SOEvalidSec = iSoeSec; + //条件判断 CONDINFO con; con.relationop = ATTRCOND_EQU; @@ -359,8 +358,9 @@ void CIEC61850cThread::InitRTUData() IEC61850C_DATA ao; vecAoColumn.push_back("rtu_no"); vecAoColumn.push_back("dot_no"); - vecAoColumn.push_back("path61850"); vecAoColumn.push_back("res_para_int1"); + vecAoColumn.push_back("res_para_int4"); + vecAoColumn.push_back("path61850"); ret = RdbAoTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_AO_TBL); if (ret == false) @@ -379,6 +379,7 @@ void CIEC61850cThread::InitRTUData() { ao.PointNo = VecAoParam[j].PointNo; ao.Index = VecAoParam[j].Param1; + ao.BitIndex = VecAoParam[j].Param4; //对于模拟量无用 strcpy(ao.PathName, VecAoParam[j].PathName); RtuPtr->aoPoint.push_back(ao); } @@ -388,7 +389,6 @@ void CIEC61850cThread::InitRTUData() } } - IEC61850cRTUPtr CIEC61850cThread::GetRtuPtrByChanNo(int ChanNo) { IEC61850cRTUPtr RTUPtr; @@ -463,7 +463,7 @@ int CIEC61850cThread::OpenAllChan(int OpenFlag) { //open chan thread CIEC61850cDataProcThreadPtr ptrCDataProc; - ptrCDataProc = boost::make_shared(m_ptrCFesBase, ptrFesChan, RTUPtr); + ptrCDataProc = boost::make_shared(m_ptrCFesBase, ptrFesChan, RTUPtr,m_ptrPingMng); if (ptrCDataProc == NULL) { LOGERROR("CIEC61850c EX_OpenChan() ChanNo:%d create CIEC61850cDataProcThreadPtr error!", ptrFesChan->m_Param.ChanNo); @@ -524,3 +524,376 @@ int CIEC61850cThread::CloseAllChan(int CloseFlag) return iotSuccess; } +void CIEC61850cThread::execute_new() +{ + std::set setToDisConnect; //等待断开连接的通道号 + std::set setToInit; //等待初始化的通道 + //std::set setAlreadyToInit; //本次循环中处理过的init状态的通道 + int i = 0; + + if (!g_IEC61850cChanelRun) + { + //LOGDEBUG("CIEC61850cThread::execute() 退出1 "); + return; + } + if (g_IEC61850cReportEnable != -1) + { + ReportEnable(g_IEC61850cReportEnable); + g_IEC61850cReportEnable = -1; + } + + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + return; + + int ProcCount = m_VecChan.size(); + //控制命令每次都需要循环 + for (i = 0; i < ProcCount; i++) + { + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + break; + + int ChanNo = m_VecChan[i]->m_Param.ChanNo; + CIEC61850cDataProcThreadPtr ProcThreadPtr = NULL; + { + boost::mutex::scoped_lock lock(m_DataMutex); + if ((ProcThreadPtr = GetDataProcThreadPtrByChan(ChanNo)) == NULL) + { + // LOGDEBUG("CIEC61850cThread::execute can not found CIEC61850cDataProcThreadPtr! "); + } + } + if (ProcThreadPtr == NULL) + continue; + + if(ProcThreadPtr->m_AppData.state== CN_IEC61850cAppState_idle) + { + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + break; + + if (ProcThreadPtr->m_ptrCFesRtu->GetRxDoCmdNum() > 0) + { + ProcThreadPtr->DoCmdProcess(); + } + else if (ProcThreadPtr->m_ptrCFesRtu->GetRxAoCmdNum() > 0) + { + ProcThreadPtr->AoCmdProcess(); + } + else if (ProcThreadPtr->m_ptrCFesRtu->GetRxDefCmdNum() > 0) + { + ProcThreadPtr->SettingCmdProcess(); + } + else if(ProcThreadPtr->m_ptrCFesRtu->GetRxMoCmdNum() > 0) + { + ProcThreadPtr->MoCmdProcess(); + } + } + else if(ProcThreadPtr->m_AppData.state== CN_IEC61850cAppState_disConnect) + { + //如果是关闭通道的状态,缓存起来,提前执行关闭,否则在大部分设备连不上的时候,会导致可以连上的设备连接速度也慢 + setToDisConnect.insert(ChanNo); + } + else if(ProcThreadPtr->m_AppData.state == CN_IEC61850cAppState_init) + { + setToInit.insert(ChanNo); + } + } + + //处理一下init状态的通道,本次循环只处理能ping通的设备,但是能Ping通也可能耗时较多,因为AB网可能只通了一个网 + int64 lCurTimeTemp = getMonotonicMsec(); + int nCurInitIdx = 0; + for(auto iterInit = setToInit.begin(); iterInit != setToInit.end();iterInit++) + { + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + return; + + if (g_IEC61850cReportEnable != -1) + { + int tempReportEnable = g_IEC61850cReportEnable; + ReportEnable(tempReportEnable); + if(tempReportEnable == g_IEC61850cReportEnable)//ReportEnable()返回的时间很长,在等待返回的过程中存在g_IEC61850cReportEnable变化的情况,如果前后状态不一致,就还需要继续切换。 + g_IEC61850cReportEnable = -1; + break; + } + + if(getMonotonicMsec() - lCurTimeTemp > 60 * MSEC_PER_SEC) + { + //如果超过1分钟,跳出,防止有大量能ping通但是服务没启动的设备,那么还是会阻塞 + //剩余没有处理的通道,靠m_lastChanIndex的逻辑去遍历 + LOGINFO("当前需要init的通道未执行完,可能存在较多设备能Ping通但无法连接.需处理数量[%d],实际处理数量[%d]",setToInit.size(),nCurInitIdx); + break; + } + + if(m_ptrPingMng->getPingResult(*iterInit)) + { + int nIpIdx = m_ptrPingMng->getPingOkIpIndex(*iterInit); + channelConnectMaintenance(*iterInit,nIpIdx); + //setAlreadyToInit.insert(*iterInit); + } + + ++nCurInitIdx; + } + + //处理需要断开连接的通道,正常关闭应该不会耗时太多,所以没有分批处理 + for(auto iterDis = setToDisConnect.begin(); iterDis != setToDisConnect.end();iterDis++) + { + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + return; + + if (g_IEC61850cReportEnable != -1) + { + int tempReportEnable = g_IEC61850cReportEnable; + ReportEnable(tempReportEnable); + if(tempReportEnable == g_IEC61850cReportEnable)//ReportEnable()返回的时间很长,在等待返回的过程中存在g_IEC61850cReportEnable变化的情况,如果前后状态不一致,就还需要继续切换。 + g_IEC61850cReportEnable = -1; + break; + } + + channelConnectMaintenance(*iterDis); + } + + //下方的代码先不执行,原因:FES_Connect中调用client.c:2804行中S_LOCK_COMMON_RESOURCES加锁操作会导致在设备连不上的情况下,锁定资源3s。 + //从而影响正常通道的正常通信,所以在启用Ping功能分支下,Ping不同的设备就不再发起连接,没有完整覆盖测试,待验证 + + /* + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + return; + + int k = 0; + for (i = m_lastChanIndex; i < ProcCount; i++) + { + int nChanNo = m_VecChan[i]->m_Param.ChanNo; + if(setToDisConnect.count(nChanNo) != 0 || setAlreadyToInit.count(nChanNo) != 0) + { + //前面刚处理的断开连接,暂时跳过,先每个通道都处理一遍 + continue; + } + +// if(setToInit.count(nChanNo) == 0) +// { +// //channelConnectMaintenance中只处理了init和disconnect这2种状态 +// //前面处理了disconnect的,本次循环不再处理,如果也不在init状态中,也就是不需要处理的,直接跳过 +// continue; +// } + + if (g_IEC61850OpenFlag == 0)//通道关闭,退出循环 + break; + + if (g_IEC61850cReportEnable != -1) + { + int tempReportEnable = g_IEC61850cReportEnable; + ReportEnable(tempReportEnable); + if(tempReportEnable == g_IEC61850cReportEnable)//ReportEnable()返回的时间很长,在等待返回的过程中存在g_IEC61850cReportEnable变化的情况,如果前后状态不一致,就还需要继续切换。 + g_IEC61850cReportEnable = -1; + break; + } + + channelConnectMaintenance(nChanNo); + + if (k++ > 1) //不能太多次,否则会影响循环,比如大量设备连不上,可能影响正常通道的控制命令 + { + m_lastChanIndex = ++i; + break; + } + } + if (i >= ProcCount) + { + m_lastChanIndex = 0; + } + else + { + m_lastChanIndex = i; + } + + */ +} + +void CIEC61850cThread::channelConnectMaintenance(const int ChanNo,const int nIpIdex) +{ + CIEC61850cDataProcThreadPtr ProcThreadPtr = NULL; + { + boost::mutex::scoped_lock lock(m_DataMutex); + if ((ProcThreadPtr = GetDataProcThreadPtrByChan(ChanNo)) == NULL) + { + // LOGDEBUG("CIEC61850cThread::execute can not found CIEC61850cDataProcThreadPtr! "); + return; + } + } + + switch (ProcThreadPtr->m_AppData.state) + { + case CN_IEC61850cAppState_disConnect: + if (g_IEC61850cIsMainFes == true) + { + if (ProcThreadPtr->m_IPNum == 2) + { + LOGDEBUG("FES_Disconnect().................IP=%s ChanNo=%d 开始", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); + ProcThreadPtr->m_StatusCallbackFlag = 1; + iec61850dll.FES_Disconnect(ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); + LOGDEBUG("FES_Disconnect().................IP=%s ChanNo=%d 结束", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); + ProcThreadPtr->m_curIP = (ProcThreadPtr->m_curIP + 1) % 2; + } + } + ProcThreadPtr->m_AppData.state = CN_IEC61850cAppState_init; + break; + case CN_IEC61850cAppState_init: + if (ProcThreadPtr->m_AppData.startConnenctDelayReset > 0) + { + int64 temp = getMonotonicMsec() - ProcThreadPtr->m_AppData.startConnenctDelay; + if (temp < ProcThreadPtr->m_AppData.startConnenctDelayReset) + break; + } + + ProcThreadPtr->m_AppData.state = CN_IEC61850cAppState_waitConnectResp; + if(nIpIdex != -1) + { + ProcThreadPtr->m_curIP = nIpIdex; //指定第几个IP连接 + } + + if (g_IEC61850cIsMainFes == true) + { + /*if (ProcThreadPtr->m_IPNum == 2) + { + LOGDEBUG("FES_Disconnect().................IP=%s ChanNo=%d 开始", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); + ProcThreadPtr->m_StatusCallbackFlag = 1; + iec61850dll.FES_Disconnect(ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); + LOGDEBUG("FES_Disconnect().................IP=%s ChanNo=%d 结束", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesChan->m_Param.ChanNo); + ProcThreadPtr->m_curIP = (ProcThreadPtr->m_curIP + 1) % 2; + }*/ + + LOGDEBUG("Fes_Connect()..............IP=%s ChanNo=%d m_curIP=%d 使能报告控制块开始", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc,ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo, ProcThreadPtr->m_curIP); + ProcThreadPtr->m_StatusCallbackFlag = 0; + iec61850dll.FES_Connect(ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo, ProcThreadPtr->m_curIP,1); + LOGDEBUG("Fes_Connect()..............ChanNo=%d 使能报告控制块结束", ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo); + } + else + { + LOGDEBUG("Fes_Connect()..............IP=%s ChanNo=%d m_curIP=%d 禁止报告控制块开始", ProcThreadPtr->m_ptrCFesChan->m_Param.NetRoute[ProcThreadPtr->m_curIP].NetDesc, ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo,ProcThreadPtr->m_curIP); + ProcThreadPtr->m_StatusCallbackFlag = 0; + iec61850dll.FES_Connect(ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo, ProcThreadPtr->m_curIP, 0); + LOGDEBUG("Fes_Connect()..............ChanNo=%d 禁止报告控制块结束", ProcThreadPtr->m_ptrCFesRtu->m_Param.ChanNo); + } + + if(ProcThreadPtr->m_AppData.state != CN_IEC61850cAppState_disConnect) + { + //FES_Connect函数的回调接口中会修改状态,如果中间状态发生了变化,就不要更新这个状态 + ProcThreadPtr->m_AppData.state = CN_IEC61850cAppState_idle; + } + break; + default: + break; + } + +} + +void CIEC61850cThread::InitPingMng() +{ + //如果没有通道启用,则不需要启动Ping + if(m_VecChan.empty()) + { + return; + } + + m_ptrPingMng = getPingInstance(); + if(m_ptrPingMng == NULL) + { + LOGERROR("创建Ping管理类失败,不启用Ping功能"); + return; + } + + for(size_t i = 0;i< m_VecChan.size();i++) + { + const CFesChanPtr ptrCh = m_VecChan[i]; + if(ptrCh->m_Param.ResParam2 == 0) + { + continue; //是否启用Ping功能 + } + + if (strlen(ptrCh->m_Param.NetRoute[0].NetDesc) > 4) + { + m_ptrPingMng->addAddress(ptrCh->m_Param.ChanNo,0,ptrCh->m_Param.NetRoute[0].NetDesc); + m_bEnablePing = true; + } + + if (strlen(ptrCh->m_Param.NetRoute[1].NetDesc) > 4) + { + m_ptrPingMng->addAddress(ptrCh->m_Param.ChanNo,1,ptrCh->m_Param.NetRoute[1].NetDesc); + m_bEnablePing = true; + } + } + + if(iotSuccess != m_ptrPingMng->start()) + { + LOGERROR("启动Ping失败"); + return; + } + + iec61850dll.setPingMngPtr(m_ptrPingMng); +} + +void CIEC61850cThread::loadDiPointInfo() +{ + iot_dbms::CRdbAccessEx RdbDiTable; + for(size_t i = 0; i < m_vecRtuPtr.size();i++) + { + //条件判断 + CONDINFO con; + con.relationop = ATTRCOND_EQU; + con.conditionval = m_vecRtuPtr[i]->iRtuNo; + strcpy(con.name, "rtu_no"); + + //READ Di TABLE + std::vector VecDiParam; + std::vector vecDiCol; + IEC61850C_DATA di; + vecDiCol.push_back("rtu_no"); + vecDiCol.push_back("dot_no"); + vecDiCol.push_back("res_para_int1"); + vecDiCol.push_back("res_para_int4"); + vecDiCol.push_back("path61850"); + + if (!RdbDiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_DI_TBL)) + { + LOGERROR("RdbDiTable::Open error"); + return; + } + + if (!RdbDiTable.selectOneOrder(con, VecDiParam, vecDiCol, "dot_no")) //默认顺序 + { + LOGERROR("RdbDiTable.selectNoCondition error!"); + return; + } + + std::map mapDi; + + for(size_t j = 0; j < VecDiParam.size(); j++) + { + di.PointNo = VecDiParam[j].PointNo; + di.Index = VecDiParam[j].Param1; + di.BitIndex = VecDiParam[j].Param4; + strcpy(di.PathName, VecDiParam[j].PathName); + + if(VecDiParam[j].Param4 == 0) + { + mapDi[VecDiParam[j].PathName] = di; + } + else if(VecDiParam[j].Param4 > 0) + { + m_vecRtuPtr[i]->mapDi[VecDiParam[j].PathName].push_back(di); + } + } + + for(auto iter = m_vecRtuPtr[i]->mapDi.begin(); iter != m_vecRtuPtr[i]->mapDi.end();iter++) + { + auto diIter = mapDi.find(iter->first); + if(diIter != mapDi.end()) + { + iter->second.push_back(diIter->second); + } + } + + if(!RdbDiTable.close()) + { + LOGERROR("RdbDiTable.close error!"); + return; + } + } +} diff --git a/product/src/fes/protocol/iec61850client2/IEC61850cThread.h b/product/src/fes/protocol/iec61850client2/IEC61850cThread.h index 975a16ed..342f5709 100644 --- a/product/src/fes/protocol/iec61850client2/IEC61850cThread.h +++ b/product/src/fes/protocol/iec61850client2/IEC61850cThread.h @@ -44,13 +44,26 @@ public: void Init(); void InitRTUData(); void InitChan(); + //初始化Ping功能管理类 + void InitPingMng(); + //加载数字量相关参数,主要用于实现按位拆分功能 + void loadDiPointInfo(); + CIEC61850cDataProcThreadPtr GetDataProcThreadPtrByChan(int ChanNo); IEC61850cRTUPtr GetRtuPtrByChanNo(int ChanNo); int OpenAllChan(int OpenFlag); int CloseAllChan(int CloseFlag); void ClearDataProcThreadByChanNo(int ChanNo); +private: + //通道状态维护,nIpIdex为当前使用第几个IP连接,如果为-1,则不指定,保持原逻辑 + void channelConnectMaintenance(const int ChanNo,const int nIpIdex = -1); + void execute_old(); + void execute_new(); +private: + iot_fes::CPingInterfacePtr m_ptrPingMng; //Ping功能管理类 + bool m_bEnablePing; //标记Ping功能是否启用,用来决定使用execute_old还是execute_new }; typedef boost::shared_ptr CIEC61850cThreadPtr; diff --git a/product/src/fes/protocol/iec61850client2/IEC61850c_pub.h b/product/src/fes/protocol/iec61850client2/IEC61850c_pub.h index 52cb4380..1edc1034 100644 --- a/product/src/fes/protocol/iec61850client2/IEC61850c_pub.h +++ b/product/src/fes/protocol/iec61850client2/IEC61850c_pub.h @@ -1,17 +1,22 @@ #pragma once #include -#include "common/DataType.h" +#include +#include "DataType.h" const int CN_IEC61850cMaxRefSize = 128; //typedef __int64 int64; //typedef unsigned __int64 uint64; typedef void *HANDLE; #define IEC61850_K_MAX_REFERENCE_SIZE 128 +//todo:此文件为什么要拷贝一份放在这?iec61850client2和fes/ice61850/include下各有一份了,暂时没敢合并,所以修改时记得2个文件同步 typedef struct { int PointType;//5:DO 6:AO int PointId; //Param1 - int ValueType;//1:int 2:float 3:int64 + int ValueType;//1:int 2:float 3:int64 对应Param2 + int CtrlObjType; //对应IEC850C_Resource.h中的eCtrlObjType,控制对象类型,用来标识当前控制点是值控制还是类似遥控的对象控制方式, + //有的设备将模拟量控制设置为一个与遥控一样的对象,$Oper$setMag$f + //用Param3标识,暂时只对混合量和模拟量生效,0代表值控制,1代表对象控制 int orCat; //for DO union { @@ -48,6 +53,7 @@ typedef struct { }SIEC61850SGResp; typedef struct { + std::string strPntRef; //不带IEDName int PointType;//1:AI 2:DI 3:ACC 4:DZ int PointId; //Param1 int ValueType;//1:int 2:float 3:int64 diff --git a/product/src/fes/protocol/iec61850client2/IEC61850dll.h b/product/src/fes/protocol/iec61850client2/IEC61850dll.h index 018948cc..20a2cdf8 100644 --- a/product/src/fes/protocol/iec61850client2/IEC61850dll.h +++ b/product/src/fes/protocol/iec61850client2/IEC61850dll.h @@ -2,6 +2,7 @@ #include #include "IEC61850c_pub.h" #include "FesDef.h" +#include "fes_ping_api/PingInterface.h" /* #ifdef WIN64 @@ -81,6 +82,7 @@ public: static bool release(); void OperTacking(); int FES_Connect(const int ChanNo, const int NetAB, const int EnableReport); + void setPingMngPtr(const iot_fes::CPingInterfacePtr ptrPingMng); // 关闭指定通道 int FES_Disconnect(const int ChanNo); diff --git a/product/src/fes/protocol/iec61850client2/iec61850client2.pro b/product/src/fes/protocol/iec61850client2/iec61850client2.pro index b320e14c..fdc3f7a7 100644 --- a/product/src/fes/protocol/iec61850client2/iec61850client2.pro +++ b/product/src/fes/protocol/iec61850client2/iec61850client2.pro @@ -14,14 +14,17 @@ HEADERS += \ IEC61850c.h \ IEC61850cThread.h \ IEC61850cDataProcThread.h \ - IEC61850c_pub.h \ KBD_dll.h \ IEC61850dll.h \ + IEC61850cRtu.h \ + ../../iec61850/include/IEC61850c_pub.h INCLUDEPATH += ../../include/ +INCLUDEPATH += ../../iec61850/include/ LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase -lrdb_api +LIBS += -lfes_ping_api LIBS += -llibasn1 LIBS += -llibmem LIBS += -llibmlog @@ -33,6 +36,7 @@ LIBS += -llibslog LIBS += -llibutil LIBS += -llibcositcps LIBS += -llibiec61850c + DEFINES += PROTOCOLBASE_API_EXPORTS include($$PWD/../../../idl_files/idl_files.pri) diff --git a/product/src/fes/protocol/kbd104/KBD104DataProcThread.cpp b/product/src/fes/protocol/kbd104/KBD104DataProcThread.cpp index 25c4e4f4..27092963 100644 --- a/product/src/fes/protocol/kbd104/KBD104DataProcThread.cpp +++ b/product/src/fes/protocol/kbd104/KBD104DataProcThread.cpp @@ -3011,7 +3011,6 @@ void CKBD104DataProcThread::SaveKBDWaveFormDat(SFesRtuDevParam *pDev,byte *pData /** * @brief RecvWaveFormEnd * 结束录波处理 - * S40 结束帧68 06 00 64 01 00 7B AA */ void CKBD104DataProcThread::RecvWaveFormEnd() { diff --git a/product/src/fes/protocol/kbd511s_info/kbd511s_info.pro b/product/src/fes/protocol/kbd511s_info/kbd511s_info.pro new file mode 100644 index 00000000..feb4dfd7 --- /dev/null +++ b/product/src/fes/protocol/kbd511s_info/kbd511s_info.pro @@ -0,0 +1,30 @@ + +#CONFIG -= qt +QT += serialport +TARGET = kbd511s_info +TEMPLATE = lib + +SOURCES += \ + kbd511s_infoRtu.cpp \ + kbd511s_infoRtuDataProcThread.cpp \ + +HEADERS += \ + kbd511s_infoRtu.h \ + kbd511s_infoRtuDataProcThread.h \ + +INCLUDEPATH += ../../include/ + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase +LIBS += -lprotobuf -lboost_locale -lboost_regex + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/fes/protocol/kbd511s_info/kbd511s_infoRtu.cpp b/product/src/fes/protocol/kbd511s_info/kbd511s_infoRtu.cpp new file mode 100644 index 00000000..178b3f2b --- /dev/null +++ b/product/src/fes/protocol/kbd511s_info/kbd511s_infoRtu.cpp @@ -0,0 +1,251 @@ +/* +@file kbd511s_infoRtu.cpp +@brief +@author Rong +@histroy + +*/ + +#include "kbd511s_infoRtu.h" +#include "pub_utility_api/CommonConfigParse.h" + +using namespace iot_public; + +Ckbd511s_infoRtu kbd511s_infoRtu; +bool g_kbd511s_infoRtuIsMainFes=false; +bool g_kbd511s_infoRtuChanelRun=true; + +int EX_SetBaseAddr(void *address) +{ + kbd511s_infoRtu.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + kbd511s_infoRtu.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + kbd511s_infoRtu.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + kbd511s_infoRtu.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + kbd511s_infoRtu.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int /*flag*/) +{ + g_kbd511s_infoRtuChanelRun =false;//使所有的线程退出。 + return iotSuccess; +} +Ckbd511s_infoRtu::Ckbd511s_infoRtu() +{ + +} + +Ckbd511s_infoRtu::~Ckbd511s_infoRtu() +{ + + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); + + LOGDEBUG("Ckbd511s_infoRtu::~Ckbd511s_infoRtu() 退出"); +} + + +int Ckbd511s_infoRtu::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + } + //规约映射表初始化 + if (m_ptrCFesBase != NULL) + { + m_ptrCFesBase->ProtocolRtuInitByParam1((char*)"kbd511s_info"); + } + + return iotSuccess; +} + +int Ckbd511s_infoRtu::SetProperty(int IsMainFes) +{ + g_kbd511s_infoRtuIsMainFes = IsMainFes; + LOGDEBUG("Ckbd511s_infoRtu::SetProperty g_kbd511s_infoRtuIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief Ckbd511s_infoRtu::OpenChan + * 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int Ckbd511s_infoRtu::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if((OpenFlag==CN_FesChanThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + ptrFesChan->SetComThreadRunFlag(CN_FesRunFlag); + ptrFesChan->SetLinkStatus(CN_FesChanRun); + ptrFesChan->SetChangeFlag(CN_FesChanUnChange); + + } + + + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + Ckbd511s_infoRtuDataProcThreadPtr ptrCDataProc; + ptrCDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan); + if (ptrCDataProc == NULL) + { + LOGERROR("Ckbd511s_infoRtu EX_OpenChan() ChanNo:%d create Ckbd511s_infoRtuDataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; + +} + +/** + * @brief Ckbd511s_infoRtu::CloseChan + * 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int Ckbd511s_infoRtu::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("Ckbd511s_infoRtu::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + if((CloseFlag==CN_FesChanThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + ptrFesChan->SetComThreadRunFlag(CN_FesStopFlag); + + } + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + + return iotSuccess; +} + +/** +* @brief Ckbd511s_infoRtu::ChanTimer +* 通道定时器,主通道会定时调用 +* @param MainChanNo 主通道号 +* @return +*/ +int Ckbd511s_infoRtu::ChanTimer(int MainChanNo) +{ + //把命令缓冲时间间隔到的命放到发送命令缓冲区 + CFesChanPtr ptrFesChan; + CFesChanPtr ptrCurrentChan; + CFesRtuPtr ptrFesRtu; + int i, j, RtuNo; + + if ((ptrFesChan = m_ptrCFesBase->GetChanDataByChanNo(MainChanNo)) == NULL) + return iotFailed; + + SModbusCmd *pCmd; + for (i = 0; im_RtuNum; i++) + { + RtuNo = ptrFesChan->m_RtuNo[i]; + if ((ptrFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) + continue; + for (j = 0; jm_Param.ModbusCmdBuf.num; j++) + { + pCmd = ptrFesRtu->m_Param.ModbusCmdBuf.pCmd + j; + pCmd->PollTimeCount++; + if (pCmd->PollTimeCount >= pCmd->PollTime)//时间到,命令放入TxBuf + { + memcpy(&ptrFesRtu->pTxCmdBuf->cmd[ptrFesRtu->pTxCmdBuf->writex], pCmd, sizeof(SModbusCmd)); + + pCmd->PollTimeCount = 0; + ptrFesRtu->pTxCmdBuf->writex = (ptrFesRtu->pTxCmdBuf->writex + 1) % CN_FesMaxModbusTxCmdNum; + if (ptrFesRtu->pTxCmdBuf->writex == ptrFesRtu->pTxCmdBuf->readx) + { + //ptrFesRtu->pTxCmdBuf->readx = (ptrFesRtu->pTxCmdBuf->readx+1)%CN_FesMaxkbd511s_infoTxCmdNum; + //clear all the data,否则缓存一直处理满的状态,部分命令会被刷掉。 + //LOGDEBUG("pTxCmdBuf overflow!\n"); + ptrFesRtu->pTxCmdBuf->writex = 0; + ptrFesRtu->pTxCmdBuf->readx = 0; + } + } + } + } + return iotSuccess; +} + + +/* + 根据通道号,清除数据线程 +*/ +void Ckbd511s_infoRtu::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + Ckbd511s_infoRtuDataProcThreadPtr ptrPort; + + if ((tempNum = (int)m_CDataProcQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) + { + ptrPort = *it; + if (ptrPort->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CDataProcQueue.erase(it);//会调用Ckbd511s_infoRtuDataProcThread::~Ckbd511s_infoRtuDataProcThread()退出线程 + LOGDEBUG("Ckbd511s_infoRtu::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + diff --git a/product/src/fes/protocol/kbd511s_info/kbd511s_infoRtu.h b/product/src/fes/protocol/kbd511s_info/kbd511s_infoRtu.h new file mode 100644 index 00000000..bf144de2 --- /dev/null +++ b/product/src/fes/protocol/kbd511s_info/kbd511s_infoRtu.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "kbd511s_infoRtuDataProcThread.h" +#include + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API Ckbd511s_infoRtu : public CProtocolBase +{ +public: + Ckbd511s_infoRtu(); + ~Ckbd511s_infoRtu(); + + vector m_CDataProcQueue; + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + +private: + void ClearDataProcThreadByChanNo(int ChanNo); +}; diff --git a/product/src/fes/protocol/kbd511s_info/kbd511s_infoRtuDataProcThread.cpp b/product/src/fes/protocol/kbd511s_info/kbd511s_infoRtuDataProcThread.cpp new file mode 100644 index 00000000..0de77325 --- /dev/null +++ b/product/src/fes/protocol/kbd511s_info/kbd511s_infoRtuDataProcThread.cpp @@ -0,0 +1,605 @@ +/* +@file kbd511s_infoRtuDataProcThread.cpp +@brief kbd511s_infoRtu 数据处理线程类。 +@author Rong +@histroy + 2020-07-17 Rong 添加对Linux版本的支持 + + +*/ +#ifdef OS_WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +using namespace std; +#pragma comment(lib,"ws2_32.lib") +#pragma comment(lib,"Iphlpapi.lib") //需要添加Iphlpapi.lib库 +#else +#include +#endif + +#include "kbd511s_infoRtuDataProcThread.h" +#include "SerialPortThread.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" +#include + +using namespace iot_public; + +extern bool g_kbd511s_infoRtuIsMainFes; +extern bool g_kbd511s_infoRtuChanelRun; + +const int g_kbd511s_infoRtuThreadTime = 100; + +char g_KBD511SInfoMultIpAddr[] = "239.0.0.11"; //组播地址 +int g_KBD511SInfoSendPort = 6664; //组播信息发送的端口号 +int g_KBD511SInfoRcvPort = 6662; //组播信息接收的端口号 + +Ckbd511s_infoRtuDataProcThread::Ckbd511s_infoRtuDataProcThread(CFesBase *ptrCFesBase, CFesChanPtr ptrCFesChan) : + CTimerThreadBase("kbd511s_infoRtuDataProcThread", g_kbd511s_infoRtuThreadTime, 0, true) +{ + CFesRtuPtr pRtu; + + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + + int RtuId = m_ptrCFesChan->m_CurrentRtuIndex; + int RtuNo = m_ptrCFesChan->m_RtuNo[RtuId]; + m_ptrCFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo); + m_ptrCInsertFesRtu = NULL; + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if(m_ptrCFesChan == NULL) + { + return ; + } + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } + + LOGDEBUG("KBD511S GPIO初始化完成..."); + + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuNormal); + m_ptrCFesRtu->SetOfflineFlag(CN_FesRtuNormal); + +} + +Ckbd511s_infoRtuDataProcThread::~Ckbd511s_infoRtuDataProcThread() +{ + CFesRtuPtr pRtu; + int RtuNo; + quit();//在调用quit()前,系统会调用beforeQuit(); + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } + LOGDEBUG("Ckbd511s_infoDataProcThread::~Ckbd511s_infoDataProcThread() ChanNo=%d EXIT", m_ptrCFesChan->m_Param.ChanNo); +} + +/** + * @brief Ckbd511s_infoRtuDataProcThread::beforeExecute + * + */ +int Ckbd511s_infoRtuDataProcThread::beforeExecute() +{ + ReadInfo(); + SocketInit(); + return iotSuccess; +} + +/* + @brief Ckbd511s_infoRtuDataProcThread::execute + + */ +void Ckbd511s_infoRtuDataProcThread::execute() +{ + //读取网络事件 + SFesNetEvent netEvent; + CFesRtuPtr pRtu; + + int RtuNo = 0; + + if (g_kbd511s_infoRtuChanelRun == false) + return; + + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + + if (m_ptrCurrentChan->ReadNetEvent(1, &netEvent) > 0) + { + switch (netEvent.EventType) + { + case CN_FesNetEvent_Connect: + LOGDEBUG("ChanNo:%d connect!", m_ptrCFesChan->m_Param.ChanNo); + break; + case CN_FesNetEvent_Disconnect: + LOGDEBUG("ChanNo:%d disconnect!", m_ptrCFesChan->m_Param.ChanNo); + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } + break; + default: + break; + } + } + + RecvNetData(); + + //SleepmSec(1000); +} + +/* + @brief 执行quit函数前的处理 + */ +void Ckbd511s_infoRtuDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); +} + + +/* +@brief 读取管理机信息 +*/ +void Ckbd511s_infoRtuDataProcThread::ReadInfo() +{ +#ifdef OS_WINDOWS + winGetHostname(m_HostName); //读出本机的机器名 + winGeEthParam(); //获取本机网口参数信息:ip地址、掩码、MAC +#else + gethostname(m_HostName, sizeof(m_HostName)); //读出本机配置的机器名 + //获取本机网卡信息 + memset(&m_LocalEthInfo[0], 0, CN_KBD511SInfoEthMaxNum * sizeof(SKBD511SInfoETH)); + m_LocalEthNum = 0; + KBD511S_GetEthParam("eth", 2); //获取有线网口参数 + KBD511S_GetEthParam("wlan", 1); //获取WIFI参数 +#endif + LOGDEBUG("HostName=%s", m_HostName); +} + + +/* +* @brief Ckbd511s_infoRtuDataProcThread::ExeCmmdScript +* 得到执行脚本命令返回信息 +*/ + +bool Ckbd511s_infoRtuDataProcThread::ExeCmmdScript(char *cmdStr, char *retCmdInfo, int infoLen) +{ + bool ret = false; + + if ((cmdStr == NULL) || (retCmdInfo == NULL)) + return ret; + + retCmdInfo[0] = '\0'; + +#ifndef OS_WINDOWS + FILE *fp; + + LOGDEBUG("%s ", cmdStr); + if ((fp = popen(cmdStr, "r")) == NULL) + { + LOGDEBUG("%s exe error!", cmdStr); + exit(1);//退出当前shell + return ret; + } + + ret = fread(retCmdInfo, sizeof(char), infoLen, fp); + LOGDEBUG("%s", retCmdInfo); + pclose(fp); +#endif + + return ret; +} + +//获取网口参数 +void Ckbd511s_infoRtuDataProcThread::KBD511S_GetEthParam(char* ethName, int ethNum) +{ + int i, ethFlag; + char buf[4096], cmd[128]; + char *spli_1; + + for (i = 0; i\n", errno, strerror(errno)); +#endif + return iotFailed; + } + + // struct sockaddr_in local; + memset(&localSin, 0, sizeof(localSin)); + localSin.sin_family = AF_INET; + localSin.sin_port = htons(g_KBD511SInfoRcvPort); + localSin.sin_addr.s_addr = htonl(INADDR_ANY); + //inet_pton(AF_INET, "0.0.0.0", &localSin.sin_addr.s_addr); + + ret = ::bind(m_Socket, (struct sockaddr *)&localSin, sizeof(localSin)); + if (ret == SOCKET_ERROR) + { +#ifdef OS_WINDOWS + LOGERROR("UDP bind(%d) failed, errno:%d ", m_Socket, WSAGetLastError()); +#else + LOGERROR("UDP bind(%d) failed, errno:%d <%s>", m_Socket, errno, strerror(errno)); +#endif + SocketClose(); + return iotFailed; + + } +/* //设置组播 +#ifdef OS_WINDOWS + n1.imr_multiaddr.s_addr = inet_addr(g_KBD511SInfoMultIpAddr); + n1.imr_interface.s_addr = htonl(INADDR_ANY); + //inet_pton(AF_INET, g_KBD511SInfoMultIpAddr, &n1.imr_multiaddr.s_addr); + //inet_pton(AF_INET, "0.0.0.0", &n1.imr_interface.s_addr); + if (setsockopt(m_Socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&n1, sizeof(n1))<0) +#else + n1.imr_multiaddr.s_addr = inet_addr(g_KBD511SInfoMultIpAddr); + n1.imr_interface.s_addr = htonl(INADDR_ANY); + //inet_pton(AF_INET, g_KBD511SInfoMultIpAddr, &n1.imr_multiaddr.s_addr); + //inet_pton(AF_INET, "0.0.0.0", &n1.imr_address.s_addr); + //n1.imr_ifindex = if_nametoindex("eth0"); + if (setsockopt(m_Socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &n1, sizeof(n1))<0) +#endif + { + LOGERROR("Usetsockopt m_Socket IP_ADD_MEMBERSHIP\n"); + //return iotFailed; + }*/ + + //设置套接字为非阻塞模式 +#ifdef OS_WINDOWS + u_long argp = 1; + if (ioctlsocket(m_Socket, FIONBIO, &argp) == SOCKET_ERROR) +#else + int flags; + flags = fcntl(m_Socket, F_GETFL, 0); + if (fcntl(m_Socket, F_SETFL, flags | O_NONBLOCK) < 0) //O_NDELAY + +#endif + { +#ifdef OS_WINDOWS + LOGERROR("ioctlsocket(sock:%d) set FIONBIO error, errno:%d \n", m_Socket, WSAGetLastError()); +#else + LOGERROR("fcntl(sock:%d) set O_NONBLOCK error, errno:%d <%s>\n", m_Socket, errno, strerror(errno)); +#endif + return iotFailed; + } + return iotSuccess; +} + +void Ckbd511s_infoRtuDataProcThread::SocketClose() +{ + if (m_Socket != INVALID_SOCKET) + { + closesocket(m_Socket); + m_Socket = INVALID_SOCKET; + LOGDEBUG("closesocket m_Socket =%d", m_Socket); + } +} + +int Ckbd511s_infoRtuDataProcThread::RxData(char *retData, int MaxDataLen) +{ + int len, fromlen; + fd_set fdSet; + sockaddr_in fromaddr; + struct timeval tv; + char fromIP[64]; + + if (m_Socket == SOCKET_ERROR) + return -1; + + //add 判断soket是否可读 + FD_ZERO(&fdSet); + FD_SET(m_Socket, &fdSet); + tv.tv_sec = 0; + tv.tv_usec = 20 * 1000; + + len = select((int)(m_Socket + 1), &fdSet, 0, 0, &tv); + if (len < 0) + { +#ifdef OS_WINDOWS + LOGWARN("select(sock+1:%d) error, errno:%d ", m_Socket + 1, WSAGetLastError()); +#else + LOGWARN("select(sock+1:%d) error, errno:%d <%s>", m_Socket, errno, strerror(errno)); +#endif + } + else + if (len > 0) + { + fromlen = sizeof(fromaddr); +#ifdef OS_WINDOWS + len = ::recvfrom(m_Socket, retData, MaxDataLen, 0, (struct sockaddr *)&fromaddr, &fromlen); +#else + len = ::recvfrom(m_Socket, retData, MaxDataLen, 0, (struct sockaddr *)&fromaddr, (socklen_t*)&fromlen); +#endif + if (len > 0) + { + memset(fromIP, 0, sizeof(fromIP)); + strcpy(fromIP, inet_ntoa(fromaddr.sin_addr)); + LOGDEBUG("Recv from %s len=%d", fromIP, len); + strcpy(g_KBD511SInfoMultIpAddr, fromIP); + } + } + + return len; +} + +int Ckbd511s_infoRtuDataProcThread::TxData(char *Data, int DataLen) +{ + struct sockaddr_in client; + int ret; + + ret = -1; + if (m_Socket == SOCKET_ERROR) + return ret; + + memset(&client, 0, sizeof(client)); + client.sin_family = AF_INET; + client.sin_port = htons(g_KBD511SInfoSendPort); + client.sin_addr.s_addr = inet_addr(g_KBD511SInfoMultIpAddr); + //inet_pton(AF_INET, g_KBD511SInfoMultIpAddr, &client.sin_addr.s_addr); + + ret = sendto(m_Socket, Data, DataLen, 0, (struct sockaddr *)&client, sizeof(client)); + if (ret < 0) + { +#ifdef OS_WINDOWS + LOGDEBUG("sendto(sock:%d) error, errno:%d ", m_Socket, WSAGetLastError()); +#else + LOGDEBUG("sendto(sock:%d) error, errno:%d <%s>", m_Socket, errno, strerror(errno)); +#endif + } + else + LOGDEBUG("sendto(%s:%d) len=%d ", g_KBD511SInfoMultIpAddr,g_KBD511SInfoSendPort,ret); + return ret; +} + +//windows获取主机名 +void Ckbd511s_infoRtuDataProcThread::winGetHostname(char* hostname) +{ +#ifdef OS_WINDOWS + WCHAR PCname[255]; + DWORD bufSizeP = 255; + memset(PCname, 0, 255); + + GetComputerName(PCname, &bufSizeP); + bufSizeP = WideCharToMultiByte(CP_ACP, 0, PCname, -1, NULL, 0, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, PCname, -1, hostname, bufSizeP, NULL, NULL); +#endif +} + +//windows获取网卡信息 +void Ckbd511s_infoRtuDataProcThread::winGeEthParam() +{ +#ifdef OS_WINDOWS + //PIP_ADAPTER_INFO结构体指针存储本机网卡信息 + PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO(); + //得到结构体大小,用于GetAdaptersInfo参数 + unsigned long stSize = sizeof(IP_ADAPTER_INFO); + //调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量 + int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize); + //记录网卡数量 + int netCardNum = 0; + //记录每张网卡上的IP地址数量 + //int IPnumPerNetCard = 0; + + memset(&m_LocalEthInfo[0], 0, CN_KBD511SInfoEthMaxNum * sizeof(SKBD511SInfoETH)); + m_LocalEthNum = 0; + if (ERROR_BUFFER_OVERFLOW == nRel) + { + //如果函数返回的是ERROR_BUFFER_OVERFLOW + //则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小 + //这也是说明为什么stSize既是一个输入量也是一个输出量 + //释放原来的内存空间 + delete pIpAdapterInfo; + //重新申请内存空间用来存储所有网卡信息 + pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize]; + //再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量 + nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize); + } + if (ERROR_SUCCESS == nRel) + { + //输出网卡信息 + //可能有多网卡,因此通过循环去判断 + while (pIpAdapterInfo) + { + //网卡名称 + strcpy(m_LocalEthInfo[netCardNum].EthName, pIpAdapterInfo->Description); + //网卡描述 + //strcpy(m_LocalEthInfo[netCardNum].EthName, pIpAdapterInfo->Description); + //网卡类型 + m_LocalEthInfo[netCardNum].Type = pIpAdapterInfo->Type; + /*switch (pIpAdapterInfo->Type) + { + case MIB_IF_TYPE_OTHER: + cout << "网卡类型:" << "OTHER" << endl; + break; + case MIB_IF_TYPE_ETHERNET: + cout << "网卡类型:" << "ETHERNET" << endl; + break; + case MIB_IF_TYPE_TOKENRING: + cout << "网卡类型:" << "TOKENRING" << endl; + break; + case MIB_IF_TYPE_FDDI: + cout << "网卡类型:" << "FDDI" << endl; + break; + case MIB_IF_TYPE_PPP: + cout << "网卡类型:" << "PPP" << endl; + break; + case MIB_IF_TYPE_LOOPBACK: + cout << "网卡类型:" << "LOOPBACK" << endl; + break; + case MIB_IF_TYPE_SLIP: + cout << "网卡类型:" << "SLIP" << endl; + break; + default: + break; + }*/ + //网卡MAC地址 + for (unsigned int i = 0; i < pIpAdapterInfo->AddressLength; i++) + { + if (i < pIpAdapterInfo->AddressLength - 1) + sprintf(&m_LocalEthInfo[netCardNum].Mac[i * 3], "%02X-", pIpAdapterInfo->Address[i]); + else + sprintf(&m_LocalEthInfo[netCardNum].Mac[i * 3], "%02X", pIpAdapterInfo->Address[i]); + } + //可能网卡有多IP,因此通过循环去判断 + IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfo->IpAddressList); + /*do { + cout << "该网卡上的IP数量:" << ++IPnumPerNetCard << endl; + cout << "IP 地址:" << pIpAddrString->IpAddress.String << endl; + cout << "子网地址:" << pIpAddrString->IpMask.String << endl; + cout << "网关地址:" << pIpAdapterInfo->GatewayList.IpAddress.String << endl; + pIpAddrString = pIpAddrString->Next; + } while (pIpAddrString);*/ + + //网卡第一个IP地址 + strcpy(m_LocalEthInfo[netCardNum].IpAddr, pIpAddrString->IpAddress.String); + //掩码 + strcpy(m_LocalEthInfo[netCardNum].Mask, pIpAddrString->IpMask.String); + //网关 + strcpy(m_LocalEthInfo[netCardNum].Gateway, pIpAdapterInfo->GatewayList.IpAddress.String); + pIpAdapterInfo = pIpAdapterInfo->Next; + netCardNum++; + } + m_LocalEthNum = netCardNum; + } + //释放内存空间 + if (pIpAdapterInfo) + delete pIpAdapterInfo; +#endif +} + +void Ckbd511s_infoRtuDataProcThread::RecvNetData() +{ + char recvBuf[100]; + int maxRecvSize; + int retLen; + + memset(recvBuf,0,100); + maxRecvSize = sizeof(recvBuf); + retLen = RxData(recvBuf, maxRecvSize); + if (retLen > 0) + { + LOGDEBUG("recv(%s:%d) %s ", g_KBD511SInfoMultIpAddr,g_KBD511SInfoSendPort,recvBuf); + if (strcmp((char *)recvBuf, "APP") == 0) + RecvDataProcess(); + } +} + +int Ckbd511s_infoRtuDataProcThread::RecvDataProcess() +{ + char sendData[1024]; + char temStr[500]; + int sendLen, ret; + + LOGDEBUG("recv(%s:%d) APP sendInfo ", g_KBD511SInfoMultIpAddr,g_KBD511SInfoSendPort); + memset(sendData,0,1024); + sprintf(sendData, "hostname:%s,\n", m_HostName); + for (int i = 0; i < m_LocalEthNum; i++) + { + memset(temStr, 0, 500); + sprintf(temStr, "%s IP:%s\nMAC:%s\nMask:%s,\n", m_LocalEthInfo[i].EthName, m_LocalEthInfo[i].IpAddr, m_LocalEthInfo[i].Mac, m_LocalEthInfo[i].Mask); + strcat(sendData, temStr); + } + sendLen = (int)strlen(sendData); + ret = TxData(sendData, sendLen); + + return ret; +} + + diff --git a/product/src/fes/protocol/kbd511s_info/kbd511s_infoRtuDataProcThread.h b/product/src/fes/protocol/kbd511s_info/kbd511s_infoRtuDataProcThread.h new file mode 100644 index 00000000..5eef377a --- /dev/null +++ b/product/src/fes/protocol/kbd511s_info/kbd511s_infoRtuDataProcThread.h @@ -0,0 +1,84 @@ +#pragma once + +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include +#ifndef OS_WINDOWS +#include +#include +//#include +#endif // WIN32 + +using namespace iot_public; +//本机网口信息 +const int CN_KBD511SInfoEthMaxNum = 8; +const int CN_KBD511SInfoEthDescMaxSize = 100; + +typedef struct _SKBD511SInfoETH { + char EthName[CN_KBD511SInfoEthDescMaxSize]; //ETH名 + char IpAddr[CN_KBD511SInfoEthDescMaxSize]; //IP + char Mask[CN_KBD511SInfoEthDescMaxSize]; //掩码 + char Mac[CN_KBD511SInfoEthDescMaxSize]; //MAC + char Bcast[CN_KBD511SInfoEthDescMaxSize]; + char Gateway[CN_KBD511SInfoEthDescMaxSize]; //网关 + unsigned int Type; //网卡类型 + _SKBD511SInfoETH() { + memset(EthName, 0, CN_KBD511SInfoEthDescMaxSize); + memset(IpAddr, 0, CN_KBD511SInfoEthDescMaxSize); + memset(Mask, 0, CN_KBD511SInfoEthDescMaxSize); + memset(Mac, 0, CN_KBD511SInfoEthDescMaxSize); + memset(Bcast, 0, CN_KBD511SInfoEthDescMaxSize); + memset(Gateway, 0, CN_KBD511SInfoEthDescMaxSize); + Type = 0; + } +}SKBD511SInfoETH; + +class Ckbd511s_infoRtuDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + Ckbd511s_infoRtuDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan); + virtual ~Ckbd511s_infoRtuDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + CFesBase* m_ptrCFesBase; + + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区 + CFesRtuPtr m_ptrCInsertFesRtu; //当前插入命令使用RTU数据区 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + +private: + + char m_HostName[CN_KBD511SInfoEthDescMaxSize]; + SKBD511SInfoETH m_LocalEthInfo[CN_KBD511SInfoEthMaxNum]; + int m_LocalEthNum; + char m_defaultGW[CN_KBD511SInfoEthDescMaxSize]; + int m_Socket; + + bool ExeCmmdScript(char *cmdStr, char *retCmdInfo, int infoLen); + void ReadInfo(); + void SocketClose(); + int RxData(char *retData, int MaxDataLen); + int TxData(char *Data, int DataLen); + void RecvNetData(); + int RecvDataProcess(); + int SocketInit(); + + void winGetHostname(char* hostname); + void winGeEthParam(); + + void KBD511S_GetEthParam(char* ethName, int ethNum); +}; + +typedef boost::shared_ptr Ckbd511s_infoRtuDataProcThreadPtr; diff --git a/product/src/fes/protocol/kbd511s_io/kbd511s_gpio.c b/product/src/fes/protocol/kbd511s_io/kbd511s_gpio.c new file mode 100644 index 00000000..05c55c37 --- /dev/null +++ b/product/src/fes/protocol/kbd511s_io/kbd511s_gpio.c @@ -0,0 +1,613 @@ +/* + KBD511S操作GPIO实现文件 +*/ + +#include +#include +#include +#include +#include //define O_WRONLY and O_RDONLY +#include "kbd511s_gpio.h" + +#ifdef WIN32 + +#else +#include +#include +//#include +#endif + +KBD511S_GPIO_STR kbd511s_dilist[KBD511S_MAX_DI_NUM]; +KBD511S_GPIO_STR kbd511s_dolist[KBD511S_MAX_DO_NUM]; +KBD511S_GPIO_STR kbd511s_comlist[KBD511S_MAX_COM_NUM]; +char KBD511S_InitFlag = 0; + +#ifdef WIN32 +/*//设置GPIO值 +int setGpioValue(const int GpioNo, const char *GpioName, const int setValue) +{ + return -1; +} + +//读取GPIO值 +int getGpioValue(const int GpioNo, const char *GpioName) +{ + return -1; +}*/ + +//获取DI状态 +int getDiValue(const int DiNo) +{ + return -1; +} + +//获取DO状态 +int getDoValue(const int DoNo) +{ + return -1; +} + +//设置DO输出 +int setDoValue(const int DoNo, const int setValue) +{ + return -1; +} + +//设置串口模式 +int setComMod(const int ComNo,const int setValue) +{ + return -1; +} + +//点亮运行灯 +int setRunLed(const int setValue) +{ + return -1; +} + +#else +/* +//文件方式读GPIO +int file_get_gpio(const int GpioNo,char outflag) +{ + char a[10] = {0}; + char gpioPath[KBD511S_PATH_LEN]; + int ret = -1; + //取出GPIO + int fd = open(SYSFS_GPIO_EXPORT, O_WRONLY); + if (fd == -1) + { + printf("open fail:%s\n", SYSFS_GPIO_EXPORT); + return -1; + } + memset(gpioPath, 0, KBD511S_PATH_LEN); + sprintf(gpioPath, "%d", GpioNo); + write(fd, gpioPath, strlen(gpioPath)); + close(fd); + printf("echo %s > %s\n", gpioPath, SYSFS_GPIO_EXPORT); + + //设置输入 /sys/class/gpio/gpioNo# echo in > direction + memset(gpioPath, 0, KBD511S_PATH_LEN); + sprintf(gpioPath, "%s/gpio%d/direction", SYSFS_GPIO_PATH, GpioNo); + fd = open(gpioPath, O_WRONLY); + if (fd == -1) + { + printf("open fail:%s\n", gpioPath); + return -1; + } + + if (outflag) + { + printf("echo out > %s\n", gpioPath); + write(fd, SYSFS_GPIO_RST_DIR_IN, sizeof(SYSFS_GPIO_RST_DIR_OUT)); + } + else + { + printf("echo in > %s\n", gpioPath); + write(fd, SYSFS_GPIO_RST_DIR_IN, sizeof(SYSFS_GPIO_RST_DIR_IN)); + } + close(fd); + + //读取GPIO的值 + memset(gpioPath, 0, KBD511S_PATH_LEN); + sprintf(gpioPath, "%s/gpio%d/value", SYSFS_GPIO_PATH, GpioNo); + fd = open(gpioPath, O_RDWR); + if (fd == -1) + { + printf("open fail:%s\n", gpioPath); + return -1; + } + ret = read(fd, a, sizeof(a)); + close(fd); + if (ret == -1) + printf("read data error\n"); + else + ret = atoi(a); + printf("ret=%d\n", ret); + return ret; +} + +//文件方式写GPIO +int file_set_gpio(const int GpioNo, const int setValue) +{ + char gpioPath[KBD511S_PATH_LEN]; + //取出GPIO + int fd = open(SYSFS_GPIO_EXPORT, O_WRONLY); + if (fd == -1) + { + printf("open fail:%s\n", SYSFS_GPIO_EXPORT); + return -1; + } + memset(gpioPath, 0, KBD511S_PATH_LEN); + sprintf(gpioPath, "%d", GpioNo); + write(fd, gpioPath, strlen(gpioPath)); + close(fd); + printf("echo %s > %s\n", gpioPath, SYSFS_GPIO_EXPORT); + + //设置为输出 /sys/class/gpio/gpio137# echo out > direction + memset(gpioPath, 0, KBD511S_PATH_LEN); + sprintf(gpioPath, "%s/gpio%d/direction", SYSFS_GPIO_PATH, GpioNo); + fd = open(gpioPath, O_WRONLY); + if (fd == -1) + { + printf("open fail:%s\n", gpioPath); + return -1; + } + printf("echo out > %s\n", gpioPath); + write(fd, SYSFS_GPIO_RST_DIR_OUT, sizeof(SYSFS_GPIO_RST_DIR_OUT)); + close(fd); + + //设置值 + memset(gpioPath, 0, KBD511S_PATH_LEN); + sprintf(gpioPath, "%s/gpio%d/value", SYSFS_GPIO_PATH, GpioNo); + fd = open(gpioPath, O_RDWR); + if (fd == -1) + { + printf("open fail:%s\n", gpioPath); + return -1; + } + if (setValue) + write(fd, SYSFS_GPIO_RST_VAL_H, sizeof(SYSFS_GPIO_RST_VAL_H)); + else + write(fd, SYSFS_GPIO_RST_VAL_L, sizeof(SYSFS_GPIO_RST_VAL_L)); + printf("echo %d > %s\n", setValue, gpioPath); + close(fd); + return 1; +}*/ + +//libgpiod库读GPIO +/*int gpiod_get_gpio(const int pNo,const char doFlag) +{ + struct gpiod_chip *chip; + struct gpiod_line *line; + int value=-1,req; + char str[KBD511S_PATH_LEN]; + int chipNo,phNo; + char consumer[KBD511S_MAX_NAME_LEN]={0}; + + if(doFlag) + { + chipNo = kbd511s_dolist[pNo].chipNo; + phNo = kbd511s_dolist[pNo].phNo; + strcpy(consumer,kbd511s_dolist[pNo].gpioName); + } + else + { + chipNo = kbd511s_dilist[pNo].chipNo; + phNo = kbd511s_dilist[pNo].phNo; + strcpy(consumer,kbd511s_dilist[pNo].gpioName); + } + + // 打开 GPIO 控制器 + memset(str, 0, KBD511S_PATH_LEN); + sprintf(str, "/dev/gpiochip%d",chipNo); + chip = gpiod_chip_open(str); + if (!chip) + { + printf("open fail:%s\n",str); + return -1; + } + + // 获取PH5引脚 + line = gpiod_chip_get_line(chip, phNo); + if (!line) + { + gpiod_chip_close(chip); + printf("gpiod_chip_get_line fail:chip%d_%d\n",chipNo,phNo); + return -1; + } + + if(doFlag) + { + value = kbd511s_dolist[pNo].value; + req = gpiod_line_request_output(line,consumer,value); // 输出 + printf("gpiochip%d_%d request_output:%d ret=%d\n",chipNo,phNo,value,req); + } + else + { + req = gpiod_line_request_input(line,consumer); // 输入 + printf("gpiochip%d_%d request_input:%d\n",chipNo,phNo,req); + } + + //读取值 + value = gpiod_line_get_value(line); + printf("gpiochip%d_%d value=%d\n",chipNo,phNo,value); + if(doFlag && (value != -1)) + kbd511s_dolist[pNo].value = value; + + gpiod_line_release(line); + gpiod_chip_close(chip); + return value; + +} + +//libgpiod库写GPIO +int gpiod_set_gpio(const int pType,const int pNo,const int setValue) +{ + struct gpiod_chip *chip; + struct gpiod_line *line; + int req; + char str[KBD511S_PATH_LEN]; + int chipNo,phNo; + char consumer[KBD511S_MAX_NAME_LEN]={0}; + + if(pType == KBD511S_DO_TYPE) + { + chipNo = kbd511s_dolist[pNo].chipNo; + phNo = kbd511s_dolist[pNo].phNo; + strcpy(consumer,kbd511s_dolist[pNo].gpioName); + } + else if(pType == KBD511S_COM_TYPE) + { + chipNo = kbd511s_comlist[pNo].chipNo; + phNo = kbd511s_comlist[pNo].phNo; + strcpy(consumer,kbd511s_comlist[pNo].gpioName); + } + else + { + chipNo = pType; + phNo = pNo; + strcpy(consumer,"gpiotest"); + } + + // 打开 GPIO 控制器 + memset(str, 0, KBD511S_PATH_LEN); + sprintf(str, "/dev/gpiochip%d",chipNo); + chip = gpiod_chip_open(str); + if (!chip) + { + printf("open fail:%s\n",str); + return -1; + } + + // 获取PH5引脚 + line = gpiod_chip_get_line(chip, phNo); + if (!line) + { + gpiod_chip_close(chip); + printf("gpiod_chip_get_line fail:chip%d_%d\n",chipNo,phNo); + return -1; + } + + // 输出 + req = gpiod_line_request_output(line,consumer,setValue); + printf("gpiochip%d_%d request_output:%d ret=%d\n",chipNo,phNo,setValue,req); + + if((pType == KBD511S_DO_TYPE) && (req != -1)) + kbd511s_dolist[pNo].value = setValue; + + //不需要了,初始化时会设置值 + //req = gpiod_line_set_value(line,setValue); + //printf("set gpiochip%d_%d:%d return=%d\n",chipNo,phNo,setValue,req); + + gpiod_line_release(line); + gpiod_chip_close(chip); + return 1; +}*/ + +int linux_get_gpio(const int pNo,const char doFlag) +{ + int value=-1; + char str[KBD511S_PATH_LEN]; + int chipNo,phNo; + char consumer[KBD511S_MAX_NAME_LEN]={0}; + + struct gpio_v2_line_values values; + struct gpio_v2_line_request req; + int fd,ret,i; + + //设置为输入 + memset(&req, 0, sizeof(req)); + //config.flags = GPIO_V2_LINE_FLAG_OUTPUT; + if(doFlag) + { + chipNo = kbd511s_dolist[pNo].chipNo; + phNo = kbd511s_dolist[pNo].phNo; + strcpy(consumer,kbd511s_dolist[pNo].gpioName); + } + else + { + chipNo = kbd511s_dilist[pNo].chipNo; + phNo = kbd511s_dilist[pNo].phNo; + strcpy(consumer,kbd511s_dilist[pNo].gpioName); + req.config.flags = GPIO_V2_LINE_FLAG_INPUT; + } + + req.offsets[0] = phNo; + req.num_lines = 1; + strcpy(req.consumer, consumer); + + //打开GPIO设备组 + memset(str, 0, KBD511S_PATH_LEN); + sprintf(str, "/dev/gpiochip%d",chipNo); + fd = open(str, 0); + if (fd == -1) { + printf("Failed to open %s, %s\n",str); + return -1; + } + + //取出GPIO组的引脚 + ret = ioctl(fd, GPIO_V2_GET_LINE_IOCTL, &req); + if (ret == -1) + { + printf("Failed to issue %s (%d)\n","GPIO_GET_LINE_IOCTL", ret); + return -1; + } + else + { + printf("fd=%d req.fd=%d \n",fd,req.fd); + close(fd); + fd = req.fd; + } + + //设置值的有效位 + values.mask = 1; + values.bits = 0; + + //取出GPIO的值 + ret = ioctl(fd, GPIO_V2_LINE_GET_VALUES_IOCTL, &values); + if (ret == -1) + printf("Failed to issue %s (%d)\n", "GPIO_V2_LINE_GET_VALUES_IOCTL", ret); + + ret = values.bits & 0x01; + printf("get gpiochip%d_%d:%d\n",chipNo,phNo,ret); + + close(fd); + return ret; +} + +int linux_set_gpio(const int pType,const int pNo,const int setValue) +{ + char str[KBD511S_PATH_LEN]; + int chipNo,phNo; + char consumer[KBD511S_MAX_NAME_LEN]={0}; + struct gpio_v2_line_values values; + struct gpio_v2_line_request req; + int fd,ret,i; + + if(pType == KBD511S_DO_TYPE) + { + chipNo = kbd511s_dolist[pNo].chipNo; + phNo = kbd511s_dolist[pNo].phNo; + strcpy(consumer,kbd511s_dolist[pNo].gpioName); + } + else if(pType == KBD511S_COM_TYPE) + { + chipNo = kbd511s_comlist[pNo].chipNo; + phNo = kbd511s_comlist[pNo].phNo; + strcpy(consumer,kbd511s_comlist[pNo].gpioName); + } + else + { + chipNo = pType; + phNo = pNo; + strcpy(consumer,"gpiotest"); + } + + //设置为输出 + memset(&req, 0, sizeof(req)); + req.config.flags = GPIO_V2_LINE_FLAG_OUTPUT; + req.offsets[0] = phNo; + req.num_lines = 1; + strcpy(req.consumer, consumer); + + //打开GPIO设备组 + memset(str, 0, KBD511S_PATH_LEN); + sprintf(str, "/dev/gpiochip%d",chipNo); + fd = open(str, 0); + if (fd == -1) { + printf("Failed to open %s, %s\n",str); + return -1; + } + + //取出GPIO组的引脚 + ret = ioctl(fd, GPIO_V2_GET_LINE_IOCTL, &req); + if (ret == -1) + { + printf("Failed to issue %s (%d)\n","GPIO_GET_LINE_IOCTL", ret); + return -1; + } + else + { + printf("fd=%d req.fd=%d \n",fd,req.fd); + close(fd); + fd = req.fd; + } + + //设置值的有效位 + values.mask = 1; + values.bits = setValue; + + //设置GPIO值 + ret = ioctl(fd, GPIO_V2_LINE_SET_VALUES_IOCTL, &values); + if (ret == -1) + printf("Failed to issue %s (%d)\n","GPIO_V2_LINE_SET_VALUES_IOCTL", ret); + + //记住DO设置值 + if((pType == KBD511S_DO_TYPE) && (ret != -1)) + kbd511s_dolist[pNo].value = setValue; + + printf("set gpiochip%d_%d:%d\n",chipNo,phNo,setValue); + close(fd); + return ret; +} + +//获取DI状态 +int getDiValue(const int DiNo) +{ + int diValue; + //DI序号越限、未初始化 + if ((DiNo < 0) || (DiNo >= KBD511S_MAX_DI_NUM) || !KBD511S_InitFlag) + return -1; + + //return gpiod_get_gpio(DiNo,0); + diValue = linux_get_gpio(DiNo, 0); + if(diValue == -1) + return -1; + + return !diValue; +} + +//获取DO状态 +int getDoValue(const int DoNo) +{ + //DO序号越限、未初始化 + if ((DoNo < 0) || (DoNo >= KBD511S_MAX_DO_NUM) || !KBD511S_InitFlag) + return -1; + + //return kbd511s_dolist[DoNo].value; + return linux_get_gpio(DoNo,1); +} + +//设置DO输出 +int setDoValue(const int DoNo, const int setValue) +{ + //DO序号越限、未初始化 + if ((DoNo < 0) || (DoNo >= KBD511S_MAX_DO_NUM) || !KBD511S_InitFlag) + return -1; + + //return gpiod_set_gpio(KBD511S_DO_TYPE,DoNo,setValue); + return linux_set_gpio(KBD511S_DO_TYPE,DoNo,setValue); +} + +//设置串口模式 +int setComMod(const int ComNo, const int setValue) +{ + //串口序号越限、未初始化 + if ((ComNo < 0) || (ComNo >= KBD511S_MAX_COM_NUM) || !KBD511S_InitFlag) + return -1; + + //return gpiod_set_gpio(KBD511S_COM_TYPE,ComNo,setValue); + return linux_set_gpio(KBD511S_COM_TYPE,ComNo,setValue); +} + +//点亮运行灯 +int setRunLed(const int setValue) +{ + //return gpiod_set_gpio(4,12,setValue); + return linux_set_gpio(4,12,setValue); +} +#endif + +void initDiParam() +{ + int i; + for(i=0;i 0) + m_CDataProcQueue.clear(); + + LOGDEBUG("Ckbd511s_ioRtu::~Ckbd511s_ioRtu() 退出"); +} + + +int Ckbd511s_ioRtu::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + } + //规约映射表初始化 + if (m_ptrCFesBase != NULL) + { + m_ptrCFesBase->ProtocolRtuInitByParam1((char*)"kbd511s_io"); + } + + return iotSuccess; +} + +int Ckbd511s_ioRtu::SetProperty(int IsMainFes) +{ + g_kbd511s_ioRtuIsMainFes = IsMainFes; + LOGDEBUG("Ckbd511s_ioRtu::SetProperty g_kbd511s_ioRtuIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief Ckbd511s_ioRtu::OpenChan + * 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int Ckbd511s_ioRtu::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if((OpenFlag==CN_FesChanThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + ptrFesChan->SetComThreadRunFlag(CN_FesRunFlag); + ptrFesChan->SetLinkStatus(CN_FesChanRun); + ptrFesChan->SetChangeFlag(CN_FesChanUnChange); + + } + + + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + Ckbd511s_ioRtuDataProcThreadPtr ptrCDataProc; + ptrCDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan); + if (ptrCDataProc == NULL) + { + LOGERROR("Ckbd511s_ioRtu EX_OpenChan() ChanNo:%d create Ckbd511s_ioRtuDataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; + +} + +/** + * @brief Ckbd511s_ioRtu::CloseChan + * 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int Ckbd511s_ioRtu::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("Ckbd511s_ioRtu::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + if((CloseFlag==CN_FesChanThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + ptrFesChan->SetComThreadRunFlag(CN_FesStopFlag); + + } + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + + return iotSuccess; +} + +/** +* @brief Ckbd511s_ioRtu::ChanTimer +* 通道定时器,主通道会定时调用 +* @param MainChanNo 主通道号 +* @return +*/ +int Ckbd511s_ioRtu::ChanTimer(int MainChanNo) +{ + //把命令缓冲时间间隔到的命放到发送命令缓冲区 + CFesChanPtr ptrFesChan; + CFesChanPtr ptrCurrentChan; + CFesRtuPtr ptrFesRtu; + int i, j, RtuNo; + + if ((ptrFesChan = m_ptrCFesBase->GetChanDataByChanNo(MainChanNo)) == NULL) + return iotFailed; + + SModbusCmd *pCmd; + for (i = 0; im_RtuNum; i++) + { + RtuNo = ptrFesChan->m_RtuNo[i]; + if ((ptrFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) + continue; + for (j = 0; jm_Param.ModbusCmdBuf.num; j++) + { + pCmd = ptrFesRtu->m_Param.ModbusCmdBuf.pCmd + j; + pCmd->PollTimeCount++; + if (pCmd->PollTimeCount >= pCmd->PollTime)//时间到,命令放入TxBuf + { + memcpy(&ptrFesRtu->pTxCmdBuf->cmd[ptrFesRtu->pTxCmdBuf->writex], pCmd, sizeof(SModbusCmd)); + + pCmd->PollTimeCount = 0; + ptrFesRtu->pTxCmdBuf->writex = (ptrFesRtu->pTxCmdBuf->writex + 1) % CN_FesMaxModbusTxCmdNum; + if (ptrFesRtu->pTxCmdBuf->writex == ptrFesRtu->pTxCmdBuf->readx) + { + //ptrFesRtu->pTxCmdBuf->readx = (ptrFesRtu->pTxCmdBuf->readx+1)%CN_FesMaxkbd511s_ioTxCmdNum; + //clear all the data,否则缓存一直处理满的状态,部分命令会被刷掉。 + //LOGDEBUG("pTxCmdBuf overflow!\n"); + ptrFesRtu->pTxCmdBuf->writex = 0; + ptrFesRtu->pTxCmdBuf->readx = 0; + } + } + } + } + return iotSuccess; +} + + +/* + 根据通道号,清除数据线程 +*/ +void Ckbd511s_ioRtu::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + Ckbd511s_ioRtuDataProcThreadPtr ptrPort; + + if ((tempNum = (int)m_CDataProcQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) + { + ptrPort = *it; + if (ptrPort->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CDataProcQueue.erase(it);//会调用Ckbd511s_ioRtuDataProcThread::~Ckbd511s_ioRtuDataProcThread()退出线程 + LOGDEBUG("Ckbd511s_ioRtu::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + diff --git a/product/src/fes/protocol/kbd511s_io/kbd511s_ioRtu.h b/product/src/fes/protocol/kbd511s_io/kbd511s_ioRtu.h new file mode 100644 index 00000000..3ef66985 --- /dev/null +++ b/product/src/fes/protocol/kbd511s_io/kbd511s_ioRtu.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "kbd511s_ioRtuDataProcThread.h" +#include + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API Ckbd511s_ioRtu : public CProtocolBase +{ +public: + Ckbd511s_ioRtu(); + ~Ckbd511s_ioRtu(); + + vector m_CDataProcQueue; + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + +private: + void ClearDataProcThreadByChanNo(int ChanNo); +}; diff --git a/product/src/fes/protocol/kbd511s_io/kbd511s_ioRtuDataProcThread.cpp b/product/src/fes/protocol/kbd511s_io/kbd511s_ioRtuDataProcThread.cpp new file mode 100644 index 00000000..b43fa634 --- /dev/null +++ b/product/src/fes/protocol/kbd511s_io/kbd511s_ioRtuDataProcThread.cpp @@ -0,0 +1,622 @@ +/* +@file kbd511s_ioRtuDataProcThread.cpp +@brief kbd511s_ioRtu 数据处理线程类。 +@author Rong +@histroy + 2020-07-17 Rong 添加对Linux版本的支持 + + +*/ + +#include "kbd511s_ioRtuDataProcThread.h" +#include "SerialPortThread.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" +#include + +using namespace iot_public; + +extern bool g_kbd511s_ioRtuIsMainFes; +extern bool g_kbd511s_ioRtuChanelRun; + +const int g_kbd511s_ioRtuThreadTime = 20; + +Ckbd511s_ioRtuDataProcThread::Ckbd511s_ioRtuDataProcThread(CFesBase *ptrCFesBase, CFesChanPtr ptrCFesChan) : + CTimerThreadBase("kbd511s_ioRtuDataProcThread", g_kbd511s_ioRtuThreadTime, 0, true) +{ + CFesRtuPtr pRtu; + + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + + int RtuId = m_ptrCFesChan->m_CurrentRtuIndex; + int RtuNo = m_ptrCFesChan->m_RtuNo[RtuId]; + m_ptrCFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo); + m_ptrCInsertFesRtu = NULL; + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if(m_ptrCFesChan == NULL) + { + return ; + } + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } + + initGpioParam(); + LOGDEBUG("KBD511S GPIO初始化完成..."); + + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuNormal); + m_ptrCFesRtu->SetOfflineFlag(CN_FesRtuNormal); + m_AppData.runLed = true; + memset(m_AppData.dostr, 0, sizeof(m_AppData.dostr)); + m_AppData.setComFlag = 1; +} + +Ckbd511s_ioRtuDataProcThread::~Ckbd511s_ioRtuDataProcThread() +{ + CFesRtuPtr pRtu; + int RtuNo; + setRunLed(1);//关闭运行灯 + quit();//在调用quit()前,系统会调用beforeQuit(); + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } + LOGDEBUG("Ckbd511s_ioDataProcThread::~Ckbd511s_ioDataProcThread() ChanNo=%d EXIT", m_ptrCFesChan->m_Param.ChanNo); +} + +/** + * @brief Ckbd511s_ioRtuDataProcThread::beforeExecute + * + */ +int Ckbd511s_ioRtuDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief Ckbd511s_ioRtuDataProcThread::execute + + */ +void Ckbd511s_ioRtuDataProcThread::execute() +{ + //读取网络事件 + SFesNetEvent netEvent; + CFesRtuPtr pRtu; + + int ret = -1, RtuNo = 0, i = 0; + + if (g_kbd511s_ioRtuChanelRun == false) + return; + + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + + if (m_ptrCurrentChan->ReadNetEvent(1, &netEvent) > 0) + { + switch (netEvent.EventType) + { + case CN_FesNetEvent_Connect: + LOGDEBUG("ChanNo:%d connect!", m_ptrCFesChan->m_Param.ChanNo); + m_AppData.state = CN_kbd511s_ioRtuAppState_idle; + break; + case CN_FesNetEvent_Disconnect: + LOGDEBUG("ChanNo:%d disconnect!", m_ptrCFesChan->m_Param.ChanNo); + m_AppData.state = CN_kbd511s_ioRtuAppState_init; + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } + break; + default: + break; + } + } + + for (i = 0; i < KBD511S_MAX_DI_NUM; i++) + { + ret = GetData(i); + if (ret >= 0) + Cmd01RespProcess(i+1, ret); + } + + uint64 msec = getMonotonicMsec(); + for (i = 0; i < KBD511S_MAX_DO_NUM; i++) + { + ret = GetData(i+ KBD511S_MAX_DI_NUM); + if (ret >= 0) + Cmd01RespProcess(i + 21, ret); + + if (m_AppData.dostr[i].lastTime > 0) + { + //脉冲模式,到时间自动分开DO + if (msec >= m_AppData.dostr[i].lastTime) + { + m_AppData.dostr[i].lastTime = 0; + setDoValue(i, 0);//分 + } + } + } + + //保持运行灯闪烁 + m_AppData.runLed = !m_AppData.runLed; + setRunLed(m_AppData.runLed); + + //通道参数自定义1用来控制线程延时 + if(m_ptrCFesChan->m_Param.ResParam1 < 500) + SleepmSec(500);//500ms一次 + else + SleepmSec(m_ptrCFesChan->m_Param.ResParam1); + + + if (m_AppData.setComFlag > 0) + { + //设置通道串口模式 + setChanComMod(); + m_AppData.setComFlag++; + if (m_AppData.setComFlag >= 3) + m_AppData.setComFlag = 0; + } +} + +/* + @brief 执行quit函数前的处理 + */ +void Ckbd511s_ioRtuDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); +} + + +/** +* @brief Ckbd511s_ioRtuDataProcThread::SendProcess +* kbd511s_io 发送处理 +* @return 返回获取的数据 +*/ +int Ckbd511s_ioRtuDataProcThread::GetData(int DiNo) +{ + int retLen = -1; + + if (m_ptrCurrentChan == NULL) + return -1; + + if (m_ptrCurrentChan->m_LinkStatus == CN_FesChanDisconnect) + return retLen; + + if ((retLen = InsertCmdProcess()) >= 0) + return retLen; + + if ((retLen = PollingCmdProcess(DiNo)) >= 0) + return retLen; + + return retLen; + +} + +/** +* @brief Ckbd511s_ioRtuDataProcThread::InsertCmdProcess +* 收到SCADA的控制命令,插入命令处理。组织kbd511s_io命令帧,并返回操作消息 +* @return 实际发送数据长度 +*/ +int Ckbd511s_ioRtuDataProcThread::InsertCmdProcess() +{ + byte data[256]; + int dataSize, retSize; + + if (g_kbd511s_ioRtuIsMainFes == false)//备机不作任何操作 + return -1; + + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + int RtuNo = m_ptrCFesChan->m_RtuNo[i]; + m_ptrCInsertFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo); //得使用局部变量 + + if (m_ptrCInsertFesRtu == NULL) + return -1; + + dataSize = sizeof(data); + retSize = -1; + if (m_ptrCInsertFesRtu->GetRxDoCmdNum() > 0) + { + retSize = DoCmdProcess(data, dataSize); //遥控 + } + } + m_ptrCInsertFesRtu = NULL; + return retSize; +} + + +/** +* @brief Ckbd511s_ioRtuDataProcThread::DoCmdProcess +* 接收SCADA传来的DO控制命令,组织kbd511s_io命令帧,并返回操作消息。 +* @param Data 发送数据区 +* @param dataSize 发送数据区长度 +* @return 实际发送数据长度 +*/ +int Ckbd511s_ioRtuDataProcThread::DoCmdProcess(byte *Data, int /*dataSize*/) +{ + SFesRxDoCmd cmd; + SFesTxDoCmd retCmd; + SFesDo *pDo; + int writex = -1; + int ret = -1; + int doNo = 0; + + memset(&retCmd, 0, sizeof(retCmd)); + memset(&cmd, 0, sizeof(cmd)); + + if (m_ptrCInsertFesRtu->ReadRxDoCmd(1, &cmd) == 1) + { + //get the cmd ok + //2019-02-21 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + + //2020-02-18 thxiao 遥控增加五防闭锁检查 + if (m_ptrCInsertFesRtu->CheckWuFangDoStatus(cmd.PointID) == 0)//闭锁 + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d 闭锁").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d 闭锁", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_kbd511s_ioRtuNoCmd; + m_AppData.state = CN_kbd511s_ioRtuAppState_idle; + return 0; + } + + //需对应分闸合闸 + if ((pDo = GetFesDoByPointNo(m_ptrCInsertFesRtu, cmd.PointID)) != NULL) + { + if (cmd.CtrlActType == CN_ControlExecute) + { + doNo = pDo->Param1 - 1; + if ((doNo < 0) || (doNo > KBD511S_MAX_DO_NUM)) + { + LOGDEBUG("DO遥控执行失败 doNo越限 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d doNO=%d", cmd.CtrlActType, cmd.iValue, cmd.RtuName, cmd.PointID, doNo); + CmdControlRespProcess(Data, 0, 0); + return 0; + } + if (cmd.iValue == 1) + { + LOGDEBUG("//合 DO%d ", pDo->Param1); + ret = setDoValue(doNo,1);//合 + } + else + { + LOGDEBUG("//分 DO%d %x", pDo->Param1); + ret = setDoValue(doNo, 0);//分 + } + + memcpy(&m_AppData.doCmd, &cmd, sizeof(cmd)); + m_AppData.lastCotrolcmd = CN_kbd511s_ioRtuDoCmd; + m_AppData.state = CN_kbd511s_ioRtuAppState_waitControlResp; + + if(ret != -1) + { + LOGDEBUG("DO遥控执行成功 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.iValue, cmd.RtuName, cmd.PointID); + CmdControlRespProcess(Data, 0, 1); + + //控合后自动控分,模拟脉冲模式 + if ((pDo->Param2 > 0) && (cmd.iValue == 1)) + { + m_AppData.dostr[doNo].lastTime = getMonotonicMsec() + pDo->Param2; + } + } + else + { + LOGDEBUG("DO遥控执行失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.iValue, cmd.RtuName, cmd.PointID); + CmdControlRespProcess(Data, 0, 0); + } + } + else if (cmd.CtrlActType == CN_ControlSelect) //遥控选择作为日后扩展用 + { + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlSuccess; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("DO遥控选择成功 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.iValue, cmd.RtuName, cmd.PointID); + //ptrFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_kbd511s_ioRtuDoCmd; + m_AppData.state = CN_kbd511s_ioRtuAppState_waitControlResp; + } + else + { + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.iValue, cmd.RtuName, cmd.PointID); + //ptrFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_kbd511s_ioRtuNoCmd; + m_AppData.state = CN_kbd511s_ioRtuAppState_idle; + } + } + else + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 找不到遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("DO遥控失败 !RtuNo:%d 找不到遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + //ptrFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_kbd511s_ioRtuNoCmd; + m_AppData.state = CN_kbd511s_ioRtuAppState_idle; + } + } + return writex; +} + +/** +* @brief Ckbd511s_ioRtuDataProcThread::PollingCmdProcess +* 循环发送读取数据命令,组织kbd511s_io命令帧。 +* @param Data 发送数据区 +* @param dataSize 发送数据区长度 +* @return 实际发送数据长度 +*/ +int Ckbd511s_ioRtuDataProcThread::PollingCmdProcess(int DiNo) +{ + //byte Data[256]; + SModbusCmd cmd; + int iStatus = -1; + + int RtuNo = m_ptrCFesChan->m_RtuNo[m_ptrCFesChan->m_CurrentRtuIndex]; + if ((m_ptrCFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) + { + NextRtuIndex(m_ptrCFesChan); + return -1; + } + if(DiNo < KBD511S_MAX_DI_NUM) + iStatus = getDiValue(DiNo); + else + iStatus = getDoValue(DiNo- KBD511S_MAX_DI_NUM); + + m_AppData.state = CN_kbd511s_ioRtuAppState_idle; + return iStatus; +} + + +void Ckbd511s_ioRtuDataProcThread::Cmd01RespProcess(const int DiNo,const int Data) +{ + byte bitValue; + int StartPointNo, ValueCount, ChgCount, SoeCount; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[50]; + uint64 mSec; + //LOGDEBUG("Cmd01RespProcess "); + + StartPointNo = 0; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + + bitValue = Data & 0x01; + pDi = GetFesDiByParam2(m_ptrCFesRtu, StartPointNo, DiNo, 0); + if (pDi != NULL) + { + //DO的逻辑:0-合,1-分 + if (pDi->Revers) + bitValue ^= 1; + + if ((bitValue != pDi->Value) && (g_kbd511s_ioRtuIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) //一次最多上送50个遥信点变化给后台 + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + //写入各转发RTU的FWSOE缓存区。 + SoeCount++; + if (SoeCount >= 50) + { + //m_ptrCFesRtu->WriteSoeEventBuf(SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + //更新点值 + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) //一次最多上送50个遥信点给后台 + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } +} + +/** +* @brief Ckbd511s_ioRtuDataProcThread::CmdControlRespProcess +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +* @param okFlag 命令成功标志 1:成功 0:失败 +* @return 是控制命令返回:TRUE 否则为:FALSE +*/ +bool Ckbd511s_ioRtuDataProcThread::CmdControlRespProcess(byte * /*Data*/, int /*DataSize*/, int okFlag) +{ + SFesTxDoCmd retDoCmd; + SFesTxAoCmd retAoCmd; + SFesTxMoCmd retMoCmd; + SFesTxDefCmd retDefCmd; + + if (m_AppData.state != CN_kbd511s_ioRtuAppState_waitControlResp) + return false; + switch (m_AppData.lastCotrolcmd) + { + case CN_kbd511s_ioRtuDoCmd: + //memset(&retDoCmd,0,sizeof(retDoCmd)); + if (okFlag) + { + retDoCmd.retStatus = CN_ControlSuccess; + sprintf(retDoCmd.strParam, I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.doCmd.PointID); + LOGINFO("遥控成功!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.doCmd.PointID); + } + else + { + retDoCmd.retStatus = CN_ControlFailed; + sprintf(retDoCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.doCmd.PointID); + LOGINFO("遥控失败!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.doCmd.PointID); + } + strcpy(retDoCmd.TableName, m_AppData.doCmd.TableName); + strcpy(retDoCmd.ColumnName, m_AppData.doCmd.ColumnName); + strcpy(retDoCmd.TagName, m_AppData.doCmd.TagName); + strcpy(retDoCmd.RtuName, m_AppData.doCmd.RtuName); + retDoCmd.CtrlActType = m_AppData.doCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retDoCmd.CtrlDir = m_AppData.doCmd.CtrlDir; + retDoCmd.RtuNo = m_AppData.doCmd.RtuNo; + retDoCmd.PointID = m_AppData.doCmd.PointID; + retDoCmd.FwSubSystem = m_AppData.doCmd.FwSubSystem; + retDoCmd.FwRtuNo = m_AppData.doCmd.FwRtuNo; + retDoCmd.FwPointNo = m_AppData.doCmd.FwPointNo; + retDoCmd.SubSystem = m_AppData.doCmd.SubSystem; + + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retDoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retDoCmd); + + m_AppData.lastCotrolcmd = CN_kbd511s_ioRtuNoCmd; + m_AppData.state = CN_kbd511s_ioRtuAppState_idle; + return true; + break; + + default: + break; + } + return false; +} + +void Ckbd511s_ioRtuDataProcThread::setChanComMod() +{ + int i,comNo=-1; + CFesChanPtr pChan = NULL; + for (i = 0; i < m_ptrCFesBase->m_vectCFesChanPtr.size(); i++) + { + pChan = m_ptrCFesBase->m_vectCFesChanPtr.at(i); + if (pChan == NULL) + continue; + + //跳过非串口的通道 + if (pChan->m_Param.CommType != 5) + continue; + + //取出串口号 + comNo = pChan->m_Param.NetRoute[0].PortNo/10 - 1; + + //串口号越限 + if ((comNo < 0) || (comNo >= KBD511S_MAX_COM_NUM)) + { + LOGERROR("ChanNo=%d 串口%s 串口号[%d]越限 !", pChan->m_Param.ChanNo, pChan->m_Param.NetRoute[0].NetDesc, comNo); + continue; + } + + //备用通道号3为串口模式,0-232,1-485 + if (pChan->m_Param.NetRoute[0].PortNo % 10 == 0) + { + setComMod(comNo, 0);//设为232 + LOGINFO("ChanNo=%d 串口%s 串口号[%d]设置为232!", pChan->m_Param.ChanNo, pChan->m_Param.NetRoute[0].NetDesc, comNo); + } + else if(pChan->m_Param.NetRoute[0].PortNo % 10 == 1) + { + setComMod(comNo, 1);//设为485 + LOGINFO("ChanNo=%d 串口%s 串口号[%d]设置为485!", pChan->m_Param.ChanNo, pChan->m_Param.NetRoute[0].NetDesc, comNo); + } + } +} + + diff --git a/product/src/fes/protocol/kbd511s_io/kbd511s_ioRtuDataProcThread.h b/product/src/fes/protocol/kbd511s_io/kbd511s_ioRtuDataProcThread.h new file mode 100644 index 00000000..4becf868 --- /dev/null +++ b/product/src/fes/protocol/kbd511s_io/kbd511s_ioRtuDataProcThread.h @@ -0,0 +1,93 @@ +#pragma once + +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include +#include "kbd511s_gpio.h" +#ifndef WIN32 +#include +#include +//#include +#endif // WIN32 + +using namespace iot_public; + +#define CN_kbd511s_ioRTU_MAX_CMD_LEN 256 + +//Skbd511s_ioRtuAppData状态 +const int CN_kbd511s_ioRtuAppState_init = 0; +const int CN_kbd511s_ioRtuAppState_waitInit = 1; +const int CN_kbd511s_ioRtuAppState_idle = 2; +const int CN_kbd511s_ioRtuAppState_waitResp = 3; +const int CN_kbd511s_ioRtuAppState_waitControlResp = 4; + +//Skbd511s_ioRtuAppData最近发送的控制命令类型 +const int CN_kbd511s_ioRtuNoCmd = 0; +const int CN_kbd511s_ioRtuDoCmd = 1; //遥控 +const int CN_kbd511s_ioRtuAoCmd = 2; //遥调 +const int CN_kbd511s_ioRtuMoCmd = 3; +const int CN_kbd511s_ioRtuDefCmd = 4; + +const int CN_kbd511s_ioRtuMaxRTUs = 254; + +typedef struct { + uint64 lastTime; +}Skbd511s_DoStr; + +//kbd511s_io 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct { + int index; + int state; + + int lastCotrolcmd; + byte lastCmdData[CN_kbd511s_ioRTU_MAX_CMD_LEN]; + int lastCmdDataLen; + SModbusCmd lastCmd; + SFesRxDoCmd doCmd; + + bool runLed; + Skbd511s_DoStr dostr[KBD511S_MAX_DO_NUM]; + + int setComFlag; + +}Skbd511s_ioRtuAppData; + +class Ckbd511s_ioRtuDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + Ckbd511s_ioRtuDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan); + virtual ~Ckbd511s_ioRtuDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + CFesBase* m_ptrCFesBase; + + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区 + CFesRtuPtr m_ptrCInsertFesRtu; //当前插入命令使用RTU数据区 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + Skbd511s_ioRtuAppData m_AppData; //内部应用数据结构 + +private: + + int GetData(int blockNum); + int InsertCmdProcess(); + int DoCmdProcess(byte *Data, int dataSize); + + int PollingCmdProcess(int blockNum); + void Cmd01RespProcess(const int DiNo, const int Data); + bool CmdControlRespProcess(byte *Data, int DataSize, int okFlag); + void setChanComMod(); +}; + +typedef boost::shared_ptr Ckbd511s_ioRtuDataProcThreadPtr; diff --git a/product/src/fes/protocol/kbd61850m/KBD61850mDataProcThread.cpp b/product/src/fes/protocol/kbd61850m/KBD61850mDataProcThread.cpp index f118c3d8..0b955968 100644 --- a/product/src/fes/protocol/kbd61850m/KBD61850mDataProcThread.cpp +++ b/product/src/fes/protocol/kbd61850m/KBD61850mDataProcThread.cpp @@ -125,9 +125,6 @@ 2、DataDefFile.h LUBO_FILE_NAME_LEN 由64->84,中电PMC68M文件名超过64 2022-08-18 thxiao AppDzRetProc()不需要判断设备类型,所有类型都通过该函数返回定值操作结果 -2023-07-12 thxiao - ReportiMeter6_QVVR_SoeProcess() QVVR事件增加三相电压 - */ //#include @@ -4930,11 +4927,6 @@ bool CKBD61850mDataProcThread::ReportiMeter6_QVVR_SoeProcess(const struct SInfor byte bitValue, status; char tempStr[100]; - /* - 2023-07-12 thxiao - iMeterSoe[15] 每相5个单元,对应5种不同的事件,幅值每收到一相会同时把5个单元的VTrsTm、MaxVTrs都填写一样, - 所以,取三相电压只有取iMeterSoe[0]、iMeterSoe[5]、iMeterSoe[10]的VTrsTm、MaxVTrs即可。 - */ for (i = 0; i < pinforRpt->number; i++) { pDataInfo = pinforRpt->pDataInfo + i; @@ -5164,9 +5156,7 @@ bool CKBD61850mDataProcThread::ReportiMeter6_QVVR_SoeProcess(const struct SInfor LOGDEBUG("@@@@@@@@StrSOE RtuNo:%d PointNo:%d %s %s", m_RTUPtr->iRtuNo, pDi->PointNo, strSoe.TagName, strEvent.FaultValueDecs); strEvent.FaultValTag = 121;//扰动特征值 - //sprintf(strEvent.FaultValueDecs, "%.2f", iMeterSoe[k * 5 + i].MaxVTrs); - //2023-07-12 thxiao 增加三相电压值 - sprintf(strEvent.FaultValueDecs, "A相:%.2f B相:%.2f C相:%.2f", iMeterSoe[0].MaxVTrs, iMeterSoe[5].MaxVTrs,iMeterSoe[10].MaxVTrs); + sprintf(strEvent.FaultValueDecs, "%.2f", iMeterSoe[k * 5 + i].MaxVTrs); strSoe.FaultStrVal.push_back(strEvent); LOGDEBUG("@@@@@@@@StrSOE RtuNo:%d PointNo:%d %s %s", m_RTUPtr->iRtuNo, pDi->PointNo, strSoe.TagName, strEvent.FaultValueDecs); diff --git a/product/src/fes/protocol/modbus_rtu/ModbusRtu.cpp b/product/src/fes/protocol/modbus_rtu/ModbusRtu.cpp index 27714f4a..971829d6 100644 --- a/product/src/fes/protocol/modbus_rtu/ModbusRtu.cpp +++ b/product/src/fes/protocol/modbus_rtu/ModbusRtu.cpp @@ -4,6 +4,7 @@ @author Rong @histroy 2020-04-26 thxiao 增加按新CSerialPortThread类调用接口 +2023-03-06 thxiao ModbusRtu.cpp\InitProtocolPointMapping() ACC,MI不需要判断Param1 */ @@ -51,6 +52,8 @@ int EX_ChanTimer(int ChanNo) int EX_ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + g_ModbusRtuChanelRun =false;//使所有的线程退出。 ModbusRtu.InformComThreadExit(); return iotSuccess; @@ -98,7 +101,7 @@ int CModbusRtu::SetBaseAddr(void *address) int CModbusRtu::SetProperty(int IsMainFes) { - g_ModbusRtuIsMainFes = IsMainFes; + g_ModbusRtuIsMainFes = (IsMainFes != 0); LOGDEBUG("CModbusRtu::SetProperty g_ModbusRtuIsMainFes:%d",IsMainFes); return iotSuccess; } @@ -318,6 +321,8 @@ int CModbusRtu::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) */ int CModbusRtu::ChanTimer(int MainChanNo) { + boost::ignore_unused_variable_warning(MainChanNo); + return iotSuccess; } @@ -470,7 +475,9 @@ void CModbusRtu::ClearTcpServerRxTxThreadByChanNo(int ChanNo) */ int CModbusRtu::GetModbusRtuProtocolInfo(char* ProtocolName) { - int i, j, ProtocolId; + boost::ignore_unused_variable_warning(ProtocolName); + + int j, ProtocolId; int OK = 1; ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"modbus_rtu"); @@ -680,7 +687,7 @@ void CModbusRtu::InitProcess() return; } - RtuCount = m_ptrCFesBase->m_vectCFesRtuPtr.size(); + RtuCount = static_cast(m_ptrCFesBase->m_vectCFesRtuPtr.size()); for (i = 0; i < RtuCount; i++) { if (m_ptrCFesBase->m_vectCFesRtuPtr[i]->m_Param.Used) @@ -755,7 +762,7 @@ bool CModbusRtu::InitProtocolPointMapping(CFesRtuPtr RtuPtr) LOGERROR("RdbAiTable::close error"); return iotFailed; } - count = VecAiParam.size(); + count = static_cast(VecAiParam.size()); if (count > 0) { //RtuPtr->m_MaxAiIndex = VecAiParam[count-1].Param1+1; @@ -832,7 +839,7 @@ bool CModbusRtu::InitProtocolPointMapping(CFesRtuPtr RtuPtr) LOGERROR("RdbDiTable::close error"); return iotFailed; } - count = VecDiParam.size(); + count = static_cast(VecDiParam.size()); if (count > 0) { RtuPtr->m_MaxDiIndex = count; @@ -906,7 +913,7 @@ bool CModbusRtu::InitProtocolPointMapping(CFesRtuPtr RtuPtr) return iotFailed; } - count = VecAccParam.size(); + count = static_cast(VecAccParam.size()); if (count > 0) { //RtuPtr->m_MaxAccIndex = VecAccParam[count-1].Param1+1; @@ -925,8 +932,8 @@ bool CModbusRtu::InitProtocolPointMapping(CFesRtuPtr RtuPtr) } for (j = 0; j < count; j++) { - if (VecAccParam[j].Param1 >= 0 && VecAccParam[j].Param1 < RtuPtr->m_MaxAccIndex) - { + //if (VecAccParam[j].Param1 >= 0 && VecAccParam[j].Param1 < RtuPtr->m_MaxAccIndex)//2023-03-06 thxiao + //{ pAccIndex = RtuPtr->m_pAccIndex + j; pAccIndex->PointNo = VecAccParam[j].PointNo; pAccIndex->PIndex = j; @@ -939,11 +946,11 @@ bool CModbusRtu::InitProtocolPointMapping(CFesRtuPtr RtuPtr) pAccIndex->Param4 = pAcc->Param4; pAccIndex->Used = 1; } - } - else - { - LOGDEBUG("RtuNo:%d Acc PointIndex %d exceed limit %d.", RtuPtr->m_Param.RtuNo, VecAccParam[j].Param1, RtuPtr->m_MaxAccIndex); - } + //} + //else + //{ + // LOGDEBUG("RtuNo:%d Acc PointIndex %d exceed limit %d.", RtuPtr->m_Param.RtuNo, VecAccParam[j].Param1, RtuPtr->m_MaxAccIndex); + //} } } else @@ -987,7 +994,7 @@ bool CModbusRtu::InitProtocolPointMapping(CFesRtuPtr RtuPtr) LOGERROR("RdbMiTable::close error"); return iotFailed; } - count = VecMiParam.size(); + count = static_cast(VecMiParam.size()); if (count > 0) { //RtuPtr->m_MaxMiIndex = VecMiParam[count-1].Param1+1; @@ -1006,8 +1013,8 @@ bool CModbusRtu::InitProtocolPointMapping(CFesRtuPtr RtuPtr) } for (j = 0; j < count; j++) { - if (VecMiParam[j].Param1 >= 0 && VecMiParam[j].Param1 < RtuPtr->m_MaxMiIndex) - { + //if (VecMiParam[j].Param1 >= 0 && VecMiParam[j].Param1 < RtuPtr->m_MaxMiIndex) + //{ pMiIndex = RtuPtr->m_pMiIndex + j; pMiIndex->PointNo = VecMiParam[j].PointNo; pMiIndex->PIndex = j; @@ -1020,11 +1027,11 @@ bool CModbusRtu::InitProtocolPointMapping(CFesRtuPtr RtuPtr) pMiIndex->Param4 = pMi->Param4; pMiIndex->Used = 1; } - } - else - { - LOGDEBUG("RtuNo:%d Mi PointIndex %d exceed limit %d.", RtuPtr->m_Param.RtuNo, VecMiParam[j].Param1, RtuPtr->m_MaxMiIndex); - } + //} + //else + //{ + // LOGDEBUG("RtuNo:%d Mi PointIndex %d exceed limit %d.", RtuPtr->m_Param.RtuNo, VecMiParam[j].Param1, RtuPtr->m_MaxMiIndex); + //} } } else diff --git a/product/src/fes/protocol/modbus_rtu/ModbusRtuDataProcThread.cpp b/product/src/fes/protocol/modbus_rtu/ModbusRtuDataProcThread.cpp index 88086f24..dde3a939 100644 --- a/product/src/fes/protocol/modbus_rtu/ModbusRtuDataProcThread.cpp +++ b/product/src/fes/protocol/modbus_rtu/ModbusRtuDataProcThread.cpp @@ -28,15 +28,12 @@ 4、RTU参数1=1,适合通信管理机PCS3000老模版,否则按新的模版实现(增加功能码的配置) 5、 RecvComData() 出现过没有正常发送数据的情况,此处加上只要通信正常,就把离线状态清除。 2021-09-26 thxiao 每个RTU都需要InitProtocolBlockDataIndexMapping()初始化 -2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 -2022-10-18 thxiao ACC很多地方取数字节偏移错误 -2022-11-23 thxiao +2022-11-21 thxiao 1、InitProtocolBlockDataIndexMapping()数据块关联数据索引赋值错误 2、AoCmdProcess()当前RTU指针应该取m_ptrCInsertFesRtu代替m_ptrCFesRtu 3、Cmd01RespProcess(),Cmd03RespProcess(),CmdTypeHybridProcess() PointIndex增加判断,防止数组过界. -2023-03-25 thxiao - 1、AO处理时,当下发的值为浮点值,除系数容易产生精度问题,所以改为乘系数;同时增加了多种设置数据类型 - + 4、电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + 5、ACC很多地方取数字节偏移错误 */ #include "ModbusRtuDataProcThread.h" @@ -606,10 +603,7 @@ int CModbusRtuDataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) failed = 0; if (pAo->Coeff != 0) { - //fValue = (tempValue - pAo->Base) / pAo->Coeff; - //2023-03-25 thxiao 当下发的值为浮点值,除系数容易产生精度问题,所以改为乘系数。 - fValue = (tempValue + pAo->Base) * pAo->Coeff; - + fValue = (tempValue - pAo->Base) / pAo->Coeff; if (pAo->MaxRange > pAo->MinRange) { if ((fValue < pAo->MinRange) || (fValue > pAo->MaxRange)) @@ -662,81 +656,11 @@ int CModbusRtuDataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) Data[writex++] = 0x00; Data[writex++] = 0x02; Data[writex++] = 0x04; - switch (pAo->Param4) - { - case AI_Word_HL: - case AI_UWord_HL: - writex = 4; - Data[writex++] = 0x00; - Data[writex++] = 0x01; - Data[writex++] = 0x02; - setValue = (short)fValue; - Data[writex++] = (byte)(setValue >> 8); - Data[writex++] = (byte)setValue; - break; - case AI_Word_LH: - case AI_UWord_LH: - writex = 4; - Data[writex++] = 0x00; - Data[writex++] = 0x01; - Data[writex++] = 0x02; - setValue = (short)fValue; - Data[writex++] = (byte)setValue; - Data[writex++] = (byte)(setValue >> 8); - break; - case AI_DWord_LL: - case AI_UDWord_LL: - iValue = (int)fValue; - Data[writex++] = (byte)iValue; - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)(iValue >> 16); - Data[writex++] = (byte)(iValue >> 24); - break; - case AI_Float_LL: - memcpy(&iValue, &fValue, sizeof(fValue)); - Data[writex++] = (byte)iValue; - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)(iValue >> 16); - Data[writex++] = (byte)(iValue >> 24); - break; - case AI_DWord_HH: - case AI_UDWord_HH: - iValue = (int)fValue; - Data[writex++] = (byte)(iValue >> 24); - Data[writex++] = (byte)(iValue >> 16); - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)iValue; - break; - case AI_Float_HH: - memcpy(&iValue, &fValue, sizeof(fValue)); - Data[writex++] = (byte)(iValue >> 24); - Data[writex++] = (byte)(iValue >> 16); - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)iValue; - break; - case AI_DWord_LH: - case AI_UDWord_LH: - iValue = (int)fValue; - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)iValue; - Data[writex++] = (byte)(iValue >> 24); - Data[writex++] = (byte)(iValue >> 16); - break; - case AI_Float_LH: - memcpy(&iValue, &fValue, sizeof(fValue)); - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)iValue; - Data[writex++] = (byte)(iValue >> 24); - Data[writex++] = (byte)(iValue >> 16); - break; - default: - iValue = (int)fValue; - Data[writex++] = (byte)(iValue >> 24); - Data[writex++] = (byte)(iValue >> 16); - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)iValue; - break; - } + memcpy(&iValue, &fValue, sizeof(fValue)); + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; } else { @@ -744,23 +668,8 @@ int CModbusRtuDataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) Data[writex++] = pAo->Param2; //command 0x06 Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address Data[writex++] = pAo->Param3 & 0x00ff; - switch (pAo->Param4) - { - case AI_Word_HL: - case AI_UWord_HL: - Data[writex++] = (setValue >> 8) & 0x00ff; - Data[writex++] = setValue & 0x00ff; - break; - case AI_Word_LH: - case AI_UWord_LH: - Data[writex++] = setValue & 0x00ff; - Data[writex++] = (setValue >> 8) & 0x00ff; - break; - default: - Data[writex++] = (setValue >> 8) & 0x00ff; - Data[writex++] = setValue & 0x00ff; - break; - } + Data[writex++] = (setValue >> 8) & 0x00ff; + Data[writex++] = setValue & 0x00ff; } crcCount = CrcSum(&Data[0], writex); Data[writex++] = crcCount & 0x00ff; @@ -822,6 +731,8 @@ int CModbusRtuDataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) */ int CModbusRtuDataProcThread::DefCmdProcess(byte *Data, int dataSize) { + boost::ignore_unused_variable_warning(dataSize); + byte data[300]; SFesRxDefCmd rxDefCmd; SFesTxDefCmd txDefCmd; @@ -1779,7 +1690,7 @@ void CModbusRtuDataProcThread::Cmd03RespProcess_PCS3000(byte *Data, int /*DataSi break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; @@ -1854,7 +1765,7 @@ void CModbusRtuDataProcThread::Cmd03RespProcess_PCS3000(byte *Data, int /*DataSi uValue32 |= (uint32)Data[5 + i * 4] << 8; uValue32 |= (uint32)Data[6 + i * 4]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + accValue = static_cast(fValue*1000);//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 break; case ACC_Float_LH://(四字节浮点 低字前 高字节前) uValue32 = (uint32)Data[5 + i * 4] << 24; @@ -1862,7 +1773,7 @@ void CModbusRtuDataProcThread::Cmd03RespProcess_PCS3000(byte *Data, int /*DataSi uValue32 |= (uint32)Data[3 + i * 4] << 8; uValue32 |= (uint32)Data[4 + i * 4]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + accValue = static_cast(fValue*1000);//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 break; case ACC_Float_LL://(四字节浮点 低字前 低字节前) uValue32 = (uint32)Data[6 + i * 4] << 24; @@ -1870,11 +1781,11 @@ void CModbusRtuDataProcThread::Cmd03RespProcess_PCS3000(byte *Data, int /*DataSi uValue32 |= (uint32)Data[4 + i * 4] << 8; uValue32 |= (uint32)Data[3 + i * 4]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + accValue = static_cast(fValue*1000);//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; @@ -2079,6 +1990,8 @@ int CModbusRtuDataProcThread::Cmd03RespProcess_BitGroup_PCS3000(SFesDi *pDi, int */ void CModbusRtuDataProcThread::Cmd01RespProcess(byte *Data, int DataSize) { + boost::ignore_unused_variable_warning(DataSize); + int FunCode; byte bitValue, byteValue; int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, SoeCount, PointIndex1, PointIndex2; @@ -2108,7 +2021,7 @@ void CModbusRtuDataProcThread::Cmd01RespProcess(byte *Data, int DataSize) continue; PointIndex1 = (pDi->Param3 - m_AppData.lastCmd.StartAddr) / 8; - //2022-11-23 增加判断,防止数组过界。 + //2022-11-21 增加判断,防止数组过界。 if ((PointIndex1 < 0) || (PointIndex1 > MODBUSRTU_K_MAX_POINT_INDEX*1.5)) { continue; @@ -2121,7 +2034,7 @@ void CModbusRtuDataProcThread::Cmd01RespProcess(byte *Data, int DataSize) if (pDi->Revers) bitValue ^= 1; //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 - StartPointNo = pDi->Param1 + 1; + //StartPointNo = pDi->Param1 + 1; if ((bitValue != pDi->Value) && (g_ModbusRtuIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 { memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); @@ -2228,6 +2141,8 @@ int CModbusRtuDataProcThread::Cmd03RespProcess_BitGroup(SFesDi *pDi, int diValue */ void CModbusRtuDataProcThread::Cmd03RespProcess(byte *Data, int DataSize) { + boost::ignore_unused_variable_warning(DataSize); + int FunCode, diValue, bitValue; int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, SoeCount, PointIndex; SFesDi *pDi; @@ -2274,7 +2189,7 @@ void CModbusRtuDataProcThread::Cmd03RespProcess(byte *Data, int DataSize) continue; PointIndex = pDi->Param3 - m_AppData.lastCmd.StartAddr; - //2022-11-23 增加判断,防止数组过界。 + //2022-11-21 增加判断,防止数组过界。 if ((PointIndex < 0) || (PointIndex > MODBUSRTU_K_MAX_POINT_INDEX)) { continue; @@ -2437,7 +2352,7 @@ void CModbusRtuDataProcThread::Cmd03RespProcess(byte *Data, int DataSize) continue; PointIndex = pAi->Param3 - m_AppData.lastCmd.StartAddr; - //2022-11-23 增加判断,防止数组过界。 + //2022-11-21 增加判断,防止数组过界。 if ((PointIndex < 0) || (PointIndex > MODBUSRTU_K_MAX_POINT_INDEX)) { continue; @@ -2503,7 +2418,7 @@ void CModbusRtuDataProcThread::Cmd03RespProcess(byte *Data, int DataSize) continue; PointIndex = (pAi->Param3 - m_AppData.lastCmd.StartAddr) / 2; - //2022-11-23 增加判断,防止数组过界。 + //2022-11-21 增加判断,防止数组过界。 if ((PointIndex < 0) || (PointIndex > MODBUSRTU_K_MAX_POINT_INDEX)) { continue; @@ -2641,7 +2556,7 @@ void CModbusRtuDataProcThread::Cmd03RespProcess(byte *Data, int DataSize) continue; PointIndex = pAcc->Param3 - m_AppData.lastCmd.StartAddr; - //2022-11-23 增加判断,防止数组过界。 + //2022-11-21 增加判断,防止数组过界。 if ((PointIndex < 0) || (PointIndex > MODBUSRTU_K_MAX_POINT_INDEX)) { continue; @@ -2670,7 +2585,7 @@ void CModbusRtuDataProcThread::Cmd03RespProcess(byte *Data, int DataSize) break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; @@ -2695,7 +2610,7 @@ void CModbusRtuDataProcThread::Cmd03RespProcess(byte *Data, int DataSize) continue; PointIndex = (pAcc->Param3 - m_AppData.lastCmd.StartAddr) / 2; - //2022-11-23 增加判断,防止数组过界。 + //2022-11-21 增加判断,防止数组过界。 if ((PointIndex < 0) || (PointIndex > MODBUSRTU_K_MAX_POINT_INDEX)) { continue; @@ -2751,7 +2666,7 @@ void CModbusRtuDataProcThread::Cmd03RespProcess(byte *Data, int DataSize) uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; uValue32 |= (uint32)Data[6 + PointIndex * 4]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + accValue = static_cast(fValue*1000);//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 break; case ACC_Float_LH://(四字节浮点 低字前 高字节前) uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; @@ -2759,7 +2674,7 @@ void CModbusRtuDataProcThread::Cmd03RespProcess(byte *Data, int DataSize) uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; uValue32 |= (uint32)Data[4 + PointIndex * 4]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + accValue = static_cast(fValue*1000);//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 break; case ACC_Float_LL://(四字节浮点 低字前 低字节前) uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; @@ -2767,11 +2682,11 @@ void CModbusRtuDataProcThread::Cmd03RespProcess(byte *Data, int DataSize) uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; uValue32 |= (uint32)Data[3 + PointIndex * 4]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + accValue = static_cast(fValue*1000);//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; @@ -2943,6 +2858,8 @@ void CModbusRtuDataProcThread::Cmd03RespProcess(byte *Data, int DataSize) void CModbusRtuDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) { + boost::ignore_unused_variable_warning(DataSize); + int FunCode; int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, PointIndex; uint64 mSec; @@ -2982,7 +2899,7 @@ void CModbusRtuDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) continue; PointIndex = pAi->Param3 - m_AppData.lastCmd.StartAddr; - //2022-11-23 增加判断,防止数组过界。 + //2022-11-21 增加判断,防止数组过界。 if ((PointIndex < 0) || (PointIndex > MODBUSRTU_K_MAX_POINT_INDEX)) { continue; @@ -3128,7 +3045,7 @@ void CModbusRtuDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) continue; PointIndex = pAcc->Param3 - m_AppData.lastCmd.StartAddr; - //2022-11-23 增加判断,防止数组过界。 + //2022-11-21 增加判断,防止数组过界。 if ((PointIndex < 0) || (PointIndex > MODBUSRTU_K_MAX_POINT_INDEX)) { continue; @@ -3204,7 +3121,7 @@ void CModbusRtuDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; uValue32 |= (uint32)Data[6 + PointIndex * 2]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000; + accValue = static_cast(fValue*1000); break; case ACC_Float_LH: //float帧(四字节浮点 低字前 高字节前) uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; @@ -3212,7 +3129,7 @@ void CModbusRtuDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; uValue32 |= (uint32)Data[4 + PointIndex * 2]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000; + accValue = static_cast(fValue*1000); break; case ACC_Float_LL: //float帧(四字节浮点 低字前 低字节前) uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; @@ -3220,7 +3137,7 @@ void CModbusRtuDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; uValue32 |= (uint32)Data[3 + PointIndex * 2]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000; + accValue = static_cast(fValue*1000); break; default: sValue16 = (int16)Data[3 + PointIndex * 2] << 8; @@ -3229,7 +3146,7 @@ void CModbusRtuDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; @@ -3299,6 +3216,9 @@ void CModbusRtuDataProcThread::Cmd10RespProcess(byte *Data, int DataSize) */ bool CModbusRtuDataProcThread::CmdControlRespProcess(byte *Data, int DataSize, int okFlag) { + boost::ignore_unused_variable_warning(Data); + boost::ignore_unused_variable_warning(DataSize); + SFesTxDoCmd retDoCmd; SFesTxAoCmd retAoCmd; SFesTxMoCmd retMoCmd; @@ -3431,7 +3351,7 @@ bool CModbusRtuDataProcThread::CmdControlRespProcess(byte *Data, int DataSize, i retDefCmd.DevId = m_AppData.defCmd.DevId; retDefCmd.CmdNum = m_AppData.defCmd.CmdNum; retDefCmd.VecCmd = m_AppData.defCmd.VecCmd; - m_ptrCInsertFesRtu->WriteTxDefCmdBuf(1, &retDefCmd);//2023-03-25 + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &retDefCmd); m_AppData.lastCotrolcmd = CN_ModbusRtuNoCmd; m_AppData.state = CN_ModbusRtuAppState_idle; return true; @@ -3451,8 +3371,6 @@ bool CModbusRtuDataProcThread::CmdControlRespProcess(byte *Data, int DataSize, i */ void CModbusRtuDataProcThread::SendDataToPort(byte *Data, int Size) { - int len; - if (m_ptrCurrentChan == NULL) return; @@ -3617,6 +3535,8 @@ void CModbusRtuDataProcThread::SetSendCmdFlag() void CModbusRtuDataProcThread::CmdTypeHybridProcess_PCS3000(byte *Data, int DataSize) { + boost::ignore_unused_variable_warning(DataSize); + int FunCode; int i, StartAddr, StartPointNo, ValueCount, ChgCount, PointCount; uint64 mSec; @@ -3878,7 +3798,7 @@ void CModbusRtuDataProcThread::CmdTypeHybridProcess_PCS3000(byte *Data, int Data uValue32 |= (uint32)Data[5 + i * 2] << 8; uValue32 |= (uint32)Data[6 + i * 2]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000; + accValue = static_cast(fValue*1000); i++; break; case ACC_Float_LH: //float帧(四字节浮点 低字前 高字节前) @@ -3887,7 +3807,7 @@ void CModbusRtuDataProcThread::CmdTypeHybridProcess_PCS3000(byte *Data, int Data uValue32 |= (uint32)Data[3 + i * 2] << 8; uValue32 |= (uint32)Data[4 + i * 2]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000; + accValue = static_cast(fValue*1000); break; case ACC_Float_LL: //float帧(四字节浮点 低字前 低字节前) uValue32 = (uint32)Data[6 + i * 2] << 24; @@ -3895,7 +3815,7 @@ void CModbusRtuDataProcThread::CmdTypeHybridProcess_PCS3000(byte *Data, int Data uValue32 |= (uint32)Data[4 + i * 2] << 8; uValue32 |= (uint32)Data[3 + i * 2]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000; + accValue = static_cast(fValue*1000); i++; break; default: @@ -3905,7 +3825,7 @@ void CModbusRtuDataProcThread::CmdTypeHybridProcess_PCS3000(byte *Data, int Data break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; @@ -4122,6 +4042,7 @@ void CModbusRtuDataProcThread::SetSerialThread(CSerialPortThreadPtr ptrSerialThr m_ClearSerialFlag = 0; } + /** * @brief CModbusRtuDataProcThread::InitProtocolBlockDataIndexMapping * 数据块关联数据索引表初始化 @@ -4197,7 +4118,7 @@ void CModbusRtuDataProcThread::InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuP if ((pAiIndex->Param2 == funCode) && (startAddr <= pAiIndex->Param3) && (pAiIndex->Param3 < (startAddr + dataLen))) { - //2022-11-23 数据块关联数据索引赋值错误 + //2022-11-21 数据块关联数据索引赋值错误 //if ((m_AiBlockDataIndexInfo.at(blockId).headIndex == -1)) //首次得到起始地址时 if ((m_AiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 m_AiBlockDataIndexInfo.at(blockId).headIndex = pAiIndex->PIndex; @@ -4223,9 +4144,9 @@ void CModbusRtuDataProcThread::InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuP if ((pDiIndex->Param2 == funCode) && (startAddr <= pDiIndex->Param3) && (pDiIndex->Param3 < (startAddr + dataLen))) { //if ((m_DiBlockDataIndexInfo.at(blockId).headIndex == -1)) //首次得到起始地址时 - //2022-11-23 数据块关联数据索引赋值错误 + //2022-11-21 数据块关联数据索引赋值错误 if ((m_DiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 - m_DiBlockDataIndexInfo.at(blockId).headIndex = pDiIndex->PIndex; + m_DiBlockDataIndexInfo.at(blockId).headIndex = pDiIndex->PIndex; m_DiBlockDataIndexInfo.at(blockId).tailIndex = pDiIndex->PIndex; } @@ -4247,7 +4168,7 @@ void CModbusRtuDataProcThread::InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuP if ((pAccIndex->Param2 == funCode) && (startAddr <= pAccIndex->Param3) && (pAccIndex->Param3 < (startAddr + dataLen))) { - //2022-11-23 数据块关联数据索引赋值错误 + //2022-11-21 数据块关联数据索引赋值错误 if ((m_AccBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 m_AccBlockDataIndexInfo.at(blockId).headIndex = pAccIndex->PIndex; @@ -4271,7 +4192,7 @@ void CModbusRtuDataProcThread::InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuP if ((pMiIndex->Param2 == funCode) && (startAddr <= pMiIndex->Param3) && (pMiIndex->Param3 < (startAddr + dataLen))) { - //2022-11-23 数据块关联数据索引赋值错误 + //2022-11-21 数据块关联数据索引赋值错误 if ((m_MiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 m_MiBlockDataIndexInfo.at(blockId).headIndex = pMiIndex->PIndex; @@ -4310,4 +4231,3 @@ void CModbusRtuDataProcThread::InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuP iter++; } } - diff --git a/product/src/fes/protocol/modbus_rtuV2/ModbusRtuV2.cpp b/product/src/fes/protocol/modbus_rtuV2/ModbusRtuV2.cpp new file mode 100644 index 00000000..0d99e7c3 --- /dev/null +++ b/product/src/fes/protocol/modbus_rtuV2/ModbusRtuV2.cpp @@ -0,0 +1,671 @@ +/* +@file ModbusRtuV2.cpp +@brief +@author Rong +@histroy +2020-04-26 thxiao 增加按新CComSerialPort类调用接口 +2023-03-06 thxiao ModbusRtuV2.cpp\InitProtocolPointMapping() ACC,MI不需要判断Param1 + +*/ + +#include "ModbusRtuV2.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "dbms/rdb_api/CRdbAccessEx.h" +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/rdb_api/RdbDefine.h" + +using namespace iot_public; + +CModbusRtuV2 ModbusRtuV2; +bool g_ModbusRtuV2IsMainFes=false; +bool g_ModbusRtuV2ChanelRun=true; + +int EX_SetBaseAddr(void *address) +{ + ModbusRtuV2.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + ModbusRtuV2.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + ModbusRtuV2.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + ModbusRtuV2.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + ModbusRtuV2.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + boost::ignore_unused_variable_warning(flag); + + g_ModbusRtuV2ChanelRun =false;//使所有的线程退出。 + ModbusRtuV2.InformComThreadExit(); + return iotSuccess; +} +CModbusRtuV2::CModbusRtuV2() +{ + m_ptrCFesBase = nullptr; + m_initRtuFlag = 0; +} + +CModbusRtuV2::~CModbusRtuV2() +{ + + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); + + LOGDEBUG("CModbusRtuV2::~CModbusRtuV2() 退出"); +} + + +int CModbusRtuV2::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + } + return iotSuccess; +} + +int CModbusRtuV2::SetProperty(int IsMainFes) +{ + g_ModbusRtuV2IsMainFes = (IsMainFes != 0); + LOGDEBUG("CModbusRtuV2::SetProperty g_ModbusRtuV2IsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief CModbusRtuV2::OpenChan + * 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CModbusRtuV2::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if (m_initRtuFlag == 0) + { + InitProcess(); + m_initRtuFlag = 1; + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + CModbusRtuV2DataProcThreadPtr ptrCDataProc; + ptrCDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan); + if (ptrCDataProc == NULL) + { + LOGERROR("CModbusRtuV2 EX_OpenChan() ChanNo:%d create CModbusRtuV2DataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + if ((OpenFlag == CN_FesChanThread_Flag) || (OpenFlag == CN_FesChanAndDataThread_Flag)) + { + switch (ptrFesChan->m_Param.CommType) + { + case CN_FesSerialPort: + case CN_FesTcpClient: + if (ptrFesChan->m_ComThreadRun == CN_FesStopFlag) + { + SetComByChanNo(MainChanNo, ChanNo); + } + break; + default: + return iotFailed; + } + } + + return iotSuccess; + +} + +/** + * @brief CModbusRtuV2::CloseChan + * 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CModbusRtuV2::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("CModbusRtuV2::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + if ((CloseFlag == CN_FesChanThread_Flag) || (CloseFlag == CN_FesChanAndDataThread_Flag)) + { + if (ptrFesChan->m_ComThreadRun == CN_FesRunFlag) + { + ClearComByChanNo(MainChanNo, ChanNo); + } + } + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + + return iotSuccess; +} + +/** +* @brief CModbusRtuV2::ChanTimer +* 通道定时器,主通道会定时调用 +* @param MainChanNo 主通道号 +* @return +*/ +int CModbusRtuV2::ChanTimer(int MainChanNo) +{ + boost::ignore_unused_variable_warning(MainChanNo); + + return iotSuccess; +} + +/* + 根据通道号,清除数据线程 +*/ +void CModbusRtuV2::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + CModbusRtuV2DataProcThreadPtr ptrPort; + + if ((tempNum = (int)m_CDataProcQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) + { + ptrPort = *it; + if (ptrPort->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CDataProcQueue.erase(it);//会调用CModbusRtuV2DataProcThread::~CModbusRtuV2DataProcThread()退出线程 + LOGDEBUG("CModbusRtuV2::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + + +/** + * @brief CMODBUS::InformTcpThreadExit + * 设置线程退出标志,通知线程退出 + * @return + */ +void CModbusRtuV2::InformComThreadExit() +{ + LOGDEBUG("CModbusRtuV2::InformTcpThreadExit() "); + +} + +void CModbusRtuV2::InitProcess() +{ + int i, RtuCount, ProtocolId; + CFesChanPtr chanPtr; + + ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"modbus_rtuV2"); + if (ProtocolId == -1) + { + LOGERROR("InitProcess() can't found ProtocolId."); + return; + } + + RtuCount = static_cast(m_ptrCFesBase->m_vectCFesRtuPtr.size()); + for (i = 0; i < RtuCount; i++) + { + if (m_ptrCFesBase->m_vectCFesRtuPtr[i]->m_Param.Used) + { + //found the Chan; + if ((chanPtr = GetChanDataByChanNo(m_ptrCFesBase->m_vectCFesRtuPtr[i]->m_Param.ChanNo)) != NULL) + { + if (chanPtr->m_Param.Used && (chanPtr->m_Param.ProtocolId == ProtocolId)) + InitProtocolPointMapping(m_ptrCFesBase->m_vectCFesRtuPtr[i]); //初始化转发表结构参数 + } + } + } +} + +bool CModbusRtuV2::InitProtocolPointMapping(CFesRtuPtr RtuPtr) +{ + iot_dbms::CRdbAccessEx RdbAiTable; + iot_dbms::CRdbAccessEx RdbAoTable; + iot_dbms::CRdbAccessEx RdbDiTable; + iot_dbms::CRdbAccessEx RdbDoTable; + iot_dbms::CRdbAccessEx RdbAccTable; + iot_dbms::CRdbAccessEx RdbMiTable; + iot_dbms::CRdbAccessEx RdbMoTable; + int count, ret; + SFesAiIndex *pAiIndex; + SFesDiIndex *pDiIndex; + SFesAccIndex *pAccIndex; + SFesMiIndex *pMiIndex; + SFesAi *pAi; + SFesDi *pDi; + SFesAcc *pAcc; + SFesMi *pMi; + + int j; + + //条件判断 + iot_dbms::CONDINFO con; + con.relationop = ATTRCOND_EQU; + con.conditionval = RtuPtr->m_Param.RtuNo; + strcpy(con.name, "rtu_no"); + + //READ AI TABLE + std::vector VecAiParam; + std::vector vecAiColumn; + std::vector vecAiOrder; + + vecAiColumn.push_back("rtu_no"); + vecAiColumn.push_back("dot_no"); + vecAiColumn.push_back("res_para_int1"); + vecAiColumn.push_back("res_para_int2"); + vecAiColumn.push_back("res_para_int3"); + vecAiColumn.push_back("res_para_int4"); + + vecAiOrder.push_back("res_para_int2"); + vecAiOrder.push_back("res_para_int3"); + + ret = RdbAiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_AI_TBL); + if (ret == false) + { + LOGERROR("RdbAiTable::Open error"); + return iotFailed; + } + ret = RdbAiTable.selectOneColumnOneOrder(con, VecAiParam, vecAiColumn, vecAiOrder);//默认顺序 ljj + if (ret == false) + { + LOGERROR("RdbAiTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbAiTable.close(); + if (ret == false) + { + LOGERROR("RdbAiTable::close error"); + return iotFailed; + } + count = static_cast(VecAiParam.size()); + if (count > 0) + { + //RtuPtr->m_MaxAiIndex = VecAiParam[count-1].Param1+1; + RtuPtr->m_MaxAiIndex = count; //ljj + if (RtuPtr->m_MaxAiIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pAiIndex = (SFesAiIndex*)malloc(RtuPtr->m_MaxAiIndex * sizeof(SFesAiIndex)); + if (RtuPtr->m_pAiIndex != NULL) + { + memset(RtuPtr->m_pAiIndex, 0xff, RtuPtr->m_MaxAiIndex * sizeof(SFesAiIndex)); + for (j = 0; j < RtuPtr->m_MaxAiIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pAiIndex = RtuPtr->m_pAiIndex + j; + pAiIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + pAiIndex = RtuPtr->m_pAiIndex + j; + pAiIndex->PointNo = VecAiParam[j].PointNo; + pAiIndex->PIndex = j; + if ((pAiIndex->PointNo >= 0) && (pAiIndex->PointNo < RtuPtr->m_MaxAiPoints)) + { + pAi = RtuPtr->m_pAi + pAiIndex->PointNo; + //pAiIndex->DevId = pAi->DevId; + pAiIndex->Param2 = pAi->Param2; + pAiIndex->Param3 = pAi->Param3; + pAiIndex->Param4 = pAi->Param4; + pAiIndex->Used = 1; + } + } + } + else + { + RtuPtr->m_MaxAiIndex = 0; + LOGDEBUG("RtuNo:%d AI protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + + //READ DI TABLE + //ljj di新增按位排序 + std::vector VecDiParam; + std::vector vecDiColumn; + std::vector vecDiOrder; + + vecDiColumn.push_back("rtu_no"); + vecDiColumn.push_back("dot_no"); + vecDiColumn.push_back("res_para_int1"); + vecDiColumn.push_back("res_para_int2"); + vecDiColumn.push_back("res_para_int3"); + vecDiColumn.push_back("res_para_int4"); + + vecDiOrder.push_back("res_para_int2"); + vecDiOrder.push_back("res_para_int3"); + vecDiOrder.push_back("res_para_int4"); + + ret = RdbDiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_DI_TBL); + if (ret == false) + { + LOGERROR("RdbDiTable::Open error"); + return iotFailed; + } + ret = RdbDiTable.selectOneColumnOneOrder(con, VecDiParam, vecDiColumn, vecDiOrder);//默认顺序 + if (ret == false) + { + LOGERROR("RdbDiTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbDiTable.close(); + if (ret == false) + { + LOGERROR("RdbDiTable::close error"); + return iotFailed; + } + count = static_cast(VecDiParam.size()); + if (count > 0) + { + RtuPtr->m_MaxDiIndex = count; + if (RtuPtr->m_MaxDiIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pDiIndex = (SFesDiIndex*)malloc(RtuPtr->m_MaxDiIndex * sizeof(SFesDiIndex)); + if (RtuPtr->m_pDiIndex != NULL) + { + memset(RtuPtr->m_pDiIndex, 0xff, RtuPtr->m_MaxDiIndex * sizeof(SFesDiIndex)); + for (j = 0; j < RtuPtr->m_MaxDiIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pDiIndex = RtuPtr->m_pDiIndex + j; + pDiIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + pDiIndex = RtuPtr->m_pDiIndex + j; + pDiIndex->PointNo = VecDiParam[j].PointNo; + pDiIndex->PIndex = j; + if ((pDiIndex->PointNo >= 0) && (pDiIndex->PointNo < RtuPtr->m_MaxDiPoints)) + { + pDi = RtuPtr->m_pDi + pDiIndex->PointNo; + //pDiIndex->DevId = pDi->DevId; + pDiIndex->Param2 = pDi->Param2; + pDiIndex->Param3 = pDi->Param3; + pDiIndex->Param4 = pDi->Param4; + pDiIndex->Used = 1; + } + } + } + else + { + RtuPtr->m_MaxDiIndex = 0; + LOGDEBUG("RtuNo:%d Di protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + //READ ACC TABLE + std::vector VecAccParam; + std::vector vecAccColumn; + std::vector vecAccOrder; + + vecAccColumn.push_back("rtu_no"); + vecAccColumn.push_back("dot_no"); + vecAccColumn.push_back("res_para_int1"); + vecAccColumn.push_back("res_para_int2"); + vecAccColumn.push_back("res_para_int3"); + vecAccColumn.push_back("res_para_int4"); + + vecAccOrder.push_back("res_para_int2"); + vecAccOrder.push_back("res_para_int3"); + + ret = RdbAccTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_ACC_TBL); + if (ret == false) + { + LOGERROR("RdbAccTable::Open error"); + return iotFailed; + } + ret = RdbAccTable.selectOneColumnOneOrder(con, VecAccParam, vecAccColumn, vecAccOrder);//默认顺序 + if (ret == false) + { + LOGERROR("RdbAccTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbAccTable.close(); + if (ret == false) + { + LOGERROR("RdbAccTable::close error"); + return iotFailed; + } + + count = static_cast(VecAccParam.size()); + if (count > 0) + { + //RtuPtr->m_MaxAccIndex = VecAccParam[count-1].Param1+1; + RtuPtr->m_MaxAccIndex = count; + if (RtuPtr->m_MaxAccIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pAccIndex = (SFesAccIndex*)malloc(RtuPtr->m_MaxAccIndex * sizeof(SFesAccIndex)); + if (RtuPtr->m_pAccIndex != NULL) + { + memset(RtuPtr->m_pAccIndex, 0xff, RtuPtr->m_MaxAccIndex * sizeof(SFesAccIndex)); + for (j = 0; j < RtuPtr->m_MaxAccIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pAccIndex = RtuPtr->m_pAccIndex + j; + pAccIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + //if (VecAccParam[j].Param1 >= 0 && VecAccParam[j].Param1 < RtuPtr->m_MaxAccIndex) //2023-03-06 thxiao + //{ + pAccIndex = RtuPtr->m_pAccIndex + j; + pAccIndex->PointNo = VecAccParam[j].PointNo; + pAccIndex->PIndex = j; + if ((pAccIndex->PointNo >= 0) && (pAccIndex->PointNo < RtuPtr->m_MaxAccPoints)) + { + pAcc = RtuPtr->m_pAcc + pAccIndex->PointNo; + //pAccIndex->DevId = pAcc->DevId; + pAccIndex->Param2 = pAcc->Param2; + pAccIndex->Param3 = pAcc->Param3; + pAccIndex->Param4 = pAcc->Param4; + pAccIndex->Used = 1; + } + //} + //else + //{ + // LOGDEBUG("RtuNo:%d Acc PointIndex %d exceed limit %d.", RtuPtr->m_Param.RtuNo, VecAccParam[j].Param1, RtuPtr->m_MaxAccIndex); + //} + } + } + else + { + RtuPtr->m_MaxAccIndex = 0; + LOGDEBUG("RtuNo:%d Acc protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + //READ MI TABLE + std::vector VecMiParam; + std::vector vecMiColumn; + std::vector vecMiOrder; + + vecMiColumn.push_back("rtu_no"); + vecMiColumn.push_back("dot_no"); + vecMiColumn.push_back("res_para_int1"); + vecMiColumn.push_back("res_para_int2"); + vecMiColumn.push_back("res_para_int3"); + vecMiColumn.push_back("res_para_int4"); + + vecMiOrder.push_back("res_para_int2"); + vecMiOrder.push_back("res_para_int3"); + + ret = RdbMiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_MI_TBL); + if (ret == false) + { + LOGERROR("RdbMiTable::Open error"); + return iotFailed; + } + ret = RdbMiTable.selectOneColumnOneOrder(con, VecMiParam, vecMiColumn, vecMiOrder);//默认顺序 + if (ret == false) + { + LOGERROR("RdbMiTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbMiTable.close(); + if (ret == false) + { + LOGERROR("RdbMiTable::close error"); + return iotFailed; + } + count = static_cast(VecMiParam.size()); + if (count > 0) + { + //RtuPtr->m_MaxMiIndex = VecMiParam[count-1].Param1+1; + RtuPtr->m_MaxMiIndex = count; + if (RtuPtr->m_MaxMiIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pMiIndex = (SFesMiIndex*)malloc(RtuPtr->m_MaxMiIndex * sizeof(SFesMiIndex)); + if (RtuPtr->m_pMiIndex != NULL) + { + memset(RtuPtr->m_pMiIndex, 0xff, RtuPtr->m_MaxMiIndex * sizeof(SFesMiIndex)); + for (j = 0; j < RtuPtr->m_MaxMiIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pMiIndex = RtuPtr->m_pMiIndex + j; + pMiIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + //if (VecMiParam[j].Param1 >= 0 && VecMiParam[j].Param1 < RtuPtr->m_MaxMiIndex) + //{ + pMiIndex = RtuPtr->m_pMiIndex + j; + pMiIndex->PointNo = VecMiParam[j].PointNo; + pMiIndex->PIndex = j; + if ((pMiIndex->PointNo >= 0) && (pMiIndex->PointNo < RtuPtr->m_MaxMiPoints)) + { + pMi = RtuPtr->m_pMi + pMiIndex->PointNo; + //pMiIndex->DevId = pMi->DevId; + pMiIndex->Param2 = pMi->Param2; + pMiIndex->Param3 = pMi->Param3; + pMiIndex->Param4 = pMi->Param4; + pMiIndex->Used = 1; + } + //} + //else + //{ + // LOGDEBUG("RtuNo:%d Mi PointIndex %d exceed limit %d.", RtuPtr->m_Param.RtuNo, VecMiParam[j].Param1, RtuPtr->m_MaxMiIndex); + //} + } + } + else + { + RtuPtr->m_MaxMiIndex = 0; + LOGDEBUG("RtuNo:%d Mi protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + return iotSuccess; +} + + +void CModbusRtuV2::SetComByChanNo(int MainChanNo, int ChanNo) +{ + CModbusRtuV2DataProcThreadPtr ptrDataProc; + int found = 0; + + if (m_CDataProcQueue.size() <= 0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin(); it != m_CDataProcQueue.end(); it++) + { + ptrDataProc = *it; + if (ptrDataProc->m_ptrCFesChan->m_Param.ChanNo == MainChanNo) + { + found = 1; + ptrDataProc->SetComByChanNo(ChanNo); + break; + } + } + if (found) + { + LOGDEBUG("SetComByChanNo() MainChanNo=%d ChanNo=%d OK", MainChanNo, ChanNo); + } + else + { + LOGDEBUG("SetComByChanNo() MainChanNo=%d ChanNo=%d failed", MainChanNo, ChanNo); + } +} + + +void CModbusRtuV2::ClearComByChanNo(int MainChanNo, int ChanNo) +{ + CModbusRtuV2DataProcThreadPtr ptrDataProc; + int found = 0; + + if (m_CDataProcQueue.size() <= 0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin(); it != m_CDataProcQueue.end(); it++) + { + ptrDataProc = *it; + if (ptrDataProc->m_ptrCFesChan->m_Param.ChanNo == MainChanNo) + { + found = 1; + ptrDataProc->ClearComByChanNo(ChanNo); + break; + } + } + if (found) + { + LOGDEBUG("ClearComByChanNo() MainChanNo=%d ChanNo=%d OK", MainChanNo, ChanNo); + } + else + { + LOGDEBUG("ClearTcpClientdByChanNo() MainChanNo=%d ChanNo=%d failed", MainChanNo, ChanNo); + } +} + diff --git a/product/src/fes/protocol/modbus_rtuV2/ModbusRtuV2.h b/product/src/fes/protocol/modbus_rtuV2/ModbusRtuV2.h new file mode 100644 index 00000000..f7c591be --- /dev/null +++ b/product/src/fes/protocol/modbus_rtuV2/ModbusRtuV2.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "ComSerialPort.h" +#include "ComTcpClient.h" +#include "ModbusRtuV2DataProcThread.h" + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API CModbusRtuV2 : public CProtocolBase +{ +public: + CModbusRtuV2(); + ~CModbusRtuV2(); + + vector m_CDataProcQueue; + + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + + void InformComThreadExit(); + +private: + //bool m_TcpServerListenThreadFlag; + int m_initRtuFlag; + + void ClearSerialPortThreadByChanNo(int ChanNo); + void ClearDataProcThreadByChanNo(int ChanNo); + bool InitProtocolPointMapping(CFesRtuPtr RtuPtr); + void InitProcess(); + void SetComByChanNo(int MainChanNo, int ChanNo); + void ClearComByChanNo(int MainChanNo, int ChanNo); + +}; diff --git a/product/src/fes/protocol/modbus_rtuV2/ModbusRtuV2DataProcThread.cpp b/product/src/fes/protocol/modbus_rtuV2/ModbusRtuV2DataProcThread.cpp new file mode 100644 index 00000000..c58f7cb5 --- /dev/null +++ b/product/src/fes/protocol/modbus_rtuV2/ModbusRtuV2DataProcThread.cpp @@ -0,0 +1,4241 @@ +/* +@file ModbusRtuV2DataProcThread.cpp +@brief ModbusRtuV2 数据处理线程类 + 1、每个通道只开一个数据处理线程,支持串口、TCP Client两种通信方式。 + 2、启用块使能 + 3、配置中不再强调块序号要唯一,块序号在读取配置时自动分配唯一块序号 + +@author thxiao +@histroy +2022-10-19 thxiao + 1、电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + 2、ACC很多地方取数字节偏移错误 +2022-11-01 thxiao 代码走查完善 +2022-11-22 thxiao + 1、InitProtocolBlockDataIndexMapping()数据块关联数据索引赋值错误 + 2、AoCmdProcess()当前RTU指针应该取m_ptrCInsertFesRtu代替m_ptrCFesRtu + 3、Cmd01RespProcess(),Cmd03RespProcess(),CmdTypeHybridProcess() PointIndex增加判断,防止数组过界. +2022-12-20 thxiao Cmd03RespProcess() Mi取点值应该为PointIndex + +*/ + +#include "ModbusRtuV2DataProcThread.h" +#include "ComSerialPort.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" +#include + +using namespace iot_public; + +extern bool g_ModbusRtuV2IsMainFes; +extern bool g_ModbusRtuV2ChanelRun; + +const int g_ModbusRtuV2ThreadTime = 10; + +CModbusRtuV2DataProcThread::CModbusRtuV2DataProcThread(CFesBase *ptrCFesBase, CFesChanPtr ptrCFesChan) : + CTimerThreadBase("ModbusRtuV2DataProcThread", g_ModbusRtuV2ThreadTime, 0, true) +{ + CFesRtuPtr pRtu; + + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + + int RtuId = m_ptrCFesChan->m_CurrentRtuIndex; + int RtuNo = m_ptrCFesChan->m_RtuNo[RtuId]; + m_ptrCFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo); + m_ptrCInsertFesRtu = NULL; + + m_AppData.setCmdCount = 0; + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if(m_ptrCFesChan == NULL) + { + return ; + } + + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + //2020-08-18 thxiao 一个通道挂多个设备的规约,初始化时需要把标志置上在线状态,保证第一次每个设备都可以发送指令。 + m_ptrCFesBase->ClearRtuOfflineFlag(m_ptrCFesChan); + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + InitProtocolBlockDataIndexMapping(pRtu);//2021-09-26 thxiao 每个RTU都需要初始化 + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } + + /*************************** COM PROCESS *****************************************************/ + m_timerCountReset = 2000 / g_ModbusRtuV2ThreadTime; //2S COUNTER + m_timerCount = 0; + + m_ptrComClient = NULL; + m_ptrComSerial = NULL; + switch (ptrCFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + m_ptrComClient = boost::make_shared(ptrCFesChan); + if (m_ptrComClient == NULL) + { + LOGERROR("create CComTcpClientPtr error!", ptrCFesChan->m_Param.ChanNo); + LOGDEBUG("CModbusRtuV2DataProcThread::CModbusRtuV2DataProcThread() ChanNo=%d 创建失败", ptrCFesChan->m_Param.ChanNo); + } + else + LOGDEBUG("CModbusRtuV2DataProcThread::CModbusRtuV2DataProcThread() ChanNo=%d 创建成功", ptrCFesChan->m_Param.ChanNo); + break; + case CN_FesSerialPort: + m_ptrComSerial = boost::make_shared(ptrCFesChan); + if (m_ptrComSerial == NULL) + { + LOGERROR("create m_ptrComSerialPtr error!", ptrCFesChan->m_Param.ChanNo); + LOGDEBUG("CModbusRtuV2DataProcThread::CModbusRtuV2DataProcThread() ChanNo=%d 创建失败", ptrCFesChan->m_Param.ChanNo); + } + else + LOGDEBUG("CModbusRtuV2DataProcThread::CModbusRtuV2DataProcThread() ChanNo=%d 创建成功", ptrCFesChan->m_Param.ChanNo); + break; + default: + LOGDEBUG("CModbusRtuV2DataProcThread::CModbusRtuV2DataProcThread() ChanNo=%d 无效通道类型,创建失败", ptrCFesChan->m_Param.ChanNo); + break; + } + /**************************************************************************************/ + +} + +CModbusRtuV2DataProcThread::~CModbusRtuV2DataProcThread() +{ + CFesRtuPtr pRtu; + int RtuNo; + + quit();//在调用quit()前,系统会调用beforeQuit(); + + switch (m_ptrCFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + if (m_ptrComClient != NULL) + { + m_ptrComClient->TcpClose(m_ptrCurrentChan); + } + break; + case CN_FesSerialPort: + if (m_ptrComSerial != NULL) + { + m_ptrComSerial->CloseChan(m_ptrCurrentChan); + } + break; + default: + break; + } + + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + + } + LOGDEBUG("CModbusDataProcThread::~CModbusDataProcThread() ChanNo=%d EXIT", m_ptrCFesChan->m_Param.ChanNo); + +} + +/** + * @brief CModbusRtuV2DataProcThread::beforeExecute + * + */ +int CModbusRtuV2DataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief CModbusRtuV2DataProcThread::execute + + */ +void CModbusRtuV2DataProcThread::execute() +{ + //读取网络事件 + SFesNetEvent netEvent; + CFesRtuPtr pRtu; + int comStatus; + + int RtuNo = 0; + + if (g_ModbusRtuV2ChanelRun == false) + return; + + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + + + if (m_timerCount++ >= m_timerCountReset) + { + m_timerCount = 0;// sec is ready + switch (m_ptrCFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + comStatus = m_ptrComClient->GetNetStatus(); + switch (comStatus) + { + case CN_FesChanDisconnect: + m_ptrComClient->TcpConnect(m_ptrCurrentChan); + break; + default: + break; + } + break; + case CN_FesSerialPort: + comStatus = m_ptrComSerial->GetComStatus(); + switch (comStatus) + { + case CN_FesChanDisconnect: + m_ptrComSerial->OpenChan(m_ptrCurrentChan); + break; + default: + break; + } + break; + default: + break; + } + } + + + if (m_ptrCurrentChan->ReadNetEvent(1, &netEvent) > 0) + { + switch (m_ptrCurrentChan->m_Param.CommType) + { + case CN_FesTcpClient: + case CN_FesSerialPort: + switch (netEvent.EventType) + { + case CN_FesNetEvent_Connect: + LOGDEBUG("ChanNo:%d connect!", m_ptrCFesChan->m_Param.ChanNo); + m_AppData.state = CN_ModbusRtuV2AppState_idle; + break; + case CN_FesNetEvent_Disconnect: + LOGDEBUG("ChanNo:%d disconnect!", m_ptrCFesChan->m_Param.ChanNo); + m_AppData.state = CN_ModbusRtuV2AppState_init; + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } + break; + default: + break; + } + break; + default: + break; + } + + } + SetSendCmdFlag(); + + if (SendProcess() > 0) + { + RecvComData(); + } + +} + +/* + @brief 执行quit函数前的处理 + */ +void CModbusRtuV2DataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + +} + + +/** +* @brief CModbusRtuV2DataProcThread::SendProcess +* MODBUS 发送处理 +* @return 返回发送数据长度 +*/ +int CModbusRtuV2DataProcThread::SendProcess() +{ + int retLen = 0; + if (m_ptrCurrentChan == NULL) + return iotFailed; + + switch (m_ptrCurrentChan->m_Param.CommType) + { + case CN_FesSerialPort: + //luojunjun 等待打开串口 + if (m_ptrCurrentChan->m_LinkStatus == CN_FesChanDisconnect) + return retLen; + default: + break; + } + + if ((retLen = InsertCmdProcess()) > 0) + return retLen; + + if ((retLen = PollingCmdProcess()) > 0) + return retLen; + + if (m_ptrCurrentChan->m_LinkStatus != CN_FesChanConnect) + { + ErrorControlRespProcess(); //通信断开时有控制命令来需要做异常处理 + } + + return retLen; + +} + +/** +* @brief CModbusRtuV2DataProcThread::InsertCmdProcess +* 收到SCADA的控制命令,插入命令处理。组织MODBUS命令帧,并返回操作消息 +* @return 实际发送数据长度 +*/ +int CModbusRtuV2DataProcThread::InsertCmdProcess() +{ + byte data[256]; + int dataSize, retSize = 0; + + if (g_ModbusRtuV2IsMainFes == false)//备机不作任何操作 + return 0; + + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + int RtuNo = m_ptrCFesChan->m_RtuNo[i]; + m_ptrCInsertFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo); //得使用局部变量 + + if (m_ptrCInsertFesRtu == NULL) + return 0; + + dataSize = sizeof(data); + retSize = 0; + if (m_ptrCInsertFesRtu->GetRxDoCmdNum() > 0) + { + retSize = DoCmdProcess(data, dataSize); //遥控 + } + else + if (m_ptrCInsertFesRtu->GetRxAoCmdNum() > 0) + { + retSize = AoCmdProcess(data, dataSize);// + } + else + if (m_ptrCInsertFesRtu->GetRxMoCmdNum() > 0) + { + //retSize = MoCmdProcess(data, dataSize); + } + else + if (m_ptrCInsertFesRtu->GetRxSettingCmdNum() > 0) + { + //retSize = SettingCmdProcess(data, dataSize); + } + else + if (m_ptrCInsertFesRtu->GetRxDefCmdNum() > 0) + { + retSize = DefCmdProcess(data, dataSize); + } + + if (retSize > 0) + { + //send data to net + SendDataToPort(data, retSize); + return retSize; + } + } + m_ptrCInsertFesRtu = NULL; + return retSize; +} + + +/** +* @brief CModbusRtuV2DataProcThread::DoCmdProcess +* 接收SCADA传来的DO控制命令,组织MODBUS命令帧,并返回操作消息。 +* @param Data 发送数据区 +* @param dataSize 发送数据区长度 +* @return 实际发送数据长度 +*/ +int CModbusRtuV2DataProcThread::DoCmdProcess(byte *Data, int /*dataSize*/) +{ + SFesRxDoCmd cmd; + SFesTxDoCmd retCmd; + SFesDo *pDo; + int writex, crcCount = 0, FunCode = 5; + + writex = 0; + memset(&retCmd, 0, sizeof(retCmd)); + memset(&cmd, 0, sizeof(cmd)); + + + if (m_ptrCInsertFesRtu->ReadRxDoCmd(1, &cmd) == 1) + { + //get the cmd ok + //2019-02-21 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + + //2020-02-18 thxiao 遥控增加五防闭锁检查 + if (m_ptrCInsertFesRtu->CheckWuFangDoStatus(cmd.PointID) == 0)//闭锁 + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d 闭锁").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d 闭锁", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuV2NoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_idle; + return 0; + } + + //需对应分闸合闸 + if ((pDo = GetFesDoByPointNo(m_ptrCInsertFesRtu, cmd.PointID)) != NULL) + { + if (cmd.CtrlActType == CN_ControlExecute) + { + if (m_ptrCFesRtu->m_Param.ResParam1 == 0) + { + //writex = 0; + Data[writex++] = m_ptrCInsertFesRtu->m_Param.RtuAddr;//设备地址 + Data[writex++] = pDo->Param2;//功能码 + if (pDo->Param2 == 0x05) + { + //2020-07-21 thxiao 增加可配置的遥控命令 + if (pDo->Attribute & CN_FesDo_Special)//点属性判断特殊遥控 + { + if (cmd.iValue == 1)//CLOSE + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff;//合值 + Data[writex++] = pDo->Param4 & 0x00ff;//合值 + } + else//OPEN + { + Data[writex++] = (pDo->Param5 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param5 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param6 >> 8) & 0x00ff;//分值 + Data[writex++] = pDo->Param6 & 0x00ff;//分值 + } + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + if (cmd.iValue == 1) + { + Data[writex++] = 0xff;/*05命令其值为,0xff00 表示合闸*/ + Data[writex++] = 0x00; + } + else + { + Data[writex++] = 0x00;/*05命令其值为,0x0000表示分闸*/ + Data[writex++] = 0x00; + } + } + } + else if (pDo->Param2 == 0x06) //暂时与ModbusTcp一致 + { + if (pDo->Attribute & CN_FesDo_Special)//点属性判断特殊遥控 + { + if (cmd.iValue == 1)//CLOSE + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff;//合值 + Data[writex++] = pDo->Param4 & 0x00ff;//合值 + } + else//OPEN + { + Data[writex++] = (pDo->Param5 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param5 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param6 >> 8) & 0x00ff;//分值 + Data[writex++] = pDo->Param6 & 0x00ff;//分值 + } + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + if (cmd.iValue == 1) + { + cmd.iValue <<= pDo->Param4; + Data[writex++] = ((cmd.iValue >> 8) & 0xff);/*06命令按寄存器bit控制PLC(复归式)*/ + Data[writex++] = (cmd.iValue & 0xff); + } + else + { + Data[writex++] = 0x00;/*06命令,值为0,PLC(复归式)不动作*/ + Data[writex++] = 0x00; + } + } + } + else + return 0; + } + else//R80 管理机模式 + { + if (pDo->Attribute & 0x04) //点属性判断特殊遥控 + FunCode = 0x06; + if (cmd.CtrlActType == CN_ControlExecute) + { + //writex = 0; + Data[writex++] = m_ptrCInsertFesRtu->m_Param.RtuAddr;//设备地址 + Data[writex++] = FunCode;//功能码 + if (FunCode == 0x05) + { + if (cmd.iValue == 1) + { + Data[writex++] = (pDo->Param2 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param2 & 0x00ff;//寄存器起始地址L + Data[writex++] = 0xff;/*05命令其值为,0xff00 表示合闸*/ + Data[writex++] = 0x00; + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = 0x00;/*05命令其值为,0x0000表示分闸*/ + Data[writex++] = 0x00; + } + } + else if (FunCode == 0x06) + { + if (cmd.iValue == 1) + { + Data[writex++] = (pDo->Param2 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param2 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->ControlParam >> 8) & 0x00ff; + Data[writex++] = pDo->ControlParam & 0x00ff; + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff; + Data[writex++] = pDo->Param4 & 0x00ff; + } + } + else + return 0; + } + } + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + memcpy(&m_AppData.doCmd, &cmd, sizeof(cmd)); + m_AppData.lastCotrolcmd = CN_ModbusRtuV2DoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_waitControlResp; + LOGDEBUG("DO遥控执行成功 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.iValue, cmd.RtuName, cmd.PointID); + } + else if (cmd.CtrlActType == CN_ControlSelect) //遥控选择作为日后扩展用 + { + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlSuccess; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("DO遥控选择成功 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.iValue, cmd.RtuName, cmd.PointID); + //ptrFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuV2DoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_waitControlResp; + } + else + { + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.iValue, cmd.RtuName, cmd.PointID); + //ptrFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuV2NoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_idle; + } + } + else + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 找不到遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("DO遥控失败 !RtuNo:%d 找不到遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + //ptrFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuV2NoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_idle; + } + } + return writex; +} + + +/** +* @brief CModbusRtuV2DataProcThread::AoCmdProcess +* 接收SCADA传来的AO控制命令,组织MODBUS命令帧,并返回操作消息。 +* @param Data 发送数据区 +* @param dataSize 发送数据区长度 +* @return 实际发送数据长度 +*/ +int CModbusRtuV2DataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) +{ + SFesRxAoCmd cmd; + SFesTxAoCmd retCmd; + short setValue; + SFesAo *pAo = NULL; + int writex; + float fValue, tempValue; + int failed; + int iValue, crcCount; + + writex = 0; + if (m_ptrCInsertFesRtu->ReadRxAoCmd(1, &cmd) == 1) + { + //get the cmd ok + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + if ((pAo = GetFesAoByPointNo(m_ptrCInsertFesRtu, cmd.PointID)) != NULL) + { + if (cmd.CtrlActType == CN_ControlExecute) + { + tempValue = cmd.fValue; + failed = 0; + if (pAo->Coeff != 0) + { + fValue = (tempValue - pAo->Base) / pAo->Coeff; + if (pAo->MaxRange > pAo->MinRange) + { + if ((fValue < pAo->MinRange) || (fValue > pAo->MaxRange)) + { + //2019-08-30 thxiao 增加失败详细描述 + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d 量程越限").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + failed = 1; + } + } + else + { + sprintf(retCmd.strParam, I18N("遥调失败,量程配置错误,最大量程<=最小量程!").str().c_str()); + failed = 1; + } + } + else + { + //2019-08-30 thxiao 增加失败详细描述 + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d 系数为0").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + failed = 1; + } + + if (failed == 1) + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + //sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(),m_ptrCInsertFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG("AO遥调失败,点系数为0或者量程越限!RtuNo:%d 遥调点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + //m_ptrCInsertFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuV2NoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_idle; + } + else + { + //writex = 0; + Data[writex++] = m_ptrCInsertFesRtu->m_Param.RtuAddr;//设备地址 + if (pAo->Param2 == 0x10) + { + Data[writex++] = pAo->Param2; //command 0x10 + Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address + Data[writex++] = pAo->Param3 & 0x00ff; + Data[writex++] = 0x00; + Data[writex++] = 0x02; + Data[writex++] = 0x04; + memcpy(&iValue, &fValue, sizeof(fValue)); + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + } + else + { + setValue = (short)fValue; + Data[writex++] = pAo->Param2; //command 0x06 + Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address + Data[writex++] = pAo->Param3 & 0x00ff; + Data[writex++] = (setValue >> 8) & 0x00ff; + Data[writex++] = setValue & 0x00ff; + } + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + memcpy(&m_AppData.aoCmd, &cmd, sizeof(cmd)); + m_AppData.lastCotrolcmd = CN_ModbusRtuV2AoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_waitControlResp; + LOGDEBUG("AO遥调成功 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.fValue, cmd.RtuName, cmd.PointID); + } + } + else + { + + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + retCmd.CtrlActType = cmd.CtrlActType; + LOGDEBUG("AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.fValue, cmd.RtuName, cmd.PointID); + //m_ptrCInsertFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuV2NoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_idle; + } + } + else + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("AO遥调失败!RtuNo:%d 找不到遥调点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + //m_ptrCInsertFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuV2NoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_idle; + } + } + return writex; +} + +/** +* @brief CModbusRtuV2DataProcThread::DefCmdProcess +* 接收SCADA传来的自定义控制命令,组织MODBUS命令帧,并返回操作消息。 +* @param Data 发送数据区 +* @param dataSize 发送数据区长度 +* @return 实际发送数据长度 +*/ +int CModbusRtuV2DataProcThread::DefCmdProcess(byte *Data, int dataSize) +{ + boost::ignore_unused_variable_warning(dataSize); + + byte data[300]; + SFesRxDefCmd rxDefCmd; + SFesTxDefCmd txDefCmd; + int writex, i, crcCount; + bool errorFlag = false; + + writex = 0; + if (m_ptrCInsertFesRtu->ReadRxDefCmd(1, &rxDefCmd) == 1) + { + m_AppData.CmdNum = (int)rxDefCmd.VecCmd.size(); + m_AppData.defCmd = rxDefCmd; + + if (CMD_TYPE == rxDefCmd.VecCmd[0].name) + { + if (DEV_ID == rxDefCmd.VecCmd[1].name) + m_AppData.deviceId = atoi(rxDefCmd.VecCmd[1].value.c_str()); + else + errorFlag = true; + //=====================================修改定值======================================// + //Modbus只有修改定值 + if (rxDefCmd.VecCmd[0].value == CONST_VALUE_EDIT) + { + m_AppData.dotNo.clear(); + m_AppData.currentValue.clear(); + m_AppData.editValue.clear(); + + m_AppData.modifyDzNum = (m_AppData.CmdNum - 2) / 2; //只减去cmd_type和dev_id,每项定值只有寄存器地址和修改值 + if (m_AppData.modifyDzNum > CN_FesMaxDzNum) + m_AppData.modifyDzNum = CN_FesMaxDzNum; + + if (m_AppData.modifyDzNum == 0) + errorFlag = true; + + for (i = 0; i < m_AppData.modifyDzNum; i++) + { + if (DOT_NO == rxDefCmd.VecCmd[2 + i * 2].name) + m_AppData.dotNo.push_back(atoi(rxDefCmd.VecCmd[2 + i * 2].value.c_str())); + else + errorFlag = true; + if (EDIT_VALUE == rxDefCmd.VecCmd[3 + i * 2].name) + m_AppData.editValue.push_back(atoi(rxDefCmd.VecCmd[3 + i * 2].value.c_str())); + else + errorFlag = true; + } + } + } + } + + if (errorFlag == true) + { + //memset(&txDefCmd, 0, sizeof(txDefCmd));//lww todo 声明结构进行初始化 + strcpy(txDefCmd.TableName, rxDefCmd.TableName); + strcpy(txDefCmd.ColumnName, rxDefCmd.ColumnName); + strcpy(txDefCmd.TagName, rxDefCmd.TagName); + strcpy(txDefCmd.RtuName, rxDefCmd.RtuName); + txDefCmd.DevId = m_AppData.deviceId; + txDefCmd.CmdNum = rxDefCmd.CmdNum; + txDefCmd.VecCmd = rxDefCmd.VecCmd; + txDefCmd.retStatus = CN_ControlFailed; + sprintf(txDefCmd.strParam, I18N("HMI命令解析失败,不下发控制命令!RtuNo:%d ").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo); + LOGERROR("HMI命令解析失败,不下发控制命令!RtuNo:%d", m_ptrCInsertFesRtu->m_Param.RtuNo); + m_ptrCInsertFesRtu->WriteTxDefCmdBuf(1, &txDefCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuV2NoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_idle; + return 0; + } + else + { + data[writex++] = m_ptrCInsertFesRtu->m_Param.RtuAddr; + data[writex++] = 0x10; + data[writex++] = (m_AppData.dotNo[0] >> 8) & 0x00ff; //modbus中定值代号暂时作为寄存器地址 + data[writex++] = (m_AppData.dotNo[0]) & 0x00ff; + data[writex++] = (m_AppData.modifyDzNum >> 8) & 0x00ff; + data[writex++] = (m_AppData.modifyDzNum) & 0x00ff; + data[writex++] = m_AppData.modifyDzNum * 2; + for (i = 0; i < m_AppData.modifyDzNum; i++) + { + data[writex++] = (m_AppData.editValue[i] >> 8) & 0xff; + data[writex++] = m_AppData.editValue[i] & 0xff; + } + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + } + SendDataToPort(data, writex); + m_AppData.lastCotrolcmd = CN_ModbusRtuV2DefCmd; + m_AppData.state = CN_ModbusRtuV2AppState_waitControlResp; + m_AppData.controlTimeout = getMonotonicMsec();//需要处理控制超时,所以置上时间。 + return writex; +} + + +/** +* @brief CModbusRtuV2DataProcThread::PollingCmdProcess +* 循环发送读取数据命令,组织MODBUS命令帧。 +* @param Data 发送数据区 +* @param dataSize 发送数据区长度 +* @return 实际发送数据长度 +*/ +int CModbusRtuV2DataProcThread::PollingCmdProcess() +{ + byte Data[256]; + SModbusCmd cmd; + int writex, crcCount = 0; + + int RtuNo = m_ptrCFesChan->m_RtuNo[m_ptrCFesChan->m_CurrentRtuIndex]; + if ((m_ptrCFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) + { + NextRtuIndex(m_ptrCFesChan); + return 0; + } + + if (GetPollingCmd(&cmd) == iotFailed) + { + return 0; + } + + memcpy(&m_AppData.lastCmd, &cmd, sizeof(SModbusCmd)); + + writex = 0; + Data[writex++] = m_ptrCFesRtu->m_Param.RtuAddr; + Data[writex++] = cmd.FunCode; + Data[writex++] = (cmd.StartAddr >> 8) & 0x00ff; + Data[writex++] = cmd.StartAddr & 0x00ff; + Data[writex++] = (cmd.DataLen >> 8) & 0x00ff; + Data[writex++] = cmd.DataLen & 0x00ff; + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + //send data to net + SendDataToPort(Data, writex); + m_AppData.state = CN_ModbusRtuV2AppState_idle; + return writex; +} + + +/** +* @brief CModbusRtuV2DataProcThread::GetPollingCmd +* 获取读取数据命令 +* @param pCmd 返回读取数据命令 +* @return 成功:iotSuccess 失败:iotFailed +*/ +int CModbusRtuV2DataProcThread::GetPollingCmd(SModbusCmd *pCmd) +{ + SModbusCmd *Cmd; + bool ComFlag = false; + int count = 0; + + if(m_ptrCFesRtu==NULL) + return iotFailed; + + //2020-05-14 thxiao 如果没有配置块,则轮训下一个设备。 + if (m_ptrCFesRtu->m_Param.ModbusCmdBuf.num == 0) + NextRtuIndex(m_ptrCFesChan); + + while (count < m_ptrCFesRtu->m_Param.ModbusCmdBuf.num) + { + Cmd = m_ptrCFesRtu->m_Param.ModbusCmdBuf.pCmd + m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx; + if (Cmd->CommandSendFlag == true) + { + ::memcpy(pCmd, Cmd, sizeof(SModbusCmd)); + Cmd->CommandSendFlag = false; + ComFlag = true; + //LOGDEBUG("GetPollingCmd chan=%d m_CurrentRtuIndex=%d RtuNo=%d readx=%d \n", m_ptrCFesRtu->m_Param.ChanNo,m_ptrCurrentChan->m_CurrentRtuIndex, m_ptrCFesRtu->m_Param.RtuNo, m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx); + } + m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx++; + if (m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx >= m_ptrCFesRtu->m_Param.ModbusCmdBuf.num) + m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx = 0; + count++; + if (ComFlag) + return iotSuccess; + + } + return iotFailed; +} + +/* + 接收数据 +*/ +int CModbusRtuV2DataProcThread::RecvComData() +{ + int count = 20; + int FunCode, DevAddr, ExpectLen; + byte Data[500]; + int recvLen, Len, i,crc,recvcrc; + + if (m_ptrCurrentChan == NULL) + return iotFailed; + + DevAddr = m_AppData.lastCmdData[0]; + FunCode = m_AppData.lastCmdData[1]; + Len = 0; + recvLen = 0; + count = m_ptrCFesChan->m_Param.RespTimeout / 10; + if (count <= 10) + count = 10;//最小响应超时为100毫秒 + ExpectLen = 0; + for (i = 0; i < count; i++) + { + switch (m_ptrCFesChan->m_Param.CommType) + { + case CN_FesSerialPort: + SleepmSec(10);//以最快速度接收到数据 + if (m_ptrComSerial != NULL) + m_ptrComSerial->RxComData(m_ptrCurrentChan); + break; + case CN_FesTcpClient: + //以最快速度接收到数据 RxData()有延时等待时间,此处可以删除 + if (m_ptrComClient != NULL) + m_ptrComClient->RxData(m_ptrCurrentChan); + break; + default: + break; + } + recvLen = m_ptrCurrentChan->ReadRxBufData(500 - Len, &Data[Len]);//数据缓存在 + if (recvLen <= 0) + continue; + m_ptrCurrentChan->DeleteReadRxBufData(recvLen);//清除已读取的数据 + Len += recvLen; + if (Len > 3) + { + if (Data[1] & 0x80)//ERROR + ExpectLen = 5; + else + { + switch (Data[1]) + { + case FunCode_01H: + case FunCode_02H: + case FunCode_03H: + case FunCode_04H: + ExpectLen = Data[2] + 5; + break; + case FunCode_05H: + case FunCode_06H: + case FunCode_10H: + ExpectLen = 8; + break; + } + } + } + if ((Len >= ExpectLen) && (ExpectLen > 0)) + { + break; + } + } + + + if (Len > 0) + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, Data, Len, CN_SFesSimComFrameTypeRecv); + + if (Len == 0)//接收不完整,重发数据 + { + if (m_ptrCInsertFesRtu != NULL) //InsertCmd + { + m_ptrCInsertFesRtu->SetResendNum(1); + if (m_ptrCInsertFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCInsertFesRtu->ResetResendNum(); //改为RTU下的resendNum + if (m_ptrCInsertFesRtu->ReadRtuSatus() == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCInsertFesRtu, CN_FesRtuComDown); + m_ptrCInsertFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCInsertFesRtu,CN_FesRtuComDown); + } + CmdControlRespProcess(NULL, 0, 0); + m_ptrCInsertFesRtu = NULL; + } + else //PollCmd + { + m_ptrCFesRtu->SetResendNum(1); + if (m_ptrCFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCFesRtu->ResetResendNum(); //改为RTU下的resendNum + if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCFesRtu,CN_FesRtuComDown); + } + NextRtuIndex(m_ptrCFesChan); + } + + return iotFailed; + } + else//长度、地址、功能码 都正确则认为数据正确。 + if ((Len == ExpectLen) && ((DevAddr == Data[0])|| (Data[0]==0xff)) && (FunCode == (Data[1] & 0x7f))) + { + //CRC CHECK + crc = CrcSum(&Data[0], ExpectLen-2); + recvcrc = (int)Data[ExpectLen - 1] << 8; + recvcrc |= (int)Data[ExpectLen - 2] ; + if (crc != recvcrc) + { + //校验错误,处理和接收长度为0 处理方法相同 + m_ptrCurrentChan->SetErrNum(1); + if (m_ptrCInsertFesRtu != NULL) //InsertCmd + { + m_ptrCInsertFesRtu->SetErrNum(1); + m_ptrCInsertFesRtu->SetResendNum(1); + if (m_ptrCInsertFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCInsertFesRtu->ResetResendNum(); //改为RTU下的resendNum + if (m_ptrCInsertFesRtu->ReadRtuSatus() == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCInsertFesRtu, CN_FesRtuComDown); + m_ptrCInsertFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCInsertFesRtu, CN_FesRtuComDown); + } + CmdControlRespProcess(NULL, 0, 0); + m_ptrCInsertFesRtu = NULL; + } + else //PollCmd + { + m_ptrCFesRtu->SetErrNum(1); + m_ptrCFesRtu->SetResendNum(1); + if (m_ptrCFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCFesRtu->ResetResendNum(); //改为RTU下的resendNum + if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCFesRtu, CN_FesRtuComDown); + } + NextRtuIndex(m_ptrCFesChan); + } + return iotFailed; + } + else + { + m_ptrCurrentChan->SetRxNum(1); + if (m_ptrCInsertFesRtu != NULL) + { + m_ptrCInsertFesRtu->ResetResendNum(); + m_ptrCInsertFesRtu->SetRxNum(1); + RecvDataProcess(&Data[0], Len); + if (m_ptrCInsertFesRtu->ReadRtuSatus() == CN_FesRtuComDown) + { + m_ptrCInsertFesRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); + m_ptrCFesBase->WriteRtuSatus(m_ptrCInsertFesRtu, CN_FesRtuNormal); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCInsertFesRtu, CN_FesRtuNormal); + m_ptrCInsertFesRtu = NULL; + } + else + { + m_ptrCFesRtu->ResetResendNum(); + m_ptrCFesRtu->SetRxNum(1); + RecvDataProcess(&Data[0], Len); + if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuComDown) + { + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuNormal); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCFesRtu, CN_FesRtuNormal);//2021-07-09 thxiao 出现过没有正常发送数据的情况,此处加上只要通信正常,就把离线状态清除。 + NextRtuIndex(m_ptrCFesChan); + } + } + return iotSuccess; + } + else + { + m_ptrCurrentChan->SetErrNum(1); + if (m_ptrCInsertFesRtu != NULL) + { + m_ptrCInsertFesRtu->SetErrNum(1); + CmdControlRespProcess(NULL, 0, 0); + m_ptrCInsertFesRtu = NULL; + } + else + { + m_ptrCFesRtu->SetErrNum(1); + NextRtuIndex(m_ptrCFesChan); + } + return iotFailed; + } +} + +/** +* @brief CModbusRtuV2DataProcThread::RecvDataProcess +* @param Data +* @param DataSize +* @return 成功:iotSuccess 失败:iotFailed +*/ +int CModbusRtuV2DataProcThread::RecvDataProcess(byte *Data, int DataSize) +{ + int FunCode; + + FunCode = Data[1]; + if (FunCode & 0x80) + { + CmdControlRespProcess(NULL, 0, 0); + return iotSuccess; + } + + if (CmdControlRespProcess(Data, DataSize, 1) == true) + return iotSuccess; + + switch (FunCode) + { + case 0x01: + case 0x02: + if (m_ptrCFesRtu->m_Param.ResParam1 == 1) + Cmd01RespProcess_PCS3000(Data, DataSize); + else + Cmd01RespProcess(Data, DataSize); + break; + case 0x03: + case 0x04: + if (m_ptrCFesRtu->m_Param.ResParam1 == 1) + { + Cmd03RespProcess_PCS3000(Data, DataSize); + CmdTypeHybridProcess_PCS3000(Data, DataSize); + } + else + { + Cmd03RespProcess(Data, DataSize); + CmdTypeHybridProcess(Data, DataSize); + } + break; + case 0x05: + Cmd05RespProcess(Data, DataSize); + break; + case 0x06: + Cmd06RespProcess(Data, DataSize); + break; + case 0x10: + Cmd10RespProcess(Data, DataSize); + break; + default: + return iotFailed; + break; + } + return iotSuccess; +} + + +/** +* @brief CModbusRtuV2DataProcThread::Cmd01RespProcess +* 命令0x01 0x02的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusRtuV2DataProcThread::Cmd01RespProcess_PCS3000(byte *Data, int /*DataSize*/) +{ + int FunCode; + byte bitValue, byteValue; + int i, j, StartAddr, StartPointNo, ValueCount, ChgCount, SoeCount; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[50]; + uint64 mSec; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + StartPointNo = 0; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + + for (i = 0; i < Data[2]; i++) + { + byteValue = Data[3 + i]; + for (j = 0; j < 8; j++) + { + bitValue = (byteValue >> j) & 0x01; + pDi = GetFesDiByParam23(m_ptrCFesRtu, 0, 0, StartAddr + i * 8 + j);//R80管理机 FunCode 忽略 + if (pDi != NULL) + { + if (pDi->Revers) + bitValue ^= 1; + + if ((bitValue != pDi->Value) && (g_ModbusRtuV2IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) //一次最多上送50个遥信点变化给后台 + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + //写入各转发RTU的FWSOE缓存区。 + SoeCount++; + if (SoeCount >= 50) + { + //m_ptrCFesRtu->WriteSoeEventBuf(SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + //更新点值 + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) //一次最多上送50个遥信点给后台 + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } +} + + +/** +* @brief CModbusRtuV2DataProcThread::Cmd03RespProcess_PCS3000 +* 命令0x03 0x04的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* 兼容PCS3000的老模板 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusRtuV2DataProcThread::Cmd03RespProcess_PCS3000(byte *Data, int /*DataSize*/) +{ + int FunCode, diValue, bitValue = 0; + int i = 0, j, StartAddr, StartPointNo, ValueCount, ChgCount, SoeCount, PointCount; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[100]; + uint64 mSec; + SFesAi *pAi; + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + SFesMi *pMi; + SFesRtuMiValue MiValue[100]; + SFesChgMi ChgMi[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + int64 accValue; + int miValue=0; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + StartPointNo = 0; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + if ((m_AppData.lastCmd.Type == DI_UWord_HL) || (m_AppData.lastCmd.Type == DI_UWord_LH))//DI (数字量1/2) + { + PointCount = Data[2] / 2; + for (i = 0; i < PointCount; i++) + { + if (m_AppData.lastCmd.Type == DI_UWord_HL) //先高位后低位 + { + diValue = (int)Data[3 + i * 2] << 8; + diValue |= (int)Data[4 + i * 2]; + } + else //先低位后高位 + { + diValue = (int)Data[4 + i * 2] << 8; + diValue |= (int)Data[3 + i * 2]; + } + if (m_AppData.lastCmd.Param1 == 1) //数据块自定义#1 = 1,遥信按位组合 + { + for (j = 0; j < (m_ptrCFesRtu->m_MaxDiPoints); j++) + { + if ((pDi = GetFesDiByPointNo(m_ptrCFesRtu, j)) == NULL) + return; + if (pDi->Param2 == StartAddr + i) + { + bitValue = Cmd03RespProcess_BitGroup_PCS3000(pDi, diValue); + + if ((bitValue != pDi->Value) && (g_ModbusRtuV2IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + } + + } + else + { + for (j = 0; j < 16; j++) + { + bitValue = (diValue >> j) & 0x01; + pDi = GetFesDiByParam23(m_ptrCFesRtu, 0, StartAddr + i, j);//R80管理机 FunCode 忽略 + if (pDi != NULL) + { + if (pDi->Revers) //取反 + bitValue ^= 1; + + if ((bitValue != pDi->Value) && (g_ModbusRtuV2IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } + } + } + else + if ((m_AppData.lastCmd.Type >= AI_Word_HL) && (m_AppData.lastCmd.Type <= AI_Float_LL))//AI(模拟量) + { + ValueCount = 0; + ChgCount = 0; + //if ((m_AppData.lastCmd.Type >= AI_Word_HL) && (m_AppData.lastCmd.Type <= AI_UWord_LH))//AI 16bit + if (m_AppData.lastCmd.Type <= AI_UWord_LH)//AI 16bit + { + PointCount = Data[2] / 2; + for (i = 0; i < PointCount; i++) + { + pAi = GetFesAiByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i);//R80管理机 FunCode 忽略 + if (pAi != NULL) + { + switch (m_AppData.lastCmd.Type) + { + case AI_Word_HL: + sValue16 = (short)Data[3 + i * 2] << 8; + sValue16 |= (short)Data[4 + i * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: + sValue16 = (short)Data[4 + i * 2] << 8; + sValue16 |= (short)Data[3 + i * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: + uValue16 = (uint16)Data[3 + i * 2] << 8; + uValue16 |= (uint16)Data[4 + i * 2]; + aiValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + i * 2] << 8; + uValue16 |= (uint16)Data[3 + i * 2]; + aiValue = uValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + } + else//AI 32bit + { + PointCount = Data[2] / 4; + for (i = 0; i < PointCount; i++) + { + pAi = GetFesAiByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i*2);//R80管理机 FunCode 忽略 + if (pAi!= NULL) + { + switch (m_AppData.lastCmd.Type) + { + case AI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + i * 4] << 24; + sValue32 |= (int)Data[4 + i * 4] << 16; + sValue32 |= (int)Data[5 + i * 4] << 8; + sValue32 |= (int)Data[6 + i * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + i * 4] << 24; + sValue32 |= (int)Data[6 + i * 4] << 16; + sValue32 |= (int)Data[3 + i * 4] << 8; + sValue32 |= (int)Data[4 + i * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + i * 4] << 24; + sValue32 |= (int)Data[5 + i * 4] << 16; + sValue32 |= (int)Data[4 + i * 4] << 8; + sValue32 |= (int)Data[3 + i * 4]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 4] << 24; + uValue32 |= (uint32)Data[4 + i * 4] << 16; + uValue32 |= (uint32)Data[5 + i * 4] << 8; + uValue32 |= (uint32)Data[6 + i * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 4] << 24; + uValue32 |= (uint32)Data[6 + i * 4] << 16; + uValue32 |= (uint32)Data[3 + i * 4] << 8; + uValue32 |= (uint32)Data[4 + i * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 4] << 24; + uValue32 |= (uint32)Data[5 + i * 4] << 16; + uValue32 |= (uint32)Data[4 + i * 4] << 8; + uValue32 |= (uint32)Data[3 + i * 4]; + aiValue = (float)uValue32; + break; + case AI_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 4] << 24; + uValue32 |= (uint32)Data[4 + i * 4] << 16; + uValue32 |= (uint32)Data[5 + i * 4] << 8; + uValue32 |= (uint32)Data[6 + i * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + // LOGDEBUG("Value : %d %d %d %d",Data[3+i*4],Data[4+i*4],Data[5+i*4],Data[6+i*4]); + // LOGDEBUG("aiValue : %f",aiValue); + break; + case AI_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 4] << 24; + uValue32 |= (uint32)Data[6 + i * 4] << 16; + uValue32 |= (uint32)Data[3 + i * 4] << 8; + uValue32 |= (uint32)Data[4 + i * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 4] << 24; + uValue32 |= (uint32)Data[5 + i * 4] << 16; + uValue32 |= (uint32)Data[4 + i * 4] << 8; + uValue32 |= (uint32)Data[3 + i * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + } + + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + + // LOGDEBUG("AiValue[ValueCount].Value : %f",AiValue[ValueCount].Value); + + ValueCount++; + + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + else + if ((m_AppData.lastCmd.Type >= ACC_Word_HL) && (m_AppData.lastCmd.Type <= ACC_Float_LL))//ACC (电度量) + { + ValueCount = 0; + ChgCount = 0; + //if ((m_AppData.lastCmd.Type >= ACC_Word_HL) && (m_AppData.lastCmd.Type <= ACC_UWord_LH))//ACC 16bit + if (m_AppData.lastCmd.Type <= ACC_UWord_LH)//ACC 16bit + { + PointCount = Data[2] / 2; + for (i = 0; i < PointCount; i++) + { + pAcc = GetFesAccByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i);//R80管理机 FunCode 忽略 + if (pAcc != NULL) + { + switch (m_AppData.lastCmd.Type) + { + case ACC_Word_HL: + sValue16 = (short)Data[3 + i * 2] << 8; + sValue16 |= (short)Data[4 + i * 2]; + accValue = sValue16; + break; + case ACC_Word_LH: + sValue16 = (short)Data[4 + i * 2] << 8; + sValue16 |= (short)Data[3 + i * 2]; + accValue = sValue16; + break; + case ACC_UWord_HL: + uValue16 = (uint16)Data[3 + i * 2] << 8; + uValue16 |= (uint16)Data[4 + i * 2]; + accValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + i * 2] << 8; + uValue16 |= (uint16)Data[3 + i * 2]; + accValue = uValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = static_cast(accValue); + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + } + else//ACC 32bit + { + PointCount = Data[2] / 4; + for (i = 0; i < PointCount; i++) + { + pAcc = GetFesAccByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i*2);//R80管理机 FunCode 忽略 + if (pAcc != NULL) + { + switch (m_AppData.lastCmd.Type) + { + case ACC_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + i * 4] << 24; + sValue32 |= (int)Data[4 + i * 4] << 16; + sValue32 |= (int)Data[5 + i * 4] << 8; + sValue32 |= (int)Data[6 + i * 4]; + accValue = sValue32; + break; + case ACC_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + i * 4] << 24; + sValue32 |= (int)Data[6 + i * 4] << 16; + sValue32 |= (int)Data[3 + i * 4] << 8; + sValue32 |= (int)Data[4 + i * 4]; + accValue = sValue32; + break; + case ACC_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + i * 4] << 24; + sValue32 |= (int)Data[5 + i * 4] << 16; + sValue32 |= (int)Data[4 + i * 4] << 8; + sValue32 |= (int)Data[3 + i * 4]; + accValue = sValue32; + break; + case ACC_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 4] << 24; + uValue32 |= (uint32)Data[4 + i * 4] << 16; + uValue32 |= (uint32)Data[5 + i * 4] << 8; + uValue32 |= (uint32)Data[6 + i * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 4] << 24; + uValue32 |= (uint32)Data[6 + i * 4] << 16; + uValue32 |= (uint32)Data[3 + i * 4] << 8; + uValue32 |= (uint32)Data[4 + i * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 4] << 24; + uValue32 |= (uint32)Data[5 + i * 4] << 16; + uValue32 |= (uint32)Data[4 + i * 4] << 8; + uValue32 |= (uint32)Data[3 + i * 4]; + accValue = uValue32; + break; + case ACC_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 4] << 24; + uValue32 |= (uint32)Data[4 + i * 4] << 16; + uValue32 |= (uint32)Data[5 + i * 4] << 8; + uValue32 |= (uint32)Data[6 + i * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000); + break; + case ACC_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 4] << 24; + uValue32 |= (uint32)Data[6 + i * 4] << 16; + uValue32 |= (uint32)Data[3 + i * 4] << 8; + uValue32 |= (uint32)Data[4 + i * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000); + break; + case ACC_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 4] << 24; + uValue32 |= (uint32)Data[5 + i * 4] << 16; + uValue32 |= (uint32)Data[4 + i * 4] << 8; + uValue32 |= (uint32)Data[3 + i * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000); + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = static_cast(accValue); + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + else + if ((m_AppData.lastCmd.Type >= MI_Word_HL) && (m_AppData.lastCmd.Type <= MI_UDWord_LL))//MI (混合量) + { + ValueCount = 0; + ChgCount = 0; + //if ((m_AppData.lastCmd.Type >= MI_Word_HL) && (m_AppData.lastCmd.Type <= MI_UWord_LH))//MI 16bit + if (m_AppData.lastCmd.Type <= MI_UWord_LH)//MI 16bit + { + PointCount = Data[2] / 2; + for (i = 0; i < PointCount; i++) + { + pMi = GetFesMiByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i);//R80管理机 FunCode 忽略 + if (pMi!= NULL) + { + switch (m_AppData.lastCmd.Type) + { + case MI_Word_HL: + sValue16 = (short)Data[3 + i * 2] << 8; + sValue16 |= (short)Data[4 + i * 2]; + miValue = sValue16; + break; + case MI_Word_LH: + sValue16 = (short)Data[4 + i * 2] << 8; + sValue16 |= (short)Data[3 + i * 2]; + miValue = sValue16; + break; + case MI_UWord_HL: + uValue16 = (uint16)Data[3 + i * 2] << 8; + uValue16 |= (uint16)Data[4 + i * 2]; + miValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + i * 2] << 8; + uValue16 |= (uint16)Data[3 + i * 2]; + miValue = uValue16; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + } + else//Mi 32bit + { + PointCount = Data[2] / 4; + for (i = 0; i < PointCount; i++) + { + pMi = GetFesMiByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i*2);//R80管理机 FunCode 忽略 + if (pMi != NULL) + { + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + //StartPointNo = pMi->Param1 + 1; + switch (m_AppData.lastCmd.Type) + { + case MI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + i * 4] << 24; + sValue32 |= (int)Data[4 + i * 4] << 16; + sValue32 |= (int)Data[5 + i * 4] << 8; + sValue32 |= (int)Data[6 + i * 4]; + miValue = sValue32; + break; + case MI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + i * 4] << 24; + sValue32 |= (int)Data[6 + i * 4] << 16; + sValue32 |= (int)Data[3 + i * 4] << 8; + sValue32 |= (int)Data[4 + i * 4]; + miValue = sValue32; + break; + case MI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + i * 4] << 24; + sValue32 |= (int)Data[5 + i * 4] << 16; + sValue32 |= (int)Data[4 + i * 4] << 8; + sValue32 |= (int)Data[3 + i * 4]; + miValue = sValue32; + break; + case MI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 4] << 24; + uValue32 |= (uint32)Data[4 + i * 4] << 16; + uValue32 |= (uint32)Data[5 + i * 4] << 8; + uValue32 |= (uint32)Data[6 + i * 4]; + miValue = uValue32; + break; + case MI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 4] << 24; + uValue32 |= (uint32)Data[6 + i * 4] << 16; + uValue32 |= (uint32)Data[3 + i * 4] << 8; + uValue32 |= (uint32)Data[4 + i * 4]; + miValue = uValue32; + break; + case MI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 4] << 24; + uValue32 |= (uint32)Data[5 + i * 4] << 16; + uValue32 |= (uint32)Data[4 + i * 4] << 8; + uValue32 |= (uint32)Data[3 + i * 4]; + miValue = uValue32; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } +} + +/** +* @brief CModbusDataProcThread::Cmd03RespProcess_BitGroup +* 按位组合的遥信解析处理 +* @param Data 遥信点结构 +* @param DataSize 遥信字节值 +*/ +int CModbusRtuV2DataProcThread::Cmd03RespProcess_BitGroup_PCS3000(SFesDi *pDi, int diValue) +{ + int temp1 = pDi->Param4; + int IntData = diValue & temp1; + int i, YxBit = 0; + + if (temp1 < 0) + return YxBit; + + for (i = 0; i < 16; i++) + { + if ((temp1 >> i) & 0x01) + { + IntData >>= i; + break; + } + } + + if (pDi->Param3 == IntData) + YxBit = 1; + + return YxBit; +} + +/** +* @brief CModbusRtuV2DataProcThread::Cmd01RespProcess +* 命令0x01 0x02的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* @param Data 接收的数据 +*/ +void CModbusRtuV2DataProcThread::Cmd01RespProcess(byte *Data, int DataSize) +{ + boost::ignore_unused_variable_warning(DataSize); + + int FunCode; + byte bitValue, byteValue; + int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, SoeCount, PointIndex1, PointIndex2; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[50]; + uint64 mSec; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + if (m_DiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd01RespProcess: 未找到blockId=%d的数字量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + for (i = StartPointNo; i <= EndPointNo; i++) + { + pDi = GetFesDiByPIndex(m_ptrCFesRtu, i); + if (pDi == NULL) + continue; + + PointIndex1 = (pDi->Param3 - m_AppData.lastCmd.StartAddr) / 8; + //2022-11-22 增加判断,防止数组过界。 + if ((PointIndex1 < 0) || (PointIndex1 > MODBUSRTUV2_K_MAX_POINT_INDEX*1.5)) + { + continue; + } + + byteValue = Data[3 + PointIndex1]; + PointIndex2 = (pDi->Param3 - m_AppData.lastCmd.StartAddr) % 8; + bitValue = (byteValue >> PointIndex2) & 0x01; + + if (pDi->Revers) + bitValue ^= 1; + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + //StartPointNo = pDi->Param1 + 1; + if ((bitValue != pDi->Value) && (g_ModbusRtuV2IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + //更新点值 + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } +} + +/** +* @brief CModbusRtuV2DataProcThread::Cmd03RespProcess_BitGroup +* 按位组合的遥信解析处理 +* @param Data 遥信点结构 +* @param DataSize 遥信字节值 +*/ +int CModbusRtuV2DataProcThread::Cmd03RespProcess_BitGroup(SFesDi *pDi, int diValue) +{ + int temp1 = pDi->Param5; + int IntData = diValue & temp1; + int i, YxBit = 0; + + if (temp1 < 0) + return YxBit; + + for (i = 0; i < 16; i++) + { + if ((temp1 >> i) & 0x01) + { + IntData >>= i; + break; + } + } + + if (pDi->Param4 == IntData) + YxBit = 1; + + return YxBit; +} + +/** +* @brief CModbusRtuV2DataProcThread::Cmd03RespProcess +* 命令0x03 0x04的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusRtuV2DataProcThread::Cmd03RespProcess(byte *Data, int DataSize) +{ + boost::ignore_unused_variable_warning(DataSize); + + int FunCode, diValue, bitValue; + int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, SoeCount, PointIndex; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[100]; + uint64 mSec; + SFesAi *pAi; + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + SFesMi *pMi; + SFesRtuMiValue MiValue[100]; + SFesChgMi ChgMi[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + int64 accValue; + int miValue; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + if ((m_AppData.lastCmd.Type == DI_UWord_HL) || (m_AppData.lastCmd.Type == DI_UWord_LH))//DI + { + if (m_DiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的数字量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + for (i = StartPointNo; i <= EndPointNo; i++) + { + pDi = GetFesDiByPIndex(m_ptrCFesRtu, i); + if (pDi == NULL) + continue; + + PointIndex = pDi->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-22 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSRTUV2_K_MAX_POINT_INDEX)) + { + continue; + } + + if (m_AppData.lastCmd.Type == DI_UWord_HL) + { + diValue = (int)Data[3 + PointIndex * 2] << 8; + diValue |= (int)Data[4 + PointIndex * 2]; + } + else//DI_UWord_LH + { + diValue = (int)Data[4 + PointIndex * 2] << 8; + diValue |= (int)Data[3 + PointIndex * 2]; + } + + if (m_AppData.lastCmd.Param1 == 1) //数据块自定义#1 = 1,遥信按位组合 + { + bitValue = Cmd03RespProcess_BitGroup(pDi, diValue); + + if ((bitValue != pDi->Value) && (g_ModbusRtuV2IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + else + { + bitValue = (diValue >> (pDi->Param4)) & 0x01; + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + if (pDi->Revers) + bitValue ^= 1; + if ((bitValue != pDi->Value) && (g_ModbusRtuV2IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } + } + else + if (((m_AppData.lastCmd.Type >= AI_Word_HL) && (m_AppData.lastCmd.Type <= AI_Float_LL)) || (m_AppData.lastCmd.Type == AI_SIGNEDFLAG16_HL) || (m_AppData.lastCmd.Type == AI_SIGNEDFLAG32_HL))//AI + { + if (m_AiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的模拟量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + ValueCount = 0; + ChgCount = 0; + if (((m_AppData.lastCmd.Type >= AI_Word_HL) && (m_AppData.lastCmd.Type <= AI_UWord_LH)) || (m_AppData.lastCmd.Type == AI_SIGNEDFLAG16_HL))//AI 16bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + PointIndex = pAi->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-22 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSRTUV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case AI_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + aiValue = uValue16; + break; + case AI_SIGNEDFLAG16_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + if (uValue16 & 0x8000) + { + aiValue = (float)(uValue16 & 0x7fff); + aiValue = 0 - aiValue; + } + else + aiValue = (float)(uValue16 & 0x7fff); + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + aiValue = uValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + else//AI 32bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + PointIndex = (pAi->Param3 - m_AppData.lastCmd.StartAddr) / 2; + //2022-11-22 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSRTUV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case AI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_SIGNEDFLAG32_HL: + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + if (uValue32 & 0x80000000) + { + aiValue = (float)(uValue32 & 0x7fffffff); + aiValue = 0 - aiValue; + } + else + aiValue = (float)(uValue32 & 0x7fffffff); + break; + } + + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + + ValueCount++; + + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + else + if ((m_AppData.lastCmd.Type >= ACC_Word_HL) && (m_AppData.lastCmd.Type <= ACC_Float_LL))//ACC + { + if (m_AccBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的累积量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + ValueCount = 0; + ChgCount = 0; + if ((m_AppData.lastCmd.Type >= ACC_Word_HL) && (m_AppData.lastCmd.Type <= ACC_UWord_LH))//ACC 16bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + PointIndex = pAcc->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-22 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSRTUV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case ACC_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + accValue = sValue16; + break; + case ACC_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + accValue = sValue16; + break; + case ACC_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + accValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + accValue = uValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = static_cast(accValue); + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + else//ACC 32bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + PointIndex = (pAcc->Param3 - m_AppData.lastCmd.StartAddr) / 2; + //2022-11-22 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSRTUV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case ACC_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000); + break; + case ACC_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000); + break; + case ACC_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000); + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = static_cast(accValue); + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + else + if ((m_AppData.lastCmd.Type >= MI_Word_HL) && (m_AppData.lastCmd.Type <= MI_UDWord_LL))//MI + { + if (m_MiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_MiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_MiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + ValueCount = 0; + ChgCount = 0; + if ((m_AppData.lastCmd.Type >= MI_Word_HL) && (m_AppData.lastCmd.Type <= MI_UWord_LH))//MI 16bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pMi = GetFesMiByPIndex(m_ptrCFesRtu, i); + if (pMi == NULL) + continue; + + //2022-12-20 thxiao Cmd03RespProcess() Mi取点值应该为PointIndex + PointIndex = pMi->Param3 - m_AppData.lastCmd.StartAddr; + if ((PointIndex < 0) || (PointIndex > MODBUSRTUV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case MI_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + miValue = sValue16; + break; + case MI_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + miValue = sValue16; + break; + case MI_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + miValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + miValue = uValue16; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + else//Mi 32bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pMi = GetFesMiByPIndex(m_ptrCFesRtu, i); + if (pMi == NULL) + continue; + + //2022-12-20 thxiao Cmd03RespProcess() Mi取点值应该为PointIndex + PointIndex = (pMi->Param3 - m_AppData.lastCmd.StartAddr) / 2; + if ((PointIndex < 0) || (PointIndex > MODBUSRTUV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case MI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + miValue = uValue32; + break; + case MI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + miValue = uValue32; + break; + case MI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + miValue = uValue32; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } +} + +void CModbusRtuV2DataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) +{ + boost::ignore_unused_variable_warning(DataSize); + + int FunCode; + int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, PointIndex; + uint64 mSec; + SFesAi *pAi; + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + int64 accValue; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + if (m_AppData.lastCmd.Type == AI_Hybrid_Type)//AI 模拟量混合量帧 + { + if (m_AiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("CmdTypeHybridProcess: 未找到blockId=%d的模拟量混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + ValueCount = 0; + ChgCount = 0; + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + PointIndex = pAi->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-22 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSRTUV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (pAi->Param4) + { + case AI_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)Data[4 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[3 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + aiValue = uValue16; + break; + case AI_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + aiValue = (float)uValue16; + break; + case AI_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 2] << 24; + sValue32 |= (int)Data[4 + PointIndex * 2] << 16; + sValue32 |= (int)Data[5 + PointIndex * 2] << 8; + sValue32 |= (int)Data[6 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 2] << 24; + sValue32 |= (int)Data[6 + PointIndex * 2] << 16; + sValue32 |= (int)Data[3 + PointIndex * 2] << 8; + sValue32 |= (int)Data[4 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 2] << 24; + sValue32 |= (int)Data[5 + PointIndex * 2] << 16; + sValue32 |= (int)Data[4 + PointIndex * 2] << 8; + sValue32 |= (int)Data[3 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case AI_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + default: + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + else if (m_AppData.lastCmd.Type == ACC_Hybrid_Type)//ACC 累积量混合量帧 + { + if (m_AccBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("CmdTypeHybridProcess: 未找到blockId=%d的累积量混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + ValueCount = 0; + ChgCount = 0; + + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + PointIndex = pAcc->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-22 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSRTUV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (pAcc->Param4) + { + case ACC_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + accValue = (int64)sValue16; + break; + case ACC_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)Data[4 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[3 + PointIndex * 2]; + accValue = (int64)sValue16; + break; + case ACC_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + accValue = (int64)uValue16; + break; + case ACC_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + accValue = (int64)uValue16; + break; + case ACC_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 2] << 24; + sValue32 |= (int)Data[4 + PointIndex * 2] << 16; + sValue32 |= (int)Data[5 + PointIndex * 2] << 8; + sValue32 |= (int)Data[6 + PointIndex * 2]; + accValue = (int64)sValue32; + break; + case ACC_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 2] << 24; + sValue32 |= (int)Data[6 + PointIndex * 2] << 16; + sValue32 |= (int)Data[3 + PointIndex * 2] << 8; + sValue32 |= (int)Data[4 + PointIndex * 2]; + accValue = (int64)sValue32; + break; + case ACC_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 2] << 24; + sValue32 |= (int)Data[5 + PointIndex * 2] << 16; + sValue32 |= (int)Data[4 + PointIndex * 2] << 8; + sValue32 |= (int)Data[3 + PointIndex * 2]; + accValue = (int64)sValue32; + break; + case ACC_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + accValue = (int64)uValue32; + break; + case ACC_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + accValue = (int64)uValue32; + break; + case ACC_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + accValue = (int64)uValue32; + break; + case ACC_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000); + break; + case ACC_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000); + break; + case ACC_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000); + break; + default: + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + accValue = (int64)sValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = static_cast(accValue); + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } +} + + +/** +* @brief CModbusDataProcThread::Cmd05RespProcess +* 命令0x05的处理。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusRtuV2DataProcThread::Cmd05RespProcess(byte *Data, int DataSize) +{ + CmdControlRespProcess(Data, DataSize, 1); +} + +/** +* @brief CModbusDataProcThread::Cmd06RespProcess +* 命令0x06的处理。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusRtuV2DataProcThread::Cmd06RespProcess(byte *Data, int DataSize) +{ + CmdControlRespProcess(Data, DataSize, 1); +} +/** +* @brief CModbusRtuV2DataProcThread::Cmd10RespProcess +* 命令0x10的处理。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusRtuV2DataProcThread::Cmd10RespProcess(byte *Data, int DataSize) +{ + CmdControlRespProcess(Data, DataSize, 1); +} + +/** +* @brief CModbusRtuV2DataProcThread::CmdControlRespProcess +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +* @param okFlag 命令成功标志 1:成功 0:失败 +* @return 是控制命令返回:TRUE 否则为:FALSE +*/ +bool CModbusRtuV2DataProcThread::CmdControlRespProcess(byte *Data, int DataSize, int okFlag) +{ + boost::ignore_unused_variable_warning(Data); + boost::ignore_unused_variable_warning(DataSize); + + SFesTxDoCmd retDoCmd; + SFesTxAoCmd retAoCmd; + SFesTxMoCmd retMoCmd; + SFesTxDefCmd retDefCmd; + + if (m_AppData.state != CN_ModbusRtuV2AppState_waitControlResp) + return false; + + switch (m_AppData.lastCotrolcmd) + { + case CN_ModbusRtuV2DoCmd: + //memset(&retDoCmd,0,sizeof(retDoCmd)); + if (okFlag) + { + retDoCmd.retStatus = CN_ControlSuccess; + sprintf(retDoCmd.strParam, I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.doCmd.PointID); + LOGINFO("遥控成功!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.doCmd.PointID); + } + else + { + retDoCmd.retStatus = CN_ControlFailed; + sprintf(retDoCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.doCmd.PointID); + LOGINFO("遥控失败!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.doCmd.PointID); + } + strcpy(retDoCmd.TableName, m_AppData.doCmd.TableName); + strcpy(retDoCmd.ColumnName, m_AppData.doCmd.ColumnName); + strcpy(retDoCmd.TagName, m_AppData.doCmd.TagName); + strcpy(retDoCmd.RtuName, m_AppData.doCmd.RtuName); + retDoCmd.CtrlActType = m_AppData.doCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retDoCmd.CtrlDir = m_AppData.doCmd.CtrlDir; + retDoCmd.RtuNo = m_AppData.doCmd.RtuNo; + retDoCmd.PointID = m_AppData.doCmd.PointID; + retDoCmd.FwSubSystem = m_AppData.doCmd.FwSubSystem; + retDoCmd.FwRtuNo = m_AppData.doCmd.FwRtuNo; + retDoCmd.FwPointNo = m_AppData.doCmd.FwPointNo; + retDoCmd.SubSystem = m_AppData.doCmd.SubSystem; + + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retDoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retDoCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuV2NoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_idle; + return true; + break; + case CN_ModbusRtuV2AoCmd: + if (okFlag) + { + retAoCmd.retStatus = CN_ControlSuccess; + sprintf(retAoCmd.strParam, I18N("遥调成功!RtuNo:%d 遥调点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + LOGINFO("遥调成功!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + } + else + { + retAoCmd.retStatus = CN_ControlFailed; + sprintf(retAoCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + LOGINFO("遥调失败!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + } + strcpy(retAoCmd.TableName, m_AppData.aoCmd.TableName); + strcpy(retAoCmd.ColumnName, m_AppData.aoCmd.ColumnName); + strcpy(retAoCmd.TagName, m_AppData.aoCmd.TagName); + strcpy(retAoCmd.RtuName, m_AppData.aoCmd.RtuName); + retAoCmd.CtrlActType = m_AppData.aoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retAoCmd.CtrlDir = m_AppData.aoCmd.CtrlDir; + retAoCmd.RtuNo = m_AppData.aoCmd.RtuNo; + retAoCmd.PointID = m_AppData.aoCmd.PointID; + retAoCmd.FwSubSystem = m_AppData.aoCmd.FwSubSystem; + retAoCmd.FwRtuNo = m_AppData.aoCmd.FwRtuNo; + retAoCmd.FwPointNo = m_AppData.aoCmd.FwPointNo; + retAoCmd.SubSystem = m_AppData.aoCmd.SubSystem; + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retAoCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuV2NoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_idle; + return true; + break; + case CN_ModbusRtuV2MoCmd: + if (okFlag) + { + retMoCmd.retStatus = CN_ControlSuccess; + sprintf(retMoCmd.strParam, I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + LOGINFO("混合量输出成功!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + } + else + { + retMoCmd.retStatus = CN_ControlFailed; + sprintf(retMoCmd.strParam, I18N("混合量输出失败!RtuNo:%d 混合量输出点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + LOGINFO("混合量输出失败!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + } + strcpy(retMoCmd.TableName, m_AppData.moCmd.TableName); + strcpy(retMoCmd.ColumnName, m_AppData.moCmd.ColumnName); + strcpy(retMoCmd.TagName, m_AppData.moCmd.TagName); + strcpy(retMoCmd.RtuName, m_AppData.moCmd.RtuName); + retMoCmd.CtrlActType = m_AppData.moCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retMoCmd.CtrlDir = m_AppData.moCmd.CtrlDir; + retMoCmd.RtuNo = m_AppData.moCmd.RtuNo; + retMoCmd.PointID = m_AppData.moCmd.PointID; + retMoCmd.FwSubSystem = m_AppData.moCmd.FwSubSystem; + retMoCmd.FwRtuNo = m_AppData.moCmd.FwRtuNo; + retMoCmd.FwPointNo = m_AppData.moCmd.FwPointNo; + retMoCmd.SubSystem = m_AppData.moCmd.SubSystem; + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retMoCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuV2NoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_idle; + return true; + break; + case CN_ModbusRtuV2DefCmd: + if (okFlag) + { + retDefCmd.retStatus = CN_ControlSuccess; + sprintf(retDefCmd.strParam, I18N("自定义命令输出成功!RtuNo:%d ").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo); + LOGINFO("自定义命令输出成功!RtuNo:%d ", m_ptrCInsertFesRtu->m_Param.RtuNo); + } + else + { + retDefCmd.retStatus = CN_ControlFailed; + sprintf(retDefCmd.strParam, I18N("自定义命令输出失败!RtuNo:%d ").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo); + LOGINFO("自定义命令输出失败!RtuNo:%d ", m_ptrCInsertFesRtu->m_Param.RtuNo); + } + strcpy(retDefCmd.TableName, m_AppData.defCmd.TableName); + strcpy(retDefCmd.ColumnName, m_AppData.defCmd.ColumnName); + strcpy(retDefCmd.TagName, m_AppData.defCmd.TagName); + strcpy(retDefCmd.RtuName, m_AppData.defCmd.RtuName); + retDefCmd.DevId = m_AppData.defCmd.DevId; + retDefCmd.CmdNum = m_AppData.defCmd.CmdNum; + retDefCmd.VecCmd = m_AppData.defCmd.VecCmd; + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &retDefCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuV2NoCmd; + m_AppData.state = CN_ModbusRtuV2AppState_idle; + return true; + break; + default: + break; + } + return false; +} + +/** +* @brief CModbusRtuV2DataProcThread::SendDataToPort +* 数据发送到发送缓冲区。 +* 如是主通道,直接使用m_ptrCFesChan通道结构;如果是备用通道,需要获取当前使用通道,在发送数据。 +* @param Data 数据区 +* @param Size 数据区长度 +*/ +void CModbusRtuV2DataProcThread::SendDataToPort(byte *Data, int Size) +{ + if (m_ptrCurrentChan == NULL) + return; + + switch (m_ptrCurrentChan->m_Param.CommType) + { + case CN_FesSerialPort: + if (m_ptrComSerial != NULL) + { + //RTU PARAM2 = 1000 为延时发送时间,单位毫秒 + if (m_ptrCFesRtu->m_Param.ResParam2 > 0) + SleepmSec(m_ptrCFesRtu->m_Param.ResParam2); + + m_ptrComSerial->TxComData(m_ptrCurrentChan,Size, Data); + + //saved last send cmd + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, Data, Size, CN_SFesSimComFrameTypeSend); + m_ptrCurrentChan->SetTxNum(1); + if (m_ptrCInsertFesRtu != NULL) //InsertCmd + m_ptrCInsertFesRtu->SetTxNum(1); + else + m_ptrCFesRtu->SetTxNum(1); + + memcpy(&m_AppData.lastCmdData[0], Data, Size); + m_AppData.lastCmdDataLen = Size; + + } + else + { + LOGDEBUG("ChanNo=%d m_ptrComSerial is NULL can not send data", m_ptrCurrentChan->m_Param.ChanNo); + } + + + break; + case CN_FesTcpClient: + if (m_ptrCurrentChan->m_LinkStatus != CN_FesChanConnect)//2021-01-22 thxiao + return; + + if (m_ptrComClient != NULL) + { + //RTU PARAM2 = 1000 为延时发送时间,单位毫秒 + if (m_ptrCFesRtu->m_Param.ResParam2 > 0) + SleepmSec(m_ptrCFesRtu->m_Param.ResParam2); + + m_ptrComClient->TxData(m_ptrCurrentChan,Size, Data); + + //saved last send cmd + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, Data, Size, CN_SFesSimComFrameTypeSend); + m_ptrCurrentChan->SetTxNum(1); + if (m_ptrCInsertFesRtu != NULL) //InsertCmd + m_ptrCInsertFesRtu->SetTxNum(1); + else + m_ptrCFesRtu->SetTxNum(1); + + memcpy(&m_AppData.lastCmdData[0], Data, Size); + m_AppData.lastCmdDataLen = Size; + + } + else + { + LOGDEBUG("ChanNo=%d m_ptrComClient is NULL can not send data", m_ptrCurrentChan->m_Param.ChanNo); + } + break; + default: + break; + + } + + +} + +int CModbusRtuV2DataProcThread::CrcSum(byte *Data, int Count) +{ + int i, j; + int Temp = 0xffff, Temp1; + for (i = 0; i < Count; i++) + { + Temp = Data[i] ^ Temp; + for (j = 0; j < 8; j++) + { + Temp1 = Temp & 1; + Temp >>= 1; + if (Temp1) + Temp ^= 0xa001; + } + } + + return Temp; +} + + +/* +2019-08-30 按原有的方式,时间间隔最大为100MS,过大,所以改为程序内部处理 +*/ +void CModbusRtuV2DataProcThread::SetSendCmdFlag() +{ + SModbusCmd *pCmd; + int i, j, RtuNo; + int64 lTime, tempTime; + CFesRtuPtr ptrFesRtu; + + if (m_AppData.setCmdCount++ > 2) + { + m_AppData.setCmdCount = 0; + lTime = getMonotonicMsec(); //MS + for (i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((ptrFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) + continue; + for (j = 0; j < ptrFesRtu->m_Param.ModbusCmdBuf.num; j++) + { + pCmd = ptrFesRtu->m_Param.ModbusCmdBuf.pCmd + j; + if(pCmd->Used)//2022-09-06 thxiao 启用块使能 + { + if (DZ_DI_BYTE_LH < pCmd->Type && pCmd->Type < DZ_AI_Float_LL) + continue; //保护定值数据块 + + tempTime = lTime - pCmd->lastPollTime; + if (tempTime > pCmd->PollTime) + { + pCmd->CommandSendFlag = true; + pCmd->lastPollTime = lTime; + //LOGDEBUG("cmd=%d m_CurrentRtuIndex=%d StartAddr=%d PollTime=%d CommandSendFlag=true", j, m_ptrCurrentChan->m_CurrentRtuIndex, pCmd->StartAddr, pCmd->PollTime); + } + else + if (tempTime <= 0)//避免时间错的情况发生 + { + pCmd->lastPollTime = lTime; + } + } + } + } + } +} + +void CModbusRtuV2DataProcThread::CmdTypeHybridProcess_PCS3000(byte *Data, int DataSize) +{ + boost::ignore_unused_variable_warning(DataSize); + + int FunCode; + int i, StartAddr, StartPointNo, ValueCount, ChgCount, PointCount; + uint64 mSec; + SFesAi *pAi; + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + int64 accValue; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + StartPointNo = 0; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + if (m_AppData.lastCmd.Type == AI_Hybrid_Type)//AI 模拟量混合量帧 + { + ValueCount = 0; + ChgCount = 0; + PointCount = Data[2] / 2; + for (i = 0; i < PointCount; i++) + { + if (m_ptrCFesRtu->m_Param.ResParam1 == 1) + { + pAi = GetFesAiByPIndexParam23(m_ptrCFesRtu, StartPointNo, FunCode, StartAddr + i); + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + if (pAi != NULL) + StartPointNo = pAi->Param1 + 1; + } + else + { + pAi = GetFesAiByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i);//R80管理机 FunCode 忽略 + } + switch (pAi->Param4) + { + case AI_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)Data[3 + i * 2] << 8; + sValue16 |= (int16)Data[4 + i * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)Data[4 + i * 2] << 8; + sValue16 |= (int16)Data[3 + i * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)Data[3 + i * 2] << 8; + uValue16 |= (uint16)Data[4 + i * 2]; + aiValue = uValue16; + break; + case AI_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)Data[4 + i * 2] << 8; + uValue16 |= (uint16)Data[3 + i * 2]; + aiValue = uValue16; + break; + case AI_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + i * 2] << 24; + sValue32 |= (int)Data[4 + i * 2] << 16; + sValue32 |= (int)Data[5 + i * 2] << 8; + sValue32 |= (int)Data[6 + i * 2]; + aiValue = (float)sValue32; + i++; + break; + case AI_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + i * 2] << 24; + sValue32 |= (int)Data[6 + i * 2] << 16; + sValue32 |= (int)Data[3 + i * 2] << 8; + sValue32 |= (int)Data[4 + i * 2]; + aiValue = (float)sValue32; + i++; + break; + case AI_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + i * 2] << 24; + sValue32 |= (int)Data[5 + i * 2] << 16; + sValue32 |= (int)Data[4 + i * 2] << 8; + sValue32 |= (int)Data[3 + i * 2]; + aiValue = (float)sValue32; + i++; + break; + case AI_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 2] << 24; + uValue32 |= (uint32)Data[4 + i * 2] << 16; + uValue32 |= (uint32)Data[5 + i * 2] << 8; + uValue32 |= (uint32)Data[6 + i * 2]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 2] << 24; + uValue32 |= (uint32)Data[6 + i * 2] << 16; + uValue32 |= (uint32)Data[3 + i * 2] << 8; + uValue32 |= (uint32)Data[4 + i * 2]; + aiValue = (float)uValue32; + i++; + break; + case AI_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 2] << 24; + uValue32 |= (uint32)Data[5 + i * 2] << 16; + uValue32 |= (uint32)Data[4 + i * 2] << 8; + uValue32 |= (uint32)Data[3 + i * 2]; + aiValue = (float)uValue32; + i++; + break; + case AI_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 2] << 24; + uValue32 |= (uint32)Data[4 + i * 2] << 16; + uValue32 |= (uint32)Data[5 + i * 2] << 8; + uValue32 |= (uint32)Data[6 + i * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + i++; + break; + case AI_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 2] << 24; + uValue32 |= (uint32)Data[6 + i * 2] << 16; + uValue32 |= (uint32)Data[3 + i * 2] << 8; + uValue32 |= (uint32)Data[4 + i * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 2] << 24; + uValue32 |= (uint32)Data[5 + i * 2] << 16; + uValue32 |= (uint32)Data[4 + i * 2] << 8; + uValue32 |= (uint32)Data[3 + i * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + i++; + break; + default: + sValue16 = (int16)Data[3 + i * 2] << 8; + sValue16 |= (int16)Data[4 + i * 2]; + aiValue = sValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + else if (m_AppData.lastCmd.Type == ACC_Hybrid_Type)//ACC 累积量混合量帧 + { + ValueCount = 0; + ChgCount = 0; + PointCount = Data[2] / 2; + for (i = 0; i < PointCount; i++) + { + if (m_ptrCFesRtu->m_Param.ResParam1 == 1) + { + pAcc = GetFesAccByPIndexParam23(m_ptrCFesRtu, StartPointNo, FunCode, StartAddr + i); + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + if (pAcc != NULL) + StartPointNo = pAcc->Param1 + 1; + } + else + { + pAcc = GetFesAccByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i);//R80管理机 FunCode 忽略 + } + + switch (pAcc->Param4) + { + case ACC_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)Data[3 + i * 2] << 8; + sValue16 |= (int16)Data[4 + i * 2]; + accValue = sValue16; + break; + case ACC_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)Data[4 + i * 2] << 8; + sValue16 |= (int16)Data[3 + i * 2]; + accValue = sValue16; + break; + case ACC_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)Data[3 + i * 2] << 8; + uValue16 |= (uint16)Data[4 + i * 2]; + accValue = uValue16; + break; + case ACC_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)Data[4 + i * 2] << 8; + uValue16 |= (uint16)Data[3 + i * 2]; + accValue = uValue16; + break; + case ACC_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + i * 2] << 24; + sValue32 |= (int)Data[4 + i * 2] << 16; + sValue32 |= (int)Data[5 + i * 2] << 8; + sValue32 |= (int)Data[6 + i * 2]; + accValue = sValue32; + i++; + break; + case ACC_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + i * 2] << 24; + sValue32 |= (int)Data[6 + i * 2] << 16; + sValue32 |= (int)Data[3 + i * 2] << 8; + sValue32 |= (int)Data[4 + i * 2]; + accValue = sValue32; + i++; + break; + case ACC_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + i * 2] << 24; + sValue32 |= (int)Data[5 + i * 2] << 16; + sValue32 |= (int)Data[4 + i * 2] << 8; + sValue32 |= (int)Data[3 + i * 2]; + accValue = sValue32; + i++; + break; + case ACC_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 2] << 24; + uValue32 |= (uint32)Data[4 + i * 2] << 16; + uValue32 |= (uint32)Data[5 + i * 2] << 8; + uValue32 |= (uint32)Data[6 + i * 2]; + accValue = uValue32; + break; + case ACC_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 2] << 24; + uValue32 |= (uint32)Data[6 + i * 2] << 16; + uValue32 |= (uint32)Data[3 + i * 2] << 8; + uValue32 |= (uint32)Data[4 + i * 2]; + accValue = uValue32; + i++; + break; + case ACC_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 2] << 24; + uValue32 |= (uint32)Data[5 + i * 2] << 16; + uValue32 |= (uint32)Data[4 + i * 2] << 8; + uValue32 |= (uint32)Data[3 + i * 2]; + accValue = uValue32; + i++; + break; + case ACC_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 2] << 24; + uValue32 |= (uint32)Data[4 + i * 2] << 16; + uValue32 |= (uint32)Data[5 + i * 2] << 8; + uValue32 |= (uint32)Data[6 + i * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000); + i++; + break; + case ACC_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 2] << 24; + uValue32 |= (uint32)Data[6 + i * 2] << 16; + uValue32 |= (uint32)Data[3 + i * 2] << 8; + uValue32 |= (uint32)Data[4 + i * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000); + break; + case ACC_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 2] << 24; + uValue32 |= (uint32)Data[5 + i * 2] << 16; + uValue32 |= (uint32)Data[4 + i * 2] << 8; + uValue32 |= (uint32)Data[3 + i * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000); + i++; + break; + default: + sValue16 = (int16)Data[3 + i * 2] << 8; + sValue16 |= (int16)Data[4 + i * 2]; + accValue = sValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = static_cast(accValue); + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } +} + +/** +* @brief CModbusRtuV2DataProcThread::ErrorControlRespProcess +* @param +* @param +* @param 网络令来需要做异常处理断开时有控制命 +* @return +*/ +void CModbusRtuV2DataProcThread::ErrorControlRespProcess() +{ + SFesRxDoCmd RxDoCmd; + SFesTxDoCmd TxDoCmd; + SFesRxAoCmd RxAoCmd; + SFesTxAoCmd TxAoCmd; + SFesRxMoCmd RxMoCmd; + SFesTxMoCmd TxMoCmd; + SFesRxDefCmd RxDefCmd; + SFesTxDefCmd TxDefCmd; + + if (m_ptrCFesRtu == NULL) + return; + + if (g_ModbusRtuV2IsMainFes == false)//备机不作任何操作 + return; + + if (m_ptrCFesRtu->GetRxDoCmdNum()>0) + { + if (m_ptrCFesRtu->ReadRxDoCmd(1, &RxDoCmd) == 1) + { + //memset(&TxDoCmd,0,sizeof(TxDoCmd)); + + strcpy(TxDoCmd.TableName, RxDoCmd.TableName); + strcpy(TxDoCmd.ColumnName, RxDoCmd.ColumnName); + strcpy(TxDoCmd.TagName, RxDoCmd.TagName); + strcpy(TxDoCmd.RtuName, RxDoCmd.RtuName); + TxDoCmd.retStatus = CN_ControlFailed; + TxDoCmd.CtrlActType = RxDoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxDoCmd.CtrlDir = RxDoCmd.CtrlDir; + TxDoCmd.RtuNo = RxDoCmd.RtuNo; + TxDoCmd.PointID = RxDoCmd.PointID; + TxDoCmd.FwSubSystem = RxDoCmd.FwSubSystem; + TxDoCmd.FwRtuNo = RxDoCmd.FwRtuNo; + TxDoCmd.FwPointNo = RxDoCmd.FwPointNo; + TxDoCmd.SubSystem = RxDoCmd.SubSystem; + sprintf(TxDoCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxDoCmd.PointID); + LOGDEBUG("通信已断开 DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", RxDoCmd.CtrlActType, RxDoCmd.iValue, RxDoCmd.RtuName, RxDoCmd.PointID); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&TxDoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &TxDoCmd); + + } + + } + else + if (m_ptrCFesRtu->GetRxAoCmdNum()>0) + { + if (m_ptrCFesRtu->ReadRxAoCmd(1, &RxAoCmd) == 1) + { + //memset(&TxAoCmd,0,sizeof(TxAoCmd)); + strcpy(TxAoCmd.TableName, RxAoCmd.TableName); + strcpy(TxAoCmd.ColumnName, RxAoCmd.ColumnName); + strcpy(TxAoCmd.TagName, RxAoCmd.TagName); + strcpy(TxAoCmd.RtuName, RxAoCmd.RtuName); + TxAoCmd.retStatus = CN_ControlFailed; + sprintf(TxAoCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxAoCmd.PointID); + TxAoCmd.CtrlActType = RxAoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxAoCmd.CtrlDir = RxAoCmd.CtrlDir; + TxAoCmd.RtuNo = RxAoCmd.RtuNo; + TxAoCmd.PointID = RxAoCmd.PointID; + TxAoCmd.FwSubSystem = RxAoCmd.FwSubSystem; + TxAoCmd.FwRtuNo = RxAoCmd.FwRtuNo; + TxAoCmd.FwPointNo = RxAoCmd.FwPointNo; + TxAoCmd.SubSystem = RxAoCmd.SubSystem; + LOGDEBUG("通信已断开 AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", RxAoCmd.CtrlActType, RxAoCmd.fValue, RxAoCmd.RtuName, RxAoCmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&TxAoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &TxAoCmd); + } + } + else + if (m_ptrCFesRtu->GetRxMoCmdNum()>0) + { + if (m_ptrCFesRtu->ReadRxMoCmd(1, &RxMoCmd) == 1) + { + //memset(&TxMoCmd,0,sizeof(TxMoCmd)); + strcpy(TxMoCmd.TableName, RxMoCmd.TableName); + strcpy(TxMoCmd.ColumnName, RxMoCmd.ColumnName); + strcpy(TxMoCmd.TagName, RxMoCmd.TagName); + strcpy(TxMoCmd.RtuName, RxMoCmd.RtuName); + TxMoCmd.retStatus = CN_ControlFailed; + TxMoCmd.CtrlActType = RxMoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxMoCmd.CtrlDir = RxMoCmd.CtrlDir; + TxMoCmd.RtuNo = RxMoCmd.RtuNo; + TxMoCmd.PointID = RxMoCmd.PointID; + TxMoCmd.FwSubSystem = RxMoCmd.FwSubSystem; + TxMoCmd.FwRtuNo = RxMoCmd.FwRtuNo; + TxMoCmd.FwPointNo = RxMoCmd.FwPointNo; + TxMoCmd.SubSystem = RxMoCmd.SubSystem; + sprintf(TxMoCmd.strParam, I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxMoCmd.PointID); + + LOGDEBUG("通信已断开 MO混合量执行失败 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", RxMoCmd.CtrlActType, RxMoCmd.iValue, RxMoCmd.RtuName, RxMoCmd.PointID); + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&TxMoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1, &TxMoCmd); + } + } + else + if (m_ptrCFesRtu->GetRxDefCmdNum() > 0) + { + if (m_ptrCFesRtu->ReadRxDefCmd(1, &RxDefCmd) == 1) + { + //memset(&TxDefCmd,0,sizeof(TxDefCmd)); + strcpy(TxDefCmd.TableName, RxDefCmd.TableName); + strcpy(TxDefCmd.ColumnName, RxDefCmd.ColumnName); + strcpy(TxDefCmd.TagName, RxDefCmd.TagName); + strcpy(TxDefCmd.RtuName, RxDefCmd.RtuName); + TxDefCmd.DevId = RxDefCmd.DevId; + TxDefCmd.CmdNum = RxDefCmd.CmdNum; + TxDefCmd.VecCmd = RxDefCmd.VecCmd; + TxDefCmd.retStatus = CN_ControlFailed; + sprintf(TxDefCmd.strParam, I18N("自定义命令输出失败!RtuNo:%d ").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo); + LOGERROR("通信已断开 自定义命令输出失败!RtuNo:%d", m_ptrCFesRtu->m_Param.RtuNo); + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &TxDefCmd); + } + } +} + +/** +* @brief CModbusRtuV2DataProcThread::InitProtocolBlockDataIndexMapping +* 数据块关联数据索引表初始化 +* @param RtuPtr +* @return +*/ +void CModbusRtuV2DataProcThread::InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuPtr) +{ + int i, j; + int blockId, funCode, startAddr, dataLen; + SModbusCmd *pCmd; + SModbusCmdBuf cmd = RtuPtr->m_Param.ModbusCmdBuf; + SFesAiIndex *pAiIndex; + SFesDiIndex *pDiIndex; + SFesAccIndex *pAccIndex; + SFesMiIndex *pMiIndex; + vector pAiBlockIndexs; + vector pDiBlockIndexs; + vector pAccBlockIndexs; + vector pMiBlockIndexs; + + //根据数据块帧类别进行分类 + for (i = 0; i < cmd.num; i++) + { + pCmd = cmd.pCmd + i; + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + SFesBaseBlockDataIndexInfo blockDataIndexInfoTemp; + //blockDataIndexInfoTemp.headIndex = -1; + //blockDataIndexInfoTemp.tailIndex = -1; + blockDataIndexInfoTemp.headIndex = 0xFFFFFFFF; + blockDataIndexInfoTemp.tailIndex = 0xFFFFFFFF; + LOGDEBUG("pCmd->Type:%d", pCmd->Type); + if ((pCmd->Type >= DI_BYTE_LH) && (pCmd->Type <= DI_UWord_LH)) //DI + { + pDiBlockIndexs.push_back(i); + m_DiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_DiBlockDataIndexInfo.insert blockId:%d", blockId); + } + else if (((pCmd->Type >= AI_Word_HL) && (pCmd->Type <= AI_Float_LL)) || (pCmd->Type == AI_SIGNEDFLAG16_HL) || (pCmd->Type == AI_SIGNEDFLAG32_HL) || (pCmd->Type == AI_Hybrid_Type)) //AI + { + pAiBlockIndexs.push_back(i); + m_AiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_AiBlockDataIndexInfo.insert blockId:%d", blockId); + } + else if (((pCmd->Type >= ACC_Word_HL) && (pCmd->Type <= ACC_Float_LL)) || (pCmd->Type == ACC_Hybrid_Type))//ACC + { + pAccBlockIndexs.push_back(i); + m_AccBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_AccBlockDataIndexInfo.insert blockId:%d", blockId); + } + else if ((pCmd->Type >= MI_Word_HL) && (pCmd->Type <= MI_UDWord_LL))//MI + { + pMiBlockIndexs.push_back(i); + m_MiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_MiBlockDataIndexInfo.insert blockId:%d", blockId); + } + + } + + //对不同帧类别的数据块存储起始索引和结束索引 + for (j = 0; j < RtuPtr->m_MaxAiIndex; j++) //Ai + { + pAiIndex = RtuPtr->m_pAiIndex + j; + + for (i = 0; i < pAiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pAiBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pAiIndex->Param2 == funCode) && (startAddr <= pAiIndex->Param3) && (pAiIndex->Param3 < (startAddr + dataLen))) + { + if ((m_AiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_AiBlockDataIndexInfo.at(blockId).headIndex = pAiIndex->PIndex; + + m_AiBlockDataIndexInfo.at(blockId).tailIndex = pAiIndex->PIndex; + } + } + } + + for (j = 0; j < RtuPtr->m_MaxDiIndex; j++) //Di + { + pDiIndex = RtuPtr->m_pDiIndex + j; + + for (i = 0; i < pDiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pDiBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pDiIndex->Param2 == funCode) && (startAddr <= pDiIndex->Param3) && (pDiIndex->Param3 < (startAddr + dataLen))) + { + if ((m_DiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_DiBlockDataIndexInfo.at(blockId).headIndex = pDiIndex->PIndex; + + m_DiBlockDataIndexInfo.at(blockId).tailIndex = pDiIndex->PIndex; + } + } + } + + for (j = 0; j < RtuPtr->m_MaxAccIndex; j++) //Acc + { + pAccIndex = RtuPtr->m_pAccIndex + j; + + for (i = 0; i < pAccBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pAccBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pAccIndex->Param2 == funCode) && (startAddr <= pAccIndex->Param3) && (pAccIndex->Param3 < (startAddr + dataLen))) + { + if ((m_AccBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_AccBlockDataIndexInfo.at(blockId).headIndex = pAccIndex->PIndex; + + m_AccBlockDataIndexInfo.at(blockId).tailIndex = pAccIndex->PIndex; + } + } + } + + for (j = 0; j < RtuPtr->m_MaxMiIndex; j++) //Mi + { + pMiIndex = RtuPtr->m_pMiIndex + j; + + for (i = 0; i < pMiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pMiBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pMiIndex->Param2 == funCode) && (startAddr <= pMiIndex->Param3) && (pMiIndex->Param3 < (startAddr + dataLen))) + { + if ((m_MiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_MiBlockDataIndexInfo.at(blockId).headIndex = pMiIndex->PIndex; + + m_MiBlockDataIndexInfo.at(blockId).tailIndex = pMiIndex->PIndex; + } + } + } + + map::iterator iter; + iter = m_AiBlockDataIndexInfo.begin(); + while (iter != m_AiBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Ai--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + iter = m_DiBlockDataIndexInfo.begin(); + while (iter != m_DiBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Di--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + iter = m_AccBlockDataIndexInfo.begin(); + while (iter != m_AccBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Acc--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + iter = m_MiBlockDataIndexInfo.begin(); + while (iter != m_MiBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Mi--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } +} + +/* +@brief CModbusRtuV2DataProcThread::ClearComByChanNo + 通道切换、关闭通道时需要清除通道的状态 +*/ +void CModbusRtuV2DataProcThread::ClearComByChanNo(int ChanNo) +{ + CFesChanPtr ptrChan; + + ptrChan = m_ptrCFesBase->GetChanDataByChanNo(ChanNo); + if (ptrChan != NULL) + { + ptrChan->SetComThreadRunFlag(CN_FesStopFlag); + ptrChan->SetChangeFlag(CN_FesChanUnChange); + + switch (ptrChan->m_Param.CommType) + { + case CN_FesSerialPort: + if ((m_ptrComSerial != NULL) && (ptrChan->m_ComThreadRun == CN_FesRunFlag)) + m_ptrComSerial->CloseChan(ptrChan); + break; + case CN_FesTcpClient: + if ((m_ptrComClient != NULL) && (ptrChan->m_ComThreadRun == CN_FesRunFlag)) + m_ptrComClient->TcpClose(ptrChan); + break; + default: + LOGDEBUG("ClearComByChanNo(%d) error,invaild CommType(%d) ", ptrChan->m_Param.ChanNo, ptrChan->m_Param.CommType); + break; + } + LOGDEBUG("ClearComByChanNo(%d) OK", ptrChan->m_Param.ChanNo); + } + +} + +void CModbusRtuV2DataProcThread::SetComByChanNo(int ChanNo) +{ + CFesChanPtr ptrChan; + + ptrChan = m_ptrCFesBase->GetChanDataByChanNo(ChanNo); + if (ptrChan != NULL) + { + ptrChan->SetComThreadRunFlag(CN_FesRunFlag); + ptrChan->SetChangeFlag(CN_FesChanUnChange); + LOGDEBUG("SetComByChanNo(%d) OK", ChanNo); + } +} diff --git a/product/src/fes/protocol/modbus_rtuV2/ModbusRtuV2DataProcThread.h b/product/src/fes/protocol/modbus_rtuV2/ModbusRtuV2DataProcThread.h new file mode 100644 index 00000000..97d22f73 --- /dev/null +++ b/product/src/fes/protocol/modbus_rtuV2/ModbusRtuV2DataProcThread.h @@ -0,0 +1,168 @@ +#pragma once + +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "ComSerialPort.h" +#include "ComTcpClient.h" +using namespace iot_public; + +#define CN_MODBUSRTU_MAX_CMD_LEN 256 + +//功能码定义 +const int FunCode_01H = 1; /*读开关量输出*/ +const int FunCode_02H = 2; /*读开关量输入*/ +const int FunCode_03H = 3; /*读保持寄存器数据*/ +const int FunCode_04H = 4; /*读输入寄存器数据*/ +const int FunCode_05H = 5; /*写单个线圈*/ +const int FunCode_06H = 6; /*写单个保持寄存器*/ +const int FunCode_10H = 16; /*写多个保持寄存器*/ + +//SModbusRtuV2AppData状态 +const int CN_ModbusRtuV2AppState_init = 0; +const int CN_ModbusRtuV2AppState_waitInit = 1; +const int CN_ModbusRtuV2AppState_idle = 2; +const int CN_ModbusRtuV2AppState_waitResp = 3; +const int CN_ModbusRtuV2AppState_waitControlResp = 4; + +//SModbusRtuV2AppData最近发送的控制命令类型 +const int CN_ModbusRtuV2NoCmd = 0; +const int CN_ModbusRtuV2DoCmd = 1; //遥控 +const int CN_ModbusRtuV2AoCmd = 2; //遥调 +const int CN_ModbusRtuV2MoCmd = 3; +const int CN_ModbusRtuV2DefCmd = 4; + +const int CN_ModbusRtuV2MaxRTUs = 254; + +#define MODBUSRTUV2_K_MAX_POINT_INDEX 200 //接收缓存最大索引 + +/***************保护定值区*********************************** / +/***KEY_name***/ +const static string CMD_TYPE = "cmd_type"; //命令类型 +const static string DEV_ID = "dev_id"; //设备id +const static string DOT_NO = "dot_no"; //定值代号 +const static string GROUP_NO = "group_no"; //定值组号 +const static string CUR_GROUP = "cur_group"; //当前定值组 +const static string EDIT_GROUP = "edit_group"; //修改定值组 +const static string CUR_VALUE = "cur_value"; //当前值 +const static string EDIT_VALUE = "edit_value"; //修改值 +const static string ACK_VALUE = "ack_value"; //反校值 + +/***value***/ +const static string CONST_VALUE_READ = "const_value_read"; //读取保护定值 +const static string CONST_GROUP_EDIT = "const_group_edit"; //修改定值组号 +const static string CONST_VALUE_EDIT = "const_value_edit"; //修改保护定值 +const static string CONST_VALUE_AFFIRM = "const_value_affirm"; //修改保护定值确认 + +//MODBUS 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct { + int index; + int state; + + int lastCotrolcmd; + byte lastCmdData[CN_MODBUSRTU_MAX_CMD_LEN]; + int lastCmdDataLen; + SModbusCmd lastCmd; + SFesRxDoCmd doCmd; + SFesRxAoCmd aoCmd; + SFesRxMoCmd moCmd; + SFesRxDefCmd defCmd; + int setCmdCount; + + uint64 controlTimeout; + + //修改定值 + int deviceId; //设备id + int CmdNum; //健值对数 + int modifyDzNum; //修改定值个数 + + vector currentValue; //当前值容器 + vector dotNo; //定值代号容器 + vector editValue; //修改值容器 + +}SModbusRtuV2AppData; + +typedef struct { + uint32 headIndex; + uint32 tailIndex; +}SFesBaseBlockDataIndexInfo; //数据块关联数据索引信息 + +class CModbusRtuV2DataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + CModbusRtuV2DataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan); + virtual ~CModbusRtuV2DataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + /* + @brief CModbusRtuV2DataProcThread::ClearComByChanNo + 通道切换、关闭通道时需要清除通道的状态 + */ + void ClearComByChanNo(int ChanNo); + void SetComByChanNo(int ChanNo); + + CFesBase* m_ptrCFesBase; + + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区 + CFesRtuPtr m_ptrCInsertFesRtu; //当前插入命令使用RTU数据区 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SModbusRtuV2AppData m_AppData; //内部应用数据结构 + + CComTcpClientPtr m_ptrComClient; + CComSerialPortPtr m_ptrComSerial; + + map m_AiBlockDataIndexInfo; //2021-06-25 ljj + map m_DiBlockDataIndexInfo; + map m_AccBlockDataIndexInfo; + map m_MiBlockDataIndexInfo; + +private: + int m_timerCount; + int m_timerCountReset; + + int SendProcess(); + int RecvComData(); + int InsertCmdProcess(); + int DoCmdProcess(byte *Data, int dataSize); + int AoCmdProcess(byte *Data, int dataSize); + //int MoCmdProcess(byte *Data, int dataSize); + //int SettingCmdProcess(byte *Data, int dataSize); + int DefCmdProcess(byte *Data, int dataSize); + int GetPollingCmd(SModbusCmd *pCmd); + int PollingCmdProcess(); + void SendDataToPort(byte *Data, int Size); + int CrcSum(byte *Data, int Count); + int RecvDataProcess(byte *Data, int DataSize); + void Cmd01RespProcess(byte *Data, int DataSize); + void Cmd03RespProcess(byte *Data, int DataSize); + int Cmd03RespProcess_BitGroup(SFesDi *pDi,int diValue); + void Cmd05RespProcess(byte *Data, int DataSize); + void Cmd06RespProcess(byte *Data, int DataSize); + void Cmd10RespProcess(byte *Data, int DataSize); + bool CmdControlRespProcess(byte *Data, int DataSize, int okFlag); + void SetSendCmdFlag(); + void CmdTypeHybridProcess(byte *Data, int DataSize); + void ErrorControlRespProcess(); + void InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuPtr); + + //以下函数适合通信管理机PCS3000老模版 + void Cmd01RespProcess_PCS3000(byte *Data, int DataSize); + void Cmd03RespProcess_PCS3000(byte *Data, int DataSize); + int Cmd03RespProcess_BitGroup_PCS3000(SFesDi *pDi, int diValue); + void CmdTypeHybridProcess_PCS3000(byte *Data, int DataSize); + + +}; + +typedef boost::shared_ptr CModbusRtuV2DataProcThreadPtr; diff --git a/product/src/fes/protocol/modbus_rtuV2/modbus_rtuV2.pro b/product/src/fes/protocol/modbus_rtuV2/modbus_rtuV2.pro new file mode 100644 index 00000000..8b97c1a3 --- /dev/null +++ b/product/src/fes/protocol/modbus_rtuV2/modbus_rtuV2.pro @@ -0,0 +1,34 @@ +#CONFIG -= qt +QT += serialport +TARGET = modbus_rtuV2 +TEMPLATE = lib + +SOURCES += \ + ModbusRtuV2.cpp \ + ModbusRtuV2DataProcThread.cpp \ + ../combase/ComSerialPort.cpp \ + ../combase/ComTcpClient.cpp \ + +HEADERS += \ + ModbusRtuV2.h \ + ModbusRtuV2DataProcThread.h \ + ../../include/ComSerialPort.h \ + ../../include/ComTcpClient.h \ + +INCLUDEPATH += ../../include/ + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase +LIBS += -lprotobuf -lboost_locale -lboost_regex -lrdb_api + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/fes/protocol/modbus_rtu_dt/ModbusRtuDT.cpp b/product/src/fes/protocol/modbus_rtu_dt/ModbusRtuDT.cpp new file mode 100644 index 00000000..5dc8721d --- /dev/null +++ b/product/src/fes/protocol/modbus_rtu_dt/ModbusRtuDT.cpp @@ -0,0 +1,834 @@ +/* +@file ModbusRtuDT.cpp +@brief +@author Rong +@histroy +2020-04-26 thxiao 增加按新CComSerialPort类调用接口 + +*/ + +#include "ModbusRtuDT.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "dbms/rdb_api/CRdbAccessEx.h" +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/rdb_api/RdbDefine.h" + +using namespace iot_public; + +CModbusRtuDT ModbusRtuDT; +bool g_ModbusRtuDTIsMainFes=false; +bool g_ModbusRtuDTChanelRun=true; + +int EX_SetBaseAddr(void *address) +{ + ModbusRtuDT.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + ModbusRtuDT.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + ModbusRtuDT.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + ModbusRtuDT.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + ModbusRtuDT.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + boost::ignore_unused_variable_warning(flag); + + g_ModbusRtuDTChanelRun =false;//使所有的线程退出。 + ModbusRtuDT.InformComThreadExit(); + return iotSuccess; +} +CModbusRtuDT::CModbusRtuDT() +{ + m_ptrCFesBase = nullptr; + m_initRtuFlag = 0; +} + +CModbusRtuDT::~CModbusRtuDT() +{ + + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); + + LOGDEBUG("CModbusRtuDT::~CModbusRtuDT() 退出"); +} + + +int CModbusRtuDT::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + } + ReadConfigParam(); + + return iotSuccess; +} + +int CModbusRtuDT::SetProperty(int IsMainFes) +{ + g_ModbusRtuDTIsMainFes = IsMainFes; + LOGDEBUG("CModbusRtuDT::SetProperty g_ModbusRtuDTIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief CModbusRtuDT::OpenChan + * 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CModbusRtuDT::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if (m_initRtuFlag == 0) + { + InitProcess(); + m_initRtuFlag = 1; + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + CModbusRtuDTDataProcThreadPtr ptrCDataProc; + ptrCDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_vecAppParam); + if (ptrCDataProc == NULL) + { + LOGERROR("CModbusRtuDT EX_OpenChan() ChanNo:%d create CModbusRtuDTDataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + if ((OpenFlag == CN_FesChanThread_Flag) || (OpenFlag == CN_FesChanAndDataThread_Flag)) + { + switch (ptrFesChan->m_Param.CommType) + { + case CN_FesSerialPort: + case CN_FesTcpClient: + if (ptrFesChan->m_ComThreadRun == CN_FesStopFlag) + { + SetComByChanNo(MainChanNo, ChanNo); + } + break; + default: + return iotFailed; + } + } + + return iotSuccess; + +} + +/** + * @brief CModbusRtuDT::CloseChan + * 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CModbusRtuDT::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("CModbusRtuDT::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + if ((CloseFlag == CN_FesChanThread_Flag) || (CloseFlag == CN_FesChanAndDataThread_Flag)) + { + if (ptrFesChan->m_ComThreadRun == CN_FesRunFlag) + { + ClearComByChanNo(MainChanNo, ChanNo); + } + } + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + + return iotSuccess; +} + +/** +* @brief CModbusRtuDT::ChanTimer +* 通道定时器,主通道会定时调用 +* @param MainChanNo 主通道号 +* @return +*/ +int CModbusRtuDT::ChanTimer(int MainChanNo) +{ + boost::ignore_unused_variable_warning(MainChanNo); + + return iotSuccess; +} + +/* + 根据通道号,清除数据线程 +*/ +void CModbusRtuDT::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + CModbusRtuDTDataProcThreadPtr ptrPort; + + if ((tempNum = (int)m_CDataProcQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) + { + ptrPort = *it; + if (ptrPort->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CDataProcQueue.erase(it);//会调用CModbusRtuDTDataProcThread::~CModbusRtuDTDataProcThread()退出线程 + LOGDEBUG("CModbusRtuDT::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + + +/** + * @brief CMODBUS::InformTcpThreadExit + * 设置线程退出标志,通知线程退出 + * @return + */ +void CModbusRtuDT::InformComThreadExit() +{ + LOGDEBUG("CModbusRtuDT::InformTcpThreadExit() "); + +} + +void CModbusRtuDT::InitProcess() +{ + int i, RtuCount, ProtocolId; + CFesChanPtr chanPtr; + + ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"modbus_rtu_dt"); + if (ProtocolId == -1) + { + LOGERROR("InitProcess() can't found ProtocolId."); + return; + } + + RtuCount = static_cast(m_ptrCFesBase->m_vectCFesRtuPtr.size()); + for (i = 0; i < RtuCount; i++) + { + if (m_ptrCFesBase->m_vectCFesRtuPtr[i]->m_Param.Used) + { + //found the Chan; + if ((chanPtr = GetChanDataByChanNo(m_ptrCFesBase->m_vectCFesRtuPtr[i]->m_Param.ChanNo)) != NULL) + { + if (chanPtr->m_Param.Used && (chanPtr->m_Param.ProtocolId == ProtocolId)) + InitProtocolPointMapping(m_ptrCFesBase->m_vectCFesRtuPtr[i]); //初始化转发表结构参数 + } + } + } +} + +bool CModbusRtuDT::InitProtocolPointMapping(CFesRtuPtr RtuPtr) +{ + iot_dbms::CRdbAccessEx RdbAiTable; + iot_dbms::CRdbAccessEx RdbAoTable; + iot_dbms::CRdbAccessEx RdbDiTable; + iot_dbms::CRdbAccessEx RdbDoTable; + iot_dbms::CRdbAccessEx RdbAccTable; + iot_dbms::CRdbAccessEx RdbMiTable; + iot_dbms::CRdbAccessEx RdbMoTable; + int count, ret; + SFesAiIndex *pAiIndex; + SFesDiIndex *pDiIndex; + SFesAccIndex *pAccIndex; + SFesMiIndex *pMiIndex; + SFesAi *pAi; + SFesDi *pDi; + SFesAcc *pAcc; + SFesMi *pMi; + int i,j; + + //条件判断 + iot_dbms::CONDINFO con; + con.relationop = ATTRCOND_EQU; + con.conditionval = RtuPtr->m_Param.RtuNo; + strcpy(con.name, "rtu_no"); + + //READ AI TABLE + std::vector VecAiParam; + std::vector vecAiColumn; + std::vector vecAiOrder; + + vecAiColumn.push_back("rtu_no"); + vecAiColumn.push_back("dot_no"); + vecAiColumn.push_back("res_para_int1"); + vecAiColumn.push_back("res_para_int2"); + vecAiColumn.push_back("res_para_int3"); + vecAiColumn.push_back("res_para_int4"); + + vecAiOrder.push_back("res_para_int2"); + vecAiOrder.push_back("res_para_int3"); + + ret = RdbAiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_AI_TBL); + if (ret == false) + { + LOGERROR("RdbAiTable::Open error"); + return iotFailed; + } + ret = RdbAiTable.selectOneColumnOneOrder(con, VecAiParam, vecAiColumn, vecAiOrder);//默认顺序 ljj + if (ret == false) + { + LOGERROR("RdbAiTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbAiTable.close(); + if (ret == false) + { + LOGERROR("RdbAiTable::close error"); + return iotFailed; + } + count = static_cast(VecAiParam.size()); + if (count > 0) + { + //RtuPtr->m_MaxAiIndex = VecAiParam[count-1].Param1+1; + RtuPtr->m_MaxAiIndex = count; //ljj + if (RtuPtr->m_MaxAiIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pAiIndex = (SFesAiIndex*)malloc(RtuPtr->m_MaxAiIndex * sizeof(SFesAiIndex)); + if (RtuPtr->m_pAiIndex != NULL) + { + memset(RtuPtr->m_pAiIndex, 0xff, RtuPtr->m_MaxAiIndex * sizeof(SFesAiIndex)); + for (j = 0; j < RtuPtr->m_MaxAiIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pAiIndex = RtuPtr->m_pAiIndex + j; + pAiIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + pAiIndex = RtuPtr->m_pAiIndex + j; + pAiIndex->PointNo = VecAiParam[j].PointNo; + pAiIndex->PIndex = j; + if ((pAiIndex->PointNo >= 0) && (pAiIndex->PointNo < RtuPtr->m_MaxAiPoints)) + { + pAi = RtuPtr->m_pAi + pAiIndex->PointNo; + //pAiIndex->DevId = pAi->DevId; + pAiIndex->Param2 = pAi->Param2; + pAiIndex->Param3 = pAi->Param3; + pAiIndex->Param4 = pAi->Param4; + pAiIndex->Used = 1; + } + } + } + else + { + RtuPtr->m_MaxAiIndex = 0; + LOGDEBUG("RtuNo:%d AI protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + + //READ DI TABLE + //ljj di新增按位排序 + std::vector VecDiParam; + std::vector vecDiColumn; + std::vector vecDiOrder; + + vecDiColumn.push_back("rtu_no"); + vecDiColumn.push_back("dot_no"); + vecDiColumn.push_back("res_para_int1"); + vecDiColumn.push_back("res_para_int2"); + vecDiColumn.push_back("res_para_int3"); + vecDiColumn.push_back("res_para_int4"); + + vecDiOrder.push_back("res_para_int2"); + vecDiOrder.push_back("res_para_int3"); + vecDiOrder.push_back("res_para_int4"); + + ret = RdbDiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_DI_TBL); + if (ret == false) + { + LOGERROR("RdbDiTable::Open error"); + return iotFailed; + } + ret = RdbDiTable.selectOneColumnOneOrder(con, VecDiParam, vecDiColumn, vecDiOrder);//默认顺序 + if (ret == false) + { + LOGERROR("RdbDiTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbDiTable.close(); + if (ret == false) + { + LOGERROR("RdbDiTable::close error"); + return iotFailed; + } + count = static_cast(VecDiParam.size()); + if (count > 0) + { + RtuPtr->m_MaxDiIndex = count; + if (RtuPtr->m_MaxDiIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pDiIndex = (SFesDiIndex*)malloc(RtuPtr->m_MaxDiIndex * sizeof(SFesDiIndex)); + if (RtuPtr->m_pDiIndex != NULL) + { + memset(RtuPtr->m_pDiIndex, 0xff, RtuPtr->m_MaxDiIndex * sizeof(SFesDiIndex)); + for (j = 0; j < RtuPtr->m_MaxDiIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pDiIndex = RtuPtr->m_pDiIndex + j; + pDiIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + pDiIndex = RtuPtr->m_pDiIndex + j; + pDiIndex->PointNo = VecDiParam[j].PointNo; + pDiIndex->PIndex = j; + if ((pDiIndex->PointNo >= 0) && (pDiIndex->PointNo < RtuPtr->m_MaxDiPoints)) + { + pDi = RtuPtr->m_pDi + pDiIndex->PointNo; + //pDiIndex->DevId = pDi->DevId; + pDiIndex->Param2 = pDi->Param2; + pDiIndex->Param3 = pDi->Param3; + pDiIndex->Param4 = pDi->Param4; + pDiIndex->Used = 1; + + } + } + } + else + { + RtuPtr->m_MaxDiIndex = 0; + LOGDEBUG("RtuNo:%d Di protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + //READ ACC TABLE + std::vector VecAccParam; + std::vector vecAccColumn; + std::vector vecAccOrder; + + vecAccColumn.push_back("rtu_no"); + vecAccColumn.push_back("dot_no"); + vecAccColumn.push_back("res_para_int1"); + vecAccColumn.push_back("res_para_int2"); + vecAccColumn.push_back("res_para_int3"); + vecAccColumn.push_back("res_para_int4"); + + vecAccOrder.push_back("res_para_int2"); + vecAccOrder.push_back("res_para_int3"); + + ret = RdbAccTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_ACC_TBL); + if (ret == false) + { + LOGERROR("RdbAccTable::Open error"); + return iotFailed; + } + ret = RdbAccTable.selectOneColumnOneOrder(con, VecAccParam, vecAccColumn, vecAccOrder);//默认顺序 + if (ret == false) + { + LOGERROR("RdbAccTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbAccTable.close(); + if (ret == false) + { + LOGERROR("RdbAccTable::close error"); + return iotFailed; + } + + count = static_cast(VecAccParam.size()); + if (count > 0) + { + //RtuPtr->m_MaxAccIndex = VecAccParam[count-1].Param1+1; + RtuPtr->m_MaxAccIndex = count; + if (RtuPtr->m_MaxAccIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pAccIndex = (SFesAccIndex*)malloc(RtuPtr->m_MaxAccIndex * sizeof(SFesAccIndex)); + if (RtuPtr->m_pAccIndex != NULL) + { + memset(RtuPtr->m_pAccIndex, 0xff, RtuPtr->m_MaxAccIndex * sizeof(SFesAccIndex)); + for (j = 0; j < RtuPtr->m_MaxAccIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pAccIndex = RtuPtr->m_pAccIndex + j; + pAccIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + //2023-03-03 thxiao 不需要判断Param1 + //if (VecAccParam[j].Param1 >= 0 && VecAccParam[j].Param1 < RtuPtr->m_MaxAccIndex) + //{ + pAccIndex = RtuPtr->m_pAccIndex + j; + pAccIndex->PointNo = VecAccParam[j].PointNo; + pAccIndex->PIndex = j; + if ((pAccIndex->PointNo >= 0) && (pAccIndex->PointNo < RtuPtr->m_MaxAccPoints)) + { + pAcc = RtuPtr->m_pAcc + pAccIndex->PointNo; + //pAccIndex->DevId = pAcc->DevId; + pAccIndex->Param2 = pAcc->Param2; + pAccIndex->Param3 = pAcc->Param3; + pAccIndex->Param4 = pAcc->Param4; + pAccIndex->Used = 1; + } + //} + //else + //{ + // LOGDEBUG("RtuNo:%d Acc PointIndex %d exceed limit %d.", RtuPtr->m_Param.RtuNo, VecAccParam[j].Param1, RtuPtr->m_MaxAccIndex); + //} + } + } + else + { + RtuPtr->m_MaxAccIndex = 0; + LOGDEBUG("RtuNo:%d Acc protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + //READ MI TABLE + std::vector VecMiParam; + std::vector vecMiColumn; + std::vector vecMiOrder; + + vecMiColumn.push_back("rtu_no"); + vecMiColumn.push_back("dot_no"); + vecMiColumn.push_back("res_para_int1"); + vecMiColumn.push_back("res_para_int2"); + vecMiColumn.push_back("res_para_int3"); + vecMiColumn.push_back("res_para_int4"); + + vecMiOrder.push_back("res_para_int2"); + vecMiOrder.push_back("res_para_int3"); + + ret = RdbMiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_MI_TBL); + if (ret == false) + { + LOGERROR("RdbMiTable::Open error"); + return iotFailed; + } + ret = RdbMiTable.selectOneColumnOneOrder(con, VecMiParam, vecMiColumn, vecMiOrder);//默认顺序 + if (ret == false) + { + LOGERROR("RdbMiTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbMiTable.close(); + if (ret == false) + { + LOGERROR("RdbMiTable::close error"); + return iotFailed; + } + count = static_cast(VecMiParam.size()); + if (count > 0) + { + //RtuPtr->m_MaxMiIndex = VecMiParam[count-1].Param1+1; + RtuPtr->m_MaxMiIndex = count; + if (RtuPtr->m_MaxMiIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pMiIndex = (SFesMiIndex*)malloc(RtuPtr->m_MaxMiIndex * sizeof(SFesMiIndex)); + if (RtuPtr->m_pMiIndex != NULL) + { + memset(RtuPtr->m_pMiIndex, 0xff, RtuPtr->m_MaxMiIndex * sizeof(SFesMiIndex)); + for (j = 0; j < RtuPtr->m_MaxMiIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pMiIndex = RtuPtr->m_pMiIndex + j; + pMiIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + //2023-03-03 thxiao 不需要判断Param1 + //if (VecMiParam[j].Param1 >= 0 && VecMiParam[j].Param1 < RtuPtr->m_MaxMiIndex) + //{ + pMiIndex = RtuPtr->m_pMiIndex + j; + pMiIndex->PointNo = VecMiParam[j].PointNo; + pMiIndex->PIndex = j; + if ((pMiIndex->PointNo >= 0) && (pMiIndex->PointNo < RtuPtr->m_MaxMiPoints)) + { + pMi = RtuPtr->m_pMi + pMiIndex->PointNo; + //pMiIndex->DevId = pMi->DevId; + pMiIndex->Param2 = pMi->Param2; + pMiIndex->Param3 = pMi->Param3; + pMiIndex->Param4 = pMi->Param4; + pMiIndex->Used = 1; + } + //} + //else + //{ + // LOGDEBUG("RtuNo:%d Mi PointIndex %d exceed limit %d.", RtuPtr->m_Param.RtuNo, VecMiParam[j].Param1, RtuPtr->m_MaxMiIndex); + //} + } + } + else + { + RtuPtr->m_MaxMiIndex = 0; + LOGDEBUG("RtuNo:%d Mi protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + + //DO Param7关连DI PIndex序号,方便遥控回读当前值 + SFesDo *pDo; + for (i = 0; i < RtuPtr->m_MaxDoPoints;i++) + { + pDo = RtuPtr->m_pDo + i; + pDo->Param7 = -1; + if (!pDo->Used) + continue; + for (j = 0; j < RtuPtr->m_MaxDiIndex; j++) + { + pDiIndex = RtuPtr->m_pDiIndex + j; + pDi = RtuPtr->m_pDi + pDiIndex->PointNo; + if ((pDi->Param2!=0)&&(pDo->Param3 == pDi->Param3) && (pDo->Param4 == pDi->Param4)) + { + pDo->Param7 = j; + LOGDEBUG("RTUNo=%d pDo->PointNo=%d Param3=%d Param4=%d pDo->Param7=%d pDi->PointNo=%d", RtuPtr->m_Param.RtuNo, pDo->PointNo, pDo->Param3, pDo->Param4, pDo->Param7, pDi->PointNo); + break; + } + } + } + + + //AO Param7关连AI PIndex序号,方便遥控回读当前值 + SFesAo *pAo; + for (i = 0; i < RtuPtr->m_MaxAoPoints; i++) + { + pAo = RtuPtr->m_pAo + i; + pAo->Param7 = -1; + if (!pAo->Used) + continue; + for (j = 0; j < RtuPtr->m_MaxAiIndex; j++) + { + pAiIndex = RtuPtr->m_pAiIndex + j; + pAi = RtuPtr->m_pAi + pAiIndex->PointNo; + if ((pAi->Param2 != 0) && (pAo->Param3 == pAi->Param3)) + { + pAo->Param7 = j; + // LOGDEBUG("pAo->PointNo=%d Param3=%d pAo->Param7=%d pAi->PointNo=%d", pAo->PointNo, pAo->Param3, pAo->Param7, pAi->PointNo); + break; + } + } + } + + //AI类型为ACC数据类型时,AI Param7关连Acc PIndex序号,方便遥控回读当前值 + for (i = 0; i < RtuPtr->m_MaxAiIndex; i++) + { + pAiIndex = RtuPtr->m_pAiIndex + i; + pAi = RtuPtr->m_pAi + pAiIndex->PointNo; + pAi->Param7 = -1; + if((pAi->Param4>= ACC_Word_HL)&&(pAi->Param4<= ACC_Float_LL)) + { + //LOGDEBUG("pAi->PointNo=%d Param3=%d pAi->Param7=%d", pAi->PointNo, pAi->Param3, pAi->Param7); + for (j = 0; j < RtuPtr->m_MaxAccPoints; j++) + { + pAcc = RtuPtr->m_pAcc + j; + if (!pAcc->Used) + continue; + //LOGDEBUG("pAcc->PointNo=%d Param3=%d pAi->Param3=%d", pAcc->PointNo, pAcc->Param3, pAi->Param3); + if (pAi->Param3 == pAcc->Param3) + { + pAi->Param7 = pAcc->PointNo; + //LOGDEBUG("pAi->PointNo=%d Param3=%d pAi->Param7=%d pAcc->PointNo=%d", pAi->PointNo, pAi->Param3, pAi->Param7, pAcc->PointNo); + break; + } + } + } + } + + //2022-12-26 主开关增加虚拟告警点及告警使能点 + //if (RtuPtr->m_Param.ResParam3 == CN_ModbusRtuDT_YD) + { + SFesDi *pDi1; + SFesDi *pDi2; + for (i = 0; i < RtuPtr->m_MaxDiPoints; i++) + { + pDi1 = RtuPtr->m_pDi + i; + pDi1->Param7 = -1; + if (!pDi1->Used&&(pDi1->Param3!= 73000)) + continue; + + for (j = 0; j < RtuPtr->m_MaxDiPoints; j++) + { + pDi2 = RtuPtr->m_pDi + j; + if ((pDi1->Param3 == 73000) && (pDi2->Param3 == 73) && (pDi1->Param4 == pDi2->Param4)&&(pDi2->Param5==5)) + { + pDi1->Param7 = pDi2->PointNo;//虚拟的告警使能点和告警点号相关连 + LOGDEBUG("RtuPtr->m_Param.RtuNo 告警使能点pDi1->PointNo=%d Param3=%d Param4=%d 告警点pDi2->PointNo=%d Param3=%d Param4=%d", RtuPtr->m_Param.RtuNo,pDi1->PointNo, pDi1->Param3, pDi1->Param4, pDi2->PointNo, pDi2->Param3, pDi2->Param4); + } + } + } + } + + return iotSuccess; +} + + +void CModbusRtuDT::SetComByChanNo(int MainChanNo, int ChanNo) +{ + CModbusRtuDTDataProcThreadPtr ptrDataProc; + int found = 0; + + if (m_CDataProcQueue.size() <= 0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin(); it != m_CDataProcQueue.end(); it++) + { + ptrDataProc = *it; + if (ptrDataProc->m_ptrCFesChan->m_Param.ChanNo == MainChanNo) + { + found = 1; + ptrDataProc->SetComByChanNo(ChanNo); + break; + } + } + if (found) + { + LOGDEBUG("SetComByChanNo() MainChanNo=%d ChanNo=%d OK", MainChanNo, ChanNo); + } + else + { + LOGDEBUG("SetComByChanNo() MainChanNo=%d ChanNo=%d failed", MainChanNo, ChanNo); + } +} + + +void CModbusRtuDT::ClearComByChanNo(int MainChanNo, int ChanNo) +{ + CModbusRtuDTDataProcThreadPtr ptrDataProc; + int found = 0; + + if (m_CDataProcQueue.size() <= 0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin(); it != m_CDataProcQueue.end(); it++) + { + ptrDataProc = *it; + if (ptrDataProc->m_ptrCFesChan->m_Param.ChanNo == MainChanNo) + { + found = 1; + ptrDataProc->ClearComByChanNo(ChanNo); + break; + } + } + if (found) + { + LOGDEBUG("ClearComByChanNo() MainChanNo=%d ChanNo=%d OK", MainChanNo, ChanNo); + } + else + { + LOGDEBUG("ClearTcpClientdByChanNo() MainChanNo=%d ChanNo=%d failed", MainChanNo, ChanNo); + } +} + + +/** +* @brief CIEC104::ReadConfigParam +* 读取配置文件 +* @return 成功返回iotSuccess,失败返回iotFailed +*/ + +int CModbusRtuDT::ReadConfigParam() +{ + CCommonConfigParse config; + int ivalue; + char strRtuNo[48]; + SModbusRtuDTConfigParam param; + int items, i, j; + CFesChanPtr ptrChan; //CHAN数据区 + CFesRtuPtr ptrRTU; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"modbus_rtu_dt"); + if (m_ProtocolId == -1) + { + LOGDEBUG("ReadConfigParam() ProtoclID error"); + return iotFailed; + } + LOGDEBUG("modbus_rtu_dt ProtoclID=%d", m_ProtocolId); + + if (config.load("../../data/fes/", "modbus_rtu_dt.xml") == iotFailed) + { + LOGDEBUG("modbus_rtu_dt load modbus_rtu_dt.xml error"); + return iotSuccess; + } + LOGDEBUG("modbus_rtu_dt load mdbus_rtu_dt.xml ok"); + + for (i = 0; i < m_ptrCFesBase->m_vectCFesChanPtr.size(); i++) + { + ptrChan = m_ptrCFesBase->m_vectCFesChanPtr[i]; + if ((ptrChan->m_Param.Used == 1) && (m_ProtocolId == ptrChan->m_Param.ProtocolId)) + { + //found RTU + for (j = 0; j < m_ptrCFesBase->m_vectCFesRtuPtr.size(); j++) + { + ptrRTU = m_ptrCFesBase->m_vectCFesRtuPtr[j]; + if (ptrRTU->m_Param.Used && (ptrRTU->m_Param.ChanNo == ptrChan->m_Param.ChanNo)) + { + memset(&strRtuNo[0], 0, sizeof(strRtuNo)); + sprintf(strRtuNo, "RTU%d", ptrRTU->m_Param.RtuNo); + memset(¶m, 0, sizeof(param)); + param.RtuNo = ptrRTU->m_Param.RtuNo; + items = 0; + if (config.getIntValue(strRtuNo, "SGZCalcDelay", ivalue) == iotSuccess) + { + param.SGZCalcDelay = ivalue * 1000; + items++; + } + else + param.SGZCalcDelay = 15 * 1000; + + m_vecAppParam.push_back(param); + } + } + } + } + return iotSuccess; +} diff --git a/product/src/fes/protocol/modbus_rtu_dt/ModbusRtuDT.h b/product/src/fes/protocol/modbus_rtu_dt/ModbusRtuDT.h new file mode 100644 index 00000000..5cfb1e7f --- /dev/null +++ b/product/src/fes/protocol/modbus_rtu_dt/ModbusRtuDT.h @@ -0,0 +1,53 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "ComSerialPort.h" +#include "ComTcpClient.h" +#include "ModbusRtuDTDataProcThread.h" + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + + + +class PROTOCOLBASE_API CModbusRtuDT : public CProtocolBase +{ +public: + CModbusRtuDT(); + ~CModbusRtuDT(); + + vector m_CDataProcQueue; + + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + + void InformComThreadExit(); + vector m_vecAppParam; + +private: + bool m_TcpServerListenThreadFlag; + int m_initRtuFlag; + int m_ProtocolId; + + void ClearSerialPortThreadByChanNo(int ChanNo); + void ClearDataProcThreadByChanNo(int ChanNo); + bool InitProtocolPointMapping(CFesRtuPtr RtuPtr); + void InitProcess(); + void SetComByChanNo(int MainChanNo, int ChanNo); + void ClearComByChanNo(int MainChanNo, int ChanNo); + int ReadConfigParam(); + + +}; diff --git a/product/src/fes/protocol/modbus_rtu_dt/ModbusRtuDTDataProcThread.cpp b/product/src/fes/protocol/modbus_rtu_dt/ModbusRtuDTDataProcThread.cpp new file mode 100644 index 00000000..876b15e0 --- /dev/null +++ b/product/src/fes/protocol/modbus_rtu_dt/ModbusRtuDTDataProcThread.cpp @@ -0,0 +1,6343 @@ +/* +@file ModbusRtuDTDataProcThread.cpp +@brief ModbusRtuDT 数据处理线程类 + 1、每个通道只开一个数据处理线程,支持串口、TCP Client两种通信方式。 + 2、启用块使能 + 3、配置中不再强调块序号要唯一,块序号在读取配置时自动分配唯一块序号 + 4、SFesDo 中使用Param7作为DI的关连点,方便控制完成后立刻读取设置值。 + SFesAo 中使用Param7作为AI的关连点,方便控制完成后立刻读取设置值。 + SFesAi 中使用Param7作为ACC的关连点,写完AI点值后,同步更新到ACC点,pAi->Param7=pAcc->PointNo。 + 5、默认2分钟发送对时,RTU ResParam3作为对时的类型处理。ResParam3=0,不对时。 + 6、电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + 7、YM-KK16要控为脉冲方式,需要程序清零。 + 8、配电柜故障输出、系统正常输出需要读取DO的当前状态。 + 9、配电柜写值之前需要把A000=0X5AA5使能开,碰到非写指令,或时间达到30S自动归零 + 10、DI规约参数5=1,首次启动为1(告警),要产生SOE告警上送后台;同时参与进行事故总运算。 + 规约参数5定义:bit0=1 参与告警 bit1=0:1为告警,bit1=1 0为告警(如通信状态) + 11、事故总的判断增加延时,避免一起动时判断不正确灯乱闪。 + 12、2022-11-16 UPS值为65535表示没采到,值为0. + 13、2022-11-16 数据块关联数据索引赋值错误 + 14、2022-12-08 UPS值为65535不再特殊处理,UPS画面做无效值的处理。 + 15、2022-12-09 Cmd03RespProcess() Mi取点值应该为PointIndex + 16、2022-12-26 主开关增加虚拟告警点及告警使能点。73000地址为开关分闸告警、及告警使能控制地址。 +@author thxiao +@histroy +2023-03-03 thxiao + 1、ModbusRtuDT.cpp\InitProtocolPointMapping() ACC,MI不需要判断Param1 +2023-03-06 thxiao + 1、本程序不可使用在郑州地铁12号线地铁电源监控,因为当时要求系统重起后,所有的存在的告警需要上送。 + 现在改为(1)系统重起后,存在的告警不需要上送。 + (2)设备存在SOE才送,没有SOE的一律不产生SOE(报告块中不勾产生SOE),只产生DI变位。 +2023-03-25 thxiao + 1、AO系数使用除法的方式精度会丢失(即使V1.3.4使用double类型也一样),所以系数改为乘法。 + +*/ +#include +#include +#include "ModbusRtuDTDataProcThread.h" +#include "ComSerialPort.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" + + +using namespace iot_public; +using namespace iot_dbms; + +extern bool g_ModbusRtuDTIsMainFes; +extern bool g_ModbusRtuDTChanelRun; + +const int g_ModbusRtuDTThreadTime = 10; + +CModbusRtuDTDataProcThread::CModbusRtuDTDataProcThread(CFesBase *ptrCFesBase, CFesChanPtr ptrCFesChan, const vector vecAppParam) : + CTimerThreadBase("ModbusRtuDTDataProcThread", g_ModbusRtuDTThreadTime, 0, true) +{ + CFesRtuPtr pRtu; + + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + + int RtuId = m_ptrCFesChan->m_CurrentRtuIndex; + int RtuNo = m_ptrCFesChan->m_RtuNo[RtuId]; + m_ptrCFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo); + m_ptrCInsertFesRtu = NULL; + + m_AppData.setCmdCount = 0; + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if(m_ptrCFesChan == NULL) + { + return ; + } + + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + //2020-08-18 thxiao 一个通道挂多个设备的规约,初始化时需要把标志置上在线状态,保证第一次每个设备都可以发送指令。 + m_ptrCFesBase->ClearRtuOfflineFlag(m_ptrCFesChan); + m_AppData.SettimemSec = getMonotonicMsec(); + m_AppData.SettimemSecReset = 120000; //2min + memset(&m_AppData.setTimeFlag[0], 0, sizeof(int)*CN_FesMaxRtuNumPerChan); + + m_ptrModelCommit = NULL; + + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + InitProtocolBlockDataIndexMapping(pRtu);//2021-09-26 thxiao 每个RTU都需要初始化 + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + m_AppData.setTimeFlag[i] = 1; + + if ((pRtu->m_Param.ResParam3 == CN_ModbusRtuDT_YD) && (m_ptrModelCommit == NULL)) + { + m_ptrModelCommit = new CDbApi(DB_CONN_MODEL_WRITE); + if (m_ptrModelCommit == NULL) + { + LOGERROR("COperateServerClass ::init(), new CDBApi(Write) fail!\n"); + } + } + } + } + + m_timerAlarmEnCountReset=10;//10S + m_timerAlarmEnCount = 0; + + /*************************** COM PROCESS *****************************************************/ + m_timerCountReset = 500 / g_ModbusRtuDTThreadTime; //1S COUNTER + m_timerSGZCountReset = 10000/ g_ModbusRtuDTThreadTime;//5s + m_timerCount = 0; + m_timerSGZCount = 0; + + m_ptrComClient = NULL; + m_ptrComSerial = NULL; + switch (ptrCFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + m_ptrComClient = boost::make_shared(ptrCFesChan); + if (m_ptrComClient == NULL) + { + LOGERROR("create CComTcpClientPtr error! ChanNo=%d", ptrCFesChan->m_Param.ChanNo); + LOGDEBUG("CModbusRtuDTDataProcThread::CModbusRtuDTDataProcThread() ChanNo=%d 创建失败", ptrCFesChan->m_Param.ChanNo); + } + else + LOGDEBUG("CModbusRtuDTDataProcThread::CModbusRtuDTDataProcThread() ChanNo=%d 创建成功", ptrCFesChan->m_Param.ChanNo); + break; + case CN_FesSerialPort: + m_ptrComSerial = boost::make_shared(ptrCFesChan); + if (m_ptrComSerial == NULL) + { + LOGERROR("create m_ptrComSerialPtr error! ChanNo=%d", ptrCFesChan->m_Param.ChanNo); + LOGDEBUG("CModbusRtuDTDataProcThread::CModbusRtuDTDataProcThread() ChanNo=%d 创建失败", ptrCFesChan->m_Param.ChanNo); + } + else + LOGDEBUG("CModbusRtuDTDataProcThread::CModbusRtuDTDataProcThread() ChanNo=%d 创建成功", ptrCFesChan->m_Param.ChanNo); + break; + default: + LOGDEBUG("CModbusRtuDTDataProcThread::CModbusRtuDTDataProcThread() ChanNo=%d 无效通道类型,创建失败", ptrCFesChan->m_Param.ChanNo); + break; + } + /**************************************************************************************/ + //告警点初始化 + AlarmInit(); + //启动时所有的命令都询问一次 + SetSendCmdFlagInit(); + m_SGZCalcFlag = 0; + m_SGZDelaymSec = 10000;//10S; + m_SGZStartmSec = getMonotonicMsec(); + + if (vecAppParam.size() > 0)//只需要取其中一个RTU的参数即可 + { + m_SGZDelaymSec = (int)vecAppParam[0].SGZCalcDelay; + } + LOGDEBUG("延时处理告警时间=%d ms", m_SGZDelaymSec); + + +} + +CModbusRtuDTDataProcThread::~CModbusRtuDTDataProcThread() +{ + CFesRtuPtr pRtu; + int RtuNo; + + quit();//在调用quit()前,系统会调用beforeQuit(); + + switch (m_ptrCFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + if (m_ptrComClient != NULL) + { + m_ptrComClient->TcpClose(m_ptrCurrentChan); + } + break; + case CN_FesSerialPort: + if (m_ptrComSerial != NULL) + { + m_ptrComSerial->CloseChan(m_ptrCurrentChan); + } + break; + default: + break; + } + + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + + } + SModbusRtuDTRTUData *pRTUData; + for (int i = 0; i < m_AppData.RTUData.size(); i++) + { + pRTUData = m_AppData.RTUData[i]; + if (pRTUData != NULL) + delete pRTUData; + } + + LOGDEBUG("CModbusDataProcThread::~CModbusDataProcThread() ChanNo=%d EXIT", m_ptrCFesChan->m_Param.ChanNo); + +} + +/** + * @brief CModbusRtuDTDataProcThread::beforeExecute + * + */ +int CModbusRtuDTDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief CModbusRtuDTDataProcThread::execute + + */ +void CModbusRtuDTDataProcThread::execute() +{ + //读取网络事件 + SFesNetEvent netEvent; + CFesRtuPtr pRtu; + int comStatus; + + int RtuNo = 0; + + if (g_ModbusRtuDTChanelRun == false) + return; + + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + + + if (m_timerCount++ >= m_timerCountReset) + { + m_timerCount = 0;// sec is ready + switch (m_ptrCFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + comStatus = m_ptrComClient->GetNetStatus(); + switch (comStatus) + { + case CN_FesChanDisconnect: + m_ptrComClient->TcpConnect(m_ptrCurrentChan); + break; + default: + break; + } + break; + case CN_FesSerialPort: + comStatus = m_ptrComSerial->GetComStatus(); + switch (comStatus) + { + case CN_FesChanDisconnect: + m_ptrComSerial->OpenChan(m_ptrCurrentChan); + break; + default: + break; + } + break; + default: + break; + } + + TimerProcess(); + } + + + if(!m_SGZCalcFlag)//延时故障检测 + { + if (m_timerSGZCount++ >= m_timerSGZCountReset) + { + m_SGZCalcFlag = 1; + LOGDEBUG("开始故障检测!"); + } + } + + if (m_ptrCurrentChan->ReadNetEvent(1, &netEvent) > 0) + { + switch (m_ptrCurrentChan->m_Param.CommType) + { + case CN_FesTcpClient: + case CN_FesSerialPort: + switch (netEvent.EventType) + { + case CN_FesNetEvent_Connect: + LOGDEBUG("ChanNo:%d connect!", m_ptrCFesChan->m_Param.ChanNo); + m_AppData.state = CN_ModbusRtuDTAppState_idle; + break; + case CN_FesNetEvent_Disconnect: + LOGDEBUG("ChanNo:%d disconnect!", m_ptrCFesChan->m_Param.ChanNo); + m_AppData.state = CN_ModbusRtuDTAppState_init; + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) != NULL) + { + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } + break; + default: + break; + } + break; + default: + break; + } + + } + SetSendCmdFlag(); + + if (SendProcess() > 0) + { + RecvComData(); + } + +} + +/* + @brief 执行quit函数前的处理 + */ +void CModbusRtuDTDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + +} + + +/** +* @brief CModbusRtuDTDataProcThread::SendProcess +* MODBUS 发送处理 +* @return 返回发送数据长度 +*/ +int CModbusRtuDTDataProcThread::SendProcess() +{ + int retLen = 0; + if (m_ptrCurrentChan == NULL) + return iotFailed; + + switch (m_ptrCurrentChan->m_Param.CommType) + { + case CN_FesSerialPort: + //luojunjun 等待打开串口 + if (m_ptrCurrentChan->m_LinkStatus == CN_FesChanDisconnect) + return retLen; + default: + break; + } + + if ((retLen = InsertCmdProcess()) > 0) + { + //LOGDEBUG("RTU%d插入命令:SeqNo=%d,StartAddr=%d,DataLen=%d,Type=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.SeqNo, + // m_AppData.lastCmd.StartAddr, m_AppData.lastCmd.DataLen, m_AppData.lastCmd.Type); + return retLen; + } + + if ((retLen = PollingCmdProcess()) > 0) + return retLen; + + if (m_ptrCurrentChan->m_LinkStatus != CN_FesChanConnect) + { + ErrorControlRespProcess(); //通信断开时有控制命令来需要做异常处理 + } + + return retLen; + +} + +/** +* @brief CModbusRtuDTDataProcThread::InsertCmdProcess +* 收到SCADA的控制命令,插入命令处理。组织MODBUS命令帧,并返回操作消息 +* @return 实际发送数据长度 +*/ +int CModbusRtuDTDataProcThread::InsertCmdProcess() +{ + byte data[256]; + int dataSize, retSize = 0; + + if (g_ModbusRtuDTIsMainFes == false)//备机不作任何操作 + return 0; + + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + int RtuNo = m_ptrCFesChan->m_RtuNo[i]; + m_ptrCInsertFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo); //得使用局部变量 + + if (m_ptrCInsertFesRtu == NULL) + return 0; + + dataSize = sizeof(data); + retSize = 0; + if (m_AppData.setTimeFlag[i] == 1) + { + retSize = SetTimeProcess(m_ptrCInsertFesRtu,data, dataSize); + m_AppData.setTimeFlag[i] = 0; + } + else + if (m_ptrCInsertFesRtu->GetRxDoCmdNum() > 0) + { + retSize = DoCmdProcess(data, dataSize); //遥控 + } + else + if (m_ptrCInsertFesRtu->GetRxAoCmdNum() > 0) + { + retSize = AoCmdProcess(data, dataSize);// + } + else + if (m_ptrCInsertFesRtu->GetRxMoCmdNum() > 0) + { + //retSize = MoCmdProcess(data, dataSize); + } + else + if (m_ptrCInsertFesRtu->GetRxSettingCmdNum() > 0) + { + //retSize = SettingCmdProcess(data, dataSize); + } + else + if (m_ptrCInsertFesRtu->GetRxDefCmdNum() > 0) + { + retSize = DefCmdProcess(data, dataSize); + } + + if (retSize > 0) + { + //send data to net + SendDataToPort(data, retSize); + return retSize; + } + } + m_ptrCInsertFesRtu = NULL; + return retSize; +} + + +/** +* @brief CModbusRtuDTDataProcThread::DoCmdProcess +* 接收SCADA传来的DO控制命令,组织MODBUS命令帧,并返回操作消息。 +* @param Data 发送数据区 +* @param dataSize 发送数据区长度 +* @return 实际发送数据长度 +*/ +int CModbusRtuDTDataProcThread::DoCmdProcess(byte *Data, int /*dataSize*/) +{ + SFesRxDoCmd cmd; + SFesTxDoCmd retCmd; + SFesDo *pDo; + byte retData[256]; + int retDataSize,retStatus,setValue, bitValue,i; + int writex, crcCount = 0, FunCode = 5; + + writex = 0; + memset(&retCmd, 0, sizeof(retCmd)); + memset(&cmd, 0, sizeof(cmd)); + + + if (m_ptrCInsertFesRtu->ReadRxDoCmd(1, &cmd) == 1) + { + //get the cmd ok + //2019-02-21 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + + //2020-02-18 thxiao 遥控增加五防闭锁检查 + if (m_ptrCInsertFesRtu->CheckWuFangDoStatus(cmd.PointID) == 0)//闭锁 + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d 闭锁").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d 闭锁", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return 0; + } + + //需对应分闸合闸 + if ((pDo = GetFesDoByPointNo(m_ptrCInsertFesRtu, cmd.PointID)) != NULL) + { + if (cmd.CtrlActType == CN_ControlExecute) + { + if (m_ptrCInsertFesRtu->m_Param.ResParam1 == 0) + { + if (m_ptrCInsertFesRtu->m_Param.ResParam3 == CN_ModbusRtuDT_YD) + { + /*if((!m_SGZCalcFlag) &&((pDo->Param3 == 45313) || (pDo->Param3 == 45312)))//延时时间没到,禁止输出 + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("延时时间没到,设备禁止设置! RtuNo:%d 遥控点:%d ").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("延时时间没到,设备禁止设置!RtuNo:%d 遥控点:%d ", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return 0; + }*/ + if (WriteEnable(m_ptrCInsertFesRtu) == iotFailed) + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败,设备禁止设置! RtuNo:%d 遥控点:%d 当前点值无法读取").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("遥控失败,设备禁止设置!RtuNo:%d 遥控点:%d 当前点值无法读取", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return 0; + } + } + Data[writex++] = m_ptrCInsertFesRtu->m_Param.RtuAddr;//设备地址 + Data[writex++] = pDo->Param2;//功能码 + switch (pDo->Param2) + { + case 0x05: + //2020-07-21 thxiao 增加可配置的遥控命令 + if(pDo->Attribute & CN_FesDo_Keep)//1自保持输出(需要程序清零) + { + if (cmd.iValue == 1) + { + retStatus = DoKeepReset(m_ptrCInsertFesRtu, cmd, pDo); + if (retStatus == iotFailed) + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d 当前点值无法读取").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d 当前点值无法读取", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return 0; + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = 0x00;/*05命令其值为,0x0000表示分闸*/ + Data[writex++] = 0x00; + } + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = 0x00;/*05命令其值为,0x0000表示分闸*/ + Data[writex++] = 0x00; + } + } + else + if (pDo->Attribute & CN_FesDo_Special)//点属性判断特殊遥控 + { + if (cmd.iValue == 1)//CLOSE + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff;//合值 + Data[writex++] = pDo->Param4 & 0x00ff;//合值 + } + else//OPEN + { + Data[writex++] = (pDo->Param5 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param5 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param6 >> 8) & 0x00ff;//分值 + Data[writex++] = pDo->Param6 & 0x00ff;//分值 + } + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + if (cmd.iValue == 1) + { + Data[writex++] = 0xff;/*05命令其值为,0xff00 表示合闸*/ + Data[writex++] = 0x00; + } + else + { + Data[writex++] = 0x00;/*05命令其值为,0x0000表示分闸*/ + Data[writex++] = 0x00; + } + } + break; + case 0x06: + if (pDo->Attribute & CN_FesDo_Special)//点属性判断特殊遥控 + { + if (cmd.iValue == 1)//CLOSE + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff;//合值 + Data[writex++] = pDo->Param4 & 0x00ff;//合值 + } + else//OPEN + { + Data[writex++] = (pDo->Param5 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param5 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param6 >> 8) & 0x00ff;//分值 + Data[writex++] = pDo->Param6 & 0x00ff;//分值 + } + } + else + if (pDo->Attribute & CN_FesDo_SetBit)//按位设置:分三步控制1、读取当前word值、2、设置当前位、3、设置完成后读取当前word值。 + { + retStatus = ReadDoStartValue(m_ptrCInsertFesRtu, pDo, retData, retDataSize); + if (retStatus == iotFailed) + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d 当前点值无法读取").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d 当前点值无法读取", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return 0; + } + else + { + setValue = (int)retData[3] << 8; + setValue |= (int)retData[4]; + bitValue = 0x0001; + if (cmd.iValue == 1)//CLOSE + { + bitValue <<= pDo->Param4; + setValue |= bitValue; + } + else + { + bitValue <<= pDo->Param4; + setValue &= ~bitValue; + } + writex = 0; + Data[writex++] = m_ptrCInsertFesRtu->m_Param.RtuAddr;//设备地址 + Data[writex++] = pDo->Param2;//功能码 + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (setValue >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = setValue & 0x00ff;//寄存器起始地址L + } + } + else + if (pDo->Attribute & CN_FesDo_SetTwoPoint)//Bit4 一次控制,设置两个点值,适用于事件清零、电度清零 + { + retStatus = DoSetTwoPoint(m_ptrCInsertFesRtu, pDo, Data, writex); + if (retStatus == iotFailed) + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d 当前点值无法读取").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d 控制第一个点设备返回失败", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return 0; + } + } + else + if (pDo->Attribute & CN_FesDo_MainPosAlarm)//主控开关告警使能 + { + retStatus = YDPosAlarmEnable(m_ptrCInsertFesRtu, cmd ,pDo); + if (retStatus == iotFailed) + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d 当前点值无法读取").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d 控制第一个点设备返回失败", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return 0; + } + else + { + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlSuccess; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控成功!RtuNo:%d 遥控点:%d ").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("遥控成功!RtuNo:%d 遥控点:%d ", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return 0; + } + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + if (cmd.iValue == 1) + { + cmd.iValue <<= pDo->Param4; + Data[writex++] = ((cmd.iValue >> 8) & 0xff);/*06命令按寄存器bit控制PLC(复归式)*/ + Data[writex++] = (cmd.iValue & 0xff); + } + else + { + Data[writex++] = 0x00;/*06命令,值为0,PLC(复归式)不动作*/ + Data[writex++] = 0x00; + } + } + break; + case 0x10: + if (pDo->Attribute & CN_FesDo_SetBlock)//Bit5 控制连续地址,全为0或1,适应用于支路开关跳闸告警使能/禁止 + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff;//长度 + Data[writex++] = pDo->Param4 & 0x00ff;//长度 + Data[writex++] = pDo->Param4*2;//字节数 + if (cmd.iValue == 1) + { + for (i = 0; i < pDo->Param4; i++) + { + Data[writex++] = 0xff; + Data[writex++] = 0xff; + } + } + else + { + for (i = 0; i < pDo->Param4; i++) + { + Data[writex++] = 0; + Data[writex++] = 0; + } + } + } + else + { + if (cmd.iValue == 1) + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = 0x00; + Data[writex++] = 0x01;//长度 + Data[writex++] = 0x02;//字节数 + Data[writex++] = ((pDo->Param4 >> 8) & 0xff); + Data[writex++] = (pDo->Param4 & 0xff); + } + else + { + Data[writex++] = (pDo->Param5 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param5 & 0x00ff;//寄存器起始地址L + Data[writex++] = 0x00; + Data[writex++] = 0x01;//长度 + Data[writex++] = 0x02;//字节数 + Data[writex++] = ((pDo->Param6 >> 8) & 0xff); + Data[writex++] = (pDo->Param6 & 0xff); + } + } + break; + default: + return 0; + } + } + else//R80 管理机模式 + { + if (pDo->Attribute & 0x04) //点属性判断特殊遥控 + FunCode = 0x06; + if (cmd.CtrlActType == CN_ControlExecute) + { + Data[writex++] = m_ptrCInsertFesRtu->m_Param.RtuAddr;//设备地址 + Data[writex++] = FunCode;//功能码 + if (FunCode == 0x05) + { + if (cmd.iValue == 1) + { + Data[writex++] = (pDo->Param2 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param2 & 0x00ff;//寄存器起始地址L + Data[writex++] = 0xff;/*05命令其值为,0xff00 表示合闸*/ + Data[writex++] = 0x00; + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = 0x00;/*05命令其值为,0x0000表示分闸*/ + Data[writex++] = 0x00; + } + } + else if (FunCode == 0x06) + { + if (cmd.iValue == 1) + { + Data[writex++] = (pDo->Param2 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param2 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->ControlParam >> 8) & 0x00ff; + Data[writex++] = pDo->ControlParam & 0x00ff; + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff; + Data[writex++] = pDo->Param4 & 0x00ff; + } + } + else + return 0; + } + } + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + memcpy(&m_AppData.doCmd, &cmd, sizeof(cmd)); + m_AppData.pLastDo = pDo; + m_AppData.lastCotrolcmd = CN_ModbusRtuDTDoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_waitControlResp; + LOGDEBUG("DO遥控执行成功 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.iValue, cmd.RtuName, cmd.PointID); + } + else if (cmd.CtrlActType == CN_ControlSelect) //遥控选择作为日后扩展用 + { + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlSuccess; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("DO遥控选择成功 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.iValue, cmd.RtuName, cmd.PointID); + //ptrFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuDTDoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_waitControlResp; + } + else + { + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.iValue, cmd.RtuName, cmd.PointID); + //ptrFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + } + } + else + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 找不到遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("DO遥控失败 !RtuNo:%d 找不到遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + //ptrFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + } + } + return writex; +} + + +/** +* @brief CModbusRtuDTDataProcThread::AoCmdProcess +* 接收SCADA传来的AO控制命令,组织MODBUS命令帧,并返回操作消息。 +* @param Data 发送数据区 +* @param dataSize 发送数据区长度 +* @return 实际发送数据长度 +*/ +int CModbusRtuDTDataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) +{ + SFesRxAoCmd cmd; + SFesTxAoCmd retCmd; + short setValue; + SFesAo *pAo = NULL; + int writex; + float fValue, tempValue; + int failed; + int iValue, crcCount; + + writex = 0; + if (m_ptrCInsertFesRtu->ReadRxAoCmd(1, &cmd) == 1) + { + //get the cmd ok + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + if ((pAo = GetFesAoByPointNo(m_ptrCInsertFesRtu, cmd.PointID)) != NULL) + { + if (cmd.CtrlActType == CN_ControlExecute) + { + tempValue = cmd.fValue; + failed = 0; + if (pAo->Coeff != 0) + { + fValue = (tempValue + pAo->Base) * pAo->Coeff; + if (pAo->MaxRange > pAo->MinRange) + { + if ((fValue < pAo->MinRange) || (fValue > pAo->MaxRange)) + { + //2019-08-30 thxiao 增加失败详细描述 + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d 量程越限").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + failed = 1; + } + } + else + { + sprintf(retCmd.strParam, I18N("遥调失败,量程配置错误,最大量程<=最小量程!").str().c_str()); + failed = 1; + } + } + else + { + //2019-08-30 thxiao 增加失败详细描述 + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d 系数为0").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + failed = 1; + } + + if (failed == 1) + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + //sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(),m_ptrCInsertFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG("AO遥调失败,点系数为0或者量程越限!RtuNo:%d 遥调点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + //m_ptrCInsertFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + } + else + { + if (m_ptrCInsertFesRtu->m_Param.ResParam3 == CN_ModbusRtuDT_YD) + { + if (WriteEnable(m_ptrCInsertFesRtu) == iotFailed) + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + //sprintf(retCmd.strParam,I18N("遥调失败!设备不允许控制RtuNo:%d 找不到遥调点:%d").str().c_str(),m_ptrCInsertFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG("AO遥调失败,设备不允许控制!RtuNo:%d 遥调点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return writex; + } + } + Data[writex++] = m_ptrCInsertFesRtu->m_Param.RtuAddr;//设备地址 + if (pAo->Param2 == 0x10) + { + Data[writex++] = pAo->Param2; //command 0x10 + Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address + Data[writex++] = pAo->Param3 & 0x00ff; + Data[writex++] = 0x00; + Data[writex++] = 0x02; + Data[writex++] = 0x04; + memcpy(&iValue, &fValue, sizeof(fValue)); + LOGDEBUG("iValue=%x fValue = %f",iValue,fValue); + switch (pAo->Param4) + { + case AI_DWord_LL: + case AI_UDWord_LL: + iValue = (int)fValue; + Data[writex++] = (byte)iValue; + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 24); + break; + case AI_Float_LL: + memcpy(&iValue, &fValue, sizeof(fValue)); + Data[writex++] = (byte)iValue; + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 24); + break; + case AI_DWord_HH: + case AI_UDWord_HH: + iValue = (int)fValue; + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + break; + case AI_Float_HH: + memcpy(&iValue, &fValue, sizeof(fValue)); + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + break; + case AI_DWord_LH: + case AI_UDWord_LH: + iValue = (int)fValue; + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + break; + case AI_Float_LH: + memcpy(&iValue, &fValue, sizeof(fValue)); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + break; + default://地铁项目默认为CDAB + memcpy(&iValue, &fValue, sizeof(fValue)); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + break; + } + + } + else + { + setValue = (short)fValue; + Data[writex++] = pAo->Param2; //command 0x06 + Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address + Data[writex++] = pAo->Param3 & 0x00ff; + switch (pAo->Param4) + { + case AI_Word_HL: + case AI_UWord_HL: + Data[writex++] = (setValue >> 8) & 0x00ff; + Data[writex++] = setValue & 0x00ff; + break; + case AI_Word_LH: + case AI_UWord_LH: + Data[writex++] = setValue & 0x00ff; + Data[writex++] = (setValue >> 8) & 0x00ff; + break; + default: + Data[writex++] = (setValue >> 8) & 0x00ff; + Data[writex++] = setValue & 0x00ff; + break; + } + } + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + memcpy(&m_AppData.aoCmd, &cmd, sizeof(cmd)); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTAoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_waitControlResp; + LOGDEBUG("AO遥调成功 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.fValue, cmd.RtuName, cmd.PointID); + } + } + else + { + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + retCmd.CtrlActType = cmd.CtrlActType; + LOGDEBUG("AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", cmd.CtrlActType, cmd.fValue, cmd.RtuName, cmd.PointID); + //m_ptrCInsertFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + } + } + else + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("AO遥调失败!RtuNo:%d 找不到遥调点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, cmd.PointID); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + } + } + return writex; +} + +/** +* @brief CModbusRtuDTDataProcThread::DefCmdProcess +* 接收SCADA传来的自定义控制命令,组织MODBUS命令帧,并返回操作消息。 +* @param Data 发送数据区 +* @param dataSize 发送数据区长度 +* @return 实际发送数据长度 +*/ +int CModbusRtuDTDataProcThread::DefCmdProcess(byte *Data, int dataSize) +{ + boost::ignore_unused_variable_warning(dataSize); + + byte data[300]; + SFesRxDefCmd rxDefCmd; + SFesTxDefCmd txDefCmd; + int writex, i, crcCount; + bool errorFlag = false; + + writex = 0; + if (m_ptrCInsertFesRtu->ReadRxDefCmd(1, &rxDefCmd) == 1) + { + m_AppData.CmdNum = (int)rxDefCmd.VecCmd.size(); + m_AppData.defCmd = rxDefCmd; + + if (CMD_TYPE == rxDefCmd.VecCmd[0].name) + { + if (DEV_ID == rxDefCmd.VecCmd[1].name) + m_AppData.deviceId = atoi(rxDefCmd.VecCmd[1].value.c_str()); + else + errorFlag = true; + //=====================================修改定值======================================// + //Modbus只有修改定值 + if (rxDefCmd.VecCmd[0].value == CONST_VALUE_EDIT) + { + m_AppData.dotNo.clear(); + m_AppData.currentValue.clear(); + m_AppData.editValue.clear(); + + m_AppData.modifyDzNum = (m_AppData.CmdNum - 2) / 2; //只减去cmd_type和dev_id,每项定值只有寄存器地址和修改值 + if (m_AppData.modifyDzNum > CN_FesMaxDzNum) + m_AppData.modifyDzNum = CN_FesMaxDzNum; + + if (m_AppData.modifyDzNum == 0) + errorFlag = true; + + for (i = 0; i < m_AppData.modifyDzNum; i++) + { + if (DOT_NO == rxDefCmd.VecCmd[2 + i * 2].name) + m_AppData.dotNo.push_back(atoi(rxDefCmd.VecCmd[2 + i * 2].value.c_str())); + else + errorFlag = true; + if (EDIT_VALUE == rxDefCmd.VecCmd[3 + i * 2].name) + m_AppData.editValue.push_back(atoi(rxDefCmd.VecCmd[3 + i * 2].value.c_str())); + else + errorFlag = true; + } + } + } + } + + if (errorFlag == true) + { + //memset(&txDefCmd, 0, sizeof(txDefCmd));//lww todo 声明结构进行初始化 + strcpy(txDefCmd.TableName, rxDefCmd.TableName); + strcpy(txDefCmd.ColumnName, rxDefCmd.ColumnName); + strcpy(txDefCmd.TagName, rxDefCmd.TagName); + strcpy(txDefCmd.RtuName, rxDefCmd.RtuName); + txDefCmd.DevId = m_AppData.deviceId; + txDefCmd.CmdNum = rxDefCmd.CmdNum; + txDefCmd.VecCmd = rxDefCmd.VecCmd; + txDefCmd.retStatus = CN_ControlFailed; + sprintf(txDefCmd.strParam, I18N("HMI命令解析失败,不下发控制命令!RtuNo:%d ").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo); + LOGERROR("HMI命令解析失败,不下发控制命令!RtuNo:%d", m_ptrCInsertFesRtu->m_Param.RtuNo); + m_ptrCInsertFesRtu->WriteTxDefCmdBuf(1, &txDefCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return 0; + } + else + { + data[writex++] = m_ptrCInsertFesRtu->m_Param.RtuAddr; + data[writex++] = 0x10; + data[writex++] = (m_AppData.dotNo[0] >> 8) & 0x00ff; //modbus中定值代号暂时作为寄存器地址 + data[writex++] = (m_AppData.dotNo[0]) & 0x00ff; + data[writex++] = (m_AppData.modifyDzNum >> 8) & 0x00ff; + data[writex++] = (m_AppData.modifyDzNum) & 0x00ff; + data[writex++] = m_AppData.modifyDzNum * 2; + for (i = 0; i < m_AppData.modifyDzNum; i++) + { + data[writex++] = (m_AppData.editValue[i] >> 8) & 0xff; + data[writex++] = m_AppData.editValue[i] & 0xff; + } + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + } + SendDataToPort(data, writex); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTDefCmd; + m_AppData.state = CN_ModbusRtuDTAppState_waitControlResp; + m_AppData.controlTimeout = getMonotonicMsec();//需要处理控制超时,所以置上时间。 + return writex; +} + + +/** +* @brief CModbusRtuDTDataProcThread::PollingCmdProcess +* 循环发送读取数据命令,组织MODBUS命令帧。 +* @param Data 发送数据区 +* @param dataSize 发送数据区长度 +* @return 实际发送数据长度 +*/ +int CModbusRtuDTDataProcThread::PollingCmdProcess() +{ + byte Data[256]; + SModbusCmd cmd; + int writex, crcCount = 0; + + int RtuNo = m_ptrCFesChan->m_RtuNo[m_ptrCFesChan->m_CurrentRtuIndex]; + if ((m_ptrCFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) + { + NextRtuIndex(m_ptrCFesChan); + return 0; + } + + if (GetPollingCmd(&cmd) == iotFailed) + { + return 0; + } + + memcpy(&m_AppData.lastCmd, &cmd, sizeof(SModbusCmd)); + + writex = 0; + Data[writex++] = m_ptrCFesRtu->m_Param.RtuAddr; + Data[writex++] = cmd.FunCode; + Data[writex++] = (cmd.StartAddr >> 8) & 0x00ff; + Data[writex++] = cmd.StartAddr & 0x00ff; + Data[writex++] = (cmd.DataLen >> 8) & 0x00ff; + Data[writex++] = cmd.DataLen & 0x00ff; + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + //send data to net + SendDataToPort(Data, writex); + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return writex; +} + + +/** +* @brief CModbusRtuDTDataProcThread::GetPollingCmd +* 获取读取数据命令 +* @param pCmd 返回读取数据命令 +* @return 成功:iotSuccess 失败:iotFailed +*/ +int CModbusRtuDTDataProcThread::GetPollingCmd(SModbusCmd *pCmd) +{ + SModbusCmd *Cmd; + bool ComFlag = false; + int count = 0; + + if(m_ptrCFesRtu==NULL) + return iotFailed; + + //2020-05-14 thxiao 如果没有配置块,则轮训下一个设备。 + if (m_ptrCFesRtu->m_Param.ModbusCmdBuf.num == 0) + NextRtuIndex(m_ptrCFesChan); + + while (count < m_ptrCFesRtu->m_Param.ModbusCmdBuf.num) + { + Cmd = m_ptrCFesRtu->m_Param.ModbusCmdBuf.pCmd + m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx; + if (Cmd->CommandSendFlag == true) + { + ::memcpy(pCmd, Cmd, sizeof(SModbusCmd)); + Cmd->CommandSendFlag = false; + ComFlag = true; + //LOGDEBUG("GetPollingCmd chan=%d m_CurrentRtuIndex=%d RtuNo=%d readx=%d \n", m_ptrCFesRtu->m_Param.ChanNo,m_ptrCurrentChan->m_CurrentRtuIndex, m_ptrCFesRtu->m_Param.RtuNo, m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx); + } + m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx++; + if (m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx >= m_ptrCFesRtu->m_Param.ModbusCmdBuf.num) + m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx = 0; + count++; + if (ComFlag) + return iotSuccess; + + } + return iotFailed; +} + +/* + 接收数据 +*/ +int CModbusRtuDTDataProcThread::RecvComData() +{ + int count; + int FunCode, DevAddr, ExpectLen; + byte Data[500]; + int recvLen, Len, i,crc,recvcrc; + + if (m_ptrCurrentChan == NULL) + return iotFailed; + + DevAddr = m_AppData.lastCmdData[0]; + FunCode = m_AppData.lastCmdData[1]; + Len = 0; + recvLen = 0; + count = m_ptrCFesChan->m_Param.RespTimeout / 10; + if (count <= 10) + count = 10;//最小响应超时为100毫秒 + ExpectLen = 0; + for (i = 0; i < count; i++) + { + switch (m_ptrCFesChan->m_Param.CommType) + { + case CN_FesSerialPort: + SleepmSec(10);//以最快速度接收到数据 + if (m_ptrComSerial != NULL) + m_ptrComSerial->RxComData(m_ptrCurrentChan); + break; + case CN_FesTcpClient: + //以最快速度接收到数据 RxData()有延时等待时间,此处可以删除 + if (m_ptrComClient != NULL) + m_ptrComClient->RxData(m_ptrCurrentChan); + break; + default: + break; + } + recvLen = m_ptrCurrentChan->ReadRxBufData(500 - Len, &Data[Len]);//数据缓存在 + if (recvLen <= 0) + continue; + m_ptrCurrentChan->DeleteReadRxBufData(recvLen);//清除已读取的数据 + Len += recvLen; + if (Len > 3) + { + if (Data[1] & 0x80)//ERROR + ExpectLen = 5; + else + { + switch (Data[1]) + { + case FunCode_01H: + case FunCode_02H: + case FunCode_03H: + case FunCode_04H: + ExpectLen = Data[2] + 5; + break; + case FunCode_05H: + case FunCode_06H: + case FunCode_10H: + ExpectLen = 8; + break; + } + } + } + if ((Len >= ExpectLen) && (ExpectLen > 0)) + { + break; + } + } + + + if (Len > 0) + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, Data, Len, CN_SFesSimComFrameTypeRecv); + + if (Len == 0)//接收不完整,重发数据 + { + if (m_ptrCInsertFesRtu != NULL) //InsertCmd + { + m_ptrCInsertFesRtu->SetResendNum(1); + if (m_ptrCInsertFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCInsertFesRtu->ResetResendNum(); //改为RTU下的resendNum + if (m_ptrCInsertFesRtu->ReadRtuSatus() == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCInsertFesRtu, CN_FesRtuComDown); + m_ptrCInsertFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCInsertFesRtu,CN_FesRtuComDown); + } + CmdControlRespProcess(NULL, 0, 0); + m_ptrCInsertFesRtu = NULL; + } + else //PollCmd + { + m_ptrCFesRtu->SetResendNum(1); + if (m_ptrCFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCFesRtu->ResetResendNum(); //改为RTU下的resendNum + if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCFesRtu,CN_FesRtuComDown); + } + NextRtuIndex(m_ptrCFesChan); + } + + return iotFailed; + } + else//长度、地址、功能码 都正确则认为数据正确。 + if ((Len == ExpectLen) && ((DevAddr == Data[0])|| (Data[0]==0xff)) && (FunCode == (Data[1] & 0x7f))) + { + //CRC CHECK + crc = CrcSum(&Data[0], ExpectLen-2); + recvcrc = (int)Data[ExpectLen - 1] << 8; + recvcrc |= (int)Data[ExpectLen - 2] ; + if (crc != recvcrc) + { + //校验错误,处理和接收长度为0 处理方法相同 + m_ptrCurrentChan->SetErrNum(1); + if (m_ptrCInsertFesRtu != NULL) //InsertCmd + { + m_ptrCInsertFesRtu->SetErrNum(1); + m_ptrCInsertFesRtu->SetResendNum(1); + if (m_ptrCInsertFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCInsertFesRtu->ResetResendNum(); //改为RTU下的resendNum + if (m_ptrCInsertFesRtu->ReadRtuSatus() == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCInsertFesRtu, CN_FesRtuComDown); + m_ptrCInsertFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCInsertFesRtu, CN_FesRtuComDown); + } + CmdControlRespProcess(NULL, 0, 0); + m_ptrCInsertFesRtu = NULL; + } + else //PollCmd + { + m_ptrCFesRtu->SetErrNum(1); + m_ptrCFesRtu->SetResendNum(1); + if (m_ptrCFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCFesRtu->ResetResendNum(); //改为RTU下的resendNum + if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCFesRtu, CN_FesRtuComDown); + } + NextRtuIndex(m_ptrCFesChan); + } + return iotFailed; + } + else + { + m_ptrCurrentChan->SetRxNum(1); + if (m_ptrCInsertFesRtu != NULL) + { + m_ptrCInsertFesRtu->ResetResendNum(); + m_ptrCInsertFesRtu->SetRxNum(1); + RecvDataProcess(&Data[0], Len); + if (m_ptrCInsertFesRtu->ReadRtuSatus() == CN_FesRtuComDown) + { + m_ptrCInsertFesRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); + m_ptrCFesBase->WriteRtuSatus(m_ptrCInsertFesRtu, CN_FesRtuNormal); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCInsertFesRtu, CN_FesRtuNormal); + m_ptrCInsertFesRtu = NULL; + } + else + { + m_ptrCFesRtu->ResetResendNum(); + m_ptrCFesRtu->SetRxNum(1); + RecvDataProcess(&Data[0], Len); + if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuComDown) + { + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuNormal); + } + m_ptrCFesBase->SetOfflineFlag(m_ptrCFesRtu, CN_FesRtuNormal);//2021-07-09 thxiao 出现过没有正常发送数据的情况,此处加上只要通信正常,就把离线状态清除。 + NextRtuIndex(m_ptrCFesChan); + } + } + return iotSuccess; + } + else + { + m_ptrCurrentChan->SetErrNum(1); + if (m_ptrCInsertFesRtu != NULL) + { + m_ptrCInsertFesRtu->SetErrNum(1); + CmdControlRespProcess(NULL, 0, 0); + m_ptrCInsertFesRtu = NULL; + } + else + { + m_ptrCFesRtu->SetErrNum(1); + NextRtuIndex(m_ptrCFesChan); + } + return iotFailed; + } +} + +/** +* @brief CModbusRtuDTDataProcThread::RecvDataProcess +* @param Data +* @param DataSize +* @return 成功:iotSuccess 失败:iotFailed +*/ +int CModbusRtuDTDataProcThread::RecvDataProcess(byte *Data, int DataSize) +{ + int FunCode; + + FunCode = Data[1]; + if (FunCode & 0x80) + { + CmdControlRespProcess(NULL, 0, 0); + return iotSuccess; + } + + if (CmdControlRespProcess(Data, DataSize, 1) == true) + return iotSuccess; + + switch (FunCode) + { + case 0x01: + case 0x02: + if (m_ptrCFesRtu->m_Param.ResParam1 == 1) + Cmd01RespProcess_PCS3000(Data, DataSize); + else + Cmd01RespProcess(Data, DataSize); + break; + case 0x03: + case 0x04: + if (m_ptrCFesRtu->m_Param.ResParam1 == 1) + { + Cmd03RespProcess_PCS3000(Data, DataSize); + CmdTypeHybridProcess_PCS3000(Data, DataSize); + } + else + { + Cmd03RespProcess(Data, DataSize); + CmdTypeHybridProcess(Data, DataSize); + } + break; + case 0x05: + Cmd05RespProcess(Data, DataSize); + break; + case 0x06: + Cmd06RespProcess(Data, DataSize); + break; + case 0x10: + Cmd10RespProcess(Data, DataSize); + break; + default: + return iotFailed; + break; + } + return iotSuccess; +} + + +/** +* @brief CModbusRtuDTDataProcThread::Cmd01RespProcess +* 命令0x01 0x02的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusRtuDTDataProcThread::Cmd01RespProcess_PCS3000(byte *Data, int /*DataSize*/) +{ + byte bitValue, byteValue; + int i, j, StartAddr, ValueCount, ChgCount, SoeCount; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[50]; + uint64 mSec; + + StartAddr = m_AppData.lastCmd.StartAddr; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + + for (i = 0; i < Data[2]; i++) + { + byteValue = Data[3 + i]; + for (j = 0; j < 8; j++) + { + bitValue = (byteValue >> j) & 0x01; + pDi = GetFesDiByParam23(m_ptrCFesRtu, 0, 0, StartAddr + i * 8 + j);//R80管理机 FunCode 忽略 + if (pDi != NULL) + { + if (pDi->Revers) + bitValue ^= 1; + + if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) //一次最多上送50个遥信点变化给后台 + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + //写入各转发RTU的FWSOE缓存区。 + SoeCount++; + if (SoeCount >= 50) + { + //m_ptrCFesRtu->WriteSoeEventBuf(SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + //更新点值 + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) //一次最多上送50个遥信点给后台 + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } +} + + +/** +* @brief CModbusRtuDTDataProcThread::Cmd03RespProcess_PCS3000 +* 命令0x03 0x04的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* 兼容PCS3000的老模板 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusRtuDTDataProcThread::Cmd03RespProcess_PCS3000(byte *Data, int /*DataSize*/) +{ + int diValue, bitValue = 0; + int i = 0, j, StartAddr, StartPointNo, ValueCount, ChgCount, SoeCount, PointCount; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[100]; + uint64 mSec; + SFesAi *pAi; + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + SFesMi *pMi; + SFesRtuMiValue MiValue[100]; + SFesChgMi ChgMi[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + int64 accValue; + int miValue=0; + + StartAddr = m_AppData.lastCmd.StartAddr; + StartPointNo = 0; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + if ((m_AppData.lastCmd.Type == DI_UWord_HL) || (m_AppData.lastCmd.Type == DI_UWord_LH))//DI (数字量1/2) + { + PointCount = Data[2] / 2; + for (i = 0; i < PointCount; i++) + { + if (m_AppData.lastCmd.Type == DI_UWord_HL) //先高位后低位 + { + diValue = (int)Data[3 + i * 2] << 8; + diValue |= (int)Data[4 + i * 2]; + } + else //先低位后高位 + { + diValue = (int)Data[4 + i * 2] << 8; + diValue |= (int)Data[3 + i * 2]; + } + if (m_AppData.lastCmd.Param1 == 1) //数据块自定义#1 = 1,遥信按位组合 + { + for (j = 0; j < (m_ptrCFesRtu->m_MaxDiPoints); j++) + { + if ((pDi = GetFesDiByPointNo(m_ptrCFesRtu, j)) == NULL) + return; + if (pDi->Param2 == StartAddr + i) + { + bitValue = Cmd03RespProcess_BitGroup_PCS3000(pDi, diValue); + + if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + } + + } + else + { + for (j = 0; j < 16; j++) + { + bitValue = (diValue >> j) & 0x01; + pDi = GetFesDiByParam23(m_ptrCFesRtu, 0, StartAddr + i, j);//R80管理机 FunCode 忽略 + if (pDi != NULL) + { + if (pDi->Revers) //取反 + bitValue ^= 1; + + if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } + } + } + else + if ((m_AppData.lastCmd.Type >= AI_Word_HL) && (m_AppData.lastCmd.Type <= AI_Float_LL))//AI(模拟量) + { + if (m_AppData.lastCmd.Type <= AI_UWord_LH)//AI 16bit + { + PointCount = Data[2] / 2; + for (i = 0; i < PointCount; i++) + { + pAi = GetFesAiByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i);//R80管理机 FunCode 忽略 + if (pAi != NULL) + { + switch (m_AppData.lastCmd.Type) + { + case AI_Word_HL: + sValue16 = (short)Data[3 + i * 2] << 8; + sValue16 |= (short)Data[4 + i * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: + sValue16 = (short)Data[4 + i * 2] << 8; + sValue16 |= (short)Data[3 + i * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: + uValue16 = (uint16)Data[3 + i * 2] << 8; + uValue16 |= (uint16)Data[4 + i * 2]; + aiValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + i * 2] << 8; + uValue16 |= (uint16)Data[3 + i * 2]; + aiValue = uValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + } + else//AI 32bit + { + PointCount = Data[2] / 4; + for (i = 0; i < PointCount; i++) + { + pAi = GetFesAiByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i*2);//R80管理机 FunCode 忽略 + if (pAi!= NULL) + { + switch (m_AppData.lastCmd.Type) + { + case AI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + i * 4] << 24; + sValue32 |= (int)Data[4 + i * 4] << 16; + sValue32 |= (int)Data[5 + i * 4] << 8; + sValue32 |= (int)Data[6 + i * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + i * 4] << 24; + sValue32 |= (int)Data[6 + i * 4] << 16; + sValue32 |= (int)Data[3 + i * 4] << 8; + sValue32 |= (int)Data[4 + i * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + i * 4] << 24; + sValue32 |= (int)Data[5 + i * 4] << 16; + sValue32 |= (int)Data[4 + i * 4] << 8; + sValue32 |= (int)Data[3 + i * 4]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 4] << 24; + uValue32 |= (uint32)Data[4 + i * 4] << 16; + uValue32 |= (uint32)Data[5 + i * 4] << 8; + uValue32 |= (uint32)Data[6 + i * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 4] << 24; + uValue32 |= (uint32)Data[6 + i * 4] << 16; + uValue32 |= (uint32)Data[3 + i * 4] << 8; + uValue32 |= (uint32)Data[4 + i * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 4] << 24; + uValue32 |= (uint32)Data[5 + i * 4] << 16; + uValue32 |= (uint32)Data[4 + i * 4] << 8; + uValue32 |= (uint32)Data[3 + i * 4]; + aiValue = (float)uValue32; + break; + case AI_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 4] << 24; + uValue32 |= (uint32)Data[4 + i * 4] << 16; + uValue32 |= (uint32)Data[5 + i * 4] << 8; + uValue32 |= (uint32)Data[6 + i * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + // LOGDEBUG("Value : %d %d %d %d",Data[3+i*4],Data[4+i*4],Data[5+i*4],Data[6+i*4]); + // LOGDEBUG("aiValue : %f",aiValue); + break; + case AI_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 4] << 24; + uValue32 |= (uint32)Data[6 + i * 4] << 16; + uValue32 |= (uint32)Data[3 + i * 4] << 8; + uValue32 |= (uint32)Data[4 + i * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 4] << 24; + uValue32 |= (uint32)Data[5 + i * 4] << 16; + uValue32 |= (uint32)Data[4 + i * 4] << 8; + uValue32 |= (uint32)Data[3 + i * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + } + + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + + // LOGDEBUG("AiValue[ValueCount].Value : %f",AiValue[ValueCount].Value); + + ValueCount++; + + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + else + if ((m_AppData.lastCmd.Type >= ACC_Word_HL) && (m_AppData.lastCmd.Type <= ACC_Float_LL))//ACC (电度量) + { + if (m_AppData.lastCmd.Type <= ACC_UWord_LH)//ACC 16bit + { + PointCount = Data[2] / 2; + for (i = 0; i < PointCount; i++) + { + pAcc = GetFesAccByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i);//R80管理机 FunCode 忽略 + if (pAcc != NULL) + { + switch (m_AppData.lastCmd.Type) + { + case ACC_Word_HL: + sValue16 = (short)Data[3 + i * 2] << 8; + sValue16 |= (short)Data[4 + i * 2]; + accValue = sValue16; + break; + case ACC_Word_LH: + sValue16 = (short)Data[4 + i * 2] << 8; + sValue16 |= (short)Data[3 + i * 2]; + accValue = sValue16; + break; + case ACC_UWord_HL: + uValue16 = (uint16)Data[3 + i * 2] << 8; + uValue16 |= (uint16)Data[4 + i * 2]; + accValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + i * 2] << 8; + uValue16 |= (uint16)Data[3 + i * 2]; + accValue = uValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + } + else//ACC 32bit + { + PointCount = Data[2] / 4; + for (i = 0; i < PointCount; i++) + { + pAcc = GetFesAccByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i*2);//R80管理机 FunCode 忽略 + if (pAcc != NULL) + { + switch (m_AppData.lastCmd.Type) + { + case ACC_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + i * 4] << 24; + sValue32 |= (int)Data[4 + i * 4] << 16; + sValue32 |= (int)Data[5 + i * 4] << 8; + sValue32 |= (int)Data[6 + i * 4]; + accValue = sValue32; + break; + case ACC_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + i * 4] << 24; + sValue32 |= (int)Data[6 + i * 4] << 16; + sValue32 |= (int)Data[3 + i * 4] << 8; + sValue32 |= (int)Data[4 + i * 4]; + accValue = sValue32; + break; + case ACC_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + i * 4] << 24; + sValue32 |= (int)Data[5 + i * 4] << 16; + sValue32 |= (int)Data[4 + i * 4] << 8; + sValue32 |= (int)Data[3 + i * 4]; + accValue = sValue32; + break; + case ACC_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 4] << 24; + uValue32 |= (uint32)Data[4 + i * 4] << 16; + uValue32 |= (uint32)Data[5 + i * 4] << 8; + uValue32 |= (uint32)Data[6 + i * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 4] << 24; + uValue32 |= (uint32)Data[6 + i * 4] << 16; + uValue32 |= (uint32)Data[3 + i * 4] << 8; + uValue32 |= (uint32)Data[4 + i * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 4] << 24; + uValue32 |= (uint32)Data[5 + i * 4] << 16; + uValue32 |= (uint32)Data[4 + i * 4] << 8; + uValue32 |= (uint32)Data[3 + i * 4]; + accValue = uValue32; + break; + case ACC_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 4] << 24; + uValue32 |= (uint32)Data[4 + i * 4] << 16; + uValue32 |= (uint32)Data[5 + i * 4] << 8; + uValue32 |= (uint32)Data[6 + i * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000; + break; + case ACC_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 4] << 24; + uValue32 |= (uint32)Data[6 + i * 4] << 16; + uValue32 |= (uint32)Data[3 + i * 4] << 8; + uValue32 |= (uint32)Data[4 + i * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000; + break; + case ACC_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 4] << 24; + uValue32 |= (uint32)Data[5 + i * 4] << 16; + uValue32 |= (uint32)Data[4 + i * 4] << 8; + uValue32 |= (uint32)Data[3 + i * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + else + if ((m_AppData.lastCmd.Type >= MI_Word_HL) && (m_AppData.lastCmd.Type <= MI_UDWord_LL))//MI (混合量) + { + if (m_AppData.lastCmd.Type <= MI_UWord_LH)//MI 16bit + { + PointCount = Data[2] / 2; + for (i = 0; i < PointCount; i++) + { + pMi = GetFesMiByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i);//R80管理机 FunCode 忽略 + if (pMi!= NULL) + { + switch (m_AppData.lastCmd.Type) + { + case MI_Word_HL: + sValue16 = (short)Data[3 + i * 2] << 8; + sValue16 |= (short)Data[4 + i * 2]; + miValue = sValue16; + break; + case MI_Word_LH: + sValue16 = (short)Data[4 + i * 2] << 8; + sValue16 |= (short)Data[3 + i * 2]; + miValue = sValue16; + break; + case MI_UWord_HL: + uValue16 = (uint16)Data[3 + i * 2] << 8; + uValue16 |= (uint16)Data[4 + i * 2]; + miValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + i * 2] << 8; + uValue16 |= (uint16)Data[3 + i * 2]; + miValue = uValue16; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + } + else//Mi 32bit + { + PointCount = Data[2] / 4; + for (i = 0; i < PointCount; i++) + { + pMi = GetFesMiByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i*2);//R80管理机 FunCode 忽略 + if (pMi != NULL) + { + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + //StartPointNo = pMi->Param1 + 1; + switch (m_AppData.lastCmd.Type) + { + case MI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + i * 4] << 24; + sValue32 |= (int)Data[4 + i * 4] << 16; + sValue32 |= (int)Data[5 + i * 4] << 8; + sValue32 |= (int)Data[6 + i * 4]; + miValue = sValue32; + break; + case MI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + i * 4] << 24; + sValue32 |= (int)Data[6 + i * 4] << 16; + sValue32 |= (int)Data[3 + i * 4] << 8; + sValue32 |= (int)Data[4 + i * 4]; + miValue = sValue32; + break; + case MI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + i * 4] << 24; + sValue32 |= (int)Data[5 + i * 4] << 16; + sValue32 |= (int)Data[4 + i * 4] << 8; + sValue32 |= (int)Data[3 + i * 4]; + miValue = sValue32; + break; + case MI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 4] << 24; + uValue32 |= (uint32)Data[4 + i * 4] << 16; + uValue32 |= (uint32)Data[5 + i * 4] << 8; + uValue32 |= (uint32)Data[6 + i * 4]; + miValue = uValue32; + break; + case MI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 4] << 24; + uValue32 |= (uint32)Data[6 + i * 4] << 16; + uValue32 |= (uint32)Data[3 + i * 4] << 8; + uValue32 |= (uint32)Data[4 + i * 4]; + miValue = uValue32; + break; + case MI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 4] << 24; + uValue32 |= (uint32)Data[5 + i * 4] << 16; + uValue32 |= (uint32)Data[4 + i * 4] << 8; + uValue32 |= (uint32)Data[3 + i * 4]; + miValue = uValue32; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } +} + +/** +* @brief CModbusDataProcThread::Cmd03RespProcess_BitGroup +* 按位组合的遥信解析处理 +* @param Data 遥信点结构 +* @param DataSize 遥信字节值 +*/ +int CModbusRtuDTDataProcThread::Cmd03RespProcess_BitGroup_PCS3000(SFesDi *pDi, int diValue) +{ + int temp1 = pDi->Param4; + int IntData = diValue & temp1; + int i, YxBit = 0; + + if (temp1 < 0) + return YxBit; + + for (i = 0; i < 16; i++) + { + if ((temp1 >> i) & 0x01) + { + IntData >>= i; + break; + } + } + + if (pDi->Param3 == IntData) + YxBit = 1; + + return YxBit; +} + +/** +* @brief CModbusRtuDTDataProcThread::Cmd01RespProcess +* 命令0x01 0x02的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* @param Data 接收的数据 +*/ +void CModbusRtuDTDataProcThread::Cmd01RespProcess(byte *Data, int DataSize) +{ + boost::ignore_unused_variable_warning(DataSize); + + byte bitValue, byteValue; + int i, StartPointNo, EndPointNo, ValueCount, ChgCount, SoeCount, PointIndex1, PointIndex2; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[50]; + uint64 mSec; + int SZFlag=0; + + if (m_DiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd01RespProcess: 未找到blockId=%d的数字量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + for (i = StartPointNo; i <= EndPointNo; i++) + { + pDi = GetFesDiByPIndex(m_ptrCFesRtu, i); + if (pDi == NULL) + continue; + + PointIndex1 = (pDi->Param3 - m_AppData.lastCmd.StartAddr) / 8; + if ((PointIndex1 < 0) || (PointIndex1 > MAX_POINT_INDEX*1.5)) + { + if (i == StartPointNo) + LOGDEBUG("RTU%d数据块:SeqNo=%d,headIndex=%d,tailIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.SeqNo, StartPointNo, EndPointNo); + LOGDEBUG("RTU%d数组下标越限,StartAddr=%d,pDi->Param3=%d,PointIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.StartAddr, pDi->Param3, PointIndex1); + continue; + } + + byteValue = Data[3 + PointIndex1]; + PointIndex2 = (pDi->Param3 - m_AppData.lastCmd.StartAddr) % 8; + bitValue = (byteValue >> PointIndex2) & 0x01; + + if (pDi->Revers) + bitValue ^= 1; + +// int reportFlag = 0; +// if (pDi->Param5 == 1)//2023-03-06 thxiao 系统重起后,存在的告警不需要上送 +// { +// if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据,更新过的点才能报告变化 +// reportFlag = 1; +// } +// else +// if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 +// reportFlag = 1; + + if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + if(m_ptrCFesRtu->m_Param.ResParam3== CN_ModbusRtuDT_YD) + SZFlag = 1; + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + //更新点值 + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } + if (SZFlag == 1) + AlarmCalc(); + +} + +/** +* @brief CModbusRtuDTDataProcThread::Cmd03RespProcess_BitGroup +* 按位组合的遥信解析处理 +* @param Data 遥信点结构 +* @param DataSize 遥信字节值 +*/ +int CModbusRtuDTDataProcThread::Cmd03RespProcess_BitGroup(SFesDi *pDi, int diValue) +{ + int temp1 = pDi->Param5; + int IntData = diValue & temp1; + int i, YxBit = 0; + + if (temp1 < 0) + return YxBit; + + for (i = 0; i < 16; i++) + { + if ((temp1 >> i) & 0x01) + { + IntData >>= i; + break; + } + } + + if (pDi->Param4 == IntData) + YxBit = 1; + + return YxBit; +} + +/** +* @brief CModbusRtuDTDataProcThread::Cmd03RespProcess +* 命令0x03 0x04的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusRtuDTDataProcThread::Cmd03RespProcess(byte *Data, int DataSize) +{ + boost::ignore_unused_variable_warning(DataSize); + + int FunCode, diValue, bitValue; + int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, SoeCount, PointIndex; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[100]; + uint64 mSec; + SFesAi *pAi; + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + SFesMi *pMi; + SFesRtuMiValue MiValue[100]; + SFesChgMi ChgMi[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + int64 accValue; + int miValue=0; + int reportFlag; + int SZFlag = 0; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + if ((m_AppData.lastCmd.Type == DI_UWord_HL) || (m_AppData.lastCmd.Type == DI_UWord_LH))//DI + { + if (m_DiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的数字量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + for (i = StartPointNo; i <= EndPointNo; i++) + { + pDi = GetFesDiByPIndex(m_ptrCFesRtu, i); + if (pDi == NULL) + continue; + + PointIndex = pDi->Param3 - m_AppData.lastCmd.StartAddr; + if ((PointIndex < 0) || (PointIndex > MAX_POINT_INDEX)) + { + if (i == StartPointNo) + LOGDEBUG("RTU%d数据块:SeqNo=%d,headIndex=%d,tailIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.SeqNo, StartPointNo, EndPointNo); + LOGDEBUG("RTU%d数组下标越限,StartAddr=%d,pDi->Param3=%d,PointIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.StartAddr, pDi->Param3, PointIndex); + continue; + } + if (m_AppData.lastCmd.Type == DI_UWord_HL) + { + diValue = (int)Data[3 + PointIndex * 2] << 8; + diValue |= (int)Data[4 + PointIndex * 2]; + } + else//DI_UWord_LH + { + diValue = (int)Data[4 + PointIndex * 2] << 8; + diValue |= (int)Data[3 + PointIndex * 2]; + } + + if (m_AppData.lastCmd.Param1 == 1) //数据块自定义#1 = 1,遥信按位组合 + { + bitValue = Cmd03RespProcess_BitGroup(pDi, diValue); + + reportFlag = 0; +// if (pDi->Param5 == 1)//2023-03-06 thxiao 系统重起后,存在的告警不需要上送 +// { +// if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据,更新过的点才能报告变化 +// reportFlag = 1; +// } +// else +// if (pDi->Param5 == 5)//2022-12-26 告警使能标志为1,才可以产生告警 +// { +// if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true) && (pDi->Param6 == 1)) +// reportFlag = 1; +// } +// else +// if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 +// reportFlag = 1; + + if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + //if(reportFlag) + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + + if ((pDi->Param5 == 5) && (pDi->Param6 == 0))//2022-12-26 告警使能标志为1,才可以产生告警 + { + //点值正常 + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = 0; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + } + else + { + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + } + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + //事故总判断 + if (m_ptrCFesRtu->m_Param.ResParam3 == CN_ModbusRtuDT_YD) + SZFlag = 1; + } + else + { + bitValue = (diValue >> (pDi->Param4)) & 0x01; + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + if (pDi->Revers) + bitValue ^= 1; + + reportFlag = 0; + if (pDi->Param5 == 1) + { + if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据,更新过的点才能报告变化 + reportFlag = 1; + } + else + if (pDi->Param5 == 5)//2022-12-26 告警使能标志为1,才可以产生告警 + { + if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true) && (pDi->Param6 == 1)) + reportFlag = 1; + } + else + if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + reportFlag = 1; + + //if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + if(reportFlag) + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + //事故总判断 + if (m_ptrCFesRtu->m_Param.ResParam3 == CN_ModbusRtuDT_YD) + SZFlag = 1; + } + if ((pDi->Param5 == 5) && (pDi->Param6 == 0))//2022-12-26 告警使能标志为1,才可以产生告警 + { + //点值正常 + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = 0; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + } + else + { + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + } + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } + if (SZFlag == 1) + AlarmCalc(); + + } + else + if (((m_AppData.lastCmd.Type >= AI_Word_HL) && (m_AppData.lastCmd.Type <= AI_Float_LL)) || (m_AppData.lastCmd.Type == AI_SIGNEDFLAG16_HL) || (m_AppData.lastCmd.Type == AI_SIGNEDFLAG32_HL))//AI + { + if (m_AiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的模拟量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + if ((m_AppData.lastCmd.Type <= AI_UWord_LH) || (m_AppData.lastCmd.Type == AI_SIGNEDFLAG16_HL))//AI 16bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + PointIndex = pAi->Param3 - m_AppData.lastCmd.StartAddr; + if ((PointIndex < 0) || (PointIndex > MAX_POINT_INDEX)) + { + if (i == StartPointNo) + LOGDEBUG("RTU%d数据块:SeqNo=%d,headIndex=%d,tailIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.SeqNo, StartPointNo, EndPointNo); + LOGDEBUG("RTU%d数组下标越限,StartAddr=%d,pAi->Param3=%d,PointIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.StartAddr, pAi->Param3, PointIndex); + continue; + } + switch (m_AppData.lastCmd.Type) + { + case AI_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + aiValue = uValue16; + break; + case AI_SIGNEDFLAG16_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + if (uValue16 & 0x8000) + { + aiValue = (float)(uValue16 & 0x7fff); + aiValue = 0 - aiValue; + } + else + aiValue = (float)(uValue16 & 0x7fff); + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + aiValue = uValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + else//AI 32bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + PointIndex = (pAi->Param3 - m_AppData.lastCmd.StartAddr) / 2; + if ((PointIndex < 0) || (PointIndex > MAX_POINT_INDEX)) + { + if (i == StartPointNo) + LOGDEBUG("RTU%d数据块:SeqNo=%d,headIndex=%d,tailIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.SeqNo, StartPointNo, EndPointNo); + LOGDEBUG("RTU%d数组下标越限,StartAddr=%d,pAi->Param3=%d,PointIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.StartAddr, pAi->Param3, PointIndex); + continue; + } + switch (m_AppData.lastCmd.Type) + { + case AI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_SIGNEDFLAG32_HL: + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + if (uValue32 & 0x80000000) + { + aiValue = (float)(uValue32 & 0x7fffffff); + aiValue = 0 - aiValue; + } + else + aiValue = (float)(uValue32 & 0x7fffffff); + break; + } + + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + + ValueCount++; + + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + else + if ((m_AppData.lastCmd.Type >= ACC_Word_HL) && (m_AppData.lastCmd.Type <= ACC_Float_LL))//ACC + { + if (m_AccBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的累积量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + if (m_AppData.lastCmd.Type <= ACC_UWord_LH)//ACC 16bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + PointIndex = pAcc->Param3 - m_AppData.lastCmd.StartAddr; + if ((PointIndex < 0) || (PointIndex > MAX_POINT_INDEX)) + { + if (i == StartPointNo) + LOGDEBUG("RTU%d数据块:SeqNo=%d,headIndex=%d,tailIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.SeqNo, StartPointNo, EndPointNo); + LOGDEBUG("RTU%d数组下标越限,StartAddr=%d,pAcc->Param3=%d,PointIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.StartAddr, pAcc->Param3, PointIndex); + continue; + } + switch (m_AppData.lastCmd.Type) + { + case ACC_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + accValue = sValue16; + break; + case ACC_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + accValue = sValue16; + break; + case ACC_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + accValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + accValue = uValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + else//ACC 32bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + PointIndex = (pAcc->Param3 - m_AppData.lastCmd.StartAddr) / 2; + if ((PointIndex < 0) || (PointIndex > MAX_POINT_INDEX)) + { + if (i == StartPointNo) + LOGDEBUG("RTU%d数据块:SeqNo=%d,headIndex=%d,tailIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.SeqNo, StartPointNo, EndPointNo); + LOGDEBUG("RTU%d数组下标越限,StartAddr=%d,pAcc->Param3=%d,PointIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.StartAddr, pAcc->Param3, PointIndex); + continue; + } + switch (m_AppData.lastCmd.Type) + { + case ACC_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000; + break; + case ACC_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000; + break; + case ACC_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + else + if ((m_AppData.lastCmd.Type >= MI_Word_HL) && (m_AppData.lastCmd.Type <= MI_UDWord_LL))//MI + { + if (m_MiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_MiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_MiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + + if (m_AppData.lastCmd.Type <= MI_UWord_LH)//MI 16bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pMi = GetFesMiByPIndex(m_ptrCFesRtu, i); + if (pMi == NULL) + continue; + + //2022-12-09 取点值应该为PointIndex + PointIndex = pMi->Param3 - m_AppData.lastCmd.StartAddr; + if ((PointIndex < 0) || (PointIndex > MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case MI_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + miValue = sValue16; + break; + case MI_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + miValue = sValue16; + break; + case MI_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + miValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + miValue = uValue16; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + else//Mi 32bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pMi = GetFesMiByPIndex(m_ptrCFesRtu, i); + if (pMi == NULL) + continue; + + //2022-12-09 取点值应该为PointIndex + PointIndex = (pMi->Param3 - m_AppData.lastCmd.StartAddr) / 2; + if ((PointIndex < 0) || (PointIndex > MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case MI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + miValue = uValue32; + break; + case MI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + miValue = uValue32; + break; + case MI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 4] << 24; + uValue32 |= (uint32)Data[5 + i * 4] << 16; + uValue32 |= (uint32)Data[4 + i * 4] << 8; + uValue32 |= (uint32)Data[3 + i * 4]; + miValue = uValue32; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } +} + + +void CModbusRtuDTDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) +{ + boost::ignore_unused_variable_warning(DataSize); + + int i, StartPointNo, EndPointNo, ValueCount, ChgCount, PointIndex; + uint64 mSec; + SFesAi *pAi; + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + int64 accValue; + int accValueCount, accChgCount,setAccFlag; + + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + if (m_AppData.lastCmd.Type == AI_Hybrid_Type)//AI 模拟量混合量帧 + { + if (m_AiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("CmdTypeHybridProcess: 未找到blockId=%d的模拟量混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + accValueCount = 0; + accChgCount = 0; + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + PointIndex = pAi->Param3 - m_AppData.lastCmd.StartAddr; + if ((PointIndex < 0) || (PointIndex > MAX_POINT_INDEX)) + { + if (i == StartPointNo) + LOGDEBUG("RTU%d数据块:SeqNo=%d,headIndex=%d,tailIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.SeqNo, StartPointNo, EndPointNo); + LOGDEBUG("RTU%d数组下标越限,StartAddr=%d,pAi->Param3=%d,PointIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.StartAddr, pAi->Param3, PointIndex); + continue; + } + setAccFlag = 0; + switch (pAi->Param4) + { + case AI_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)Data[4 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[3 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + aiValue = uValue16; + break; + case AI_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + aiValue = (float)uValue16; + break; + case AI_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 2] << 24; + sValue32 |= (int)Data[4 + PointIndex * 2] << 16; + sValue32 |= (int)Data[5 + PointIndex * 2] << 8; + sValue32 |= (int)Data[6 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 2] << 24; + sValue32 |= (int)Data[6 + PointIndex * 2] << 16; + sValue32 |= (int)Data[3 + PointIndex * 2] << 8; + sValue32 |= (int)Data[4 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 2] << 24; + sValue32 |= (int)Data[5 + PointIndex * 2] << 16; + sValue32 |= (int)Data[4 + PointIndex * 2] << 8; + sValue32 |= (int)Data[3 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case AI_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + //以下ACC类型也同样处理 + case ACC_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 2] << 24; + sValue32 |= (int)Data[4 + PointIndex * 2] << 16; + sValue32 |= (int)Data[5 + PointIndex * 2] << 8; + sValue32 |= (int)Data[6 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case ACC_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 2] << 24; + sValue32 |= (int)Data[6 + PointIndex * 2] << 16; + sValue32 |= (int)Data[3 + PointIndex * 2] << 8; + sValue32 |= (int)Data[4 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case ACC_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 2] << 24; + sValue32 |= (int)Data[5 + PointIndex * 2] << 16; + sValue32 |= (int)Data[4 + PointIndex * 2] << 8; + sValue32 |= (int)Data[3 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case ACC_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case ACC_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case ACC_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case ACC_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue*1000; + break; + case ACC_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue*1000; + if (pAi->Param7 != -1) + { + setAccFlag = 1;//设置ACC + accValue = aiValue; + } + break; + case ACC_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue*1000; + break; + case AI_16BIT_BYBITS://模拟量帧(取16bit 按位组合取值) + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + uValue16 &= pAi->Param5; + aiValue = (uValue16>> pAi->Param6)&0x0f; + break; + default: + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + if (setAccFlag) + { + AccValue[accValueCount].PointNo = pAi->Param7;//pAi->Param7=pAcc->PointNo; + AccValue[accValueCount].Value = accValue; + AccValue[accValueCount].Status = CN_FesValueUpdate; + AccValue[accValueCount].time = mSec; + accValueCount++; + if (accValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(accValueCount, &AccValue[0], &accChgCount, &ChgAcc[0]); + accValueCount = 0; + if ((accChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + accChgCount = 0; + } + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + + if (accValueCount >0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(accValueCount, &AccValue[0], &accChgCount, &ChgAcc[0]); + accValueCount = 0; + if ((accChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + accChgCount = 0; + } + } + } + else if (m_AppData.lastCmd.Type == ACC_Hybrid_Type)//ACC 累积量混合量帧 + { + if (m_AccBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("CmdTypeHybridProcess: 未找到blockId=%d的累积量混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + PointIndex = pAcc->Param3 - m_AppData.lastCmd.StartAddr; + if ((PointIndex < 0) || (PointIndex > MAX_POINT_INDEX)) + { + if (i == StartPointNo) + LOGDEBUG("RTU%d数据块:SeqNo=%d,headIndex=%d,tailIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.SeqNo, StartPointNo, EndPointNo); + LOGDEBUG("RTU%d数组下标越限,StartAddr=%d,pAcc->Param3=%d,PointIndex=%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.lastCmd.StartAddr, pAcc->Param3, PointIndex); + continue; + } + switch (pAcc->Param4) + { + case ACC_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + accValue = (int64)sValue16; + break; + case ACC_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)Data[4 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[3 + PointIndex * 2]; + accValue = (int64)sValue16; + break; + case ACC_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + accValue = (int64)uValue16; + break; + case ACC_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + accValue = (int64)uValue16; + break; + case ACC_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 2] << 24; + sValue32 |= (int)Data[4 + PointIndex * 2] << 16; + sValue32 |= (int)Data[5 + PointIndex * 2] << 8; + sValue32 |= (int)Data[6 + PointIndex * 2]; + accValue = (int64)sValue32; + break; + case ACC_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 2] << 24; + sValue32 |= (int)Data[6 + PointIndex * 2] << 16; + sValue32 |= (int)Data[3 + PointIndex * 2] << 8; + sValue32 |= (int)Data[4 + PointIndex * 2]; + accValue = (int64)sValue32; + break; + case ACC_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 2] << 24; + sValue32 |= (int)Data[5 + PointIndex * 2] << 16; + sValue32 |= (int)Data[4 + PointIndex * 2] << 8; + sValue32 |= (int)Data[3 + PointIndex * 2]; + accValue = (int64)sValue32; + break; + case ACC_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + accValue = (int64)uValue32; + break; + case ACC_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + accValue = (int64)uValue32; + break; + case ACC_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + accValue = (int64)uValue32; + break; + case ACC_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000; + break; + case ACC_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000; + break; + case ACC_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000; + break; + default: + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + accValue = (int64)sValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } +} + + +/** +* @brief CModbusDataProcThread::Cmd05RespProcess +* 命令0x05的处理。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusRtuDTDataProcThread::Cmd05RespProcess(byte *Data, int DataSize) +{ + CmdControlRespProcess(Data, DataSize, 1); +} + +/** +* @brief CModbusDataProcThread::Cmd06RespProcess +* 命令0x06的处理。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusRtuDTDataProcThread::Cmd06RespProcess(byte *Data, int DataSize) +{ + CmdControlRespProcess(Data, DataSize, 1); +} +/** +* @brief CModbusRtuDTDataProcThread::Cmd10RespProcess +* 命令0x10的处理。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusRtuDTDataProcThread::Cmd10RespProcess(byte *Data, int DataSize) +{ + CmdControlRespProcess(Data, DataSize, 1); +} + +/** +* @brief CModbusRtuDTDataProcThread::CmdControlRespProcess +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +* @param okFlag 命令成功标志 1:成功 0:失败 +* @return 是控制命令返回:TRUE 否则为:FALSE +*/ +bool CModbusRtuDTDataProcThread::CmdControlRespProcess(byte *Data, int DataSize, int okFlag) +{ + boost::ignore_unused_variable_warning(Data); + boost::ignore_unused_variable_warning(DataSize); + + SFesTxDoCmd retDoCmd; + SFesTxAoCmd retAoCmd; + SFesTxMoCmd retMoCmd; + SFesTxDefCmd retDefCmd; + + if (m_AppData.state != CN_ModbusRtuDTAppState_waitControlResp) + return false; + + switch (m_AppData.lastCotrolcmd) + { + case CN_ModbusRtuDTDoCmd: + //memset(&retDoCmd,0,sizeof(retDoCmd)); + if (okFlag) + { + retDoCmd.retStatus = CN_ControlSuccess; + sprintf(retDoCmd.strParam, I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.doCmd.PointID); + LOGINFO("遥控成功!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.doCmd.PointID); + + //遥控操作返回成功后,反校处理 + DoVerifyProcess(); + } + else + { + retDoCmd.retStatus = CN_ControlFailed; + sprintf(retDoCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.doCmd.PointID); + LOGINFO("遥控失败!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.doCmd.PointID); + } + strcpy(retDoCmd.TableName, m_AppData.doCmd.TableName); + strcpy(retDoCmd.ColumnName, m_AppData.doCmd.ColumnName); + strcpy(retDoCmd.TagName, m_AppData.doCmd.TagName); + strcpy(retDoCmd.RtuName, m_AppData.doCmd.RtuName); + retDoCmd.CtrlActType = m_AppData.doCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retDoCmd.CtrlDir = m_AppData.doCmd.CtrlDir; + retDoCmd.RtuNo = m_AppData.doCmd.RtuNo; + retDoCmd.PointID = m_AppData.doCmd.PointID; + retDoCmd.FwSubSystem = m_AppData.doCmd.FwSubSystem; + retDoCmd.FwRtuNo = m_AppData.doCmd.FwRtuNo; + retDoCmd.FwPointNo = m_AppData.doCmd.FwPointNo; + retDoCmd.SubSystem = m_AppData.doCmd.SubSystem; + + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retDoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retDoCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return true; + break; + case CN_ModbusRtuDTAoCmd: + if (okFlag) + { + retAoCmd.retStatus = CN_ControlSuccess; + sprintf(retAoCmd.strParam, I18N("遥调成功!RtuNo:%d 遥调点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + LOGINFO("遥调成功!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + + AoVerifyProcess(); + LOGDEBUG("遥调成功!AoVerifyProcess 成功!"); + + } + else + { + retAoCmd.retStatus = CN_ControlFailed; + sprintf(retAoCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + LOGINFO("遥调失败!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + } + strcpy(retAoCmd.TableName, m_AppData.aoCmd.TableName); + strcpy(retAoCmd.ColumnName, m_AppData.aoCmd.ColumnName); + strcpy(retAoCmd.TagName, m_AppData.aoCmd.TagName); + strcpy(retAoCmd.RtuName, m_AppData.aoCmd.RtuName); + retAoCmd.CtrlActType = m_AppData.aoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retAoCmd.CtrlDir = m_AppData.aoCmd.CtrlDir; + retAoCmd.RtuNo = m_AppData.aoCmd.RtuNo; + retAoCmd.PointID = m_AppData.aoCmd.PointID; + retAoCmd.FwSubSystem = m_AppData.aoCmd.FwSubSystem; + retAoCmd.FwRtuNo = m_AppData.aoCmd.FwRtuNo; + retAoCmd.FwPointNo = m_AppData.aoCmd.FwPointNo; + retAoCmd.SubSystem = m_AppData.aoCmd.SubSystem; + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retAoCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return true; + break; + case CN_ModbusRtuDTMoCmd: + if (okFlag) + { + retMoCmd.retStatus = CN_ControlSuccess; + sprintf(retMoCmd.strParam, I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + LOGINFO("混合量输出成功!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + } + else + { + retMoCmd.retStatus = CN_ControlFailed; + sprintf(retMoCmd.strParam, I18N("混合量输出失败!RtuNo:%d 混合量输出点:%d").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + LOGINFO("混合量输出失败!RtuNo:%d 遥控点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + } + strcpy(retMoCmd.TableName, m_AppData.moCmd.TableName); + strcpy(retMoCmd.ColumnName, m_AppData.moCmd.ColumnName); + strcpy(retMoCmd.TagName, m_AppData.moCmd.TagName); + strcpy(retMoCmd.RtuName, m_AppData.moCmd.RtuName); + retMoCmd.CtrlActType = m_AppData.moCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retMoCmd.CtrlDir = m_AppData.moCmd.CtrlDir; + retMoCmd.RtuNo = m_AppData.moCmd.RtuNo; + retMoCmd.PointID = m_AppData.moCmd.PointID; + retMoCmd.FwSubSystem = m_AppData.moCmd.FwSubSystem; + retMoCmd.FwRtuNo = m_AppData.moCmd.FwRtuNo; + retMoCmd.FwPointNo = m_AppData.moCmd.FwPointNo; + retMoCmd.SubSystem = m_AppData.moCmd.SubSystem; + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1, &retMoCmd); + + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return true; + break; + case CN_ModbusRtuDTDefCmd: + if (okFlag) + { + retDefCmd.retStatus = CN_ControlSuccess; + sprintf(retDefCmd.strParam, I18N("自定义命令输出成功!RtuNo:%d ").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo); + LOGINFO("自定义命令输出成功!RtuNo:%d ", m_ptrCInsertFesRtu->m_Param.RtuNo); + } + else + { + retDefCmd.retStatus = CN_ControlFailed; + sprintf(retDefCmd.strParam, I18N("自定义命令输出失败!RtuNo:%d ").str().c_str(), m_ptrCInsertFesRtu->m_Param.RtuNo); + LOGINFO("自定义命令输出失败!RtuNo:%d ", m_ptrCInsertFesRtu->m_Param.RtuNo); + } + strcpy(retDefCmd.TableName, m_AppData.defCmd.TableName); + strcpy(retDefCmd.ColumnName, m_AppData.defCmd.ColumnName); + strcpy(retDefCmd.TagName, m_AppData.defCmd.TagName); + strcpy(retDefCmd.RtuName, m_AppData.defCmd.RtuName); + retDefCmd.DevId = m_AppData.defCmd.DevId; + retDefCmd.CmdNum = m_AppData.defCmd.CmdNum; + retDefCmd.VecCmd = m_AppData.defCmd.VecCmd; + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &retDefCmd); + m_AppData.lastCotrolcmd = CN_ModbusRtuDTNoCmd; + m_AppData.state = CN_ModbusRtuDTAppState_idle; + return true; + break; + default: + break; + } + return false; +} + +/** +* @brief CModbusRtuDTDataProcThread::SendDataToPort +* 数据发送到发送缓冲区。 +* 如是主通道,直接使用m_ptrCFesChan通道结构;如果是备用通道,需要获取当前使用通道,在发送数据。 +* @param Data 数据区 +* @param Size 数据区长度 +*/ +void CModbusRtuDTDataProcThread::SendDataToPort(byte *Data, int Size) +{ + if (m_ptrCurrentChan == NULL) + return; + + switch (m_ptrCurrentChan->m_Param.CommType) + { + case CN_FesSerialPort: + if (m_ptrComSerial != NULL) + { + //RTU PARAM2 = 1000 为延时发送时间,单位毫秒 + if (m_ptrCFesRtu->m_Param.ResParam2 > 0) + SleepmSec(m_ptrCFesRtu->m_Param.ResParam2); + + m_ptrComSerial->TxComData(m_ptrCurrentChan,Size, Data); + + //saved last send cmd + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, Data, Size, CN_SFesSimComFrameTypeSend); + m_ptrCurrentChan->SetTxNum(1); + if (m_ptrCInsertFesRtu != NULL) //InsertCmd + m_ptrCInsertFesRtu->SetTxNum(1); + else + m_ptrCFesRtu->SetTxNum(1); + + memcpy(&m_AppData.lastCmdData[0], Data, Size); + m_AppData.lastCmdDataLen = Size; + + } + else + { + LOGDEBUG("ChanNo=%d m_ptrComSerial is NULL can not send data", m_ptrCurrentChan->m_Param.ChanNo); + } + + + break; + case CN_FesTcpClient: + if (m_ptrCurrentChan->m_LinkStatus != CN_FesChanConnect)//2021-01-22 thxiao + return; + + if (m_ptrComClient != NULL) + { + //RTU PARAM2 = 1000 为延时发送时间,单位毫秒 + if (m_ptrCFesRtu->m_Param.ResParam2 > 0) + SleepmSec(m_ptrCFesRtu->m_Param.ResParam2); + + m_ptrComClient->TxData(m_ptrCurrentChan,Size, Data); + + //saved last send cmd + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, Data, Size, CN_SFesSimComFrameTypeSend); + m_ptrCurrentChan->SetTxNum(1); + if (m_ptrCInsertFesRtu != NULL) //InsertCmd + m_ptrCInsertFesRtu->SetTxNum(1); + else + m_ptrCFesRtu->SetTxNum(1); + + memcpy(&m_AppData.lastCmdData[0], Data, Size); + m_AppData.lastCmdDataLen = Size; + + } + else + { + LOGDEBUG("ChanNo=%d m_ptrComClient is NULL can not send data", m_ptrCurrentChan->m_Param.ChanNo); + } + break; + default: + break; + + } + + +} + +int CModbusRtuDTDataProcThread::CrcSum(byte *Data, int Count) +{ + int i, j; + int Temp = 0xffff, Temp1; + for (i = 0; i < Count; i++) + { + Temp = Data[i] ^ Temp; + for (j = 0; j < 8; j++) + { + Temp1 = Temp & 1; + Temp >>= 1; + if (Temp1) + Temp ^= 0xa001; + } + } + + return Temp; +} + + +/* +2019-08-30 按原有的方式,时间间隔最大为100MS,过大,所以改为程序内部处理 +*/ +void CModbusRtuDTDataProcThread::SetSendCmdFlag() +{ + SModbusCmd *pCmd; + int i, j, RtuNo; + int64 lTime, tempTime; + CFesRtuPtr ptrFesRtu; + + if (m_AppData.setCmdCount++ > 2) + { + m_AppData.setCmdCount = 0; + lTime = getMonotonicMsec(); //MS + for (i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((ptrFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) + continue; + for (j = 0; j < ptrFesRtu->m_Param.ModbusCmdBuf.num; j++) + { + pCmd = ptrFesRtu->m_Param.ModbusCmdBuf.pCmd + j; + if(pCmd->Used)//2022-09-06 thxiao 启用块使能 + { + if (DZ_DI_BYTE_LH < pCmd->Type && pCmd->Type < DZ_AI_Float_LL) + continue; //保护定值数据块 + + tempTime = lTime - pCmd->lastPollTime; + if (tempTime > pCmd->PollTime) + { + pCmd->CommandSendFlag = true; + pCmd->lastPollTime = lTime; + //LOGDEBUG("cmd=%d m_CurrentRtuIndex=%d StartAddr=%d PollTime=%d CommandSendFlag=true", j, m_ptrCurrentChan->m_CurrentRtuIndex, pCmd->StartAddr, pCmd->PollTime); + } + else + if (tempTime <= 0)//避免时间错的情况发生 + { + pCmd->lastPollTime = lTime; + } + } + } + } + } +} + +void CModbusRtuDTDataProcThread::CmdTypeHybridProcess_PCS3000(byte *Data, int DataSize) +{ + boost::ignore_unused_variable_warning(DataSize); + + int FunCode; + int i, StartAddr, StartPointNo, ValueCount, ChgCount, PointCount; + uint64 mSec; + SFesAi *pAi; + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + int64 accValue; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + StartPointNo = 0; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + if (m_AppData.lastCmd.Type == AI_Hybrid_Type)//AI 模拟量混合量帧 + { + PointCount = Data[2] / 2; + for (i = 0; i < PointCount; i++) + { + if (m_ptrCFesRtu->m_Param.ResParam1 == 1) + { + pAi = GetFesAiByPIndexParam23(m_ptrCFesRtu, StartPointNo, FunCode, StartAddr + i); + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + if (pAi != NULL) + StartPointNo = pAi->Param1 + 1; + } + else + { + pAi = GetFesAiByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i);//R80管理机 FunCode 忽略 + } + switch (pAi->Param4) + { + case AI_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)Data[3 + i * 2] << 8; + sValue16 |= (int16)Data[4 + i * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)Data[4 + i * 2] << 8; + sValue16 |= (int16)Data[3 + i * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)Data[3 + i * 2] << 8; + uValue16 |= (uint16)Data[4 + i * 2]; + aiValue = uValue16; + break; + case AI_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)Data[4 + i * 2] << 8; + uValue16 |= (uint16)Data[3 + i * 2]; + aiValue = uValue16; + break; + case AI_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + i * 2] << 24; + sValue32 |= (int)Data[4 + i * 2] << 16; + sValue32 |= (int)Data[5 + i * 2] << 8; + sValue32 |= (int)Data[6 + i * 2]; + aiValue = (float)sValue32; + i++; + break; + case AI_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + i * 2] << 24; + sValue32 |= (int)Data[6 + i * 2] << 16; + sValue32 |= (int)Data[3 + i * 2] << 8; + sValue32 |= (int)Data[4 + i * 2]; + aiValue = (float)sValue32; + i++; + break; + case AI_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + i * 2] << 24; + sValue32 |= (int)Data[5 + i * 2] << 16; + sValue32 |= (int)Data[4 + i * 2] << 8; + sValue32 |= (int)Data[3 + i * 2]; + aiValue = (float)sValue32; + i++; + break; + case AI_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 2] << 24; + uValue32 |= (uint32)Data[4 + i * 2] << 16; + uValue32 |= (uint32)Data[5 + i * 2] << 8; + uValue32 |= (uint32)Data[6 + i * 2]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 2] << 24; + uValue32 |= (uint32)Data[6 + i * 2] << 16; + uValue32 |= (uint32)Data[3 + i * 2] << 8; + uValue32 |= (uint32)Data[4 + i * 2]; + aiValue = (float)uValue32; + i++; + break; + case AI_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 2] << 24; + uValue32 |= (uint32)Data[5 + i * 2] << 16; + uValue32 |= (uint32)Data[4 + i * 2] << 8; + uValue32 |= (uint32)Data[3 + i * 2]; + aiValue = (float)uValue32; + i++; + break; + case AI_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 2] << 24; + uValue32 |= (uint32)Data[4 + i * 2] << 16; + uValue32 |= (uint32)Data[5 + i * 2] << 8; + uValue32 |= (uint32)Data[6 + i * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + i++; + break; + case AI_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 2] << 24; + uValue32 |= (uint32)Data[6 + i * 2] << 16; + uValue32 |= (uint32)Data[3 + i * 2] << 8; + uValue32 |= (uint32)Data[4 + i * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 2] << 24; + uValue32 |= (uint32)Data[5 + i * 2] << 16; + uValue32 |= (uint32)Data[4 + i * 2] << 8; + uValue32 |= (uint32)Data[3 + i * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + i++; + break; + default: + sValue16 = (int16)Data[3 + i * 2] << 8; + sValue16 |= (int16)Data[4 + i * 2]; + aiValue = sValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + else if (m_AppData.lastCmd.Type == ACC_Hybrid_Type)//ACC 累积量混合量帧 + { + PointCount = Data[2] / 2; + for (i = 0; i < PointCount; i++) + { + if (m_ptrCFesRtu->m_Param.ResParam1 == 1) + { + pAcc = GetFesAccByPIndexParam23(m_ptrCFesRtu, StartPointNo, FunCode, StartAddr + i); + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + if (pAcc != NULL) + StartPointNo = pAcc->Param1 + 1; + } + else + { + pAcc = GetFesAccByParam23(m_ptrCFesRtu, StartPointNo, 0, StartAddr + i);//R80管理机 FunCode 忽略 + } + + switch (pAcc->Param4) + { + case ACC_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)Data[3 + i * 2] << 8; + sValue16 |= (int16)Data[4 + i * 2]; + accValue = sValue16; + break; + case ACC_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)Data[4 + i * 2] << 8; + sValue16 |= (int16)Data[3 + i * 2]; + accValue = sValue16; + break; + case ACC_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)Data[3 + i * 2] << 8; + uValue16 |= (uint16)Data[4 + i * 2]; + accValue = uValue16; + break; + case ACC_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)Data[4 + i * 2] << 8; + uValue16 |= (uint16)Data[3 + i * 2]; + accValue = uValue16; + break; + case ACC_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + i * 2] << 24; + sValue32 |= (int)Data[4 + i * 2] << 16; + sValue32 |= (int)Data[5 + i * 2] << 8; + sValue32 |= (int)Data[6 + i * 2]; + accValue = sValue32; + i++; + break; + case ACC_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + i * 2] << 24; + sValue32 |= (int)Data[6 + i * 2] << 16; + sValue32 |= (int)Data[3 + i * 2] << 8; + sValue32 |= (int)Data[4 + i * 2]; + accValue = sValue32; + i++; + break; + case ACC_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + i * 2] << 24; + sValue32 |= (int)Data[5 + i * 2] << 16; + sValue32 |= (int)Data[4 + i * 2] << 8; + sValue32 |= (int)Data[3 + i * 2]; + accValue = sValue32; + i++; + break; + case ACC_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 2] << 24; + uValue32 |= (uint32)Data[4 + i * 2] << 16; + uValue32 |= (uint32)Data[5 + i * 2] << 8; + uValue32 |= (uint32)Data[6 + i * 2]; + accValue = uValue32; + break; + case ACC_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 2] << 24; + uValue32 |= (uint32)Data[6 + i * 2] << 16; + uValue32 |= (uint32)Data[3 + i * 2] << 8; + uValue32 |= (uint32)Data[4 + i * 2]; + accValue = uValue32; + i++; + break; + case ACC_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 2] << 24; + uValue32 |= (uint32)Data[5 + i * 2] << 16; + uValue32 |= (uint32)Data[4 + i * 2] << 8; + uValue32 |= (uint32)Data[3 + i * 2]; + accValue = uValue32; + i++; + break; + case ACC_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + i * 2] << 24; + uValue32 |= (uint32)Data[4 + i * 2] << 16; + uValue32 |= (uint32)Data[5 + i * 2] << 8; + uValue32 |= (uint32)Data[6 + i * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000; + i++; + break; + case ACC_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + i * 2] << 24; + uValue32 |= (uint32)Data[6 + i * 2] << 16; + uValue32 |= (uint32)Data[3 + i * 2] << 8; + uValue32 |= (uint32)Data[4 + i * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000; + break; + case ACC_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + i * 2] << 24; + uValue32 |= (uint32)Data[5 + i * 2] << 16; + uValue32 |= (uint32)Data[4 + i * 2] << 8; + uValue32 |= (uint32)Data[3 + i * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000; + i++; + break; + default: + sValue16 = (int16)Data[3 + i * 2] << 8; + sValue16 |= (int16)Data[4 + i * 2]; + accValue = sValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } +} + +/** +* @brief CModbusRtuDTDataProcThread::ErrorControlRespProcess +* @param +* @param +* @param 网络令来需要做异常处理断开时有控制命 +* @return +*/ +void CModbusRtuDTDataProcThread::ErrorControlRespProcess() +{ + SFesRxDoCmd RxDoCmd; + SFesTxDoCmd TxDoCmd; + SFesRxAoCmd RxAoCmd; + SFesTxAoCmd TxAoCmd; + SFesRxMoCmd RxMoCmd; + SFesTxMoCmd TxMoCmd; + SFesRxDefCmd RxDefCmd; + SFesTxDefCmd TxDefCmd; + + if (m_ptrCFesRtu == NULL) + return; + + if (g_ModbusRtuDTIsMainFes == false)//备机不作任何操作 + return; + + if (m_ptrCFesRtu->GetRxDoCmdNum()>0) + { + if (m_ptrCFesRtu->ReadRxDoCmd(1, &RxDoCmd) == 1) + { + //memset(&TxDoCmd,0,sizeof(TxDoCmd)); + + strcpy(TxDoCmd.TableName, RxDoCmd.TableName); + strcpy(TxDoCmd.ColumnName, RxDoCmd.ColumnName); + strcpy(TxDoCmd.TagName, RxDoCmd.TagName); + strcpy(TxDoCmd.RtuName, RxDoCmd.RtuName); + TxDoCmd.retStatus = CN_ControlFailed; + TxDoCmd.CtrlActType = RxDoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxDoCmd.CtrlDir = RxDoCmd.CtrlDir; + TxDoCmd.RtuNo = RxDoCmd.RtuNo; + TxDoCmd.PointID = RxDoCmd.PointID; + TxDoCmd.FwSubSystem = RxDoCmd.FwSubSystem; + TxDoCmd.FwRtuNo = RxDoCmd.FwRtuNo; + TxDoCmd.FwPointNo = RxDoCmd.FwPointNo; + TxDoCmd.SubSystem = RxDoCmd.SubSystem; + sprintf(TxDoCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxDoCmd.PointID); + LOGDEBUG("通信已断开 DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", RxDoCmd.CtrlActType, RxDoCmd.iValue, RxDoCmd.RtuName, RxDoCmd.PointID); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&TxDoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1, &TxDoCmd); + + } + + } + else + if (m_ptrCFesRtu->GetRxAoCmdNum()>0) + { + if (m_ptrCFesRtu->ReadRxAoCmd(1, &RxAoCmd) == 1) + { + //memset(&TxAoCmd,0,sizeof(TxAoCmd)); + strcpy(TxAoCmd.TableName, RxAoCmd.TableName); + strcpy(TxAoCmd.ColumnName, RxAoCmd.ColumnName); + strcpy(TxAoCmd.TagName, RxAoCmd.TagName); + strcpy(TxAoCmd.RtuName, RxAoCmd.RtuName); + TxAoCmd.retStatus = CN_ControlFailed; + sprintf(TxAoCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxAoCmd.PointID); + TxAoCmd.CtrlActType = RxAoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxAoCmd.CtrlDir = RxAoCmd.CtrlDir; + TxAoCmd.RtuNo = RxAoCmd.RtuNo; + TxAoCmd.PointID = RxAoCmd.PointID; + TxAoCmd.FwSubSystem = RxAoCmd.FwSubSystem; + TxAoCmd.FwRtuNo = RxAoCmd.FwRtuNo; + TxAoCmd.FwPointNo = RxAoCmd.FwPointNo; + TxAoCmd.SubSystem = RxAoCmd.SubSystem; + LOGDEBUG("通信已断开 AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", RxAoCmd.CtrlActType, RxAoCmd.fValue, RxAoCmd.RtuName, RxAoCmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&TxAoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1, &TxAoCmd); + } + } + else + if (m_ptrCFesRtu->GetRxMoCmdNum()>0) + { + if (m_ptrCFesRtu->ReadRxMoCmd(1, &RxMoCmd) == 1) + { + //memset(&TxMoCmd,0,sizeof(TxMoCmd)); + strcpy(TxMoCmd.TableName, RxMoCmd.TableName); + strcpy(TxMoCmd.ColumnName, RxMoCmd.ColumnName); + strcpy(TxMoCmd.TagName, RxMoCmd.TagName); + strcpy(TxMoCmd.RtuName, RxMoCmd.RtuName); + TxMoCmd.retStatus = CN_ControlFailed; + TxMoCmd.CtrlActType = RxMoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxMoCmd.CtrlDir = RxMoCmd.CtrlDir; + TxMoCmd.RtuNo = RxMoCmd.RtuNo; + TxMoCmd.PointID = RxMoCmd.PointID; + TxMoCmd.FwSubSystem = RxMoCmd.FwSubSystem; + TxMoCmd.FwRtuNo = RxMoCmd.FwRtuNo; + TxMoCmd.FwPointNo = RxMoCmd.FwPointNo; + TxMoCmd.SubSystem = RxMoCmd.SubSystem; + sprintf(TxMoCmd.strParam, I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxMoCmd.PointID); + + LOGDEBUG("通信已断开 MO混合量执行失败 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d", RxMoCmd.CtrlActType, RxMoCmd.iValue, RxMoCmd.RtuName, RxMoCmd.PointID); + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&TxMoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1, &TxMoCmd); + } + } + else + if (m_ptrCFesRtu->GetRxDefCmdNum() > 0) + { + if (m_ptrCFesRtu->ReadRxDefCmd(1, &RxDefCmd) == 1) + { + //memset(&TxDefCmd,0,sizeof(TxDefCmd)); + strcpy(TxDefCmd.TableName, RxDefCmd.TableName); + strcpy(TxDefCmd.ColumnName, RxDefCmd.ColumnName); + strcpy(TxDefCmd.TagName, RxDefCmd.TagName); + strcpy(TxDefCmd.RtuName, RxDefCmd.RtuName); + TxDefCmd.DevId = RxDefCmd.DevId; + TxDefCmd.CmdNum = RxDefCmd.CmdNum; + TxDefCmd.VecCmd = RxDefCmd.VecCmd; + TxDefCmd.retStatus = CN_ControlFailed; + sprintf(TxDefCmd.strParam, I18N("自定义命令输出失败!RtuNo:%d ").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo); + LOGERROR("通信已断开 自定义命令输出失败!RtuNo:%d", m_ptrCFesRtu->m_Param.RtuNo); + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &TxDefCmd); + } + } +} + +/** +* @brief CModbusRtuDTDataProcThread::InitProtocolBlockDataIndexMapping +* 数据块关联数据索引表初始化 +* @param RtuPtr +* @return +*/ +void CModbusRtuDTDataProcThread::InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuPtr) +{ + int i, j; + int blockId, funCode, startAddr, dataLen; + SModbusCmd *pCmd; + SModbusCmdBuf cmd = RtuPtr->m_Param.ModbusCmdBuf; + SFesAiIndex *pAiIndex; + SFesDiIndex *pDiIndex; + SFesAccIndex *pAccIndex; + SFesMiIndex *pMiIndex; + vector pAiBlockIndexs; + vector pDiBlockIndexs; + vector pAccBlockIndexs; + vector pMiBlockIndexs; + + //根据数据块帧类别进行分类 + for (i = 0; i < cmd.num; i++) + { + pCmd = cmd.pCmd + i; + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + SFesBaseBlockDataIndexInfo blockDataIndexInfoTemp; + blockDataIndexInfoTemp.headIndex = 0xFFFFFFFF; + blockDataIndexInfoTemp.tailIndex = 0xFFFFFFFF; + LOGDEBUG("pCmd->Type:%d", pCmd->Type); + if ((pCmd->Type >= DI_BYTE_LH) && (pCmd->Type <= DI_UWord_LH)) //DI + { + pDiBlockIndexs.push_back(i); + m_DiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_DiBlockDataIndexInfo.insert blockId:%d", blockId); + } + else if (((pCmd->Type >= AI_Word_HL) && (pCmd->Type <= AI_Float_LL)) || (pCmd->Type == AI_SIGNEDFLAG16_HL) || (pCmd->Type == AI_SIGNEDFLAG32_HL) || (pCmd->Type == AI_Hybrid_Type)) //AI + { + pAiBlockIndexs.push_back(i); + m_AiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_AiBlockDataIndexInfo.insert blockId:%d", blockId); + } + else if (((pCmd->Type >= ACC_Word_HL) && (pCmd->Type <= ACC_Float_LL)) || (pCmd->Type == ACC_Hybrid_Type))//ACC + { + pAccBlockIndexs.push_back(i); + m_AccBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_AccBlockDataIndexInfo.insert blockId:%d", blockId); + } + else if ((pCmd->Type >= MI_Word_HL) && (pCmd->Type <= MI_UDWord_LL))//MI + { + pMiBlockIndexs.push_back(i); + m_MiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_MiBlockDataIndexInfo.insert blockId:%d", blockId); + } + + } + + //对不同帧类别的数据块存储起始索引和结束索引 + for (j = 0; j < RtuPtr->m_MaxAiIndex; j++) //Ai + { + pAiIndex = RtuPtr->m_pAiIndex + j; + + for (i = 0; i < pAiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pAiBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pAiIndex->Param2 == funCode) && (startAddr <= pAiIndex->Param3) && (pAiIndex->Param3 < (startAddr + dataLen))) + { + //2022-11-16 数据块关联数据索引赋值错误 + //if ((m_AiBlockDataIndexInfo.at(blockId).headIndex == -1)) //首次得到起始地址时 + if ((m_AiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_AiBlockDataIndexInfo.at(blockId).headIndex = pAiIndex->PIndex; + + m_AiBlockDataIndexInfo.at(blockId).tailIndex = pAiIndex->PIndex; + } + } + } + + for (j = 0; j < RtuPtr->m_MaxDiIndex; j++) //Di + { + pDiIndex = RtuPtr->m_pDiIndex + j; + + for (i = 0; i < pDiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pDiBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pDiIndex->Param2 == funCode) && (startAddr <= pDiIndex->Param3) && (pDiIndex->Param3 < (startAddr + dataLen))) + { + //2022-11-16 数据块关联数据索引赋值错误 + //if ((m_DiBlockDataIndexInfo.at(blockId).headIndex == -1)) //首次得到起始地址时 + if ((m_DiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_DiBlockDataIndexInfo.at(blockId).headIndex = pDiIndex->PIndex; + + m_DiBlockDataIndexInfo.at(blockId).tailIndex = pDiIndex->PIndex; + } + + } + } + //for log + /*for (i = 0; i < pDiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pDiBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + LOGDEBUG("RTUNo=%d blockId=%d funCode=%d startAddr=%d dataLen=%d headIndex=%d tailIndex=%d ", RtuPtr->m_Param.RtuNo, blockId, funCode, startAddr, dataLen, m_DiBlockDataIndexInfo.at(blockId).headIndex, m_DiBlockDataIndexInfo.at(blockId).tailIndex); + }*/ + + for (j = 0; j < RtuPtr->m_MaxAccIndex; j++) //Acc + { + pAccIndex = RtuPtr->m_pAccIndex + j; + + for (i = 0; i < pAccBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pAccBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pAccIndex->Param2 == funCode) && (startAddr <= pAccIndex->Param3) && (pAccIndex->Param3 < (startAddr + dataLen))) + { + //2022-11-16 数据块关联数据索引赋值错误 + //if ((m_AccBlockDataIndexInfo.at(blockId).headIndex == -1)) //首次得到起始地址时 + if ((m_AccBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_AccBlockDataIndexInfo.at(blockId).headIndex = pAccIndex->PIndex; + + m_AccBlockDataIndexInfo.at(blockId).tailIndex = pAccIndex->PIndex; + } + } + } + + for (j = 0; j < RtuPtr->m_MaxMiIndex; j++) //Mi + { + pMiIndex = RtuPtr->m_pMiIndex + j; + + for (i = 0; i < pMiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pMiBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pMiIndex->Param2 == funCode) && (startAddr <= pMiIndex->Param3) && (pMiIndex->Param3 < (startAddr + dataLen))) + { + //2022-11-16 数据块关联数据索引赋值错误 + //if ((m_MiBlockDataIndexInfo.at(blockId).headIndex == -1)) //首次得到起始地址时 + if ((m_MiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_MiBlockDataIndexInfo.at(blockId).headIndex = pMiIndex->PIndex; + + m_MiBlockDataIndexInfo.at(blockId).tailIndex = pMiIndex->PIndex; + + } + } + } + + map::iterator iter; + iter = m_AiBlockDataIndexInfo.begin(); + while (iter != m_AiBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Ai--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + iter = m_DiBlockDataIndexInfo.begin(); + while (iter != m_DiBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Di--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + iter = m_AccBlockDataIndexInfo.begin(); + while (iter != m_AccBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Acc--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + iter = m_MiBlockDataIndexInfo.begin(); + while (iter != m_MiBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Mi--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + + +} + +/* +@brief CModbusRtuDTDataProcThread::ClearComByChanNo + 通道切换、关闭通道时需要清除通道的状态 +*/ +void CModbusRtuDTDataProcThread::ClearComByChanNo(int ChanNo) +{ + CFesChanPtr ptrChan; + + ptrChan = m_ptrCFesBase->GetChanDataByChanNo(ChanNo); + if (ptrChan != NULL) + { + ptrChan->SetComThreadRunFlag(CN_FesStopFlag); + ptrChan->SetChangeFlag(CN_FesChanUnChange); + + switch (ptrChan->m_Param.CommType) + { + case CN_FesSerialPort: + if ((m_ptrComSerial != NULL) && (ptrChan->m_ComThreadRun == CN_FesRunFlag)) + m_ptrComSerial->CloseChan(ptrChan); + break; + case CN_FesTcpClient: + if ((m_ptrComClient != NULL) && (ptrChan->m_ComThreadRun == CN_FesRunFlag)) + m_ptrComClient->TcpClose(ptrChan); + break; + default: + LOGDEBUG("ClearComByChanNo(%d) error,invaild CommType(%d) ", ptrChan->m_Param.ChanNo, ptrChan->m_Param.CommType); + break; + } + LOGDEBUG("ClearComByChanNo(%d) OK", ptrChan->m_Param.ChanNo); + } + +} + +void CModbusRtuDTDataProcThread::SetComByChanNo(int ChanNo) +{ + CFesChanPtr ptrChan; + + ptrChan = m_ptrCFesBase->GetChanDataByChanNo(ChanNo); + if (ptrChan != NULL) + { + ptrChan->SetComThreadRunFlag(CN_FesRunFlag); + ptrChan->SetChangeFlag(CN_FesChanUnChange); + LOGDEBUG("SetComByChanNo(%d) OK", ChanNo); + } +} + + +int CModbusRtuDTDataProcThread::RecvProcessComData(CFesRtuPtr RtuPtr,int FunCode,byte *retData, int &retDataLen) +{ + boost::ignore_unused_variable_warning(FunCode); + + int count; + int ExpectLen; + byte Data[500]; + int recvLen, Len, i, crc, recvcrc; + + retDataLen = 0; + if (m_ptrCurrentChan == NULL) + return iotFailed; + + Len = 0; + recvLen = 0; + count = m_ptrCFesChan->m_Param.RespTimeout / 10; + if (count <= 10) + count = 10;//最小响应超时为100毫秒 + ExpectLen = 0; + for (i = 0; i < count; i++) + { + switch (m_ptrCFesChan->m_Param.CommType) + { + case CN_FesSerialPort: + SleepmSec(10);//以最快速度接收到数据 + if (m_ptrComSerial != NULL) + m_ptrComSerial->RxComData(m_ptrCurrentChan); + break; + case CN_FesTcpClient: + //以最快速度接收到数据 RxData()有延时等待时间,此处可以删除 + if (m_ptrComClient != NULL) + m_ptrComClient->RxData(m_ptrCurrentChan); + break; + default: + break; + } + recvLen = m_ptrCurrentChan->ReadRxBufData(500 - Len, &Data[Len]);//数据缓存在 + if (recvLen <= 0) + continue; + m_ptrCurrentChan->DeleteReadRxBufData(recvLen);//清除已读取的数据 + Len += recvLen; + if (Len > 3) + { + if (Data[1] & 0x80)//ERROR + ExpectLen = 5; + else + { + switch (Data[1]) + { + case FunCode_01H: + case FunCode_02H: + case FunCode_03H: + case FunCode_04H: + ExpectLen = Data[2] + 5; + break; + case FunCode_05H: + case FunCode_06H: + case FunCode_10H: + ExpectLen = 8; + break; + } + } + } + if ((Len >= ExpectLen) && (ExpectLen > 0)) + { + break; + } + } + + if (Len > 0) + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, Data, Len, CN_SFesSimComFrameTypeRecv); + + if (Len == 0)//接收不完整 + { + return iotFailed; + } + else//长度、地址、功能码 都正确则认为数据正确。 + if (Len == ExpectLen) + { + //CRC CHECK + crc = CrcSum(&Data[0], ExpectLen - 2); + recvcrc = (int)Data[ExpectLen - 1] << 8; + recvcrc |= (int)Data[ExpectLen - 2]; + if (crc != recvcrc) + { + return iotFailed; + } + else + { + m_ptrCurrentChan->SetRxNum(1); + RtuPtr->ResetResendNum(); + RtuPtr->SetRxNum(1); + memcpy(retData, Data, ExpectLen); + retDataLen = ExpectLen; + return iotSuccess; + } + } + return iotSuccess; +} + + +//按位设置:分三步控制1、读取当前遥控值、2、设置当前位、3、设置完成后再次读取当前遥控值。 +int CModbusRtuDTDataProcThread::ReadDoStartValue(CFesRtuPtr RtuPtr, SFesDo *pDo, byte *retData, int &retDataSize) +{ + byte Data[256]; + int writex = 0; + int ret,crcCount; + + Data[writex++] = RtuPtr->m_Param.RtuAddr;//设备地址 + Data[writex++] = 0x03;//功能码 + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = 0x00; + Data[writex++] = 0x01; + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + SendDataToPort(Data, writex); + ret = RecvProcessComData(RtuPtr, 0x03, retData, retDataSize); + + return ret; + +} + +int CModbusRtuDTDataProcThread::ReadDoEndValue(CFesRtuPtr RtuPtr, SFesRxDoCmd cmd, SFesDo *pDo) +{ + boost::ignore_unused_variable_warning(cmd); + + byte Data[256]; + int writex; + int ret; + byte retData[256]; + int retDataSize, iValue,bitValue, crcCount; + SFesRtuDiValue DiValue; + SFesChgDi ChgDi; + SFesSoeEvent SoeEvent; + uint64 mSec; + SFesDi *pDi; + + + if(pDo->Param7==-1) + return iotFailed; + + writex = 0; + Data[writex++] = RtuPtr->m_Param.RtuAddr;//设备地址 + Data[writex++] = 0x03;//功能码 + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = 0x00; + Data[writex++] = 0x01; + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + SendDataToPort(Data, writex); + ret = RecvProcessComData(RtuPtr, 0x03, retData, retDataSize); + + if (ret == iotSuccess) + { + pDi = GetFesDiByPIndex(RtuPtr, pDo->Param7); + if (pDi != NULL) + { + iValue = (int)retData[3] << 8; + iValue |= (int)retData[4]; + bitValue = (iValue >> (pDi->Param4)) & 0x01; + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + if (pDi->Revers) + bitValue ^= 1; + mSec = getUTCTimeMsec(); + if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi.TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi.ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi.TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi.RtuNo = RtuPtr->m_Param.RtuNo; + ChgDi.PointNo = pDi->PointNo; + ChgDi.Value = bitValue; + ChgDi.Status = CN_FesValueUpdate; + ChgDi.time = mSec; + m_ptrCFesBase->WriteChgDiValue(RtuPtr, 1, &ChgDi); + //Create Soe + //if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent.time = mSec; + memcpy(SoeEvent.TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent.ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent.TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent.RtuNo = RtuPtr->m_Param.RtuNo; + SoeEvent.PointNo = pDi->PointNo; + SoeEvent.Status = CN_FesValueUpdate; + SoeEvent.Value = bitValue; + SoeEvent.FaultNum = 0; + m_ptrCFesBase->WriteSoeEventBuf(RtuPtr, 1, &SoeEvent); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(1, &SoeEvent); + } + } + DiValue.PointNo = pDi->PointNo; + DiValue.Value = bitValue; + DiValue.Status = CN_FesValueUpdate; + DiValue.time = mSec; + RtuPtr->WriteRtuDiValue(1, &DiValue); + } + } + return ret; + +} + + + +//一次控制设置两个点值,适用于事件清零、电度清零 +int CModbusRtuDTDataProcThread::DoSetTwoPoint(CFesRtuPtr RtuPtr, SFesDo *pDo, byte *retData, int &retDataSize) +{ + byte Data[256]; + byte respData[256]; + int writex = 0; + int ret, crcCount,respDataSize; + + Data[writex++] = RtuPtr->m_Param.RtuAddr;//设备地址 + Data[writex++] = pDo->Param2;//功能码 + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff; + Data[writex++] = pDo->Param3 & 0x00ff; + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff; + Data[writex++] = pDo->Param4 & 0x00ff; + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + SendDataToPort(Data, writex); + ret = RecvProcessComData(RtuPtr, 0x06, respData, respDataSize); + if(ret==iotFailed) + return ret; + + if (respData[1] & 0x80) + { + LOGDEBUG("DOPointNo=%d Param3=%x Param4=%x 控制第一个点设备返回失败", pDo->PointNo, pDo->Param3, pDo->Param4); + return iotFailed; + } + LOGDEBUG("DOPointNo=%d Param3=%x Param4=%x 控制第一个点设备返回成功", pDo->PointNo, pDo->Param3, pDo->Param4); + //第二个点的设置返回主控制程序,按常控制流程走 + writex = 0; + retData[writex++] = RtuPtr->m_Param.RtuAddr;//设备地址 + retData[writex++] = pDo->Param2;//功能码 + retData[writex++] = (pDo->Param5 >> 8) & 0x00ff; + retData[writex++] = pDo->Param5 & 0x00ff; + retData[writex++] = (pDo->Param6 >> 8) & 0x00ff; + retData[writex++] = pDo->Param6 & 0x00ff; + retDataSize = writex; + //校验在主程序中 + return iotSuccess; +} + +//读取主路电度 +int CModbusRtuDTDataProcThread::ReadZLAccValue(CFesRtuPtr RtuPtr) +{ + + byte Data[256]; + byte respData[256]; + int writex; + int ret, crcCount, respDataSize, ChgCount, ValueCount; + float fValue1,fValue2; + unsigned int tempValue; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[2]; + SFesChgAcc ChgAcc[2]; + uint64 mSec; + + //1QF1 + writex = 0; + Data[writex++] = RtuPtr->m_Param.RtuAddr;//设备地址 + Data[writex++] = 0x03;//功能码 + //1104 0x0450 正向有功电能 + Data[writex++] = 0x04;//寄存器地址 + Data[writex++] = 0x50; + Data[writex++] = 0x00;//寄存器起始地址H + Data[writex++] = 0x02; + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + SendDataToPort(Data, writex); + ret = RecvProcessComData(RtuPtr, 0x03, respData, respDataSize); + if (ret == iotFailed) + return iotFailed; + + tempValue = (uint32)respData[6] << 24; + tempValue |= (uint32)respData[5] << 16; + tempValue |= (uint32)respData[4] << 8; + tempValue |= (uint32)respData[3]; + memcpy(&fValue1, &tempValue, sizeof(float)); + + //1QF2 + writex = 0; + Data[writex++] = RtuPtr->m_Param.RtuAddr;//设备地址 + Data[writex++] = 0x03;//功能码 + //1616 0X0650 正向有功电能 + Data[writex++] = 0x06;//寄存器地址 + Data[writex++] = 0x50; + Data[writex++] = 0x00;//寄存器起始地址H + Data[writex++] = 0x02; + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + SendDataToPort(Data, writex); + ret = RecvProcessComData(RtuPtr, 0x03, respData, respDataSize); + if (ret == iotFailed) + return iotFailed; + + tempValue = (uint32)respData[6] << 24; + tempValue |= (uint32)respData[5] << 16; + tempValue |= (uint32)respData[4] << 8; + tempValue |= (uint32)respData[3]; + memcpy(&fValue2, &tempValue, sizeof(float)); + mSec = getUTCTimeMsec(); + //报告电度值 + ValueCount = 0; + pAcc = GetFesAccByParam23(RtuPtr, 0, 0x03,0x0450); + if (pAcc != NULL) + { + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = fValue1; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + } + pAcc = GetFesAccByParam23(RtuPtr, 0, 0x03,0x0650); + if (pAcc != NULL) + { + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = fValue2; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + } + if (ValueCount > 0) + { + RtuPtr->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(RtuPtr, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + return iotSuccess; +} + + +int CModbusRtuDTDataProcThread::ReadDoBlockValue(CFesRtuPtr RtuPtr, SFesRxDoCmd cmd, SFesDo *pDo) +{ + boost::ignore_unused_variable_warning(cmd); + + byte Data[256]; + int writex; + int ret; + byte retData[256]; + int retDataSize, iValue, bitValue, crcCount,StartAddr; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[50]; + uint64 mSec; + SFesDi *pDi; + int i, j, ValueCount, ChgCount, SoeCount; + + + writex = 0; + Data[writex++] = RtuPtr->m_Param.RtuAddr;//设备地址 + Data[writex++] = 0x03;//功能码 + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff; + Data[writex++] = pDo->Param4 & 0x00ff; + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + SendDataToPort(Data, writex); + ret = RecvProcessComData(RtuPtr, 0x03, retData, retDataSize); + + if (ret == iotSuccess) + { + if (retData[1] & 0x80) + return iotFailed; + + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + for (i = 0; i < pDo->Param4; i++) + { + StartAddr = pDo->Param3+i; + iValue = (int)retData[3 + i * 2] << 8; + iValue |= (int)retData[4 + i * 2]; + for (j = 0; j < 16; j++) + { + pDi = GetFesDiByParam234(RtuPtr, 0, 0x03, StartAddr,j); + if (pDi != NULL) + { + iValue = (int)retData[3] << 8; + iValue |= (int)retData[4]; + bitValue = (iValue >> (pDi->Param4)) & 0x01; + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + if (pDi->Revers) + bitValue ^= 1; + mSec = getUTCTimeMsec(); + if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = RtuPtr->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(RtuPtr, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + //if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = RtuPtr->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(RtuPtr, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + RtuPtr->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + } + } + //Updata Value + if (ValueCount > 0) + RtuPtr->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(RtuPtr, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(RtuPtr, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } + } + return ret; + +} + +//高压配电柜遥控返校读取 +int CModbusRtuDTDataProcThread::ReadPDGDoValue(CFesRtuPtr RtuPtr) +{ + byte Data[256]; + int writex; + int ret; + byte retData[256]; + int retDataSize, iValue, bitValue, crcCount; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[50]; + uint64 mSec; + SFesDi *pDi; + int j, ValueCount, ChgCount, SoeCount; + + writex = 0; + Data[writex++] = RtuPtr->m_Param.RtuAddr;//设备地址 + Data[writex++] = 0x03;//功能码 + Data[writex++] = 0x64;//寄存器起始地址H + Data[writex++] = 0x16;//寄存器起始地址L + Data[writex++] = 0x00; + Data[writex++] = 0x01; + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + SendDataToPort(Data, writex); + ret = RecvProcessComData(RtuPtr, 0x03, retData, retDataSize); + + if (ret == iotSuccess) + { + if (retData[1] & 0x80) + return iotFailed; + + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + iValue = (int)retData[3] << 8; + iValue |= (int)retData[4]; + + for (j = 0; j < 2; j++) + { + pDi = GetFesDiByParam234(RtuPtr, 0, 0x03, 0x6416, j); + if (pDi != NULL) + { + bitValue = (iValue >> (pDi->Param4)) & 0x01; + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + if (pDi->Revers) + bitValue ^= 1; + mSec = getUTCTimeMsec(); + if ((bitValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = RtuPtr->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + //Create Soe + //if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = RtuPtr->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + + } + LOGDEBUG("1 ReadPDGDoValue......rtuno=%d PointNo=%d Value=%d\n", RtuPtr->m_Param.RtuNo, pDi->PointNo,bitValue); + + } + else + LOGDEBUG("2 ReadPDGDoValue......rtuno=%d PointNo=%d Value=%d\n", RtuPtr->m_Param.RtuNo, pDi->PointNo, bitValue); + + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + } + } + //Updata Value + if (ValueCount > 0) + RtuPtr->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(RtuPtr, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(RtuPtr, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } + } + return ret; + +} + +//遥控操作返回成功后,反校处理 +int CModbusRtuDTDataProcThread::DoVerifyProcess() +{ + SFesDo *pDo; + + //读取控制结果 + if (m_ptrCInsertFesRtu == NULL) + return iotFailed; + if ((pDo = GetFesDoByPointNo(m_ptrCInsertFesRtu, m_AppData.doCmd.PointID)) == NULL) + return iotFailed; + + if(pDo->Attribute &CN_FesDo_SetBit) + ReadDoEndValue(m_ptrCInsertFesRtu, m_AppData.doCmd, pDo); + else + if (pDo->Attribute &CN_FesDo_SetTwoPoint) + { + if((pDo->Param4== 0X5A01)|| (pDo->Param4 == 0X5A08))//清电能 + ReadZLAccValue(m_ptrCInsertFesRtu); + } + else + if (pDo->Attribute &CN_FesDo_SetBlock) + { + ReadDoBlockValue(m_ptrCInsertFesRtu, m_AppData.doCmd, pDo); + } + else + if ((m_ptrCInsertFesRtu->m_Param.ResParam3 == CN_ModbusRtuDT_YD) + && ((pDo->Param3 == 0XB100) || (pDo->Param3 == 0XB101))) + { + ReadPDGDoValue(m_ptrCInsertFesRtu); + } + + + + return iotSuccess; +} + +int CModbusRtuDTDataProcThread::AoVerifyProcess() +{ + byte Data[256]; + int writex; + int ret; + byte respData[256]; + int respDataSize, crcCount; + SFesRtuAiValue AiValue; + SFesChgAi ChgAi; + // uint64 mSec; + SFesAi *pAi; + SFesAo *pAo; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + int ChgCount; + float fValue, aiValue; + + //LOGDEBUG("AoVerifyProcess......1"); + //读取控制结果 + if (m_ptrCInsertFesRtu == NULL) + return iotFailed; + + //LOGDEBUG("AoVerifyProcess......2"); + if ((pAo = GetFesAoByPointNo(m_ptrCInsertFesRtu, m_AppData.aoCmd.PointID)) == NULL) + return iotFailed; + //LOGDEBUG("AoVerifyProcess......3"); + + if (pAo->Param7 == -1) + return iotFailed; + + //LOGDEBUG("AoVerifyProcess......4 pAo->Param7=%d", pAo->Param7); + pAi = GetFesAiByPIndex(m_ptrCInsertFesRtu, pAo->Param7); + //LOGDEBUG("AoVerifyProcess......5"); + + if (pAi != NULL) + { + //LOGDEBUG("AoVerifyProcess......6 pAiIndex->PointNo=%d", pAi->PointNo); + + writex = 0; + Data[writex++] = m_ptrCInsertFesRtu->m_Param.RtuAddr;//设备地址 + Data[writex++] = pAi->Param2;//功能码 + //LOGDEBUG("AoVerifyProcess......7"); + + Data[writex++] = (pAi->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pAi->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = 0x00; + Data[writex++] = 0x02;//无论是单字还是双字都满足 + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + SendDataToPort(Data, writex); + //LOGDEBUG("AoVerifyProcess......8"); + + ret = RecvProcessComData(m_ptrCInsertFesRtu, 0x03, respData, respDataSize); + //LOGDEBUG("AoVerifyProcess......9"); + + if (ret == iotFailed) + return iotFailed; + //LOGDEBUG("AoVerifyProcess......5"); + + if (respData[1] & 0x80) + return iotFailed; + + switch (pAi->Param4) + { + case AI_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)respData[3] << 8; + sValue16 |= (int16)respData[4]; + aiValue = sValue16; + break; + case AI_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)respData[4] << 8; + sValue16 |= (int16)respData[3]; + aiValue = sValue16; + break; + case AI_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)respData[3] << 8; + uValue16 |= (uint16)respData[4]; + aiValue = uValue16; + break; + case AI_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)respData[4] << 8; + uValue16 |= (uint16)respData[3]; + aiValue = (float)uValue16; + break; + case AI_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)respData[3] << 24; + sValue32 |= (int)respData[4] << 16; + sValue32 |= (int)respData[5] << 8; + sValue32 |= (int)respData[6]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)respData[5] << 24; + sValue32 |= (int)respData[6] << 16; + sValue32 |= (int)respData[3] << 8; + sValue32 |= (int)respData[4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)respData[6] << 24; + sValue32 |= (int)respData[5] << 16; + sValue32 |= (int)respData[4] << 8; + sValue32 |= (int)respData[3]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)respData[3] << 24; + uValue32 |= (uint32)respData[4] << 16; + uValue32 |= (uint32)respData[5] << 8; + uValue32 |= (uint32)respData[6]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)respData[5] << 24; + uValue32 |= (uint32)respData[6] << 16; + uValue32 |= (uint32)respData[3] << 8; + uValue32 |= (uint32)respData[4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)respData[6] << 24; + uValue32 |= (uint32)respData[5] << 16; + uValue32 |= (uint32)respData[4] << 8; + uValue32 |= (uint32)respData[3]; + aiValue = (float)uValue32; + break; + case AI_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)respData[3] << 24; + uValue32 |= (uint32)respData[4] << 16; + uValue32 |= (uint32)respData[5] << 8; + uValue32 |= (uint32)respData[6]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)respData[5] << 24; + uValue32 |= (uint32)respData[6] << 16; + uValue32 |= (uint32)respData[3] << 8; + uValue32 |= (uint32)respData[4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)respData[6] << 24; + uValue32 |= (uint32)respData[5] << 16; + uValue32 |= (uint32)respData[4] << 8; + uValue32 |= (uint32)respData[3]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + default: + sValue16 = (int16)respData[3] << 8; + sValue16 |= (int16)respData[4]; + aiValue = sValue16; + break; + } + AiValue.PointNo = pAi->PointNo; + AiValue.Value = aiValue; + AiValue.Status = CN_FesValueUpdate; + AiValue.time = getUTCTimeMsec(); + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCInsertFesRtu->WriteRtuAiValueAndRetChg(1, &AiValue, &ChgCount, &ChgAi); + if ((ChgCount > 0) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCInsertFesRtu, ChgCount, &ChgAi); + } + //LOGDEBUG("AoVerifyProcess......6"); + + } + return iotSuccess; +} + + +/************************************************************ +函 数 名: BcdToDec +作 用: 十进制转换为bcd码 +入口参数: +出口参数: 返回bcd码 +*************************************************************/ +byte CModbusRtuDTDataProcThread::DecToBCD(byte Data) +{ + int Vaue = 0, temp, temp1; + + temp = Data%10; + temp1 = Data/10; + Vaue = temp; + Vaue |= temp1<<4; + + return Vaue; +} + +int CModbusRtuDTDataProcThread::SetTimeYD(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen) +{ + boost::ignore_unused_variable_warning(MaxDataLen); + + int writex, crcCount; + LOCALTIME stTime; + int ret; + + ret = WriteEnable(RtuPtr); + if (ret == iotFailed) + return 0; + + writex = 0; + Data[writex++] = RtuPtr->m_Param.RtuAddr; + Data[writex++] = 0x10; + Data[writex++] = 0xB0; + Data[writex++] = 0x01; + Data[writex++] = 0x00; + Data[writex++] = 0x03; + Data[writex++] = 0x06; + + getLocalSysTime(stTime); + Data[writex++] = DecToBCD(stTime.wYear % 100); + Data[writex++] = DecToBCD(stTime.wMonth); + Data[writex++] = DecToBCD(stTime.wDay); + Data[writex++] = DecToBCD(stTime.wHour); + Data[writex++] = DecToBCD(stTime.wMinute); + Data[writex++] = DecToBCD(stTime.wSecond); + + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + return writex; +} + +int CModbusRtuDTDataProcThread::SetTimeYMKK16(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen) +{ + boost::ignore_unused_variable_warning(MaxDataLen); + + int writex, crcCount; + LOCALTIME stTime; + + writex = 0; + Data[writex++] = RtuPtr->m_Param.RtuAddr; + Data[writex++] = 0x10; + Data[writex++] = 0x00; + Data[writex++] = 0x05; + Data[writex++] = 0x00; + Data[writex++] = 0x03; + Data[writex++] = 0x06; + + getLocalSysTime(stTime); + Data[writex++] = DecToBCD(stTime.wSecond); + Data[writex++] = DecToBCD(stTime.wMinute); + Data[writex++] = DecToBCD(stTime.wHour); + Data[writex++] = DecToBCD(stTime.wDay); + Data[writex++] = DecToBCD(stTime.wMonth); + Data[writex++] = DecToBCD(stTime.wYear % 100); + + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + return writex; +} + + +int CModbusRtuDTDataProcThread::SetTimeGK(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen) +{ + boost::ignore_unused_variable_warning(MaxDataLen); + + int writex, crcCount; + LOCALTIME stTime; + + writex = 0; + Data[writex++] = RtuPtr->m_Param.RtuAddr; + Data[writex++] = 0x10; + Data[writex++] = 0x07; + Data[writex++] = 0x00; + Data[writex++] = 0x00; + Data[writex++] = 0x06; + Data[writex++] = 0x0c; + + getLocalSysTime(stTime); + Data[writex++] = 0x00; + Data[writex++] = (byte)(stTime.wYear % 100); + Data[writex++] = 0x00; + Data[writex++] = (byte)stTime.wMonth; + Data[writex++] = 0x00; + Data[writex++] = (byte)stTime.wDay; + Data[writex++] = 0x00; + Data[writex++] = (byte)stTime.wHour; + Data[writex++] = 0x00; + Data[writex++] = (byte)stTime.wMinute; + Data[writex++] = 0x00; + Data[writex++] = (byte)stTime.wSecond; + + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + return writex; +} + +int CModbusRtuDTDataProcThread::SetTimeBMS(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen) +{ + boost::ignore_unused_variable_warning(MaxDataLen); + + int writex, crcCount; + LOCALTIME stTime; + + writex = 0; + Data[writex++] = RtuPtr->m_Param.RtuAddr; + Data[writex++] = 0x10; + Data[writex++] = 0x13; + Data[writex++] = 0x27; + Data[writex++] = 0x00; + Data[writex++] = 0x04; + Data[writex++] = 0x08; + + getLocalSysTime(stTime); + Data[writex++] = (byte)(stTime.wYear % 100); + Data[writex++] = (byte)stTime.wMonth; + Data[writex++] = (byte)stTime.wDay; + Data[writex++] = (byte)stTime.wHour; + Data[writex++] = (byte)stTime.wMinute; + Data[writex++] = (byte)stTime.wSecond; + Data[writex++] = 0xF0;//修改此位为0xf0f0并将时间写入到对应的地址,系统将修改时钟 + Data[writex++] = 0xF0; + + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + return writex; +} + +int CModbusRtuDTDataProcThread::SetTimeNormal(CFesRtuPtr RtuPtr,int StartAddr, byte *Data, int MaxDataLen) +{ + boost::ignore_unused_variable_warning(MaxDataLen); + + int writex, crcCount; + LOCALTIME stTime; + + writex = 0; + Data[writex++] = RtuPtr->m_Param.RtuAddr; + Data[writex++] = 0x10; + Data[writex++] = (StartAddr>>8)&0xff; + Data[writex++] = StartAddr&0xff;//74 + Data[writex++] = 0x00; + Data[writex++] = 0x06; + Data[writex++] = 0x0c; + + getLocalSysTime(stTime); + //Data[writex++] = 0x00; + //Data[writex++] = (byte)(stTime.wYear % 100); + Data[writex++] = (stTime.wYear>>8)&0xff; + Data[writex++] = (byte)stTime.wYear&0xff; + Data[writex++] = 0x00; + Data[writex++] = (byte)stTime.wMonth; + Data[writex++] = 0x00; + Data[writex++] = (byte)stTime.wDay; + Data[writex++] = 0x00; + Data[writex++] = (byte)stTime.wHour; + Data[writex++] = 0x00; + Data[writex++] = (byte)stTime.wMinute; + Data[writex++] = 0x00; + Data[writex++] = (byte)stTime.wSecond; + + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + return writex; +} + +int CModbusRtuDTDataProcThread::SetTimeProcess(CFesRtuPtr RtuPtr,byte *Data,int MaxDataLen) +{ + int retLen=0; + + switch (RtuPtr->m_Param.ResParam3) + { + case CN_ModbusRtuDT_YD: + retLen = SetTimeYD(RtuPtr, Data, MaxDataLen); + break; + case CN_ModbusRtuDT_YM_KK16: + retLen = SetTimeYMKK16(RtuPtr, Data, MaxDataLen); + break; + case CN_ModbusRtuDT_GK: + retLen = SetTimeGK(RtuPtr, Data, MaxDataLen); + break; + case CN_ModbusRtuDT_KHUPS: + retLen = SetTimeNormal(RtuPtr,5500, Data, MaxDataLen); + break; + case CN_ModbusRtuDT_BMS: + retLen = SetTimeBMS(RtuPtr, Data, MaxDataLen); + break; + default: + break; + } + return retLen; +} + +void CModbusRtuDTDataProcThread::TimerProcess() +{ + int64 curmsec = getMonotonicMsec(); + + if (curmsec - m_AppData.SettimemSec > m_AppData.SettimemSecReset) + { + m_AppData.SettimemSec = curmsec; + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + m_AppData.setTimeFlag[i] = 1; + } + + AlarmCalc(); + + if (m_timerAlarmEnCount++ > m_timerAlarmEnCountReset) + { + m_timerAlarmEnCount = 0; + PosAlarmEnableUpdate(); + } + +} + + +int CModbusRtuDTDataProcThread::DoKeepReset(CFesRtuPtr RtuPtr, SFesRxDoCmd cmd, SFesDo *pDo) +{ + boost::ignore_unused_variable_warning(cmd); + + byte Data[256]; + int writex; + int ret; + byte retData[256]; + int retDataSize,crcCount; + + + writex = 0; + Data[writex++] = RtuPtr->m_Param.RtuAddr;//设备地址 + Data[writex++] = 0x05;//功能码 + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = 0xff;/*05命令其值为,0xff00表示合闸*/ + Data[writex++] = 0x00; + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + SendDataToPort(Data, writex); + ret = RecvProcessComData(RtuPtr, 0x05, retData, retDataSize); + + if (ret == iotSuccess) + { + if (retData[1] & 0x80) + return iotFailed; + } + Sleep(500); + return ret; + +} + + +//40960 A000 写编程使能 R/W 写0X5AA5使能开,碰到非写指令,或时间达到30S自动归零 +int CModbusRtuDTDataProcThread::WriteEnable(CFesRtuPtr RtuPtr) +{ + byte Data[256]; + byte retData[256]; + int writex = 0; + int ret, crcCount,retDataSize; + + Data[writex++] = RtuPtr->m_Param.RtuAddr;//设备地址 + Data[writex++] = 0x06;//功能码 + Data[writex++] = 0xA0;//寄存器起始地址H + Data[writex++] = 0x00;//寄存器起始地址L + Data[writex++] = 0x5A; + Data[writex++] = 0xA5; + crcCount = CrcSum(&Data[0], writex); + Data[writex++] = crcCount & 0x00ff; + Data[writex++] = (crcCount >> 8) & 0x00ff; + + SendDataToPort(Data, writex); + ret = RecvProcessComData(RtuPtr, 0x06, retData, retDataSize); + return ret; +} + + +//DI规约参数5=1,首次启动为1(告警),要产生SOE告警上送后台;同时参与进行事故总运算。 +void CModbusRtuDTDataProcThread::RTUAlarmInit(CFesRtuPtr RtuPtr) +{ + int i; + SFesDi *pDi; + SModbusRtuDTRTUData *pRTUData=new SModbusRtuDTRTUData; + + + pRTUData->m_RtuPtr = RtuPtr; + for (i = 0; i < RtuPtr->m_MaxDiPoints; i++) + { + pDi = RtuPtr->m_pDi + i; + if (pDi->Used == 1) + { + if (pDi->Param5 &0x01)//bit0=1 参与告警 bit1=0:1为告警,bit1=1 0为告警(如通信状态) + { + pRTUData->m_AlarmPointPtr.push_back(pDi); + //LOGDEBUG("告警点 RTUNo=%d %s pointNo=%d", RtuPtr->m_Param.RtuNo,pDi->PointDesc, pDi->PointNo); + } + if ((pDi->Param2 == 65534) && (pDi->Param3 == 65534)) + { + pRTUData->m_AlarmDiPtr = pDi; + //LOGDEBUG("事故总 RTUNo=%d %s pointNo=%d", RtuPtr->m_Param.RtuNo,pDi->PointDesc, pDi->PointNo); + } + + //告警使能点 + if (pDi->Param3 == 73000) + { + pRTUData->m_YDPosAlarmEnable.push_back(pDi); + LOGDEBUG("告警使能点pDi1->PointNo=%d Param3=%d Param4=%d ", pDi->PointNo, pDi->Param3, pDi->Param4); + } + + } + } + m_AppData.RTUData.push_back(pRTUData); + +} + +void CModbusRtuDTDataProcThread::AlarmInit() +{ + int RtuNo; + CFesRtuPtr pRtu; + + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + pRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo); + if (pRtu) + { + RTUAlarmInit(pRtu); + } + } +} + +void CModbusRtuDTDataProcThread::RTUAlarmCalc(SModbusRtuDTRTUData *pRtuData) +{ + SFesDi *pDi; + int i,size; + int alarmFlag = 0; + CFesRtuPtr RtuPtr; + + + if (!m_SGZCalcFlag) + return; + + if (pRtuData->m_AlarmDiPtr == NULL) + return; + size = (int)pRtuData->m_AlarmPointPtr.size(); + if (size == 0) + return; + + RtuPtr = pRtuData->m_RtuPtr; + pDi = NULL; + for (i = 0; i < size; i++) + { + pDi = pRtuData->m_AlarmPointPtr[i]; + if((pDi->Value)&&(!(pDi->Param5&0x02)))//bit1=0: 1为告警 + { + alarmFlag = 1; + break; + } + else + if ((!pDi->Value) && (pDi->Param5 & 0x02))//bit1=0: 0为告警 + { + alarmFlag = 1; + break; + } + } + + pDi = pRtuData->m_AlarmDiPtr; + SFesRtuDiValue DiValue; + SFesChgDi ChgDi; + SFesSoeEvent SoeEvent; + uint64 mSec; + + mSec = getUTCTimeMsec(); + if ((alarmFlag != pDi->Value) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi.TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi.ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi.TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi.RtuNo = RtuPtr->m_Param.RtuNo; + ChgDi.PointNo = pDi->PointNo; + ChgDi.Value = alarmFlag; + ChgDi.Status = CN_FesValueUpdate; + ChgDi.time = mSec; + m_ptrCFesBase->WriteChgDiValue(RtuPtr, 1, &ChgDi); + + SoeEvent.time = mSec; + memcpy(SoeEvent.TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent.ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent.TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent.RtuNo = RtuPtr->m_Param.RtuNo; + SoeEvent.PointNo = pDi->PointNo; + SoeEvent.Value = alarmFlag; + SoeEvent.Status = CN_FesValueUpdate; + SoeEvent.FaultNum = 0; + m_ptrCFesBase->WriteSoeEventBuf(RtuPtr, 1, &SoeEvent); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(1, &SoeEvent); + LOGDEBUG("RTUNo=%d ALARM value=%d", RtuPtr->m_Param.RtuNo, alarmFlag); + } + //更新点值 + DiValue.PointNo = pDi->PointNo; + DiValue.Value = alarmFlag; + DiValue.Status = CN_FesValueUpdate; + DiValue.time = mSec; + RtuPtr->WriteRtuDiValue(1, &DiValue); + +} + +void CModbusRtuDTDataProcThread::AlarmCalc() +{ + CFesRtuPtr pRtu; + SModbusRtuDTRTUData *pRtuData; + //uint64 curmsec; + + /*if (m_SGZCalcFlag == 0) + { + curmsec = getMonotonicMsec(); + //LOGDEBUG("curmsec=%lld m_SGZStartmSec=%lld m_SGZDelaymSec=%d", curmsec, m_SGZStartmSec, m_SGZDelaymSec); + if ((curmsec - m_SGZStartmSec) > m_SGZDelaymSec) + { + m_SGZCalcFlag = 1; + LOGDEBUG("开始故障检测!"); + } + return; + }*/ + //事故总计算 + for (int i = 0; i < m_AppData.RTUData.size(); i++) + { + pRtuData = m_AppData.RTUData[i]; + RTUAlarmCalc(pRtuData); + } +} + +//启动时所有的命令都询问一次 +void CModbusRtuDTDataProcThread::SetSendCmdFlagInit() +{ + SModbusCmd *pCmd; + int i, j, RtuNo; + int64 lTime; + CFesRtuPtr ptrFesRtu; + + lTime = getMonotonicMsec(); //MS + for (i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((ptrFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) + continue; + for (j = 0; j < ptrFesRtu->m_Param.ModbusCmdBuf.num; j++) + { + pCmd = ptrFesRtu->m_Param.ModbusCmdBuf.pCmd + j; + if (pCmd->Used)//2022-09-06 thxiao 启用块使能 + { + if (DZ_DI_BYTE_LH < pCmd->Type && pCmd->Type < DZ_AI_Float_LL) + continue; //保护定值数据块 + pCmd->CommandSendFlag = true; + pCmd->lastPollTime = lTime; + } + } + } +} + + +int CModbusRtuDTDataProcThread::YDPosAlarmEnable(CFesRtuPtr RtuPtr, SFesRxDoCmd cmd, SFesDo *pDo) +{ + SFesDi *pDi; + SFesDi *pEnableDi; + SFesRtuDiValue DiValue[5]; + SFesChgDi ChgDi[5]; + SFesSoeEvent SoeEvent[5]; + int64 mSec; + int ValueCount, ChgCount, SoeCount; + + if (pDo->Param7 == -1) + return iotFailed; + + pDi = GetFesDiByPIndex(RtuPtr, pDo->Param7); + if (pDi == NULL) + return iotFailed; + + pEnableDi = RtuPtr->GetDiByPointNo(pDi->Param7); + if (pEnableDi == NULL) + return iotFailed; + + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + mSec = getUTCTimeMsec(); + if ((pEnableDi->Param6 != cmd.iValue)|| (cmd.iValue != pDi->Value)) + { + //修改当前值,并且上送后台 + pEnableDi->Param6 = cmd.iValue; + //写入关系库 + if (m_ptrModelCommit != NULL) + { + //2:使用之前打开数据库 + if (m_ptrModelCommit->open() == false) + { + LOGERROR("COperateServerClass::setPlanShieldCfg m_ptrModelCommit->open() fail!\n"); + return iotFailed; + } + + //3:提交SQL 到模型 strObjSql为SQL 命令; + //update fes_digital set res_para_int6 = 0 where TAG_NAME = 'occ.PSCADA.Chan0.RTU0.0' + QString strObjSql = QString("update fes_digital set res_para_int6=%1 where app_tag_name = '%2'").arg(cmd.iValue).arg(pEnableDi->TagName); + if (m_ptrModelCommit->execute(strObjSql) == false) + { + std::string str1 = strObjSql.toStdString(); + LOGWARN("UpdateShieldInfo, strObjSql = %s, m_ptrModelCommit->execute error!", str1.c_str()); + m_ptrModelCommit->close(); + return iotFailed; + } + else + { + std::string str1 = strObjSql.toStdString(); + LOGINFO("UpdateShieldInfo, sendSyn success, strObjSql = %s", str1.c_str()); + } + m_ptrModelCommit->close(); + } + + if ((cmd.iValue != pDi->Value) && (g_ModbusRtuDTIsMainFes == true))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = RtuPtr->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = cmd.iValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + //Create Soe + //if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = RtuPtr->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = cmd.iValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + + } + LOGDEBUG("1 YDPosAlarmEnable......rtuno=%d PointNo=%d Value=%d\n", RtuPtr->m_Param.RtuNo, pDi->PointNo, cmd.iValue); + + } + else + LOGDEBUG("2 YDPosAlarmEnable......rtuno=%d PointNo=%d Value=%d\n", RtuPtr->m_Param.RtuNo, pDi->PointNo, cmd.iValue); + + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = cmd.iValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + } + //Updata Value + if (ValueCount > 0) + RtuPtr->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(RtuPtr, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(RtuPtr, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } + + return iotSuccess; + +} + + +void CModbusRtuDTDataProcThread::RTUPosAlarmEnableUpdate(SModbusRtuDTRTUData *pRtuData) +{ + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[50]; + int64 mSec; + int ValueCount, ChgCount, SoeCount; + SFesDi *pDi; + SFesDi *pDi2; + int i; + CFesRtuPtr RtuPtr; + + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + + if (pRtuData->m_YDPosAlarmEnable.size() == 0) + return; + + RtuPtr = pRtuData->m_RtuPtr; + mSec = getUTCTimeMsec(); + for (i = 0; i < pRtuData->m_YDPosAlarmEnable.size(); i++) + { + pDi = pRtuData->m_YDPosAlarmEnable[i]; + pDi2 = RtuPtr->GetDiByPointNo(pDi->Param7);//回路开关分闸告警点 + if (pDi2 == NULL) + continue; + if ((pDi->Value != pDi2->Param6) && (g_ModbusRtuDTIsMainFes == true) && (pDi->Status&CN_FesValueUpdate)) + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = RtuPtr->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = pDi2->Param6;//使能标志 + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(RtuPtr, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = RtuPtr->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Value = pDi2->Param6; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(RtuPtr, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + + } + //更新点值 + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = pDi2->Param6; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + RtuPtr->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + //Updata Value + if (ValueCount > 0) + RtuPtr->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(RtuPtr, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(RtuPtr, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } + +} + +void CModbusRtuDTDataProcThread::PosAlarmEnableUpdate() +{ + CFesRtuPtr pRtu; + SModbusRtuDTRTUData *pRtuData; + + //事故总计算 + for (int i = 0; i < m_AppData.RTUData.size(); i++) + { + pRtuData = m_AppData.RTUData[i]; + RTUPosAlarmEnableUpdate(pRtuData); + } +} diff --git a/product/src/fes/protocol/modbus_rtu_dt/ModbusRtuDTDataProcThread.h b/product/src/fes/protocol/modbus_rtu_dt/ModbusRtuDTDataProcThread.h new file mode 100644 index 00000000..85c0f41b --- /dev/null +++ b/product/src/fes/protocol/modbus_rtu_dt/ModbusRtuDTDataProcThread.h @@ -0,0 +1,271 @@ +#pragma once + +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "ComSerialPort.h" +#include "ComTcpClient.h" +#include "db_api_ex/CDbApi.h" + + +using namespace iot_public; + +#define CN_MODBUSRTU_MAX_CMD_LEN 256 + +//功能码定义 +const int FunCode_01H = 1; /*读开关量输出*/ +const int FunCode_02H = 2; /*读开关量输入*/ +const int FunCode_03H = 3; /*读保持寄存器数据*/ +const int FunCode_04H = 4; /*读输入寄存器数据*/ +const int FunCode_05H = 5; /*写单个线圈*/ +const int FunCode_06H = 6; /*写单个保持寄存器*/ +const int FunCode_10H = 16; /*写多个保持寄存器*/ + +//SModbusRtuDTAppData状态 +const int CN_ModbusRtuDTAppState_init = 0; +const int CN_ModbusRtuDTAppState_waitInit = 1; +const int CN_ModbusRtuDTAppState_idle = 2; +const int CN_ModbusRtuDTAppState_waitResp = 3; +const int CN_ModbusRtuDTAppState_waitControlResp = 4; + +//SModbusRtuDTAppData最近发送的控制命令类型 +const int CN_ModbusRtuDTNoCmd = 0; +const int CN_ModbusRtuDTDoCmd = 1; //遥控 +const int CN_ModbusRtuDTAoCmd = 2; //遥调 +const int CN_ModbusRtuDTMoCmd = 3; +const int CN_ModbusRtuDTDefCmd = 4; + +const int CN_ModbusRtuDTMaxRTUs = 254; + +/***************保护定值区*********************************** / +/***KEY_name***/ +const static string CMD_TYPE = "cmd_type"; //命令类型 +const static string DEV_ID = "dev_id"; //设备id +const static string DOT_NO = "dot_no"; //定值代号 +const static string GROUP_NO = "group_no"; //定值组号 +const static string CUR_GROUP = "cur_group"; //当前定值组 +const static string EDIT_GROUP = "edit_group"; //修改定值组 +const static string CUR_VALUE = "cur_value"; //当前值 +const static string EDIT_VALUE = "edit_value"; //修改值 +const static string ACK_VALUE = "ack_value"; //反校值 + +/***value***/ +const static string CONST_VALUE_READ = "const_value_read"; //读取保护定值 +const static string CONST_GROUP_EDIT = "const_group_edit"; //修改定值组号 +const static string CONST_VALUE_EDIT = "const_value_edit"; //修改保护定值 +const static string CONST_VALUE_AFFIRM = "const_value_affirm"; //修改保护定值确认 + + +/* +//Attribute + //Bit0 遥控类型。0脉冲输出,1自保持输出(需要程序清零)。 + //Bit1 遥控复归。0:表示普通遥控,1:表示复归。 + //Bit2 特殊遥控点0:表示普通遥控,1:特殊遥控点。 +const int CN_FesDo_Normal = 0x00; +const int CN_FesDo_Pulse = 0x00; +const int CN_FesDo_Keep = 0x01; +const int CN_FesDo_Reset = 0x02; +const int CN_FesDo_Special = 0x04; +*/ +//Bit3 按位设置:分三步控制1、读取当前word值、2、设置当前位、3、设置完成后读取当前word值。 +const int CN_FesDo_SetBit = 0x08; +//Bit4 一次控制设置两个点值,适用于事件清零、电度清零 +const int CN_FesDo_SetTwoPoint = 0x10; +//Bit5 控制连续地址,全为0或1,适应用于支路开关跳闸告警使能/禁止 +const int CN_FesDo_SetBlock = 0x20; +//Bit6 主控开关告警使能 +const int CN_FesDo_MainPosAlarm = 0x40; + +// +#define DT_AI_SIGNEDFLAG16_HL 62 //模拟量帧(符号位(bit15)加数值 高字节前) +#define DT_AI_SIGNEDFLAG32_HL 63 //模拟量帧(符号位(bit31)加数值 高字节前) + +#define MAX_POINT_INDEX 200 //接收缓存最大索引 + +//设备类型 +const int CN_ModbusRtuDT_YD = 1; +const int CN_ModbusRtuDT_YM_KK16 = 2; //16路继电器输出模块|YM-KK16|雅达 +const int CN_ModbusRtuDT_KHUPS = 3; +const int CN_ModbusRtuDT_GK = 4; +const int CN_ModbusRtuDT_BMS = 5; + +typedef struct _SModbusRtuDTRTUData{ + CFesRtuPtr m_RtuPtr; + vector m_AlarmPointPtr; + SFesDi *m_AlarmDiPtr; + vector m_YDPosAlarmEnable; + + _SModbusRtuDTRTUData() { + m_RtuPtr = NULL; + m_AlarmDiPtr = NULL; + } +}SModbusRtuDTRTUData; + +typedef struct _SModbusRtuDTConfigParam { + int RtuNo; + uint64 SGZCalcDelay; + _SModbusRtuDTConfigParam() { + SGZCalcDelay = 0; + RtuNo = 0; + } +}SModbusRtuDTConfigParam; + + +//MODBUS 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct { + int index; + int state; + + int lastCotrolcmd; + byte lastCmdData[CN_MODBUSRTU_MAX_CMD_LEN]; + int lastCmdDataLen; + SModbusCmd lastCmd; + SFesDo *pLastDo; + SFesRxDoCmd doCmd; + SFesRxAoCmd aoCmd; + SFesRxMoCmd moCmd; + SFesRxDefCmd defCmd; + int setCmdCount; + + uint64 controlTimeout; + + //修改定值 + int deviceId; //设备id + int CmdNum; //健值对数 + int modifyDzNum; //修改定值个数 + + //对时处理 + int64 SettimemSec; + int64 SettimemSecReset; + int setTimeFlag[CN_FesMaxRtuNumPerChan]; + + vector currentValue; //当前值容器 + vector dotNo; //定值代号容器 + vector editValue; //修改值容器 + + vector RTUData; + +}SModbusRtuDTAppData; + +typedef struct { + uint32 headIndex; + uint32 tailIndex; +}SFesBaseBlockDataIndexInfo; //数据块关联数据索引信息 + +class CModbusRtuDTDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + CModbusRtuDTDataProcThread(CFesBase *ptrCFesBase, CFesChanPtr ptrCFesChan, const vector vecAppParam); + virtual ~CModbusRtuDTDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + /* + @brief CModbusRtuDTDataProcThread::ClearComByChanNo + 通道切换、关闭通道时需要清除通道的状态 + */ + void ClearComByChanNo(int ChanNo); + void SetComByChanNo(int ChanNo); + + CFesBase* m_ptrCFesBase; + + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区 + CFesRtuPtr m_ptrCInsertFesRtu; //当前插入命令使用RTU数据区 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SModbusRtuDTAppData m_AppData; //内部应用数据结构 + + CComTcpClientPtr m_ptrComClient; + CComSerialPortPtr m_ptrComSerial; + + map m_AiBlockDataIndexInfo; //2021-06-25 ljj + map m_DiBlockDataIndexInfo; + map m_AccBlockDataIndexInfo; + map m_MiBlockDataIndexInfo; + + iot_dbms::CDbApi* m_ptrModelCommit; //模型提交接口 + +private: + int m_timerCount; + int m_timerCountReset; + int m_SGZDelaymSec;//事故总延时 + int m_SGZCalcFlag;//事故总计算标志 + uint64 m_SGZStartmSec; + int m_timerSGZCountReset; + int m_timerSGZCount; + int m_timerAlarmEnCountReset; + int m_timerAlarmEnCount; + + int SendProcess(); + int RecvComData(); + int InsertCmdProcess(); + int DoCmdProcess(byte *Data, int dataSize); + int AoCmdProcess(byte *Data, int dataSize); + //int MoCmdProcess(byte *Data, int dataSize); + //int SettingCmdProcess(byte *Data, int dataSize); + int DefCmdProcess(byte *Data, int dataSize); + int GetPollingCmd(SModbusCmd *pCmd); + int PollingCmdProcess(); + void SendDataToPort(byte *Data, int Size); + int CrcSum(byte *Data, int Count); + int RecvDataProcess(byte *Data, int DataSize); + void Cmd01RespProcess(byte *Data, int DataSize); + void Cmd03RespProcess(byte *Data, int DataSize); + int Cmd03RespProcess_BitGroup(SFesDi *pDi,int diValue); + void Cmd05RespProcess(byte *Data, int DataSize); + void Cmd06RespProcess(byte *Data, int DataSize); + void Cmd10RespProcess(byte *Data, int DataSize); + bool CmdControlRespProcess(byte *Data, int DataSize, int okFlag); + void SetSendCmdFlag(); + void CmdTypeHybridProcess(byte *Data, int DataSize); + void ErrorControlRespProcess(); + void InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuPtr); + + //以下函数适合通信管理机PCS3000老模版 + void Cmd01RespProcess_PCS3000(byte *Data, int DataSize); + void Cmd03RespProcess_PCS3000(byte *Data, int DataSize); + int Cmd03RespProcess_BitGroup_PCS3000(SFesDi *pDi, int diValue); + void CmdTypeHybridProcess_PCS3000(byte *Data, int DataSize); + + int RecvProcessComData(CFesRtuPtr RtuPtr, int FunCode, byte *retData, int &retDataLen); + int ReadDoStartValue(CFesRtuPtr RtuPtr, SFesDo *pDo, byte *retData, int &retDataSize); + int ReadDoEndValue(CFesRtuPtr RtuPtr, SFesRxDoCmd cmd, SFesDo *pDo); + int DoSetTwoPoint(CFesRtuPtr RtuPtr, SFesDo *pDo, byte *retData, int &retDataSize); + int ReadZLAccValue(CFesRtuPtr RtuPtr); + int ReadDoBlockValue(CFesRtuPtr RtuPtr, SFesRxDoCmd cmd, SFesDo *pDo); + int DoVerifyProcess(); + int AoVerifyProcess(); + byte DecToBCD(byte Data); + int SetTimeYD(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen); + int SetTimeYMKK16(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen); + int SetTimeProcess(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen); + int SetTimeGK(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen); + int SetTimeNormal(CFesRtuPtr RtuPtr, int StartAddr, byte *Data, int MaxDataLen); + int SetTimeBMS(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen); + void TimerProcess(); + int DoKeepReset(CFesRtuPtr RtuPtr, SFesRxDoCmd cmd, SFesDo *pDo); + int WriteEnable(CFesRtuPtr RtuPtr); + + void RTUAlarmInit(CFesRtuPtr RtuPtr); + void RTUAlarmCalc(SModbusRtuDTRTUData *pRtuData); + void AlarmCalc(); + void AlarmInit(); + int ReadPDGDoValue(CFesRtuPtr RtuPtr); + void SetSendCmdFlagInit(); + int YDPosAlarmEnable(CFesRtuPtr RtuPtr, SFesRxDoCmd cmd, SFesDo *pDo); + void RTUPosAlarmEnableUpdate(SModbusRtuDTRTUData *pRtuData); + void PosAlarmEnableUpdate(); + + +}; + +typedef boost::shared_ptr CModbusRtuDTDataProcThreadPtr; diff --git a/product/src/fes/protocol/modbus_rtu_dt/modbus_rtu_dt.pro b/product/src/fes/protocol/modbus_rtu_dt/modbus_rtu_dt.pro new file mode 100644 index 00000000..140f3f35 --- /dev/null +++ b/product/src/fes/protocol/modbus_rtu_dt/modbus_rtu_dt.pro @@ -0,0 +1,36 @@ +#CONFIG -= qt +QT += serialport +QT += sql + +TARGET = modbus_rtu_dt +TEMPLATE = lib + +SOURCES += \ + ModbusRtuDT.cpp \ + ModbusRtuDTDataProcThread.cpp \ + ../combase/ComSerialPort.cpp \ + ../combase/ComTcpClient.cpp \ + +HEADERS += \ + ModbusRtuDT.h \ + ModbusRtuDTDataProcThread.h \ + ../../include/ComSerialPort.h \ + ../../include/ComTcpClient.h \ + +INCLUDEPATH += ../../include/ + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase +LIBS += -lprotobuf -lboost_locale -lboost_regex -lrdb_api -ldb_api_ex -ldb_base_api + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/fes/protocol/modbus_tcp/ModbusDataProcThread.cpp b/product/src/fes/protocol/modbus_tcp/ModbusDataProcThread.cpp index bd99798f..b427fac7 100644 --- a/product/src/fes/protocol/modbus_tcp/ModbusDataProcThread.cpp +++ b/product/src/fes/protocol/modbus_tcp/ModbusDataProcThread.cpp @@ -41,7 +41,6 @@ 2、科华很多设备响应是事务处理标识符+1,所以默认是不处理。自定义参数3=1,才判断事务处理标识符。 2022-04-22 thxiao clientTransID error close socket 2022-05-09 thxiao m_AppData.m_TransIDFailCount 需要初始化为0 - 2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 */ #include "ModbusDataProcThread.h" @@ -817,7 +816,7 @@ int CModbusDataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) } else if (pAo->Param4 == 1) { - ui32Value = fValue; + ui32Value = static_cast(fValue); Data[writex++] = (byte)(ui32Value >> 24); Data[writex++] = (byte)(ui32Value >> 16); Data[writex++] = (byte)(ui32Value >> 8); @@ -825,7 +824,7 @@ int CModbusDataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) } else if (pAo->Param4 == 2) { - iValue = fValue; + iValue = static_cast(fValue); Data[writex++] = (byte)(iValue >> 24); Data[writex++] = (byte)(iValue >> 16); Data[writex++] = (byte)(iValue >> 8); @@ -1049,6 +1048,9 @@ int CModbusDataProcThread::SettingCmdProcess() */ int CModbusDataProcThread::DefCmdProcess(byte *Data, int dataSize) { + boost::ignore_unused_variable_warning(Data); + boost::ignore_unused_variable_warning(dataSize); + SFesRxDefCmd cmd; int writex; @@ -1714,7 +1716,7 @@ void CModbusDataProcThread::Cmd03RespProcess(byte *Data,int /*DataSize*/) break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; @@ -1790,8 +1792,7 @@ void CModbusDataProcThread::Cmd03RespProcess(byte *Data,int /*DataSize*/) uValue32 |= (uint32)Data[5+i*4]<<8; uValue32 |= (uint32)Data[6+i*4]; memcpy(&fValue,&uValue32,sizeof(float)); - accValue = (int64)fValue * 1000; //2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 - + accValue = (int64)fValue; break; case ACC_Float_LH://(四字节浮点 低字前 高字节前) uValue32 = (uint32)Data[5+i*4]<<24; @@ -1799,7 +1800,7 @@ void CModbusDataProcThread::Cmd03RespProcess(byte *Data,int /*DataSize*/) uValue32 |= (uint32)Data[3+i*4]<<8; uValue32 |= (uint32)Data[4+i*4]; memcpy(&fValue,&uValue32,sizeof(float)); - accValue = (int64)fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + accValue = (int64)fValue; break; case ACC_Float_LL://(四字节浮点 低字前 低字节前) uValue32 = (uint32)Data[6+i*4]<<24; @@ -1807,11 +1808,11 @@ void CModbusDataProcThread::Cmd03RespProcess(byte *Data,int /*DataSize*/) uValue32 |= (uint32)Data[4+i*4]<<8; uValue32 |= (uint32)Data[3+i*4]; memcpy(&fValue,&uValue32,sizeof(float)); - accValue = (int64)fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + accValue = (int64)fValue; break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; @@ -2015,6 +2016,8 @@ void CModbusDataProcThread::Cmd10RespProcess(byte *Data,int DataSize) void CModbusDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) { + boost::ignore_unused_variable_warning(DataSize); + int FunCode; int i,StartAddr,StartPointNo,ValueCount,ChgCount,PointCount; uint64 mSec; @@ -2267,7 +2270,7 @@ void CModbusDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) uValue32 |= (uint32)Data[5+i*2]<<8; uValue32 |= (uint32)Data[6+i*2]; memcpy(&fValue,&uValue32,sizeof(float)); - accValue = (int64)fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + accValue = (int64)fValue; i++; break; case ACC_Float_LH: //float帧(四字节浮点 低字前 高字节前) @@ -2276,7 +2279,7 @@ void CModbusDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) uValue32 |= (uint32)Data[3+i*2]<<8; uValue32 |= (uint32)Data[4+i*2]; memcpy(&fValue,&uValue32,sizeof(float)); - accValue = (int64)fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + accValue = (int64)fValue; i++; break; case ACC_Float_LL: //float帧(四字节浮点 低字前 低字节前) @@ -2285,7 +2288,7 @@ void CModbusDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) uValue32 |= (uint32)Data[4+i*2]<<8; uValue32 |= (uint32)Data[3+i*2]; memcpy(&fValue,&uValue32,sizeof(float)); - accValue = (int64)fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + accValue = (int64)fValue; i++; break; default: @@ -2295,7 +2298,7 @@ void CModbusDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; @@ -2334,6 +2337,9 @@ void CModbusDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) */ bool CModbusDataProcThread::CmdControlRespProcess(byte *Data,int DataSize,int okFlag) { + boost::ignore_unused_variable_warning(Data); + boost::ignore_unused_variable_warning(DataSize); + SFesTxDoCmd retDoCmd; SFesTxAoCmd retAoCmd; SFesTxMoCmd retMoCmd; @@ -2800,9 +2806,11 @@ SFesMi* CModbusDataProcThread::ModbusTcp_GetFesMiByPIndex(int Index) void CModbusDataProcThread::Cmd01RespProcess_BigData(byte *Data, int DataSize) { + boost::ignore_unused_variable_warning(DataSize); + int FunCode; byte bitValue, byteValue; - int i, j, StartAddr, StartPointNo, ValueCount, ChgCount, SoeCount; + int i, StartAddr, StartPointNo, ValueCount, ChgCount, SoeCount; SFesDi *pDi; SFesRtuDiValue DiValue[50]; SFesChgDi ChgDi[50]; @@ -2905,8 +2913,10 @@ void CModbusDataProcThread::Cmd01RespProcess_BigData(byte *Data, int DataSize) void CModbusDataProcThread::Cmd03RespProcess_BigData(byte *Data, int DataSize) { + boost::ignore_unused_variable_warning(DataSize); + int FunCode, diValue, bitValue; - int i, j, StartAddr, StartPointNo, ValueCount, ChgCount, SoeCount, PointCount; + int i, StartAddr, StartPointNo, ValueCount, ChgCount, SoeCount, PointCount; SFesDi *pDi; SFesRtuDiValue DiValue[50]; SFesChgDi ChgDi[50]; @@ -2928,7 +2938,7 @@ void CModbusDataProcThread::Cmd03RespProcess_BigData(byte *Data, int DataSize) float fValue, aiValue; int64 accValue; int miValue; - int dataIndex,bitIndex,StartIndex,EndIndex; + int dataIndex,StartIndex,EndIndex; FunCode = m_AppData.lastCmd.FunCode; StartAddr = m_AppData.lastCmd.StartAddr; @@ -3126,42 +3136,42 @@ void CModbusDataProcThread::Cmd03RespProcess_BigData(byte *Data, int DataSize) sValue32 |= (int)Data[4 + dataIndex * 2] << 16; sValue32 |= (int)Data[5 + dataIndex * 2] << 8; sValue32 |= (int)Data[6 + dataIndex * 2]; - aiValue = sValue32; + aiValue = static_cast(sValue32); break; case AI_DWord_LH://(32bit 有符号 低字前 高字节前) sValue32 = (int)Data[5 + dataIndex * 2] << 24; sValue32 |= (int)Data[6 + dataIndex * 2] << 16; sValue32 |= (int)Data[3 + dataIndex * 2] << 8; sValue32 |= (int)Data[4 + dataIndex * 2]; - aiValue = sValue32; + aiValue = static_cast(sValue32); break; case AI_DWord_LL://(32bit 有符号 低字前 低字节前) sValue32 = (int)Data[6 + dataIndex * 2] << 24; sValue32 |= (int)Data[5 + dataIndex * 2] << 16; sValue32 |= (int)Data[4 + dataIndex * 2] << 8; sValue32 |= (int)Data[3 + dataIndex * 2]; - aiValue = sValue32; + aiValue = static_cast(sValue32); break; case AI_UDWord_HH://(32bit 无符号 高字前 高字节前) uValue32 = (uint32)Data[3 + dataIndex * 2] << 24; uValue32 |= (uint32)Data[4 + dataIndex * 2] << 16; uValue32 |= (uint32)Data[5 + dataIndex * 2] << 8; uValue32 |= (uint32)Data[6 + dataIndex * 2]; - aiValue = uValue32; + aiValue = static_cast(uValue32); break; case AI_UDWord_LH://(32bit 无符号 低字前 高字节前) uValue32 = (uint32)Data[5 + dataIndex * 2] << 24; uValue32 |= (uint32)Data[6 + dataIndex * 2] << 16; uValue32 |= (uint32)Data[3 + dataIndex * 2] << 8; uValue32 |= (uint32)Data[4 + dataIndex * 2]; - aiValue = uValue32; + aiValue = static_cast(uValue32); break; case AI_UDWord_LL://(32bit 无符号 低字前 低字节前) uValue32 = (uint32)Data[6 + dataIndex * 2] << 24; uValue32 |= (uint32)Data[5 + dataIndex * 2] << 16; uValue32 |= (uint32)Data[4 + dataIndex * 2] << 8; uValue32 |= (uint32)Data[3 + dataIndex * 2]; - aiValue = uValue32; + aiValue = static_cast(uValue32); break; case AI_Float_HH://(四字节浮点 高字前 高字节前) uValue32 = (uint32)Data[3 + dataIndex * 2] << 24; @@ -3261,7 +3271,7 @@ void CModbusDataProcThread::Cmd03RespProcess_BigData(byte *Data, int DataSize) break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; @@ -3328,7 +3338,7 @@ void CModbusDataProcThread::Cmd03RespProcess_BigData(byte *Data, int DataSize) uValue32 |= (uint32)Data[6 + dataIndex * 2] << 16; uValue32 |= (uint32)Data[3 + dataIndex * 2] << 8; uValue32 |= (uint32)Data[4 + dataIndex * 2]; - aiValue = uValue32; + aiValue = static_cast(uValue32); break; case ACC_UDWord_LL://(32bit 无符号 低字前 低字节前) uValue32 = (uint32)Data[6 + dataIndex * 2] << 24; @@ -3343,7 +3353,7 @@ void CModbusDataProcThread::Cmd03RespProcess_BigData(byte *Data, int DataSize) uValue32 |= (uint32)Data[5 + dataIndex * 2] << 8; uValue32 |= (uint32)Data[6 + dataIndex * 2]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue; + accValue = static_cast(fValue); break; case ACC_Float_LH://(四字节浮点 低字前 高字节前) uValue32 = (uint32)Data[5 + dataIndex * 2] << 24; @@ -3351,7 +3361,7 @@ void CModbusDataProcThread::Cmd03RespProcess_BigData(byte *Data, int DataSize) uValue32 |= (uint32)Data[3 + dataIndex * 2] << 8; uValue32 |= (uint32)Data[4 + dataIndex * 2]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue; + accValue = static_cast(fValue); break; case ACC_Float_LL://(四字节浮点 低字前 低字节前) uValue32 = (uint32)Data[6 + dataIndex * 2] << 24; @@ -3359,11 +3369,11 @@ void CModbusDataProcThread::Cmd03RespProcess_BigData(byte *Data, int DataSize) uValue32 |= (uint32)Data[4 + dataIndex * 2] << 8; uValue32 |= (uint32)Data[3 + dataIndex * 2]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue; + accValue = static_cast(fValue); break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; @@ -3547,8 +3557,10 @@ void CModbusDataProcThread::Cmd03RespProcess_BigData(byte *Data, int DataSize) void CModbusDataProcThread::CmdTypeHybridProcess_BigData(byte *Data, int DataSize) { + boost::ignore_unused_variable_warning(DataSize); + int FunCode; - int i, StartAddr, StartPointNo, ValueCount, ChgCount, PointCount; + int i, StartAddr, StartPointNo, ValueCount, ChgCount; uint64 mSec; SFesAi *pAi; SFesRtuAiValue AiValue[100]; @@ -3562,7 +3574,7 @@ void CModbusDataProcThread::CmdTypeHybridProcess_BigData(byte *Data, int DataSiz uint32 uValue32; float fValue, aiValue; int64 accValue; - int dataIndex, bitIndex, StartIndex, EndIndex; + int dataIndex, StartIndex, EndIndex; FunCode = m_AppData.lastCmd.FunCode; StartAddr = m_AppData.lastCmd.StartAddr; @@ -3818,7 +3830,7 @@ void CModbusDataProcThread::CmdTypeHybridProcess_BigData(byte *Data, int DataSiz break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; diff --git a/product/src/fes/protocol/modbus_tcp/ModbusTcp.cpp b/product/src/fes/protocol/modbus_tcp/ModbusTcp.cpp index ce971015..b191ed5e 100644 --- a/product/src/fes/protocol/modbus_tcp/ModbusTcp.cpp +++ b/product/src/fes/protocol/modbus_tcp/ModbusTcp.cpp @@ -51,6 +51,8 @@ int EX_ChanTimer(int ChanNo) int EX_ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + g_ModbusChanelRun=false;//使所有的线程退出。 ModbusTcp.InformTcpThreadExit(); return iotSuccess; @@ -92,7 +94,7 @@ int CModbusTcp::SetBaseAddr(void *address) int CModbusTcp::SetProperty(int IsMainFes) { - g_ModbusIsMainFes = IsMainFes; + g_ModbusIsMainFes = (IsMainFes != 0); return iotSuccess; } @@ -215,7 +217,8 @@ int CModbusTcp::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) */ int CModbusTcp::ChanTimer(int MainChanNo) { - + boost::ignore_unused_variable_warning(MainChanNo); + return iotSuccess; } diff --git a/product/src/fes/protocol/modbus_tcpV2/ModbusTcpV2.cpp b/product/src/fes/protocol/modbus_tcpV2/ModbusTcpV2.cpp new file mode 100644 index 00000000..91940dc9 --- /dev/null +++ b/product/src/fes/protocol/modbus_tcpV2/ModbusTcpV2.cpp @@ -0,0 +1,699 @@ +/* + @file ModbusTcpV2.cpp + @brief MODBUS TCP client类 + + @author thxiao + @history + 2021-02-22 thxiao 使用人工干预模式读取数据 + 2021-02-23 thxiao CloseChan() CModbusDataProcThread使用了CTcpClientThread,所以先析构CModbusDataProcThread再析构CTcpClientThread. + 2021-07-08 thxiao 初始参数需要清零 + +*/ +#include "ModbusTcpV2.h" +#include "pub_utility_api/I18N.h" +#include "dbms/rdb_api/CRdbAccessEx.h" +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/rdb_api/RdbDefine.h" + +using namespace iot_public; + +CModbusTcpV2 ModbusTcpV2; +bool g_ModbusTcpV2IsMainFes=false; +bool g_ModbusTcpV2ChanelRun=true; + + +int EX_SetBaseAddr(void *address) +{ + ModbusTcpV2.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + ModbusTcpV2.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + ModbusTcpV2.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + ModbusTcpV2.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + ModbusTcpV2.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + g_ModbusTcpV2ChanelRun=false;//使所有的线程退出。 + ModbusTcpV2.InformTcpThreadExit(); + return iotSuccess; +} + +CModbusTcpV2::CModbusTcpV2() +{ + m_ptrCFesBase = nullptr; + m_initRtuFlag = 0;//2021-07-08 thxiao 初始参数需要清零 +} + +CModbusTcpV2::~CModbusTcpV2() +{ + if (m_CTcpClientQueue.size()>0 ) + { + m_CTcpClientQueue.clear(); + } + + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); + + LOGDEBUG("CModbusTcpV2::~CModbusTcpV2 退出"); + +} + + +int CModbusTcpV2::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + } + return iotSuccess; +} + +int CModbusTcpV2::SetProperty(int IsMainFes) +{ + g_ModbusTcpV2IsMainFes = IsMainFes; + return iotSuccess; +} + +/** + * @brief CModbusTcpV2::OpenChan + * 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CModbusTcpV2::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + CTcpClientThreadPtr ptrCTcpClient=NULL; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if (m_initRtuFlag == 0) + { + InitProcess(); + m_initRtuFlag = 1; + } + + if((OpenFlag==CN_FesChanThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + switch(ptrFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + if(ptrFesChan->m_ComThreadRun == CN_FesStopFlag) + { + //open chan thread + ptrCTcpClient = boost::make_shared(ptrFesChan); + if (ptrCTcpClient == NULL) + { + LOGERROR("CModbusTcpV2 EX_OpenChan() ChanNo:%d create CTcpClientThread error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + ptrCTcpClient->SetThreadRunMode(1);//2021-02-22 thxiao 使用人工干预读取数据。 + DataProcSetTcpThreadByChanNo(ptrMainFesChan->m_Param.ChanNo,ptrCTcpClient); + m_CTcpClientQueue.push_back(ptrCTcpClient); + ptrCTcpClient->resume(); //start TCP CLIENT THREAD + } + break; + default: + return iotFailed; + } + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + CModbusTcpV2DataProcThreadPtr ptrCDataProc; + ptrCDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan); + if (ptrCDataProc == NULL) + { + LOGERROR("CModbusTcpV2 EX_OpenChan() ChanNo:%d create CModbusDataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + ptrCDataProc->SetClientThread(ptrCTcpClient); + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; + +} + +/** + * @brief CModbusTcpV2::CloseChan + * 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CModbusTcpV2::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + //2021-02-23 thxiao CModbusTcpV2DataProcThread使用了CTcpClientThread,所以先析构CModbusTcpV2DataProcThread再析构CTcpClientThread. + if((CloseFlag==CN_FesChanThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrFesChan->m_ComThreadRun == CN_FesRunFlag) + { + DataProcClearTcpThreadByChanNo(ptrMainFesChan->m_Param.ChanNo); + //close chan thread + ClearTcpClientThreadByChanNo(ChanNo); + } + } + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + + return iotSuccess; +} + +/** + * @brief CModbusTcpV2::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int CModbusTcpV2::ChanTimer(int MainChanNo) +{ + + return iotSuccess; +} + + +void CModbusTcpV2::ClearTcpClientThreadByChanNo(int ChanNo) +{ + CTcpClientThreadPtr ptrTcp; + + if (m_CTcpClientQueue.size()<=0) + return; + vector::iterator it; + for (it = m_CTcpClientQueue.begin();it != m_CTcpClientQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CTcpClientQueue.erase(it); + LOGDEBUG("CModbusTcpV2::ClearTcpClientThreadByChanNo %d ok",ChanNo); + break; + } + } +} + +void CModbusTcpV2::ClearDataProcThreadByChanNo(int ChanNo) +{ + CModbusTcpV2DataProcThreadPtr ptrTcp; + + if (m_CDataProcQueue.size()<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it != m_CDataProcQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + LOGDEBUG("CModbusTcpV2::ClearDataProcThreadByChanNo %d start",ChanNo); + m_CDataProcQueue.erase(it); + LOGDEBUG("CModbusTcpV2::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + +/** + * @brief CModbusTcpV2::InformTcpThreadExit + * 设置线程退出标志,通知线程退出 + * @return + */ +void CModbusTcpV2::InformTcpThreadExit() +{ + CTcpClientThreadPtr ptrTcp; + + if (m_CTcpClientQueue.size()<=0) + return; + vector::iterator it; + for (it = m_CTcpClientQueue.begin();it!=m_CTcpClientQueue.end();it++) + { + ptrTcp = *it; + ptrTcp->SetThreadRunFlag(0); + } +} + + +void CModbusTcpV2::DataProcClearTcpThreadByChanNo(int ChanNo) +{ + CModbusTcpV2DataProcThreadPtr ptrTcp; + int found=0; + + if (m_CDataProcQueue.size()<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it != m_CDataProcQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + ptrTcp->ClearClientThread(); + found = 1; + break; + } + } + if(found) + { + LOGDEBUG("DataProcClearTcpThreadByChanNo() ChanNo=%d OK",ChanNo); + } + else + { + LOGDEBUG("DataProcClearTcpThreadByChanNo() ChanNo=%d failed",ChanNo); + } +} + + +void CModbusTcpV2::DataProcSetTcpThreadByChanNo(int ChanNo,CTcpClientThreadPtr ptrClientThread) +{ + CModbusTcpV2DataProcThreadPtr ptrTcp; + int found= 0; + + if (m_CDataProcQueue.size()<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it != m_CDataProcQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + ptrTcp->SetClientThread(ptrClientThread); + found = 1; + break; + } + } + if(found) + { + LOGDEBUG("DataProcSetTcpThreadByChanNo() ChanNo=%d OK",ChanNo); + } + else + { + LOGDEBUG("DataProcSetTcpThreadByChanNo() ChanNo=%d failed",ChanNo); + } + +} + +void CModbusTcpV2::InitProcess() +{ + int i, RtuCount, ProtocolId; + CFesChanPtr chanPtr; + + ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"modbus_tcpV2"); + if (ProtocolId == -1) + { + LOGERROR("InitProcess() can't found ProtocolId."); + return; + } + + RtuCount = m_ptrCFesBase->m_vectCFesRtuPtr.size(); + for (i = 0; i < RtuCount; i++) + { + if (m_ptrCFesBase->m_vectCFesRtuPtr[i]->m_Param.Used) + { + //found the Chan; + if ((chanPtr = GetChanDataByChanNo(m_ptrCFesBase->m_vectCFesRtuPtr[i]->m_Param.ChanNo)) != NULL) + { + if (chanPtr->m_Param.Used && (chanPtr->m_Param.ProtocolId == ProtocolId)) + InitProtocolPointMappingV2(m_ptrCFesBase->m_vectCFesRtuPtr[i]); //初始化转发表结构参数 + } + } + + } +} + +bool CModbusTcpV2::InitProtocolPointMappingV2(CFesRtuPtr RtuPtr) +{ + iot_dbms::CRdbAccessEx RdbAiTable; + iot_dbms::CRdbAccessEx RdbAoTable; + iot_dbms::CRdbAccessEx RdbDiTable; + iot_dbms::CRdbAccessEx RdbDoTable; + iot_dbms::CRdbAccessEx RdbAccTable; + iot_dbms::CRdbAccessEx RdbMiTable; + iot_dbms::CRdbAccessEx RdbMoTable; + int count, ret; + SFesAiIndex *pAiIndex; + SFesDiIndex *pDiIndex; + SFesAccIndex *pAccIndex; + SFesMiIndex *pMiIndex; + SFesAi *pAi; + SFesDi *pDi; + SFesAcc *pAcc; + SFesMi *pMi; + + int j; + + //条件判断 + iot_dbms::CONDINFO con; + con.relationop = ATTRCOND_EQU; + con.conditionval = RtuPtr->m_Param.RtuNo; + strcpy(con.name, "rtu_no"); + + //READ AI TABLE + std::vector VecAiParam; + std::vector vecAiColumn; + std::vector vecAiOrder; + + vecAiColumn.push_back("rtu_no"); + vecAiColumn.push_back("dot_no"); + vecAiColumn.push_back("res_para_int1"); + vecAiColumn.push_back("res_para_int2"); + vecAiColumn.push_back("res_para_int3"); + vecAiColumn.push_back("res_para_int4"); + + vecAiOrder.push_back("res_para_int2"); + vecAiOrder.push_back("res_para_int3"); + + ret = RdbAiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_AI_TBL); + if (ret == false) + { + LOGERROR("RdbAiTable::Open error"); + return iotFailed; + } + ret = RdbAiTable.selectOneColumnOneOrder(con, VecAiParam, vecAiColumn, vecAiOrder);//默认顺序 ljj + if (ret == false) + { + LOGERROR("RdbAiTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbAiTable.close(); + if (ret == false) + { + LOGERROR("RdbAiTable::close error"); + return iotFailed; + } + count = VecAiParam.size(); + if (count > 0) + { + //RtuPtr->m_MaxAiIndex = VecAiParam[count-1].Param1+1; + RtuPtr->m_MaxAiIndex = count; //ljj + if (RtuPtr->m_MaxAiIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pAiIndex = (SFesAiIndex*)malloc(RtuPtr->m_MaxAiIndex * sizeof(SFesAiIndex)); + if (RtuPtr->m_pAiIndex != NULL) + { + memset(RtuPtr->m_pAiIndex, 0xff, RtuPtr->m_MaxAiIndex * sizeof(SFesAiIndex)); + for (j = 0; j < RtuPtr->m_MaxAiIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pAiIndex = RtuPtr->m_pAiIndex + j; + pAiIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + pAiIndex = RtuPtr->m_pAiIndex + j; + pAiIndex->PointNo = VecAiParam[j].PointNo; + pAiIndex->PIndex = j; + if ((pAiIndex->PointNo >= 0) && (pAiIndex->PointNo < RtuPtr->m_MaxAiPoints)) + { + pAi = RtuPtr->m_pAi + pAiIndex->PointNo; + pAiIndex->DevId = pAi->DevId; + pAiIndex->Param2 = pAi->Param2; + pAiIndex->Param3 = pAi->Param3; + pAiIndex->Param4 = pAi->Param4; + pAiIndex->Used = 1; + } + } + } + else + { + RtuPtr->m_MaxAiIndex = 0; + LOGDEBUG("RtuNo:%d AI protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + + //READ DI TABLE + //ljj di新增按位排序 + std::vector VecDiParam; + std::vector vecDiColumn; + std::vector vecDiOrder; + + vecDiColumn.push_back("rtu_no"); + vecDiColumn.push_back("dot_no"); + vecDiColumn.push_back("res_para_int1"); + vecDiColumn.push_back("res_para_int2"); + vecDiColumn.push_back("res_para_int3"); + vecDiColumn.push_back("res_para_int4"); + + vecDiOrder.push_back("res_para_int2"); + vecDiOrder.push_back("res_para_int3"); + vecDiOrder.push_back("res_para_int4"); + + ret = RdbDiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_DI_TBL); + if (ret == false) + { + LOGERROR("RdbDiTable::Open error"); + return iotFailed; + } + ret = RdbDiTable.selectOneColumnOneOrder(con, VecDiParam, vecDiColumn, vecDiOrder);//默认顺序 + if (ret == false) + { + LOGERROR("RdbDiTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbDiTable.close(); + if (ret == false) + { + LOGERROR("RdbDiTable::close error"); + return iotFailed; + } + count = VecDiParam.size(); + if (count > 0) + { + RtuPtr->m_MaxDiIndex = count; + if (RtuPtr->m_MaxDiIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pDiIndex = (SFesDiIndex*)malloc(RtuPtr->m_MaxDiIndex * sizeof(SFesDiIndex)); + if (RtuPtr->m_pDiIndex != NULL) + { + memset(RtuPtr->m_pDiIndex, 0xff, RtuPtr->m_MaxDiIndex * sizeof(SFesDiIndex)); + for (j = 0; j < RtuPtr->m_MaxDiIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pDiIndex = RtuPtr->m_pDiIndex + j; + pDiIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + pDiIndex = RtuPtr->m_pDiIndex + j; + pDiIndex->PointNo = VecDiParam[j].PointNo; + pDiIndex->PIndex = j; + if ((pDiIndex->PointNo >= 0) && (pDiIndex->PointNo < RtuPtr->m_MaxDiPoints)) + { + pDi = RtuPtr->m_pDi + pDiIndex->PointNo; + pDiIndex->DevId = pDi->DevId; + pDiIndex->Param2 = pDi->Param2; + pDiIndex->Param3 = pDi->Param3; + pDiIndex->Param4 = pDi->Param4; + pDiIndex->Used = 1; + } + } + } + else + { + RtuPtr->m_MaxDiIndex = 0; + LOGDEBUG("RtuNo:%d Di protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + //READ ACC TABLE + std::vector VecAccParam; + std::vector vecAccColumn; + std::vector vecAccOrder; + + vecAccColumn.push_back("rtu_no"); + vecAccColumn.push_back("dot_no"); + vecAccColumn.push_back("res_para_int1"); + vecAccColumn.push_back("res_para_int2"); + vecAccColumn.push_back("res_para_int3"); + vecAccColumn.push_back("res_para_int4"); + + vecAccOrder.push_back("res_para_int2"); + vecAccOrder.push_back("res_para_int3"); + + ret = RdbAccTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_ACC_TBL); + if (ret == false) + { + LOGERROR("RdbAccTable::Open error"); + return iotFailed; + } + ret = RdbAccTable.selectOneColumnOneOrder(con, VecAccParam, vecAccColumn, vecAccOrder);//默认顺序 + if (ret == false) + { + LOGERROR("RdbAccTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbAccTable.close(); + if (ret == false) + { + LOGERROR("RdbAccTable::close error"); + return iotFailed; + } + + count = VecAccParam.size(); + if (count > 0) + { + //RtuPtr->m_MaxAccIndex = VecAccParam[count-1].Param1+1; + RtuPtr->m_MaxAccIndex = count; + if (RtuPtr->m_MaxAccIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pAccIndex = (SFesAccIndex*)malloc(RtuPtr->m_MaxAccIndex * sizeof(SFesAccIndex)); + if (RtuPtr->m_pAccIndex != NULL) + { + memset(RtuPtr->m_pAccIndex, 0xff, RtuPtr->m_MaxAccIndex * sizeof(SFesAccIndex)); + for (j = 0; j < RtuPtr->m_MaxAccIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pAccIndex = RtuPtr->m_pAccIndex + j; + pAccIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + pAccIndex = RtuPtr->m_pAccIndex + j; + pAccIndex->PointNo = VecAccParam[j].PointNo; + pAccIndex->PIndex = j; + if ((pAccIndex->PointNo >= 0) && (pAccIndex->PointNo < RtuPtr->m_MaxAccPoints)) + { + pAcc = RtuPtr->m_pAcc + pAccIndex->PointNo; + pAccIndex->DevId = pAcc->DevId; + pAccIndex->Param2 = pAcc->Param2; + pAccIndex->Param3 = pAcc->Param3; + pAccIndex->Param4 = pAcc->Param4; + pAccIndex->Used = 1; + } + } + } + else + { + RtuPtr->m_MaxAccIndex = 0; + LOGDEBUG("RtuNo:%d Acc protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + //READ MI TABLE + std::vector VecMiParam; + std::vector vecMiColumn; + std::vector vecMiOrder; + + vecMiColumn.push_back("rtu_no"); + vecMiColumn.push_back("dot_no"); + vecMiColumn.push_back("res_para_int1"); + vecMiColumn.push_back("res_para_int2"); + vecMiColumn.push_back("res_para_int3"); + vecMiColumn.push_back("res_para_int4"); + + vecMiOrder.push_back("res_para_int2"); + vecMiOrder.push_back("res_para_int3"); + + ret = RdbMiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_MI_TBL); + if (ret == false) + { + LOGERROR("RdbMiTable::Open error"); + return iotFailed; + } + ret = RdbMiTable.selectOneColumnOneOrder(con, VecMiParam, vecMiColumn, vecMiOrder);//默认顺序 + if (ret == false) + { + LOGERROR("RdbMiTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbMiTable.close(); + if (ret == false) + { + LOGERROR("RdbMiTable::close error"); + return iotFailed; + } + count = VecMiParam.size(); + if (count > 0) + { + //RtuPtr->m_MaxMiIndex = VecMiParam[count-1].Param1+1; + RtuPtr->m_MaxMiIndex = count; + if (RtuPtr->m_MaxMiIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pMiIndex = (SFesMiIndex*)malloc(RtuPtr->m_MaxMiIndex * sizeof(SFesMiIndex)); + if (RtuPtr->m_pMiIndex != NULL) + { + memset(RtuPtr->m_pMiIndex, 0xff, RtuPtr->m_MaxMiIndex * sizeof(SFesMiIndex)); + for (j = 0; j < RtuPtr->m_MaxMiIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pMiIndex = RtuPtr->m_pMiIndex + j; + pMiIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + pMiIndex = RtuPtr->m_pMiIndex + j; + pMiIndex->PointNo = VecMiParam[j].PointNo; + pMiIndex->PIndex = j; + if ((pMiIndex->PointNo >= 0) && (pMiIndex->PointNo < RtuPtr->m_MaxMiPoints)) + { + pMi = RtuPtr->m_pMi + pMiIndex->PointNo; + pMiIndex->DevId = pMi->DevId; + pMiIndex->Param2 = pMi->Param2; + pMiIndex->Param3 = pMi->Param3; + pMiIndex->Param4 = pMi->Param4; + pMiIndex->Used = 1; + } + } + } + else + { + RtuPtr->m_MaxMiIndex = 0; + LOGDEBUG("RtuNo:%d Mi protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + return iotSuccess; +} diff --git a/product/src/fes/protocol/modbus_tcpV2/ModbusTcpV2.h b/product/src/fes/protocol/modbus_tcpV2/ModbusTcpV2.h new file mode 100644 index 00000000..d6eb5fab --- /dev/null +++ b/product/src/fes/protocol/modbus_tcpV2/ModbusTcpV2.h @@ -0,0 +1,56 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "TcpClientThread.h" +#include "ModbusTcpV2DataProcThread.h" + +/* +#ifndef MODBUSTCP_API_EXPORT +#ifdef OS_WINDOWS +#define MODBUSTCP_API G_DECL_EXPORT +#else + //LINUX下 默认情况下会使用C++ API函数命名规则(函数名会增加字符),使用extern "C"修饰后变为C的函数名,便于使用。 +#define MODBUSTCP_API extern "C" +#endif +#else +#define MODBUSTCP_API G_DECL_IMPORT +#endif +*/ + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API CModbusTcpV2 : public CProtocolBase +{ +public: + CModbusTcpV2(); + ~CModbusTcpV2(); + + vector m_CTcpClientQueue; + vector m_CDataProcQueue; + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + + int m_initRtuFlag; + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + void InformTcpThreadExit(); +private: + void ClearTcpClientThreadByChanNo(int ChanNo); + void ClearDataProcThreadByChanNo(int ChanNo); + void DataProcClearTcpThreadByChanNo(int ChanNo); + void DataProcSetTcpThreadByChanNo(int ChanNo,CTcpClientThreadPtr ptrClientThread); + bool InitProtocolPointMappingV2(CFesRtuPtr RtuPtr); + void InitProcess(); +}; + diff --git a/product/src/fes/protocol/modbus_tcpV2/ModbusTcpV2DataProcThread.cpp b/product/src/fes/protocol/modbus_tcpV2/ModbusTcpV2DataProcThread.cpp new file mode 100644 index 00000000..b650cdf4 --- /dev/null +++ b/product/src/fes/protocol/modbus_tcpV2/ModbusTcpV2DataProcThread.cpp @@ -0,0 +1,2975 @@ +/* + @file CModbusTcpV2DataProcThread.cpp + @brief ModbusTcpV2 数据处理线程类。 + 主框架调用时,传入的ptrCFesChan是主通道的数据结构。如果存在通达切换的情况,也是通过主通道的数据来得到对应的通道。 + 规约参数1:数据地址序号,序号唯一,不可重复。序号从低地址向高地址排序。 + @author thxiao + + 2019-8-7 jacky 取消定时器缓冲命令,修改了数据块轮询方式 + 2019-8-14 jacky 增加了CmdTypeHybridProcess(Data,DataSize)处理AI和ACC的混合解析功能 + 2019-08-30 thxiao AoCmdProcess()增加失败详细描述 + 2019-08-30 命令的发送按原有的方式,时间间隔最小为100MS,过大,所以改为程序内部处理。 + 2020-01-11 thxiao + 1、按支持转发数据新接口完善程序。 + 2020-02-18 thxiao 遥控增加五防闭锁检查 + 2020-02-19 thxiao CmdTypeHybridProcess()种8位的数据格式不处理,删除;格式类型不在本程序内重新定义,需要在FesDef.h同一定义。 + 2020-02-24 thxiao 创建时设置ThreadRun标识。 + 2020-04-20 thxiao + 1、SendProcess() 不再判断通信状态,因为通信中断在接收函数判断,导致无法设置通信中断标志。 + 2、SendDataToPort() 通信不正常,不发送数据. + 2020-05-14 thxiao GetPollingCmd() 如果没有配置块,则轮训下一个设备 + 2020-05-20 thxiao 增加03遥信处理,数据块自定义#1 = 1,遥信按位组合。 + 2020-07-21 thxiao 0X05功能码,增加可配置的遥控命令 + 2020-08-18 thxiao 一个通道挂多个设备的规约,初始化时需要把标志置上在线状态,保证第一次每个设备都可以发送指令。 + 2021-01-18 thxiao 增加模拟量解析62(模拟量帧(符号位(bit15)加数值 高字节前)),63(模拟量帧(符号位(bit31)加数值 高字节前)) + 2021-01-22 thxiao SendDataToPort()中m_LinkStatus的判断使用了主通道m_LinkStatus,导致有备通道无法正常发送数据。 + 2021-02-03 thxiao 测试过程中发现数据接收会错位,因为协议是POLLING的,所以当收到正确的数据包后,数据缓冲清空。RecvNetData()完善。 + 2021-02-05 thxiao 测试过程中发现数据接收会错位,因为协议是POLLING的,所以当发送数据包前,数据缓冲清空。SendDataToPort()完善。 + 2021-02-22 thxiao 使用人工干预模式读取数据,SendDataToPort()、RecvNetData()完善。 + 2021-04-29 thxiao + 1、对于点少的设备采用原来通过报文去查找点的方法,CPU的占用率不高,使用没有问题。 + 对于才集一个站的数据(上万点),还采用该方法,CPU的占用率很高,不再适合使用。新增从点去找到报文数据的方法。 + 这时需要配置RTU PARAM1=1;点规约参数1(Index)不可重复;数据块配置参数2=本块数据起始Index,数据块配置参数2=本块数据结束Index; + 每块的数据的数据类型不可混合。 + 2021-04-30 thxiao + RTU PARAM2=1000 为延时发送时间,单位毫秒 + 2021-05-13 thxiao 增加了CmdTypeHybridProcess_BigData(Data,DataSize)处理AI和ACC的混合解析功能 + 2021-06-04 thxiao 完善SendDataToPort() + 2021-06-24 ljj 0x10功能码的遥调数据增加整数的配置 + 2021-06-25 ljj modbusTcpV2 + 1.自动根据测点寄存器地址和位地址排序后,设置测点索引; + 2.数据块关联对应测点的起始索引和结束索引; + 3.解析数据时,根据请求数据块的序号,遍历对应测点,并根据测点配置解析数据; + 2021-09-26 ljj 每个RTU都需要InitProtocolBlockDataIndexMapping()初始化 + 2022-03-31 thxiao + 1、AoCmdProcess()增加0x10 设置命令16位 + 2、科华很多设备响应是事务处理标识符+1,所以默认是不处理。自定义参数3=1,才判断事务处理标识符。 + 2022-04-22 thxiao clientTransID error close socket + 2022-05-09 thxiao m_AppData.m_TransIDFailCount 需要初始化为0 + 2022-09-02 thxiao + 1、MODBUSTCPV2 目前没有推广使用,所以m_ptrCFesRtu->m_Param.ResParam3=0默认为判断clientTransID。 + 2、科华有UPS设备响应是事务处理标识符+1,增加这种特殊的判断,m_ptrCFesRtu->m_Param.ResParam3=1,其他值不进行clientTransID判断 +2022-11-24 thxiao + 1、InitProtocolBlockDataIndexMapping()数据块关联数据索引赋值错误 + 2、Cmd01RespProcess(),Cmd03RespProcess(),CmdTypeHybridProcess() PointIndex增加判断,防止数组过界. +2022-12-20 thxiao + 1、Cmd03RespProcess() Mi取点值应该为PointIndex + 2、电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + 3、ACC很多地方取数字节偏移错误 + +*/ +#include "ModbusTcpV2DataProcThread.h" +#include "pub_utility_api/I18N.h" + +using namespace iot_public; + +extern bool g_ModbusTcpV2IsMainFes; +extern bool g_ModbusTcpV2ChanelRun; + + +CModbusTcpV2DataProcThread::CModbusTcpV2DataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan): + CTimerThreadBase("ModbusTcpV2DataProcThread",10,0,true) +{ + CFesRtuPtr pRtu; + int RtuNo; + + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + m_AppData.comState = CN_FesRtuComDown; + m_AppData.setCmdCount = 0; + m_ClearClientFlag = 0; + m_AppData.m_TransIDFailCount = 0;//2022-05-09 thxiao m_AppData.m_TransIDFailCount 需要初始化 + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL)) + { + return ; + } + + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + //2020-08-18 thxiao 一个通道挂多个设备的规约,初始化时需要把标志置上在线状态,保证第一次每个设备都可以发送指令。 + m_ptrCFesBase->ClearRtuOfflineFlag(m_ptrCFesChan); + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + InitProtocolBlockDataIndexMapping(pRtu);//2021-09-26 ljj 每个RTU都需要初始化 + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } + + LOGDEBUG("CModbusTcpV2DataProcThread::CModbusTcpV2DataProcThread() ChanNo=%d 创建", m_ptrCurrentChan->m_Param.ChanNo); +} + + +CModbusTcpV2DataProcThread::~CModbusTcpV2DataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + LOGDEBUG("CModbusTcpV2DataProcThread::~CModbusTcpV2DataProcThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); + +} + +/** + * @brief CModbusTcpV2DataProcThread::beforeExecute + * + */ +int CModbusTcpV2DataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief CModbusTcpV2DataProcThread::execute + + */ +void CModbusTcpV2DataProcThread::execute() +{ + SFesNetEvent netEvent; + + if(!g_ModbusTcpV2ChanelRun) + return; + + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + + if(m_ptrCurrentChan == NULL) + return; + + //读取网络事件,但不做任何处理 + if(m_ptrCurrentChan->ReadNetEvent(1,&netEvent)>0) + { + switch(netEvent.EventType) + { + case CN_FesNetEvent_Connect: + break; + case CN_FesNetEvent_Disconnect: + break; + default: + break; + } + } + + SetSendCmdFlag(); + + //LOGDEBUG("ChanNo=%d SendProcess START",m_ptrCurrentChan->m_Param.ChanNo); + if(SendProcess()>0) + { + RecvNetData(); + } + //LOGDEBUG("ChanNo=%d SendProcess END",m_ptrCurrentChan->m_Param.ChanNo); + + if(m_ClearClientFlag) + { + m_ClearClientFlag = 0; + m_ptrClientThread = NULL; + } +} + +/* + @brief 执行quit函数前的处理 + */ +void CModbusTcpV2DataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); +} + +/** + * @brief CModbusTcpV2DataProcThread::SendProcess + * ModbusTcpV2 发送处理 + * @return 返回发送数据长度 + */ +int CModbusTcpV2DataProcThread::SendProcess() +{ + int retLen = 0; + + if(m_ptrCurrentChan==NULL) + return iotFailed; + + //有多个RTU时,才需要获取当前最新的RTU结构,否则m_ptrCFesRtu在构造函数初始化。 + if(m_ptrCFesChan->m_RtuNum >1) + { + //需要得到当前的RTU数据结构 + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + } + + //2020-04-20 thxiao 不再判断通信状态,因为通信中断在接收函数判断,导致无法设置通信中断标志。 + //if(m_ptrCurrentChan->m_LinkStatus == CN_FesChanConnect) + //{ + if((retLen=InsertCmdProcess())>0) + return retLen; + + if((retLen=PollingCmdProcess())>0) + return retLen; + //} + + if (m_ptrCurrentChan->m_LinkStatus != CN_FesChanConnect) + { + ErrorControlRespProcess(); //网络断开时有控制命令来需要做异常处理 + } + return retLen; + +} + +/** + * @brief CModbusTcpV2DataProcThread::RecvNetData + * ModbusTcpV2 TCP 接收处理 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CModbusTcpV2DataProcThread::RecvNetData() +{ + int count =20; + int FunCode,DevAddr,ExpectLen; + byte Data[512]; + int recvLen,Len,i; + + if(m_ptrCurrentChan==NULL) + return iotFailed; + + DevAddr = m_AppData.lastCmdData[6]; + FunCode = m_AppData.lastCmdData[7]; + //int ChanNo = m_ptrCurrentChan->m_Param.ChanNo; + Len=0; + recvLen=0; + count = m_ptrCFesChan->m_Param.RespTimeout/10; + if(count<=10) + count = 10;//最小响应超时为100毫秒 + ExpectLen =0; + for(i=0;iRxData(); + + recvLen = m_ptrCurrentChan->ReadRxBufData(500-Len,&Data[Len]);//数据缓存在 + if(recvLen<=0) + { + if(ExpectLen==0) + continue; + else//没有后续数据,退出接收 + if((Len>=ExpectLen)&&(ExpectLen>0)) + { + //LOGDEBUG("没有后续数据,退出接收 ChanNo=%d",m_ptrCFesChan->m_Param.ChanNo); + break; + } + } + + m_ptrCurrentChan->DeleteReadRxBufData(recvLen);//清除已读取的数据 + Len += recvLen; + if(Len >8) + { + //cmd = Data[7]; + if(Data[7]&0x80)//ERROR + ExpectLen = 9; + else + { + switch(Data[7]) + { + case 0x01: + case 0x02: + ExpectLen = Data[8]+9; + break; + case 0x05: + case 0x06: + case 0x10: + ExpectLen = 12; + break; + default://0x03\0x04 + ExpectLen = Data[8]+9; + } + } + } + /*if((Len>=ExpectLen)&&(ExpectLen>0)) + { + break; + }*/ + } + if(Len>0) + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo,Data,Len,CN_SFesSimComFrameTypeRecv); + + if(Len==0)//接收不完整,重发数据 + { + m_ptrCurrentChan->SetResendNum(1); + if(m_ptrCurrentChan->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCurrentChan->ResetResendNum(); + if(m_AppData.comState == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + m_AppData.comState = CN_FesRtuComDown; + } + } + CmdControlRespProcess(NULL,0,0); + NextRtuIndex(m_ptrCFesChan); + return iotFailed; + } + //长度、地址、功能码 都正确则认为数据正确。 + if ((Len == ExpectLen) && (DevAddr == Data[6]) && (FunCode == (Data[7] & 0x7f))) + { + //2022-03-31 thxiao 为了避免帧错位的情况出现,事务处理标识符不同,放弃处理,并且清空接收队列。 + uint16 clientTransID; + clientTransID = (uint16)Data[0] << 8; + clientTransID |= (uint16)Data[1]; + clientTransID++; + //2022-09-02 thxiao MODBUSTCPV2 目前没有推广使用,所以默认为判断clientTransID。 + if ((m_ptrCFesRtu->m_Param.ResParam3 == 0) && (clientTransID != m_ptrCFesRtu->m_clientTransID)) + { + if (m_ptrClientThread != NULL) + { + for (i = 0; i < 5; i++) + m_ptrClientThread->RxData();//读取多余的数据 + m_ptrCurrentChan->ClearDataBuf();//清除缓冲的数据 + } + if (m_AppData.m_TransIDFailCount++ > 5)//2022-04-22 thxiao clientTransID error exceed max times close socket + { + m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao + //close the soclet + SFesAppNetEvent event; + event.EventType = CN_FesAppNetEvent_CloseSock; + m_ptrCurrentChan->WriteAppNetEvent(1, &event); + LOGDEBUG("frame clientTransID error exceed max times close socket !", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + LOGDEBUG("clientTransID=%d m_ptrCFesRtu->m_clientTransID=%d discard the frame!", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + else//2022-09-02 thxiao 科华有UPS设备响应是事务处理标识符+1,增加这种特殊的判断 + if ((m_ptrCFesRtu->m_Param.ResParam3 == 1) && (clientTransID != (m_ptrCFesRtu->m_clientTransID+1))) + { + if (m_ptrClientThread != NULL) + { + for (i = 0; i < 5; i++) + m_ptrClientThread->RxData();//读取多余的数据 + m_ptrCurrentChan->ClearDataBuf();//清除缓冲的数据 + } + if (m_AppData.m_TransIDFailCount++ > 5)//2022-04-22 thxiao clientTransID error exceed max times close socket + { + m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao + //close the soclet + SFesAppNetEvent event; + event.EventType = CN_FesAppNetEvent_CloseSock; + m_ptrCurrentChan->WriteAppNetEvent(1, &event); + LOGDEBUG("frame clientTransID error exceed max times close socket !", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + LOGDEBUG("clientTransID=%d m_ptrCFesRtu->m_clientTransID=%d discard the frame!", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + else + { + m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao + m_ptrCurrentChan->ResetResendNum(); + m_ptrCurrentChan->SetRxNum(1); + RecvDataProcess(&Data[6], Len - 6);//保文头不再处理 + if (m_AppData.comState == CN_FesRtuComDown) + { + m_AppData.comState = CN_FesRtuNormal; + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuNormal); + } + //next RTU + NextRtuIndex(m_ptrCFesChan); + } + return iotSuccess; + } + else + { + m_ptrCurrentChan->SetErrNum(1); + //next RTU + CmdControlRespProcess(NULL, 0, 0); + NextRtuIndex(m_ptrCFesChan); + return iotFailed; + } +} + +/** + * @brief CModbusTcpV2DataProcThread::InsertCmdProcess + * 收到SCADA的控制命令,插入命令处理。组织ModbusTcpV2命令帧,并返回操作消息 + * @return 实际发送数据长度 + */ +int CModbusTcpV2DataProcThread::InsertCmdProcess() +{ + byte data[256]; + int dataSize,retSize; + int len =0; + + if(m_ptrCFesRtu == NULL) + return 0; + + if(g_ModbusTcpV2IsMainFes==false)//备机不作任何操作 + return 0; + + dataSize = sizeof(data); + retSize = 0; + if(m_ptrCFesRtu->GetRxDoCmdNum()>0) + { + retSize = DoCmdProcess(data,dataSize); + } + else + if(m_ptrCFesRtu->GetRxAoCmdNum()>0) + { + retSize = AoCmdProcess(data,dataSize); + } + else + if(m_ptrCFesRtu->GetRxMoCmdNum()>0) + { + retSize = MoCmdProcess(data,dataSize); + } + else + if(m_ptrCFesRtu->GetRxSettingCmdNum()>0) + { + retSize = SettingCmdProcess(); + } + else + if(m_ptrCFesRtu->GetRxDefCmdNum()>0) + { + retSize = DefCmdProcess(data,dataSize); + + } + + if(retSize > 0) + { + //send data to net + len = SendDataToPort(data,retSize); + } + + return len; +} + +/** + * @brief CModbusTcpV2DataProcThread::PollingCmdProcess + * 循环发送读取数据命令,组织ModbusTcpV2命令帧。 + * @param Data 发送数据区 + * @param dataSize 发送数据区长度 + * @return 实际发送数据长度 + */ +int CModbusTcpV2DataProcThread::PollingCmdProcess() +{ + byte Data[256]; + SModbusCmd cmd; + int writex; + int len=0; + + if(GetPollingCmd(&cmd)==iotFailed) + { + //LOGERROR("CModbusTcpV2DataProcThread::PollingCmdProcess() return 0"); + return 0; + } + memcpy(&m_AppData.lastCmd,&cmd,sizeof(SModbusCmd)); + writex = 7; + Data[writex++] = cmd.FunCode; + Data[writex++] = (cmd.StartAddr>>8)&0x00ff; + Data[writex++] = cmd.StartAddr&0x00ff; + Data[writex++] = (cmd.DataLen>>8)&0x00ff; + Data[writex++] = cmd.DataLen&0x00ff; + FillHeader(Data, writex - 6); + + //send data to net + len = SendDataToPort(Data,writex); + m_AppData.state = CN_ModbusTcpV2AppState_idle; + return len; +} + +/** + * @brief CModbusTcpV2DataProcThread::FillHeader + * 组帧头 + * @param Data 数据区 + * @param Size 数据区长度 + */ +void CModbusTcpV2DataProcThread::FillHeader(byte *Data, int DataSize) +{ + /* MBAP 头编码*/ + /* + the ModbusTcpV2 TCP/IP ADU(MBAP) Header format: + +---------------+---------------+----------+----------+--------+--------+--------+ + |clientTransIDH |clientTransIDL |prtclNoH | prtclNoL |lengthH |lengthL | unitID | + +---------------+---------------+----------+----------+--------+--------+--------+ + + short clientTransID; 事务处理标识符 + short prtclNo; 协议标识符( 0x0000 = ModbusTcpV2协议) + short length; 长度 + char unitID; 单元标识符,为远端设备的ModbusTcpV2 从站地址. + 当对直接连接到TCP/IP网络上的ModbusTcpV2服务 + 器寻址时,建议不要在"单元标识符"域使 + 用有效的ModbusTcpV2从站地址,使用0xFF作为无效值 + + */ + + Data[0] = (byte)((m_ptrCFesRtu->m_clientTransID >> 8) & 0xff); + Data[1] = (byte)(m_ptrCFesRtu->m_clientTransID & 0xff); + Data[2] = 0x00; + Data[3] = 0x00; + Data[4] = (char)((DataSize >> 8) & 0x00ff); + Data[5] = (char)(DataSize & 0x00ff); + Data[6] = m_ptrCFesRtu->m_Param.RtuAddr; + m_ptrCFesRtu->m_clientTransID++; +} + +/** + * @brief CModbusTcpV2DataProcThread::SendDataToPort + * 数据发送到发送缓冲区。 + * 如是主通道,直接使用m_ptrCFesChan通道结构;如果是备用通道,需要获取当前使用通道,在发送数据。 + * @param Data 数据区 + * @param Size 数据区长度 + */ +int CModbusTcpV2DataProcThread::SendDataToPort(byte *Data, int Size) +{ + int len = 0; + + if(m_ptrCurrentChan==NULL) + return 0; + + //2021-02-05 thxiao 测试过程中发现数据接收会错位,因为协议是POLLING的,所以当发送数据包前,数据缓冲清空。 + m_ptrCurrentChan->ClearDataBuf(); + + //2020-04-20 thxiao 通信不正常,不发送数据 + if (m_ptrCurrentChan->m_LinkStatus != CN_FesChanConnect)//2021-01-22 thxiao + return Size;//2021-06-04 thxiao 因为通信中断在接收函数判断,导致无法设置通信中断标志 + + //2021-02-22 thxiao 直接把数据发送出去。 + //m_ptrCurrentChan->WriteTxBufData(Size, Data); + if(m_ptrClientThread != NULL) + { + //2021-04-30 thxiao RTU PARAM2 = 1000 为延时发送时间,单位毫秒 + if (m_ptrCFesRtu->m_Param.ResParam2 > 0) + SleepmSec(m_ptrCFesRtu->m_Param.ResParam2); + + len = m_ptrClientThread->TxData(Size,Data); + + //saved last send cmd + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo,Data,Size,CN_SFesSimComFrameTypeSend); + m_ptrCurrentChan->SetTxNum(1); + + memcpy(&m_AppData.lastCmdData[0],Data,Size); + m_AppData.lastCmdDataLen = Size; + + } + else + { + LOGDEBUG("ChanNo=%d m_ptrClientThread is NULL can not send data",m_ptrCurrentChan->m_Param.ChanNo); + } + + return Size; + +} + +/** + * @brief CModbusTcpV2DataProcThread::DoCmdProcess + * 接收SCADA传来的DO控制命令,组织ModbusTcpV2命令帧,并返回操作消息。 + * @param Data 发送数据区 + * @param dataSize 发送数据区长度 + * @return 实际发送数据长度 + */ +int CModbusTcpV2DataProcThread::DoCmdProcess(byte *Data, int /*dataSize*/) +{ + SFesRxDoCmd cmd; + SFesTxDoCmd retCmd; + SFesDo *pDo; + int writex; + + writex = 0; + memset(&retCmd,0,sizeof(retCmd)); + memset(&cmd,0,sizeof(cmd)); + if(m_ptrCFesRtu->ReadRxDoCmd(1,&cmd)==1) + { + //get the cmd ok + //2019-02-21 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + + //2020-02-18 thxiao 遥控增加五防闭锁检查 + if (m_ptrCFesRtu->CheckWuFangDoStatus(cmd.PointID) == 0)//闭锁 + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d 闭锁").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d 闭锁", m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + return 0; + } + + if ((pDo = GetFesDoByPointNo(m_ptrCFesRtu, cmd.PointID)) != NULL) + { + if(cmd.CtrlActType == CN_ControlExecute) + { + writex = 7; + Data[writex++] = pDo->Param2;/*command*/ + if(pDo->Param2==0x05) + { + //2020-07-21 thxiao 增加可配置的遥控命令 + if (pDo->Attribute & CN_FesDo_Special)//点属性判断特殊遥控 + { + if (cmd.iValue == 1)//CLOSE + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff;//合值 + Data[writex++] = pDo->Param4 & 0x00ff;//合值 + } + else//OPEN + { + Data[writex++] = (pDo->Param5 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param5 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param6 >> 8) & 0x00ff;//分值 + Data[writex++] = pDo->Param6 & 0x00ff;//分值 + } + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff; + Data[writex++] = pDo->Param3 & 0x00ff; + if (cmd.iValue == 1) + { + Data[writex++] = 0xff;/*05命令其值为,0xff00 表示合闸*/ + Data[writex++] = 0x00; + } + else + { + Data[writex++] = 0x00;/*05命令其值为,0x0000表示分闸*/ + Data[writex++] = 0x00; + } + } + } + else if(pDo->Param2==0x06) + { + //Attribute + //Bit0 遥控类型。0脉冲输出,1自保持输出(需要程序清零)。 + //Bit1 遥控复归。0:表示普通遥控,1:表示复归。 + //Bit2 特殊遥控点0:表示普通遥控,1:特殊遥控点。 + + if (pDo->Attribute & CN_FesDo_Special)//点属性判断特殊遥控 + { + if (cmd.iValue == 1)//CLOSE + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff;//合值 + Data[writex++] = pDo->Param4 & 0x00ff;//合值 + } + else//OPEN + { + Data[writex++] = (pDo->Param5 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param5 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param6 >> 8) & 0x00ff;//分值 + Data[writex++] = pDo->Param6 & 0x00ff;//分值 + } + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff; + Data[writex++] = pDo->Param3 & 0x00ff; + if (cmd.iValue == 1) + { + cmd.iValue <<= pDo->Param4; + Data[writex++] = ((cmd.iValue >> 8) & 0xff);/*06命令按寄存器bit控制PLC(复归式)*/ + Data[writex++] = (cmd.iValue & 0xff); + } + else + { + Data[writex++] = 0x00;/*06命令,值为0,PLC(复归式)不动作*/ + Data[writex++] = 0x00; + } + } + } + else + return 0; + FillHeader(Data, writex - 6); + memcpy(&m_AppData.doCmd,&cmd,sizeof(cmd)); + m_AppData.lastCotrolcmd = CN_ModbusTcpV2DoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_waitControlResp; + LOGDEBUG ("DO遥控执行成功 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); + } + else if(cmd.CtrlActType == CN_ControlSelect) //遥控选择作为日后扩展用 + { + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlSuccess; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("DO遥控选择成功 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpV2DoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_waitControlResp; + } + else + { + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + } + } + else + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N("遥控失败!RtuNo:%d 找不到遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("DO遥控失败 !RtuNo:%d 找不到遥控点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + } + } + return writex; +} + +/** + * @brief CModbusTcpV2DataProcThread::AoCmdProcess + * 接收SCADA传来的AO控制命令,组织ModbusTcpV2命令帧,并返回操作消息。 + * @param Data 发送数据区 + * @param dataSize 发送数据区长度 + * @return 实际发送数据长度 + */ +int CModbusTcpV2DataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) +{ + SFesRxAoCmd cmd; + SFesTxAoCmd retCmd; + short setValue; + SFesAo *pAo=NULL; + int writex; + float fValue,tempValue; + uint32 ui32Value; + int failed; + int iValue; + + writex = 0; + if(m_ptrCFesRtu->ReadRxAoCmd(1,&cmd)==1) + { + //get the cmd ok + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + if ((pAo = GetFesAoByPointNo(m_ptrCFesRtu, cmd.PointID)) != NULL) + { + if(cmd.CtrlActType == CN_ControlExecute) + { + tempValue = cmd.fValue; + failed = 0; + if(pAo->Coeff!=0) + { + fValue=(tempValue-pAo->Base)/pAo->Coeff; + if(pAo->MaxRange>pAo->MinRange) + { + if ((fValue < pAo->MinRange) || (fValue > pAo->MaxRange)) + { + //2019-08-30 thxiao 增加失败详细描述 + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d 量程越限").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); + failed = 1; + } + } + else + { + sprintf(retCmd.strParam, I18N("遥调失败,量程配置错误,最大量程<=最小量程!").str().c_str()); + failed = 1; + } + } + else + { + //2019-08-30 thxiao 增加失败详细描述 + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d 系数为0").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); + failed = 1; + } + + if(failed == 1) + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + //sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("AO遥调失败,点系数为0或者量程越限!RtuNo:%d 遥调点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + } + else + { + writex = 7; + if(pAo->Param2==0x10) + { + if (pAo->Param4 == 3)//2022-03-31 thxiao 增加0x10 设置命令16位 + { + Data[writex++] = pAo->Param2; //command 0x10 + Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address + Data[writex++] = pAo->Param3 & 0x00ff; + Data[writex++] = 0x00; + Data[writex++] = 0x01; + Data[writex++] = 0x02; + setValue = (short)fValue; + Data[writex++] = (byte)(setValue >> 8); + Data[writex++] = (byte)setValue; + } + else + { + Data[writex++] = pAo->Param2; //command 0x10 + Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address + Data[writex++] = pAo->Param3 & 0x00ff; + Data[writex++] = 0x00; + Data[writex++] = 0x02; + Data[writex++] = 0x04; + if (pAo->Param4 == 0) //2021-06-24 ljj + { + memcpy(&iValue, &fValue, sizeof(fValue)); + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + } + else if (pAo->Param4 == 1) + { + ui32Value = fValue; + Data[writex++] = (byte)(ui32Value >> 24); + Data[writex++] = (byte)(ui32Value >> 16); + Data[writex++] = (byte)(ui32Value >> 8); + Data[writex++] = (byte)ui32Value; + } + else if (pAo->Param4 == 2) + { + iValue = fValue; + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + } + } + } + else + { + setValue = (short)fValue; + Data[writex++] = pAo->Param2; //command 0x06 + Data[writex++] = (pAo->Param3>>8)&0x00ff; //address + Data[writex++] = pAo->Param3&0x00ff; + Data[writex++] = (setValue>>8)&0x00ff; + Data[writex++] = setValue&0x00ff; + + } + + FillHeader(Data, writex - 6); + memcpy(&m_AppData.aoCmd,&cmd,sizeof(cmd)); + m_AppData.lastCotrolcmd = CN_ModbusTcpV2AoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_waitControlResp; + LOGDEBUG ("AO遥调成功 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.fValue,cmd.RtuName,cmd.PointID); + } + } + else + { + + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + retCmd.CtrlActType = cmd.CtrlActType; + LOGDEBUG ("AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.fValue,cmd.RtuName,cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + } + } + else + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("AO遥调失败!RtuNo:%d 找不到遥调点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + } + } + return writex; +} + +/** + * @brief CModbusTcpV2DataProcThread::MoCmdProcess + * 接收SCADA传来的MO控制命令,组织ModbusTcpV2命令帧,并返回操作消息。 + * @param Data 发送数据区 + * @param dataSize 发送数据区长度 + * @return 实际发送数据长度 + */ +int CModbusTcpV2DataProcThread::MoCmdProcess(byte *Data, int /*dataSize*/) +{ + SFesRxMoCmd cmd; + SFesTxMoCmd retCmd; + SFesMo *pMo; + int writex,iValue,failed; + + writex = 0; + if(m_ptrCFesRtu->ReadRxMoCmd(1,&cmd)==1) + { + LOGDEBUG ("cmd.TableName :%s cmd.ColumnName : %s cmd.RtuName : %s cmd.TagName : %s",cmd.TableName,cmd.ColumnName,cmd.RtuName,cmd.TagName); + LOGDEBUG ("cmd.PointID = %d cmd.CtrlActType = %d ",cmd.PointID,cmd.CtrlActType); + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + //get the cmd ok + //memset(&retCmd,0,sizeof(retCmd)); + if((pMo = GetFesMoByPIndex(m_ptrCFesRtu,cmd.PointID))!=NULL) + { + if(cmd.CtrlActType == CN_ControlExecute) + { + failed = 0; + if(pMo->Coeff!=0) + { + iValue=(cmd.iValue-pMo->Base)/pMo->Coeff; + if(pMo->MaxRange>pMo->MinRange) + { + if((iValueMinRange)||(iValue>pMo->MaxRange)) + failed = 1; + } + } + else + failed = 1; + + if(failed == 1) + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N("混合量输出失败!RtuNo:%d 找不到混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("MO混合量输出失败,点系数为0或者量程越限!RtuNo:%d 混合量输出点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + } + else + { + writex = 7; + if(pMo->Param2==0x10) + { + Data[writex++] = pMo->Param2; //command 0x10 + Data[writex++] = (pMo->Param3>>8)&0x00ff; //address + Data[writex++] = pMo->Param3&0x00ff; + Data[writex++] = 0x00; + Data[writex++] = 0x01; + Data[writex++] =0x02; + Data[writex++] = (iValue>>8)&0x00ff; + Data[writex++] = iValue&0x00ff; + } + else//0x06 + { + Data[writex++] = pMo->Param2; //command 0x06 + Data[writex++] = (pMo->Param3>>8)&0x00ff; //address + Data[writex++] = pMo->Param3&0x00ff; + Data[writex++] = (iValue>>8)&0x00ff; + Data[writex++] = iValue&0x00ff; + } + FillHeader(Data, writex - 6); + memcpy(&m_AppData.moCmd,&cmd,sizeof(cmd)); + m_AppData.lastCotrolcmd = CN_ModbusTcpV2MoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_waitControlResp; + LOGDEBUG ("MO混合量输出成功 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); + } + } + else + { + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + + LOGDEBUG ("MO混合量执行失败 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + } + } + else + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + sprintf(retCmd.strParam,I18N("混合量输出失败!RtuNo:%d 找不到混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + + LOGDEBUG ("MO混合量输出失败!RtuNo:%d 找不到混合量输出点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + retCmd.CtrlActType = cmd.CtrlActType; + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + } + } + LOGDEBUG("CModbusTcpV2DataProcThread::MoCmdProcess"); + return writex; +} + +/** + * @brief CModbusTcpV2DataProcThread::SettingCmdProcess + * 接收SCADA传来的Setting控制命令,组织ModbusTcpV2命令帧,并返回操作消息。 + * @param Data 发送数据区 + * @param dataSize 发送数据区长度 + * @return 实际发送数据长度 + */ +int CModbusTcpV2DataProcThread::SettingCmdProcess() +{ + return 0; +} + +/** + * @brief CModbusTcpV2DataProcThread::DefCmdProcess + * 接收SCADA传来的自定义控制命令,组织ModbusTcpV2命令帧,并返回操作消息。 + * @param Data 发送数据区 + * @param dataSize 发送数据区长度 + * @return 实际发送数据长度 + */ +int CModbusTcpV2DataProcThread::DefCmdProcess(byte *Data, int dataSize) +{ + SFesRxDefCmd cmd; + int writex; + + writex = 0; + if(m_ptrCFesRtu->ReadRxDefCmd(1,&cmd)==1) + { + //get the cmd ok,do something yourself +#if 0 + m_AppData.defCmd = cmd; + LOGDEBUG("TableName:%s ColumnName:%s TagName:%s RtuName:%s DevId:%d",cmd.TableName,cmd.ColumnName,cmd.TagName,cmd.RtuName,cmd.DevId); + int count = cmd.VecCmd.size(); + for(int k=0;km_Param.ModbusCmdBuf.pCmd==NULL) + { + return iotFailed; + } + //2020-05-14 thxiao 如果没有配置块,则轮训下一个设备。 + if (m_ptrCFesRtu->m_Param.ModbusCmdBuf.num == 0) + NextRtuIndex(m_ptrCFesChan); + + while(countm_Param.ModbusCmdBuf.num) + { + Cmd = m_ptrCFesRtu->m_Param.ModbusCmdBuf.pCmd+m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx; + if(Cmd->CommandSendFlag==true) + { + memcpy(pCmd, Cmd, sizeof(SModbusCmd)); + Cmd->CommandSendFlag = false; + ComFlag = true; + //LOGDEBUG("GetPollingCmd chan=%d readx=%d \n", m_ptrCFesRtu->m_Param.ChanNo, m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx); + } + m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx++; + if(m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx >= m_ptrCFesRtu->m_Param.ModbusCmdBuf.num) + m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx = 0; + count++; + if (ComFlag) + return iotSuccess; + + } + return iotFailed; +} + +/** + * @brief CModbusTcpV2DataProcThread::RecvDataProcess + * @param Data + * @param DataSize + * @return 成功:iotSuccess 失败:iotFailed + */ +int CModbusTcpV2DataProcThread::RecvDataProcess(byte *Data,int DataSize) +{ + int FunCode; + + FunCode=Data[1]; + if(FunCode&0x80) + { + CmdControlRespProcess(NULL,0,0); + return iotSuccess; + } + + switch(FunCode) + { + case 0x01: + case 0x02: + Cmd01RespProcessV2(Data); + break; + case 0x03: + case 0x04: + Cmd03RespProcessV2(Data); + CmdTypeHybridProcessV2(Data, DataSize); + break; + case 0x05: + Cmd05RespProcess(Data,DataSize); + break; + case 0x06: + Cmd06RespProcess(Data,DataSize); + break; + case 0x10: + Cmd10RespProcess(Data,DataSize); + break; + default: + return iotFailed; + break; + } + return iotSuccess; +} + +/** +* @brief CModbusTcpV2DataProcThread::Cmd01RespProcessV2 +* 命令0x01 0x02的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* @param Data 接收的数据 +*/ +void CModbusTcpV2DataProcThread::Cmd01RespProcessV2(byte *Data) +{ + int FunCode; + byte bitValue, byteValue; + int i, j, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, SoeCount, PointIndex1, PointIndex2; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[50]; + uint64 mSec; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + if (m_DiBlockDataIndexInfo.count(m_AppData.lastCmd.Index) == 0) + { + LOGDEBUG("Cmd01RespProcessV2: 未找到blockId=%d的数字量数据块,不解析该帧数据",m_AppData.lastCmd.Index); + return; + } + StartPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.Index).headIndex; + EndPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.Index).tailIndex; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + for (i = StartPointNo; i <= EndPointNo; i++) + { + pDi = GetFesDiByPIndex(m_ptrCFesRtu, i); + if (pDi == NULL) + continue; + + PointIndex1 = (pDi->Param3 - m_AppData.lastCmd.StartAddr)/8; + //2022-11-24 增加判断,防止数组过界。 + if ((PointIndex1 < 0) || (PointIndex1 > MODBUSTCPV2_K_MAX_POINT_INDEX*1.5)) + { + continue; + } + + byteValue = Data[3 + PointIndex1]; + PointIndex2 = (pDi->Param3 - m_AppData.lastCmd.StartAddr) % 8; + bitValue = (byteValue >> PointIndex2) & 0x01; + + if (pDi->Revers) + bitValue ^= 1; + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + StartPointNo = pDi->Param1 + 1; + if ((bitValue != pDi->Value) && (g_ModbusTcpV2IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + //更新点值 + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } +} + + +/** +* @brief CModbusTcpV2DataProcThread::Cmd03RespProcess +* 命令0x03 0x04的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusTcpV2DataProcThread::Cmd03RespProcessV2(byte *Data) +{ + int FunCode, diValue, bitValue; + int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, SoeCount, PointIndex; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[100]; + uint64 mSec; + SFesAi *pAi; + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + SFesMi *pMi; + SFesRtuMiValue MiValue[100]; + SFesChgMi ChgMi[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + int64 accValue; + int miValue; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + if ((m_AppData.lastCmd.Type == DI_UWord_HL) || (m_AppData.lastCmd.Type == DI_UWord_LH))//DI + { + if (m_DiBlockDataIndexInfo.count(m_AppData.lastCmd.Index) == 0) + { + LOGDEBUG("Cmd03RespProcessV2: 未找到blockId=%d的数字量数据块,不解析该帧数据", m_AppData.lastCmd.Index); + return; + } + StartPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.Index).headIndex; + EndPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.Index).tailIndex; + for (i = StartPointNo; i<=EndPointNo; i++) + { + pDi = GetFesDiByPIndex(m_ptrCFesRtu, i); + if (pDi == NULL) + continue; + + PointIndex = pDi->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-24 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV2_K_MAX_POINT_INDEX)) + { + continue; + } + + if (m_AppData.lastCmd.Type == DI_UWord_HL) + { + diValue = (int)Data[3 + PointIndex * 2] << 8; + diValue |= (int)Data[4 + PointIndex * 2]; + } + else//DI_UWord_LH + { + diValue = (int)Data[4 + PointIndex * 2] << 8; + diValue |= (int)Data[3 + PointIndex * 2]; + } + + if (m_AppData.lastCmd.Param1 == 1) //数据块自定义#1 = 1,遥信按位组合 + { + bitValue = Cmd03RespProcess_BitGroup(pDi, diValue); + + if ((bitValue != pDi->Value) && (g_ModbusTcpV2IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + else + { + bitValue = (diValue >> (pDi->Param4)) & 0x01; + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + if (pDi->Revers) + bitValue ^= 1; + if ((bitValue != pDi->Value) && (g_ModbusTcpV2IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } + } + else + if (((m_AppData.lastCmd.Type >= AI_Word_HL) && (m_AppData.lastCmd.Type <= AI_Float_LL)) || (m_AppData.lastCmd.Type == AI_SIGNEDFLAG16_HL) || (m_AppData.lastCmd.Type == AI_SIGNEDFLAG32_HL))//AI + { + if (m_AiBlockDataIndexInfo.count(m_AppData.lastCmd.Index) == 0) + { + LOGDEBUG("Cmd03RespProcessV2: 未找到blockId=%d的模拟量数据块,不解析该帧数据", m_AppData.lastCmd.Index); + return; + } + StartPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.Index).headIndex; + EndPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.Index).tailIndex; + ValueCount = 0; + ChgCount = 0; + if (((m_AppData.lastCmd.Type >= AI_Word_HL) && (m_AppData.lastCmd.Type <= AI_UWord_LH)) || (m_AppData.lastCmd.Type == AI_SIGNEDFLAG16_HL))//AI 16bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + PointIndex = pAi->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-24 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case AI_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + aiValue = uValue16; + break; + case AI_SIGNEDFLAG16_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + if (uValue16 & 0x8000) + { + aiValue = (float)(uValue16 & 0x7fff); + aiValue = 0 - aiValue; + } + else + aiValue = (float)(uValue16 & 0x7fff); + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + aiValue = uValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + else//AI 32bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + PointIndex = (pAi->Param3 - m_AppData.lastCmd.StartAddr)/2; + //2022-11-24 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case AI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_SIGNEDFLAG32_HL: + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + if (uValue32 & 0x80000000) + { + aiValue = (float)(uValue32 & 0x7fffffff); + aiValue = 0 - aiValue; + } + else + aiValue = (float)(uValue32 & 0x7fffffff); + break; + } + + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + + ValueCount++; + + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + if (ValueCount>0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount>0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + else + if ((m_AppData.lastCmd.Type >= ACC_Word_HL) && (m_AppData.lastCmd.Type <= ACC_Float_LL))//ACC + { + if (m_AccBlockDataIndexInfo.count(m_AppData.lastCmd.Index) == 0) + { + LOGDEBUG("Cmd03RespProcessV2: 未找到blockId=%d的累积量数据块,不解析该帧数据", m_AppData.lastCmd.Index); + return; + } + StartPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.Index).headIndex; + EndPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.Index).tailIndex; + ValueCount = 0; + ChgCount = 0; + if ((m_AppData.lastCmd.Type >= ACC_Word_HL) && (m_AppData.lastCmd.Type <= ACC_UWord_LH))//ACC 16bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + PointIndex = pAcc->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-24 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case ACC_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + accValue = sValue16; + break; + case ACC_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + accValue = sValue16; + break; + case ACC_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + accValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + accValue = uValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + else//ACC 32bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + PointIndex = (pAcc->Param3 - m_AppData.lastCmd.StartAddr)/2; + //2022-11-24 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case ACC_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + break; + case ACC_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + break; + case ACC_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + if (ValueCount>0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount>0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + else + if ((m_AppData.lastCmd.Type >= MI_Word_HL) && (m_AppData.lastCmd.Type <= MI_UDWord_LL))//MI + { + if (m_MiBlockDataIndexInfo.count(m_AppData.lastCmd.Index) == 0) + { + LOGDEBUG("Cmd03RespProcessV2: 未找到blockId=%d的混合量数据块,不解析该帧数据", m_AppData.lastCmd.Index); + return; + } + StartPointNo = m_MiBlockDataIndexInfo.at(m_AppData.lastCmd.Index).headIndex; + EndPointNo = m_MiBlockDataIndexInfo.at(m_AppData.lastCmd.Index).tailIndex; + ValueCount = 0; + ChgCount = 0; + if ((m_AppData.lastCmd.Type >= MI_Word_HL) && (m_AppData.lastCmd.Type <= MI_UWord_LH))//MI 16bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pMi = GetFesMiByPIndex(m_ptrCFesRtu, i); + if (pMi == NULL) + continue; + + //2022-12-20 thxiao Cmd03RespProcess() Mi取点值应该为PointIndex + PointIndex = pMi->Param3 - m_AppData.lastCmd.StartAddr; + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV2_K_MAX_POINT_INDEX)) + { + continue; + } + switch (m_AppData.lastCmd.Type) + { + case MI_Word_HL: + sValue16 = (short)Data[3 + i * 2] << 8; + sValue16 |= (short)Data[4 + i * 2]; + miValue = sValue16; + break; + case MI_Word_LH: + sValue16 = (short)Data[4 + i * 2] << 8; + sValue16 |= (short)Data[3 + i * 2]; + miValue = sValue16; + break; + case MI_UWord_HL: + uValue16 = (uint16)Data[3 + i * 2] << 8; + uValue16 |= (uint16)Data[4 + i * 2]; + miValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + i * 2] << 8; + uValue16 |= (uint16)Data[3 + i * 2]; + miValue = uValue16; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + else//Mi 32bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pMi = GetFesMiByPIndex(m_ptrCFesRtu, i); + if (pMi == NULL) + continue; + + //2022-12-20 thxiao Cmd03RespProcess() Mi取点值应该为PointIndex + PointIndex = (pMi->Param3 - m_AppData.lastCmd.StartAddr) / 2; + //2022-11-24 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case MI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + miValue = uValue32; + break; + case MI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + miValue = uValue32; + break; + case MI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + miValue = uValue32; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + if (ValueCount>0) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount>0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } +} + + +/** + * @brief CModbusTcpV2DataProcThread::Cmd05RespProcess + * 命令0x05的处理。 + * @param Data 接收的数据 + * @param DataSize 接收的数据长度 + */ +void CModbusTcpV2DataProcThread::Cmd05RespProcess(byte *Data,int DataSize) +{ + CmdControlRespProcess(Data,DataSize,1); +} + +/** + * @brief CModbusTcpV2DataProcThread::Cmd06RespProcess + * 命令0x06的处理。 + * @param Data 接收的数据 + * @param DataSize 接收的数据长度 + */ +void CModbusTcpV2DataProcThread::Cmd06RespProcess(byte *Data,int DataSize) +{ + CmdControlRespProcess(Data,DataSize,1); +} + +/** + * @brief CModbusTcpV2DataProcThread::Cmd10RespProcess + * 命令0x10的处理。 + * @param Data 接收的数据 + * @param DataSize 接收的数据长度 + */ +void CModbusTcpV2DataProcThread::Cmd10RespProcess(byte *Data,int DataSize) +{ + CmdControlRespProcess(Data,DataSize,1); +} + +void CModbusTcpV2DataProcThread::CmdTypeHybridProcessV2(byte *Data, int DataSize) +{ + int FunCode; + int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, PointIndex; + uint64 mSec; + SFesAi *pAi; + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + int64 accValue; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + if (m_AppData.lastCmd.Type == AI_Hybrid_Type)//AI 模拟量混合量帧 + { + if (m_AiBlockDataIndexInfo.count(m_AppData.lastCmd.Index) == 0) + { + LOGDEBUG("CmdTypeHybridProcessV2: 未找到blockId=%d的模拟量混合量数据块,不解析该帧数据", m_AppData.lastCmd.Index); + return; + } + StartPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.Index).headIndex; + EndPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.Index).tailIndex; + ValueCount = 0; + ChgCount = 0; + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + PointIndex = pAi->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-24 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (pAi->Param4) + { + case AI_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)Data[4 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[3 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + aiValue = uValue16; + break; + case AI_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + aiValue = (float)uValue16; + break; + case AI_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 2] << 24; + sValue32 |= (int)Data[4 + PointIndex * 2] << 16; + sValue32 |= (int)Data[5 + PointIndex * 2] << 8; + sValue32 |= (int)Data[6 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 2] << 24; + sValue32 |= (int)Data[6 + PointIndex * 2] << 16; + sValue32 |= (int)Data[3 + PointIndex * 2] << 8; + sValue32 |= (int)Data[4 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 2] << 24; + sValue32 |= (int)Data[5 + PointIndex * 2] << 16; + sValue32 |= (int)Data[4 + PointIndex * 2] << 8; + sValue32 |= (int)Data[3 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case AI_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + default: + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + else if (m_AppData.lastCmd.Type == ACC_Hybrid_Type)//ACC 累积量混合量帧 + { + if (m_AccBlockDataIndexInfo.count(m_AppData.lastCmd.Index) == 0) + { + LOGDEBUG("CmdTypeHybridProcessV2: 未找到blockId=%d的累积量混合量数据块,不解析该帧数据", m_AppData.lastCmd.Index); + return; + } + StartPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.Index).headIndex; + EndPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.Index).tailIndex; + ValueCount = 0; + ChgCount = 0; + + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + PointIndex = pAcc->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-24 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV2_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (pAcc->Param4) + { + case ACC_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + accValue = (int64)sValue16; + break; + case ACC_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)Data[4 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[3 + PointIndex * 2]; + accValue = (int64)sValue16; + break; + case ACC_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + accValue = (int64)uValue16; + break; + case ACC_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + accValue = (int64)uValue16; + break; + case ACC_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 2] << 24; + sValue32 |= (int)Data[4 + PointIndex * 2] << 16; + sValue32 |= (int)Data[5 + PointIndex * 2] << 8; + sValue32 |= (int)Data[6 + PointIndex * 2]; + accValue = (int64)sValue32; + break; + case ACC_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 2] << 24; + sValue32 |= (int)Data[6 + PointIndex * 2] << 16; + sValue32 |= (int)Data[3 + PointIndex * 2] << 8; + sValue32 |= (int)Data[4 + PointIndex * 2]; + accValue = (int64)sValue32; + break; + case ACC_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 2] << 24; + sValue32 |= (int)Data[5 + PointIndex * 2] << 16; + sValue32 |= (int)Data[4 + PointIndex * 2] << 8; + sValue32 |= (int)Data[3 + PointIndex * 2]; + accValue = (int64)sValue32; + break; + case ACC_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + accValue = (int64)uValue32; + break; + case ACC_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + accValue = (int64)uValue32; + break; + case ACC_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + accValue = (int64)uValue32; + break; + case ACC_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = (int64)fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + break; + case ACC_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = (int64)fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + break; + case ACC_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = (int64)fValue*1000;//2022-10-17 thxiao 电度量ACC当采集为FLOAT时,会丢失小数位,固定扩大1000倍 + break; + default: + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + accValue = (int64)sValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV2IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } +} + + +/** + * @brief CModbusTcpV2DataProcThread::CmdControlRespProcess + * @param Data 接收的数据 + * @param DataSize 接收的数据长度 + * @param okFlag 命令成功标志 1:成功 0:失败 + * @return 是控制命令返回:TRUE 否则为:FALSE + */ +bool CModbusTcpV2DataProcThread::CmdControlRespProcess(byte *Data,int DataSize,int okFlag) +{ + SFesTxDoCmd retDoCmd; + SFesTxAoCmd retAoCmd; + SFesTxMoCmd retMoCmd; + SFesTxDefCmd retDefCmd; + + if(m_AppData.state != CN_ModbusTcpV2AppState_waitControlResp) + return false; + + switch (m_AppData.lastCotrolcmd) + { + case CN_ModbusTcpV2DoCmd: + //memset(&retDoCmd,0,sizeof(retDoCmd)); + if(okFlag) + { + retDoCmd.retStatus = CN_ControlSuccess; + sprintf(retDoCmd.strParam,I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + LOGINFO("遥控成功!RtuNo:%d 遥控点:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + } + else + { + retDoCmd.retStatus = CN_ControlFailed; + sprintf(retDoCmd.strParam,I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + } + strcpy(retDoCmd.TableName,m_AppData.doCmd.TableName); + strcpy(retDoCmd.ColumnName,m_AppData.doCmd.ColumnName); + strcpy(retDoCmd.TagName,m_AppData.doCmd.TagName); + strcpy(retDoCmd.RtuName,m_AppData.doCmd.RtuName); + retDoCmd.CtrlActType = m_AppData.doCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retDoCmd.CtrlDir = m_AppData.doCmd.CtrlDir; + retDoCmd.RtuNo = m_AppData.doCmd.RtuNo; + retDoCmd.PointID = m_AppData.doCmd.PointID; + retDoCmd.FwSubSystem = m_AppData.doCmd.FwSubSystem; + retDoCmd.FwRtuNo = m_AppData.doCmd.FwRtuNo; + retDoCmd.FwPointNo = m_AppData.doCmd.FwPointNo; + retDoCmd.SubSystem = m_AppData.doCmd.SubSystem; + + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retDoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1,&retDoCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + return true; + break; + case CN_ModbusTcpV2AoCmd: + if(okFlag) + { + retAoCmd.retStatus = CN_ControlSuccess; + sprintf(retAoCmd.strParam,I18N("遥调成功!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); + LOGINFO("遥调成功!RtuNo:%d 遥调点:%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + } + else + { + retAoCmd.retStatus = CN_ControlFailed; + sprintf(retAoCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); + LOGINFO("遥调失败!RtuNo:%d 遥调点:%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + } + strcpy(retAoCmd.TableName,m_AppData.aoCmd.TableName); + strcpy(retAoCmd.ColumnName,m_AppData.aoCmd.ColumnName); + strcpy(retAoCmd.TagName,m_AppData.aoCmd.TagName); + strcpy(retAoCmd.RtuName,m_AppData.aoCmd.RtuName); + retAoCmd.CtrlActType = m_AppData.aoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retAoCmd.CtrlDir = m_AppData.aoCmd.CtrlDir; + retAoCmd.RtuNo = m_AppData.aoCmd.RtuNo; + retAoCmd.PointID = m_AppData.aoCmd.PointID; + retAoCmd.FwSubSystem = m_AppData.aoCmd.FwSubSystem; + retAoCmd.FwRtuNo = m_AppData.aoCmd.FwRtuNo; + retAoCmd.FwPointNo = m_AppData.aoCmd.FwPointNo; + retAoCmd.SubSystem = m_AppData.aoCmd.SubSystem; + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retAoCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + return true; + break; + case CN_ModbusTcpV2MoCmd: + if(okFlag) + { + retMoCmd.retStatus = CN_ControlSuccess; + sprintf(retMoCmd.strParam,I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.moCmd.PointID); + LOGINFO("混合量输出成功!RtuNo:%d 混合量输出点:%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + } + else + { + retMoCmd.retStatus = CN_ControlFailed; + sprintf(retMoCmd.strParam,I18N("混合量输出失败!RtuNo:%d 混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.moCmd.PointID); + LOGINFO("混合量输出失败!RtuNo:%d 混合量输出点:%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + } + strcpy(retMoCmd.TableName,m_AppData.moCmd.TableName); + strcpy(retMoCmd.ColumnName,m_AppData.moCmd.ColumnName); + strcpy(retMoCmd.TagName,m_AppData.moCmd.TagName); + strcpy(retMoCmd.RtuName,m_AppData.moCmd.RtuName); + retMoCmd.CtrlActType = m_AppData.moCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retMoCmd.CtrlDir = m_AppData.moCmd.CtrlDir; + retMoCmd.RtuNo = m_AppData.moCmd.RtuNo; + retMoCmd.PointID = m_AppData.moCmd.PointID; + retMoCmd.FwSubSystem = m_AppData.moCmd.FwSubSystem; + retMoCmd.FwRtuNo = m_AppData.moCmd.FwRtuNo; + retMoCmd.FwPointNo = m_AppData.moCmd.FwPointNo; + retMoCmd.SubSystem = m_AppData.moCmd.SubSystem; + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&retMoCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + return true; + break; + case CN_ModbusTcpV2DefCmd: + if(okFlag) + { + retDefCmd.retStatus = CN_ControlSuccess; + sprintf(retDefCmd.strParam,I18N("自定义命令输出成功!RtuNo:%d ").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo); + LOGINFO("自定义命令输出成功!RtuNo:%d", m_ptrCFesRtu->m_Param.RtuNo); + } + else + { + retDefCmd.retStatus = CN_ControlFailed; + sprintf(retDefCmd.strParam,I18N("自定义命令输出失败!RtuNo:%d ").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo); + LOGINFO("自定义命令输出失败!RtuNo:%d", m_ptrCFesRtu->m_Param.RtuNo); + } + strcpy(retDefCmd.TableName,m_AppData.defCmd.TableName); + strcpy(retDefCmd.ColumnName,m_AppData.defCmd.ColumnName); + strcpy(retDefCmd.TagName,m_AppData.defCmd.TagName); + strcpy(retDefCmd.RtuName,m_AppData.defCmd.RtuName); + retDefCmd.DevId = m_AppData.defCmd.DevId; + retDefCmd.CmdNum = m_AppData.defCmd.CmdNum; + retDefCmd.VecCmd = m_AppData.defCmd.VecCmd; + m_ptrCFesRtu->WriteTxDefCmdBuf(1,&retDefCmd); + m_AppData.lastCotrolcmd = CN_ModbusTcpV2NoCmd; + m_AppData.state = CN_ModbusTcpV2AppState_idle; + return true; + break; + default: + break; + } + return false; +} +/** + * @brief CModbusTcpV2DataProcThread::ErrorControlRespProcess + * @param + * @param + * @param 网络令来需要做异常处理断开时有控制命 + * @return + */ +void CModbusTcpV2DataProcThread::ErrorControlRespProcess() +{ + SFesRxDoCmd RxDoCmd; + SFesTxDoCmd TxDoCmd; + SFesRxAoCmd RxAoCmd; + SFesTxAoCmd TxAoCmd; + SFesRxMoCmd RxMoCmd; + SFesTxMoCmd TxMoCmd; + SFesRxDefCmd RxDefCmd; + SFesTxDefCmd TxDefCmd; + + if(m_ptrCFesRtu == NULL) + return ; + + if(g_ModbusTcpV2IsMainFes==false)//备机不作任何操作 + return ; + + if(m_ptrCFesRtu->GetRxDoCmdNum()>0) + { + if(m_ptrCFesRtu->ReadRxDoCmd(1,&RxDoCmd)==1) + { + //memset(&TxDoCmd,0,sizeof(TxDoCmd)); + + strcpy(TxDoCmd.TableName,RxDoCmd.TableName); + strcpy(TxDoCmd.ColumnName,RxDoCmd.ColumnName); + strcpy(TxDoCmd.TagName,RxDoCmd.TagName); + strcpy(TxDoCmd.RtuName,RxDoCmd.RtuName); + TxDoCmd.retStatus = CN_ControlFailed; + TxDoCmd.CtrlActType = RxDoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxDoCmd.CtrlDir = RxDoCmd.CtrlDir; + TxDoCmd.RtuNo = RxDoCmd.RtuNo; + TxDoCmd.PointID = RxDoCmd.PointID; + TxDoCmd.FwSubSystem = RxDoCmd.FwSubSystem; + TxDoCmd.FwRtuNo = RxDoCmd.FwRtuNo; + TxDoCmd.FwPointNo = RxDoCmd.FwPointNo; + TxDoCmd.SubSystem = RxDoCmd.SubSystem; + sprintf(TxDoCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxDoCmd.PointID); + LOGDEBUG ("网络已断开 DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",RxDoCmd.CtrlActType,RxDoCmd.iValue,RxDoCmd.RtuName,RxDoCmd.PointID); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&TxDoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1,&TxDoCmd); + + } + + } + else + if(m_ptrCFesRtu->GetRxAoCmdNum()>0) + { + if(m_ptrCFesRtu->ReadRxAoCmd(1,&RxAoCmd)==1) + { + //memset(&TxAoCmd,0,sizeof(TxAoCmd)); + strcpy(TxAoCmd.TableName,RxAoCmd.TableName); + strcpy(TxAoCmd.ColumnName,RxAoCmd.ColumnName); + strcpy(TxAoCmd.TagName,RxAoCmd.TagName); + strcpy(TxAoCmd.RtuName,RxAoCmd.RtuName); + TxAoCmd.retStatus = CN_ControlFailed; + sprintf(TxAoCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,RxAoCmd.PointID); + TxAoCmd.CtrlActType = RxAoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxAoCmd.CtrlDir = RxAoCmd.CtrlDir; + TxAoCmd.RtuNo = RxAoCmd.RtuNo; + TxAoCmd.PointID = RxAoCmd.PointID; + TxAoCmd.FwSubSystem = RxAoCmd.FwSubSystem; + TxAoCmd.FwRtuNo = RxAoCmd.FwRtuNo; + TxAoCmd.FwPointNo = RxAoCmd.FwPointNo; + TxAoCmd.SubSystem = RxAoCmd.SubSystem; + LOGDEBUG("网络已断开 AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", RxAoCmd.CtrlActType, RxAoCmd.fValue, RxAoCmd.RtuName, RxAoCmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&TxAoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&TxAoCmd); + } + } + else + if(m_ptrCFesRtu->GetRxMoCmdNum()>0) + { + if(m_ptrCFesRtu->ReadRxMoCmd(1,&RxMoCmd)==1) + { + //memset(&TxMoCmd,0,sizeof(TxMoCmd)); + strcpy(TxMoCmd.TableName,RxMoCmd.TableName); + strcpy(TxMoCmd.ColumnName,RxMoCmd.ColumnName); + strcpy(TxMoCmd.TagName,RxMoCmd.TagName); + strcpy(TxMoCmd.RtuName,RxMoCmd.RtuName); + TxMoCmd.retStatus = CN_ControlFailed; + TxMoCmd.CtrlActType = RxMoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxMoCmd.CtrlDir = RxMoCmd.CtrlDir; + TxMoCmd.RtuNo = RxMoCmd.RtuNo; + TxMoCmd.PointID = RxMoCmd.PointID; + TxMoCmd.FwSubSystem = RxMoCmd.FwSubSystem; + TxMoCmd.FwRtuNo = RxMoCmd.FwRtuNo; + TxMoCmd.FwPointNo = RxMoCmd.FwPointNo; + TxMoCmd.SubSystem = RxMoCmd.SubSystem; + sprintf(TxMoCmd.strParam, I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxMoCmd.PointID); + + LOGDEBUG ("网络已断开 MO混合量执行失败 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",RxMoCmd.CtrlActType,RxMoCmd.iValue,RxMoCmd.RtuName,RxMoCmd.PointID); + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&TxMoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&TxMoCmd); + } + } + else + if(m_ptrCFesRtu->GetRxDefCmdNum()>0) + { + if(m_ptrCFesRtu->ReadRxDefCmd(1,&RxDefCmd)==1) + { + //memset(&TxDefCmd,0,sizeof(TxDefCmd)); + strcpy(TxDefCmd.TableName,RxDefCmd.TableName); + strcpy(TxDefCmd.ColumnName,RxDefCmd.ColumnName); + strcpy(TxDefCmd.TagName,RxDefCmd.TagName); + strcpy(TxDefCmd.RtuName,RxDefCmd.RtuName); + TxDefCmd.DevId = RxDefCmd.DevId; + TxDefCmd.CmdNum = RxDefCmd.CmdNum; + TxDefCmd.VecCmd = RxDefCmd.VecCmd; + TxDefCmd.retStatus = CN_ControlFailed; + sprintf(TxDefCmd.strParam,I18N("自定义命令输出失败!RtuNo:%d ").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo); + LOGERROR("网络已断开 自定义命令输出失败!RtuNo:%d",m_ptrCFesRtu->m_Param.RtuNo); + m_ptrCFesRtu->WriteTxDefCmdBuf(1,&TxDefCmd); + } + } +} + +/* +2019-08-30 按原有的方式,时间间隔最大为100MS,过大,所以改为程序内部处理 +*/ +void CModbusTcpV2DataProcThread::SetSendCmdFlag() +{ + SModbusCmd *pCmd; + CFesRtuPtr ptrFesRtu; + int i,j, RtuNo; + int64 lTime,tempTime; + + if (m_AppData.setCmdCount++ > 2) + { + m_AppData.setCmdCount = 0; + lTime = getUTCTimeMsec(); //MS + for (i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((ptrFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) + continue; + for (j = 0; j < ptrFesRtu->m_Param.ModbusCmdBuf.num; j++) + { + pCmd = ptrFesRtu->m_Param.ModbusCmdBuf.pCmd + j; + tempTime = lTime - pCmd->lastPollTime; + if (tempTime > pCmd->PollTime) + { + pCmd->CommandSendFlag = true; + pCmd->lastPollTime = lTime; + //LOGDEBUG("cmd=%d PollTime=%d CommandSendFlag=true", j, pCmd->PollTime); + } + else + if (tempTime <= 0)//避免时间错的情况发生 + { + pCmd->lastPollTime = lTime; + } + } + } + } +} + + +/** +* @brief CModbusTcpV2DataProcThread::Cmd03RespProcess_BitGroup +* 按位组合的遥信解析处理 +* @param Data 遥信点结构 +* @param DataSize 遥信字节值 +*/ +int CModbusTcpV2DataProcThread::Cmd03RespProcess_BitGroup(SFesDi *pDi, int diValue) +{ + int temp1 = pDi->Param5; + int IntData = diValue & temp1; + int i, YxBit = 0; + + if (temp1 < 0) + return YxBit; + + for (i = 0; i < 16; i++) + { + if ((temp1 >> i) & 0x01) + { + IntData >>= i; + break; + } + } + + if (pDi->Param4 == IntData) + YxBit = 1; + + return YxBit; +} + +void CModbusTcpV2DataProcThread::ClearClientThread() +{ + m_ClearClientFlag = 1; +} + + +void CModbusTcpV2DataProcThread::SetClientThread(CTcpClientThreadPtr ptrClientThread) +{ + if(ptrClientThread==NULL) + { + LOGDEBUG("CModbusTcpV2DataProcThread::SetClientThread ptrClientThread is NULL"); + } + else + { + LOGDEBUG("CModbusTcpV2DataProcThread::SetClientThread ptrClientThread is OK"); + } + + m_ptrClientThread = ptrClientThread; + m_ClearClientFlag = 0; +} + +//2021-06-25 ljj +/** +* @brief CModbusTcpV2DataProcThread::InitProtocolBlockDataIndexMapping +* 数据块关联数据索引表初始化 +* @param RtuPtr +* @return +*/ +void CModbusTcpV2DataProcThread::InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuPtr) +{ + int i, j; + int blockId, funCode, startAddr, dataLen; + SModbusCmd *pCmd; + SModbusCmdBuf cmd = RtuPtr->m_Param.ModbusCmdBuf; + SFesAiIndex *pAiIndex; + SFesDiIndex *pDiIndex; + SFesAccIndex *pAccIndex; + SFesMiIndex *pMiIndex; + vector pAiBlockIndexs; + vector pDiBlockIndexs; + vector pAccBlockIndexs; + vector pMiBlockIndexs; + + //根据数据块帧类别进行分类 + for (i = 0; i < cmd.num; i++) + { + pCmd = cmd.pCmd + i; + blockId = pCmd->Index; + SFesBaseBlockDataIndexInfo blockDataIndexInfoTemp; + blockDataIndexInfoTemp.headIndex = 0xFFFFFFFF; + blockDataIndexInfoTemp.tailIndex = 0xFFFFFFFF; + LOGDEBUG("pCmd->Type:%d", pCmd->Type); + if ((pCmd->Type >= DI_BYTE_LH) && (pCmd->Type <= DI_UWord_LH)) //DI + { + pDiBlockIndexs.push_back(i); + m_DiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_DiBlockDataIndexInfo.insert blockId:%d", blockId); + } + else if (((pCmd->Type >= AI_Word_HL) && (pCmd->Type <= AI_Float_LL)) || (pCmd->Type == AI_SIGNEDFLAG16_HL) || (pCmd->Type == AI_SIGNEDFLAG32_HL) || (pCmd->Type == AI_Hybrid_Type)) //AI + { + pAiBlockIndexs.push_back(i); + m_AiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_AiBlockDataIndexInfo.insert blockId:%d", blockId); + } + else if (((pCmd->Type >= ACC_Word_HL) && (pCmd->Type <= ACC_Float_LL)) || (pCmd->Type == ACC_Hybrid_Type))//ACC + { + pAccBlockIndexs.push_back(i); + m_AccBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_AccBlockDataIndexInfo.insert blockId:%d", blockId); + } + else if ((pCmd->Type >= MI_Word_HL) && (pCmd->Type <= MI_UDWord_LL))//MI + { + pMiBlockIndexs.push_back(i); + m_MiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_MiBlockDataIndexInfo.insert blockId:%d", blockId); + } + + } + + //对不同帧类别的数据块存储起始索引和结束索引 + for (j = 0; j < RtuPtr->m_MaxAiIndex; j++) //Ai + { + pAiIndex = RtuPtr->m_pAiIndex + j; + + for (i = 0; i < pAiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pAiBlockIndexs.at(i); + + blockId = pCmd->Index; + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pAiIndex->Param2 == funCode) && (startAddr <= pAiIndex->Param3) && (pAiIndex->Param3 < (startAddr + dataLen))) + { + if ((m_AiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_AiBlockDataIndexInfo.at(blockId).headIndex = pAiIndex->PIndex; + + m_AiBlockDataIndexInfo.at(blockId).tailIndex = pAiIndex->PIndex; + } + } + } + + for (j = 0; j < RtuPtr->m_MaxDiIndex; j++) //Di + { + pDiIndex = RtuPtr->m_pDiIndex + j; + + for (i = 0; i < pDiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pDiBlockIndexs.at(i); + + blockId = pCmd->Index; + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pDiIndex->Param2 == funCode) && (startAddr <= pDiIndex->Param3) && (pDiIndex->Param3 < (startAddr + dataLen))) + { + if ((m_DiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_DiBlockDataIndexInfo.at(blockId).headIndex = pDiIndex->PIndex; + + m_DiBlockDataIndexInfo.at(blockId).tailIndex = pDiIndex->PIndex; + } + } + } + + for (j = 0; j < RtuPtr->m_MaxAccIndex; j++) //Acc + { + pAccIndex = RtuPtr->m_pAccIndex + j; + for (i = 0; i < pAccBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pAccBlockIndexs.at(i); + + blockId = pCmd->Index; + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pAccIndex->Param2 == funCode) && (startAddr <= pAccIndex->Param3) && (pAccIndex->Param3 < (startAddr + dataLen))) + { + if ((m_AccBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_AccBlockDataIndexInfo.at(blockId).headIndex = pAccIndex->PIndex; + + m_AccBlockDataIndexInfo.at(blockId).tailIndex = pAccIndex->PIndex; + } + } + } + + for (j = 0; j < RtuPtr->m_MaxMiIndex; j++) //Mi + { + pMiIndex = RtuPtr->m_pMiIndex + j; + + for (i = 0; i < pMiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pMiBlockIndexs.at(i); + + blockId = pCmd->Index; + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pMiIndex->Param2 == funCode) && (startAddr <= pMiIndex->Param3) && (pMiIndex->Param3 < (startAddr + dataLen))) + { + if ((m_MiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_MiBlockDataIndexInfo.at(blockId).headIndex = pMiIndex->PIndex; + + m_MiBlockDataIndexInfo.at(blockId).tailIndex = pMiIndex->PIndex; + } + } + } + + map::iterator iter; + iter = m_AiBlockDataIndexInfo.begin(); + while (iter != m_AiBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Ai--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + iter = m_DiBlockDataIndexInfo.begin(); + while (iter != m_DiBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Di--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + iter = m_AccBlockDataIndexInfo.begin(); + while (iter != m_AccBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Acc--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + iter = m_MiBlockDataIndexInfo.begin(); + while (iter != m_MiBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Mi--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } +} + diff --git a/product/src/fes/protocol/modbus_tcpV2/ModbusTcpV2DataProcThread.h b/product/src/fes/protocol/modbus_tcpV2/ModbusTcpV2DataProcThread.h new file mode 100644 index 00000000..909fb164 --- /dev/null +++ b/product/src/fes/protocol/modbus_tcpV2/ModbusTcpV2DataProcThread.h @@ -0,0 +1,126 @@ +/* + @file CModbusTcpV2DataProcThread.h + @brief ModbusTcpV2 数据处理线程类 + @author thxiao +*/ +#pragma once + +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "TcpClientThread.h" + +using namespace iot_public; + +#define CN_ModbusTcpV2_MAX_CMD_LEN 256 + +//define SModbusTcpV2AppData state +const int CN_ModbusTcpV2AppState_idle = 0; +const int CN_ModbusTcpV2AppState_waitControlResp = 1; + +//define SModbusTcpV2AppData lastCotrolcmd +const int CN_ModbusTcpV2NoCmd = 0; +const int CN_ModbusTcpV2DoCmd = 1; +const int CN_ModbusTcpV2AoCmd = 2; +const int CN_ModbusTcpV2MoCmd = 3; +const int CN_ModbusTcpV2DefCmd = 4; + +//增加的数据类型,之前的定义在FesDef.h +#define AI_SIGNEDFLAG16_HL 62 //模拟量帧(符号位(bit15)加数值 高字节前) +#define AI_SIGNEDFLAG32_HL 63 //模拟量帧(符号位(bit31)加数值 高字节前) + +#define MODBUSTCPV2_K_MAX_POINT_INDEX 200 //接收缓存最大索引 + +//ModbusTcpV2 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct{ + int index; + int state; + int comState; + int lastCotrolcmd; + byte lastCmdData[CN_ModbusTcpV2_MAX_CMD_LEN]; + int lastCmdDataLen; + SModbusCmd lastCmd; + SFesRxDoCmd doCmd; + SFesRxAoCmd aoCmd; + SFesRxMoCmd moCmd; + SFesRxDefCmd defCmd; + int setCmdCount; + int m_TransIDFailCount; //2022-04-22 thxiao +}SModbusTcpV2AppData; + +//2021-06-25 ljj +typedef struct { + uint32 headIndex; + uint32 tailIndex; +}SFesBaseBlockDataIndexInfo; //数据块关联数据索引信息 + +class CModbusTcpV2DataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + CModbusTcpV2DataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan); + virtual ~CModbusTcpV2DataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + /* + @brief 执行quit函数前的处理 + */ + virtual void beforeQuit(); + + void ClearClientThread(); + void SetClientThread(CTcpClientThreadPtr ptrClientThread); + + + CFesBase* m_ptrCFesBase; + + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,ModbusTcpV2 每个通道对应一个RTU数据,所以不需要轮询处理。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + int m_ClearClientFlag; + CTcpClientThreadPtr m_ptrClientThread; + + SModbusTcpV2AppData m_AppData; //内部应用数据结构 + + map m_AiBlockDataIndexInfo; //2021-06-25 ljj + map m_DiBlockDataIndexInfo; + map m_AccBlockDataIndexInfo; + map m_MiBlockDataIndexInfo; +private: + int SendProcess(); + int RecvNetData(); + int InsertCmdProcess(); + void ErrorControlRespProcess(); + int PollingCmdProcess(); + void FillHeader(byte *Data, int Size); + int SendDataToPort(byte *Data, int Size); + int DoCmdProcess(byte *Data, int dataSize); + int AoCmdProcess(byte *Data, int dataSize); + int MoCmdProcess(byte *Data, int dataSize); + int SettingCmdProcess(); + int DefCmdProcess(byte *Data, int dataSize); + int GetPollingCmd(SModbusCmd *pCmd); + int RecvDataProcess(byte *Data,int DataSize); + void Cmd05RespProcess(byte *Data,int DataSize); + void Cmd06RespProcess(byte *Data,int DataSize); + void Cmd10RespProcess(byte *Data,int DataSize); + bool CmdControlRespProcess(byte *Data,int DataSize,int okFlag); + void SetSendCmdFlag(); + int Cmd03RespProcess_BitGroup(SFesDi *pDi, int diValue); + + void InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuPtr); + void Cmd01RespProcessV2(byte *Data); + void Cmd03RespProcessV2(byte *Data); + void CmdTypeHybridProcessV2(byte *Data, int DataSize); + + + +}; + +typedef boost::shared_ptr CModbusTcpV2DataProcThreadPtr; + diff --git a/product/src/fes/protocol/modbus_tcpV2/modbus_tcpV2.pro b/product/src/fes/protocol/modbus_tcpV2/modbus_tcpV2.pro new file mode 100644 index 00000000..125df817 --- /dev/null +++ b/product/src/fes/protocol/modbus_tcpV2/modbus_tcpV2.pro @@ -0,0 +1,39 @@ +QT -= core gui +CONFIG -= qt + +TARGET = modbus_tcpV2 +TEMPLATE = lib + +SOURCES += \ + ModbusTcpV2.cpp \ + ModbusTcpV2DataProcThread.cpp \ + ../combase/TcpClientThread.cpp \ + +HEADERS += \ + ModbusTcpV2.h \ + ModbusTcpV2DataProcThread.h \ + ../../include/TcpClientThread.h \ + +INCLUDEPATH += \ + ../../include/ \ + ../../../include/ \ + ../../../3rd/include/ + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase +LIBS += -lprotobuf -lboost_locale -lboost_regex +LIBS += -lrdb_api + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + +DEFINES += PROTOCOLBASE_API_EXPORTS + + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/fes/protocol/modbus_tcpV3/ModbusTcpV3.cpp b/product/src/fes/protocol/modbus_tcpV3/ModbusTcpV3.cpp index bbe1798f..a4bca263 100644 --- a/product/src/fes/protocol/modbus_tcpV3/ModbusTcpV3.cpp +++ b/product/src/fes/protocol/modbus_tcpV3/ModbusTcpV3.cpp @@ -51,6 +51,8 @@ int EX_ChanTimer(int ChanNo) int EX_ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + g_ModbusTcpV3ChanelRun=false;//使所有的线程退出。 return iotSuccess; } @@ -82,7 +84,7 @@ int CModbusTcpV3::SetBaseAddr(void *address) int CModbusTcpV3::SetProperty(int IsMainFes) { - g_ModbusTcpV3IsMainFes = IsMainFes; + g_ModbusTcpV3IsMainFes = (IsMainFes != 0); return iotSuccess; } @@ -187,7 +189,8 @@ int CModbusTcpV3::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) */ int CModbusTcpV3::ChanTimer(int MainChanNo) { - + boost::ignore_unused_variable_warning(MainChanNo); + return iotSuccess; } @@ -283,7 +286,7 @@ void CModbusTcpV3::InitProcess() return; } - RtuCount = m_ptrCFesBase->m_vectCFesRtuPtr.size(); + RtuCount = static_cast(m_ptrCFesBase->m_vectCFesRtuPtr.size()); for (i = 0; i < RtuCount; i++) { if (m_ptrCFesBase->m_vectCFesRtuPtr[i]->m_Param.Used) @@ -359,7 +362,7 @@ bool CModbusTcpV3::InitPointMapping(CFesRtuPtr RtuPtr) LOGERROR("RdbAiTable::close error"); return iotFailed; } - count = VecAiParam.size(); + count = static_cast(VecAiParam.size()); if (count > 0) { //RtuPtr->m_MaxAiIndex = VecAiParam[count-1].Param1+1; @@ -436,7 +439,7 @@ bool CModbusTcpV3::InitPointMapping(CFesRtuPtr RtuPtr) LOGERROR("RdbDiTable::close error"); return iotFailed; } - count = VecDiParam.size(); + count = static_cast(VecDiParam.size()); if (count > 0) { RtuPtr->m_MaxDiIndex = count; @@ -510,7 +513,7 @@ bool CModbusTcpV3::InitPointMapping(CFesRtuPtr RtuPtr) return iotFailed; } - count = VecAccParam.size(); + count = static_cast(VecAccParam.size()); if (count > 0) { //RtuPtr->m_MaxAccIndex = VecAccParam[count-1].Param1+1; @@ -584,7 +587,7 @@ bool CModbusTcpV3::InitPointMapping(CFesRtuPtr RtuPtr) LOGERROR("RdbMiTable::close error"); return iotFailed; } - count = VecMiParam.size(); + count = static_cast(VecMiParam.size()); if (count > 0) { //RtuPtr->m_MaxMiIndex = VecMiParam[count-1].Param1+1; diff --git a/product/src/fes/protocol/modbus_tcpV3/ModbusTcpV3DataProcThread.cpp b/product/src/fes/protocol/modbus_tcpV3/ModbusTcpV3DataProcThread.cpp index b6e581bc..fa558f1d 100644 --- a/product/src/fes/protocol/modbus_tcpV3/ModbusTcpV3DataProcThread.cpp +++ b/product/src/fes/protocol/modbus_tcpV3/ModbusTcpV3DataProcThread.cpp @@ -15,17 +15,6 @@ 1、InitProtocolBlockDataIndexMapping()数据块关联数据索引赋值错误 2、Cmd01RespProcess(),Cmd03RespProcess(),CmdTypeHybridProcess() PointIndex增加判断,防止数组过界. 2022-12-20 thxiao Cmd03RespProcess() Mi取点值应该为PointIndex -2023-03-25 thxiao - 1、之前的版本只支持一个通道多个RTU数据的查询,但是控制命令的处理有问题,现已完善。 - 2、m_clientTransID改为通道的全局变量。 - 3、AO处理时,当下发的值为浮点值,除系数容易产生精度问题,所以改为乘系数;同时增加了多种设置数据类型 - 4、m_ptrCFesRtu当前轮询到的RTU;m_ptrCInsertFesRtu插入命令的RTU,数据处理完成后置为NULL。 - 程序编写还有不足,函数的入参应带上RTU的指针,这样程序层次更清晰由于改动太大,暂不修改。 -2023-04-12 thxiao - 1、多RTU时就会发生地址或功能码不正确的情况,也需要强制关闭SOCKET -2023-04-21 thxiao - 1、中航光电R80作为网关,支持两个客户端总是会产生误报,R80所有的判断已使用但还是出问题。 - RTU ResParam3=1(遥信可靠判断):DI数据需要收到两次为相同值,数据才能更新。 */ #include "ModbusTcpV3DataProcThread.h" @@ -49,11 +38,10 @@ CModbusTcpV3DataProcThread::CModbusTcpV3DataProcThread(CFesBase *ptrCFesBase,CF m_ptrCurrentChan = ptrCFesChan; -// m_AppData.comState = CN_FesRtuComDown; + m_AppData.comState = CN_FesRtuComDown; m_AppData.setCmdCount = 0; m_ClearClientFlag = 0; m_AppData.m_TransIDFailCount = 0;//2022-05-09 thxiao m_AppData.m_TransIDFailCount 需要初始化 - m_AppData.m_clientTransID = 0; //2020-02-24 thxiao 创建时设置ThreadRun标识。 m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); @@ -75,7 +63,6 @@ CModbusTcpV3DataProcThread::CModbusTcpV3DataProcThread(CFesBase *ptrCFesBase,CF pRtu->SetOfflineFlag(CN_FesRtuComDown); } } - CheckRTUCmdNum(); /*************************** TCP PROCESS *****************************************************/ m_timerCountReset = 2000 / g_ModbusTcpV3ThreadTime; //2S COUNTER @@ -214,7 +201,7 @@ int CModbusTcpV3DataProcThread::RecvNetData() int count =20; int FunCode,DevAddr,ExpectLen; byte Data[512]; - int recvLen,Len,i,recvFailed; + int recvLen,Len,i; if(m_ptrCurrentChan==NULL) return iotFailed; @@ -271,47 +258,30 @@ int CModbusTcpV3DataProcThread::RecvNetData() } } } - /*if((Len>=ExpectLen)&&(ExpectLen>0)) + if((Len>=ExpectLen)&&(ExpectLen>0)) { - break; - }*/ + break; + } } if(Len>0) ShowChanData(m_ptrCurrentChan->m_Param.ChanNo,Data,Len,CN_SFesSimComFrameTypeRecv); if(Len==0)//接收不完整,重发数据 { - if (m_ptrCInsertFesRtu != NULL) //InsertCmd - { - m_ptrCInsertFesRtu->SetResendNum(1); - if (m_ptrCInsertFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) - { - m_ptrCInsertFesRtu->ResetResendNum(); //改为RTU下的resendNum - if (m_ptrCInsertFesRtu->ReadRtuSatus() == CN_FesRtuNormal) - { - m_ptrCFesBase->WriteRtuSatus(m_ptrCInsertFesRtu, CN_FesRtuComDown); - m_ptrCInsertFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); - } - m_ptrCFesBase->SetOfflineFlag(m_ptrCInsertFesRtu, CN_FesRtuComDown); - } - CmdControlRespProcess(NULL, 0, 0); - m_ptrCInsertFesRtu = NULL; - } - else //PollCmd - { - m_ptrCFesRtu->SetResendNum(1); - if (m_ptrCFesRtu->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) - { - m_ptrCFesRtu->ResetResendNum(); - if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuNormal) - { - m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); - m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); - } - m_ptrTcpClient->TcpClose(m_ptrCurrentChan); - } - NextRtuIndex(m_ptrCFesChan); - } + m_ptrCurrentChan->SetResendNum(1); + if(m_ptrCurrentChan->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCurrentChan->ResetResendNum(); + if(m_AppData.comState == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + m_AppData.comState = CN_FesRtuComDown; + } + m_ptrTcpClient->TcpClose(m_ptrCurrentChan); + } + CmdControlRespProcess(NULL,0,0); + NextRtuIndex(m_ptrCFesChan); return iotFailed; } //长度、地址、功能码 都正确则认为数据正确。 @@ -322,97 +292,41 @@ int CModbusTcpV3DataProcThread::RecvNetData() clientTransID = (uint16)Data[0] << 8; clientTransID |= (uint16)Data[1]; clientTransID++; - - recvFailed = 0; - if (m_ptrCInsertFesRtu != NULL) //InsertCmd + //2022-09-02 thxiao MODBUSTCPV2 目前没有推广使用,所以默认为判断clientTransID。 + if ((m_ptrCFesRtu->m_Param.ResParam3 == 0) && (clientTransID != m_ptrCFesRtu->m_clientTransID)) { - //2022-09-02 thxiao MODBUSTCPV2 目前没有推广使用,所以默认为判断clientTransID。 - if ((m_ptrCInsertFesRtu->m_Param.ResParam1 == 0) && (clientTransID != m_AppData.m_clientTransID)) + m_ptrCurrentChan->ClearDataBuf();//清除缓冲的数据 + if (m_AppData.m_TransIDFailCount++ > 5)//2022-04-22 thxiao clientTransID error exceed max times close socket { - m_ptrCurrentChan->ClearDataBuf();//清除缓冲的数据 - if (m_AppData.m_TransIDFailCount++ > 5)//2022-04-22 thxiao clientTransID error exceed max times close socket - { - m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao - m_AppData.m_clientTransID = 0; - m_ptrTcpClient->TcpClose(m_ptrCurrentChan); - LOGDEBUG("frame clientTransID error exceed max times close socket !", clientTransID, m_AppData.m_clientTransID); - } - LOGDEBUG("clientTransID=%d m_ptrCInsertFesRtu->m_clientTransID=%d discard the frame!", clientTransID, m_AppData.m_clientTransID); - recvFailed = 1; - } - else//2022-09-02 thxiao 科华有UPS设备响应是事务处理标识符+1,增加这种特殊的判断 - if ((m_ptrCInsertFesRtu->m_Param.ResParam1 == 1) && (clientTransID != (m_AppData.m_clientTransID + 1))) - { - m_ptrCurrentChan->ClearDataBuf();//清除缓冲的数据 - if (m_AppData.m_TransIDFailCount++ > 5)//2022-04-22 thxiao clientTransID error exceed max times close socket - { - m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao - m_AppData.m_clientTransID = 0; - m_ptrTcpClient->TcpClose(m_ptrCurrentChan); - LOGDEBUG("frame clientTransID error exceed max times close socket !", clientTransID, m_AppData.m_clientTransID); - } - LOGDEBUG("clientTransID=%d m_ptrCInsertFesRtu->m_clientTransID=%d discard the frame!", clientTransID, m_AppData.m_clientTransID); - recvFailed = 1; - } - else - { - m_AppData.m_TransIDFailCount = 0; - m_ptrCurrentChan->ResetResendNum(); - m_ptrCurrentChan->SetRxNum(1); - RecvDataProcess(&Data[6], Len - 6);//报文头不再处理 - if (m_ptrCInsertFesRtu->ReadRtuSatus() == CN_FesRtuComDown) - { - m_ptrCInsertFesRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); - m_ptrCFesBase->WriteRtuSatus(m_ptrCInsertFesRtu, CN_FesRtuNormal); - } - } - if (recvFailed) - { - CmdControlRespProcess(NULL, 0, 0); - } - m_ptrCInsertFesRtu = NULL; - return iotFailed; - } - else //PollCmd - { - //2022-09-02 thxiao MODBUSTCPV2 目前没有推广使用,所以默认为判断clientTransID。 - if ((m_ptrCFesRtu->m_Param.ResParam1 == 0) && (clientTransID != m_AppData.m_clientTransID)) - { - m_ptrCurrentChan->ClearDataBuf();//清除缓冲的数据 - if (m_AppData.m_TransIDFailCount++ > 5)//2022-04-22 thxiao clientTransID error exceed max times close socket - { - LOGDEBUG("frame clientTransID error exceed max times close socket !", clientTransID, m_AppData.m_clientTransID); - m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao - m_AppData.m_clientTransID = 0; - m_ptrTcpClient->TcpClose(m_ptrCurrentChan); - } - LOGDEBUG("clientTransID=%d m_ptrCFesRtu->m_clientTransID=%d discard the frame!", clientTransID, m_AppData.m_clientTransID); - } - else//2022-09-02 thxiao 科华有UPS设备响应是事务处理标识符+1,增加这种特殊的判断 - if ((m_ptrCFesRtu->m_Param.ResParam1 == 1) && (clientTransID != (m_AppData.m_clientTransID + 1))) - { - m_ptrCurrentChan->ClearDataBuf();//清除缓冲的数据 - if (m_AppData.m_TransIDFailCount++ > 5)//2022-04-22 thxiao clientTransID error exceed max times close socket - { - LOGDEBUG("frame clientTransID error exceed max times close socket !", clientTransID, m_AppData.m_clientTransID); - m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao - m_AppData.m_clientTransID = 0; - m_ptrTcpClient->TcpClose(m_ptrCurrentChan); - } - LOGDEBUG("clientTransID=%d m_ptrCFesRtu->m_clientTransID=%d discard the frame!", clientTransID, m_AppData.m_clientTransID); - } - else - { - m_AppData.m_FrameFailCount = 0; m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao - m_ptrCurrentChan->ResetResendNum(); - m_ptrCurrentChan->SetRxNum(1); - RecvDataProcess(&Data[6], Len - 6);//报文头不再处理 - if (m_ptrCFesRtu->ReadRtuSatus() == CN_FesRtuComDown) - { - m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); - m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuNormal); - } + m_ptrTcpClient->TcpClose(m_ptrCurrentChan); + LOGDEBUG("frame clientTransID error exceed max times close socket !", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + LOGDEBUG("clientTransID=%d m_ptrCFesRtu->m_clientTransID=%d discard the frame!", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + else//2022-09-02 thxiao 科华有UPS设备响应是事务处理标识符+1,增加这种特殊的判断 + if ((m_ptrCFesRtu->m_Param.ResParam3 == 1) && (clientTransID != (m_ptrCFesRtu->m_clientTransID+1))) + { + m_ptrCurrentChan->ClearDataBuf();//清除缓冲的数据 + if (m_AppData.m_TransIDFailCount++ > 5)//2022-04-22 thxiao clientTransID error exceed max times close socket + { + m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao + m_ptrTcpClient->TcpClose(m_ptrCurrentChan); + LOGDEBUG("frame clientTransID error exceed max times close socket !", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + LOGDEBUG("clientTransID=%d m_ptrCFesRtu->m_clientTransID=%d discard the frame!", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + else + { + m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao + m_ptrCurrentChan->ResetResendNum(); + m_ptrCurrentChan->SetRxNum(1); + RecvDataProcess(&Data[6], Len - 6);//保文头不再处理 + if (m_AppData.comState == CN_FesRtuComDown) + { + m_AppData.comState = CN_FesRtuNormal; + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuNormal); } //next RTU NextRtuIndex(m_ptrCFesChan); @@ -421,15 +335,6 @@ int CModbusTcpV3DataProcThread::RecvNetData() } else { - //2023-04-12 thxiao 多RTU时就会发生地址或功能码不正确的情况 - if (m_AppData.m_FrameFailCount++ > 5)//2022-04-22 thxiao 连续帧错误 error exceed max times close socket - { - m_AppData.m_FrameFailCount = 0;//2022-04-22 thxiao - m_AppData.m_clientTransID = 0; - m_ptrTcpClient->TcpClose(m_ptrCurrentChan); - LOGDEBUG("frame error exceed max times close socket !"); - } - m_ptrCurrentChan->SetErrNum(1); //next RTU CmdControlRespProcess(NULL, 0, 0); @@ -449,53 +354,46 @@ int CModbusTcpV3DataProcThread::InsertCmdProcess() int dataSize,retSize; int len =0; + if(m_ptrCFesRtu == NULL) + return 0; + if(g_ModbusTcpV3IsMainFes==false)//备机不作任何操作 return 0; - - for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) - { - int RtuNo = m_ptrCFesChan->m_RtuNo[i]; - m_ptrCInsertFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo); //得使用局部变量 - if (m_ptrCInsertFesRtu == NULL) - continue; - - dataSize = sizeof(data); - retSize = 0; - if (m_ptrCInsertFesRtu->GetRxDoCmdNum() > 0) - { - retSize = DoCmdProcess(m_ptrCInsertFesRtu,data, dataSize); - } - else - if (m_ptrCInsertFesRtu->GetRxAoCmdNum() > 0) - { - retSize = AoCmdProcess(m_ptrCInsertFesRtu,data, dataSize); - } - else - if (m_ptrCInsertFesRtu->GetRxMoCmdNum() > 0) - { - retSize = MoCmdProcess(m_ptrCInsertFesRtu,data, dataSize); - } - else - if (m_ptrCInsertFesRtu->GetRxSettingCmdNum() > 0) - { - retSize = SettingCmdProcess(m_ptrCInsertFesRtu, data, dataSize); - } - else - if (m_ptrCInsertFesRtu->GetRxDefCmdNum() > 0) - { - retSize = DefCmdProcess(m_ptrCInsertFesRtu,data, dataSize); - } - if (retSize > 0) - { - //send data to net - len = SendDataToPort(data, retSize); - return retSize; - } + dataSize = sizeof(data); + retSize = 0; + if(m_ptrCFesRtu->GetRxDoCmdNum()>0) + { + retSize = DoCmdProcess(data,dataSize); + } + else + if(m_ptrCFesRtu->GetRxAoCmdNum()>0) + { + retSize = AoCmdProcess(data,dataSize); + } + else + if(m_ptrCFesRtu->GetRxMoCmdNum()>0) + { + retSize = MoCmdProcess(data,dataSize); + } + else + if(m_ptrCFesRtu->GetRxSettingCmdNum()>0) + { + retSize = SettingCmdProcess(); + } + else + if(m_ptrCFesRtu->GetRxDefCmdNum()>0) + { + retSize = DefCmdProcess(data,dataSize); } - m_ptrCInsertFesRtu = NULL; - return 0; + if(retSize > 0) + { + //send data to net + len = SendDataToPort(data,retSize); + } + + return len; } /** @@ -524,7 +422,7 @@ int CModbusTcpV3DataProcThread::PollingCmdProcess() Data[writex++] = cmd.StartAddr&0x00ff; Data[writex++] = (cmd.DataLen>>8)&0x00ff; Data[writex++] = cmd.DataLen&0x00ff; - FillHeader(m_ptrCFesRtu,Data, writex - 6); + FillHeader(Data, writex - 6); //send data to net len = SendDataToPort(Data,writex); @@ -538,7 +436,7 @@ int CModbusTcpV3DataProcThread::PollingCmdProcess() * @param Data 数据区 * @param Size 数据区长度 */ -void CModbusTcpV3DataProcThread::FillHeader(CFesRtuPtr RtuPtr, byte *Data, int DataSize) +void CModbusTcpV3DataProcThread::FillHeader(byte *Data, int DataSize) { /* MBAP 头编码*/ /* @@ -557,14 +455,14 @@ void CModbusTcpV3DataProcThread::FillHeader(CFesRtuPtr RtuPtr, byte *Data, int D */ - Data[0] = (byte)((m_AppData.m_clientTransID >> 8) & 0xff); - Data[1] = (byte)(m_AppData.m_clientTransID & 0xff); + Data[0] = (byte)((m_ptrCFesRtu->m_clientTransID >> 8) & 0xff); + Data[1] = (byte)(m_ptrCFesRtu->m_clientTransID & 0xff); Data[2] = 0x00; Data[3] = 0x00; Data[4] = (char)((DataSize >> 8) & 0x00ff); Data[5] = (char)(DataSize & 0x00ff); - Data[6] = RtuPtr->m_Param.RtuAddr; - m_AppData.m_clientTransID++; + Data[6] = m_ptrCFesRtu->m_Param.RtuAddr; + m_ptrCFesRtu->m_clientTransID++; } /** @@ -611,7 +509,7 @@ int CModbusTcpV3DataProcThread::SendDataToPort(byte *Data, int Size) * @param dataSize 发送数据区长度 * @return 实际发送数据长度 */ -int CModbusTcpV3DataProcThread::DoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int /*dataSize*/) +int CModbusTcpV3DataProcThread::DoCmdProcess(byte *Data, int /*dataSize*/) { SFesRxDoCmd cmd; SFesTxDoCmd retCmd; @@ -621,7 +519,7 @@ int CModbusTcpV3DataProcThread::DoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / writex = 0; memset(&retCmd,0,sizeof(retCmd)); memset(&cmd,0,sizeof(cmd)); - if(RtuPtr->ReadRxDoCmd(1,&cmd)==1) + if(m_ptrCFesRtu->ReadRxDoCmd(1,&cmd)==1) { //get the cmd ok //2019-02-21 thxiao 为适应转发规约增加 @@ -634,7 +532,7 @@ int CModbusTcpV3DataProcThread::DoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / retCmd.SubSystem = cmd.SubSystem; //2020-02-18 thxiao 遥控增加五防闭锁检查 - if (RtuPtr->CheckWuFangDoStatus(cmd.PointID) == 0)//闭锁 + if (m_ptrCFesRtu->CheckWuFangDoStatus(cmd.PointID) == 0)//闭锁 { //return failed to scada strcpy(retCmd.TableName, cmd.TableName); @@ -643,15 +541,15 @@ int CModbusTcpV3DataProcThread::DoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / strcpy(retCmd.RtuName, cmd.RtuName); retCmd.retStatus = CN_ControlFailed; retCmd.CtrlActType = cmd.CtrlActType; - sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d 闭锁").str().c_str(), RtuPtr->m_Param.RtuNo, cmd.PointID); - LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d 闭锁", RtuPtr->m_Param.RtuNo, cmd.PointID); + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d 闭锁").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d 闭锁", m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); m_AppData.lastCotrolcmd = CN_ModbusTcpV3NoCmd; m_AppData.state = CN_ModbusTcpV3AppState_idle; return 0; } - if ((pDo = GetFesDoByPointNo(RtuPtr, cmd.PointID)) != NULL) + if ((pDo = GetFesDoByPointNo(m_ptrCFesRtu, cmd.PointID)) != NULL) { if(cmd.CtrlActType == CN_ControlExecute) { @@ -736,7 +634,7 @@ int CModbusTcpV3DataProcThread::DoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / } else return 0; - FillHeader(RtuPtr,Data, writex - 6); + FillHeader(Data, writex - 6); memcpy(&m_AppData.doCmd,&cmd,sizeof(cmd)); m_AppData.lastCotrolcmd = CN_ModbusTcpV3DoCmd; m_AppData.state = CN_ModbusTcpV3AppState_waitControlResp; @@ -750,9 +648,9 @@ int CModbusTcpV3DataProcThread::DoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / strcpy(retCmd.RtuName,cmd.RtuName); retCmd.retStatus = CN_ControlSuccess; retCmd.CtrlActType = cmd.CtrlActType; - sprintf(retCmd.strParam,I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(),RtuPtr->m_Param.RtuNo,cmd.PointID); + sprintf(retCmd.strParam,I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); LOGDEBUG ("DO遥控选择成功 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); - //RtuPtr->WriteTxDoCmdBuf(1,&retCmd); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retCmd); //2019-03-18 thxiao 为适应转发规约 m_ptrCFesBase->WritexDoRespCmdBuf(1,&retCmd); @@ -767,9 +665,9 @@ int CModbusTcpV3DataProcThread::DoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / strcpy(retCmd.RtuName,cmd.RtuName); retCmd.retStatus = CN_ControlFailed; retCmd.CtrlActType = cmd.CtrlActType; - sprintf(retCmd.strParam,I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(),RtuPtr->m_Param.RtuNo,cmd.PointID); + sprintf(retCmd.strParam,I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); LOGDEBUG ("DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); - //RtuPtr->WriteTxDoCmdBuf(1,&retCmd); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retCmd); //2019-03-18 thxiao 为适应转发规约 m_ptrCFesBase->WritexDoRespCmdBuf(1,&retCmd); @@ -786,9 +684,9 @@ int CModbusTcpV3DataProcThread::DoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / strcpy(retCmd.RtuName,cmd.RtuName); retCmd.retStatus = CN_ControlPointErr; retCmd.CtrlActType = cmd.CtrlActType; - sprintf(retCmd.strParam,I18N("遥控失败!RtuNo:%d 找不到遥控点:%d").str().c_str(),RtuPtr->m_Param.RtuNo,cmd.PointID); - LOGDEBUG ("DO遥控失败 !RtuNo:%d 找不到遥控点:%d",RtuPtr->m_Param.RtuNo,cmd.PointID); - //RtuPtr->WriteTxDoCmdBuf(1,&retCmd); + sprintf(retCmd.strParam,I18N("遥控失败!RtuNo:%d 找不到遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("DO遥控失败 !RtuNo:%d 找不到遥控点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retCmd); //2019-03-18 thxiao 为适应转发规约 m_ptrCFesBase->WritexDoRespCmdBuf(1,&retCmd); @@ -806,7 +704,7 @@ int CModbusTcpV3DataProcThread::DoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / * @param dataSize 发送数据区长度 * @return 实际发送数据长度 */ -int CModbusTcpV3DataProcThread::AoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int /*dataSize*/) +int CModbusTcpV3DataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) { SFesRxAoCmd cmd; SFesTxAoCmd retCmd; @@ -819,7 +717,7 @@ int CModbusTcpV3DataProcThread::AoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / int iValue; writex = 0; - if(RtuPtr->ReadRxAoCmd(1,&cmd)==1) + if(m_ptrCFesRtu->ReadRxAoCmd(1,&cmd)==1) { //get the cmd ok //2019-03-18 thxiao 为适应转发规约增加 @@ -830,7 +728,7 @@ int CModbusTcpV3DataProcThread::AoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / retCmd.FwRtuNo = cmd.FwRtuNo; retCmd.FwPointNo = cmd.FwPointNo; retCmd.SubSystem = cmd.SubSystem; - if ((pAo = GetFesAoByPointNo(RtuPtr, cmd.PointID)) != NULL) + if ((pAo = GetFesAoByPointNo(m_ptrCFesRtu, cmd.PointID)) != NULL) { if(cmd.CtrlActType == CN_ControlExecute) { @@ -838,16 +736,13 @@ int CModbusTcpV3DataProcThread::AoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / failed = 0; if(pAo->Coeff!=0) { - //fValue=(tempValue-pAo->Base)/pAo->Coeff; - //2023-03-25 thxiao 当下发的值为浮点值,除系数容易产生精度问题,所以改为乘系数。 - fValue = (tempValue + pAo->Base) * pAo->Coeff; - - if(pAo->MaxRange>pAo->MinRange) + fValue=(tempValue-pAo->Base)/pAo->Coeff; + if(pAo->MaxRange>pAo->MinRange) { if ((fValue < pAo->MinRange) || (fValue > pAo->MaxRange)) { //2019-08-30 thxiao 增加失败详细描述 - sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d 量程越限").str().c_str(), RtuPtr->m_Param.RtuNo, cmd.PointID); + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d 量程越限").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); failed = 1; } } @@ -860,7 +755,7 @@ int CModbusTcpV3DataProcThread::AoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / else { //2019-08-30 thxiao 增加失败详细描述 - sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d 系数为0").str().c_str(), RtuPtr->m_Param.RtuNo, cmd.PointID); + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d 系数为0").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); failed = 1; } @@ -873,9 +768,9 @@ int CModbusTcpV3DataProcThread::AoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / strcpy(retCmd.RtuName,cmd.RtuName); retCmd.retStatus = CN_ControlPointErr; retCmd.CtrlActType = cmd.CtrlActType; - //sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(),RtuPtr->m_Param.RtuNo,cmd.PointID); - LOGDEBUG ("AO遥调失败,点系数为0或者量程越限!RtuNo:%d 遥调点:%d",RtuPtr->m_Param.RtuNo,cmd.PointID); - //RtuPtr->WriteTxAoCmdBuf(1,&retCmd); + //sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("AO遥调失败,点系数为0或者量程越限!RtuNo:%d 遥调点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); //2019-03-18 thxiao 为适应转发规约 m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); @@ -885,117 +780,66 @@ int CModbusTcpV3DataProcThread::AoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / else { writex = 7; - if (pAo->Param2 == 0x10) - { - Data[writex++] = pAo->Param2; //command 0x10 - Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address - Data[writex++] = pAo->Param3 & 0x00ff; - Data[writex++] = 0x00; - Data[writex++] = 0x02; - Data[writex++] = 0x04; - memcpy(&iValue, &fValue, sizeof(fValue)); - switch (pAo->Param4) + if(pAo->Param2==0x10) + { + if (pAo->Param4 == 3)//2022-03-31 thxiao 增加0x10 设置命令16位 { - case AI_Word_HL: - case AI_UWord_HL: - writex = 10; + Data[writex++] = pAo->Param2; //command 0x10 + Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address + Data[writex++] = pAo->Param3 & 0x00ff; Data[writex++] = 0x00; Data[writex++] = 0x01; Data[writex++] = 0x02; setValue = (short)fValue; Data[writex++] = (byte)(setValue >> 8); Data[writex++] = (byte)setValue; - break; - case AI_Word_LH: - case AI_UWord_LH: - writex = 10; - Data[writex++] = 0x00; - Data[writex++] = 0x01; - Data[writex++] = 0x02; - setValue = (short)fValue; - Data[writex++] = (byte)setValue; - Data[writex++] = (byte)(setValue >> 8); - break; - case AI_DWord_LL: - case AI_UDWord_LL: - iValue = (int)fValue; - Data[writex++] = (byte)iValue; - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)(iValue >> 16); - Data[writex++] = (byte)(iValue >> 24); - break; - case AI_Float_LL: - memcpy(&iValue, &fValue, sizeof(fValue)); - Data[writex++] = (byte)iValue; - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)(iValue >> 16); - Data[writex++] = (byte)(iValue >> 24); - break; - case AI_DWord_HH: - case AI_UDWord_HH: - iValue = (int)fValue; - Data[writex++] = (byte)(iValue >> 24); - Data[writex++] = (byte)(iValue >> 16); - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)iValue; - break; - case AI_Float_HH: - memcpy(&iValue, &fValue, sizeof(fValue)); - Data[writex++] = (byte)(iValue >> 24); - Data[writex++] = (byte)(iValue >> 16); - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)iValue; - break; - case AI_DWord_LH: - case AI_UDWord_LH: - iValue = (int)fValue; - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)iValue; - Data[writex++] = (byte)(iValue >> 24); - Data[writex++] = (byte)(iValue >> 16); - break; - case AI_Float_LH: - memcpy(&iValue, &fValue, sizeof(fValue)); - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)iValue; - Data[writex++] = (byte)(iValue >> 24); - Data[writex++] = (byte)(iValue >> 16); - break; - default: - iValue = (int)fValue; - Data[writex++] = (byte)(iValue >> 24); - Data[writex++] = (byte)(iValue >> 16); - Data[writex++] = (byte)(iValue >> 8); - Data[writex++] = (byte)iValue; - break; } + else + { + Data[writex++] = pAo->Param2; //command 0x10 + Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address + Data[writex++] = pAo->Param3 & 0x00ff; + Data[writex++] = 0x00; + Data[writex++] = 0x02; + Data[writex++] = 0x04; + if (pAo->Param4 == 0) //2021-06-24 ljj + { + memcpy(&iValue, &fValue, sizeof(fValue)); + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + } + else if (pAo->Param4 == 1) + { + ui32Value = static_cast(fValue); + Data[writex++] = (byte)(ui32Value >> 24); + Data[writex++] = (byte)(ui32Value >> 16); + Data[writex++] = (byte)(ui32Value >> 8); + Data[writex++] = (byte)ui32Value; + } + else if (pAo->Param4 == 2) + { + iValue = static_cast(fValue); + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + } + } + } + else + { + setValue = (short)fValue; + Data[writex++] = pAo->Param2; //command 0x06 + Data[writex++] = (pAo->Param3>>8)&0x00ff; //address + Data[writex++] = pAo->Param3&0x00ff; + Data[writex++] = (setValue>>8)&0x00ff; + Data[writex++] = setValue&0x00ff; - } - else - { - setValue = (short)fValue; - Data[writex++] = pAo->Param2; //command 0x06 - Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address - Data[writex++] = pAo->Param3 & 0x00ff; - switch (pAo->Param4) - { - case AI_Word_HL: - case AI_UWord_HL: - Data[writex++] = (setValue >> 8) & 0x00ff; - Data[writex++] = setValue & 0x00ff; - break; - case AI_Word_LH: - case AI_UWord_LH: - Data[writex++] = setValue & 0x00ff; - Data[writex++] = (setValue >> 8) & 0x00ff; - break; - default: - Data[writex++] = (setValue >> 8) & 0x00ff; - Data[writex++] = setValue & 0x00ff; - break; - } - } - FillHeader(RtuPtr,Data, writex - 6); + } + + FillHeader(Data, writex - 6); memcpy(&m_AppData.aoCmd,&cmd,sizeof(cmd)); m_AppData.lastCotrolcmd = CN_ModbusTcpV3AoCmd; m_AppData.state = CN_ModbusTcpV3AppState_waitControlResp; @@ -1010,10 +854,10 @@ int CModbusTcpV3DataProcThread::AoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / strcpy(retCmd.TagName,cmd.TagName); strcpy(retCmd.RtuName,cmd.RtuName); retCmd.retStatus = CN_ControlFailed; - sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),RtuPtr->m_Param.RtuNo,cmd.PointID); + sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); retCmd.CtrlActType = cmd.CtrlActType; LOGDEBUG ("AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.fValue,cmd.RtuName,cmd.PointID); - //RtuPtr->WriteTxAoCmdBuf(1,&retCmd); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); //2019-03-18 thxiao 为适应转发规约 m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); @@ -1030,9 +874,9 @@ int CModbusTcpV3DataProcThread::AoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / strcpy(retCmd.RtuName,cmd.RtuName); retCmd.retStatus = CN_ControlPointErr; retCmd.CtrlActType = cmd.CtrlActType; - sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(),RtuPtr->m_Param.RtuNo,cmd.PointID); - LOGDEBUG ("AO遥调失败!RtuNo:%d 找不到遥调点:%d",RtuPtr->m_Param.RtuNo,cmd.PointID); - //RtuPtr->WriteTxAoCmdBuf(1,&retCmd); + sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("AO遥调失败!RtuNo:%d 找不到遥调点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); //2019-03-18 thxiao 为适应转发规约 m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); @@ -1050,7 +894,7 @@ int CModbusTcpV3DataProcThread::AoCmdProcess(CFesRtuPtr RtuPtr,byte *Data, int / * @param dataSize 发送数据区长度 * @return 实际发送数据长度 */ -int CModbusTcpV3DataProcThread::MoCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int /*dataSize*/) +int CModbusTcpV3DataProcThread::MoCmdProcess(byte *Data, int /*dataSize*/) { SFesRxMoCmd cmd; SFesTxMoCmd retCmd; @@ -1058,7 +902,7 @@ int CModbusTcpV3DataProcThread::MoCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int int writex,iValue,failed; writex = 0; - if(RtuPtr->ReadRxMoCmd(1,&cmd)==1) + if(m_ptrCFesRtu->ReadRxMoCmd(1,&cmd)==1) { LOGDEBUG ("cmd.TableName :%s cmd.ColumnName : %s cmd.RtuName : %s cmd.TagName : %s",cmd.TableName,cmd.ColumnName,cmd.RtuName,cmd.TagName); LOGDEBUG ("cmd.PointID = %d cmd.CtrlActType = %d ",cmd.PointID,cmd.CtrlActType); @@ -1072,7 +916,7 @@ int CModbusTcpV3DataProcThread::MoCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int retCmd.SubSystem = cmd.SubSystem; //get the cmd ok //memset(&retCmd,0,sizeof(retCmd)); - if((pMo = GetFesMoByPIndex(RtuPtr,cmd.PointID))!=NULL) + if((pMo = GetFesMoByPointNo(m_ptrCFesRtu,cmd.PointID))!=NULL) { if(cmd.CtrlActType == CN_ControlExecute) { @@ -1098,9 +942,9 @@ int CModbusTcpV3DataProcThread::MoCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int strcpy(retCmd.RtuName,cmd.RtuName); retCmd.retStatus = CN_ControlPointErr; retCmd.CtrlActType = cmd.CtrlActType; - sprintf(retCmd.strParam,I18N("混合量输出失败!RtuNo:%d 找不到混合量输出点:%d").str().c_str(),RtuPtr->m_Param.RtuNo,cmd.PointID); - LOGDEBUG ("MO混合量输出失败,点系数为0或者量程越限!RtuNo:%d 混合量输出点:%d",RtuPtr->m_Param.RtuNo,cmd.PointID); - //RtuPtr->WriteTxMoCmdBuf(1,&retCmd); + sprintf(retCmd.strParam,I18N("混合量输出失败!RtuNo:%d 找不到混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("MO混合量输出失败,点系数为0或者量程越限!RtuNo:%d 混合量输出点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&retCmd); //2019-03-18 thxiao 为适应转发规约 m_ptrCFesBase->WritexMoRespCmdBuf(1,&retCmd); @@ -1129,7 +973,7 @@ int CModbusTcpV3DataProcThread::MoCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int Data[writex++] = (iValue>>8)&0x00ff; Data[writex++] = iValue&0x00ff; } - FillHeader(RtuPtr, Data, writex - 6); + FillHeader(Data, writex - 6); memcpy(&m_AppData.moCmd,&cmd,sizeof(cmd)); m_AppData.lastCotrolcmd = CN_ModbusTcpV3MoCmd; m_AppData.state = CN_ModbusTcpV3AppState_waitControlResp; @@ -1144,10 +988,10 @@ int CModbusTcpV3DataProcThread::MoCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int strcpy(retCmd.RtuName,cmd.RtuName); retCmd.retStatus = CN_ControlFailed; retCmd.CtrlActType = cmd.CtrlActType; - sprintf(retCmd.strParam,I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(),RtuPtr->m_Param.RtuNo,cmd.PointID); + sprintf(retCmd.strParam,I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); LOGDEBUG ("MO混合量执行失败 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); - //RtuPtr->WriteTxMoCmdBuf(1,&retCmd); + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&retCmd); //2019-03-18 thxiao 为适应转发规约 m_ptrCFesBase->WritexMoRespCmdBuf(1,&retCmd); @@ -1163,11 +1007,11 @@ int CModbusTcpV3DataProcThread::MoCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int strcpy(retCmd.TagName,cmd.TagName); strcpy(retCmd.RtuName,cmd.RtuName); retCmd.retStatus = CN_ControlPointErr; - sprintf(retCmd.strParam,I18N("混合量输出失败!RtuNo:%d 找不到混合量输出点:%d").str().c_str(),RtuPtr->m_Param.RtuNo,cmd.PointID); + sprintf(retCmd.strParam,I18N("混合量输出失败!RtuNo:%d 找不到混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); - LOGDEBUG ("MO混合量输出失败!RtuNo:%d 找不到混合量输出点:%d",RtuPtr->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("MO混合量输出失败!RtuNo:%d 找不到混合量输出点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); retCmd.CtrlActType = cmd.CtrlActType; - //RtuPtr->WriteTxMoCmdBuf(1,&retCmd); + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&retCmd); //2019-03-18 thxiao 为适应转发规约 m_ptrCFesBase->WritexMoRespCmdBuf(1,&retCmd); @@ -1186,7 +1030,7 @@ int CModbusTcpV3DataProcThread::MoCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int * @param dataSize 发送数据区长度 * @return 实际发送数据长度 */ -int CModbusTcpV3DataProcThread::SettingCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int dataSize) +int CModbusTcpV3DataProcThread::SettingCmdProcess() { return 0; } @@ -1198,13 +1042,16 @@ int CModbusTcpV3DataProcThread::SettingCmdProcess(CFesRtuPtr RtuPtr, byte *Data, * @param dataSize 发送数据区长度 * @return 实际发送数据长度 */ -int CModbusTcpV3DataProcThread::DefCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int dataSize) +int CModbusTcpV3DataProcThread::DefCmdProcess(byte *Data, int dataSize) { + boost::ignore_unused_variable_warning(Data); + boost::ignore_unused_variable_warning(dataSize); + SFesRxDefCmd cmd; int writex; writex = 0; - if(RtuPtr->ReadRxDefCmd(1,&cmd)==1) + if(m_ptrCFesRtu->ReadRxDefCmd(1,&cmd)==1) { //get the cmd ok,do something yourself #if 0 @@ -1223,7 +1070,7 @@ int CModbusTcpV3DataProcThread::DefCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int Data[writex++] = 0x00;//address Data[writex++] = 0x00; Data[writex++] = 0x01;//length - FillHeader(RtuPtr, Data, writex - 6); + FillHeader(Data, writex - 6); m_AppData.lastCotrolcmd = CN_ModbusTcpV3DefCmd; m_AppData.state = CN_ModbusTcpV3AppState_waitControlResp; #endif @@ -1293,19 +1140,16 @@ int CModbusTcpV3DataProcThread::RecvDataProcess(byte *Data,int DataSize) return iotSuccess; } - if (CmdControlRespProcess(Data, DataSize, 1) == true) - return iotSuccess; - switch(FunCode) { case 0x01: case 0x02: - Cmd01RespProcess(Data); + Cmd01RespProcessV2(Data); break; case 0x03: case 0x04: - Cmd03RespProcess(Data); - CmdTypeHybridProcess(Data, DataSize); + Cmd03RespProcessV2(m_AppData.lastCmd,Data); + CmdTypeHybridProcessV2(Data, DataSize); break; case 0x05: Cmd05RespProcess(Data,DataSize); @@ -1324,11 +1168,11 @@ int CModbusTcpV3DataProcThread::RecvDataProcess(byte *Data,int DataSize) } /** -* @brief CModbusTcpV3DataProcThread::Cmd01RespProcess +* @brief CModbusTcpV3DataProcThread::Cmd01RespProcessV2 * 命令0x01 0x02的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 * @param Data 接收的数据 */ -void CModbusTcpV3DataProcThread::Cmd01RespProcess(byte *Data) +void CModbusTcpV3DataProcThread::Cmd01RespProcessV2(byte *Data) { int FunCode; byte bitValue, byteValue; @@ -1343,7 +1187,7 @@ void CModbusTcpV3DataProcThread::Cmd01RespProcess(byte *Data) StartAddr = m_AppData.lastCmd.StartAddr; if (m_DiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) { - LOGDEBUG("Cmd01RespProcess: 未找到blockId=%d的数字量数据块,不解析该帧数据",m_AppData.lastCmd.SeqNo); + LOGDEBUG("Cmd01RespProcessV2: 未找到blockId=%d的数字量数据块,不解析该帧数据",m_AppData.lastCmd.SeqNo); return; } StartPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; @@ -1373,119 +1217,56 @@ void CModbusTcpV3DataProcThread::Cmd01RespProcess(byte *Data) bitValue ^= 1; //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 StartPointNo = pDi->Param1 + 1; - - //2023-04-21 thxiao RTU ResParam3 = 1(遥信可靠判断):DI数据需要收到两次为相同值,数据才能更新。pDi->Param8为上次的值 - if (m_ptrCFesRtu->m_Param.ResParam3 == 1) + if ((bitValue != pDi->Value) && (g_ModbusTcpV3IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 { - if (bitValue == pDi->Param8) + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) { - if ((bitValue != pDi->Value) && (g_ModbusTcpV3IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) { - memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); - memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); - memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); - ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - ChgDi[ChgCount].PointNo = pDi->PointNo; - ChgDi[ChgCount].Value = bitValue; - ChgDi[ChgCount].Status = CN_FesValueUpdate; - ChgDi[ChgCount].time = mSec; - ChgCount++; - if (ChgCount >= 50) - { - m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); - ChgCount = 0; - } - //Create Soe - if (m_AppData.lastCmd.IsCreateSoe) - { - SoeEvent[SoeCount].time = mSec; - memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); - memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); - memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); - SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - SoeEvent[SoeCount].PointNo = pDi->PointNo; - SoeEvent[SoeCount].Value = bitValue; - SoeEvent[SoeCount].Status = CN_FesValueUpdate; - SoeEvent[SoeCount].Value = bitValue; - SoeEvent[SoeCount].FaultNum = 0; - SoeCount++; - if (SoeCount >= 50) - { - m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); - //保存FesSim监视数据 - m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); - SoeCount = 0; - } - } - } - //更新点值 - DiValue[ValueCount].PointNo = pDi->PointNo; - DiValue[ValueCount].Value = bitValue; - DiValue[ValueCount].Status = CN_FesValueUpdate; - DiValue[ValueCount].time = mSec; - ValueCount++; - if (ValueCount >= 50) - { - m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); - ValueCount = 0; + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; } } - pDi->Param8 = bitValue; - } - else//*************正常处理***************************** + //更新点值 + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) { - if ((bitValue != pDi->Value) && (g_ModbusTcpV3IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 - { - memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); - memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); - memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); - ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - ChgDi[ChgCount].PointNo = pDi->PointNo; - ChgDi[ChgCount].Value = bitValue; - ChgDi[ChgCount].Status = CN_FesValueUpdate; - ChgDi[ChgCount].time = mSec; - ChgCount++; - if (ChgCount >= 50) - { - m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); - ChgCount = 0; - } - //Create Soe - if (m_AppData.lastCmd.IsCreateSoe) - { - SoeEvent[SoeCount].time = mSec; - memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); - memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); - memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); - SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - SoeEvent[SoeCount].PointNo = pDi->PointNo; - SoeEvent[SoeCount].Value = bitValue; - SoeEvent[SoeCount].Status = CN_FesValueUpdate; - SoeEvent[SoeCount].Value = bitValue; - SoeEvent[SoeCount].FaultNum = 0; - SoeCount++; - if (SoeCount >= 50) - { - m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); - //保存FesSim监视数据 - m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); - SoeCount = 0; - } - } - } - //更新点值 - DiValue[ValueCount].PointNo = pDi->PointNo; - DiValue[ValueCount].Value = bitValue; - DiValue[ValueCount].Status = CN_FesValueUpdate; - DiValue[ValueCount].time = mSec; - ValueCount++; - if (ValueCount >= 50) - { - m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); - ValueCount = 0; - } - }//*************正常处理***************************** + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } } //Updata Value if (ValueCount > 0) @@ -1511,7 +1292,8 @@ void CModbusTcpV3DataProcThread::Cmd01RespProcess(byte *Data) * @param Data 接收的数据 * @param DataSize 接收的数据长度 */ -void CModbusTcpV3DataProcThread::Cmd03RespProcess(byte *Data) +/* +void CModbusTcpV3DataProcThread::Cmd03RespProcessV2(byte *Data) { int FunCode, diValue, bitValue; int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, SoeCount, PointIndex; @@ -1547,7 +1329,7 @@ void CModbusTcpV3DataProcThread::Cmd03RespProcess(byte *Data) { if (m_DiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) { - LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的数字量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + LOGDEBUG("Cmd03RespProcessV2: 未找到blockId=%d的数字量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); return; } StartPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; @@ -1635,113 +1417,54 @@ void CModbusTcpV3DataProcThread::Cmd03RespProcess(byte *Data) //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 if (pDi->Revers) bitValue ^= 1; - //2023-04-21 thxiao RTU ResParam3 = 1(遥信可靠判断):DI数据需要收到两次为相同值,数据才能更新。pDi->Param8为上次的值 - if (m_ptrCFesRtu->m_Param.ResParam3 == 1) + if ((bitValue != pDi->Value) && (g_ModbusTcpV3IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 { - if (bitValue == pDi->Param8) + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) { - if ((bitValue != pDi->Value) && (g_ModbusTcpV3IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) { - memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); - memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); - memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); - ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - ChgDi[ChgCount].PointNo = pDi->PointNo; - ChgDi[ChgCount].Value = bitValue; - ChgDi[ChgCount].Status = CN_FesValueUpdate; - ChgDi[ChgCount].time = mSec; - ChgCount++; - if (ChgCount >= 50) - { - m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); - ChgCount = 0; - } - //Create Soe - if (m_AppData.lastCmd.IsCreateSoe) - { - SoeEvent[SoeCount].time = mSec; - memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); - memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); - memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); - SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - SoeEvent[SoeCount].PointNo = pDi->PointNo; - SoeEvent[SoeCount].Status = CN_FesValueUpdate; - SoeEvent[SoeCount].Value = bitValue; - SoeEvent[SoeCount].FaultNum = 0; - SoeCount++; - if (SoeCount >= 50) - { - m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); - //保存FesSim监视数据 - m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); - SoeCount = 0; - } - } - } - DiValue[ValueCount].PointNo = pDi->PointNo; - DiValue[ValueCount].Value = bitValue; - DiValue[ValueCount].Status = CN_FesValueUpdate; - DiValue[ValueCount].time = mSec; - ValueCount++; - if (ValueCount >= 50) - { - m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); - ValueCount = 0; + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; } } - pDi->Param8 = bitValue; } - else//*************正常处理***************************** + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) { - if ((bitValue != pDi->Value) && (g_ModbusTcpV3IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 - { - memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); - memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); - memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); - ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - ChgDi[ChgCount].PointNo = pDi->PointNo; - ChgDi[ChgCount].Value = bitValue; - ChgDi[ChgCount].Status = CN_FesValueUpdate; - ChgDi[ChgCount].time = mSec; - ChgCount++; - if (ChgCount >= 50) - { - m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); - ChgCount = 0; - } - //Create Soe - if (m_AppData.lastCmd.IsCreateSoe) - { - SoeEvent[SoeCount].time = mSec; - memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); - memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); - memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); - SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; - SoeEvent[SoeCount].PointNo = pDi->PointNo; - SoeEvent[SoeCount].Status = CN_FesValueUpdate; - SoeEvent[SoeCount].Value = bitValue; - SoeEvent[SoeCount].FaultNum = 0; - SoeCount++; - if (SoeCount >= 50) - { - m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); - //保存FesSim监视数据 - m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); - SoeCount = 0; - } - } - } - DiValue[ValueCount].PointNo = pDi->PointNo; - DiValue[ValueCount].Value = bitValue; - DiValue[ValueCount].Status = CN_FesValueUpdate; - DiValue[ValueCount].time = mSec; - ValueCount++; - if (ValueCount >= 50) - { - m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); - ValueCount = 0; - } - }//*************正常处理********************************* + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } } } //Updata Value @@ -1765,7 +1488,7 @@ void CModbusTcpV3DataProcThread::Cmd03RespProcess(byte *Data) { if (m_AiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) { - LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的模拟量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + LOGDEBUG("Cmd03RespProcessV2: 未找到blockId=%d的模拟量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); return; } StartPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; @@ -1969,7 +1692,7 @@ void CModbusTcpV3DataProcThread::Cmd03RespProcess(byte *Data) { if (m_AccBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) { - LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的累积量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + LOGDEBUG("Cmd03RespProcessV2: 未找到blockId=%d的累积量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); return; } StartPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; @@ -2148,7 +1871,7 @@ void CModbusTcpV3DataProcThread::Cmd03RespProcess(byte *Data) { if (m_MiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) { - LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + LOGDEBUG("Cmd03RespProcessV2: 未找到blockId=%d的混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); return; } StartPointNo = m_MiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; @@ -2299,7 +2022,7 @@ void CModbusTcpV3DataProcThread::Cmd03RespProcess(byte *Data) } } } - +*/ /** * @brief CModbusTcpV3DataProcThread::Cmd05RespProcess @@ -2334,8 +2057,10 @@ void CModbusTcpV3DataProcThread::Cmd10RespProcess(byte *Data,int DataSize) CmdControlRespProcess(Data,DataSize,1); } -void CModbusTcpV3DataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) +void CModbusTcpV3DataProcThread::CmdTypeHybridProcessV2(byte *Data, int DataSize) { + boost::ignore_unused_variable_warning(DataSize); + int FunCode; int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, PointIndex; uint64 mSec; @@ -2361,7 +2086,7 @@ void CModbusTcpV3DataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) { if (m_AiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) { - LOGDEBUG("CmdTypeHybridProcess: 未找到blockId=%d的模拟量混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + LOGDEBUG("CmdTypeHybridProcessV2: 未找到blockId=%d的模拟量混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); return; } StartPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; @@ -2506,7 +2231,7 @@ void CModbusTcpV3DataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) { if (m_AccBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) { - LOGDEBUG("CmdTypeHybridProcess: 未找到blockId=%d的累积量混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + LOGDEBUG("CmdTypeHybridProcessV2: 未找到blockId=%d的累积量混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); return; } StartPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; @@ -2597,7 +2322,7 @@ void CModbusTcpV3DataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; uValue32 |= (uint32)Data[6 + PointIndex * 2]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000;//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 + accValue = static_cast(fValue*1000);//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 break; case ACC_Float_LH: //float帧(四字节浮点 低字前 高字节前) uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; @@ -2605,7 +2330,7 @@ void CModbusTcpV3DataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; uValue32 |= (uint32)Data[4 + PointIndex * 2]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000;//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 + accValue = static_cast(fValue*1000);//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 break; case ACC_Float_LL: //float帧(四字节浮点 低字前 低字节前) uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; @@ -2613,7 +2338,7 @@ void CModbusTcpV3DataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; uValue32 |= (uint32)Data[3 + PointIndex * 2]; memcpy(&fValue, &uValue32, sizeof(float)); - accValue = fValue*1000;//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 + accValue = static_cast(fValue*1000);//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 break; default: sValue16 = (int16)Data[3 + PointIndex * 2] << 8; @@ -2622,7 +2347,7 @@ void CModbusTcpV3DataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) break; } AccValue[ValueCount].PointNo = pAcc->PointNo; - AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Value = static_cast(accValue); AccValue[ValueCount].Status = CN_FesValueUpdate; AccValue[ValueCount].time = mSec; ValueCount++; @@ -2653,7 +2378,6 @@ void CModbusTcpV3DataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) /** * @brief CModbusTcpV3DataProcThread::CmdControlRespProcess - * 该函数只能是插入RTU调用 * @param Data 接收的数据 * @param DataSize 接收的数据长度 * @param okFlag 命令成功标志 1:成功 0:失败 @@ -2661,6 +2385,9 @@ void CModbusTcpV3DataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) */ bool CModbusTcpV3DataProcThread::CmdControlRespProcess(byte *Data,int DataSize,int okFlag) { + boost::ignore_unused_variable_warning(Data); + boost::ignore_unused_variable_warning(DataSize); + SFesTxDoCmd retDoCmd; SFesTxAoCmd retAoCmd; SFesTxMoCmd retMoCmd; @@ -2676,14 +2403,14 @@ bool CModbusTcpV3DataProcThread::CmdControlRespProcess(byte *Data,int DataSize,i if(okFlag) { retDoCmd.retStatus = CN_ControlSuccess; - sprintf(retDoCmd.strParam,I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCInsertFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); - LOGINFO("遥控成功!RtuNo:%d 遥控点:%d",m_ptrCInsertFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + sprintf(retDoCmd.strParam,I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + LOGINFO("遥控成功!RtuNo:%d 遥控点:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); } else { retDoCmd.retStatus = CN_ControlFailed; - sprintf(retDoCmd.strParam,I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCInsertFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); - LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d",m_ptrCInsertFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + sprintf(retDoCmd.strParam,I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); } strcpy(retDoCmd.TableName,m_AppData.doCmd.TableName); strcpy(retDoCmd.ColumnName,m_AppData.doCmd.ColumnName); @@ -2699,7 +2426,7 @@ bool CModbusTcpV3DataProcThread::CmdControlRespProcess(byte *Data,int DataSize,i retDoCmd.FwPointNo = m_AppData.doCmd.FwPointNo; retDoCmd.SubSystem = m_AppData.doCmd.SubSystem; - //m_ptrCInsertFesRtu->WriteTxDoCmdBuf(1,&retDoCmd); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retDoCmd); //2019-03-18 thxiao 为适应转发规约 m_ptrCFesBase->WritexDoRespCmdBuf(1,&retDoCmd); @@ -2711,14 +2438,14 @@ bool CModbusTcpV3DataProcThread::CmdControlRespProcess(byte *Data,int DataSize,i if(okFlag) { retAoCmd.retStatus = CN_ControlSuccess; - sprintf(retAoCmd.strParam,I18N("遥调成功!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCInsertFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); - LOGINFO("遥调成功!RtuNo:%d 遥调点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + sprintf(retAoCmd.strParam,I18N("遥调成功!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); + LOGINFO("遥调成功!RtuNo:%d 遥调点:%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); } else { retAoCmd.retStatus = CN_ControlFailed; - sprintf(retAoCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCInsertFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); - LOGINFO("遥调失败!RtuNo:%d 遥调点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + sprintf(retAoCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); + LOGINFO("遥调失败!RtuNo:%d 遥调点:%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); } strcpy(retAoCmd.TableName,m_AppData.aoCmd.TableName); strcpy(retAoCmd.ColumnName,m_AppData.aoCmd.ColumnName); @@ -2744,14 +2471,14 @@ bool CModbusTcpV3DataProcThread::CmdControlRespProcess(byte *Data,int DataSize,i if(okFlag) { retMoCmd.retStatus = CN_ControlSuccess; - sprintf(retMoCmd.strParam,I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(),m_ptrCInsertFesRtu->m_Param.RtuNo,m_AppData.moCmd.PointID); - LOGINFO("混合量输出成功!RtuNo:%d 混合量输出点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + sprintf(retMoCmd.strParam,I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.moCmd.PointID); + LOGINFO("混合量输出成功!RtuNo:%d 混合量输出点:%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); } else { retMoCmd.retStatus = CN_ControlFailed; - sprintf(retMoCmd.strParam,I18N("混合量输出失败!RtuNo:%d 混合量输出点:%d").str().c_str(),m_ptrCInsertFesRtu->m_Param.RtuNo,m_AppData.moCmd.PointID); - LOGINFO("混合量输出失败!RtuNo:%d 混合量输出点:%d", m_ptrCInsertFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + sprintf(retMoCmd.strParam,I18N("混合量输出失败!RtuNo:%d 混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.moCmd.PointID); + LOGINFO("混合量输出失败!RtuNo:%d 混合量输出点:%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); } strcpy(retMoCmd.TableName,m_AppData.moCmd.TableName); strcpy(retMoCmd.ColumnName,m_AppData.moCmd.ColumnName); @@ -2777,14 +2504,14 @@ bool CModbusTcpV3DataProcThread::CmdControlRespProcess(byte *Data,int DataSize,i if(okFlag) { retDefCmd.retStatus = CN_ControlSuccess; - sprintf(retDefCmd.strParam,I18N("自定义命令输出成功!RtuNo:%d ").str().c_str(),m_ptrCInsertFesRtu->m_Param.RtuNo); - LOGINFO("自定义命令输出成功!RtuNo:%d", m_ptrCInsertFesRtu->m_Param.RtuNo); + sprintf(retDefCmd.strParam,I18N("自定义命令输出成功!RtuNo:%d ").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo); + LOGINFO("自定义命令输出成功!RtuNo:%d", m_ptrCFesRtu->m_Param.RtuNo); } else { retDefCmd.retStatus = CN_ControlFailed; - sprintf(retDefCmd.strParam,I18N("自定义命令输出失败!RtuNo:%d ").str().c_str(),m_ptrCInsertFesRtu->m_Param.RtuNo); - LOGINFO("自定义命令输出失败!RtuNo:%d", m_ptrCInsertFesRtu->m_Param.RtuNo); + sprintf(retDefCmd.strParam,I18N("自定义命令输出失败!RtuNo:%d ").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo); + LOGINFO("自定义命令输出失败!RtuNo:%d", m_ptrCFesRtu->m_Param.RtuNo); } strcpy(retDefCmd.TableName,m_AppData.defCmd.TableName); strcpy(retDefCmd.ColumnName,m_AppData.defCmd.ColumnName); @@ -2793,7 +2520,7 @@ bool CModbusTcpV3DataProcThread::CmdControlRespProcess(byte *Data,int DataSize,i retDefCmd.DevId = m_AppData.defCmd.DevId; retDefCmd.CmdNum = m_AppData.defCmd.CmdNum; retDefCmd.VecCmd = m_AppData.defCmd.VecCmd; - m_ptrCInsertFesRtu->WriteTxDefCmdBuf(1,&retDefCmd); + m_ptrCFesRtu->WriteTxDefCmdBuf(1,&retDefCmd); m_AppData.lastCotrolcmd = CN_ModbusTcpV3NoCmd; m_AppData.state = CN_ModbusTcpV3AppState_idle; return true; @@ -2857,79 +2584,79 @@ void CModbusTcpV3DataProcThread::ErrorControlRespProcess() } else - if(m_ptrCFesRtu->GetRxAoCmdNum()>0) - { - if(m_ptrCFesRtu->ReadRxAoCmd(1,&RxAoCmd)==1) + if(m_ptrCFesRtu->GetRxAoCmdNum()>0) { - //memset(&TxAoCmd,0,sizeof(TxAoCmd)); - strcpy(TxAoCmd.TableName,RxAoCmd.TableName); - strcpy(TxAoCmd.ColumnName,RxAoCmd.ColumnName); - strcpy(TxAoCmd.TagName,RxAoCmd.TagName); - strcpy(TxAoCmd.RtuName,RxAoCmd.RtuName); - TxAoCmd.retStatus = CN_ControlFailed; - sprintf(TxAoCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,RxAoCmd.PointID); - TxAoCmd.CtrlActType = RxAoCmd.CtrlActType; - //2019-03-18 thxiao 为适应转发规约增加 - TxAoCmd.CtrlDir = RxAoCmd.CtrlDir; - TxAoCmd.RtuNo = RxAoCmd.RtuNo; - TxAoCmd.PointID = RxAoCmd.PointID; - TxAoCmd.FwSubSystem = RxAoCmd.FwSubSystem; - TxAoCmd.FwRtuNo = RxAoCmd.FwRtuNo; - TxAoCmd.FwPointNo = RxAoCmd.FwPointNo; - TxAoCmd.SubSystem = RxAoCmd.SubSystem; - LOGDEBUG("网络已断开 AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", RxAoCmd.CtrlActType, RxAoCmd.fValue, RxAoCmd.RtuName, RxAoCmd.PointID); - //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&TxAoCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexAoRespCmdBuf(1,&TxAoCmd); + if(m_ptrCFesRtu->ReadRxAoCmd(1,&RxAoCmd)==1) + { + //memset(&TxAoCmd,0,sizeof(TxAoCmd)); + strcpy(TxAoCmd.TableName,RxAoCmd.TableName); + strcpy(TxAoCmd.ColumnName,RxAoCmd.ColumnName); + strcpy(TxAoCmd.TagName,RxAoCmd.TagName); + strcpy(TxAoCmd.RtuName,RxAoCmd.RtuName); + TxAoCmd.retStatus = CN_ControlFailed; + sprintf(TxAoCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,RxAoCmd.PointID); + TxAoCmd.CtrlActType = RxAoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxAoCmd.CtrlDir = RxAoCmd.CtrlDir; + TxAoCmd.RtuNo = RxAoCmd.RtuNo; + TxAoCmd.PointID = RxAoCmd.PointID; + TxAoCmd.FwSubSystem = RxAoCmd.FwSubSystem; + TxAoCmd.FwRtuNo = RxAoCmd.FwRtuNo; + TxAoCmd.FwPointNo = RxAoCmd.FwPointNo; + TxAoCmd.SubSystem = RxAoCmd.SubSystem; + LOGDEBUG("网络已断开 AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", RxAoCmd.CtrlActType, RxAoCmd.fValue, RxAoCmd.RtuName, RxAoCmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&TxAoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&TxAoCmd); + } } - } - else - if(m_ptrCFesRtu->GetRxMoCmdNum()>0) - { - if(m_ptrCFesRtu->ReadRxMoCmd(1,&RxMoCmd)==1) - { - //memset(&TxMoCmd,0,sizeof(TxMoCmd)); - strcpy(TxMoCmd.TableName,RxMoCmd.TableName); - strcpy(TxMoCmd.ColumnName,RxMoCmd.ColumnName); - strcpy(TxMoCmd.TagName,RxMoCmd.TagName); - strcpy(TxMoCmd.RtuName,RxMoCmd.RtuName); - TxMoCmd.retStatus = CN_ControlFailed; - TxMoCmd.CtrlActType = RxMoCmd.CtrlActType; - //2019-03-18 thxiao 为适应转发规约增加 - TxMoCmd.CtrlDir = RxMoCmd.CtrlDir; - TxMoCmd.RtuNo = RxMoCmd.RtuNo; - TxMoCmd.PointID = RxMoCmd.PointID; - TxMoCmd.FwSubSystem = RxMoCmd.FwSubSystem; - TxMoCmd.FwRtuNo = RxMoCmd.FwRtuNo; - TxMoCmd.FwPointNo = RxMoCmd.FwPointNo; - TxMoCmd.SubSystem = RxMoCmd.SubSystem; - sprintf(TxMoCmd.strParam, I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxMoCmd.PointID); + else + if(m_ptrCFesRtu->GetRxMoCmdNum()>0) + { + if(m_ptrCFesRtu->ReadRxMoCmd(1,&RxMoCmd)==1) + { + //memset(&TxMoCmd,0,sizeof(TxMoCmd)); + strcpy(TxMoCmd.TableName,RxMoCmd.TableName); + strcpy(TxMoCmd.ColumnName,RxMoCmd.ColumnName); + strcpy(TxMoCmd.TagName,RxMoCmd.TagName); + strcpy(TxMoCmd.RtuName,RxMoCmd.RtuName); + TxMoCmd.retStatus = CN_ControlFailed; + TxMoCmd.CtrlActType = RxMoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxMoCmd.CtrlDir = RxMoCmd.CtrlDir; + TxMoCmd.RtuNo = RxMoCmd.RtuNo; + TxMoCmd.PointID = RxMoCmd.PointID; + TxMoCmd.FwSubSystem = RxMoCmd.FwSubSystem; + TxMoCmd.FwRtuNo = RxMoCmd.FwRtuNo; + TxMoCmd.FwPointNo = RxMoCmd.FwPointNo; + TxMoCmd.SubSystem = RxMoCmd.SubSystem; + sprintf(TxMoCmd.strParam, I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxMoCmd.PointID); - LOGDEBUG ("网络已断开 MO混合量执行失败 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",RxMoCmd.CtrlActType,RxMoCmd.iValue,RxMoCmd.RtuName,RxMoCmd.PointID); - //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&TxMoCmd); - //2019-03-18 thxiao 为适应转发规约 - m_ptrCFesBase->WritexMoRespCmdBuf(1,&TxMoCmd); - } - } - else - if(m_ptrCFesRtu->GetRxDefCmdNum()>0) - { - if(m_ptrCFesRtu->ReadRxDefCmd(1,&RxDefCmd)==1) - { - //memset(&TxDefCmd,0,sizeof(TxDefCmd)); - strcpy(TxDefCmd.TableName,RxDefCmd.TableName); - strcpy(TxDefCmd.ColumnName,RxDefCmd.ColumnName); - strcpy(TxDefCmd.TagName,RxDefCmd.TagName); - strcpy(TxDefCmd.RtuName,RxDefCmd.RtuName); - TxDefCmd.DevId = RxDefCmd.DevId; - TxDefCmd.CmdNum = RxDefCmd.CmdNum; - TxDefCmd.VecCmd = RxDefCmd.VecCmd; - TxDefCmd.retStatus = CN_ControlFailed; - sprintf(TxDefCmd.strParam,I18N("自定义命令输出失败!RtuNo:%d ").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo); - LOGERROR("网络已断开 自定义命令输出失败!RtuNo:%d",m_ptrCFesRtu->m_Param.RtuNo); - m_ptrCFesRtu->WriteTxDefCmdBuf(1,&TxDefCmd); - } - } + LOGDEBUG ("网络已断开 MO混合量执行失败 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",RxMoCmd.CtrlActType,RxMoCmd.iValue,RxMoCmd.RtuName,RxMoCmd.PointID); + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&TxMoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&TxMoCmd); + } + } + else + if(m_ptrCFesRtu->GetRxDefCmdNum()>0) + { + if(m_ptrCFesRtu->ReadRxDefCmd(1,&RxDefCmd)==1) + { + //memset(&TxDefCmd,0,sizeof(TxDefCmd)); + strcpy(TxDefCmd.TableName,RxDefCmd.TableName); + strcpy(TxDefCmd.ColumnName,RxDefCmd.ColumnName); + strcpy(TxDefCmd.TagName,RxDefCmd.TagName); + strcpy(TxDefCmd.RtuName,RxDefCmd.RtuName); + TxDefCmd.DevId = RxDefCmd.DevId; + TxDefCmd.CmdNum = RxDefCmd.CmdNum; + TxDefCmd.VecCmd = RxDefCmd.VecCmd; + TxDefCmd.retStatus = CN_ControlFailed; + sprintf(TxDefCmd.strParam,I18N("自定义命令输出失败!RtuNo:%d ").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo); + LOGERROR("网络已断开 自定义命令输出失败!RtuNo:%d",m_ptrCFesRtu->m_Param.RtuNo); + m_ptrCFesRtu->WriteTxDefCmdBuf(1,&TxDefCmd); + } + } } /* @@ -3026,6 +2753,8 @@ void CModbusTcpV3DataProcThread::InitProtocolBlockDataIndexMapping(CFesRtuPtr Rt vector pDiBlockIndexs; vector pAccBlockIndexs; vector pMiBlockIndexs; + vector pHybridBlockIndexs; + vector pDisableBlockIndexs; //根据数据块帧类别进行分类 for (i = 0; i < cmd.num; i++) @@ -3038,34 +2767,77 @@ void CModbusTcpV3DataProcThread::InitProtocolBlockDataIndexMapping(CFesRtuPtr Rt //blockDataIndexInfoTemp.tailIndex = -1; blockDataIndexInfoTemp.headIndex = 0xFFFFFFFF; blockDataIndexInfoTemp.tailIndex = 0xFFFFFFFF; - LOGDEBUG("pCmd->Type:%d", pCmd->Type); + LOGTRACE("pCmd->Type:%d", pCmd->Type); if ((pCmd->Type >= DI_BYTE_LH) && (pCmd->Type <= DI_UWord_LH)) //DI { pDiBlockIndexs.push_back(i); m_DiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); - LOGDEBUG("m_DiBlockDataIndexInfo.insert blockId:%d", blockId); + LOGTRACE("m_DiBlockDataIndexInfo.insert blockId:%d", blockId); + + if(pCmd->Used == 0){ //防止cmd.pCmd有空洞,所以放在每个分支中判断 + pDisableBlockIndexs.push_back(i); + } } else if (((pCmd->Type >= AI_Word_HL) && (pCmd->Type <= AI_Float_LL)) || (pCmd->Type == AI_SIGNEDFLAG16_HL) || (pCmd->Type == AI_SIGNEDFLAG32_HL) || (pCmd->Type == AI_Hybrid_Type)) //AI { pAiBlockIndexs.push_back(i); m_AiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); - LOGDEBUG("m_AiBlockDataIndexInfo.insert blockId:%d", blockId); + LOGTRACE("m_AiBlockDataIndexInfo.insert blockId:%d", blockId); + + if(pCmd->Used == 0){ //防止cmd.pCmd有空洞,所以放在每个分支中判断 + pDisableBlockIndexs.push_back(i); + } } else if (((pCmd->Type >= ACC_Word_HL) && (pCmd->Type <= ACC_Float_LL)) || (pCmd->Type == ACC_Hybrid_Type))//ACC { pAccBlockIndexs.push_back(i); m_AccBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); - LOGDEBUG("m_AccBlockDataIndexInfo.insert blockId:%d", blockId); + LOGTRACE("m_AccBlockDataIndexInfo.insert blockId:%d", blockId); + + if(pCmd->Used == 0){ //防止cmd.pCmd有空洞,所以放在每个分支中判断 + pDisableBlockIndexs.push_back(i); + } } else if ((pCmd->Type >= MI_Word_HL) && (pCmd->Type <= MI_UDWord_LL))//MI { pMiBlockIndexs.push_back(i); m_MiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); - LOGDEBUG("m_MiBlockDataIndexInfo.insert blockId:%d", blockId); - } + LOGTRACE("m_MiBlockDataIndexInfo.insert blockId:%d", blockId); + if(pCmd->Used == 0){ //防止cmd.pCmd有空洞,所以放在每个分支中判断 + pDisableBlockIndexs.push_back(i); + } + } + else if(pCmd->Type == Hybrid_Type) + { + pHybridBlockIndexs.push_back(i); + LOGTRACE("pHybridBlockIndexs.insert blockId:%d", blockId); + } } + //建立混合类型帧索引,主要用于连续地址内包含多种帧的情况,减少轮询帧数量,方案: + //建一个混合类型帧,正常填写连续区间,其中包含的多种帧分别建立数据块,但是数据块设置为未使能 + for(int nDisIdx = 0; nDisIdx < pDisableBlockIndexs.size();nDisIdx++) + { + SModbusCmd *pDisCmd = cmd.pCmd + pDisableBlockIndexs.at(nDisIdx); + int nDisStartAddr = pDisCmd->StartAddr;//起始地址 + int nDisEndAddr = nDisStartAddr + pDisCmd->DataLen; //结束地址 + + for(int nHybridIdx = 0; nHybridIdx < pHybridBlockIndexs.size();nHybridIdx++) + { + SModbusCmd *pHybridCmd = cmd.pCmd + pHybridBlockIndexs.at(nHybridIdx); + int nHybridStartAddr = pHybridCmd->StartAddr;//起始地址 + int nHybridEndAddr = nHybridStartAddr + pHybridCmd->DataLen; //结束地址 + + //必须功能码和轮询时间一致才能合并在一起 + if((pDisCmd->FunCode == pHybridCmd->FunCode) && (pDisCmd->PollTime == pHybridCmd->PollTime) && + (nDisStartAddr >= nHybridStartAddr) && (nDisEndAddr <= nHybridEndAddr)) + { + m_mapSeqNoToHybridCmd[pHybridCmd->SeqNo].push_back(pDisCmd); + } + } + } + //对不同帧类别的数据块存储起始索引和结束索引 for (j = 0; j < RtuPtr->m_MaxAiIndex; j++) //Ai { @@ -3169,28 +2941,28 @@ void CModbusTcpV3DataProcThread::InitProtocolBlockDataIndexMapping(CFesRtuPtr Rt while (iter != m_AiBlockDataIndexInfo.end()) { SFesBaseBlockDataIndexInfo temp = iter->second; - LOGDEBUG("Ai--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + LOGTRACE("Ai--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); iter++; } iter = m_DiBlockDataIndexInfo.begin(); while (iter != m_DiBlockDataIndexInfo.end()) { SFesBaseBlockDataIndexInfo temp = iter->second; - LOGDEBUG("Di--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + LOGTRACE("Di--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); iter++; } iter = m_AccBlockDataIndexInfo.begin(); while (iter != m_AccBlockDataIndexInfo.end()) { SFesBaseBlockDataIndexInfo temp = iter->second; - LOGDEBUG("Acc--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + LOGTRACE("Acc--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); iter++; } iter = m_MiBlockDataIndexInfo.begin(); while (iter != m_MiBlockDataIndexInfo.end()) { SFesBaseBlockDataIndexInfo temp = iter->second; - LOGDEBUG("Mi--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + LOGTRACE("Mi--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); iter++; } } @@ -3216,7 +2988,6 @@ void CModbusTcpV3DataProcThread::ClearTcpClientByChanNo(int ChanNo) } - void CModbusTcpV3DataProcThread::SetTcpClientByChanNo(int ChanNo) { CFesChanPtr ptrChan; @@ -3230,37 +3001,810 @@ void CModbusTcpV3DataProcThread::SetTcpClientByChanNo(int ChanNo) } -/* -@brief CModbusTcpV3DataProcThread::CheckRTUCmdNum - 检查数据块是否使用,如果所有的数据块都不使用,ptrFesRtu->m_Param.ModbusCmdBuf.num=0, - 以便轮询RTU时可以跳过,不至于总是在无效的RTU中查询 - +/** +* @brief CModbusTcpV3DataProcThread::Cmd03RespProcess +* 命令0x03 0x04的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 */ -void CModbusTcpV3DataProcThread::CheckRTUCmdNum() +void CModbusTcpV3DataProcThread::Cmd03RespProcessV2(const SModbusCmd &lastCmd,byte *Data) { - SModbusCmd *pCmd; - CFesRtuPtr ptrFesRtu; - int i,j, count, RtuNo; - - for (i = 0; i < m_ptrCFesChan->m_RtuNum; i++) - { - RtuNo = m_ptrCFesChan->m_RtuNo[i]; - if ((ptrFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) - continue; - count = 0; - for (j = 0; j < ptrFesRtu->m_Param.ModbusCmdBuf.num; j++) - { - pCmd = ptrFesRtu->m_Param.ModbusCmdBuf.pCmd + j; - if (pCmd->Used)//2022-09-06 thxiao 启用块使能 - { - count++; - break; - } - } - if (count == 0) - { - ptrFesRtu->m_Param.ModbusCmdBuf.num = 0;//置为0,不再轮询该RTU - LOGDEBUG("RtuNo=%d m_Param.ModbusCmdBuf.num置为0,不再轮询该RTU"); - } - } + if ((lastCmd.Type == DI_UWord_HL) || (lastCmd.Type == DI_UWord_LH))//DI + { + Cmd03RespProcessV2_DI(lastCmd,Data); + } + else if (((lastCmd.Type >= AI_Word_HL) && (lastCmd.Type <= AI_Float_LL)) || + (lastCmd.Type == AI_SIGNEDFLAG16_HL) || + (lastCmd.Type == AI_SIGNEDFLAG32_HL))//AI + { + Cmd03RespProcessV2_AI(lastCmd,Data); + } + else if ((lastCmd.Type >= ACC_Word_HL) && (lastCmd.Type <= ACC_Float_LL))//ACC + { + Cmd03RespProcessV2_ACC(lastCmd,Data); + } + else if ((lastCmd.Type >= MI_Word_HL) && (lastCmd.Type <= MI_UDWord_LL))//MI + { + Cmd03RespProcessV2_MI(lastCmd,Data); + } + else if(lastCmd.Type == Hybrid_Type) + { + Cmd03RespProcessV2_Hybrid(lastCmd,Data); + } +} + +void CModbusTcpV3DataProcThread::Cmd03RespProcessV2_DI(const SModbusCmd &lastCmd,byte *Data) +{ + int diValue, bitValue; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[100]; + uint64 mSec = getUTCTimeMsec(); + int ValueCount = 0; + int ChgCount = 0; + int SoeCount = 0; + + map::const_iterator iterDataBlock = m_DiBlockDataIndexInfo.find(lastCmd.SeqNo); + + if (iterDataBlock == m_DiBlockDataIndexInfo.end()) + { + LOGDEBUG("Cmd03RespProcessV2_DI: 未找到blockId=%d的数字量数据块,不解析该帧数据", lastCmd.SeqNo); + return; + } + + const SFesBaseBlockDataIndexInfo &dataBlockInfo = iterDataBlock->second; + int StartPointNo = dataBlockInfo.headIndex; + int EndPointNo = dataBlockInfo.tailIndex; + for (int i = StartPointNo; i<=EndPointNo; i++) + { + SFesDi *pDi = GetFesDiByPIndex(m_ptrCFesRtu, i); + if (pDi == NULL) + continue; + + int PointIndex = pDi->Param3 - lastCmd.StartAddr; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + if (lastCmd.Type == DI_UWord_HL) + { + diValue = (int)Data[3 + PointIndex * 2] << 8; + diValue |= (int)Data[4 + PointIndex * 2]; + } + else//DI_UWord_LH + { + diValue = (int)Data[4 + PointIndex * 2] << 8; + diValue |= (int)Data[3 + PointIndex * 2]; + } + + if (lastCmd.Param1 == 1) //数据块自定义#1 = 1,遥信按位组合 + { + bitValue = Cmd03RespProcess_BitGroup(pDi, diValue); + + if ((bitValue != pDi->Value) && (g_ModbusTcpV3IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + else + { + bitValue = (diValue >> (pDi->Param4)) & 0x01; + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + if (pDi->Revers) + bitValue ^= 1; + if ((bitValue != pDi->Value) && (g_ModbusTcpV3IsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } +} + +void CModbusTcpV3DataProcThread::Cmd03RespProcessV2_AI(const SModbusCmd &lastCmd, byte *Data) +{ + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + + uint64 mSec = getUTCTimeMsec(); + int ChgCount = 0; + int ValueCount = 0; + + map::const_iterator iterDataBlock = m_AiBlockDataIndexInfo.find(lastCmd.SeqNo); + if (iterDataBlock == m_AiBlockDataIndexInfo.end()) + { + LOGDEBUG("Cmd03RespProcessV2_AI: 未找到blockId=%d的模拟量数据块,不解析该帧数据", lastCmd.SeqNo); + return; + } + + const SFesBaseBlockDataIndexInfo &dataBlockInfo = iterDataBlock->second; + int StartPointNo = dataBlockInfo.headIndex; + int EndPointNo = dataBlockInfo.tailIndex; + + if (((lastCmd.Type >= AI_Word_HL) && (lastCmd.Type <= AI_UWord_LH)) || (lastCmd.Type == AI_SIGNEDFLAG16_HL))//AI 16bit + { + for (int i = StartPointNo; i <= EndPointNo; i++) + { + SFesAi *pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + int PointIndex = pAi->Param3 - lastCmd.StartAddr; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (lastCmd.Type) + { + case AI_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + aiValue = uValue16; + break; + case AI_SIGNEDFLAG16_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + if (uValue16 & 0x8000) + { + aiValue = (float)(uValue16 & 0x7fff); + aiValue = 0 - aiValue; + } + else + aiValue = (float)(uValue16 & 0x7fff); + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + aiValue = uValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV3IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + else//AI 32bit + { + for (int i = StartPointNo; i <= EndPointNo; i++) + { + SFesAi *pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + int PointIndex = (pAi->Param3 - lastCmd.StartAddr)/2; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (lastCmd.Type) + { + case AI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_SIGNEDFLAG32_HL: + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + if (uValue32 & 0x80000000) + { + aiValue = (float)(uValue32 & 0x7fffffff); + aiValue = 0 - aiValue; + } + else + aiValue = (float)(uValue32 & 0x7fffffff); + break; + } + + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + + ValueCount++; + + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV3IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + if (ValueCount>0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount>0) && (g_ModbusTcpV3IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } +} + +void CModbusTcpV3DataProcThread::Cmd03RespProcessV2_ACC(const SModbusCmd &lastCmd, byte *Data) +{ + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue; + int64 accValue; + + uint64 mSec = getUTCTimeMsec(); + int ValueCount = 0; + int ChgCount = 0; + + map::const_iterator iterDataBlock = m_AccBlockDataIndexInfo.find(lastCmd.SeqNo); + if (iterDataBlock == m_AccBlockDataIndexInfo.end()) + { + LOGDEBUG("Cmd03RespProcessV2_ACC: 未找到blockId=%d的累积量数据块,不解析该帧数据", lastCmd.SeqNo); + return; + } + + const SFesBaseBlockDataIndexInfo &dataBlockInfo = iterDataBlock->second; + int StartPointNo = dataBlockInfo.headIndex; + int EndPointNo = dataBlockInfo.tailIndex; + + if ((lastCmd.Type >= ACC_Word_HL) && (lastCmd.Type <= ACC_UWord_LH))//ACC 16bit + { + for (int i = StartPointNo; i <= EndPointNo; i++) + { + SFesAcc *pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + int PointIndex = pAcc->Param3 - lastCmd.StartAddr; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (lastCmd.Type) + { + case ACC_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + accValue = sValue16; + break; + case ACC_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + accValue = sValue16; + break; + case ACC_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + accValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + accValue = uValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = static_cast(accValue); + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV3IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + else//ACC 32bit + { + for (int i = StartPointNo; i <= EndPointNo; i++) + { + SFesAcc *pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + int PointIndex = (pAcc->Param3 - lastCmd.StartAddr)/2; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (lastCmd.Type) + { + case ACC_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue*1000);//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 + break; + case ACC_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue * 1000);//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 + break; + case ACC_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = static_cast(fValue * 1000);//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = static_cast(accValue); + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV3IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + if (ValueCount>0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount>0) && (g_ModbusTcpV3IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } +} + +void CModbusTcpV3DataProcThread::Cmd03RespProcessV2_MI(const SModbusCmd &lastCmd, byte *Data) +{ + SFesRtuMiValue MiValue[100]; + SFesChgMi ChgMi[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + int miValue; + + uint64 mSec = getUTCTimeMsec(); + int ValueCount = 0; + int ChgCount = 0; + + map::const_iterator iterDataBlock = m_MiBlockDataIndexInfo.find(lastCmd.SeqNo); + if (iterDataBlock == m_MiBlockDataIndexInfo.end()) + { + LOGDEBUG("Cmd03RespProcessV2_MI: 未找到blockId=%d的混合量数据块,不解析该帧数据", lastCmd.SeqNo); + return; + } + + const SFesBaseBlockDataIndexInfo &dataBlockInfo = iterDataBlock->second; + int StartPointNo = dataBlockInfo.headIndex; + int EndPointNo = dataBlockInfo.tailIndex; + + if ((lastCmd.Type >= MI_Word_HL) && (lastCmd.Type <= MI_UWord_LH))//MI 16bit + { + for (int i = StartPointNo; i <= EndPointNo; i++) + { + SFesMi *pMi = GetFesMiByPIndex(m_ptrCFesRtu, i); + if (pMi == NULL) + continue; + + //2022-12-20 取点值应该为PointIndex + int PointIndex = pMi->Param3 - lastCmd.StartAddr; + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (lastCmd.Type) + { + case MI_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + miValue = sValue16; + break; + case MI_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + miValue = sValue16; + break; + case MI_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + miValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + miValue = uValue16; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV3IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + else//Mi 32bit + { + for (int i = StartPointNo; i <= EndPointNo; i++) + { + SFesMi *pMi = GetFesMiByPIndex(m_ptrCFesRtu, i); + if (pMi == NULL) + continue; + + //2022-12-20 取点值应该为PointIndex + int PointIndex = (pMi->Param3 - lastCmd.StartAddr) / 2; + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (lastCmd.Type) + { + case MI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + miValue = uValue32; + break; + case MI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + miValue = uValue32; + break; + case MI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + miValue = uValue32; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpV3IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + if (ValueCount>0) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount>0) && (g_ModbusTcpV3IsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } +} + +void CModbusTcpV3DataProcThread::Cmd03RespProcessV2_Hybrid(const SModbusCmd &lastCmd, byte *Data) +{ + std::map >::const_iterator iter = m_mapSeqNoToHybridCmd.find(lastCmd.SeqNo); + if(iter == m_mapSeqNoToHybridCmd.end()) + { + LOGDEBUG("Cmd03RespProcessV2_Hybrid: 未找到blockId=%d的混合类型数据块,不解析该帧数据", lastCmd.SeqNo); + return; + } + + const std::vector vecCmd = iter->second; + SModbusCmd tmpCmd; + + for(int i = 0; i < vecCmd.size();i++) + { + memcpy(&tmpCmd,vecCmd[i],sizeof(SModbusCmd)); + tmpCmd.StartAddr = m_AppData.lastCmd.StartAddr; + tmpCmd.DataLen = m_AppData.lastCmd.DataLen; + + Cmd03RespProcessV2(tmpCmd,Data); + } } diff --git a/product/src/fes/protocol/modbus_tcpV3/ModbusTcpV3DataProcThread.h b/product/src/fes/protocol/modbus_tcpV3/ModbusTcpV3DataProcThread.h index 5565f814..1d9dffcd 100644 --- a/product/src/fes/protocol/modbus_tcpV3/ModbusTcpV3DataProcThread.h +++ b/product/src/fes/protocol/modbus_tcpV3/ModbusTcpV3DataProcThread.h @@ -28,6 +28,7 @@ const int CN_ModbusTcpV3DefCmd = 4; //增加的数据类型,之前的定义在FesDef.h #define AI_SIGNEDFLAG16_HL 62 //模拟量帧(符号位(bit15)加数值 高字节前) #define AI_SIGNEDFLAG32_HL 63 //模拟量帧(符号位(bit31)加数值 高字节前) +#define Hybrid_Type 99 //混合类型,表示此帧中包含了多种数据类型,比如一帧中包括了按位取的数字量帧,模拟量帧、混合量帧 #define MODBUSTCPV3_K_MAX_POINT_INDEX 200 //接收缓存最大索引 @@ -35,7 +36,7 @@ const int CN_ModbusTcpV3DefCmd = 4; typedef struct{ int index; int state; - // int comState; + int comState; int lastCotrolcmd; byte lastCmdData[CN_ModbusTcpV3_MAX_CMD_LEN]; int lastCmdDataLen; @@ -46,8 +47,6 @@ typedef struct{ SFesRxDefCmd defCmd; int setCmdCount; int m_TransIDFailCount; //2022-04-22 thxiao - uint16 m_clientTransID; - int m_FrameFailCount; //2022-04-22 thxiao }SModbusTcpV3AppData; //2021-06-25 ljj @@ -81,10 +80,9 @@ public: CFesBase* m_ptrCFesBase; CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 - CFesRtuPtr m_ptrCFesRtu; //支持轮询处理,当前轮询使用RTU数据区 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,ModbusTcpV3 每个通道对应一个RTU数据,所以不需要轮询处理。 CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 int m_ClearClientFlag; - CFesRtuPtr m_ptrCInsertFesRtu; //2023-03-25 thxiao 当前插入命令使用RTU数据区 SModbusTcpV3AppData m_AppData; //内部应用数据结构 @@ -92,25 +90,23 @@ public: map m_DiBlockDataIndexInfo; map m_AccBlockDataIndexInfo; map m_MiBlockDataIndexInfo; + std::map > m_mapSeqNoToHybridCmd; //存放混合帧对应的子数据块,<块SeqNo,数据块指针> CComTcpClientPtr m_ptrTcpClient; private: - int m_timerCount; - int m_timerCountReset; - - int SendProcess(); + int SendProcess(); int RecvNetData(); int InsertCmdProcess(); void ErrorControlRespProcess(); int PollingCmdProcess(); - void FillHeader(CFesRtuPtr RtuPtr,byte *Data, int Size); + void FillHeader(byte *Data, int Size); int SendDataToPort(byte *Data, int Size); - int DoCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int dataSize); - int AoCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int dataSize); - int MoCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int dataSize); - int SettingCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int dataSize); - int DefCmdProcess(CFesRtuPtr RtuPtr, byte *Data, int dataSize); + int DoCmdProcess(byte *Data, int dataSize); + int AoCmdProcess(byte *Data, int dataSize); + int MoCmdProcess(byte *Data, int dataSize); + int SettingCmdProcess(); + int DefCmdProcess(byte *Data, int dataSize); int GetPollingCmd(SModbusCmd *pCmd); int RecvDataProcess(byte *Data,int DataSize); void Cmd05RespProcess(byte *Data,int DataSize); @@ -121,10 +117,42 @@ private: int Cmd03RespProcess_BitGroup(SFesDi *pDi, int diValue); void InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuPtr); - void Cmd01RespProcess(byte *Data); - void Cmd03RespProcess(byte *Data); - void CmdTypeHybridProcess(byte *Data, int DataSize); - void CheckRTUCmdNum(); + void Cmd01RespProcessV2(byte *Data); + void Cmd03RespProcessV2(const SModbusCmd &lastCmd,byte *Data); + void CmdTypeHybridProcessV2(byte *Data, int DataSize); + + void Cmd03RespProcessV2_DI(const SModbusCmd &lastCmd,byte *Data); + void Cmd03RespProcessV2_AI(const SModbusCmd &lastCmd,byte *Data); + void Cmd03RespProcessV2_ACC(const SModbusCmd &lastCmd,byte *Data); + void Cmd03RespProcessV2_MI(const SModbusCmd &lastCmd,byte *Data); + void Cmd03RespProcessV2_Hybrid(const SModbusCmd &lastCmd,byte *Data); + + int m_timerCount; + int m_timerCountReset; +#if 0 + /*************************** TCP PROCESS *****************************************************/ + int TcpConnect(); + void TcpClose(); + int ConnectNonb(int sock, const struct sockaddr *saptr, socklen_t salen, int nsec); + bool SelectNextRoute(); + int TxData(int dateLen, byte *pData); + void RxData(); + + + SOCKET m_Socket; + int m_CurRoute; + int m_RetryTimes; + int m_RetryCount; + int m_RecvTimeout; + int m_ConnectTimeout; //ms + int m_NetStatus; //网络状态 + int64 m_lRecvTime; + int64 m_lLastRecvTime; + int64 m_lConnectTime; + int64 m_lLastConnectTime; + + /***************************************************************************************/ +#endif }; diff --git a/product/src/fes/protocol/modbus_tcp_mz/ModbusTcpMZ.cpp b/product/src/fes/protocol/modbus_tcp_mz/ModbusTcpMZ.cpp new file mode 100644 index 00000000..cd30f815 --- /dev/null +++ b/product/src/fes/protocol/modbus_tcp_mz/ModbusTcpMZ.cpp @@ -0,0 +1,651 @@ +/* + @file ModbusTcpMZ.cpp + @brief MODBUS TCP client类 + + @author thxiao + @history + +*/ +#include "ModbusTcpMZ.h" +#include "pub_utility_api/I18N.h" +#include "dbms/rdb_api/CRdbAccessEx.h" +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/rdb_api/RdbDefine.h" + +using namespace iot_public; + +CModbusTcpMZ ModbusTcpMZ; +bool g_ModbusTcpMZIsMainFes=false; +bool g_ModbusTcpMZChanelRun=true; + + +int EX_SetBaseAddr(void *address) +{ + ModbusTcpMZ.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + ModbusTcpMZ.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + ModbusTcpMZ.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + ModbusTcpMZ.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + ModbusTcpMZ.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + g_ModbusTcpMZChanelRun=false;//使所有的线程退出。 + return iotSuccess; +} + +CModbusTcpMZ::CModbusTcpMZ() +{ + m_ptrCFesBase = nullptr; + m_initRtuFlag = 0;//2021-07-08 thxiao 初始参数需要清零 +} + +CModbusTcpMZ::~CModbusTcpMZ() +{ + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); + + LOGDEBUG("CModbusTcpMZ::~CModbusTcpMZ 退出"); + +} + + +int CModbusTcpMZ::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + } + return iotSuccess; +} + +int CModbusTcpMZ::SetProperty(int IsMainFes) +{ + g_ModbusTcpMZIsMainFes = IsMainFes; + return iotSuccess; +} + +/** + * @brief CModbusTcpMZ::OpenChan + * 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CModbusTcpMZ::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if (m_initRtuFlag == 0) + { + InitProcess(); + m_initRtuFlag = 1; + } + + if ((OpenFlag == CN_FesChanThread_Flag) || (OpenFlag == CN_FesChanAndDataThread_Flag)) + { + if (ptrFesChan->m_ComThreadRun == CN_FesStopFlag) + { + SetTcpClientByChanNo(MainChanNo, ChanNo); + } + } + if ((OpenFlag == CN_FesDataThread_Flag) || (OpenFlag == CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + CModbusTcpMZDataProcThreadPtr ptrCDataProc; + ptrCDataProc = boost::make_shared(m_ptrCFesBase, ptrMainFesChan); + if (ptrCDataProc == NULL) + { + LOGERROR("CModbusTcpMZ EX_OpenChan() ChanNo:%d create CModbusDataProcThreadPtr error!", ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; + +} + +/** + * @brief CModbusTcpMZ::CloseChan + * 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CModbusTcpMZ::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if ((CloseFlag == CN_FesChanThread_Flag) || (CloseFlag == CN_FesChanAndDataThread_Flag)) + { + if (ptrFesChan->m_ComThreadRun == CN_FesRunFlag) + { + ClearTcpClientdByChanNo(MainChanNo, ChanNo); + } + } + if ((CloseFlag == CN_FesDataThread_Flag) || (CloseFlag == CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + return iotSuccess; +} + +/** + * @brief CModbusTcpMZ::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int CModbusTcpMZ::ChanTimer(int MainChanNo) +{ + + return iotSuccess; +} + + +void CModbusTcpMZ::ClearTcpClientdByChanNo(int MainChanNo,int ChanNo) +{ + CModbusTcpMZDataProcThreadPtr ptrDataProc; + int found = 0; + + if (m_CDataProcQueue.size() <= 0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin(); it != m_CDataProcQueue.end(); it++) + { + ptrDataProc = *it; + if (ptrDataProc->m_ptrCFesChan->m_Param.ChanNo == MainChanNo) + { + found = 1; + ptrDataProc->ClearTcpClientByChanNo(ChanNo); + break; + } + } + if (found) + { + LOGDEBUG("ClearTcpClientdByChanNo() MainChanNo=%d ChanNo=%d OK", MainChanNo, ChanNo); + } + else + { + LOGDEBUG("ClearTcpClientdByChanNo() MainChanNo=%d ChanNo=%d failed", MainChanNo, ChanNo); + } +} + + +void CModbusTcpMZ::SetTcpClientByChanNo(int MainChanNo,int ChanNo) +{ + CModbusTcpMZDataProcThreadPtr ptrDataProc; + int found = 0; + + if (m_CDataProcQueue.size() <= 0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin(); it != m_CDataProcQueue.end(); it++) + { + ptrDataProc = *it; + if (ptrDataProc->m_ptrCFesChan->m_Param.ChanNo == MainChanNo) + { + found = 1; + ptrDataProc->SetTcpClientByChanNo(ChanNo); + break; + } + } + if (found) + { + LOGDEBUG("SetTcpClientByChanNo() MainChanNo=%d ChanNo=%d OK", MainChanNo,ChanNo); + } + else + { + LOGDEBUG("SetTcpClientByChanNo() MainChanNo=%d ChanNo=%d failed", MainChanNo,ChanNo); + } + +} + + +void CModbusTcpMZ::ClearDataProcThreadByChanNo(int MainChanNo) +{ + CModbusTcpMZDataProcThreadPtr ptrTcp; + + if (m_CDataProcQueue.size()<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it != m_CDataProcQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == MainChanNo) + { + m_CDataProcQueue.erase(it); + LOGDEBUG("ClearDataProcThreadByChanNo MainChanNo=%d ok", MainChanNo); + break; + } + } +} + + +void CModbusTcpMZ::InitProcess() +{ + int i, RtuCount, ProtocolId; + CFesChanPtr chanPtr; + + ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"modbus_tcp_mz"); + if (ProtocolId == -1) + { + LOGERROR("InitProcess() can't found ProtocolId."); + return; + } + + RtuCount = m_ptrCFesBase->m_vectCFesRtuPtr.size(); + for (i = 0; i < RtuCount; i++) + { + if (m_ptrCFesBase->m_vectCFesRtuPtr[i]->m_Param.Used) + { + //found the Chan; + if ((chanPtr = GetChanDataByChanNo(m_ptrCFesBase->m_vectCFesRtuPtr[i]->m_Param.ChanNo)) != NULL) + { + if (chanPtr->m_Param.Used && (chanPtr->m_Param.ProtocolId == ProtocolId)) + InitPointMapping(m_ptrCFesBase->m_vectCFesRtuPtr[i]); //初始化转发表结构参数 + } + } + + } +} + +bool CModbusTcpMZ::InitPointMapping(CFesRtuPtr RtuPtr) +{ + iot_dbms::CRdbAccessEx RdbAiTable; + iot_dbms::CRdbAccessEx RdbAoTable; + iot_dbms::CRdbAccessEx RdbDiTable; + iot_dbms::CRdbAccessEx RdbDoTable; + iot_dbms::CRdbAccessEx RdbAccTable; + iot_dbms::CRdbAccessEx RdbMiTable; + iot_dbms::CRdbAccessEx RdbMoTable; + int count, ret; + SFesAiIndex *pAiIndex; + SFesDiIndex *pDiIndex; + SFesAccIndex *pAccIndex; + SFesMiIndex *pMiIndex; + SFesAi *pAi; + SFesDi *pDi; + SFesAcc *pAcc; + SFesMi *pMi; + + int i,j; + + //条件判断 + iot_dbms::CONDINFO con; + con.relationop = ATTRCOND_EQU; + con.conditionval = RtuPtr->m_Param.RtuNo; + strcpy(con.name, "rtu_no"); + + //READ AI TABLE + std::vector VecAiParam; + std::vector vecAiColumn; + std::vector vecAiOrder; + + vecAiColumn.push_back("rtu_no"); + vecAiColumn.push_back("dot_no"); + vecAiColumn.push_back("res_para_int1"); + vecAiColumn.push_back("res_para_int2"); + vecAiColumn.push_back("res_para_int3"); + vecAiColumn.push_back("res_para_int4"); + + vecAiOrder.push_back("res_para_int2"); + vecAiOrder.push_back("res_para_int3"); + + ret = RdbAiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_AI_TBL); + if (ret == false) + { + LOGERROR("RdbAiTable::Open error"); + return iotFailed; + } + ret = RdbAiTable.selectOneColumnOneOrder(con, VecAiParam, vecAiColumn, vecAiOrder);//默认顺序 ljj + if (ret == false) + { + LOGERROR("RdbAiTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbAiTable.close(); + if (ret == false) + { + LOGERROR("RdbAiTable::close error"); + return iotFailed; + } + count = VecAiParam.size(); + if (count > 0) + { + //RtuPtr->m_MaxAiIndex = VecAiParam[count-1].Param1+1; + RtuPtr->m_MaxAiIndex = count; //ljj + if (RtuPtr->m_MaxAiIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pAiIndex = (SFesAiIndex*)malloc(RtuPtr->m_MaxAiIndex * sizeof(SFesAiIndex)); + if (RtuPtr->m_pAiIndex != NULL) + { + memset(RtuPtr->m_pAiIndex, 0xff, RtuPtr->m_MaxAiIndex * sizeof(SFesAiIndex)); + for (j = 0; j < RtuPtr->m_MaxAiIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pAiIndex = RtuPtr->m_pAiIndex + j; + pAiIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + pAiIndex = RtuPtr->m_pAiIndex + j; + pAiIndex->PointNo = VecAiParam[j].PointNo; + pAiIndex->PIndex = j; + if ((pAiIndex->PointNo >= 0) && (pAiIndex->PointNo < RtuPtr->m_MaxAiPoints)) + { + pAi = RtuPtr->m_pAi + pAiIndex->PointNo; + pAiIndex->DevId = pAi->DevId; + pAiIndex->Param2 = pAi->Param2; + pAiIndex->Param3 = pAi->Param3; + pAiIndex->Param4 = pAi->Param4; + pAiIndex->Used = 1; + } + } + } + else + { + RtuPtr->m_MaxAiIndex = 0; + LOGDEBUG("RtuNo:%d AI protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + + //READ DI TABLE + //ljj di新增按位排序 + std::vector VecDiParam; + std::vector vecDiColumn; + std::vector vecDiOrder; + + vecDiColumn.push_back("rtu_no"); + vecDiColumn.push_back("dot_no"); + vecDiColumn.push_back("res_para_int1"); + vecDiColumn.push_back("res_para_int2"); + vecDiColumn.push_back("res_para_int3"); + vecDiColumn.push_back("res_para_int4"); + + vecDiOrder.push_back("res_para_int2"); + vecDiOrder.push_back("res_para_int3"); + vecDiOrder.push_back("res_para_int4"); + + ret = RdbDiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_DI_TBL); + if (ret == false) + { + LOGERROR("RdbDiTable::Open error"); + return iotFailed; + } + ret = RdbDiTable.selectOneColumnOneOrder(con, VecDiParam, vecDiColumn, vecDiOrder);//默认顺序 + if (ret == false) + { + LOGERROR("RdbDiTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbDiTable.close(); + if (ret == false) + { + LOGERROR("RdbDiTable::close error"); + return iotFailed; + } + count = VecDiParam.size(); + if (count > 0) + { + RtuPtr->m_MaxDiIndex = count; + if (RtuPtr->m_MaxDiIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pDiIndex = (SFesDiIndex*)malloc(RtuPtr->m_MaxDiIndex * sizeof(SFesDiIndex)); + if (RtuPtr->m_pDiIndex != NULL) + { + memset(RtuPtr->m_pDiIndex, 0xff, RtuPtr->m_MaxDiIndex * sizeof(SFesDiIndex)); + for (j = 0; j < RtuPtr->m_MaxDiIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pDiIndex = RtuPtr->m_pDiIndex + j; + pDiIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + pDiIndex = RtuPtr->m_pDiIndex + j; + pDiIndex->PointNo = VecDiParam[j].PointNo; + pDiIndex->PIndex = j; + if ((pDiIndex->PointNo >= 0) && (pDiIndex->PointNo < RtuPtr->m_MaxDiPoints)) + { + pDi = RtuPtr->m_pDi + pDiIndex->PointNo; + pDiIndex->DevId = pDi->DevId; + pDiIndex->Param2 = pDi->Param2; + pDiIndex->Param3 = pDi->Param3; + pDiIndex->Param4 = pDi->Param4; + pDiIndex->Used = 1; + } + } + } + else + { + RtuPtr->m_MaxDiIndex = 0; + LOGDEBUG("RtuNo:%d Di protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + //READ ACC TABLE + std::vector VecAccParam; + std::vector vecAccColumn; + std::vector vecAccOrder; + + vecAccColumn.push_back("rtu_no"); + vecAccColumn.push_back("dot_no"); + vecAccColumn.push_back("res_para_int1"); + vecAccColumn.push_back("res_para_int2"); + vecAccColumn.push_back("res_para_int3"); + vecAccColumn.push_back("res_para_int4"); + + vecAccOrder.push_back("res_para_int2"); + vecAccOrder.push_back("res_para_int3"); + + ret = RdbAccTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_ACC_TBL); + if (ret == false) + { + LOGERROR("RdbAccTable::Open error"); + return iotFailed; + } + ret = RdbAccTable.selectOneColumnOneOrder(con, VecAccParam, vecAccColumn, vecAccOrder);//默认顺序 + if (ret == false) + { + LOGERROR("RdbAccTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbAccTable.close(); + if (ret == false) + { + LOGERROR("RdbAccTable::close error"); + return iotFailed; + } + + count = VecAccParam.size(); + if (count > 0) + { + //RtuPtr->m_MaxAccIndex = VecAccParam[count-1].Param1+1; + RtuPtr->m_MaxAccIndex = count; + if (RtuPtr->m_MaxAccIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pAccIndex = (SFesAccIndex*)malloc(RtuPtr->m_MaxAccIndex * sizeof(SFesAccIndex)); + if (RtuPtr->m_pAccIndex != NULL) + { + memset(RtuPtr->m_pAccIndex, 0xff, RtuPtr->m_MaxAccIndex * sizeof(SFesAccIndex)); + for (j = 0; j < RtuPtr->m_MaxAccIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pAccIndex = RtuPtr->m_pAccIndex + j; + pAccIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + pAccIndex = RtuPtr->m_pAccIndex + j; + pAccIndex->PointNo = VecAccParam[j].PointNo; + pAccIndex->PIndex = j; + if ((pAccIndex->PointNo >= 0) && (pAccIndex->PointNo < RtuPtr->m_MaxAccPoints)) + { + pAcc = RtuPtr->m_pAcc + pAccIndex->PointNo; + pAccIndex->DevId = pAcc->DevId; + pAccIndex->Param2 = pAcc->Param2; + pAccIndex->Param3 = pAcc->Param3; + pAccIndex->Param4 = pAcc->Param4; + pAccIndex->Used = 1; + } + } + } + else + { + RtuPtr->m_MaxAccIndex = 0; + LOGDEBUG("RtuNo:%d Acc protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + //READ MI TABLE + std::vector VecMiParam; + std::vector vecMiColumn; + std::vector vecMiOrder; + + vecMiColumn.push_back("rtu_no"); + vecMiColumn.push_back("dot_no"); + vecMiColumn.push_back("res_para_int1"); + vecMiColumn.push_back("res_para_int2"); + vecMiColumn.push_back("res_para_int3"); + vecMiColumn.push_back("res_para_int4"); + + vecMiOrder.push_back("res_para_int2"); + vecMiOrder.push_back("res_para_int3"); + + ret = RdbMiTable.open(m_ptrCFesBase->m_strAppLabel.c_str(), RT_FES_MI_TBL); + if (ret == false) + { + LOGERROR("RdbMiTable::Open error"); + return iotFailed; + } + ret = RdbMiTable.selectOneColumnOneOrder(con, VecMiParam, vecMiColumn, vecMiOrder);//默认顺序 + if (ret == false) + { + LOGERROR("RdbMiTable.selectNoCondition error!"); + return iotFailed; + } + ret = RdbMiTable.close(); + if (ret == false) + { + LOGERROR("RdbMiTable::close error"); + return iotFailed; + } + count = VecMiParam.size(); + if (count > 0) + { + //RtuPtr->m_MaxMiIndex = VecMiParam[count-1].Param1+1; + RtuPtr->m_MaxMiIndex = count; + if (RtuPtr->m_MaxMiIndex > 0) + { + //动态分配数据空间 + RtuPtr->m_pMiIndex = (SFesMiIndex*)malloc(RtuPtr->m_MaxMiIndex * sizeof(SFesMiIndex)); + if (RtuPtr->m_pMiIndex != NULL) + { + memset(RtuPtr->m_pMiIndex, 0xff, RtuPtr->m_MaxMiIndex * sizeof(SFesMiIndex)); + for (j = 0; j < RtuPtr->m_MaxMiIndex; j++)//2021-04-28 thxiao 初始化每个点的 Used=0;原来初始化为-1,但是如果使用if(Used)的判断,也会满足条件,所以对值进行初始化。 + { + pMiIndex = RtuPtr->m_pMiIndex + j; + pMiIndex->Used = 0; + } + for (j = 0; j < count; j++) + { + pMiIndex = RtuPtr->m_pMiIndex + j; + pMiIndex->PointNo = VecMiParam[j].PointNo; + pMiIndex->PIndex = j; + if ((pMiIndex->PointNo >= 0) && (pMiIndex->PointNo < RtuPtr->m_MaxMiPoints)) + { + pMi = RtuPtr->m_pMi + pMiIndex->PointNo; + pMiIndex->DevId = pMi->DevId; + pMiIndex->Param2 = pMi->Param2; + pMiIndex->Param3 = pMi->Param3; + pMiIndex->Param4 = pMi->Param4; + pMiIndex->Used = 1; + } + } + } + else + { + RtuPtr->m_MaxMiIndex = 0; + LOGDEBUG("RtuNo:%d Mi protocol point mapping create failed.\n", RtuPtr->m_Param.RtuNo); + } + } + } + + + //AO Param7关连AI PIndex序号,方便遥控回读当前值 + SFesAo *pAo; + for (i = 0; i < RtuPtr->m_MaxAoPoints; i++) + { + pAo = RtuPtr->m_pAo + i; + pAo->Param7 = -1; + if (!pAo->Used) + continue; + for (j = 0; j < RtuPtr->m_MaxAiIndex; j++) + { + pAiIndex = RtuPtr->m_pAiIndex + j; + pAi = RtuPtr->m_pAi + pAiIndex->PointNo; + if ((pAi->Param2 != 0) && (pAo->Param3 == pAi->Param3)) + { + pAo->Param7 = j; + // LOGDEBUG("pAo->PointNo=%d Param3=%d pAo->Param7=%d pAi->PointNo=%d", pAo->PointNo, pAo->Param3, pAo->Param7, pAi->PointNo); + break; + } + } + } + + return iotSuccess; +} diff --git a/product/src/fes/protocol/modbus_tcp_mz/ModbusTcpMZ.h b/product/src/fes/protocol/modbus_tcp_mz/ModbusTcpMZ.h new file mode 100644 index 00000000..cdae16c4 --- /dev/null +++ b/product/src/fes/protocol/modbus_tcp_mz/ModbusTcpMZ.h @@ -0,0 +1,53 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "ModbusTcpMZDataProcThread.h" + +/* +#ifndef MODBUSTCP_API_EXPORT +#ifdef OS_WINDOWS +#define MODBUSTCP_API G_DECL_EXPORT +#else + //LINUX下 默认情况下会使用C++ API函数命名规则(函数名会增加字符),使用extern "C"修饰后变为C的函数名,便于使用。 +#define MODBUSTCP_API extern "C" +#endif +#else +#define MODBUSTCP_API G_DECL_IMPORT +#endif +*/ + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API CModbusTcpMZ : public CProtocolBase +{ +public: + CModbusTcpMZ(); + ~CModbusTcpMZ(); + + vector m_CDataProcQueue; + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + + int m_initRtuFlag; + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + +private: + void ClearDataProcThreadByChanNo(int MainChanNo); + void ClearTcpClientdByChanNo(int MainChanNo,int ChanNo); + void SetTcpClientByChanNo(int MainChanNo,int ChanNo); + bool InitPointMapping(CFesRtuPtr RtuPtr); + void InitProcess(); +}; + diff --git a/product/src/fes/protocol/modbus_tcp_mz/ModbusTcpMZDataProcThread.cpp b/product/src/fes/protocol/modbus_tcp_mz/ModbusTcpMZDataProcThread.cpp new file mode 100644 index 00000000..cfdfcc60 --- /dev/null +++ b/product/src/fes/protocol/modbus_tcp_mz/ModbusTcpMZDataProcThread.cpp @@ -0,0 +1,4035 @@ +/* + @file CModbusTcpMZDataProcThread.cpp + @brief ModbusTcpMZ 数据处理线程类。 + 1、在ModbusTcpV3的基础上升级到云动力电力模组ModbusTcpMZ + 2、增加事故总的处理 + 3、RTU自定义参数从新定义 + 自定义参数1:收发事务处理标识处理方法 + 自定义参数2:发送延时时间,单位毫秒 + 自定义参数3:设备类型 + 4、LD-B10 m_clientTransID固定为AA0C、AA0D + 5、AO系数使用除法的方式精度会丢失(即使V1.3.4使用double类型也一样),所以系数改为乘法 + 6、SFesAo 中使用Param7作为AI的关连点,方便控制完成后立刻读取设置值。 + + @author thxiao + @history + +*/ +#include "ModbusTcpMZDataProcThread.h" +#include "pub_utility_api/I18N.h" + +using namespace iot_public; + +extern bool g_ModbusTcpMZIsMainFes; +extern bool g_ModbusTcpMZChanelRun; +const int g_ModbusTcpMZThreadTime = 10; + + +CModbusTcpMZDataProcThread::CModbusTcpMZDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan): + CTimerThreadBase("ModbusTcpMZDataProcThread", g_ModbusTcpMZThreadTime,0,true) +{ + CFesRtuPtr pRtu; + int RtuNo; + + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + + + m_AppData.comState = CN_FesRtuComDown; + m_AppData.setCmdCount = 0; + m_ClearClientFlag = 0; + m_AppData.m_TransIDFailCount = 0;//2022-05-09 thxiao m_AppData.m_TransIDFailCount 需要初始化 + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL)) + { + return ; + } + + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + //2020-08-18 thxiao 一个通道挂多个设备的规约,初始化时需要把标志置上在线状态,保证第一次每个设备都可以发送指令。 + m_ptrCFesBase->ClearRtuOfflineFlag(m_ptrCFesChan); + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((pRtu = GetRtuDataByRtuNo(RtuNo)) != NULL) + { + InitProtocolBlockDataIndexMapping(pRtu);//2021-09-26 ljj 每个RTU都需要初始化 + m_ptrCFesBase->WriteRtuSatus(pRtu, CN_FesRtuComDown); + pRtu->SetOfflineFlag(CN_FesRtuComDown); + } + } + + m_AppData.SettimemSec = getMonotonicMsec(); + m_AppData.SettimemSecReset = 120000; //2min + m_AppData.setTimeFlag = 1; + + AlarmInit(); + + RTUABBTripInit(m_ptrCFesRtu); + m_AppData.CBEvent.Type = 0; + m_AppData.CBEvent.Sec = 0; + m_AppData.CBEvent.mSec = 0; + + + /*************************** TCP PROCESS *****************************************************/ + m_timerCountReset = 2000 / g_ModbusTcpMZThreadTime; //2S COUNTER + m_timerCount = 0; + + m_ptrTcpClient = NULL; + m_ptrTcpClient = boost::make_shared(ptrCFesChan); + if (m_ptrTcpClient == NULL) + { + LOGERROR("create CComTcpClientPtr error!", ptrCFesChan->m_Param.ChanNo); + LOGDEBUG("CModbusTcpMZDataProcThread::CModbusTcpMZDataProcThread() ChanNo=%d 创建失败", ptrCFesChan->m_Param.ChanNo); + return; + } + /**************************************************************************************/ + + LOGDEBUG("CModbusTcpMZDataProcThread::CModbusTcpMZDataProcThread() ChanNo=%d 创建", m_ptrCurrentChan->m_Param.ChanNo); +} + + +CModbusTcpMZDataProcThread::~CModbusTcpMZDataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + m_ptrTcpClient->TcpClose(m_ptrCurrentChan); + if (m_ptrCFesChan != NULL) + { + m_ptrCFesChan->SetLinkStatus(CN_FesChanDisconnect); + // m_ptrCFesChan->ClearStatusInit(); + LOGDEBUG("PortNo=%d IP1=%s IP2=%s退出", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[1].NetDesc); + } + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + LOGDEBUG("CModbusTcpMZDataProcThread::~CModbusTcpMZDataProcThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); + +} + +/** + * @brief CModbusTcpMZDataProcThread::beforeExecute + * + */ +int CModbusTcpMZDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief CModbusTcpMZDataProcThread::execute + + */ +void CModbusTcpMZDataProcThread::execute() +{ + int netStatus; + + if(!g_ModbusTcpMZChanelRun) + return; + + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + + if(m_ptrCurrentChan == NULL) + return; + + if (m_timerCount++ >= m_timerCountReset) + { + m_timerCount = 0;// sec is ready + netStatus = m_ptrTcpClient->GetNetStatus(); + switch (netStatus) + { + case CN_FesChanDisconnect: + m_ptrTcpClient->TcpConnect(m_ptrCurrentChan); + break; + default: + break; + } + + TimerProcess(); + + } + + SetSendCmdFlag(); + + if(SendProcess()>0) + { + RecvNetData(); + } + +} + +/* + @brief 执行quit函数前的处理 + */ +void CModbusTcpMZDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); +} + +/** + * @brief CModbusTcpMZDataProcThread::SendProcess + * ModbusTcpMZ 发送处理 + * @return 返回发送数据长度 + */ +int CModbusTcpMZDataProcThread::SendProcess() +{ + int retLen = 0; + + if(m_ptrCurrentChan==NULL) + return iotFailed; + + //有多个RTU时,才需要获取当前最新的RTU结构,否则m_ptrCFesRtu在构造函数初始化。 + if(m_ptrCFesChan->m_RtuNum >1) + { + //需要得到当前的RTU数据结构 + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + } + + //2020-04-20 thxiao 不再判断通信状态,因为通信中断在接收函数判断,导致无法设置通信中断标志。 + //if(m_ptrCurrentChan->m_LinkStatus == CN_FesChanConnect) + //{ + if((retLen=InsertCmdProcess())>0) + return retLen; + + if((retLen=PollingCmdProcess())>0) + return retLen; + //} + + if (m_ptrCurrentChan->m_LinkStatus != CN_FesChanConnect) + { + ErrorControlRespProcess(); //网络断开时有控制命令来需要做异常处理 + } + return retLen; + +} + +/** + * @brief CModbusTcpMZDataProcThread::RecvNetData + * ModbusTcpMZ TCP 接收处理 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CModbusTcpMZDataProcThread::RecvNetData() +{ + int count =20; + int FunCode,DevAddr,ExpectLen; + byte Data[512]; + int recvLen,Len,i; + + if(m_ptrCurrentChan==NULL) + return iotFailed; + + DevAddr = m_AppData.lastCmdData[6]; + FunCode = m_AppData.lastCmdData[7]; + //int ChanNo = m_ptrCurrentChan->m_Param.ChanNo; + Len=0; + recvLen=0; + count = m_ptrCurrentChan->m_Param.RespTimeout/10; + if(count<=10) + count = 10;//最小响应超时为100毫秒 + ExpectLen =0; + for(i=0;iRxData(m_ptrCurrentChan); + + recvLen = m_ptrCurrentChan->ReadRxBufData(500-Len,&Data[Len]);//数据缓存在 + if(recvLen<=0) + { + if(ExpectLen==0) + continue; + else//没有后续数据,退出接收 + if((Len>=ExpectLen)&&(ExpectLen>0)) + { + //LOGDEBUG("没有后续数据,退出接收 ChanNo=%d",m_ptrCFesChan->m_Param.ChanNo); + break; + } + } + + m_ptrCurrentChan->DeleteReadRxBufData(recvLen);//清除已读取的数据 + Len += recvLen; + if(Len >8) + { + //cmd = Data[7]; + if(Data[7]&0x80)//ERROR + ExpectLen = 9; + else + { + switch(Data[7]) + { + case 0x01: + case 0x02: + ExpectLen = Data[8]+9; + break; + case 0x05: + case 0x06: + case 0x10: + ExpectLen = 12; + break; + default://0x03\0x04 + ExpectLen = Data[8]+9; + } + } + } + /*if((Len>=ExpectLen)&&(ExpectLen>0)) + { + break; + }*/ + } + if(Len>0) + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo,Data,Len,CN_SFesSimComFrameTypeRecv); + + if(Len==0)//接收不完整,重发数据 + { + m_ptrCurrentChan->SetResendNum(1); + if(m_ptrCurrentChan->m_ResendNum > m_ptrCurrentChan->m_Param.RetryTimes) + { + m_ptrCurrentChan->ResetResendNum(); + if(m_AppData.comState == CN_FesRtuNormal) + { + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuComDown); + m_AppData.comState = CN_FesRtuComDown; + } + m_ptrTcpClient->TcpClose(m_ptrCurrentChan); + } + CmdControlRespProcess(NULL,0,0); + NextRtuIndex(m_ptrCFesChan); + return iotFailed; + } + //长度、地址、功能码 都正确则认为数据正确。 + if ((Len == ExpectLen) && (DevAddr == Data[6]) && (FunCode == (Data[7] & 0x7f))) + { + //2022-03-31 thxiao 为了避免帧错位的情况出现,事务处理标识符不同,放弃处理,并且清空接收队列。 + uint16 clientTransID; + clientTransID = (uint16)Data[0] << 8; + clientTransID |= (uint16)Data[1]; + clientTransID++; + //2022-09-02 thxiao MODBUSTCPV2 目前没有推广使用,所以默认为判断clientTransID。 + if ((m_ptrCFesRtu->m_Param.ResParam1 == 0) && (clientTransID != m_ptrCFesRtu->m_clientTransID)) + { + m_ptrCurrentChan->ClearDataBuf();//清除缓冲的数据 + if (m_AppData.m_TransIDFailCount++ > 5)//2022-04-22 thxiao clientTransID error exceed max times close socket + { + m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao + m_ptrTcpClient->TcpClose(m_ptrCurrentChan); + LOGDEBUG("frame clientTransID error exceed max times close socket !", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + LOGDEBUG("clientTransID=%d m_ptrCFesRtu->m_clientTransID=%d discard the frame!", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + else//2022-09-02 thxiao 科华有UPS设备响应是事务处理标识符+1,增加这种特殊的判断 + if ((m_ptrCFesRtu->m_Param.ResParam1 == 1) && (clientTransID != (m_ptrCFesRtu->m_clientTransID+1))) + { + m_ptrCurrentChan->ClearDataBuf();//清除缓冲的数据 + if (m_AppData.m_TransIDFailCount++ > 5)//2022-04-22 thxiao clientTransID error exceed max times close socket + { + m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao + m_ptrTcpClient->TcpClose(m_ptrCurrentChan); + LOGDEBUG("frame clientTransID error exceed max times close socket !", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + LOGDEBUG("clientTransID=%d m_ptrCFesRtu->m_clientTransID=%d discard the frame!", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + else + { + m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao + m_ptrCurrentChan->ResetResendNum(); + m_ptrCurrentChan->SetRxNum(1); + RecvDataProcess(&Data[6], Len - 6);//保文头不再处理 + if (m_AppData.comState == CN_FesRtuComDown) + { + m_AppData.comState = CN_FesRtuNormal; + m_ptrCFesRtu->WriteRtuPointsComStatus(CN_FesRtuNormal); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuNormal); + } + //next RTU + NextRtuIndex(m_ptrCFesChan); + } + return iotSuccess; + } + else + { + m_ptrCurrentChan->SetErrNum(1); + //next RTU + CmdControlRespProcess(NULL, 0, 0); + NextRtuIndex(m_ptrCFesChan); + return iotFailed; + } +} + +/** + * @brief CModbusTcpMZDataProcThread::InsertCmdProcess + * 收到SCADA的控制命令,插入命令处理。组织ModbusTcpMZ命令帧,并返回操作消息 + * @return 实际发送数据长度 + */ +int CModbusTcpMZDataProcThread::InsertCmdProcess() +{ + byte data[256]; + int dataSize,retSize; + int len =0; + + if(m_ptrCFesRtu == NULL) + return 0; + + if(g_ModbusTcpMZIsMainFes==false)//备机不作任何操作 + return 0; + + dataSize = sizeof(data); + retSize = 0; + if(m_ptrCFesRtu->GetRxDoCmdNum()>0) + { + retSize = DoCmdProcess(data,dataSize); + } + else + if(m_ptrCFesRtu->GetRxAoCmdNum()>0) + { + retSize = AoCmdProcess(data,dataSize); + } + else + if(m_ptrCFesRtu->GetRxMoCmdNum()>0) + { + retSize = MoCmdProcess(data,dataSize); + } + else + if(m_ptrCFesRtu->GetRxSettingCmdNum()>0) + { + retSize = SettingCmdProcess(); + } + else + if(m_ptrCFesRtu->GetRxDefCmdNum()>0) + { + retSize = DefCmdProcess(data,dataSize); + } + else + if (m_AppData.setTimeFlag == 1) + { + retSize = SetTimeProcess(m_ptrCFesRtu, data, dataSize); + m_AppData.setTimeFlag = 0; + } + + if(retSize > 0) + { + //send data to net + len = SendDataToPort(data,retSize); + } + + return len; +} + +/** + * @brief CModbusTcpMZDataProcThread::PollingCmdProcess + * 循环发送读取数据命令,组织ModbusTcpMZ命令帧。 + * @param Data 发送数据区 + * @param dataSize 发送数据区长度 + * @return 实际发送数据长度 + */ +int CModbusTcpMZDataProcThread::PollingCmdProcess() +{ + byte Data[256]; + SModbusCmd cmd; + int writex; + int len=0; + + if(GetPollingCmd(&cmd)==iotFailed) + { + //LOGERROR("CModbusTcpMZDataProcThread::PollingCmdProcess() return 0"); + return 0; + } + memcpy(&m_AppData.lastCmd,&cmd,sizeof(SModbusCmd)); + writex = 7; + Data[writex++] = cmd.FunCode; + Data[writex++] = (cmd.StartAddr>>8)&0x00ff; + Data[writex++] = cmd.StartAddr&0x00ff; + Data[writex++] = (cmd.DataLen>>8)&0x00ff; + Data[writex++] = cmd.DataLen&0x00ff; + + //2023-03-06 thxiao LD-B10 m_clientTransID固定为AA0C、AA0D + if (m_ptrCFesRtu->m_Param.ResParam3 == CN_ModbusRtuMZ_LDB10) + { + if (cmd.FunCode == 0x03) + m_ptrCFesRtu->m_clientTransID = 0xAA0C; + else + m_ptrCFesRtu->m_clientTransID = 0xAA0D; + } + + FillHeader(Data, writex - 6); + + //send data to net + len = SendDataToPort(Data,writex); + m_AppData.state = CN_ModbusTcpMZAppState_idle; + return len; +} + +/** + * @brief CModbusTcpMZDataProcThread::FillHeader + * 组帧头 + * @param Data 数据区 + * @param Size 数据区长度 + */ +void CModbusTcpMZDataProcThread::FillHeader(byte *Data, int DataSize) +{ + /* MBAP 头编码*/ + /* + the ModbusTcpMZ TCP/IP ADU(MBAP) Header format: + +---------------+---------------+----------+----------+--------+--------+--------+ + |clientTransIDH |clientTransIDL |prtclNoH | prtclNoL |lengthH |lengthL | unitID | + +---------------+---------------+----------+----------+--------+--------+--------+ + + short clientTransID; 事务处理标识符 + short prtclNo; 协议标识符( 0x0000 = ModbusTcpMZ协议) + short length; 长度 + char unitID; 单元标识符,为远端设备的ModbusTcpMZ 从站地址. + 当对直接连接到TCP/IP网络上的ModbusTcpMZ服务 + 器寻址时,建议不要在"单元标识符"域使 + 用有效的ModbusTcpMZ从站地址,使用0xFF作为无效值 + + */ + + Data[0] = (byte)((m_ptrCFesRtu->m_clientTransID >> 8) & 0xff); + Data[1] = (byte)(m_ptrCFesRtu->m_clientTransID & 0xff); + Data[2] = 0x00; + Data[3] = 0x00; + Data[4] = (char)((DataSize >> 8) & 0x00ff); + Data[5] = (char)(DataSize & 0x00ff); + Data[6] = m_ptrCFesRtu->m_Param.RtuAddr; + m_ptrCFesRtu->m_clientTransID++; + +} + +/** + * @brief CModbusTcpMZDataProcThread::SendDataToPort + * 数据发送到发送缓冲区。 + * 如是主通道,直接使用m_ptrCFesChan通道结构;如果是备用通道,需要获取当前使用通道,在发送数据。 + * @param Data 数据区 + * @param Size 数据区长度 + */ +int CModbusTcpMZDataProcThread::SendDataToPort(byte *Data, int Size) +{ + int len = 0; + + if(m_ptrCurrentChan==NULL) + return 0; + + //2021-02-05 thxiao 测试过程中发现数据接收会错位,因为协议是POLLING的,所以当发送数据包前,数据缓冲清空。 + m_ptrCurrentChan->ClearDataBuf(); + + //2020-04-20 thxiao 通信不正常,不发送数据 + if (m_ptrCurrentChan->m_LinkStatus != CN_FesChanConnect)//2021-01-22 thxiao + return Size;//2021-06-04 thxiao 因为通信中断在接收函数判断,导致无法设置通信中断标志 + + //2021-04-30 thxiao RTU PARAM2 = 1000 为延时发送时间,单位毫秒 + if (m_ptrCFesRtu->m_Param.ResParam2 > 0) + SleepmSec(m_ptrCFesRtu->m_Param.ResParam2); + + len = m_ptrTcpClient->TxData(m_ptrCurrentChan,Size,Data); + + //saved last send cmd + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo,Data,Size,CN_SFesSimComFrameTypeSend); + m_ptrCurrentChan->SetTxNum(1); + + memcpy(&m_AppData.lastCmdData[0],Data,Size); + m_AppData.lastCmdDataLen = Size; + return Size; + +} + +/** + * @brief CModbusTcpMZDataProcThread::DoCmdProcess + * 接收SCADA传来的DO控制命令,组织ModbusTcpMZ命令帧,并返回操作消息。 + * @param Data 发送数据区 + * @param dataSize 发送数据区长度 + * @return 实际发送数据长度 + */ +int CModbusTcpMZDataProcThread::DoCmdProcess(byte *Data, int /*dataSize*/) +{ + SFesRxDoCmd cmd; + SFesTxDoCmd retCmd; + SFesDo *pDo; + int writex; + + writex = 0; + memset(&retCmd,0,sizeof(retCmd)); + memset(&cmd,0,sizeof(cmd)); + if(m_ptrCFesRtu->ReadRxDoCmd(1,&cmd)==1) + { + //get the cmd ok + //2019-02-21 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + + //2020-02-18 thxiao 遥控增加五防闭锁检查 + if (m_ptrCFesRtu->CheckWuFangDoStatus(cmd.PointID) == 0)//闭锁 + { + //return failed to scada + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d 闭锁").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d 闭锁", m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + return 0; + } + + if ((pDo = GetFesDoByPointNo(m_ptrCFesRtu, cmd.PointID)) != NULL) + { + if(cmd.CtrlActType == CN_ControlExecute) + { + writex = 7; + Data[writex++] = pDo->Param2;/*command*/ + if(pDo->Param2==0x05) + { + //2020-07-21 thxiao 增加可配置的遥控命令 + if (pDo->Attribute & CN_FesDo_Special)//点属性判断特殊遥控 + { + if (cmd.iValue == 1)//CLOSE + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff;//合值 + Data[writex++] = pDo->Param4 & 0x00ff;//合值 + } + else//OPEN + { + Data[writex++] = (pDo->Param5 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param5 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param6 >> 8) & 0x00ff;//分值 + Data[writex++] = pDo->Param6 & 0x00ff;//分值 + } + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff; + Data[writex++] = pDo->Param3 & 0x00ff; + if (cmd.iValue == 1) + { + Data[writex++] = 0xff;/*05命令其值为,0xff00 表示合闸*/ + Data[writex++] = 0x00; + } + else + { + Data[writex++] = 0x00;/*05命令其值为,0x0000表示分闸*/ + Data[writex++] = 0x00; + } + } + } + else if(pDo->Param2==0x06) + { + //Attribute + //Bit0 遥控类型。0脉冲输出,1自保持输出(需要程序清零)。 + //Bit1 遥控复归。0:表示普通遥控,1:表示复归。 + //Bit2 特殊遥控点0:表示普通遥控,1:特殊遥控点。 + + if (pDo->Attribute & CN_FesDo_Special)//点属性判断特殊遥控 + { + if (cmd.iValue == 1)//CLOSE + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param3 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param4 >> 8) & 0x00ff;//合值 + Data[writex++] = pDo->Param4 & 0x00ff;//合值 + } + else//OPEN + { + Data[writex++] = (pDo->Param5 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pDo->Param5 & 0x00ff;//寄存器起始地址L + Data[writex++] = (pDo->Param6 >> 8) & 0x00ff;//分值 + Data[writex++] = pDo->Param6 & 0x00ff;//分值 + } + } + else + { + Data[writex++] = (pDo->Param3 >> 8) & 0x00ff; + Data[writex++] = pDo->Param3 & 0x00ff; + if (cmd.iValue == 1) + { + cmd.iValue <<= pDo->Param4; + Data[writex++] = ((cmd.iValue >> 8) & 0xff);/*06命令按寄存器bit控制PLC(复归式)*/ + Data[writex++] = (cmd.iValue & 0xff); + } + else + { + Data[writex++] = 0x00;/*06命令,值为0,PLC(复归式)不动作*/ + Data[writex++] = 0x00; + } + } + } + else + return 0; + FillHeader(Data, writex - 6); + memcpy(&m_AppData.doCmd,&cmd,sizeof(cmd)); + m_AppData.lastCotrolcmd = CN_ModbusTcpMZDoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_waitControlResp; + LOGDEBUG ("DO遥控执行成功 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); + } + else if(cmd.CtrlActType == CN_ControlSelect) //遥控选择作为日后扩展用 + { + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlSuccess; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("DO遥控选择成功 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpMZDoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_waitControlResp; + } + else + { + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + } + } + else + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N("遥控失败!RtuNo:%d 找不到遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("DO遥控失败 !RtuNo:%d 找不到遥控点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + } + } + return writex; +} + +/** + * @brief CModbusTcpMZDataProcThread::AoCmdProcess + * 接收SCADA传来的AO控制命令,组织ModbusTcpMZ命令帧,并返回操作消息。 + * @param Data 发送数据区 + * @param dataSize 发送数据区长度 + * @return 实际发送数据长度 + */ +int CModbusTcpMZDataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) +{ + SFesRxAoCmd cmd; + SFesTxAoCmd retCmd; + short setValue; + SFesAo *pAo=NULL; + int writex; + float fValue,tempValue; + uint32 ui32Value; + int failed; + int iValue; + uint16 UnValue16; + + writex = 0; + if(m_ptrCFesRtu->ReadRxAoCmd(1,&cmd)==1) + { + //get the cmd ok + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + if ((pAo = GetFesAoByPointNo(m_ptrCFesRtu, cmd.PointID)) != NULL) + { + if(cmd.CtrlActType == CN_ControlExecute) + { + tempValue = cmd.fValue; + failed = 0; + if(pAo->Coeff!=0) + { + //2023-3-16 thxiao 系数使用除法的方式精度会丢失(即使V1.3.4使用double类型也一样),所以系数改为乘法 + //fValue=(tempValue-pAo->Base)/pAo->Coeff; + fValue = tempValue*pAo->Coeff; + + if(pAo->MaxRange>pAo->MinRange) + { + if ((fValue < pAo->MinRange) || (fValue > pAo->MaxRange)) + { + //2019-08-30 thxiao 增加失败详细描述 + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d 量程越限").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); + failed = 1; + } + } + else + { + sprintf(retCmd.strParam, I18N("遥调失败,量程配置错误,最大量程<=最小量程!").str().c_str()); + failed = 1; + } + } + else + { + //2019-08-30 thxiao 增加失败详细描述 + sprintf(retCmd.strParam, I18N("遥调失败!RtuNo:%d 遥调点:%d 系数为0").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, cmd.PointID); + failed = 1; + } + + if(failed == 1) + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + //sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("AO遥调失败,点系数为0或者量程越限!RtuNo:%d 遥调点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + } + else + { + writex = 7; + if(pAo->Param2==0x10) + { + memcpy(&iValue, &fValue, sizeof(fValue)); + //LOGDEBUG("iValue=%x fValue = %f", iValue, fValue); + if (pAo->Param4 == AI_Word_HL)//2022-03-31 thxiao 增加0x10 设置命令16位 + { + Data[writex++] = pAo->Param2; //command 0x10 + Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address + Data[writex++] = pAo->Param3 & 0x00ff; + Data[writex++] = 0x00; + Data[writex++] = 0x01; + Data[writex++] = 0x02; + setValue = (short)fValue; + Data[writex++] = (byte)(setValue >> 8); + Data[writex++] = (byte)setValue; + } + else + { + Data[writex++] = pAo->Param2; //command 0x10 + Data[writex++] = (pAo->Param3 >> 8) & 0x00ff; //address + Data[writex++] = pAo->Param3 & 0x00ff; + Data[writex++] = 0x00; + Data[writex++] = 0x02; + Data[writex++] = 0x04; + switch (pAo->Param4) + { + case AI_DWord_LL: + case AI_UDWord_LL: + iValue = (int)fValue; + Data[writex++] = (byte)iValue; + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 24); + break; + case AI_Float_LL: + memcpy(&iValue, &fValue, sizeof(fValue)); + Data[writex++] = (byte)iValue; + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 24); + break; + case AI_DWord_HH: + case AI_UDWord_HH: + iValue = (int)fValue; + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + break; + case AI_Float_HH: + memcpy(&iValue, &fValue, sizeof(fValue)); + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + break; + case AI_DWord_LH: + case AI_UDWord_LH: + iValue = (int)fValue; + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + break; + case AI_Float_LH: + memcpy(&iValue, &fValue, sizeof(fValue)); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + break; + default: + iValue = (int)fValue; + Data[writex++] = (byte)(iValue >> 24); + Data[writex++] = (byte)(iValue >> 16); + Data[writex++] = (byte)(iValue >> 8); + Data[writex++] = (byte)iValue; + break; + } + } + } + else + { + setValue = (short)fValue; + UnValue16 = fValue; + Data[writex++] = pAo->Param2; //command 0x06 + Data[writex++] = (pAo->Param3>>8)&0x00ff; //address + Data[writex++] = pAo->Param3&0x00ff; + switch (pAo->Param4) + { + case AI_Word_HL: + Data[writex++] = (setValue >> 8) & 0x00ff; + Data[writex++] = setValue & 0x00ff; + break; + case AI_UWord_HL: + Data[writex++] = (UnValue16 >> 8) & 0x00ff; + Data[writex++] = UnValue16 & 0x00ff; + break; + case AI_Word_LH: + Data[writex++] = setValue & 0x00ff; + Data[writex++] = (setValue >> 8) & 0x00ff; + break; + case AI_UWord_LH: + Data[writex++] = UnValue16 & 0x00ff; + Data[writex++] = (UnValue16 >> 8) & 0x00ff; + break; + default: + Data[writex++] = (setValue >> 8) & 0x00ff; + Data[writex++] = setValue & 0x00ff; + break; + } + } + + FillHeader(Data, writex - 6); + memcpy(&m_AppData.aoCmd,&cmd,sizeof(cmd)); + m_AppData.lastCotrolcmd = CN_ModbusTcpMZAoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_waitControlResp; + LOGDEBUG ("AO遥调成功 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.fValue,cmd.RtuName,cmd.PointID); + } + } + else + { + + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + retCmd.CtrlActType = cmd.CtrlActType; + LOGDEBUG ("AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.fValue,cmd.RtuName,cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + } + } + else + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N("遥调失败!RtuNo:%d 找不到遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("AO遥调失败!RtuNo:%d 找不到遥调点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + } + } + return writex; +} + +/** + * @brief CModbusTcpMZDataProcThread::MoCmdProcess + * 接收SCADA传来的MO控制命令,组织ModbusTcpMZ命令帧,并返回操作消息。 + * @param Data 发送数据区 + * @param dataSize 发送数据区长度 + * @return 实际发送数据长度 + */ +int CModbusTcpMZDataProcThread::MoCmdProcess(byte *Data, int /*dataSize*/) +{ + SFesRxMoCmd cmd; + SFesTxMoCmd retCmd; + SFesMo *pMo; + int writex,iValue,failed; + + writex = 0; + if(m_ptrCFesRtu->ReadRxMoCmd(1,&cmd)==1) + { + LOGDEBUG ("cmd.TableName :%s cmd.ColumnName : %s cmd.RtuName : %s cmd.TagName : %s",cmd.TableName,cmd.ColumnName,cmd.RtuName,cmd.TagName); + LOGDEBUG ("cmd.PointID = %d cmd.CtrlActType = %d ",cmd.PointID,cmd.CtrlActType); + //2019-03-18 thxiao 为适应转发规约增加 + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + //get the cmd ok + //memset(&retCmd,0,sizeof(retCmd)); + if((pMo = GetFesMoByPIndex(m_ptrCFesRtu,cmd.PointID))!=NULL) + { + if(cmd.CtrlActType == CN_ControlExecute) + { + failed = 0; + if(pMo->Coeff!=0) + { + iValue=(cmd.iValue-pMo->Base)/pMo->Coeff; + if(pMo->MaxRange>pMo->MinRange) + { + if((iValueMinRange)||(iValue>pMo->MaxRange)) + failed = 1; + } + } + else + failed = 1; + + if(failed == 1) + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N("混合量输出失败!RtuNo:%d 找不到混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + LOGDEBUG ("MO混合量输出失败,点系数为0或者量程越限!RtuNo:%d 混合量输出点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + } + else + { + writex = 7; + if(pMo->Param2==0x10) + { + Data[writex++] = pMo->Param2; //command 0x10 + Data[writex++] = (pMo->Param3>>8)&0x00ff; //address + Data[writex++] = pMo->Param3&0x00ff; + Data[writex++] = 0x00; + Data[writex++] = 0x01; + Data[writex++] =0x02; + Data[writex++] = (iValue>>8)&0x00ff; + Data[writex++] = iValue&0x00ff; + } + else//0x06 + { + Data[writex++] = pMo->Param2; //command 0x06 + Data[writex++] = (pMo->Param3>>8)&0x00ff; //address + Data[writex++] = pMo->Param3&0x00ff; + Data[writex++] = (iValue>>8)&0x00ff; + Data[writex++] = iValue&0x00ff; + } + FillHeader(Data, writex - 6); + memcpy(&m_AppData.moCmd,&cmd,sizeof(cmd)); + m_AppData.lastCotrolcmd = CN_ModbusTcpMZMoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_waitControlResp; + LOGDEBUG ("MO混合量输出成功 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); + } + } + else + { + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlFailed; + retCmd.CtrlActType = cmd.CtrlActType; + sprintf(retCmd.strParam,I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + + LOGDEBUG ("MO混合量执行失败 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",cmd.CtrlActType,cmd.iValue,cmd.RtuName,cmd.PointID); + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + } + } + else + { + //return failed to scada + strcpy(retCmd.TableName,cmd.TableName); + strcpy(retCmd.ColumnName,cmd.ColumnName); + strcpy(retCmd.TagName,cmd.TagName); + strcpy(retCmd.RtuName,cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + sprintf(retCmd.strParam,I18N("混合量输出失败!RtuNo:%d 找不到混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + + LOGDEBUG ("MO混合量输出失败!RtuNo:%d 找不到混合量输出点:%d",m_ptrCFesRtu->m_Param.RtuNo,cmd.PointID); + retCmd.CtrlActType = cmd.CtrlActType; + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&retCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&retCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + } + } + LOGDEBUG("CModbusTcpMZDataProcThread::MoCmdProcess"); + return writex; +} + +/** + * @brief CModbusTcpMZDataProcThread::SettingCmdProcess + * 接收SCADA传来的Setting控制命令,组织ModbusTcpMZ命令帧,并返回操作消息。 + * @param Data 发送数据区 + * @param dataSize 发送数据区长度 + * @return 实际发送数据长度 + */ +int CModbusTcpMZDataProcThread::SettingCmdProcess() +{ + return 0; +} + +/** + * @brief CModbusTcpMZDataProcThread::DefCmdProcess + * 接收SCADA传来的自定义控制命令,组织ModbusTcpMZ命令帧,并返回操作消息。 + * @param Data 发送数据区 + * @param dataSize 发送数据区长度 + * @return 实际发送数据长度 + */ +int CModbusTcpMZDataProcThread::DefCmdProcess(byte *Data, int dataSize) +{ + SFesRxDefCmd cmd; + int writex; + + writex = 0; + if(m_ptrCFesRtu->ReadRxDefCmd(1,&cmd)==1) + { + //get the cmd ok,do something yourself +#if 0 + m_AppData.defCmd = cmd; + LOGDEBUG("TableName:%s ColumnName:%s TagName:%s RtuName:%s DevId:%d",cmd.TableName,cmd.ColumnName,cmd.TagName,cmd.RtuName,cmd.DevId); + int count = cmd.VecCmd.size(); + for(int k=0;km_Param.ModbusCmdBuf.pCmd==NULL) + { + return iotFailed; + } + //2020-05-14 thxiao 如果没有配置块,则轮训下一个设备。 + if (m_ptrCFesRtu->m_Param.ModbusCmdBuf.num == 0) + NextRtuIndex(m_ptrCFesChan); + + while(countm_Param.ModbusCmdBuf.num) + { + Cmd = m_ptrCFesRtu->m_Param.ModbusCmdBuf.pCmd+m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx; + if(Cmd->CommandSendFlag==true) + { + memcpy(pCmd, Cmd, sizeof(SModbusCmd)); + Cmd->CommandSendFlag = false; + ComFlag = true; + //LOGDEBUG("GetPollingCmd chan=%d readx=%d \n", m_ptrCFesRtu->m_Param.ChanNo, m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx); + } + m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx++; + if(m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx >= m_ptrCFesRtu->m_Param.ModbusCmdBuf.num) + m_ptrCFesRtu->m_Param.ModbusCmdBuf.readx = 0; + count++; + if (ComFlag) + return iotSuccess; + + } + return iotFailed; +} + +/** + * @brief CModbusTcpMZDataProcThread::RecvDataProcess + * @param Data + * @param DataSize + * @return 成功:iotSuccess 失败:iotFailed + */ +int CModbusTcpMZDataProcThread::RecvDataProcess(byte *Data,int DataSize) +{ + int FunCode; + + FunCode=Data[1]; + if(FunCode&0x80) + { + CmdControlRespProcess(NULL,0,0); + return iotSuccess; + } + + switch(FunCode) + { + case 0x01: + case 0x02: + Cmd01RespProcess(Data); + break; + case 0x03: + case 0x04: + Cmd03RespProcess(Data); + CmdTypeHybridProcess(Data, DataSize); + break; + case 0x05: + Cmd05RespProcess(Data,DataSize); + break; + case 0x06: + Cmd06RespProcess(Data,DataSize); + break; + case 0x10: + Cmd10RespProcess(Data,DataSize); + break; + default: + return iotFailed; + break; + } + return iotSuccess; +} + +/** +* @brief CModbusTcpMZDataProcThread::Cmd01RespProcess +* 命令0x01 0x02的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* @param Data 接收的数据 +*/ +void CModbusTcpMZDataProcThread::Cmd01RespProcess(byte *Data) +{ + int FunCode; + byte bitValue, byteValue; + int i,StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, SoeCount, PointIndex1, PointIndex2; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[50]; + uint64 mSec; + int SZFlag = 0; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + if (m_DiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd01RespProcess: 未找到blockId=%d的数字量数据块,不解析该帧数据",m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + for (i = StartPointNo; i <= EndPointNo; i++) + { + pDi = GetFesDiByPIndex(m_ptrCFesRtu, i); + if (pDi == NULL) + continue; + + PointIndex1 = (pDi->Param3 - m_AppData.lastCmd.StartAddr)/8; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex1 < 0) || (PointIndex1 > MODBUSTCPV3_K_MAX_POINT_INDEX*1.5)) + { + continue; + } + + byteValue = Data[3 + PointIndex1]; + PointIndex2 = (pDi->Param3 - m_AppData.lastCmd.StartAddr) % 8; + bitValue = (byteValue >> PointIndex2) & 0x01; + + if (pDi->Revers) + bitValue ^= 1; + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + StartPointNo = pDi->Param1 + 1; + if ((bitValue != pDi->Value) && (g_ModbusTcpMZIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + if(pDi->Param5&0x01) + SZFlag = 1; + + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + //更新点值 + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } + if (SZFlag == 1) + AlarmCalc(); + +} + + +/** +* @brief CModbusTcpMZDataProcThread::Cmd03RespProcess +* 命令0x03 0x04的处理。FES点表必须按每个请求命令的起始地址,从小到大顺序排列。 +* @param Data 接收的数据 +* @param DataSize 接收的数据长度 +*/ +void CModbusTcpMZDataProcThread::Cmd03RespProcess(byte *Data) +{ + int FunCode, diValue, bitValue; + int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, SoeCount, PointIndex; + SFesDi *pDi; + SFesRtuDiValue DiValue[50]; + SFesChgDi ChgDi[50]; + SFesSoeEvent SoeEvent[100]; + uint64 mSec; + SFesAi *pAi; + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + SFesMi *pMi; + SFesRtuMiValue MiValue[100]; + SFesChgMi ChgMi[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + int64 accValue; + int miValue; + int SZFlag = 0; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + SoeCount = 0; + if ((m_AppData.lastCmd.Type == DI_UWord_HL) || (m_AppData.lastCmd.Type == DI_UWord_LH))//DI + { + //ABB 断路器事件处理 + if ((m_ptrCFesRtu->m_Param.ResParam3 == CN_ModbusRtuMZ_ABBCB) && (StartAddr >= 3500) && (StartAddr <= 4500)) + { + ABBCBEventProcess(m_ptrCFesRtu, Data); + return; + } + + if (m_DiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的数字量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_DiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + for (i = StartPointNo; i<=EndPointNo; i++) + { + pDi = GetFesDiByPIndex(m_ptrCFesRtu, i); + if (pDi == NULL) + continue; + + PointIndex = pDi->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + if (m_AppData.lastCmd.Type == DI_UWord_HL) + { + diValue = (int)Data[3 + PointIndex * 2] << 8; + diValue |= (int)Data[4 + PointIndex * 2]; + } + else//DI_UWord_LH + { + diValue = (int)Data[4 + PointIndex * 2] << 8; + diValue |= (int)Data[3 + PointIndex * 2]; + } + + if (m_AppData.lastCmd.Param1 == 1) //数据块自定义#1 = 1,遥信按位组合 + { + bitValue = Cmd03RespProcess_BitGroup(pDi, diValue); + + if ((bitValue != pDi->Value) && (g_ModbusTcpMZIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + if (pDi->Param5 & 0x01) + SZFlag = 1; + + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + else + { + bitValue = (diValue >> (pDi->Param4)) & 0x01; + //FES点表必须按每个请求命令的起始地址,从小到大顺序排列,所以每次都从当前点的下一个点开始查找。 + if (pDi->Revers) + bitValue ^= 1; + if ((bitValue != pDi->Value) && (g_ModbusTcpMZIsMainFes == true) && (pDi->Status&CN_FesValueUpdate))//主机才报告变化数据,更新过的点才能报告变化 + { + if (pDi->Param5 & 0x01) + SZFlag = 1; + + memcpy(ChgDi[ChgCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgDi[ChgCount].Value = bitValue; + ChgDi[ChgCount].Status = CN_FesValueUpdate; + ChgDi[ChgCount].time = mSec; + ChgCount++; + if (ChgCount >= 50) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + ChgCount = 0; + } + //Create Soe + if (m_AppData.lastCmd.IsCreateSoe) + { + SoeEvent[SoeCount].time = mSec; + memcpy(SoeEvent[SoeCount].TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent[SoeCount].ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent[SoeCount].TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent[SoeCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + SoeEvent[SoeCount].PointNo = pDi->PointNo; + SoeEvent[SoeCount].Status = CN_FesValueUpdate; + SoeEvent[SoeCount].Value = bitValue; + SoeEvent[SoeCount].FaultNum = 0; + SoeCount++; + if (SoeCount >= 50) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + SoeCount = 0; + } + } + } + DiValue[ValueCount].PointNo = pDi->PointNo; + DiValue[ValueCount].Value = bitValue; + DiValue[ValueCount].Status = CN_FesValueUpdate; + DiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 50) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + ValueCount = 0; + } + } + } + //Updata Value + if (ValueCount > 0) + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + + //Updata change value + if (ChgCount > 0) + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu, ChgCount, &ChgDi[0]); + + //Updata soe + if (SoeCount > 0) + { + m_ptrCFesBase->WriteSoeEventBuf(m_ptrCFesRtu, SoeCount, &SoeEvent[0]); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(SoeCount, &SoeEvent[0]); + } + } + else + if (((m_AppData.lastCmd.Type >= AI_Word_HL) && (m_AppData.lastCmd.Type <= AI_Float_LL)) || (m_AppData.lastCmd.Type == AI_SIGNEDFLAG16_HL) || (m_AppData.lastCmd.Type == AI_SIGNEDFLAG32_HL))//AI + { + if (m_AiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的模拟量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + ValueCount = 0; + ChgCount = 0; + if (((m_AppData.lastCmd.Type >= AI_Word_HL) && (m_AppData.lastCmd.Type <= AI_UWord_LH)) || (m_AppData.lastCmd.Type == AI_SIGNEDFLAG16_HL))//AI 16bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + PointIndex = pAi->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case AI_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + aiValue = uValue16; + break; + case AI_SIGNEDFLAG16_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + if (uValue16 & 0x8000) + { + aiValue = (float)(uValue16 & 0x7fff); + aiValue = 0 - aiValue; + } + else + aiValue = (float)(uValue16 & 0x7fff); + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + aiValue = uValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + else//AI 32bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + PointIndex = (pAi->Param3 - m_AppData.lastCmd.StartAddr)/2; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case AI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + aiValue = (float)uValue32; + break; + case AI_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = (float)fValue; + break; + case AI_SIGNEDFLAG32_HL: + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + if (uValue32 & 0x80000000) + { + aiValue = (float)(uValue32 & 0x7fffffff); + aiValue = 0 - aiValue; + } + else + aiValue = (float)(uValue32 & 0x7fffffff); + break; + } + + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + + ValueCount++; + + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + } + if (ValueCount>0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount>0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + else + if ((m_AppData.lastCmd.Type >= ACC_Word_HL) && (m_AppData.lastCmd.Type <= ACC_Float_LL))//ACC + { + if (m_AccBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的累积量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + ValueCount = 0; + ChgCount = 0; + if ((m_AppData.lastCmd.Type >= ACC_Word_HL) && (m_AppData.lastCmd.Type <= ACC_UWord_LH))//ACC 16bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + PointIndex = pAcc->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case ACC_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + accValue = sValue16; + break; + case ACC_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + accValue = sValue16; + break; + case ACC_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + accValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + accValue = uValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + else//ACC 32bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + PointIndex = (pAcc->Param3 - m_AppData.lastCmd.StartAddr)/2; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case ACC_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + accValue = sValue32; + break; + case ACC_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + accValue = uValue32; + break; + case ACC_Float_HH://(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000;//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 + break; + case ACC_Float_LH://(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue * 1000;//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 + break; + case ACC_Float_LL://(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue * 1000;//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + } + if (ValueCount>0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount>0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + else + if ((m_AppData.lastCmd.Type >= MI_Word_HL) && (m_AppData.lastCmd.Type <= MI_UDWord_LL))//MI + { + if (m_MiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("Cmd03RespProcess: 未找到blockId=%d的混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_MiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_MiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + ValueCount = 0; + ChgCount = 0; + if ((m_AppData.lastCmd.Type >= MI_Word_HL) && (m_AppData.lastCmd.Type <= MI_UWord_LH))//MI 16bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pMi = GetFesMiByPIndex(m_ptrCFesRtu, i); + if (pMi == NULL) + continue; + + //2022-12-20 取点值应该为PointIndex + PointIndex = pMi->Param3 - m_AppData.lastCmd.StartAddr; + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case MI_Word_HL: + sValue16 = (short)Data[3 + PointIndex * 2] << 8; + sValue16 |= (short)Data[4 + PointIndex * 2]; + miValue = sValue16; + break; + case MI_Word_LH: + sValue16 = (short)Data[4 + PointIndex * 2] << 8; + sValue16 |= (short)Data[3 + PointIndex * 2]; + miValue = sValue16; + break; + case MI_UWord_HL: + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + miValue = uValue16; + break; + default:// AI_UWord_LH: + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + miValue = uValue16; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + else//Mi 32bit + { + for (i = StartPointNo; i <= EndPointNo; i++) + { + pMi = GetFesMiByPIndex(m_ptrCFesRtu, i); + if (pMi == NULL) + continue; + + //2022-12-20 取点值应该为PointIndex + PointIndex = (pMi->Param3 - m_AppData.lastCmd.StartAddr) / 2; + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (m_AppData.lastCmd.Type) + { + case MI_DWord_HH://(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 4] << 24; + sValue32 |= (int)Data[4 + PointIndex * 4] << 16; + sValue32 |= (int)Data[5 + PointIndex * 4] << 8; + sValue32 |= (int)Data[6 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_DWord_LH://(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 4] << 24; + sValue32 |= (int)Data[6 + PointIndex * 4] << 16; + sValue32 |= (int)Data[3 + PointIndex * 4] << 8; + sValue32 |= (int)Data[4 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_DWord_LL://(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 4] << 24; + sValue32 |= (int)Data[5 + PointIndex * 4] << 16; + sValue32 |= (int)Data[4 + PointIndex * 4] << 8; + sValue32 |= (int)Data[3 + PointIndex * 4]; + miValue = sValue32; + break; + case MI_UDWord_HH://(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 4]; + miValue = uValue32; + break; + case MI_UDWord_LH://(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 4]; + miValue = uValue32; + break; + case MI_UDWord_LL://(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 4] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 4] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 4] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 4]; + miValue = uValue32; + break; + } + MiValue[ValueCount].PointNo = pMi->PointNo; + MiValue[ValueCount].Value = miValue; + MiValue[ValueCount].Status = CN_FesValueUpdate; + MiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + } + if (ValueCount>0) + { + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(ValueCount, &MiValue[0], &ChgCount, &ChgMi[0]); + ValueCount = 0; + if ((ChgCount>0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + } + } + + if (SZFlag == 1) + AlarmCalc(); + +} + + +/** + * @brief CModbusTcpMZDataProcThread::Cmd05RespProcess + * 命令0x05的处理。 + * @param Data 接收的数据 + * @param DataSize 接收的数据长度 + */ +void CModbusTcpMZDataProcThread::Cmd05RespProcess(byte *Data,int DataSize) +{ + CmdControlRespProcess(Data,DataSize,1); +} + +/** + * @brief CModbusTcpMZDataProcThread::Cmd06RespProcess + * 命令0x06的处理。 + * @param Data 接收的数据 + * @param DataSize 接收的数据长度 + */ +void CModbusTcpMZDataProcThread::Cmd06RespProcess(byte *Data,int DataSize) +{ + CmdControlRespProcess(Data,DataSize,1); +} + +/** + * @brief CModbusTcpMZDataProcThread::Cmd10RespProcess + * 命令0x10的处理。 + * @param Data 接收的数据 + * @param DataSize 接收的数据长度 + */ +void CModbusTcpMZDataProcThread::Cmd10RespProcess(byte *Data,int DataSize) +{ + CmdControlRespProcess(Data,DataSize,1); +} + +void CModbusTcpMZDataProcThread::CmdTypeHybridProcess(byte *Data, int DataSize) +{ + int FunCode; + int i, StartAddr, StartPointNo, EndPointNo, ValueCount, ChgCount, PointIndex; + uint64 mSec; + SFesAi *pAi; + SFesRtuAiValue AiValue[100]; + SFesChgAi ChgAi[100]; + SFesAcc *pAcc; + SFesRtuAccValue AccValue[100]; + SFesChgAcc ChgAcc[100]; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + float fValue, aiValue; + int64 accValue; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + mSec = getUTCTimeMsec(); + ValueCount = 0; + ChgCount = 0; + if (m_AppData.lastCmd.Type == AI_Hybrid_Type)//AI 模拟量混合量帧 + { + if (m_AiBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("CmdTypeHybridProcess: 未找到blockId=%d的模拟量混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_AiBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + ValueCount = 0; + ChgCount = 0; + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAi = GetFesAiByPIndex(m_ptrCFesRtu, i); + if (pAi == NULL) + continue; + + PointIndex = pAi->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (pAi->Param4) + { + case AI_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)Data[4 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[3 + PointIndex * 2]; + aiValue = sValue16; + break; + case AI_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + aiValue = uValue16; + break; + case AI_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + aiValue = (float)uValue16; + break; + case AI_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 2] << 24; + sValue32 |= (int)Data[4 + PointIndex * 2] << 16; + sValue32 |= (int)Data[5 + PointIndex * 2] << 8; + sValue32 |= (int)Data[6 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 2] << 24; + sValue32 |= (int)Data[6 + PointIndex * 2] << 16; + sValue32 |= (int)Data[3 + PointIndex * 2] << 8; + sValue32 |= (int)Data[4 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 2] << 24; + sValue32 |= (int)Data[5 + PointIndex * 2] << 16; + sValue32 |= (int)Data[4 + PointIndex * 2] << 8; + sValue32 |= (int)Data[3 + PointIndex * 2]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + aiValue = (float)uValue32; + break; + case AI_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + default: + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + aiValue = sValue16; + break; + } + AiValue[ValueCount].PointNo = pAi->PointNo; + AiValue[ValueCount].Value = aiValue; + AiValue[ValueCount].Status = CN_FesValueUpdate; + AiValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(ValueCount, &AiValue[0], &ChgCount, &ChgAi[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + } + } + } + else if (m_AppData.lastCmd.Type == ACC_Hybrid_Type)//ACC 累积量混合量帧 + { + if (m_AccBlockDataIndexInfo.count(m_AppData.lastCmd.SeqNo) == 0) + { + LOGDEBUG("CmdTypeHybridProcess: 未找到blockId=%d的累积量混合量数据块,不解析该帧数据", m_AppData.lastCmd.SeqNo); + return; + } + StartPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).headIndex; + EndPointNo = m_AccBlockDataIndexInfo.at(m_AppData.lastCmd.SeqNo).tailIndex; + ValueCount = 0; + ChgCount = 0; + + for (i = StartPointNo; i <= EndPointNo; i++) + { + pAcc = GetFesAccByPIndex(m_ptrCFesRtu, i); + if (pAcc == NULL) + continue; + + PointIndex = pAcc->Param3 - m_AppData.lastCmd.StartAddr; + //2022-11-23 增加判断,防止数组过界。 + if ((PointIndex < 0) || (PointIndex > MODBUSTCPV3_K_MAX_POINT_INDEX)) + { + continue; + } + + switch (pAcc->Param4) + { + case ACC_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + accValue = (int64)sValue16; + break; + case ACC_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)Data[4 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[3 + PointIndex * 2]; + accValue = (int64)sValue16; + break; + case ACC_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)Data[3 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[4 + PointIndex * 2]; + accValue = (int64)uValue16; + break; + case ACC_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)Data[4 + PointIndex * 2] << 8; + uValue16 |= (uint16)Data[3 + PointIndex * 2]; + accValue = (int64)uValue16; + break; + case ACC_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)Data[3 + PointIndex * 2] << 24; + sValue32 |= (int)Data[4 + PointIndex * 2] << 16; + sValue32 |= (int)Data[5 + PointIndex * 2] << 8; + sValue32 |= (int)Data[6 + PointIndex * 2]; + accValue = (int64)sValue32; + break; + case ACC_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)Data[5 + PointIndex * 2] << 24; + sValue32 |= (int)Data[6 + PointIndex * 2] << 16; + sValue32 |= (int)Data[3 + PointIndex * 2] << 8; + sValue32 |= (int)Data[4 + PointIndex * 2]; + accValue = (int64)sValue32; + break; + case ACC_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)Data[6 + PointIndex * 2] << 24; + sValue32 |= (int)Data[5 + PointIndex * 2] << 16; + sValue32 |= (int)Data[4 + PointIndex * 2] << 8; + sValue32 |= (int)Data[3 + PointIndex * 2]; + accValue = (int64)sValue32; + break; + case ACC_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + accValue = (int64)uValue32; + break; + case ACC_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + accValue = (int64)uValue32; + break; + case ACC_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + accValue = (int64)uValue32; + break; + case ACC_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)Data[3 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[6 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000;//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 + break; + case ACC_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)Data[5 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[6 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[3 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[4 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000;//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 + break; + case ACC_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)Data[6 + PointIndex * 2] << 24; + uValue32 |= (uint32)Data[5 + PointIndex * 2] << 16; + uValue32 |= (uint32)Data[4 + PointIndex * 2] << 8; + uValue32 |= (uint32)Data[3 + PointIndex * 2]; + memcpy(&fValue, &uValue32, sizeof(float)); + accValue = fValue*1000;//2022-10-17 thxiao当采集为FLOAT时,这种做法会丢失小数位,固定扩大1000倍 + break; + default: + sValue16 = (int16)Data[3 + PointIndex * 2] << 8; + sValue16 |= (int16)Data[4 + PointIndex * 2]; + accValue = (int64)sValue16; + break; + } + AccValue[ValueCount].PointNo = pAcc->PointNo; + AccValue[ValueCount].Value = accValue; + AccValue[ValueCount].Status = CN_FesValueUpdate; + AccValue[ValueCount].time = mSec; + ValueCount++; + if (ValueCount >= 100) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } + if (ValueCount > 0) + { + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(ValueCount, &AccValue[0], &ChgCount, &ChgAcc[0]); + ValueCount = 0; + if ((ChgCount > 0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + } + } +} + + +/** + * @brief CModbusTcpMZDataProcThread::CmdControlRespProcess + * @param Data 接收的数据 + * @param DataSize 接收的数据长度 + * @param okFlag 命令成功标志 1:成功 0:失败 + * @return 是控制命令返回:TRUE 否则为:FALSE + */ +bool CModbusTcpMZDataProcThread::CmdControlRespProcess(byte *Data,int DataSize,int okFlag) +{ + SFesTxDoCmd retDoCmd; + SFesTxAoCmd retAoCmd; + SFesTxMoCmd retMoCmd; + SFesTxDefCmd retDefCmd; + + if(m_AppData.state != CN_ModbusTcpMZAppState_waitControlResp) + return false; + + switch (m_AppData.lastCotrolcmd) + { + case CN_ModbusTcpMZDoCmd: + //memset(&retDoCmd,0,sizeof(retDoCmd)); + if(okFlag) + { + retDoCmd.retStatus = CN_ControlSuccess; + sprintf(retDoCmd.strParam,I18N("遥控成功!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + LOGINFO("遥控成功!RtuNo:%d 遥控点:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + } + else + { + retDoCmd.retStatus = CN_ControlFailed; + sprintf(retDoCmd.strParam,I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + LOGDEBUG("遥控失败!RtuNo:%d 遥控点:%d",m_ptrCFesRtu->m_Param.RtuNo,m_AppData.doCmd.PointID); + } + strcpy(retDoCmd.TableName,m_AppData.doCmd.TableName); + strcpy(retDoCmd.ColumnName,m_AppData.doCmd.ColumnName); + strcpy(retDoCmd.TagName,m_AppData.doCmd.TagName); + strcpy(retDoCmd.RtuName,m_AppData.doCmd.RtuName); + retDoCmd.CtrlActType = m_AppData.doCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retDoCmd.CtrlDir = m_AppData.doCmd.CtrlDir; + retDoCmd.RtuNo = m_AppData.doCmd.RtuNo; + retDoCmd.PointID = m_AppData.doCmd.PointID; + retDoCmd.FwSubSystem = m_AppData.doCmd.FwSubSystem; + retDoCmd.FwRtuNo = m_AppData.doCmd.FwRtuNo; + retDoCmd.FwPointNo = m_AppData.doCmd.FwPointNo; + retDoCmd.SubSystem = m_AppData.doCmd.SubSystem; + + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&retDoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1,&retDoCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + return true; + break; + case CN_ModbusTcpMZAoCmd: + if(okFlag) + { + retAoCmd.retStatus = CN_ControlSuccess; + sprintf(retAoCmd.strParam,I18N("遥调成功!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); + LOGINFO("遥调成功!RtuNo:%d 遥调点:%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + + AoVerifyProcess(m_ptrCFesRtu); + } + else + { + retAoCmd.retStatus = CN_ControlFailed; + sprintf(retAoCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.aoCmd.PointID); + LOGINFO("遥调失败!RtuNo:%d 遥调点:%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.aoCmd.PointID); + } + strcpy(retAoCmd.TableName,m_AppData.aoCmd.TableName); + strcpy(retAoCmd.ColumnName,m_AppData.aoCmd.ColumnName); + strcpy(retAoCmd.TagName,m_AppData.aoCmd.TagName); + strcpy(retAoCmd.RtuName,m_AppData.aoCmd.RtuName); + retAoCmd.CtrlActType = m_AppData.aoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retAoCmd.CtrlDir = m_AppData.aoCmd.CtrlDir; + retAoCmd.RtuNo = m_AppData.aoCmd.RtuNo; + retAoCmd.PointID = m_AppData.aoCmd.PointID; + retAoCmd.FwSubSystem = m_AppData.aoCmd.FwSubSystem; + retAoCmd.FwRtuNo = m_AppData.aoCmd.FwRtuNo; + retAoCmd.FwPointNo = m_AppData.aoCmd.FwPointNo; + retAoCmd.SubSystem = m_AppData.aoCmd.SubSystem; + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&retAoCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + return true; + break; + case CN_ModbusTcpMZMoCmd: + if(okFlag) + { + retMoCmd.retStatus = CN_ControlSuccess; + sprintf(retMoCmd.strParam,I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.moCmd.PointID); + LOGINFO("混合量输出成功!RtuNo:%d 混合量输出点:%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + } + else + { + retMoCmd.retStatus = CN_ControlFailed; + sprintf(retMoCmd.strParam,I18N("混合量输出失败!RtuNo:%d 混合量输出点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,m_AppData.moCmd.PointID); + LOGINFO("混合量输出失败!RtuNo:%d 混合量输出点:%d", m_ptrCFesRtu->m_Param.RtuNo, m_AppData.moCmd.PointID); + } + strcpy(retMoCmd.TableName,m_AppData.moCmd.TableName); + strcpy(retMoCmd.ColumnName,m_AppData.moCmd.ColumnName); + strcpy(retMoCmd.TagName,m_AppData.moCmd.TagName); + strcpy(retMoCmd.RtuName,m_AppData.moCmd.RtuName); + retMoCmd.CtrlActType = m_AppData.moCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + retMoCmd.CtrlDir = m_AppData.moCmd.CtrlDir; + retMoCmd.RtuNo = m_AppData.moCmd.RtuNo; + retMoCmd.PointID = m_AppData.moCmd.PointID; + retMoCmd.FwSubSystem = m_AppData.moCmd.FwSubSystem; + retMoCmd.FwRtuNo = m_AppData.moCmd.FwRtuNo; + retMoCmd.FwPointNo = m_AppData.moCmd.FwPointNo; + retMoCmd.SubSystem = m_AppData.moCmd.SubSystem; + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&retMoCmd); + + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + return true; + break; + case CN_ModbusTcpMZDefCmd: + if(okFlag) + { + retDefCmd.retStatus = CN_ControlSuccess; + sprintf(retDefCmd.strParam,I18N("自定义命令输出成功!RtuNo:%d ").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo); + LOGINFO("自定义命令输出成功!RtuNo:%d", m_ptrCFesRtu->m_Param.RtuNo); + } + else + { + retDefCmd.retStatus = CN_ControlFailed; + sprintf(retDefCmd.strParam,I18N("自定义命令输出失败!RtuNo:%d ").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo); + LOGINFO("自定义命令输出失败!RtuNo:%d", m_ptrCFesRtu->m_Param.RtuNo); + } + strcpy(retDefCmd.TableName,m_AppData.defCmd.TableName); + strcpy(retDefCmd.ColumnName,m_AppData.defCmd.ColumnName); + strcpy(retDefCmd.TagName,m_AppData.defCmd.TagName); + strcpy(retDefCmd.RtuName,m_AppData.defCmd.RtuName); + retDefCmd.DevId = m_AppData.defCmd.DevId; + retDefCmd.CmdNum = m_AppData.defCmd.CmdNum; + retDefCmd.VecCmd = m_AppData.defCmd.VecCmd; + m_ptrCFesRtu->WriteTxDefCmdBuf(1,&retDefCmd); + m_AppData.lastCotrolcmd = CN_ModbusTcpMZNoCmd; + m_AppData.state = CN_ModbusTcpMZAppState_idle; + return true; + break; + default: + break; + } + return false; +} +/** + * @brief CModbusTcpMZDataProcThread::ErrorControlRespProcess + * @param + * @param + * @param 网络令来需要做异常处理断开时有控制命 + * @return + */ +void CModbusTcpMZDataProcThread::ErrorControlRespProcess() +{ + SFesRxDoCmd RxDoCmd; + SFesTxDoCmd TxDoCmd; + SFesRxAoCmd RxAoCmd; + SFesTxAoCmd TxAoCmd; + SFesRxMoCmd RxMoCmd; + SFesTxMoCmd TxMoCmd; + SFesRxDefCmd RxDefCmd; + SFesTxDefCmd TxDefCmd; + + if(m_ptrCFesRtu == NULL) + return ; + + if(g_ModbusTcpMZIsMainFes==false)//备机不作任何操作 + return ; + + if(m_ptrCFesRtu->GetRxDoCmdNum()>0) + { + if(m_ptrCFesRtu->ReadRxDoCmd(1,&RxDoCmd)==1) + { + //memset(&TxDoCmd,0,sizeof(TxDoCmd)); + + strcpy(TxDoCmd.TableName,RxDoCmd.TableName); + strcpy(TxDoCmd.ColumnName,RxDoCmd.ColumnName); + strcpy(TxDoCmd.TagName,RxDoCmd.TagName); + strcpy(TxDoCmd.RtuName,RxDoCmd.RtuName); + TxDoCmd.retStatus = CN_ControlFailed; + TxDoCmd.CtrlActType = RxDoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxDoCmd.CtrlDir = RxDoCmd.CtrlDir; + TxDoCmd.RtuNo = RxDoCmd.RtuNo; + TxDoCmd.PointID = RxDoCmd.PointID; + TxDoCmd.FwSubSystem = RxDoCmd.FwSubSystem; + TxDoCmd.FwRtuNo = RxDoCmd.FwRtuNo; + TxDoCmd.FwPointNo = RxDoCmd.FwPointNo; + TxDoCmd.SubSystem = RxDoCmd.SubSystem; + sprintf(TxDoCmd.strParam, I18N("遥控失败!RtuNo:%d 遥控点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxDoCmd.PointID); + LOGDEBUG ("网络已断开 DO遥控失败 DoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",RxDoCmd.CtrlActType,RxDoCmd.iValue,RxDoCmd.RtuName,RxDoCmd.PointID); + //m_ptrCFesRtu->WriteTxDoCmdBuf(1,&TxDoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexDoRespCmdBuf(1,&TxDoCmd); + + } + + } + else + if(m_ptrCFesRtu->GetRxAoCmdNum()>0) + { + if(m_ptrCFesRtu->ReadRxAoCmd(1,&RxAoCmd)==1) + { + //memset(&TxAoCmd,0,sizeof(TxAoCmd)); + strcpy(TxAoCmd.TableName,RxAoCmd.TableName); + strcpy(TxAoCmd.ColumnName,RxAoCmd.ColumnName); + strcpy(TxAoCmd.TagName,RxAoCmd.TagName); + strcpy(TxAoCmd.RtuName,RxAoCmd.RtuName); + TxAoCmd.retStatus = CN_ControlFailed; + sprintf(TxAoCmd.strParam,I18N("遥调失败!RtuNo:%d 遥调点:%d").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo,RxAoCmd.PointID); + TxAoCmd.CtrlActType = RxAoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxAoCmd.CtrlDir = RxAoCmd.CtrlDir; + TxAoCmd.RtuNo = RxAoCmd.RtuNo; + TxAoCmd.PointID = RxAoCmd.PointID; + TxAoCmd.FwSubSystem = RxAoCmd.FwSubSystem; + TxAoCmd.FwRtuNo = RxAoCmd.FwRtuNo; + TxAoCmd.FwPointNo = RxAoCmd.FwPointNo; + TxAoCmd.SubSystem = RxAoCmd.SubSystem; + LOGDEBUG("网络已断开 AO遥调执行失败 AoCmdProcess::CtrlActType=%d ,fValue=%f,RtuName=%s,PointID=%d", RxAoCmd.CtrlActType, RxAoCmd.fValue, RxAoCmd.RtuName, RxAoCmd.PointID); + //m_ptrCFesRtu->WriteTxAoCmdBuf(1,&TxAoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexAoRespCmdBuf(1,&TxAoCmd); + } + } + else + if(m_ptrCFesRtu->GetRxMoCmdNum()>0) + { + if(m_ptrCFesRtu->ReadRxMoCmd(1,&RxMoCmd)==1) + { + //memset(&TxMoCmd,0,sizeof(TxMoCmd)); + strcpy(TxMoCmd.TableName,RxMoCmd.TableName); + strcpy(TxMoCmd.ColumnName,RxMoCmd.ColumnName); + strcpy(TxMoCmd.TagName,RxMoCmd.TagName); + strcpy(TxMoCmd.RtuName,RxMoCmd.RtuName); + TxMoCmd.retStatus = CN_ControlFailed; + TxMoCmd.CtrlActType = RxMoCmd.CtrlActType; + //2019-03-18 thxiao 为适应转发规约增加 + TxMoCmd.CtrlDir = RxMoCmd.CtrlDir; + TxMoCmd.RtuNo = RxMoCmd.RtuNo; + TxMoCmd.PointID = RxMoCmd.PointID; + TxMoCmd.FwSubSystem = RxMoCmd.FwSubSystem; + TxMoCmd.FwRtuNo = RxMoCmd.FwRtuNo; + TxMoCmd.FwPointNo = RxMoCmd.FwPointNo; + TxMoCmd.SubSystem = RxMoCmd.SubSystem; + sprintf(TxMoCmd.strParam, I18N("混合量输出成功!RtuNo:%d 混合量输出点:%d").str().c_str(), m_ptrCFesRtu->m_Param.RtuNo, RxMoCmd.PointID); + + LOGDEBUG ("网络已断开 MO混合量执行失败 MoCmdProcess::CtrlActType=%d ,iValue=%d,RtuName=%s,PointID=%d",RxMoCmd.CtrlActType,RxMoCmd.iValue,RxMoCmd.RtuName,RxMoCmd.PointID); + //m_ptrCFesRtu->WriteTxMoCmdBuf(1,&TxMoCmd); + //2019-03-18 thxiao 为适应转发规约 + m_ptrCFesBase->WritexMoRespCmdBuf(1,&TxMoCmd); + } + } + else + if(m_ptrCFesRtu->GetRxDefCmdNum()>0) + { + if(m_ptrCFesRtu->ReadRxDefCmd(1,&RxDefCmd)==1) + { + //memset(&TxDefCmd,0,sizeof(TxDefCmd)); + strcpy(TxDefCmd.TableName,RxDefCmd.TableName); + strcpy(TxDefCmd.ColumnName,RxDefCmd.ColumnName); + strcpy(TxDefCmd.TagName,RxDefCmd.TagName); + strcpy(TxDefCmd.RtuName,RxDefCmd.RtuName); + TxDefCmd.DevId = RxDefCmd.DevId; + TxDefCmd.CmdNum = RxDefCmd.CmdNum; + TxDefCmd.VecCmd = RxDefCmd.VecCmd; + TxDefCmd.retStatus = CN_ControlFailed; + sprintf(TxDefCmd.strParam,I18N("自定义命令输出失败!RtuNo:%d ").str().c_str(),m_ptrCFesRtu->m_Param.RtuNo); + LOGERROR("网络已断开 自定义命令输出失败!RtuNo:%d",m_ptrCFesRtu->m_Param.RtuNo); + m_ptrCFesRtu->WriteTxDefCmdBuf(1,&TxDefCmd); + } + } +} + +/* +2019-08-30 按原有的方式,时间间隔最大为100MS,过大,所以改为程序内部处理 +*/ +void CModbusTcpMZDataProcThread::SetSendCmdFlag() +{ + SModbusCmd *pCmd; + CFesRtuPtr ptrFesRtu; + int i,j, RtuNo; + int64 lTime,tempTime; + + if (m_AppData.setCmdCount++ > 2) + { + m_AppData.setCmdCount = 0; + lTime = getUTCTimeMsec(); //MS + for (i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + if ((ptrFesRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo)) == NULL) + continue; + for (j = 0; j < ptrFesRtu->m_Param.ModbusCmdBuf.num; j++) + { + pCmd = ptrFesRtu->m_Param.ModbusCmdBuf.pCmd + j; + if (pCmd->Used)//2022-09-06 thxiao 启用块使能 + { + tempTime = lTime - pCmd->lastPollTime; + if (tempTime > pCmd->PollTime) + { + pCmd->CommandSendFlag = true; + pCmd->lastPollTime = lTime; + //LOGDEBUG("cmd=%d PollTime=%d CommandSendFlag=true", j, pCmd->PollTime); + } + else + if (tempTime <= 0)//避免时间错的情况发生 + { + pCmd->lastPollTime = lTime; + } + } + } + } + } +} + + +/** +* @brief CModbusTcpMZDataProcThread::Cmd03RespProcess_BitGroup +* 按位组合的遥信解析处理 +* @param Data 遥信点结构 +* @param DataSize 遥信字节值 +*/ +int CModbusTcpMZDataProcThread::Cmd03RespProcess_BitGroup(SFesDi *pDi, int diValue) +{ + int temp1 = pDi->Param5; + int IntData = diValue & temp1; + int i, YxBit = 0; + + if (temp1 < 0) + return YxBit; + + for (i = 0; i < 16; i++) + { + if ((temp1 >> i) & 0x01) + { + IntData >>= i; + break; + } + } + + if (pDi->Param4 == IntData) + YxBit = 1; + + return YxBit; +} + +//2021-06-25 ljj +/** +* @brief CModbusTcpMZDataProcThread::InitProtocolBlockDataIndexMapping +* 数据块关联数据索引表初始化 +* @param RtuPtr +* @return +*/ +void CModbusTcpMZDataProcThread::InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuPtr) +{ + int i, j; + int blockId, funCode, startAddr, dataLen; + SModbusCmd *pCmd; + SModbusCmdBuf cmd = RtuPtr->m_Param.ModbusCmdBuf; + SFesAiIndex *pAiIndex; + SFesDiIndex *pDiIndex; + SFesAccIndex *pAccIndex; + SFesMiIndex *pMiIndex; + vector pAiBlockIndexs; + vector pDiBlockIndexs; + vector pAccBlockIndexs; + vector pMiBlockIndexs; + + //根据数据块帧类别进行分类 + for (i = 0; i < cmd.num; i++) + { + pCmd = cmd.pCmd + i; + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + SFesBaseBlockDataIndexInfo blockDataIndexInfoTemp; + //blockDataIndexInfoTemp.headIndex = -1; + //blockDataIndexInfoTemp.tailIndex = -1; + blockDataIndexInfoTemp.headIndex = 0xFFFFFFFF; + blockDataIndexInfoTemp.tailIndex = 0xFFFFFFFF; + LOGDEBUG("pCmd->Type:%d", pCmd->Type); + if ((pCmd->Type >= DI_BYTE_LH) && (pCmd->Type <= DI_UWord_LH)) //DI + { + pDiBlockIndexs.push_back(i); + m_DiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_DiBlockDataIndexInfo.insert blockId:%d", blockId); + } + else if (((pCmd->Type >= AI_Word_HL) && (pCmd->Type <= AI_Float_LL)) || (pCmd->Type == AI_SIGNEDFLAG16_HL) || (pCmd->Type == AI_SIGNEDFLAG32_HL) || (pCmd->Type == AI_Hybrid_Type)) //AI + { + pAiBlockIndexs.push_back(i); + m_AiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_AiBlockDataIndexInfo.insert blockId:%d", blockId); + } + else if (((pCmd->Type >= ACC_Word_HL) && (pCmd->Type <= ACC_Float_LL)) || (pCmd->Type == ACC_Hybrid_Type))//ACC + { + pAccBlockIndexs.push_back(i); + m_AccBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_AccBlockDataIndexInfo.insert blockId:%d", blockId); + } + else if ((pCmd->Type >= MI_Word_HL) && (pCmd->Type <= MI_UDWord_LL))//MI + { + pMiBlockIndexs.push_back(i); + m_MiBlockDataIndexInfo.insert(std::pair(blockId, blockDataIndexInfoTemp)); + LOGDEBUG("m_MiBlockDataIndexInfo.insert blockId:%d", blockId); + } + + } + + //对不同帧类别的数据块存储起始索引和结束索引 + for (j = 0; j < RtuPtr->m_MaxAiIndex; j++) //Ai + { + pAiIndex = RtuPtr->m_pAiIndex + j; + + for (i = 0; i < pAiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pAiBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + //LOGDEBUG("blockId=%d funCode=%d startAddr=%d dataLen=%d", blockId, funCode, startAddr, dataLen); + //LOGDEBUG("j=%d Param2=%d Param3=%d PIndex=%d", j, pAiIndex->Param2, pAiIndex->Param3, pAiIndex->PIndex); + if ((pAiIndex->Param2 == funCode) && (startAddr <= pAiIndex->Param3) && (pAiIndex->Param3 < (startAddr + dataLen))) + { + if ((m_AiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_AiBlockDataIndexInfo.at(blockId).headIndex = pAiIndex->PIndex; + + m_AiBlockDataIndexInfo.at(blockId).tailIndex = pAiIndex->PIndex; + } + } + } + + for (j = 0; j < RtuPtr->m_MaxDiIndex; j++) //Di + { + pDiIndex = RtuPtr->m_pDiIndex + j; + + for (i = 0; i < pDiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pDiBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pDiIndex->Param2 == funCode) && (startAddr <= pDiIndex->Param3) && (pDiIndex->Param3 < (startAddr + dataLen))) + { + if ((m_DiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_DiBlockDataIndexInfo.at(blockId).headIndex = pDiIndex->PIndex; + + m_DiBlockDataIndexInfo.at(blockId).tailIndex = pDiIndex->PIndex; + } + } + + } + + for (j = 0; j < RtuPtr->m_MaxAccIndex; j++) //Acc + { + pAccIndex = RtuPtr->m_pAccIndex + j; + for (i = 0; i < pAccBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pAccBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pAccIndex->Param2 == funCode) && (startAddr <= pAccIndex->Param3) && (pAccIndex->Param3 < (startAddr + dataLen))) + { + if ((m_AccBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_AccBlockDataIndexInfo.at(blockId).headIndex = pAccIndex->PIndex; + + m_AccBlockDataIndexInfo.at(blockId).tailIndex = pAccIndex->PIndex; + } + } + } + + for (j = 0; j < RtuPtr->m_MaxMiIndex; j++) //Mi + { + pMiIndex = RtuPtr->m_pMiIndex + j; + + for (i = 0; i < pMiBlockIndexs.size(); i++) + { + pCmd = cmd.pCmd + pMiBlockIndexs.at(i); + + //blockId = pCmd->Index; + blockId = pCmd->SeqNo; //2022-09-06 thxiao 使用自动分配块唯一序号, 不再强调配置块序号唯一 + + funCode = pCmd->FunCode; + startAddr = pCmd->StartAddr; + dataLen = pCmd->DataLen; + + if ((pMiIndex->Param2 == funCode) && (startAddr <= pMiIndex->Param3) && (pMiIndex->Param3 < (startAddr + dataLen))) + { + if ((m_MiBlockDataIndexInfo.at(blockId).headIndex == 0xFFFFFFFF)) //首次得到起始地址时 + m_MiBlockDataIndexInfo.at(blockId).headIndex = pMiIndex->PIndex; + + m_MiBlockDataIndexInfo.at(blockId).tailIndex = pMiIndex->PIndex; + } + } + } + + map::iterator iter; + iter = m_AiBlockDataIndexInfo.begin(); + while (iter != m_AiBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Ai--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + iter = m_DiBlockDataIndexInfo.begin(); + while (iter != m_DiBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Di--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + iter = m_AccBlockDataIndexInfo.begin(); + while (iter != m_AccBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Acc--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } + iter = m_MiBlockDataIndexInfo.begin(); + while (iter != m_MiBlockDataIndexInfo.end()) + { + SFesBaseBlockDataIndexInfo temp = iter->second; + LOGDEBUG("Mi--- blockId:%d headIndex:%d tailIndex:%d", iter->first, temp.headIndex, temp.tailIndex); + iter++; + } +} + +/* +@brief CModbusTcpMZDataProcThread::ClearTcpClientByChanNo +通道切换、关闭通道时需要清除通道的状态 + +*/ +void CModbusTcpMZDataProcThread::ClearTcpClientByChanNo(int ChanNo) +{ + CFesChanPtr ptrChan; + + ptrChan = m_ptrCFesBase->GetChanDataByChanNo(ChanNo); + if (ptrChan != NULL) + { + ptrChan->SetComThreadRunFlag(CN_FesStopFlag); + ptrChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrTcpClient->TcpClose(m_ptrCurrentChan); + ptrChan->SetLinkStatus(CN_FesChanDisconnect); + LOGDEBUG("PortNo=%d IP1=%s IP2=%s退出", ptrChan->m_Param.ChanNo, ptrChan->m_Param.NetRoute[0].NetDesc, ptrChan->m_Param.NetRoute[1].NetDesc); + } + +} + +void CModbusTcpMZDataProcThread::SetTcpClientByChanNo(int ChanNo) +{ + CFesChanPtr ptrChan; + + ptrChan = m_ptrCFesBase->GetChanDataByChanNo(ChanNo); + if (ptrChan != NULL) + { + ptrChan->SetComThreadRunFlag(CN_FesRunFlag); + ptrChan->SetChangeFlag(CN_FesChanUnChange); + } + +} + +void CModbusTcpMZDataProcThread::TimerProcess() +{ + + int64 curmsec = getMonotonicMsec(); + + if ((curmsec - m_AppData.SettimemSec) > m_AppData.SettimemSecReset) + { + m_AppData.SettimemSec = curmsec; + m_AppData.setTimeFlag = 1; + } + + AlarmCalc(); + +} + + +//DI规约参数5=1,首次启动为1(告警),要产生SOE告警上送后台;同时参与进行事故总运算。 +void CModbusTcpMZDataProcThread::RTUAlarmInit(CFesRtuPtr RtuPtr) +{ + int i; + SFesDi *pDi; + SModbusTcpMZRTUData *pRTUData = new SModbusTcpMZRTUData; + + + pRTUData->m_RtuPtr = RtuPtr; + for (i = 0; i < RtuPtr->m_MaxDiPoints; i++) + { + pDi = RtuPtr->m_pDi + i; + if (pDi->Used == 1) + { + if (pDi->Param5 & 0x01)//bit0=1 参与告警 bit1=0:1为告警,bit1=1 0为告警(如通信状态) + { + pRTUData->m_AlarmPointPtr.push_back(pDi); + //LOGDEBUG("告警点 RTUNo=%d %s pointNo=%d", RtuPtr->m_Param.RtuNo,pDi->PointDesc, pDi->PointNo); + } + if ((pDi->Param2 == 65534) && (pDi->Param3 == 65534)) + { + pRTUData->m_AlarmDiPtr = pDi; + //LOGDEBUG("事故总 RTUNo=%d %s pointNo=%d", RtuPtr->m_Param.RtuNo,pDi->PointDesc, pDi->PointNo); + } + } + } + m_AppData.RTUData.push_back(pRTUData); + +} + +void CModbusTcpMZDataProcThread::AlarmInit() +{ + int RtuNo; + CFesRtuPtr pRtu; + + for (int i = 0; i < m_ptrCFesChan->m_RtuNum; i++) + { + RtuNo = m_ptrCFesChan->m_RtuNo[i]; + pRtu = m_ptrCFesBase->GetRtuDataByRtuNo(RtuNo); + if (pRtu) + { + RTUAlarmInit(pRtu); + } + } +} + +void CModbusTcpMZDataProcThread::RTUAlarmCalc(SModbusTcpMZRTUData *pRtuData) +{ + SFesDi *pDi; + int i, size; + int alarmFlag = 0; + CFesRtuPtr RtuPtr; + + + if (pRtuData->m_AlarmDiPtr == NULL) + return; + size = (int)pRtuData->m_AlarmPointPtr.size(); + if (size == 0) + return; + + RtuPtr = pRtuData->m_RtuPtr; + pDi = NULL; + for (i = 0; i < size; i++) + { + pDi = pRtuData->m_AlarmPointPtr[i]; + if ((pDi->Value) && (!(pDi->Param5 & 0x02)))//bit1=0: 1为告警 + { + alarmFlag = 1; + break; + } + else + if ((!pDi->Value) && (pDi->Param5 & 0x02))//bit1=0: 0为告警 + { + alarmFlag = 1; + break; + } + } + + pDi = pRtuData->m_AlarmDiPtr; + SFesRtuDiValue DiValue; + SFesChgDi ChgDi; +// SFesSoeEvent SoeEvent; + uint64 mSec; + + mSec = getUTCTimeMsec(); + if ((alarmFlag != pDi->Value) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据,更新过的点才能报告变化 + { + memcpy(ChgDi.TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi.ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi.TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi.RtuNo = RtuPtr->m_Param.RtuNo; + ChgDi.PointNo = pDi->PointNo; + ChgDi.Value = alarmFlag; + ChgDi.Status = CN_FesValueUpdate; + ChgDi.time = mSec; + m_ptrCFesBase->WriteChgDiValue(RtuPtr, 1, &ChgDi); + +// SoeEvent.time = mSec; +// memcpy(SoeEvent.TableName, pDi->TableName, CN_FesMaxTableNameSize); +// memcpy(SoeEvent.ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); +// memcpy(SoeEvent.TagName, pDi->TagName, CN_FesMaxTagSize); +// SoeEvent.RtuNo = RtuPtr->m_Param.RtuNo; +// SoeEvent.PointNo = pDi->PointNo; +// SoeEvent.Value = alarmFlag; +// SoeEvent.Status = CN_FesValueUpdate; +// SoeEvent.FaultNum = 0; +// m_ptrCFesBase->WriteSoeEventBuf(RtuPtr, 1, &SoeEvent); +// //保存FesSim监视数据 +// m_ptrCFesBase->FesSimServerWriteSoeEvent(1, &SoeEvent); +// LOGDEBUG("RTUNo=%d ALARM value=%d", RtuPtr->m_Param.RtuNo, alarmFlag); + } + //更新点值 + DiValue.PointNo = pDi->PointNo; + DiValue.Value = alarmFlag; + DiValue.Status = CN_FesValueUpdate; + DiValue.time = mSec; + RtuPtr->WriteRtuDiValue(1, &DiValue); + +} + +void CModbusTcpMZDataProcThread::AlarmCalc() +{ + CFesRtuPtr pRtu; + SModbusTcpMZRTUData *pRtuData; + //uint64 curmsec; + + /*if (m_SGZCalcFlag == 0) + { + curmsec = getMonotonicMsec(); + //LOGDEBUG("curmsec=%lld m_SGZStartmSec=%lld m_SGZDelaymSec=%d", curmsec, m_SGZStartmSec, m_SGZDelaymSec); + if ((curmsec - m_SGZStartmSec) > m_SGZDelaymSec) + { + m_SGZCalcFlag = 1; + LOGDEBUG("开始故障检测!"); + } + return; + }*/ + //事故总计算 + for (int i = 0; i < m_AppData.RTUData.size(); i++) + { + pRtuData = m_AppData.RTUData[i]; + RTUAlarmCalc(pRtuData); + } +} + +int CModbusTcpMZDataProcThread::SetTimeProcess(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen) +{ + int retLen = 0; + + switch (RtuPtr->m_Param.ResParam3) + { + case CN_ModbusRtuMZ_PMC53AE: + retLen = SetTimePMC53AE(RtuPtr, Data, MaxDataLen); + break; + case CN_ModbusRtuMZ_ABBCB: + retLen = SetTimeABBCB(RtuPtr, Data, MaxDataLen); + break; + default: + break; + } + return retLen; +} + + +int CModbusTcpMZDataProcThread::SetTimePMC53AE(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen) +{ + int writex; + LOCALTIME stTime; + + writex = 7; + + getLocalSysTime(stTime); + Data[writex++] = 0x10; + Data[writex++] = 0x23; + Data[writex++] = 0x28;//9000 + Data[writex++] = 0; + Data[writex++] = 4; + Data[writex++] = 8;// char Count + Data[writex++] = (byte)(stTime.wYear % 100); + Data[writex++] = (byte)stTime.wMonth; + Data[writex++] = (byte)stTime.wDay; + Data[writex++] = (byte)stTime.wHour; + Data[writex++] = (byte)stTime.wMinute; + Data[writex++] = (byte)stTime.wSecond; + Data[writex++] = (byte)(stTime.wMilliseconds>>8)&0xff; + Data[writex++] = (byte)stTime.wMilliseconds & 0xff; + + FillHeader(Data, writex - 6); + return writex; + +} + +/* +@brief This service is used to convert the number of seconds since + 2000 to a full struct tm record. +*/ + +static const unsigned int tb_Days[] = +{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +/******************************************************************************** +struct tm { +// System defined we defined // +int tm_sec; // seconds after the minute - [0,59] | same // +int tm_min; // minutes after the hour - [0,59] | same // +int tm_hour; // hours since midnight - [0,23] | same // +int tm_mday; // day of the month - [1,31] | same // +int tm_mon; // months since January - [0,11] | same // +int tm_year; // years since 1900 | year(2000,...) // +int tm_wday; // days since Sunday - [0,6] | same // +int tm_yday; // days since January 1 - [0,365] | same // +int tm_isdst; // daylight savings time flag | not used // +}; +*********************************************************************************/ + +void CModbusTcpMZDataProcThread::MyLocaltime(unsigned int seconds, struct tm *tmtime) +{ + unsigned int Time = seconds; + unsigned int Timezone = 0; + + Time -= Timezone; + tmtime->tm_sec = Time % 60; /* Time in seconds */ + Time /= 60; + tmtime->tm_min = Time % 60; /* Time in minutes */ + Time /= 60; + tmtime->tm_wday = ((((unsigned int)Time / 24L) % 7) + 6) % 7; /* day in 2000.1.1 (Sat) */ + + tmtime->tm_year = 2000 + (int)((Time / (1461L * 24L)) * 4); + Time %= 1461L * 24L; + + if (Time >= 366 * 24) + { + Time -= 366 * 24; + tmtime->tm_year++; /*First year in the cycal:ep 2000->2001*/ + if (Time >= 365 * 24) + { + Time -= 365 * 24; + tmtime->tm_year++; + if (Time >= 365 * 24) + { + Time -= 365 * 24; + tmtime->tm_year++; + } + } + + } + tmtime->tm_hour = Time % 24; /* Time in hours */ + Time /= 24; + tmtime->tm_yday = Time; /* Days in years */ + Time++; + if ((tmtime->tm_year % 4) == 0) + { + if (Time > 60) + Time--; + else + if (Time == 60) + { + tmtime->tm_mon = 1; /* Month is 0~11 */ + tmtime->tm_mday = 29; + return; + } + } + for (tmtime->tm_mon = 0; tb_Days[tmtime->tm_mon] < Time; tmtime->tm_mon++) + Time -= tb_Days[tmtime->tm_mon]; + tmtime->tm_mday = Time; + +} + +/********************* TOPBAND AUTOMATION SYSTEM Ltd.************************** +* +* TITLE : tb_secfrom2000 +* +* BY : thxiao +* +* DATE : 3-Jun-2002 +* +* DESCRIPTION : 通过年月日时分秒(当地时间),得到从2000开始的秒数(系统时间) +* +******************************************************************************/ +/* +@brief 通过年月日时分秒(当地时间),得到从2000开始的秒数(系统时间) + +*/ +struct { + short mon; + unsigned int sec; + unsigned int specialSec; +}tb_mon_sec_table[] = { + /*月,年 ,闰年 */ + { 0, 0, 0 }, + { 1, 2678400,2678400 }, + { 2, 2419200,2505600 }, + { 3, 2678400,2678400 }, + { 4, 2592000,2592000 }, + { 5, 2678400,2678400 }, + { 6, 2592000,2592000 }, + { 7, 2678400,2678400 }, + { 8, 2678400,2678400 }, + { 9, 2592000,2592000 }, + { 10,2678400,2678400 }, + { 11,2592000,2592000 }, +}; + +unsigned int CModbusTcpMZDataProcThread::Secfrom2000( + short year, /* >=2000 */ + short month, /* 0~11 */ + short date, /* 1~31 */ + short hour, /* 0~23 */ + short minute, /* 0~59 */ + short second) /* 0~59 */ +{ + unsigned int sec[12], specialSec[12]; + unsigned int retSec; + int i; + short tempYear; + + memset(sec, 0, sizeof(sec)); + memset(specialSec, 0, sizeof(specialSec)); + for (i = 0; i<11; i++) + { + sec[i + 1] = tb_mon_sec_table[i + 1].sec + sec[i]; + specialSec[i + 1] = tb_mon_sec_table[i + 1].specialSec + specialSec[i]; + } + if ((year<2000) || (month<0) || (month>11) || (date<1) || (date>31) + || (hour<0) || (hour>23) || (minute<0) || (minute>59) || (second<0) || (second>59)) + return 0; + + retSec = 0; + retSec = (unsigned int)((year - 2000) / 4) * 126230400L;/* 126230400L = 1461 * 24 * 3600 */ + tempYear = 2000 + (year - 2000) / 4 * 4; + for (i = tempYear; i> 8) & 0xff; + Data[writex++] = (byte)sec2000 & 0xff; + Data[writex++] = (byte)(sec2000 >> 24) & 0xff; + Data[writex++] = (byte)(sec2000 >> 16) & 0xff; + Data[writex++] = (byte)(stTime.wMilliseconds >> 8) & 0xff; + Data[writex++] = (byte)stTime.wMilliseconds & 0xff; + FillHeader(Data, writex - 6); + return writex; + +} + +int CModbusTcpMZDataProcThread::RecvProcessComData(CFesRtuPtr RtuPtr, int FunCode, byte *retData, int &retDataLen) +{ + int count = 20; + int DevAddr, ExpectLen; + byte Data[512]; + int recvLen, Len, i; + + if (m_ptrCurrentChan == NULL) + return iotFailed; + + Len = 0; + recvLen = 0; + DevAddr = RtuPtr->m_Param.RtuAddr; + count = m_ptrCurrentChan->m_Param.RespTimeout / 10; + if (count <= 10) + count = 10;//最小响应超时为100毫秒 + ExpectLen = 0; + for (i = 0; iRxData(m_ptrCurrentChan); + + recvLen = m_ptrCurrentChan->ReadRxBufData(500 - Len, &Data[Len]);//数据缓存在 + if (recvLen <= 0) + { + if (ExpectLen == 0) + continue; + else//没有后续数据,退出接收 + if ((Len >= ExpectLen) && (ExpectLen>0)) + { + //LOGDEBUG("没有后续数据,退出接收 ChanNo=%d",m_ptrCFesChan->m_Param.ChanNo); + break; + } + } + + m_ptrCurrentChan->DeleteReadRxBufData(recvLen);//清除已读取的数据 + Len += recvLen; + if (Len >8) + { + //cmd = Data[7]; + if (Data[7] & 0x80)//ERROR + ExpectLen = 9; + else + { + switch (Data[7]) + { + case 0x01: + case 0x02: + ExpectLen = Data[8] + 9; + break; + case 0x05: + case 0x06: + case 0x10: + ExpectLen = 12; + break; + default://0x03\0x04 + ExpectLen = Data[8] + 9; + } + } + } + /*if((Len>=ExpectLen)&&(ExpectLen>0)) + { + break; + }*/ + } + if (Len>0) + ShowChanData(m_ptrCurrentChan->m_Param.ChanNo, Data, Len, CN_SFesSimComFrameTypeRecv); + + if (Len == 0)//接收不完整,重发数据 + { + return iotFailed; + } + //长度、地址、功能码 都正确则认为数据正确。 + if ((Len == ExpectLen) && (DevAddr == Data[6]) && (FunCode == (Data[7] & 0x7f))) + { + //2022-03-31 thxiao 为了避免帧错位的情况出现,事务处理标识符不同,放弃处理,并且清空接收队列。 + uint16 clientTransID; + clientTransID = (uint16)Data[0] << 8; + clientTransID |= (uint16)Data[1]; + clientTransID++; + //2022-09-02 thxiao MODBUSTCPV2 目前没有推广使用,所以默认为判断clientTransID。 + if ((m_ptrCFesRtu->m_Param.ResParam1 == 0) && (clientTransID != m_ptrCFesRtu->m_clientTransID)) + { + m_ptrCurrentChan->ClearDataBuf();//清除缓冲的数据 + if (m_AppData.m_TransIDFailCount++ > 5)//2022-04-22 thxiao clientTransID error exceed max times close socket + { + m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao + m_ptrTcpClient->TcpClose(m_ptrCurrentChan); + LOGDEBUG("frame clientTransID error exceed max times close socket !", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + LOGDEBUG("clientTransID=%d m_ptrCFesRtu->m_clientTransID=%d discard the frame!", clientTransID, m_ptrCFesRtu->m_clientTransID); + return iotFailed; + } + else//2022-09-02 thxiao 科华有UPS设备响应是事务处理标识符+1,增加这种特殊的判断 + if ((m_ptrCFesRtu->m_Param.ResParam1 == 1) && (clientTransID != (m_ptrCFesRtu->m_clientTransID + 1))) + { + m_ptrCurrentChan->ClearDataBuf();//清除缓冲的数据 + if (m_AppData.m_TransIDFailCount++ > 5)//2022-04-22 thxiao clientTransID error exceed max times close socket + { + m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao + m_ptrTcpClient->TcpClose(m_ptrCurrentChan); + LOGDEBUG("frame clientTransID error exceed max times close socket !", clientTransID, m_ptrCFesRtu->m_clientTransID); + } + LOGDEBUG("clientTransID=%d m_ptrCFesRtu->m_clientTransID=%d discard the frame!", clientTransID, m_ptrCFesRtu->m_clientTransID); + return iotFailed; + } + else + { + m_AppData.m_TransIDFailCount = 0;//2022-04-22 thxiao + m_ptrCurrentChan->SetRxNum(1); + RtuPtr->ResetResendNum(); + RtuPtr->SetRxNum(1); + memcpy(retData, &Data[6], ExpectLen-6); + retDataLen = ExpectLen-6; + return iotSuccess; + + } + return iotSuccess; + } + else + { + return iotFailed; + } +} + +int CModbusTcpMZDataProcThread::AoVerifyProcess(CFesRtuPtr RtuPtr) +{ + byte Data[256]; + int writex; + int ret; + byte respData[256]; + int respDataSize, crcCount; + SFesRtuAiValue AiValue; + SFesChgAi ChgAi; + // uint64 mSec; + SFesAi *pAi; + SFesAo *pAo; + short sValue16; + uint16 uValue16; + int sValue32; + uint32 uValue32; + int ChgCount; + float fValue, aiValue; + + //读取控制结果 + if ((pAo = GetFesAoByPointNo(RtuPtr, m_AppData.aoCmd.PointID)) == NULL) + return iotFailed; + + if (pAo->Param7 == -1) + return iotFailed; + + //LOGDEBUG("AoVerifyProcess......4 pAo->Param7=%d", pAo->Param7); + pAi = GetFesAiByPIndex(RtuPtr, pAo->Param7); + + if (pAi != NULL) + { + writex = 7; + Data[writex++] = pAi->Param2;//功能码 + Data[writex++] = (pAi->Param3 >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = pAi->Param3 & 0x00ff;//寄存器起始地址L + if (pAi->Param4 <= 6)//3-6 16bit + { + Data[writex++] = 0x00; + Data[writex++] = 0x01; + } + else//7-15 32bit + { + Data[writex++] = 0x00; + Data[writex++] = 0x02; + } + FillHeader(Data, writex - 6); + + //send data to net + SendDataToPort(Data, writex); + + ret = RecvProcessComData(RtuPtr, pAi->Param2, respData, respDataSize); + + if (ret == iotFailed) + return iotFailed; + + if (respData[1] & 0x80) + return iotFailed; + + switch (pAi->Param4) + { + case AI_Word_HL: //word帧(16bit 有符号 高字节前) + sValue16 = (int16)respData[3] << 8; + sValue16 |= (int16)respData[4]; + aiValue = sValue16; + break; + case AI_Word_LH: //word帧(16bit 有符号 低字节前) + sValue16 = (int16)respData[4] << 8; + sValue16 |= (int16)respData[3]; + aiValue = sValue16; + break; + case AI_UWord_HL: //word帧(16bit 无符号 高字节前) + uValue16 = (uint16)respData[3] << 8; + uValue16 |= (uint16)respData[4]; + aiValue = uValue16; + break; + case AI_UWord_LH: //word帧(16bit 无符号 低字节前) + uValue16 = (uint16)respData[4] << 8; + uValue16 |= (uint16)respData[3]; + aiValue = (float)uValue16; + break; + case AI_DWord_HH: //dword帧(32bit 有符号 高字前 高字节前) + sValue32 = (int)respData[3] << 24; + sValue32 |= (int)respData[4] << 16; + sValue32 |= (int)respData[5] << 8; + sValue32 |= (int)respData[6]; + aiValue = (float)sValue32; + break; + case AI_DWord_LH: //dword帧(32bit 有符号 低字前 高字节前) + sValue32 = (int)respData[5] << 24; + sValue32 |= (int)respData[6] << 16; + sValue32 |= (int)respData[3] << 8; + sValue32 |= (int)respData[4]; + aiValue = (float)sValue32; + break; + case AI_DWord_LL: //dword帧(32bit 有符号 低字前 低字节前) + sValue32 = (int)respData[6] << 24; + sValue32 |= (int)respData[5] << 16; + sValue32 |= (int)respData[4] << 8; + sValue32 |= (int)respData[3]; + aiValue = (float)sValue32; + break; + case AI_UDWord_HH: //dword帧(32bit 无符号 高字前 高字节前) + uValue32 = (uint32)respData[3] << 24; + uValue32 |= (uint32)respData[4] << 16; + uValue32 |= (uint32)respData[5] << 8; + uValue32 |= (uint32)respData[6]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LH: //dword帧(32bit 无符号 低字前 高字节前) + uValue32 = (uint32)respData[5] << 24; + uValue32 |= (uint32)respData[6] << 16; + uValue32 |= (uint32)respData[3] << 8; + uValue32 |= (uint32)respData[4]; + aiValue = (float)uValue32; + break; + case AI_UDWord_LL: //dword帧(32bit 无符号 低字前 低字节前) + uValue32 = (uint32)respData[6] << 24; + uValue32 |= (uint32)respData[5] << 16; + uValue32 |= (uint32)respData[4] << 8; + uValue32 |= (uint32)respData[3]; + aiValue = (float)uValue32; + break; + case AI_Float_HH: //float帧(四字节浮点 高字前 高字节前) + uValue32 = (uint32)respData[3] << 24; + uValue32 |= (uint32)respData[4] << 16; + uValue32 |= (uint32)respData[5] << 8; + uValue32 |= (uint32)respData[6]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LH: //float帧(四字节浮点 低字前 高字节前) + uValue32 = (uint32)respData[5] << 24; + uValue32 |= (uint32)respData[6] << 16; + uValue32 |= (uint32)respData[3] << 8; + uValue32 |= (uint32)respData[4]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + case AI_Float_LL: //float帧(四字节浮点 低字前 低字节前) + uValue32 = (uint32)respData[6] << 24; + uValue32 |= (uint32)respData[5] << 16; + uValue32 |= (uint32)respData[4] << 8; + uValue32 |= (uint32)respData[3]; + memcpy(&fValue, &uValue32, sizeof(float)); + aiValue = fValue; + break; + default: + sValue16 = (int16)respData[3] << 8; + sValue16 |= (int16)respData[4]; + aiValue = sValue16; + break; + } + AiValue.PointNo = pAi->PointNo; + AiValue.Value = aiValue; + AiValue.Status = CN_FesValueUpdate; + AiValue.time = getUTCTimeMsec(); + //AI 需要判断的情况很多,所以“WriteRtuAiValueAndRetChg”内部进行判断 + RtuPtr->WriteRtuAiValueAndRetChg(1, &AiValue, &ChgCount, &ChgAi); + if ((ChgCount > 0) && (g_ModbusTcpMZIsMainFes == true))//主机才报告变化数据 + { + m_ptrCFesBase->WriteChgAiValue(RtuPtr, ChgCount, &ChgAi); + } + LOGDEBUG("遥调成功!AoVerifyProcess 成功,PointNo=%d value=%f!", pAi->PointNo, aiValue); + } + return iotSuccess; +} + + + +void CModbusTcpMZDataProcThread::RTUABBTripInit(CFesRtuPtr RtuPtr) +{ + int i; + SFesDi *pDi; + + if (RtuPtr->m_Param.ResParam3 != CN_ModbusRtuMZ_ABBCB) + return; + + for (i = 0; i < RtuPtr->m_MaxDiPoints; i++) + { + pDi = RtuPtr->m_pDi + i; + if ((pDi->Used == 1) && (pDi->Param3 == 3500)) + { + m_AppData.CBTripPtr.push_back(pDi); + m_AppData.CBTripMap.insert(make_pair(pDi->Param4, pDi)); + LOGDEBUG("CBTrip pDi->PointNo=%d Param3=%d Param4=%d", pDi->PointNo, pDi->Param3, pDi->Param4); + } + } + +} + +void CModbusTcpMZDataProcThread::ABBCBEventProcess(CFesRtuPtr RtuPtr,byte *Data) +{ + int FunCode, diValue, bitValue; + int i, StartAddr, DataLen, ValueCount, ChgCount, SoeCount, PointIndex; + SFesDi *pDi; + SABBCBEvent event; + vector vetEvent; + int ECnt,finsh; + byte reqData[256]; + int writex; + int ret; + byte respData[256]; + int respDataSize, frameCnt,eventCount; + + FunCode = m_AppData.lastCmd.FunCode; + StartAddr = m_AppData.lastCmd.StartAddr; + DataLen = m_AppData.lastCmd.DataLen; + + if (m_AppData.CBEvent.Type == 0)//第一次读取事件,不做任何处理,只是把最近的事件时间保存下来。 + { + if (StartAddr == 3500) + { + m_AppData.CBEvent.Type = (uint16)Data[3] << 8; + m_AppData.CBEvent.Type |= (uint16)Data[4]; + m_AppData.CBEvent.Sec = (uint32)Data[5] << 8; + m_AppData.CBEvent.Sec |= (uint32)Data[6]; + m_AppData.CBEvent.Sec |= (uint32)Data[7] << 24; + m_AppData.CBEvent.Sec |= (uint32)Data[8] << 16; + m_AppData.CBEvent.mSec = (uint16)Data[9] << 8; + m_AppData.CBEvent.mSec |= (uint16)Data[10]; + LOGDEBUG("RtuNo=%d 第一次读取事件", RtuPtr->m_Param.RtuAddr); + } + return; + } + ECnt = Data[2] / 8; + finsh = 0; + for (i = 0; i < ECnt; i++) + { + event.Type = (uint16)Data[i * 8 + 3] << 8; + event.Type |= (uint16)Data[i * 8 + 4]; + event.Sec = (uint32)Data[i * 8 + 5] << 8; + event.Sec |= (uint32)Data[i * 8 + 6]; + event.Sec |= (uint32)Data[i * 8 + 7] << 24; + event.Sec |= (uint32)Data[i * 8 + 8] << 16; + event.mSec = (uint16)Data[i * 8 + 9] << 8; + event.mSec |= (uint16)Data[i * 8 + 10]; + if ((event.Type == m_AppData.CBEvent.Type) && (event.Sec == m_AppData.CBEvent.Sec) && (event.mSec == m_AppData.CBEvent.mSec)) + { + finsh = 1; + break; + } + if ((event.Sec + 3600) < m_AppData.CBEvent.Sec) + { + //只处理离最新时间一小时内的事件 + finsh = 1; + break; + } + LOGDEBUG("ABB CB事件 RtuNo=%d Type=%d Sec=%lld mSec=%d", RtuPtr->m_Param.RtuAddr, event.Type, event.Sec, event.mSec); + vetEvent.push_back(event); + } + frameCnt = 0; + while (!finsh) + { + //继续读取事件 + writex = 7; + StartAddr += DataLen; + + if (StartAddr >= 4500) + break; + + if ((StartAddr + DataLen) > 4500) + { + int tempLen; + tempLen = 4500 - StartAddr; + DataLen = tempLen; + if (DataLen <= 0) + { + LOGDEBUG("read event no data to read"); + break; + } + LOGDEBUG("read event last frame"); + } + frameCnt++; + LOGDEBUG("read event frameCnt=%d FunCode=%d StartAddr=%d DataLen=%d", frameCnt, FunCode, StartAddr, DataLen); + + Data[writex++] = FunCode;//功能码 + Data[writex++] = (StartAddr >> 8) & 0x00ff;//寄存器起始地址H + Data[writex++] = StartAddr & 0x00ff;//寄存器起始地址L + Data[writex++] = (DataLen >> 8) & 0x00ff; + Data[writex++] = DataLen & 0x00ff; + FillHeader(Data, writex - 6); + + //send data to net + SendDataToPort(Data, writex); + ret = RecvProcessComData(RtuPtr, FunCode, respData, respDataSize); + if (ret == iotFailed) + return; + + ECnt = respData[3] / 8; + finsh = 0; + for (i = 0; i < ECnt; i++) + { + event.Type = (uint16)respData[i * 8 + 3] << 8; + event.Type |= (uint16)respData[i * 8 + 4]; + event.Sec = (uint32)respData[i * 8 + 5] << 8; + event.Sec |= (uint32)respData[i * 8 + 6]; + event.Sec |= (uint32)respData[i * 8 + 7] << 24; + event.Sec |= (uint32)respData[i * 8 + 8] << 16; + event.mSec = (uint16)respData[i * 8 + 9] << 8; + event.mSec |= (uint16)respData[i * 8 + 10]; + if ((event.Type == m_AppData.CBEvent.Type) && (event.Sec == m_AppData.CBEvent.Sec) && (event.mSec == m_AppData.CBEvent.mSec)) + { + finsh = 1; + break; + } + if ((event.Sec + 3600) < m_AppData.CBEvent.Sec) + { + //只处理离最新时间一小时内的事件 + finsh = 1; + break; + } + LOGDEBUG("ABB CB事件 RtuNo=%d Type=%d Sec=%" PRId64 " mSec=%d", RtuPtr->m_Param.RtuAddr, event.Type, event.Sec, event.mSec); + vetEvent.push_back(event); + } + } + + //在所有符合条件的事件中提取我们需要的事件 + eventCount = vetEvent.size(); + if (eventCount == 0) + return; + for (i = 0; i < eventCount; i++) + { + event = vetEvent[eventCount - 1 - i];//按时间顺序处理事件 + if (event.Type == CN_ABBCB_TripReset)//34=Trip reset,所有的跳闸信号清零 + ABBCBResetTrip(RtuPtr, event); + else + if((event.Type >= CN_ABBCB_Ltripped)&&(event.Type <= CN_ABBCB_Gtripped)) + ABBCBTrip(RtuPtr, event); + } + + //更新最新的时间 + m_AppData.CBEvent.Type = vetEvent[0].Type; + m_AppData.CBEvent.Sec = vetEvent[0].Sec; + m_AppData.CBEvent.mSec = vetEvent[0].mSec; + LOGDEBUG("RtuNo=%d 更新事件最新时间 ", RtuPtr->m_Param.RtuAddr); + +} + + +int CModbusTcpMZDataProcThread::ABBCBResetTrip(CFesRtuPtr RtuPtr, SABBCBEvent &RestEvent) +{ + int i; + SFesDi *pDi; + SFesRtuDiValue DiValue; + SFesChgDi ChgDi; + SFesSoeEvent SoeEvent; + int64 mSec; + + if (m_AppData.CBTripPtr.size() == 0) + return iotFailed; + for (i = 0; i < m_AppData.CBTripPtr.size(); i++) + { + pDi = m_AppData.CBTripPtr[i]; + if (pDi->Value) + { + mSec = RestEvent.Sec * 1000 + CN_ABBCB_BasemSec; + mSec += RestEvent.mSec; + memset(&ChgDi, 0, sizeof(ChgDi)); + + memcpy(ChgDi.TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi.ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi.TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi.RtuNo = RtuPtr->m_Param.RtuNo; + ChgDi.PointNo = pDi->PointNo; + ChgDi.Value = 0; + ChgDi.Status = CN_FesValueUpdate; + ChgDi.time = mSec; + m_ptrCFesBase->WriteChgDiValue(RtuPtr, 1, &ChgDi); + + memset(&SoeEvent, 0, sizeof(SoeEvent)); + memcpy(SoeEvent.TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent.ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent.TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent.RtuNo = RtuPtr->m_Param.RtuNo; + SoeEvent.PointNo = pDi->PointNo; + SoeEvent.Status = CN_FesValueUpdate; + SoeEvent.time = mSec; + SoeEvent.Value = 0; + SoeEvent.FaultNum = 0; + m_ptrCFesBase->WriteSoeEventBuf(RtuPtr, 1, &SoeEvent); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(1, &SoeEvent); + + DiValue.PointNo = pDi->PointNo; + DiValue.Value = 0; + DiValue.Status = CN_FesValueUpdate; + DiValue.time = mSec; + RtuPtr->WriteRtuDiValue(1, &DiValue); + + LOGDEBUG("ABBCBResetTrip RtuNo=%d PointNo=%d DiValue=%d", RtuPtr->m_Param.RtuNo, pDi->PointNo,DiValue.Value ); + } + } + return iotSuccess; +} + + +int CModbusTcpMZDataProcThread::ABBCBTrip(CFesRtuPtr RtuPtr, SABBCBEvent &TripEvent) +{ + SFesDi *pDi; + SFesRtuDiValue DiValue; + SFesChgDi ChgDi; + SFesSoeEvent SoeEvent; + int64 mSec; + std::map::iterator pos; + + pos = m_AppData.CBTripMap.find(TripEvent.Type); + if (pos == m_AppData.CBTripMap.end())//没有找到 + return iotFailed; + else + pDi =(SFesDi*)pos->second; + + if (pDi->Value==0) + { + mSec = TripEvent.Sec * 1000 + CN_ABBCB_BasemSec; + mSec += TripEvent.mSec; + memset(&ChgDi, 0, sizeof(ChgDi)); + + memcpy(ChgDi.TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(ChgDi.ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(ChgDi.TagName, pDi->TagName, CN_FesMaxTagSize); + ChgDi.RtuNo = RtuPtr->m_Param.RtuNo; + ChgDi.PointNo = pDi->PointNo; + ChgDi.Value = 1; + ChgDi.Status = CN_FesValueUpdate; + ChgDi.time = mSec; + m_ptrCFesBase->WriteChgDiValue(RtuPtr, 1, &ChgDi); + + memset(&SoeEvent, 0, sizeof(SoeEvent)); + memcpy(SoeEvent.TableName, pDi->TableName, CN_FesMaxTableNameSize); + memcpy(SoeEvent.ColumnName, pDi->ColumnName, CN_FesMaxColumnNameSize); + memcpy(SoeEvent.TagName, pDi->TagName, CN_FesMaxTagSize); + SoeEvent.RtuNo = RtuPtr->m_Param.RtuNo; + SoeEvent.PointNo = pDi->PointNo; + SoeEvent.Status = CN_FesValueUpdate; + SoeEvent.time = mSec; + SoeEvent.Value = 1; + SoeEvent.FaultNum = 0; + m_ptrCFesBase->WriteSoeEventBuf(RtuPtr, 1, &SoeEvent); + //保存FesSim监视数据 + m_ptrCFesBase->FesSimServerWriteSoeEvent(1, &SoeEvent); + + DiValue.PointNo = pDi->PointNo; + DiValue.Value = 1; + DiValue.Status = CN_FesValueUpdate; + DiValue.time = mSec; + RtuPtr->WriteRtuDiValue(1, &DiValue); + + LOGDEBUG("ABBCBTrip RtuNo=%d PointNo=%d DiValue=%d", RtuPtr->m_Param.RtuNo, pDi->PointNo, DiValue.Value); + + } +} diff --git a/product/src/fes/protocol/modbus_tcp_mz/ModbusTcpMZDataProcThread.h b/product/src/fes/protocol/modbus_tcp_mz/ModbusTcpMZDataProcThread.h new file mode 100644 index 00000000..43ed0847 --- /dev/null +++ b/product/src/fes/protocol/modbus_tcp_mz/ModbusTcpMZDataProcThread.h @@ -0,0 +1,207 @@ +/* + @file CModbusTcpMZDataProcThread.h + @brief ModbusTcpMZ 数据处理线程类 + @author thxiao +*/ +#pragma once + +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "ComTcpClient.h" + +using namespace iot_public; + +//*****************设备类型************************ +const int CN_ModbusRtuMZ_Other = 0; //其他 +// 地铁电源监控设备类型 +// const int CN_ModbusRtuDT_YD = 1; +// const int CN_ModbusRtuDT_YM_KK16 = 2; //16路继电器输出模块|YM-KK16|雅达 +// const int CN_ModbusRtuDT_KHUPS = 3; +// const int CN_ModbusRtuDT_GK = 4; +// const int CN_ModbusRtuDT_BMS = 5; +//云动力模组设备类型 +const int CN_ModbusRtuMZ_LDB10 = 6; //LD 系列干式变压器温控器 +const int CN_ModbusRtuMZ_PMC53AE = 7; //PMC-53A-E 三相数字电表装置 +const int CN_ModbusRtuMZ_ABBCB = 8; //ABB 断路器 + +// ABB 断路器事件代号 +const int CN_ABBCB_TripReset = 34; +const int CN_ABBCB_Ltripped = 161; //过载跳闸 +const int CN_ABBCB_Stripped = 162; //短路选择跳闸 +const int CN_ABBCB_Itripped = 163; //短路瞬时跳闸 +const int CN_ABBCB_Gtripped = 164; //接地跳闸 + +const int64 CN_ABBCB_BaseSec = 0x386D4380; //10957*24*3600L=946684800L +const int64 CN_ABBCB_BasemSec = 0xDC6ACFAC00; //10957*24*3600=946684800000L 1970~2000.1.1.00:00的秒数 + +#define CN_ModbusTcpMZ_MAX_CMD_LEN 256 + +//define SModbusTcpMZAppData state +const int CN_ModbusTcpMZAppState_idle = 0; +const int CN_ModbusTcpMZAppState_waitControlResp = 1; + +//define SModbusTcpMZAppData lastCotrolcmd +const int CN_ModbusTcpMZNoCmd = 0; +const int CN_ModbusTcpMZDoCmd = 1; +const int CN_ModbusTcpMZAoCmd = 2; +const int CN_ModbusTcpMZMoCmd = 3; +const int CN_ModbusTcpMZDefCmd = 4; + +//增加的数据类型,之前的定义在FesDef.h +#define AI_SIGNEDFLAG16_HL 62 //模拟量帧(符号位(bit15)加数值 高字节前) +#define AI_SIGNEDFLAG32_HL 63 //模拟量帧(符号位(bit31)加数值 高字节前) + +#define MODBUSTCPV3_K_MAX_POINT_INDEX 200 //接收缓存最大索引 + + +typedef struct _SModbusTcpMZRTUData { + CFesRtuPtr m_RtuPtr; + vector m_AlarmPointPtr; + SFesDi *m_AlarmDiPtr; + + _SModbusTcpMZRTUData() { + m_RtuPtr = NULL; + m_AlarmDiPtr = NULL; + } +}SModbusTcpMZRTUData; + +//ABB CB event +typedef struct _SABBCBEvent { + uint16 Type; + uint32 Sec; + uint16 mSec; + _SABBCBEvent() { + Type = 0; + Sec = 0; + mSec = 0; + } +}SABBCBEvent; + +//ModbusTcpMZ 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct{ + int index; + int state; + int comState; + int lastCotrolcmd; + byte lastCmdData[CN_ModbusTcpMZ_MAX_CMD_LEN]; + int lastCmdDataLen; + SModbusCmd lastCmd; + SFesRxDoCmd doCmd; + SFesRxAoCmd aoCmd; + SFesRxMoCmd moCmd; + SFesRxDefCmd defCmd; + int setCmdCount; + int m_TransIDFailCount; //2022-04-22 thxiao + + //对时处理 + int64 SettimemSec; + int64 SettimemSecReset; + int setTimeFlag; + + SABBCBEvent CBEvent; + vector CBTripPtr; + map CBTripMap; + + vector RTUData; + +}SModbusTcpMZAppData; + +//2021-06-25 ljj +typedef struct { + uint32 headIndex; + uint32 tailIndex; +}SFesBaseBlockDataIndexInfo; //数据块关联数据索引信息 + +class CModbusTcpMZDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + CModbusTcpMZDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan); + virtual ~CModbusTcpMZDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + /* + @brief 执行quit函数前的处理 + */ + virtual void beforeQuit(); + + void ClearTcpClientByChanNo(int ChanNo); + void SetTcpClientByChanNo(int ChanNo); + + CFesBase* m_ptrCFesBase; + + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,ModbusTcpMZ 每个通道对应一个RTU数据,所以不需要轮询处理。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + int m_ClearClientFlag; + + SModbusTcpMZAppData m_AppData; //内部应用数据结构 + + map m_AiBlockDataIndexInfo; //2021-06-25 ljj + map m_DiBlockDataIndexInfo; + map m_AccBlockDataIndexInfo; + map m_MiBlockDataIndexInfo; + + CComTcpClientPtr m_ptrTcpClient; + +private: + int SendProcess(); + int RecvNetData(); + int InsertCmdProcess(); + void ErrorControlRespProcess(); + int PollingCmdProcess(); + void FillHeader(byte *Data, int Size); + int SendDataToPort(byte *Data, int Size); + int DoCmdProcess(byte *Data, int dataSize); + int AoCmdProcess(byte *Data, int dataSize); + int MoCmdProcess(byte *Data, int dataSize); + int SettingCmdProcess(); + int DefCmdProcess(byte *Data, int dataSize); + int GetPollingCmd(SModbusCmd *pCmd); + int RecvDataProcess(byte *Data,int DataSize); + void Cmd05RespProcess(byte *Data,int DataSize); + void Cmd06RespProcess(byte *Data,int DataSize); + void Cmd10RespProcess(byte *Data,int DataSize); + bool CmdControlRespProcess(byte *Data,int DataSize,int okFlag); + void SetSendCmdFlag(); + int Cmd03RespProcess_BitGroup(SFesDi *pDi, int diValue); + + void InitProtocolBlockDataIndexMapping(CFesRtuPtr RtuPtr); + void Cmd01RespProcess(byte *Data); + void Cmd03RespProcess(byte *Data); + void CmdTypeHybridProcess(byte *Data, int DataSize); + + + int m_timerCount; + int m_timerCountReset; + + void RTUAlarmInit(CFesRtuPtr RtuPtr); + void RTUAlarmCalc(SModbusTcpMZRTUData *pRtuData); + void AlarmCalc(); + void AlarmInit(); + void TimerProcess(); + int SetTimeProcess(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen); + int SetTimePMC53AE(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen); + + void MyLocaltime(unsigned int seconds, struct tm *tmtime); + unsigned int Secfrom2000(short year, short month, short date, short hour, short minute, short second); + int SetTimeABBCB(CFesRtuPtr RtuPtr, byte *Data, int MaxDataLen); + + int RecvProcessComData(CFesRtuPtr RtuPtr, int FunCode, byte *retData, int &retDataLen); + int AoVerifyProcess(CFesRtuPtr RtuPtr); + void RTUABBTripInit(CFesRtuPtr RtuPtr); + void ABBCBEventProcess(CFesRtuPtr RtuPtr,byte *Data); + int ABBCBResetTrip(CFesRtuPtr RtuPtr, SABBCBEvent &RestEvent); + int ABBCBTrip(CFesRtuPtr RtuPtr, SABBCBEvent &TripEvent); + +}; + +typedef boost::shared_ptr CModbusTcpMZDataProcThreadPtr; + diff --git a/product/src/fes/protocol/modbus_tcp_mz/modbus_tcp_mz.pro b/product/src/fes/protocol/modbus_tcp_mz/modbus_tcp_mz.pro new file mode 100644 index 00000000..106c07f8 --- /dev/null +++ b/product/src/fes/protocol/modbus_tcp_mz/modbus_tcp_mz.pro @@ -0,0 +1,39 @@ +QT -= core gui +CONFIG -= qt + +TARGET = modbus_tcp_mz +TEMPLATE = lib + +SOURCES += \ + ModbusTcpMZ.cpp \ + ModbusTcpMZDataProcThread.cpp \ + ../combase/ComTcpClient.cpp \ + +HEADERS += \ + ModbusTcpMZ.h \ + ModbusTcpMZDataProcThread.h \ + ../../include/ComTcpClient.h \ + +INCLUDEPATH += \ + ../../include/ \ + ../../../include/ \ + ../../../3rd/include/ + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase +LIBS += -lprotobuf -lboost_locale -lboost_regex +LIBS += -lrdb_api + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + +DEFINES += PROTOCOLBASE_API_EXPORTS + + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/fes/protocol/modbus_tcp_s/MdbTcpSer.cpp b/product/src/fes/protocol/modbus_tcp_s/MdbTcpSer.cpp index f6085c27..08737233 100644 --- a/product/src/fes/protocol/modbus_tcp_s/MdbTcpSer.cpp +++ b/product/src/fes/protocol/modbus_tcp_s/MdbTcpSer.cpp @@ -93,7 +93,7 @@ int CMdbTcpSer::SetBaseAddr(void *address) int CMdbTcpSer::SetProperty(int IsMainFes) { - g_MdbTcpSerIsMainFes = (bool)IsMainFes; + g_MdbTcpSerIsMainFes = (IsMainFes != 0); LOGDEBUG("CMdbTcpSer::SetProperty g_MdbTcpSerIsMainFes:%d",IsMainFes); return iotSuccess; } @@ -226,12 +226,16 @@ int CMdbTcpSer::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) */ int CMdbTcpSer::ChanTimer(int MainChanNo) { + boost::ignore_unused_variable_warning(MainChanNo); + //把命令缓冲时间间隔到的命放到发送命令缓冲区 return iotSuccess; } int CMdbTcpSer::ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + InformTcpThreadExit(); return iotSuccess; } diff --git a/product/src/fes/protocol/modbus_tcp_s/MdbTcpSerDataProcThread.cpp b/product/src/fes/protocol/modbus_tcp_s/MdbTcpSerDataProcThread.cpp index 46dac65f..db8221b1 100644 --- a/product/src/fes/protocol/modbus_tcp_s/MdbTcpSerDataProcThread.cpp +++ b/product/src/fes/protocol/modbus_tcp_s/MdbTcpSerDataProcThread.cpp @@ -28,6 +28,14 @@ using namespace iot_public; extern bool g_MdbTcpSerIsMainFes; extern bool g_MdbTcpSerChanelRun; const int gMdbTcpSerThreadTime = 10; + +_SYTPntParam::_SYTPntParam() +{ + nPntType = -1; + pFwAo = NULL; + pFwMo = NULL; +} + CMdbTcpSerDataProcThread::CMdbTcpSerDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam): CTimerThreadBase("MdbTcpSerDataProcThread", gMdbTcpSerThreadTime,0,true) { @@ -92,6 +100,11 @@ CMdbTcpSerDataProcThread::CMdbTcpSerDataProcThread(CFesBase *ptrCFesBase,CFesCh m_AppData.startDelay = getMonotonicMsec();//2021-05-06 thxiao + m_nMiMinPntNo = -1; + m_nMiMaxPntNo = -1; + parseMiMaxMinPntNo(); + + buildYtRelation(); } @@ -236,7 +249,6 @@ void CMdbTcpSerDataProcThread::DiDataProcess(int FunCode,int StartAddr, int Regi bool bErrnoFlag=false; SFesFwDi *pFwDi; uint8 data[DATA_MAX_LEN]; - SFesFwDiValue retValue; int temp1 = StartAddr + RegisterNum; int temp2 = m_AppData.diStartAddress + m_ptrCFesRtu->m_MaxFwDiPoints; @@ -303,10 +315,80 @@ void CMdbTcpSerDataProcThread::DiDataProcess(int FunCode,int StartAddr, int Regi void CMdbTcpSerDataProcThread::AiDataProcess(int FunCode,int StartAddr, int RegisterNum) { - if(m_AppData.AiRegisterType==32) - Ai32DataProcess(FunCode,StartAddr,RegisterNum); - else - Ai16DataProcess(FunCode, StartAddr, RegisterNum); + int nMaxPntNo = m_ptrCFesRtu->m_MaxFwAiPoints; + if(m_ptrCFesRtu->m_MaxFwMiPoints > nMaxPntNo) + { + nMaxPntNo = m_ptrCFesRtu->m_MaxFwMiPoints; + } + + int nReqEndAddr = StartAddr + RegisterNum; + int nFwEndAddr = m_AppData.aiStartAddress + nMaxPntNo; + int nAddrOffset = StartAddr - m_AppData.aiStartAddress; + + if((nMaxPntNo <= 0) || (nMaxPntNo < RegisterNum) || (RegisterNum > SEND_16AI_COUNT) || + (nAddrOffset < 0) || (nAddrOffset >= nMaxPntNo) || (nReqEndAddr > nFwEndAddr)) + { + return ErrorFrameProcess(FunCode,ERRORREGISTER); + } + + int nLastPntNo = nAddrOffset + RegisterNum - 1; + SFesFwAi *pFwAi = m_ptrCFesRtu->m_pFwAi + nLastPntNo; //此时指针不一定合法,不能直接使用 + if(nLastPntNo < m_ptrCFesRtu->m_MaxAiPoints && pFwAi->Used && pFwAi->ResParam1 >= 10) + { + //最后一个测点配置了32格式,被拆分认为块分配错误 + return ErrorFrameProcess(FunCode,ERRORREGISTER); + } + + bool bIncludeMi = false; //本次请求范围是否包含混合量测点 + if((m_nMiMinPntNo >= nAddrOffset && m_nMiMinPntNo <= nLastPntNo) || + (m_nMiMaxPntNo >= nAddrOffset && m_nMiMaxPntNo <= nLastPntNo)) + { + SFesFwMi *pMi = m_ptrCFesRtu->m_pFwMi + nLastPntNo; + if(pMi->Used && pMi->ResParam1 >= 10)//最后一个测点配置了32格式,被拆分认为块分配错误 + { + return ErrorFrameProcess(FunCode,ERRORREGISTER); + } + + bIncludeMi = true; + } + + uint8 data[DATA_MAX_LEN]; + int writex = 6; + data[writex++] = m_AppData.address; + data[writex++] = FunCode; + data[writex++] = RegisterNum*2; + for(int i= 0;i < RegisterNum;) + { + int nPntNo = nAddrOffset+i; + float fAiValue = 0.0; + int nResParam1 = -1; + if(nPntNo < m_ptrCFesRtu->m_MaxFwAiPoints) + { + pFwAi = m_ptrCFesRtu->m_pFwAi + nPntNo; + if(pFwAi->Used) + { + fAiValue = pFwAi->Value; + nResParam1 = pFwAi->ResParam1; + } + } + + if(bIncludeMi) + { + SFesFwMi *pFwMi = m_ptrCFesRtu->m_pFwMi + nPntNo; + if(pFwMi->Used) + { + fAiValue = (float)(pFwMi->Value); + nResParam1 = pFwMi->ResParam1; + } + } + + int nRegSize = buildValueToBuffer(&data[writex],nResParam1,fAiValue); //返回寄存器个数 + writex += nRegSize * 2; //字节数 + i += nRegSize; + } + + FillIFrameHeader(data,writex); + SendDataToPort(data,writex); } void CMdbTcpSerDataProcThread::Ai16DataProcess(int FunCode, int StartAddr, int RegisterNum) @@ -318,19 +400,19 @@ void CMdbTcpSerDataProcThread::Ai16DataProcess(int FunCode, int StartAddr, int R SFesFwAi *pFwAi; uint8 data[DATA_MAX_LEN]; - int temp1 = StartAddr + RegisterNum; - int temp2 = m_AppData.aiStartAddress + m_ptrCFesRtu->m_MaxFwAiPoints; - int temp3 = StartAddr - m_AppData.aiStartAddress; - + int temp1 = StartAddr + RegisterNum; + int temp2 = m_AppData.aiStartAddress + m_ptrCFesRtu->m_MaxFwAiPoints; + int temp3 = StartAddr - m_AppData.aiStartAddress; + if((m_ptrCFesRtu->m_MaxFwAiPoints<=0)||(m_ptrCFesRtu->m_MaxFwAiPointsSEND_16AI_COUNT)) { bErrnoFlag = true; } - else - if ((temp3 >= 0) && (temp3 < m_ptrCFesRtu->m_MaxFwAiPoints) && (temp1 <= temp2)) - bErrnoFlag = false; - else - bErrnoFlag = true; + else + if ((temp3 >= 0) && (temp3 < m_ptrCFesRtu->m_MaxFwAiPoints) && (temp1 <= temp2)) + bErrnoFlag = false; + else + bErrnoFlag = true; if(!bErrnoFlag) { @@ -340,28 +422,28 @@ void CMdbTcpSerDataProcThread::Ai16DataProcess(int FunCode, int StartAddr, int R data[writex++] = RegisterNum*2; for(i= 0;im_MaxFwAiPoints) - { - pFwAi = m_ptrCFesRtu->m_pFwAi+temp3+i; - fAiValue = (float)(pFwAi->Value*pFwAi->Coeff + pFwAi->Base); - wordValue = (int)fAiValue; - if (pFwAi->ResParam1 == 1) //备用参数为1:低字节在前、高字节在后 - { - data[writex++] = (uint8)wordValue; - data[writex++] = (uint8)(wordValue >> 8); - } - else //缺省品质属性为0:高字节在前、低字节在后 - { - data[writex++] = (uint8)(wordValue >> 8); - data[writex++] = (uint8)wordValue; - } - } - else - { - data[writex++] = 0; - data[writex++] = 0; - } + wordValue = 0; + if ((temp3 +i) < m_ptrCFesRtu->m_MaxFwAiPoints) + { + pFwAi = m_ptrCFesRtu->m_pFwAi+temp3+i; + fAiValue = pFwAi->Value; + wordValue = (int)fAiValue; + if (pFwAi->ResParam1 == 1) //备用参数为1:低字节在前、高字节在后 + { + data[writex++] = (uint8)wordValue; + data[writex++] = (uint8)(wordValue >> 8); + } + else //缺省品质属性为0:高字节在前、低字节在后 + { + data[writex++] = (uint8)(wordValue >> 8); + data[writex++] = (uint8)wordValue; + } + } + else + { + data[writex++] = 0; + data[writex++] = 0; + } } FillIFrameHeader(data,writex); SendDataToPort(data,writex); @@ -410,8 +492,8 @@ void CMdbTcpSerDataProcThread::Ai32DataProcess(int FunCode, int StartAddr, int R if((startNum + i)< m_ptrCFesRtu->m_MaxFwAiPoints) { pFwAi = m_ptrCFesRtu->m_pFwAi + startNum + i; - fAiValue = (float)(pFwAi->Value*pFwAi->Coeff + pFwAi->Base); - dWordValue = (int)fAiValue; + fAiValue = pFwAi->Value; + dWordValue = (int)fAiValue; switch (pFwAi->ResParam1) { case 1: // (1--int 低字在前,高字在后;高字节在前,低字节在后) @@ -479,13 +561,43 @@ void CMdbTcpSerDataProcThread::Ai32DataProcess(int FunCode, int StartAddr, int R } } - void CMdbTcpSerDataProcThread::AccDataProcess(int FunCode,int StartAddr, int RegisterNum) { - if(m_AppData.AccRegisterType==32) - Acc32DataProcess(FunCode,StartAddr,RegisterNum); - else - Acc16DataProcess(FunCode, StartAddr, RegisterNum); + int nReqEndAddr = StartAddr + RegisterNum; + int nFwEndAddr = m_AppData.accStartAddress + m_ptrCFesRtu->m_MaxFwAccPoints; + int nAddrOffset = StartAddr - m_AppData.accStartAddress; + + if( (m_ptrCFesRtu->m_MaxFwAccPoints <= 0) || (m_ptrCFesRtu->m_MaxFwAccPoints < RegisterNum) || + (RegisterNum > SEND_16ACC_COUNT) || (nAddrOffset < 0) || + (nAddrOffset >= m_ptrCFesRtu->m_MaxFwAccPoints) || (nReqEndAddr > nFwEndAddr) ) + { + return ErrorFrameProcess(FunCode,ERRORREGISTER); + } + + int nLastPntNo = nAddrOffset + RegisterNum - 1; + SFesFwAcc *pFwAcc = m_ptrCFesRtu->m_pFwAcc + nLastPntNo; + if(pFwAcc->ResParam1 >= 10) //最后一个测点配置了32格式,被拆分认为块分配错误 + { + return ErrorFrameProcess(FunCode,ERRORREGISTER); + } + + uint8 data[DATA_MAX_LEN]; + int writex = 6; + data[writex++] = m_AppData.address; + data[writex++] = FunCode; + data[writex++] = RegisterNum*2; + for (int i = 0; i < RegisterNum;) + { + pFwAcc = m_ptrCFesRtu->m_pFwAcc + nAddrOffset + i; + float fAccValue = (float)(pFwAcc->Value); + + int nRegSize = buildValueToBuffer(&data[writex],pFwAcc->ResParam1,fAccValue); //返回寄存器个数 + writex += nRegSize * 2; //字节数 + i += nRegSize; + } + + FillIFrameHeader(data,writex); + SendDataToPort(data,writex); } void CMdbTcpSerDataProcThread::Acc16DataProcess(int FunCode, int StartAddr, int RegisterNum) @@ -524,7 +636,7 @@ void CMdbTcpSerDataProcThread::Acc16DataProcess(int FunCode, int StartAddr, int if ((temp3 + i) < m_ptrCFesRtu->m_MaxFwAccPoints) { pFwAcc = m_ptrCFesRtu->m_pFwAcc + temp3 + i; - fAccValue = (float)(pFwAcc->Value*pFwAcc->Coeff + pFwAcc->Base); + fAccValue = (float)(pFwAcc->Value); wordValue = (int)fAccValue; if (pFwAcc->ResParam1 == 1) //备用参数为1:低字节在前、高字节在后 { @@ -589,7 +701,7 @@ void CMdbTcpSerDataProcThread::Acc32DataProcess(int FunCode, int StartAddr, int if ((startNum + i) < m_ptrCFesRtu->m_MaxFwAccPoints) { pFwAcc = m_ptrCFesRtu->m_pFwAcc + startNum + i; - fAccValue = (float)(pFwAcc->Value*pFwAcc->Coeff + pFwAcc->Base); + fAccValue = (float)(pFwAcc->Value); dWordValue = (int)fAccValue; switch (pFwAcc->ResParam1) { @@ -740,143 +852,137 @@ void CMdbTcpSerDataProcThread::DoDataProcess(int FunCode,int StartAddr, int Regi void CMdbTcpSerDataProcThread::AoDataProcess(int FunCode,int StartAddr, int RegisterNum) { - int writex; - int contrlValue=0; - SFesFwAo *pFwAo; - uint8 data[DATA_MAX_LEN]; - SFesRxAoCmd retRxCmd; + int nAddrOffset = StartAddr - m_AppData.aoStartAddress; - contrlValue = RegisterNum; - int tempi1, tempi2; - //2020-10-27 thxiao AO需要处理负数 - if (RegisterNum & 0x8000) - { - tempi1 = ~RegisterNum; - tempi2 = tempi1 & 0xffff; - tempi2 += 1; - contrlValue = 0 - tempi2; - } - else - contrlValue = RegisterNum; - - int temp3 = StartAddr - m_AppData.aoStartAddress; - if ((temp3 >= 0) && (temp3 < m_ptrCFesRtu->m_MaxFwAoPoints)) + auto iter = m_mapYtParam.find(nAddrOffset); + if(iter == m_mapYtParam.end()) { - pFwAo = m_ptrCFesRtu->m_pFwAo+ temp3; - retRxCmd.fValue = (float)(contrlValue*pFwAo->Coeff+pFwAo->Base);//2020-10-19 thxiao 遥调增加系数处理 - sprintf(retRxCmd.TableName,"cmd.TableName"); - sprintf(retRxCmd.TagName,"cmd.TagName"); - sprintf(retRxCmd.RtuName,"cmd.RtuName"); - sprintf(retRxCmd.ColumnName,"cmd.ColumnName"); - retRxCmd.CtrlDir = CN_Fes_CtrlDir_InSide; - retRxCmd.RtuNo = pFwAo->FesRtuNo; //采集RTU号 - retRxCmd.PointID = pFwAo->FesPointNo; - retRxCmd.CtrlActType = CN_ControlExecute; - retRxCmd.FwSubSystem = m_ptrCFesRtu->m_Param.nSubSystem; - retRxCmd.FwRtuNo = m_ptrCFesRtu->m_Param.RtuNo; - retRxCmd.FwPointNo = temp3; - retRxCmd.SubSystem = pFwAo->SrcSubSystem; - m_ptrCFesBase->WriteAoReqCmdBuf(1, &retRxCmd); + LOGDEBUG("AO/MO遥调失败.原因:未配置此地址,addr=%d",nAddrOffset); + return ErrorFrameProcess(FunCode,ERRORREGISTER); + } - writex = 6; - data[writex++] = m_AppData.address; - data[writex++] = FunCode; - data[writex++] = (uint8)(StartAddr>>8); - data[writex++] = (uint8)StartAddr; - data[writex++] = (uint8)(contrlValue>>8); - data[writex++] = (uint8)contrlValue; - FillIFrameHeader(data,writex); - SendDataToPort(data,writex); - LOGDEBUG("AO:%d 遥调成功,值:%d!", temp3, contrlValue); - } + SYTPntParam &stParam = iter->second; + + SFesRxAoCmd aoCmd; + SFesRxMoCmd moCmd; + int nAoCmdCount = 0; + int nMoCmdCount = 0; + + int nDataIdx = 10; + int nRegSize = 0; + if(stParam.nPntType == CN_Fes_AO) + { + nRegSize = buildAoCmd(&m_AppData.recvBuf[nDataIdx],stParam.pFwAo,aoCmd); + nAoCmdCount = 1; + } else { - ErrorFrameProcess(FunCode,ERRORREGISTER); - LOGDEBUG("AO:%d 遥调失败!", temp3); - + nRegSize = buildMoCmd(&m_AppData.recvBuf[nDataIdx],stParam.pFwMo,moCmd); + nMoCmdCount = 1; } + + if(nRegSize <= 0) //配置有错误 + { + return ErrorFrameProcess(FunCode,ERRORVALUE); + } + + if(nRegSize > RegisterNum) //说明最后一个寄存器对应的测点配置了32bit的数据类型,超出长度 + { + LOGDEBUG("AO遥调失败.原因:地址%d对应测点规约参数1配置超出长度", StartAddr + RegisterNum); + return ErrorFrameProcess(FunCode,ERRORREGISTER); + } + + if(nAoCmdCount > 0) + { + m_ptrCFesBase->WriteAoReqCmdBuf(nAoCmdCount,&aoCmd); + } + + if(nMoCmdCount > 0) + { + m_ptrCFesBase->WriteMoReqCmdBuf(nMoCmdCount,&moCmd); + } + + uint8 data[DATA_MAX_LEN]; + int writex = 6; + data[writex++] = m_AppData.address; + data[writex++] = FunCode; + data[writex++] = m_AppData.recvBuf[8]; + data[writex++] = m_AppData.recvBuf[9]; + data[writex++] = m_AppData.recvBuf[10]; + data[writex++] = m_AppData.recvBuf[11]; + FillIFrameHeader(data,writex); + SendDataToPort(data,writex); } void CMdbTcpSerDataProcThread::AoMultDataProcess(int FunCode,int StartAddr, int RegisterNum) { - int i,writex,count; - int contrlValue=0; - bool bErrnoFlag=false; - SFesFwAo *pFwAo; - uint8 data[DATA_MAX_LEN]; - SFesRxAoCmd retRxCmd[SEND_AO_COUNT]; - int tempi1, tempi2, tempi3; + SFesRxAoCmd aoCmdArray[SEND_AO_COUNT]; + SFesRxMoCmd moCmdArray[SEND_AO_COUNT]; + int nAoCmdCount = 0; + int nMoCmdCount = 0; - int temp1 = StartAddr + RegisterNum; - int temp2 = m_AppData.aoStartAddress + m_ptrCFesRtu->m_MaxFwAoPoints; - int temp3 = StartAddr - m_AppData.aoStartAddress; - - if ((m_ptrCFesRtu->m_MaxFwAoPoints <= 0) || (m_ptrCFesRtu->m_MaxFwAoPoints < RegisterNum) || (RegisterNum > SEND_AO_COUNT)) - { - bErrnoFlag = true; - } - else - if ((temp3 >= 0) && (temp3 < m_ptrCFesRtu->m_MaxFwAoPoints) && (temp1 <= temp2)) - bErrnoFlag = false; - else - bErrnoFlag = true; - - if (!bErrnoFlag) - { - count = 0; - for(i= 0;im_MaxFwAoPoints) - { - pFwAo = m_ptrCFesRtu->m_pFwAo + temp3 + i; - sprintf(retRxCmd[count].TableName, "cmd.TableName"); - sprintf(retRxCmd[count].TagName, "cmd.TagName"); - sprintf(retRxCmd[count].RtuName, "cmd.RtuName"); - sprintf(retRxCmd[count].ColumnName, "cmd.ColumnName"); - tempi3 = (int)m_AppData.recvBuf[13 + 2 * i]<<8; - tempi3 += m_AppData.recvBuf[14 + 2 * i]; - //2020-10-27 thxiao AO需要处理负数 - if (tempi3 & 0x8000) - { - tempi1 = ~tempi3; - tempi2 = tempi1 & 0xffff; - tempi2 += 1; - contrlValue = 0 - tempi2; - } - else - contrlValue = tempi3; - - retRxCmd[count].RtuNo = pFwAo->FesRtuNo; - retRxCmd[count].PointID = pFwAo->FesPointNo; - retRxCmd[count].fValue = (float)contrlValue; - retRxCmd[count].CtrlDir = CN_Fes_CtrlDir_InSide; - retRxCmd[count].CtrlActType = CN_ControlExecute; - retRxCmd[count].FwSubSystem = m_ptrCFesRtu->m_Param.nSubSystem; - retRxCmd[count].FwRtuNo = m_ptrCFesRtu->m_Param.RtuNo; - retRxCmd[count].FwPointNo = temp3+i; - retRxCmd[count].SubSystem = pFwAo->SrcSubSystem; - count++; - LOGDEBUG("%d AO:%d 遥调成功,值:%d!", temp3+i, contrlValue); - } - } - if(count) - m_ptrCFesBase->WriteAoReqCmdBuf(count, &retRxCmd[0]); - - writex = 6; - data[writex++] = m_AppData.address; - data[writex++] = FunCode; - data[writex++] = (uint8)(StartAddr >> 8); - data[writex++] = (uint8)StartAddr; - data[writex++] = (uint8)(RegisterNum >> 8); - data[writex++] = (uint8)RegisterNum; - FillIFrameHeader(data, writex); - SendDataToPort(data, writex); - LOGDEBUG("AO批量遥调%d个成功 !",count); - } - else + int nAddrOffset = StartAddr - m_AppData.aoStartAddress; + int nDataIdx = 13; + int nRegNumIdx = 0; + while(nRegNumIdx < RegisterNum) { - ErrorFrameProcess(FunCode,ERRORREGISTER); + auto iter = m_mapYtParam.find(nRegNumIdx + nAddrOffset); + if(iter == m_mapYtParam.end()) + { + LOGDEBUG("AO/MO遥调失败.原因:未配置此地址,addr=%d",nRegNumIdx + nAddrOffset); + return ErrorFrameProcess(FunCode,ERRORREGISTER); + } + + SYTPntParam &stParam = iter->second; + + int nRegSize = 0; + if(stParam.nPntType == CN_Fes_AO) + { + SFesRxAoCmd &aoCmd = aoCmdArray[nAoCmdCount++]; + nRegSize = buildAoCmd(&m_AppData.recvBuf[nDataIdx],stParam.pFwAo,aoCmd); + } + else + { + SFesRxMoCmd &moCmd = moCmdArray[nMoCmdCount++]; + nRegSize = buildMoCmd(&m_AppData.recvBuf[nDataIdx],stParam.pFwMo,moCmd); + } + + if(nRegSize <= 0) //配置有错误 + { + return ErrorFrameProcess(FunCode,ERRORVALUE); + } + + nDataIdx += nRegSize * 2; + nRegNumIdx += nRegSize; } + + if(nRegNumIdx > RegisterNum) //说明最后一个寄存器对应的测点配置了32bit的数据类型,超出长度 + { + LOGDEBUG("AO遥调失败.原因:地址%d对应测点规约参数1配置超出长度", StartAddr + RegisterNum); + return ErrorFrameProcess(FunCode,ERRORREGISTER); + } + + if(nAoCmdCount > 0) + { + m_ptrCFesBase->WriteAoReqCmdBuf(nAoCmdCount, &aoCmdArray[0]); + } + + if(nMoCmdCount > 0) + { + m_ptrCFesBase->WriteMoReqCmdBuf(nMoCmdCount, &moCmdArray[0]); + } + + uint8 data[DATA_MAX_LEN]; + int writex = 6; + data[writex++] = m_AppData.address; + data[writex++] = FunCode; + data[writex++] = (uint8)(StartAddr >> 8); + data[writex++] = (uint8)StartAddr; + data[writex++] = (uint8)(RegisterNum >> 8); + data[writex++] = (uint8)RegisterNum; + FillIFrameHeader(data, writex); + SendDataToPort(data, writex); + LOGDEBUG("AO/MO批量遥调%d个成功 !",nAoCmdCount + nMoCmdCount); } void CMdbTcpSerDataProcThread::ErrorFrameProcess(int FunCode,int ErrorType) @@ -1313,5 +1419,337 @@ void CMdbTcpSerDataProcThread::MobTcpSerDisconnect() event.EventType = CN_FesAppNetEvent_CloseSock; LOGDEBUG("MobTcpSerDisconnect() by itself!"); - m_ptrCurrentChan->WriteAppNetEvent(1, &event); + m_ptrCurrentChan->WriteAppNetEvent(1, &event); +} + +void CMdbTcpSerDataProcThread::parseMiMaxMinPntNo() +{ + for(int i = 0; i < m_ptrCFesRtu->m_MaxFwMiPoints; i++) + { + SFesFwMi *pMi = m_ptrCFesRtu->m_pFwMi + i; + if(pMi->Used) + { + if(m_nMiMinPntNo < 0 || i < m_nMiMinPntNo) + { + m_nMiMinPntNo = i; + } + + if(m_nMiMaxPntNo < 0 || i > m_nMiMaxPntNo) + { + m_nMiMaxPntNo = i; + } + } + } +} + +void CMdbTcpSerDataProcThread::buildYtRelation() +{ + for(int i = 0; i < m_ptrCFesRtu->m_MaxFwAoPoints;i++) + { + SFesFwAo *pAo = m_ptrCFesRtu->m_pFwAo + i; + if(pAo->Used) + { + m_mapYtParam[i].nPntType = CN_Fes_AO; + m_mapYtParam[i].pFwAo = pAo; + } + } + + for(int i = 0; i < m_ptrCFesRtu->m_MaxFwMoPoints;i++) + { + SFesFwMo *pMo = m_ptrCFesRtu->m_pFwMo + i; + if(pMo->Used) + { + m_mapYtParam[i].nPntType = CN_Fes_MO; + m_mapYtParam[i].pFwMo = pMo; + } + } +} + +int CMdbTcpSerDataProcThread::buildValueToBuffer(uint8 *pBuf, const int &nType, const float &fVal) +{ + int nSize = 1; + int nValue = static_cast(fVal); + uint8 *pTemp = NULL; + + switch (nType) + { + case 0: //备用参数为0 - 16bit整数:高字节在前、低字节在后 + *pBuf++ = (uint8)(nValue >> 8); + *pBuf++ = (uint8)nValue; + break; + case 1: //备用参数为1 - 16bit整数:低字节在前、高字节在后 + *pBuf++ = (uint8)nValue; + *pBuf++ = (uint8)(nValue >> 8); + break; + case 10: //备用参数为10 - 32bit整数: 高字在前,低字在后;高字节在前,低字节在后 + *pBuf++ = (uint8)(nValue >> 24); + *pBuf++ = (uint8)(nValue >> 16); + *pBuf++ = (uint8)(nValue >> 8); + *pBuf++ = (uint8)nValue; + nSize = 2; + break; + case 11: //备用参数为11 - 32bit整数:低字在前,高字在后;高字节在前,低字节在后 + *pBuf++ = (uint8)(nValue >> 8); + *pBuf++ = (uint8)nValue; + *pBuf++ = (uint8)(nValue >> 24); + *pBuf++ = (uint8)(nValue >> 16); + nSize = 2; + break; + case 12: //备用参数为12 - 32bit整数:高字在前,低字在后;低字节在前,高字节在后 + *pBuf++ = (uint8)(nValue >> 16); + *pBuf++ = (uint8)(nValue >> 24); + *pBuf++ = (uint8)nValue; + *pBuf++ = (uint8)(nValue >> 8); + nSize = 2; + break; + case 13: //备用参数为13 - 32bit整数:低字在前,高字在后;低字节在前,高字节在后 + *pBuf++ = (uint8)nValue; + *pBuf++ = (uint8)(nValue >> 8); + *pBuf++ = (uint8)(nValue >> 16); + *pBuf++ = (uint8)(nValue >> 24); + nSize = 2; + break; + case 14: //备用参数为14 - float 高字在前,低字在后;高字节在前,低字节在后 如100.0 0x42c80000(高前低后) 发送顺序 42 C8 00 00 + pTemp = (uint8 *)&fVal; + *pBuf++ = (uint8)*(pTemp + 3); + *pBuf++ = (uint8)*(pTemp + 2); + *pBuf++ = (uint8)*(pTemp + 1); + *pBuf++ = (uint8)*pTemp; + nSize = 2; + break; + case 15: //备用参数为15--float 低字在前,高字在后;低字节在前,高字节在后 发送顺序 00 00 C8 42 + pTemp = (uint8 *)&fVal; + *pBuf++ = (uint8)*pTemp; + *pBuf++ = (uint8)*(pTemp + 1); + *pBuf++ = (uint8)*(pTemp + 2); + *pBuf++ = (uint8)*(pTemp + 3); + nSize = 2; + break; + case 16: //备用参数为16 --float 低字在前,高字在后;高字节在前,低字节在后 发送顺序 00 00 42 C8 modscan使用该种浮点解析 + pTemp = (uint8 *)&fVal; + *pBuf++ = (uint8)*(pTemp + 1); + *pBuf++ = (uint8)*pTemp; + *pBuf++ = (uint8)*(pTemp + 3); + *pBuf++ = (uint8)*(pTemp + 2); + nSize = 2; + break; + default: + *pBuf++ = 0; + *pBuf++ = 0; + break; + } + + return nSize; +} + +int CMdbTcpSerDataProcThread::buildAoCmd(uint8 *pBuf, SFesFwAo *pFwAo, SFesRxAoCmd &stCmd) +{ + int nRegSize = 0; + uint32 u32 = 0; + float fVal = 0.0; + uint8 *pU32 = (uint8*)&u32; + uint8 *pFloat = (uint8*)&fVal; + + switch (pFwAo->ResParam1) + { + case 0: //备用参数为0 - 16bit整数:高字节在前、低字节在后 + *(pU32 + 1) = *pBuf++; + *pU32 = *pBuf++; + fVal = static_cast((pFwAo->ResParam2 == 1) ? static_cast(u32) : static_cast(u32)); + nRegSize = 1; + break; + case 1: //备用参数为1 - 16bit整数:低字节在前、高字节在后 + *pU32 = *pBuf++; + *(pU32 + 1) = *pBuf++; + fVal = static_cast((pFwAo->ResParam2 == 1) ? static_cast(u32) : static_cast(u32)); + nRegSize = 1; + break; + case 10: //备用参数为10 - 32bit整数: 高字在前,低字在后;高字节在前,低字节在后 + *(pU32 + 3) = *pBuf++; + *(pU32 + 2) = *pBuf++; + *(pU32 + 1) = *pBuf++; + *pU32 = *pBuf++; + fVal = static_cast((pFwAo->ResParam2 == 1) ? u32 : static_cast(u32)); + nRegSize = 2; + break; + case 11: //备用参数为11 - 32bit整数:低字在前,高字在后;高字节在前,低字节在后 + *(pU32 + 1) = *pBuf++; + *pU32 = *pBuf++; + *(pU32 + 3) = *pBuf++; + *(pU32 + 2) = *pBuf++; + fVal = static_cast((pFwAo->ResParam2 == 1) ? u32 : static_cast(u32)); + nRegSize = 2; + break; + case 12: //备用参数为12 - 32bit整数:高字在前,低字在后;低字节在前,高字节在后 + *(pU32 + 2) = *pBuf++; + *(pU32 + 3) = *pBuf++; + *pU32 = *pBuf++; + *(pU32 + 1) = *pBuf++; + fVal = static_cast((pFwAo->ResParam2 == 1) ? u32 : static_cast(u32)); + nRegSize = 2; + break; + case 13: //备用参数为13 - 32bit整数:低字在前,高字在后;低字节在前,高字节在后 + *pU32 = *pBuf++; + *(pU32 + 1) = *pBuf++; + *(pU32 + 2) = *pBuf++; + *(pU32 + 3) = *pBuf++; + fVal = static_cast((pFwAo->ResParam2 == 1) ? u32 : static_cast(u32)); + nRegSize = 2; + break; + case 14: //备用参数为14 - float 高字在前,低字在后;高字节在前,低字节在后 如100.0 0x42c80000(高前低后) 发送顺序 42 C8 00 00 + *(pFloat + 3) = *pBuf++; + *(pFloat + 2) = *pBuf++; + *(pFloat + 1) = *pBuf++; + *pFloat = *pBuf++; + nRegSize = 2; + break; + case 15: //备用参数为15--float 低字在前,高字在后;低字节在前,高字节在后 发送顺序 00 00 C8 42 + *pFloat = *pBuf++; + *(pFloat + 1) = *pBuf++; + *(pFloat + 2) = *pBuf++; + *(pFloat + 3) = *pBuf++; + nRegSize = 2; + break; + case 16: //备用参数为16 --float 低字在前,高字在后;高字节在前,低字节在后 发送顺序 00 00 42 C8 modscan使用该种浮点解析 + *(pFloat + 1) = *pBuf++; + *pFloat = *pBuf++; + *(pFloat + 3) = *pBuf++; + *(pFloat + 2) = *pBuf++; + nRegSize = 2; + break; + default: + nRegSize = 0; + break; + } + + if(nRegSize <= 0) + { + LOGDEBUG("AO:%d 遥调失败.原因:规约参数1配置错误", pFwAo->RemoteNo); + return nRegSize; + } + + sprintf(stCmd.TableName, "cmd.TableName"); + sprintf(stCmd.TagName, "cmd.TagName"); + sprintf(stCmd.RtuName, "cmd.RtuName"); + sprintf(stCmd.ColumnName, "cmd.ColumnName"); + stCmd.RtuNo = pFwAo->FesRtuNo; + stCmd.PointID = pFwAo->FesPointNo; + stCmd.fValue = static_cast(fVal * pFwAo->Coeff + pFwAo->Base); + stCmd.CtrlDir = CN_Fes_CtrlDir_InSide; + stCmd.CtrlActType = CN_ControlExecute; + stCmd.FwSubSystem = m_ptrCFesRtu->m_Param.nSubSystem; + stCmd.FwRtuNo = m_ptrCFesRtu->m_Param.RtuNo; + stCmd.FwPointNo = pFwAo->RemoteNo; + stCmd.SubSystem = pFwAo->SrcSubSystem; + + LOGDEBUG("AO:%d 遥调成功,原始值:%f", pFwAo->RemoteNo, fVal); + return nRegSize; +} + +int CMdbTcpSerDataProcThread::buildMoCmd(uint8 *pBuf, SFesFwMo *pFwMo, SFesRxMoCmd &stCmd) +{ + int nRegSize = 0; + uint32 u32 = 0; + int nCtrlValue = 0; + float fVal = 0.0; + uint8 *pU32 = (uint8*)&u32; + uint8 *pFloat = (uint8*)&fVal; + + switch (pFwMo->ResParam1) + { + case 0: //备用参数为0 - 16bit整数:高字节在前、低字节在后 + *(pU32 + 1) = *pBuf++; + *pU32 = *pBuf++; + nCtrlValue = (pFwMo->ResParam2 == 1) ? static_cast(u32) : static_cast(u32); + nRegSize = 1; + break; + case 1: //备用参数为1 - 16bit整数:低字节在前、高字节在后 + *pU32 = *pBuf++; + *(pU32 + 1) = *pBuf++; + nCtrlValue = (pFwMo->ResParam2 == 1) ? static_cast(u32) : static_cast(u32); + nRegSize = 1; + break; + case 10: //备用参数为10 - 32bit整数: 高字在前,低字在后;高字节在前,低字节在后 + *(pU32 + 3) = *pBuf++; + *(pU32 + 2) = *pBuf++; + *(pU32 + 1) = *pBuf++; + *pU32 = *pBuf++; + nCtrlValue = (pFwMo->ResParam2 == 1) ? u32 : static_cast(u32); + nRegSize = 2; + break; + case 11: //备用参数为11 - 32bit整数:低字在前,高字在后;高字节在前,低字节在后 + *(pU32 + 1) = *pBuf++; + *pU32 = *pBuf++; + *(pU32 + 3) = *pBuf++; + *(pU32 + 2) = *pBuf++; + nCtrlValue = (pFwMo->ResParam2 == 1) ? u32 : static_cast(u32); + nRegSize = 2; + break; + case 12: //备用参数为12 - 32bit整数:高字在前,低字在后;低字节在前,高字节在后 + *(pU32 + 2) = *pBuf++; + *(pU32 + 3) = *pBuf++; + *pU32 = *pBuf++; + *(pU32 + 1) = *pBuf++; + nCtrlValue = (pFwMo->ResParam2 == 1) ? u32 : static_cast(u32); + nRegSize = 2; + break; + case 13: //备用参数为13 - 32bit整数:低字在前,高字在后;低字节在前,高字节在后 + *pU32 = *pBuf++; + *(pU32 + 1) = *pBuf++; + *(pU32 + 2) = *pBuf++; + *(pU32 + 3) = *pBuf++; + nCtrlValue = (pFwMo->ResParam2 == 1) ? u32 : static_cast(u32); + nRegSize = 2; + break; + case 14: //备用参数为14 - float 高字在前,低字在后;高字节在前,低字节在后 如100.0 0x42c80000(高前低后) 发送顺序 42 C8 00 00 + *(pFloat + 3) = *pBuf++; + *(pFloat + 2) = *pBuf++; + *(pFloat + 1) = *pBuf++; + *pFloat = *pBuf++; + nCtrlValue = static_cast(fVal); + nRegSize = 2; + break; + case 15: //备用参数为15--float 低字在前,高字在后;低字节在前,高字节在后 发送顺序 00 00 C8 42 + *pFloat = *pBuf++; + *(pFloat + 1) = *pBuf++; + *(pFloat + 2) = *pBuf++; + *(pFloat + 3) = *pBuf++; + nCtrlValue = static_cast(fVal); + nRegSize = 2; + break; + case 16: //备用参数为16 --float 低字在前,高字在后;高字节在前,低字节在后 发送顺序 00 00 42 C8 modscan使用该种浮点解析 + *(pFloat + 1) = *pBuf++; + *pFloat = *pBuf++; + *(pFloat + 3) = *pBuf++; + *(pFloat + 2) = *pBuf++; + nCtrlValue = static_cast(fVal); + nRegSize = 2; + break; + default: + nRegSize = 0; + break; + } + + if(nRegSize <= 0) + { + LOGDEBUG("MO:%d 遥调失败.原因:规约参数1配置错误", pFwMo->RemoteNo); + return nRegSize; + } + + sprintf(stCmd.TableName, "cmd.TableName"); + sprintf(stCmd.TagName, "cmd.TagName"); + sprintf(stCmd.RtuName, "cmd.RtuName"); + sprintf(stCmd.ColumnName, "cmd.ColumnName"); + stCmd.RtuNo = pFwMo->FesRtuNo; + stCmd.PointID = pFwMo->FesPointNo; + stCmd.iValue = nCtrlValue; + stCmd.CtrlDir = CN_Fes_CtrlDir_InSide; + stCmd.CtrlActType = CN_ControlExecute; + stCmd.FwSubSystem = m_ptrCFesRtu->m_Param.nSubSystem; + stCmd.FwRtuNo = m_ptrCFesRtu->m_Param.RtuNo; + stCmd.FwPointNo = pFwMo->RemoteNo; + stCmd.SubSystem = pFwMo->SrcSubSystem; + + LOGDEBUG("MO:%d 遥调成功,原始值:%d", pFwMo->RemoteNo, nCtrlValue); + return nRegSize; } diff --git a/product/src/fes/protocol/modbus_tcp_s/MdbTcpSerDataProcThread.h b/product/src/fes/protocol/modbus_tcp_s/MdbTcpSerDataProcThread.h index 2f696457..ae84277a 100644 --- a/product/src/fes/protocol/modbus_tcp_s/MdbTcpSerDataProcThread.h +++ b/product/src/fes/protocol/modbus_tcp_s/MdbTcpSerDataProcThread.h @@ -3,10 +3,7 @@ @brief MdbTcpSer 数据处理线程类。 @author JACKYWU @date 2019-05-07 - @history - 2022-09-15 thxiao 以255为最大长度取点数 - - */ +*/ #pragma once #include "FesDef.h" @@ -33,7 +30,6 @@ using namespace iot_public; #define ERRORVALUE 0x03 #define ERRORDEVICE 0x04 /* 每帧发送的最大个数值描述词 ------------------------- */ -/* #define SEND_DI_COUNT 2000 #define SEND_DO_COUNT 2000 #define SEND_AO_COUNT 120 @@ -41,15 +37,6 @@ using namespace iot_public; #define SEND_32AI_COUNT 60 #define SEND_16ACC_COUNT 120 #define SEND_32ACC_COUNT 60 -*/ -//2022-09-15 thxiao 以255为最大长度取点数 -#define SEND_DI_COUNT 2040 -#define SEND_AO_COUNT 127 -#define SEND_16AI_COUNT 127 -#define SEND_32AI_COUNT 63 -#define SEND_16ACC_COUNT 127 -#define SEND_32ACC_COUNT 63 - /* float data compare precision-------------------- */ const double ZERO_PRECISION = 0.000001; const int CN_MdbTcpSerMaxRecvDataSize = 300; @@ -116,6 +103,15 @@ typedef struct{ uint64 lastUpdateTime; }SMdbTcpSerAppData; +//缓存AO和MO测点配置,用于处理遥调指令 +typedef struct _SYTPntParam +{ + int nPntType; + SFesFwAo *pFwAo; + SFesFwMo *pFwMo; + + _SYTPntParam(); +}SYTPntParam,*PSYTPntParam; class CMdbTcpSerDataProcThread : public CTimerThreadBase,CProtocolBase { @@ -134,15 +130,7 @@ public: virtual void beforeQuit(); - CFesBase* m_ptrCFesBase; - CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 - CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,MdbTcpSer tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 - CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 - SMdbTcpSerAppData m_AppData; //内部应用数据结构 private: - int m_timerCount; - int m_timerCountReset; - int RecvNetData(); int InitConfigParam(); void MdbTcpSerConnect(); @@ -172,6 +160,30 @@ private: void TimerProcess(); void MobTcpSerDisconnect(); + //解析mi的最大点号和最小点号 + void parseMiMaxMinPntNo(); + //建立点号到AO/MO的映射关系 + void buildYtRelation(); + + //将fVal按格式填充到buf中,返回填充字节数 + int buildValueToBuffer(uint8 *pBuf,const int &nType,const float &fVal); + + int buildAoCmd(uint8 *pBuf,SFesFwAo *pFwAo,SFesRxAoCmd &stCmd); + int buildMoCmd(uint8 *pBuf,SFesFwMo *pFwMo,SFesRxMoCmd &stCmd); + +public: + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + +private: + CFesBase* m_ptrCFesBase; + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,MdbTcpSer tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SMdbTcpSerAppData m_AppData; //内部应用数据结构 + int m_timerCount; + int m_timerCountReset; + int m_nMiMinPntNo; //记录混合量最小的远动号 + int m_nMiMaxPntNo; //记录混合量最大的远动号 + std::map m_mapYtParam; }; typedef boost::shared_ptr CMdbTcpSerDataProcThreadPtr; diff --git a/product/src/fes/protocol/mqtt_hcfy/CMbCommHandleThread.cpp b/product/src/fes/protocol/mqtt_hcfy/CMbCommHandleThread.cpp new file mode 100644 index 00000000..90190609 --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/CMbCommHandleThread.cpp @@ -0,0 +1,101 @@ +#include "CMbCommHandleThread.h" + +#include + +#include "rapidjson/stringbuffer.h" + +#include "common/Common.h" +#include "common/MessageChannel.h" +#include "pub_logger_api/logger.h" + +CMbCommHandleThread::CMbCommHandleThread() + : CTimerThreadBase("CMbCommHandleThread") +{ + +} + +void CMbCommHandleThread::execute() +{ + if( m_ptrMbComm == NULL ) + { + m_ptrMbComm = new iot_net::CMbCommunicator(); + + if( m_ptrMbComm->addSub(CN_AppId_COMAPP, CH_OPT_TO_FES_CTRL_DOWN) ) + { + LOGINFO(" sub CH_OPT_TO_FES_CTRL_DOWN ok"); + } + } + + iot_net::CMbMessage recvMessage; + while( m_ptrMbComm->recvMsg(recvMessage, 100) ) + { + if( recvMessage.getChannelID() == CH_OPT_TO_FES_CTRL_DOWN ) + { + std::string str((char*)recvMessage.getDataPtr(), recvMessage.getDataSize()); + + LOGINFO("mbcomm recv message: %s", str.c_str()); + + rapidjson::Document doc; + doc.Parse(str.c_str()); + + if( doc.HasParseError() ) + { + LOGERROR("json parse error: %s", str.c_str()); + continue; + } + + if( doc.HasMember("strategySrc") && + doc["strategySrc"].IsString() && + (std::string(doc["strategySrc"].GetString()) == HC_REMOTE_FLAG) ) + { + handleRecvMessage(doc); + } + } + } +} + +int CMbCommHandleThread::getPublishMsg(SPublishMsg &msg) +{ + boost::mutex::scoped_lock lock(m_TxMutex); + + if( !m_TxBuffer.empty() ) + { + msg = m_TxBuffer.front(); + m_TxBuffer.pop(); + + return 1; + } + + return 0; +} + +void CMbCommHandleThread::putPublishMsg(const SPublishMsg& msg) +{ + boost::mutex::scoped_lock lock(m_TxMutex); + m_TxBuffer.push(msg); +} + +void CMbCommHandleThread::handleRecvMessage(rapidjson::Document& doc) +{ + if( doc.HasMember("content") && doc["content"].IsObject() ) + { + rapidjson::Value& contentJson = doc["content"]; + + std::string respTopic; + if( contentJson.HasMember("respTopic") && contentJson["respTopic"].IsString() ) + { + respTopic = contentJson["respTopic"].GetString(); + contentJson.EraseMember("respTopic"); + } + + rapidjson::StringBuffer buffer; + rapidjson::Writer write(buffer); + contentJson.Accept(write); + + SPublishMsg publishMessage; + publishMessage.topic = respTopic; + publishMessage.msg = buffer.GetString(); + + putPublishMsg(publishMessage); + } +} diff --git a/product/src/fes/protocol/mqtt_hcfy/CMbCommHandleThread.h b/product/src/fes/protocol/mqtt_hcfy/CMbCommHandleThread.h new file mode 100644 index 00000000..da8bd52c --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/CMbCommHandleThread.h @@ -0,0 +1,37 @@ +#ifndef CMBCOMMHANDLETHREAD_H +#define CMBCOMMHANDLETHREAD_H + +#include "pub_utility_api/TimerThreadBase.h" +#include "net_msg_bus_api/CMbCommunicator.h" + +#include "rapidjson/document.h" + +#include "CmdHandleThread.h" // import SPublishMsg + +class CMbCommHandleThread : public iot_public::CTimerThreadBase +{ +public: + CMbCommHandleThread(); + + /** + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + int getPublishMsg(SPublishMsg& msg); + void putPublishMsg(const SPublishMsg& msg); + +private: + void handleRecvMessage(rapidjson::Document& doc); + + iot_net::CMbCommunicator* m_ptrMbComm{NULL}; + + std::queue m_TxBuffer; + boost::mutex m_TxMutex; + + const char* const HC_REMOTE_FLAG = "hc"; +}; + +typedef boost::shared_ptr CMbCommHandleThreadPtr; + +#endif // CMBCOMMHANDLETHREAD_H diff --git a/product/src/fes/protocol/mqtt_hcfy/CMosquitto.cpp b/product/src/fes/protocol/mqtt_hcfy/CMosquitto.cpp new file mode 100644 index 00000000..53f82034 --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/CMosquitto.cpp @@ -0,0 +1,76 @@ +#include "CMosquitto.h" +#include + +CMosquitto::CMosquitto(const char *id): mosquittopp(id) +{ + +} + +CMosquitto::~CMosquitto() +{ + LOGINFO("CMosquitto has quit"); +} + +void CMosquitto::on_message(const mosquitto_message *message) +{ + boost::mutex::scoped_lock lock(m_MsgMutex); + try + { + + if(message->payload && message->payloadlen > 0) + { + char* cstr = static_cast(message->payload); + std::string recMessage(cstr, message->payloadlen); + SMsg sm; + sm.content=recMessage; + sm.topic=message->topic; + m_queue.push(sm); + + } + }catch(const std::exception& e) + { + LOGERROR("CMosquitto Failed to %s" , e.what()); + } + + +} + +void CMosquitto::on_connect(int rc) +{ + if (rc == 0) { + LOGINFO("CMosquitto Connected to the MQTT broker successfully"); + if(!subscription.empty()) + { + int rc=subscribe(NULL,subscription.data()); + if( MOSQ_ERR_SUCCESS != rc) + { + LOGERROR("subscribeRc != MOSQ_ERR_SUCCESS Error: %s" , mosquitto_strerror(rc)); + } + } + } else { + LOGINFO("CMosquitto Failed to connect to the MQTT broker. Return code: %d" , rc); + } +} + +void CMosquitto::on_subscribe(int mid, int qos_count, const int *granted_qos) +{ + LOGINFO("CMosquitto Subscription successful! mid: %d" , mid); +} + +int CMosquitto::get_message(SMsg &msg) +{ + boost::mutex::scoped_lock lock(m_MsgMutex); + int64_t count=0; + if(!m_queue.empty()) + { + msg=m_queue.front(); + m_queue.pop(); + ++count; + } + + return count; +} + + + + diff --git a/product/src/fes/protocol/mqtt_hcfy/CMosquitto.h b/product/src/fes/protocol/mqtt_hcfy/CMosquitto.h new file mode 100644 index 00000000..0a0a164c --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/CMosquitto.h @@ -0,0 +1,38 @@ +#pragma once + +#include "mosquitto.h" +#include "mosquittopp.h" +#include "pub_logger_api/logger.h" +#include +#include +#include "boost/circular_buffer.hpp" + #include + + +struct SMsg +{ + std::string topic; + std::string content; + SMsg() { + topic=""; + content=""; + } +}; + +class CMosquitto: public mosqpp::mosquittopp +{ +public: + CMosquitto(const char *id); + virtual ~CMosquitto(); + void on_message(const struct mosquitto_message *message) override; + void on_connect(int rc) override; + void on_subscribe(int mid, int qos_count, const int *granted_qos) override; + int get_message(SMsg& content); +private: + //boost::container::deque m_queue; + boost::mutex m_MsgMutex; //< 互斥锁 + std::queue m_queue; + +public: + std::string subscription; +}; diff --git a/product/src/fes/protocol/mqtt_hcfy/CmdHandleThread.cpp b/product/src/fes/protocol/mqtt_hcfy/CmdHandleThread.cpp new file mode 100644 index 00000000..e0df1db9 --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/CmdHandleThread.cpp @@ -0,0 +1,1044 @@ +#include "CmdHandleThread.h" + +#include "common/MessageChannel.h" + +const int gCmdHandleThreadTime = 300; +CmdHandleThread::CmdHandleThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan, vector vecConfig): + CTimerThreadBase("HcCloudCmdHandleThread", gCmdHandleThreadTime,0,true),m_bReady(true) +{ + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + + + if (m_ptrCFesChan == NULL ) + { + return; + } + m_ptrCFesRtu=GetRtuDataByChanData(m_ptrCFesChan); + + bool found = false; + if(vecConfig.size()>0) + { + for (size_t i = 0; i < vecConfig.size(); i++) + { + if(m_ptrCFesRtu->m_Param.RtuNo == vecConfig[i].RtuNo) + { + //配置 + m_cmdHandleConfig=vecConfig[i]; + found = true; + break; + } + } + } + + if(found) + { + if(!m_cmdHandleConfig.Subscription.empty()) + { + //bool ret=m_ptrMQTT->mqttSubscribe(m_cmdHandleConfig.Subscription); + //if(ret) + //{ + // LOGINFO("HcCloudCmdHandleThread ChanNo=%d Subscribe-ok %s ", m_ptrCFesChan->m_Param.ChanNo,m_cmdHandleConfig.Subscription.data()); + //} + + getLocalStrategyData(m_sCurrentStrategy); + loadAoPoint(); + + m_ptrMbComm = new iot_net::CMbCommunicator(); + } + else + { + m_bReady=false; + } + } + else + { + m_bReady=false; + } + +} + +CmdHandleThread::~CmdHandleThread() +{ + delete m_ptrMbComm; + + LOGDEBUG("CmdHandleThread::~CmdHandleThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); +} + +int CmdHandleThread::beforeExecute() +{ + return iotSuccess; +} + +void CmdHandleThread::execute() +{ + try{ + if(!m_bReady) + { + LOGERROR("CmdHandleThread ChanNo=%d has bad and do nothing ", m_ptrCFesChan->m_Param.ChanNo); + return; + } + //处理消息 + SMsg msg; + bool needHandle=false; + { + boost::mutex::scoped_lock lock(m_RxMutex); + if(!m_RxBuffer.empty()) + { + msg=m_RxBuffer.front(); + m_RxBuffer.pop(); + needHandle=true; + } + } + + if(needHandle) + { + handleMsg(msg); + } + //处理功率的输出 + handleOutput(); + }catch (const std::exception& e) { + LOGERROR("CmdHandleThread ChanNo=%d exec has err %s ", m_ptrCFesChan->m_Param.ChanNo,e.what()); + }catch (...) { + LOGERROR("CmdHandleThread ChanNo=%d exec has unknown exception", m_ptrCFesChan->m_Param.ChanNo); + } + +} + +void CmdHandleThread::beforeQuit() +{ + +} + +int CmdHandleThread::getLocalStrategyData(SStrategy &strategy) +{ + boost::mutex::scoped_lock lock(m_objMutex); + const boost::filesystem::path& filePath(m_cmdHandleConfig.LocalStrategyPath); + boost::filesystem::ifstream inFile(filePath, std::ios::in | std::ios::binary); + if (!inFile.is_open()) { + + LOGERROR("HcCloudCmdHandleThread ChanNo=%d JSON get file(%s) faild ", m_ptrCFesChan->m_Param.ChanNo,m_cmdHandleConfig.LocalStrategyPath.data()); + return iotFailed; + } + std::ostringstream content; + content << inFile.rdbuf(); // 读取文件内容到字符串流 + inFile.close(); + std::string localStr=content.str(); + rapidjson::Document document; + SStrategy ssData; + if (document.Parse(localStr.data()).HasParseError()) { + LOGERROR("HcCloudCmdHandleThread ChanNo=%d JSON(%s) parse error %s at offset %d content(%s)", m_ptrCFesChan->m_Param.ChanNo,m_cmdHandleConfig.LocalStrategyPath.data(),rapidjson::GetParseError_En(document.GetParseError()), document.GetErrorOffset(),localStr.data()); + return iotFailed; + } + if(parseJson(document,ssData,false,localStr)) + { + strategy=ssData; + } + else + { + LOGERROR("HcCloudCmdHandleThread ChanNo=%d JSON(%s) parse error and data publish maybe err", m_ptrCFesChan->m_Param.ChanNo,m_cmdHandleConfig.LocalStrategyPath.data()); + return iotFailed; + } + + return iotSuccess; +} + +void CmdHandleThread::handleMsg(SMsg &msg) +{ + //根据消息类型分函数执行 + rapidjson::Document document; + SStrategy ssData; + if (document.Parse(msg.content.data()).HasParseError()) { + LOGERROR("HcCloudCmdHandleThread ChanNo=%d JSON parse error %s at offset %d", m_ptrCFesChan->m_Param.ChanNo,rapidjson::GetParseError_En(document.GetParseError()), document.GetErrorOffset()); + return; + } + if(document.HasMember("method")&&document["method"].IsString()) + { + std::string strMethod=document["method"].GetString(); + if(strMethod=="SetStrategyData") + { + if(parseJson(document,ssData,false,msg.content)) + { + handleSetStrategyData(ssData); + } + } + else if(strMethod=="GetStrategyData") + { + if(parseJson(document,ssData,true,msg.content)) + { + handleGetStrategyData(ssData); + } + } + else if(strMethod=="StartStrategy") + { + if(parseJson(document,ssData,true,msg.content)) + { + handleStartStrategy(ssData); + } + } + else if(strMethod=="StopStrategy") + { + if(parseJson(document,ssData,true,msg.content)) + { + handleStopStrategy(ssData); + } + } + else if(strMethod=="GetStrategyStatus") + { + if(parseJson(document,ssData,true,msg.content)) + { + handleGetStrategyStatus(ssData); + } + } + else + { + LOGERROR("HcCloudCmdHandleThread ChanNo=%d JSON can not match method %s ", m_ptrCFesChan->m_Param.ChanNo,msg.content.data()); + + } + + std::string dataStr = buildStrategyJson(ssData); + + iot_net::CMbMessage message; + message.setSubject(CN_AppId_PUBLIC, CH_FES_TO_OPT_CTRL_UP); + message.setData(dataStr); + + m_ptrMbComm->sendMsgToDomain(message); + } + else + { + LOGERROR("HcCloudCmdHandleThread ChanNo=%d JSON is bad can not find method or not string %s ", m_ptrCFesChan->m_Param.ChanNo,msg.content.data()); + + } +} + +int CmdHandleThread::handleSetStrategyData(const SStrategy &ssData) +{ + boost::mutex::scoped_lock lock(m_objMutex); + SCommonReply reply; + reply.method=ssData.method; + reply.dId=ssData.dId; + reply.msgId=ssData.msgId; + reply.version=ssData.version; + reply.ts=getUTCTimeMsec(); + reply.code=0; + + //更改内存 + m_sCurrentStrategy.method=ssData.method; + m_sCurrentStrategy.dId=ssData.dId; + m_sCurrentStrategy.msgId=ssData.msgId; + m_sCurrentStrategy.version=ssData.version; + m_sCurrentStrategy.ts=getUTCTimeMsec(); + m_sCurrentStrategy.data=ssData.data; + m_sCurrentStrategy.respTopic=ssData.respTopic; + + //写出缓冲文件 + + std::string strStrategyJson=generateJson(m_sCurrentStrategy); + const boost::filesystem::path& filePath(m_cmdHandleConfig.LocalStrategyPath); + boost::filesystem::ofstream outFile(filePath, std::ios::out | std::ios::binary); + if (!outFile.is_open()) { + reply.code=1; + LOGERROR("HcCloudCmdHandleThread ChanNo=%d JSON write file(%s) faild conent %s", m_ptrCFesChan->m_Param.ChanNo,m_cmdHandleConfig.LocalStrategyPath.data(),strStrategyJson.data()); + + } + else + { + outFile << strStrategyJson; // 写入内容 + } + outFile.close(); // 关闭文件 + + std::string sendMsg=generateJson(reply); + + + SPublishMsg pubmsgs; + pubmsgs.topic=ssData.respTopic; + pubmsgs.msg=sendMsg; + putPublishMsg(pubmsgs); + + if(1==reply.code) + { + return iotFailed; + } + else + { + return iotSuccess; + } + +} + +int CmdHandleThread::handleGetStrategyData(const SStrategy &ssData) +{ + boost::mutex::scoped_lock lock(m_objMutex); + SStrategyInfoReply reply; + reply.method=ssData.method; + reply.dId=ssData.dId; + reply.msgId=ssData.msgId; + reply.version=ssData.version; + reply.ts=getUTCTimeMsec(); + reply.data=m_sCurrentStrategy.data; + reply.code=0; + + std::string sendMsg=generateJson(reply); + + SPublishMsg pubmsgs; + pubmsgs.topic=ssData.respTopic; + pubmsgs.msg=sendMsg; + putPublishMsg(pubmsgs); + + if(1==reply.code) + { + return iotFailed; + } + else + { + return iotSuccess; + } + + return iotSuccess; +} + +int CmdHandleThread::handleGetStrategyStatus(const SStrategy &ssData) +{ + //获取当前的内存 + double fvalue; + SFesFwAi *pFwAi; + SStrategyStatusReply reply; + reply.method=ssData.method; + reply.dId=ssData.dId; + reply.msgId=ssData.msgId; + reply.version=ssData.version; + reply.ts=getUTCTimeMsec(); + + if(m_mapAoPoint.find(PublishMethod::GetStrategyStatus)==m_mapAoPoint.end()) + { + reply.code=1; + LOGERROR("HcCloudCmdHandleThread ChanNo=%d can not find GetStrategyStatusPoint in rtu %d ", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo); + + } + else + { + int64_t pointOffset=m_mapAoPoint[PublishMethod::GetStrategyStatus]; + pFwAi = m_ptrCFesRtu->m_pFwAi + pointOffset; + fvalue = pFwAi->Value; + if(0==fvalue) + { + reply.RunStatus=false; + } + else + { + reply.RunStatus=true; + } + reply.code=0; + } + + std::string sendMsg=generateJson(reply); + + SPublishMsg pubmsgs; + pubmsgs.topic=ssData.respTopic; + pubmsgs.msg=sendMsg; + putPublishMsg(pubmsgs); + + if(1==reply.code) + { + return iotFailed; + } + else + { + return iotSuccess; + } +} + +int CmdHandleThread::handleStartStrategy(const SStrategy &ssData) +{ + SFesFwAo *pFwAo; + SFesRxAoCmd aoCmd; + SCommonReply reply; + reply.method=ssData.method; + reply.dId=ssData.dId; + reply.msgId=ssData.msgId; + reply.version=ssData.version; + reply.ts=getUTCTimeMsec(); + + if(m_mapAoPoint.find(PublishMethod::StartStrategy)==m_mapAoPoint.end()) + { + //发送执行失败 + reply.code=1; + LOGERROR("HcCloudCmdHandleThread ChanNo=%d can not find StartStrategyPoint in rtu %d ", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo); + } + else + { + int64_t pointId=m_mapAoPoint[PublishMethod::StartStrategy]; + if(pointIdm_MaxFwAoPoints) + { + pFwAo = m_ptrCFesRtu->m_pFwAo + pointId; + sprintf(aoCmd.TableName, "cmd.TableName"); + sprintf(aoCmd.TagName, "cmd.TagName"); + sprintf(aoCmd.RtuName, "cmd.RtuName"); + sprintf(aoCmd.ColumnName, "cmd.ColumnName"); + aoCmd.CtrlDir = CN_Fes_CtrlDir_InSide; + aoCmd.FwSubSystem = m_ptrCFesRtu->m_Param.nSubSystem; + aoCmd.FwRtuNo = m_ptrCFesRtu->m_Param.RtuNo; + aoCmd.FwPointNo = pointId; + aoCmd.RtuNo = pFwAo->FesRtuNo; + aoCmd.PointID = pFwAo->FesPointNo; + aoCmd.SubSystem = pFwAo->SrcSubSystem; + aoCmd.fValue = 1; + aoCmd.CtrlActType = CN_ControlExecute; + m_ptrCFesBase->WriteAoReqCmdBuf(1, &aoCmd); + reply.code=0; + } + else + { + reply.code=1; + LOGERROR("HcCloudCmdHandleThread ChanNo=%d can not find StartStrategyPoint in rtu %d by pointId %d when StartStrategy", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo,pointId); + } + + pointId=m_mapAoPoint[PublishMethod::StopStrategy]; + if(pointIdm_MaxFwAoPoints) + { + pFwAo = m_ptrCFesRtu->m_pFwAo + pointId; + sprintf(aoCmd.TableName, "cmd.TableName"); + sprintf(aoCmd.TagName, "cmd.TagName"); + sprintf(aoCmd.RtuName, "cmd.RtuName"); + sprintf(aoCmd.ColumnName, "cmd.ColumnName"); + aoCmd.CtrlDir = CN_Fes_CtrlDir_InSide; + aoCmd.FwSubSystem = m_ptrCFesRtu->m_Param.nSubSystem; + aoCmd.FwRtuNo = m_ptrCFesRtu->m_Param.RtuNo; + aoCmd.FwPointNo = pointId; + aoCmd.RtuNo = pFwAo->FesRtuNo; + aoCmd.PointID = pFwAo->FesPointNo; + aoCmd.SubSystem = pFwAo->SrcSubSystem; + aoCmd.fValue = 0; + aoCmd.CtrlActType = CN_ControlExecute; + m_ptrCFesBase->WriteAoReqCmdBuf(1, &aoCmd); + reply.code=0; + } + else + { + reply.code=1; + LOGERROR("HcCloudCmdHandleThread ChanNo=%d can not find StopStrategyPoint in rtu %d by pointId %d when StartStrategy", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo,pointId); + } + + } + + std::string sendMsg=generateJson(reply); + + SPublishMsg pubmsgs; + pubmsgs.topic=ssData.respTopic; + pubmsgs.msg=sendMsg; + putPublishMsg(pubmsgs); + + if(1==reply.code) + { + return iotFailed; + } + else + { + return iotSuccess; + } + +} + +int CmdHandleThread::handleStopStrategy(const SStrategy &ssData) +{ + SFesFwAo *pFwAo; + SFesRxAoCmd aoCmd; + SCommonReply reply; + reply.method=ssData.method; + reply.dId=ssData.dId; + reply.msgId=ssData.msgId; + reply.version=ssData.version; + reply.ts=getUTCTimeMsec(); + + if(m_mapAoPoint.find(PublishMethod::StopStrategy)==m_mapAoPoint.end()) + { + //发送执行失败 + reply.code=1; + LOGERROR("HcCloudCmdHandleThread ChanNo=%d can not find StopStrategyPoint in rtu %d ", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo); + } + else + { + int64_t pointId=m_mapAoPoint[PublishMethod::StopStrategy]; + if(pointIdm_MaxFwAoPoints) + { + pFwAo = m_ptrCFesRtu->m_pFwAo + pointId; + sprintf(aoCmd.TableName, "cmd.TableName"); + sprintf(aoCmd.TagName, "cmd.TagName"); + sprintf(aoCmd.RtuName, "cmd.RtuName"); + sprintf(aoCmd.ColumnName, "cmd.ColumnName"); + aoCmd.CtrlDir = CN_Fes_CtrlDir_InSide; + aoCmd.FwSubSystem = m_ptrCFesRtu->m_Param.nSubSystem; + aoCmd.FwRtuNo = m_ptrCFesRtu->m_Param.RtuNo; + aoCmd.FwPointNo = pointId; + aoCmd.RtuNo = pFwAo->FesRtuNo; + aoCmd.PointID = pFwAo->FesPointNo; + aoCmd.SubSystem = pFwAo->SrcSubSystem; + aoCmd.fValue = 1; + aoCmd.CtrlActType = CN_ControlExecute; + m_ptrCFesBase->WriteAoReqCmdBuf(1, &aoCmd); + reply.code=0; + } + else + { + reply.code=1; + LOGERROR("HcCloudCmdHandleThread ChanNo=%d can not find StopStrategyPoint in rtu %d by pointId %d when StopStrategy", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo,pointId); + } + + pointId=m_mapAoPoint[PublishMethod::StartStrategy]; + if(pointIdm_MaxFwAoPoints) + { + pFwAo = m_ptrCFesRtu->m_pFwAo + pointId; + sprintf(aoCmd.TableName, "cmd.TableName"); + sprintf(aoCmd.TagName, "cmd.TagName"); + sprintf(aoCmd.RtuName, "cmd.RtuName"); + sprintf(aoCmd.ColumnName, "cmd.ColumnName"); + aoCmd.CtrlDir = CN_Fes_CtrlDir_InSide; + aoCmd.FwSubSystem = m_ptrCFesRtu->m_Param.nSubSystem; + aoCmd.FwRtuNo = m_ptrCFesRtu->m_Param.RtuNo; + aoCmd.FwPointNo = pointId; + aoCmd.RtuNo = pFwAo->FesRtuNo; + aoCmd.PointID = pFwAo->FesPointNo; + aoCmd.SubSystem = pFwAo->SrcSubSystem; + aoCmd.fValue = 0; + aoCmd.CtrlActType = CN_ControlExecute; + m_ptrCFesBase->WriteAoReqCmdBuf(1, &aoCmd); + reply.code=0; + } + else + { + reply.code=1; + LOGERROR("HcCloudCmdHandleThread ChanNo=%d can not find StartStrategyPoint in rtu %d by pointId %d when StopStrategy", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo,pointId); + } + + } + + std::string sendMsg=generateJson(reply); + + + SPublishMsg pubmsgs; + pubmsgs.topic=ssData.respTopic; + pubmsgs.msg=sendMsg; + putPublishMsg(pubmsgs); + + if(1==reply.code) + { + return iotFailed; + } + else + { + return iotSuccess; + } + +} + +std::string CmdHandleThread::buildStrategyJson(const SStrategy& strategyStruct) +{ + rapidjson::Document doc; + doc.SetObject(); + + rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); + + doc.AddMember(rapidjson::StringRef("strategySrc"), rapidjson::StringRef("hc"), allocator); + + rapidjson::Value content(rapidjson::kObjectType); + content.AddMember("method", rapidjson::StringRef(strategyStruct.method.c_str()), allocator); + content.AddMember("dId", rapidjson::StringRef(strategyStruct.dId.c_str()), allocator); + content.AddMember("msgId", rapidjson::StringRef(strategyStruct.msgId.c_str()), allocator); + content.AddMember("version", rapidjson::StringRef(strategyStruct.version.c_str()), allocator); + content.AddMember("ts", iot_public::getUTCTimeMsec(), allocator); + content.AddMember("respTopic", rapidjson::StringRef(strategyStruct.respTopic.c_str()), allocator); + + rapidjson::Value data(rapidjson::kObjectType); + + if( strategyStruct.method == "SetStrategyData" ) + { + rapidjson::Value times(rapidjson::kArrayType); + for( int i=0; i write(buffer); + + doc.Accept(write); + + return buffer.GetString(); +} + +string CmdHandleThread::generateJson(const SStrategyInfoReply &ssir) +{ + rapidjson::StringBuffer s; + rapidjson::Writer writer(s); + + writer.StartObject(); //起始 + writer.Key("method"); + writer.String(ssir.method.c_str()); + writer.Key("dId"); + writer.String(ssir.dId.c_str()); + writer.Key("msgId"); + writer.String(ssir.msgId.c_str()); + writer.Key("version"); + writer.String(ssir.version.c_str()); + writer.Key("ts"); + writer.Int64(ssir.ts); + writer.Key("code"); + writer.Int(ssir.code); + + writer.Key("data"); + writer.StartObject(); + writer.Key("Demand"); + writer.String(ssir.data.Demand.c_str()); + writer.Key("Mode"); + writer.String(ssir.data.Mode.c_str()); + writer.Key("TotalCapacity"); + writer.String(ssir.data.TotalCapacity.c_str()); + + writer.Key("Times"); + writer.StartArray(); + for(size_t i = 0; i < ssir.data.Times.size(); i++) + { + const SStrategyTime &sst = ssir.data.Times.at(i); + writer.StartObject(); + writer.Key("StartTime"); + writer.String(sst.StartTime.c_str()); + writer.Key("EndTime"); + writer.String(sst.EndTime.c_str()); + writer.Key("Power"); + writer.Double(sst.Power); + writer.EndObject(); + } + writer.EndArray(); + + writer.EndObject(); + + writer.EndObject(); //结束 + + + return s.GetString(); +} + +string CmdHandleThread::generateJson(const SStrategyStatusReply &sssr) +{ + rapidjson::StringBuffer s; + rapidjson::Writer writer(s); + + writer.StartObject(); //起始 + writer.Key("method"); + writer.String(sssr.method.c_str()); + writer.Key("dId"); + writer.String(sssr.dId.c_str()); + writer.Key("msgId"); + writer.String(sssr.msgId.c_str()); + writer.Key("version"); + writer.String(sssr.version.c_str()); + writer.Key("ts"); + writer.Int64(sssr.ts); + writer.Key("code"); + writer.Int(sssr.code); + + writer.Key("data"); + writer.StartObject(); + writer.Key("RunStatus"); + writer.Bool(sssr.RunStatus); + writer.EndObject(); + + writer.EndObject(); //结束 + + return s.GetString(); +} + +string CmdHandleThread::generateJson(const SCommonReply &scr) +{ + rapidjson::StringBuffer s; + rapidjson::Writer writer(s); + + writer.StartObject(); //起始 + writer.Key("method"); + writer.String(scr.method.c_str()); + writer.Key("dId"); + writer.String(scr.dId.c_str()); + writer.Key("msgId"); + writer.String(scr.msgId.c_str()); + writer.Key("version"); + writer.String(scr.version.c_str()); + writer.Key("ts"); + writer.Int64(scr.ts); + writer.Key("code"); + writer.Int(scr.code); + + writer.Key("data"); + writer.StartObject(); + writer.EndObject(); + + writer.EndObject(); //结束 + + return s.GetString(); +} + +string CmdHandleThread::generateJson(const SStrategy &ss) +{ + rapidjson::StringBuffer s; + rapidjson::Writer writer(s); + + writer.StartObject(); //起始 + writer.Key("method"); + writer.String(ss.method.c_str()); + writer.Key("dId"); + writer.String(ss.dId.c_str()); + writer.Key("msgId"); + writer.String(ss.msgId.c_str()); + writer.Key("version"); + writer.String(ss.version.c_str()); + writer.Key("ts"); + writer.Int64(ss.ts); + writer.Key("respTopic"); + writer.String(ss.respTopic.c_str()); + + writer.Key("data"); + writer.StartObject(); + writer.Key("Demand"); + writer.String(ss.data.Demand.c_str()); + writer.Key("Mode"); + writer.String(ss.data.Mode.c_str()); + writer.Key("TotalCapacity"); + writer.String(ss.data.TotalCapacity.c_str()); + + writer.Key("Times"); + writer.StartArray(); + for(size_t i = 0; i < ss.data.Times.size(); i++) + { + const SStrategyTime &sst = ss.data.Times.at(i); + writer.StartObject(); + writer.Key("StartTime"); + writer.String(sst.StartTime.c_str()); + writer.Key("EndTime"); + writer.String(sst.EndTime.c_str()); + writer.Key("Power"); + writer.Double(sst.Power); + writer.EndObject(); + } + writer.EndArray(); + + writer.EndObject(); + + writer.EndObject(); //结束 + + + return s.GetString(); +} + +double CmdHandleThread::getJsonNumber(const rapidjson::Value& obj, string key) +{ + rapidjson::Value::ConstMemberIterator iter = obj.FindMember(key.c_str()); + if(iter == obj.MemberEnd()) + { + return 0; + } + const rapidjson::Value& value = iter->value; + switch (value.GetType()) { + case rapidjson::kNumberType: + if (value.IsInt()) { + return value.GetInt(); + } else if (value.IsUint()) { + return value.GetUint(); + } else if (value.IsInt64()) { + return value.GetInt64(); + } else if (value.IsUint64()) { + return value.GetUint64(); + } else if (value.IsFloat()) { + return value.GetFloat() ; + } else if (value.IsDouble()) { + return value.GetDouble() ; + } + break; + default: + return 0; + } + return 0; +} + +void CmdHandleThread::handleOutput() +{ + boost::mutex::scoped_lock lock(m_objMutex); + double_t power=0; + SFesFwAo *pFwAo; + SFesRxAoCmd aoCmd; + boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); // 获取当前本地时间 + boost::posix_time::time_duration currentTime = now.time_of_day(); // 获取时间部分 + int64_t currentMinutes = currentTime.hours() * 60 + currentTime.minutes(); // 转换为分钟数 + for(size_t i = 0; i < m_sCurrentStrategy.data.Times.size(); ++i) + { + if( m_sCurrentStrategy.data.Times[i].isInTimePeriod(currentMinutes)) + { + power= m_sCurrentStrategy.data.Times[i].Power; + + if(m_mapAoPoint.find(PublishMethod::SetStrategyData)==m_mapAoPoint.end()) + { + + LOGERROR("HcCloudCmdHandleThread ChanNo=%d can not find OutputPowerPoint in rtu %d value=%lf", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo,power); + } + else + { + int64_t pointId=m_mapAoPoint[PublishMethod::SetStrategyData]; + if(pointIdm_MaxFwAoPoints) + { + pFwAo = m_ptrCFesRtu->m_pFwAo + pointId; + sprintf(aoCmd.TableName, "cmd.TableName"); + sprintf(aoCmd.TagName, "cmd.TagName"); + sprintf(aoCmd.RtuName, "cmd.RtuName"); + sprintf(aoCmd.ColumnName, "cmd.ColumnName"); + aoCmd.CtrlDir = CN_Fes_CtrlDir_InSide; + aoCmd.FwSubSystem = m_ptrCFesRtu->m_Param.nSubSystem; + aoCmd.FwRtuNo = m_ptrCFesRtu->m_Param.RtuNo; + aoCmd.FwPointNo = pointId; + aoCmd.RtuNo = pFwAo->FesRtuNo; + aoCmd.PointID = pFwAo->FesPointNo; + aoCmd.SubSystem = pFwAo->SrcSubSystem; + aoCmd.fValue = power; + aoCmd.CtrlActType = CN_ControlExecute; + m_ptrCFesBase->WriteAoReqCmdBuf(1, &aoCmd); + } + else + { + LOGERROR("HcCloudCmdHandleThread ChanNo=%d can not find OutputPowerPoint in rtu %d by pointId %d value=%lf", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo,pointId,power); + } + + } + + + break; + } + } + + + +} + +void CmdHandleThread::loadAoPoint() +{ + //和方法的枚举值对应(只处理模拟量) + SFesFwAo *pFwAo; + for (int aoPoint = 0; aoPoint < m_ptrCFesRtu->m_MaxFwAoPoints; aoPoint++) + { + pFwAo = m_ptrCFesRtu->m_pFwAo + aoPoint; + if(0==pFwAo->ResParam1&&0!=pFwAo->ResParam2) + { + PublishMethod pm = static_cast(pFwAo->ResParam2); + m_mapAoPoint[pm]=aoPoint;//采集点特殊处理 + } + } + //采集点 + SFesFwAi *pFwAi; + for (int aiPoint = 0; aiPoint < m_ptrCFesRtu->m_MaxFwAiPoints; aiPoint++) + { + pFwAi = m_ptrCFesRtu->m_pFwAi + aiPoint; + if(0==pFwAi->ResParam1&&0!=pFwAi->ResParam2) + { + PublishMethod pm = static_cast(pFwAi->ResParam2); + m_mapAoPoint[pm]=aiPoint;//采集点特殊处理 + } + } + +} + +void CmdHandleThread::putReceiveMsg(SMsg msg) +{ + boost::mutex::scoped_lock lock(m_RxMutex); + m_RxBuffer.push(msg); +} + +int CmdHandleThread::getPublishMsg(SPublishMsg &msg) +{ + boost::mutex::scoped_lock lock(m_TxMutex); + if(!m_TxBuffer.empty()) + { + msg=m_TxBuffer.front(); + m_TxBuffer.pop(); + return 1; + } + return 0; +} + +void CmdHandleThread::putPublishMsg(SPublishMsg msg) +{ + boost::mutex::scoped_lock lock(m_TxMutex); + m_TxBuffer.push(msg); +} + +string CmdHandleThread::getSubscription() +{ + return m_cmdHandleConfig.Subscription; +} + +bool CmdHandleThread::parseJson(const rapidjson::Document &doc, SStrategy &ss, bool ignoreData,const std::string &msg) +{ + + bool ret=true; + + if(doc.HasMember("method")&&doc["method"].IsString()) + { + ss.method=doc["method"].GetString(); + } + else + { + LOGERROR(" ChanNo=%d JSON miss method(string) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + + } + if(doc.HasMember("dId")&&doc["dId"].IsString()) + { + ss.dId=doc["dId"].GetString(); + } + else + { + LOGERROR(" ChanNo=%d JSON miss dId(string) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + + if(doc.HasMember("msgId")&&doc["msgId"].IsString()) + { + ss.msgId=doc["msgId"].GetString(); + } + else + { + LOGERROR(" ChanNo=%d JSON miss msgId(string) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + if(doc.HasMember("version")&&doc["version"].IsString()) + { + ss.version=doc["version"].GetString(); + } + else + { + LOGERROR(" ChanNo=%d JSON miss version(string) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + + if(doc.HasMember("ts")&&doc["ts"].IsNumber()) + { + ss.ts=getJsonNumber(doc,"ts"); + } + else + { + LOGERROR(" ChanNo=%d JSON miss ts(number) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + + if(doc.HasMember("respTopic")&&doc["respTopic"].IsString()) + { + ss.respTopic=doc["respTopic"].GetString(); + } + else + { + LOGERROR(" ChanNo=%d JSON miss respTopic(string) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + + + if(!ignoreData) + { + if(doc.HasMember("data")&&doc["data"].IsObject()) + { + const rapidjson::Value& obj=doc["data"]; + if(obj.HasMember("Demand")&&obj["Demand"].IsString()) + { + ss.data.Demand=obj["Demand"].GetString(); + } + else + { + LOGERROR(" ChanNo=%d JSON miss Demand(string) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + + if(obj.HasMember("Mode")&&obj["Mode"].IsString()) + { + ss.data.Mode=obj["Mode"].GetString(); + } + else + { + LOGERROR(" ChanNo=%d JSON miss Mode(string) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + + if(obj.HasMember("TotalCapacity")&&obj["TotalCapacity"].IsString()) + { + ss.data.TotalCapacity=obj["TotalCapacity"].GetString(); + } + else + { + LOGERROR(" ChanNo=%d JSON miss TotalCapacity(string) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + + if(obj.HasMember("Times")&&obj["Times"].IsArray()) + { + const rapidjson::Value& itemsArray = obj["Times"]; + for (rapidjson::SizeType i = 0; i < itemsArray.Size(); ++i) { + SStrategyTime sst; + const rapidjson::Value& item=itemsArray[i]; + if(item.HasMember("StartTime")&&item["StartTime"].IsString()) + { + sst.StartTime=item["StartTime"].GetString(); + } + else + { + LOGERROR(" ChanNo=%d JSON miss StartTime(string) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + if(item.HasMember("EndTime")&&item["EndTime"].IsString()) + { + sst.EndTime=item["EndTime"].GetString(); + } + else + { + LOGERROR(" ChanNo=%d JSON miss EndTime(string) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + if(item.HasMember("Power")&&item["Power"].IsNumber()) + { + sst.Power=getJsonNumber(item,"Power"); + } + else + { + LOGERROR(" ChanNo=%d JSON miss Power(number) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + ss.data.Times.push_back(sst); + + } + } + else + { + LOGERROR(" ChanNo=%d JSON miss Times(array) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + + } + else + { + LOGERROR(" ChanNo=%d JSON miss data(object) %s ", m_ptrCFesChan->m_Param.ChanNo,msg.data()); + return false; + } + } + + + return ret; + +} + + + diff --git a/product/src/fes/protocol/mqtt_hcfy/CmdHandleThread.h b/product/src/fes/protocol/mqtt_hcfy/CmdHandleThread.h new file mode 100644 index 00000000..13ec3f4c --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/CmdHandleThread.h @@ -0,0 +1,189 @@ +#pragma once +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "pub_utility_api/TimerThreadBase.h" + +#include "net_msg_bus_api/MsgBusApi.h" +#include +#include +#include "rapidjson/document.h" +#include "rapidjson/writer.h" +#include "rapidjson/stringbuffer.h" +#include +#include +#include +#include +#include +#include "CMosquitto.h" +#include + + +typedef struct{ + int RtuNo; + std::string LocalStrategyPath;//json格式的文件 + std::string Subscription; +}SCmdHandleConfig; + +typedef struct { + std::string StartTime; + std::string EndTime; + double_t Power; + + // 将时间字符串转换为分钟数 + int64_t timeToMinutes(const std::string& timeStr) const { + + boost::posix_time::ptime pt = boost::posix_time::time_from_string("1970-01-01 " + timeStr); // 用任意日期将时间转换为ptime + boost::posix_time::time_duration td = pt.time_of_day(); // 获取时间部分 + return td.hours() * 60 + td.minutes(); // 转换为分钟数 + } + // 判断当前时间是否在此时间段内 + bool isInTimePeriod(int currentTime) const { + int startMinutes = timeToMinutes(StartTime); + int endMinutes = timeToMinutes(EndTime); + return currentTime >= startMinutes && currentTime < endMinutes; + } + + +}SStrategyTime; + +typedef struct { + std::string Demand; + std::string Mode; + std::string TotalCapacity; + std::vector Times; +}SStrategyData; + + +typedef struct { + std::string method; + std::string dId; + std::string msgId; + std::string version; + int64_t ts; + std::string respTopic; + SStrategyData data; +}SStrategy; //所有消息用此结构体 + + + +typedef struct { + std::string method; + std::string dId; + std::string msgId; + std::string version; + int64_t ts; + int64_t code; + SStrategyData data; +}SStrategyInfoReply; + +typedef struct { + std::string method; + std::string dId; + std::string msgId; + std::string version; + int64_t ts; + int64_t code; + bool RunStatus; +}SStrategyStatusReply; + +typedef struct { + std::string method; + std::string dId; + std::string msgId; + std::string version; + int64_t ts; + int64_t code; +}SCommonReply; + +enum class PublishMethod { + FULL, + VARY, + SetStrategyData, + GetStrategyStatus, + StartStrategy, + StopStrategy +}; + + +typedef struct { + std::string topic; + std::string msg; +}SPublishMsg; + + + + +class CmdHandleThread: public iot_public::CTimerThreadBase,CProtocolBase +{ +public: + CmdHandleThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,vector vecConfig); + virtual ~CmdHandleThread(); + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + 处理点的输出 + */ + virtual void execute(); + + virtual void beforeQuit(); + void putReceiveMsg(SMsg msg); + + int getPublishMsg(SPublishMsg& msg); + void putPublishMsg(SPublishMsg msg); + std::string getSubscription(); + +private: + bool m_bReady;//线程是否准备好 + boost::container::map m_mapAoPoint;//输出的遥调点号/偏移量 + CFesChanPtr m_ptrCFesChan; + CFesBase* m_ptrCFesBase; + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区 + SCmdHandleConfig m_cmdHandleConfig; + SStrategy m_sCurrentStrategy;//current当前的策略 + boost::mutex m_objMutex;// + std::queue m_RxBuffer; + boost::mutex m_RxMutex;// + std::queue m_TxBuffer; + boost::mutex m_TxMutex;// + + iot_net::CMbCommunicator* m_ptrMbComm{NULL}; +private: + /* + @brief 获取本地路径策略 + 处理遥控点的输出 + */ + int getLocalStrategyData(SStrategy& strategy); + + + void handleMsg(SMsg& msg); + int handleSetStrategyData(const SStrategy& ssData); + int handleGetStrategyData(const SStrategy& ssData); + int handleGetStrategyStatus(const SStrategy& ssData); + int handleStartStrategy(const SStrategy& ssData); + int handleStopStrategy(const SStrategy& ssData); + + std::string buildStrategyJson(const SStrategy& strategyStruct); + + bool parseJson(const rapidjson::Document& doc,SStrategy& ssData,bool ignoreData,const std::string &msg); + + + std::string generateJson(const SStrategyInfoReply& ssir); + std::string generateJson(const SStrategyStatusReply& sssr); + std::string generateJson(const SCommonReply& scr); + std::string generateJson(const SStrategy& ss); + + double getJsonNumber(const rapidjson::Value& obj,std::string key); + + void handleOutput(); + + void loadAoPoint(); + + + +}; + +typedef boost::shared_ptr CCmdHandleThreadPtr; diff --git a/product/src/fes/protocol/mqtt_hcfy/Hccloudmqtts.cpp b/product/src/fes/protocol/mqtt_hcfy/Hccloudmqtts.cpp new file mode 100644 index 00000000..cef6107f --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/Hccloudmqtts.cpp @@ -0,0 +1,488 @@ +#include "Hccloudmqtts.h" + + +using namespace iot_public; + +CHccloudmqtts Hccloudmqtts; +bool g_HccloudmqttsIsMainFes=false; +bool g_HccloudmqttsChanelRun=true; + +int EX_SetBaseAddr(void *address) +{ + Hccloudmqtts.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + Hccloudmqtts.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + Hccloudmqtts.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + Hccloudmqtts.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + Hccloudmqtts.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + LOGDEBUG("hccloud_mqtt_V1 EX_ExitSystem() start"); + g_HccloudmqttsChanelRun=false;//使所有的线程退出。 + Hccloudmqtts.ExitSystem(flag); + LOGDEBUG("hccloud_mqtt_V1 EX_ExitSystem() end"); + return iotSuccess; +} +CHccloudmqtts::CHccloudmqtts() +{ + // 2020-02-13 thxiao ReadConfigParam()需要使用m_ptrCFesBase,所以改为SetBaseAddr()处调用 + //ReadConfigParam(); + m_ProtocolId = 0; +} + +CHccloudmqtts::~CHccloudmqtts() +{ + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); +} + + +int CHccloudmqtts::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + ReadConfigParam(); + } + return iotSuccess; +} + +int CHccloudmqtts::SetProperty(int IsMainFes) +{ + g_HccloudmqttsIsMainFes = (bool)IsMainFes; + LOGDEBUG("CHccloudmqtts::SetProperty g_YxcloudmqttsIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief CHccloudmqtts::OpenChan 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CHccloudmqtts::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if ((OpenFlag == CN_FesChanThread_Flag) || (OpenFlag == CN_FesChanAndDataThread_Flag)) + { + switch (ptrFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + case CN_FesTcpServer: + break; + default: + LOGERROR("CHccloudmqtts EX_OpenChan() ChanNo:%d CommType=%d is not TCP SERVER/Client!", ptrFesChan->m_Param.ChanNo, ptrFesChan->m_Param.CommType); + return iotFailed; + } + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + + CCmdHandleThreadPtr ptrCmd=boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_cmdHandleConfig); + CMQTTHandleThreadPtr ptrMQTT=boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_mqttConfig,ptrCmd); + + CHccloudmqttsDataProcThreadPtr ptrCDataProc; + ptrCDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_vecAppParam,ptrMQTT); + if (ptrCDataProc == NULL) + { + LOGERROR("CHccloudmqtts EX_OpenChan() ChanNo:%d create CHccloudmqttsDataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + LOGINFO("CHccloudmqtts EX_OpenChan() ChanNo:%d create CHccloudmqttsDataProcThreadPtr ok!", ptrFesChan->m_Param.ChanNo); + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; +} + +/** + * @brief CHccloudmqtts::CloseChan 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CHccloudmqtts::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("CHccloudmqtts::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + return iotSuccess; +} + +/** + * @brief CHccloudmqtts::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int CHccloudmqtts::ChanTimer(int MainChanNo) +{ + //把命令缓冲时间间隔到的命放到发送命令缓冲区 + return iotSuccess; +} + +int CHccloudmqtts::ExitSystem(int flag) +{ + InformTcpThreadExit(); + return iotSuccess; +} + +void CHccloudmqtts::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + CHccloudmqttsDataProcThreadPtr ptrTcp; + + if ((tempNum = (int)m_CDataProcQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CDataProcQueue.erase(it);//会调用CYxcloudmqttsDataProcThread::~CHccloudmqttsDataProcThread()退出线程 + LOGDEBUG("CHccloudmqtts::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + +/** +* @brief CHccloudmqtts::ReadConfigParam +* 读取Yxcloudmqtts配置文件 +* @return 成功返回iotSuccess,失败返回iotFailed +*/ +int CHccloudmqtts::ReadConfigParam() +{ + CCommonConfigParse config; + int ivalue; + std::string strvalue; + char strRtuNo[48]; + SHccloudmqttsAppConfigParam param; + SHccloudMqttsConfig mqttConfig; + SCmdHandleConfig cmdConfig; + int items,i,j; + CFesChanPtr ptrChan; //CHAN数据区 + CFesRtuPtr ptrRTU; + + //memset(¶m, 0, sizeof(SYxcloudmqttsAppConfigParam)); + + if (m_ptrCFesBase == NULL) + return iotFailed; + + m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"mqtt_hcfy"); + if (m_ProtocolId == -1) + { + LOGDEBUG("ReadConfigParam ProtoclID error"); + return iotFailed; + } + LOGINFO("hccloud_mqtt_V1 ProtoclID=%d", m_ProtocolId); + + if (config.load("../../data/fes/", "mqtt_hcfy.xml") == iotFailed) + { + LOGDEBUG("mqtt_hcfy load mqtt_hcfy.xml error"); + return iotSuccess; + } + LOGDEBUG("mqtt_hcfy load mqtt_hcfy.xml ok"); + + + for (i = 0; i < m_ptrCFesBase->m_vectCFesChanPtr.size(); i++) + { + ptrChan = m_ptrCFesBase->m_vectCFesChanPtr[i]; + if ((ptrChan->m_Param.Used == 1) && (m_ProtocolId == ptrChan->m_Param.ProtocolId)) + { + //found RTU + for (j = 0; j < m_ptrCFesBase->m_vectCFesRtuPtr.size(); j++) + { + ptrRTU = m_ptrCFesBase->m_vectCFesRtuPtr[j]; + if (ptrRTU->m_Param.Used && (ptrRTU->m_Param.ChanNo == ptrChan->m_Param.ChanNo)) + { + memset(&strRtuNo[0], 0, sizeof(strRtuNo)); + sprintf(strRtuNo, "RTU%d", ptrRTU->m_Param.RtuNo); + //memset(¶m, 0, sizeof(param)); + param.RtuNo = ptrRTU->m_Param.RtuNo; + items = 0; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "topicConfigPath", strvalue) == iotSuccess) + { + param.topicConfigPath = strvalue; + items++; + } + else + { + param.topicConfigPath.clear(); + } + + if (config.getIntValue(strRtuNo, "cycCheckFileTime", ivalue) == iotSuccess) + { + param.cycCheckFileTime = ivalue; + items++; + } + else + { + param.cycCheckFileTime=0; + } + + if (config.getIntValue(strRtuNo, "startDelay", ivalue) == iotSuccess) + { + param.startDelay = ivalue; + items++; + } + else + { + param.startDelay = 30;//30s + } + + + + if (items > 0)//对应的RTU有配置项 + { + m_vecAppParam.push_back(param); + } + + + //mqtt的配置 + items = 0; + mqttConfig.RtuNo = ptrRTU->m_Param.RtuNo; + if (config.getIntValue(strRtuNo, "PasswordFlag", ivalue) == iotSuccess) + { + mqttConfig.PasswordFlag = ivalue; + items++; + } + else + { + mqttConfig.PasswordFlag = 0; + } + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "ClientId", strvalue) == iotSuccess) + { + mqttConfig.ClientId = strvalue; + items++; + } + else + { + //获取当前时间 + char timeBuff[256]; + memset(timeBuff , 0 , 256); + std::time_t now = std::time(nullptr); + std::tm* now_tm = std::localtime(&now); + std::strftime(timeBuff , 256 , "%Y%m%d%H%M%S" , now_tm); + mqttConfig.ClientId = "hcfyClient_"; //避免ID一样导致不停的发送信息 + mqttConfig.ClientId.append(timeBuff); + } + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "UserName", strvalue) == iotSuccess) + { + mqttConfig.UserName = strvalue; + items++; + } + else + { + mqttConfig.UserName.clear(); + + } + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "Password", strvalue) == iotSuccess) + { + mqttConfig.Password = strvalue; + items++; + } + else + { + mqttConfig.Password.clear(); + } + + if (config.getIntValue(strRtuNo, "KeepAlive", ivalue) == iotSuccess) + { + mqttConfig.KeepAlive = ivalue; + items++; + } + else + { + mqttConfig.KeepAlive = 180; //心跳检测时间间隔 + } + + if (config.getIntValue(strRtuNo, "Retain", ivalue) == iotSuccess) + { + mqttConfig.Retain = (bool)(ivalue & 0x01); + items++; + } + else + { + mqttConfig.Retain = false; //默认0 + } + + if (config.getIntValue(strRtuNo, "QoS", ivalue) == iotSuccess) + { + mqttConfig.QoS = ivalue; + items++; + } + else + { + mqttConfig.QoS = 1; + } + + if (config.getIntValue(strRtuNo, "WillFlag", ivalue) == iotSuccess) + { + mqttConfig.WillFlag = ivalue; + items++; + } + else + { + mqttConfig.WillFlag = 1; + } + + + if (config.getIntValue(strRtuNo, "WillQos", ivalue) == iotSuccess) + { + mqttConfig.WillQos = ivalue; + items++; + } + else + { + mqttConfig.WillQos = 1; + } + + + if (config.getIntValue(strRtuNo, "sslFlag", ivalue) == iotSuccess) + { + mqttConfig.sslFlag = ivalue; + items++; + } + else + { + mqttConfig.sslFlag = 0; + } + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "tls_version", strvalue) == iotSuccess) + { + mqttConfig.tls_version = strvalue; + items++; + } + else + { + mqttConfig.tls_version = "tlsv1.1"; + } + + if (items > 0)//对应的RTU有配置项 + { + m_mqttConfig.push_back(mqttConfig); + } + + + //命令配置 + items = 0; + cmdConfig.RtuNo = ptrRTU->m_Param.RtuNo; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "Subscription", strvalue) == iotSuccess) + { + cmdConfig.Subscription = strvalue; + items++; + } + else + { + cmdConfig.Subscription.clear(); + + } + + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "LocalStrategyPath", strvalue) == iotSuccess) + { + cmdConfig.LocalStrategyPath = strvalue; + items++; + } + else + { + cmdConfig.LocalStrategyPath.clear(); + + } + + + if (items > 0)//对应的RTU有配置项 + { + m_cmdHandleConfig.push_back(cmdConfig); + } + + } + } + } + } + return iotSuccess; +} + + +/** + * @brief CHccloudmqtts::InformTcpThreadExit + * 设置线程退出标志,通知线程退出 + * @return + */ +void CHccloudmqtts::InformTcpThreadExit() +{ + +} + + diff --git a/product/src/fes/protocol/mqtt_hcfy/Hccloudmqtts.h b/product/src/fes/protocol/mqtt_hcfy/Hccloudmqtts.h new file mode 100644 index 00000000..b5f780d8 --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/Hccloudmqtts.h @@ -0,0 +1,42 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "HccloudmqttsDataProcThread.h" +#include "pub_utility_api/CommonConfigParse.h" + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API CHccloudmqtts : public CProtocolBase +{ +public: + CHccloudmqtts(); + ~CHccloudmqtts(); + + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + vector m_CDataProcQueue; + vector m_vecAppParam; + + vector m_mqttConfig; + vector m_cmdHandleConfig; + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + int ExitSystem(int flag); + int ReadConfigParam(); + void InformTcpThreadExit(); +private: + int m_ProtocolId; + void ClearDataProcThreadByChanNo(int ChanNo); +}; + diff --git a/product/src/fes/protocol/mqtt_hcfy/HccloudmqttsDataProcThread.cpp b/product/src/fes/protocol/mqtt_hcfy/HccloudmqttsDataProcThread.cpp new file mode 100644 index 00000000..f7e905f9 --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/HccloudmqttsDataProcThread.cpp @@ -0,0 +1,945 @@ +#include +#include "HccloudmqttsDataProcThread.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" +#include +#include +#include + + + +using namespace iot_public; + +extern bool g_HccloudmqttsIsMainFes; +extern bool g_HccloudmqttsChanelRun; +const int gHccloudmqttsThreadTime = 10; + + +CHccloudmqttsDataProcThread::CHccloudmqttsDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam, + CMQTTHandleThreadPtr ptrMQTT + + ): + CTimerThreadBase("HccloudmqttsDataProcThread", gHccloudmqttsThreadTime,0,true),m_bReady(true) +{ + m_pChgAiData=NULL; + m_pChgDiData=NULL; + m_pChgAccData=NULL; + m_pChgMiData=NULL; + + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + + m_ptrMQTT=ptrMQTT; + m_ptrMQTT->resume(); + + + + m_timerCountReset = 10; + m_timerCount = 0; + m_AppData.startTime=getMonotonicMsec() / 1000; + + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL)) + { + return; + } + m_ptrCFesChan->SetLinkStatus(CN_FesChanConnect); + m_ptrCFesChan->SetComThreadRunFlag(CN_FesRunFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + //2020-03-03 thxiao 不需要数据变化 +// m_ptrCFesRtu->SetFwAiChgStop(1); +// m_ptrCFesRtu->SetFwDiChgStop(1); +// m_ptrCFesRtu->SetFwMiChgStop(1); +// m_ptrCFesRtu->SetFwAccChgStop(1); + m_ptrCFesRtu->SetFwDDiChgStop(1); + + + bool found = false; + if(vecAppParam.size()>0) + { + for (size_t i = 0; i < vecAppParam.size(); i++) + { + if(m_ptrCFesRtu->m_Param.RtuNo == vecAppParam[i].RtuNo) + { + //配置 + m_AppData.RtuNo = vecAppParam[i].RtuNo; + m_AppData.topicConfigPath = vecAppParam[i].topicConfigPath; + m_AppData.cycCheckFileTime = vecAppParam[i].cycCheckFileTime; + m_AppData.startDelay=vecAppParam[i].startDelay; + m_AppData.lastReadFileTime=0; + found = true; + break; + } + } + } + + + //读取mqtt_topic_cfg.csv文件,并更新参数确定map + if(found) + { + GetTopicCfg(); + } + else + { + m_bReady=false; + LOGERROR("CHccloudmqttsDataProcThread ChanNo=%d can not match rtuNo in config due to now rtuNo is %d and do nothing", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo); + } + + initDevicePointCount(); + + +} + +CHccloudmqttsDataProcThread::~CHccloudmqttsDataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + + ClearTopicStr(); + + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + if(m_pChgAiData) + { + free(m_pChgAiData); + } + if(m_pChgDiData) + { + free(m_pChgDiData); + } + if(m_pChgMiData) + { + free(m_pChgMiData); + } + if(m_pChgAccData) + { + free(m_pChgAccData); + } + LOGDEBUG("CHccloudmqttsDataProcThread::~CHccloudmqttsDataProcThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); + +} + +/** + * @brief CHccloudmqttsDataProcThread::beforeExecute + * + */ +int CHccloudmqttsDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief CHccloudmqttsDataProcThread::execute + + */ +void CHccloudmqttsDataProcThread::execute() +{ + if(!m_bReady) + { + LOGERROR("CHccloudmqttsDataProcThread ChanNo=%d rtuNo %d has bad and do nothing ", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo); + return; + } + if (m_timerCount++ >= m_timerCountReset) + m_timerCount = 0;// 1sec is ready + + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + if(m_ptrCurrentChan== NULL) + return; + + int64 cursec = getMonotonicMsec() / 1000; + if (m_AppData.startDelay > 0) + { + if ((cursec - m_AppData.startTime) < m_AppData.startDelay) + { + return; + } + } + + + + //秒级判断流程 + TimerProcess(); + + //mqtt转发流程 + HccloudmqttsProcess(); +} + +/* + @brief 执行quit函数前的处理 + */ +void CHccloudmqttsDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetComThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetLinkStatus(CN_FesChanDisconnect); + + LOGDEBUG("CHccloudmqttsDataProcThread::beforeQuit() "); +} + + + +void CHccloudmqttsDataProcThread::TimerProcess() +{ + + //启动主线程判断逻辑 + bool needUpdate=ifNeedUpdateCache(); + if(needUpdate) + { + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + + //定时读取遥控命令响应缓冲区,及时清除队列释放空间,不对遥控成败作处理 + if (m_ptrCFesRtu->GetFwDoRespCmdNum() > 0) + { + SFesFwDoRespCmd retCmd; + m_ptrCFesRtu->ReadFwDoRespCmd(1, &retCmd); + } + + if (m_ptrCFesRtu->GetFwAoRespCmdNum() > 0) + { + SFesFwAoRespCmd retCmd; + m_ptrCFesRtu->ReadFwAoRespCmd(1, &retCmd); + } + } + +} + +void CHccloudmqttsDataProcThread::HccloudmqttsProcess() +{ + //处理变化数据 + ifDataChgAndPublish(); + //全量数据上送 + ifTimeToPublish(); + +} + +//获取文件MD5 +std::string CHccloudmqttsDataProcThread::GetFileMd5(const std::string &file) +{ + ifstream in(file.c_str(), ios::binary); + if (!in) + return ""; + + MD5 md5; + std::streamsize length; + char buffer[1024]; + while (!in.eof()) + { + in.read(buffer, 1024); + length = in.gcount(); + if (length > 0) + md5.update(buffer, length); + } + in.close(); + return md5.toString(); +} + + +//清空topic列表 +void CHccloudmqttsDataProcThread::ClearTopicStr() +{ + m_AppData.deviceTopicMap.clear(); +} + + +void CHccloudmqttsDataProcThread::GetTopicCfg( ) +{ + //先清空原来的list + ClearTopicStr(); + //[topic,device,interval] + + auto csvData=parseCSV(m_AppData.topicConfigPath); + //去掉表头 + csvData.erase(csvData.begin()); + + for (size_t i = 0; i < csvData.size(); ++i) { + if(csvData[i].size()>=4) + { + auto deviceName=csvData[i][1]; + TopicInfo stTopic; + stTopic.topic=csvData[i][0]; + stTopic.deviceTopic=csvData[i][2]; + int value=10; + try { + value = std::stoi(csvData[i][3]); // 尝试将字符串转换为整数 + } catch (const std::invalid_argument& e) { + LOGERROR("%s invalid_argument at index-%s",csvData[i][3].data(),stTopic.topic.data()); + } catch (const std::out_of_range& e) { + LOGERROR("%s out_of_range at index-%s",csvData[i][3].data(),stTopic.topic.data()); + } + stTopic.interval=value; + stTopic.needPublish=false; + stTopic.lastNeedPublish=0; + m_AppData.deviceTopicMap[deviceName]=stTopic; + } + else + { + LOGERROR("%s error size--%d and need 3 col",m_AppData.topicConfigPath.data(),csvData[i].size()); + + } + } + +} + + +bool CHccloudmqttsDataProcThread::ifNeedUpdateCache() +{ + std::string md5Str; + //系统启动后的运行的秒数 + int64 cursec = getMonotonicMsec() / 1000; + + //周期检查文件是否修改 + if(0!= m_AppData.cycCheckFileTime) + { + if ((cursec - m_AppData.lastReadFileTime) > m_AppData.cycCheckFileTime) + { + m_AppData.lastReadFileTime = cursec; + + //配置参数修改后,需要在线更新 + md5Str = GetFileMd5(m_AppData.topicConfigPath); + if (md5Str != m_AppData.topicCfgMd5) + { + m_AppData.topicCfgMd5 = md5Str; + //读取mqtt_topic_cfg.csv文件,并更新参数 + GetTopicCfg(); + } + } + } + + + bool needUpdate=false; + //检查各个Topic的发送周期是否到了 + cursec=getUTCTimeSec(); + for(auto it= m_AppData.deviceTopicMap.begin();it!= m_AppData.deviceTopicMap.end();++it) + { + + TopicInfo& deviceTopic=it->second; + if(0==deviceTopic.lastNeedPublish) + { + deviceTopic.lastNeedPublish=getUTCTimeSec(); + deviceTopic.needPublish=true; + needUpdate=true; + continue; + } + if(0==deviceTopic.interval) + { + deviceTopic.needPublish=false; + continue; + } + if(cursec-deviceTopic.lastNeedPublish>=deviceTopic.interval) + { + deviceTopic.lastNeedPublish=getUTCTimeSec(); + deviceTopic.needPublish=true; + needUpdate=true; + } + else + { + deviceTopic.needPublish=false; + } + + + } + + + return needUpdate; +} + + +void CHccloudmqttsDataProcThread::ifDataChgAndPublish() +{ + //查看更新数据缓冲区 + handleChgAiData(); + handleChgDiData(); + handleChgAccData(); + handleChgMiData(); + //triggerPublish(PublishMethod::VARY); + +} + +void CHccloudmqttsDataProcThread::handleChgAiData() +{ + int nAiCount = m_ptrCFesRtu->GetFwChgAiNum(); + if(0==nAiCount) + { + return; + } + SFesFwChgAi *pChgAi = NULL; + SFesFwAi *pFwAi = NULL; + + if (m_pChgAiData == NULL) + m_pChgAiData = (SFesFwChgAi*)malloc(nAiCount * sizeof(SFesFwChgAi)); + else + m_pChgAiData = (SFesFwChgAi*)realloc(m_pChgAiData, nAiCount * sizeof(SFesFwChgAi)); + + int nReadNum = m_ptrCFesRtu->ReadFwChgAi(nAiCount, m_pChgAiData); + + for (int i = 0; i < nReadNum; i++) + { + pChgAi = m_pChgAiData + i; + if(pChgAi->RemoteNo >= m_ptrCFesRtu->m_MaxFwAiPoints) + { + continue; + } + pFwAi = m_ptrCFesRtu->m_pFwAi + pChgAi->RemoteNo; + float AiFloatValue = static_cast(pChgAi->Value * pFwAi->Coeff + pFwAi->Base); + //压入额外发送线程的缓冲区 + std::string tagname = pFwAi->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + + if((nReadNum-1)==i) + { + if( (0!=pFwAi->ResParam2) || (pFwAi->Status&CN_FesValueInvaild)) + { + //最后一个点 + + continue; + } + + } + + + std::string fmtVal=formatToPrecision(AiFloatValue); + PointData pt; + pt.key=std::to_string(pFwAi->ResParam1); + pt.value=fmtVal; + //压入额外发送线程的缓冲区 + m_ptrMQTT->sendSingleSoePublish(m_AppData.deviceTopicMap[deviceName].topic , pt , PublishMethod::VARY , + m_AppData.deviceTopicMap[deviceName].deviceTopic , pChgAi->time); + //m_ptrMQTT->putMessage(m_AppData.deviceTopicMap[deviceName].topic,pt); + + } +} + +void CHccloudmqttsDataProcThread::handleChgDiData() +{ + SFesFwChgDi *pChgDi; + int DiValue; + SFesFwDi *pFwDi; + int nDiCount = m_ptrCFesRtu->GetFwChgDiNum(); + if(0==nDiCount) + { + return; + } + if (m_pChgDiData == NULL) + m_pChgDiData = (SFesFwChgDi*)malloc(nDiCount * sizeof(SFesFwChgDi)); + else + m_pChgDiData = (SFesFwChgDi*)realloc(m_pChgDiData, nDiCount * sizeof(SFesFwChgDi)); + + int retNum = m_ptrCFesRtu->ReadFwChgDi(nDiCount, m_pChgDiData); + for (int i=0;iRemoteNo >= m_ptrCFesRtu->m_MaxFwDiPoints) + continue; + pFwDi = m_ptrCFesRtu->m_pFwDi+ pChgDi->RemoteNo; + + DiValue = pChgDi->Value&0x01; + + //压入额外发送线程的缓冲区 + std::string tagname = pFwDi->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + if((retNum-1)==i) + { + if(pFwDi->Status&CN_FesValueInvaild) + { + //最后一个点 + + continue; + } + + } + + PointData pt; + pt.key=std::to_string(pFwDi->ResParam1); + pt.value=std::to_string(DiValue); + m_ptrMQTT->sendSingleSoePublish(m_AppData.deviceTopicMap[deviceName].topic , pt , PublishMethod::VARY , + m_AppData.deviceTopicMap[deviceName].deviceTopic , pChgDi->time); + //m_ptrMQTT->putMessage(m_AppData.deviceTopicMap[deviceName].topic,pt); + + } + +} + +void CHccloudmqttsDataProcThread::handleChgAccData() +{ + int nAccCount = m_ptrCFesRtu->GetFwChgAccNum(); + if(0==nAccCount) + { + return; + } + SFesFwChgAcc *pChgAcc; + SFesFwAcc *pFwAcc; + if (m_pChgAccData == NULL) + m_pChgAccData = (SFesFwChgAcc*)malloc(nAccCount * sizeof(SFesFwChgAcc)); + else + m_pChgAccData = (SFesFwChgAcc*)realloc(m_pChgAccData, nAccCount * sizeof(SFesFwChgAcc)); + + int nReadNum = m_ptrCFesRtu->ReadFwChgAcc(nAccCount, m_pChgAccData); + + for (int i = 0; i < nReadNum; i++) + { + pChgAcc = m_pChgAccData + i; + if(pChgAcc->RemoteNo >= m_ptrCFesRtu->m_MaxFwAccPoints) + { + continue; + } + pFwAcc = m_ptrCFesRtu->m_pFwAcc + pChgAcc->RemoteNo; + + float AccFloatValue = static_cast(pChgAcc->Value * pFwAcc->Coeff + pFwAcc->Base); + //压入额外发送线程的缓冲区 + std::string tagname = pFwAcc->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + if((nReadNum-1)==i) + { + if(pFwAcc->Status&CN_FesValueInvaild) + { + //最后一台设备 + + continue; + } + + } + std::string fmtVal=formatToPrecision(AccFloatValue); + PointData pt; + pt.key=std::to_string(pFwAcc->ResParam1); + pt.value=fmtVal; + m_ptrMQTT->sendSingleSoePublish(m_AppData.deviceTopicMap[deviceName].topic , pt , PublishMethod::VARY , + m_AppData.deviceTopicMap[deviceName].deviceTopic , pChgAcc->time); + } + +} + +void CHccloudmqttsDataProcThread::handleChgMiData() +{ + int nMiCount = m_ptrCFesRtu->GetFwChgMiNum(); + if(0==nMiCount) + { + return; + } + SFesFwChgMi *pChgMi; + SFesFwMi *pFwMi; + if (m_pChgMiData == NULL) + m_pChgMiData = (SFesFwChgMi*)malloc(nMiCount * sizeof(SFesFwChgMi)); + else + m_pChgMiData = (SFesFwChgMi*)realloc(m_pChgMiData, nMiCount * sizeof(SFesFwChgMi)); + + int nReadNum = m_ptrCFesRtu->ReadFwChgMi(nMiCount, m_pChgMiData); + + for (int i = 0; i < nReadNum; i++) + { + pChgMi = m_pChgMiData + i; + if(pChgMi->RemoteNo >= m_ptrCFesRtu->m_MaxFwMiPoints) + { + continue; + } + pFwMi = m_ptrCFesRtu->m_pFwMi + pChgMi->RemoteNo; + + float MiFloatValue = static_cast(pChgMi->Value * pFwMi->Coeff + pFwMi->Base); + //压入额外发送线程的缓冲区 + std::string tagname = pFwMi->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + + if((nReadNum-1)==i) + { + if(pFwMi->Status&CN_FesValueInvaild) + { + //最后一台设备 + + continue; + } + + } + std::string fmtVal=formatToPrecision(MiFloatValue); + PointData pt; + pt.key=std::to_string(pFwMi->ResParam1); + pt.value=fmtVal; + m_ptrMQTT->sendSingleSoePublish(m_AppData.deviceTopicMap[deviceName].topic , pt , PublishMethod::VARY , + m_AppData.deviceTopicMap[deviceName].deviceTopic , pChgMi->time); + //m_ptrMQTT->putMessage(m_AppData.deviceTopicMap[deviceName].topic,pt); + + } +} + +void CHccloudmqttsDataProcThread::ifTimeToPublish() +{ + //轮询点位看是否需要属于需要发送的主题 + handleAiData(); + handleDiData(); + handleAccData(); + handleMiData(); + triggerPublish(PublishMethod::FULL); + +} + +void CHccloudmqttsDataProcThread::handleAiData() +{ + double fvalue; + SFesFwAi *pFwAi; + for (int aiPoint = 0; aiPoint < m_ptrCFesRtu->m_MaxFwAiPoints; aiPoint++) + { + pFwAi = m_ptrCFesRtu->m_pFwAi + aiPoint; + + std::string tagname = pFwAi->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + if(!m_AppData.deviceTopicMap[deviceName].needPublish) + { + continue; + } + + //特殊处理 + if((m_ptrCFesRtu->m_MaxFwAiPoints-1)==aiPoint) + { + if((0!=pFwAi->ResParam2) ||(pFwAi->Status&CN_FesValueInvaild)) + { + continue; + } + + } + + fvalue = pFwAi->Value*pFwAi->Coeff + pFwAi->Base; + std::string fmtVal=formatToPrecision(fvalue); + PointData pt; + pt.key=std::to_string(pFwAi->ResParam1); + pt.value=fmtVal; + //压入额外发送线程的缓冲区 + m_ptrMQTT->putMessage(m_AppData.deviceTopicMap[deviceName].topic,pt); + + } +} + +void CHccloudmqttsDataProcThread::handleDiData() +{ + SFesFwDi *pFwDi; + int yxbit; + for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxFwDiPoints; diPoint++) + { + pFwDi = m_ptrCFesRtu->m_pFwDi + diPoint; + std::string tagname = pFwDi->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + + if(!m_AppData.deviceTopicMap[deviceName].needPublish) + { + continue; + } + if((m_ptrCFesRtu->m_MaxFwDiPoints-1)==diPoint) + { + if(pFwDi->Status&CN_FesValueInvaild) + { + continue; + } + + } + + yxbit = pFwDi->Value & 0x01; + //压入额外发送线程的缓冲区 + PointData pt; + pt.key=std::to_string(pFwDi->ResParam1); + pt.value=std::to_string(yxbit); + m_ptrMQTT->putMessage(m_AppData.deviceTopicMap[deviceName].topic,pt); + + } +} + +void CHccloudmqttsDataProcThread::handleAccData() +{ + double fvalue; + SFesFwAcc *pFwAcc; + + for (int accPoint = 0; accPoint < m_ptrCFesRtu->m_MaxFwAccPoints; accPoint++) + { + pFwAcc = m_ptrCFesRtu->m_pFwAcc + accPoint; + std::string tagname = pFwAcc->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + + if(!m_AppData.deviceTopicMap[deviceName].needPublish) + { + continue; + } + + if((m_ptrCFesRtu->m_MaxFwAccPoints-1)==accPoint) + { + if(pFwAcc->Status&CN_FesValueInvaild) + { + //最后一个点 + + continue; + } + + } + fvalue = pFwAcc->Value*pFwAcc->Coeff + pFwAcc->Base; + std::string fmtVal=formatToPrecision(fvalue); + //压入额外发送线程的缓冲区 + PointData pt; + pt.key=std::to_string(pFwAcc->ResParam1); + pt.value=fmtVal; + m_ptrMQTT->putMessage(m_AppData.deviceTopicMap[deviceName].topic,pt); + + } +} + +void CHccloudmqttsDataProcThread::handleMiData() +{ + double fvalue; + SFesFwMi *pFwMi; + + for (int miPoint = 0; miPoint < m_ptrCFesRtu->m_MaxFwMiPoints; miPoint++) + { + pFwMi = m_ptrCFesRtu->m_pFwMi + miPoint; + std::string tagname = pFwMi->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + + if(!m_AppData.deviceTopicMap[deviceName].needPublish) + { + continue; + } + if((m_ptrCFesRtu->m_MaxFwMiPoints-1)==miPoint) + { + if(pFwMi->Status&CN_FesValueInvaild) + { + //最后一个点 + + continue; + } + + } + fvalue = pFwMi->Value*pFwMi->Coeff + pFwMi->Base; + std::string fmtVal=formatToPrecision(fvalue); + //压入额外发送线程的缓冲区 + PointData pt; + pt.key=std::to_string(pFwMi->ResParam1); + pt.value=fmtVal; + m_ptrMQTT->putMessage(m_AppData.deviceTopicMap[deviceName].topic,pt); + + + } + +} + +string CHccloudmqttsDataProcThread::getDeviceNameByTag(const string& tagName) +{ + // 查找最后一个点的位置 + std::size_t pos = tagName.rfind('.'); + std::string result="NULL"; + if (pos != std::string::npos) { + // 截取从开头到最后一个点之前的部分 + result = tagName.substr(0, pos); + } + + return result; + +} + + + +std::vector > CHccloudmqttsDataProcThread::parseCSV(const string &filename) +{ + std::vector> data; + char line[1024]; + FILE *fpin; + if ((fpin = fopen(filename.c_str(), "r")) == NULL) + { + LOGERROR("mqtt_hcfy load mqttconfig.csv error %s",filename.c_str()); + return data; + } + + + while (fgets(line, 1024, fpin) != NULL) + { + char *token; + token = strtok(line, ","); + int j = 0; + std::vector row; + while (token != NULL) + { + if (0 == j)//主题 + { + if (strlen(token) <= 0) + break; + row.push_back(token); + } + else if (1 == j)//后台设备标签名 + { + if (strlen(token) <= 0) + break; + row.push_back(token); + } + else if(2 == j)//设备标识 + { + if (strlen(token) <= 0) + break; + row.push_back(token); + } + else if(3 == j)//上传周期 + { + if (strlen(token) <= 0) + break; + row.push_back(token); + } + else + break; + token = strtok(NULL, ","); + j++; + } + + data.push_back(row); + } + fclose(fpin); + + return data; +} + +string CHccloudmqttsDataProcThread::formatToPrecision(double dvalue) +{ + std::ostringstream oss;//保留3位小数 + oss << std::fixed << std::setprecision(3) << dvalue; + std::string result = oss.str(); + size_t found = result.find_last_not_of('0');//去掉多余的0和点 + if (found != std::string::npos) + { + if (result[found] == '.') + result.erase(found); + else + result.erase(found + 1); + } + + return result; +} + +void CHccloudmqttsDataProcThread::initDevicePointCount() +{ + SFesFwAi *pFwAi; + for (int aiPoint = 0; aiPoint < m_ptrCFesRtu->m_MaxFwAiPoints; aiPoint++) + { + pFwAi = m_ptrCFesRtu->m_pFwAi + aiPoint; + + std::string tagname = pFwAi->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + + + if(m_mapDevicePointCount.find(deviceName)!=m_mapDevicePointCount.end()) + { + m_mapDevicePointCount[deviceName]++; + } + else + { + m_mapDevicePointCount[deviceName]=1; + } + } + SFesFwDi *pFwDi; + for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxFwDiPoints; diPoint++) + { + pFwDi = m_ptrCFesRtu->m_pFwDi + diPoint; + std::string tagname = pFwDi->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + + if(m_mapDevicePointCount.find(deviceName)!=m_mapDevicePointCount.end()) + { + m_mapDevicePointCount[deviceName]++; + } + else + { + m_mapDevicePointCount[deviceName]=1; + } + } + + SFesFwAcc *pFwAcc; + for (int accPoint = 0; accPoint < m_ptrCFesRtu->m_MaxFwAccPoints; accPoint++) + { + pFwAcc = m_ptrCFesRtu->m_pFwAcc + accPoint; + std::string tagname = pFwAcc->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + + if(m_mapDevicePointCount.find(deviceName)!=m_mapDevicePointCount.end()) + { + m_mapDevicePointCount[deviceName]++; + } + else + { + m_mapDevicePointCount[deviceName]=1; + } + } + + SFesFwMi *pFwMi; + for (int miPoint = 0; miPoint < m_ptrCFesRtu->m_MaxFwMiPoints; miPoint++) + { + pFwMi = m_ptrCFesRtu->m_pFwMi + miPoint; + std::string tagname = pFwMi->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + + if(m_mapDevicePointCount.find(deviceName)!=m_mapDevicePointCount.end()) + { + m_mapDevicePointCount[deviceName]++; + } + else + { + m_mapDevicePointCount[deviceName]=1; + } + } + + +} + +void CHccloudmqttsDataProcThread::triggerPublish(PublishMethod method) +{ + for(auto it=m_mapDevicePointCount.cbegin();it!=m_mapDevicePointCount.cend();++it) + { + std::string deviceName=it->first; + m_ptrMQTT->topicCanPublish(m_AppData.deviceTopicMap[deviceName].topic,method,m_AppData.deviceTopicMap[deviceName].deviceTopic); + } +} diff --git a/product/src/fes/protocol/mqtt_hcfy/HccloudmqttsDataProcThread.h b/product/src/fes/protocol/mqtt_hcfy/HccloudmqttsDataProcThread.h new file mode 100644 index 00000000..d349e96e --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/HccloudmqttsDataProcThread.h @@ -0,0 +1,145 @@ +#pragma once +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "Md5/Md5.h" +#include +#include // 包含 int64_t 的定义 +#include "MQTTHandleThread.h" + + +using namespace iot_public; + +#define MAX_TOPIC_NUM 1000 + +struct TopicInfo +{ + std::string topic; //topic + int interval; //上送周期(s) + int64_t lastNeedPublish; //最近一次需要上送时间(每次循环检查) + bool needPublish; //是否需要发布标记位(循环检查时间后更新标志位) + std::string deviceTopic; //客户的设备主题 + TopicInfo() { + topic = ""; + interval = 0; + lastNeedPublish = 0; + needPublish = false; + } +}; + +typedef boost::container::map CTopicMap; + +//配置参数 +typedef struct{ + int RtuNo; + int cycCheckFileTime;//周期检查文件时间(s),0即不检查 + int startDelay;//延迟启动上送时间 + std::string topicConfigPath;//主题配置的csv文件 +}SHccloudmqttsAppConfigParam; + +//Hccloudmqtts 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct{ + int RtuNo; + int cycCheckFileTime;//周期检查文件时间(s),0即不检查 + int startDelay;//延迟启动上送时间 + int startTime;//线程的启动时间 + int64 lastReadFileTime;//最近读取文件时间 + std::string topicCfgMd5;//mqtt_topic_cfg文件MD5 + std::string topicConfigPath;//主题配置的csv文件(UTF-8编码) + CTopicMap deviceTopicMap;//[设备标签,主题名] +}SHccloudmqttsAppData; + + + +class CHccloudmqttsDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + CHccloudmqttsDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam, + CMQTTHandleThreadPtr ptrMQTT + + ); + virtual ~CHccloudmqttsDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + CFesBase* m_ptrCFesBase; + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,Hccloudmqtts tcp 每个通道对应一个RTU数据,所以只处理一个rtu。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SHccloudmqttsAppData m_AppData; //内部应用数据结构 + + +private: + int m_timerCount; + int m_timerCountReset; + bool m_bReady;//线程是否准备好 + + + + + + int64 publishTime; + + SFesFwChgAi *m_pChgAiData; + SFesFwChgDi *m_pChgDiData; + SFesFwChgAcc *m_pChgAccData; + SFesFwChgMi *m_pChgMiData; + + CMQTTHandleThreadPtr m_ptrMQTT; + CCmdHandleThreadPtr m_ptrCmd; + boost::container::map m_mapDevicePointCount;// + +private: + + void TimerProcess(); + void HccloudmqttsProcess(); + void GetTopicCfg(); + void ReadTopic(); + //获取MD5 + std::string GetFileMd5(const std::string &file); + + + //是否需要更新本fes的数据 + bool ifNeedUpdateCache(); + void ClearTopicStr(); + + + //数据是否变化和发布 + void ifDataChgAndPublish(); + + void handleChgAiData(); + void handleChgDiData(); + void handleChgAccData(); + void handleChgMiData(); + + //数据到了上送时间 + void ifTimeToPublish(); + void handleAiData(); + void handleDiData(); + void handleAccData(); + void handleMiData(); + + //根据标签名获取设备名 + std::string getDeviceNameByTag(const std::string& tagName); + + //解析csv + std::vector> parseCSV(const std::string& filename); + + //格式化数据 + std::string formatToPrecision(double dvalue); + + void initDevicePointCount(); + + void triggerPublish(PublishMethod method); +}; + +typedef boost::shared_ptr CHccloudmqttsDataProcThreadPtr; diff --git a/product/src/fes/protocol/mqtt_hcfy/MQTTHandleThread.cpp b/product/src/fes/protocol/mqtt_hcfy/MQTTHandleThread.cpp new file mode 100644 index 00000000..448e27c7 --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/MQTTHandleThread.cpp @@ -0,0 +1,418 @@ +#include "MQTTHandleThread.h" +#include "Common.h" +#include "pub_logger_api/logger.h" +#include "rapidjson/document.h" +#include "rapidjson/writer.h" +#include "rapidjson/stringbuffer.h" +#include "pub_utility_api/TimeUtil.h" + +static const int CACHE_SIZE = 50000; //<消息环形缓冲区的大小 +const int gMqttHandleThreadTime = 10; +std::string g_KeyPassword; //私钥密码 +static int password_callback(char* buf, int size, int rwflag, void* userdata) +{ + memcpy(buf, g_KeyPassword.data(), size); + buf[size - 1] = '\0'; + + return (int)strlen(buf); +} + +MQTTHandleThread::MQTTHandleThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecMqttConfig,CCmdHandleThreadPtr ptrCmd) + : CTimerThreadBase("MQTTHandleThread", gMqttHandleThreadTime,0,true),m_buffer(CACHE_SIZE),m_bReady(true) +{ + + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if (m_ptrCFesChan == NULL ) + { + return; + } + + CFesRtuPtr ptrCFesRtu=GetRtuDataByChanData(m_ptrCFesChan); + + bool found = false; + if(vecMqttConfig.size()>0) + { + for (size_t i = 0; i < vecMqttConfig.size(); i++) + { + if(ptrCFesRtu->m_Param.RtuNo == vecMqttConfig[i].RtuNo) + { + //配置 + m_mqttConfig=vecMqttConfig[i]; + found = true; + break; + } + } + } + + m_ptrCmd=ptrCmd; + m_ptrCmd->resume(); + + m_ptrMbCommHandleThread = boost::make_shared(); + m_ptrMbCommHandleThread->resume(); + + if(found) + { + mqttConnect(); + } + else + { + m_bReady=false; + } + +} + +MQTTHandleThread::~MQTTHandleThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + + if(m_mqttClient) + { + m_mqttClient->disconnect(); + delete m_mqttClient; + } + + + LOGDEBUG("MQTTHandleThread::~MQTTHandleThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); + + //释放mosqpp库 + mosqpp::lib_cleanup(); +} + +int MQTTHandleThread::beforeExecute() +{ + return iotSuccess; +} + +void MQTTHandleThread::execute() +{ + if(!m_bReady) + { + LOGERROR("MQTTHandleThread ChanNo=%d has bad and do nothing ", m_ptrCFesChan->m_Param.ChanNo); + return; + } + int rc = m_mqttClient->loop(); + if (rc != MOSQ_ERR_SUCCESS) { + LOGERROR("MQTTHandleThread::execute() ChanNo=%d reconnect %s %d", m_ptrCFesChan->m_Param.ChanNo,strerror(rc),rc); + m_bConnected = false; + int resultConnect=m_mqttClient->reconnect(); + if(resultConnect==MOSQ_ERR_SUCCESS) + { + m_bConnected = true; + } + else + { + LOGERROR("MQTTHandleThread::execute() ChanNo=%d reconnect faild", m_ptrCFesChan->m_Param.ChanNo); + } + } + + SMsg msg; + if(m_mqttClient->get_message(msg)>0) + { + m_ptrCmd->putReceiveMsg(msg); + } + + + DeviceData stMes; + bool bNeedSend=false; + { + boost::mutex::scoped_lock lock(m_bufferMutex); + if(m_buffer.size()==CACHE_SIZE) + { + LOGWARN("MQTTHandleThread.cpp ChanNo=%d data packet is full load ", m_ptrCFesChan->m_Param.ChanNo); + } + + if(m_buffer.size()>0) + { + if(m_bConnected) + { + stMes=m_buffer.front(); + m_buffer.pop_front(); + bNeedSend=true; + } + else + { + LOGWARN("MQTTHandleThread.cpp ChanNo=%d disconnected and data will next time try", m_ptrCFesChan->m_Param.ChanNo); + } + } + else + { + //return; + } + } + + if(bNeedSend) + { + auto strPub=generateJson(stMes); + mqttPublish(stMes.topic,strPub); + } + + SPublishMsg pubmsg; + if( m_ptrMbCommHandleThread->getPublishMsg(pubmsg) > 0 ) + { + mqttPublish(pubmsg.topic, pubmsg.msg); + } +} + +void MQTTHandleThread::beforeQuit() +{ + + LOGDEBUG("MQTTHandleThread::beforeQuit() "); +} + +bool MQTTHandleThread::putMessage(string mqttTopic, PointData data) +{ + if(!m_bReady) + { + LOGERROR("MQTTHandleThread ChanNo=%d topic %s refuse putMessage", m_ptrCFesChan->m_Param.ChanNo,mqttTopic.c_str()); + return false; + } + + + auto it=m_mapTopicPoint.find(mqttTopic); + if(it!=m_mapTopicPoint.end()) + { + vector& vec=m_mapTopicPoint[mqttTopic]; + vec.push_back(data); + } + else + { + vector vec; + vec.push_back(data); + m_mapTopicPoint[mqttTopic]=vec; + } + + return true; +} + +void MQTTHandleThread::topicCanPublish(string mqttTopic, PublishMethod method,std::string deviceTopic) +{ + DeviceData stDD; + stDD.topic=mqttTopic; + if(method==PublishMethod::FULL) + { + stDD.method="FULL"; + }else if(method==PublishMethod::VARY) + { + stDD.method="VARY"; + } + stDD.dId=deviceTopic; + stDD.version="1.0.0"; + stDD.code=1; + stDD.ts=getUTCTimeMsec(); + + auto it=m_mapTopicPoint.find(mqttTopic); + if(it!=m_mapTopicPoint.end()) + { + vector vec=m_mapTopicPoint[mqttTopic]; + stDD.data=vec; + { + boost::mutex::scoped_lock lock(m_bufferMutex); + m_buffer.push_back(stDD); + } + + m_mapTopicPoint.erase(mqttTopic); + } + +} + +void MQTTHandleThread::sendSingleSoePublish(const string &topic, const PointData &pt, PublishMethod method, const string &deviceTopic, int64_t timestamp) +{ + DeviceData stDD; + stDD.data.clear(); + stDD.topic=topic; + if(method==PublishMethod::FULL) + { + stDD.method="FULL"; + }else if(method==PublishMethod::VARY) + { + stDD.method="VARY"; + } + stDD.dId=deviceTopic; + stDD.version="1.0.0"; + stDD.code=1; + stDD.ts=timestamp; + stDD.data.push_back(pt); + boost::mutex::scoped_lock lock(m_bufferMutex); + m_buffer.push_back(stDD); +} + + +void MQTTHandleThread::mqttConnect() +{ + mosqpp::lib_init(); + m_mqttClient=new CMosquitto(m_mqttConfig.ClientId.data()); + m_mqttClient->subscription=m_ptrCmd->getSubscription(); + int ret = 0; + char slog[256]; + memset(slog, 0, 256); + + //不判断服务器地址 + m_mqttClient->tls_insecure_set(1); + + //设置SSL加密(可以考虑去掉) + if (m_mqttConfig.sslFlag == 2) //双向加密 + { + //2022-9-21 lj tls_opt_set需要设置为0,即不验证服务器证书,山东海辰服务器的证书有问题,认证不过 + m_mqttClient->tls_opts_set(0, m_mqttConfig.tls_version.data(), NULL); + if (m_mqttConfig.keyPassword.length() < 1) + m_mqttClient->tls_set(m_mqttConfig.caFile.data(), m_mqttConfig.caPath.data(), m_mqttConfig.certFile.data(), m_mqttConfig.keyFile.data()); + else + { + //更新私钥的密码 + g_KeyPassword = m_mqttConfig.keyPassword; + m_mqttClient->tls_set(m_mqttConfig.caFile.data(), m_mqttConfig.caPath.data(), m_mqttConfig.certFile.data(), m_mqttConfig.keyFile.data(), password_callback); + } + LOGDEBUG("MQTTHandleThread.cpp ChanNo:%d MqttConnect caFile=%s keyPassword=%d!", m_ptrCFesChan->m_Param.ChanNo, m_mqttConfig.caFile.data(), m_mqttConfig.keyPassword.length()); + } + else if (m_mqttConfig.sslFlag == 1) //单向加密 + { + //2022-9-21 lj tls_opt_set需要设置为0,即不验证服务器证书,山东海辰服务器的证书有问题,认证不过 + m_mqttClient->tls_opts_set(0, m_mqttConfig.tls_version.data(), NULL); + m_mqttClient->tls_set(m_mqttConfig.caFile.data()); + } + + if (m_mqttConfig.QoS) + m_mqttClient->message_retry_set(3); + + //设置用户名和密码 + if (m_mqttConfig.PasswordFlag) + m_mqttClient->username_pw_set(m_mqttConfig.UserName.data(), m_mqttConfig.Password.data()); + + + std::string serverIp=m_ptrCFesChan->m_Param.NetRoute[0].NetDesc; + int port=m_ptrCFesChan->m_Param.NetRoute[0].PortNo; + ret = m_mqttClient->connect(serverIp.data(), port, m_mqttConfig.KeepAlive); + if (ret != MOSQ_ERR_SUCCESS) + { + sprintf_s(slog, sizeof(slog),"MQTT %s:%d 连接失败!", serverIp.data(),port); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGERROR("MQTTHandleThread.cpp MQTT %s:%d连接失败!", serverIp.data(), port); + return; + } + + m_bConnected=true; + + sprintf_s(slog, sizeof(slog),"MQTT %s:%d 连接成功!", serverIp.data(), port); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog,CN_SFesSimComFrameTypeSend); + LOGINFO("MQTTHandleThread.cpp ChanNo:%d MQTT %s:%d连接成功!", m_ptrCFesChan->m_Param.ChanNo, serverIp.data(), port); + +} + +bool MQTTHandleThread::mqttPublish(const std::string& mqttTopic, const std::string& mqttPayload) +{ + + boost::mutex::scoped_lock lock(m_publishMutex); + //主题和内容为空 + if ((mqttTopic.length() < 1) || (mqttPayload.length() < 1)) + return true; + + //发布主题数据 + int rc = m_mqttClient->publish(NULL, mqttTopic.data(), (int)mqttPayload.length(), mqttPayload.data(), m_mqttConfig.QoS, m_mqttConfig.Retain); + if (rc != MOSQ_ERR_SUCCESS) + { + std::string msg="MQTT 上抛失败 "+mqttTopic; + LOGDEBUG("MQTTHandleThread.cpp publish-err ChanNo:%d %s:%d %s", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo,msg.data()); +// m_mqttClient->disconnect(); +// m_bConnected = false; + ShowChanData(msg); + return false; + } + + if (m_mqttConfig.WillFlag > 0) + { + m_mqttClient->will_set(mqttTopic.data(), (int)mqttPayload.length(), mqttPayload.data(), m_mqttConfig.WillQos, m_mqttConfig.Retain); + } + + return true; +} + +bool MQTTHandleThread::mqttSubscribe(string subTopic) +{ + bool ret = false; + int rc = m_mqttClient->subscribe(NULL, subTopic.data()); + if( MOSQ_ERR_SUCCESS != rc) + { + LOGINFO("subscribeRc != MOSQ_ERR_SUCCESS Error: %s" , mosquitto_strerror(rc)); + }else + { + ret = true; + } + + return ret; +} + +bool MQTTHandleThread::mqttUnSubscribe(string unTopic) +{ + bool ret = false; + int rc = m_mqttClient->unsubscribe(NULL, unTopic.data()); + if( MOSQ_ERR_SUCCESS != rc) + { + LOGINFO("unsubscribeRc != MOSQ_ERR_SUCCESS Error: %s" , mosquitto_strerror(rc)); + }else + { + ret = true; + } + + return ret; +} + +std::string MQTTHandleThread::generateJson(const DeviceData &deviceData) +{ + //生成调整为使用rapidjson生成,格式为紧凑格式 + rapidjson::StringBuffer s; + rapidjson::Writer writer(s); + + writer.StartObject(); //起始 + writer.Key("method"); + writer.String(deviceData.method.c_str()); + writer.Key("dId"); + writer.String(deviceData.dId.c_str()); + writer.Key("msgId"); + writer.String(deviceData.msgId.c_str()); + writer.Key("version"); + writer.String(deviceData.version.c_str()); + writer.Key("ts"); + writer.Int64(deviceData.ts); + writer.Key("code"); + writer.Int(deviceData.code); + + writer.Key("data"); + writer.StartObject(); + for(size_t i = 0; i < deviceData.data.size(); i++) + { + const PointData &pd = deviceData.data.at(i); + writer.Key(pd.key.c_str()); + writer.String(pd.value.c_str()); + } + + writer.EndObject(); //< 结束写入测点数组 + writer.EndObject(); //结束 + return s.GetString(); +} + +void MQTTHandleThread::ShowChanData(const string &msgData) +{ + + + const char* host = m_ptrCFesChan->m_Param.NetRoute[0].NetDesc; + + // 使用 snprintf 来计算格式化后字符串的大小(不包括 null 终止符) + size_t neededSize = snprintf(nullptr, 0, "mqtt host: %s, content: %s", host, msgData.c_str()) + 1; // +1 for null terminator + + // 为字符串分配合适大小的缓冲区 + char* slog = new char[neededSize]; // 动态分配缓冲区 + + // 使用 sprintf_s 填充数据 + sprintf_s(slog, neededSize, "mqtt host: %s, content: %s", host, msgData.c_str()); + + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + + // 使用完后释放动态分配的内存 + delete[] slog; +} + + diff --git a/product/src/fes/protocol/mqtt_hcfy/MQTTHandleThread.h b/product/src/fes/protocol/mqtt_hcfy/MQTTHandleThread.h new file mode 100644 index 00000000..f11a8d65 --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/MQTTHandleThread.h @@ -0,0 +1,121 @@ +#pragma once +#include "CMosquitto.h" +#include "pub_utility_api/TimerThreadBase.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "boost/circular_buffer.hpp" +#include +#include +#include + +#include "CmdHandleThread.h" +#include "CMbCommHandleThread.h" + +typedef struct{ + int RtuNo; + int PasswordFlag; + std::string ClientId; //客户端ID + std::string UserName; //用户名 + std::string Password; //密码 + + int KeepAlive; //心跳检测时间间隔 + bool Retain; //MQTT服务器是否保持消息 默认0 + int QoS; //服务质量 默认1 + int WillFlag; //遗愿消息标志 默认1 + int WillQos; //遗愿消息服务质量 默认1 + + //SSL加密配置参数 + int sslFlag; //SSL加密标志 0不加密 1单向加密 2双向加密 + std::string tls_version; //加密协议版本 + std::string caPath; //加密文件路径 + std::string caFile; //CA文件名 + std::string certFile; //证书文件名 + std::string keyFile; //私钥文件名 + std::string keyPassword; //私钥密码 + +}SHccloudMqttsConfig; + +struct PointData { + std::string key; + std::string value; +}; + +typedef struct { + std::string topic;//主题,不参与序列化 + std::string method; + std::string dId;//设备id + std::string msgId; + std::string version; + int64_t ts; + int code; + std::vector data; +}DeviceData; + + + + + +typedef boost::container::map, std::less, std::allocator>>> TopicMap; + +//typedef boost::container::map> TopicMap; + +class MQTTHandleThread: public iot_public::CTimerThreadBase,CProtocolBase +{ +public: + MQTTHandleThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector mqttConfig,CCmdHandleThreadPtr ptrCmd); + virtual ~MQTTHandleThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + //放入测点数据以待发送 + bool putMessage(std::string mqttTopic,PointData data); + + //topic的数据已经集齐可以发送 + void topicCanPublish(std::string mqttTopic,PublishMethod method,std::string deviceTopic); + + //单个变化数据信息发送 + void sendSingleSoePublish(const std::string& topic, const PointData& pt, + PublishMethod method, const std::string& deviceTopic, + int64_t timestamp); + + bool mqttPublish(const std::string& mqttTopic, const std::string& mqttPayload); + + bool mqttSubscribe(std::string subTopic); + + bool mqttUnSubscribe(std::string unTopic); + +private: + void mqttConnect(); + + std::string generateJson(const DeviceData& deviceData); + + void ShowChanData(const std::string& msgData); + +private: + CMosquitto *m_mqttClient; + SHccloudMqttsConfig m_mqttConfig; + std::atomic m_bConnected{false}; + CFesChanPtr m_ptrCFesChan; + CFesBase* m_ptrCFesBase; + boost::mutex m_bufferMutex;//消息锁 + boost::circular_buffer m_buffer; //待发送消息缓冲区 + TopicMap m_mapTopicPoint;//测点数据暂存区 + bool m_bReady;//线程是否准备好 + boost::mutex m_publishMutex;//发布锁 + CCmdHandleThreadPtr m_ptrCmd; + CMbCommHandleThreadPtr m_ptrMbCommHandleThread; +}; + +typedef boost::shared_ptr CMQTTHandleThreadPtr; + + diff --git a/product/src/fes/protocol/mqtt_hcfy/Md5/Md5.cpp b/product/src/fes/protocol/mqtt_hcfy/Md5/Md5.cpp new file mode 100644 index 00000000..dd4f18ef --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/Md5/Md5.cpp @@ -0,0 +1,372 @@ +#include "Md5.h" + +//using namespace std; + +/* Constants for MD5Transform routine. */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + + +/* F, G, H and I are basic MD5 functions. +*/ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. +*/ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. +*/ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} + + +const byte MD5::PADDING[64] = { 0x80 }; +const char MD5::HEX[16] = +{ + '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f' +}; + +/* Default construct. */ +MD5::MD5() +{ + + reset(); +} + +/* Construct a MD5 object with a input buffer. */ +MD5::MD5(const void *input, size_t length) +{ + reset(); + update(input, length); +} + +/* Construct a MD5 object with a string. */ +MD5::MD5(const string &str) +{ + reset(); + update(str); +} + +/* Construct a MD5 object with a file. */ +MD5::MD5(ifstream &in) +{ + reset(); + update(in); +} + +/* Return the message-digest */ +const byte *MD5::digest() +{ + if (!_finished) + { + _finished = true; + final(); + } + return _digest; +} + +/* Reset the calculate state */ +void MD5::reset() +{ + + _finished = false; + /* reset number of bits. */ + _count[0] = _count[1] = 0; + /* Load magic initialization constants. */ + _state[0] = 0x67452301; + _state[1] = 0xefcdab89; + _state[2] = 0x98badcfe; + _state[3] = 0x10325476; +} + +/* Updating the context with a input buffer. */ +void MD5::update(const void *input, size_t length) +{ + update((const byte *)input, length); +} + +/* Updating the context with a string. */ +void MD5::update(const string &str) +{ + update((const byte *)str.c_str(), str.length()); +} + +/* Updating the context with a file. */ +void MD5::update(ifstream &in) +{ + + if (!in) + { + return; + } + + const size_t BUFFER_SIZE = 1024; + std::streamsize length; + char buffer[BUFFER_SIZE]; + while (!in.eof()) + { + in.read(buffer, BUFFER_SIZE); + length = in.gcount(); + if (length > 0) + { + update(buffer, length); + } + } + in.close(); +} + +/* MD5 block update operation. Continues an MD5 message-digest +operation, processing another message block, and updating the +context. +*/ +void MD5::update(const byte *input, size_t length) +{ + + uint32 i, index, partLen; + + _finished = false; + + /* Compute number of bytes mod 64 */ + index = (uint32)((_count[0] >> 3) & 0x3f); + + /* update number of bits */ + if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) + { + _count[1]++; + } + _count[1] += ((uint32)length >> 29); + + partLen = 64 - index; + + /* transform as many times as possible. */ + if (length >= partLen) + { + + memcpy(&_buffer[index], input, partLen); + transform(_buffer); + + for (i = partLen; i + 63 < length; i += 64) + { + transform(&input[i]); + } + index = 0; + + } + else + { + i = 0; + } + + /* Buffer remaining input */ + memcpy(&_buffer[index], &input[i], length - i); +} + +/* MD5 finalization. Ends an MD5 message-_digest operation, writing the +the message _digest and zeroizing the context. +*/ +void MD5::final() +{ + + byte bits[8]; + uint32 oldState[4]; + uint32 oldCount[2]; + uint32 index, padLen; + + /* Save current state and count. */ + memcpy(oldState, _state, 16); + memcpy(oldCount, _count, 8); + + /* Save number of bits */ + encode(_count, bits, 8); + + /* Pad out to 56 mod 64. */ + index = (uint32)((_count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + update(PADDING, padLen); + + /* Append length (before padding) */ + update(bits, 8); + + /* Store state in digest */ + encode(_state, _digest, 16); + + /* Restore current state and count. */ + memcpy(_state, oldState, 16); + memcpy(_count, oldCount, 8); +} + +/* MD5 basic transformation. Transforms _state based on block. */ +void MD5::transform(const byte block[64]) +{ + + uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16]; + + decode(block, x, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + _state[0] += a; + _state[1] += b; + _state[2] += c; + _state[3] += d; +} + +/* Encodes input (ulong) into output (byte). Assumes length is +a multiple of 4. +*/ +void MD5::encode(const uint32 *input, byte *output, size_t length) +{ + + for (size_t i = 0, j = 0; j < length; i++, j += 4) + { + output[j] = (byte)(input[i] & 0xff); + output[j + 1] = (byte)((input[i] >> 8) & 0xff); + output[j + 2] = (byte)((input[i] >> 16) & 0xff); + output[j + 3] = (byte)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (byte) into output (ulong). Assumes length is +a multiple of 4. +*/ +void MD5::decode(const byte *input, uint32 *output, size_t length) +{ + + for (size_t i = 0, j = 0; j < length; i++, j += 4) + { + output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) | + (((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24); + } +} + +/* Convert byte array to hex string. */ +string MD5::bytesToHexString(const byte *input, size_t length) +{ + string str; + str.reserve(length << 1); + for (size_t i = 0; i < length; i++) + { + int t = input[i]; + int a = t / 16; + int b = t % 16; + str.append(1, HEX[a]); + str.append(1, HEX[b]); + } + return str; +} + +/* Convert digest to string value */ +string MD5::toString() +{ + return bytesToHexString(digest(), 16); +} diff --git a/product/src/fes/protocol/mqtt_hcfy/Md5/Md5.h b/product/src/fes/protocol/mqtt_hcfy/Md5/Md5.h new file mode 100644 index 00000000..3be512ae --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/Md5/Md5.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include + +/* Type define */ +typedef unsigned char byte; +typedef unsigned int uint32; + +using std::string; +using std::ifstream; + +/* MD5 declaration. */ +class MD5 +{ +public: + MD5(); + MD5(const void *input, size_t length); + MD5(const string &str); + MD5(ifstream &in); + void update(const void *input, size_t length); + void update(const string &str); + void update(ifstream &in); + const byte *digest(); + string toString(); + void reset(); +private: + void update(const byte *input, size_t length); + void final(); + void transform(const byte block[64]); + void encode(const uint32 *input, byte *output, size_t length); + void decode(const byte *input, uint32 *output, size_t length); + string bytesToHexString(const byte *input, size_t length); + + /* class uncopyable */ + MD5(const MD5 &); + MD5 &operator=(const MD5 &); +private: + uint32 _state[4]; /* state (ABCD) */ + uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */ + byte _buffer[64]; /* input buffer */ + byte _digest[16]; /* message digest */ + bool _finished; /* calculate finished ? */ + + static const byte PADDING[64]; /* padding for calculate */ + static const char HEX[16]; + static const size_t BUFFER_SIZE; + +}; diff --git a/product/src/fes/protocol/mqtt_hcfy/mosquitto.h b/product/src/fes/protocol/mqtt_hcfy/mosquitto.h new file mode 100644 index 00000000..83fb350f --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/mosquitto.h @@ -0,0 +1,3084 @@ +/* +Copyright (c) 2010-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_H +#define MOSQUITTO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(WIN32) && !defined(WITH_BROKER) && !defined(LIBMOSQUITTO_STATIC) +# ifdef libmosquitto_EXPORTS +# define libmosq_EXPORT __declspec(dllexport) +# else +# define libmosq_EXPORT __declspec(dllimport) +# endif +#else +# define libmosq_EXPORT +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# ifndef __cplusplus +# define bool char +# define true 1 +# define false 0 +# endif +#else +# ifndef __cplusplus +# include +# endif +#endif + +#include +#include + +#define LIBMOSQUITTO_MAJOR 1 +#define LIBMOSQUITTO_MINOR 6 +#define LIBMOSQUITTO_REVISION 10 +/* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ +#define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION) + +/* Log types */ +#define MOSQ_LOG_NONE 0 +#define MOSQ_LOG_INFO (1<<0) +#define MOSQ_LOG_NOTICE (1<<1) +#define MOSQ_LOG_WARNING (1<<2) +#define MOSQ_LOG_ERR (1<<3) +#define MOSQ_LOG_DEBUG (1<<4) +#define MOSQ_LOG_SUBSCRIBE (1<<5) +#define MOSQ_LOG_UNSUBSCRIBE (1<<6) +#define MOSQ_LOG_WEBSOCKETS (1<<7) +#define MOSQ_LOG_INTERNAL 0x80000000U +#define MOSQ_LOG_ALL 0xFFFFFFFFU + +/* Error values */ +enum mosq_err_t { + MOSQ_ERR_AUTH_CONTINUE = -4, + MOSQ_ERR_NO_SUBSCRIBERS = -3, + MOSQ_ERR_SUB_EXISTS = -2, + MOSQ_ERR_CONN_PENDING = -1, + MOSQ_ERR_SUCCESS = 0, + MOSQ_ERR_NOMEM = 1, + MOSQ_ERR_PROTOCOL = 2, + MOSQ_ERR_INVAL = 3, + MOSQ_ERR_NO_CONN = 4, + MOSQ_ERR_CONN_REFUSED = 5, + MOSQ_ERR_NOT_FOUND = 6, + MOSQ_ERR_CONN_LOST = 7, + MOSQ_ERR_TLS = 8, + MOSQ_ERR_PAYLOAD_SIZE = 9, + MOSQ_ERR_NOT_SUPPORTED = 10, + MOSQ_ERR_AUTH = 11, + MOSQ_ERR_ACL_DENIED = 12, + MOSQ_ERR_UNKNOWN = 13, + MOSQ_ERR_ERRNO = 14, + MOSQ_ERR_EAI = 15, + MOSQ_ERR_PROXY = 16, + MOSQ_ERR_PLUGIN_DEFER = 17, + MOSQ_ERR_MALFORMED_UTF8 = 18, + MOSQ_ERR_KEEPALIVE = 19, + MOSQ_ERR_LOOKUP = 20, + MOSQ_ERR_MALFORMED_PACKET = 21, + MOSQ_ERR_DUPLICATE_PROPERTY = 22, + MOSQ_ERR_TLS_HANDSHAKE = 23, + MOSQ_ERR_QOS_NOT_SUPPORTED = 24, + MOSQ_ERR_OVERSIZE_PACKET = 25, + MOSQ_ERR_OCSP = 26, +}; + +/* Option values */ +enum mosq_opt_t { + MOSQ_OPT_PROTOCOL_VERSION = 1, + MOSQ_OPT_SSL_CTX = 2, + MOSQ_OPT_SSL_CTX_WITH_DEFAULTS = 3, + MOSQ_OPT_RECEIVE_MAXIMUM = 4, + MOSQ_OPT_SEND_MAXIMUM = 5, + MOSQ_OPT_TLS_KEYFORM = 6, + MOSQ_OPT_TLS_ENGINE = 7, + MOSQ_OPT_TLS_ENGINE_KPASS_SHA1 = 8, + MOSQ_OPT_TLS_OCSP_REQUIRED = 9, + MOSQ_OPT_TLS_ALPN = 10, +}; + + +/* MQTT specification restricts client ids to a maximum of 23 characters */ +#define MOSQ_MQTT_ID_MAX_LENGTH 23 + +#define MQTT_PROTOCOL_V31 3 +#define MQTT_PROTOCOL_V311 4 +#define MQTT_PROTOCOL_V5 5 + +struct mosquitto_message{ + int mid; + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct mosquitto; +typedef struct mqtt5__property mosquitto_property; + +/* + * Topic: Threads + * libmosquitto provides thread safe operation, with the exception of + * which is not thread safe. + * + * If your application uses threads you must use to + * tell the library this is the case, otherwise it makes some optimisations + * for the single threaded case that may result in unexpected behaviour for + * the multi threaded case. + */ +/*************************************************** + * Important note + * + * The following functions that deal with network operations will return + * MOSQ_ERR_SUCCESS on success, but this does not mean that the operation has + * taken place. An attempt will be made to write the network data, but if the + * socket is not available for writing at that time then the packet will not be + * sent. To ensure the packet is sent, call mosquitto_loop() (which must also + * be called to process incoming network data). + * This is especially important when disconnecting a client that has a will. If + * the broker does not receive the DISCONNECT command, it will assume that the + * client has disconnected unexpectedly and send the will. + * + * mosquitto_connect() + * mosquitto_disconnect() + * mosquitto_subscribe() + * mosquitto_unsubscribe() + * mosquitto_publish() + ***************************************************/ + + +/* ====================================================================== + * + * Section: Library version, init, and cleanup + * + * ====================================================================== */ +/* + * Function: mosquitto_lib_version + * + * Can be used to obtain version information for the mosquitto library. + * This allows the application to compare the library version against the + * version it was compiled against by using the LIBMOSQUITTO_MAJOR, + * LIBMOSQUITTO_MINOR and LIBMOSQUITTO_REVISION defines. + * + * Parameters: + * major - an integer pointer. If not NULL, the major version of the + * library will be returned in this variable. + * minor - an integer pointer. If not NULL, the minor version of the + * library will be returned in this variable. + * revision - an integer pointer. If not NULL, the revision of the library will + * be returned in this variable. + * + * Returns: + * LIBMOSQUITTO_VERSION_NUMBER, which is a unique number based on the major, + * minor and revision values. + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_version(int *major, int *minor, int *revision); + +/* + * Function: mosquitto_lib_init + * + * Must be called before any other mosquitto functions. + * + * This function is *not* thread safe. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_UNKNOWN - on Windows, if sockets couldn't be initialized. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_init(void); + +/* + * Function: mosquitto_lib_cleanup + * + * Call to free resources associated with the library. + * + * Returns: + * MOSQ_ERR_SUCCESS - always + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_cleanup(void); + + +/* ====================================================================== + * + * Section: Client creation, destruction, and reinitialisation + * + * ====================================================================== */ +/* + * Function: mosquitto_new + * + * Create a new mosquitto client instance. + * + * Parameters: + * id - String to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Note that a client will never discard its own outgoing + * messages on disconnect. Calling or + * will cause the messages to be resent. + * Use to reset a client to its + * original state. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * Pointer to a struct mosquitto on success. + * NULL on failure. Interrogate errno to determine the cause for the failure: + * - ENOMEM on out of memory. + * - EINVAL on invalid input parameters. + * + * See Also: + * , , + */ +libmosq_EXPORT struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj); + +/* + * Function: mosquitto_destroy + * + * Use to free memory associated with a mosquitto client instance. + * + * Parameters: + * mosq - a struct mosquitto pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_destroy(struct mosquitto *mosq); + +/* + * Function: mosquitto_reinitialise + * + * This function allows an existing mosquitto client to be reused. Call on a + * mosquitto instance to close any open network connections, free memory + * and reinitialise the client with the new parameters. The end result is the + * same as the output of . + * + * Parameters: + * mosq - a valid mosquitto instance. + * id - string to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *obj); + + +/* ====================================================================== + * + * Section: Will + * + * ====================================================================== */ +/* + * Function: mosquitto_will_set + * + * Configure will information for a mosquitto instance. By default, clients do + * not have a will. This must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + */ +libmosq_EXPORT int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + +/* + * Function: mosquitto_will_set_v5 + * + * Configure will information for a mosquitto instance, with attached + * properties. By default, clients do not have a will. This must be called + * before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * properties - list of MQTT 5 properties. Can be NULL. On success only, the + * property list becomes the property of libmosquitto once this + * function is called and will be freed by the library. The + * property list must be freed by the application on error. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + * MOSQ_ERR_NOT_SUPPORTED - if properties is not NULL and the client is not + * using MQTT v5 + * MOSQ_ERR_PROTOCOL - if a property is invalid for use with wills. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + */ +libmosq_EXPORT int mosquitto_will_set_v5(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties); + +/* + * Function: mosquitto_will_clear + * + * Remove a previously configured will. This must be called before calling + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_will_clear(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Username and password + * + * ====================================================================== */ +/* + * Function: mosquitto_username_pw_set + * + * Configure username and password for a mosquitto instance. By default, no + * username or password will be sent. For v3.1 and v3.1.1 clients, if username + * is NULL, the password argument is ignored. + * + * This is must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * username - the username to send as a string, or NULL to disable + * authentication. + * password - the password to send as a string. Set to NULL when username is + * valid in order to send just a username. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password); + + +/* ====================================================================== + * + * Section: Connecting, reconnecting, disconnecting + * + * ====================================================================== */ +/* + * Function: mosquitto_connect + * + * Connect to an MQTT broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter. Use this function + * if you need to restrict network communication over a particular interface. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_bind_v5 + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter and MQTT v5 + * properties. Use this function if you need to restrict network communication + * over a particular interface. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * properties - the MQTT 5 properties for the connect (not for the Will). + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with CONNECT. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_v5(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, const mosquitto_property *properties); + +/* + * Function: mosquitto_connect_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * This extends the functionality of by adding the + * bind_address parameter. Use this function if you need to restrict network + * communication over a particular interface. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_async(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_srv + * + * Connect to an MQTT broker. + * + * If you set `host` to `example.com`, then this call will attempt to retrieve + * the DNS SRV record for `_secure-mqtt._tcp.example.com` or + * `_mqtt._tcp.example.com` to discover which actual host to connect to. + * + * DNS SRV support is not usually compiled in to libmosquitto, use of this call + * is not recommended. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname to search for an SRV record. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_srv(struct mosquitto *mosq, const char *host, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_reconnect + * + * Reconnect to a broker. + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * call. It must not be called before + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_reconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_reconnect_async + * + * Reconnect to a broker. Non blocking version of . + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * or calls. It must not be + * called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reconnect_async(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect + * + * Disconnect from the broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + */ +libmosq_EXPORT int mosquitto_disconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect_v5 + * + * Disconnect from the broker, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * reason_code - the disconnect reason code. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with DISCONNECT. + */ +libmosq_EXPORT int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Publishing, subscribing, unsubscribing + * + * ====================================================================== */ +/* + * Function: mosquitto_publish + * + * Publish a message on a given topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + + +/* + * Function: mosquitto_publish_v5 + * + * Publish a message on a given topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Requires the mosquitto instance to be connected with MQTT 5. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with PUBLISH. + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_publish_v5( + struct mosquitto *mosq, + int *mid, + const char *topic, + int payloadlen, + const void *payload, + int qos, + bool retain, + const mosquitto_property *properties); + + +/* + * Function: mosquitto_subscribe + * + * Subscribe to a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos); + +/* + * Function: mosquitto_subscribe_v5 + * + * Subscribe to a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Requires the mosquitto instance to be connected with MQTT 5. + * + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * options - options to apply to this subscription, OR'd together. Set to 0 to + * use the default options, otherwise choose from the list: + * MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client + * publishes to a topic to which it is subscribed, the + * broker will not publish the message back to the + * client. + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages + * published for this subscription will keep the + * retain flag as was set by the publishing client. + * The default behaviour without this option set has + * the retain flag indicating whether a message is + * fresh/stale. + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set, + * pre-existing retained messages are sent as soon as + * the subscription is made, even if the subscription + * already exists. This is the default behaviour, so + * it is not necessary to set this option. + * MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing + * retained messages for this subscription will be + * sent when the subscription is made, but only if the + * subscription does not already exist. + * MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set, + * pre-existing retained messages will never be sent + * for this subscription. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with SUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_subscribe_multiple + * + * Subscribe to multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of subscriptions to be made + * sub - array of sub_count pointers, each pointing to a subscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * qos - the requested Quality of Service for each subscription. + * options - options to apply to this subscription, OR'd together. This + * argument is not used for MQTT v3 susbcriptions. Set to 0 to use + * the default options, otherwise choose from the list: + * MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client + * publishes to a topic to which it is subscribed, the + * broker will not publish the message back to the + * client. + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages + * published for this subscription will keep the + * retain flag as was set by the publishing client. + * The default behaviour without this option set has + * the retain flag indicating whether a message is + * fresh/stale. + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set, + * pre-existing retained messages are sent as soon as + * the subscription is made, even if the subscription + * already exists. This is the default behaviour, so + * it is not necessary to set this option. + * MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing + * retained messages for this subscription will be + * sent when the subscription is made, but only if the + * subscription does not already exist. + * MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set, + * pre-existing retained messages will never be sent + * for this subscription. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe + * + * Unsubscribe from a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub); + +/* + * Function: mosquitto_unsubscribe_v5 + * + * Unsubscribe from a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with UNSUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe_multiple + * + * Unsubscribe from multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of unsubscriptions to be made + * sub - array of sub_count pointers, each pointing to an unsubscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Struct mosquitto_message helper functions + * + * ====================================================================== */ +/* + * Function: mosquitto_message_copy + * + * Copy the contents of a mosquitto message to another message. + * Useful for preserving a message received in the on_message() callback. + * + * Parameters: + * dst - a pointer to a valid mosquitto_message struct to copy to. + * src - a pointer to a valid mosquitto_message struct to copy from. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src); + +/* + * Function: mosquitto_message_free + * + * Completely free a mosquitto_message struct. + * + * Parameters: + * message - pointer to a mosquitto_message pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_message_free(struct mosquitto_message **message); + +/* + * Function: mosquitto_message_free_contents + * + * Free a mosquitto_message struct contents, leaving the struct unaffected. + * + * Parameters: + * message - pointer to a mosquitto_message struct to free its contents. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_message_free_contents(struct mosquitto_message *message); + + +/* ====================================================================== + * + * Section: Network loop (managed by libmosquitto) + * + * The internal network loop must be called at a regular interval. The two + * recommended approaches are to use either or + * . is a blocking call and is + * suitable for the situation where you only want to handle incoming messages + * in callbacks. is a non-blocking call, it creates a + * separate thread to run the loop for you. Use this function when you have + * other tasks you need to run at the same time as the MQTT client, e.g. + * reading data from a sensor. + * + * ====================================================================== */ + +/* + * Function: mosquitto_loop_forever + * + * This function call loop() for you in an infinite blocking loop. It is useful + * for the case where you only want to run the MQTT client loop in your + * program. + * + * It handles reconnecting in case server connection is lost. If you call + * mosquitto_disconnect() in a callback it will return. + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets); + +/* + * Function: mosquitto_loop_start + * + * This is part of the threaded client interface. Call this once to start a new + * thread to process network traffic. This provides an alternative to + * repeatedly calling yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_start(struct mosquitto *mosq); + +/* + * Function: mosquitto_loop_stop + * + * This is part of the threaded client interface. Call this once to stop the + * network thread previously created with . This call + * will block until the network thread finishes. For the network thread to end, + * you must have previously called or have set the force + * parameter to true. + * + * Parameters: + * mosq - a valid mosquitto instance. + * force - set to true to force thread cancellation. If false, + * must have already been called. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_stop(struct mosquitto *mosq, bool force); + +/* + * Function: mosquitto_loop + * + * The main network loop for the client. This must be called frequently + * to keep communications between the client and broker working. This is + * carried out by and , which + * are the recommended ways of handling the network loop. You may also use this + * function if you wish. It must not be called inside a callback. + * + * If incoming data is present it will then be processed. Outgoing commands, + * from e.g. , are normally sent immediately that their + * function is called, but this is not always possible. will + * also attempt to send any remaining outgoing messages, which also includes + * commands that are part of the flow for messages with QoS>0. + * + * This calls select() to monitor the client network socket. If you want to + * integrate mosquitto client operation with your own select() call, use + * , , and + * . + * + * Threads: + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets); + +/* ====================================================================== + * + * Section: Network loop (for use in other event loops) + * + * ====================================================================== */ +/* + * Function: mosquitto_loop_read + * + * Carry out network read operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_read(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_write + * + * Carry out network write operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_write(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_misc + * + * Carry out miscellaneous operations required as part of the network loop. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * This function deals with handling PINGs and checking whether messages need + * to be retried, so should be called fairly frequently, around once per second + * is sufficient. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_misc(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Network loop (helper functions) + * + * ====================================================================== */ +/* + * Function: mosquitto_socket + * + * Return the socket handle for a mosquitto instance. Useful if you want to + * include a mosquitto client in your own select() calls. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * The socket for the mosquitto client or -1 on failure. + */ +libmosq_EXPORT int mosquitto_socket(struct mosquitto *mosq); + +/* + * Function: mosquitto_want_write + * + * Returns true if there is data ready to be written on the socket. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * See Also: + * , , + */ +libmosq_EXPORT bool mosquitto_want_write(struct mosquitto *mosq); + +/* + * Function: mosquitto_threaded_set + * + * Used to tell the library that your application is using threads, but not + * using . The library operates slightly differently when + * not in threaded mode in order to simplify its operation. If you are managing + * your own threads and do not use this function you will experience crashes + * due to race conditions. + * + * When using , this is set automatically. + * + * Parameters: + * mosq - a valid mosquitto instance. + * threaded - true if your application is using threads, false otherwise. + */ +libmosq_EXPORT int mosquitto_threaded_set(struct mosquitto *mosq, bool threaded); + + +/* ====================================================================== + * + * Section: Client options + * + * ====================================================================== */ +/* + * Function: mosquitto_opts_set + * + * Used to set options for the client. + * + * This function is deprecated, the replacement and + * functions should be used instead. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_PROTOCOL_VERSION + * Value must be an int, set to either MQTT_PROTOCOL_V31 or + * MQTT_PROTOCOL_V311. Must be set before the client connects. + * Defaults to MQTT_PROTOCOL_V31. + * + * MOSQ_OPT_SSL_CTX + * Pass an openssl SSL_CTX to be used when creating TLS connections + * rather than libmosquitto creating its own. This must be called + * before connecting to have any effect. If you use this option, the + * onus is on you to ensure that you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS + * Value must be an int set to 1 or 0. If set to 1, then the user + * specified SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the + * default options applied to it. This means that you only need to + * change the values that are relevant to you. If you use this + * option then you must configure the TLS options as normal, i.e. + * you should use to configure the cafile/capath + * as a minimum. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + +/* + * Function: mosquitto_int_option + * + * Used to set integer options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_PROTOCOL_VERSION - + * Value must be set to either MQTT_PROTOCOL_V31, + * MQTT_PROTOCOL_V311, or MQTT_PROTOCOL_V5. Must be set before the + * client connects. Defaults to MQTT_PROTOCOL_V311. + * + * MOSQ_OPT_RECEIVE_MAXIMUM - + * Value can be set between 1 and 65535 inclusive, and represents + * the maximum number of incoming QoS 1 and QoS 2 messages that this + * client wants to process at once. Defaults to 20. This option is + * not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the MQTT_PROP_RECEIVE_MAXIMUM property is in the + * proplist passed to mosquitto_connect_v5(), then that property + * will override this option. Using this option is the recommended + * method however. + * + * MOSQ_OPT_SEND_MAXIMUM - + * Value can be set between 1 and 65535 inclusive, and represents + * the maximum number of outgoing QoS 1 and QoS 2 messages that this + * client will attempt to have "in flight" at once. Defaults to 20. + * This option is not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the broker being connected to sends a + * MQTT_PROP_RECEIVE_MAXIMUM property that has a lower value than + * this option, then the broker provided value will be used. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS - + * If value is set to a non zero value, then the user specified + * SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the default + * options applied to it. This means that you only need to change + * the values that are relevant to you. If you use this option then + * you must configure the TLS options as normal, i.e. you should + * use to configure the cafile/capath as a + * minimum. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_TLS_OCSP_REQUIRED - + * Set whether OCSP checking on TLS connections is required. Set to + * 1 to enable checking, or 0 (the default) for no checking. + */ +libmosq_EXPORT int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t option, int value); + + +/* + * Function: mosquitto_void_option + * + * Used to set void* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_SSL_CTX - + * Pass an openssl SSL_CTX to be used when creating TLS connections + * rather than libmosquitto creating its own. This must be called + * before connecting to have any effect. If you use this option, the + * onus is on you to ensure that you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_void_option(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + +/* + * Function: mosquitto_max_inflight_messages_set + * + * This function is deprected. Use the function with the + * MOSQ_OPT_SEND_MAXIMUM option instead. + * + * Set the number of QoS 1 and 2 messages that can be "in flight" at one time. + * An in flight message is part way through its delivery flow. Attempts to send + * further messages with will result in the messages being + * queued until the number of in flight messages reduces. + * + * A higher number here results in greater message throughput, but if set + * higher than the maximum in flight messages on the broker may lead to + * delays in the messages being acknowledged. + * + * Set to 0 for no maximum. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_inflight_messages - the maximum number of inflight messages. Defaults + * to 20. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages); + +/* + * Function: mosquitto_message_retry_set + * + * This function now has no effect. + */ +libmosq_EXPORT void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry); + +/* + * Function: mosquitto_user_data_set + * + * When is called, the pointer given as the "obj" parameter + * will be passed to the callbacks as user data. The + * function allows this obj parameter to be updated at any time. This function + * will not modify the memory pointed to by the current user data pointer. If + * it is dynamically allocated memory you must free it yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * obj - A user pointer that will be passed as an argument to any callbacks + * that are specified. + */ +libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj); + +/* Function: mosquitto_userdata + * + * Retrieve the "userdata" variable for a mosquitto client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * A pointer to the userdata member variable. + */ +libmosq_EXPORT void *mosquitto_userdata(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: TLS support + * + * ====================================================================== */ +/* + * Function: mosquitto_tls_set + * + * Configure the client for certificate based SSL/TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Define the Certificate Authority certificates to be trusted (ie. the server + * certificate must be signed with one of these certificates) using cafile. + * + * If the server you are connecting to requires clients to provide a + * certificate, define certfile and keyfile with your client certificate and + * private key. If your private key is encrypted, provide a password callback + * function or you will have to enter the password at the command line. + * + * Parameters: + * mosq - a valid mosquitto instance. + * cafile - path to a file containing the PEM encoded trusted CA + * certificate files. Either cafile or capath must not be NULL. + * capath - path to a directory containing the PEM encoded trusted CA + * certificate files. See mosquitto.conf for more details on + * configuring this directory. Either cafile or capath must not + * be NULL. + * certfile - path to a file containing the PEM encoded certificate file + * for this client. If NULL, keyfile must also be NULL and no + * client certificate will be used. + * keyfile - path to a file containing the PEM encoded private key for + * this client. If NULL, certfile must also be NULL and no + * client certificate will be used. + * pw_callback - if keyfile is encrypted, set pw_callback to allow your client + * to pass the correct password for decryption. If set to NULL, + * the password must be entered on the command line. + * Your callback must write the password into "buf", which is + * "size" bytes long. The return value must be the length of the + * password. "userdata" will be set to the calling mosquitto + * instance. The mosquitto userdata member variable can be + * retrieved using . + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , , + * , + */ +libmosq_EXPORT int mosquitto_tls_set(struct mosquitto *mosq, + const char *cafile, const char *capath, + const char *certfile, const char *keyfile, + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)); + +/* + * Function: mosquitto_tls_insecure_set + * + * Configure verification of the server hostname in the server certificate. If + * value is set to true, it is impossible to guarantee that the host you are + * connecting to is not impersonating your server. This can be useful in + * initial server testing, but makes it possible for a malicious third party to + * impersonate your server through DNS spoofing, for example. + * Do not use this function in a real system. Setting value to true makes the + * connection encryption pointless. + * Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * value - if set to false, the default, certificate hostname checking is + * performed. If set to true, no hostname checking is performed and + * the connection is insecure. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_insecure_set(struct mosquitto *mosq, bool value); + +/* + * Function: mosquitto_tls_opts_set + * + * Set advanced SSL/TLS options. Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * cert_reqs - an integer defining the verification requirements the client + * will impose on the server. This can be one of: + * * SSL_VERIFY_NONE (0): the server will not be verified in any way. + * * SSL_VERIFY_PEER (1): the server certificate will be verified + * and the connection aborted if the verification fails. + * The default and recommended value is SSL_VERIFY_PEER. Using + * SSL_VERIFY_NONE provides no security. + * tls_version - the version of the SSL/TLS protocol to use as a string. If NULL, + * the default value is used. The default value and the + * available values depend on the version of openssl that the + * library was compiled against. For openssl >= 1.0.1, the + * available options are tlsv1.2, tlsv1.1 and tlsv1, with tlv1.2 + * as the default. For openssl < 1.0.1, only tlsv1 is available. + * ciphers - a string describing the ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tls_version, const char *ciphers); + +/* + * Function: mosquitto_tls_psk_set + * + * Configure the client for pre-shared-key based TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Parameters: + * mosq - a valid mosquitto instance. + * psk - the pre-shared-key in hex format with no leading "0x". + * identity - the identity of this client. May be used as the username + * depending on the server settings. + * ciphers - a string describing the PSK ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers); + + +/* ====================================================================== + * + * Section: Callbacks + * + * ====================================================================== */ +/* + * Function: mosquitto_connect_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_connect_with_flags_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * flags - the connect flags. + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int)); + +/* + * Function: mosquitto_connect_v5_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + * flags - the connect flags. + * props - list of MQTT 5 properties, or NULL + * + */ +libmosq_EXPORT void mosquitto_connect_v5_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int, const mosquitto_property *props)); + +/* + * Function: mosquitto_disconnect_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + */ +libmosq_EXPORT void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_disconnect_v5_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_disconnect_v5_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *)); + +/* + * Function: mosquitto_publish_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker successfully. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + */ +libmosq_EXPORT void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_publish_v5_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker. This callback will be + * called both if the message is sent successfully, or if the broker responded + * with an error, which will be reflected in the reason_code parameter. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + * reason_code - the MQTT 5 reason code + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_publish_v5_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int, int, const mosquitto_property *)); + +/* + * Function: mosquitto_message_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *)); + +/* + * Function: mosquitto_message_v5_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * props - list of MQTT 5 properties, or NULL + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_v5_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *, const mosquitto_property *)); + +/* + * Function: mosquitto_subscribe_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + */ +libmosq_EXPORT void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *)); + +/* + * Function: mosquitto_subscribe_v5_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_subscribe_v5_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *)); + +/* + * Function: mosquitto_unsubscribe_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + */ +libmosq_EXPORT void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_unsubscribe_v5_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, const mosquitto_property *)); + +/* + * Function: mosquitto_log_callback_set + * + * Set the logging callback. This should be used if you want event logging + * information from the client library. + * + * mosq - a valid mosquitto instance. + * on_log - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int level, const char *str) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * level - the log message level from the values: + * MOSQ_LOG_INFO + * MOSQ_LOG_NOTICE + * MOSQ_LOG_WARNING + * MOSQ_LOG_ERR + * MOSQ_LOG_DEBUG + * str - the message string. + */ +libmosq_EXPORT void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *)); + +/* + * Function: mosquitto_string_option + * + * Used to set const char* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_TLS_ENGINE + * Configure the client for TLS Engine support. Pass a TLS Engine ID + * to be used when creating TLS connections. + * Must be set before . + * MOSQ_OPT_TLS_KEYFORM + * Configure the client to treat the keyfile differently depending + * on its type. Must be set before . + * Set as either "pem" or "engine", to determine from where the + * private key for a TLS connection will be obtained. Defaults to + * "pem", a normal private key file. + * MOSQ_OPT_TLS_KPASS_SHA1 + * Where the TLS Engine requires the use of a password to be + * accessed, this option allows a hex encoded SHA1 hash of the + * private key password to be passed to the engine directly. + * Must be set before . + * MOSQ_OPT_TLS_ALPN + * If the broker being connected to has multiple services available + * on a single TLS port, such as both MQTT and WebSockets, use this + * option to configure the ALPN option for the connection. + */ +libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value); + + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + + +/* ============================================================================= + * + * Section: SOCKS5 proxy functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_socks5_set + * + * Configure the client to use a SOCKS5 proxy when connecting. Must be called + * before connecting. "None" and "username/password" authentication is + * supported. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the SOCKS5 proxy host to connect to. + * port - the SOCKS5 proxy port to use. + * username - if not NULL, use this username when authenticating with the proxy. + * password - if not NULL and username is not NULL, use this password when + * authenticating with the proxy. + */ +libmosq_EXPORT int mosquitto_socks5_set(struct mosquitto *mosq, const char *host, int port, const char *username, const char *password); + + +/* ============================================================================= + * + * Section: Utility functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_strerror + * + * Call to obtain a const string description of a mosquitto error number. + * + * Parameters: + * mosq_errno - a mosquitto error number. + * + * Returns: + * A constant string describing the error. + */ +libmosq_EXPORT const char *mosquitto_strerror(int mosq_errno); + +/* + * Function: mosquitto_connack_string + * + * Call to obtain a const string description of an MQTT connection result. + * + * Parameters: + * connack_code - an MQTT connection result. + * + * Returns: + * A constant string describing the result. + */ +libmosq_EXPORT const char *mosquitto_connack_string(int connack_code); + +/* + * Function: mosquitto_reason_string + * + * Call to obtain a const string description of an MQTT reason code. + * + * Parameters: + * reason_code - an MQTT reason code. + * + * Returns: + * A constant string describing the reason. + */ +libmosq_EXPORT const char *mosquitto_reason_string(int reason_code); + +/* Function: mosquitto_string_to_command + * + * Take a string input representing an MQTT command and convert it to the + * libmosquitto integer representation. + * + * Parameters: + * str - the string to parse. + * cmd - pointer to an int, for the result. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - on an invalid input. + * + * Example: + * mosquitto_string_to_command("CONNECT", &cmd); + * // cmd == CMD_CONNECT + */ +libmosq_EXPORT int mosquitto_string_to_command(const char *str, int *cmd); + +/* + * Function: mosquitto_sub_topic_tokenise + * + * Tokenise a topic or subscription string into an array of strings + * representing the topic hierarchy. + * + * For example: + * + * subtopic: "a/deep/topic/hierarchy" + * + * Would result in: + * + * topics[0] = "a" + * topics[1] = "deep" + * topics[2] = "topic" + * topics[3] = "hierarchy" + * + * and: + * + * subtopic: "/a/deep/topic/hierarchy/" + * + * Would result in: + * + * topics[0] = NULL + * topics[1] = "a" + * topics[2] = "deep" + * topics[3] = "topic" + * topics[4] = "hierarchy" + * + * Parameters: + * subtopic - the subscription/topic to tokenise + * topics - a pointer to store the array of strings + * count - an int pointer to store the number of items in the topics array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * + * Example: + * + * > char **topics; + * > int topic_count; + * > int i; + * > + * > mosquitto_sub_topic_tokenise("$SYS/broker/uptime", &topics, &topic_count); + * > + * > for(i=0; i printf("%d: %s\n", i, topics[i]); + * > } + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *count); + +/* + * Function: mosquitto_sub_topic_tokens_free + * + * Free memory that was allocated in . + * + * Parameters: + * topics - pointer to string array. + * count - count of items in string array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokens_free(char ***topics, int count); + +/* + * Function: mosquitto_topic_matches_sub + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * topic - topic to check. + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result); + + +/* + * Function: mosquitto_topic_matches_sub2 + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * sublen - length in bytes of sub string + * topic - topic to check. + * topiclen - length in bytes of topic string + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub2(const char *sub, size_t sublen, const char *topic, size_t topiclen, bool *result); + +/* + * Function: mosquitto_pub_topic_check + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check(const char *topic); + +/* + * Function: mosquitto_pub_topic_check2 + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - length of the topic in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check2(const char *topic, size_t topiclen); + +/* + * Function: mosquitto_sub_topic_check + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check(const char *topic); + +/* + * Function: mosquitto_sub_topic_check2 + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - the length in bytes of the topic + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check2(const char *topic, size_t topiclen); + + +/* + * Function: mosquitto_validate_utf8 + * + * Helper function to validate whether a UTF-8 string is valid, according to + * the UTF-8 spec and the MQTT additions. + * + * Parameters: + * str - a string to check + * len - the length of the string in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if str is NULL or len<0 or len>65536 + * MOSQ_ERR_MALFORMED_UTF8 - if str is not valid UTF-8 + */ +libmosq_EXPORT int mosquitto_validate_utf8(const char *str, int len); + + +/* ============================================================================= + * + * Section: One line client helper functions + * + * ============================================================================= + */ + +struct libmosquitto_will { + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct libmosquitto_auth { + char *username; + char *password; +}; + +struct libmosquitto_tls { + char *cafile; + char *capath; + char *certfile; + char *keyfile; + char *ciphers; + char *tls_version; + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata); + int cert_reqs; +}; + +/* + * Function: mosquitto_subscribe_simple + * + * Helper function to make subscribing to a topic and retrieving some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, waits for msg_count + * messages to be received, then returns after disconnecting cleanly. + * + * Parameters: + * messages - pointer to a "struct mosquitto_message *". The received + * messages will be returned here. On error, this will be set to + * NULL. + * msg_count - the number of messages to retrieve. + * want_retained - if set to true, stale retained messages will be treated as + * normal messages with regards to msg_count. If set to + * false, they will be ignored. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * >0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool want_retained, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* + * Function: mosquitto_subscribe_callback + * + * Helper function to make subscribing to a topic and processing some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, then passes received + * messages to a user provided callback. If the callback returns a 1, it then + * disconnects cleanly and returns. + * + * Parameters: + * callback - a callback function in the following form: + * int callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * Note that this is the same as the normal on_message callback, + * except that it returns an int. + * userdata - user provided pointer that will be passed to the callback. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * >0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* ============================================================================= + * + * Section: Properties + * + * ============================================================================= + */ + + +/* + * Function: mosquitto_property_add_byte + * + * Add a new byte property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_byte(&proplist, MQTT_PROP_PAYLOAD_FORMAT_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value); + +/* + * Function: mosquitto_property_add_int16 + * + * Add a new int16 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_RECEIVE_MAXIMUM) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_int16(&proplist, MQTT_PROP_RECEIVE_MAXIMUM, 1000); + */ +libmosq_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value); + +/* + * Function: mosquitto_property_add_int32 + * + * Add a new int32 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_MESSAGE_EXPIRY_INTERVAL) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_int32(&proplist, MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, 86400); + */ +libmosq_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_varint + * + * Add a new varint property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_SUBSCRIPTION_IDENTIFIER) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_varint(&proplist, MQTT_PROP_SUBSCRIPTION_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_binary + * + * Add a new binary property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to the property data + * len - length of property data in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_binary(&proplist, MQTT_PROP_AUTHENTICATION_DATA, auth_data, auth_data_len); + */ +libmosq_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len); + +/* + * Function: mosquitto_property_add_string + * + * Add a new string property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_CONTENT_TYPE) + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - value is not valid UTF-8. + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_string(&proplist, MQTT_PROP_CONTENT_TYPE, "application/json"); + */ +libmosq_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value); + +/* + * Function: mosquitto_property_add_string_pair + * + * Add a new string pair property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_USER_PROPERTY) + * name - string name for the new property, must be UTF-8 and zero terminated + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if name or value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - if name or value are not valid UTF-8. + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_string_pair(&proplist, MQTT_PROP_USER_PROPERTY, "client", "mosquitto_pub"); + */ +libmosq_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value); + +/* + * Function: mosquitto_property_read_byte + * + * Attempt to read a byte property matching an identifier, from a property list + * or single property. This function can search for multiple entries of the + * same identifier by using the returned value and skip_first. Note however + * that it is forbidden for most properties to be duplicated. + * + * If the property is not found, *value will not be modified, so it is safe to + * pass a variable with a default value to be potentially overwritten: + * + * uint16_t keepalive = 60; // default value + * // Get value from property list, or keep default if not found. + * mosquitto_property_read_int16(proplist, MQTT_PROP_SERVER_KEEP_ALIVE, &keepalive, false); + * + * Parameters: + * proplist - mosquitto_property pointer, the list of properties or single property + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * // proplist is obtained from a callback + * mosquitto_property *prop; + * prop = mosquitto_property_read_byte(proplist, identifier, &value, false); + * while(prop){ + * printf("value: %s\n", value); + * prop = mosquitto_property_read_byte(prop, identifier, &value); + * } + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_byte( + const mosquitto_property *proplist, + int identifier, + uint8_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int16 + * + * Read an int16 property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int16( + const mosquitto_property *proplist, + int identifier, + uint16_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int32 + * + * Read an int32 property value from a property. + * + * Parameters: + * property - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int32( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_varint + * + * Read a varint property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_varint( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_binary + * + * Read a binary property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_binary( + const mosquitto_property *proplist, + int identifier, + void **value, + uint16_t *len, + bool skip_first); + +/* + * Function: mosquitto_property_read_string + * + * Read a string property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string( + const mosquitto_property *proplist, + int identifier, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_read_string_pair + * + * Read a string pair property value pair from a property. + * + * On success, name and value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * name - pointer to char* for the name property data to be stored in, or NULL + * if the name is not required. + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string_pair( + const mosquitto_property *proplist, + int identifier, + char **name, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_free_all + * + * Free all properties from a list of properties. Frees the list and sets *properties to NULL. + * + * Parameters: + * properties - list of properties to free + * + * Example: + * mosquitto_properties *properties = NULL; + * // Add properties + * mosquitto_property_free_all(&properties); + */ +libmosq_EXPORT void mosquitto_property_free_all(mosquitto_property **properties); + +/* + * Function: mosquitto_property_copy_all + * + * Parameters: + * dest : pointer for new property list + * src : property list + * + * Returns: + * MOSQ_ERR_SUCCESS - on successful copy + * MOSQ_ERR_INVAL - if dest is NULL + * MOSQ_ERR_NOMEM - on out of memory (dest will be set to NULL) + */ +libmosq_EXPORT int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_property *src); + +/* + * Function: mosquitto_property_check_command + * + * Check whether a property identifier is valid for the given command. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * identifier - MQTT property (e.g. MQTT_PROP_USER_PROPERTY) + * + * Returns: + * MOSQ_ERR_SUCCESS - if the identifier is valid for command + * MOSQ_ERR_PROTOCOL - if the identifier is not valid for use with command. + */ +libmosq_EXPORT int mosquitto_property_check_command(int command, int identifier); + + +/* + * Function: mosquitto_property_check_all + * + * Check whether a list of properties are valid for a particular command, + * whether there are duplicates, and whether the values are valid where + * possible. + * + * Note that this function is used internally in the library whenever + * properties are passed to it, so in basic use this is not needed, but should + * be helpful to check property lists *before* the point of using them. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * properties - list of MQTT properties to check. + * + * Returns: + * MOSQ_ERR_SUCCESS - if all properties are valid + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid + */ +libmosq_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties); + +/* Function: mosquitto_string_to_property_info + * + * Parse a property name string and convert to a property identifier and data type. + * The property name is as defined in the MQTT specification, with - as a + * separator, for example: payload-format-indicator. + * + * Parameters: + * propname - the string to parse + * identifier - pointer to an int to receive the property identifier + * type - pointer to an int to receive the property type + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the string does not match a property + * + * Example: + * mosquitto_string_to_property_info("response-topic", &id, &type); + * // id == MQTT_PROP_RESPONSE_TOPIC + * // type == MQTT_PROP_TYPE_STRING + */ +libmosq_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/mqtt_hcfy/mosquitto_plugin.h b/product/src/fes/protocol/mqtt_hcfy/mosquitto_plugin.h new file mode 100644 index 00000000..e8fb1eaa --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/mosquitto_plugin.h @@ -0,0 +1,319 @@ +/* +Copyright (c) 2012-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_PLUGIN_H +#define MOSQUITTO_PLUGIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MOSQ_AUTH_PLUGIN_VERSION 4 + +#define MOSQ_ACL_NONE 0x00 +#define MOSQ_ACL_READ 0x01 +#define MOSQ_ACL_WRITE 0x02 +#define MOSQ_ACL_SUBSCRIBE 0x04 + +#include +#include + +struct mosquitto; + +struct mosquitto_opt { + char *key; + char *value; +}; + +struct mosquitto_auth_opt { + char *key; + char *value; +}; + +struct mosquitto_acl_msg { + const char *topic; + const void *payload; + long payloadlen; + int qos; + bool retain; +}; + +/* + * To create an authentication plugin you must include this file then implement + * the functions listed in the "Plugin Functions" section below. The resulting + * code should then be compiled as a shared library. Using gcc this can be + * achieved as follows: + * + * gcc -I -fPIC -shared plugin.c -o plugin.so + * + * On Mac OS X: + * + * gcc -I -fPIC -shared plugin.c -undefined dynamic_lookup -o plugin.so + * + * Authentication plugins can implement one or both of authentication and + * access control. If your plugin does not wish to handle either of + * authentication or access control it should return MOSQ_ERR_PLUGIN_DEFER. In + * this case, the next plugin will handle it. If all plugins return + * MOSQ_ERR_PLUGIN_DEFER, the request will be denied. + * + * For each check, the following flow happens: + * + * * The default password file and/or acl file checks are made. If either one + * of these is not defined, then they are considered to be deferred. If either + * one accepts the check, no further checks are made. If an error occurs, the + * check is denied + * * The first plugin does the check, if it returns anything other than + * MOSQ_ERR_PLUGIN_DEFER, then the check returns immediately. If the plugin + * returns MOSQ_ERR_PLUGIN_DEFER then the next plugin runs its check. + * * If the final plugin returns MOSQ_ERR_PLUGIN_DEFER, then access will be + * denied. + */ + +/* ========================================================================= + * + * Helper Functions + * + * ========================================================================= */ + +/* There are functions that are available for plugin developers to use in + * mosquitto_broker.h, including logging and accessor functions. + */ + + +/* ========================================================================= + * + * Plugin Functions + * + * You must implement these functions in your plugin. + * + * ========================================================================= */ + +/* + * Function: mosquitto_auth_plugin_version + * + * The broker will call this function immediately after loading the plugin to + * check it is a supported plugin version. Your code must simply return + * MOSQ_AUTH_PLUGIN_VERSION. + */ +int mosquitto_auth_plugin_version(void); + + +/* + * Function: mosquitto_auth_plugin_init + * + * Called after the plugin has been loaded and + * has been called. This will only ever be called once and can be used to + * initialise the plugin. + * + * Parameters: + * + * user_data : The pointer set here will be passed to the other plugin + * functions. Use to hold connection information for example. + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_plugin_cleanup + * + * Called when the broker is shutting down. This will only ever be called once + * per plugin. + * Note that will be called directly before + * this function. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_security_init + * + * This function is called in two scenarios: + * + * 1. When the broker starts up. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, will be called first, then + * this function will be called. In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_init(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_security_cleanup + * + * This function is called in two scenarios: + * + * 1. When the broker is shutting down. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, this function will be called, followed by + * . In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_acl_check + * + * Called by the broker when topic access must be checked. access will be one + * of: + * MOSQ_ACL_SUBSCRIBE when a client is asking to subscribe to a topic string. + * This differs from MOSQ_ACL_READ in that it allows you to + * deny access to topic strings rather than by pattern. For + * example, you may use MOSQ_ACL_SUBSCRIBE to deny + * subscriptions to '#', but allow all topics in + * MOSQ_ACL_READ. This allows clients to subscribe to any + * topic they want, but not discover what topics are in use + * on the server. + * MOSQ_ACL_READ when a message is about to be sent to a client (i.e. whether + * it can read that topic or not). + * MOSQ_ACL_WRITE when a message has been received from a client (i.e. whether + * it can write to that topic or not). + * + * Return: + * MOSQ_ERR_SUCCESS if access was granted. + * MOSQ_ERR_ACL_DENIED if access was not granted. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_acl_check(void *user_data, int access, struct mosquitto *client, const struct mosquitto_acl_msg *msg); + + +/* + * Function: mosquitto_auth_unpwd_check + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making basic username/password checks. + * + * Called by the broker when a username/password must be checked. + * + * Return: + * MOSQ_ERR_SUCCESS if the user is authenticated. + * MOSQ_ERR_AUTH if authentication failed. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_unpwd_check(void *user_data, struct mosquitto *client, const char *username, const char *password); + + +/* + * Function: mosquitto_psk_key_get + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making TLS-PSK checks. + * + * Called by the broker when a client connects to a listener using TLS/PSK. + * This is used to retrieve the pre-shared-key associated with a client + * identity. + * + * Examine hint and identity to determine the required PSK (which must be a + * hexadecimal string with no leading "0x") and copy this string into key. + * + * Parameters: + * user_data : the pointer provided in . + * hint : the psk_hint for the listener the client is connecting to. + * identity : the identity string provided by the client + * key : a string where the hex PSK should be copied + * max_key_len : the size of key + * + * Return value: + * Return 0 on success. + * Return >0 on failure. + * Return MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_psk_key_get(void *user_data, struct mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len); + +/* + * Function: mosquitto_auth_start + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making extended authentication checks. + * + * Parameters: + * user_data : the pointer provided in . + * method : the authentication method + * reauth : this is set to false if this is the first authentication attempt + * on a connection, set to true if the client is attempting to + * reauthenticate. + * data_in : pointer to authentication data, or NULL + * data_in_len : length of data_in, in bytes + * data_out : if your plugin wishes to send authentication data back to the + * client, allocate some memory using malloc or friends and set + * data_out. The broker will free the memory after use. + * data_out_len : Set the length of data_out in bytes. + * + * Return value: + * Return MOSQ_ERR_SUCCESS if authentication was successful. + * Return MOSQ_ERR_AUTH_CONTINUE if the authentication is a multi step process and can continue. + * Return MOSQ_ERR_AUTH if authentication was valid but did not succeed. + * Return any other relevant positive integer MOSQ_ERR_* to produce an error. + */ +int mosquitto_auth_start(void *user_data, struct mosquitto *client, const char *method, bool reauth, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + +int mosquitto_auth_continue(void *user_data, struct mosquitto *client, const char *method, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/mqtt_hcfy/mosquittopp.h b/product/src/fes/protocol/mqtt_hcfy/mosquittopp.h new file mode 100644 index 00000000..fd2f1793 --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/mosquittopp.h @@ -0,0 +1,146 @@ +/* +Copyright (c) 2010-2019 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTOPP_H +#define MOSQUITTOPP_H + +#if defined(_WIN32) && !defined(LIBMOSQUITTO_STATIC) +# ifdef mosquittopp_EXPORTS +# define mosqpp_EXPORT __declspec(dllexport) +# else +# define mosqpp_EXPORT __declspec(dllimport) +# endif +#else +# define mosqpp_EXPORT +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define DEPRECATED __attribute__ ((deprecated)) +#else +# define DEPRECATED +#endif + +#include +#include +#include + +namespace mosqpp { + + +mosqpp_EXPORT const char * DEPRECATED strerror(int mosq_errno); +mosqpp_EXPORT const char * DEPRECATED connack_string(int connack_code); +mosqpp_EXPORT int DEPRECATED sub_topic_tokenise(const char *subtopic, char ***topics, int *count); +mosqpp_EXPORT int DEPRECATED sub_topic_tokens_free(char ***topics, int count); +mosqpp_EXPORT int DEPRECATED lib_version(int *major, int *minor, int *revision); +mosqpp_EXPORT int DEPRECATED lib_init(); +mosqpp_EXPORT int DEPRECATED lib_cleanup(); +mosqpp_EXPORT int DEPRECATED topic_matches_sub(const char *sub, const char *topic, bool *result); +mosqpp_EXPORT int DEPRECATED validate_utf8(const char *str, int len); +mosqpp_EXPORT int DEPRECATED subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool retained, + const char *topic, + int qos=0, + const char *host="localhost", + int port=1883, + const char *client_id=NULL, + int keepalive=60, + bool clean_session=true, + const char *username=NULL, + const char *password=NULL, + const struct libmosquitto_will *will=NULL, + const struct libmosquitto_tls *tls=NULL); + +mosqpp_EXPORT int DEPRECATED subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos=0, + bool retained=true, + const char *host="localhost", + int port=1883, + const char *client_id=NULL, + int keepalive=60, + bool clean_session=true, + const char *username=NULL, + const char *password=NULL, + const struct libmosquitto_will *will=NULL, + const struct libmosquitto_tls *tls=NULL); + +/* + * Class: mosquittopp + * + * A mosquitto client class. This is a C++ wrapper class for the mosquitto C + * library. Please see mosquitto.h for details of the functions. + */ +class mosqpp_EXPORT DEPRECATED mosquittopp { + private: + struct mosquitto *m_mosq; + public: + DEPRECATED mosquittopp(const char *id=NULL, bool clean_session=true); + virtual ~mosquittopp(); + + int DEPRECATED reinitialise(const char *id, bool clean_session); + int DEPRECATED socket(); + int DEPRECATED will_set(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int DEPRECATED will_clear(); + int DEPRECATED username_pw_set(const char *username, const char *password=NULL); + int DEPRECATED connect(const char *host, int port=1883, int keepalive=60); + int DEPRECATED connect_async(const char *host, int port=1883, int keepalive=60); + int DEPRECATED connect(const char *host, int port, int keepalive, const char *bind_address); + int DEPRECATED connect_async(const char *host, int port, int keepalive, const char *bind_address); + int DEPRECATED reconnect(); + int DEPRECATED reconnect_async(); + int DEPRECATED disconnect(); + int DEPRECATED publish(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int DEPRECATED subscribe(int *mid, const char *sub, int qos=0); + int DEPRECATED unsubscribe(int *mid, const char *sub); + void DEPRECATED reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + int DEPRECATED max_inflight_messages_set(unsigned int max_inflight_messages); + void DEPRECATED message_retry_set(unsigned int message_retry); + void DEPRECATED user_data_set(void *userdata); + int DEPRECATED tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL); + int DEPRECATED tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL); + int DEPRECATED tls_insecure_set(bool value); + int DEPRECATED tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL); + int DEPRECATED opts_set(enum mosq_opt_t option, void *value); + + int DEPRECATED loop(int timeout=-1, int max_packets=1); + int DEPRECATED loop_misc(); + int DEPRECATED loop_read(int max_packets=1); + int DEPRECATED loop_write(int max_packets=1); + int DEPRECATED loop_forever(int timeout=-1, int max_packets=1); + int DEPRECATED loop_start(); + int DEPRECATED loop_stop(bool force=false); + bool DEPRECATED want_write(); + int DEPRECATED threaded_set(bool threaded=true); + int DEPRECATED socks5_set(const char *host, int port=1080, const char *username=NULL, const char *password=NULL); + + // names in the functions commented to prevent unused parameter warning + virtual void on_connect(int /*rc*/) {return;} + virtual void on_connect_with_flags(int /*rc*/, int /*flags*/) {return;} + virtual void on_disconnect(int /*rc*/) {return;} + virtual void on_publish(int /*mid*/) {return;} + virtual void on_message(const struct mosquitto_message * /*message*/) {return;} + virtual void on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/) {return;} + virtual void on_unsubscribe(int /*mid*/) {return;} + virtual void on_log(int /*level*/, const char * /*str*/) {return;} + virtual void on_error() {return;} +}; + +} +#endif diff --git a/product/src/fes/protocol/mqtt_hcfy/mqtt_hcfy.pro b/product/src/fes/protocol/mqtt_hcfy/mqtt_hcfy.pro new file mode 100644 index 00000000..02a900b1 --- /dev/null +++ b/product/src/fes/protocol/mqtt_hcfy/mqtt_hcfy.pro @@ -0,0 +1,52 @@ +# ARM板上资源有限,不会与云平台混用,不编译 +message("Compile only in x86 environment") +# requires(contains(QMAKE_HOST.arch, x86_64)) +requires(!contains(QMAKE_HOST.arch, aarch64):!linux-aarch64*) + +#海辰福耀ems +QT -= core gui +CONFIG -= qt + +TARGET = mqtt_hcfy +TEMPLATE = lib + +SOURCES += \ + Hccloudmqtts.cpp \ + Md5/Md5.cpp \ + HccloudmqttsDataProcThread.cpp \ + MQTTHandleThread.cpp \ + CmdHandleThread.cpp \ + CMosquitto.cpp \ + CMbCommHandleThread.cpp + +HEADERS += \ + Hccloudmqtts.h \ + mosquitto_plugin.h \ + mosquittopp.h \ + mosquitto.h \ + Md5/Md5.h \ + HccloudmqttsDataProcThread.h \ + MQTTHandleThread.h \ + CmdHandleThread.h \ + CMosquitto.h \ + CMbCommHandleThread.h + +INCLUDEPATH += \ + ../../include/ \ + ../../../include/ \ + ../../../3rd/include/ + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time -lboost_filesystem +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase -lnet_msg_bus_api +LIBS += -lmosquitto -lmosquittopp + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/fes/protocol/mqtt_yxCloud/CMbCommHandleThread.cpp b/product/src/fes/protocol/mqtt_yxCloud/CMbCommHandleThread.cpp new file mode 100644 index 00000000..57daec3f --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/CMbCommHandleThread.cpp @@ -0,0 +1,99 @@ +#include "CMbCommHandleThread.h" + +#include "rapidjson/writer.h" +#include "rapidjson/stringbuffer.h" + +#include "common/Common.h" +#include "common/MessageChannel.h" +#include "pub_logger_api/logger.h" + +CMbCommHandleThread::CMbCommHandleThread() + : CTimerThreadBase("CMbCommHandleThread") +{ + +} + +void CMbCommHandleThread::execute() +{ + if( m_ptrMbComm == NULL ) + { + m_ptrMbComm = new iot_net::CMbCommunicator(); + + if( m_ptrMbComm->addSub(CN_AppId_COMAPP, CH_OPT_TO_FES_CTRL_DOWN) ) + { + LOGINFO(" sub CH_OPT_TO_FES_CTRL_DOWN ok"); + } + } + + iot_net::CMbMessage recvMessage; + while( m_ptrMbComm->recvMsg(recvMessage, 100) ) + { + if( recvMessage.getChannelID() == CH_OPT_TO_FES_CTRL_DOWN ) + { + std::string str((char*)recvMessage.getDataPtr(), recvMessage.getDataSize()); + + LOGINFO("mbcomm recv message: %s", str.c_str()); + + rapidjson::Document doc; + doc.Parse(str.c_str()); + + if( doc.HasParseError() ) + { + LOGERROR("json parse error: %s", str.c_str()); + continue; + } + + if( doc.HasMember("strategySrc") && + doc["strategySrc"].IsString() && + (std::string(doc["strategySrc"].GetString()) == YX_CLOUD_FLAG) ) + { + handleRecvMessage(doc); + } + } + } +} + +int CMbCommHandleThread::getPublishMsg(SPublishMsg &msg) +{ + boost::mutex::scoped_lock lock(m_TxMutex); + + if( !m_TxBuffer.empty() ) + { + msg = m_TxBuffer.front(); + m_TxBuffer.pop(); + + return 1; + } + + return 0; +} + +void CMbCommHandleThread::putPublishMsg(const SPublishMsg& msg) +{ + boost::mutex::scoped_lock lock(m_TxMutex); + m_TxBuffer.push(msg); +} + +void CMbCommHandleThread::handleRecvMessage(rapidjson::Document& doc) +{ + if( doc.HasMember("content") && doc["content"].IsObject() ) + { + rapidjson::Value& contentJson = doc["content"]; + + std::string respTopic; + if( contentJson.HasMember("respTopic") && contentJson["respTopic"].IsString() ) + { + respTopic = contentJson["respTopic"].GetString(); + } + + rapidjson::StringBuffer buffer; + rapidjson::Writer write(buffer); + doc.Accept(write); + + SPublishMsg publishMessage; + publishMessage.topic = respTopic; + publishMessage.msg = buffer.GetString(); + + putPublishMsg(publishMessage); + } +} diff --git a/product/src/fes/protocol/mqtt_yxCloud/CMbCommHandleThread.h b/product/src/fes/protocol/mqtt_yxCloud/CMbCommHandleThread.h new file mode 100644 index 00000000..ccf3047d --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/CMbCommHandleThread.h @@ -0,0 +1,43 @@ +#ifndef CMBCOMMHANDLETHREAD_H +#define CMBCOMMHANDLETHREAD_H + +#include + +#include "rapidjson/document.h" + +#include "pub_utility_api/TimerThreadBase.h" +#include "net_msg_bus_api/CMbCommunicator.h" + + +typedef struct { + std::string topic; + std::string msg; +}SPublishMsg; + +class CMbCommHandleThread : public iot_public::CTimerThreadBase +{ +public: + CMbCommHandleThread(); + + /** + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + int getPublishMsg(SPublishMsg& msg); + void putPublishMsg(const SPublishMsg& msg); + +private: + void handleRecvMessage(rapidjson::Document& doc); + + iot_net::CMbCommunicator* m_ptrMbComm{NULL}; + + std::queue m_TxBuffer; + boost::mutex m_TxMutex; + + const char* const YX_CLOUD_FLAG = "yx"; +}; + +typedef boost::shared_ptr CMbCommHandleThreadPtr; + +#endif // CMBCOMMHANDLETHREAD_H diff --git a/product/src/fes/protocol/mqtt_yxCloud/CMosquitto.cpp b/product/src/fes/protocol/mqtt_yxCloud/CMosquitto.cpp new file mode 100644 index 00000000..dce41186 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/CMosquitto.cpp @@ -0,0 +1,69 @@ +#include "CMosquitto.h" +#include +#include +using namespace fes_yxCloud; +CMosquitto::CMosquitto(const char *id): mosquittopp(id) +{ + +} + +CMosquitto::~CMosquitto() +{ + LOGINFO("CMosquitto has quit"); +} + +void CMosquitto::on_message(const mosquitto_message *message) +{ + boost::mutex::scoped_lock lock(m_MsgMutex); + try + { + if(message->payload && message->payloadlen > 0) + { + m_queue.push(*message); + } + }catch(const std::exception& e) + { + LOGERROR("CMosquitto Failed to %s" , e.what()); + } + + +} + +void CMosquitto::on_connect(int rc) +{ + if (rc == 0) { + LOGINFO("CMosquitto Connected to the MQTT broker successfully"); + if(!subscription.empty()) + { + int rc=subscribe(NULL,subscription.data()); + if( MOSQ_ERR_SUCCESS != rc) + { + LOGERROR("subscribeRc != MOSQ_ERR_SUCCESS Error: %s" , mosquitto_strerror(rc)); + } + } + } else { + LOGINFO("CMosquitto Failed to connect to the MQTT broker. Return code: %d" , rc); + } +} + +void CMosquitto::on_subscribe(int mid, int qos_count, const int *granted_qos) +{ + boost::ignore_unused(qos_count); + boost::ignore_unused(granted_qos); + LOGINFO("CMosquitto Subscription successful! mid: %d" , mid); +} + +int CMosquitto::get_message(mosquitto_message &msg) +{ + boost::mutex::scoped_lock lock(m_MsgMutex); + int64_t count=0; + if(!m_queue.empty()) + { + msg=m_queue.front(); + m_queue.pop(); + ++count; + } + + return count; +} + diff --git a/product/src/fes/protocol/mqtt_yxCloud/CMosquitto.h b/product/src/fes/protocol/mqtt_yxCloud/CMosquitto.h new file mode 100644 index 00000000..fafe15da --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/CMosquitto.h @@ -0,0 +1,34 @@ +#pragma once + +#include "mosquitto.h" +#include "mosquittopp.h" +#include "pub_logger_api/logger.h" +#include +#include +#include "boost/circular_buffer.hpp" +#include + +namespace fes_yxCloud { + + + + class CMosquitto: public mosqpp::mosquittopp + { + public: + CMosquitto(const char *id); + virtual ~CMosquitto(); + void on_message(const struct mosquitto_message *message) override; + void on_connect(int rc) override; + void on_subscribe(int mid, int qos_count, const int *granted_qos) override; + int get_message(mosquitto_message& content); + private: + //boost::container::deque m_queue; + boost::mutex m_MsgMutex; //< 互斥锁 + std::queue m_queue; + + public: + std::string subscription; + }; +} + + diff --git a/product/src/fes/protocol/mqtt_yxCloud/CmdHandleThread.cpp b/product/src/fes/protocol/mqtt_yxCloud/CmdHandleThread.cpp new file mode 100644 index 00000000..f8850f2e --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/CmdHandleThread.cpp @@ -0,0 +1,284 @@ +#include "CmdHandleThread.h" +#include "./proto/RequestControl.pb.h" +#include "./proto/RequestControlPoint.pb.h" +#include "./proto/TypePoint.pb.h" +#include "./proto/EnumBase.pb.h" + +#include "rapidjson/writer.h" +#include "rapidjson/stringbuffer.h" + +#include "common/MessageChannel.h" + +using namespace fes_yxCloud ; + +const int gCmdHandleThreadTime = 300; +CmdHandleThread::CmdHandleThread(CFesBase *ptrCFesBase, CFesChanPtr ptrCFesChan, vector vecConfig) + :CTimerThreadBase("YxCloudCmdHandleThread", gCmdHandleThreadTime,0,true),m_bReady(true) +{ + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + + if (m_ptrCFesChan == NULL ) + { + return; + } + m_ptrCFesRtu=GetRtuDataByChanData(m_ptrCFesChan); + + bool found = false; + if(vecConfig.size()>0) + { + for (size_t i = 0; i < vecConfig.size(); i++) + { + if(m_ptrCFesRtu->m_Param.RtuNo == vecConfig[i].RtuNo) + { + //配置 + m_cmdHandleConfig=vecConfig[i]; + found = true; + break; + } + } + } + + if(found) + { + if(!m_cmdHandleConfig.Subscription.empty()) + { + m_ptrMbComm = new iot_net::CMbCommunicator(); + } + else + { + m_bReady=false; + } + } + else + { + m_bReady=false; + } +} + +CmdHandleThread::~CmdHandleThread() +{ + delete m_ptrMbComm; + + LOGINFO("CmdHandleThread::~CmdHandleThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); +} + +int CmdHandleThread::beforeExecute() +{ + return iotSuccess; +} + +void CmdHandleThread::execute() +{ + if(!m_bReady) + { + LOGTRACE("CmdHandleThread ChanNo=%d has bad and do nothing ", m_ptrCFesChan->m_Param.ChanNo); + return; + } + //处理消息 + mosquitto_message msg; + bool needHandle=false; + { + boost::mutex::scoped_lock lock(m_RxMutex); + if(!m_RxBuffer.empty()) + { + msg=m_RxBuffer.front(); + m_RxBuffer.pop(); + needHandle=true; + } + } + + if(needHandle) + { + handleMsg(msg); + } +} + +void CmdHandleThread::beforeQuit() +{ + +} + +void CmdHandleThread::handleMsg(mosquitto_message &msg) +{ + if( std::string(msg.topic).find("srv/req/strategy") != -1 ) + { + iot_net::CMbMessage message; + message.setSubject(CN_AppId_PUBLIC, CH_FES_TO_OPT_CTRL_UP); + message.setData(std::string((char*)msg.payload, msg.payloadlen)); + + m_ptrMbComm->sendMsgToDomain(message); + + return; + } + + // 反序列化解析 + com_relyez_ems_common::RequestControl* rqtControlPoint = new com_relyez_ems_common::RequestControl(); + if (rqtControlPoint->ParseFromArray(msg.payload, msg.payloadlen)) + { + // 每次只下达一种类型 + //CommandType sCmdType = rqtControlPoint->commandtype(); + string sUserId = rqtControlPoint->userid(); + //RequestSource sSrouce = rqtControlPoint->source(); + com_relyez_ems_common::RequestControlPoint ctlPoint = rqtControlPoint->controlpoint(); + com_relyez_ems_common::TypePoint tpPoint = ctlPoint.typepoint(0); + string sPointType = tpPoint.type(); + for (int nIndex = 0; nIndex < tpPoint.point_size(); ++nIndex) + { + com_relyez_ems_common::Point pt = tpPoint.point(nIndex); + + rapidjson::Document doc; + doc.SetObject(); + + rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); + + doc.AddMember("strategySrc", "yx", allocator); + + rapidjson::Value content(rapidjson::kObjectType); + content.AddMember("method", "TagData", allocator); + + std::string tagName = pt.tagname(); + if( tagName.find("value") == -1 ) + { + tagName.append(".value"); + } + rapidjson::Value data(rapidjson::kObjectType); + data.AddMember("tagName", rapidjson::StringRef(tagName.c_str()), allocator); + data.AddMember("value", rapidjson::StringRef(pt.value().c_str()), allocator); + + content.AddMember("data", data, allocator); + doc.AddMember("content", content, allocator); + + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + doc.Accept(writer); + + iot_net::CMbMessage message; + message.setSubject(CN_AppId_PUBLIC, CH_FES_TO_OPT_CTRL_UP); + message.setData(buffer.GetString()); + + m_ptrMbComm->sendMsgToDomain(message); + + string sTagName = pt.tagname(); + int nParams1 = boost::lexical_cast(pt.protocolparameter1()); + float nValue = boost::lexical_cast(pt.value()); + string sDeviceStr = ""; + for (int n = 0; n < pt.identification_size(); ++n) + { + sDeviceStr += pt.identification(n); + } + + if (sPointType == "0") + { + // 模拟量 + SFesFwAo* pFwAo = nullptr; + pFwAo = m_ptrCFesRtu->m_pFwAo + 1; + pFwAo = m_ptrCFesRtu->m_pFwAo + nParams1; // 根据协议中的规约参数值来算出当前实际的Rtu信息; + if (pFwAo != nullptr) + { + if (sTagName == "") + sTagName = pFwAo->TagName; + + SFesRxAoCmd aoCmd; + sprintf(aoCmd.TableName, "cmd.TableName"); + sprintf(aoCmd.TagName, "cmd.TagName"); + sprintf(aoCmd.RtuName, "cmd.RtuName"); + sprintf(aoCmd.ColumnName, "cmd.ColumnName"); + aoCmd.CtrlDir = CN_Fes_CtrlDir_InSide; + aoCmd.FwSubSystem = m_ptrCFesRtu->m_Param.nSubSystem; + aoCmd.FwRtuNo = m_ptrCFesRtu->m_Param.RtuNo; + aoCmd.FwPointNo = nParams1; + aoCmd.fValue = (float)(nValue); + aoCmd.RtuNo = pFwAo->FesRtuNo; + aoCmd.PointID = pFwAo->FesPointNo; + aoCmd.SubSystem = pFwAo->SrcSubSystem; + aoCmd.CtrlActType = CN_ControlExecute; + m_ptrCFesBase->WriteAoReqCmdBuf(1, &aoCmd); + } + else + { + LOGINFO("current Ret info is empty, can not direct instr !!!!"); + } + } + else if (sPointType == "1") + { + SFesFwDo *pFwDo = nullptr; + pFwDo = m_ptrCFesRtu->m_pFwDo + nParams1; // 根据协议中的规约参数值来算出当前实际的Rtu信息; + if (pFwDo != nullptr) + { + // 数字量 + if (sTagName == "") + sTagName = pFwDo->TagName; + + SFesRxDoCmd doCmd; + sprintf(doCmd.TableName, "cmd.TableName"); + sprintf(doCmd.TagName, "cmd.TagName"); + sprintf(doCmd.RtuName, "cmd.RtuName"); + sprintf(doCmd.ColumnName, "cmd.ColumnName"); + doCmd.CtrlDir = CN_Fes_CtrlDir_InSide; + doCmd.FwSubSystem = m_ptrCFesRtu->m_Param.nSubSystem; + doCmd.FwRtuNo = m_ptrCFesRtu->m_Param.RtuNo; + doCmd.FwPointNo = nParams1; + doCmd.iValue = (int)(nValue); + doCmd.RtuNo = pFwDo->FesRtuNo; + doCmd.PointID = pFwDo->FesPointNo[0]; + doCmd.SubSystem = pFwDo->SrcSubSystem; + doCmd.CtrlActType = CN_ControlExecute; + m_ptrCFesBase->WriteDoReqCmdBuf(1, &doCmd); + } + else + { + LOGINFO("current Rtu FwDi info is empty, can not direct instr !!!!"); + } + + } + else if (sPointType == "2") + { + SFesFwMo *pFwMo = nullptr; + if (pFwMo != nullptr) + { + if (sTagName == "") + sTagName = pFwMo->TagName; + + SFesRxMoCmd moCmd; + sprintf(moCmd.TableName, "cmd.TableName"); + sprintf(moCmd.TagName, "cmd.TagName"); + sprintf(moCmd.RtuName, "cmd.RtuName"); + sprintf(moCmd.ColumnName, "cmd.ColumnName"); + moCmd.CtrlDir = CN_Fes_CtrlDir_InSide; + moCmd.FwSubSystem = m_ptrCFesRtu->m_Param.nSubSystem; + moCmd.FwRtuNo = m_ptrCFesRtu->m_Param.RtuNo; + moCmd.FwPointNo = nParams1; + moCmd.iValue = (int)(nValue); + moCmd.RtuNo = pFwMo->FesRtuNo; + moCmd.PointID = pFwMo->FesPointNo; + moCmd.SubSystem = pFwMo->SrcSubSystem; + moCmd.CtrlActType = CN_ControlExecute; + m_ptrCFesBase->WriteMoReqCmdBuf(1, &moCmd); + } + else + { + LOGINFO("current Rtu FwMi info is empty, can not direct instr !!!!"); + } + } + else + { + LOGINFO("device tag name is empty, skip this point!!!!"); + } + } + + delete rqtControlPoint; + rqtControlPoint = nullptr; + } + +} +void CmdHandleThread::putReceiveMsg(mosquitto_message msg) +{ + boost::mutex::scoped_lock lock(m_RxMutex); + m_RxBuffer.push(msg); +} + +string CmdHandleThread::getSubscription() +{ + return m_cmdHandleConfig.Subscription; +} diff --git a/product/src/fes/protocol/mqtt_yxCloud/CmdHandleThread.h b/product/src/fes/protocol/mqtt_yxCloud/CmdHandleThread.h new file mode 100644 index 00000000..e26e51d9 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/CmdHandleThread.h @@ -0,0 +1,52 @@ +#pragma once +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "pub_utility_api/TimerThreadBase.h" +#include "mosquitto.h" + +#include "net_msg_bus_api/MsgBusApi.h" + + +namespace fes_yxCloud { + typedef struct{ + int RtuNo; + std::string Subscription; + }SCmdHandleConfig; + + class CmdHandleThread: public iot_public::CTimerThreadBase,CProtocolBase + { + public: + CmdHandleThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,vector vecConfig); + virtual ~CmdHandleThread(); + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + 处理点的输出 + */ + virtual void execute(); + + virtual void beforeQuit(); + void putReceiveMsg(mosquitto_message msg); + std::string getSubscription(); + + private: + bool m_bReady;//线程是否准备好 + CFesChanPtr m_ptrCFesChan; + CFesBase* m_ptrCFesBase; + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区 + SCmdHandleConfig m_cmdHandleConfig; + std::queue m_RxBuffer; + boost::mutex m_RxMutex; + + iot_net::CMbCommunicator* m_ptrMbComm{NULL}; + + private: + void handleMsg(mosquitto_message& msg); + }; + +typedef boost::shared_ptr CCmdHandleThreadPtr; +} diff --git a/product/src/fes/protocol/mqtt_yxCloud/MQTTHandleThread.cpp b/product/src/fes/protocol/mqtt_yxCloud/MQTTHandleThread.cpp new file mode 100644 index 00000000..d75cfa36 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/MQTTHandleThread.cpp @@ -0,0 +1,339 @@ +#include "MQTTHandleThread.h" +#include +#include +#include +#include + +using namespace fes_yxCloud ; + +static const int CACHE_SIZE = 1000; //<消息环形缓冲区的大小 +const int gMqttHandleThreadTime = 10; +std::string g_KeyPassword; //私钥密码 +static int password_callback(char* buf, int size, int rwflag, void* userdata) +{ + boost::ignore_unused(rwflag); + boost::ignore_unused(userdata); + memcpy(buf, g_KeyPassword.data(), size); + buf[size - 1] = '\0'; + + return (int)strlen(buf); +} + +MQTTHandleThread::MQTTHandleThread(CFesBase *ptrCFesBase, CFesChanPtr ptrCFesChan, const vector vecMqttConfig,CCmdHandleThreadPtr ptrCmd) + : CTimerThreadBase("MQTTHandleThread", gMqttHandleThreadTime,0,true),m_bReady(true),m_buffer(CACHE_SIZE) +{ + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if (m_ptrCFesChan == NULL ) + { + return; + } + + CFesRtuPtr ptrCFesRtu=GetRtuDataByChanData(m_ptrCFesChan); + + bool found = false; + if(vecMqttConfig.size()>0) + { + for (size_t i = 0; i < vecMqttConfig.size(); i++) + { + if(ptrCFesRtu->m_Param.RtuNo == vecMqttConfig[i].RtuNo) + { + //配置 + m_mqttConfig=vecMqttConfig[i]; + found = true; + break; + } + } + } + m_ptrCmd=ptrCmd; + m_ptrCmd->resume(); + + m_ptrMbCommHandleThread = boost::make_shared(); + m_ptrMbCommHandleThread->resume(); + + if(found) + { + mqttConnect(); + } + else + { + m_bReady=false; + } +} + +MQTTHandleThread::~MQTTHandleThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + + if(m_mqttClient) + { + m_mqttClient->disconnect(); + delete m_mqttClient; + } + + //释放mosqpp库 + mosqpp::lib_cleanup(); + LOGINFO("MQTTHandleThread::~MQTTHandleThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); +} + +int MQTTHandleThread::beforeExecute() +{ + return iotSuccess; +} + +void MQTTHandleThread::execute() +{ + if(!m_bReady) + { + LOGERROR("MQTTHandleThread ChanNo=%d has bad and do nothing ", m_ptrCFesChan->m_Param.ChanNo); + return; + } + int rc = m_mqttClient->loop(); + if (rc != MOSQ_ERR_SUCCESS) { + LOGERROR("MQTTHandleThread::execute() ChanNo=%d reconnect %s %d", m_ptrCFesChan->m_Param.ChanNo,strerror(rc),rc); + m_bConnected = false; + int resultConnect=m_mqttClient->reconnect(); + if(resultConnect==MOSQ_ERR_SUCCESS) + { + m_bConnected = true; + } + else + { + LOGERROR("MQTTHandleThread::execute() ChanNo=%d reconnect faild", m_ptrCFesChan->m_Param.ChanNo); + } + } + + mosquitto_message msg; + if(m_mqttClient->get_message(msg)>0) + { + m_ptrCmd->putReceiveMsg(msg); + } + + + DeviceData stdd; + bool bNeedSend=false; + { + boost::mutex::scoped_lock lock(m_bufferMutex); + if(m_buffer.size()==CACHE_SIZE) + { + LOGWARN("MQTTHandleThread.cpp ChanNo=%d data packet is full load ", m_ptrCFesChan->m_Param.ChanNo); + } + + if(m_buffer.size()>0) + { + if(m_bConnected) + { + stdd=m_buffer.front(); + m_buffer.pop_front(); + bNeedSend=true; + } + else + { + LOGWARN("MQTTHandleThread.cpp ChanNo=%d disconnected and data will next time try", m_ptrCFesChan->m_Param.ChanNo); + } + } + else + { + //return; + } + } + + if(bNeedSend) + { + mqttPublish(stdd.topic,stdd.content->SerializeAsString()); + } + + SPublishMsg pubmsg; + if( m_ptrMbCommHandleThread->getPublishMsg(pubmsg) > 0 ) + { + mqttPublish(pubmsg.topic, pubmsg.msg); + } +} + +void MQTTHandleThread::beforeQuit() +{ + LOGTRACE("MQTTHandleThread::beforeQuit() "); +} + +bool MQTTHandleThread::mqttPublish(const string &mqttTopic, const string &mqttPayload) +{ + boost::mutex::scoped_lock lock(m_publishMutex); + //主题和内容为空 + if ((mqttTopic.length() < 1) || (mqttPayload.length() < 1)) + return true; + + //发布主题数据 + int rc = m_mqttClient->publish(NULL, mqttTopic.data(), (int)mqttPayload.length(), mqttPayload.data(), m_mqttConfig.QoS, m_mqttConfig.Retain); + if (rc != MOSQ_ERR_SUCCESS) + { + std::string msg="MQTT 上抛失败 "+mqttTopic; + LOGDEBUG("MQTTHandleThread.cpp publish-err ChanNo:%d %s:%d %s", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo,msg.data()); + ShowChanData(msg); + return false; + } + + if (m_mqttConfig.WillFlag > 0) + { + m_mqttClient->will_set(mqttTopic.data(), (int)mqttPayload.length(), mqttPayload.data(), m_mqttConfig.WillQos, m_mqttConfig.Retain); + } + + return true; +} + +bool MQTTHandleThread::mqttSubscribe(string subTopic) +{ + bool ret = false; + int rc = m_mqttClient->subscribe(NULL, subTopic.data()); + if( MOSQ_ERR_SUCCESS != rc) + { + LOGINFO("subscribeRc != MOSQ_ERR_SUCCESS Error: %s" , mosquitto_strerror(rc)); + }else + { + ret = true; + } + + return ret; +} + +bool MQTTHandleThread::mqttUnSubscribe(string unTopic) +{ + bool ret = false; + int rc = m_mqttClient->unsubscribe(NULL, unTopic.data()); + if( MOSQ_ERR_SUCCESS != rc) + { + LOGINFO("unsubscribeRc != MOSQ_ERR_SUCCESS Error: %s" , mosquitto_strerror(rc)); + }else + { + ret = true; + } + + return ret; +} + +void MQTTHandleThread::pushMessage(std::string deviceTag, std::string topic,com_relyez_ems_common::TypePoint& points) +{ + if(!m_bReady) + { + LOGERROR("MQTTHandleThread ChanNo=%d topic %s refuse putMessage", m_ptrCFesChan->m_Param.ChanNo,deviceTag.c_str()); + return ; + } + + + auto it=m_mapDeviceData.find(deviceTag); + if(it!=m_mapDeviceData.end()) + { + DeviceData& dd=it->second; + com_relyez_ems_common::RequestReportPoint* requestReportPoint=dd.content->mutable_reportpoint(); + com_relyez_ems_common::TypePoint* typePoint=requestReportPoint->add_typepoint(); + typePoint->CopyFrom(points); + + } + else + { + DeviceData dd; + dd.topic=topic; + dd.content=boost::make_shared(); + dd.content->set_reporttype(com_relyez_ems_common::ReportType::REPORT_DEVICE_POINT); + com_relyez_ems_common::RequestReportPoint* requestReportPoint=dd.content->mutable_reportpoint(); + com_relyez_ems_common::TypePoint* typePoint=requestReportPoint->add_typepoint(); + typePoint->CopyFrom(points); + m_mapDeviceData[deviceTag]=dd; + } + + + +} + +void MQTTHandleThread::deviceCanPublish(string deviceTag) +{ + auto it=m_mapDeviceData.find(deviceTag); + if(it!=m_mapDeviceData.end()) + { + DeviceData& dd=it->second; + boost::posix_time::ptime current_time = boost::posix_time::second_clock::local_time(); + std::stringstream ss; + boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%Y-%m-%d %H:%M:%S"); + ss.imbue(std::locale(std::cout.getloc(), facet)); + ss << current_time; + { + boost::mutex::scoped_lock lock(m_bufferMutex); + dd.content->mutable_reportpoint()->set_time(ss.str()); + m_buffer.push_back(dd); + } + + m_mapDeviceData.erase(deviceTag); + } +} + +void MQTTHandleThread::mqttConnect() +{ + mosqpp::lib_init(); + m_mqttClient=new CMosquitto(m_mqttConfig.ClientId.data()); + m_mqttClient->subscription=m_ptrCmd->getSubscription(); + int ret = 0; + char slog[256]; + memset(slog, 0, 256); + + //不判断服务器地址 + m_mqttClient->tls_insecure_set(1); + + //设置SSL加密(可以考虑去掉) + if (m_mqttConfig.sslFlag == 2) //双向加密 + { + //2022-9-21 lj tls_opt_set需要设置为0,即不验证服务器证书,山东海辰服务器的证书有问题,认证不过 + m_mqttClient->tls_opts_set(0, m_mqttConfig.tls_version.data(), NULL); + if (m_mqttConfig.keyPassword.length() < 1) + m_mqttClient->tls_set(m_mqttConfig.caFile.data(), m_mqttConfig.caPath.data(), m_mqttConfig.certFile.data(), m_mqttConfig.keyFile.data()); + else + { + //更新私钥的密码 + g_KeyPassword = m_mqttConfig.keyPassword; + m_mqttClient->tls_set(m_mqttConfig.caFile.data(), m_mqttConfig.caPath.data(), m_mqttConfig.certFile.data(), m_mqttConfig.keyFile.data(), password_callback); + } + LOGDEBUG("MQTTHandleThread.cpp ChanNo:%d MqttConnect caFile=%s keyPassword=%d!", m_ptrCFesChan->m_Param.ChanNo, m_mqttConfig.caFile.data(), (int)m_mqttConfig.keyPassword.length()); + } + else if (m_mqttConfig.sslFlag == 1) //单向加密 + { + //2022-9-21 lj tls_opt_set需要设置为0,即不验证服务器证书,山东海辰服务器的证书有问题,认证不过 + m_mqttClient->tls_opts_set(0, m_mqttConfig.tls_version.data(), NULL); + m_mqttClient->tls_set(m_mqttConfig.caFile.data()); + } + + if (m_mqttConfig.QoS) + m_mqttClient->message_retry_set(3); + + //设置用户名和密码 + if (m_mqttConfig.PasswordFlag) + m_mqttClient->username_pw_set(m_mqttConfig.UserName.data(), m_mqttConfig.Password.data()); + + + std::string serverIp=m_ptrCFesChan->m_Param.NetRoute[0].NetDesc; + int port=m_ptrCFesChan->m_Param.NetRoute[0].PortNo; + ret = m_mqttClient->connect(serverIp.data(), port, m_mqttConfig.KeepAlive); + if (ret != MOSQ_ERR_SUCCESS) + { + sprintf_s(slog, sizeof(slog),"MQTT %s:%d 连接失败!", serverIp.data(),port); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGERROR("MQTTHandleThread.cpp MQTT %s:%d连接失败!", serverIp.data(), port); + return; + } + + m_bConnected=true; + + sprintf_s(slog, sizeof(slog),"MQTT %s:%d 连接成功!", serverIp.data(), port); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog,CN_SFesSimComFrameTypeSend); + LOGINFO("MQTTHandleThread.cpp ChanNo:%d MQTT %s:%d连接成功!", m_ptrCFesChan->m_Param.ChanNo, serverIp.data(), port); +} + +void MQTTHandleThread::ShowChanData(const string &msgData) +{ + const char* host = m_ptrCFesChan->m_Param.NetRoute[0].NetDesc; + size_t neededSize = snprintf(nullptr, 0, "mqtt host: %s, content: %s", host, msgData.c_str()) + 1; // +1 for null terminator + char* slog = new char[neededSize]; + sprintf_s(slog, neededSize, "mqtt host: %s, content: %s", host, msgData.c_str()); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + delete[] slog; +} diff --git a/product/src/fes/protocol/mqtt_yxCloud/MQTTHandleThread.h b/product/src/fes/protocol/mqtt_yxCloud/MQTTHandleThread.h new file mode 100644 index 00000000..6d55d2e3 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/MQTTHandleThread.h @@ -0,0 +1,99 @@ +#pragma once +#include "CMosquitto.h" +#include "pub_utility_api/TimerThreadBase.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "boost/circular_buffer.hpp" +#include +#include +#include +#include "CmdHandleThread.h" +#include "./proto/RequestReport.pb.h" +#include "./proto/RequestReportPoint.pb.h" +#include "./proto/TypePoint.pb.h" +#include "./proto/EnumBase.pb.h" +#include "CMbCommHandleThread.h" + + + +typedef boost::shared_ptr SRequestReportPtr; + +namespace fes_yxCloud { + typedef struct{ + int RtuNo; + int PasswordFlag; + std::string ClientId; //客户端ID + std::string UserName; //用户名 + std::string Password; //密码 + + int KeepAlive; //心跳检测时间间隔 + bool Retain; //MQTT服务器是否保持消息 默认0 + int QoS; //服务质量 默认1 + int WillFlag; //遗愿消息标志 默认1 + int WillQos; //遗愿消息服务质量 默认1 + + //SSL加密配置参数 + int sslFlag; //SSL加密标志 0不加密 1单向加密 2双向加密 + std::string tls_version; //加密协议版本 + std::string caPath; //加密文件路径 + std::string caFile; //CA文件名 + std::string certFile; //证书文件名 + std::string keyFile; //私钥文件名 + std::string keyPassword; //私钥密码 + + }SYxcloudMqttsConfig; + + typedef struct { + std::string topic;//主题 + SRequestReportPtr content; + }DeviceData; + + typedef boost::container::map DeviceDataMap; + + class MQTTHandleThread: public iot_public::CTimerThreadBase,CProtocolBase + { + public: + MQTTHandleThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector mqttConfig,CCmdHandleThreadPtr ptrCmd); + virtual ~MQTTHandleThread(); + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + bool mqttPublish(const std::string& mqttTopic, const std::string& mqttPayload); + + bool mqttSubscribe(std::string subTopic); + + bool mqttUnSubscribe(std::string unTopic); + + void pushMessage(std::string deviceTag,std::string topic,com_relyez_ems_common::TypePoint& points); + + void deviceCanPublish(std::string deviceTag); + + private: + void mqttConnect(); + void ShowChanData(const std::string& msgData); + private: + CMosquitto *m_mqttClient; + SYxcloudMqttsConfig m_mqttConfig; + std::atomic m_bConnected{false}; + CFesChanPtr m_ptrCFesChan; + CFesBase* m_ptrCFesBase; + boost::mutex m_bufferMutex;//消息锁 + boost::mutex m_publishMutex;//发布锁 + bool m_bReady;//线程是否准备好 + boost::circular_buffer m_buffer; //待发送消息缓冲区 + CCmdHandleThreadPtr m_ptrCmd; + DeviceDataMap m_mapDeviceData;//[deviceTag,data] + CMbCommHandleThreadPtr m_ptrMbCommHandleThread; + }; + + typedef boost::shared_ptr CMQTTHandleThreadPtr; +} diff --git a/product/src/fes/protocol/mqtt_yxCloud/Md5/Md5.cpp b/product/src/fes/protocol/mqtt_yxCloud/Md5/Md5.cpp new file mode 100644 index 00000000..c6664c5e --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/Md5/Md5.cpp @@ -0,0 +1,372 @@ +#include "Md5.h" + +//using namespace std; + +/* Constants for MD5Transform routine. */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + + +/* F, G, H and I are basic MD5 functions. +*/ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. +*/ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. +*/ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} + + +const byte MD5::PADDING[64] = { 0x80 }; +const char MD5::HEX[16] = +{ + '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f' +}; + +/* Default construct. */ +MD5::MD5() +{ + + reset(); +} + +/* Construct a MD5 object with a input buffer. */ +MD5::MD5(const void *input, size_t length) +{ + reset(); + update(input, length); +} + +/* Construct a MD5 object with a string. */ +MD5::MD5(const string &str) +{ + reset(); + update(str); +} + +/* Construct a MD5 object with a file. */ +MD5::MD5(ifstream &in) +{ + reset(); + update(in); +} + +/* Return the message-digest */ +const byte *MD5::digest() +{ + if (!_finished) + { + _finished = true; + final(); + } + return _digest; +} + +/* Reset the calculate state */ +void MD5::reset() +{ + + _finished = false; + /* reset number of bits. */ + _count[0] = _count[1] = 0; + /* Load magic initialization constants. */ + _state[0] = 0x67452301; + _state[1] = 0xefcdab89; + _state[2] = 0x98badcfe; + _state[3] = 0x10325476; +} + +/* Updating the context with a input buffer. */ +void MD5::update(const void *input, size_t length) +{ + update((const byte *)input, length); +} + +/* Updating the context with a string. */ +void MD5::update(const string &str) +{ + update((const byte *)str.c_str(), str.length()); +} + +/* Updating the context with a file. */ +void MD5::update(ifstream &in) +{ + + if (!in) + { + return; + } + + const size_t BUFFER_SIZE = 1024; + std::streamsize length; + char buffer[BUFFER_SIZE]; + while (!in.eof()) + { + in.read(buffer, BUFFER_SIZE); + length = in.gcount(); + if (length > 0) + { + update(buffer, length); + } + } + in.close(); +} + +/* MD5 block update operation. Continues an MD5 message-digest +operation, processing another message block, and updating the +context. +*/ +void MD5::update(const byte *input, size_t length) +{ + + uint32 i, index, partLen; + + _finished = false; + + /* Compute number of bytes mod 64 */ + index = (uint32)((_count[0] >> 3) & 0x3f); + + /* update number of bits */ + if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) + { + _count[1]++; + } + _count[1] += ((uint32)length >> 29); + + partLen = 64 - index; + + /* transform as many times as possible. */ + if (length >= partLen) + { + + memcpy(&_buffer[index], input, partLen); + transform(_buffer); + + for (i = partLen; i + 63 < length; i += 64) + { + transform(&input[i]); + } + index = 0; + + } + else + { + i = 0; + } + + /* Buffer remaining input */ + memcpy(&_buffer[index], &input[i], length - i); +} + +/* MD5 finalization. Ends an MD5 message-_digest operation, writing the +the message _digest and zeroizing the context. +*/ +void MD5::final() +{ + + byte bits[8]; + uint32 oldState[4]; + uint32 oldCount[2]; + uint32 index, padLen; + + /* Save current state and count. */ + memcpy(oldState, _state, 16); + memcpy(oldCount, _count, 8); + + /* Save number of bits */ + encode(_count, bits, 8); + + /* Pad out to 56 mod 64. */ + index = (uint32)((_count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + update(PADDING, padLen); + + /* Append length (before padding) */ + update(bits, 8); + + /* Store state in digest */ + encode(_state, _digest, 16); + + /* Restore current state and count. */ + memcpy(_state, oldState, 16); + memcpy(_count, oldCount, 8); +} + +/* MD5 basic transformation. Transforms _state based on block. */ +void MD5::transform(const byte block[64]) +{ + + uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16]; + + decode(block, x, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + _state[0] += a; + _state[1] += b; + _state[2] += c; + _state[3] += d; +} + +/* Encodes input (ulong) into output (byte). Assumes length is +a multiple of 4. +*/ +void MD5::encode(const uint32 *input, byte *output, size_t length) +{ + + for (size_t i = 0, j = 0; j < length; i++, j += 4) + { + output[j] = (byte)(input[i] & 0xff); + output[j + 1] = (byte)((input[i] >> 8) & 0xff); + output[j + 2] = (byte)((input[i] >> 16) & 0xff); + output[j + 3] = (byte)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (byte) into output (ulong). Assumes length is +a multiple of 4. +*/ +void MD5::decode(const byte *input, uint32 *output, size_t length) +{ + + for (size_t i = 0, j = 0; j < length; i++, j += 4) + { + output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) | + (((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24); + } +} + +/* Convert byte array to hex string. */ +string MD5::bytesToHexString(const byte *input, size_t length) +{ + string str; + str.reserve(length << 1); + for (size_t i = 0; i < length; i++) + { + int t = input[i]; + int a = t / 16; + int b = t % 16; + str.append(1, HEX[a]); + str.append(1, HEX[b]); + } + return str; +} + +/* Convert digest to string value */ +string MD5::toString() +{ + return bytesToHexString(digest(), 16); +} diff --git a/product/src/fes/protocol/mqtt_yxCloud/Md5/Md5.h b/product/src/fes/protocol/mqtt_yxCloud/Md5/Md5.h new file mode 100644 index 00000000..826a9cf1 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/Md5/Md5.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include + +/* Type define */ +typedef unsigned char byte; +typedef unsigned int uint32; + +using std::string; +using std::ifstream; + +/* MD5 declaration. */ +class MD5 +{ +public: + MD5(); + MD5(const void *input, size_t length); + MD5(const string &str); + MD5(ifstream &in); + void update(const void *input, size_t length); + void update(const string &str); + void update(ifstream &in); + const byte *digest(); + string toString(); + void reset(); +private: + void update(const byte *input, size_t length); + void final(); + void transform(const byte block[64]); + void encode(const uint32 *input, byte *output, size_t length); + void decode(const byte *input, uint32 *output, size_t length); + string bytesToHexString(const byte *input, size_t length); + + /* class uncopyable */ + MD5(const MD5 &); + MD5 &operator=(const MD5 &); +private: + uint32 _state[4]; /* state (ABCD) */ + uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */ + byte _buffer[64]; /* input buffer */ + byte _digest[16]; /* message digest */ + bool _finished; /* calculate finished ? */ + + static const byte PADDING[64]; /* padding for calculate */ + static const char HEX[16]; + static const size_t BUFFER_SIZE; + +}; diff --git a/product/src/fes/protocol/mqtt_yxCloud/Yxcloudmqtts.cpp b/product/src/fes/protocol/mqtt_yxCloud/Yxcloudmqtts.cpp new file mode 100644 index 00000000..04a337bd --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/Yxcloudmqtts.cpp @@ -0,0 +1,515 @@ +#include "Yxcloudmqtts.h" +#include "pub_utility_api/CommonConfigParse.h" +#include +using namespace iot_public; + +CYxcloudmqtts Yxcloudmqtts; +bool g_YxcloudmqttsIsMainFes=false; +bool g_YxcloudmqttsChanelRun=true; + +int EX_SetBaseAddr(void *address) +{ + Yxcloudmqtts.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + Yxcloudmqtts.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + Yxcloudmqtts.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + Yxcloudmqtts.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + Yxcloudmqtts.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + LOGDEBUG("yxcloud_mqttV1 EX_ExitSystem() start"); + g_YxcloudmqttsChanelRun=false;//使所有的线程退出。 + Yxcloudmqtts.ExitSystem(flag); + LOGDEBUG("yxcloud_mqttV1 EX_ExitSystem() end"); + return iotSuccess; +} +CYxcloudmqtts::CYxcloudmqtts() +{ + // 2020-02-13 thxiao ReadConfigParam()需要使用m_ptrCFesBase,所以改为SetBaseAddr()处调用 + //ReadConfigParam(); + m_ProtocolId = 0; +} + +CYxcloudmqtts::~CYxcloudmqtts() +{ + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); +} + + +int CYxcloudmqtts::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + ReadConfigParam(); + } + return iotSuccess; +} + +int CYxcloudmqtts::SetProperty(int IsMainFes) +{ + g_YxcloudmqttsIsMainFes = (bool)IsMainFes; + LOGDEBUG("CYxcloudmqtts::SetProperty g_YxcloudmqttsIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief CYxcloudmqtts::OpenChan 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CYxcloudmqtts::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if ((OpenFlag == CN_FesChanThread_Flag) || (OpenFlag == CN_FesChanAndDataThread_Flag)) + { + switch (ptrFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + case CN_FesTcpServer: + break; + default: + LOGERROR("CYxcloudmqtts EX_OpenChan() ChanNo:%d CommType=%d is not TCP SERVER/Client!", ptrFesChan->m_Param.ChanNo, ptrFesChan->m_Param.CommType); + return iotFailed; + } + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + fes_yxCloud::CCmdHandleThreadPtr ptrCmd=boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_cmdHandleConfig); + fes_yxCloud::CMQTTHandleThreadPtr ptrMQTT=boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_mqttConfig,ptrCmd); + CYxcloudmqttsDataProcThreadPtr ptrCDataProc; + ptrCDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_vecAppParam,ptrMQTT); + if (ptrCDataProc == NULL) + { + LOGERROR("CYxcloudmqtts EX_OpenChan() ChanNo:%d create CYxcloudmqttsDataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + LOGINFO("CYxcloudmqtts EX_OpenChan() ChanNo:%d create CYxcloudmqttsDataProcThreadPtr ok!", ptrFesChan->m_Param.ChanNo); + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; +} + +/** + * @brief CYxcloudmqtts::CloseChan 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CYxcloudmqtts::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("CYxcloudmqtts::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + return iotSuccess; +} + +/** + * @brief CYxcloudmqtts::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int CYxcloudmqtts::ChanTimer(int MainChanNo) +{ + boost::ignore_unused(MainChanNo); + //把命令缓冲时间间隔到的命放到发送命令缓冲区 + return iotSuccess; +} + +int CYxcloudmqtts::ExitSystem(int flag) +{ + boost::ignore_unused(flag); + InformTcpThreadExit(); + return iotSuccess; +} + +void CYxcloudmqtts::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + CYxcloudmqttsDataProcThreadPtr ptrTcp; + + if ((tempNum = (int)m_CDataProcQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CDataProcQueue.erase(it);//会调用CYxcloudmqttsDataProcThread::~CYxcloudmqttsDataProcThread()退出线程 + LOGDEBUG("CYxcloudmqtts::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + +/** +* @brief CYxcloudmqtts::ReadConfigParam +* 读取Yxcloudmqtts配置文件 +* @return 成功返回iotSuccess,失败返回iotFailed +*/ +int CYxcloudmqtts::ReadConfigParam() +{ + CCommonConfigParse config; + int ivalue; + std::string strvalue; + char strRtuNo[48]; + SYxcloudmqttsAppConfigParam param; + fes_yxCloud::SYxcloudMqttsConfig mqttConfig; + fes_yxCloud::SCmdHandleConfig cmdConfig; + std::size_t items,i,j; + CFesChanPtr ptrChan; //CHAN数据区 + CFesRtuPtr ptrRTU; + + + if (m_ptrCFesBase == NULL) + return iotFailed; + + m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"mqtt_yxCloud"); + if (m_ProtocolId == -1) + { + LOGERROR("ReadConfigParam ProtoclID error"); + return iotFailed; + } + LOGINFO("mqtt_yxCloud ProtoclID=%d", m_ProtocolId); + + if (config.load("../../data/fes/", "mqtt_yxCloud.xml") == iotFailed) + { + LOGERROR("mqtt_yxCloud load mqtt_yxCloud.xml error"); + return iotSuccess; + } + LOGINFO("mqtt_yxCloud load mqtt_yxCloud.xml ok"); + + for (i= 0; i < m_ptrCFesBase->m_vectCFesChanPtr.size(); i++) + { + ptrChan = m_ptrCFesBase->m_vectCFesChanPtr[i]; + if ((ptrChan->m_Param.Used == 1) && (m_ProtocolId == ptrChan->m_Param.ProtocolId)) + { + //found RTU + for (j = 0; j < m_ptrCFesBase->m_vectCFesRtuPtr.size(); j++) + { + ptrRTU = m_ptrCFesBase->m_vectCFesRtuPtr[j]; + if (ptrRTU->m_Param.Used && (ptrRTU->m_Param.ChanNo == ptrChan->m_Param.ChanNo)) + { + memset(&strRtuNo[0], 0, sizeof(strRtuNo)); + sprintf(strRtuNo, "RTU%d", ptrRTU->m_Param.RtuNo); + //memset(¶m, 0, sizeof(param)); + param.RtuNo = ptrRTU->m_Param.RtuNo; + items = 0; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "topicConfigPath", strvalue) == iotSuccess) + { + param.topicConfigPath = strvalue; + items++; + } + else + { + param.topicConfigPath.clear(); + } + + if (config.getIntValue(strRtuNo, "cycCheckFileTime", ivalue) == iotSuccess) + { + param.cycCheckFileTime = ivalue; + items++; + } + else + { + param.cycCheckFileTime=0; + } + + if (config.getIntValue(strRtuNo, "startDelay", ivalue) == iotSuccess) + { + param.startDelay = ivalue; + items++; + } + else + { + param.startDelay = 30;//30s + } + + + + if (items > 0)//对应的RTU有配置项 + { + m_vecAppParam.push_back(param); + } + + + //mqtt的配置 + items = 0; + mqttConfig.RtuNo = ptrRTU->m_Param.RtuNo; + if (config.getIntValue(strRtuNo, "PasswordFlag", ivalue) == iotSuccess) + { + mqttConfig.PasswordFlag = ivalue; + items++; + } + else + { + mqttConfig.PasswordFlag = 0; + } + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "ClientId", strvalue) == iotSuccess) + { + mqttConfig.ClientId = strvalue; + items++; + } + else + { + //获取当前时间 + char timeBuff[256]; + memset(timeBuff , 0 , 256); + std::time_t now = std::time(nullptr); + std::tm* now_tm = std::localtime(&now); + std::strftime(timeBuff , 256 , "%Y%m%d%H%M%S" , now_tm); + mqttConfig.ClientId = "yxCloudClient_"; //避免ID一样导致不停的发送信息 + mqttConfig.ClientId.append(timeBuff); + } + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "UserName", strvalue) == iotSuccess) + { + mqttConfig.UserName = strvalue; + items++; + } + else + { + mqttConfig.UserName.clear(); + + } + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "Password", strvalue) == iotSuccess) + { + mqttConfig.Password = strvalue; + items++; + } + else + { + mqttConfig.Password.clear(); + } + + if (config.getIntValue(strRtuNo, "KeepAlive", ivalue) == iotSuccess) + { + mqttConfig.KeepAlive = ivalue; + items++; + } + else + { + mqttConfig.KeepAlive = 180; //心跳检测时间间隔 + } + + if (config.getIntValue(strRtuNo, "Retain", ivalue) == iotSuccess) + { + mqttConfig.Retain = (bool)(ivalue & 0x01); + items++; + } + else + { + mqttConfig.Retain = false; //默认0 + } + + if (config.getIntValue(strRtuNo, "QoS", ivalue) == iotSuccess) + { + mqttConfig.QoS = ivalue; + items++; + } + else + { + mqttConfig.QoS = 1; + } + + if (config.getIntValue(strRtuNo, "WillFlag", ivalue) == iotSuccess) + { + mqttConfig.WillFlag = ivalue; + items++; + } + else + { + mqttConfig.WillFlag = 1; + } + + + if (config.getIntValue(strRtuNo, "WillQos", ivalue) == iotSuccess) + { + mqttConfig.WillQos = ivalue; + items++; + } + else + { + mqttConfig.WillQos = 1; + } + + + if (config.getIntValue(strRtuNo, "sslFlag", ivalue) == iotSuccess) + { + mqttConfig.sslFlag = ivalue; + items++; + } + else + { + mqttConfig.sslFlag = 0; + } + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "tls_version", strvalue) == iotSuccess) + { + mqttConfig.tls_version = strvalue; + items++; + } + else + { + mqttConfig.tls_version = "tlsv1.1"; + } + strvalue.clear(); + if (config.getStringValue(strRtuNo, "caPath", strvalue) == iotSuccess) + { + mqttConfig.caPath = strvalue; + items++; + } + else + mqttConfig.caPath = "../../data/fes/"; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "caFile", strvalue) == iotSuccess) + { + mqttConfig.caFile = mqttConfig.caPath + strvalue; + items++; + } + else + mqttConfig.caFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "certFile", strvalue) == iotSuccess) + { + mqttConfig.certFile = mqttConfig.caPath + strvalue; + items++; + } + else + mqttConfig.certFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "keyFile", strvalue) == iotSuccess) + { + mqttConfig.keyFile = mqttConfig.caPath + strvalue; + items++; + } + else + mqttConfig.keyFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "keyPassword", strvalue) == iotSuccess) + { + mqttConfig.keyPassword = strvalue; + items++; + } + else + mqttConfig.keyPassword.clear(); + + + if (items > 0)//对应的RTU有配置项 + { + m_mqttConfig.push_back(mqttConfig); + } + + + //命令配置 + items = 0; + cmdConfig.RtuNo = ptrRTU->m_Param.RtuNo; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "Subscription", strvalue) == iotSuccess) + { + cmdConfig.Subscription = strvalue; + items++; + } + else + { + cmdConfig.Subscription.clear(); + + } + + + if (items > 0)//对应的RTU有配置项 + { + m_cmdHandleConfig.push_back(cmdConfig); + } + + } + } + } + } + return iotSuccess; +} + +/** + * @brief CYxcloudmqtts::InformTcpThreadExit + * 设置线程退出标志,通知线程退出 + * @return + */ +void CYxcloudmqtts::InformTcpThreadExit() +{ + +} diff --git a/product/src/fes/protocol/mqtt_yxCloud/Yxcloudmqtts.h b/product/src/fes/protocol/mqtt_yxCloud/Yxcloudmqtts.h new file mode 100644 index 00000000..a5003b78 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/Yxcloudmqtts.h @@ -0,0 +1,40 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "YxcloudmqttsDataProcThread.h" + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API CYxcloudmqtts : public CProtocolBase +{ +public: + CYxcloudmqtts(); + ~CYxcloudmqtts(); + + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + vector m_CDataProcQueue; + vector m_vecAppParam; + + vector m_mqttConfig; + vector m_cmdHandleConfig; + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + int ExitSystem(int flag); + int ReadConfigParam(); + void InformTcpThreadExit(); +private: + int m_ProtocolId; + void ClearDataProcThreadByChanNo(int ChanNo); +}; diff --git a/product/src/fes/protocol/mqtt_yxCloud/YxcloudmqttsDataProcThread.cpp b/product/src/fes/protocol/mqtt_yxCloud/YxcloudmqttsDataProcThread.cpp new file mode 100644 index 00000000..7c04e94f --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/YxcloudmqttsDataProcThread.cpp @@ -0,0 +1,723 @@ +#include +#include "YxcloudmqttsDataProcThread.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" +#include +#include + + +using namespace iot_public; + + +extern bool g_YxcloudmqttsIsMainFes; +extern bool g_YxcloudmqttsChanelRun; +const int gYxcloudmqttsThreadTime = 10; + + +CYxcloudmqttsDataProcThread::CYxcloudmqttsDataProcThread(CFesBase *ptrCFesBase, CFesChanPtr ptrCFesChan, const vector vecAppParam,fes_yxCloud::CMQTTHandleThreadPtr ptrMQTT) : + CTimerThreadBase("YxcloudmqttsDataProcThread", gYxcloudmqttsThreadTime, 0, true),m_bReady(true) +{ + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + + m_ptrMQTT=ptrMQTT; + m_ptrMQTT->resume(); + + + + m_timerCountReset = 10; + m_timerCount = 0; + m_AppData.startTime=getMonotonicMsec() / 1000; + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL)) + { + return; + } + m_ptrCFesChan->SetLinkStatus(CN_FesChanConnect); + m_ptrCFesChan->SetComThreadRunFlag(CN_FesRunFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + //2020-03-03 thxiao 不需要数据变化 + m_ptrCFesRtu->SetFwAiChgStop(1); + m_ptrCFesRtu->SetFwDiChgStop(1); + m_ptrCFesRtu->SetFwDDiChgStop(1); + m_ptrCFesRtu->SetFwMiChgStop(1); + m_ptrCFesRtu->SetFwAccChgStop(1); + + bool found = false; + if (vecAppParam.size() > 0) + { + for (size_t i = 0; i < vecAppParam.size(); i++) + { + if (m_ptrCFesRtu->m_Param.RtuNo == vecAppParam[i].RtuNo) + { + //配置 + m_AppData.RtuNo = vecAppParam[i].RtuNo; + m_AppData.topicConfigPath = vecAppParam[i].topicConfigPath; + m_AppData.cycCheckFileTime = vecAppParam[i].cycCheckFileTime; + m_AppData.startDelay=vecAppParam[i].startDelay; + m_AppData.lastReadFileTime=0; + found = true; + break; + } + } + } + //读取mqtt_topic_cfg.csv文件,并更新参数确定map + if(found) + { + GetTopicCfg(); + } + else + { + m_bReady=false; + LOGERROR("YxcloudmqttsDataProcThread ChanNo=%d can not match rtuNo in config due to now rtuNo is %d and do nothing", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo); + } + +} + +CYxcloudmqttsDataProcThread::~CYxcloudmqttsDataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + + ClearTopicStr(); + + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + LOGDEBUG("CYxcloudmqttsDataProcThread::~CYxcloudmqttsDataProcThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); +} + +/** + * @brief CYxcloudmqttsDataProcThread::beforeExecute + * + */ +int CYxcloudmqttsDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief CYxcloudmqttsDataProcThread::execute + + */ +void CYxcloudmqttsDataProcThread::execute() +{ + if(!m_bReady) + { + LOGERROR("CYxcloudmqttsDataProcThread ChanNo=%d rtuNo %d has bad and do nothing ", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo); + return; + } + + if (m_timerCount++ >= m_timerCountReset) + m_timerCount = 0;// 1sec is ready + + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + if (m_ptrCurrentChan == NULL) + return; + int64 cursec = getMonotonicMsec() / 1000; + if (m_AppData.startDelay > 0) + { + if ((cursec - m_AppData.startTime) < m_AppData.startDelay) + { + return; + } + } + + + //秒级判断流程 + TimerProcess(); + + //主机才转发 + if(!g_YxcloudmqttsIsMainFes) + { + return; + } + //mqtt转发流程 + YxcloudmqttsProcess(); +} + +/* + @brief 执行quit函数前的处理 + */ +void CYxcloudmqttsDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetComThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetLinkStatus(CN_FesChanDisconnect); + + LOGDEBUG("CYxcloudmqttsDataProcThread::beforeQuit() "); +} + + +void CYxcloudmqttsDataProcThread::TimerProcess() +{ + //启动主线程判断逻辑 + bool needUpdate=ifNeedUpdateCache(); + if(needUpdate) + { + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + + //定时读取遥控命令响应缓冲区,及时清除队列释放空间,不对遥控成败作处理 + if (m_ptrCFesRtu->GetFwDoRespCmdNum() > 0) + { + SFesFwDoRespCmd retCmd; + m_ptrCFesRtu->ReadFwDoRespCmd(1, &retCmd); + } + + if (m_ptrCFesRtu->GetFwAoRespCmdNum() > 0) + { + SFesFwAoRespCmd retCmd; + m_ptrCFesRtu->ReadFwAoRespCmd(1, &retCmd); + } + } +} + +void CYxcloudmqttsDataProcThread::YxcloudmqttsProcess() +{ + + //全量数据上送 + ifTimeToPublish(); +} + + +//获取文件MD5 +std::string CYxcloudmqttsDataProcThread::GetFileMd5(const std::string &file) +{ + ifstream in(file.c_str(), ios::binary); + if (!in) + return ""; + + MD5 md5; + std::streamsize length; + char buffer[1024]; + while (!in.eof()) + { + in.read(buffer, 1024); + length = in.gcount(); + if (length > 0) + md5.update(buffer, length); + } + in.close(); + return md5.toString(); +} + +bool CYxcloudmqttsDataProcThread::ifNeedUpdateCache() +{ + std::string md5Str; + //系统启动后的运行的秒数 + int64 cursec = getMonotonicMsec() / 1000; + + //周期检查文件是否修改 + if(0!= m_AppData.cycCheckFileTime) + { + if ((cursec - m_AppData.lastReadFileTime) > m_AppData.cycCheckFileTime) + { + m_AppData.lastReadFileTime = cursec; + + //配置参数修改后,需要在线更新 + md5Str = GetFileMd5(m_AppData.topicConfigPath); + if (md5Str != m_AppData.topicCfgMd5) + { + m_AppData.topicCfgMd5 = md5Str; + //读取mqtt_topic_cfg.csv文件,并更新参数 + GetTopicCfg(); + } + } + } + + + bool needUpdate=false; + //检查各个Topic的发送周期是否到了 + cursec=getUTCTimeSec(); + for(auto it= m_AppData.deviceTopicMap.begin();it!= m_AppData.deviceTopicMap.end();++it) + { + + TopicInfo& deviceTopic=it->second; + if(0==deviceTopic.lastNeedPublish) + { + deviceTopic.lastNeedPublish=getUTCTimeSec(); + deviceTopic.needPublish=true; + needUpdate=true; + continue; + } + if(0==deviceTopic.interval) + { + deviceTopic.needPublish=false; + continue; + } + if(cursec-deviceTopic.lastNeedPublish>=deviceTopic.interval) + { + deviceTopic.lastNeedPublish=getUTCTimeSec(); + deviceTopic.needPublish=true; + needUpdate=true; + } + else + { + deviceTopic.needPublish=false; + } + + + } + + + return needUpdate; +} + + +//清空topic列表 +void CYxcloudmqttsDataProcThread::ClearTopicStr() +{ + m_AppData.deviceTopicMap.clear(); +} + +void CYxcloudmqttsDataProcThread::ifTimeToPublish() +{ + //轮询点位看是否需要属于需要发送的主题 + handleAiData(); + handleDiData(); + handleAccData(); + handleMiData(); +} + +void CYxcloudmqttsDataProcThread::handleAiData() +{ + double fvalue; + SFesFwAi *pFwAi; + std::string preDevice; + com_relyez_ems_common::TypePoint typePoint; + typePoint.set_type("0"); + + for (int aiPoint = 0; aiPoint < m_ptrCFesRtu->m_MaxFwAiPoints; aiPoint++) + { + pFwAi = m_ptrCFesRtu->m_pFwAi + aiPoint; + + std::string tagname = pFwAi->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + auto it=m_AppData.deviceTopicMap.find(deviceName); + if(it!=m_AppData.deviceTopicMap.end()) + { + if(!(it->second.needPublish)) + { + continue; + } + } + else + { + continue; + } + + if(preDevice.empty()) + { + preDevice=deviceName; + } + + if(preDevice!=deviceName) + { + //handle last time msg + if(0!=typePoint.point_size()) + { + m_ptrMQTT->pushMessage(deviceName,it->second.topic,typePoint); + m_ptrMQTT->deviceCanPublish(deviceName); + } + typePoint.clear_point(); + preDevice=deviceName; + } + + + fvalue = pFwAi->Value*pFwAi->Coeff + pFwAi->Base; + com_relyez_ems_common::Point* devPoint = typePoint.add_point(); + devPoint->set_tagname(tagname); + int proParams1 = pFwAi->ResParam1; + devPoint->set_protocolparameter1(to_string(proParams1)); + if( pFwAi->Status&CN_FesValueInvaild)//点值无效传NULL + { + devPoint->set_value("NULL"); + } + else if(pFwAi->Status&CN_FesValueComDown)//通讯中断也需要传NULL + { + devPoint->set_value("NULL"); + } + else + { + std::string fmtVal=formatToPrecision(fvalue); + devPoint->set_value(fmtVal.c_str()); + } + + if(aiPoint==(m_ptrCFesRtu->m_MaxFwAiPoints-1)) + { + //the end device + m_ptrMQTT->pushMessage(deviceName,it->second.topic,typePoint); + m_ptrMQTT->deviceCanPublish(deviceName); + typePoint.clear_point(); + preDevice=deviceName; + } + + + } + + +} + +void CYxcloudmqttsDataProcThread::handleDiData() +{ + unsigned char yxbit; + SFesFwDi *pFwDi; + std::string preDevice; + com_relyez_ems_common::TypePoint typePoint; + typePoint.set_type("1"); + + for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxFwDiPoints; diPoint++) + { + pFwDi = m_ptrCFesRtu->m_pFwDi + diPoint; + + std::string tagname = pFwDi->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + auto it=m_AppData.deviceTopicMap.find(deviceName); + if(it!=m_AppData.deviceTopicMap.end()) + { + if(!(it->second.needPublish)) + { + continue; + } + } + else + { + continue; + } + + if(preDevice.empty()) + { + preDevice=deviceName; + } + + if(preDevice!=deviceName) + { + //handle last time msg + if(0!=typePoint.point_size()) + { + m_ptrMQTT->pushMessage(deviceName,it->second.topic,typePoint); + m_ptrMQTT->deviceCanPublish(deviceName); + } + typePoint.clear_point(); + preDevice=deviceName; + } + + + yxbit = pFwDi->Value & 0x01; + com_relyez_ems_common::Point* devPoint = typePoint.add_point(); + devPoint->set_tagname(tagname); + int proParams1 = pFwDi->ResParam1; + devPoint->set_protocolparameter1(to_string(proParams1)); + if( pFwDi->Status&CN_FesValueInvaild) + { + devPoint->set_value("NULL"); + }else + { + devPoint->set_value(to_string(yxbit).c_str()); + } + + if(diPoint==(m_ptrCFesRtu->m_MaxFwDiPoints-1)) + { + //the end device + m_ptrMQTT->pushMessage(deviceName,it->second.topic,typePoint); + m_ptrMQTT->deviceCanPublish(deviceName); + typePoint.clear_point(); + preDevice=deviceName; + } + + + } + +} + +void CYxcloudmqttsDataProcThread::handleAccData() +{ + double fvalue; + SFesFwAcc *pFwAcc; + std::string preDevice; + com_relyez_ems_common::TypePoint typePoint; + typePoint.set_type("3"); + + for (int accPoint = 0; accPoint < m_ptrCFesRtu->m_MaxFwAccPoints; accPoint++) + { + pFwAcc = m_ptrCFesRtu->m_pFwAcc + accPoint; + + std::string tagname = pFwAcc->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + auto it=m_AppData.deviceTopicMap.find(deviceName); + if(it!=m_AppData.deviceTopicMap.end()) + { + if(!(it->second.needPublish)) + { + continue; + } + } + else + { + continue; + } + + if(preDevice.empty()) + { + preDevice=deviceName; + } + + if(preDevice!=deviceName) + { + //handle last time msg + if(0!=typePoint.point_size()) + { + m_ptrMQTT->pushMessage(deviceName,it->second.topic,typePoint); + m_ptrMQTT->deviceCanPublish(deviceName); + } + typePoint.clear_point(); + preDevice=deviceName; + } + + + fvalue = pFwAcc->Value*pFwAcc->Coeff + pFwAcc->Base; + com_relyez_ems_common::Point* devPoint = typePoint.add_point(); + devPoint->set_tagname(tagname); + int proParams1 = pFwAcc->ResParam1; + devPoint->set_protocolparameter1(to_string(proParams1)); + if( pFwAcc->Status&CN_FesValueInvaild) + { + devPoint->set_value("NULL"); + }else + { + std::string fmtVal=formatToPrecision(fvalue); + devPoint->set_value(fmtVal.c_str()); + } + + if(accPoint==(m_ptrCFesRtu->m_MaxFwAccPoints-1)) + { + //the end device + m_ptrMQTT->pushMessage(deviceName,it->second.topic,typePoint); + m_ptrMQTT->deviceCanPublish(deviceName); + typePoint.clear_point(); + preDevice=deviceName; + } + + + } + +} + +void CYxcloudmqttsDataProcThread::handleMiData() +{ + double fvalue; + SFesFwMi *pFwMi; + std::string preDevice; + com_relyez_ems_common::TypePoint typePoint; + typePoint.set_type("2"); + + for (int miPoint = 0; miPoint < m_ptrCFesRtu->m_MaxFwMiPoints; miPoint++) + { + pFwMi = m_ptrCFesRtu->m_pFwMi + miPoint; + + std::string tagname = pFwMi->DPTagName; + std::string deviceName=getDeviceNameByTag(tagname); + if(deviceName.empty()) + { + continue; + } + auto it=m_AppData.deviceTopicMap.find(deviceName); + if(it!=m_AppData.deviceTopicMap.end()) + { + if(!(it->second.needPublish)) + { + continue; + } + } + else + { + continue; + } + + if(preDevice.empty()) + { + preDevice=deviceName; + } + + if(preDevice!=deviceName) + { + //handle last time msg + if(0!=typePoint.point_size()) + { + m_ptrMQTT->pushMessage(deviceName,it->second.topic,typePoint); + m_ptrMQTT->deviceCanPublish(deviceName); + } + typePoint.clear_point(); + preDevice=deviceName; + } + + + fvalue = pFwMi->Value*pFwMi->Coeff + pFwMi->Base; + com_relyez_ems_common::Point* devPoint = typePoint.add_point(); + devPoint->set_tagname(tagname); + int proParams1 = pFwMi->ResParam1; + devPoint->set_protocolparameter1(to_string(proParams1)); + if( pFwMi->Status&CN_FesValueInvaild) + { + devPoint->set_value("NULL"); + }else + { + std::string fmtVal=formatToPrecision(fvalue); + devPoint->set_value(fmtVal.c_str()); + } + + if(miPoint==(m_ptrCFesRtu->m_MaxFwMiPoints-1)) + { + //the end device + m_ptrMQTT->pushMessage(deviceName,it->second.topic,typePoint); + m_ptrMQTT->deviceCanPublish(deviceName); + typePoint.clear_point(); + preDevice=deviceName; + } + + + } + +} + +string CYxcloudmqttsDataProcThread::formatToPrecision(double dvalue) +{ + std::ostringstream oss;//保留3位小数 + oss << std::fixed << std::setprecision(3) << dvalue; + std::string result = oss.str(); + size_t found = result.find_last_not_of('0');//去掉多余的0和点 + if (found != std::string::npos) + { + if (result[found] == '.') + result.erase(found); + else + result.erase(found + 1); + } + + return result; +} + + + +void CYxcloudmqttsDataProcThread::GetTopicCfg() +{ + ClearTopicStr(); + auto csvData=parseCSV(m_AppData.topicConfigPath); + //去掉表头 + csvData.erase(csvData.begin()); + for (size_t i = 0; i < csvData.size(); ++i) { + //[topic,device,interval] + if(csvData[i].size()>=3) + { + auto deviceName=csvData[i][1]; + TopicInfo stTopic; + stTopic.topic=csvData[i][0]; + int value=10; + try { + value = std::stoi(csvData[i][2]); // 尝试将字符串转换为整数 + } catch (const std::invalid_argument& e) { + LOGERROR("%s invalid_argument at index-%s",csvData[i][3].data(),stTopic.topic.data()); + } catch (const std::out_of_range& e) { + LOGERROR("%s out_of_range at index-%s",csvData[i][3].data(),stTopic.topic.data()); + } + stTopic.interval=value; + stTopic.needPublish=false; + stTopic.lastNeedPublish=0; + m_AppData.deviceTopicMap[deviceName]=stTopic; + } + else + { + LOGERROR("%s error size--%d and need 3 col",m_AppData.topicConfigPath.data(),(int)csvData[i].size()); + + } + } + + +} + + + +string CYxcloudmqttsDataProcThread::getDeviceNameByTag(const string &tagName) +{ + // 查找最后一个点的位置 + std::size_t pos = tagName.rfind('.'); + std::string result="NULL"; + if (pos != std::string::npos) { + // 截取从开头到最后一个点之前的部分 + result = tagName.substr(0, pos); + } + + return result; +} + +std::vector > CYxcloudmqttsDataProcThread::parseCSV(const string &filename) +{ + std::vector> data; + char line[1024]; + FILE *fpin; + if ((fpin = fopen(filename.c_str(), "r")) == NULL) + { + LOGERROR("mqtt_yxCloud load mqttconfigtopic.csv error %s",filename.c_str()); + return data; + } + + + while (fgets(line, 1024, fpin) != NULL) + { + char *token; + token = strtok(line, ","); + int j = 0; + std::vector row; + while (token != NULL) + { + if (0 == j)//主题 + { + if (strlen(token) <= 0) + break; + row.push_back(token); + } + else if (1 == j)//后台设备标签名 + { + if (strlen(token) <= 0) + break; + row.push_back(token); + } + else if(2 == j)//上传周期 + { + if (strlen(token) <= 0) + break; + row.push_back(token); + } + else + break; + token = strtok(NULL, ","); + j++; + } + + data.push_back(row); + } + fclose(fpin); + + return data; +} + diff --git a/product/src/fes/protocol/mqtt_yxCloud/YxcloudmqttsDataProcThread.h b/product/src/fes/protocol/mqtt_yxCloud/YxcloudmqttsDataProcThread.h new file mode 100644 index 00000000..d9c5ef50 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/YxcloudmqttsDataProcThread.h @@ -0,0 +1,117 @@ +#pragma once +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "mosquitto.h" +#include "mosquittopp.h" +#include "Md5/Md5.h" +#include "MQTTHandleThread.h" + + + +using namespace iot_public; +struct TopicInfo +{ + std::string topic; //topic + int interval; //上送周期(s)设备的上送周期 + int64_t lastNeedPublish; //最近一次需要上送时间(每次循环检查) + bool needPublish; //是否需要发布标记位(循环检查时间后更新标志位) + TopicInfo() { + topic = ""; + interval = 0; + lastNeedPublish = 0; + needPublish = false; + } +}; + +typedef boost::container::map CTopicMap; +//本FES数据跟新间隔 +const int CN_YxcloudmqttsStartUpateTime = 10000;//10s +const int CN_YxcloudmqttsNormalUpateTime = 60000;//60s + +//配置参数 +typedef struct{ + int RtuNo; + int cycCheckFileTime;//周期检查文件时间(s),0即不检查 + int startDelay;//延迟启动上送时间 + std::string topicConfigPath;//主题配置的csv文件 +}SYxcloudmqttsAppConfigParam; + +//Hccloudmqtts 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct{ + int RtuNo; + int cycCheckFileTime;//周期检查文件时间(s),0即不检查 + int startDelay;//延迟启动上送时间 + int startTime;//线程的启动时间 + int64 lastReadFileTime;//最近读取文件时间 + std::string topicCfgMd5;//mqtt_topic_cfg文件MD5 + std::string topicConfigPath;//主题配置的csv文件 + CTopicMap deviceTopicMap;//[设备标签,主题信息] +}SYxcloudmqttsAppData; + + +class CYxcloudmqttsDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + CYxcloudmqttsDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam,fes_yxCloud::CMQTTHandleThreadPtr ptrMQTT); + virtual ~CYxcloudmqttsDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + CFesBase* m_ptrCFesBase; + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,Yxcloudmqtts tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SYxcloudmqttsAppData m_AppData; //内部应用数据结构 + fes_yxCloud::CMQTTHandleThreadPtr m_ptrMQTT; + + +private: + int m_timerCount; + int m_timerCountReset; + bool m_bReady;//线程是否准备好 + + + void TimerProcess(); + void YxcloudmqttsProcess(); + void GetTopicCfg(); + + //获取MD5 + std::string GetFileMd5(const std::string &file); + + + + //是否需要更新本fes的数据 + bool ifNeedUpdateCache(); + void ClearTopicStr(); + + + //数据到了上送时间 + void ifTimeToPublish(); + void handleAiData(); + void handleDiData(); + void handleAccData(); + void handleMiData(); + + + //格式化数据 + std::string formatToPrecision(double dvalue); + + + + //根据标签名获取设备名 + std::string getDeviceNameByTag(const std::string& tagName); + + std::vector> parseCSV(const std::string& filename); +}; + +typedef boost::shared_ptr CYxcloudmqttsDataProcThreadPtr; diff --git a/product/src/fes/protocol/mqtt_yxCloud/mosquitto.h b/product/src/fes/protocol/mqtt_yxCloud/mosquitto.h new file mode 100644 index 00000000..879184dc --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/mosquitto.h @@ -0,0 +1,3084 @@ +/* +Copyright (c) 2010-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_H +#define MOSQUITTO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(WIN32) && !defined(WITH_BROKER) && !defined(LIBMOSQUITTO_STATIC) +# ifdef libmosquitto_EXPORTS +# define libmosq_EXPORT __declspec(dllexport) +# else +# define libmosq_EXPORT __declspec(dllimport) +# endif +#else +# define libmosq_EXPORT +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# ifndef __cplusplus +# define bool char +# define true 1 +# define false 0 +# endif +#else +# ifndef __cplusplus +# include +# endif +#endif + +#include +#include + +#define LIBMOSQUITTO_MAJOR 1 +#define LIBMOSQUITTO_MINOR 6 +#define LIBMOSQUITTO_REVISION 10 +/* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ +#define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION) + +/* Log types */ +#define MOSQ_LOG_NONE 0 +#define MOSQ_LOG_INFO (1<<0) +#define MOSQ_LOG_NOTICE (1<<1) +#define MOSQ_LOG_WARNING (1<<2) +#define MOSQ_LOG_ERR (1<<3) +#define MOSQ_LOG_DEBUG (1<<4) +#define MOSQ_LOG_SUBSCRIBE (1<<5) +#define MOSQ_LOG_UNSUBSCRIBE (1<<6) +#define MOSQ_LOG_WEBSOCKETS (1<<7) +#define MOSQ_LOG_INTERNAL 0x80000000U +#define MOSQ_LOG_ALL 0xFFFFFFFFU + +/* Error values */ +enum mosq_err_t { + MOSQ_ERR_AUTH_CONTINUE = -4, + MOSQ_ERR_NO_SUBSCRIBERS = -3, + MOSQ_ERR_SUB_EXISTS = -2, + MOSQ_ERR_CONN_PENDING = -1, + MOSQ_ERR_SUCCESS = 0, + MOSQ_ERR_NOMEM = 1, + MOSQ_ERR_PROTOCOL = 2, + MOSQ_ERR_INVAL = 3, + MOSQ_ERR_NO_CONN = 4, + MOSQ_ERR_CONN_REFUSED = 5, + MOSQ_ERR_NOT_FOUND = 6, + MOSQ_ERR_CONN_LOST = 7, + MOSQ_ERR_TLS = 8, + MOSQ_ERR_PAYLOAD_SIZE = 9, + MOSQ_ERR_NOT_SUPPORTED = 10, + MOSQ_ERR_AUTH = 11, + MOSQ_ERR_ACL_DENIED = 12, + MOSQ_ERR_UNKNOWN = 13, + MOSQ_ERR_ERRNO = 14, + MOSQ_ERR_EAI = 15, + MOSQ_ERR_PROXY = 16, + MOSQ_ERR_PLUGIN_DEFER = 17, + MOSQ_ERR_MALFORMED_UTF8 = 18, + MOSQ_ERR_KEEPALIVE = 19, + MOSQ_ERR_LOOKUP = 20, + MOSQ_ERR_MALFORMED_PACKET = 21, + MOSQ_ERR_DUPLICATE_PROPERTY = 22, + MOSQ_ERR_TLS_HANDSHAKE = 23, + MOSQ_ERR_QOS_NOT_SUPPORTED = 24, + MOSQ_ERR_OVERSIZE_PACKET = 25, + MOSQ_ERR_OCSP = 26, +}; + +/* Option values */ +enum mosq_opt_t { + MOSQ_OPT_PROTOCOL_VERSION = 1, + MOSQ_OPT_SSL_CTX = 2, + MOSQ_OPT_SSL_CTX_WITH_DEFAULTS = 3, + MOSQ_OPT_RECEIVE_MAXIMUM = 4, + MOSQ_OPT_SEND_MAXIMUM = 5, + MOSQ_OPT_TLS_KEYFORM = 6, + MOSQ_OPT_TLS_ENGINE = 7, + MOSQ_OPT_TLS_ENGINE_KPASS_SHA1 = 8, + MOSQ_OPT_TLS_OCSP_REQUIRED = 9, + MOSQ_OPT_TLS_ALPN = 10, +}; + + +/* MQTT specification restricts client ids to a maximum of 23 characters */ +#define MOSQ_MQTT_ID_MAX_LENGTH 23 + +#define MQTT_PROTOCOL_V31 3 +#define MQTT_PROTOCOL_V311 4 +#define MQTT_PROTOCOL_V5 5 + +struct mosquitto_message{ + int mid; + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct mosquitto; +typedef struct mqtt5__property mosquitto_property; + +/* + * Topic: Threads + * libmosquitto provides thread safe operation, with the exception of + * which is not thread safe. + * + * If your application uses threads you must use to + * tell the library this is the case, otherwise it makes some optimisations + * for the single threaded case that may result in unexpected behaviour for + * the multi threaded case. + */ +/*************************************************** + * Important note + * + * The following functions that deal with network operations will return + * MOSQ_ERR_SUCCESS on success, but this does not mean that the operation has + * taken place. An attempt will be made to write the network data, but if the + * socket is not available for writing at that time then the packet will not be + * sent. To ensure the packet is sent, call mosquitto_loop() (which must also + * be called to process incoming network data). + * This is especially important when disconnecting a client that has a will. If + * the broker does not receive the DISCONNECT command, it will assume that the + * client has disconnected unexpectedly and send the will. + * + * mosquitto_connect() + * mosquitto_disconnect() + * mosquitto_subscribe() + * mosquitto_unsubscribe() + * mosquitto_publish() + ***************************************************/ + + +/* ====================================================================== + * + * Section: Library version, init, and cleanup + * + * ====================================================================== */ +/* + * Function: mosquitto_lib_version + * + * Can be used to obtain version information for the mosquitto library. + * This allows the application to compare the library version against the + * version it was compiled against by using the LIBMOSQUITTO_MAJOR, + * LIBMOSQUITTO_MINOR and LIBMOSQUITTO_REVISION defines. + * + * Parameters: + * major - an integer pointer. If not NULL, the major version of the + * library will be returned in this variable. + * minor - an integer pointer. If not NULL, the minor version of the + * library will be returned in this variable. + * revision - an integer pointer. If not NULL, the revision of the library will + * be returned in this variable. + * + * Returns: + * LIBMOSQUITTO_VERSION_NUMBER, which is a unique number based on the major, + * minor and revision values. + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_version(int *major, int *minor, int *revision); + +/* + * Function: mosquitto_lib_init + * + * Must be called before any other mosquitto functions. + * + * This function is *not* thread safe. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_UNKNOWN - on Windows, if sockets couldn't be initialized. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_init(void); + +/* + * Function: mosquitto_lib_cleanup + * + * Call to free resources associated with the library. + * + * Returns: + * MOSQ_ERR_SUCCESS - always + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_cleanup(void); + + +/* ====================================================================== + * + * Section: Client creation, destruction, and reinitialisation + * + * ====================================================================== */ +/* + * Function: mosquitto_new + * + * Create a new mosquitto client instance. + * + * Parameters: + * id - String to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Note that a client will never discard its own outgoing + * messages on disconnect. Calling or + * will cause the messages to be resent. + * Use to reset a client to its + * original state. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * Pointer to a struct mosquitto on success. + * NULL on failure. Interrogate errno to determine the cause for the failure: + * - ENOMEM on out of memory. + * - EINVAL on invalid input parameters. + * + * See Also: + * , , + */ +libmosq_EXPORT struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj); + +/* + * Function: mosquitto_destroy + * + * Use to free memory associated with a mosquitto client instance. + * + * Parameters: + * mosq - a struct mosquitto pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_destroy(struct mosquitto *mosq); + +/* + * Function: mosquitto_reinitialise + * + * This function allows an existing mosquitto client to be reused. Call on a + * mosquitto instance to close any open network connections, free memory + * and reinitialise the client with the new parameters. The end result is the + * same as the output of . + * + * Parameters: + * mosq - a valid mosquitto instance. + * id - string to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *obj); + + +/* ====================================================================== + * + * Section: Will + * + * ====================================================================== */ +/* + * Function: mosquitto_will_set + * + * Configure will information for a mosquitto instance. By default, clients do + * not have a will. This must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + */ +libmosq_EXPORT int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + +/* + * Function: mosquitto_will_set_v5 + * + * Configure will information for a mosquitto instance, with attached + * properties. By default, clients do not have a will. This must be called + * before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * properties - list of MQTT 5 properties. Can be NULL. On success only, the + * property list becomes the property of libmosquitto once this + * function is called and will be freed by the library. The + * property list must be freed by the application on error. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + * MOSQ_ERR_NOT_SUPPORTED - if properties is not NULL and the client is not + * using MQTT v5 + * MOSQ_ERR_PROTOCOL - if a property is invalid for use with wills. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + */ +libmosq_EXPORT int mosquitto_will_set_v5(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties); + +/* + * Function: mosquitto_will_clear + * + * Remove a previously configured will. This must be called before calling + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_will_clear(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Username and password + * + * ====================================================================== */ +/* + * Function: mosquitto_username_pw_set + * + * Configure username and password for a mosquitto instance. By default, no + * username or password will be sent. For v3.1 and v3.1.1 clients, if username + * is NULL, the password argument is ignored. + * + * This is must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * username - the username to send as a string, or NULL to disable + * authentication. + * password - the password to send as a string. Set to NULL when username is + * valid in order to send just a username. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password); + + +/* ====================================================================== + * + * Section: Connecting, reconnecting, disconnecting + * + * ====================================================================== */ +/* + * Function: mosquitto_connect + * + * Connect to an MQTT broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter. Use this function + * if you need to restrict network communication over a particular interface. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_bind_v5 + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter and MQTT v5 + * properties. Use this function if you need to restrict network communication + * over a particular interface. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * properties - the MQTT 5 properties for the connect (not for the Will). + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with CONNECT. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_v5(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, const mosquitto_property *properties); + +/* + * Function: mosquitto_connect_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * This extends the functionality of by adding the + * bind_address parameter. Use this function if you need to restrict network + * communication over a particular interface. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_async(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_srv + * + * Connect to an MQTT broker. + * + * If you set `host` to `example.com`, then this call will attempt to retrieve + * the DNS SRV record for `_secure-mqtt._tcp.example.com` or + * `_mqtt._tcp.example.com` to discover which actual host to connect to. + * + * DNS SRV support is not usually compiled in to libmosquitto, use of this call + * is not recommended. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname to search for an SRV record. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_srv(struct mosquitto *mosq, const char *host, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_reconnect + * + * Reconnect to a broker. + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * call. It must not be called before + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_reconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_reconnect_async + * + * Reconnect to a broker. Non blocking version of . + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * or calls. It must not be + * called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reconnect_async(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect + * + * Disconnect from the broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + */ +libmosq_EXPORT int mosquitto_disconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect_v5 + * + * Disconnect from the broker, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * reason_code - the disconnect reason code. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with DISCONNECT. + */ +libmosq_EXPORT int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Publishing, subscribing, unsubscribing + * + * ====================================================================== */ +/* + * Function: mosquitto_publish + * + * Publish a message on a given topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + + +/* + * Function: mosquitto_publish_v5 + * + * Publish a message on a given topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Requires the mosquitto instance to be connected with MQTT 5. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with PUBLISH. + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_publish_v5( + struct mosquitto *mosq, + int *mid, + const char *topic, + int payloadlen, + const void *payload, + int qos, + bool retain, + const mosquitto_property *properties); + + +/* + * Function: mosquitto_subscribe + * + * Subscribe to a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos); + +/* + * Function: mosquitto_subscribe_v5 + * + * Subscribe to a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Requires the mosquitto instance to be connected with MQTT 5. + * + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * options - options to apply to this subscription, OR'd together. Set to 0 to + * use the default options, otherwise choose from the list: + * MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client + * publishes to a topic to which it is subscribed, the + * broker will not publish the message back to the + * client. + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages + * published for this subscription will keep the + * retain flag as was set by the publishing client. + * The default behaviour without this option set has + * the retain flag indicating whether a message is + * fresh/stale. + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set, + * pre-existing retained messages are sent as soon as + * the subscription is made, even if the subscription + * already exists. This is the default behaviour, so + * it is not necessary to set this option. + * MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing + * retained messages for this subscription will be + * sent when the subscription is made, but only if the + * subscription does not already exist. + * MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set, + * pre-existing retained messages will never be sent + * for this subscription. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with SUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_subscribe_multiple + * + * Subscribe to multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of subscriptions to be made + * sub - array of sub_count pointers, each pointing to a subscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * qos - the requested Quality of Service for each subscription. + * options - options to apply to this subscription, OR'd together. This + * argument is not used for MQTT v3 susbcriptions. Set to 0 to use + * the default options, otherwise choose from the list: + * MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client + * publishes to a topic to which it is subscribed, the + * broker will not publish the message back to the + * client. + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages + * published for this subscription will keep the + * retain flag as was set by the publishing client. + * The default behaviour without this option set has + * the retain flag indicating whether a message is + * fresh/stale. + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set, + * pre-existing retained messages are sent as soon as + * the subscription is made, even if the subscription + * already exists. This is the default behaviour, so + * it is not necessary to set this option. + * MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing + * retained messages for this subscription will be + * sent when the subscription is made, but only if the + * subscription does not already exist. + * MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set, + * pre-existing retained messages will never be sent + * for this subscription. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe + * + * Unsubscribe from a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub); + +/* + * Function: mosquitto_unsubscribe_v5 + * + * Unsubscribe from a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with UNSUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe_multiple + * + * Unsubscribe from multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of unsubscriptions to be made + * sub - array of sub_count pointers, each pointing to an unsubscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Struct mosquitto_message helper functions + * + * ====================================================================== */ +/* + * Function: mosquitto_message_copy + * + * Copy the contents of a mosquitto message to another message. + * Useful for preserving a message received in the on_message() callback. + * + * Parameters: + * dst - a pointer to a valid mosquitto_message struct to copy to. + * src - a pointer to a valid mosquitto_message struct to copy from. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src); + +/* + * Function: mosquitto_message_free + * + * Completely free a mosquitto_message struct. + * + * Parameters: + * message - pointer to a mosquitto_message pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_message_free(struct mosquitto_message **message); + +/* + * Function: mosquitto_message_free_contents + * + * Free a mosquitto_message struct contents, leaving the struct unaffected. + * + * Parameters: + * message - pointer to a mosquitto_message struct to free its contents. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_message_free_contents(struct mosquitto_message *message); + + +/* ====================================================================== + * + * Section: Network loop (managed by libmosquitto) + * + * The internal network loop must be called at a regular interval. The two + * recommended approaches are to use either or + * . is a blocking call and is + * suitable for the situation where you only want to handle incoming messages + * in callbacks. is a non-blocking call, it creates a + * separate thread to run the loop for you. Use this function when you have + * other tasks you need to run at the same time as the MQTT client, e.g. + * reading data from a sensor. + * + * ====================================================================== */ + +/* + * Function: mosquitto_loop_forever + * + * This function call loop() for you in an infinite blocking loop. It is useful + * for the case where you only want to run the MQTT client loop in your + * program. + * + * It handles reconnecting in case server connection is lost. If you call + * mosquitto_disconnect() in a callback it will return. + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets); + +/* + * Function: mosquitto_loop_start + * + * This is part of the threaded client interface. Call this once to start a new + * thread to process network traffic. This provides an alternative to + * repeatedly calling yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_start(struct mosquitto *mosq); + +/* + * Function: mosquitto_loop_stop + * + * This is part of the threaded client interface. Call this once to stop the + * network thread previously created with . This call + * will block until the network thread finishes. For the network thread to end, + * you must have previously called or have set the force + * parameter to true. + * + * Parameters: + * mosq - a valid mosquitto instance. + * force - set to true to force thread cancellation. If false, + * must have already been called. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_stop(struct mosquitto *mosq, bool force); + +/* + * Function: mosquitto_loop + * + * The main network loop for the client. This must be called frequently + * to keep communications between the client and broker working. This is + * carried out by and , which + * are the recommended ways of handling the network loop. You may also use this + * function if you wish. It must not be called inside a callback. + * + * If incoming data is present it will then be processed. Outgoing commands, + * from e.g. , are normally sent immediately that their + * function is called, but this is not always possible. will + * also attempt to send any remaining outgoing messages, which also includes + * commands that are part of the flow for messages with QoS>0. + * + * This calls select() to monitor the client network socket. If you want to + * integrate mosquitto client operation with your own select() call, use + * , , and + * . + * + * Threads: + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets); + +/* ====================================================================== + * + * Section: Network loop (for use in other event loops) + * + * ====================================================================== */ +/* + * Function: mosquitto_loop_read + * + * Carry out network read operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_read(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_write + * + * Carry out network write operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_write(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_misc + * + * Carry out miscellaneous operations required as part of the network loop. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * This function deals with handling PINGs and checking whether messages need + * to be retried, so should be called fairly frequently, around once per second + * is sufficient. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_misc(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Network loop (helper functions) + * + * ====================================================================== */ +/* + * Function: mosquitto_socket + * + * Return the socket handle for a mosquitto instance. Useful if you want to + * include a mosquitto client in your own select() calls. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * The socket for the mosquitto client or -1 on failure. + */ +libmosq_EXPORT int mosquitto_socket(struct mosquitto *mosq); + +/* + * Function: mosquitto_want_write + * + * Returns true if there is data ready to be written on the socket. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * See Also: + * , , + */ +libmosq_EXPORT bool mosquitto_want_write(struct mosquitto *mosq); + +/* + * Function: mosquitto_threaded_set + * + * Used to tell the library that your application is using threads, but not + * using . The library operates slightly differently when + * not in threaded mode in order to simplify its operation. If you are managing + * your own threads and do not use this function you will experience crashes + * due to race conditions. + * + * When using , this is set automatically. + * + * Parameters: + * mosq - a valid mosquitto instance. + * threaded - true if your application is using threads, false otherwise. + */ +libmosq_EXPORT int mosquitto_threaded_set(struct mosquitto *mosq, bool threaded); + + +/* ====================================================================== + * + * Section: Client options + * + * ====================================================================== */ +/* + * Function: mosquitto_opts_set + * + * Used to set options for the client. + * + * This function is deprecated, the replacement and + * functions should be used instead. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_PROTOCOL_VERSION + * Value must be an int, set to either MQTT_PROTOCOL_V31 or + * MQTT_PROTOCOL_V311. Must be set before the client connects. + * Defaults to MQTT_PROTOCOL_V31. + * + * MOSQ_OPT_SSL_CTX + * Pass an openssl SSL_CTX to be used when creating TLS connections + * rather than libmosquitto creating its own. This must be called + * before connecting to have any effect. If you use this option, the + * onus is on you to ensure that you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS + * Value must be an int set to 1 or 0. If set to 1, then the user + * specified SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the + * default options applied to it. This means that you only need to + * change the values that are relevant to you. If you use this + * option then you must configure the TLS options as normal, i.e. + * you should use to configure the cafile/capath + * as a minimum. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + +/* + * Function: mosquitto_int_option + * + * Used to set integer options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_PROTOCOL_VERSION - + * Value must be set to either MQTT_PROTOCOL_V31, + * MQTT_PROTOCOL_V311, or MQTT_PROTOCOL_V5. Must be set before the + * client connects. Defaults to MQTT_PROTOCOL_V311. + * + * MOSQ_OPT_RECEIVE_MAXIMUM - + * Value can be set between 1 and 65535 inclusive, and represents + * the maximum number of incoming QoS 1 and QoS 2 messages that this + * client wants to process at once. Defaults to 20. This option is + * not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the MQTT_PROP_RECEIVE_MAXIMUM property is in the + * proplist passed to mosquitto_connect_v5(), then that property + * will override this option. Using this option is the recommended + * method however. + * + * MOSQ_OPT_SEND_MAXIMUM - + * Value can be set between 1 and 65535 inclusive, and represents + * the maximum number of outgoing QoS 1 and QoS 2 messages that this + * client will attempt to have "in flight" at once. Defaults to 20. + * This option is not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the broker being connected to sends a + * MQTT_PROP_RECEIVE_MAXIMUM property that has a lower value than + * this option, then the broker provided value will be used. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS - + * If value is set to a non zero value, then the user specified + * SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the default + * options applied to it. This means that you only need to change + * the values that are relevant to you. If you use this option then + * you must configure the TLS options as normal, i.e. you should + * use to configure the cafile/capath as a + * minimum. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_TLS_OCSP_REQUIRED - + * Set whether OCSP checking on TLS connections is required. Set to + * 1 to enable checking, or 0 (the default) for no checking. + */ +libmosq_EXPORT int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t option, int value); + + +/* + * Function: mosquitto_void_option + * + * Used to set void* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_SSL_CTX - + * Pass an openssl SSL_CTX to be used when creating TLS connections + * rather than libmosquitto creating its own. This must be called + * before connecting to have any effect. If you use this option, the + * onus is on you to ensure that you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_void_option(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + +/* + * Function: mosquitto_max_inflight_messages_set + * + * This function is deprected. Use the function with the + * MOSQ_OPT_SEND_MAXIMUM option instead. + * + * Set the number of QoS 1 and 2 messages that can be "in flight" at one time. + * An in flight message is part way through its delivery flow. Attempts to send + * further messages with will result in the messages being + * queued until the number of in flight messages reduces. + * + * A higher number here results in greater message throughput, but if set + * higher than the maximum in flight messages on the broker may lead to + * delays in the messages being acknowledged. + * + * Set to 0 for no maximum. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_inflight_messages - the maximum number of inflight messages. Defaults + * to 20. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages); + +/* + * Function: mosquitto_message_retry_set + * + * This function now has no effect. + */ +libmosq_EXPORT void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry); + +/* + * Function: mosquitto_user_data_set + * + * When is called, the pointer given as the "obj" parameter + * will be passed to the callbacks as user data. The + * function allows this obj parameter to be updated at any time. This function + * will not modify the memory pointed to by the current user data pointer. If + * it is dynamically allocated memory you must free it yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * obj - A user pointer that will be passed as an argument to any callbacks + * that are specified. + */ +libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj); + +/* Function: mosquitto_userdata + * + * Retrieve the "userdata" variable for a mosquitto client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * A pointer to the userdata member variable. + */ +libmosq_EXPORT void *mosquitto_userdata(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: TLS support + * + * ====================================================================== */ +/* + * Function: mosquitto_tls_set + * + * Configure the client for certificate based SSL/TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Define the Certificate Authority certificates to be trusted (ie. the server + * certificate must be signed with one of these certificates) using cafile. + * + * If the server you are connecting to requires clients to provide a + * certificate, define certfile and keyfile with your client certificate and + * private key. If your private key is encrypted, provide a password callback + * function or you will have to enter the password at the command line. + * + * Parameters: + * mosq - a valid mosquitto instance. + * cafile - path to a file containing the PEM encoded trusted CA + * certificate files. Either cafile or capath must not be NULL. + * capath - path to a directory containing the PEM encoded trusted CA + * certificate files. See mosquitto.conf for more details on + * configuring this directory. Either cafile or capath must not + * be NULL. + * certfile - path to a file containing the PEM encoded certificate file + * for this client. If NULL, keyfile must also be NULL and no + * client certificate will be used. + * keyfile - path to a file containing the PEM encoded private key for + * this client. If NULL, certfile must also be NULL and no + * client certificate will be used. + * pw_callback - if keyfile is encrypted, set pw_callback to allow your client + * to pass the correct password for decryption. If set to NULL, + * the password must be entered on the command line. + * Your callback must write the password into "buf", which is + * "size" bytes long. The return value must be the length of the + * password. "userdata" will be set to the calling mosquitto + * instance. The mosquitto userdata member variable can be + * retrieved using . + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , , + * , + */ +libmosq_EXPORT int mosquitto_tls_set(struct mosquitto *mosq, + const char *cafile, const char *capath, + const char *certfile, const char *keyfile, + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)); + +/* + * Function: mosquitto_tls_insecure_set + * + * Configure verification of the server hostname in the server certificate. If + * value is set to true, it is impossible to guarantee that the host you are + * connecting to is not impersonating your server. This can be useful in + * initial server testing, but makes it possible for a malicious third party to + * impersonate your server through DNS spoofing, for example. + * Do not use this function in a real system. Setting value to true makes the + * connection encryption pointless. + * Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * value - if set to false, the default, certificate hostname checking is + * performed. If set to true, no hostname checking is performed and + * the connection is insecure. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_insecure_set(struct mosquitto *mosq, bool value); + +/* + * Function: mosquitto_tls_opts_set + * + * Set advanced SSL/TLS options. Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * cert_reqs - an integer defining the verification requirements the client + * will impose on the server. This can be one of: + * * SSL_VERIFY_NONE (0): the server will not be verified in any way. + * * SSL_VERIFY_PEER (1): the server certificate will be verified + * and the connection aborted if the verification fails. + * The default and recommended value is SSL_VERIFY_PEER. Using + * SSL_VERIFY_NONE provides no security. + * tls_version - the version of the SSL/TLS protocol to use as a string. If NULL, + * the default value is used. The default value and the + * available values depend on the version of openssl that the + * library was compiled against. For openssl >= 1.0.1, the + * available options are tlsv1.2, tlsv1.1 and tlsv1, with tlv1.2 + * as the default. For openssl < 1.0.1, only tlsv1 is available. + * ciphers - a string describing the ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tls_version, const char *ciphers); + +/* + * Function: mosquitto_tls_psk_set + * + * Configure the client for pre-shared-key based TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Parameters: + * mosq - a valid mosquitto instance. + * psk - the pre-shared-key in hex format with no leading "0x". + * identity - the identity of this client. May be used as the username + * depending on the server settings. + * ciphers - a string describing the PSK ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers); + + +/* ====================================================================== + * + * Section: Callbacks + * + * ====================================================================== */ +/* + * Function: mosquitto_connect_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_connect_with_flags_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * flags - the connect flags. + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int)); + +/* + * Function: mosquitto_connect_v5_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + * flags - the connect flags. + * props - list of MQTT 5 properties, or NULL + * + */ +libmosq_EXPORT void mosquitto_connect_v5_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int, const mosquitto_property *props)); + +/* + * Function: mosquitto_disconnect_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + */ +libmosq_EXPORT void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_disconnect_v5_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_disconnect_v5_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *)); + +/* + * Function: mosquitto_publish_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker successfully. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + */ +libmosq_EXPORT void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_publish_v5_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker. This callback will be + * called both if the message is sent successfully, or if the broker responded + * with an error, which will be reflected in the reason_code parameter. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + * reason_code - the MQTT 5 reason code + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_publish_v5_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int, int, const mosquitto_property *)); + +/* + * Function: mosquitto_message_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *)); + +/* + * Function: mosquitto_message_v5_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * props - list of MQTT 5 properties, or NULL + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_v5_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *, const mosquitto_property *)); + +/* + * Function: mosquitto_subscribe_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + */ +libmosq_EXPORT void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *)); + +/* + * Function: mosquitto_subscribe_v5_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_subscribe_v5_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *)); + +/* + * Function: mosquitto_unsubscribe_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + */ +libmosq_EXPORT void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_unsubscribe_v5_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, const mosquitto_property *)); + +/* + * Function: mosquitto_log_callback_set + * + * Set the logging callback. This should be used if you want event logging + * information from the client library. + * + * mosq - a valid mosquitto instance. + * on_log - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int level, const char *str) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * level - the log message level from the values: + * MOSQ_LOG_INFO + * MOSQ_LOG_NOTICE + * MOSQ_LOG_WARNING + * MOSQ_LOG_ERR + * MOSQ_LOG_DEBUG + * str - the message string. + */ +libmosq_EXPORT void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *)); + +/* + * Function: mosquitto_string_option + * + * Used to set const char* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_TLS_ENGINE + * Configure the client for TLS Engine support. Pass a TLS Engine ID + * to be used when creating TLS connections. + * Must be set before . + * MOSQ_OPT_TLS_KEYFORM + * Configure the client to treat the keyfile differently depending + * on its type. Must be set before . + * Set as either "pem" or "engine", to determine from where the + * private key for a TLS connection will be obtained. Defaults to + * "pem", a normal private key file. + * MOSQ_OPT_TLS_KPASS_SHA1 + * Where the TLS Engine requires the use of a password to be + * accessed, this option allows a hex encoded SHA1 hash of the + * private key password to be passed to the engine directly. + * Must be set before . + * MOSQ_OPT_TLS_ALPN + * If the broker being connected to has multiple services available + * on a single TLS port, such as both MQTT and WebSockets, use this + * option to configure the ALPN option for the connection. + */ +libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value); + + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + + +/* ============================================================================= + * + * Section: SOCKS5 proxy functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_socks5_set + * + * Configure the client to use a SOCKS5 proxy when connecting. Must be called + * before connecting. "None" and "username/password" authentication is + * supported. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the SOCKS5 proxy host to connect to. + * port - the SOCKS5 proxy port to use. + * username - if not NULL, use this username when authenticating with the proxy. + * password - if not NULL and username is not NULL, use this password when + * authenticating with the proxy. + */ +libmosq_EXPORT int mosquitto_socks5_set(struct mosquitto *mosq, const char *host, int port, const char *username, const char *password); + + +/* ============================================================================= + * + * Section: Utility functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_strerror + * + * Call to obtain a const string description of a mosquitto error number. + * + * Parameters: + * mosq_errno - a mosquitto error number. + * + * Returns: + * A constant string describing the error. + */ +libmosq_EXPORT const char *mosquitto_strerror(int mosq_errno); + +/* + * Function: mosquitto_connack_string + * + * Call to obtain a const string description of an MQTT connection result. + * + * Parameters: + * connack_code - an MQTT connection result. + * + * Returns: + * A constant string describing the result. + */ +libmosq_EXPORT const char *mosquitto_connack_string(int connack_code); + +/* + * Function: mosquitto_reason_string + * + * Call to obtain a const string description of an MQTT reason code. + * + * Parameters: + * reason_code - an MQTT reason code. + * + * Returns: + * A constant string describing the reason. + */ +libmosq_EXPORT const char *mosquitto_reason_string(int reason_code); + +/* Function: mosquitto_string_to_command + * + * Take a string input representing an MQTT command and convert it to the + * libmosquitto integer representation. + * + * Parameters: + * str - the string to parse. + * cmd - pointer to an int, for the result. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - on an invalid input. + * + * Example: + * mosquitto_string_to_command("CONNECT", &cmd); + * // cmd == CMD_CONNECT + */ +libmosq_EXPORT int mosquitto_string_to_command(const char *str, int *cmd); + +/* + * Function: mosquitto_sub_topic_tokenise + * + * Tokenise a topic or subscription string into an array of strings + * representing the topic hierarchy. + * + * For example: + * + * subtopic: "a/deep/topic/hierarchy" + * + * Would result in: + * + * topics[0] = "a" + * topics[1] = "deep" + * topics[2] = "topic" + * topics[3] = "hierarchy" + * + * and: + * + * subtopic: "/a/deep/topic/hierarchy/" + * + * Would result in: + * + * topics[0] = NULL + * topics[1] = "a" + * topics[2] = "deep" + * topics[3] = "topic" + * topics[4] = "hierarchy" + * + * Parameters: + * subtopic - the subscription/topic to tokenise + * topics - a pointer to store the array of strings + * count - an int pointer to store the number of items in the topics array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * + * Example: + * + * > char **topics; + * > int topic_count; + * > int i; + * > + * > mosquitto_sub_topic_tokenise("$SYS/broker/uptime", &topics, &topic_count); + * > + * > for(i=0; i printf("%d: %s\n", i, topics[i]); + * > } + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *count); + +/* + * Function: mosquitto_sub_topic_tokens_free + * + * Free memory that was allocated in . + * + * Parameters: + * topics - pointer to string array. + * count - count of items in string array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokens_free(char ***topics, int count); + +/* + * Function: mosquitto_topic_matches_sub + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * topic - topic to check. + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result); + + +/* + * Function: mosquitto_topic_matches_sub2 + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * sublen - length in bytes of sub string + * topic - topic to check. + * topiclen - length in bytes of topic string + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub2(const char *sub, size_t sublen, const char *topic, size_t topiclen, bool *result); + +/* + * Function: mosquitto_pub_topic_check + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check(const char *topic); + +/* + * Function: mosquitto_pub_topic_check2 + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - length of the topic in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check2(const char *topic, size_t topiclen); + +/* + * Function: mosquitto_sub_topic_check + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check(const char *topic); + +/* + * Function: mosquitto_sub_topic_check2 + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - the length in bytes of the topic + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check2(const char *topic, size_t topiclen); + + +/* + * Function: mosquitto_validate_utf8 + * + * Helper function to validate whether a UTF-8 string is valid, according to + * the UTF-8 spec and the MQTT additions. + * + * Parameters: + * str - a string to check + * len - the length of the string in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if str is NULL or len<0 or len>65536 + * MOSQ_ERR_MALFORMED_UTF8 - if str is not valid UTF-8 + */ +libmosq_EXPORT int mosquitto_validate_utf8(const char *str, int len); + + +/* ============================================================================= + * + * Section: One line client helper functions + * + * ============================================================================= + */ + +struct libmosquitto_will { + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct libmosquitto_auth { + char *username; + char *password; +}; + +struct libmosquitto_tls { + char *cafile; + char *capath; + char *certfile; + char *keyfile; + char *ciphers; + char *tls_version; + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata); + int cert_reqs; +}; + +/* + * Function: mosquitto_subscribe_simple + * + * Helper function to make subscribing to a topic and retrieving some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, waits for msg_count + * messages to be received, then returns after disconnecting cleanly. + * + * Parameters: + * messages - pointer to a "struct mosquitto_message *". The received + * messages will be returned here. On error, this will be set to + * NULL. + * msg_count - the number of messages to retrieve. + * want_retained - if set to true, stale retained messages will be treated as + * normal messages with regards to msg_count. If set to + * false, they will be ignored. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * >0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool want_retained, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* + * Function: mosquitto_subscribe_callback + * + * Helper function to make subscribing to a topic and processing some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, then passes received + * messages to a user provided callback. If the callback returns a 1, it then + * disconnects cleanly and returns. + * + * Parameters: + * callback - a callback function in the following form: + * int callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * Note that this is the same as the normal on_message callback, + * except that it returns an int. + * userdata - user provided pointer that will be passed to the callback. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * >0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* ============================================================================= + * + * Section: Properties + * + * ============================================================================= + */ + + +/* + * Function: mosquitto_property_add_byte + * + * Add a new byte property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_byte(&proplist, MQTT_PROP_PAYLOAD_FORMAT_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value); + +/* + * Function: mosquitto_property_add_int16 + * + * Add a new int16 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_RECEIVE_MAXIMUM) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_int16(&proplist, MQTT_PROP_RECEIVE_MAXIMUM, 1000); + */ +libmosq_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value); + +/* + * Function: mosquitto_property_add_int32 + * + * Add a new int32 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_MESSAGE_EXPIRY_INTERVAL) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_int32(&proplist, MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, 86400); + */ +libmosq_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_varint + * + * Add a new varint property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_SUBSCRIPTION_IDENTIFIER) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_varint(&proplist, MQTT_PROP_SUBSCRIPTION_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_binary + * + * Add a new binary property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to the property data + * len - length of property data in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_binary(&proplist, MQTT_PROP_AUTHENTICATION_DATA, auth_data, auth_data_len); + */ +libmosq_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len); + +/* + * Function: mosquitto_property_add_string + * + * Add a new string property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_CONTENT_TYPE) + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - value is not valid UTF-8. + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_string(&proplist, MQTT_PROP_CONTENT_TYPE, "application/json"); + */ +libmosq_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value); + +/* + * Function: mosquitto_property_add_string_pair + * + * Add a new string pair property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_USER_PROPERTY) + * name - string name for the new property, must be UTF-8 and zero terminated + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if name or value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - if name or value are not valid UTF-8. + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_string_pair(&proplist, MQTT_PROP_USER_PROPERTY, "client", "mosquitto_pub"); + */ +libmosq_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value); + +/* + * Function: mosquitto_property_read_byte + * + * Attempt to read a byte property matching an identifier, from a property list + * or single property. This function can search for multiple entries of the + * same identifier by using the returned value and skip_first. Note however + * that it is forbidden for most properties to be duplicated. + * + * If the property is not found, *value will not be modified, so it is safe to + * pass a variable with a default value to be potentially overwritten: + * + * uint16_t keepalive = 60; // default value + * // Get value from property list, or keep default if not found. + * mosquitto_property_read_int16(proplist, MQTT_PROP_SERVER_KEEP_ALIVE, &keepalive, false); + * + * Parameters: + * proplist - mosquitto_property pointer, the list of properties or single property + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * // proplist is obtained from a callback + * mosquitto_property *prop; + * prop = mosquitto_property_read_byte(proplist, identifier, &value, false); + * while(prop){ + * printf("value: %s\n", value); + * prop = mosquitto_property_read_byte(prop, identifier, &value); + * } + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_byte( + const mosquitto_property *proplist, + int identifier, + uint8_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int16 + * + * Read an int16 property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int16( + const mosquitto_property *proplist, + int identifier, + uint16_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int32 + * + * Read an int32 property value from a property. + * + * Parameters: + * property - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int32( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_varint + * + * Read a varint property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_varint( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_binary + * + * Read a binary property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_binary( + const mosquitto_property *proplist, + int identifier, + void **value, + uint16_t *len, + bool skip_first); + +/* + * Function: mosquitto_property_read_string + * + * Read a string property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string( + const mosquitto_property *proplist, + int identifier, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_read_string_pair + * + * Read a string pair property value pair from a property. + * + * On success, name and value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * name - pointer to char* for the name property data to be stored in, or NULL + * if the name is not required. + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string_pair( + const mosquitto_property *proplist, + int identifier, + char **name, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_free_all + * + * Free all properties from a list of properties. Frees the list and sets *properties to NULL. + * + * Parameters: + * properties - list of properties to free + * + * Example: + * mosquitto_properties *properties = NULL; + * // Add properties + * mosquitto_property_free_all(&properties); + */ +libmosq_EXPORT void mosquitto_property_free_all(mosquitto_property **properties); + +/* + * Function: mosquitto_property_copy_all + * + * Parameters: + * dest : pointer for new property list + * src : property list + * + * Returns: + * MOSQ_ERR_SUCCESS - on successful copy + * MOSQ_ERR_INVAL - if dest is NULL + * MOSQ_ERR_NOMEM - on out of memory (dest will be set to NULL) + */ +libmosq_EXPORT int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_property *src); + +/* + * Function: mosquitto_property_check_command + * + * Check whether a property identifier is valid for the given command. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * identifier - MQTT property (e.g. MQTT_PROP_USER_PROPERTY) + * + * Returns: + * MOSQ_ERR_SUCCESS - if the identifier is valid for command + * MOSQ_ERR_PROTOCOL - if the identifier is not valid for use with command. + */ +libmosq_EXPORT int mosquitto_property_check_command(int command, int identifier); + + +/* + * Function: mosquitto_property_check_all + * + * Check whether a list of properties are valid for a particular command, + * whether there are duplicates, and whether the values are valid where + * possible. + * + * Note that this function is used internally in the library whenever + * properties are passed to it, so in basic use this is not needed, but should + * be helpful to check property lists *before* the point of using them. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * properties - list of MQTT properties to check. + * + * Returns: + * MOSQ_ERR_SUCCESS - if all properties are valid + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid + */ +libmosq_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties); + +/* Function: mosquitto_string_to_property_info + * + * Parse a property name string and convert to a property identifier and data type. + * The property name is as defined in the MQTT specification, with - as a + * separator, for example: payload-format-indicator. + * + * Parameters: + * propname - the string to parse + * identifier - pointer to an int to receive the property identifier + * type - pointer to an int to receive the property type + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the string does not match a property + * + * Example: + * mosquitto_string_to_property_info("response-topic", &id, &type); + * // id == MQTT_PROP_RESPONSE_TOPIC + * // type == MQTT_PROP_TYPE_STRING + */ +libmosq_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/mqtt_yxCloud/mosquitto_plugin.h b/product/src/fes/protocol/mqtt_yxCloud/mosquitto_plugin.h new file mode 100644 index 00000000..b2ef79d0 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/mosquitto_plugin.h @@ -0,0 +1,319 @@ +/* +Copyright (c) 2012-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_PLUGIN_H +#define MOSQUITTO_PLUGIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MOSQ_AUTH_PLUGIN_VERSION 4 + +#define MOSQ_ACL_NONE 0x00 +#define MOSQ_ACL_READ 0x01 +#define MOSQ_ACL_WRITE 0x02 +#define MOSQ_ACL_SUBSCRIBE 0x04 + +#include +#include + +struct mosquitto; + +struct mosquitto_opt { + char *key; + char *value; +}; + +struct mosquitto_auth_opt { + char *key; + char *value; +}; + +struct mosquitto_acl_msg { + const char *topic; + const void *payload; + long payloadlen; + int qos; + bool retain; +}; + +/* + * To create an authentication plugin you must include this file then implement + * the functions listed in the "Plugin Functions" section below. The resulting + * code should then be compiled as a shared library. Using gcc this can be + * achieved as follows: + * + * gcc -I -fPIC -shared plugin.c -o plugin.so + * + * On Mac OS X: + * + * gcc -I -fPIC -shared plugin.c -undefined dynamic_lookup -o plugin.so + * + * Authentication plugins can implement one or both of authentication and + * access control. If your plugin does not wish to handle either of + * authentication or access control it should return MOSQ_ERR_PLUGIN_DEFER. In + * this case, the next plugin will handle it. If all plugins return + * MOSQ_ERR_PLUGIN_DEFER, the request will be denied. + * + * For each check, the following flow happens: + * + * * The default password file and/or acl file checks are made. If either one + * of these is not defined, then they are considered to be deferred. If either + * one accepts the check, no further checks are made. If an error occurs, the + * check is denied + * * The first plugin does the check, if it returns anything other than + * MOSQ_ERR_PLUGIN_DEFER, then the check returns immediately. If the plugin + * returns MOSQ_ERR_PLUGIN_DEFER then the next plugin runs its check. + * * If the final plugin returns MOSQ_ERR_PLUGIN_DEFER, then access will be + * denied. + */ + +/* ========================================================================= + * + * Helper Functions + * + * ========================================================================= */ + +/* There are functions that are available for plugin developers to use in + * mosquitto_broker.h, including logging and accessor functions. + */ + + +/* ========================================================================= + * + * Plugin Functions + * + * You must implement these functions in your plugin. + * + * ========================================================================= */ + +/* + * Function: mosquitto_auth_plugin_version + * + * The broker will call this function immediately after loading the plugin to + * check it is a supported plugin version. Your code must simply return + * MOSQ_AUTH_PLUGIN_VERSION. + */ +int mosquitto_auth_plugin_version(void); + + +/* + * Function: mosquitto_auth_plugin_init + * + * Called after the plugin has been loaded and + * has been called. This will only ever be called once and can be used to + * initialise the plugin. + * + * Parameters: + * + * user_data : The pointer set here will be passed to the other plugin + * functions. Use to hold connection information for example. + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_plugin_cleanup + * + * Called when the broker is shutting down. This will only ever be called once + * per plugin. + * Note that will be called directly before + * this function. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_security_init + * + * This function is called in two scenarios: + * + * 1. When the broker starts up. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, will be called first, then + * this function will be called. In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_init(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_security_cleanup + * + * This function is called in two scenarios: + * + * 1. When the broker is shutting down. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, this function will be called, followed by + * . In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_acl_check + * + * Called by the broker when topic access must be checked. access will be one + * of: + * MOSQ_ACL_SUBSCRIBE when a client is asking to subscribe to a topic string. + * This differs from MOSQ_ACL_READ in that it allows you to + * deny access to topic strings rather than by pattern. For + * example, you may use MOSQ_ACL_SUBSCRIBE to deny + * subscriptions to '#', but allow all topics in + * MOSQ_ACL_READ. This allows clients to subscribe to any + * topic they want, but not discover what topics are in use + * on the server. + * MOSQ_ACL_READ when a message is about to be sent to a client (i.e. whether + * it can read that topic or not). + * MOSQ_ACL_WRITE when a message has been received from a client (i.e. whether + * it can write to that topic or not). + * + * Return: + * MOSQ_ERR_SUCCESS if access was granted. + * MOSQ_ERR_ACL_DENIED if access was not granted. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_acl_check(void *user_data, int access, struct mosquitto *client, const struct mosquitto_acl_msg *msg); + + +/* + * Function: mosquitto_auth_unpwd_check + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making basic username/password checks. + * + * Called by the broker when a username/password must be checked. + * + * Return: + * MOSQ_ERR_SUCCESS if the user is authenticated. + * MOSQ_ERR_AUTH if authentication failed. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_unpwd_check(void *user_data, struct mosquitto *client, const char *username, const char *password); + + +/* + * Function: mosquitto_psk_key_get + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making TLS-PSK checks. + * + * Called by the broker when a client connects to a listener using TLS/PSK. + * This is used to retrieve the pre-shared-key associated with a client + * identity. + * + * Examine hint and identity to determine the required PSK (which must be a + * hexadecimal string with no leading "0x") and copy this string into key. + * + * Parameters: + * user_data : the pointer provided in . + * hint : the psk_hint for the listener the client is connecting to. + * identity : the identity string provided by the client + * key : a string where the hex PSK should be copied + * max_key_len : the size of key + * + * Return value: + * Return 0 on success. + * Return >0 on failure. + * Return MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_psk_key_get(void *user_data, struct mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len); + +/* + * Function: mosquitto_auth_start + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making extended authentication checks. + * + * Parameters: + * user_data : the pointer provided in . + * method : the authentication method + * reauth : this is set to false if this is the first authentication attempt + * on a connection, set to true if the client is attempting to + * reauthenticate. + * data_in : pointer to authentication data, or NULL + * data_in_len : length of data_in, in bytes + * data_out : if your plugin wishes to send authentication data back to the + * client, allocate some memory using malloc or friends and set + * data_out. The broker will free the memory after use. + * data_out_len : Set the length of data_out in bytes. + * + * Return value: + * Return MOSQ_ERR_SUCCESS if authentication was successful. + * Return MOSQ_ERR_AUTH_CONTINUE if the authentication is a multi step process and can continue. + * Return MOSQ_ERR_AUTH if authentication was valid but did not succeed. + * Return any other relevant positive integer MOSQ_ERR_* to produce an error. + */ +int mosquitto_auth_start(void *user_data, struct mosquitto *client, const char *method, bool reauth, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + +int mosquitto_auth_continue(void *user_data, struct mosquitto *client, const char *method, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/mqtt_yxCloud/mosquittopp.h b/product/src/fes/protocol/mqtt_yxCloud/mosquittopp.h new file mode 100644 index 00000000..d3f388c0 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/mosquittopp.h @@ -0,0 +1,146 @@ +/* +Copyright (c) 2010-2019 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTOPP_H +#define MOSQUITTOPP_H + +#if defined(_WIN32) && !defined(LIBMOSQUITTO_STATIC) +# ifdef mosquittopp_EXPORTS +# define mosqpp_EXPORT __declspec(dllexport) +# else +# define mosqpp_EXPORT __declspec(dllimport) +# endif +#else +# define mosqpp_EXPORT +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define DEPRECATED __attribute__ ((deprecated)) +#else +# define DEPRECATED +#endif + +#include +#include +#include + +namespace mosqpp { + + +mosqpp_EXPORT const char * DEPRECATED strerror(int mosq_errno); +mosqpp_EXPORT const char * DEPRECATED connack_string(int connack_code); +mosqpp_EXPORT int DEPRECATED sub_topic_tokenise(const char *subtopic, char ***topics, int *count); +mosqpp_EXPORT int DEPRECATED sub_topic_tokens_free(char ***topics, int count); +mosqpp_EXPORT int DEPRECATED lib_version(int *major, int *minor, int *revision); +mosqpp_EXPORT int DEPRECATED lib_init(); +mosqpp_EXPORT int DEPRECATED lib_cleanup(); +mosqpp_EXPORT int DEPRECATED topic_matches_sub(const char *sub, const char *topic, bool *result); +mosqpp_EXPORT int DEPRECATED validate_utf8(const char *str, int len); +mosqpp_EXPORT int DEPRECATED subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool retained, + const char *topic, + int qos=0, + const char *host="localhost", + int port=1883, + const char *client_id=NULL, + int keepalive=60, + bool clean_session=true, + const char *username=NULL, + const char *password=NULL, + const struct libmosquitto_will *will=NULL, + const struct libmosquitto_tls *tls=NULL); + +mosqpp_EXPORT int DEPRECATED subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos=0, + bool retained=true, + const char *host="localhost", + int port=1883, + const char *client_id=NULL, + int keepalive=60, + bool clean_session=true, + const char *username=NULL, + const char *password=NULL, + const struct libmosquitto_will *will=NULL, + const struct libmosquitto_tls *tls=NULL); + +/* + * Class: mosquittopp + * + * A mosquitto client class. This is a C++ wrapper class for the mosquitto C + * library. Please see mosquitto.h for details of the functions. + */ +class mosqpp_EXPORT DEPRECATED mosquittopp { + private: + struct mosquitto *m_mosq; + public: + DEPRECATED mosquittopp(const char *id=NULL, bool clean_session=true); + virtual ~mosquittopp(); + + int DEPRECATED reinitialise(const char *id, bool clean_session); + int DEPRECATED socket(); + int DEPRECATED will_set(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int DEPRECATED will_clear(); + int DEPRECATED username_pw_set(const char *username, const char *password=NULL); + int DEPRECATED connect(const char *host, int port=1883, int keepalive=60); + int DEPRECATED connect_async(const char *host, int port=1883, int keepalive=60); + int DEPRECATED connect(const char *host, int port, int keepalive, const char *bind_address); + int DEPRECATED connect_async(const char *host, int port, int keepalive, const char *bind_address); + int DEPRECATED reconnect(); + int DEPRECATED reconnect_async(); + int DEPRECATED disconnect(); + int DEPRECATED publish(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int DEPRECATED subscribe(int *mid, const char *sub, int qos=0); + int DEPRECATED unsubscribe(int *mid, const char *sub); + void DEPRECATED reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + int DEPRECATED max_inflight_messages_set(unsigned int max_inflight_messages); + void DEPRECATED message_retry_set(unsigned int message_retry); + void DEPRECATED user_data_set(void *userdata); + int DEPRECATED tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL); + int DEPRECATED tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL); + int DEPRECATED tls_insecure_set(bool value); + int DEPRECATED tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL); + int DEPRECATED opts_set(enum mosq_opt_t option, void *value); + + int DEPRECATED loop(int timeout=-1, int max_packets=1); + int DEPRECATED loop_misc(); + int DEPRECATED loop_read(int max_packets=1); + int DEPRECATED loop_write(int max_packets=1); + int DEPRECATED loop_forever(int timeout=-1, int max_packets=1); + int DEPRECATED loop_start(); + int DEPRECATED loop_stop(bool force=false); + bool DEPRECATED want_write(); + int DEPRECATED threaded_set(bool threaded=true); + int DEPRECATED socks5_set(const char *host, int port=1080, const char *username=NULL, const char *password=NULL); + + // names in the functions commented to prevent unused parameter warning + virtual void on_connect(int /*rc*/) {return;} + virtual void on_connect_with_flags(int /*rc*/, int /*flags*/) {return;} + virtual void on_disconnect(int /*rc*/) {return;} + virtual void on_publish(int /*mid*/) {return;} + virtual void on_message(const struct mosquitto_message * /*message*/) {return;} + virtual void on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/) {return;} + virtual void on_unsubscribe(int /*mid*/) {return;} + virtual void on_log(int /*level*/, const char * /*str*/) {return;} + virtual void on_error() {return;} +}; + +} +#endif diff --git a/product/src/fes/protocol/mqtt_yxCloud/mqtt_yxCloud.pro b/product/src/fes/protocol/mqtt_yxCloud/mqtt_yxCloud.pro new file mode 100644 index 00000000..04f84833 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/mqtt_yxCloud.pro @@ -0,0 +1,68 @@ +# ARM板上资源有限,不会与云平台混用,不编译 +message("Compile only in x86 environment") +# requires(contains(QMAKE_HOST.arch, x86_64)) +requires(!contains(QMAKE_HOST.arch, aarch64):!linux-aarch64*) + +QT -= core gui +CONFIG -= qt + +TARGET = mqtt_yxCloud +TEMPLATE = lib + +#win命令生成pb文件 +# for %f in (*.proto) do protoc --cpp_out=. "%f" +SOURCES += \ + Yxcloudmqtts.cpp \ + YxcloudmqttsDataProcThread.cpp \ + Md5/Md5.cpp \ + proto/RequestReportPoint.pb.cc \ + proto/RequestReport.pb.cc \ + proto/RequestControlPoint.pb.cc \ + proto/RequestControl.pb.cc \ + proto/EnumBase.pb.cc \ + proto/TypePoint.pb.cc \ + CMosquitto.cpp \ + MQTTHandleThread.cpp \ + CmdHandleThread.cpp \ + CMbCommHandleThread.cpp + +HEADERS += \ + Yxcloudmqtts.h \ + YxcloudmqttsDataProcThread.h \ + mosquitto.h \ + mosquitto_plugin.h \ + mosquittopp.h \ + Md5/Md5.h \ + proto/EnumBase.pb.h \ + proto/RequestControl.pb.h \ + proto/RequestControlPoint.pb.h \ + proto/RequestReport.pb.h \ + proto/RequestReportPoint.pb.h\ + proto/TypePoint.pb.h \ + CMosquitto.h \ + MQTTHandleThread.h \ + CmdHandleThread.h \ + CMbCommHandleThread.h + +INCLUDEPATH += \ + ../../include/ \ + ../../../include/ \ + ../../../3rd/include/ \ + + + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase -lnet_msg_bus_api +LIBS += -lmosquitto -lmosquittopp +LIBS += -lprotobuf + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/EnumBase.pb.cc b/product/src/fes/protocol/mqtt_yxCloud/proto/EnumBase.pb.cc new file mode 100644 index 00000000..cfb0a6a5 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/EnumBase.pb.cc @@ -0,0 +1,149 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: EnumBase.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "EnumBase.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace com_relyez_ems_common { + +namespace { + +const ::google::protobuf::EnumDescriptor* CommandType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* ReportType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* ResponseCommon_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestSource_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_EnumBase_2eproto() { + protobuf_AddDesc_EnumBase_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "EnumBase.proto"); + GOOGLE_CHECK(file != NULL); + CommandType_descriptor_ = file->enum_type(0); + ReportType_descriptor_ = file->enum_type(1); + ResponseCommon_descriptor_ = file->enum_type(2); + RequestSource_descriptor_ = file->enum_type(3); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_EnumBase_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); +} + +} // namespace + +void protobuf_ShutdownFile_EnumBase_2eproto() { +} + +void protobuf_AddDesc_EnumBase_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\016EnumBase.proto\022\025com_relyez_ems_common*" + "\'\n\013CommandType\022\030\n\024CONTROL_DEVICE_POINT\020\000" + "*%\n\nReportType\022\027\n\023REPORT_DEVICE_POINT\020\000*" + "\247\001\n\016ResponseCommon\022\034\n\030RESULT_RESPONSE_AC" + "CEPTED\020\000\022\034\n\030RESULT_RESPONSE_REJECTED\020\001\022\037" + "\n\033RESULT_RESPONSE_UNSUPPORTED\020\002\022\033\n\027RESUL" + "T_RESPONSE_INVALID\020\003\022\033\n\027RESULT_RESPONSE_" + "TIMEOUT\020\004*\?\n\rRequestSource\022\026\n\022REQUEST_SO" + "URCE_WEB\020\000\022\026\n\022REQUEST_SOURCE_APP\020\001", 354); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "EnumBase.proto", &protobuf_RegisterTypes); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_EnumBase_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_EnumBase_2eproto { + StaticDescriptorInitializer_EnumBase_2eproto() { + protobuf_AddDesc_EnumBase_2eproto(); + } +} static_descriptor_initializer_EnumBase_2eproto_; +const ::google::protobuf::EnumDescriptor* CommandType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return CommandType_descriptor_; +} +bool CommandType_IsValid(int value) { + switch(value) { + case 0: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* ReportType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ReportType_descriptor_; +} +bool ReportType_IsValid(int value) { + switch(value) { + case 0: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* ResponseCommon_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseCommon_descriptor_; +} +bool ResponseCommon_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + case 4: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* RequestSource_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestSource_descriptor_; +} +bool RequestSource_IsValid(int value) { + switch(value) { + case 0: + case 1: + return true; + default: + return false; + } +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace com_relyez_ems_common + +// @@protoc_insertion_point(global_scope) diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/EnumBase.pb.h b/product/src/fes/protocol/mqtt_yxCloud/proto/EnumBase.pb.h new file mode 100644 index 00000000..c8d5bf53 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/EnumBase.pb.h @@ -0,0 +1,157 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: EnumBase.proto + +#ifndef PROTOBUF_EnumBase_2eproto__INCLUDED +#define PROTOBUF_EnumBase_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2006000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace com_relyez_ems_common { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_EnumBase_2eproto(); +void protobuf_AssignDesc_EnumBase_2eproto(); +void protobuf_ShutdownFile_EnumBase_2eproto(); + + +enum CommandType { + CONTROL_DEVICE_POINT = 0 +}; +bool CommandType_IsValid(int value); +const CommandType CommandType_MIN = CONTROL_DEVICE_POINT; +const CommandType CommandType_MAX = CONTROL_DEVICE_POINT; +const int CommandType_ARRAYSIZE = CommandType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* CommandType_descriptor(); +inline const ::std::string& CommandType_Name(CommandType value) { + return ::google::protobuf::internal::NameOfEnum( + CommandType_descriptor(), value); +} +inline bool CommandType_Parse( + const ::std::string& name, CommandType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + CommandType_descriptor(), name, value); +} +enum ReportType { + REPORT_DEVICE_POINT = 0 +}; +bool ReportType_IsValid(int value); +const ReportType ReportType_MIN = REPORT_DEVICE_POINT; +const ReportType ReportType_MAX = REPORT_DEVICE_POINT; +const int ReportType_ARRAYSIZE = ReportType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ReportType_descriptor(); +inline const ::std::string& ReportType_Name(ReportType value) { + return ::google::protobuf::internal::NameOfEnum( + ReportType_descriptor(), value); +} +inline bool ReportType_Parse( + const ::std::string& name, ReportType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ReportType_descriptor(), name, value); +} +enum ResponseCommon { + RESULT_RESPONSE_ACCEPTED = 0, + RESULT_RESPONSE_REJECTED = 1, + RESULT_RESPONSE_UNSUPPORTED = 2, + RESULT_RESPONSE_INVALID = 3, + RESULT_RESPONSE_TIMEOUT = 4 +}; +bool ResponseCommon_IsValid(int value); +const ResponseCommon ResponseCommon_MIN = RESULT_RESPONSE_ACCEPTED; +const ResponseCommon ResponseCommon_MAX = RESULT_RESPONSE_TIMEOUT; +const int ResponseCommon_ARRAYSIZE = ResponseCommon_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ResponseCommon_descriptor(); +inline const ::std::string& ResponseCommon_Name(ResponseCommon value) { + return ::google::protobuf::internal::NameOfEnum( + ResponseCommon_descriptor(), value); +} +inline bool ResponseCommon_Parse( + const ::std::string& name, ResponseCommon* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ResponseCommon_descriptor(), name, value); +} +enum RequestSource { + REQUEST_SOURCE_WEB = 0, + REQUEST_SOURCE_APP = 1 +}; +bool RequestSource_IsValid(int value); +const RequestSource RequestSource_MIN = REQUEST_SOURCE_WEB; +const RequestSource RequestSource_MAX = REQUEST_SOURCE_APP; +const int RequestSource_ARRAYSIZE = RequestSource_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestSource_descriptor(); +inline const ::std::string& RequestSource_Name(RequestSource value) { + return ::google::protobuf::internal::NameOfEnum( + RequestSource_descriptor(), value); +} +inline bool RequestSource_Parse( + const ::std::string& name, RequestSource* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestSource_descriptor(), name, value); +} +// =================================================================== + + +// =================================================================== + + +// =================================================================== + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace com_relyez_ems_common + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::com_relyez_ems_common::CommandType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::com_relyez_ems_common::CommandType>() { + return ::com_relyez_ems_common::CommandType_descriptor(); +} +template <> struct is_proto_enum< ::com_relyez_ems_common::ReportType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::com_relyez_ems_common::ReportType>() { + return ::com_relyez_ems_common::ReportType_descriptor(); +} +template <> struct is_proto_enum< ::com_relyez_ems_common::ResponseCommon> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::com_relyez_ems_common::ResponseCommon>() { + return ::com_relyez_ems_common::ResponseCommon_descriptor(); +} +template <> struct is_proto_enum< ::com_relyez_ems_common::RequestSource> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::com_relyez_ems_common::RequestSource>() { + return ::com_relyez_ems_common::RequestSource_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_EnumBase_2eproto__INCLUDED diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/EnumBase.proto b/product/src/fes/protocol/mqtt_yxCloud/proto/EnumBase.proto new file mode 100644 index 00000000..d22c18ad --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/EnumBase.proto @@ -0,0 +1,37 @@ +syntax = "proto2"; +package com_relyez_ems_common; + +/** + 请求命令类型 +*/ +enum CommandType { + // 测点控制 + CONTROL_DEVICE_POINT = 0; +} + +/** + 上报数据类型 +*/ +enum ReportType { + // 测点数据上报 + REPORT_DEVICE_POINT = 0; +} + +/** + 通用回复消息定义 +*/ +enum ResponseCommon { + RESULT_RESPONSE_ACCEPTED = 0; // 接受 + RESULT_RESPONSE_REJECTED = 1; // 拒绝 + RESULT_RESPONSE_UNSUPPORTED = 2; // 不支持 + RESULT_RESPONSE_INVALID = 3; // 无效 + RESULT_RESPONSE_TIMEOUT = 4; // 超时 +} + +/** + 请求来源 +*/ +enum RequestSource { + REQUEST_SOURCE_WEB = 0; // WEB端 + REQUEST_SOURCE_APP = 1; // APP +} \ No newline at end of file diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControl.pb.cc b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControl.pb.cc new file mode 100644 index 00000000..fc14ea5f --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControl.pb.cc @@ -0,0 +1,541 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: RequestControl.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "RequestControl.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace com_relyez_ems_common { + +namespace { + +const ::google::protobuf::Descriptor* RequestControl_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestControl_reflection_ = NULL; +struct RequestControlOneofInstance { + const ::com_relyez_ems_common::RequestControlPoint* controlpoint_; +}* RequestControl_default_oneof_instance_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_RequestControl_2eproto() { + protobuf_AddDesc_RequestControl_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "RequestControl.proto"); + GOOGLE_CHECK(file != NULL); + RequestControl_descriptor_ = file->message_type(0); + static const int RequestControl_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControl, commandtype_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControl, userid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControl, source_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(RequestControl_default_oneof_instance_, controlpoint_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControl, detail_), + }; + RequestControl_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestControl_descriptor_, + RequestControl::default_instance_, + RequestControl_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControl, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControl, _unknown_fields_), + -1, + RequestControl_default_oneof_instance_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControl, _oneof_case_[0]), + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestControl)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_RequestControl_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestControl_descriptor_, &RequestControl::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_RequestControl_2eproto() { + delete RequestControl::default_instance_; + delete RequestControl_default_oneof_instance_; + delete RequestControl_reflection_; +} + +void protobuf_AddDesc_RequestControl_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::com_relyez_ems_common::protobuf_AddDesc_EnumBase_2eproto(); + ::com_relyez_ems_common::protobuf_AddDesc_RequestControlPoint_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\024RequestControl.proto\022\025com_relyez_ems_c" + "ommon\032\016EnumBase.proto\032\031RequestControlPoi" + "nt.proto\"\335\001\n\016RequestControl\0227\n\013commandTy" + "pe\030\001 \001(\0162\".com_relyez_ems_common.Command" + "Type\022\016\n\006userId\030\002 \001(\t\0224\n\006source\030\003 \001(\0162$.c" + "om_relyez_ems_common.RequestSource\022B\n\014co" + "ntrolPoint\030d \001(\0132*.com_relyez_ems_common" + ".RequestControlPointH\000B\010\n\006detail", 312); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "RequestControl.proto", &protobuf_RegisterTypes); + RequestControl::default_instance_ = new RequestControl(); + RequestControl_default_oneof_instance_ = new RequestControlOneofInstance; + RequestControl::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_RequestControl_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_RequestControl_2eproto { + StaticDescriptorInitializer_RequestControl_2eproto() { + protobuf_AddDesc_RequestControl_2eproto(); + } +} static_descriptor_initializer_RequestControl_2eproto_; + +// =================================================================== + +#ifndef _MSC_VER +const int RequestControl::kCommandTypeFieldNumber; +const int RequestControl::kUserIdFieldNumber; +const int RequestControl::kSourceFieldNumber; +const int RequestControl::kControlPointFieldNumber; +#endif // !_MSC_VER + +RequestControl::RequestControl() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:com_relyez_ems_common.RequestControl) +} + +void RequestControl::InitAsDefaultInstance() { + RequestControl_default_oneof_instance_->controlpoint_ = const_cast< ::com_relyez_ems_common::RequestControlPoint*>(&::com_relyez_ems_common::RequestControlPoint::default_instance()); +} + +RequestControl::RequestControl(const RequestControl& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:com_relyez_ems_common.RequestControl) +} + +void RequestControl::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + commandtype_ = 0; + userid_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + source_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + clear_has_detail(); +} + +RequestControl::~RequestControl() { + // @@protoc_insertion_point(destructor:com_relyez_ems_common.RequestControl) + SharedDtor(); +} + +void RequestControl::SharedDtor() { + if (userid_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete userid_; + } + if (has_detail()) { + clear_detail(); + } + if (this != default_instance_) { + } +} + +void RequestControl::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestControl::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestControl_descriptor_; +} + +const RequestControl& RequestControl::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_RequestControl_2eproto(); + return *default_instance_; +} + +RequestControl* RequestControl::default_instance_ = NULL; + +RequestControl* RequestControl::New() const { + return new RequestControl; +} + +void RequestControl::clear_detail() { + switch(detail_case()) { + case kControlPoint: { + delete detail_.controlpoint_; + break; + } + case DETAIL_NOT_SET: { + break; + } + } + _oneof_case_[0] = DETAIL_NOT_SET; +} + + +void RequestControl::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 7) { + ZR_(commandtype_, source_); + if (has_userid()) { + if (userid_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + userid_->clear(); + } + } + } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + clear_detail(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestControl::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:com_relyez_ems_common.RequestControl) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .com_relyez_ems_common.CommandType commandType = 1; + case 1: { + if (tag == 8) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::com_relyez_ems_common::CommandType_IsValid(value)) { + set_commandtype(static_cast< ::com_relyez_ems_common::CommandType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_userId; + break; + } + + // optional string userId = 2; + case 2: { + if (tag == 18) { + parse_userId: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_userid())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->userid().data(), this->userid().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "userid"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_source; + break; + } + + // optional .com_relyez_ems_common.RequestSource source = 3; + case 3: { + if (tag == 24) { + parse_source: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::com_relyez_ems_common::RequestSource_IsValid(value)) { + set_source(static_cast< ::com_relyez_ems_common::RequestSource >(value)); + } else { + mutable_unknown_fields()->AddVarint(3, value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(802)) goto parse_controlPoint; + break; + } + + // optional .com_relyez_ems_common.RequestControlPoint controlPoint = 100; + case 100: { + if (tag == 802) { + parse_controlPoint: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_controlpoint())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:com_relyez_ems_common.RequestControl) + return true; +failure: + // @@protoc_insertion_point(parse_failure:com_relyez_ems_common.RequestControl) + return false; +#undef DO_ +} + +void RequestControl::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:com_relyez_ems_common.RequestControl) + // optional .com_relyez_ems_common.CommandType commandType = 1; + if (has_commandtype()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->commandtype(), output); + } + + // optional string userId = 2; + if (has_userid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->userid().data(), this->userid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "userid"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->userid(), output); + } + + // optional .com_relyez_ems_common.RequestSource source = 3; + if (has_source()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 3, this->source(), output); + } + + // optional .com_relyez_ems_common.RequestControlPoint controlPoint = 100; + if (has_controlpoint()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 100, this->controlpoint(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:com_relyez_ems_common.RequestControl) +} + +::google::protobuf::uint8* RequestControl::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:com_relyez_ems_common.RequestControl) + // optional .com_relyez_ems_common.CommandType commandType = 1; + if (has_commandtype()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->commandtype(), target); + } + + // optional string userId = 2; + if (has_userid()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->userid().data(), this->userid().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "userid"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->userid(), target); + } + + // optional .com_relyez_ems_common.RequestSource source = 3; + if (has_source()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 3, this->source(), target); + } + + // optional .com_relyez_ems_common.RequestControlPoint controlPoint = 100; + if (has_controlpoint()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 100, this->controlpoint(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:com_relyez_ems_common.RequestControl) + return target; +} + +int RequestControl::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional .com_relyez_ems_common.CommandType commandType = 1; + if (has_commandtype()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->commandtype()); + } + + // optional string userId = 2; + if (has_userid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->userid()); + } + + // optional .com_relyez_ems_common.RequestSource source = 3; + if (has_source()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->source()); + } + + } + switch (detail_case()) { + // optional .com_relyez_ems_common.RequestControlPoint controlPoint = 100; + case kControlPoint: { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->controlpoint()); + break; + } + case DETAIL_NOT_SET: { + break; + } + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestControl::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestControl* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestControl::MergeFrom(const RequestControl& from) { + GOOGLE_CHECK_NE(&from, this); + switch (from.detail_case()) { + case kControlPoint: { + mutable_controlpoint()->::com_relyez_ems_common::RequestControlPoint::MergeFrom(from.controlpoint()); + break; + } + case DETAIL_NOT_SET: { + break; + } + } + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_commandtype()) { + set_commandtype(from.commandtype()); + } + if (from.has_userid()) { + set_userid(from.userid()); + } + if (from.has_source()) { + set_source(from.source()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestControl::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestControl::CopyFrom(const RequestControl& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestControl::IsInitialized() const { + + if (has_controlpoint()) { + if (!this->controlpoint().IsInitialized()) return false; + } + return true; +} + +void RequestControl::Swap(RequestControl* other) { + if (other != this) { + std::swap(commandtype_, other->commandtype_); + std::swap(userid_, other->userid_); + std::swap(source_, other->source_); + std::swap(detail_, other->detail_); + std::swap(_oneof_case_[0], other->_oneof_case_[0]); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestControl::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestControl_descriptor_; + metadata.reflection = RequestControl_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace com_relyez_ems_common + +// @@protoc_insertion_point(global_scope) diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControl.pb.h b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControl.pb.h new file mode 100644 index 00000000..09bc3a8d --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControl.pb.h @@ -0,0 +1,370 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: RequestControl.proto + +#ifndef PROTOBUF_RequestControl_2eproto__INCLUDED +#define PROTOBUF_RequestControl_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2006000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include "EnumBase.pb.h" +#include "RequestControlPoint.pb.h" +// @@protoc_insertion_point(includes) + +namespace com_relyez_ems_common { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_RequestControl_2eproto(); +void protobuf_AssignDesc_RequestControl_2eproto(); +void protobuf_ShutdownFile_RequestControl_2eproto(); + +class RequestControl; + +// =================================================================== + +class RequestControl : public ::google::protobuf::Message { + public: + RequestControl(); + virtual ~RequestControl(); + + RequestControl(const RequestControl& from); + + inline RequestControl& operator=(const RequestControl& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestControl& default_instance(); + + enum DetailCase { + kControlPoint = 100, + DETAIL_NOT_SET = 0, + }; + + void Swap(RequestControl* other); + + // implements Message ---------------------------------------------- + + RequestControl* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestControl& from); + void MergeFrom(const RequestControl& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .com_relyez_ems_common.CommandType commandType = 1; + inline bool has_commandtype() const; + inline void clear_commandtype(); + static const int kCommandTypeFieldNumber = 1; + inline ::com_relyez_ems_common::CommandType commandtype() const; + inline void set_commandtype(::com_relyez_ems_common::CommandType value); + + // optional string userId = 2; + inline bool has_userid() const; + inline void clear_userid(); + static const int kUserIdFieldNumber = 2; + inline const ::std::string& userid() const; + inline void set_userid(const ::std::string& value); + inline void set_userid(const char* value); + inline void set_userid(const char* value, size_t size); + inline ::std::string* mutable_userid(); + inline ::std::string* release_userid(); + inline void set_allocated_userid(::std::string* userid); + + // optional .com_relyez_ems_common.RequestSource source = 3; + inline bool has_source() const; + inline void clear_source(); + static const int kSourceFieldNumber = 3; + inline ::com_relyez_ems_common::RequestSource source() const; + inline void set_source(::com_relyez_ems_common::RequestSource value); + + // optional .com_relyez_ems_common.RequestControlPoint controlPoint = 100; + inline bool has_controlpoint() const; + inline void clear_controlpoint(); + static const int kControlPointFieldNumber = 100; + inline const ::com_relyez_ems_common::RequestControlPoint& controlpoint() const; + inline ::com_relyez_ems_common::RequestControlPoint* mutable_controlpoint(); + inline ::com_relyez_ems_common::RequestControlPoint* release_controlpoint(); + inline void set_allocated_controlpoint(::com_relyez_ems_common::RequestControlPoint* controlpoint); + + inline DetailCase detail_case() const; + // @@protoc_insertion_point(class_scope:com_relyez_ems_common.RequestControl) + private: + inline void set_has_commandtype(); + inline void clear_has_commandtype(); + inline void set_has_userid(); + inline void clear_has_userid(); + inline void set_has_source(); + inline void clear_has_source(); + inline void set_has_controlpoint(); + + inline bool has_detail(); + void clear_detail(); + inline void clear_has_detail(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* userid_; + int commandtype_; + int source_; + union DetailUnion { + ::com_relyez_ems_common::RequestControlPoint* controlpoint_; + } detail_; + ::google::protobuf::uint32 _oneof_case_[1]; + + friend void protobuf_AddDesc_RequestControl_2eproto(); + friend void protobuf_AssignDesc_RequestControl_2eproto(); + friend void protobuf_ShutdownFile_RequestControl_2eproto(); + + void InitAsDefaultInstance(); + static RequestControl* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// RequestControl + +// optional .com_relyez_ems_common.CommandType commandType = 1; +inline bool RequestControl::has_commandtype() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestControl::set_has_commandtype() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestControl::clear_has_commandtype() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestControl::clear_commandtype() { + commandtype_ = 0; + clear_has_commandtype(); +} +inline ::com_relyez_ems_common::CommandType RequestControl::commandtype() const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.RequestControl.commandType) + return static_cast< ::com_relyez_ems_common::CommandType >(commandtype_); +} +inline void RequestControl::set_commandtype(::com_relyez_ems_common::CommandType value) { + assert(::com_relyez_ems_common::CommandType_IsValid(value)); + set_has_commandtype(); + commandtype_ = value; + // @@protoc_insertion_point(field_set:com_relyez_ems_common.RequestControl.commandType) +} + +// optional string userId = 2; +inline bool RequestControl::has_userid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void RequestControl::set_has_userid() { + _has_bits_[0] |= 0x00000002u; +} +inline void RequestControl::clear_has_userid() { + _has_bits_[0] &= ~0x00000002u; +} +inline void RequestControl::clear_userid() { + if (userid_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + userid_->clear(); + } + clear_has_userid(); +} +inline const ::std::string& RequestControl::userid() const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.RequestControl.userId) + return *userid_; +} +inline void RequestControl::set_userid(const ::std::string& value) { + set_has_userid(); + if (userid_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + userid_ = new ::std::string; + } + userid_->assign(value); + // @@protoc_insertion_point(field_set:com_relyez_ems_common.RequestControl.userId) +} +inline void RequestControl::set_userid(const char* value) { + set_has_userid(); + if (userid_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + userid_ = new ::std::string; + } + userid_->assign(value); + // @@protoc_insertion_point(field_set_char:com_relyez_ems_common.RequestControl.userId) +} +inline void RequestControl::set_userid(const char* value, size_t size) { + set_has_userid(); + if (userid_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + userid_ = new ::std::string; + } + userid_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:com_relyez_ems_common.RequestControl.userId) +} +inline ::std::string* RequestControl::mutable_userid() { + set_has_userid(); + if (userid_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + userid_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:com_relyez_ems_common.RequestControl.userId) + return userid_; +} +inline ::std::string* RequestControl::release_userid() { + clear_has_userid(); + if (userid_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = userid_; + userid_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void RequestControl::set_allocated_userid(::std::string* userid) { + if (userid_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete userid_; + } + if (userid) { + set_has_userid(); + userid_ = userid; + } else { + clear_has_userid(); + userid_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:com_relyez_ems_common.RequestControl.userId) +} + +// optional .com_relyez_ems_common.RequestSource source = 3; +inline bool RequestControl::has_source() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void RequestControl::set_has_source() { + _has_bits_[0] |= 0x00000004u; +} +inline void RequestControl::clear_has_source() { + _has_bits_[0] &= ~0x00000004u; +} +inline void RequestControl::clear_source() { + source_ = 0; + clear_has_source(); +} +inline ::com_relyez_ems_common::RequestSource RequestControl::source() const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.RequestControl.source) + return static_cast< ::com_relyez_ems_common::RequestSource >(source_); +} +inline void RequestControl::set_source(::com_relyez_ems_common::RequestSource value) { + assert(::com_relyez_ems_common::RequestSource_IsValid(value)); + set_has_source(); + source_ = value; + // @@protoc_insertion_point(field_set:com_relyez_ems_common.RequestControl.source) +} + +// optional .com_relyez_ems_common.RequestControlPoint controlPoint = 100; +inline bool RequestControl::has_controlpoint() const { + return detail_case() == kControlPoint; +} +inline void RequestControl::set_has_controlpoint() { + _oneof_case_[0] = kControlPoint; +} +inline void RequestControl::clear_controlpoint() { + if (has_controlpoint()) { + delete detail_.controlpoint_; + clear_has_detail(); + } +} +inline const ::com_relyez_ems_common::RequestControlPoint& RequestControl::controlpoint() const { + return has_controlpoint() ? *detail_.controlpoint_ + : ::com_relyez_ems_common::RequestControlPoint::default_instance(); +} +inline ::com_relyez_ems_common::RequestControlPoint* RequestControl::mutable_controlpoint() { + if (!has_controlpoint()) { + clear_detail(); + set_has_controlpoint(); + detail_.controlpoint_ = new ::com_relyez_ems_common::RequestControlPoint; + } + return detail_.controlpoint_; +} +inline ::com_relyez_ems_common::RequestControlPoint* RequestControl::release_controlpoint() { + if (has_controlpoint()) { + clear_has_detail(); + ::com_relyez_ems_common::RequestControlPoint* temp = detail_.controlpoint_; + detail_.controlpoint_ = NULL; + return temp; + } else { + return NULL; + } +} +inline void RequestControl::set_allocated_controlpoint(::com_relyez_ems_common::RequestControlPoint* controlpoint) { + clear_detail(); + if (controlpoint) { + set_has_controlpoint(); + detail_.controlpoint_ = controlpoint; + } +} + +inline bool RequestControl::has_detail() { + return detail_case() != DETAIL_NOT_SET; +} +inline void RequestControl::clear_has_detail() { + _oneof_case_[0] = DETAIL_NOT_SET; +} +inline RequestControl::DetailCase RequestControl::detail_case() const { + return RequestControl::DetailCase(_oneof_case_[0]); +} + +// @@protoc_insertion_point(namespace_scope) + +} // namespace com_relyez_ems_common + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_RequestControl_2eproto__INCLUDED diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControl.proto b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControl.proto new file mode 100644 index 00000000..5c41a12e --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControl.proto @@ -0,0 +1,24 @@ +syntax = "proto2"; +package com_relyez_ems_common; + +import "EnumBase.proto"; +import "RequestControlPoint.proto"; + +/** + 设备命令请求的消息定义 +*/ +message RequestControl { + // 请求命令类型 + optional CommandType commandType = 1; + + // 用户ID + optional string userId = 2; + + // 请求发起端 + optional RequestSource source = 3; + + oneof detail { + // 测点控制 + RequestControlPoint controlPoint = 100; + } +} \ No newline at end of file diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControlPoint.pb.cc b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControlPoint.pb.cc new file mode 100644 index 00000000..e71a3ba1 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControlPoint.pb.cc @@ -0,0 +1,324 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: RequestControlPoint.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "RequestControlPoint.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace com_relyez_ems_common { + +namespace { + +const ::google::protobuf::Descriptor* RequestControlPoint_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestControlPoint_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_RequestControlPoint_2eproto() { + protobuf_AddDesc_RequestControlPoint_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "RequestControlPoint.proto"); + GOOGLE_CHECK(file != NULL); + RequestControlPoint_descriptor_ = file->message_type(0); + static const int RequestControlPoint_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControlPoint, typepoint_), + }; + RequestControlPoint_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestControlPoint_descriptor_, + RequestControlPoint::default_instance_, + RequestControlPoint_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControlPoint, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControlPoint, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestControlPoint)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_RequestControlPoint_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestControlPoint_descriptor_, &RequestControlPoint::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_RequestControlPoint_2eproto() { + delete RequestControlPoint::default_instance_; + delete RequestControlPoint_reflection_; +} + +void protobuf_AddDesc_RequestControlPoint_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::com_relyez_ems_common::protobuf_AddDesc_TypePoint_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\031RequestControlPoint.proto\022\025com_relyez_" + "ems_common\032\017TypePoint.proto\"J\n\023RequestCo" + "ntrolPoint\0223\n\ttypePoint\030\001 \003(\0132 .com_rely" + "ez_ems_common.TypePoint", 143); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "RequestControlPoint.proto", &protobuf_RegisterTypes); + RequestControlPoint::default_instance_ = new RequestControlPoint(); + RequestControlPoint::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_RequestControlPoint_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_RequestControlPoint_2eproto { + StaticDescriptorInitializer_RequestControlPoint_2eproto() { + protobuf_AddDesc_RequestControlPoint_2eproto(); + } +} static_descriptor_initializer_RequestControlPoint_2eproto_; + +// =================================================================== + +#ifndef _MSC_VER +const int RequestControlPoint::kTypePointFieldNumber; +#endif // !_MSC_VER + +RequestControlPoint::RequestControlPoint() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:com_relyez_ems_common.RequestControlPoint) +} + +void RequestControlPoint::InitAsDefaultInstance() { +} + +RequestControlPoint::RequestControlPoint(const RequestControlPoint& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:com_relyez_ems_common.RequestControlPoint) +} + +void RequestControlPoint::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestControlPoint::~RequestControlPoint() { + // @@protoc_insertion_point(destructor:com_relyez_ems_common.RequestControlPoint) + SharedDtor(); +} + +void RequestControlPoint::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestControlPoint::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestControlPoint::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestControlPoint_descriptor_; +} + +const RequestControlPoint& RequestControlPoint::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_RequestControlPoint_2eproto(); + return *default_instance_; +} + +RequestControlPoint* RequestControlPoint::default_instance_ = NULL; + +RequestControlPoint* RequestControlPoint::New() const { + return new RequestControlPoint; +} + +void RequestControlPoint::Clear() { + typepoint_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestControlPoint::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:com_relyez_ems_common.RequestControlPoint) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .com_relyez_ems_common.TypePoint typePoint = 1; + case 1: { + if (tag == 10) { + parse_typePoint: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_typepoint())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(10)) goto parse_typePoint; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:com_relyez_ems_common.RequestControlPoint) + return true; +failure: + // @@protoc_insertion_point(parse_failure:com_relyez_ems_common.RequestControlPoint) + return false; +#undef DO_ +} + +void RequestControlPoint::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:com_relyez_ems_common.RequestControlPoint) + // repeated .com_relyez_ems_common.TypePoint typePoint = 1; + for (int i = 0; i < this->typepoint_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->typepoint(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:com_relyez_ems_common.RequestControlPoint) +} + +::google::protobuf::uint8* RequestControlPoint::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:com_relyez_ems_common.RequestControlPoint) + // repeated .com_relyez_ems_common.TypePoint typePoint = 1; + for (int i = 0; i < this->typepoint_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->typepoint(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:com_relyez_ems_common.RequestControlPoint) + return target; +} + +int RequestControlPoint::ByteSize() const { + int total_size = 0; + + // repeated .com_relyez_ems_common.TypePoint typePoint = 1; + total_size += 1 * this->typepoint_size(); + for (int i = 0; i < this->typepoint_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->typepoint(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestControlPoint::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestControlPoint* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestControlPoint::MergeFrom(const RequestControlPoint& from) { + GOOGLE_CHECK_NE(&from, this); + typepoint_.MergeFrom(from.typepoint_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestControlPoint::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestControlPoint::CopyFrom(const RequestControlPoint& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestControlPoint::IsInitialized() const { + + if (!::google::protobuf::internal::AllAreInitialized(this->typepoint())) return false; + return true; +} + +void RequestControlPoint::Swap(RequestControlPoint* other) { + if (other != this) { + typepoint_.Swap(&other->typepoint_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestControlPoint::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestControlPoint_descriptor_; + metadata.reflection = RequestControlPoint_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace com_relyez_ems_common + +// @@protoc_insertion_point(global_scope) diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControlPoint.pb.h b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControlPoint.pb.h new file mode 100644 index 00000000..ce8b03b3 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControlPoint.pb.h @@ -0,0 +1,174 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: RequestControlPoint.proto + +#ifndef PROTOBUF_RequestControlPoint_2eproto__INCLUDED +#define PROTOBUF_RequestControlPoint_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2006000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include "TypePoint.pb.h" +// @@protoc_insertion_point(includes) + +namespace com_relyez_ems_common { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_RequestControlPoint_2eproto(); +void protobuf_AssignDesc_RequestControlPoint_2eproto(); +void protobuf_ShutdownFile_RequestControlPoint_2eproto(); + +class RequestControlPoint; + +// =================================================================== + +class RequestControlPoint : public ::google::protobuf::Message { + public: + RequestControlPoint(); + virtual ~RequestControlPoint(); + + RequestControlPoint(const RequestControlPoint& from); + + inline RequestControlPoint& operator=(const RequestControlPoint& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestControlPoint& default_instance(); + + void Swap(RequestControlPoint* other); + + // implements Message ---------------------------------------------- + + RequestControlPoint* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestControlPoint& from); + void MergeFrom(const RequestControlPoint& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .com_relyez_ems_common.TypePoint typePoint = 1; + inline int typepoint_size() const; + inline void clear_typepoint(); + static const int kTypePointFieldNumber = 1; + inline const ::com_relyez_ems_common::TypePoint& typepoint(int index) const; + inline ::com_relyez_ems_common::TypePoint* mutable_typepoint(int index); + inline ::com_relyez_ems_common::TypePoint* add_typepoint(); + inline const ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::TypePoint >& + typepoint() const; + inline ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::TypePoint >* + mutable_typepoint(); + + // @@protoc_insertion_point(class_scope:com_relyez_ems_common.RequestControlPoint) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::TypePoint > typepoint_; + friend void protobuf_AddDesc_RequestControlPoint_2eproto(); + friend void protobuf_AssignDesc_RequestControlPoint_2eproto(); + friend void protobuf_ShutdownFile_RequestControlPoint_2eproto(); + + void InitAsDefaultInstance(); + static RequestControlPoint* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// RequestControlPoint + +// repeated .com_relyez_ems_common.TypePoint typePoint = 1; +inline int RequestControlPoint::typepoint_size() const { + return typepoint_.size(); +} +inline void RequestControlPoint::clear_typepoint() { + typepoint_.Clear(); +} +inline const ::com_relyez_ems_common::TypePoint& RequestControlPoint::typepoint(int index) const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.RequestControlPoint.typePoint) + return typepoint_.Get(index); +} +inline ::com_relyez_ems_common::TypePoint* RequestControlPoint::mutable_typepoint(int index) { + // @@protoc_insertion_point(field_mutable:com_relyez_ems_common.RequestControlPoint.typePoint) + return typepoint_.Mutable(index); +} +inline ::com_relyez_ems_common::TypePoint* RequestControlPoint::add_typepoint() { + // @@protoc_insertion_point(field_add:com_relyez_ems_common.RequestControlPoint.typePoint) + return typepoint_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::TypePoint >& +RequestControlPoint::typepoint() const { + // @@protoc_insertion_point(field_list:com_relyez_ems_common.RequestControlPoint.typePoint) + return typepoint_; +} +inline ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::TypePoint >* +RequestControlPoint::mutable_typepoint() { + // @@protoc_insertion_point(field_mutable_list:com_relyez_ems_common.RequestControlPoint.typePoint) + return &typepoint_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace com_relyez_ems_common + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_RequestControlPoint_2eproto__INCLUDED diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControlPoint.proto b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControlPoint.proto new file mode 100644 index 00000000..d8ac7ca0 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestControlPoint.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; +package com_relyez_ems_common; + +import "TypePoint.proto"; + +/* 测点控制请求的消息定义*/ +message RequestControlPoint { + // 控制数据 + repeated TypePoint typePoint = 1; +} diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReport.pb.cc b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReport.pb.cc new file mode 100644 index 00000000..e25051de --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReport.pb.cc @@ -0,0 +1,417 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: RequestReport.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "RequestReport.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace com_relyez_ems_common { + +namespace { + +const ::google::protobuf::Descriptor* RequestReport_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestReport_reflection_ = NULL; +struct RequestReportOneofInstance { + const ::com_relyez_ems_common::RequestReportPoint* reportpoint_; +}* RequestReport_default_oneof_instance_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_RequestReport_2eproto() { + protobuf_AddDesc_RequestReport_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "RequestReport.proto"); + GOOGLE_CHECK(file != NULL); + RequestReport_descriptor_ = file->message_type(0); + static const int RequestReport_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestReport, reporttype_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(RequestReport_default_oneof_instance_, reportpoint_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestReport, detail_), + }; + RequestReport_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestReport_descriptor_, + RequestReport::default_instance_, + RequestReport_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestReport, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestReport, _unknown_fields_), + -1, + RequestReport_default_oneof_instance_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestReport, _oneof_case_[0]), + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestReport)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_RequestReport_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestReport_descriptor_, &RequestReport::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_RequestReport_2eproto() { + delete RequestReport::default_instance_; + delete RequestReport_default_oneof_instance_; + delete RequestReport_reflection_; +} + +void protobuf_AddDesc_RequestReport_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::com_relyez_ems_common::protobuf_AddDesc_EnumBase_2eproto(); + ::com_relyez_ems_common::protobuf_AddDesc_RequestReportPoint_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\023RequestReport.proto\022\025com_relyez_ems_co" + "mmon\032\016EnumBase.proto\032\030RequestReportPoint" + ".proto\"\222\001\n\rRequestReport\0225\n\nreportType\030\001" + " \001(\0162!.com_relyez_ems_common.ReportType\022" + "@\n\013reportPoint\030d \001(\0132).com_relyez_ems_co" + "mmon.RequestReportPointH\000B\010\n\006detail", 235); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "RequestReport.proto", &protobuf_RegisterTypes); + RequestReport::default_instance_ = new RequestReport(); + RequestReport_default_oneof_instance_ = new RequestReportOneofInstance; + RequestReport::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_RequestReport_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_RequestReport_2eproto { + StaticDescriptorInitializer_RequestReport_2eproto() { + protobuf_AddDesc_RequestReport_2eproto(); + } +} static_descriptor_initializer_RequestReport_2eproto_; + +// =================================================================== + +#ifndef _MSC_VER +const int RequestReport::kReportTypeFieldNumber; +const int RequestReport::kReportPointFieldNumber; +#endif // !_MSC_VER + +RequestReport::RequestReport() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:com_relyez_ems_common.RequestReport) +} + +void RequestReport::InitAsDefaultInstance() { + RequestReport_default_oneof_instance_->reportpoint_ = const_cast< ::com_relyez_ems_common::RequestReportPoint*>(&::com_relyez_ems_common::RequestReportPoint::default_instance()); +} + +RequestReport::RequestReport(const RequestReport& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:com_relyez_ems_common.RequestReport) +} + +void RequestReport::SharedCtor() { + _cached_size_ = 0; + reporttype_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + clear_has_detail(); +} + +RequestReport::~RequestReport() { + // @@protoc_insertion_point(destructor:com_relyez_ems_common.RequestReport) + SharedDtor(); +} + +void RequestReport::SharedDtor() { + if (has_detail()) { + clear_detail(); + } + if (this != default_instance_) { + } +} + +void RequestReport::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestReport::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestReport_descriptor_; +} + +const RequestReport& RequestReport::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_RequestReport_2eproto(); + return *default_instance_; +} + +RequestReport* RequestReport::default_instance_ = NULL; + +RequestReport* RequestReport::New() const { + return new RequestReport; +} + +void RequestReport::clear_detail() { + switch(detail_case()) { + case kReportPoint: { + delete detail_.reportpoint_; + break; + } + case DETAIL_NOT_SET: { + break; + } + } + _oneof_case_[0] = DETAIL_NOT_SET; +} + + +void RequestReport::Clear() { + reporttype_ = 0; + clear_detail(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestReport::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:com_relyez_ems_common.RequestReport) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .com_relyez_ems_common.ReportType reportType = 1; + case 1: { + if (tag == 8) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::com_relyez_ems_common::ReportType_IsValid(value)) { + set_reporttype(static_cast< ::com_relyez_ems_common::ReportType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_unusual; + } + if (input->ExpectTag(802)) goto parse_reportPoint; + break; + } + + // optional .com_relyez_ems_common.RequestReportPoint reportPoint = 100; + case 100: { + if (tag == 802) { + parse_reportPoint: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_reportpoint())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:com_relyez_ems_common.RequestReport) + return true; +failure: + // @@protoc_insertion_point(parse_failure:com_relyez_ems_common.RequestReport) + return false; +#undef DO_ +} + +void RequestReport::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:com_relyez_ems_common.RequestReport) + // optional .com_relyez_ems_common.ReportType reportType = 1; + if (has_reporttype()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->reporttype(), output); + } + + // optional .com_relyez_ems_common.RequestReportPoint reportPoint = 100; + if (has_reportpoint()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 100, this->reportpoint(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:com_relyez_ems_common.RequestReport) +} + +::google::protobuf::uint8* RequestReport::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:com_relyez_ems_common.RequestReport) + // optional .com_relyez_ems_common.ReportType reportType = 1; + if (has_reporttype()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->reporttype(), target); + } + + // optional .com_relyez_ems_common.RequestReportPoint reportPoint = 100; + if (has_reportpoint()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 100, this->reportpoint(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:com_relyez_ems_common.RequestReport) + return target; +} + +int RequestReport::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional .com_relyez_ems_common.ReportType reportType = 1; + if (has_reporttype()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->reporttype()); + } + + } + switch (detail_case()) { + // optional .com_relyez_ems_common.RequestReportPoint reportPoint = 100; + case kReportPoint: { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->reportpoint()); + break; + } + case DETAIL_NOT_SET: { + break; + } + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestReport::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestReport* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestReport::MergeFrom(const RequestReport& from) { + GOOGLE_CHECK_NE(&from, this); + switch (from.detail_case()) { + case kReportPoint: { + mutable_reportpoint()->::com_relyez_ems_common::RequestReportPoint::MergeFrom(from.reportpoint()); + break; + } + case DETAIL_NOT_SET: { + break; + } + } + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_reporttype()) { + set_reporttype(from.reporttype()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestReport::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestReport::CopyFrom(const RequestReport& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestReport::IsInitialized() const { + + if (has_reportpoint()) { + if (!this->reportpoint().IsInitialized()) return false; + } + return true; +} + +void RequestReport::Swap(RequestReport* other) { + if (other != this) { + std::swap(reporttype_, other->reporttype_); + std::swap(detail_, other->detail_); + std::swap(_oneof_case_[0], other->_oneof_case_[0]); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestReport::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestReport_descriptor_; + metadata.reflection = RequestReport_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace com_relyez_ems_common + +// @@protoc_insertion_point(global_scope) diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReport.pb.h b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReport.pb.h new file mode 100644 index 00000000..17050d30 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReport.pb.h @@ -0,0 +1,244 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: RequestReport.proto + +#ifndef PROTOBUF_RequestReport_2eproto__INCLUDED +#define PROTOBUF_RequestReport_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2006000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include "EnumBase.pb.h" +#include "RequestReportPoint.pb.h" +// @@protoc_insertion_point(includes) + +namespace com_relyez_ems_common { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_RequestReport_2eproto(); +void protobuf_AssignDesc_RequestReport_2eproto(); +void protobuf_ShutdownFile_RequestReport_2eproto(); + +class RequestReport; + +// =================================================================== + +class RequestReport : public ::google::protobuf::Message { + public: + RequestReport(); + virtual ~RequestReport(); + + RequestReport(const RequestReport& from); + + inline RequestReport& operator=(const RequestReport& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestReport& default_instance(); + + enum DetailCase { + kReportPoint = 100, + DETAIL_NOT_SET = 0, + }; + + void Swap(RequestReport* other); + + // implements Message ---------------------------------------------- + + RequestReport* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestReport& from); + void MergeFrom(const RequestReport& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .com_relyez_ems_common.ReportType reportType = 1; + inline bool has_reporttype() const; + inline void clear_reporttype(); + static const int kReportTypeFieldNumber = 1; + inline ::com_relyez_ems_common::ReportType reporttype() const; + inline void set_reporttype(::com_relyez_ems_common::ReportType value); + + // optional .com_relyez_ems_common.RequestReportPoint reportPoint = 100; + inline bool has_reportpoint() const; + inline void clear_reportpoint(); + static const int kReportPointFieldNumber = 100; + inline const ::com_relyez_ems_common::RequestReportPoint& reportpoint() const; + inline ::com_relyez_ems_common::RequestReportPoint* mutable_reportpoint(); + inline ::com_relyez_ems_common::RequestReportPoint* release_reportpoint(); + inline void set_allocated_reportpoint(::com_relyez_ems_common::RequestReportPoint* reportpoint); + + inline DetailCase detail_case() const; + // @@protoc_insertion_point(class_scope:com_relyez_ems_common.RequestReport) + private: + inline void set_has_reporttype(); + inline void clear_has_reporttype(); + inline void set_has_reportpoint(); + + inline bool has_detail(); + void clear_detail(); + inline void clear_has_detail(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + int reporttype_; + union DetailUnion { + ::com_relyez_ems_common::RequestReportPoint* reportpoint_; + } detail_; + ::google::protobuf::uint32 _oneof_case_[1]; + + friend void protobuf_AddDesc_RequestReport_2eproto(); + friend void protobuf_AssignDesc_RequestReport_2eproto(); + friend void protobuf_ShutdownFile_RequestReport_2eproto(); + + void InitAsDefaultInstance(); + static RequestReport* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// RequestReport + +// optional .com_relyez_ems_common.ReportType reportType = 1; +inline bool RequestReport::has_reporttype() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestReport::set_has_reporttype() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestReport::clear_has_reporttype() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestReport::clear_reporttype() { + reporttype_ = 0; + clear_has_reporttype(); +} +inline ::com_relyez_ems_common::ReportType RequestReport::reporttype() const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.RequestReport.reportType) + return static_cast< ::com_relyez_ems_common::ReportType >(reporttype_); +} +inline void RequestReport::set_reporttype(::com_relyez_ems_common::ReportType value) { + assert(::com_relyez_ems_common::ReportType_IsValid(value)); + set_has_reporttype(); + reporttype_ = value; + // @@protoc_insertion_point(field_set:com_relyez_ems_common.RequestReport.reportType) +} + +// optional .com_relyez_ems_common.RequestReportPoint reportPoint = 100; +inline bool RequestReport::has_reportpoint() const { + return detail_case() == kReportPoint; +} +inline void RequestReport::set_has_reportpoint() { + _oneof_case_[0] = kReportPoint; +} +inline void RequestReport::clear_reportpoint() { + if (has_reportpoint()) { + delete detail_.reportpoint_; + clear_has_detail(); + } +} +inline const ::com_relyez_ems_common::RequestReportPoint& RequestReport::reportpoint() const { + return has_reportpoint() ? *detail_.reportpoint_ + : ::com_relyez_ems_common::RequestReportPoint::default_instance(); +} +inline ::com_relyez_ems_common::RequestReportPoint* RequestReport::mutable_reportpoint() { + if (!has_reportpoint()) { + clear_detail(); + set_has_reportpoint(); + detail_.reportpoint_ = new ::com_relyez_ems_common::RequestReportPoint; + } + return detail_.reportpoint_; +} +inline ::com_relyez_ems_common::RequestReportPoint* RequestReport::release_reportpoint() { + if (has_reportpoint()) { + clear_has_detail(); + ::com_relyez_ems_common::RequestReportPoint* temp = detail_.reportpoint_; + detail_.reportpoint_ = NULL; + return temp; + } else { + return NULL; + } +} +inline void RequestReport::set_allocated_reportpoint(::com_relyez_ems_common::RequestReportPoint* reportpoint) { + clear_detail(); + if (reportpoint) { + set_has_reportpoint(); + detail_.reportpoint_ = reportpoint; + } +} + +inline bool RequestReport::has_detail() { + return detail_case() != DETAIL_NOT_SET; +} +inline void RequestReport::clear_has_detail() { + _oneof_case_[0] = DETAIL_NOT_SET; +} +inline RequestReport::DetailCase RequestReport::detail_case() const { + return RequestReport::DetailCase(_oneof_case_[0]); +} + +// @@protoc_insertion_point(namespace_scope) + +} // namespace com_relyez_ems_common + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_RequestReport_2eproto__INCLUDED diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReport.proto b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReport.proto new file mode 100644 index 00000000..c0354686 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReport.proto @@ -0,0 +1,15 @@ +syntax = "proto2"; +package com_relyez_ems_common; + +import "EnumBase.proto"; +import "RequestReportPoint.proto"; + +message RequestReport { + // 上报类型 + optional ReportType reportType = 1; + + oneof detail { + // 测点数据上报 + RequestReportPoint reportPoint = 100; + } +} \ No newline at end of file diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReportPoint.pb.cc b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReportPoint.pb.cc new file mode 100644 index 00000000..a490e4ce --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReportPoint.pb.cc @@ -0,0 +1,388 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: RequestReportPoint.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "RequestReportPoint.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace com_relyez_ems_common { + +namespace { + +const ::google::protobuf::Descriptor* RequestReportPoint_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestReportPoint_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_RequestReportPoint_2eproto() { + protobuf_AddDesc_RequestReportPoint_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "RequestReportPoint.proto"); + GOOGLE_CHECK(file != NULL); + RequestReportPoint_descriptor_ = file->message_type(0); + static const int RequestReportPoint_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestReportPoint, time_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestReportPoint, typepoint_), + }; + RequestReportPoint_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestReportPoint_descriptor_, + RequestReportPoint::default_instance_, + RequestReportPoint_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestReportPoint, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestReportPoint, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestReportPoint)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_RequestReportPoint_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestReportPoint_descriptor_, &RequestReportPoint::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_RequestReportPoint_2eproto() { + delete RequestReportPoint::default_instance_; + delete RequestReportPoint_reflection_; +} + +void protobuf_AddDesc_RequestReportPoint_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::com_relyez_ems_common::protobuf_AddDesc_TypePoint_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\030RequestReportPoint.proto\022\025com_relyez_e" + "ms_common\032\017TypePoint.proto\"W\n\022RequestRep" + "ortPoint\022\014\n\004time\030\001 \001(\t\0223\n\ttypePoint\030\002 \003(" + "\0132 .com_relyez_ems_common.TypePoint", 155); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "RequestReportPoint.proto", &protobuf_RegisterTypes); + RequestReportPoint::default_instance_ = new RequestReportPoint(); + RequestReportPoint::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_RequestReportPoint_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_RequestReportPoint_2eproto { + StaticDescriptorInitializer_RequestReportPoint_2eproto() { + protobuf_AddDesc_RequestReportPoint_2eproto(); + } +} static_descriptor_initializer_RequestReportPoint_2eproto_; + +// =================================================================== + +#ifndef _MSC_VER +const int RequestReportPoint::kTimeFieldNumber; +const int RequestReportPoint::kTypePointFieldNumber; +#endif // !_MSC_VER + +RequestReportPoint::RequestReportPoint() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:com_relyez_ems_common.RequestReportPoint) +} + +void RequestReportPoint::InitAsDefaultInstance() { +} + +RequestReportPoint::RequestReportPoint(const RequestReportPoint& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:com_relyez_ems_common.RequestReportPoint) +} + +void RequestReportPoint::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + time_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestReportPoint::~RequestReportPoint() { + // @@protoc_insertion_point(destructor:com_relyez_ems_common.RequestReportPoint) + SharedDtor(); +} + +void RequestReportPoint::SharedDtor() { + if (time_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete time_; + } + if (this != default_instance_) { + } +} + +void RequestReportPoint::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestReportPoint::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestReportPoint_descriptor_; +} + +const RequestReportPoint& RequestReportPoint::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_RequestReportPoint_2eproto(); + return *default_instance_; +} + +RequestReportPoint* RequestReportPoint::default_instance_ = NULL; + +RequestReportPoint* RequestReportPoint::New() const { + return new RequestReportPoint; +} + +void RequestReportPoint::Clear() { + if (has_time()) { + if (time_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + time_->clear(); + } + } + typepoint_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestReportPoint::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:com_relyez_ems_common.RequestReportPoint) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string time = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_time())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->time().data(), this->time().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "time"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_typePoint; + break; + } + + // repeated .com_relyez_ems_common.TypePoint typePoint = 2; + case 2: { + if (tag == 18) { + parse_typePoint: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_typepoint())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_typePoint; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:com_relyez_ems_common.RequestReportPoint) + return true; +failure: + // @@protoc_insertion_point(parse_failure:com_relyez_ems_common.RequestReportPoint) + return false; +#undef DO_ +} + +void RequestReportPoint::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:com_relyez_ems_common.RequestReportPoint) + // optional string time = 1; + if (has_time()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->time().data(), this->time().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "time"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->time(), output); + } + + // repeated .com_relyez_ems_common.TypePoint typePoint = 2; + for (int i = 0; i < this->typepoint_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->typepoint(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:com_relyez_ems_common.RequestReportPoint) +} + +::google::protobuf::uint8* RequestReportPoint::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:com_relyez_ems_common.RequestReportPoint) + // optional string time = 1; + if (has_time()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->time().data(), this->time().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "time"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->time(), target); + } + + // repeated .com_relyez_ems_common.TypePoint typePoint = 2; + for (int i = 0; i < this->typepoint_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->typepoint(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:com_relyez_ems_common.RequestReportPoint) + return target; +} + +int RequestReportPoint::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string time = 1; + if (has_time()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->time()); + } + + } + // repeated .com_relyez_ems_common.TypePoint typePoint = 2; + total_size += 1 * this->typepoint_size(); + for (int i = 0; i < this->typepoint_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->typepoint(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestReportPoint::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestReportPoint* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestReportPoint::MergeFrom(const RequestReportPoint& from) { + GOOGLE_CHECK_NE(&from, this); + typepoint_.MergeFrom(from.typepoint_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_time()) { + set_time(from.time()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestReportPoint::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestReportPoint::CopyFrom(const RequestReportPoint& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestReportPoint::IsInitialized() const { + + if (!::google::protobuf::internal::AllAreInitialized(this->typepoint())) return false; + return true; +} + +void RequestReportPoint::Swap(RequestReportPoint* other) { + if (other != this) { + std::swap(time_, other->time_); + typepoint_.Swap(&other->typepoint_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestReportPoint::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestReportPoint_descriptor_; + metadata.reflection = RequestReportPoint_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace com_relyez_ems_common + +// @@protoc_insertion_point(global_scope) diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReportPoint.pb.h b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReportPoint.pb.h new file mode 100644 index 00000000..b8a200a5 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReportPoint.pb.h @@ -0,0 +1,265 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: RequestReportPoint.proto + +#ifndef PROTOBUF_RequestReportPoint_2eproto__INCLUDED +#define PROTOBUF_RequestReportPoint_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2006000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include "TypePoint.pb.h" +// @@protoc_insertion_point(includes) + +namespace com_relyez_ems_common { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_RequestReportPoint_2eproto(); +void protobuf_AssignDesc_RequestReportPoint_2eproto(); +void protobuf_ShutdownFile_RequestReportPoint_2eproto(); + +class RequestReportPoint; + +// =================================================================== + +class RequestReportPoint : public ::google::protobuf::Message { + public: + RequestReportPoint(); + virtual ~RequestReportPoint(); + + RequestReportPoint(const RequestReportPoint& from); + + inline RequestReportPoint& operator=(const RequestReportPoint& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestReportPoint& default_instance(); + + void Swap(RequestReportPoint* other); + + // implements Message ---------------------------------------------- + + RequestReportPoint* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestReportPoint& from); + void MergeFrom(const RequestReportPoint& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string time = 1; + inline bool has_time() const; + inline void clear_time(); + static const int kTimeFieldNumber = 1; + inline const ::std::string& time() const; + inline void set_time(const ::std::string& value); + inline void set_time(const char* value); + inline void set_time(const char* value, size_t size); + inline ::std::string* mutable_time(); + inline ::std::string* release_time(); + inline void set_allocated_time(::std::string* time); + + // repeated .com_relyez_ems_common.TypePoint typePoint = 2; + inline int typepoint_size() const; + inline void clear_typepoint(); + static const int kTypePointFieldNumber = 2; + inline const ::com_relyez_ems_common::TypePoint& typepoint(int index) const; + inline ::com_relyez_ems_common::TypePoint* mutable_typepoint(int index); + inline ::com_relyez_ems_common::TypePoint* add_typepoint(); + inline const ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::TypePoint >& + typepoint() const; + inline ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::TypePoint >* + mutable_typepoint(); + + // @@protoc_insertion_point(class_scope:com_relyez_ems_common.RequestReportPoint) + private: + inline void set_has_time(); + inline void clear_has_time(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* time_; + ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::TypePoint > typepoint_; + friend void protobuf_AddDesc_RequestReportPoint_2eproto(); + friend void protobuf_AssignDesc_RequestReportPoint_2eproto(); + friend void protobuf_ShutdownFile_RequestReportPoint_2eproto(); + + void InitAsDefaultInstance(); + static RequestReportPoint* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// RequestReportPoint + +// optional string time = 1; +inline bool RequestReportPoint::has_time() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestReportPoint::set_has_time() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestReportPoint::clear_has_time() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestReportPoint::clear_time() { + if (time_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + time_->clear(); + } + clear_has_time(); +} +inline const ::std::string& RequestReportPoint::time() const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.RequestReportPoint.time) + return *time_; +} +inline void RequestReportPoint::set_time(const ::std::string& value) { + set_has_time(); + if (time_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + time_ = new ::std::string; + } + time_->assign(value); + // @@protoc_insertion_point(field_set:com_relyez_ems_common.RequestReportPoint.time) +} +inline void RequestReportPoint::set_time(const char* value) { + set_has_time(); + if (time_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + time_ = new ::std::string; + } + time_->assign(value); + // @@protoc_insertion_point(field_set_char:com_relyez_ems_common.RequestReportPoint.time) +} +inline void RequestReportPoint::set_time(const char* value, size_t size) { + set_has_time(); + if (time_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + time_ = new ::std::string; + } + time_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:com_relyez_ems_common.RequestReportPoint.time) +} +inline ::std::string* RequestReportPoint::mutable_time() { + set_has_time(); + if (time_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + time_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:com_relyez_ems_common.RequestReportPoint.time) + return time_; +} +inline ::std::string* RequestReportPoint::release_time() { + clear_has_time(); + if (time_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = time_; + time_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void RequestReportPoint::set_allocated_time(::std::string* time) { + if (time_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete time_; + } + if (time) { + set_has_time(); + time_ = time; + } else { + clear_has_time(); + time_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:com_relyez_ems_common.RequestReportPoint.time) +} + +// repeated .com_relyez_ems_common.TypePoint typePoint = 2; +inline int RequestReportPoint::typepoint_size() const { + return typepoint_.size(); +} +inline void RequestReportPoint::clear_typepoint() { + typepoint_.Clear(); +} +inline const ::com_relyez_ems_common::TypePoint& RequestReportPoint::typepoint(int index) const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.RequestReportPoint.typePoint) + return typepoint_.Get(index); +} +inline ::com_relyez_ems_common::TypePoint* RequestReportPoint::mutable_typepoint(int index) { + // @@protoc_insertion_point(field_mutable:com_relyez_ems_common.RequestReportPoint.typePoint) + return typepoint_.Mutable(index); +} +inline ::com_relyez_ems_common::TypePoint* RequestReportPoint::add_typepoint() { + // @@protoc_insertion_point(field_add:com_relyez_ems_common.RequestReportPoint.typePoint) + return typepoint_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::TypePoint >& +RequestReportPoint::typepoint() const { + // @@protoc_insertion_point(field_list:com_relyez_ems_common.RequestReportPoint.typePoint) + return typepoint_; +} +inline ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::TypePoint >* +RequestReportPoint::mutable_typepoint() { + // @@protoc_insertion_point(field_mutable_list:com_relyez_ems_common.RequestReportPoint.typePoint) + return &typepoint_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace com_relyez_ems_common + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_RequestReportPoint_2eproto__INCLUDED diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReportPoint.proto b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReportPoint.proto new file mode 100644 index 00000000..c2e7b260 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/RequestReportPoint.proto @@ -0,0 +1,16 @@ +syntax = "proto2"; +package com_relyez_ems_common; + +import "TypePoint.proto"; + +/** + * 测点数据上报 + */ +message RequestReportPoint { + // 时间 + optional string time = 1; + + // 上报数据 + repeated TypePoint typePoint = 2; +} + diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/TypePoint.pb.cc b/product/src/fes/protocol/mqtt_yxCloud/proto/TypePoint.pb.cc new file mode 100644 index 00000000..a2750f93 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/TypePoint.pb.cc @@ -0,0 +1,831 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: TypePoint.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "TypePoint.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace com_relyez_ems_common { + +namespace { + +const ::google::protobuf::Descriptor* TypePoint_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + TypePoint_reflection_ = NULL; +const ::google::protobuf::Descriptor* Point_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Point_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_TypePoint_2eproto() { + protobuf_AddDesc_TypePoint_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "TypePoint.proto"); + GOOGLE_CHECK(file != NULL); + TypePoint_descriptor_ = file->message_type(0); + static const int TypePoint_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TypePoint, type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TypePoint, point_), + }; + TypePoint_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + TypePoint_descriptor_, + TypePoint::default_instance_, + TypePoint_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TypePoint, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TypePoint, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(TypePoint)); + Point_descriptor_ = file->message_type(1); + static const int Point_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, tagname_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, protocolparameter1_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, identification_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, value_), + }; + Point_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Point_descriptor_, + Point::default_instance_, + Point_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Point, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Point)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_TypePoint_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + TypePoint_descriptor_, &TypePoint::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Point_descriptor_, &Point::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_TypePoint_2eproto() { + delete TypePoint::default_instance_; + delete TypePoint_reflection_; + delete Point::default_instance_; + delete Point_reflection_; +} + +void protobuf_AddDesc_TypePoint_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\017TypePoint.proto\022\025com_relyez_ems_common" + "\"F\n\tTypePoint\022\014\n\004type\030\001 \002(\t\022+\n\005point\030\002 \003" + "(\0132\034.com_relyez_ems_common.Point\"[\n\005Poin" + "t\022\017\n\007tagName\030\001 \001(\t\022\032\n\022protocolParameter1" + "\030\002 \001(\t\022\026\n\016identification\030\003 \003(\t\022\r\n\005value\030" + "\004 \002(\t", 205); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "TypePoint.proto", &protobuf_RegisterTypes); + TypePoint::default_instance_ = new TypePoint(); + Point::default_instance_ = new Point(); + TypePoint::default_instance_->InitAsDefaultInstance(); + Point::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_TypePoint_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_TypePoint_2eproto { + StaticDescriptorInitializer_TypePoint_2eproto() { + protobuf_AddDesc_TypePoint_2eproto(); + } +} static_descriptor_initializer_TypePoint_2eproto_; + +// =================================================================== + +#ifndef _MSC_VER +const int TypePoint::kTypeFieldNumber; +const int TypePoint::kPointFieldNumber; +#endif // !_MSC_VER + +TypePoint::TypePoint() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:com_relyez_ems_common.TypePoint) +} + +void TypePoint::InitAsDefaultInstance() { +} + +TypePoint::TypePoint(const TypePoint& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:com_relyez_ems_common.TypePoint) +} + +void TypePoint::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +TypePoint::~TypePoint() { + // @@protoc_insertion_point(destructor:com_relyez_ems_common.TypePoint) + SharedDtor(); +} + +void TypePoint::SharedDtor() { + if (type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete type_; + } + if (this != default_instance_) { + } +} + +void TypePoint::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* TypePoint::descriptor() { + protobuf_AssignDescriptorsOnce(); + return TypePoint_descriptor_; +} + +const TypePoint& TypePoint::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_TypePoint_2eproto(); + return *default_instance_; +} + +TypePoint* TypePoint::default_instance_ = NULL; + +TypePoint* TypePoint::New() const { + return new TypePoint; +} + +void TypePoint::Clear() { + if (has_type()) { + if (type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + type_->clear(); + } + } + point_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool TypePoint::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:com_relyez_ems_common.TypePoint) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string type = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_type())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->type().data(), this->type().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "type"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_point; + break; + } + + // repeated .com_relyez_ems_common.Point point = 2; + case 2: { + if (tag == 18) { + parse_point: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_point())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_point; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:com_relyez_ems_common.TypePoint) + return true; +failure: + // @@protoc_insertion_point(parse_failure:com_relyez_ems_common.TypePoint) + return false; +#undef DO_ +} + +void TypePoint::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:com_relyez_ems_common.TypePoint) + // required string type = 1; + if (has_type()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->type().data(), this->type().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "type"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->type(), output); + } + + // repeated .com_relyez_ems_common.Point point = 2; + for (int i = 0; i < this->point_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->point(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:com_relyez_ems_common.TypePoint) +} + +::google::protobuf::uint8* TypePoint::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:com_relyez_ems_common.TypePoint) + // required string type = 1; + if (has_type()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->type().data(), this->type().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "type"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->type(), target); + } + + // repeated .com_relyez_ems_common.Point point = 2; + for (int i = 0; i < this->point_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->point(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:com_relyez_ems_common.TypePoint) + return target; +} + +int TypePoint::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string type = 1; + if (has_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->type()); + } + + } + // repeated .com_relyez_ems_common.Point point = 2; + total_size += 1 * this->point_size(); + for (int i = 0; i < this->point_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->point(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void TypePoint::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const TypePoint* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void TypePoint::MergeFrom(const TypePoint& from) { + GOOGLE_CHECK_NE(&from, this); + point_.MergeFrom(from.point_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_type()) { + set_type(from.type()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void TypePoint::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void TypePoint::CopyFrom(const TypePoint& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool TypePoint::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->point())) return false; + return true; +} + +void TypePoint::Swap(TypePoint* other) { + if (other != this) { + std::swap(type_, other->type_); + point_.Swap(&other->point_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata TypePoint::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = TypePoint_descriptor_; + metadata.reflection = TypePoint_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Point::kTagNameFieldNumber; +const int Point::kProtocolParameter1FieldNumber; +const int Point::kIdentificationFieldNumber; +const int Point::kValueFieldNumber; +#endif // !_MSC_VER + +Point::Point() + : ::google::protobuf::Message() { + SharedCtor(); + // @@protoc_insertion_point(constructor:com_relyez_ems_common.Point) +} + +void Point::InitAsDefaultInstance() { +} + +Point::Point(const Point& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:com_relyez_ems_common.Point) +} + +void Point::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + tagname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + protocolparameter1_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Point::~Point() { + // @@protoc_insertion_point(destructor:com_relyez_ems_common.Point) + SharedDtor(); +} + +void Point::SharedDtor() { + if (tagname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete tagname_; + } + if (protocolparameter1_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete protocolparameter1_; + } + if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete value_; + } + if (this != default_instance_) { + } +} + +void Point::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Point::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Point_descriptor_; +} + +const Point& Point::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_TypePoint_2eproto(); + return *default_instance_; +} + +Point* Point::default_instance_ = NULL; + +Point* Point::New() const { + return new Point; +} + +void Point::Clear() { + if (_has_bits_[0 / 32] & 11) { + if (has_tagname()) { + if (tagname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tagname_->clear(); + } + } + if (has_protocolparameter1()) { + if (protocolparameter1_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + protocolparameter1_->clear(); + } + } + if (has_value()) { + if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + value_->clear(); + } + } + } + identification_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Point::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:com_relyez_ems_common.Point) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string tagName = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_tagname())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->tagname().data(), this->tagname().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "tagname"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_protocolParameter1; + break; + } + + // optional string protocolParameter1 = 2; + case 2: { + if (tag == 18) { + parse_protocolParameter1: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_protocolparameter1())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->protocolparameter1().data(), this->protocolparameter1().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "protocolparameter1"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_identification; + break; + } + + // repeated string identification = 3; + case 3: { + if (tag == 26) { + parse_identification: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_identification())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->identification(this->identification_size() - 1).data(), + this->identification(this->identification_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE, + "identification"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_identification; + if (input->ExpectTag(34)) goto parse_value; + break; + } + + // required string value = 4; + case 4: { + if (tag == 34) { + parse_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "value"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:com_relyez_ems_common.Point) + return true; +failure: + // @@protoc_insertion_point(parse_failure:com_relyez_ems_common.Point) + return false; +#undef DO_ +} + +void Point::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:com_relyez_ems_common.Point) + // optional string tagName = 1; + if (has_tagname()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->tagname().data(), this->tagname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "tagname"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->tagname(), output); + } + + // optional string protocolParameter1 = 2; + if (has_protocolparameter1()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->protocolparameter1().data(), this->protocolparameter1().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "protocolparameter1"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->protocolparameter1(), output); + } + + // repeated string identification = 3; + for (int i = 0; i < this->identification_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->identification(i).data(), this->identification(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "identification"); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->identification(i), output); + } + + // required string value = 4; + if (has_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "value"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 4, this->value(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:com_relyez_ems_common.Point) +} + +::google::protobuf::uint8* Point::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:com_relyez_ems_common.Point) + // optional string tagName = 1; + if (has_tagname()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->tagname().data(), this->tagname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "tagname"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->tagname(), target); + } + + // optional string protocolParameter1 = 2; + if (has_protocolparameter1()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->protocolparameter1().data(), this->protocolparameter1().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "protocolparameter1"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->protocolparameter1(), target); + } + + // repeated string identification = 3; + for (int i = 0; i < this->identification_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->identification(i).data(), this->identification(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "identification"); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(3, this->identification(i), target); + } + + // required string value = 4; + if (has_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "value"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->value(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:com_relyez_ems_common.Point) + return target; +} + +int Point::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // optional string tagName = 1; + if (has_tagname()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->tagname()); + } + + // optional string protocolParameter1 = 2; + if (has_protocolparameter1()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->protocolparameter1()); + } + + // required string value = 4; + if (has_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->value()); + } + + } + // repeated string identification = 3; + total_size += 1 * this->identification_size(); + for (int i = 0; i < this->identification_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->identification(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Point::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Point* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Point::MergeFrom(const Point& from) { + GOOGLE_CHECK_NE(&from, this); + identification_.MergeFrom(from.identification_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_tagname()) { + set_tagname(from.tagname()); + } + if (from.has_protocolparameter1()) { + set_protocolparameter1(from.protocolparameter1()); + } + if (from.has_value()) { + set_value(from.value()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Point::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Point::CopyFrom(const Point& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Point::IsInitialized() const { + if ((_has_bits_[0] & 0x00000008) != 0x00000008) return false; + + return true; +} + +void Point::Swap(Point* other) { + if (other != this) { + std::swap(tagname_, other->tagname_); + std::swap(protocolparameter1_, other->protocolparameter1_); + identification_.Swap(&other->identification_); + std::swap(value_, other->value_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Point::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Point_descriptor_; + metadata.reflection = Point_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace com_relyez_ems_common + +// @@protoc_insertion_point(global_scope) diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/TypePoint.pb.h b/product/src/fes/protocol/mqtt_yxCloud/proto/TypePoint.pb.h new file mode 100644 index 00000000..e2d322a5 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/TypePoint.pb.h @@ -0,0 +1,682 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: TypePoint.proto + +#ifndef PROTOBUF_TypePoint_2eproto__INCLUDED +#define PROTOBUF_TypePoint_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2006000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace com_relyez_ems_common { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_TypePoint_2eproto(); +void protobuf_AssignDesc_TypePoint_2eproto(); +void protobuf_ShutdownFile_TypePoint_2eproto(); + +class TypePoint; +class Point; + +// =================================================================== + +class TypePoint : public ::google::protobuf::Message { + public: + TypePoint(); + virtual ~TypePoint(); + + TypePoint(const TypePoint& from); + + inline TypePoint& operator=(const TypePoint& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const TypePoint& default_instance(); + + void Swap(TypePoint* other); + + // implements Message ---------------------------------------------- + + TypePoint* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const TypePoint& from); + void MergeFrom(const TypePoint& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string type = 1; + inline bool has_type() const; + inline void clear_type(); + static const int kTypeFieldNumber = 1; + inline const ::std::string& type() const; + inline void set_type(const ::std::string& value); + inline void set_type(const char* value); + inline void set_type(const char* value, size_t size); + inline ::std::string* mutable_type(); + inline ::std::string* release_type(); + inline void set_allocated_type(::std::string* type); + + // repeated .com_relyez_ems_common.Point point = 2; + inline int point_size() const; + inline void clear_point(); + static const int kPointFieldNumber = 2; + inline const ::com_relyez_ems_common::Point& point(int index) const; + inline ::com_relyez_ems_common::Point* mutable_point(int index); + inline ::com_relyez_ems_common::Point* add_point(); + inline const ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::Point >& + point() const; + inline ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::Point >* + mutable_point(); + + // @@protoc_insertion_point(class_scope:com_relyez_ems_common.TypePoint) + private: + inline void set_has_type(); + inline void clear_has_type(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* type_; + ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::Point > point_; + friend void protobuf_AddDesc_TypePoint_2eproto(); + friend void protobuf_AssignDesc_TypePoint_2eproto(); + friend void protobuf_ShutdownFile_TypePoint_2eproto(); + + void InitAsDefaultInstance(); + static TypePoint* default_instance_; +}; +// ------------------------------------------------------------------- + +class Point : public ::google::protobuf::Message { + public: + Point(); + virtual ~Point(); + + Point(const Point& from); + + inline Point& operator=(const Point& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Point& default_instance(); + + void Swap(Point* other); + + // implements Message ---------------------------------------------- + + Point* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Point& from); + void MergeFrom(const Point& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string tagName = 1; + inline bool has_tagname() const; + inline void clear_tagname(); + static const int kTagNameFieldNumber = 1; + inline const ::std::string& tagname() const; + inline void set_tagname(const ::std::string& value); + inline void set_tagname(const char* value); + inline void set_tagname(const char* value, size_t size); + inline ::std::string* mutable_tagname(); + inline ::std::string* release_tagname(); + inline void set_allocated_tagname(::std::string* tagname); + + // optional string protocolParameter1 = 2; + inline bool has_protocolparameter1() const; + inline void clear_protocolparameter1(); + static const int kProtocolParameter1FieldNumber = 2; + inline const ::std::string& protocolparameter1() const; + inline void set_protocolparameter1(const ::std::string& value); + inline void set_protocolparameter1(const char* value); + inline void set_protocolparameter1(const char* value, size_t size); + inline ::std::string* mutable_protocolparameter1(); + inline ::std::string* release_protocolparameter1(); + inline void set_allocated_protocolparameter1(::std::string* protocolparameter1); + + // repeated string identification = 3; + inline int identification_size() const; + inline void clear_identification(); + static const int kIdentificationFieldNumber = 3; + inline const ::std::string& identification(int index) const; + inline ::std::string* mutable_identification(int index); + inline void set_identification(int index, const ::std::string& value); + inline void set_identification(int index, const char* value); + inline void set_identification(int index, const char* value, size_t size); + inline ::std::string* add_identification(); + inline void add_identification(const ::std::string& value); + inline void add_identification(const char* value); + inline void add_identification(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& identification() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_identification(); + + // required string value = 4; + inline bool has_value() const; + inline void clear_value(); + static const int kValueFieldNumber = 4; + inline const ::std::string& value() const; + inline void set_value(const ::std::string& value); + inline void set_value(const char* value); + inline void set_value(const char* value, size_t size); + inline ::std::string* mutable_value(); + inline ::std::string* release_value(); + inline void set_allocated_value(::std::string* value); + + // @@protoc_insertion_point(class_scope:com_relyez_ems_common.Point) + private: + inline void set_has_tagname(); + inline void clear_has_tagname(); + inline void set_has_protocolparameter1(); + inline void clear_has_protocolparameter1(); + inline void set_has_value(); + inline void clear_has_value(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::std::string* tagname_; + ::std::string* protocolparameter1_; + ::google::protobuf::RepeatedPtrField< ::std::string> identification_; + ::std::string* value_; + friend void protobuf_AddDesc_TypePoint_2eproto(); + friend void protobuf_AssignDesc_TypePoint_2eproto(); + friend void protobuf_ShutdownFile_TypePoint_2eproto(); + + void InitAsDefaultInstance(); + static Point* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// TypePoint + +// required string type = 1; +inline bool TypePoint::has_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void TypePoint::set_has_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void TypePoint::clear_has_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void TypePoint::clear_type() { + if (type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + type_->clear(); + } + clear_has_type(); +} +inline const ::std::string& TypePoint::type() const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.TypePoint.type) + return *type_; +} +inline void TypePoint::set_type(const ::std::string& value) { + set_has_type(); + if (type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + type_ = new ::std::string; + } + type_->assign(value); + // @@protoc_insertion_point(field_set:com_relyez_ems_common.TypePoint.type) +} +inline void TypePoint::set_type(const char* value) { + set_has_type(); + if (type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + type_ = new ::std::string; + } + type_->assign(value); + // @@protoc_insertion_point(field_set_char:com_relyez_ems_common.TypePoint.type) +} +inline void TypePoint::set_type(const char* value, size_t size) { + set_has_type(); + if (type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + type_ = new ::std::string; + } + type_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:com_relyez_ems_common.TypePoint.type) +} +inline ::std::string* TypePoint::mutable_type() { + set_has_type(); + if (type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + type_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:com_relyez_ems_common.TypePoint.type) + return type_; +} +inline ::std::string* TypePoint::release_type() { + clear_has_type(); + if (type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = type_; + type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void TypePoint::set_allocated_type(::std::string* type) { + if (type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete type_; + } + if (type) { + set_has_type(); + type_ = type; + } else { + clear_has_type(); + type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:com_relyez_ems_common.TypePoint.type) +} + +// repeated .com_relyez_ems_common.Point point = 2; +inline int TypePoint::point_size() const { + return point_.size(); +} +inline void TypePoint::clear_point() { + point_.Clear(); +} +inline const ::com_relyez_ems_common::Point& TypePoint::point(int index) const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.TypePoint.point) + return point_.Get(index); +} +inline ::com_relyez_ems_common::Point* TypePoint::mutable_point(int index) { + // @@protoc_insertion_point(field_mutable:com_relyez_ems_common.TypePoint.point) + return point_.Mutable(index); +} +inline ::com_relyez_ems_common::Point* TypePoint::add_point() { + // @@protoc_insertion_point(field_add:com_relyez_ems_common.TypePoint.point) + return point_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::Point >& +TypePoint::point() const { + // @@protoc_insertion_point(field_list:com_relyez_ems_common.TypePoint.point) + return point_; +} +inline ::google::protobuf::RepeatedPtrField< ::com_relyez_ems_common::Point >* +TypePoint::mutable_point() { + // @@protoc_insertion_point(field_mutable_list:com_relyez_ems_common.TypePoint.point) + return &point_; +} + +// ------------------------------------------------------------------- + +// Point + +// optional string tagName = 1; +inline bool Point::has_tagname() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Point::set_has_tagname() { + _has_bits_[0] |= 0x00000001u; +} +inline void Point::clear_has_tagname() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Point::clear_tagname() { + if (tagname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tagname_->clear(); + } + clear_has_tagname(); +} +inline const ::std::string& Point::tagname() const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.Point.tagName) + return *tagname_; +} +inline void Point::set_tagname(const ::std::string& value) { + set_has_tagname(); + if (tagname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tagname_ = new ::std::string; + } + tagname_->assign(value); + // @@protoc_insertion_point(field_set:com_relyez_ems_common.Point.tagName) +} +inline void Point::set_tagname(const char* value) { + set_has_tagname(); + if (tagname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tagname_ = new ::std::string; + } + tagname_->assign(value); + // @@protoc_insertion_point(field_set_char:com_relyez_ems_common.Point.tagName) +} +inline void Point::set_tagname(const char* value, size_t size) { + set_has_tagname(); + if (tagname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tagname_ = new ::std::string; + } + tagname_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:com_relyez_ems_common.Point.tagName) +} +inline ::std::string* Point::mutable_tagname() { + set_has_tagname(); + if (tagname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + tagname_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:com_relyez_ems_common.Point.tagName) + return tagname_; +} +inline ::std::string* Point::release_tagname() { + clear_has_tagname(); + if (tagname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = tagname_; + tagname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void Point::set_allocated_tagname(::std::string* tagname) { + if (tagname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete tagname_; + } + if (tagname) { + set_has_tagname(); + tagname_ = tagname; + } else { + clear_has_tagname(); + tagname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:com_relyez_ems_common.Point.tagName) +} + +// optional string protocolParameter1 = 2; +inline bool Point::has_protocolparameter1() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Point::set_has_protocolparameter1() { + _has_bits_[0] |= 0x00000002u; +} +inline void Point::clear_has_protocolparameter1() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Point::clear_protocolparameter1() { + if (protocolparameter1_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + protocolparameter1_->clear(); + } + clear_has_protocolparameter1(); +} +inline const ::std::string& Point::protocolparameter1() const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.Point.protocolParameter1) + return *protocolparameter1_; +} +inline void Point::set_protocolparameter1(const ::std::string& value) { + set_has_protocolparameter1(); + if (protocolparameter1_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + protocolparameter1_ = new ::std::string; + } + protocolparameter1_->assign(value); + // @@protoc_insertion_point(field_set:com_relyez_ems_common.Point.protocolParameter1) +} +inline void Point::set_protocolparameter1(const char* value) { + set_has_protocolparameter1(); + if (protocolparameter1_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + protocolparameter1_ = new ::std::string; + } + protocolparameter1_->assign(value); + // @@protoc_insertion_point(field_set_char:com_relyez_ems_common.Point.protocolParameter1) +} +inline void Point::set_protocolparameter1(const char* value, size_t size) { + set_has_protocolparameter1(); + if (protocolparameter1_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + protocolparameter1_ = new ::std::string; + } + protocolparameter1_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:com_relyez_ems_common.Point.protocolParameter1) +} +inline ::std::string* Point::mutable_protocolparameter1() { + set_has_protocolparameter1(); + if (protocolparameter1_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + protocolparameter1_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:com_relyez_ems_common.Point.protocolParameter1) + return protocolparameter1_; +} +inline ::std::string* Point::release_protocolparameter1() { + clear_has_protocolparameter1(); + if (protocolparameter1_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = protocolparameter1_; + protocolparameter1_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void Point::set_allocated_protocolparameter1(::std::string* protocolparameter1) { + if (protocolparameter1_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete protocolparameter1_; + } + if (protocolparameter1) { + set_has_protocolparameter1(); + protocolparameter1_ = protocolparameter1; + } else { + clear_has_protocolparameter1(); + protocolparameter1_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:com_relyez_ems_common.Point.protocolParameter1) +} + +// repeated string identification = 3; +inline int Point::identification_size() const { + return identification_.size(); +} +inline void Point::clear_identification() { + identification_.Clear(); +} +inline const ::std::string& Point::identification(int index) const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.Point.identification) + return identification_.Get(index); +} +inline ::std::string* Point::mutable_identification(int index) { + // @@protoc_insertion_point(field_mutable:com_relyez_ems_common.Point.identification) + return identification_.Mutable(index); +} +inline void Point::set_identification(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:com_relyez_ems_common.Point.identification) + identification_.Mutable(index)->assign(value); +} +inline void Point::set_identification(int index, const char* value) { + identification_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:com_relyez_ems_common.Point.identification) +} +inline void Point::set_identification(int index, const char* value, size_t size) { + identification_.Mutable(index)->assign( + reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:com_relyez_ems_common.Point.identification) +} +inline ::std::string* Point::add_identification() { + return identification_.Add(); +} +inline void Point::add_identification(const ::std::string& value) { + identification_.Add()->assign(value); + // @@protoc_insertion_point(field_add:com_relyez_ems_common.Point.identification) +} +inline void Point::add_identification(const char* value) { + identification_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:com_relyez_ems_common.Point.identification) +} +inline void Point::add_identification(const char* value, size_t size) { + identification_.Add()->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_add_pointer:com_relyez_ems_common.Point.identification) +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +Point::identification() const { + // @@protoc_insertion_point(field_list:com_relyez_ems_common.Point.identification) + return identification_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +Point::mutable_identification() { + // @@protoc_insertion_point(field_mutable_list:com_relyez_ems_common.Point.identification) + return &identification_; +} + +// required string value = 4; +inline bool Point::has_value() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void Point::set_has_value() { + _has_bits_[0] |= 0x00000008u; +} +inline void Point::clear_has_value() { + _has_bits_[0] &= ~0x00000008u; +} +inline void Point::clear_value() { + if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + value_->clear(); + } + clear_has_value(); +} +inline const ::std::string& Point::value() const { + // @@protoc_insertion_point(field_get:com_relyez_ems_common.Point.value) + return *value_; +} +inline void Point::set_value(const ::std::string& value) { + set_has_value(); + if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + value_ = new ::std::string; + } + value_->assign(value); + // @@protoc_insertion_point(field_set:com_relyez_ems_common.Point.value) +} +inline void Point::set_value(const char* value) { + set_has_value(); + if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + value_ = new ::std::string; + } + value_->assign(value); + // @@protoc_insertion_point(field_set_char:com_relyez_ems_common.Point.value) +} +inline void Point::set_value(const char* value, size_t size) { + set_has_value(); + if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + value_ = new ::std::string; + } + value_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:com_relyez_ems_common.Point.value) +} +inline ::std::string* Point::mutable_value() { + set_has_value(); + if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + value_ = new ::std::string; + } + // @@protoc_insertion_point(field_mutable:com_relyez_ems_common.Point.value) + return value_; +} +inline ::std::string* Point::release_value() { + clear_has_value(); + if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + return NULL; + } else { + ::std::string* temp = value_; + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return temp; + } +} +inline void Point::set_allocated_value(::std::string* value) { + if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete value_; + } + if (value) { + set_has_value(); + value_ = value; + } else { + clear_has_value(); + value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:com_relyez_ems_common.Point.value) +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace com_relyez_ems_common + +#ifndef SWIG +namespace google { +namespace protobuf { + + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_TypePoint_2eproto__INCLUDED diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/TypePoint.proto b/product/src/fes/protocol/mqtt_yxCloud/proto/TypePoint.proto new file mode 100644 index 00000000..138c81b5 --- /dev/null +++ b/product/src/fes/protocol/mqtt_yxCloud/proto/TypePoint.proto @@ -0,0 +1,23 @@ +syntax = "proto2"; +package com_relyez_ems_common; + +message TypePoint { + // + required string type = 1; + // + repeated Point point = 2; +} + +message Point { + // ǩ + optional string tagName = 1; + + // Լ1 + optional string protocolParameter1 = 2; + + // ʶչδʹ + repeated string identification = 3; + + // ֵ + required string value = 4; +} \ No newline at end of file diff --git a/product/src/fes/protocol/mqtt_yxCloud/proto/protoc.exe b/product/src/fes/protocol/mqtt_yxCloud/proto/protoc.exe new file mode 100644 index 00000000..9b0ebdc9 Binary files /dev/null and b/product/src/fes/protocol/mqtt_yxCloud/proto/protoc.exe differ diff --git a/product/src/fes/protocol/opc_ua_client_s/DataProcThread.cpp b/product/src/fes/protocol/opc_ua_client_s/DataProcThread.cpp new file mode 100644 index 00000000..92017d00 --- /dev/null +++ b/product/src/fes/protocol/opc_ua_client_s/DataProcThread.cpp @@ -0,0 +1,928 @@ +#include "DataProcThread.h" + + +extern bool g_OpcUaIsMainFes; +extern bool g_OpcUaChanelRun; +const int gOpcUaThreadTime = 10; + +COpcUaDataProcThread::COpcUaDataProcThread(CFesBase *ptrCFesBase, CFesChanPtr ptrCFesChan, const vector vecAppParam) + :CTimerThreadBase("COpcUaDataProcThread", gOpcUaThreadTime, 0, true),m_bReady(true),m_bConnected(false), + m_ptrUaClient(NULL),m_ptrDIWriteValue(NULL),m_ptrAIWriteValue(NULL),m_ptrMIWriteValue(NULL),m_ptrAccWriteValue(NULL),m_lastBatchUpateTime(0) +{ + m_pChgAiData=NULL; + m_pChgDiData=NULL; + m_pChgAccData=NULL; + m_pChgMiData=NULL; + + + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL)) + { + return; + } + m_ptrCFesChan->SetLinkStatus(CN_FesChanConnect); + m_ptrCFesChan->SetComThreadRunFlag(CN_FesRunFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + + + bool found = false; + if (vecAppParam.size() > 0) + { + for (size_t i = 0; i < vecAppParam.size(); i++) + { + if (m_ptrCFesRtu->m_Param.RtuNo == vecAppParam[i].RtuNo) + { + //配置 + m_AppData= vecAppParam[i]; + found = true; + break; + } + } + } + + if(found) + { + initWriteValueArray(); + connectServer(); + } + else + { + m_bReady=false; + LOGERROR("COpcUaDataProcThread ChanNo=%d can not match rtuNo in config due to now rtuNo is %d and do nothing", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo); + } + +} + + +COpcUaDataProcThread::~COpcUaDataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + clearData(); + + if(m_ptrUaClient) + { + UA_Client_delete(m_ptrUaClient); + m_ptrUaClient=NULL; + } + + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + LOGDEBUG("COpcUaDataProcThread::~COpcUaDataProcThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); +} + +int COpcUaDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +void COpcUaDataProcThread::execute() +{ + + if(m_bReady) + { + LOGTRACE("COpcUaDataProcThread ChanNo=%d not ready ,check log which has record err", m_ptrCurrentChan->m_Param.ChanNo); + return; + } + if(!m_bConnected) + { + if(iotSuccess!=connectServer()) + { + m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuComDown); + LOGERROR("COpcUaDataProcThread ChanNo=%d reconnect failed ", m_ptrCurrentChan->m_Param.ChanNo); + return; + } + } + UA_StatusCode status = UA_Client_run_iterate(m_ptrUaClient, 100); // most wait 100 ms + if (status != UA_STATUSCODE_GOOD) { + if(iotSuccess!=connectServer()) + { + m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuComDown); + LOGERROR("COpcUaDataProcThread ChanNo=%d reconnect failed ", m_ptrCurrentChan->m_Param.ChanNo); + return; + } + } + + if(g_OpcUaIsMainFes) + { + ForwardData(); + } + + +} + + +void COpcUaDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetComThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetLinkStatus(CN_FesChanDisconnect); + + LOGDEBUG("COpcUaDataProcThread::beforeQuit() "); +} + +void COpcUaDataProcThread::ForwardData() +{ + + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + + //定时读取遥控命令响应缓冲区,及时清除队列释放空间,不对遥控成败作处理 + if (m_ptrCFesRtu->GetFwDoRespCmdNum() > 0) + { + SFesFwDoRespCmd retCmd; + m_ptrCFesRtu->ReadFwDoRespCmd(1, &retCmd); + } + + if (m_ptrCFesRtu->GetFwAoRespCmdNum() > 0) + { + SFesFwAoRespCmd retCmd; + m_ptrCFesRtu->ReadFwAoRespCmd(1, &retCmd); + } + + + + + + ifDataChgAndWrite(); + ifTimeToPublish(); + + + + + + +} + +void COpcUaDataProcThread::ifTimeToPublish() +{ + int64 cursec = getMonotonicMsec(); + if(0!=m_AppData.intervalTime) + { + if ((cursec - m_lastBatchUpateTime) > m_AppData.intervalTime) + { + m_lastBatchUpateTime=cursec; + } + else + { + return; + } + } + + + + handleAiData(); + handleDiData(); + handleMiData(); + handleAccData(); +} + + +void COpcUaDataProcThread::handleDiData() +{ + SFesFwDi *pFwDi=NULL; + int yxbit; + for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxFwDiPoints; diPoint++) + { + pFwDi = m_ptrCFesRtu->m_pFwDi + diPoint; + UA_WriteValue* tmp=&m_ptrDIWriteValue[diPoint]; + tmp->value.hasValue=true; + yxbit = pFwDi->Value & 0x01; + buildValue(pFwDi->ResParam1,yxbit,tmp->value.value); + tmp->value.hasStatus=true; + if(pFwDi->Status&CN_FesValueInvaild) + { + tmp->value.status=UA_STATUSCODE_BAD; + } + else + { + tmp->value.status=UA_STATUSCODE_GOOD; + } + + } + + + if(m_ptrCFesRtu->m_MaxFwDiPoints>0) + { + BatchRequest(m_ptrDIWriteValue,m_ptrCFesRtu->m_MaxFwDiPoints+1,"batchDi"); + } + +} + +void COpcUaDataProcThread::handleAiData() +{ + SFesFwAi *pFwAi=NULL; + double fvalue; + for (int aiPoint = 0; aiPoint < m_ptrCFesRtu->m_MaxFwAiPoints; aiPoint++) + { + pFwAi = m_ptrCFesRtu->m_pFwAi + aiPoint; + UA_WriteValue* tmp=&m_ptrAIWriteValue[aiPoint]; + tmp->value.hasValue=true; + fvalue = pFwAi->Value*pFwAi->Coeff + pFwAi->Base; + buildValue(pFwAi->ResParam1,fvalue,tmp->value.value); + tmp->value.hasStatus=true; + if(pFwAi->Status&CN_FesValueInvaild) + { + tmp->value.status=UA_STATUSCODE_BAD; + } + else + { + tmp->value.status=UA_STATUSCODE_GOOD; + } + + } + + + + + + if(m_ptrCFesRtu->m_MaxFwAiPoints>0) + { + BatchRequest(m_ptrAIWriteValue,m_ptrCFesRtu->m_MaxFwAiPoints+1,"batchAi"); + } + +} + +void COpcUaDataProcThread::handleAccData() +{ + SFesFwAcc *pFwAcc=NULL; + double fvalue; + for (int accPoint = 0; accPoint < m_ptrCFesRtu->m_MaxFwAccPoints; accPoint++) + { + pFwAcc = m_ptrCFesRtu->m_pFwAcc + accPoint; + UA_WriteValue* tmp=&m_ptrAccWriteValue[accPoint]; + tmp->value.hasValue=true; + fvalue = pFwAcc->Value*pFwAcc->Coeff + pFwAcc->Base; + buildValue(pFwAcc->ResParam1,fvalue,tmp->value.value); + tmp->value.hasStatus=true; + if(pFwAcc->Status&CN_FesValueInvaild) + { + tmp->value.status=UA_STATUSCODE_BAD; + } + else + { + tmp->value.status=UA_STATUSCODE_GOOD; + } + + } + + if(m_ptrCFesRtu->m_MaxFwAccPoints>0) + { + + BatchRequest(m_ptrAccWriteValue,m_ptrCFesRtu->m_MaxFwAccPoints+1,"batchAcc"); + } + +} + + +void COpcUaDataProcThread::handleMiData() +{ + SFesFwMi *pFwMi=NULL; + double fvalue; + for (int miPoint = 0; miPoint < m_ptrCFesRtu->m_MaxFwMiPoints; miPoint++) + { + pFwMi = m_ptrCFesRtu->m_pFwMi + miPoint; + UA_WriteValue* tmp=&m_ptrMIWriteValue[miPoint]; + tmp->value.hasValue=true; + fvalue = pFwMi->Value*pFwMi->Coeff + pFwMi->Base; + buildValue(pFwMi->ResParam1,fvalue,tmp->value.value); + tmp->value.hasStatus=true; + if(pFwMi->Status&CN_FesValueInvaild) + { + tmp->value.status=UA_STATUSCODE_BAD; + } + else + { + tmp->value.status=UA_STATUSCODE_GOOD; + } + + } + + + if(m_ptrCFesRtu->m_MaxFwMiPoints>0) + { + BatchRequest(m_ptrMIWriteValue,m_ptrCFesRtu->m_MaxFwMiPoints+1,"batchMi"); + } + +} + +void COpcUaDataProcThread::ifDataChgAndWrite() +{ + handleChgAiData(); + handleChgDiData(); + handleChgAccData(); + handleChgMiData(); +} + +void COpcUaDataProcThread::handleChgAiData() +{ + int nAiCount = m_ptrCFesRtu->GetFwChgAiNum(); + if(0==nAiCount) + { + return; + } + SFesFwChgAi *pChgAi = NULL; + SFesFwAi *pFwAi = NULL; + + if (m_pChgAiData == NULL) + m_pChgAiData = (SFesFwChgAi*)malloc(nAiCount * sizeof(SFesFwChgAi)); + else + m_pChgAiData = (SFesFwChgAi*)realloc(m_pChgAiData, nAiCount * sizeof(SFesFwChgAi)); + + int nReadNum = m_ptrCFesRtu->ReadFwChgAi(nAiCount, m_pChgAiData); + + + UA_WriteValue* ptrAiWriteValue=new UA_WriteValue[nReadNum]; + + + for (int i = 0; i < nReadNum; i++) + { + pChgAi = m_pChgAiData + i; + if(pChgAi->RemoteNo >= m_ptrCFesRtu->m_MaxFwAiPoints) + { + continue; + } + pFwAi = m_ptrCFesRtu->m_pFwAi + pChgAi->RemoteNo; + float AiFloatValue = static_cast(pChgAi->Value * pFwAi->Coeff + pFwAi->Base); + UA_WriteValue* tmp=&ptrAiWriteValue[nReadNum]; + tmp->value.hasValue=true; + buildValue(pFwAi->ResParam1,AiFloatValue,tmp->value.value); + tmp->value.hasStatus=true; + tmp->value.status=UA_STATUSCODE_GOOD; + } + + if(nReadNum>0) + { + BatchRequest(ptrAiWriteValue,nReadNum,"ChgAiData"); + } + + + for (int i = 0; i < nReadNum; i++) + { + UA_WriteValue* tmp=&ptrAiWriteValue[i]; + if(tmp) + { + UA_WriteValue_clear(tmp); + } + + } + + delete[] ptrAiWriteValue; + +} + +void COpcUaDataProcThread::handleChgDiData() +{ + SFesFwChgDi *pChgDi; + int DiValue; + SFesFwDi *pFwDi; + int nDiCount = m_ptrCFesRtu->GetFwChgDiNum(); + if(0==nDiCount) + { + return; + } + if (m_pChgDiData == NULL) + m_pChgDiData = (SFesFwChgDi*)malloc(nDiCount * sizeof(SFesFwChgDi)); + else + m_pChgDiData = (SFesFwChgDi*)realloc(m_pChgDiData, nDiCount * sizeof(SFesFwChgDi)); + + int retNum = m_ptrCFesRtu->ReadFwChgDi(nDiCount, m_pChgDiData); + + UA_WriteValue* ptrDiWriteValue=new UA_WriteValue[retNum]; + for (int i=0;iRemoteNo >= m_ptrCFesRtu->m_MaxFwDiPoints) + continue; + pFwDi = m_ptrCFesRtu->m_pFwDi+ pChgDi->RemoteNo; + + DiValue = pChgDi->Value&0x01; + + UA_WriteValue* tmp=&ptrDiWriteValue[i]; + tmp->value.hasValue=true; + buildValue(pFwDi->ResParam1,DiValue,tmp->value.value); + tmp->value.hasStatus=true; + tmp->value.status=UA_STATUSCODE_GOOD; + } + + if(retNum>0) + { + BatchRequest(ptrDiWriteValue,retNum,"ChgDiData"); + } + + + for (int i = 0; i < retNum; i++) + { + UA_WriteValue* tmp=&ptrDiWriteValue[i]; + if(tmp) + { + UA_WriteValue_clear(tmp); + } + + } + + delete[] ptrDiWriteValue; + + +} + +void COpcUaDataProcThread::handleChgAccData() +{ + int nAccCount = m_ptrCFesRtu->GetFwChgAccNum(); + if(0==nAccCount) + { + return; + } + SFesFwChgAcc *pChgAcc; + SFesFwAcc *pFwAcc; + if (m_pChgAccData == NULL) + m_pChgAccData = (SFesFwChgAcc*)malloc(nAccCount * sizeof(SFesFwChgAcc)); + else + m_pChgAccData = (SFesFwChgAcc*)realloc(m_pChgAccData, nAccCount * sizeof(SFesFwChgAcc)); + + int nReadNum = m_ptrCFesRtu->ReadFwChgAcc(nAccCount, m_pChgAccData); + + UA_WriteValue* ptrAccWriteValue=new UA_WriteValue[nReadNum]; + for (int i = 0; i < nReadNum; i++) + { + pChgAcc = m_pChgAccData + i; + if(pChgAcc->RemoteNo >= m_ptrCFesRtu->m_MaxFwAccPoints) + { + continue; + } + pFwAcc = m_ptrCFesRtu->m_pFwAcc + pChgAcc->RemoteNo; + + float AccFloatValue = static_cast(pChgAcc->Value * pFwAcc->Coeff + pFwAcc->Base); + + UA_WriteValue* tmp=&ptrAccWriteValue[nReadNum]; + tmp->value.hasValue=true; + buildValue(pFwAcc->ResParam1,AccFloatValue,tmp->value.value); + tmp->value.hasStatus=true; + tmp->value.status=UA_STATUSCODE_GOOD; + + } + + + if(nReadNum>0) + { + BatchRequest(ptrAccWriteValue,nReadNum,"ChgAccData"); + } + + + for (int i = 0; i < nReadNum; i++) + { + UA_WriteValue* tmp=&ptrAccWriteValue[i]; + if(tmp) + { + UA_WriteValue_clear(tmp); + } + + } + + delete[] ptrAccWriteValue; +} + +void COpcUaDataProcThread::handleChgMiData() +{ + int nMiCount = m_ptrCFesRtu->GetFwChgMiNum(); + if(0==nMiCount) + { + return; + } + SFesFwChgMi *pChgMi; + SFesFwMi *pFwMi; + if (m_pChgMiData == NULL) + m_pChgMiData = (SFesFwChgMi*)malloc(nMiCount * sizeof(SFesFwChgMi)); + else + m_pChgMiData = (SFesFwChgMi*)realloc(m_pChgMiData, nMiCount * sizeof(SFesFwChgMi)); + + int nReadNum = m_ptrCFesRtu->ReadFwChgMi(nMiCount, m_pChgMiData); + + + UA_WriteValue* ptrMiWriteValue=new UA_WriteValue[nReadNum]; + + for (int i = 0; i < nReadNum; i++) + { + pChgMi = m_pChgMiData + i; + if(pChgMi->RemoteNo >= m_ptrCFesRtu->m_MaxFwMiPoints) + { + continue; + } + pFwMi = m_ptrCFesRtu->m_pFwMi + pChgMi->RemoteNo; + + float MiFloatValue = static_cast(pChgMi->Value * pFwMi->Coeff + pFwMi->Base); + UA_WriteValue* tmp=&ptrMiWriteValue[nReadNum]; + tmp->value.hasValue=true; + buildValue(pFwMi->ResParam1,MiFloatValue,tmp->value.value); + tmp->value.hasStatus=true; + tmp->value.status=UA_STATUSCODE_GOOD; + + } + + + if(nReadNum>0) + { + BatchRequest(ptrMiWriteValue,nReadNum,"ChgAiData"); + } + + + for (int i = 0; i < nReadNum; i++) + { + UA_WriteValue* tmp=&ptrMiWriteValue[i]; + if(tmp) + { + UA_WriteValue_clear(tmp); + } + + } + + delete[] ptrMiWriteValue; +} + +int COpcUaDataProcThread::connectServer() +{ + if(m_ptrUaClient) + { + UA_Client_delete(m_ptrUaClient); + m_ptrUaClient=NULL; + } + UA_ClientConfig *config=new UA_ClientConfig(); + UA_ClientConfig_setDefault(config); + m_ptrUaClient = UA_Client_newWithConfig(config); + std::string serverIp=m_ptrCFesChan->m_Param.NetRoute[0].NetDesc; + int port=m_ptrCFesChan->m_Param.NetRoute[0].PortNo; + + + std::ostringstream oss; + oss << serverIp <<":"<< port; + std::string resultUrl = oss.str(); // opc.tcp://192.168.3.17:4840 + + if((!m_AppData.pwd.empty()) + &&(!m_AppData.userName.empty())) + { + + //todo + LOGERROR("COpcUaDataProcThread ChanNo=%d current only support Anonymously connect (%s)", m_ptrCFesChan->m_Param.ChanNo,resultUrl.c_str()); + + } + else + { + UA_StatusCode stauts=UA_Client_connect(m_ptrUaClient,resultUrl.c_str()); + if(stauts!=UA_STATUSCODE_GOOD) + { + UA_Client_delete(m_ptrUaClient); + m_ptrUaClient=NULL; + m_bConnected=false; + std::string statusMessage = getStatusMessage(stauts); + m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuComDown); + LOGERROR("COpcUaDataProcThread ChanNo=%d initClient faild to connect(%s) err(%s)", m_ptrCFesChan->m_Param.ChanNo,resultUrl.c_str(),statusMessage.c_str()); + return iotFailed; + } + } + + + + + m_bConnected=true; + m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuNormal); + LOGINFO("COpcUaDataProcThread ChanNo=%d connect %s ok", m_ptrCFesChan->m_Param.ChanNo,resultUrl.c_str()); + return iotSuccess; +} + +string COpcUaDataProcThread::getStatusMessage(UA_StatusCode status) +{ + std::ostringstream oss; + oss <<" statusCode("<< status <<")"<<" statusDesc("<< UA_StatusCode_name(status)<<")"; + return oss.str(); +} + +int COpcUaDataProcThread::initWriteValueArray() +{ + m_ptrDIWriteValue=new UA_WriteValue[m_ptrCFesRtu->m_MaxDiPoints+1]; + SFesFwDi *pFwDi=NULL; + for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxFwDiPoints; diPoint++) + { + pFwDi = m_ptrCFesRtu->m_pFwDi + diPoint; + UA_WriteValue* tmp=&m_ptrDIWriteValue[diPoint]; + UA_WriteValue_init(tmp); + tmp->attributeId=UA_ATTRIBUTEID_VALUE; + buildNodeId(pFwDi->ResParam2,pFwDi->szResParam1,tmp->nodeId); + std::string resultIndex; + if(hasDataIndex(pFwDi->szResParam1,resultIndex)) + { + tmp->indexRange=UA_STRING_ALLOC(resultIndex.c_str()); + } + else + { + tmp->indexRange=UA_STRING_ALLOC(""); + } + } + + m_ptrAIWriteValue=new UA_WriteValue[m_ptrCFesRtu->m_MaxAiPoints+1]; + SFesFwAi *pFwAi=NULL; + for (int aiPoint = 0; aiPoint < m_ptrCFesRtu->m_MaxFwAiPoints; aiPoint++) + { + pFwAi = m_ptrCFesRtu->m_pFwAi + aiPoint; + UA_WriteValue* tmp=&m_ptrAIWriteValue[aiPoint]; + UA_WriteValue_init(tmp); + tmp->attributeId=UA_ATTRIBUTEID_VALUE; + buildNodeId(pFwAi->ResParam2,pFwAi->szResParam1,tmp->nodeId); + std::string resultIndex; + if(hasDataIndex(pFwAi->szResParam1,resultIndex)) + { + tmp->indexRange=UA_STRING_ALLOC(resultIndex.c_str()); + } + else + { + tmp->indexRange=UA_STRING_ALLOC(""); + } + } + + m_ptrMIWriteValue=new UA_WriteValue[m_ptrCFesRtu->m_MaxMiPoints+1]; + SFesFwMi *pFwMi=NULL; + for (int miPoint = 0; miPoint < m_ptrCFesRtu->m_MaxFwMiPoints; miPoint++) + { + pFwMi = m_ptrCFesRtu->m_pFwMi + miPoint; + UA_WriteValue* tmp=&m_ptrMIWriteValue[miPoint]; + UA_WriteValue_init(tmp); + tmp->attributeId=UA_ATTRIBUTEID_VALUE; + buildNodeId(pFwMi->ResParam2,pFwMi->szResParam1,tmp->nodeId); + std::string resultIndex; + if(hasDataIndex(pFwMi->szResParam1,resultIndex)) + { + tmp->indexRange=UA_STRING_ALLOC(resultIndex.c_str()); + } + else + { + tmp->indexRange=UA_STRING_ALLOC(""); + } + } + + + + + m_ptrAccWriteValue=new UA_WriteValue[m_ptrCFesRtu->m_MaxAccPoints+1]; + SFesFwAcc *pFwAcc=NULL; + for (int accPoint = 0; accPoint < m_ptrCFesRtu->m_MaxAccPoints; accPoint++) + { + pFwAcc = m_ptrCFesRtu->m_pFwAcc + accPoint; + UA_WriteValue* tmp=&m_ptrAccWriteValue[accPoint]; + UA_WriteValue_init(tmp); + tmp->attributeId=UA_ATTRIBUTEID_VALUE; + buildNodeId(pFwAcc->ResParam2,pFwAcc->szResParam1,tmp->nodeId); + std::string resultIndex; + if(hasDataIndex(pFwAcc->szResParam1,resultIndex)) + { + tmp->indexRange=UA_STRING_ALLOC(resultIndex.c_str()); + } + else + { + tmp->indexRange=UA_STRING_ALLOC(""); + } + } + + + + m_bReady=true; + return iotSuccess; +} + +int COpcUaDataProcThread::buildNodeId(int nodeIdType, const string &tagStr,UA_NodeId& nodeId) +{ + string strNodeId=""; + string namespaceIndex="0"; + size_t pos = tagStr.find('!'); + if(pos != std::string::npos) + { + strNodeId = tagStr.substr(pos + 1); + std::string preStr = tagStr.substr(0, pos); + + size_t pos2 = tagStr.find('['); + + if(pos2!=std::string::npos) + { + namespaceIndex=preStr.substr(0, pos2); + } + else + { + namespaceIndex=preStr; + } + + if(nodeIdType==UA_NODEIDTYPE_NUMERIC) + { + nodeId=UA_NODEID_NUMERIC(atoi(namespaceIndex.c_str()), atoi(strNodeId.c_str())); + } + else if(nodeIdType==UA_NODEIDTYPE_STRING) + { + nodeId=UA_NODEID_STRING_ALLOC(atoi(namespaceIndex.c_str()), strNodeId.c_str()); + }else if(nodeIdType==UA_NODEIDTYPE_GUID) + { + nodeId=UA_NODEID_GUID(atoi(namespaceIndex.c_str()), UA_GUID(strNodeId.c_str())); + }else + { + LOGERROR("COpcUaDataProcThread ChanNo=%d get bad tagStr(%s) ,nodeIdType is not imple ", m_ptrCFesChan->m_Param.ChanNo,tagStr.c_str()); + return iotFailed; + } + + return iotSuccess; + } + else + { + LOGERROR("COpcUaDataProcThread ChanNo=%d get bad tagStr(%s) ,due to not find (!) ", m_ptrCFesChan->m_Param.ChanNo,tagStr.c_str()); + return iotFailed; + } +} + +int COpcUaDataProcThread::buildValue(int dataType, double curValue, UA_Variant &value) +{ + UA_Variant_init(&value); + DataType enumDataType=static_cast(dataType); + switch (enumDataType) { + case SByte:{ + UA_SByte val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_SBYTE]); + break; + } + case Int16:{ + UA_Int16 val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_INT16]); + break; + } + + case Int32:{ + UA_Int32 val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_INT32]); + break; + } + + case Int64:{ + UA_Int64 val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_INT64]); + break; + } + + case Byte:{ + UA_Byte val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_BYTE]); + break; + } + + case UInt16:{ + UA_UInt16 val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_UINT16]); + break; + } + + case UInt32:{ + UA_UInt32 val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_UINT32]); + break; + } + + case UInt64:{ + UA_UInt64 val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_UINT64]); + break; + } + + case Float:{ + UA_Float val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_FLOAT]); + break; + } + + case Double:{ + UA_Variant_setScalarCopy(&value, &curValue, &UA_TYPES[UA_TYPES_DOUBLE]); + break; + } + + case Boolean:{ + UA_Boolean val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_BOOLEAN]); + break; + } + + default: + LOGERROR("COpcUaDataProcThread ChanNo=%d DataType(%d) not imple ", m_ptrCFesChan->m_Param.ChanNo,(int)enumDataType); + return iotFailed; + break; + } + + + return iotSuccess; +} + +bool COpcUaDataProcThread::hasDataIndex(const string &tagStr, string &resultIndex) +{ + size_t pos = tagStr.find('!'); + if(pos != std::string::npos) + { + std::string preStr = tagStr.substr(0, pos); + + size_t start = preStr.find('['); + size_t end = preStr.find(']'); + + if(start != std::string::npos&&end != std::string::npos) + { + resultIndex = preStr.substr(start + 1, end - start - 1); + } + else + { + return false; + } + } + + return true; +} + +void COpcUaDataProcThread::clearData() +{ + for (int miPoint = 0; miPoint < m_ptrCFesRtu->m_MaxMiPoints; miPoint++) + { + UA_WriteValue* tmp=&m_ptrMIWriteValue[miPoint]; + if(tmp) + { + UA_WriteValue_clear(tmp); + } + } + delete[] m_ptrMIWriteValue; + + + for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxDiPoints; diPoint++) + { + UA_WriteValue* tmp=&m_ptrDIWriteValue[diPoint]; + if(tmp) + { + UA_WriteValue_clear(tmp); + } + } + delete[] m_ptrDIWriteValue; + + + for (int aiPoint = 0; aiPoint < m_ptrCFesRtu->m_MaxAiPoints; aiPoint++) + { + UA_WriteValue* tmp=&m_ptrAIWriteValue[aiPoint]; + if(tmp) + { + UA_WriteValue_clear(tmp); + } + } + delete[] m_ptrAIWriteValue; + + for (int accPoint = 0; accPoint < m_ptrCFesRtu->m_MaxAccPoints; accPoint++) + { + UA_WriteValue* tmp=&m_ptrAccWriteValue[accPoint]; + if(tmp) + { + UA_WriteValue_clear(tmp); + } + } + delete[] m_ptrAccWriteValue; + + + if(m_pChgAiData) + { + free(m_pChgAiData); + } + if(m_pChgDiData) + { + free(m_pChgDiData); + } + if(m_pChgMiData) + { + free(m_pChgMiData); + } + if(m_pChgAccData) + { + free(m_pChgAccData); + } + +} + +void COpcUaDataProcThread::BatchRequest(UA_WriteValue *ptrWriteValue, size_t writeSize, string strFlag) +{ + UA_WriteRequest request; + UA_WriteRequest_init(&request); + request.nodesToWrite =ptrWriteValue; + request.nodesToWriteSize = writeSize; + + UA_WriteResponse response=UA_Client_Service_write(m_ptrUaClient,request); + if(response.responseHeader.serviceResult==UA_STATUSCODE_GOOD||response.resultsSize == 0) + { + std::string statusMessage = getStatusMessage(response.responseHeader.serviceResult); + LOGERROR("COpcUaDataProcThread ChanNo=%d (%s) writeRequest faild err(%s)", m_ptrCFesChan->m_Param.ChanNo,strFlag.c_str(),statusMessage.c_str()); + } + + UA_WriteResponse_clear(&response); +} diff --git a/product/src/fes/protocol/opc_ua_client_s/DataProcThread.h b/product/src/fes/protocol/opc_ua_client_s/DataProcThread.h new file mode 100644 index 00000000..36d84f7b --- /dev/null +++ b/product/src/fes/protocol/opc_ua_client_s/DataProcThread.h @@ -0,0 +1,88 @@ +#pragma once +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "OPCUA_Common.h" + + +using namespace iot_public; + + +class COpcUaDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + COpcUaDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam); + virtual ~COpcUaDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + CFesBase* m_ptrCFesBase; + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,Yxcloudmqtts tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SOpcUaAppConfigParam m_AppData; //内部应用数据结构 + + + SFesFwChgAi *m_pChgAiData; + SFesFwChgDi *m_pChgDiData; + SFesFwChgAcc *m_pChgAccData; + SFesFwChgMi *m_pChgMiData; + +private: + bool m_bReady;//线程是否准备好 + bool m_bConnected; + UA_Client* m_ptrUaClient; + UA_WriteValue* m_ptrDIWriteValue; + UA_WriteValue* m_ptrAIWriteValue; + UA_WriteValue* m_ptrMIWriteValue; + UA_WriteValue* m_ptrAccWriteValue; + int64 m_lastBatchUpateTime; + +private: + + void ForwardData(); + + //数据到了上送时间 + void ifTimeToPublish(); + void handleAiData(); + void handleDiData(); + void handleAccData(); + void handleMiData(); + + + //数据是否变化和发布 + void ifDataChgAndWrite(); + + void handleChgAiData(); + void handleChgDiData(); + void handleChgAccData(); + void handleChgMiData(); + + + + + int connectServer(); + void ShowChanData(const std::string& msgData); + std::string getStatusMessage(UA_StatusCode status); + int initWriteValueArray(); + + int buildNodeId(int nodeIdType, const string &tagStr,UA_NodeId& nodeId); + + int buildValue(int dataType, double curValue,UA_Variant& value); + + bool hasDataIndex(const string &tagStr,string& resultIndex); + + void clearData(); + + void BatchRequest(UA_WriteValue* ptrWriteValue,size_t writeSize,std::string strFlag); +}; +typedef boost::shared_ptr COpcUaDataProcThreadPtr; diff --git a/product/src/fes/protocol/opc_ua_client_s/OPCUA.cpp b/product/src/fes/protocol/opc_ua_client_s/OPCUA.cpp new file mode 100644 index 00000000..cb299d32 --- /dev/null +++ b/product/src/fes/protocol/opc_ua_client_s/OPCUA.cpp @@ -0,0 +1,318 @@ +#include "OPCUA.h" +#include "pub_utility_api/CommonConfigParse.h" +#include + + +COPCUA OpcUa; +bool g_OpcUaIsMainFes=false; +bool g_OpcUaChanelRun=true; + + + +int EX_SetBaseAddr(void *address) +{ + OpcUa.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + OpcUa.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + OpcUa.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + OpcUa.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + OpcUa.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + LOGDEBUG("opc_ua_zf_client EX_ExitSystem() start"); + g_OpcUaChanelRun=false;//使所有的线程退出。 + OpcUa.ExitSystem(flag); + LOGDEBUG("opc_ua_zf_client EX_ExitSystem() end"); + return iotSuccess; +} + +COPCUA::COPCUA():m_ProtocolId(-1),m_ptrCFesBase(NULL) +{ + +} + +COPCUA::~COPCUA() +{ + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); +} + +int COPCUA::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + ReadConfigParam(); + } + return iotSuccess; +} + +int COPCUA::SetProperty(int IsMainFes) +{ + g_OpcUaIsMainFes = (bool)IsMainFes; + LOGDEBUG("COPCUA::SetProperty g_OpcUaIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +int COPCUA::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if ((OpenFlag == CN_FesChanThread_Flag) || (OpenFlag == CN_FesChanAndDataThread_Flag)) + { + switch (ptrFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + case CN_FesTcpServer: + break; + default: + LOGERROR("COPCUA EX_OpenChan() ChanNo:%d CommType=%d is not TCP SERVER/Client!", ptrFesChan->m_Param.ChanNo, ptrFesChan->m_Param.CommType); + return iotFailed; + } + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + COpcUaDataProcThreadPtr ptrCDataProc=boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_vecAppParam); + if (ptrCDataProc == NULL) + { + LOGERROR("COPCUA EX_OpenChan() ChanNo:%d create DataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + LOGINFO("COPCUA EX_OpenChan() ChanNo:%d create DataProcThreadPtr ok!", ptrFesChan->m_Param.ChanNo); + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; +} + + +int COPCUA::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("COPCUA::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + return iotSuccess; +} + + +/** + * @brief COPCUA::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int COPCUA::ChanTimer(int MainChanNo) +{ + boost::ignore_unused(MainChanNo); + //把命令缓冲时间间隔到的命放到发送命令缓冲区 + return iotSuccess; +} + +int COPCUA::ExitSystem(int flag) +{ + boost::ignore_unused(flag); + InformTcpThreadExit(); + return iotSuccess; +} + + + +void COPCUA::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + COpcUaDataProcThreadPtr ptrTcp; + + if ((tempNum = (int)m_CDataProcQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CDataProcQueue.erase(it);//COPCUA::~COpcUaDataProcThread()退出线程 + LOGDEBUG("COPCUA::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + + +int COPCUA::ReadConfigParam() +{ + CCommonConfigParse config; + char strRtuNo[48]; + SOpcUaAppConfigParam param; + int items,i,j; + CFesChanPtr ptrChan; //CHAN数据区 + CFesRtuPtr ptrRTU; + std::string strvalue; + int ivalue; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"opc_ua_client_s"); + if (m_ProtocolId == -1) + { + LOGDEBUG("ReadConfigParam ProtoclID error"); + return iotFailed; + } + LOGINFO("opc_ua_client_s ProtoclID=%d", m_ProtocolId); + + if (config.load("../../data/fes/", "opc_ua_client_s.xml") == iotFailed) + { + LOGDEBUG("opc_ua_client_s load opc_ua_client_s.xml error"); + return iotSuccess; + } + LOGDEBUG("opc_ua_client_s load opc_ua_client_s.xml ok"); + + for (i = 0; i < m_ptrCFesBase->m_vectCFesChanPtr.size(); i++) + { + ptrChan = m_ptrCFesBase->m_vectCFesChanPtr[i]; + if ((ptrChan->m_Param.Used == 1) && (m_ProtocolId == ptrChan->m_Param.ProtocolId)) + { + //found RTU + for (j = 0; j < m_ptrCFesBase->m_vectCFesRtuPtr.size(); j++) + { + ptrRTU = m_ptrCFesBase->m_vectCFesRtuPtr[j]; + if (ptrRTU->m_Param.Used && (ptrRTU->m_Param.ChanNo == ptrChan->m_Param.ChanNo)) + { + memset(&strRtuNo[0], 0, sizeof(strRtuNo)); + sprintf(strRtuNo, "RTU%d", ptrRTU->m_Param.RtuNo); + + param.RtuNo = ptrRTU->m_Param.RtuNo; + items = 0; + param.pwd = "pwd"; + strvalue.clear(); + if (config.getStringValue(strRtuNo, "pwd", strvalue) == iotSuccess) + { + param.pwd = strvalue; + items++; + } + + param.userName = "userName"; + strvalue.clear(); + if (config.getStringValue(strRtuNo, "userName", strvalue) == iotSuccess) + { + param.userName = strvalue; + items++; + } + + param.securityPolicy = "securityPolicy"; + strvalue.clear(); + if (config.getStringValue(strRtuNo, "securityPolicy", strvalue) == iotSuccess) + { + param.securityPolicy = strvalue; + items++; + } + + param.messageSecurityMode = "messageSecurityMode"; + strvalue.clear(); + if (config.getStringValue(strRtuNo, "messageSecurityMode", strvalue) == iotSuccess) + { + param.messageSecurityMode = strvalue; + items++; + } + + param.certificateFilePath = "certificateFilePath"; + strvalue.clear(); + if (config.getStringValue(strRtuNo, "certificateFilePath", strvalue) == iotSuccess) + { + param.certificateFilePath = strvalue; + items++; + } + + + param.privateKeyPath = "privateKeyPath"; + strvalue.clear(); + if (config.getStringValue(strRtuNo, "privateKeyPath", strvalue) == iotSuccess) + { + param.privateKeyPath = strvalue; + items++; + } + + param.intervalTime = 0; + if (config.getIntValue(strRtuNo, "intervalTime", ivalue) == iotSuccess) + { + param.intervalTime = ivalue; + items++; + } + + + + + if (items > 0)//对应的RTU有配置项 + { + m_vecAppParam.push_back(param); + } + } + } + } + } + return iotSuccess; + +} + + + +void COPCUA::InformTcpThreadExit() +{ + +} + + diff --git a/product/src/fes/protocol/opc_ua_client_s/OPCUA.h b/product/src/fes/protocol/opc_ua_client_s/OPCUA.h new file mode 100644 index 00000000..f520e868 --- /dev/null +++ b/product/src/fes/protocol/opc_ua_client_s/OPCUA.h @@ -0,0 +1,44 @@ +#pragma once + + +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "DataProcThread.h" + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + + + + +class PROTOCOLBASE_API COPCUA : public CProtocolBase +{ +public: + COPCUA(); + ~COPCUA(); + + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + vector m_CDataProcQueue; + vector m_vecAppParam; + + + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + int ExitSystem(int flag); + int ReadConfigParam(); + void InformTcpThreadExit(); +private: + int m_ProtocolId; + void ClearDataProcThreadByChanNo(int ChanNo); +}; diff --git a/product/src/fes/protocol/opc_ua_client_s/OPCUA_Common.h b/product/src/fes/protocol/opc_ua_client_s/OPCUA_Common.h new file mode 100644 index 00000000..b7114177 --- /dev/null +++ b/product/src/fes/protocol/opc_ua_client_s/OPCUA_Common.h @@ -0,0 +1,42 @@ +#pragma once +#include "open62541/client.h" +#include "open62541/client_highlevel.h" +#include "open62541/client_config_default.h" +#include "open62541/config.h" +#include "string" + + +enum DataType +{ + SByte=1, + Int16, + Int32, + Int64, + Byte, + UInt16, + UInt32, + UInt64, + Float, + Double, + Boolean, + //String, + //Datetime +}; + + + +//配置参数 +typedef struct{ + int RtuNo; + std::string pwd; + std::string userName; + std::string securityPolicy; + std::string messageSecurityMode; + std::string certificateFilePath; + std::string privateKeyPath; + int intervalTime; +}SOpcUaAppConfigParam; + + + + diff --git a/product/src/fes/protocol/opc_ua_client_s/opc_ua_client_s.pro b/product/src/fes/protocol/opc_ua_client_s/opc_ua_client_s.pro new file mode 100644 index 00000000..cfff3325 --- /dev/null +++ b/product/src/fes/protocol/opc_ua_client_s/opc_ua_client_s.pro @@ -0,0 +1,42 @@ +# ARM板上资源有限,不会与云平台混用,不编译 +message("Compile only in x86 environment") +# requires(contains(QMAKE_HOST.arch, x86_64)) +requires(!contains(QMAKE_HOST.arch, aarch64):!linux-aarch64*) + +QT -= core gui +CONFIG -= qt + +TARGET = opc_ua_client_s + +TEMPLATE = lib + +SOURCES += \ + DataProcThread.cpp \ + OPCUA.cpp + + +HEADERS += \ + DataProcThread.h \ + OPCUA_Common.h \ + OPCUA.h + + +INCLUDEPATH += ../../include/ +INCLUDEPATH += ../../include/open62541 + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase -lrdb_api +LIBS += -lopen62541 -lhal-shared + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/fes/protocol/opc_ua_server_s/DataProcThread.cpp b/product/src/fes/protocol/opc_ua_server_s/DataProcThread.cpp new file mode 100644 index 00000000..e8b75b6a --- /dev/null +++ b/product/src/fes/protocol/opc_ua_server_s/DataProcThread.cpp @@ -0,0 +1,849 @@ +#include "DataProcThread.h" + + +extern bool g_OpcUaIsMainFes; +extern bool g_OpcUaChanelRun; +const int gOpcUaThreadTime = 10; + +COpcUaDataProcThread::COpcUaDataProcThread(CFesBase *ptrCFesBase, CFesChanPtr ptrCFesChan, const vector vecAppParam) + :CTimerThreadBase("COpcUaDataProcThread", gOpcUaThreadTime, 0, true),m_bReady(true),m_bServerOK(false), + m_lastBatchUpateTime(0) +{ + m_pChgAiData=NULL; + m_pChgDiData=NULL; + m_pChgAccData=NULL; + m_pChgMiData=NULL; + + + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL)) + { + return; + } + m_ptrCFesChan->SetLinkStatus(CN_FesChanConnect); + m_ptrCFesChan->SetComThreadRunFlag(CN_FesRunFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + + + bool found = false; + if (vecAppParam.size() > 0) + { + for (size_t i = 0; i < vecAppParam.size(); i++) + { + if (m_ptrCFesRtu->m_Param.RtuNo == vecAppParam[i].RtuNo) + { + //配置 + m_AppData= vecAppParam[i]; + found = true; + break; + } + } + } + + if(found) + { + initServer(); + } + else + { + m_bReady=false; + LOGERROR("COpcUaDataProcThread ChanNo=%d can not match rtuNo in config due to now rtuNo is %d and do nothing", m_ptrCFesChan->m_Param.ChanNo,m_ptrCFesRtu->m_Param.RtuNo); + } + +} + + +COpcUaDataProcThread::~COpcUaDataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + clearData(); + + if(m_ptrUaServer) + { + UA_Server_delete(m_ptrUaServer); + m_ptrUaServer=NULL; + } + + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + LOGDEBUG("COpcUaDataProcThread::~COpcUaDataProcThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); +} + +int COpcUaDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +void COpcUaDataProcThread::execute() +{ + + if(m_bReady) + { + LOGTRACE("COpcUaDataProcThread ChanNo=%d not ready ,check log which has record err", m_ptrCurrentChan->m_Param.ChanNo); + return; + } + if(!m_bServerOK) + { + if(iotSuccess!=initServer()) + { + m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuComDown); + LOGERROR("COpcUaDataProcThread ChanNo=%d initServer failed ", m_ptrCurrentChan->m_Param.ChanNo); + return; + } + } + UA_Server_run_iterate(m_ptrUaServer, true); + + if(g_OpcUaIsMainFes) + { + ForwardData(); + } + + +} + + +void COpcUaDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetComThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetLinkStatus(CN_FesChanDisconnect); + + LOGDEBUG("COpcUaDataProcThread::beforeQuit() "); +} + +void COpcUaDataProcThread::ForwardData() +{ + + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + + //定时读取遥控命令响应缓冲区,及时清除队列释放空间,不对遥控成败作处理 + if (m_ptrCFesRtu->GetFwDoRespCmdNum() > 0) + { + SFesFwDoRespCmd retCmd; + m_ptrCFesRtu->ReadFwDoRespCmd(1, &retCmd); + } + + if (m_ptrCFesRtu->GetFwAoRespCmdNum() > 0) + { + SFesFwAoRespCmd retCmd; + m_ptrCFesRtu->ReadFwAoRespCmd(1, &retCmd); + } + + + + + + ifDataChgAndWrite(); + ifTimeToBatchUpdate(); + + + + + + +} + +void COpcUaDataProcThread::ifTimeToBatchUpdate() +{ + int64 cursec = getMonotonicMsec(); + if(0!=m_AppData.intervalTime) + { + if ((cursec - m_lastBatchUpateTime) > m_AppData.intervalTime) + { + m_lastBatchUpateTime=cursec; + } + else + { + return; + } + } + + + + handleAiData(); + handleDiData(); + handleMiData(); + handleAccData(); +} + + +void COpcUaDataProcThread::handleDiData() +{ + SFesFwDi *pFwDi=NULL; + int yxbit; + for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxFwDiPoints; diPoint++) + { + pFwDi = m_ptrCFesRtu->m_pFwDi + diPoint; + UA_NodeId curNodeId=m_vecDiNodeId[diPoint]; + UA_Variant curValue; + yxbit = pFwDi->Value & 0x01; + buildValue(pFwDi->ResParam1,yxbit,curValue); + UA_StatusCode writeStatus=UA_Server_writeValue(m_ptrUaServer, curNodeId, curValue); + if(!UA_StatusCode_isGood(writeStatus)) + { + std::string statusMessage = getStatusMessage(writeStatus); + LOGERROR("COpcUaDataProcThread ChanNo=%d diPointNo(%d) write value faild(%s)", m_ptrCFesChan->m_Param.ChanNo,pFwDi->RemoteNo,statusMessage.c_str()); + } + + UA_Variant_clear(&curValue); + } + + +} + +void COpcUaDataProcThread::handleAiData() +{ + SFesFwAi *pFwAi=NULL; + double fvalue; + for (int aiPoint = 0; aiPoint < m_ptrCFesRtu->m_MaxFwAiPoints; aiPoint++) + { + pFwAi = m_ptrCFesRtu->m_pFwAi + aiPoint; + UA_NodeId curNodeId=m_vecAiNodeId[aiPoint]; + UA_Variant curValue; + fvalue = pFwAi->Value*pFwAi->Coeff + pFwAi->Base; + buildValue(pFwAi->ResParam1,fvalue,curValue); + UA_StatusCode writeStatus=UA_Server_writeValue(m_ptrUaServer, curNodeId, curValue); + if(!UA_StatusCode_isGood(writeStatus)) + { + std::string statusMessage = getStatusMessage(writeStatus); + LOGERROR("COpcUaDataProcThread ChanNo=%d aiPointNo(%d) write value faild(%s)", m_ptrCFesChan->m_Param.ChanNo,pFwAi->RemoteNo,statusMessage.c_str()); + } + + UA_Variant_clear(&curValue); + + } + + + + +} + +void COpcUaDataProcThread::handleAccData() +{ + SFesFwAcc *pFwAcc=NULL; + double fvalue; + for (int accPoint = 0; accPoint < m_ptrCFesRtu->m_MaxFwAccPoints; accPoint++) + { + pFwAcc = m_ptrCFesRtu->m_pFwAcc + accPoint; + UA_NodeId curNodeId=m_vecAccNodeId[accPoint]; + UA_Variant curValue; + fvalue = pFwAcc->Value*pFwAcc->Coeff + pFwAcc->Base; + buildValue(pFwAcc->ResParam1,fvalue,curValue); + UA_StatusCode writeStatus=UA_Server_writeValue(m_ptrUaServer, curNodeId, curValue); + if(!UA_StatusCode_isGood(writeStatus)) + { + std::string statusMessage = getStatusMessage(writeStatus); + LOGERROR("COpcUaDataProcThread ChanNo=%d accPointNo(%d) write value faild(%s)", m_ptrCFesChan->m_Param.ChanNo,pFwAcc->RemoteNo,statusMessage.c_str()); + } + + UA_Variant_clear(&curValue); + + } + + + +} + + +void COpcUaDataProcThread::handleMiData() +{ + SFesFwMi *pFwMi=NULL; + double fvalue; + for (int miPoint = 0; miPoint < m_ptrCFesRtu->m_MaxFwMiPoints; miPoint++) + { + pFwMi = m_ptrCFesRtu->m_pFwMi + miPoint; + + UA_NodeId curNodeId=m_vecMiNodeId[miPoint]; + UA_Variant curValue; + fvalue = pFwMi->Value*pFwMi->Coeff + pFwMi->Base; + buildValue(pFwMi->ResParam1,fvalue,curValue); + UA_StatusCode writeStatus=UA_Server_writeValue(m_ptrUaServer, curNodeId, curValue); + if(!UA_StatusCode_isGood(writeStatus)) + { + std::string statusMessage = getStatusMessage(writeStatus); + LOGERROR("COpcUaDataProcThread ChanNo=%d miPointNo(%d) write value faild(%s)", m_ptrCFesChan->m_Param.ChanNo,pFwMi->RemoteNo,statusMessage.c_str()); + } + + UA_Variant_clear(&curValue); + + } + + + +} + +void COpcUaDataProcThread::ifDataChgAndWrite() +{ + handleChgAiData(); + handleChgDiData(); + handleChgAccData(); + handleChgMiData(); +} + +void COpcUaDataProcThread::handleChgAiData() +{ + int nAiCount = m_ptrCFesRtu->GetFwChgAiNum(); + if(0==nAiCount) + { + return; + } + SFesFwChgAi *pChgAi = NULL; + SFesFwAi *pFwAi = NULL; + + if (m_pChgAiData == NULL) + m_pChgAiData = (SFesFwChgAi*)malloc(nAiCount * sizeof(SFesFwChgAi)); + else + m_pChgAiData = (SFesFwChgAi*)realloc(m_pChgAiData, nAiCount * sizeof(SFesFwChgAi)); + + int nReadNum = m_ptrCFesRtu->ReadFwChgAi(nAiCount, m_pChgAiData); + + + for (int i = 0; i < nReadNum; i++) + { + pChgAi = m_pChgAiData + i; + if(pChgAi->RemoteNo >= m_ptrCFesRtu->m_MaxFwAiPoints) + { + continue; + } + pFwAi = m_ptrCFesRtu->m_pFwAi + pChgAi->RemoteNo; + float AiFloatValue = static_cast(pChgAi->Value * pFwAi->Coeff + pFwAi->Base); + int64 curNodeIdIndex=m_mapAiVecIndex[pChgAi->RemoteNo]; + UA_NodeId curNodeId=m_vecMiNodeId[curNodeIdIndex]; + UA_Variant curValue; + buildValue(pFwAi->ResParam1,AiFloatValue,curValue); + UA_StatusCode writeStatus=UA_Server_writeValue(m_ptrUaServer, curNodeId, curValue); + if(!UA_StatusCode_isGood(writeStatus)) + { + std::string statusMessage = getStatusMessage(writeStatus); + LOGERROR("COpcUaDataProcThread ChanNo=%d aiPointRemoteNo(%d) write value faild(%s)", m_ptrCFesChan->m_Param.ChanNo,pFwAi->RemoteNo,statusMessage.c_str()); + } + + UA_Variant_clear(&curValue); + } + + + +} + +void COpcUaDataProcThread::handleChgDiData() +{ + SFesFwChgDi *pChgDi; + int DiValue; + SFesFwDi *pFwDi; + int nDiCount = m_ptrCFesRtu->GetFwChgDiNum(); + if(0==nDiCount) + { + return; + } + if (m_pChgDiData == NULL) + m_pChgDiData = (SFesFwChgDi*)malloc(nDiCount * sizeof(SFesFwChgDi)); + else + m_pChgDiData = (SFesFwChgDi*)realloc(m_pChgDiData, nDiCount * sizeof(SFesFwChgDi)); + + int retNum = m_ptrCFesRtu->ReadFwChgDi(nDiCount, m_pChgDiData); + + + for (int i=0;iRemoteNo >= m_ptrCFesRtu->m_MaxFwDiPoints) + continue; + pFwDi = m_ptrCFesRtu->m_pFwDi+ pChgDi->RemoteNo; + int64 curNodeIdIndex=m_mapAiVecIndex[pChgDi->RemoteNo]; + UA_NodeId curNodeId=m_vecMiNodeId[curNodeIdIndex]; + UA_Variant curValue; + DiValue = pChgDi->Value&0x01; + buildValue(pFwDi->ResParam1,DiValue,curValue); + UA_StatusCode writeStatus=UA_Server_writeValue(m_ptrUaServer, curNodeId, curValue); + if(!UA_StatusCode_isGood(writeStatus)) + { + std::string statusMessage = getStatusMessage(writeStatus); + LOGERROR("COpcUaDataProcThread ChanNo=%d diPointRemoteNo(%d) write value faild(%s)", m_ptrCFesChan->m_Param.ChanNo,pFwDi->RemoteNo,statusMessage.c_str()); + } + + UA_Variant_clear(&curValue); + } + + + + +} + +void COpcUaDataProcThread::handleChgAccData() +{ + int nAccCount = m_ptrCFesRtu->GetFwChgAccNum(); + if(0==nAccCount) + { + return; + } + SFesFwChgAcc *pChgAcc; + SFesFwAcc *pFwAcc; + if (m_pChgAccData == NULL) + m_pChgAccData = (SFesFwChgAcc*)malloc(nAccCount * sizeof(SFesFwChgAcc)); + else + m_pChgAccData = (SFesFwChgAcc*)realloc(m_pChgAccData, nAccCount * sizeof(SFesFwChgAcc)); + + int nReadNum = m_ptrCFesRtu->ReadFwChgAcc(nAccCount, m_pChgAccData); + + + for (int i = 0; i < nReadNum; i++) + { + pChgAcc = m_pChgAccData + i; + if(pChgAcc->RemoteNo >= m_ptrCFesRtu->m_MaxFwAccPoints) + { + continue; + } + pFwAcc = m_ptrCFesRtu->m_pFwAcc + pChgAcc->RemoteNo; + + float AccFloatValue = static_cast(pChgAcc->Value * pFwAcc->Coeff + pFwAcc->Base); + int64 curNodeIdIndex=m_mapAiVecIndex[pFwAcc->RemoteNo]; + UA_NodeId curNodeId=m_vecMiNodeId[curNodeIdIndex]; + UA_Variant curValue; + buildValue(pFwAcc->ResParam1,AccFloatValue,curValue); + UA_StatusCode writeStatus=UA_Server_writeValue(m_ptrUaServer, curNodeId, curValue); + if(!UA_StatusCode_isGood(writeStatus)) + { + std::string statusMessage = getStatusMessage(writeStatus); + LOGERROR("COpcUaDataProcThread ChanNo=%d accPointRemoteNo(%d) write value faild(%s)", m_ptrCFesChan->m_Param.ChanNo,pFwAcc->RemoteNo,statusMessage.c_str()); + } + + UA_Variant_clear(&curValue); + + } + + + +} + +void COpcUaDataProcThread::handleChgMiData() +{ + int nMiCount = m_ptrCFesRtu->GetFwChgMiNum(); + if(0==nMiCount) + { + return; + } + SFesFwChgMi *pChgMi; + SFesFwMi *pFwMi; + if (m_pChgMiData == NULL) + m_pChgMiData = (SFesFwChgMi*)malloc(nMiCount * sizeof(SFesFwChgMi)); + else + m_pChgMiData = (SFesFwChgMi*)realloc(m_pChgMiData, nMiCount * sizeof(SFesFwChgMi)); + + int nReadNum = m_ptrCFesRtu->ReadFwChgMi(nMiCount, m_pChgMiData); + + + + + for (int i = 0; i < nReadNum; i++) + { + pChgMi = m_pChgMiData + i; + if(pChgMi->RemoteNo >= m_ptrCFesRtu->m_MaxFwMiPoints) + { + continue; + } + pFwMi = m_ptrCFesRtu->m_pFwMi + pChgMi->RemoteNo; + + float MiFloatValue = static_cast(pChgMi->Value * pFwMi->Coeff + pFwMi->Base); + int64 curNodeIdIndex=m_mapMiVecIndex[pFwMi->RemoteNo]; + UA_NodeId curNodeId=m_vecMiNodeId[curNodeIdIndex]; + UA_Variant curValue; + + + buildValue(pFwMi->ResParam1,MiFloatValue,curValue); + UA_StatusCode writeStatus=UA_Server_writeValue(m_ptrUaServer, curNodeId, curValue); + if(!UA_StatusCode_isGood(writeStatus)) + { + std::string statusMessage = getStatusMessage(writeStatus); + LOGERROR("COpcUaDataProcThread ChanNo=%d miPointRemoteNo(%d) write value faild(%s)", m_ptrCFesChan->m_Param.ChanNo,pFwMi->RemoteNo,statusMessage.c_str()); + } + + UA_Variant_clear(&curValue); + + + } + + + +} + +int COpcUaDataProcThread::initServer() +{ + + std::string serverIp=m_ptrCFesChan->m_Param.NetRoute[0].NetDesc; + int port=m_ptrCFesChan->m_Param.NetRoute[0].PortNo; + + + std::ostringstream oss; + oss << serverIp <<":"<< port; + std::string resultUrl = oss.str(); // opc.tcp://192.168.3.17:4840 + + if((!m_AppData.pwd.empty()) + &&(!m_AppData.userName.empty())) + { + + //todo + m_bServerOK=false; + LOGERROR("COpcUaDataProcThread ChanNo=%d current only support Anonymously connect (%s)", m_ptrCFesChan->m_Param.ChanNo,resultUrl.c_str()); + + } + else + { + m_ptrUaServer = UA_Server_new(); + UA_ServerConfig *config = UA_Server_getConfig(m_ptrUaServer); + UA_String endpointUrl = UA_STRING(const_cast(resultUrl.c_str())); + config->serverUrls=&endpointUrl; + + UA_StatusCode retval = UA_Server_run_startup(m_ptrUaServer); + if (retval != UA_STATUSCODE_GOOD) { + std::string statusMessage = getStatusMessage(retval); + m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuComDown); + LOGERROR("COpcUaDataProcThread ChanNo=%d start UAserver(%s) faild err(%s)", m_ptrCFesChan->m_Param.ChanNo,resultUrl.c_str(),statusMessage.c_str()); + UA_Server_delete(m_ptrUaServer); + m_ptrUaServer=NULL; + m_bServerOK=false; + } + + + } + + + m_bServerOK=true; + m_ptrCFesRtu->WriteRtuSatus(CN_FesRtuNormal); + LOGINFO("COpcUaDataProcThread ChanNo=%d start UAserver %s ok", m_ptrCFesChan->m_Param.ChanNo,resultUrl.c_str()); + return iotSuccess; +} + +string COpcUaDataProcThread::getStatusMessage(UA_StatusCode status) +{ + std::ostringstream oss; + oss <<" statusCode("<< status <<")"<<" statusDesc("<< UA_StatusCode_name(status)<<")"; + return oss.str(); +} + + +int COpcUaDataProcThread::buildNodeId(int nodeIdType, const string &tagStr,UA_NodeId& nodeId) +{ + string strNodeId=""; + string namespaceIndex="0"; + size_t pos = tagStr.find('!'); + if(pos != std::string::npos) + { + strNodeId = tagStr.substr(pos + 1); + std::string preStr = tagStr.substr(0, pos); + + size_t pos2 = tagStr.find('['); + + if(pos2!=std::string::npos) + { + namespaceIndex=preStr.substr(0, pos2); + } + else + { + namespaceIndex=preStr; + } + + if(nodeIdType==UA_NODEIDTYPE_NUMERIC) + { + nodeId=UA_NODEID_NUMERIC(atoi(namespaceIndex.c_str()), atoi(strNodeId.c_str())); + } + else if(nodeIdType==UA_NODEIDTYPE_STRING) + { + nodeId=UA_NODEID_STRING_ALLOC(atoi(namespaceIndex.c_str()), strNodeId.c_str()); + }else if(nodeIdType==UA_NODEIDTYPE_GUID) + { + nodeId=UA_NODEID_GUID(atoi(namespaceIndex.c_str()), UA_GUID(strNodeId.c_str())); + }else + { + LOGERROR("COpcUaDataProcThread ChanNo=%d get bad tagStr(%s) ,nodeIdType is not imple ", m_ptrCFesChan->m_Param.ChanNo,tagStr.c_str()); + return iotFailed; + } + + return iotSuccess; + } + else + { + LOGERROR("COpcUaDataProcThread ChanNo=%d get bad tagStr(%s) ,due to not find (!) ", m_ptrCFesChan->m_Param.ChanNo,tagStr.c_str()); + return iotFailed; + } +} + +int COpcUaDataProcThread::buildValue(int dataType, double curValue, UA_Variant &value) +{ + UA_Variant_init(&value); + DataType enumDataType=static_cast(dataType); + switch (enumDataType) { + case SByte:{ + UA_SByte val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_SBYTE]); + break; + } + case Int16:{ + UA_Int16 val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_INT16]); + break; + } + + case Int32:{ + UA_Int32 val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_INT32]); + break; + } + + case Int64:{ + UA_Int64 val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_INT64]); + break; + } + + case Byte:{ + UA_Byte val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_BYTE]); + break; + } + + case UInt16:{ + UA_UInt16 val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_UINT16]); + break; + } + + case UInt32:{ + UA_UInt32 val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_UINT32]); + break; + } + + case UInt64:{ + UA_UInt64 val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_UINT64]); + break; + } + + case Float:{ + UA_Float val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_FLOAT]); + break; + } + + case Double:{ + UA_Variant_setScalarCopy(&value, &curValue, &UA_TYPES[UA_TYPES_DOUBLE]); + break; + } + + case Boolean:{ + UA_Boolean val = static_cast(curValue); + UA_Variant_setScalarCopy(&value, &val, &UA_TYPES[UA_TYPES_BOOLEAN]); + break; + } + + default: + LOGERROR("COpcUaDataProcThread ChanNo=%d DataType(%d) not imple ", m_ptrCFesChan->m_Param.ChanNo,(int)enumDataType); + return iotFailed; + break; + } + + + return iotSuccess; +} + +bool COpcUaDataProcThread::hasDataIndex(const string &tagStr, string &resultIndex) +{ + size_t pos = tagStr.find('!'); + if(pos != std::string::npos) + { + std::string preStr = tagStr.substr(0, pos); + + size_t start = preStr.find('['); + size_t end = preStr.find(']'); + + if(start != std::string::npos&&end != std::string::npos) + { + resultIndex = preStr.substr(start + 1, end - start - 1); + } + else + { + return false; + } + } + + return true; +} + +void COpcUaDataProcThread::clearData() +{ + for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxDiPoints; diPoint++) + { + UA_NodeId* tmp=&m_vecDiNodeId[diPoint]; + if(tmp) + { + UA_NodeId_clear(tmp); + } + } + + + + for (int aiPoint = 0; aiPoint < m_ptrCFesRtu->m_MaxAiPoints; aiPoint++) + { + UA_NodeId* tmp=&m_vecAiNodeId[aiPoint]; + if(tmp) + { + UA_NodeId_clear(tmp); + } + } + + + for (int miPoint = 0; miPoint < m_ptrCFesRtu->m_MaxMiPoints; miPoint++) + { + UA_NodeId* tmp=&m_vecMiNodeId[miPoint]; + if(tmp) + { + UA_NodeId_clear(tmp); + } + } + + + for (int accPoint = 0; accPoint < m_ptrCFesRtu->m_MaxAccPoints; accPoint++) + { + UA_NodeId* tmp=&m_vecAccNodeId[accPoint]; + if(tmp) + { + UA_NodeId_clear(tmp); + } + } + + if(m_pChgAiData) + { + free(m_pChgAiData); + } + if(m_pChgDiData) + { + free(m_pChgDiData); + } + if(m_pChgMiData) + { + free(m_pChgMiData); + } + if(m_pChgAccData) + { + free(m_pChgAccData); + } + + +} + +void COpcUaDataProcThread::initNodeId() +{ + SFesFwDi *pFwDi=NULL; + for (int diPoint = 0; diPoint < m_ptrCFesRtu->m_MaxDiPoints; diPoint++) + { + pFwDi = m_ptrCFesRtu->m_pFwDi + diPoint; + UA_VariableAttributes attr = UA_VariableAttributes_default; + attr.description = UA_LOCALIZEDTEXT_ALLOC("en-US",pFwDi->PointDesc); + attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US",pFwDi->PointDesc); + attr.accessLevel = UA_ACCESSLEVELMASK_READ; + + m_vecDiNodeId.push_back(UA_NodeId()); + UA_NodeId_init(&m_vecDiNodeId[diPoint]); + buildNodeId(pFwDi->ResParam2,pFwDi->szResParam1,m_vecDiNodeId[diPoint]); + + UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(1, pFwDi->PointDesc); + UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_OBJECTSFOLDER); + UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_ORGANIZES); + UA_Server_addVariableNode(m_ptrUaServer, m_vecDiNodeId[diPoint], parentNodeId, + parentReferenceNodeId, qualifiedName, + UA_NODEID_NULL, attr, NULL, NULL); + m_mapDiVecIndex[pFwDi->RemoteNo]=diPoint; + } + + + SFesFwAi *pFwAi=NULL; + for (int aiPoint = 0; aiPoint < m_ptrCFesRtu->m_MaxAiPoints; aiPoint++) + { + pFwAi = m_ptrCFesRtu->m_pFwAi + aiPoint; + UA_VariableAttributes attr = UA_VariableAttributes_default; + attr.description = UA_LOCALIZEDTEXT_ALLOC("en-US",pFwAi->PointDesc); + attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US",pFwAi->PointDesc); + attr.accessLevel = UA_ACCESSLEVELMASK_READ; + + m_vecAiNodeId.push_back(UA_NodeId()); + UA_NodeId_init(&m_vecAiNodeId[aiPoint]); + buildNodeId(pFwAi->ResParam2,pFwAi->szResParam1,m_vecAiNodeId[aiPoint]); + + UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(1, pFwAi->PointDesc); + UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_OBJECTSFOLDER); + UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_ORGANIZES); + UA_Server_addVariableNode(m_ptrUaServer, m_vecAiNodeId[aiPoint], parentNodeId, + parentReferenceNodeId, qualifiedName, + UA_NODEID_NULL, attr, NULL, NULL); + + m_mapAiVecIndex[pFwAi->RemoteNo]=aiPoint; + } + + + SFesFwMi *pFwMi=NULL; + for (int miPoint = 0; miPoint < m_ptrCFesRtu->m_MaxMiPoints; miPoint++) + { + pFwMi = m_ptrCFesRtu->m_pFwMi + miPoint; + UA_VariableAttributes attr = UA_VariableAttributes_default; + attr.description = UA_LOCALIZEDTEXT_ALLOC("en-US",pFwMi->PointDesc); + attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US",pFwMi->PointDesc); + attr.accessLevel = UA_ACCESSLEVELMASK_READ; + + m_vecDiNodeId.push_back(UA_NodeId()); + UA_NodeId_init(&m_vecMiNodeId[miPoint]); + buildNodeId(pFwMi->ResParam2,pFwMi->szResParam1,m_vecMiNodeId[miPoint]); + + UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(1, pFwMi->PointDesc); + UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_OBJECTSFOLDER); + UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_ORGANIZES); + UA_Server_addVariableNode(m_ptrUaServer, m_vecMiNodeId[miPoint], parentNodeId, + parentReferenceNodeId, qualifiedName, + UA_NODEID_NULL, attr, NULL, NULL); + + m_mapMiVecIndex[pFwMi->RemoteNo]=miPoint; + } + + + SFesFwAcc *pFwAcc=NULL; + for (int accPoint = 0; accPoint < m_ptrCFesRtu->m_MaxAccPoints; accPoint++) + { + pFwAcc = m_ptrCFesRtu->m_pFwAcc + accPoint; + UA_VariableAttributes attr = UA_VariableAttributes_default; + attr.description = UA_LOCALIZEDTEXT_ALLOC("en-US",pFwAcc->PointDesc); + attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US",pFwAcc->PointDesc); + attr.accessLevel = UA_ACCESSLEVELMASK_READ; + + m_vecAccNodeId.push_back(UA_NodeId()); + UA_NodeId_init(&m_vecAccNodeId[accPoint]); + buildNodeId(pFwAcc->ResParam2,pFwAcc->szResParam1,m_vecAccNodeId[accPoint]); + + UA_QualifiedName qualifiedName = UA_QUALIFIEDNAME_ALLOC(1, pFwAcc->PointDesc); + UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_OBJECTSFOLDER); + UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_ORGANIZES); + UA_Server_addVariableNode(m_ptrUaServer, m_vecAccNodeId[accPoint], parentNodeId, + parentReferenceNodeId, qualifiedName, + UA_NODEID_NULL, attr, NULL, NULL); + + m_mapAccVecIndex[pFwAcc->RemoteNo]=accPoint; + } + + + + + +} + + diff --git a/product/src/fes/protocol/opc_ua_server_s/DataProcThread.h b/product/src/fes/protocol/opc_ua_server_s/DataProcThread.h new file mode 100644 index 00000000..ad295ece --- /dev/null +++ b/product/src/fes/protocol/opc_ua_server_s/DataProcThread.h @@ -0,0 +1,94 @@ +#pragma once +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "OPCUA_Common.h" +#include "boost/container/map.hpp" + + +using namespace iot_public; + + +class COpcUaDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + COpcUaDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam); + virtual ~COpcUaDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + CFesBase* m_ptrCFesBase; + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,Yxcloudmqtts tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SOpcUaAppConfigParam m_AppData; //内部应用数据结构 + + + SFesFwChgAi *m_pChgAiData; + SFesFwChgDi *m_pChgDiData; + SFesFwChgAcc *m_pChgAccData; + SFesFwChgMi *m_pChgMiData; + +private: + bool m_bReady;//线程是否准备好 + bool m_bServerOK; + UA_Server* m_ptrUaServer; + std::vector m_vecDiNodeId; + std::vector m_vecAiNodeId; + std::vector m_vecMiNodeId; + std::vector m_vecAccNodeId; + int64 m_lastBatchUpateTime; + boost::container::map m_mapDiVecIndex; + boost::container::map m_mapAiVecIndex; + boost::container::map m_mapMiVecIndex; + boost::container::map m_mapAccVecIndex; + +private: + + void ForwardData(); + + //到时刷新 + void ifTimeToBatchUpdate(); + void handleAiData(); + void handleDiData(); + void handleAccData(); + void handleMiData(); + + + //数据是否变化 + void ifDataChgAndWrite(); + + void handleChgAiData(); + void handleChgDiData(); + void handleChgAccData(); + void handleChgMiData(); + + + + + int initServer(); + void ShowChanData(const std::string& msgData); + std::string getStatusMessage(UA_StatusCode status); + + int buildNodeId(int nodeIdType, const string &tagStr,UA_NodeId& nodeId); + + int buildValue(int dataType, double curValue,UA_Variant& value); + + bool hasDataIndex(const string &tagStr,string& resultIndex); + + void clearData(); + + + void initNodeId(); + +}; +typedef boost::shared_ptr COpcUaDataProcThreadPtr; diff --git a/product/src/fes/protocol/opc_ua_server_s/OPCUA.cpp b/product/src/fes/protocol/opc_ua_server_s/OPCUA.cpp new file mode 100644 index 00000000..1df983d0 --- /dev/null +++ b/product/src/fes/protocol/opc_ua_server_s/OPCUA.cpp @@ -0,0 +1,322 @@ +#include "OPCUA.h" +#include "pub_utility_api/CommonConfigParse.h" +#include + + +COPCUA OpcUa; +bool g_OpcUaIsMainFes=false; +bool g_OpcUaChanelRun=true; + + + +int EX_SetBaseAddr(void *address) +{ + OpcUa.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + OpcUa.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + OpcUa.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + OpcUa.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + OpcUa.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + LOGDEBUG("opc_ua_server EX_ExitSystem() start"); + g_OpcUaChanelRun=false;//使所有的线程退出。 + OpcUa.ExitSystem(flag); + LOGDEBUG("opc_ua_server EX_ExitSystem() end"); + return iotSuccess; +} + +COPCUA::COPCUA():m_ProtocolId(-1),m_ptrCFesBase(NULL) +{ + +} + +COPCUA::~COPCUA() +{ + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); +} + +int COPCUA::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + ReadConfigParam(); + } + return iotSuccess; +} + +int COPCUA::SetProperty(int IsMainFes) +{ + g_OpcUaIsMainFes = (bool)IsMainFes; + LOGDEBUG("COPCUA::SetProperty g_OpcUaIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +int COPCUA::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if ((OpenFlag == CN_FesChanThread_Flag) || (OpenFlag == CN_FesChanAndDataThread_Flag)) + { + switch (ptrFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + case CN_FesTcpServer: + break; + default: + LOGERROR("COPCUA EX_OpenChan() ChanNo:%d CommType=%d is not TCP SERVER/Client!", ptrFesChan->m_Param.ChanNo, ptrFesChan->m_Param.CommType); + return iotFailed; + } + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + COpcUaDataProcThreadPtr ptrCDataProc=boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_vecAppParam); + if (ptrCDataProc == NULL) + { + LOGERROR("COPCUA EX_OpenChan() ChanNo:%d create DataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + LOGINFO("COPCUA EX_OpenChan() ChanNo:%d create DataProcThreadPtr ok!", ptrFesChan->m_Param.ChanNo); + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; +} + + +int COPCUA::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("COPCUA::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + return iotSuccess; +} + + +/** + * @brief COPCUA::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int COPCUA::ChanTimer(int MainChanNo) +{ + boost::ignore_unused(MainChanNo); + //把命令缓冲时间间隔到的命放到发送命令缓冲区 + return iotSuccess; +} + +int COPCUA::ExitSystem(int flag) +{ + boost::ignore_unused(flag); + InformTcpThreadExit(); + return iotSuccess; +} + + + +void COPCUA::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + COpcUaDataProcThreadPtr ptrTcp; + + if ((tempNum = (int)m_CDataProcQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CDataProcQueue.erase(it);//COPCUA::~COpcUaDataProcThread()退出线程 + LOGDEBUG("COPCUA::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + + +int COPCUA::ReadConfigParam() +{ + CCommonConfigParse config; + char strRtuNo[48]; + SOpcUaAppConfigParam param; + int items,i,j; + CFesChanPtr ptrChan; //CHAN数据区 + CFesRtuPtr ptrRTU; + std::string strvalue; + int ivalue; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"opc_ua_server_s"); + if (m_ProtocolId == -1) + { + LOGDEBUG("ReadConfigParam ProtoclID error"); + return iotFailed; + } + LOGINFO("opc_ua_server_s ProtoclID=%d", m_ProtocolId); + + if (config.load("../../data/fes/", "opc_ua_server_s.xml") == iotFailed) + { + LOGDEBUG("opc_ua_server_s load opc_ua_server_s.xml error"); + return iotSuccess; + } + LOGDEBUG("opc_ua_server_s load opc_ua_server_s.xml ok"); + + for (i = 0; i < m_ptrCFesBase->m_vectCFesChanPtr.size(); i++) + { + ptrChan = m_ptrCFesBase->m_vectCFesChanPtr[i]; + if ((ptrChan->m_Param.Used == 1) && (m_ProtocolId == ptrChan->m_Param.ProtocolId)) + { + //found RTU + for (j = 0; j < m_ptrCFesBase->m_vectCFesRtuPtr.size(); j++) + { + ptrRTU = m_ptrCFesBase->m_vectCFesRtuPtr[j]; + if (ptrRTU->m_Param.Used && (ptrRTU->m_Param.ChanNo == ptrChan->m_Param.ChanNo)) + { + memset(&strRtuNo[0], 0, sizeof(strRtuNo)); + sprintf(strRtuNo, "RTU%d", ptrRTU->m_Param.RtuNo); + + param.RtuNo = ptrRTU->m_Param.RtuNo; + items = 0; + + + param.pwd = "pwd"; + strvalue.clear(); + if (config.getStringValue(strRtuNo, "pwd", strvalue) == iotSuccess) + { + param.pwd = strvalue; + items++; + } + + param.userName = "userName"; + strvalue.clear(); + if (config.getStringValue(strRtuNo, "userName", strvalue) == iotSuccess) + { + param.userName = strvalue; + items++; + } + + + + param.securityPolicy = "securityPolicy"; + strvalue.clear(); + if (config.getStringValue(strRtuNo, "securityPolicy", strvalue) == iotSuccess) + { + param.securityPolicy = strvalue; + items++; + } + + param.messageSecurityMode = "messageSecurityMode"; + strvalue.clear(); + if (config.getStringValue(strRtuNo, "messageSecurityMode", strvalue) == iotSuccess) + { + param.messageSecurityMode = strvalue; + items++; + } + + param.certificateFilePath = "certificateFilePath"; + strvalue.clear(); + if (config.getStringValue(strRtuNo, "certificateFilePath", strvalue) == iotSuccess) + { + param.certificateFilePath = strvalue; + items++; + } + + + param.privateKeyPath = "privateKeyPath"; + strvalue.clear(); + if (config.getStringValue(strRtuNo, "privateKeyPath", strvalue) == iotSuccess) + { + param.privateKeyPath = strvalue; + items++; + } + + param.intervalTime = 0; + if (config.getIntValue(strRtuNo, "intervalTime", ivalue) == iotSuccess) + { + param.intervalTime = ivalue; + items++; + } + + + + + if (items > 0)//对应的RTU有配置项 + { + m_vecAppParam.push_back(param); + } + } + } + } + } + return iotSuccess; + +} + + + +void COPCUA::InformTcpThreadExit() +{ + +} + + diff --git a/product/src/fes/protocol/opc_ua_server_s/OPCUA.h b/product/src/fes/protocol/opc_ua_server_s/OPCUA.h new file mode 100644 index 00000000..f520e868 --- /dev/null +++ b/product/src/fes/protocol/opc_ua_server_s/OPCUA.h @@ -0,0 +1,44 @@ +#pragma once + + +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "DataProcThread.h" + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + + + + +class PROTOCOLBASE_API COPCUA : public CProtocolBase +{ +public: + COPCUA(); + ~COPCUA(); + + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + vector m_CDataProcQueue; + vector m_vecAppParam; + + + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + int ExitSystem(int flag); + int ReadConfigParam(); + void InformTcpThreadExit(); +private: + int m_ProtocolId; + void ClearDataProcThreadByChanNo(int ChanNo); +}; diff --git a/product/src/fes/protocol/opc_ua_server_s/OPCUA_Common.h b/product/src/fes/protocol/opc_ua_server_s/OPCUA_Common.h new file mode 100644 index 00000000..4fb1ed85 --- /dev/null +++ b/product/src/fes/protocol/opc_ua_server_s/OPCUA_Common.h @@ -0,0 +1,40 @@ +#pragma once +#include "open62541/server.h" +#include "open62541/config.h" +#include "string" + + +enum DataType +{ + SByte=1, + Int16, + Int32, + Int64, + Byte, + UInt16, + UInt32, + UInt64, + Float, + Double, + Boolean, + //String, + //Datetime +}; + + + +//配置参数 +typedef struct{ + int RtuNo; + std::string pwd; + std::string userName; + std::string securityPolicy; + std::string messageSecurityMode; + std::string certificateFilePath; + std::string privateKeyPath; + int intervalTime; +}SOpcUaAppConfigParam; + + + + diff --git a/product/src/fes/protocol/opc_ua_server_s/opc_ua_server_s.pro b/product/src/fes/protocol/opc_ua_server_s/opc_ua_server_s.pro new file mode 100644 index 00000000..1b41ff27 --- /dev/null +++ b/product/src/fes/protocol/opc_ua_server_s/opc_ua_server_s.pro @@ -0,0 +1,42 @@ +# ARM板上资源有限,不会与云平台混用,不编译 +message("Compile only in x86 environment") +# requires(contains(QMAKE_HOST.arch, x86_64)) +requires(!contains(QMAKE_HOST.arch, aarch64):!linux-aarch64*) + +QT -= core gui +CONFIG -= qt + +TARGET = opc_ua_server_s + +TEMPLATE = lib + +SOURCES += \ + DataProcThread.cpp \ + OPCUA.cpp + + +HEADERS += \ + DataProcThread.h \ + OPCUA_Common.h \ + OPCUA.h + + +INCLUDEPATH += ../../include/ +INCLUDEPATH += ../../include/open62541 + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase -lrdb_api +LIBS += -lopen62541 -lhal-shared + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + diff --git a/product/src/fes/protocol/opcclient/OpcClient.cpp b/product/src/fes/protocol/opcclient/OpcClient.cpp index 59720a81..b2fa3430 100644 --- a/product/src/fes/protocol/opcclient/OpcClient.cpp +++ b/product/src/fes/protocol/opcclient/OpcClient.cpp @@ -48,6 +48,8 @@ int EX_ChanTimer(int ChanNo) int EX_ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + g_OpcClientChanelRun=false;//使所有的线程退出。 OpcClient.InformTcpThreadExit(); return iotSuccess; @@ -217,6 +219,8 @@ int COpcClient::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) */ int COpcClient::ChanTimer(int MainChanNo) { + boost::ignore_unused_variable_warning(MainChanNo); + return iotSuccess; } diff --git a/product/src/fes/protocol/opcclient/OpcClientDataProcThread.cpp b/product/src/fes/protocol/opcclient/OpcClientDataProcThread.cpp index 0bd67d09..134ea00c 100644 --- a/product/src/fes/protocol/opcclient/OpcClientDataProcThread.cpp +++ b/product/src/fes/protocol/opcclient/OpcClientDataProcThread.cpp @@ -1207,7 +1207,7 @@ void COpcClientDataProcThread::KwhPro(int tdNo, int RtuNo, int iKwh, float fval) ShowChanStrData(tdNo, dispstr, CN_SFesSimComFrameTypeRecv); AccValue.PointNo = iKwh; - AccValue.Value = (int64)fval; + AccValue.Value = fval; AccValue.Status = CN_FesValueUpdate; AccValue.time = mSec; diff --git a/product/src/fes/protocol/opcclient/OpcRtu.h b/product/src/fes/protocol/opcclient/OpcRtu.h index 249e6fe7..37d9d8f1 100644 --- a/product/src/fes/protocol/opcclient/OpcRtu.h +++ b/product/src/fes/protocol/opcclient/OpcRtu.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include @@ -29,8 +29,8 @@ const int OneRead_MaxNum = 1000; typedef struct { int RtuNo; - int PointNo;//Point - char dbPath[CN_KBDOpcNameLen];//61850 Point· + int PointNo;//Point号 + char dbPath[CN_KBDOpcNameLen];//61850 Point路径 }SKBDOpcRdbPointParam; typedef struct { @@ -38,29 +38,29 @@ typedef struct { int GroupNo; int PointNo; int ValueType; - double MaxValue;//ֵ - double MinValue;//Сֵ - double Modulus;//ϵ - double Revise;//ֵ - char chDir[CN_KBDOpcNameLen];//· - short index;//λ + double MaxValue;//最大值 + double MinValue;//最小值 + double Modulus;//系数 + double Revise;//附加值 + char chDir[CN_KBDOpcNameLen];//路径 + short index;//所在位置 }SKBDOpcRdbSettingParam; struct DZ_DATA { - int DeviceID;//豸ID - char PointDsp[80];//ֵ + int DeviceID;//设备ID + char PointDsp[80];//定值描述 int GroupNo; int PointNo; int ValueType; //5:chang dz group - float MaxValue;//ֵ - float MinValue;//Сֵ - float Modulus;//ϵ - float Revise;//ֵ - char Unit[20];//λ - char cPara1[40];//Զ1 - char chDir[CN_KBDOpcNameLen];//· - int index;//λ + float MaxValue;//最大值 + float MinValue;//最小值 + float Modulus;//系数 + float Revise;//附加值 + char Unit[20];//单位 + char cPara1[40];//自定义命令1 + char chDir[CN_KBDOpcNameLen];//路径 + int index;//所在位置 BOOL initOK; int tagNo; }; @@ -77,27 +77,27 @@ struct TagStr struct OPC_LINK { - BOOL bLinkState;//OPC״̬ - BOOL bClose;//ǰѾر - DWORD64 hConnect;//ӷ - OPCHANDLE hGroup;//ľ - DWORD dwIndex;//ǰOPC - char chServerName[50];//"Citect.OPC.1" 'OPC - char chMachineName[50];//192.168.1.108 'ڼIPַ + BOOL bLinkState;//OPC链接状态 + BOOL bClose;//当前已经关闭了 + DWORD64 hConnect;//链接服务器句柄 + OPCHANDLE hGroup;//组的句柄 + DWORD dwIndex;//当前OPC的序号 + char chServerName[50];//"Citect.OPC.1" 'OPC服务器名 + char chMachineName[50];//192.168.1.108 '服务器所在计算机名或IP地址 int tdNo; - int iVer; //OPC汾 Ĭ2.0 1ʾ1.0 ʾ2.0 - DWORD tFirst;//ʱʱ + int iVer; //OPC版本 默认是2.0 填1表示1.0 填其它表示2.0 + DWORD tFirst;//超时记时 int tagnum; - DWORD cycTime; //OPCȡ λ Ĭ500 + DWORD cycTime; //OPC读取数据周期 单位毫秒 默认500毫秒 - BOOL InitTagFlag; //ǩʼ־ + BOOL InitTagFlag; //标签初始化标志 IOPCItemMgt *pItemMgt = NULL; OPCITEMRESULT *pItemResult = NULL; IOPCSyncIO *pISync = NULL; TagStr *tag; }; -union DATA_VAL//ֵ +union DATA_VAL//数据值 { long nVal; double dVal; @@ -108,10 +108,10 @@ struct OPC_DATA { float GetVal() { - //ϵƫ + //返回数据增加系数与偏移量 // 2,int2; 3,int4; 4,float;5,double;8,string;11,bool - // ַݲ 8,string - //ǩͶ4,float;5,double;8,string; + // 字符串暂不处理 8,string + //标签的类型多增加了4,float;5,double;8,string; if (iVariantType == 2 || iVariantType == 3) { return (float)union_dataVal.nVal; @@ -126,34 +126,34 @@ struct OPC_DATA return 0; } int PointNo;// - char chName[LEN_NAME];//tag + char chName[LEN_NAME];//tag名 int iVariantType; - DATA_VAL union_dataVal;//ֵ - WORD iQuality; //洢ݿ + DATA_VAL union_dataVal;//数据值 + WORD iQuality; //质量,不存储到数据库 FILETIME timestamp; - //WORD wMilliseconds; // + //WORD wMilliseconds; //毫秒 BOOL firstFlag; BOOL initOK; int tagNo; }; struct RTU_DATA { - int iChanNo;//ͨ - int sChanNo;//ͨ - int iRtuNo; //RTU + int iChanNo;//通道号 + int sChanNo;//备用通道号 + int iRtuNo; //RTU序号 - char chServerName[50];//"Citect.OPC.1" 'OPC - char chMachineName[50];//192.168.1.108 'ڼIPַ + char chServerName[50];//"Citect.OPC.1" 'OPC服务器名 + char chMachineName[50];//192.168.1.108 '服务器所在计算机名或IP地址 - int iYCNum;//ǰRTUõYC - int iKWHNum;//ǰRTUõKWH - int iYXNum;//ǰRTUõYX - int iYKNum;//ǰRTUõYK - int iAoNum;//ǰRTUõAO - //int iMiNum;//ǰRTUõMi - //int iMoNum;//ǰRTUõMO - //int iDzNum;//ǰRTUõDZ + int iYCNum;//当前RTU中配置的YC个数 + int iKWHNum;//当前RTU中配置的KWH个数 + int iYXNum;//当前RTU中配置的YX个数 + int iYKNum;//当前RTU中配置的YK个数 + int iAoNum;//当前RTU中配置的AO个数 + //int iMiNum;//当前RTU中配置的Mi个数 + //int iMoNum;//当前RTU中配置的MO个数 + //int iDzNum;//当前RTU中配置的DZ个数 OPC_DATA *yc; OPC_DATA *yx; @@ -164,20 +164,20 @@ struct RTU_DATA // OPC_DATA *mo; // vector dz; - BOOL bRcvOk;//յ + BOOL bRcvOk;//有收到数据 BOOL useFlag; }; typedef struct { - unsigned short aMs; // + unsigned short aMs; //毫秒 unsigned char aSec; unsigned char aMin; unsigned char aHour; unsigned char aDay; unsigned char aWeek; //0-6,sunday=0 unsigned char aMon; - unsigned char aYear; //start from 1900,=ǰ-1900 + unsigned char aYear; //start from 1900,即=当前年-1900 }FETIME; diff --git a/product/src/fes/protocol/protocol.pro b/product/src/fes/protocol/protocol.pro index 6f528236..83c002b9 100644 --- a/product/src/fes/protocol/protocol.pro +++ b/product/src/fes/protocol/protocol.pro @@ -1,55 +1,72 @@ - -#各子工程按书写顺序编译,清注意各子工程的依赖关系,被依赖的库应写在前面。 - -TEMPLATE = subdirs -CONFIG += ordered - - -SUBDIRS += \ - protocolbase \ - modbus_tcp \ - modbus_tcp_s \ - iec104 \ - iec104s \ - iec101s \ - kbd104 \ - kbd61850m \ - modbus_rtu \ - wfudpcdt \ - szdt_robot \ - modbus_sepam \ - modbus_c30 \ - modbus_pm \ - cdt \ - modbus_rtu_s \ - iec103 \ - cdts \ - dlt645 \ - khbas \ - siemens103_tcp \ - modbus_tcp_nhats \ - modbus_tcp_pis \ - modbus_tcp_pa \ - snmp \ - snmpv3 \ - r80x_io \ - virtualrtu \ - iec61850client2 \ - gf104s \ - modbus_tcp_vamp \ - modbus_tcp_fpd \ - modbus_micomP \ - modbus_tcp_epm9200 \ - gf104 \ - fesdatazf \ - fesdatarecv \ - modbus_tcpV3 \ - iec104V2 \ - ad104s \ - sqlserver_s - - -win32-msvc* { - SUBDIRS += opcclient -} - + +#各子工程按书写顺序编译,清注意各子工程的依赖关系,被依赖的库应写在前面。 + +TEMPLATE = subdirs +CONFIG += ordered + + +SUBDIRS += \ + protocolbase \ + modbus_tcp \ + modbus_tcp_s \ + iec104 \ + iec104s \ + #iec101s \ + #kbd104 \ + #kbd61850m \ + modbus_rtu \ + #wfudpcdt \ + #szdt_robot \ + #modbus_sepam \ + #modbus_c30 \ + #modbus_pm \ + #cdt \ + #modbus_rtu_s \ + #iec103 \ + #cdts \ + dlt645 \ + #khbas \ + #siemens103_tcp \ + #modbus_tcp_nhats \ + #modbus_tcp_pis \ + #modbus_tcp_pa \ + snmp \ + snmpv3 \ + #r80x_io \ + virtualrtu \ +# iec61850client2 \ + #gf104s \ + #modbus_tcp_vamp \ + #modbus_tcp_fpd \ + #modbus_micomP \ + #modbus_tcp_epm9200 \ + #gf104 \ + fesdatazf \ + fesdatarecv \ + fespartdatazf \ + fespartdatarecv \ + modbus_tcpV3 \ + iec104V2 \ + iec61850_clientV3 \ + yxcloud_mqtt_s \ + modbus_rtuV2 \ + modbus_rtu_dt \ + yxcloud_mqtt_wn \ + #fes_yxcloud_protobuf \ + mqtt_hcfy \ + dgls_mqttclient \ + #modbus_tcp_mz + sqlserver_s \ + mqtt_yxCloud \ + #dnp3_master \ + dnp3_transmit + +win32-msvc* { + SUBDIRS += opcclient \ + httpClient_szdt +} + +linux:contains(QMAKE_HOST.arch, aarch64) | linux-aarch64* { + SUBDIRS += kbd511s_io +} + diff --git a/product/src/fes/protocol/protocolbase/ProtocolBase.cpp b/product/src/fes/protocol/protocolbase/ProtocolBase.cpp index d8ad7362..8f3ff3f1 100644 --- a/product/src/fes/protocol/protocolbase/ProtocolBase.cpp +++ b/product/src/fes/protocol/protocolbase/ProtocolBase.cpp @@ -220,7 +220,7 @@ void CProtocolBase::ShowChanStrData(int ChanNo, char *Data, int SendFlag) frame.FrameType = SendFlag; frame.DataType = CN_SFesSimComDataType_Str; frame.Time = getUTCTimeMsec(); - frame.FrameLen = strlen(Data); + frame.FrameLen = static_cast(strlen(Data)); if(frame.FrameLen > CN_SFesSimComFrameMaxLen) frame.FrameLen = CN_SFesSimComFrameMaxLen-1; memcpy(frame.Data,Data,CN_SFesSimComFrameMaxLen); diff --git a/product/src/fes/protocol/r80x_io/r80x_io.pro b/product/src/fes/protocol/r80x_io/r80x_io.pro index 79f0f326..3151db44 100644 --- a/product/src/fes/protocol/r80x_io/r80x_io.pro +++ b/product/src/fes/protocol/r80x_io/r80x_io.pro @@ -1,6 +1,6 @@ # r80x专用的,必然是x86架构,arm下编译不过 -requires(contains(QMAKE_HOST.arch, x86_64)) +requires(contains(QMAKE_HOST.arch, x86_64):!linux-aarch64*) #CONFIG -= qt QT += serialport diff --git a/product/src/fes/protocol/snmp/asn1.h b/product/src/fes/protocol/snmp/asn1.h index 520e179d..e277145f 100644 --- a/product/src/fes/protocol/snmp/asn1.h +++ b/product/src/fes/protocol/snmp/asn1.h @@ -1,4 +1,4 @@ -/*_############################################################################ +/*_############################################################################ _## _## asn1.h _## diff --git a/product/src/fes/protocol/snmp/snmp.cpp b/product/src/fes/protocol/snmp/snmp.cpp index de6af220..94beb234 100644 --- a/product/src/fes/protocol/snmp/snmp.cpp +++ b/product/src/fes/protocol/snmp/snmp.cpp @@ -89,7 +89,7 @@ int CSnmp::SetBaseAddr(void *address) int CSnmp::SetProperty(int IsMainFes) { - g_snmpIsMainFes = IsMainFes; + g_snmpIsMainFes = (IsMainFes != 0); LOGDEBUG("CSnmp::SetProperty g_smnpIsMainFes:%d",IsMainFes); return iotSuccess; } @@ -219,11 +219,15 @@ int CSnmp::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) */ int CSnmp::ChanTimer(int MainChanNo) { + boost::ignore_unused_variable_warning(MainChanNo); + return iotSuccess; } int CSnmp::ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + InformComThreadExit(); return iotSuccess; @@ -231,11 +235,13 @@ int CSnmp::ExitSystem(int flag) void CSnmp::ClearComThreadByChanNo(int ChanNo) { - int tempNum; - CUdpClientThreadPtr ptrTcp; - - if ((tempNum = m_UdpClientThreadQueue.size())<=0) + if(m_UdpClientThreadQueue.empty()) + { return; + } + + CUdpClientThreadPtr ptrTcp; + vector::iterator it; for (it = m_UdpClientThreadQueue.begin();it!= m_UdpClientThreadQueue.end();it++) { @@ -251,11 +257,13 @@ void CSnmp::ClearComThreadByChanNo(int ChanNo) void CSnmp::ClearDataProcThreadByChanNo(int ChanNo) { - int tempNum; - CSnmpDataProcThreadPtr ptrTcp; - - if ((tempNum = m_DataProcThreadQueue.size())<=0) + if(m_DataProcThreadQueue.empty()) + { return; + } + + CSnmpDataProcThreadPtr ptrTcp; + vector::iterator it; for (it = m_DataProcThreadQueue.begin();it!= m_DataProcThreadQueue.end();it++) { @@ -281,7 +289,7 @@ int CSnmp::ReadConfigParam() int ivalue; char strRtuNo[48]; SSnmpAppConfigParam param; - int items,i,j,ProtoclID; + int items,i,j; CFesChanPtr ptrChan; //CHAN数据区 CFesRtuPtr ptrRTU; std::string svalue; @@ -335,7 +343,7 @@ int CSnmp::ReadConfigParam() if (config.getStringValue(strRtuNo, "community", svalue) == iotSuccess) { memcpy(param.communityStr, svalue.c_str(), svalue.size()); - param.communityLen = strlen((const char *)param.communityStr); + param.communityLen = static_cast(strlen((const char *)param.communityStr)); //LOGDEBUG("CSnmp::ReadConfigParam %s %d", svalue.c_str(), svalue.size()); //LOGDEBUG("CSnmp::ReadConfigParam %s", param.communityStr); @@ -343,7 +351,7 @@ int CSnmp::ReadConfigParam() } else { - param.communityLen = strlen("public"); + param.communityLen = static_cast(strlen("public")); memcpy((char*)param.communityStr, "public", sizeof("public")); //LOGDEBUG("CSnmp::ReadConfigParam %s", param.communityStr); @@ -413,7 +421,7 @@ void CSnmp::InitRTUData() LOGERROR("InitRTUData() can't found ProtocolId."); return; } - RtuCount = m_ptrCFesBase->m_vectCFesRtuPtr.size(); + RtuCount = static_cast(m_ptrCFesBase->m_vectCFesRtuPtr.size()); for (i = 0; im_vectCFesRtuPtr[i]->m_Param.ProtocolId == ProtocolId) @@ -483,6 +491,7 @@ void CSnmp::InitRTUData() strcpy(RtuPtr->DevLuboPath, VecRtuParam[0].DevLuboPath); RtuPtr->CallLuboTime = VecRtuParam[0].CallLuboTime;//s RtuPtr->CallLuboTime *= 1000;//ms + RtuPtr->readIndex = 0; strcpy(RtuPtr->DeviceDesc, VecRtuParam[0].DeviceDesc); ret = RdbRtuTable.close(); @@ -515,7 +524,7 @@ void CSnmp::InitRTUData() LOGERROR("RdbAiTable.selectNoCondition error!"); return; } - PointCount = VecAiParam.size(); + PointCount = static_cast(VecAiParam.size()); if (PointCount>0) { RtuPtr->iYCNum = VecAiParam[PointCount - 1].PointNo + 1; @@ -588,7 +597,7 @@ void CSnmp::InitRTUData() LOGERROR("RdbDiTable.selectNoCondition error!"); return; } - PointCount = VecDiParam.size(); + PointCount = static_cast(VecDiParam.size()); if (PointCount>0) { RtuPtr->iYXNum = VecDiParam[PointCount - 1].PointNo + 1; @@ -639,7 +648,7 @@ void CSnmp::InitRTUData() LOGERROR("RdbAccTable.selectNoCondition error!"); return; } - PointCount = VecAccParam.size(); + PointCount = static_cast(VecAccParam.size()); if (PointCount>0) { RtuPtr->iKWHNum = VecAccParam[PointCount - 1].PointNo + 1; @@ -713,7 +722,7 @@ void CSnmp::InitRTUData() LOGERROR("RdbDoTable.selectNoCondition error!"); return; } - PointCount = VecDoParam.size(); + PointCount = static_cast(VecDoParam.size()); if (PointCount > 0) { RtuPtr->iYKNum = VecDoParam[PointCount - 1].PointNo + 1; @@ -773,7 +782,7 @@ void CSnmp::InitRTUData() return; } - PointCount = VecSetting.size(); + PointCount = static_cast(VecSetting.size()); if (PointCount > 0) { DZ_DATA dzdata; @@ -783,10 +792,10 @@ void CSnmp::InitRTUData() dzdata.GroupNo = VecSetting[j].GroupNo; dzdata.PointNo = VecSetting[j].PointNo; dzdata.ValueType = VecSetting[j].ValueType; - dzdata.MaxValue = VecSetting[j].MaxValue; - dzdata.MinValue = VecSetting[j].MinValue; - dzdata.Modulus = VecSetting[j].Modulus; - dzdata.Revise = VecSetting[j].Revise; + dzdata.MaxValue = static_cast(VecSetting[j].MaxValue); + dzdata.MinValue = static_cast(VecSetting[j].MinValue); + dzdata.Modulus = static_cast(VecSetting[j].Modulus); + dzdata.Revise = static_cast(VecSetting[j].Revise); strcpy(dzdata.chDir, VecSetting[j].chDir); dzdata.index = VecSetting[j].index; RtuPtr->dz.push_back(dzdata); @@ -817,7 +826,7 @@ void CSnmp::InitRTUData() LOGERROR("RdbAoTable.selectNoCondition error!"); return; } - PointCount = VecAoParam.size(); + PointCount = static_cast(VecAoParam.size()); if (PointCount > 0) { RtuPtr->iYTNum = VecAoParam[PointCount - 1].PointNo + 1; diff --git a/product/src/fes/protocol/snmp/snmpDataProcThread.cpp b/product/src/fes/protocol/snmp/snmpDataProcThread.cpp index 0946b6cb..ede9913c 100644 --- a/product/src/fes/protocol/snmp/snmpDataProcThread.cpp +++ b/product/src/fes/protocol/snmp/snmpDataProcThread.cpp @@ -469,8 +469,8 @@ int CSnmpDataProcThread::DoCmdProcess(byte *Data, int /*dataSize*/) SFesRxDoCmd cmd; SFesTxDoCmd retCmd; SFesDo *pDo; - int writex, crcCount = 0, FunCode = 5; - int pswReg, pswVal, regNum, i, status; + int writex; + int status; //SNMPM_D_VB pVB; SNMPM_D_RAW_PDU rawPdu; @@ -613,12 +613,11 @@ int CSnmpDataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) { SFesRxAoCmd cmd; SFesTxAoCmd retCmd; - short setValue; SFesAo *pAo = NULL; int writex; float fValue, tempValue; int failed; - int iValue, crcCount, status; + int status; //SNMPM_D_VB *pVB; SNMPM_D_RAW_PDU rawPdu; writex = 0; @@ -767,17 +766,18 @@ int CSnmpDataProcThread::AoCmdProcess(byte *Data, int /*dataSize*/) */ int CSnmpDataProcThread::DefCmdProcess(byte *Data, int dataSize) { - byte data[300]; + boost::ignore_unused_variable_warning(dataSize); + SFesRxDefCmd rxDefCmd; SFesTxDefCmd txDefCmd; - int writex, i, groupNo, groupNodotNo, crcCount, status; + int writex, i, status; bool errorFlag = false; SNMPM_D_RAW_PDU rawPdu; SFesDz* pDz; writex = 0; if (m_ptrCInsertFesRtu->ReadRxDefCmd(1, &rxDefCmd) == 1) { - m_AppData.CmdNum = rxDefCmd.VecCmd.size(); + m_AppData.CmdNum = static_cast(rxDefCmd.VecCmd.size()); m_AppData.defCmd = rxDefCmd; if (CMD_TYPE == rxDefCmd.VecCmd[0].name) @@ -889,22 +889,14 @@ int CSnmpDataProcThread::SendProcess() int retLen = 0; int count = 0; int retsts = 1; - char logMsg[256]; unsigned char databuff[MAX_SNMP_PACKET]; unsigned int bufflen; - unsigned char recvbuff[MAX_SNMP_PACKET]; - unsigned int recvbufflen; - unsigned char community_name[SNMPM_K_MAX_LEN_COMMUNITY]; // int community_len = SNMPM_K_MAX_LEN_COMMUNITY; int status; - int version_num; - SNMPM_D_VB *pVB; SNMPM_D_RAW_PDU rawPdu; YC_DATA *pYc; YX_DATA *pYx; KWH_DATA *pYm; - int strValueLen; - char oidStr[SNMPM_K_MAX_OID_SIZE]; memset(&rawPdu, 0, sizeof(rawPdu)); //LOGDEBUG("============"); @@ -1051,6 +1043,19 @@ bool CSnmpDataProcThread::isTimetoSend() int64 curmSec; curmSec = getMonotonicMsec(); + if(curmSec - m_AppData.sendInterval > m_AppData.sendIntervalReset) + { + m_AppData.sendInterval = curmSec; + m_AppData.sendIntervalCount = 0; + return true; + } + else + { + return false; + } + + /* + if ((curmSec - m_AppData.sendInterval) < m_AppData.sendIntervalReset) { if (m_AppData.sendIntervalCount++ > 200)//2秒,纠错处理 @@ -1068,6 +1073,7 @@ bool CSnmpDataProcThread::isTimetoSend() m_AppData.sendIntervalCount = 0; return true; } + */ } /** * @brief CSnmpDataProcThread::CmdControlRespProcess @@ -1078,6 +1084,9 @@ bool CSnmpDataProcThread::isTimetoSend() */ bool CSnmpDataProcThread::CmdControlRespProcess(byte *Data, int DataSize, int okFlag) { + boost::ignore_unused_variable_warning(Data); + boost::ignore_unused_variable_warning(DataSize); + SFesTxDoCmd retDoCmd; SFesTxAoCmd retAoCmd; SFesTxMoCmd retMoCmd; @@ -1233,17 +1242,13 @@ int CSnmpDataProcThread::RecvDataProcess(byte *Data, int DataSize) int status, i, errCount = 0; int version_num; SNMPM_D_VB *pVB; - SNMPM_D_RAW_PDU rawPdu; YC_DATA *Yc; YX_DATA *Yx; KWH_DATA *Ym; - int count, WriteValue; - int retsts; - char message[100]; // for the system descriptor printable octet + int WriteValue; int strValueLen; char oidStr[SNMPM_K_MAX_OID_SIZE]; - int bread, CurrDevId; SNMPM_D_RAW_PDU recvPdu; SFesDi *pDi; SFesRtuDiValue DiValue[50]; @@ -1257,8 +1262,6 @@ int CSnmpDataProcThread::RecvDataProcess(byte *Data, int DataSize) SFesRtuAccValue AccValue[100]; SFesChgAcc ChgAcc[100]; - float aiValue; - long accValue; int ValueCount = 0, ChgCount, bitValue, SoeCount = 0; mSec = getUTCTimeMsec(); //LOGDEBUG("111m_RTUPtr:%d m_ptrCFesRtu:%d", m_RTUPtr->iRtuNo, m_ptrCFesRtu->m_Param.RtuNo); @@ -1286,7 +1289,7 @@ int CSnmpDataProcThread::RecvDataProcess(byte *Data, int DataSize) pVB = &recvPdu.vb[i]; OidToStr(pVB); strcpy(oidStr, pVB->oidStr); - strValueLen = strlen(pVB->oidStr); + strValueLen = static_cast(strlen(pVB->oidStr)); if (strValueLen > 0)// && (pPoint != NULL)) { ValueCount = 0; @@ -1309,7 +1312,7 @@ int CSnmpDataProcThread::RecvDataProcess(byte *Data, int DataSize) Yc->val = 0; WriteValue = Yc->val; AiValue[ValueCount].PointNo = pAi->PointNo; - AiValue[ValueCount].Value = WriteValue; + AiValue[ValueCount].Value = static_cast(WriteValue); AiValue[ValueCount].Status = CN_FesValueUpdate; AiValue[ValueCount].time = mSec; ValueCount++; @@ -1403,7 +1406,7 @@ int CSnmpDataProcThread::RecvDataProcess(byte *Data, int DataSize) Ym->val = pVB->val.integer; WriteValue = Ym->val; AiValue[ValueCount].PointNo = pAcc->PointNo; - AiValue[ValueCount].Value = WriteValue; + AiValue[ValueCount].Value = static_cast(WriteValue); AiValue[ValueCount].Status = CN_FesValueUpdate; AiValue[ValueCount].time = mSec; ValueCount++; @@ -1434,7 +1437,7 @@ int CSnmpDataProcThread::RecvDataProcess(byte *Data, int DataSize) errCount++; } } - LOGDEBUG("222m_RTUPtr:%d m_ptrCFesRtu:%d", m_RTUPtr->iRtuNo, m_ptrCFesRtu->m_Param.RtuNo); + LOGTRACE("m_RTUPtr:%d m_ptrCFesRtu:%d", m_RTUPtr->iRtuNo, m_ptrCFesRtu->m_Param.RtuNo); } return iotSuccess; } @@ -1513,8 +1516,15 @@ void CSnmpDataProcThread::AppDataInit(vector vecAppParam, v if (!found) InitConfigParam();//配置文件读取失败,取默认配置 - - + //todo:caodingfa临时解决方案,通道保留参数1作为轮询周期使用 + if(m_ptrCFesChan != NULL) + { + m_AppData.sendIntervalReset = m_ptrCFesChan->m_Param.ResParam1; + if(m_AppData.sendIntervalReset < 100) + { + m_AppData.sendIntervalReset = 1000;//1000ms + } + } } int CSnmpDataProcThread::InitConfigParam() @@ -1524,7 +1534,7 @@ int CSnmpDataProcThread::InitConfigParam() LOGDEBUG("InitConfigParam"); //memset(&m_AppData, 0, sizeof(SSnmpAppData));//lww todo 声明结构进行初始化 m_AppData.version = 1; - m_AppData.communityLen = strlen("public"); + m_AppData.communityLen = static_cast(strlen("public")); m_AppData.maxGetPoints = 150; memcpy(m_AppData.communityStr, "public", sizeof("public")); m_AppData.sendIntervalReset = 100;//100ms @@ -3520,7 +3530,7 @@ int snmp_parse_vb(SNMPM_D_RAW_PDU *pdu, unsigned char *data, int *data_len) asn_parse_string(var_val, &len, &vp->type, tempStr, &tempLen); if (strstr((char*)tempStr, ".")) { - vp->val.fValue = atof((char*)tempStr); + vp->val.fValue = static_cast(atof((char*)tempStr)); vp->valueType = 1; } else diff --git a/product/src/fes/protocol/snmps/snmpAgent/CAgentServer.cpp b/product/src/fes/protocol/snmps/snmpAgent/CAgentServer.cpp index b4a9d8e9..ee33e1cd 100644 --- a/product/src/fes/protocol/snmps/snmpAgent/CAgentServer.cpp +++ b/product/src/fes/protocol/snmps/snmpAgent/CAgentServer.cpp @@ -179,8 +179,8 @@ bool CAgentServer::initialize() std::string strLogFile("/net_snmp_agent.log"); int nLogErrFlt = 15, nLogWarFlt = 4, nLogEvtFlt = 0, nLogInfFlt = 0, nLogDbgFlt = 0, nLogUsrFlt = ULL_EVENT; std::string strCommunity("public"); - std::string strAdminAuth("kbdct"); - std::string strAdminPriv("kbdct@0755"); + std::string strAdminAuth("admin"); + std::string strAdminPriv(EMS_DEFAULT_PASSWD); std::set setProcWhiteList; const std::string &&strCurModuleDir = iot_net::getCurModuleDir(); @@ -298,7 +298,7 @@ bool CAgentServer::initialize() //< 业务相关 { //< add() 后由MIB接管,无需我们来释放内存 - pMib->add(new sysGroup("Agent of KBDCT", CN_OID_KBD_ROOT, 10)); + pMib->add(new sysGroup("Snmp Agent", CN_OID_KBD_ROOT, 10)); pMib->add(new snmpGroup()); //mib->add(new snmp_target_mib()); //mib->add(new snmp_notification_mib()); diff --git a/product/src/fes/protocol/snmps/snmpAgent/test/snmp_test.sh b/product/src/fes/protocol/snmps/snmpAgent/test/snmp_test.sh index 320120cd..963c9950 100644 --- a/product/src/fes/protocol/snmps/snmpAgent/test/snmp_test.sh +++ b/product/src/fes/protocol/snmps/snmpAgent/test/snmp_test.sh @@ -1,6 +1,6 @@ #!/bin/sh while true do -#snmpbulkwalk -v 3 -u admin -l authPriv -a sha -A kbdct@0755 -x des -X kbdct@0755 192.168.77.79:4700 ".1.3" -snmpbulkwalk -v 3 -u admin -l authPriv -a sha -A kbdct@0755 -x des -X kbdct@0755 127.0.0.1:4700 ".1.3" +#snmpbulkwalk -v 3 -u admin -l authPriv -a sha -A ems@byd23 -x des -X ems@byd23 192.168.77.79:4700 ".1.3" +snmpbulkwalk -v 3 -u admin -l authPriv -a sha -A ems@byd23 -x des -X ems@byd23 127.0.0.1:4700 ".1.3" done diff --git a/product/src/fes/protocol/snmps/snmpsDataProcThread.cpp b/product/src/fes/protocol/snmps/snmpsDataProcThread.cpp index 0ae87a8a..001a8434 100644 --- a/product/src/fes/protocol/snmps/snmpsDataProcThread.cpp +++ b/product/src/fes/protocol/snmps/snmpsDataProcThread.cpp @@ -65,11 +65,11 @@ int CSnmpsDataProcThread::InitSnmpAgent() pRequestList->set_snmp(pSnmp); //增加系统组oid的相关值 - pMib->add(new sysGroup("Agent of KBDCT", CN_SYSOBJECT_OID, 10)); + pMib->add(new sysGroup("Snmp Agent", CN_SYSOBJECT_OID, 10)); pMib->add(new snmpGroup()); #ifdef _SNMPv3 - initV3(m_snmpPort, "public", "private", "kbdct@0755", "kbdct@0755"); + initV3(m_snmpPort, "public", "private", EMS_DEFAULT_PASSWD, EMS_DEFAULT_PASSWD); #endif //< 主要是加载之前保存的数据,如果有的话 diff --git a/product/src/fes/protocol/snmpv3/snmp.cpp b/product/src/fes/protocol/snmpv3/snmp.cpp index 37514513..c3926add 100644 --- a/product/src/fes/protocol/snmpv3/snmp.cpp +++ b/product/src/fes/protocol/snmpv3/snmp.cpp @@ -89,7 +89,7 @@ int CSnmp::SetBaseAddr(void *address) int CSnmp::SetProperty(int IsMainFes) { - g_snmpIsMainFes = IsMainFes; + g_snmpIsMainFes = (IsMainFes != 0); LOGDEBUG("CSnmp::SetProperty g_smnpIsMainFes:%d",IsMainFes); return iotSuccess; } @@ -210,11 +210,15 @@ int CSnmp::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) */ int CSnmp::ChanTimer(int MainChanNo) { + boost::ignore_unused_variable_warning(MainChanNo); + return iotSuccess; } int CSnmp::ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + InformComThreadExit(); return iotSuccess; @@ -222,6 +226,8 @@ int CSnmp::ExitSystem(int flag) void CSnmp::ClearComThreadByChanNo(int ChanNo) { + boost::ignore_unused_variable_warning(ChanNo); + #if 0 int tempNum; CUdpClientThreadPtr ptrTcp; @@ -245,11 +251,13 @@ void CSnmp::ClearComThreadByChanNo(int ChanNo) void CSnmp::ClearDataProcThreadByChanNo(int ChanNo) { - int tempNum; - CSnmpDataProcThreadPtr ptrTcp; - - if ((tempNum = m_DataProcThreadQueue.size())<=0) + if(m_DataProcThreadQueue.empty()) + { return; + } + + CSnmpDataProcThreadPtr ptrTcp; + vector::iterator it; for (it = m_DataProcThreadQueue.begin();it!= m_DataProcThreadQueue.end();it++) { @@ -275,7 +283,7 @@ int CSnmp::ReadConfigParam() int ivalue; char strRtuNo[48]; SSnmpAppConfigParam param; - int items,i,j,ProtoclID; + int items,i,j; CFesChanPtr ptrChan; //CHAN数据区 CFesRtuPtr ptrRTU; std::string svalue; @@ -331,7 +339,7 @@ int CSnmp::ReadConfigParam() if (config.getStringValue(strRtuNo, "community", svalue) == iotSuccess) { memcpy(param.communityStr, svalue.c_str(), svalue.size()); - param.communityLen = strlen((const char *)param.communityStr); + param.communityLen = static_cast(strlen((const char *)param.communityStr)); //LOGDEBUG("CSnmp::ReadConfigParam %s %d", svalue.c_str(), svalue.size()); //LOGDEBUG("CSnmp::ReadConfigParam %s", param.communityStr); @@ -339,7 +347,7 @@ int CSnmp::ReadConfigParam() } else { - param.communityLen = strlen("public"); + param.communityLen = static_cast(strlen("public")); memcpy((char*)param.communityStr, "public", sizeof("public")); //LOGDEBUG("CSnmp::ReadConfigParam %s", param.communityStr); @@ -383,7 +391,7 @@ int CSnmp::ReadConfigParam() } else { - memcpy(param.securityName, "kbdct@0755", sizeof("kbdct@0755")); + memcpy(param.securityName, EMS_DEFAULT_PASSWD, sizeof(EMS_DEFAULT_PASSWD)); } if (config.getStringValue(strRtuNo, "authPassword", svalue) == iotSuccess) @@ -394,7 +402,7 @@ int CSnmp::ReadConfigParam() } else { - memcpy(param.securityName, "kbdct", sizeof("kbdct")); + memcpy(param.securityName, "admin", sizeof("admin")); LOGDEBUG("CSnmp::ReadConfigParam"); } @@ -453,6 +461,11 @@ int CSnmp::ReadConfigParam() { m_vecAppParam.push_back(param); } + else + { + LOGINFO("SNMP:未找到配置项,使用默认配置.RTU%d",ptrRTU->m_Param.RtuNo); + m_vecAppParam.push_back(param); + } //LOGDEBUG("CSnmp::ReadConfigParam j=%d",j); } @@ -492,7 +505,7 @@ void CSnmp::InitRTUData() LOGERROR("InitRTUData() can't found ProtocolId."); return; } - RtuCount = m_ptrCFesBase->m_vectCFesRtuPtr.size(); + RtuCount = static_cast(m_ptrCFesBase->m_vectCFesRtuPtr.size()); for (i = 0; im_vectCFesRtuPtr[i]->m_Param.ProtocolId == ProtocolId) @@ -592,7 +605,7 @@ void CSnmp::InitRTUData() LOGERROR("RdbAiTable.selectNoCondition error!"); return; } - PointCount = VecAiParam.size(); + PointCount = static_cast(VecAiParam.size()); if (PointCount>0) { RtuPtr->iYCNum = VecAiParam[PointCount - 1].PointNo + 1; @@ -664,7 +677,7 @@ void CSnmp::InitRTUData() LOGERROR("RdbDiTable.selectNoCondition error!"); return; } - PointCount = VecDiParam.size(); + PointCount = static_cast(VecDiParam.size()); if (PointCount>0) { RtuPtr->iYXNum = VecDiParam[PointCount - 1].PointNo + 1; @@ -714,7 +727,7 @@ void CSnmp::InitRTUData() LOGERROR("RdbAccTable.selectNoCondition error!"); return; } - PointCount = VecAccParam.size(); + PointCount = static_cast(VecAccParam.size()); if (PointCount>0) { RtuPtr->iKWHNum = VecAccParam[PointCount - 1].PointNo + 1; diff --git a/product/src/fes/protocol/snmpv3/snmpDataProcThread.cpp b/product/src/fes/protocol/snmpv3/snmpDataProcThread.cpp index b72334da..853e3b6d 100644 --- a/product/src/fes/protocol/snmpv3/snmpDataProcThread.cpp +++ b/product/src/fes/protocol/snmpv3/snmpDataProcThread.cpp @@ -364,13 +364,11 @@ int CSnmpDataProcThread::snmpGet() int count = 0; int retsts = true; - char logMsg[256]; YC_DATA *Yc; YX_DATA *Yx; KWH_DATA *Ym; int WriteValue; - char message[100]; // for the system descriptor printable octet char oidStr[SNMPM_K_MAX_OID_SIZE]; SFesDi *pDi; SFesRtuDiValue DiValue[50]; @@ -384,16 +382,12 @@ int CSnmpDataProcThread::snmpGet() SFesRtuAccValue AccValue[100]; SFesChgAcc ChgAcc[100]; - float aiValue; - long accValue; - int ValueCount = 0, ChgCount, bitValue, SoeCount = 0, value; + int ValueCount = 0, ChgCount, bitValue, SoeCount = 0; int status; - int version_num; YC_DATA *pYc; YX_DATA *pYx; KWH_DATA *pYm; - int strValueLen; mSec = getUTCTimeMsec(); diff --git a/product/src/fes/protocol/virtualrtu/virtualrtu.cpp b/product/src/fes/protocol/virtualrtu/virtualrtu.cpp index 5556efc5..4dbd7be1 100644 --- a/product/src/fes/protocol/virtualrtu/virtualrtu.cpp +++ b/product/src/fes/protocol/virtualrtu/virtualrtu.cpp @@ -47,6 +47,8 @@ int EX_ChanTimer(int ChanNo) int EX_ExitSystem(int flag) { + boost::ignore_unused_variable_warning(flag); + g_virtualrtu_IsMainFes =false;//使所有的线程退出。 return iotSuccess; } @@ -179,6 +181,7 @@ int CVirtualRtu::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) */ int CVirtualRtu::ChanTimer(int MainChanNo) { + boost::ignore_unused_variable_warning(MainChanNo); return iotSuccess; } @@ -189,11 +192,12 @@ int CVirtualRtu::ChanTimer(int MainChanNo) */ void CVirtualRtu::ClearDataProcThreadByChanNo(int ChanNo) { - int tempNum; - CVirtualRtuDataProcThreadPtr ptrPort; - - if ((tempNum = m_CDataProcQueue.size())<=0) + if(m_CDataProcQueue.empty()) + { return; + } + + CVirtualRtuDataProcThreadPtr ptrPort; vector::iterator it; for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) { diff --git a/product/src/fes/protocol/wfudpcdt/wfudpcdtDataProcThread.cpp b/product/src/fes/protocol/wfudpcdt/wfudpcdtDataProcThread.cpp index 50cbade4..53632752 100644 --- a/product/src/fes/protocol/wfudpcdt/wfudpcdtDataProcThread.cpp +++ b/product/src/fes/protocol/wfudpcdt/wfudpcdtDataProcThread.cpp @@ -739,6 +739,8 @@ void CWfudpcdtDataProcThread::SendAccFrame() SFesFwAcc *pFwAcc; int writex; uint8 crc, wordLen, funCode; + double AccDoubleValue; + int64 shortAccValue; maxCount = 32; writex = 12; @@ -750,12 +752,18 @@ void CWfudpcdtDataProcThread::SendAccFrame() while (!over && (m_AppData.sendAccIndex < m_ptrCFesRtu->m_FwAccPointsNum)) { pFwAcc = m_ptrCFesRtu->m_pFwAcc + m_AppData.sendAccIndex; + AccDoubleValue = (double)(pFwAcc->Value*pFwAcc->Coeff + pFwAcc->Base); + shortAccValue = (int64)AccDoubleValue; funCode = 0xA0 | m_AppData.sendAccIndex;//功能码 m_AppData.sendData[writex++] = funCode; - m_AppData.sendData[writex++] = pFwAcc->Value & 0xff; - m_AppData.sendData[writex++] = (pFwAcc->Value>>8) & 0xff; - m_AppData.sendData[writex++] = (pFwAcc->Value>>16) & 0xff; - m_AppData.sendData[writex++] = (pFwAcc->Value>>24) & 0xff; + // m_AppData.sendData[writex++] = pFwAcc->Value & 0xff; + // m_AppData.sendData[writex++] = (pFwAcc->Value>>8) & 0xff; + // m_AppData.sendData[writex++] = (pFwAcc->Value>>16) & 0xff; + // m_AppData.sendData[writex++] = (pFwAcc->Value>>24) & 0xff; + m_AppData.sendData[writex++] = shortAccValue & 0xff; + m_AppData.sendData[writex++] = (shortAccValue>>8) & 0xff; + m_AppData.sendData[writex++] = (shortAccValue>>16) & 0xff; + m_AppData.sendData[writex++] = (shortAccValue>>24) & 0xff; MakeBch(&m_AppData.sendData[writex - 5], &crc); m_AppData.sendData[writex++] = crc; m_AppData.sendAccIndex++; diff --git a/product/src/fes/protocol/yxcloud_mqtt_s/Md5/Md5.cpp b/product/src/fes/protocol/yxcloud_mqtt_s/Md5/Md5.cpp new file mode 100644 index 00000000..c6664c5e --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_s/Md5/Md5.cpp @@ -0,0 +1,372 @@ +#include "Md5.h" + +//using namespace std; + +/* Constants for MD5Transform routine. */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + + +/* F, G, H and I are basic MD5 functions. +*/ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. +*/ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. +*/ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} + + +const byte MD5::PADDING[64] = { 0x80 }; +const char MD5::HEX[16] = +{ + '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f' +}; + +/* Default construct. */ +MD5::MD5() +{ + + reset(); +} + +/* Construct a MD5 object with a input buffer. */ +MD5::MD5(const void *input, size_t length) +{ + reset(); + update(input, length); +} + +/* Construct a MD5 object with a string. */ +MD5::MD5(const string &str) +{ + reset(); + update(str); +} + +/* Construct a MD5 object with a file. */ +MD5::MD5(ifstream &in) +{ + reset(); + update(in); +} + +/* Return the message-digest */ +const byte *MD5::digest() +{ + if (!_finished) + { + _finished = true; + final(); + } + return _digest; +} + +/* Reset the calculate state */ +void MD5::reset() +{ + + _finished = false; + /* reset number of bits. */ + _count[0] = _count[1] = 0; + /* Load magic initialization constants. */ + _state[0] = 0x67452301; + _state[1] = 0xefcdab89; + _state[2] = 0x98badcfe; + _state[3] = 0x10325476; +} + +/* Updating the context with a input buffer. */ +void MD5::update(const void *input, size_t length) +{ + update((const byte *)input, length); +} + +/* Updating the context with a string. */ +void MD5::update(const string &str) +{ + update((const byte *)str.c_str(), str.length()); +} + +/* Updating the context with a file. */ +void MD5::update(ifstream &in) +{ + + if (!in) + { + return; + } + + const size_t BUFFER_SIZE = 1024; + std::streamsize length; + char buffer[BUFFER_SIZE]; + while (!in.eof()) + { + in.read(buffer, BUFFER_SIZE); + length = in.gcount(); + if (length > 0) + { + update(buffer, length); + } + } + in.close(); +} + +/* MD5 block update operation. Continues an MD5 message-digest +operation, processing another message block, and updating the +context. +*/ +void MD5::update(const byte *input, size_t length) +{ + + uint32 i, index, partLen; + + _finished = false; + + /* Compute number of bytes mod 64 */ + index = (uint32)((_count[0] >> 3) & 0x3f); + + /* update number of bits */ + if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) + { + _count[1]++; + } + _count[1] += ((uint32)length >> 29); + + partLen = 64 - index; + + /* transform as many times as possible. */ + if (length >= partLen) + { + + memcpy(&_buffer[index], input, partLen); + transform(_buffer); + + for (i = partLen; i + 63 < length; i += 64) + { + transform(&input[i]); + } + index = 0; + + } + else + { + i = 0; + } + + /* Buffer remaining input */ + memcpy(&_buffer[index], &input[i], length - i); +} + +/* MD5 finalization. Ends an MD5 message-_digest operation, writing the +the message _digest and zeroizing the context. +*/ +void MD5::final() +{ + + byte bits[8]; + uint32 oldState[4]; + uint32 oldCount[2]; + uint32 index, padLen; + + /* Save current state and count. */ + memcpy(oldState, _state, 16); + memcpy(oldCount, _count, 8); + + /* Save number of bits */ + encode(_count, bits, 8); + + /* Pad out to 56 mod 64. */ + index = (uint32)((_count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + update(PADDING, padLen); + + /* Append length (before padding) */ + update(bits, 8); + + /* Store state in digest */ + encode(_state, _digest, 16); + + /* Restore current state and count. */ + memcpy(_state, oldState, 16); + memcpy(_count, oldCount, 8); +} + +/* MD5 basic transformation. Transforms _state based on block. */ +void MD5::transform(const byte block[64]) +{ + + uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16]; + + decode(block, x, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + _state[0] += a; + _state[1] += b; + _state[2] += c; + _state[3] += d; +} + +/* Encodes input (ulong) into output (byte). Assumes length is +a multiple of 4. +*/ +void MD5::encode(const uint32 *input, byte *output, size_t length) +{ + + for (size_t i = 0, j = 0; j < length; i++, j += 4) + { + output[j] = (byte)(input[i] & 0xff); + output[j + 1] = (byte)((input[i] >> 8) & 0xff); + output[j + 2] = (byte)((input[i] >> 16) & 0xff); + output[j + 3] = (byte)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (byte) into output (ulong). Assumes length is +a multiple of 4. +*/ +void MD5::decode(const byte *input, uint32 *output, size_t length) +{ + + for (size_t i = 0, j = 0; j < length; i++, j += 4) + { + output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) | + (((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24); + } +} + +/* Convert byte array to hex string. */ +string MD5::bytesToHexString(const byte *input, size_t length) +{ + string str; + str.reserve(length << 1); + for (size_t i = 0; i < length; i++) + { + int t = input[i]; + int a = t / 16; + int b = t % 16; + str.append(1, HEX[a]); + str.append(1, HEX[b]); + } + return str; +} + +/* Convert digest to string value */ +string MD5::toString() +{ + return bytesToHexString(digest(), 16); +} diff --git a/product/src/fes/protocol/yxcloud_mqtt_s/Md5/Md5.h b/product/src/fes/protocol/yxcloud_mqtt_s/Md5/Md5.h new file mode 100644 index 00000000..826a9cf1 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_s/Md5/Md5.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include + +/* Type define */ +typedef unsigned char byte; +typedef unsigned int uint32; + +using std::string; +using std::ifstream; + +/* MD5 declaration. */ +class MD5 +{ +public: + MD5(); + MD5(const void *input, size_t length); + MD5(const string &str); + MD5(ifstream &in); + void update(const void *input, size_t length); + void update(const string &str); + void update(ifstream &in); + const byte *digest(); + string toString(); + void reset(); +private: + void update(const byte *input, size_t length); + void final(); + void transform(const byte block[64]); + void encode(const uint32 *input, byte *output, size_t length); + void decode(const byte *input, uint32 *output, size_t length); + string bytesToHexString(const byte *input, size_t length); + + /* class uncopyable */ + MD5(const MD5 &); + MD5 &operator=(const MD5 &); +private: + uint32 _state[4]; /* state (ABCD) */ + uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */ + byte _buffer[64]; /* input buffer */ + byte _digest[16]; /* message digest */ + bool _finished; /* calculate finished ? */ + + static const byte PADDING[64]; /* padding for calculate */ + static const char HEX[16]; + static const size_t BUFFER_SIZE; + +}; diff --git a/product/src/fes/protocol/yxcloud_mqtt_s/Yxcloudmqtts.cpp b/product/src/fes/protocol/yxcloud_mqtt_s/Yxcloudmqtts.cpp new file mode 100644 index 00000000..22b605fe --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_s/Yxcloudmqtts.cpp @@ -0,0 +1,474 @@ +#include "Yxcloudmqtts.h" +#include "pub_utility_api/CommonConfigParse.h" + +using namespace iot_public; + +CYxcloudmqtts Yxcloudmqtts; +bool g_YxcloudmqttsIsMainFes=false; +bool g_YxcloudmqttsChanelRun=true; + +int EX_SetBaseAddr(void *address) +{ + Yxcloudmqtts.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + Yxcloudmqtts.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + Yxcloudmqtts.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + Yxcloudmqtts.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + Yxcloudmqtts.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + LOGDEBUG("yxcloud_mqtt_s EX_ExitSystem() start"); + g_YxcloudmqttsChanelRun=false;//使所有的线程退出。 + Yxcloudmqtts.ExitSystem(flag); + LOGDEBUG("yxcloud_mqtt_s EX_ExitSystem() end"); + return iotSuccess; +} +CYxcloudmqtts::CYxcloudmqtts() +{ + // 2020-02-13 thxiao ReadConfigParam()需要使用m_ptrCFesBase,所以改为SetBaseAddr()处调用 + //ReadConfigParam(); + m_ProtocolId = 0; +} + +CYxcloudmqtts::~CYxcloudmqtts() +{ + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); +} + + +int CYxcloudmqtts::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + ReadConfigParam(); + } + return iotSuccess; +} + +int CYxcloudmqtts::SetProperty(int IsMainFes) +{ + g_YxcloudmqttsIsMainFes = (IsMainFes != 0); + LOGDEBUG("CYxcloudmqtts::SetProperty g_YxcloudmqttsIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief CYxcloudmqtts::OpenChan 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CYxcloudmqtts::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if ((OpenFlag == CN_FesChanThread_Flag) || (OpenFlag == CN_FesChanAndDataThread_Flag)) + { + switch (ptrFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + case CN_FesTcpServer: + break; + default: + LOGERROR("CYxcloudmqtts EX_OpenChan() ChanNo:%d CommType=%d is not TCP SERVER/Client!", ptrFesChan->m_Param.ChanNo, ptrFesChan->m_Param.CommType); + return iotFailed; + } + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + CYxcloudmqttsDataProcThreadPtr ptrCDataProc; + ptrCDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_vecAppParam); + if (ptrCDataProc == NULL) + { + LOGERROR("CYxcloudmqtts EX_OpenChan() ChanNo:%d create CYxcloudmqttsDataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + LOGERROR("CYxcloudmqtts EX_OpenChan() ChanNo:%d create CYxcloudmqttsDataProcThreadPtr ok!", ptrFesChan->m_Param.ChanNo); + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; +} + +/** + * @brief CYxcloudmqtts::CloseChan 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CYxcloudmqtts::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("CYxcloudmqtts::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + return iotSuccess; +} + +/** + * @brief CYxcloudmqtts::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int CYxcloudmqtts::ChanTimer(int MainChanNo) +{ + boost::ignore_unused_variable_warning(MainChanNo); + + //把命令缓冲时间间隔到的命放到发送命令缓冲区 + return iotSuccess; +} + +int CYxcloudmqtts::ExitSystem(int flag) +{ + boost::ignore_unused_variable_warning(flag); + + InformTcpThreadExit(); + return iotSuccess; +} + +void CYxcloudmqtts::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + CYxcloudmqttsDataProcThreadPtr ptrTcp; + + if ((tempNum = (int)m_CDataProcQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CDataProcQueue.erase(it);//会调用CYxcloudmqttsDataProcThread::~CYxcloudmqttsDataProcThread()退出线程 + LOGDEBUG("CYxcloudmqtts::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + +/** +* @brief CYxcloudmqtts::ReadConfigParam +* 读取Yxcloudmqtts配置文件 +* @return 成功返回iotSuccess,失败返回iotFailed +*/ +int CYxcloudmqtts::ReadConfigParam() +{ + CCommonConfigParse config; + int ivalue; + std::string strvalue; + char strRtuNo[48]; + SYxcloudmqttsAppConfigParam param; + int items,i,j; + CFesChanPtr ptrChan; //CHAN数据区 + CFesRtuPtr ptrRTU; + + //memset(¶m, 0, sizeof(SYxcloudmqttsAppConfigParam)); + + if (m_ptrCFesBase == NULL) + return iotFailed; + + m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"yxcloud_mqtt_s"); + if (m_ProtocolId == -1) + { + LOGDEBUG("ReadConfigParam ProtoclID error"); + return iotFailed; + } + LOGINFO("yxcloud_mqtt_s ProtoclID=%d", m_ProtocolId); + + if (config.load("../../data/fes/", "yxcloud_mqtt_s.xml") == iotFailed) + { + LOGDEBUG("yxcloud_mqtt_s load yxcloudmqtts.xml error"); + return iotSuccess; + } + LOGDEBUG("yxcloud_mqtt_s load yxcloudmqtts.xml ok"); + + for (i = 0; i < m_ptrCFesBase->m_vectCFesChanPtr.size(); i++) + { + ptrChan = m_ptrCFesBase->m_vectCFesChanPtr[i]; + if ((ptrChan->m_Param.Used == 1) && (m_ProtocolId == ptrChan->m_Param.ProtocolId)) + { + //found RTU + for (j = 0; j < m_ptrCFesBase->m_vectCFesRtuPtr.size(); j++) + { + ptrRTU = m_ptrCFesBase->m_vectCFesRtuPtr[j]; + if (ptrRTU->m_Param.Used && (ptrRTU->m_Param.ChanNo == ptrChan->m_Param.ChanNo)) + { + memset(&strRtuNo[0], 0, sizeof(strRtuNo)); + sprintf(strRtuNo, "RTU%d", ptrRTU->m_Param.RtuNo); + //memset(¶m, 0, sizeof(param)); + param.RtuNo = ptrRTU->m_Param.RtuNo; + items = 0; + + if (config.getIntValue(strRtuNo, "startDelay", ivalue) == iotSuccess) + { + param.startDelay = ivalue; + items++; + } + else + param.startDelay = 30;//30s + + if (config.getIntValue(strRtuNo, "ymStartDelay", ivalue) == iotSuccess) + { + param.ymStartDelay = ivalue; + items++; + } + else + param.ymStartDelay = 350; //350s + + if (config.getIntValue(strRtuNo, "max_update_count", ivalue) == iotSuccess) + { + param.maxUpdateCount = ivalue; + items++; + } + else + param.maxUpdateCount = 18; //3MIN + + if (config.getIntValue(strRtuNo, "mqttDelayTime", ivalue) == iotSuccess) + { + param.mqttDelayTime = ivalue; + items++; + } + else + param.mqttDelayTime = 100; + + if (config.getIntValue(strRtuNo, "PasswordFlag", ivalue) == iotSuccess) + { + param.PasswordFlag = ivalue; + items++; + } + else + param.PasswordFlag = 0; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "ClientId", strvalue) == iotSuccess) + { + param.ClientId = strvalue; + items++; + } + else + param.ClientId = "MQTTClient"; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "UserName", strvalue) == iotSuccess) + { + param.UserName = strvalue; + items++; + } + else + param.UserName.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "Password", strvalue) == iotSuccess) + { + param.Password = strvalue; + items++; + } + else + param.Password.clear(); + + if (config.getIntValue(strRtuNo, "KeepAlive", ivalue) == iotSuccess) + { + param.KeepAlive = ivalue; + items++; + } + else + param.KeepAlive = 180; //心跳检测时间间隔 + + if (config.getIntValue(strRtuNo, "Retain", ivalue) == iotSuccess) + { + param.Retain = (bool)(ivalue & 0x01); + items++; + } + else + param.Retain = false; //默认0 + + if (config.getIntValue(strRtuNo, "QoS", ivalue) == iotSuccess) + { + param.QoS = ivalue; + items++; + } + else + param.QoS = 1; + + if (config.getIntValue(strRtuNo, "WillFlag", ivalue) == iotSuccess) + { + param.WillFlag = ivalue; + items++; + } + else + param.WillFlag = 1; + + if (config.getIntValue(strRtuNo, "WillQos", ivalue) == iotSuccess) + { + param.WillQos = ivalue; + items++; + } + else + param.WillQos = 1; + + if (config.getIntValue(strRtuNo, "sslFlag", ivalue) == iotSuccess) + { + param.sslFlag = ivalue; + items++; + } + else + param.sslFlag = 0; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "tls_version", strvalue) == iotSuccess) + { + param.tls_version = strvalue; + items++; + } + else + param.tls_version = "tlsv1.1"; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "caPath", strvalue) == iotSuccess) + { + param.caPath = strvalue; + items++; + } + else + param.caPath = "../../data/fes/"; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "caFile", strvalue) == iotSuccess) + { + param.caFile = param.caPath + strvalue; + items++; + } + else + param.caFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "certFile", strvalue) == iotSuccess) + { + param.certFile = param.caPath + strvalue; + items++; + } + else + param.certFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "keyFile", strvalue) == iotSuccess) + { + param.keyFile = param.caPath + strvalue; + items++; + } + else + param.keyFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "keyPassword", strvalue) == iotSuccess) + { + param.keyPassword = strvalue; + items++; + } + else + param.keyPassword.clear(); + + if (config.getIntValue(strRtuNo, "CycReadFileTime", ivalue) == iotSuccess) + { + param.CycReadFileTime = ivalue; + items++; + } + else + param.CycReadFileTime = 300; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "AlarmProjectType", strvalue) == iotSuccess) + { + param.AlarmProjectType = strvalue; + items++; + } + else + param.AlarmProjectType.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "AlarmTopic", strvalue) == iotSuccess) + { + param.AlarmTopic = strvalue; + items++; + } + else + param.AlarmTopic.clear(); + + if (items > 0)//对应的RTU有配置项 + { + m_vecAppParam.push_back(param); + } + } + } + } + } + return iotSuccess; +} + +/** + * @brief CYxcloudmqtts::InformTcpThreadExit + * 设置线程退出标志,通知线程退出 + * @return + */ +void CYxcloudmqtts::InformTcpThreadExit() +{ + +} diff --git a/product/src/fes/protocol/yxcloud_mqtt_s/Yxcloudmqtts.h b/product/src/fes/protocol/yxcloud_mqtt_s/Yxcloudmqtts.h new file mode 100644 index 00000000..b444b80f --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_s/Yxcloudmqtts.h @@ -0,0 +1,37 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "YxcloudmqttsDataProcThread.h" + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API CYxcloudmqtts : public CProtocolBase +{ +public: + CYxcloudmqtts(); + ~CYxcloudmqtts(); + + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + vector m_CDataProcQueue; + vector m_vecAppParam; + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + int ExitSystem(int flag); + int ReadConfigParam(); + void InformTcpThreadExit(); +private: + int m_ProtocolId; + void ClearDataProcThreadByChanNo(int ChanNo); +}; diff --git a/product/src/fes/protocol/yxcloud_mqtt_s/YxcloudmqttsDataProcThread.cpp b/product/src/fes/protocol/yxcloud_mqtt_s/YxcloudmqttsDataProcThread.cpp new file mode 100644 index 00000000..476d9c20 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_s/YxcloudmqttsDataProcThread.cpp @@ -0,0 +1,1214 @@ +#include +#include "YxcloudmqttsDataProcThread.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" +#include +#include + + +using namespace iot_public; + +extern bool g_YxcloudmqttsIsMainFes; +extern bool g_YxcloudmqttsChanelRun; +const int gYxcloudmqttsThreadTime = 10; +std::string g_KeyPassword; //私钥密码 + +static int password_callback(char* buf, int size, int rwflag, void* userdata) +{ + boost::ignore_unused_variable_warning(rwflag); + boost::ignore_unused_variable_warning(userdata); + + memcpy(buf, g_KeyPassword.data(), size); + buf[size - 1] = '\0'; + + return (int)strlen(buf); +} + +CYxcloudmqttsDataProcThread::CYxcloudmqttsDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam): + CTimerThreadBase("YxcloudmqttsDataProcThread", gYxcloudmqttsThreadTime,0,true) +{ + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + m_pSoeData = NULL; + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + + m_timerCountReset = 10; + m_timerCount = 0; + + publishTime = 0; + memset(&mqttTime, 0, sizeof(MqttPublishTime)); + mqttTime.startTime = getMonotonicMsec() / 1000; + mqttTime.CycTime = getMonotonicMsec() / 1000; + + //2020-02-24 thxiao 创建时设置ThreadRun标识。 + if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL)) + { + return; + } + m_ptrCFesChan->SetLinkStatus(CN_FesChanConnect); + m_ptrCFesChan->SetComThreadRunFlag(CN_FesRunFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + //2020-03-03 thxiao 不需要数据变化 + m_ptrCFesRtu->SetFwAiChgStop(1); + m_ptrCFesRtu->SetFwDiChgStop(1); + m_ptrCFesRtu->SetFwDDiChgStop(1); + m_ptrCFesRtu->SetFwMiChgStop(1); + m_ptrCFesRtu->SetFwAccChgStop(1); + + int found = 0; + if(vecAppParam.size()>0) + { + for (size_t i = 0; i < vecAppParam.size(); i++) + { + if(m_ptrCFesRtu->m_Param.RtuNo == vecAppParam[i].RtuNo) + { + //memset(&m_AppData,0,sizeof(SYxcloudmqttsAppData)); + + + //配置 + m_AppData.mqttDelayTime = vecAppParam[i].mqttDelayTime; + m_AppData.PasswordFlag = vecAppParam[i].PasswordFlag; + m_AppData.ClientId = vecAppParam[i].ClientId; + m_AppData.UserName = vecAppParam[i].UserName; + m_AppData.Password = vecAppParam[i].Password; + m_AppData.KeepAlive = vecAppParam[i].KeepAlive; + m_AppData.Retain = vecAppParam[i].Retain; + m_AppData.QoS = vecAppParam[i].QoS; + m_AppData.WillFlag = vecAppParam[i].WillFlag; + m_AppData.WillQos = vecAppParam[i].WillQos; + //SSL加密配置 + m_AppData.sslFlag = vecAppParam[i].sslFlag; + m_AppData.tls_version = vecAppParam[i].tls_version; + m_AppData.caPath = vecAppParam[i].caPath; + m_AppData.caFile = vecAppParam[i].caFile; + m_AppData.certFile = vecAppParam[i].certFile; + m_AppData.keyFile = vecAppParam[i].keyFile; + m_AppData.keyPassword = vecAppParam[i].keyPassword; + m_AppData.AlarmProjectType = vecAppParam[i].AlarmProjectType; + m_AppData.AlarmTopic = vecAppParam[i].AlarmTopic; + m_AppData.maxUpdateCount = vecAppParam[i].maxUpdateCount; + m_AppData.startDelay = vecAppParam[i].startDelay; + m_AppData.ymStartDelay = vecAppParam[i].ymStartDelay; + m_AppData.CycReadFileTime = vecAppParam[i].CycReadFileTime; + + found = 1; + break; + } + } + } + if(!found) + InitConfigParam();//配置文件读取失败,取默认配置 + + //读取mqtt_topic_cfg.csv文件,并更新参数 + GetTopicCfg(); + + m_AppData.mqttContFlag = false; + + //告警主题为空,则不发告警数据 + if (m_AppData.AlarmTopic.length() < 1) + { + m_ptrCFesRtu->SetFwSoeChgStop(1); + m_ptrCFesRtu->SetFwDSoeChgStop(1); + } + m_AppData.alarmList.clear(); + GetAlarmCfg(); + + //创建mqttclient对象 + mosqpp::lib_init(); + mqttClient = new mosqpp::mosquittopp(m_AppData.ClientId.data()); +} + +CYxcloudmqttsDataProcThread::~CYxcloudmqttsDataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + if(m_pSoeData != NULL) + free(m_pSoeData); + + if (m_AppData.mqttContFlag) + mqttClient->disconnect(); + + //删除MQTT对象 + if(mqttClient) + delete mqttClient; + + ClearTopicStr(); + + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + LOGDEBUG("CYxcloudmqttsDataProcThread::~CYxcloudmqttsDataProcThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); + //释放mosqpp库 + mosqpp::lib_cleanup(); +} + +/** + * @brief CYxcloudmqttsDataProcThread::beforeExecute + * + */ +int CYxcloudmqttsDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief CYxcloudmqttsDataProcThread::execute + + */ +void CYxcloudmqttsDataProcThread::execute() +{ + //读取网络事件 + if(!g_YxcloudmqttsChanelRun) //收到线程退出标志不再往下执行 + return; + + if (m_timerCount++ >= m_timerCountReset) + m_timerCount = 0;// 1sec is ready + + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + if(m_ptrCurrentChan== NULL) + return; + + //秒级判断流程 + TimerProcess(); + + //mqtt转发流程 + YxcloudmqttsProcess(); +} + +/* + @brief 执行quit函数前的处理 + */ +void CYxcloudmqttsDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetComThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetLinkStatus(CN_FesChanDisconnect); + + LOGDEBUG("CYxcloudmqttsDataProcThread::beforeQuit() "); +} + +/** + * @brief CYxcloudmqttsDataProcThread::InitConfigParam + * Yxcloudmqtts 初始化配置参数 + * @return 成功返回iotSuccess,失败返回iotFailed + */ +int CYxcloudmqttsDataProcThread::InitConfigParam() +{ + if((m_ptrCFesChan == NULL)||(m_ptrCFesRtu==NULL)) + return iotFailed; + + //memset(&m_AppData,0,sizeof(SYxcloudmqttsAppData)); + m_AppData.mqttDelayTime = 100; + m_AppData.PasswordFlag = 0; + m_AppData.ClientId = "KhMqttClient"; + m_AppData.KeepAlive = 180; + m_AppData.Retain = 0; + m_AppData.QoS = 0; + m_AppData.WillFlag = 0; + m_AppData.WillQos = 0; + + //SSL加密设置 + m_AppData.sslFlag = 0; + + m_AppData.maxUpdateCount = 18; + m_AppData.updateCount = 0; + m_AppData.startDelay = 30; + m_AppData.ymStartDelay = 350; + m_AppData.CycReadFileTime = 300; + + return iotSuccess; +} + +void CYxcloudmqttsDataProcThread::TimerProcess() +{ + if (m_timerCount == 0)//秒级判断,减少CPU负荷 + { + uint64 curmsec = getMonotonicMsec(); + + //定时更新本FES数据 + if (m_AppData.updateCount < m_AppData.maxUpdateCount) + { + if ((curmsec - m_AppData.lastUpdateTime) > CN_YxcloudmqttsStartUpateTime)//10s + { + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + m_AppData.updateCount++; + m_AppData.lastUpdateTime = curmsec; + } + } + else + { + if ((curmsec - m_AppData.lastUpdateTime) > CN_YxcloudmqttsNormalUpateTime)//60s + { + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + m_AppData.lastUpdateTime = curmsec; + } + } + //定时读取遥控命令响应缓冲区,及时清除队列释放空间,不对遥控成败作处理 + if (m_ptrCFesRtu->GetFwDoRespCmdNum() > 0) + { + SFesFwDoRespCmd retCmd; + m_ptrCFesRtu->ReadFwDoRespCmd(1, &retCmd); + } + + if (m_ptrCFesRtu->GetFwAoRespCmdNum() > 0) + { + SFesFwAoRespCmd retCmd; + m_ptrCFesRtu->ReadFwAoRespCmd(1, &retCmd); + } + + //启动主线程判断逻辑 + MainThread(); + } +} + +void CYxcloudmqttsDataProcThread::YxcloudmqttsProcess() +{ + //延迟启动MQTT上抛流程 + if (!mqttTime.mqttStartFlag) + return; + + //延时时间未到,不发送数据 + if ((getMonotonicMsec() - publishTime) < (m_AppData.mqttDelayTime/10)) + return; + + //上传SOE + if (m_AppData.AlarmTopic.length() > 0) + SendSoeDataFrame(); + + int i = 0; + for (i = mqttTime.topicIndex; i < m_AppData.sendTopicNum; i++) + { + if (m_AppData.sendTopicStr[i].TopicSendFlag) + { + FormJsonData(i); + SendTopicData(i); + m_AppData.sendTopicStr[i].TopicSendFlag = false; + break; + } + } + + //处理MQTT网络事件 + int ret = mqttClient->loop(); + char slog[256]; + memset(slog, 0, 256); + if (ret != MOSQ_ERR_SUCCESS) + { + m_AppData.mqttContFlag = false; + sprintf_s(slog,sizeof(slog),"MQTT %s:%d 连接异常,需要重连!错误代号[%d]", m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo, ret); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("YxcloudmqttsDataProcThread.cpp ChanNo:%d MQTT %s:%d连接异常,需要重连错误代号[%d]!", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo,ret); + } + + mqttTime.topicIndex = i; + if (mqttTime.topicIndex >= m_AppData.sendTopicNum) + {//一轮topic发送结束 + mqttTime.topicIndex = 0; + mqttTime.mqttSendEndFlag = true; + } +} + +//通过遥信远动号找告警点 +int CYxcloudmqttsDataProcThread::GetAlarmNo(const int RemoteNo) +{ + for (int i = 0; i < m_AppData.alarmList.size(); i++) + { + if (m_AppData.alarmList[i].yxNo == RemoteNo) + return i; + } + return -1; +} + +//上传SOE +void CYxcloudmqttsDataProcThread::SendSoeDataFrame() +{ + int i, DiValue; + LOCALTIME SysLocalTime; + SFesFwSoeEvent *pSoeEvent = NULL; + int count, retNum; + std::string jsonStr; + std::string DPTagName; + std::string pName; + std::string devId; + + count = m_ptrCFesRtu->GetFwSOEEventNum(); + if (count == 0) + return; + + //最多一次传100条事件 + if (count > 100) + count = 100; + + if (m_pSoeData == NULL) + m_pSoeData = (SFesFwSoeEvent*)malloc(count * sizeof(SFesFwSoeEvent)); + else + m_pSoeData = (SFesFwSoeEvent*)realloc(m_pSoeData, count * sizeof(SFesFwSoeEvent)); + + retNum = m_ptrCFesRtu->ReadFwSOEEvent(count, m_pSoeData); + jsonStr = "{\"DATATYPE\":\"ALARM_INFO\","; + if(m_AppData.AlarmProjectType.length() > 0) + jsonStr += "\"PROJECTTYPE\":\"" + m_AppData.AlarmProjectType + "\","; + jsonStr += "\"DATA\":["; + count = 0; + char vstr[50]; + int alarmNo = -1; + for (i = 0; i < retNum; i++) + { + pSoeEvent = m_pSoeData + i; + if (pSoeEvent->RemoteNo > m_ptrCFesRtu->m_MaxFwDiPoints) + continue; + + //取出告警列表索引 + alarmNo = GetAlarmNo(pSoeEvent->RemoteNo); + if(alarmNo == -1) + continue; + + DiValue = pSoeEvent->Value & 0x01; + SysLocalTime = convertUTCMsecToLocalTime(pSoeEvent->time); //把Soe时间戳转成本地时标 + + //第一个对象前不需要逗号 + if (count != 0) + jsonStr += ","; + jsonStr += "{\"deviceId\":" + to_string(m_AppData.alarmList[alarmNo].devId) + ",\"alarmId\":" + to_string(m_AppData.alarmList[alarmNo].alarmId) + ","; + //加上时标 + memset(vstr, 0, 50); + sprintf_s(vstr, sizeof(vstr),"\"generationDataTime\":\"%04d-%02d-%02d %02d:%02d:%02d\",", SysLocalTime.wYear, SysLocalTime.wMonth, + SysLocalTime.wDay, SysLocalTime.wHour, SysLocalTime.wMinute, SysLocalTime.wSecond); + jsonStr += vstr; + jsonStr += "\"message\":\"" + m_AppData.alarmList[alarmNo].alarmCode + "\","; + if(DiValue) + jsonStr += "\"status\":true}"; + else + jsonStr += "\"status\":false}"; + count++; + } + jsonStr += "]}"; + if (count > 0) + { + //将上抛信息传给通道报文显示 + char slog[256]; + memset(slog, 0, 256); + sprintf_s(slog, sizeof(slog),"MQTT Publish:%s, AlarmNum:%d", m_AppData.AlarmTopic.data(), count); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + //上抛数据 + if (MqttPublish(m_AppData.AlarmTopic, jsonStr) == false) + MqttPublish(m_AppData.AlarmTopic, jsonStr);//上抛失败,重新上抛一次 + SleepmSec(m_AppData.mqttDelayTime); + } +} + +void CYxcloudmqttsDataProcThread::MqttConnect() +{ + int ret = 0; + char slog[256]; + memset(slog, 0, 256); + //已结连接上则不需重连 + if (m_AppData.mqttContFlag) + return; + + //不判断服务器地址 + mqttClient->tls_insecure_set(1); + + //设置SSL加密 + if (m_AppData.sslFlag == 2) //双向加密 + { + //2022-9-21 lj tls_opt_set需要设置为0,即不验证服务器证书,山东海辰服务器的证书有问题,认证不过 + mqttClient->tls_opts_set(0, m_AppData.tls_version.data(), NULL); + if (m_AppData.keyPassword.length() < 1) + mqttClient->tls_set(m_AppData.caFile.data(), m_AppData.caPath.data(), m_AppData.certFile.data(), m_AppData.keyFile.data()); + else + { + //更新私钥的密码 + g_KeyPassword = m_AppData.keyPassword; + mqttClient->tls_set(m_AppData.caFile.data(), m_AppData.caPath.data(), m_AppData.certFile.data(), m_AppData.keyFile.data(), password_callback); + } + LOGDEBUG("YxcloudmqttsDataProcThread.cpp ChanNo:%d MqttConnect caFile=%s keyPassword=%d!", m_ptrCFesChan->m_Param.ChanNo, m_AppData.caFile.data(), m_AppData.keyPassword.length()); + } + else if (m_AppData.sslFlag == 1) //单向加密 + { + mqttClient->tls_opts_set(0, m_AppData.tls_version.data(), NULL); + mqttClient->tls_set(m_AppData.caFile.data()); + } + + if (m_AppData.QoS) + mqttClient->message_retry_set(3); + + //设置用户名和密码 + if (m_AppData.PasswordFlag) + mqttClient->username_pw_set(m_AppData.UserName.data(), m_AppData.Password.data()); + + //连接Broker服务器 + //m_ptrCFesChan->m_Param.NetRoute[0].NetDesc localhost + char ServerIp[CN_FesMaxNetDescSize]; //通道IP + memset(ServerIp, 0, CN_FesMaxNetDescSize); + strcpy(ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc); + ret = mqttClient->connect(ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo, m_AppData.KeepAlive);//IP + if (ret != MOSQ_ERR_SUCCESS) + { + m_AppData.mqttContFlag = false; + sprintf_s(slog, sizeof(slog),"MQTT %s:%d 连接失败!", ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("YxcloudmqttsDataProcThread.cpp ChanNo:%d MQTT %s:%d连接失败!", m_ptrCFesChan->m_Param.ChanNo, ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); + return; + } + + m_AppData.mqttContFlag = true; + sprintf_s(slog, sizeof(slog),"MQTT %s:%d 连接成功!", ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog,CN_SFesSimComFrameTypeSend); + LOGDEBUG("YxcloudmqttsDataProcThread.cpp ChanNo:%d MQTT %s:%d连接成功!", m_ptrCFesChan->m_Param.ChanNo, ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); +} + +bool CYxcloudmqttsDataProcThread::MqttPublish(std::string mqttTopic, std::string mqttPayload) +{ + //连接MQTT服务器 + MqttConnect(); + if (!m_AppData.mqttContFlag) + return false; + + //主题和内容为空 + if ((mqttTopic.length() < 1) || (mqttPayload.length() < 1)) + return false; + + char slog[256]; + memset(slog, 0, 256); + + //发布主题数据 + int rc = mqttClient->publish(NULL, mqttTopic.data(), (int)mqttPayload.length(), mqttPayload.data(), m_AppData.QoS, m_AppData.Retain); + if (rc != MOSQ_ERR_SUCCESS) + { + sprintf_s(slog, sizeof(slog),"MQTT 上抛 %s 失败,断开连接!", mqttTopic.data()); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("YxcloudmqttsDataProcThread.cpp ChanNo:%d %s:%d %s", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo,slog); + mqttClient->disconnect(); + m_AppData.mqttContFlag = false; + return false; + } + + if (m_AppData.WillFlag > 0) + { + mqttClient->will_set(mqttTopic.data(), (int)mqttPayload.length(), mqttPayload.data(), m_AppData.WillQos, m_AppData.Retain); + } + //记下发送时间 单位毫秒 + publishTime = getMonotonicMsec(); + SleepmSec(m_AppData.mqttDelayTime); + return true; +} + +//获取文件MD5 +std::string CYxcloudmqttsDataProcThread::GetFileMd5(const std::string &file) +{ + ifstream in(file.c_str(), ios::binary); + if (!in) + return ""; + + MD5 md5; + std::streamsize length; + char buffer[1024]; + while (!in.eof()) + { + in.read(buffer, 1024); + length = in.gcount(); + if (length > 0) + md5.update(buffer, length); + } + in.close(); + return md5.toString(); +} + +//获取字符串MD5 +std::string CYxcloudmqttsDataProcThread::GetStringMd5(const std::string &src_str) +{ + if (src_str.size() < 1) + return ""; + + MD5 md5; + int rsaNum = ((int)src_str.size() + 1023) / 1024; + for (int i = 0; i 0) + md5.update(tmps.c_str(), tmps.size()); + } + return md5.toString(); +} + +//清空topic列表 +void CYxcloudmqttsDataProcThread::ClearTopicStr() +{ + for (int i = 0; i < MAX_TOPIC_NUM; i++) + { + m_AppData.sendTopicStr[i].jsonTimeList.clear(); + m_AppData.sendTopicStr[i].jsonValueList.clear(); + if (m_AppData.sendTopicStr[i].rootJson != NULL) + { + cJSON_Delete(m_AppData.sendTopicStr[i].rootJson); + m_AppData.sendTopicStr[i].rootJson = NULL; + } + } + //memset(m_AppData.sendTopicStr, 0, sizeof(SEND_TOPIC_STR)*MAX_TOPIC_NUM); +} + +void CYxcloudmqttsDataProcThread::GetAlarmCfg() +{ + char filename[100]; + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_alarm_cfg%d.csv", m_ptrCFesRtu->m_Param.RtuNo); + char line[1024]; + FILE *fpin; + if ((fpin = fopen(filename, "r")) == NULL) + { + LOGDEBUG("yxcloud_mqtt_s load mqtt_alarm_cfg.csv error"); + return; + } + LOGDEBUG("yxcloud_mqtt_s load mqtt_alarm_cfg.csv ok"); + + if (fgets(line, 1024, fpin) == NULL) + { + fclose(fpin); + return; + } + + //先清空原来的list + m_AppData.alarmList.clear(); + while (fgets(line, 1024, fpin) != NULL) + { + char *token; + token = strtok(line, ","); + int j = 0; + Alarm_Value_Str alarmValStr; + //memset(&alarmValStr,0,sizeof(Alarm_Value_Str)); + while (token != NULL) + { + if (0 == j)//设备ID + { + if (strlen(token) <= 0) + break; + alarmValStr.devId = atoi(token); + } + else if (1 == j)//告警ID + { + if (strlen(token) <= 0) + break; + alarmValStr.alarmId = atoi(token); + } + else if (2 == j)//遥信转发远动号 + { + if (strlen(token) <= 0) + break; + alarmValStr.yxNo = atoi(token); + } + else if (3 == j)//告警描述 + { + if (strlen(token) <= 0) + break; + alarmValStr.alarmCode = GbkToUtf8(token); + m_AppData.alarmList.push_back(alarmValStr); + } + else + break; + token = strtok(NULL, ","); + j++; + } + } + fclose(fpin); +} + +void CYxcloudmqttsDataProcThread::GetTopicCfg( ) +{ + char filename[100]; + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_topic_cfg%d.csv", m_ptrCFesRtu->m_Param.RtuNo); + char line[1024]; + FILE *fpin; + if ((fpin = fopen(filename, "r")) == NULL) + { + LOGDEBUG("yxcloud_mqtt_s load mqttconfig.csv error"); + return; + } + LOGDEBUG("yxcloud_mqtt_s load mqttconfig.csv ok"); + + if (fgets(line, 1024, fpin) == NULL) + { + fclose(fpin); + return; + } + + //先清空原来的list + ClearTopicStr(); + m_AppData.sendTopicNum = 0; + int topicNum = 0; + while (fgets(line, 1024, fpin) != NULL) + { + char *token; + token = strtok(line, ","); + int j = 0; + while (token != NULL) + { + if (0 == j)//主题 + { + if (strlen(token) <= 0) + break; + m_AppData.sendTopicStr[topicNum].topic = token; + } + else if (1 == j)//sn名 + { + if (strlen(token) <= 0) + break; + m_AppData.sendTopicStr[topicNum].snName = token; + } + else if(2 == j)//sn下设备名合集 + { + if (strlen(token) <= 0) + break; + m_AppData.sendTopicStr[topicNum].snDeviceName = token; + } + else if (3 == j)//上传周期 + { + if (strlen(token) <= 0) + break; + m_AppData.sendTopicStr[topicNum].sendTime = atoi(token); + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_topic_cfg%s.csv", m_AppData.sendTopicStr[topicNum].jsonFileName.c_str()); + m_AppData.sendTopicStr[topicNum].fileMd5 = GetFileMd5(filename); + topicNum ++; + } + else + break; + token = strtok(NULL, ","); + j++; + } + + //超过上限的不处理 + if (topicNum >= MAX_TOPIC_NUM) + { + topicNum = MAX_TOPIC_NUM; + break; + } + } + fclose(fpin); + m_AppData.sendTopicNum = topicNum; + + //读取Topic关联的JSON文件 + ReadTopic(); +} + +void CYxcloudmqttsDataProcThread::ReadTopic() +{ + std::string jsonStr; + char filename[100]; + for (int i = 0; i < m_AppData.sendTopicNum; i++) + { + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/%s", m_AppData.sendTopicStr[i].jsonFileName.c_str()); + + m_AppData.sendTopicStr[i].JsonUpdataFlag = true; + m_AppData.sendTopicStr[i].TopicSendFlag = true; + } +} + +bool CYxcloudmqttsDataProcThread::ReadJson(const char *fileName, std::string &outStr) +{ + char slog[256]; + memset(slog, 0, 256); + ifstream ifile(fileName); + if (!ifile.is_open()) + { + //sprintf_s(slog, "%s打开失败!请检查文件是否存在!", fileName); + sprintf_s(slog, sizeof(slog),"%s打开失败!请检查文件是否存在!", fileName); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + return false; + } + ostringstream buf; + char ch; + while (buf && ifile.get(ch)) + { + if ((ch != '\n') && (ch != '\t') && (ch != '\0')) + buf.put(ch); + } + outStr = buf.str(); + ifile.close(); + + int strLen = (int)outStr.size(); + if (strLen < 1) + return false; + + return true; +} + +//分割字符串 +int CYxcloudmqttsDataProcThread::StringSplit(std::vector &dst, const std::string &src, const std::string separator) +{ + if (src.empty() || separator.empty()) + return 0; + + int nCount = 0; + std::string temp; + size_t pos = 0, offset = 0; + + //分割第1~n-1个 + while ((pos = src.find_first_of(separator, offset)) != std::string::npos) + { + temp = src.substr(offset, pos - offset); + if (temp.length() > 0) + { + dst.push_back(temp); + nCount++; + } + offset = pos + 1; + } + + //分割第n个 + temp = src.substr(offset, src.length() - offset); + if (temp.length() > 0) + { + dst.push_back(temp); + nCount++; + } + return nCount; +} + +void CYxcloudmqttsDataProcThread::FormJsonData(const int topicNo) +{ + m_AppData.sendTopicStr[topicNo].rootJson = cJSON_CreateObject(); + cJSON_AddStringToObject(m_AppData.sendTopicStr[topicNo].rootJson, "type", "real"); + cJSON_AddStringToObject(m_AppData.sendTopicStr[topicNo].rootJson, "sn", m_AppData.sendTopicStr[topicNo].snName.c_str()); +// cJSON_AddStringToObject(m_AppData.sendTopicStr[topicNo].rootJson, "time", "timeval"); //UpdataJsonTime(topicNo)中更新 + UpdataJsonTime(topicNo); + UpdataJsonValue(topicNo); + + + +} + +void CYxcloudmqttsDataProcThread::SendTopicData(const int topicNo) +{ + if (m_AppData.sendTopicStr[topicNo].rootJson != NULL) + { + SendJsonData(topicNo, m_AppData.sendTopicStr[topicNo].rootJson); + } +} + + +bool CYxcloudmqttsDataProcThread::UpdataJsonValue(const int topicNo) +{ +// if (m_AppData.sendTopicStr[topicNo].jsonValueList.size() < 1) +// return false; + double fvalue; + unsigned char yxbit; + SFesFwAi *pFwAi; + SFesFwAcc *pFwAcc; + SFesFwDi *pFwDi; + SFesFwMi *pFwMi; + + cJSON* data = cJSON_CreateObject(); + + std::stringstream ss(m_AppData.sendTopicStr[topicNo].snDeviceName); + std::string token; + std::vector tokens; + while (std::getline(ss, token, ' ')) + { + tokens.push_back(token); + } + cJSON** devicearray = new cJSON*[tokens.size()]; + //cJSON* devicearray[tokens.size()]; + for(int i = 0;im_MaxFwAiPoints; aiPoint++) + { + pFwAi = m_ptrCFesRtu->m_pFwAi + aiPoint; + std::string tagnames = pFwAi->DPTagName; + std::stringstream ssTagneme(tagnames); + + std::vector temps1;//1次分割,g1.PCS_PCS.IA到g1,PCS_PCS,IA + std::vector temps2;//2次分割,PCS_PCS到PCS + std::string temp1; + while (std::getline(ssTagneme, temp1, '.')) + { + temps1.push_back(temp1); + } + std::stringstream sTagneme(temps1[1]); + std::string temp2; + while (std::getline(sTagneme, temp2, '_')) + { + temps2.push_back(temp2); + } + bool aivalNormalFlag = 1; + if(pFwAi->Status != 1) + { + aivalNormalFlag = 0; + } + fvalue = pFwAi->Value; + std::ostringstream oss;//保留3位小数 + oss << std::fixed << std::setprecision(3) << fvalue; + std::string result = oss.str(); + size_t found = result.find_last_not_of('0');//去掉多余的0和点 + if (found != std::string::npos) + { + if (result[found] == '.') + result.erase(found); + else + result.erase(found + 1); + } + for(int i = 0;im_MaxFwDiPoints; diPoint++) + { + pFwDi = m_ptrCFesRtu->m_pFwDi + diPoint; + std::string tagnames = pFwDi->DPTagName; + std::stringstream ssTagneme(tagnames); + + std::vector temps1;//1次分割,g1.PCS_PCS.IA到g1,PCS_PCS,IA + std::vector temps2;//2次分割,PCS_PCS到PCS + std::string temp1; + while (std::getline(ssTagneme, temp1, '.')) + { + temps1.push_back(temp1); + } + std::stringstream sTagneme(temps1[1]); + std::string temp2; + while (std::getline(sTagneme, temp2, '_')) + { + temps2.push_back(temp2); + } + bool divalNormalFlag = 1; + if(pFwDi->Status != 1) + { + divalNormalFlag = 0; + } + yxbit = pFwDi->Value & 0x01; + for(int i = 0;im_MaxFwAccPoints; accPoint++) + { + pFwAcc = m_ptrCFesRtu->m_pFwAcc + accPoint; + std::string tagnames = pFwAcc->DPTagName; + std::stringstream ssTagneme(tagnames); + + std::vector temps1;//1次分割,g1.PCS_PCS.IA到g1,PCS_PCS,IA + std::vector temps2;//2次分割,PCS_PCS到PCS + std::string temp1; + while (std::getline(ssTagneme, temp1, '.')) + { + temps1.push_back(temp1); + } + std::stringstream sTagneme(temps1[1]); + std::string temp2; + while (std::getline(sTagneme, temp2, '_')) + { + temps2.push_back(temp2); + } + // 判断点值是否正常 + bool accvalNormalFlag = 1; + if(pFwAcc->Status != 1) + { + accvalNormalFlag = 0; + } + fvalue = pFwAcc->Value; + std::ostringstream oss;//保留3位小数 + oss << std::fixed << std::setprecision(3) << fvalue; + std::string result = oss.str(); + size_t found = result.find_last_not_of('0');//去掉多余的0和点 + if (found != std::string::npos) + { + if (result[found] == '.') + result.erase(found); + else + result.erase(found + 1); + } + for(int i = 0;im_MaxFwMiPoints; miPoint++) + { + pFwMi = m_ptrCFesRtu->m_pFwMi + miPoint; + std::string tagnames = pFwMi->DPTagName; + std::stringstream ssTagneme(tagnames); + + std::vector temps1;//1次分割,g1.PCS_PCS.IA到g1,PCS_PCS,IA + std::vector temps2;//2次分割,PCS_PCS到PCS + std::string temp1; + while (std::getline(ssTagneme, temp1, '.')) + { + temps1.push_back(temp1); + } + std::stringstream sTagneme(temps1[1]); + std::string temp2; + while (std::getline(sTagneme, temp2, '_')) + { + temps2.push_back(temp2); + } + bool mivalNormalFlag = 1; + if(pFwMi->Status != 1) + { + mivalNormalFlag = 0; + } + fvalue = pFwMi->Value; + std::ostringstream oss;//保留3位小数 + oss << std::fixed << std::setprecision(3) << fvalue; + std::string result = oss.str(); + size_t found = result.find_last_not_of('0');//去掉多余的0和点 + if (found != std::string::npos) + { + if (result[found] == '.') + result.erase(found); + else + result.erase(found + 1); + } + for(int i = 0;itm_year+1900, st->tm_mon+1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec); + cJSON_AddStringToObject(m_AppData.sendTopicStr[topicNo].rootJson, "time", time); + return true; +} + +void CYxcloudmqttsDataProcThread::MainThread() +{ + char fileName[100]; + std::string md5Str; + //系统启动后的运行的秒数 + int64 cursec = getMonotonicMsec() / 1000; + + if (m_AppData.startDelay > 0)//2021-05-06 thxiao 增加延时起动 + { + if ((cursec - mqttTime.startTime) < m_AppData.startDelay) + mqttTime.mqttStartFlag = false; + else + mqttTime.mqttStartFlag = true; + } + else + mqttTime.mqttStartFlag = true; + + if (m_AppData.ymStartDelay > 0) + { + if ((cursec - mqttTime.startTime) < m_AppData.ymStartDelay) + mqttTime.ymStartFlag = false; + else + mqttTime.ymStartFlag = true; + } + else + mqttTime.ymStartFlag = true; + + //周期检查文件是否修改 + if ((cursec - mqttTime.CycTime) > m_AppData.CycReadFileTime) + { + mqttTime.CycTime = cursec; + + //配置参数修改后,需要在线更新 + memset(fileName, 0, 100); + sprintf(fileName, "../../data/fes/mqtt_topic_cfg%d.csv", m_ptrCFesRtu->m_Param.RtuNo); + md5Str = GetFileMd5(fileName); + if (md5Str != m_AppData.TopicCfgMd5) + { + m_AppData.TopicCfgMd5 = md5Str; + //读取mqtt_topic_cfg.csv文件,并更新参数 + GetTopicCfg(); + } + } + //检查各个Topic的发送周期是否到了 + for (int i = 0; i < m_AppData.sendTopicNum; i++) + { + if (m_AppData.sendTopicStr[i].sendTime > 0) + { + //上传周期到,置上发送标志 + if (((cursec - m_AppData.sendTopicStr[i].TopicSendTime) >= m_AppData.sendTopicStr[i].sendTime) + && (m_AppData.sendTopicStr[i].rootJson != NULL)) + { + m_AppData.sendTopicStr[i].TopicSendTime = cursec; + m_AppData.sendTopicStr[i].TopicSendFlag = true; + } + } + } + + //一轮上抛完毕,关闭连接(不关闭连接) + if (mqttTime.mqttSendEndFlag && m_AppData.mqttContFlag) + { + char slog[256]; + memset(slog, 0, 256); + mqttTime.mqttSendEndFlag = false; + sprintf_s(slog, sizeof(slog),"MQTT 一轮上抛完毕!"); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("YxcloudmqttsDataProcThread.cpp ChanNo:%d %s:%d %s", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo, slog); + } +} + +void CYxcloudmqttsDataProcThread::SendJsonData(const int topicNo,cJSON *rootJson) +{ + std::string jsonStr; + int i, j; + bool sendFlag = false; + //将JSON打印成字符串,此处会申请内存,使用完毕注意释放 + char* pStr = NULL; + pStr = cJSON_Print(rootJson); + if (pStr == NULL) + return; + + //去掉JSON中的TAB缩进符和换行符 + for (i = j = 0; im_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + +} + +//GBK转化为UTF8格式 +std::string CYxcloudmqttsDataProcThread::GbkToUtf8(std::string src_str) +{ + return boost::locale::conv::to_utf(src_str,std::string("gb2312")); +} + +// UTF-8转为GBK2312 +std::string CYxcloudmqttsDataProcThread::Utf8ToGbk(std::string src_str) +{ + return boost::locale::conv::from_utf(src_str,std::string("gb2312")); +} diff --git a/product/src/fes/protocol/yxcloud_mqtt_s/YxcloudmqttsDataProcThread.h b/product/src/fes/protocol/yxcloud_mqtt_s/YxcloudmqttsDataProcThread.h new file mode 100644 index 00000000..7b319a35 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_s/YxcloudmqttsDataProcThread.h @@ -0,0 +1,226 @@ +#pragma once +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "mosquitto.h" +#include "mosquittopp.h" +#include "cJSON.h" +#include "Md5/Md5.h" +using namespace iot_public; + +//本FES数据跟新间隔 +const int CN_YxcloudmqttsStartUpateTime = 10000;//10s +const int CN_YxcloudmqttsNormalUpateTime = 60000;//60s + +#define MAX_TOPIC_NUM 1000 + +typedef struct +{ + int devId; //设备ID + int alarmId; //告警ID + int yxNo; //遥信转发远动号 + std::string alarmCode; //告警描述 +}Alarm_Value_Str; + +typedef struct +{ + int pNo; //点号 + int pType; //点类型 1-YC 2-YX 3-YM 4-混合 + std::string DataType; //数据类型 + cJSON* item = nullptr; //节点指针 +}Json_Value_Str; + +typedef struct +{ + cJSON* item = nullptr; //节点指针 +}Json_Time_Str; + + +typedef std::vector Json_Value_List; +typedef std::vector Json_Time_List; +typedef std::vector Alarm_Value_List; + +typedef struct +{ + cJSON *rootJson = nullptr; //cJson指针,保存解析后的JSON文件内容 + int64 TopicSendTime; //主题发送时间,用于判断是否需要发送 + bool JsonUpdataFlag; //JSON文件更新标志 + bool TopicSendFlag; //发送标志 + + int sendTime; //上传周期,单位秒,0表示启动上传一次,后面变化上传,大于1的值表示间隔多少秒上传 + std::string topic; //topic + std::string jsonFileName; //JSON文件名 + std::string snName; //柜名 + std::string snDeviceName; //设备名 + std::string fileMd5; //文件MD5,用于判断文件内容是否改变 + + //值 + Json_Value_List jsonValueList; + //时标 + Json_Time_List jsonTimeList; +}SEND_TOPIC_STR; + +typedef struct{ + int RtuNo; + int mqttDelayTime; //每个主题上抛延时,单位毫秒 + int CycReadFileTime; //周期检查文件的时间,单位秒 + + int PasswordFlag; //是否启用密码 0不启用 1启用 默认0 + std::string ClientId; //客户端ID + std::string UserName; //用户名 + std::string Password; //密码 + + int KeepAlive; //心跳检测时间间隔 + bool Retain; //MQTT服务器是否保持消息 默认0 + int QoS; //服务质量 默认1 + int WillFlag; //遗愿消息标志 默认1 + int WillQos; //遗愿消息服务质量 默认1 + + //SSL加密配置参数 + int sslFlag; //SSL加密标志 0不加密 1单向加密 2双向加密 + std::string tls_version; //加密协议版本 + std::string caPath; //加密文件路径 + std::string caFile; //CA文件名 + std::string certFile; //证书文件名 + std::string keyFile; //私钥文件名 + std::string keyPassword; //私钥密码 + + std::string AlarmProjectType; //告警数据项目类型 + std::string AlarmTopic; //告警数据主题 + + int maxUpdateCount; //系统启动前,本FES数据每10S跟新一次全数据,直到该值到到达最大值,变为60S跟新全数据。 + int startDelay; //系统启动延时,单位秒 + int ymStartDelay; //遥脉启动延时,单位秒 +}SYxcloudmqttsAppConfigParam; + +//Yxcloudmqtts 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct{ + //配置参数 + int RtuNo; + int64 startDelay; + int64 ymStartDelay; //遥脉启动延时,单位秒 + int CycReadFileTime; //周期检查文件的时间,单位秒 + int maxUpdateCount; + int updateCount; //系统启动前,本FES数据没10S跟新一次全数据,直到该值到到达最大值,变为60S跟新全数据。 + + uint64 updateTime; + uint64 lastUpdateTime; + bool mqttContFlag; + + int mqttDelayTime; //每个主题上抛延时,单位毫秒 + int PasswordFlag; //是否启用密码 0不启用 1启用 默认0 + std::string ClientId; //客户端ID + std::string UserName; //用户名 + std::string Password; //密码 + std::string AlarmProjectType; //告警数据项目类型 + std::string AlarmTopic; //告警数据主题 + + int KeepAlive; //心跳检测时间间隔 + bool Retain; //MQTT服务器是否保持消息 默认0 + int QoS; //品质 默认1 + int WillFlag; //遗愿消息标志 默认1 + int WillQos; //遗愿消息品质 默认1 + + //SSL加密配置参数 + int sslFlag; //SSL加密标志 0不加密 1单向加密 2双向加密 + std::string tls_version; //加密协议版本 + std::string caPath; //文件路径 + std::string caFile; //CA文件名 + std::string certFile; //证书文件名 + std::string keyFile; //私钥文件名 + std::string keyPassword; //私钥密码 + + //mqtt_topic_cfg文件MD5 + std::string TopicCfgMd5; + + + //主题列表 + SEND_TOPIC_STR sendTopicStr[MAX_TOPIC_NUM]; + int sendTopicNum; + + //告警列表 + Alarm_Value_List alarmList; +}SYxcloudmqttsAppData; + +typedef struct { + int64 startTime; //系统启动时间 + int64 CycTime; //周期检查文件时间 + int topicIndex; //已上抛主题索引 + bool mqttStartFlag; + bool ymStartFlag; //遥脉启动转发标志 + bool mqttSendEndFlag; //Mqtt发送结束标志 +}MqttPublishTime; + +class CYxcloudmqttsDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + CYxcloudmqttsDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam); + virtual ~CYxcloudmqttsDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + CFesBase* m_ptrCFesBase; + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,Yxcloudmqtts tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SYxcloudmqttsAppData m_AppData; //内部应用数据结构 + SFesFwSoeEvent *m_pSoeData; + + MqttPublishTime mqttTime; //MQTT上抛时间管理 + mosqpp::mosquittopp *mqttClient; //MQTT句柄 +private: + int m_timerCount; + int m_timerCountReset; + + int InitConfigParam(); + + void TimerProcess(); + void YxcloudmqttsProcess(); + + void SendSoeDataFrame(); + int64 publishTime; + + void MqttConnect(); + bool MqttPublish(std::string mqttTopic, std::string mqttPayload); + void GetTopicCfg(); + void ReadTopic(); + //获取MD5 + std::string GetFileMd5(const std::string &file); + std::string GetStringMd5(const std::string &src_str); + + //分割字符串 + int StringSplit(std::vector &dst, const std::string &src, const std::string separator); + + //解析JSON + bool ReadJson(const char *fileName, std::string &outStr); + void AnalyzeJson(cJSON *root, Json_Value_List &jsonValList, Json_Time_List &jsonTimeList); + bool UpdataJsonValue(const int topicNo); + bool UpdataJsonTime(const int topicNo); + + void FormJsonData(const int topicNo); + + void SendTopicData(const int topicNo); + void SendJsonData(const int topicNo, cJSON *rootJson); + + //主线程 + void MainThread(); + void ClearTopicStr(); + + //获取告警配置 + void GetAlarmCfg(); + int GetAlarmNo(const int RemoteNo); + + std::string GbkToUtf8(std::string src_str); + std::string Utf8ToGbk(std::string src_str); +}; + +typedef boost::shared_ptr CYxcloudmqttsDataProcThreadPtr; diff --git a/product/src/fes/protocol/yxcloud_mqtt_s/cJSON.c b/product/src/fes/protocol/yxcloud_mqtt_s/cJSON.c new file mode 100644 index 00000000..d6e210d8 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_s/cJSON.c @@ -0,0 +1,3100 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +/* disable warnings about old C89 functions in MSVC */ +#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +#define _CRT_SECURE_NO_DEPRECATE +#endif + +#ifdef __GNUC__ +#pragma GCC visibility push(default) +#endif +#if defined(_MSC_VER) +#pragma warning (push) +/* disable warning about single line comments in system headers */ +#pragma warning (disable : 4001) +#endif +#include +#include +#include +#include +#include +#include +#include + +#ifdef ENABLE_LOCALES +#include +#endif + +#if defined(_MSC_VER) +#pragma warning (pop) +#endif +#ifdef __GNUC__ +#pragma GCC visibility pop +#endif + +#include "cJSON.h" + +/* define our own boolean type */ +#ifdef true +#undef true +#endif +#define true ((cJSON_bool)1) + +#ifdef false +#undef false +#endif +#define false ((cJSON_bool)0) + +/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */ +#ifndef isinf +#define isinf(d) (isnan((d - d)) && !isnan(d)) +#endif +#ifndef isnan +#define isnan(d) (d != d) +#endif + +#ifndef _HUGE_ENUF + #define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow +#endif + +#define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) +#ifndef NAN +#define NAN ((float)(INFINITY * 0.0F))//sqrt(-1.0f)//0.0/0.0 +#endif + +typedef struct { + const unsigned char *json; + size_t position; +} error; +static error global_error = { NULL, 0 }; + +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) +{ + return (const char*) (global_error.json + global_error.position); +} + +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) +{ + if (!cJSON_IsString(item)) + { + return NULL; + } + + return item->valuestring; +} + +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) +{ + if (!cJSON_IsNumber(item)) + { + return (double) NAN; + } + + return item->valuedouble; +} + +/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ +#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 13) + #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. +#endif + +CJSON_PUBLIC(const char*) cJSON_Version(void) +{ + static char version[15]; + sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); + + return version; +} + +/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ +static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2) +{ + if ((string1 == NULL) || (string2 == NULL)) + { + return 1; + } + + if (string1 == string2) + { + return 0; + } + + for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) + { + if (*string1 == '\0') + { + return 0; + } + } + + return tolower(*string1) - tolower(*string2); +} + +typedef struct internal_hooks +{ + void *(CJSON_CDECL *allocate)(size_t size); + void (CJSON_CDECL *deallocate)(void *pointer); + void *(CJSON_CDECL *reallocate)(void *pointer, size_t size); +} internal_hooks; + +#if defined(_MSC_VER) +/* work around MSVC error C2322: '...' address of dllimport '...' is not static */ +static void * CJSON_CDECL internal_malloc(size_t size) +{ + return malloc(size); +} +static void CJSON_CDECL internal_free(void *pointer) +{ + free(pointer); +} +static void * CJSON_CDECL internal_realloc(void *pointer, size_t size) +{ + return realloc(pointer, size); +} +#else +#define internal_malloc malloc +#define internal_free free +#define internal_realloc realloc +#endif + +/* strlen of character literals resolved at compile time */ +#define static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) + +static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; + +static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks) +{ + size_t length = 0; + unsigned char *copy = NULL; + + if (string == NULL) + { + return NULL; + } + + length = strlen((const char*)string) + sizeof(""); + copy = (unsigned char*)hooks->allocate(length); + if (copy == NULL) + { + return NULL; + } + memcpy(copy, string, length); + + return copy; +} + +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (hooks == NULL) + { + /* Reset hooks */ + global_hooks.allocate = malloc; + global_hooks.deallocate = free; + global_hooks.reallocate = realloc; + return; + } + + global_hooks.allocate = malloc; + if (hooks->malloc_fn != NULL) + { + global_hooks.allocate = hooks->malloc_fn; + } + + global_hooks.deallocate = free; + if (hooks->free_fn != NULL) + { + global_hooks.deallocate = hooks->free_fn; + } + + /* use realloc only if both free and malloc are used */ + global_hooks.reallocate = NULL; + if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free)) + { + global_hooks.reallocate = realloc; + } +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(const internal_hooks * const hooks) +{ + cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON)); + if (node) + { + memset(node, '\0', sizeof(cJSON)); + } + + return node; +} + +/* Delete a cJSON structure. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) +{ + cJSON *next = NULL; + while (item != NULL) + { + next = item->next; + if (!(item->type & cJSON_IsReference) && (item->child != NULL)) + { + cJSON_Delete(item->child); + } + if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) + { + global_hooks.deallocate(item->valuestring); + } + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + global_hooks.deallocate(item->string); + } + global_hooks.deallocate(item); + item = next; + } +} + +/* get the decimal point character of the current locale */ +static unsigned char get_decimal_point(void) +{ +#ifdef ENABLE_LOCALES + struct lconv *lconv = localeconv(); + return (unsigned char) lconv->decimal_point[0]; +#else + return '.'; +#endif +} + +typedef struct +{ + const unsigned char *content; + size_t length; + size_t offset; + size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ + internal_hooks hooks; +} parse_buffer; + +/* check if the given size is left to read in a given parse buffer (starting with 1) */ +#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) +/* check if the buffer can be accessed at the given index (starting with 0) */ +#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) +#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) +/* get a pointer to the buffer at the position */ +#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) + +/* Parse the input text to generate a number, and populate the result into item. */ +static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer) +{ + double number = 0; + unsigned char *after_end = NULL; + unsigned char number_c_string[64]; + unsigned char decimal_point = get_decimal_point(); + size_t i = 0; + + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; + } + + /* copy the number into a temporary buffer and replace '.' with the decimal point + * of the current locale (for strtod) + * This also takes care of '\0' not necessarily being available for marking the end of the input */ + for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) + { + switch (buffer_at_offset(input_buffer)[i]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + case 'e': + case 'E': + number_c_string[i] = buffer_at_offset(input_buffer)[i]; + break; + + case '.': + number_c_string[i] = decimal_point; + break; + + default: + goto loop_end; + } + } +loop_end: + number_c_string[i] = '\0'; + + number = strtod((const char*)number_c_string, (char**)&after_end); + if (number_c_string == after_end) + { + return false; /* parse_error */ + } + + item->valuedouble = number; + + /* use saturation in case of overflow */ + if (number >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (number <= (double)INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)number; + } + + item->type = cJSON_Number; + + input_buffer->offset += (size_t)(after_end - number_c_string); + return true; +} + +/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) +{ + if (number >= INT_MAX) + { + object->valueint = INT_MAX; + } + else if (number <= (double)INT_MIN) + { + object->valueint = INT_MIN; + } + else + { + object->valueint = (int)number; + } + + return object->valuedouble = number; +} + +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring) +{ + char *copy = NULL; + /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */ + if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference)) + { + return NULL; + } + if (strlen(valuestring) <= strlen(object->valuestring)) + { + strcpy(object->valuestring, valuestring); + return object->valuestring; + } + copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks); + if (copy == NULL) + { + return NULL; + } + if (object->valuestring != NULL) + { + cJSON_free(object->valuestring); + } + object->valuestring = copy; + + return copy; +} + +typedef struct +{ + unsigned char *buffer; + size_t length; + size_t offset; + size_t depth; /* current nesting depth (for formatted printing) */ + cJSON_bool noalloc; + cJSON_bool format; /* is this print a formatted print */ + internal_hooks hooks; +} printbuffer; + +/* realloc printbuffer if necessary to have at least "needed" bytes more */ +static unsigned char* ensure(printbuffer * const p, size_t needed) +{ + unsigned char *newbuffer = NULL; + size_t newsize = 0; + + if ((p == NULL) || (p->buffer == NULL)) + { + return NULL; + } + + if ((p->length > 0) && (p->offset >= p->length)) + { + /* make sure that offset is valid */ + return NULL; + } + + if (needed > INT_MAX) + { + /* sizes bigger than INT_MAX are currently not supported */ + return NULL; + } + + needed += p->offset + 1; + if (needed <= p->length) + { + return p->buffer + p->offset; + } + + if (p->noalloc) { + return NULL; + } + + /* calculate new buffer size */ + if (needed > (INT_MAX / 2)) + { + /* overflow of int, use INT_MAX if possible */ + if (needed <= INT_MAX) + { + newsize = INT_MAX; + } + else + { + return NULL; + } + } + else + { + newsize = needed * 2; + } + + if (p->hooks.reallocate != NULL) + { + /* reallocate with realloc if available */ + newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize); + if (newbuffer == NULL) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + } + else + { + /* otherwise reallocate manually */ + newbuffer = (unsigned char*)p->hooks.allocate(newsize); + if (!newbuffer) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + if (newbuffer) + { + memcpy(newbuffer, p->buffer, p->offset + 1); + } + p->hooks.deallocate(p->buffer); + } + p->length = newsize; + p->buffer = newbuffer; + + return newbuffer + p->offset; +} + +/* calculate the new length of the string in a printbuffer and update the offset */ +static void update_offset(printbuffer * const buffer) +{ + const unsigned char *buffer_pointer = NULL; + if ((buffer == NULL) || (buffer->buffer == NULL)) + { + return; + } + buffer_pointer = buffer->buffer + buffer->offset; + + buffer->offset += strlen((const char*)buffer_pointer); +} + +/* securely comparison of floating-point variables */ +static cJSON_bool compare_double(double a, double b) +{ + double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b); + return (fabs(a - b) <= maxVal * DBL_EPSILON); +} + +/* Render the number nicely from the given item into a string. */ +static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + double d = item->valuedouble; + int length = 0; + size_t i = 0; + unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */ + unsigned char decimal_point = get_decimal_point(); + double test = 0.0; + + if (output_buffer == NULL) + { + return false; + } + + /* This checks for NaN and Infinity */ + if (isnan(d) || isinf(d)) + { + length = sprintf((char*)number_buffer, "null"); + } + else + { + /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ + length = sprintf((char*)number_buffer, "%1.15g", d); + + /* Check whether the original double can be recovered */ + if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d)) + { + /* If not, print with 17 decimal places of precision */ + length = sprintf((char*)number_buffer, "%1.17g", d); + } + } + + /* sprintf failed or buffer overrun occurred */ + if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) + { + return false; + } + + /* reserve appropriate space in the output */ + output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); + if (output_pointer == NULL) + { + return false; + } + + /* copy the printed number to the output and replace locale + * dependent decimal point with '.' */ + for (i = 0; i < ((size_t)length); i++) + { + if (number_buffer[i] == decimal_point) + { + output_pointer[i] = '.'; + continue; + } + + output_pointer[i] = number_buffer[i]; + } + output_pointer[i] = '\0'; + + output_buffer->offset += (size_t)length; + + return true; +} + +/* parse 4 digit hexadecimal number */ +static unsigned parse_hex4(const unsigned char * const input) +{ + unsigned int h = 0; + size_t i = 0; + + for (i = 0; i < 4; i++) + { + /* parse digit */ + if ((input[i] >= '0') && (input[i] <= '9')) + { + h += (unsigned int) input[i] - '0'; + } + else if ((input[i] >= 'A') && (input[i] <= 'F')) + { + h += (unsigned int) 10 + input[i] - 'A'; + } + else if ((input[i] >= 'a') && (input[i] <= 'f')) + { + h += (unsigned int) 10 + input[i] - 'a'; + } + else /* invalid */ + { + return 0; + } + + if (i < 3) + { + /* shift left to make place for the next nibble */ + h = h << 4; + } + } + + return h; +} + +/* converts a UTF-16 literal to UTF-8 + * A literal can be one or two sequences of the form \uXXXX */ +static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer) +{ + long unsigned int codepoint = 0; + unsigned int first_code = 0; + const unsigned char *first_sequence = input_pointer; + unsigned char utf8_length = 0; + unsigned char utf8_position = 0; + unsigned char sequence_length = 0; + unsigned char first_byte_mark = 0; + + if ((input_end - first_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + /* get the first utf16 sequence */ + first_code = parse_hex4(first_sequence + 2); + + /* check that the code is valid */ + if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) + { + goto fail; + } + + /* UTF16 surrogate pair */ + if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) + { + const unsigned char *second_sequence = first_sequence + 6; + unsigned int second_code = 0; + sequence_length = 12; /* \uXXXX\uXXXX */ + + if ((input_end - second_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) + { + /* missing second half of the surrogate pair */ + goto fail; + } + + /* get the second utf16 sequence */ + second_code = parse_hex4(second_sequence + 2); + /* check that the code is valid */ + if ((second_code < 0xDC00) || (second_code > 0xDFFF)) + { + /* invalid second half of the surrogate pair */ + goto fail; + } + + + /* calculate the unicode codepoint from the surrogate pair */ + codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); + } + else + { + sequence_length = 6; /* \uXXXX */ + codepoint = first_code; + } + + /* encode as UTF-8 + * takes at maximum 4 bytes to encode: + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (codepoint < 0x80) + { + /* normal ascii, encoding 0xxxxxxx */ + utf8_length = 1; + } + else if (codepoint < 0x800) + { + /* two bytes, encoding 110xxxxx 10xxxxxx */ + utf8_length = 2; + first_byte_mark = 0xC0; /* 11000000 */ + } + else if (codepoint < 0x10000) + { + /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ + utf8_length = 3; + first_byte_mark = 0xE0; /* 11100000 */ + } + else if (codepoint <= 0x10FFFF) + { + /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + utf8_length = 4; + first_byte_mark = 0xF0; /* 11110000 */ + } + else + { + /* invalid unicode codepoint */ + goto fail; + } + + /* encode as utf8 */ + for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--) + { + /* 10xxxxxx */ + (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF); + codepoint >>= 6; + } + /* encode first byte */ + if (utf8_length > 1) + { + (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF); + } + else + { + (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F); + } + + *output_pointer += utf8_length; + + return sequence_length; + +fail: + return 0; +} + +/* Parse the input text into an unescaped cinput, and populate item. */ +static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) +{ + const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; + const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; + unsigned char *output_pointer = NULL; + unsigned char *output = NULL; + + /* not a string */ + if (buffer_at_offset(input_buffer)[0] != '\"') + { + goto fail; + } + + { + /* calculate approximate size of the output (overestimate) */ + size_t allocation_length = 0; + size_t skipped_bytes = 0; + while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) + { + /* is escape sequence */ + if (input_end[0] == '\\') + { + if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) + { + /* prevent buffer overflow when last input character is a backslash */ + goto fail; + } + skipped_bytes++; + input_end++; + } + input_end++; + } + if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) + { + goto fail; /* string ended unexpectedly */ + } + + /* This is at most how much we need for the output */ + allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes; + output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); + if (output == NULL) + { + goto fail; /* allocation failure */ + } + } + + output_pointer = output; + /* loop through the string literal */ + while (input_pointer < input_end) + { + if (*input_pointer != '\\') + { + *output_pointer++ = *input_pointer++; + } + /* escape sequence */ + else + { + unsigned char sequence_length = 2; + if ((input_end - input_pointer) < 1) + { + goto fail; + } + + switch (input_pointer[1]) + { + case 'b': + *output_pointer++ = '\b'; + break; + case 'f': + *output_pointer++ = '\f'; + break; + case 'n': + *output_pointer++ = '\n'; + break; + case 'r': + *output_pointer++ = '\r'; + break; + case 't': + *output_pointer++ = '\t'; + break; + case '\"': + case '\\': + case '/': + *output_pointer++ = input_pointer[1]; + break; + + /* UTF-16 literal */ + case 'u': + sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); + if (sequence_length == 0) + { + /* failed to convert UTF16-literal to UTF-8 */ + goto fail; + } + break; + + default: + goto fail; + } + input_pointer += sequence_length; + } + } + + /* zero terminate the output */ + *output_pointer = '\0'; + + item->type = cJSON_String; + item->valuestring = (char*)output; + + input_buffer->offset = (size_t) (input_end - input_buffer->content); + input_buffer->offset++; + + return true; + +fail: + if (output != NULL) + { + input_buffer->hooks.deallocate(output); + } + + if (input_pointer != NULL) + { + input_buffer->offset = (size_t)(input_pointer - input_buffer->content); + } + + return false; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer) +{ + const unsigned char *input_pointer = NULL; + unsigned char *output = NULL; + unsigned char *output_pointer = NULL; + size_t output_length = 0; + /* numbers of additional characters needed for escaping */ + size_t escape_characters = 0; + + if (output_buffer == NULL) + { + return false; + } + + /* empty string */ + if (input == NULL) + { + output = ensure(output_buffer, sizeof("\"\"")); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "\"\""); + + return true; + } + + /* set "flag" to 1 if something needs to be escaped */ + for (input_pointer = input; *input_pointer; input_pointer++) + { + switch (*input_pointer) + { + case '\"': + case '\\': + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + /* one character escape sequence */ + escape_characters++; + break; + default: + if (*input_pointer < 32) + { + /* UTF-16 escape sequence uXXXX */ + escape_characters += 5; + } + break; + } + } + output_length = (size_t)(input_pointer - input) + escape_characters; + + output = ensure(output_buffer, output_length + sizeof("\"\"")); + if (output == NULL) + { + return false; + } + + /* no characters have to be escaped */ + if (escape_characters == 0) + { + output[0] = '\"'; + memcpy(output + 1, input, output_length); + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; + } + + output[0] = '\"'; + output_pointer = output + 1; + /* copy the string */ + for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) + { + if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) + { + /* normal character, copy */ + *output_pointer = *input_pointer; + } + else + { + /* character needs to be escaped */ + *output_pointer++ = '\\'; + switch (*input_pointer) + { + case '\\': + *output_pointer = '\\'; + break; + case '\"': + *output_pointer = '\"'; + break; + case '\b': + *output_pointer = 'b'; + break; + case '\f': + *output_pointer = 'f'; + break; + case '\n': + *output_pointer = 'n'; + break; + case '\r': + *output_pointer = 'r'; + break; + case '\t': + *output_pointer = 't'; + break; + default: + /* escape and print as unicode codepoint */ + sprintf((char*)output_pointer, "u%04x", *input_pointer); + output_pointer += 4; + break; + } + } + } + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; +} + +/* Invoke print_string_ptr (which is useful) on an item. */ +static cJSON_bool print_string(const cJSON * const item, printbuffer * const p) +{ + return print_string_ptr((unsigned char*)item->valuestring, p); +} + +/* Predeclare these prototypes. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer); + +/* Utility to jump whitespace and cr/lf */ +static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL)) + { + return NULL; + } + + if (cannot_access_at_index(buffer, 0)) + { + return buffer; + } + + while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) + { + buffer->offset++; + } + + if (buffer->offset == buffer->length) + { + buffer->offset--; + } + + return buffer; +} + +/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ +static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) + { + return NULL; + } + + if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) + { + buffer->offset += 3; + } + + return buffer; +} + +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + size_t buffer_length; + + if (NULL == value) + { + return NULL; + } + + /* Adding null character size due to require_null_terminated. */ + buffer_length = strlen(value) + sizeof(""); + + return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated); +} + +/* Parse an object - create a new root, and populate. */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; + cJSON *item = NULL; + + /* reset error position */ + global_error.json = NULL; + global_error.position = 0; + + if (value == NULL || 0 == buffer_length) + { + goto fail; + } + + buffer.content = (const unsigned char*)value; + buffer.length = buffer_length; + buffer.offset = 0; + buffer.hooks = global_hooks; + + item = cJSON_New_Item(&global_hooks); + if (item == NULL) /* memory fail */ + { + goto fail; + } + + if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) + { + /* parse failure. ep is set. */ + goto fail; + } + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) + { + buffer_skip_whitespace(&buffer); + if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0') + { + goto fail; + } + } + if (return_parse_end) + { + *return_parse_end = (const char*)buffer_at_offset(&buffer); + } + + return item; + +fail: + if (item != NULL) + { + cJSON_Delete(item); + } + + if (value != NULL) + { + error local_error; + local_error.json = (const unsigned char*)value; + local_error.position = 0; + + if (buffer.offset < buffer.length) + { + local_error.position = buffer.offset; + } + else if (buffer.length > 0) + { + local_error.position = buffer.length - 1; + } + + if (return_parse_end != NULL) + { + *return_parse_end = (const char*)local_error.json + local_error.position; + } + + global_error = local_error; + } + + return NULL; +} + +/* Default options for cJSON_Parse */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) +{ + return cJSON_ParseWithOpts(value, 0, 0); +} + +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length) +{ + return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0); +} + +#define cjson_min(a, b) (((a) < (b)) ? (a) : (b)) + +static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks) +{ + static const size_t default_buffer_size = 256; + printbuffer buffer[1]; + unsigned char *printed = NULL; + + memset(buffer, 0, sizeof(buffer)); + + /* create buffer */ + buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size); + buffer->length = default_buffer_size; + buffer->format = format; + buffer->hooks = *hooks; + if (buffer->buffer == NULL) + { + goto fail; + } + + /* print the value */ + if (!print_value(item, buffer)) + { + goto fail; + } + update_offset(buffer); + + /* check if reallocate is available */ + if (hooks->reallocate != NULL) + { + printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); + if (printed == NULL) { + goto fail; + } + buffer->buffer = NULL; + } + else /* otherwise copy the JSON over to a new buffer */ + { + printed = (unsigned char*) hooks->allocate(buffer->offset + 1); + if (printed == NULL) + { + goto fail; + } + memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); + printed[buffer->offset] = '\0'; /* just to be sure */ + + /* free the buffer */ + hooks->deallocate(buffer->buffer); + } + + return printed; + +fail: + if (buffer->buffer != NULL) + { + hooks->deallocate(buffer->buffer); + } + + if (printed != NULL) + { + hooks->deallocate(printed); + } + + return NULL; +} + +/* Render a cJSON item/entity/structure to text. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item) +{ + return (char*)print(item, true, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item) +{ + return (char*)print(item, false, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if (prebuffer < 0) + { + return NULL; + } + + p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer); + if (!p.buffer) + { + return NULL; + } + + p.length = (size_t)prebuffer; + p.offset = 0; + p.noalloc = false; + p.format = fmt; + p.hooks = global_hooks; + + if (!print_value(item, &p)) + { + global_hooks.deallocate(p.buffer); + return NULL; + } + + return (char*)p.buffer; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if ((length < 0) || (buffer == NULL)) + { + return false; + } + + p.buffer = (unsigned char*)buffer; + p.length = (size_t)length; + p.offset = 0; + p.noalloc = true; + p.format = format; + p.hooks = global_hooks; + + return print_value(item, &p); +} + +/* Parser core - when encountering text, process appropriately. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer) +{ + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; /* no input */ + } + + /* parse the different types of values */ + /* null */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0)) + { + item->type = cJSON_NULL; + input_buffer->offset += 4; + return true; + } + /* false */ + if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0)) + { + item->type = cJSON_False; + input_buffer->offset += 5; + return true; + } + /* true */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0)) + { + item->type = cJSON_True; + item->valueint = 1; + input_buffer->offset += 4; + return true; + } + /* string */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) + { + return parse_string(item, input_buffer); + } + /* number */ + if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) + { + return parse_number(item, input_buffer); + } + /* array */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) + { + return parse_array(item, input_buffer); + } + /* object */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) + { + return parse_object(item, input_buffer); + } + + return false; +} + +/* Render a value to text. */ +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output = NULL; + + if ((item == NULL) || (output_buffer == NULL)) + { + return false; + } + + switch ((item->type) & 0xFF) + { + case cJSON_NULL: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "null"); + return true; + + case cJSON_False: + output = ensure(output_buffer, 6); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "false"); + return true; + + case cJSON_True: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "true"); + return true; + + case cJSON_Number: + return print_number(item, output_buffer); + + case cJSON_Raw: + { + size_t raw_length = 0; + if (item->valuestring == NULL) + { + return false; + } + + raw_length = strlen(item->valuestring) + sizeof(""); + output = ensure(output_buffer, raw_length); + if (output == NULL) + { + return false; + } + memcpy(output, item->valuestring, raw_length); + return true; + } + + case cJSON_String: + return print_string(item, output_buffer); + + case cJSON_Array: + return print_array(item, output_buffer); + + case cJSON_Object: + return print_object(item, output_buffer); + + default: + return false; + } +} + +/* Build an array from input text. */ +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* head of the linked list */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (buffer_at_offset(input_buffer)[0] != '[') + { + /* not an array */ + goto fail; + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) + { + /* empty array */ + goto success; + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse next value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') + { + goto fail; /* expected end of array */ + } + +success: + input_buffer->depth--; + + if (head != NULL) { + head->prev = current_item; + } + + item->type = cJSON_Array; + item->child = head; + + input_buffer->offset++; + + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an array to text */ +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_element = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output array. */ + /* opening square bracket */ + output_pointer = ensure(output_buffer, 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer = '['; + output_buffer->offset++; + output_buffer->depth++; + + while (current_element != NULL) + { + if (!print_value(current_element, output_buffer)) + { + return false; + } + update_offset(output_buffer); + if (current_element->next) + { + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ','; + if(output_buffer->format) + { + *output_pointer++ = ' '; + } + *output_pointer = '\0'; + output_buffer->offset += length; + } + current_element = current_element->next; + } + + output_pointer = ensure(output_buffer, 2); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ']'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Build an object from the text. */ +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* linked list head */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) + { + goto fail; /* not an object */ + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) + { + goto success; /* empty object */ + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse the name of the child */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_string(current_item, input_buffer)) + { + goto fail; /* failed to parse name */ + } + buffer_skip_whitespace(input_buffer); + + /* swap valuestring and string, because we parsed the name */ + current_item->string = current_item->valuestring; + current_item->valuestring = NULL; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) + { + goto fail; /* invalid object */ + } + + /* parse the value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) + { + goto fail; /* expected end of object */ + } + +success: + input_buffer->depth--; + + if (head != NULL) { + head->prev = current_item; + } + + item->type = cJSON_Object; + item->child = head; + + input_buffer->offset++; + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an object to text. */ +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_item = item->child; + + if (output_buffer == NULL) + { + return false; + } + + /* Compose the output: */ + length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */ + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer++ = '{'; + output_buffer->depth++; + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + output_buffer->offset += length; + + while (current_item) + { + if (output_buffer->format) + { + size_t i; + output_pointer = ensure(output_buffer, output_buffer->depth); + if (output_pointer == NULL) + { + return false; + } + for (i = 0; i < output_buffer->depth; i++) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += output_buffer->depth; + } + + /* print key */ + if (!print_string_ptr((unsigned char*)current_item->string, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ':'; + if (output_buffer->format) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += length; + + /* print value */ + if (!print_value(current_item, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + /* print comma if not last */ + length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0)); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + if (current_item->next) + { + *output_pointer++ = ','; + } + + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + *output_pointer = '\0'; + output_buffer->offset += length; + + current_item = current_item->next; + } + + output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); + if (output_pointer == NULL) + { + return false; + } + if (output_buffer->format) + { + size_t i; + for (i = 0; i < (output_buffer->depth - 1); i++) + { + *output_pointer++ = '\t'; + } + } + *output_pointer++ = '}'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Get Array size/item / object item. */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) +{ + cJSON *child = NULL; + size_t size = 0; + + if (array == NULL) + { + return 0; + } + + child = array->child; + + while(child != NULL) + { + size++; + child = child->next; + } + + /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ + + return (int)size; +} + +static cJSON* get_array_item(const cJSON *array, size_t index) +{ + cJSON *current_child = NULL; + + if (array == NULL) + { + return NULL; + } + + current_child = array->child; + while ((current_child != NULL) && (index > 0)) + { + index--; + current_child = current_child->next; + } + + return current_child; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) +{ + if (index < 0) + { + return NULL; + } + + return get_array_item(array, (size_t)index); +} + +static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) +{ + cJSON *current_element = NULL; + + if ((object == NULL) || (name == NULL)) + { + return NULL; + } + + current_element = object->child; + if (case_sensitive) + { + while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0)) + { + current_element = current_element->next; + } + } + else + { + while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) + { + current_element = current_element->next; + } + } + + if ((current_element == NULL) || (current_element->string == NULL)) { + return NULL; + } + + return current_element; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, false); +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) +{ + return cJSON_GetObjectItem(object, string) ? 1 : 0; +} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev, cJSON *item) +{ + prev->next = item; + item->prev = prev; +} + +/* Utility for handling references. */ +static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks) +{ + cJSON *reference = NULL; + if (item == NULL) + { + return NULL; + } + + reference = cJSON_New_Item(hooks); + if (reference == NULL) + { + return NULL; + } + + memcpy(reference, item, sizeof(cJSON)); + reference->string = NULL; + reference->type |= cJSON_IsReference; + reference->next = reference->prev = NULL; + return reference; +} + +static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) +{ + cJSON *child = NULL; + + if ((item == NULL) || (array == NULL) || (array == item)) + { + return false; + } + + child = array->child; + /* + * To find the last item in array quickly, we use prev in array + */ + if (child == NULL) + { + /* list is empty, start new one */ + array->child = item; + item->prev = item; + item->next = NULL; + } + else + { + /* append to the end */ + if (child->prev) + { + suffix_object(child->prev, item); + array->child->prev = item; + } + else + { + while (child->next) + { + child = child->next; + } + suffix_object(child, item); + array->child->prev = item; + } + } + + return true; +} + +/* Add item to array/object. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + return add_item_to_array(array, item); +} + +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic push +#endif +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif +/* helper function to cast away const */ +static void* cast_away_const(const void* string) +{ + return (void*)string; +} +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic pop +#endif + + +static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) +{ + char *new_key = NULL; + int new_type = cJSON_Invalid; + + if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item)) + { + return false; + } + + if (constant_key) + { + new_key = (char*)cast_away_const(string); + new_type = item->type | cJSON_StringIsConst; + } + else + { + new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks); + if (new_key == NULL) + { + return false; + } + + new_type = item->type & ~cJSON_StringIsConst; + } + + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + hooks->deallocate(item->string); + } + + item->string = new_key; + item->type = new_type; + + return add_item_to_array(object, item); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + return add_item_to_object(object, string, item, &global_hooks, false); +} + +/* Add an item to an object with constant string as key */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) +{ + return add_item_to_object(object, string, item, &global_hooks, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +{ + if (array == NULL) + { + return false; + } + + return add_item_to_array(array, create_reference(item, &global_hooks)); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +{ + if ((object == NULL) || (string == NULL)) + { + return false; + } + + return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) +{ + cJSON *null = cJSON_CreateNull(); + if (add_item_to_object(object, name, null, &global_hooks, false)) + { + return null; + } + + cJSON_Delete(null); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) +{ + cJSON *true_item = cJSON_CreateTrue(); + if (add_item_to_object(object, name, true_item, &global_hooks, false)) + { + return true_item; + } + + cJSON_Delete(true_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) +{ + cJSON *false_item = cJSON_CreateFalse(); + if (add_item_to_object(object, name, false_item, &global_hooks, false)) + { + return false_item; + } + + cJSON_Delete(false_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) +{ + cJSON *bool_item = cJSON_CreateBool(boolean); + if (add_item_to_object(object, name, bool_item, &global_hooks, false)) + { + return bool_item; + } + + cJSON_Delete(bool_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +{ + cJSON *number_item = cJSON_CreateNumber(number); + if (add_item_to_object(object, name, number_item, &global_hooks, false)) + { + return number_item; + } + + cJSON_Delete(number_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) +{ + cJSON *string_item = cJSON_CreateString(string); + if (add_item_to_object(object, name, string_item, &global_hooks, false)) + { + return string_item; + } + + cJSON_Delete(string_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) +{ + cJSON *raw_item = cJSON_CreateRaw(raw); + if (add_item_to_object(object, name, raw_item, &global_hooks, false)) + { + return raw_item; + } + + cJSON_Delete(raw_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) +{ + cJSON *object_item = cJSON_CreateObject(); + if (add_item_to_object(object, name, object_item, &global_hooks, false)) + { + return object_item; + } + + cJSON_Delete(object_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) +{ + cJSON *array = cJSON_CreateArray(); + if (add_item_to_object(object, name, array, &global_hooks, false)) + { + return array; + } + + cJSON_Delete(array); + return NULL; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) +{ + if ((parent == NULL) || (item == NULL)) + { + return NULL; + } + + if (item != parent->child) + { + /* not the first element */ + item->prev->next = item->next; + } + if (item->next != NULL) + { + /* not the last element */ + item->next->prev = item->prev; + } + + if (item == parent->child) + { + /* first element */ + parent->child = item->next; + } + else if (item->next == NULL) + { + /* last element */ + parent->child->prev = item->prev; + } + + /* make sure the detached item doesn't point anywhere anymore */ + item->prev = NULL; + item->next = NULL; + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) +{ + if (which < 0) + { + return NULL; + } + + return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which) +{ + cJSON_Delete(cJSON_DetachItemFromArray(array, which)); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItem(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObject(object, string)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); +} + +/* Replace array/object items with new ones. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +{ + cJSON *after_inserted = NULL; + + if (which < 0) + { + return false; + } + + after_inserted = get_array_item(array, (size_t)which); + if (after_inserted == NULL) + { + return add_item_to_array(array, newitem); + } + + newitem->next = after_inserted; + newitem->prev = after_inserted->prev; + after_inserted->prev = newitem; + if (after_inserted == array->child) + { + array->child = newitem; + } + else + { + newitem->prev->next = newitem; + } + return true; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) +{ + if ((parent == NULL) || (replacement == NULL) || (item == NULL)) + { + return false; + } + + if (replacement == item) + { + return true; + } + + replacement->next = item->next; + replacement->prev = item->prev; + + if (replacement->next != NULL) + { + replacement->next->prev = replacement; + } + if (parent->child == item) + { + if (parent->child->prev == parent->child) + { + replacement->prev = replacement; + } + parent->child = replacement; + } + else + { /* + * To find the last item in array quickly, we use prev in array. + * We can't modify the last item's next pointer where this item was the parent's child + */ + if (replacement->prev != NULL) + { + replacement->prev->next = replacement; + } + if (replacement->next == NULL) + { + parent->child->prev = replacement; + } + } + + item->next = NULL; + item->prev = NULL; + cJSON_Delete(item); + + return true; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + if (which < 0) + { + return false; + } + + return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); +} + +static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) +{ + if ((replacement == NULL) || (string == NULL)) + { + return false; + } + + /* replace the name in the replacement */ + if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) + { + cJSON_free(replacement->string); + } + replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + replacement->type &= ~cJSON_StringIsConst; + + return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +{ + return replace_item_in_object(object, string, newitem, false); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +{ + return replace_item_in_object(object, string, newitem, true); +} + +/* Create basic types: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_NULL; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_True; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = boolean ? cJSON_True : cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Number; + item->valuedouble = num; + + /* use saturation in case of overflow */ + if (num >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (num <= (double)INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)num; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_String; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) + { + item->type = cJSON_String | cJSON_IsReference; + item->valuestring = (char*)cast_away_const(string); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Object | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) { + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Array | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Raw; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type=cJSON_Array; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item) + { + item->type = cJSON_Object; + } + + return item; +} + +/* Create Arrays: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if (!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber((double)numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0;a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (strings == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for (i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateString(strings[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p,n); + } + p = n; + } + + return a; +} + +/* Duplication */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) +{ + cJSON *newitem = NULL; + cJSON *child = NULL; + cJSON *next = NULL; + cJSON *newchild = NULL; + + /* Bail on bad ptr */ + if (!item) + { + goto fail; + } + /* Create new item */ + newitem = cJSON_New_Item(&global_hooks); + if (!newitem) + { + goto fail; + } + /* Copy over all vars */ + newitem->type = item->type & (~cJSON_IsReference); + newitem->valueint = item->valueint; + newitem->valuedouble = item->valuedouble; + if (item->valuestring) + { + newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks); + if (!newitem->valuestring) + { + goto fail; + } + } + if (item->string) + { + newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); + if (!newitem->string) + { + goto fail; + } + } + /* If non-recursive, then we're done! */ + if (!recurse) + { + return newitem; + } + /* Walk the ->next chain for the child. */ + child = item->child; + while (child != NULL) + { + newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) + { + goto fail; + } + if (next != NULL) + { + /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + next->next = newchild; + newchild->prev = next; + next = newchild; + } + else + { + /* Set newitem->child and move to it */ + newitem->child = newchild; + next = newchild; + } + child = child->next; + } + + return newitem; + +fail: + if (newitem != NULL) + { + cJSON_Delete(newitem); + } + + return NULL; +} + +static void skip_oneline_comment(char **input) +{ + *input += static_strlen("//"); + + for (; (*input)[0] != '\0'; ++(*input)) + { + if ((*input)[0] == '\n') { + *input += static_strlen("\n"); + return; + } + } +} + +static void skip_multiline_comment(char **input) +{ + *input += static_strlen("/*"); + + for (; (*input)[0] != '\0'; ++(*input)) + { + if (((*input)[0] == '*') && ((*input)[1] == '/')) + { + *input += static_strlen("*/"); + return; + } + } +} + +static void minify_string(char **input, char **output) { + (*output)[0] = (*input)[0]; + *input += static_strlen("\""); + *output += static_strlen("\""); + + + for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) { + (*output)[0] = (*input)[0]; + + if ((*input)[0] == '\"') { + (*output)[0] = '\"'; + *input += static_strlen("\""); + *output += static_strlen("\""); + return; + } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) { + (*output)[1] = (*input)[1]; + *input += static_strlen("\""); + *output += static_strlen("\""); + } + } +} + +CJSON_PUBLIC(void) cJSON_Minify(char *json) +{ + char *into = json; + + if (json == NULL) + { + return; + } + + while (json[0] != '\0') + { + switch (json[0]) + { + case ' ': + case '\t': + case '\r': + case '\n': + json++; + break; + + case '/': + if (json[1] == '/') + { + skip_oneline_comment(&json); + } + else if (json[1] == '*') + { + skip_multiline_comment(&json); + } else { + json++; + } + break; + + case '\"': + minify_string(&json, (char**)&into); + break; + + default: + into[0] = json[0]; + json++; + into++; + } + } + + /* and null-terminate. */ + *into = '\0'; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Invalid; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_False; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xff) == cJSON_True; +} + + +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & (cJSON_True | cJSON_False)) != 0; +} +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_NULL; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Number; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_String; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Array; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Object; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Raw; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive) +{ + if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a)) + { + return false; + } + + /* check if type is valid */ + switch (a->type & 0xFF) + { + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + case cJSON_Number: + case cJSON_String: + case cJSON_Raw: + case cJSON_Array: + case cJSON_Object: + break; + + default: + return false; + } + + /* identical objects are equal */ + if (a == b) + { + return true; + } + + switch (a->type & 0xFF) + { + /* in these cases and equal type is enough */ + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + return true; + + case cJSON_Number: + if (compare_double(a->valuedouble, b->valuedouble)) + { + return true; + } + return false; + + case cJSON_String: + case cJSON_Raw: + if ((a->valuestring == NULL) || (b->valuestring == NULL)) + { + return false; + } + if (strcmp(a->valuestring, b->valuestring) == 0) + { + return true; + } + + return false; + + case cJSON_Array: + { + cJSON *a_element = a->child; + cJSON *b_element = b->child; + + for (; (a_element != NULL) && (b_element != NULL);) + { + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + + a_element = a_element->next; + b_element = b_element->next; + } + + /* one of the arrays is longer than the other */ + if (a_element != b_element) { + return false; + } + + return true; + } + + case cJSON_Object: + { + cJSON *a_element = NULL; + cJSON *b_element = NULL; + cJSON_ArrayForEach(a_element, a) + { + /* TODO This has O(n^2) runtime, which is horrible! */ + b_element = get_object_item(b, a_element->string, case_sensitive); + if (b_element == NULL) + { + return false; + } + + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + } + + /* doing this twice, once on a and b to prevent true comparison if a subset of b + * TODO: Do this the proper way, this is just a fix for now */ + cJSON_ArrayForEach(b_element, b) + { + a_element = get_object_item(a, b_element->string, case_sensitive); + if (a_element == NULL) + { + return false; + } + + if (!cJSON_Compare(b_element, a_element, case_sensitive)) + { + return false; + } + } + + return true; + } + + default: + return false; + } +} + +CJSON_PUBLIC(void *) cJSON_malloc(size_t size) +{ + return global_hooks.allocate(size); +} + +CJSON_PUBLIC(void) cJSON_free(void *object) +{ + global_hooks.deallocate(object); +} diff --git a/product/src/fes/protocol/yxcloud_mqtt_s/cJSON.h b/product/src/fes/protocol/yxcloud_mqtt_s/cJSON.h new file mode 100644 index 00000000..dd8feb2c --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_s/cJSON.h @@ -0,0 +1,293 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) +#define __WINDOWS__ +#endif + +#ifdef __WINDOWS__ + +/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options: + +CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols +CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) +CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol + +For *nix builds that support visibility attribute, you can define similar behavior by + +setting default visibility to hidden by adding +-fvisibility=hidden (for gcc) +or +-xldscope=hidden (for sun cc) +to CFLAGS + +then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does + +*/ + +#define CJSON_CDECL __cdecl +#define CJSON_STDCALL __stdcall + +/* export symbols by default, this is necessary for copy pasting the C and header file */ +#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_EXPORT_SYMBOLS +#endif + +#if defined(CJSON_HIDE_SYMBOLS) +#define CJSON_PUBLIC(type) type CJSON_STDCALL +#elif defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL +#elif defined(CJSON_IMPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL +#endif +#else /* !__WINDOWS__ */ +#define CJSON_CDECL +#define CJSON_STDCALL + +#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) +#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type +#else +#define CJSON_PUBLIC(type) type +#endif +#endif + +/* project version */ +#define CJSON_VERSION_MAJOR 1 +#define CJSON_VERSION_MINOR 7 +#define CJSON_VERSION_PATCH 13 + +#include + +/* cJSON Types: */ +#define cJSON_Invalid (0) +#define cJSON_False (1 << 0) +#define cJSON_True (1 << 1) +#define cJSON_NULL (1 << 2) +#define cJSON_Number (1 << 3) +#define cJSON_String (1 << 4) +#define cJSON_Array (1 << 5) +#define cJSON_Object (1 << 6) +#define cJSON_Raw (1 << 7) /* raw json */ + +#define cJSON_IsReference 256 +#define cJSON_StringIsConst 512 + +/* The cJSON structure: */ +typedef struct cJSON +{ + /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *next; + struct cJSON *prev; + /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + struct cJSON *child; + + /* The type of the item, as above. */ + int type; + + /* The item's string, if type==cJSON_String and type == cJSON_Raw */ + char *valuestring; + /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ + int valueint; + /* The item's number, if type==cJSON_Number */ + double valuedouble; + + /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + char *string; +} cJSON; + +typedef struct cJSON_Hooks +{ + /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */ + void *(CJSON_CDECL *malloc_fn)(size_t sz); + void (CJSON_CDECL *free_fn)(void *ptr); +} cJSON_Hooks; + +typedef int cJSON_bool; + +/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. + * This is to prevent stack overflows. */ +#ifndef CJSON_NESTING_LIMIT +#define CJSON_NESTING_LIMIT 1000 +#endif + +/* returns the version of cJSON as a string */ +CJSON_PUBLIC(const char*) cJSON_Version(void); + +/* Supply malloc, realloc and free functions to cJSON */ +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); + +/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length); +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated); + +/* Render a cJSON entity to text for transfer/storage. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. */ +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); +/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); +/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ +/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); +/* Delete a cJSON entity and all subentities. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); + +/* Returns the number of items in an array (or object). */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); +/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); +/* Get item "string" from object. Case insensitive. */ +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); + +/* Check item type and return its value */ +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item); +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item); + +/* These functions check the type of an item */ +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); + +/* These calls create a cJSON item of the appropriate type. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); +/* raw json */ +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); + +/* Create a string where valuestring references a string so + * it will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); +/* Create an object/array that only references it's elements so + * they will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); + +/* These utilities create an Array of count items. + * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); + +/* Append item to the specified array/object. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. + * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before + * writing to `item->string` */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); + +/* Remove/Detach items from Arrays/Objects. */ +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); + +/* Update array items. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will + * need to be released. With recurse!=0, it will duplicate any children connected to the item. + * The item->next and ->prev pointers are always zero on return from Duplicate. */ +/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. + * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); + +/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings. + * The input pointer json cannot point to a read-only address area, such as a string constant, + * but should point to a readable and writable adress area. */ +CJSON_PUBLIC(void) cJSON_Minify(char *json); + +/* Helper functions for creating and adding items to an object at the same time. + * They return the added item or NULL on failure. */ +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) +/* helper for the cJSON_SetNumberValue macro */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); +#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) +/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring); + +/* Macro for iterating over an array or object */ +#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) + +/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ +CJSON_PUBLIC(void *) cJSON_malloc(size_t size); +CJSON_PUBLIC(void) cJSON_free(void *object); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/yxcloud_mqtt_s/mosquitto.h b/product/src/fes/protocol/yxcloud_mqtt_s/mosquitto.h new file mode 100644 index 00000000..879184dc --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_s/mosquitto.h @@ -0,0 +1,3084 @@ +/* +Copyright (c) 2010-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_H +#define MOSQUITTO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(WIN32) && !defined(WITH_BROKER) && !defined(LIBMOSQUITTO_STATIC) +# ifdef libmosquitto_EXPORTS +# define libmosq_EXPORT __declspec(dllexport) +# else +# define libmosq_EXPORT __declspec(dllimport) +# endif +#else +# define libmosq_EXPORT +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# ifndef __cplusplus +# define bool char +# define true 1 +# define false 0 +# endif +#else +# ifndef __cplusplus +# include +# endif +#endif + +#include +#include + +#define LIBMOSQUITTO_MAJOR 1 +#define LIBMOSQUITTO_MINOR 6 +#define LIBMOSQUITTO_REVISION 10 +/* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ +#define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION) + +/* Log types */ +#define MOSQ_LOG_NONE 0 +#define MOSQ_LOG_INFO (1<<0) +#define MOSQ_LOG_NOTICE (1<<1) +#define MOSQ_LOG_WARNING (1<<2) +#define MOSQ_LOG_ERR (1<<3) +#define MOSQ_LOG_DEBUG (1<<4) +#define MOSQ_LOG_SUBSCRIBE (1<<5) +#define MOSQ_LOG_UNSUBSCRIBE (1<<6) +#define MOSQ_LOG_WEBSOCKETS (1<<7) +#define MOSQ_LOG_INTERNAL 0x80000000U +#define MOSQ_LOG_ALL 0xFFFFFFFFU + +/* Error values */ +enum mosq_err_t { + MOSQ_ERR_AUTH_CONTINUE = -4, + MOSQ_ERR_NO_SUBSCRIBERS = -3, + MOSQ_ERR_SUB_EXISTS = -2, + MOSQ_ERR_CONN_PENDING = -1, + MOSQ_ERR_SUCCESS = 0, + MOSQ_ERR_NOMEM = 1, + MOSQ_ERR_PROTOCOL = 2, + MOSQ_ERR_INVAL = 3, + MOSQ_ERR_NO_CONN = 4, + MOSQ_ERR_CONN_REFUSED = 5, + MOSQ_ERR_NOT_FOUND = 6, + MOSQ_ERR_CONN_LOST = 7, + MOSQ_ERR_TLS = 8, + MOSQ_ERR_PAYLOAD_SIZE = 9, + MOSQ_ERR_NOT_SUPPORTED = 10, + MOSQ_ERR_AUTH = 11, + MOSQ_ERR_ACL_DENIED = 12, + MOSQ_ERR_UNKNOWN = 13, + MOSQ_ERR_ERRNO = 14, + MOSQ_ERR_EAI = 15, + MOSQ_ERR_PROXY = 16, + MOSQ_ERR_PLUGIN_DEFER = 17, + MOSQ_ERR_MALFORMED_UTF8 = 18, + MOSQ_ERR_KEEPALIVE = 19, + MOSQ_ERR_LOOKUP = 20, + MOSQ_ERR_MALFORMED_PACKET = 21, + MOSQ_ERR_DUPLICATE_PROPERTY = 22, + MOSQ_ERR_TLS_HANDSHAKE = 23, + MOSQ_ERR_QOS_NOT_SUPPORTED = 24, + MOSQ_ERR_OVERSIZE_PACKET = 25, + MOSQ_ERR_OCSP = 26, +}; + +/* Option values */ +enum mosq_opt_t { + MOSQ_OPT_PROTOCOL_VERSION = 1, + MOSQ_OPT_SSL_CTX = 2, + MOSQ_OPT_SSL_CTX_WITH_DEFAULTS = 3, + MOSQ_OPT_RECEIVE_MAXIMUM = 4, + MOSQ_OPT_SEND_MAXIMUM = 5, + MOSQ_OPT_TLS_KEYFORM = 6, + MOSQ_OPT_TLS_ENGINE = 7, + MOSQ_OPT_TLS_ENGINE_KPASS_SHA1 = 8, + MOSQ_OPT_TLS_OCSP_REQUIRED = 9, + MOSQ_OPT_TLS_ALPN = 10, +}; + + +/* MQTT specification restricts client ids to a maximum of 23 characters */ +#define MOSQ_MQTT_ID_MAX_LENGTH 23 + +#define MQTT_PROTOCOL_V31 3 +#define MQTT_PROTOCOL_V311 4 +#define MQTT_PROTOCOL_V5 5 + +struct mosquitto_message{ + int mid; + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct mosquitto; +typedef struct mqtt5__property mosquitto_property; + +/* + * Topic: Threads + * libmosquitto provides thread safe operation, with the exception of + * which is not thread safe. + * + * If your application uses threads you must use to + * tell the library this is the case, otherwise it makes some optimisations + * for the single threaded case that may result in unexpected behaviour for + * the multi threaded case. + */ +/*************************************************** + * Important note + * + * The following functions that deal with network operations will return + * MOSQ_ERR_SUCCESS on success, but this does not mean that the operation has + * taken place. An attempt will be made to write the network data, but if the + * socket is not available for writing at that time then the packet will not be + * sent. To ensure the packet is sent, call mosquitto_loop() (which must also + * be called to process incoming network data). + * This is especially important when disconnecting a client that has a will. If + * the broker does not receive the DISCONNECT command, it will assume that the + * client has disconnected unexpectedly and send the will. + * + * mosquitto_connect() + * mosquitto_disconnect() + * mosquitto_subscribe() + * mosquitto_unsubscribe() + * mosquitto_publish() + ***************************************************/ + + +/* ====================================================================== + * + * Section: Library version, init, and cleanup + * + * ====================================================================== */ +/* + * Function: mosquitto_lib_version + * + * Can be used to obtain version information for the mosquitto library. + * This allows the application to compare the library version against the + * version it was compiled against by using the LIBMOSQUITTO_MAJOR, + * LIBMOSQUITTO_MINOR and LIBMOSQUITTO_REVISION defines. + * + * Parameters: + * major - an integer pointer. If not NULL, the major version of the + * library will be returned in this variable. + * minor - an integer pointer. If not NULL, the minor version of the + * library will be returned in this variable. + * revision - an integer pointer. If not NULL, the revision of the library will + * be returned in this variable. + * + * Returns: + * LIBMOSQUITTO_VERSION_NUMBER, which is a unique number based on the major, + * minor and revision values. + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_version(int *major, int *minor, int *revision); + +/* + * Function: mosquitto_lib_init + * + * Must be called before any other mosquitto functions. + * + * This function is *not* thread safe. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_UNKNOWN - on Windows, if sockets couldn't be initialized. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_init(void); + +/* + * Function: mosquitto_lib_cleanup + * + * Call to free resources associated with the library. + * + * Returns: + * MOSQ_ERR_SUCCESS - always + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_cleanup(void); + + +/* ====================================================================== + * + * Section: Client creation, destruction, and reinitialisation + * + * ====================================================================== */ +/* + * Function: mosquitto_new + * + * Create a new mosquitto client instance. + * + * Parameters: + * id - String to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Note that a client will never discard its own outgoing + * messages on disconnect. Calling or + * will cause the messages to be resent. + * Use to reset a client to its + * original state. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * Pointer to a struct mosquitto on success. + * NULL on failure. Interrogate errno to determine the cause for the failure: + * - ENOMEM on out of memory. + * - EINVAL on invalid input parameters. + * + * See Also: + * , , + */ +libmosq_EXPORT struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj); + +/* + * Function: mosquitto_destroy + * + * Use to free memory associated with a mosquitto client instance. + * + * Parameters: + * mosq - a struct mosquitto pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_destroy(struct mosquitto *mosq); + +/* + * Function: mosquitto_reinitialise + * + * This function allows an existing mosquitto client to be reused. Call on a + * mosquitto instance to close any open network connections, free memory + * and reinitialise the client with the new parameters. The end result is the + * same as the output of . + * + * Parameters: + * mosq - a valid mosquitto instance. + * id - string to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *obj); + + +/* ====================================================================== + * + * Section: Will + * + * ====================================================================== */ +/* + * Function: mosquitto_will_set + * + * Configure will information for a mosquitto instance. By default, clients do + * not have a will. This must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + */ +libmosq_EXPORT int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + +/* + * Function: mosquitto_will_set_v5 + * + * Configure will information for a mosquitto instance, with attached + * properties. By default, clients do not have a will. This must be called + * before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * properties - list of MQTT 5 properties. Can be NULL. On success only, the + * property list becomes the property of libmosquitto once this + * function is called and will be freed by the library. The + * property list must be freed by the application on error. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + * MOSQ_ERR_NOT_SUPPORTED - if properties is not NULL and the client is not + * using MQTT v5 + * MOSQ_ERR_PROTOCOL - if a property is invalid for use with wills. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + */ +libmosq_EXPORT int mosquitto_will_set_v5(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties); + +/* + * Function: mosquitto_will_clear + * + * Remove a previously configured will. This must be called before calling + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_will_clear(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Username and password + * + * ====================================================================== */ +/* + * Function: mosquitto_username_pw_set + * + * Configure username and password for a mosquitto instance. By default, no + * username or password will be sent. For v3.1 and v3.1.1 clients, if username + * is NULL, the password argument is ignored. + * + * This is must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * username - the username to send as a string, or NULL to disable + * authentication. + * password - the password to send as a string. Set to NULL when username is + * valid in order to send just a username. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password); + + +/* ====================================================================== + * + * Section: Connecting, reconnecting, disconnecting + * + * ====================================================================== */ +/* + * Function: mosquitto_connect + * + * Connect to an MQTT broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter. Use this function + * if you need to restrict network communication over a particular interface. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_bind_v5 + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter and MQTT v5 + * properties. Use this function if you need to restrict network communication + * over a particular interface. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * properties - the MQTT 5 properties for the connect (not for the Will). + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with CONNECT. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_v5(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, const mosquitto_property *properties); + +/* + * Function: mosquitto_connect_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * This extends the functionality of by adding the + * bind_address parameter. Use this function if you need to restrict network + * communication over a particular interface. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_async(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_srv + * + * Connect to an MQTT broker. + * + * If you set `host` to `example.com`, then this call will attempt to retrieve + * the DNS SRV record for `_secure-mqtt._tcp.example.com` or + * `_mqtt._tcp.example.com` to discover which actual host to connect to. + * + * DNS SRV support is not usually compiled in to libmosquitto, use of this call + * is not recommended. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname to search for an SRV record. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_srv(struct mosquitto *mosq, const char *host, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_reconnect + * + * Reconnect to a broker. + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * call. It must not be called before + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_reconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_reconnect_async + * + * Reconnect to a broker. Non blocking version of . + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * or calls. It must not be + * called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reconnect_async(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect + * + * Disconnect from the broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + */ +libmosq_EXPORT int mosquitto_disconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect_v5 + * + * Disconnect from the broker, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * reason_code - the disconnect reason code. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with DISCONNECT. + */ +libmosq_EXPORT int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Publishing, subscribing, unsubscribing + * + * ====================================================================== */ +/* + * Function: mosquitto_publish + * + * Publish a message on a given topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + + +/* + * Function: mosquitto_publish_v5 + * + * Publish a message on a given topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Requires the mosquitto instance to be connected with MQTT 5. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with PUBLISH. + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_publish_v5( + struct mosquitto *mosq, + int *mid, + const char *topic, + int payloadlen, + const void *payload, + int qos, + bool retain, + const mosquitto_property *properties); + + +/* + * Function: mosquitto_subscribe + * + * Subscribe to a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos); + +/* + * Function: mosquitto_subscribe_v5 + * + * Subscribe to a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Requires the mosquitto instance to be connected with MQTT 5. + * + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * options - options to apply to this subscription, OR'd together. Set to 0 to + * use the default options, otherwise choose from the list: + * MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client + * publishes to a topic to which it is subscribed, the + * broker will not publish the message back to the + * client. + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages + * published for this subscription will keep the + * retain flag as was set by the publishing client. + * The default behaviour without this option set has + * the retain flag indicating whether a message is + * fresh/stale. + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set, + * pre-existing retained messages are sent as soon as + * the subscription is made, even if the subscription + * already exists. This is the default behaviour, so + * it is not necessary to set this option. + * MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing + * retained messages for this subscription will be + * sent when the subscription is made, but only if the + * subscription does not already exist. + * MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set, + * pre-existing retained messages will never be sent + * for this subscription. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with SUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_subscribe_multiple + * + * Subscribe to multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of subscriptions to be made + * sub - array of sub_count pointers, each pointing to a subscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * qos - the requested Quality of Service for each subscription. + * options - options to apply to this subscription, OR'd together. This + * argument is not used for MQTT v3 susbcriptions. Set to 0 to use + * the default options, otherwise choose from the list: + * MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client + * publishes to a topic to which it is subscribed, the + * broker will not publish the message back to the + * client. + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages + * published for this subscription will keep the + * retain flag as was set by the publishing client. + * The default behaviour without this option set has + * the retain flag indicating whether a message is + * fresh/stale. + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set, + * pre-existing retained messages are sent as soon as + * the subscription is made, even if the subscription + * already exists. This is the default behaviour, so + * it is not necessary to set this option. + * MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing + * retained messages for this subscription will be + * sent when the subscription is made, but only if the + * subscription does not already exist. + * MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set, + * pre-existing retained messages will never be sent + * for this subscription. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe + * + * Unsubscribe from a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub); + +/* + * Function: mosquitto_unsubscribe_v5 + * + * Unsubscribe from a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with UNSUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe_multiple + * + * Unsubscribe from multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of unsubscriptions to be made + * sub - array of sub_count pointers, each pointing to an unsubscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Struct mosquitto_message helper functions + * + * ====================================================================== */ +/* + * Function: mosquitto_message_copy + * + * Copy the contents of a mosquitto message to another message. + * Useful for preserving a message received in the on_message() callback. + * + * Parameters: + * dst - a pointer to a valid mosquitto_message struct to copy to. + * src - a pointer to a valid mosquitto_message struct to copy from. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src); + +/* + * Function: mosquitto_message_free + * + * Completely free a mosquitto_message struct. + * + * Parameters: + * message - pointer to a mosquitto_message pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_message_free(struct mosquitto_message **message); + +/* + * Function: mosquitto_message_free_contents + * + * Free a mosquitto_message struct contents, leaving the struct unaffected. + * + * Parameters: + * message - pointer to a mosquitto_message struct to free its contents. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_message_free_contents(struct mosquitto_message *message); + + +/* ====================================================================== + * + * Section: Network loop (managed by libmosquitto) + * + * The internal network loop must be called at a regular interval. The two + * recommended approaches are to use either or + * . is a blocking call and is + * suitable for the situation where you only want to handle incoming messages + * in callbacks. is a non-blocking call, it creates a + * separate thread to run the loop for you. Use this function when you have + * other tasks you need to run at the same time as the MQTT client, e.g. + * reading data from a sensor. + * + * ====================================================================== */ + +/* + * Function: mosquitto_loop_forever + * + * This function call loop() for you in an infinite blocking loop. It is useful + * for the case where you only want to run the MQTT client loop in your + * program. + * + * It handles reconnecting in case server connection is lost. If you call + * mosquitto_disconnect() in a callback it will return. + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets); + +/* + * Function: mosquitto_loop_start + * + * This is part of the threaded client interface. Call this once to start a new + * thread to process network traffic. This provides an alternative to + * repeatedly calling yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_start(struct mosquitto *mosq); + +/* + * Function: mosquitto_loop_stop + * + * This is part of the threaded client interface. Call this once to stop the + * network thread previously created with . This call + * will block until the network thread finishes. For the network thread to end, + * you must have previously called or have set the force + * parameter to true. + * + * Parameters: + * mosq - a valid mosquitto instance. + * force - set to true to force thread cancellation. If false, + * must have already been called. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_stop(struct mosquitto *mosq, bool force); + +/* + * Function: mosquitto_loop + * + * The main network loop for the client. This must be called frequently + * to keep communications between the client and broker working. This is + * carried out by and , which + * are the recommended ways of handling the network loop. You may also use this + * function if you wish. It must not be called inside a callback. + * + * If incoming data is present it will then be processed. Outgoing commands, + * from e.g. , are normally sent immediately that their + * function is called, but this is not always possible. will + * also attempt to send any remaining outgoing messages, which also includes + * commands that are part of the flow for messages with QoS>0. + * + * This calls select() to monitor the client network socket. If you want to + * integrate mosquitto client operation with your own select() call, use + * , , and + * . + * + * Threads: + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets); + +/* ====================================================================== + * + * Section: Network loop (for use in other event loops) + * + * ====================================================================== */ +/* + * Function: mosquitto_loop_read + * + * Carry out network read operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_read(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_write + * + * Carry out network write operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_write(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_misc + * + * Carry out miscellaneous operations required as part of the network loop. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * This function deals with handling PINGs and checking whether messages need + * to be retried, so should be called fairly frequently, around once per second + * is sufficient. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_misc(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Network loop (helper functions) + * + * ====================================================================== */ +/* + * Function: mosquitto_socket + * + * Return the socket handle for a mosquitto instance. Useful if you want to + * include a mosquitto client in your own select() calls. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * The socket for the mosquitto client or -1 on failure. + */ +libmosq_EXPORT int mosquitto_socket(struct mosquitto *mosq); + +/* + * Function: mosquitto_want_write + * + * Returns true if there is data ready to be written on the socket. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * See Also: + * , , + */ +libmosq_EXPORT bool mosquitto_want_write(struct mosquitto *mosq); + +/* + * Function: mosquitto_threaded_set + * + * Used to tell the library that your application is using threads, but not + * using . The library operates slightly differently when + * not in threaded mode in order to simplify its operation. If you are managing + * your own threads and do not use this function you will experience crashes + * due to race conditions. + * + * When using , this is set automatically. + * + * Parameters: + * mosq - a valid mosquitto instance. + * threaded - true if your application is using threads, false otherwise. + */ +libmosq_EXPORT int mosquitto_threaded_set(struct mosquitto *mosq, bool threaded); + + +/* ====================================================================== + * + * Section: Client options + * + * ====================================================================== */ +/* + * Function: mosquitto_opts_set + * + * Used to set options for the client. + * + * This function is deprecated, the replacement and + * functions should be used instead. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_PROTOCOL_VERSION + * Value must be an int, set to either MQTT_PROTOCOL_V31 or + * MQTT_PROTOCOL_V311. Must be set before the client connects. + * Defaults to MQTT_PROTOCOL_V31. + * + * MOSQ_OPT_SSL_CTX + * Pass an openssl SSL_CTX to be used when creating TLS connections + * rather than libmosquitto creating its own. This must be called + * before connecting to have any effect. If you use this option, the + * onus is on you to ensure that you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS + * Value must be an int set to 1 or 0. If set to 1, then the user + * specified SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the + * default options applied to it. This means that you only need to + * change the values that are relevant to you. If you use this + * option then you must configure the TLS options as normal, i.e. + * you should use to configure the cafile/capath + * as a minimum. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + +/* + * Function: mosquitto_int_option + * + * Used to set integer options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_PROTOCOL_VERSION - + * Value must be set to either MQTT_PROTOCOL_V31, + * MQTT_PROTOCOL_V311, or MQTT_PROTOCOL_V5. Must be set before the + * client connects. Defaults to MQTT_PROTOCOL_V311. + * + * MOSQ_OPT_RECEIVE_MAXIMUM - + * Value can be set between 1 and 65535 inclusive, and represents + * the maximum number of incoming QoS 1 and QoS 2 messages that this + * client wants to process at once. Defaults to 20. This option is + * not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the MQTT_PROP_RECEIVE_MAXIMUM property is in the + * proplist passed to mosquitto_connect_v5(), then that property + * will override this option. Using this option is the recommended + * method however. + * + * MOSQ_OPT_SEND_MAXIMUM - + * Value can be set between 1 and 65535 inclusive, and represents + * the maximum number of outgoing QoS 1 and QoS 2 messages that this + * client will attempt to have "in flight" at once. Defaults to 20. + * This option is not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the broker being connected to sends a + * MQTT_PROP_RECEIVE_MAXIMUM property that has a lower value than + * this option, then the broker provided value will be used. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS - + * If value is set to a non zero value, then the user specified + * SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the default + * options applied to it. This means that you only need to change + * the values that are relevant to you. If you use this option then + * you must configure the TLS options as normal, i.e. you should + * use to configure the cafile/capath as a + * minimum. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_TLS_OCSP_REQUIRED - + * Set whether OCSP checking on TLS connections is required. Set to + * 1 to enable checking, or 0 (the default) for no checking. + */ +libmosq_EXPORT int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t option, int value); + + +/* + * Function: mosquitto_void_option + * + * Used to set void* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_SSL_CTX - + * Pass an openssl SSL_CTX to be used when creating TLS connections + * rather than libmosquitto creating its own. This must be called + * before connecting to have any effect. If you use this option, the + * onus is on you to ensure that you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_void_option(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + +/* + * Function: mosquitto_max_inflight_messages_set + * + * This function is deprected. Use the function with the + * MOSQ_OPT_SEND_MAXIMUM option instead. + * + * Set the number of QoS 1 and 2 messages that can be "in flight" at one time. + * An in flight message is part way through its delivery flow. Attempts to send + * further messages with will result in the messages being + * queued until the number of in flight messages reduces. + * + * A higher number here results in greater message throughput, but if set + * higher than the maximum in flight messages on the broker may lead to + * delays in the messages being acknowledged. + * + * Set to 0 for no maximum. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_inflight_messages - the maximum number of inflight messages. Defaults + * to 20. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages); + +/* + * Function: mosquitto_message_retry_set + * + * This function now has no effect. + */ +libmosq_EXPORT void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry); + +/* + * Function: mosquitto_user_data_set + * + * When is called, the pointer given as the "obj" parameter + * will be passed to the callbacks as user data. The + * function allows this obj parameter to be updated at any time. This function + * will not modify the memory pointed to by the current user data pointer. If + * it is dynamically allocated memory you must free it yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * obj - A user pointer that will be passed as an argument to any callbacks + * that are specified. + */ +libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj); + +/* Function: mosquitto_userdata + * + * Retrieve the "userdata" variable for a mosquitto client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * A pointer to the userdata member variable. + */ +libmosq_EXPORT void *mosquitto_userdata(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: TLS support + * + * ====================================================================== */ +/* + * Function: mosquitto_tls_set + * + * Configure the client for certificate based SSL/TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Define the Certificate Authority certificates to be trusted (ie. the server + * certificate must be signed with one of these certificates) using cafile. + * + * If the server you are connecting to requires clients to provide a + * certificate, define certfile and keyfile with your client certificate and + * private key. If your private key is encrypted, provide a password callback + * function or you will have to enter the password at the command line. + * + * Parameters: + * mosq - a valid mosquitto instance. + * cafile - path to a file containing the PEM encoded trusted CA + * certificate files. Either cafile or capath must not be NULL. + * capath - path to a directory containing the PEM encoded trusted CA + * certificate files. See mosquitto.conf for more details on + * configuring this directory. Either cafile or capath must not + * be NULL. + * certfile - path to a file containing the PEM encoded certificate file + * for this client. If NULL, keyfile must also be NULL and no + * client certificate will be used. + * keyfile - path to a file containing the PEM encoded private key for + * this client. If NULL, certfile must also be NULL and no + * client certificate will be used. + * pw_callback - if keyfile is encrypted, set pw_callback to allow your client + * to pass the correct password for decryption. If set to NULL, + * the password must be entered on the command line. + * Your callback must write the password into "buf", which is + * "size" bytes long. The return value must be the length of the + * password. "userdata" will be set to the calling mosquitto + * instance. The mosquitto userdata member variable can be + * retrieved using . + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , , + * , + */ +libmosq_EXPORT int mosquitto_tls_set(struct mosquitto *mosq, + const char *cafile, const char *capath, + const char *certfile, const char *keyfile, + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)); + +/* + * Function: mosquitto_tls_insecure_set + * + * Configure verification of the server hostname in the server certificate. If + * value is set to true, it is impossible to guarantee that the host you are + * connecting to is not impersonating your server. This can be useful in + * initial server testing, but makes it possible for a malicious third party to + * impersonate your server through DNS spoofing, for example. + * Do not use this function in a real system. Setting value to true makes the + * connection encryption pointless. + * Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * value - if set to false, the default, certificate hostname checking is + * performed. If set to true, no hostname checking is performed and + * the connection is insecure. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_insecure_set(struct mosquitto *mosq, bool value); + +/* + * Function: mosquitto_tls_opts_set + * + * Set advanced SSL/TLS options. Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * cert_reqs - an integer defining the verification requirements the client + * will impose on the server. This can be one of: + * * SSL_VERIFY_NONE (0): the server will not be verified in any way. + * * SSL_VERIFY_PEER (1): the server certificate will be verified + * and the connection aborted if the verification fails. + * The default and recommended value is SSL_VERIFY_PEER. Using + * SSL_VERIFY_NONE provides no security. + * tls_version - the version of the SSL/TLS protocol to use as a string. If NULL, + * the default value is used. The default value and the + * available values depend on the version of openssl that the + * library was compiled against. For openssl >= 1.0.1, the + * available options are tlsv1.2, tlsv1.1 and tlsv1, with tlv1.2 + * as the default. For openssl < 1.0.1, only tlsv1 is available. + * ciphers - a string describing the ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tls_version, const char *ciphers); + +/* + * Function: mosquitto_tls_psk_set + * + * Configure the client for pre-shared-key based TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Parameters: + * mosq - a valid mosquitto instance. + * psk - the pre-shared-key in hex format with no leading "0x". + * identity - the identity of this client. May be used as the username + * depending on the server settings. + * ciphers - a string describing the PSK ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers); + + +/* ====================================================================== + * + * Section: Callbacks + * + * ====================================================================== */ +/* + * Function: mosquitto_connect_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_connect_with_flags_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * flags - the connect flags. + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int)); + +/* + * Function: mosquitto_connect_v5_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + * flags - the connect flags. + * props - list of MQTT 5 properties, or NULL + * + */ +libmosq_EXPORT void mosquitto_connect_v5_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int, const mosquitto_property *props)); + +/* + * Function: mosquitto_disconnect_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + */ +libmosq_EXPORT void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_disconnect_v5_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_disconnect_v5_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *)); + +/* + * Function: mosquitto_publish_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker successfully. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + */ +libmosq_EXPORT void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_publish_v5_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker. This callback will be + * called both if the message is sent successfully, or if the broker responded + * with an error, which will be reflected in the reason_code parameter. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + * reason_code - the MQTT 5 reason code + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_publish_v5_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int, int, const mosquitto_property *)); + +/* + * Function: mosquitto_message_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *)); + +/* + * Function: mosquitto_message_v5_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * props - list of MQTT 5 properties, or NULL + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_v5_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *, const mosquitto_property *)); + +/* + * Function: mosquitto_subscribe_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + */ +libmosq_EXPORT void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *)); + +/* + * Function: mosquitto_subscribe_v5_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_subscribe_v5_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *)); + +/* + * Function: mosquitto_unsubscribe_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + */ +libmosq_EXPORT void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_unsubscribe_v5_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, const mosquitto_property *)); + +/* + * Function: mosquitto_log_callback_set + * + * Set the logging callback. This should be used if you want event logging + * information from the client library. + * + * mosq - a valid mosquitto instance. + * on_log - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int level, const char *str) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * level - the log message level from the values: + * MOSQ_LOG_INFO + * MOSQ_LOG_NOTICE + * MOSQ_LOG_WARNING + * MOSQ_LOG_ERR + * MOSQ_LOG_DEBUG + * str - the message string. + */ +libmosq_EXPORT void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *)); + +/* + * Function: mosquitto_string_option + * + * Used to set const char* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_TLS_ENGINE + * Configure the client for TLS Engine support. Pass a TLS Engine ID + * to be used when creating TLS connections. + * Must be set before . + * MOSQ_OPT_TLS_KEYFORM + * Configure the client to treat the keyfile differently depending + * on its type. Must be set before . + * Set as either "pem" or "engine", to determine from where the + * private key for a TLS connection will be obtained. Defaults to + * "pem", a normal private key file. + * MOSQ_OPT_TLS_KPASS_SHA1 + * Where the TLS Engine requires the use of a password to be + * accessed, this option allows a hex encoded SHA1 hash of the + * private key password to be passed to the engine directly. + * Must be set before . + * MOSQ_OPT_TLS_ALPN + * If the broker being connected to has multiple services available + * on a single TLS port, such as both MQTT and WebSockets, use this + * option to configure the ALPN option for the connection. + */ +libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value); + + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + + +/* ============================================================================= + * + * Section: SOCKS5 proxy functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_socks5_set + * + * Configure the client to use a SOCKS5 proxy when connecting. Must be called + * before connecting. "None" and "username/password" authentication is + * supported. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the SOCKS5 proxy host to connect to. + * port - the SOCKS5 proxy port to use. + * username - if not NULL, use this username when authenticating with the proxy. + * password - if not NULL and username is not NULL, use this password when + * authenticating with the proxy. + */ +libmosq_EXPORT int mosquitto_socks5_set(struct mosquitto *mosq, const char *host, int port, const char *username, const char *password); + + +/* ============================================================================= + * + * Section: Utility functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_strerror + * + * Call to obtain a const string description of a mosquitto error number. + * + * Parameters: + * mosq_errno - a mosquitto error number. + * + * Returns: + * A constant string describing the error. + */ +libmosq_EXPORT const char *mosquitto_strerror(int mosq_errno); + +/* + * Function: mosquitto_connack_string + * + * Call to obtain a const string description of an MQTT connection result. + * + * Parameters: + * connack_code - an MQTT connection result. + * + * Returns: + * A constant string describing the result. + */ +libmosq_EXPORT const char *mosquitto_connack_string(int connack_code); + +/* + * Function: mosquitto_reason_string + * + * Call to obtain a const string description of an MQTT reason code. + * + * Parameters: + * reason_code - an MQTT reason code. + * + * Returns: + * A constant string describing the reason. + */ +libmosq_EXPORT const char *mosquitto_reason_string(int reason_code); + +/* Function: mosquitto_string_to_command + * + * Take a string input representing an MQTT command and convert it to the + * libmosquitto integer representation. + * + * Parameters: + * str - the string to parse. + * cmd - pointer to an int, for the result. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - on an invalid input. + * + * Example: + * mosquitto_string_to_command("CONNECT", &cmd); + * // cmd == CMD_CONNECT + */ +libmosq_EXPORT int mosquitto_string_to_command(const char *str, int *cmd); + +/* + * Function: mosquitto_sub_topic_tokenise + * + * Tokenise a topic or subscription string into an array of strings + * representing the topic hierarchy. + * + * For example: + * + * subtopic: "a/deep/topic/hierarchy" + * + * Would result in: + * + * topics[0] = "a" + * topics[1] = "deep" + * topics[2] = "topic" + * topics[3] = "hierarchy" + * + * and: + * + * subtopic: "/a/deep/topic/hierarchy/" + * + * Would result in: + * + * topics[0] = NULL + * topics[1] = "a" + * topics[2] = "deep" + * topics[3] = "topic" + * topics[4] = "hierarchy" + * + * Parameters: + * subtopic - the subscription/topic to tokenise + * topics - a pointer to store the array of strings + * count - an int pointer to store the number of items in the topics array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * + * Example: + * + * > char **topics; + * > int topic_count; + * > int i; + * > + * > mosquitto_sub_topic_tokenise("$SYS/broker/uptime", &topics, &topic_count); + * > + * > for(i=0; i printf("%d: %s\n", i, topics[i]); + * > } + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *count); + +/* + * Function: mosquitto_sub_topic_tokens_free + * + * Free memory that was allocated in . + * + * Parameters: + * topics - pointer to string array. + * count - count of items in string array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokens_free(char ***topics, int count); + +/* + * Function: mosquitto_topic_matches_sub + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * topic - topic to check. + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result); + + +/* + * Function: mosquitto_topic_matches_sub2 + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * sublen - length in bytes of sub string + * topic - topic to check. + * topiclen - length in bytes of topic string + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub2(const char *sub, size_t sublen, const char *topic, size_t topiclen, bool *result); + +/* + * Function: mosquitto_pub_topic_check + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check(const char *topic); + +/* + * Function: mosquitto_pub_topic_check2 + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - length of the topic in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check2(const char *topic, size_t topiclen); + +/* + * Function: mosquitto_sub_topic_check + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check(const char *topic); + +/* + * Function: mosquitto_sub_topic_check2 + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - the length in bytes of the topic + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check2(const char *topic, size_t topiclen); + + +/* + * Function: mosquitto_validate_utf8 + * + * Helper function to validate whether a UTF-8 string is valid, according to + * the UTF-8 spec and the MQTT additions. + * + * Parameters: + * str - a string to check + * len - the length of the string in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if str is NULL or len<0 or len>65536 + * MOSQ_ERR_MALFORMED_UTF8 - if str is not valid UTF-8 + */ +libmosq_EXPORT int mosquitto_validate_utf8(const char *str, int len); + + +/* ============================================================================= + * + * Section: One line client helper functions + * + * ============================================================================= + */ + +struct libmosquitto_will { + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct libmosquitto_auth { + char *username; + char *password; +}; + +struct libmosquitto_tls { + char *cafile; + char *capath; + char *certfile; + char *keyfile; + char *ciphers; + char *tls_version; + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata); + int cert_reqs; +}; + +/* + * Function: mosquitto_subscribe_simple + * + * Helper function to make subscribing to a topic and retrieving some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, waits for msg_count + * messages to be received, then returns after disconnecting cleanly. + * + * Parameters: + * messages - pointer to a "struct mosquitto_message *". The received + * messages will be returned here. On error, this will be set to + * NULL. + * msg_count - the number of messages to retrieve. + * want_retained - if set to true, stale retained messages will be treated as + * normal messages with regards to msg_count. If set to + * false, they will be ignored. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * >0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool want_retained, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* + * Function: mosquitto_subscribe_callback + * + * Helper function to make subscribing to a topic and processing some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, then passes received + * messages to a user provided callback. If the callback returns a 1, it then + * disconnects cleanly and returns. + * + * Parameters: + * callback - a callback function in the following form: + * int callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * Note that this is the same as the normal on_message callback, + * except that it returns an int. + * userdata - user provided pointer that will be passed to the callback. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * >0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* ============================================================================= + * + * Section: Properties + * + * ============================================================================= + */ + + +/* + * Function: mosquitto_property_add_byte + * + * Add a new byte property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_byte(&proplist, MQTT_PROP_PAYLOAD_FORMAT_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value); + +/* + * Function: mosquitto_property_add_int16 + * + * Add a new int16 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_RECEIVE_MAXIMUM) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_int16(&proplist, MQTT_PROP_RECEIVE_MAXIMUM, 1000); + */ +libmosq_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value); + +/* + * Function: mosquitto_property_add_int32 + * + * Add a new int32 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_MESSAGE_EXPIRY_INTERVAL) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_int32(&proplist, MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, 86400); + */ +libmosq_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_varint + * + * Add a new varint property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_SUBSCRIPTION_IDENTIFIER) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_varint(&proplist, MQTT_PROP_SUBSCRIPTION_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_binary + * + * Add a new binary property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to the property data + * len - length of property data in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_binary(&proplist, MQTT_PROP_AUTHENTICATION_DATA, auth_data, auth_data_len); + */ +libmosq_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len); + +/* + * Function: mosquitto_property_add_string + * + * Add a new string property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_CONTENT_TYPE) + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - value is not valid UTF-8. + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_string(&proplist, MQTT_PROP_CONTENT_TYPE, "application/json"); + */ +libmosq_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value); + +/* + * Function: mosquitto_property_add_string_pair + * + * Add a new string pair property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_USER_PROPERTY) + * name - string name for the new property, must be UTF-8 and zero terminated + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if name or value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - if name or value are not valid UTF-8. + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_string_pair(&proplist, MQTT_PROP_USER_PROPERTY, "client", "mosquitto_pub"); + */ +libmosq_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value); + +/* + * Function: mosquitto_property_read_byte + * + * Attempt to read a byte property matching an identifier, from a property list + * or single property. This function can search for multiple entries of the + * same identifier by using the returned value and skip_first. Note however + * that it is forbidden for most properties to be duplicated. + * + * If the property is not found, *value will not be modified, so it is safe to + * pass a variable with a default value to be potentially overwritten: + * + * uint16_t keepalive = 60; // default value + * // Get value from property list, or keep default if not found. + * mosquitto_property_read_int16(proplist, MQTT_PROP_SERVER_KEEP_ALIVE, &keepalive, false); + * + * Parameters: + * proplist - mosquitto_property pointer, the list of properties or single property + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * // proplist is obtained from a callback + * mosquitto_property *prop; + * prop = mosquitto_property_read_byte(proplist, identifier, &value, false); + * while(prop){ + * printf("value: %s\n", value); + * prop = mosquitto_property_read_byte(prop, identifier, &value); + * } + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_byte( + const mosquitto_property *proplist, + int identifier, + uint8_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int16 + * + * Read an int16 property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int16( + const mosquitto_property *proplist, + int identifier, + uint16_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int32 + * + * Read an int32 property value from a property. + * + * Parameters: + * property - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int32( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_varint + * + * Read a varint property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_varint( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_binary + * + * Read a binary property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_binary( + const mosquitto_property *proplist, + int identifier, + void **value, + uint16_t *len, + bool skip_first); + +/* + * Function: mosquitto_property_read_string + * + * Read a string property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string( + const mosquitto_property *proplist, + int identifier, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_read_string_pair + * + * Read a string pair property value pair from a property. + * + * On success, name and value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * name - pointer to char* for the name property data to be stored in, or NULL + * if the name is not required. + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string_pair( + const mosquitto_property *proplist, + int identifier, + char **name, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_free_all + * + * Free all properties from a list of properties. Frees the list and sets *properties to NULL. + * + * Parameters: + * properties - list of properties to free + * + * Example: + * mosquitto_properties *properties = NULL; + * // Add properties + * mosquitto_property_free_all(&properties); + */ +libmosq_EXPORT void mosquitto_property_free_all(mosquitto_property **properties); + +/* + * Function: mosquitto_property_copy_all + * + * Parameters: + * dest : pointer for new property list + * src : property list + * + * Returns: + * MOSQ_ERR_SUCCESS - on successful copy + * MOSQ_ERR_INVAL - if dest is NULL + * MOSQ_ERR_NOMEM - on out of memory (dest will be set to NULL) + */ +libmosq_EXPORT int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_property *src); + +/* + * Function: mosquitto_property_check_command + * + * Check whether a property identifier is valid for the given command. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * identifier - MQTT property (e.g. MQTT_PROP_USER_PROPERTY) + * + * Returns: + * MOSQ_ERR_SUCCESS - if the identifier is valid for command + * MOSQ_ERR_PROTOCOL - if the identifier is not valid for use with command. + */ +libmosq_EXPORT int mosquitto_property_check_command(int command, int identifier); + + +/* + * Function: mosquitto_property_check_all + * + * Check whether a list of properties are valid for a particular command, + * whether there are duplicates, and whether the values are valid where + * possible. + * + * Note that this function is used internally in the library whenever + * properties are passed to it, so in basic use this is not needed, but should + * be helpful to check property lists *before* the point of using them. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * properties - list of MQTT properties to check. + * + * Returns: + * MOSQ_ERR_SUCCESS - if all properties are valid + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid + */ +libmosq_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties); + +/* Function: mosquitto_string_to_property_info + * + * Parse a property name string and convert to a property identifier and data type. + * The property name is as defined in the MQTT specification, with - as a + * separator, for example: payload-format-indicator. + * + * Parameters: + * propname - the string to parse + * identifier - pointer to an int to receive the property identifier + * type - pointer to an int to receive the property type + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the string does not match a property + * + * Example: + * mosquitto_string_to_property_info("response-topic", &id, &type); + * // id == MQTT_PROP_RESPONSE_TOPIC + * // type == MQTT_PROP_TYPE_STRING + */ +libmosq_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/yxcloud_mqtt_s/mosquitto_plugin.h b/product/src/fes/protocol/yxcloud_mqtt_s/mosquitto_plugin.h new file mode 100644 index 00000000..b2ef79d0 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_s/mosquitto_plugin.h @@ -0,0 +1,319 @@ +/* +Copyright (c) 2012-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_PLUGIN_H +#define MOSQUITTO_PLUGIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MOSQ_AUTH_PLUGIN_VERSION 4 + +#define MOSQ_ACL_NONE 0x00 +#define MOSQ_ACL_READ 0x01 +#define MOSQ_ACL_WRITE 0x02 +#define MOSQ_ACL_SUBSCRIBE 0x04 + +#include +#include + +struct mosquitto; + +struct mosquitto_opt { + char *key; + char *value; +}; + +struct mosquitto_auth_opt { + char *key; + char *value; +}; + +struct mosquitto_acl_msg { + const char *topic; + const void *payload; + long payloadlen; + int qos; + bool retain; +}; + +/* + * To create an authentication plugin you must include this file then implement + * the functions listed in the "Plugin Functions" section below. The resulting + * code should then be compiled as a shared library. Using gcc this can be + * achieved as follows: + * + * gcc -I -fPIC -shared plugin.c -o plugin.so + * + * On Mac OS X: + * + * gcc -I -fPIC -shared plugin.c -undefined dynamic_lookup -o plugin.so + * + * Authentication plugins can implement one or both of authentication and + * access control. If your plugin does not wish to handle either of + * authentication or access control it should return MOSQ_ERR_PLUGIN_DEFER. In + * this case, the next plugin will handle it. If all plugins return + * MOSQ_ERR_PLUGIN_DEFER, the request will be denied. + * + * For each check, the following flow happens: + * + * * The default password file and/or acl file checks are made. If either one + * of these is not defined, then they are considered to be deferred. If either + * one accepts the check, no further checks are made. If an error occurs, the + * check is denied + * * The first plugin does the check, if it returns anything other than + * MOSQ_ERR_PLUGIN_DEFER, then the check returns immediately. If the plugin + * returns MOSQ_ERR_PLUGIN_DEFER then the next plugin runs its check. + * * If the final plugin returns MOSQ_ERR_PLUGIN_DEFER, then access will be + * denied. + */ + +/* ========================================================================= + * + * Helper Functions + * + * ========================================================================= */ + +/* There are functions that are available for plugin developers to use in + * mosquitto_broker.h, including logging and accessor functions. + */ + + +/* ========================================================================= + * + * Plugin Functions + * + * You must implement these functions in your plugin. + * + * ========================================================================= */ + +/* + * Function: mosquitto_auth_plugin_version + * + * The broker will call this function immediately after loading the plugin to + * check it is a supported plugin version. Your code must simply return + * MOSQ_AUTH_PLUGIN_VERSION. + */ +int mosquitto_auth_plugin_version(void); + + +/* + * Function: mosquitto_auth_plugin_init + * + * Called after the plugin has been loaded and + * has been called. This will only ever be called once and can be used to + * initialise the plugin. + * + * Parameters: + * + * user_data : The pointer set here will be passed to the other plugin + * functions. Use to hold connection information for example. + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_plugin_cleanup + * + * Called when the broker is shutting down. This will only ever be called once + * per plugin. + * Note that will be called directly before + * this function. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_security_init + * + * This function is called in two scenarios: + * + * 1. When the broker starts up. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, will be called first, then + * this function will be called. In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_init(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_security_cleanup + * + * This function is called in two scenarios: + * + * 1. When the broker is shutting down. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, this function will be called, followed by + * . In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_acl_check + * + * Called by the broker when topic access must be checked. access will be one + * of: + * MOSQ_ACL_SUBSCRIBE when a client is asking to subscribe to a topic string. + * This differs from MOSQ_ACL_READ in that it allows you to + * deny access to topic strings rather than by pattern. For + * example, you may use MOSQ_ACL_SUBSCRIBE to deny + * subscriptions to '#', but allow all topics in + * MOSQ_ACL_READ. This allows clients to subscribe to any + * topic they want, but not discover what topics are in use + * on the server. + * MOSQ_ACL_READ when a message is about to be sent to a client (i.e. whether + * it can read that topic or not). + * MOSQ_ACL_WRITE when a message has been received from a client (i.e. whether + * it can write to that topic or not). + * + * Return: + * MOSQ_ERR_SUCCESS if access was granted. + * MOSQ_ERR_ACL_DENIED if access was not granted. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_acl_check(void *user_data, int access, struct mosquitto *client, const struct mosquitto_acl_msg *msg); + + +/* + * Function: mosquitto_auth_unpwd_check + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making basic username/password checks. + * + * Called by the broker when a username/password must be checked. + * + * Return: + * MOSQ_ERR_SUCCESS if the user is authenticated. + * MOSQ_ERR_AUTH if authentication failed. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_unpwd_check(void *user_data, struct mosquitto *client, const char *username, const char *password); + + +/* + * Function: mosquitto_psk_key_get + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making TLS-PSK checks. + * + * Called by the broker when a client connects to a listener using TLS/PSK. + * This is used to retrieve the pre-shared-key associated with a client + * identity. + * + * Examine hint and identity to determine the required PSK (which must be a + * hexadecimal string with no leading "0x") and copy this string into key. + * + * Parameters: + * user_data : the pointer provided in . + * hint : the psk_hint for the listener the client is connecting to. + * identity : the identity string provided by the client + * key : a string where the hex PSK should be copied + * max_key_len : the size of key + * + * Return value: + * Return 0 on success. + * Return >0 on failure. + * Return MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_psk_key_get(void *user_data, struct mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len); + +/* + * Function: mosquitto_auth_start + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making extended authentication checks. + * + * Parameters: + * user_data : the pointer provided in . + * method : the authentication method + * reauth : this is set to false if this is the first authentication attempt + * on a connection, set to true if the client is attempting to + * reauthenticate. + * data_in : pointer to authentication data, or NULL + * data_in_len : length of data_in, in bytes + * data_out : if your plugin wishes to send authentication data back to the + * client, allocate some memory using malloc or friends and set + * data_out. The broker will free the memory after use. + * data_out_len : Set the length of data_out in bytes. + * + * Return value: + * Return MOSQ_ERR_SUCCESS if authentication was successful. + * Return MOSQ_ERR_AUTH_CONTINUE if the authentication is a multi step process and can continue. + * Return MOSQ_ERR_AUTH if authentication was valid but did not succeed. + * Return any other relevant positive integer MOSQ_ERR_* to produce an error. + */ +int mosquitto_auth_start(void *user_data, struct mosquitto *client, const char *method, bool reauth, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + +int mosquitto_auth_continue(void *user_data, struct mosquitto *client, const char *method, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/yxcloud_mqtt_s/mosquittopp.h b/product/src/fes/protocol/yxcloud_mqtt_s/mosquittopp.h new file mode 100644 index 00000000..d3f388c0 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_s/mosquittopp.h @@ -0,0 +1,146 @@ +/* +Copyright (c) 2010-2019 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTOPP_H +#define MOSQUITTOPP_H + +#if defined(_WIN32) && !defined(LIBMOSQUITTO_STATIC) +# ifdef mosquittopp_EXPORTS +# define mosqpp_EXPORT __declspec(dllexport) +# else +# define mosqpp_EXPORT __declspec(dllimport) +# endif +#else +# define mosqpp_EXPORT +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define DEPRECATED __attribute__ ((deprecated)) +#else +# define DEPRECATED +#endif + +#include +#include +#include + +namespace mosqpp { + + +mosqpp_EXPORT const char * DEPRECATED strerror(int mosq_errno); +mosqpp_EXPORT const char * DEPRECATED connack_string(int connack_code); +mosqpp_EXPORT int DEPRECATED sub_topic_tokenise(const char *subtopic, char ***topics, int *count); +mosqpp_EXPORT int DEPRECATED sub_topic_tokens_free(char ***topics, int count); +mosqpp_EXPORT int DEPRECATED lib_version(int *major, int *minor, int *revision); +mosqpp_EXPORT int DEPRECATED lib_init(); +mosqpp_EXPORT int DEPRECATED lib_cleanup(); +mosqpp_EXPORT int DEPRECATED topic_matches_sub(const char *sub, const char *topic, bool *result); +mosqpp_EXPORT int DEPRECATED validate_utf8(const char *str, int len); +mosqpp_EXPORT int DEPRECATED subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool retained, + const char *topic, + int qos=0, + const char *host="localhost", + int port=1883, + const char *client_id=NULL, + int keepalive=60, + bool clean_session=true, + const char *username=NULL, + const char *password=NULL, + const struct libmosquitto_will *will=NULL, + const struct libmosquitto_tls *tls=NULL); + +mosqpp_EXPORT int DEPRECATED subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos=0, + bool retained=true, + const char *host="localhost", + int port=1883, + const char *client_id=NULL, + int keepalive=60, + bool clean_session=true, + const char *username=NULL, + const char *password=NULL, + const struct libmosquitto_will *will=NULL, + const struct libmosquitto_tls *tls=NULL); + +/* + * Class: mosquittopp + * + * A mosquitto client class. This is a C++ wrapper class for the mosquitto C + * library. Please see mosquitto.h for details of the functions. + */ +class mosqpp_EXPORT DEPRECATED mosquittopp { + private: + struct mosquitto *m_mosq; + public: + DEPRECATED mosquittopp(const char *id=NULL, bool clean_session=true); + virtual ~mosquittopp(); + + int DEPRECATED reinitialise(const char *id, bool clean_session); + int DEPRECATED socket(); + int DEPRECATED will_set(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int DEPRECATED will_clear(); + int DEPRECATED username_pw_set(const char *username, const char *password=NULL); + int DEPRECATED connect(const char *host, int port=1883, int keepalive=60); + int DEPRECATED connect_async(const char *host, int port=1883, int keepalive=60); + int DEPRECATED connect(const char *host, int port, int keepalive, const char *bind_address); + int DEPRECATED connect_async(const char *host, int port, int keepalive, const char *bind_address); + int DEPRECATED reconnect(); + int DEPRECATED reconnect_async(); + int DEPRECATED disconnect(); + int DEPRECATED publish(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int DEPRECATED subscribe(int *mid, const char *sub, int qos=0); + int DEPRECATED unsubscribe(int *mid, const char *sub); + void DEPRECATED reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + int DEPRECATED max_inflight_messages_set(unsigned int max_inflight_messages); + void DEPRECATED message_retry_set(unsigned int message_retry); + void DEPRECATED user_data_set(void *userdata); + int DEPRECATED tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL); + int DEPRECATED tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL); + int DEPRECATED tls_insecure_set(bool value); + int DEPRECATED tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL); + int DEPRECATED opts_set(enum mosq_opt_t option, void *value); + + int DEPRECATED loop(int timeout=-1, int max_packets=1); + int DEPRECATED loop_misc(); + int DEPRECATED loop_read(int max_packets=1); + int DEPRECATED loop_write(int max_packets=1); + int DEPRECATED loop_forever(int timeout=-1, int max_packets=1); + int DEPRECATED loop_start(); + int DEPRECATED loop_stop(bool force=false); + bool DEPRECATED want_write(); + int DEPRECATED threaded_set(bool threaded=true); + int DEPRECATED socks5_set(const char *host, int port=1080, const char *username=NULL, const char *password=NULL); + + // names in the functions commented to prevent unused parameter warning + virtual void on_connect(int /*rc*/) {return;} + virtual void on_connect_with_flags(int /*rc*/, int /*flags*/) {return;} + virtual void on_disconnect(int /*rc*/) {return;} + virtual void on_publish(int /*mid*/) {return;} + virtual void on_message(const struct mosquitto_message * /*message*/) {return;} + virtual void on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/) {return;} + virtual void on_unsubscribe(int /*mid*/) {return;} + virtual void on_log(int /*level*/, const char * /*str*/) {return;} + virtual void on_error() {return;} +}; + +} +#endif diff --git a/product/src/fes/protocol/yxcloud_mqtt_s/yxcloud_mqtt_s.pro b/product/src/fes/protocol/yxcloud_mqtt_s/yxcloud_mqtt_s.pro new file mode 100644 index 00000000..50c348d0 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_s/yxcloud_mqtt_s.pro @@ -0,0 +1,47 @@ +# ARM板上资源有限,不会与云平台混用,不编译 +message("Compile only in x86 environment") +# requires(contains(QMAKE_HOST.arch, x86_64)) +requires(!contains(QMAKE_HOST.arch, aarch64):!linux-aarch64*) + +QT -= core gui +CONFIG -= qt + +TARGET = yxcloud_mqtt_s +TEMPLATE = lib + + +SOURCES += \ + Yxcloudmqtts.cpp \ + YxcloudmqttsDataProcThread.cpp \ + Md5/Md5.cpp \ + cJSON.c \ + +HEADERS += \ + Yxcloudmqtts.h \ + YxcloudmqttsDataProcThread.h \ + mosquitto.h \ + mosquitto_plugin.h \ + mosquittopp.h \ + Md5/Md5.h \ + cJSON.h \ + + +INCLUDEPATH += \ + ../../include/ \ + ../../../include/ \ + ../../../3rd/include/ + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase +LIBS += -lmosquitto -lmosquittopp + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/CMQTTClient.cpp b/product/src/fes/protocol/yxcloud_mqtt_wn/CMQTTClient.cpp new file mode 100644 index 00000000..f913c645 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/CMQTTClient.cpp @@ -0,0 +1,14 @@ +#include "CMQTTClient.h" + +namespace Yxcloud { + +CMQTTClient::CMQTTClient() +{ + +} + +CMQTTClient::~CMQTTClient() +{ + +} +} diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/CMQTTClient.h b/product/src/fes/protocol/yxcloud_mqtt_wn/CMQTTClient.h new file mode 100644 index 00000000..32bb5333 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/CMQTTClient.h @@ -0,0 +1,13 @@ +#ifndef CMQTTCLIENT_H +#define CMQTTCLIENT_H + +namespace Yxcloud { +class CMQTTClient +{ +public: + CMQTTClient(); + ~CMQTTClient(); + +}; +} +#endif // CMQTTCLIENT_H diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/CMQTTDataThread.cpp b/product/src/fes/protocol/yxcloud_mqtt_wn/CMQTTDataThread.cpp new file mode 100644 index 00000000..8e60f4f7 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/CMQTTDataThread.cpp @@ -0,0 +1,36 @@ +#include "CMQTTDataThread.h" +#include "CMQTTClient.h" + +const int gCMQTTDataThreadTime = 10; + +namespace Yxcloud { + +CMQTTDataThread::CMQTTDataThread():CTimerThreadBase("CMQTTDataThread", gCMQTTDataThreadTime,0,true) +{ + +} + +int CMQTTDataThread::beforeExecute() +{ + return iotSuccess; +} + +void CMQTTDataThread::execute() +{ + +} + +void CMQTTDataThread::beforeQuit() +{ + +} + +CMQTTDataThread::~CMQTTDataThread() +{ + +} + + +} + + diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/CMQTTDataThread.h b/product/src/fes/protocol/yxcloud_mqtt_wn/CMQTTDataThread.h new file mode 100644 index 00000000..ebec8bc9 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/CMQTTDataThread.h @@ -0,0 +1,63 @@ +#ifndef CMQTTDATATHREAD_H +#define CMQTTDATATHREAD_H +#include "mosquitto.h" +#include "mosquittopp.h" +#include +#include "DataType.h" +#include +#include "pub_utility_api/TimerThreadBase.h" +#include "YxcloudmqttsDataProcThread.h" +#include "CMQTTClient.h" + +namespace Yxcloud { + + typedef struct { + byte RecvMsg[512]; + std::string receivedTopic = ""; + + }Message; + + enum class Status + { + SUCCESS=0, + FAILD=1 + }; + + + class CMQTTDataThread : public iot_public::CTimerThreadBase + { + public: + CMQTTDataThread(); + Status getData(Message & buffer);//获取数据 + Status publishData(std::string mqttTopic, std::string mqttPayload);//发布数据 + /* + @brief 执行execute函数前的处理 + */ + int beforeExecute() override; + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + void execute() override ; + void beforeQuit() override ; + ~CMQTTDataThread(); + private: + std::unique_ptr pMqttClient; + std::shared_ptr pAppData; + void MqttConnect(); + void MqttSubscribe(); + + private: + std::string convertToHesString(); + int8_t hexStringToUint8(const std::string& hexString); + + }; + + + + + + +} + + +#endif // CMQTTCLIENT_H diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/Md5/Md5.cpp b/product/src/fes/protocol/yxcloud_mqtt_wn/Md5/Md5.cpp new file mode 100644 index 00000000..c6664c5e --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/Md5/Md5.cpp @@ -0,0 +1,372 @@ +#include "Md5.h" + +//using namespace std; + +/* Constants for MD5Transform routine. */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + + +/* F, G, H and I are basic MD5 functions. +*/ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. +*/ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. +*/ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + ac; \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ +} + + +const byte MD5::PADDING[64] = { 0x80 }; +const char MD5::HEX[16] = +{ + '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f' +}; + +/* Default construct. */ +MD5::MD5() +{ + + reset(); +} + +/* Construct a MD5 object with a input buffer. */ +MD5::MD5(const void *input, size_t length) +{ + reset(); + update(input, length); +} + +/* Construct a MD5 object with a string. */ +MD5::MD5(const string &str) +{ + reset(); + update(str); +} + +/* Construct a MD5 object with a file. */ +MD5::MD5(ifstream &in) +{ + reset(); + update(in); +} + +/* Return the message-digest */ +const byte *MD5::digest() +{ + if (!_finished) + { + _finished = true; + final(); + } + return _digest; +} + +/* Reset the calculate state */ +void MD5::reset() +{ + + _finished = false; + /* reset number of bits. */ + _count[0] = _count[1] = 0; + /* Load magic initialization constants. */ + _state[0] = 0x67452301; + _state[1] = 0xefcdab89; + _state[2] = 0x98badcfe; + _state[3] = 0x10325476; +} + +/* Updating the context with a input buffer. */ +void MD5::update(const void *input, size_t length) +{ + update((const byte *)input, length); +} + +/* Updating the context with a string. */ +void MD5::update(const string &str) +{ + update((const byte *)str.c_str(), str.length()); +} + +/* Updating the context with a file. */ +void MD5::update(ifstream &in) +{ + + if (!in) + { + return; + } + + const size_t BUFFER_SIZE = 1024; + std::streamsize length; + char buffer[BUFFER_SIZE]; + while (!in.eof()) + { + in.read(buffer, BUFFER_SIZE); + length = in.gcount(); + if (length > 0) + { + update(buffer, length); + } + } + in.close(); +} + +/* MD5 block update operation. Continues an MD5 message-digest +operation, processing another message block, and updating the +context. +*/ +void MD5::update(const byte *input, size_t length) +{ + + uint32 i, index, partLen; + + _finished = false; + + /* Compute number of bytes mod 64 */ + index = (uint32)((_count[0] >> 3) & 0x3f); + + /* update number of bits */ + if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) + { + _count[1]++; + } + _count[1] += ((uint32)length >> 29); + + partLen = 64 - index; + + /* transform as many times as possible. */ + if (length >= partLen) + { + + memcpy(&_buffer[index], input, partLen); + transform(_buffer); + + for (i = partLen; i + 63 < length; i += 64) + { + transform(&input[i]); + } + index = 0; + + } + else + { + i = 0; + } + + /* Buffer remaining input */ + memcpy(&_buffer[index], &input[i], length - i); +} + +/* MD5 finalization. Ends an MD5 message-_digest operation, writing the +the message _digest and zeroizing the context. +*/ +void MD5::final() +{ + + byte bits[8]; + uint32 oldState[4]; + uint32 oldCount[2]; + uint32 index, padLen; + + /* Save current state and count. */ + memcpy(oldState, _state, 16); + memcpy(oldCount, _count, 8); + + /* Save number of bits */ + encode(_count, bits, 8); + + /* Pad out to 56 mod 64. */ + index = (uint32)((_count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + update(PADDING, padLen); + + /* Append length (before padding) */ + update(bits, 8); + + /* Store state in digest */ + encode(_state, _digest, 16); + + /* Restore current state and count. */ + memcpy(_state, oldState, 16); + memcpy(_count, oldCount, 8); +} + +/* MD5 basic transformation. Transforms _state based on block. */ +void MD5::transform(const byte block[64]) +{ + + uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16]; + + decode(block, x, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + _state[0] += a; + _state[1] += b; + _state[2] += c; + _state[3] += d; +} + +/* Encodes input (ulong) into output (byte). Assumes length is +a multiple of 4. +*/ +void MD5::encode(const uint32 *input, byte *output, size_t length) +{ + + for (size_t i = 0, j = 0; j < length; i++, j += 4) + { + output[j] = (byte)(input[i] & 0xff); + output[j + 1] = (byte)((input[i] >> 8) & 0xff); + output[j + 2] = (byte)((input[i] >> 16) & 0xff); + output[j + 3] = (byte)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (byte) into output (ulong). Assumes length is +a multiple of 4. +*/ +void MD5::decode(const byte *input, uint32 *output, size_t length) +{ + + for (size_t i = 0, j = 0; j < length; i++, j += 4) + { + output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) | + (((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24); + } +} + +/* Convert byte array to hex string. */ +string MD5::bytesToHexString(const byte *input, size_t length) +{ + string str; + str.reserve(length << 1); + for (size_t i = 0; i < length; i++) + { + int t = input[i]; + int a = t / 16; + int b = t % 16; + str.append(1, HEX[a]); + str.append(1, HEX[b]); + } + return str; +} + +/* Convert digest to string value */ +string MD5::toString() +{ + return bytesToHexString(digest(), 16); +} diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/Md5/Md5.h b/product/src/fes/protocol/yxcloud_mqtt_wn/Md5/Md5.h new file mode 100644 index 00000000..826a9cf1 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/Md5/Md5.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include + +/* Type define */ +typedef unsigned char byte; +typedef unsigned int uint32; + +using std::string; +using std::ifstream; + +/* MD5 declaration. */ +class MD5 +{ +public: + MD5(); + MD5(const void *input, size_t length); + MD5(const string &str); + MD5(ifstream &in); + void update(const void *input, size_t length); + void update(const string &str); + void update(ifstream &in); + const byte *digest(); + string toString(); + void reset(); +private: + void update(const byte *input, size_t length); + void final(); + void transform(const byte block[64]); + void encode(const uint32 *input, byte *output, size_t length); + void decode(const byte *input, uint32 *output, size_t length); + string bytesToHexString(const byte *input, size_t length); + + /* class uncopyable */ + MD5(const MD5 &); + MD5 &operator=(const MD5 &); +private: + uint32 _state[4]; /* state (ABCD) */ + uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */ + byte _buffer[64]; /* input buffer */ + byte _digest[16]; /* message digest */ + bool _finished; /* calculate finished ? */ + + static const byte PADDING[64]; /* padding for calculate */ + static const char HEX[16]; + static const size_t BUFFER_SIZE; + +}; diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/Yxcloudmqtts.cpp b/product/src/fes/protocol/yxcloud_mqtt_wn/Yxcloudmqtts.cpp new file mode 100644 index 00000000..b692fd9a --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/Yxcloudmqtts.cpp @@ -0,0 +1,502 @@ +#include "Yxcloudmqtts.h" +#include "pub_utility_api/CommonConfigParse.h" + +using namespace iot_public; + +CYxcloudmqtts Yxcloudmqtts; +bool g_YxcloudmqttsIsMainFes=false; +bool g_YxcloudmqttsChanelRun=true; + +int EX_SetBaseAddr(void *address) +{ + Yxcloudmqtts.SetBaseAddr(address); + return iotSuccess; +} + +int EX_SetProperty(int FesStatus) +{ + Yxcloudmqtts.SetProperty(FesStatus); + return iotSuccess; +} + +int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + Yxcloudmqtts.OpenChan(MainChanNo,ChanNo,OpenFlag); + return iotSuccess; +} + +int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + Yxcloudmqtts.CloseChan(MainChanNo,ChanNo,CloseFlag); + return iotSuccess; +} + +int EX_ChanTimer(int ChanNo) +{ + Yxcloudmqtts.ChanTimer(ChanNo); + return iotSuccess; +} + +int EX_ExitSystem(int flag) +{ + LOGDEBUG("yxcloud_mqtt_wn EX_ExitSystem() start"); + g_YxcloudmqttsChanelRun=false;//使所有的线程退出。 + Yxcloudmqtts.ExitSystem(flag); + LOGDEBUG("yxcloud_mqtt_wn EX_ExitSystem() end"); + return iotSuccess; +} +CYxcloudmqtts::CYxcloudmqtts() +{ + // 2020-02-13 thxiao ReadConfigParam()需要使用m_ptrCFesBase,所以改为SetBaseAddr()处调用 + //ReadConfigParam(); + m_ProtocolId = 0; +} + +CYxcloudmqtts::~CYxcloudmqtts() +{ + if (m_CDataProcQueue.size() > 0) + m_CDataProcQueue.clear(); +} + + +int CYxcloudmqtts::SetBaseAddr(void *address) +{ + if (m_ptrCFesBase == NULL) + { + m_ptrCFesBase = (CFesBase *)address; + ReadConfigParam(); + } + return iotSuccess; +} + +int CYxcloudmqtts::SetProperty(int IsMainFes) +{ + g_YxcloudmqttsIsMainFes = (IsMainFes != 0); + LOGDEBUG("CYxcloudmqtts::SetProperty g_YxcloudmqttsIsMainFes:%d",IsMainFes); + return iotSuccess; +} + +/** + * @brief CYxcloudmqtts::OpenChan 根据OpenFlag,打开通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 打开标志 1:打开通道线程 2:打开数据处理线程 3:打开通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CYxcloudmqtts::OpenChan(int MainChanNo,int ChanNo,int OpenFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + if ((OpenFlag == CN_FesChanThread_Flag) || (OpenFlag == CN_FesChanAndDataThread_Flag)) + { + switch (ptrFesChan->m_Param.CommType) + { + case CN_FesTcpClient: + case CN_FesTcpServer: + break; + default: + LOGERROR("CYxcloudmqtts EX_OpenChan() ChanNo:%d CommType=%d is not TCP SERVER/Client!", ptrFesChan->m_Param.ChanNo, ptrFesChan->m_Param.CommType); + return iotFailed; + } + } + + if((OpenFlag==CN_FesDataThread_Flag)||(OpenFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesStopFlag) + { + //open chan thread + CYxcloudmqttsDataProcThreadPtr ptrCDataProc; + ptrCDataProc = boost::make_shared(m_ptrCFesBase,ptrMainFesChan,m_vecAppParam); + if (ptrCDataProc == NULL) + { + LOGERROR("CYxcloudmqtts EX_OpenChan() ChanNo:%d create CYxcloudmqttsDataProcThreadPtr error!",ptrFesChan->m_Param.ChanNo); + return iotFailed; + } + LOGERROR("CYxcloudmqtts EX_OpenChan() ChanNo:%d create CYxcloudmqttsDataProcThreadPtr ok!", ptrFesChan->m_Param.ChanNo); + m_CDataProcQueue.push_back(ptrCDataProc); + ptrCDataProc->resume(); //start Data THREAD + } + } + return iotSuccess; +} + +/** + * @brief CYxcloudmqtts::CloseChan 根据OpenFlag,关闭通道线程或数据处理线程。 + * @param MainChanNo 主通道号 + * @param ChanNo 当前通道号 + * @param OpenFlag 关闭标志 1:关闭通道线程 2:关闭数据处理线程 3:关闭通道线程和数据处理线程 + * @return 成功:iotSuccess 失败:iotFailed + */ +int CYxcloudmqtts::CloseChan(int MainChanNo,int ChanNo,int CloseFlag) +{ + CFesChanPtr ptrMainFesChan; + CFesChanPtr ptrFesChan; + + if (m_ptrCFesBase == NULL) + return iotFailed; + + if((ptrMainFesChan = GetChanDataByChanNo(MainChanNo))==NULL) + return iotFailed; + if((ptrFesChan = GetChanDataByChanNo(ChanNo))==NULL) + return iotFailed; + + LOGDEBUG("CYxcloudmqtts::CloseChan MainChanNo=%d chanNo=%d m_ComThreadRun=%d m_DataThreadRun=%d",MainChanNo,ChanNo,ptrFesChan->m_ComThreadRun,ptrMainFesChan->m_DataThreadRun); + + if((CloseFlag==CN_FesDataThread_Flag)||(CloseFlag==CN_FesChanAndDataThread_Flag)) + { + if (ptrMainFesChan->m_DataThreadRun == CN_FesRunFlag) + { + //close data thread + ClearDataProcThreadByChanNo(MainChanNo); + } + } + return iotSuccess; +} + +/** + * @brief CYxcloudmqtts::ChanTimer + * 通道定时器,主通道会定时调用 + * @param MainChanNo 主通道号 + * @return + */ +int CYxcloudmqtts::ChanTimer(int MainChanNo) +{ + boost::ignore_unused_variable_warning(MainChanNo); + + //把命令缓冲时间间隔到的命放到发送命令缓冲区 + return iotSuccess; +} + +int CYxcloudmqtts::ExitSystem(int flag) +{ + boost::ignore_unused_variable_warning(flag); + + InformTcpThreadExit(); + return iotSuccess; +} + +void CYxcloudmqtts::ClearDataProcThreadByChanNo(int ChanNo) +{ + int tempNum; + CYxcloudmqttsDataProcThreadPtr ptrTcp; + + if ((tempNum = (int)m_CDataProcQueue.size())<=0) + return; + vector::iterator it; + for (it = m_CDataProcQueue.begin();it!=m_CDataProcQueue.end();it++) + { + ptrTcp = *it; + if (ptrTcp->m_ptrCFesChan->m_Param.ChanNo == ChanNo) + { + m_CDataProcQueue.erase(it);//会调用CYxcloudmqttsDataProcThread::~CYxcloudmqttsDataProcThread()退出线程 + LOGDEBUG("CYxcloudmqtts::ClearDataProcThreadByChanNo %d ok",ChanNo); + break; + } + } +} + +/** +* @brief CYxcloudmqtts::ReadConfigParam +* 读取Yxcloudmqtts配置文件 +* @return 成功返回iotSuccess,失败返回iotFailed +*/ +int CYxcloudmqtts::ReadConfigParam() +{ + CCommonConfigParse config; + int ivalue; + std::string strvalue; + char strRtuNo[48]; + SYxcloudmqttsAppConfigParam param; + int items,i,j; + CFesChanPtr ptrChan; //CHAN数据区 + CFesRtuPtr ptrRTU; + + //memset(¶m, 0, sizeof(SYxcloudmqttsAppConfigParam)); + + if (m_ptrCFesBase == NULL) + return iotFailed; + + m_ProtocolId = m_ptrCFesBase->GetProtocolID((char*)"yxcloud_mqtt_wn"); + if (m_ProtocolId == -1) + { + LOGDEBUG("ReadConfigParam ProtoclID error"); + return iotFailed; + } + LOGINFO("yxcloud_mqtt_wn ProtoclID=%d", m_ProtocolId); + + if (config.load("../../data/fes/", "yxcloud_mqtt_wn.xml") == iotFailed) + { + LOGDEBUG("yxcloud_mqtt_wn load yxcloudmqtts.xml error"); + return iotSuccess; + } + LOGDEBUG("yxcloud_mqtt_wn load yxcloudmqtts.xml ok"); + + for (i = 0; i < m_ptrCFesBase->m_vectCFesChanPtr.size(); i++) + { + ptrChan = m_ptrCFesBase->m_vectCFesChanPtr[i]; + if ((ptrChan->m_Param.Used == 1) && (m_ProtocolId == ptrChan->m_Param.ProtocolId)) + { + //found RTU + for (j = 0; j < m_ptrCFesBase->m_vectCFesRtuPtr.size(); j++) + { + ptrRTU = m_ptrCFesBase->m_vectCFesRtuPtr[j]; + if (ptrRTU->m_Param.Used && (ptrRTU->m_Param.ChanNo == ptrChan->m_Param.ChanNo)) + { + memset(&strRtuNo[0], 0, sizeof(strRtuNo)); + sprintf(strRtuNo, "RTU%d", ptrRTU->m_Param.RtuNo); + //memset(¶m, 0, sizeof(param)); + param.RtuNo = ptrRTU->m_Param.RtuNo; + items = 0; + + if (config.getIntValue(strRtuNo, "startDelay", ivalue) == iotSuccess) + { + param.startDelay = ivalue; + items++; + } + else + param.startDelay = 30;//30s + + if (config.getIntValue(strRtuNo, "ymStartDelay", ivalue) == iotSuccess) + { + param.ymStartDelay = ivalue; + items++; + } + else + param.ymStartDelay = 350; //350s + + if (config.getIntValue(strRtuNo, "max_update_count", ivalue) == iotSuccess) + { + param.maxUpdateCount = ivalue; + items++; + } + else + param.maxUpdateCount = 18; //3MIN + + if (config.getIntValue(strRtuNo, "mqttDelayTime", ivalue) == iotSuccess) + { + param.mqttDelayTime = ivalue; + items++; + } + else + param.mqttDelayTime = 100; + + if (config.getIntValue(strRtuNo, "PasswordFlag", ivalue) == iotSuccess) + { + param.PasswordFlag = ivalue; + items++; + } + else + param.PasswordFlag = 0; + + strvalue.clear(); + //获取当前时间 + char timeBuff[256]; + memset(timeBuff , 0 , 256); + std::time_t now = std::time(nullptr); + std::tm* now_tm = std::localtime(&now); + std::strftime(timeBuff , 256 , "%Y%m%d%H%M%S" , now_tm); + if (config.getStringValue(strRtuNo, "ClientId", strvalue) == iotSuccess) + { + param.ClientId = strvalue; + items++; + } + else + { + param.ClientId = "MQTTClient_"; //避免ID一样导致不停的发送信息 + param.ClientId.append(timeBuff); + } + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "UserName", strvalue) == iotSuccess) + { + param.UserName = strvalue; + items++; + } + else + param.UserName.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "Password", strvalue) == iotSuccess) + { + param.Password = strvalue; + items++; + } + else + param.Password.clear(); + + if (config.getIntValue(strRtuNo, "KeepAlive", ivalue) == iotSuccess) + { + param.KeepAlive = ivalue; + items++; + } + else + param.KeepAlive = 180; //心跳检测时间间隔 + + if (config.getIntValue(strRtuNo, "Retain", ivalue) == iotSuccess) + { + param.Retain = (bool)(ivalue & 0x01); + items++; + } + else + param.Retain = false; //默认0 + + if (config.getIntValue(strRtuNo, "QoS", ivalue) == iotSuccess) + { + param.QoS = ivalue; + items++; + } + else + param.QoS = 1; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "ParaConfigPath", strvalue) == iotSuccess) + { + param.wnParaConPath = strvalue; + items++; + } + else + param.wnParaConPath.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "ParaConfigPath2", strvalue) == iotSuccess) + { + param.wnParaConPath2 = strvalue; + items++; + } + else + param.wnParaConPath2.clear(); + + + if (config.getIntValue(strRtuNo, "WillFlag", ivalue) == iotSuccess) + { + param.WillFlag = ivalue; + items++; + } + else + param.WillFlag = 1; + + if (config.getIntValue(strRtuNo, "WillQos", ivalue) == iotSuccess) + { + param.WillQos = ivalue; + items++; + } + else + param.WillQos = 1; + + if (config.getIntValue(strRtuNo, "sslFlag", ivalue) == iotSuccess) + { + param.sslFlag = ivalue; + items++; + } + else + param.sslFlag = 0; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "tls_version", strvalue) == iotSuccess) + { + param.tls_version = strvalue; + items++; + } + else + param.tls_version = "tlsv1.1"; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "caPath", strvalue) == iotSuccess) + { + param.caPath = strvalue; + items++; + } + else + param.caPath = "../../data/fes/"; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "caFile", strvalue) == iotSuccess) + { + param.caFile = param.caPath + strvalue; + items++; + } + else + param.caFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "certFile", strvalue) == iotSuccess) + { + param.certFile = param.caPath + strvalue; + items++; + } + else + param.certFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "keyFile", strvalue) == iotSuccess) + { + param.keyFile = param.caPath + strvalue; + items++; + } + else + param.keyFile.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "keyPassword", strvalue) == iotSuccess) + { + param.keyPassword = strvalue; + items++; + } + else + param.keyPassword.clear(); + + if (config.getIntValue(strRtuNo, "CycReadFileTime", ivalue) == iotSuccess) + { + param.CycReadFileTime = ivalue; + items++; + } + else + param.CycReadFileTime = 300; + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "AlarmProjectType", strvalue) == iotSuccess) + { + param.AlarmProjectType = strvalue; + items++; + } + else + param.AlarmProjectType.clear(); + + strvalue.clear(); + if (config.getStringValue(strRtuNo, "AlarmTopic", strvalue) == iotSuccess) + { + param.AlarmTopic = strvalue; + items++; + } + else + param.AlarmTopic.clear(); + + if (items > 0)//对应的RTU有配置项 + { + m_vecAppParam.push_back(param); + } + } + } + } + } + return iotSuccess; +} + +/** + * @brief CYxcloudmqtts::InformTcpThreadExit + * 设置线程退出标志,通知线程退出 + * @return + */ +void CYxcloudmqtts::InformTcpThreadExit() +{ + +} diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/Yxcloudmqtts.h b/product/src/fes/protocol/yxcloud_mqtt_wn/Yxcloudmqtts.h new file mode 100644 index 00000000..4c6d2299 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/Yxcloudmqtts.h @@ -0,0 +1,37 @@ +#pragma once +#include +#include "Export.h" +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "YxcloudmqttsDataProcThread.h" + +extern "C" PROTOCOLBASE_API int EX_SetBaseAddr(void *Address); +extern "C" PROTOCOLBASE_API int EX_SetProperty(int FesStatus); +extern "C" PROTOCOLBASE_API int EX_OpenChan(int MainChanNo,int ChanNo,int OpenFlag); +extern "C" PROTOCOLBASE_API int EX_CloseChan(int MainChanNo,int ChanNo,int CloseFlag); +extern "C" PROTOCOLBASE_API int EX_ChanTimer(int MainChanNo); +extern "C" PROTOCOLBASE_API int EX_ExitSystem(int flag); + +class PROTOCOLBASE_API CYxcloudmqtts : public CProtocolBase +{ +public: + CYxcloudmqtts(); + ~CYxcloudmqtts(); + + CFesBase* m_ptrCFesBase; //CProtocolBase类中定义 + vector m_CDataProcQueue; + vector m_vecAppParam; + + int SetBaseAddr(void *address); + int SetProperty(int IsMainFes); + int OpenChan(int MainChanNo,int ChanNo,int OpenFlag); + int CloseChan(int MainChanNo,int ChanNo,int CloseFlag); + int ChanTimer(int MainChanNo); + int ExitSystem(int flag); + int ReadConfigParam(); + void InformTcpThreadExit(); +private: + int m_ProtocolId; + void ClearDataProcThreadByChanNo(int ChanNo); +}; diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/YxcloudmqttsDataProcThread.cpp b/product/src/fes/protocol/yxcloud_mqtt_wn/YxcloudmqttsDataProcThread.cpp new file mode 100644 index 00000000..9bbf33f3 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/YxcloudmqttsDataProcThread.cpp @@ -0,0 +1,3462 @@ +#include +#include "YxcloudmqttsDataProcThread.h" +#include "pub_utility_api/CommonConfigParse.h" +#include "pub_utility_api/I18N.h" +#include "boost/algorithm/string.hpp" +#include "xlsxio/xlsxio_read.h" +#include "dbms/db_api_ex/CDbApi.h" +#include +#include +#include + + +using namespace iot_public; + +extern bool g_YxcloudmqttsIsMainFes; +extern bool g_YxcloudmqttsChanelRun; +const int gYxcloudmqttsThreadTime = 10; +std::string g_KeyPassword; //私钥密码 + +static int password_callback(char* buf, int size, int rwflag, void* userdata) +{ + boost::ignore_unused_variable_warning(rwflag); + boost::ignore_unused_variable_warning(userdata); + + memcpy(buf, g_KeyPassword.data(), size); + buf[size - 1] = '\0'; + + return (int)strlen(buf); +} + +int CrcSum(byte *Data, int Count) +{ + int wCRCin = 0x0000; // CRC值 + int wCPoly = 0x1021; // CRC多项式 + int i; + + while (Count--) + { + wCRCin ^= (*(Data++) << 8); + + for (i = 0; i < 8; i++) + { + if (wCRCin & 0x8000) + wCRCin = (wCRCin << 1) ^ wCPoly; + else + wCRCin = wCRCin << 1; + } + } + return wCRCin; +} + +CYxcloudmqttsDataProcThread::CYxcloudmqttsDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam): + CTimerThreadBase("YxcloudmqttsDataProcThread", gYxcloudmqttsThreadTime,0,true) +{ + m_ptrCFesChan = ptrCFesChan; + m_ptrCFesBase = ptrCFesBase; + m_ptrCurrentChan = ptrCFesChan; + m_pSoeData = NULL; + m_ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + getAllRTUByCurrChan(); + + m_timerCountReset = 10; + m_timerCount = 0; + + publishTime = 0; + memset(&mqttTime, 0, sizeof(MqttPublishTime)); + memset(&mqttMsg, 0, sizeof(MqttRecvMsg)); + + mqttTime.startTime = getMonotonicMsec() / 1000; + mqttTime.CycTime = getMonotonicMsec() / 1000; + if ((m_ptrCFesChan == NULL) || (m_ptrCFesRtu == NULL)) + { + return; + } + m_ptrCFesChan->SetLinkStatus(CN_FesChanConnect); + m_ptrCFesChan->SetComThreadRunFlag(CN_FesRunFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesRunFlag); + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + m_ptrCFesRtu->SetFwAiChgStop(1); + m_ptrCFesRtu->SetFwDiChgStop(1); + m_ptrCFesRtu->SetFwDDiChgStop(1); + m_ptrCFesRtu->SetFwMiChgStop(1); + m_ptrCFesRtu->SetFwAccChgStop(1); + + int found = 0; + if(vecAppParam.size()>0) + { + for (size_t i = 0; i < vecAppParam.size(); i++) + { + if(m_ptrCFesRtu->m_Param.RtuNo == vecAppParam[i].RtuNo) + { + //memset(&m_AppData,0,sizeof(SYxcloudmqttsAppData)); + + + //配置 + m_AppData.mqttDelayTime = vecAppParam[i].mqttDelayTime; + m_AppData.PasswordFlag = vecAppParam[i].PasswordFlag; + m_AppData.ClientId = vecAppParam[i].ClientId; + m_AppData.UserName = vecAppParam[i].UserName; + m_AppData.Password = vecAppParam[i].Password; + m_AppData.KeepAlive = vecAppParam[i].KeepAlive; + m_AppData.Retain = vecAppParam[i].Retain; + m_AppData.QoS = vecAppParam[i].QoS; + m_AppData.WillFlag = vecAppParam[i].WillFlag; + m_AppData.WillQos = vecAppParam[i].WillQos; + //SSL加密配置 + m_AppData.sslFlag = vecAppParam[i].sslFlag; + m_AppData.tls_version = vecAppParam[i].tls_version; + m_AppData.caPath = vecAppParam[i].caPath; + m_AppData.caFile = vecAppParam[i].caFile; + m_AppData.certFile = vecAppParam[i].certFile; + m_AppData.keyFile = vecAppParam[i].keyFile; + m_AppData.keyPassword = vecAppParam[i].keyPassword; + m_AppData.AlarmProjectType = vecAppParam[i].AlarmProjectType; + m_AppData.AlarmTopic = vecAppParam[i].AlarmTopic; + m_AppData.maxUpdateCount = vecAppParam[i].maxUpdateCount; + m_AppData.startDelay = vecAppParam[i].startDelay; + m_AppData.ymStartDelay = vecAppParam[i].ymStartDelay; + m_AppData.CycReadFileTime = vecAppParam[i].CycReadFileTime; + m_AppData.wnParaConPath = vecAppParam[i].wnParaConPath; + m_AppData.wnParaConPath2 = vecAppParam[i].wnParaConPath2; + found = 1; + break; + } + } + } + if(!found) + InitConfigParam();//配置文件读取失败,取默认配置 + + //读取mqtt_topic_cfg.csv文件,并更新参数 + GetTopicCfg(); + + + m_AppData.mqttContFlag = false; + + //告警主题为空,则不发告警数据 + if (m_AppData.AlarmTopic.length() < 1) + { + m_ptrCFesRtu->SetFwSoeChgStop(1); + m_ptrCFesRtu->SetFwDSoeChgStop(1); + } + m_AppData.alarmList.clear(); + GetAlarmCfg(); + + m_AppData.protectparaList.clear(); + GetProtectParaCfg(); + + m_AppData.m_parasConfig.clear(); + GetParaCfg(m_AppData.wnParaConPath.c_str()); + GetParaCfg(m_AppData.wnParaConPath2.c_str()); +// std::string strTmp = "../../data/fes/mgtt_wn_paraConfig2.xlsx"; +// GetParaCfg(strTmp.c_str()); + + + //创建mqttclient对象 + mosqpp::lib_init(); + mqttClient = new CMosquittoppFix(m_AppData.ClientId.data()); +} + +CYxcloudmqttsDataProcThread::~CYxcloudmqttsDataProcThread() +{ + quit();//在调用quit()前,系统会调用beforeQuit(); + + if(m_pSoeData != NULL) + free(m_pSoeData); + + + if (m_AppData.mqttContFlag) + mqttClient->disconnect(); + + //删除MQTT对象 + if(mqttClient) +// mqttClient.reset(); + delete mqttClient; + + + + ClearTopicStr(); + + m_ptrCFesBase->WriteRtuSatus(m_ptrCFesRtu, CN_FesRtuComDown); + LOGDEBUG("CYxcloudmqttsDataProcThread::~CYxcloudmqttsDataProcThread() ChanNo=%d 退出", m_ptrCFesChan->m_Param.ChanNo); + //释放mosqpp库 + mosqpp::lib_cleanup(); +} + +/** + * @brief CYxcloudmqttsDataProcThread::beforeExecute + * + */ +int CYxcloudmqttsDataProcThread::beforeExecute() +{ + return iotSuccess; +} + +/* + @brief CYxcloudmqttsDataProcThread::execute + + */ +void CYxcloudmqttsDataProcThread::execute() +{ + //读取网络事件 + if(!g_YxcloudmqttsChanelRun) //收到线程退出标志不再往下执行 + return; + + if (m_timerCount++ >= m_timerCountReset) + m_timerCount = 0;// 1sec is ready + + m_ptrCurrentChan = GetCurrentChanData(m_ptrCFesChan); + if(m_ptrCurrentChan== NULL) + return; + + //MqttConnect(); + + //秒级判断流程 + TimerProcess(); + + //mqtt转发流程 + YxcloudmqttsProcess(); +} + +/* + @brief 执行quit函数前的处理 + */ +void CYxcloudmqttsDataProcThread::beforeQuit() +{ + m_ptrCFesChan->SetComThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetChangeFlag(CN_FesChanUnChange); + m_ptrCFesChan->SetDataThreadRunFlag(CN_FesStopFlag); + m_ptrCFesChan->SetLinkStatus(CN_FesChanDisconnect); + + LOGDEBUG("CYxcloudmqttsDataProcThread::beforeQuit() "); +} + +/** + * @brief CYxcloudmqttsDataProcThread::InitConfigParam + * Yxcloudmqtts 初始化配置参数 + * @return 成功返回iotSuccess,失败返回iotFailed + */ +int CYxcloudmqttsDataProcThread::InitConfigParam() +{ + if((m_ptrCFesChan == NULL)||(m_ptrCFesRtu==NULL)) + return iotFailed; + + //memset(&m_AppData,0,sizeof(SYxcloudmqttsAppData)); + m_AppData.mqttDelayTime = 100; + m_AppData.PasswordFlag = 0; + m_AppData.ClientId = "wnMqttClient"; + m_AppData.KeepAlive = 180; + m_AppData.Retain = 0; + m_AppData.QoS = 0; + m_AppData.WillFlag = 0; + m_AppData.WillQos = 0; + m_AppData.wnParaConPath = ""; + m_AppData.wnParaConPath2 = ""; + + //SSL加密设置 + m_AppData.sslFlag = 0; + + m_AppData.maxUpdateCount = 18; + m_AppData.updateCount = 0; + m_AppData.startDelay = 30; + m_AppData.ymStartDelay = 350; + m_AppData.CycReadFileTime = 300; + + return iotSuccess; +} + +void CYxcloudmqttsDataProcThread::TimerProcess() +{ + if (m_timerCount == 0)//秒级判断,减少CPU负荷 + { + + uint64 curmsec = getMonotonicMsec(); + + //定时更新本FES数据 + if (m_AppData.updateCount < m_AppData.maxUpdateCount) + { + if ((curmsec - m_AppData.lastUpdateTime) > CN_YxcloudmqttsStartUpateTime)//10s + { + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + m_AppData.updateCount++; + m_AppData.lastUpdateTime = curmsec; + } + } + else + { + if ((curmsec - m_AppData.lastUpdateTime) > CN_YxcloudmqttsNormalUpateTime)//60s + { + m_ptrCFesBase->UpdateFesAiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesDiValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesAccValue(m_ptrCFesRtu); + m_ptrCFesBase->UpdateFesMiValue(m_ptrCFesRtu); + m_AppData.lastUpdateTime = curmsec; + } + } + + int loopCount = 0; + while( loopCount < m_ptrCFesChan->m_RtuNum ) + { + CFesRtuPtr ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + if (ptrCFesRtu->GetRxDoCmdNum() > 0) + { + DoCmdProcess(ptrCFesRtu); + } + if (ptrCFesRtu->GetRxAoCmdNum() > 0) + { + AoCmdProcess(ptrCFesRtu); + } + if (ptrCFesRtu->GetRxDefCmdNum() > 0) + { + DefCmdProcess(ptrCFesRtu); + } + + + //定时读取遥控命令响应缓冲区,及时清除队列释放空间,不对遥控成败作处理 + if (ptrCFesRtu->GetFwDoRespCmdNum() > 0) + { + SFesFwDoRespCmd retCmd; + ptrCFesRtu->ReadFwDoRespCmd(1, &retCmd); + } + + if (ptrCFesRtu->GetFwAoRespCmdNum() > 0) + { + SFesFwAoRespCmd retCmd; + ptrCFesRtu->ReadFwAoRespCmd(1, &retCmd); + } + + + NextRtuIndex(m_ptrCFesChan); + loopCount++; + } + + //启动主线程判断逻辑 + MainThread(); + } +} + +void CYxcloudmqttsDataProcThread::YxcloudmqttsProcess() +{ + + if ((getMonotonicMsec() - publishTime) < 100) + return; + + //上传SOE + if (m_AppData.AlarmTopic.length() > 0) + SendSoeDataFrame(); + + int i = 0; + for (i = mqttTime.topicIndex; i < m_AppData.sendTopicNum; i++) + { + if (m_AppData.sendTopicStr[i].TopicSendFlag) + { +// FormJsonData(i); +// SendTopicData(i); + m_AppData.sendTopicStr[i].TopicSendFlag = false; + break; + } + } + + if (!m_AppData.mqttContFlag) + { + MqttConnect(); + } + if(!subFlag) + { + subFlag = MqttSubscribe(); + } + + int ret = mqttClient->loop(); + char slog[256]; + memset(slog, 0, 256); + if (ret != MOSQ_ERR_SUCCESS) + { + m_AppData.mqttContFlag = false; + sprintf_s(slog,sizeof(slog),"MQTT %s:%d 连接异常,需要重连!错误代号[%d]", m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo, ret); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("YxcloudmqttsDataProcThread.cpp ChanNo:%d MQTT %s:%d连接异常,需要重连错误代号[%d]!", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo,ret); + //return; + } + + OnProcessReceive(mqttClient->RecvMsg , mqttClient->receivedTopic); + + time_t currentTime = time(nullptr); + struct tm* st = localtime(¤tTime); + if((st->tm_hour == 0) && (st->tm_min == 0) && (st->tm_sec == 0)) + { + OnSend(CMD_UPDATE_GATEWAY_RTC,1); + } + + //memset(mqttClient->RecvMsg,0,sizeof(mqttClient->RecvMsg)); + + checkAllPointStatus(); //检测测点状态 + mqttTime.topicIndex = i; + if (mqttTime.topicIndex >= m_AppData.sendTopicNum) + {//一轮topic发送结束 + mqttTime.topicIndex = 0; + mqttTime.mqttSendEndFlag = true; + } +} + +//通过遥信远动号找告警点 +int CYxcloudmqttsDataProcThread::GetAlarmNo(const int RemoteNo) +{ + for (int i = 0; i < m_AppData.alarmList.size(); i++) + { + if (m_AppData.alarmList[i].yxNo == RemoteNo) + return i; + } + return -1; +} + +//获取保护参数配置 +void CYxcloudmqttsDataProcThread::GetProtectParaCfg() +{ + char filename[100]; + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_wn_protectPara_cfg.csv"); + char line[1024]; + FILE *fpin; + if ((fpin = fopen(filename, "r")) == NULL) + { + LOGDEBUG("yxcloud_mqtt_wn load mqtt_wn_protectPara_cfg.csv error"); + return; + } + LOGDEBUG("yxcloud_mqtt_wn load mqtt_wn_protectPara_cfg.csv ok"); + + if (fgets(line, 1024, fpin) == NULL) + { + fclose(fpin); + return; + } + + //清空原先数据 + m_AppData.protectparaList.clear(); + std::string lineStr = ""; + std::vector tokens; + tokens.clear(); + + while (fgets(line, 1024, fpin) != NULL) + { + ProtectPara proParaStr; + lineStr = line; + tokens.clear(); + boost::split(tokens, lineStr, boost::is_any_of(","), boost::token_compress_off); + + if (tokens.size() != 5) continue; + proParaStr.proParaDesc = GbkToUtf8(tokens.at(0)); + proParaStr.byteNum = atoi(tokens.at(1).c_str()); + proParaStr.resolvingPower = atof(tokens.at(2).c_str()); + proParaStr.ppUnit = GbkToUtf8(tokens.at(3)); + if( !tokens.at(4).empty() && tokens.at(4).back() == '\n') + { + tokens.at(4).pop_back(); + } + proParaStr.ppRange = GbkToUtf8(tokens.at(4)); + m_AppData.protectparaList.push_back(proParaStr); + } + fclose(fpin); +} + +/** + * @brief CYxcloudmqttsDataProcThread::GetParaCfg + * 获取参数配置 + */ +void CYxcloudmqttsDataProcThread::GetParaCfg(const char *filename) +{ + ProtectPara_List list; + list.clear(); + xlsxioreader xlsxioread; + xlsxioread = xlsxioread_open(filename); + + if (xlsxioread == nullptr) { + LOGDEBUG("yxcloud_mqtt_wn load mgtt_wn_paraConfig.xlsx error!"); + return; + } + LOGDEBUG("yxcloud_mqtt_wn load mgtt_wn_paraConfig.xlsx ok!"); + + //读取所有sheet文件 + xlsxioreadersheetlist sheet_list; + const char* sheet_name; + sheet_list = xlsxioread_sheetlist_open(xlsxioread); + while ((sheet_name = xlsxioread_sheetlist_next(sheet_list)) != nullptr) + { + LOGDEBUG("yxcloud_mqtt_wn load mgtt_wn_paraConfig.xlsx in sheetName : %s" , sheet_name); + + xlsxioreadersheet sheet = xlsxioread_sheet_open(xlsxioread, sheet_name, XLSXIOREAD_SKIP_EMPTY_ROWS ); + const char* cell_value; + list.clear(); + xlsxioread_sheet_next_row(sheet); //跳过第一行 + int i = 0; + //循环读取每一行 + while ( i = xlsxioread_sheet_next_row(sheet)) + { + ProtectPara paraTmp; + paraTmp.proParaDesc = ""; + paraTmp.byteNum = 0; + paraTmp.resolvingPower = 1.0; + paraTmp.ppUnit = ""; + paraTmp.ppRange = ""; + paraTmp.parentDesc = ""; + int index = 0; + while ((cell_value = xlsxioread_sheet_next_cell(sheet)) != nullptr) { + switch (index) { + case 0: + paraTmp.proParaDesc = cell_value; // 点位名称 + break; + case 1: + paraTmp.byteNum = atoi(cell_value); // 点位字节 + break; + case 2: + paraTmp.resolvingPower = atof(cell_value); // 点位分辨率 + break; + case 3: + paraTmp.ppUnit = cell_value; // 点位单位 + break; + case 4: + paraTmp.ppRange = cell_value; // 点位取值范围 + break; + case 5: + paraTmp.parentDesc = cell_value; // 父节点名称 + break; + default: + break; + } + index++; + } + + // 将结构体加入到向量中 + list.push_back(paraTmp); + } + + // 关闭 Sheet + xlsxioread_sheet_close(sheet); + m_AppData.m_parasConfig[sheet_name] = list; + } + xlsxioread_sheetlist_close(sheet_list); + + // 关闭文件 + xlsxioread_close(xlsxioread); + +} + +//上传SOE +void CYxcloudmqttsDataProcThread::SendSoeDataFrame() +{ + int i, DiValue; + LOCALTIME SysLocalTime; + SFesFwSoeEvent *pSoeEvent = NULL; + int count, retNum; + std::string jsonStr; + std::string DPTagName; + std::string pName; + std::string devId; + + count = m_ptrCFesRtu->GetFwSOEEventNum(); + if (count == 0) + return; + + //最多一次传100条事件 + if (count > 100) + count = 100; + + if (m_pSoeData == NULL) + m_pSoeData = (SFesFwSoeEvent*)malloc(count * sizeof(SFesFwSoeEvent)); + else + + m_pSoeData = (SFesFwSoeEvent*)realloc(m_pSoeData, count * sizeof(SFesFwSoeEvent)); + + retNum = m_ptrCFesRtu->ReadFwSOEEvent(count, m_pSoeData); + jsonStr = "{\"DATATYPE\":\"ALARM_INFO\","; + if(m_AppData.AlarmProjectType.length() > 0) + jsonStr += "\"PROJECTTYPE\":\"" + m_AppData.AlarmProjectType + "\","; + jsonStr += "\"DATA\":["; + count = 0; + char vstr[50]; + int alarmNo = -1; + for (i = 0; i < retNum; i++) + { + pSoeEvent = m_pSoeData + i; + if (pSoeEvent->RemoteNo > m_ptrCFesRtu->m_MaxFwDiPoints) + continue; + + //取出告警列表索引 + alarmNo = GetAlarmNo(pSoeEvent->RemoteNo); + if(alarmNo == -1) + continue; + + DiValue = pSoeEvent->Value & 0x01; + SysLocalTime = convertUTCMsecToLocalTime(pSoeEvent->time); //把Soe时间戳转成本地时标 + + //第一个对象前不需要逗号 + if (count != 0) + jsonStr += ","; + jsonStr += "{\"deviceId\":" + to_string(m_AppData.alarmList[alarmNo].devId) + ",\"alarmId\":" + to_string(m_AppData.alarmList[alarmNo].alarmId) + ","; + //加上时标 + memset(vstr, 0, 50); + sprintf_s(vstr, sizeof(vstr),"\"generationDataTime\":\"%04d-%02d-%02d %02d:%02d:%02d\",", SysLocalTime.wYear, SysLocalTime.wMonth, + SysLocalTime.wDay, SysLocalTime.wHour, SysLocalTime.wMinute, SysLocalTime.wSecond); + jsonStr += vstr; + jsonStr += "\"message\":\"" + m_AppData.alarmList[alarmNo].alarmCode + "\","; + if(DiValue) + jsonStr += "\"status\":true}"; + else + jsonStr += "\"status\":false}"; + count++; + } + jsonStr += "]}"; + if (count > 0) + { + //将上抛信息传给通道报文显示 + char slog[256]; + memset(slog, 0, 256); + sprintf_s(slog, sizeof(slog),"MQTT Publish:%s, AlarmNum:%d", m_AppData.AlarmTopic.data(), count); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + //上抛数据 + if (MqttPublish(m_AppData.AlarmTopic, jsonStr) == false) + MqttPublish(m_AppData.AlarmTopic, jsonStr);//上抛失败,重新上抛一次 + SleepmSec(m_AppData.mqttDelayTime); + } +} + +void CYxcloudmqttsDataProcThread::MqttConnect() +{ + int ret = 0; + char slog[256]; + memset(slog, 0, 256); + //已结连接上则不需重连 + if (m_AppData.mqttContFlag) + return; + + //不判断服务器地址 + mqttClient->tls_insecure_set(1); + + //设置SSL加密 + if (m_AppData.sslFlag == 2) //双向加密 + { + mqttClient->tls_opts_set(0, m_AppData.tls_version.data(), NULL); + if (m_AppData.keyPassword.length() < 1) + mqttClient->tls_set(m_AppData.caFile.data(), m_AppData.caPath.data(), m_AppData.certFile.data(), m_AppData.keyFile.data()); + else + { + //更新私钥的密码 + g_KeyPassword = m_AppData.keyPassword; + mqttClient->tls_set(m_AppData.caFile.data(), m_AppData.caPath.data(), m_AppData.certFile.data(), m_AppData.keyFile.data(), password_callback); + } + LOGDEBUG("YxcloudmqttsDataProcThread.cpp ChanNo:%d MqttConnect caFile=%s keyPassword=%d!", m_ptrCFesChan->m_Param.ChanNo, m_AppData.caFile.data(), m_AppData.keyPassword.length()); + } + else if (m_AppData.sslFlag == 1) //单向加密 + { + mqttClient->tls_opts_set(0, m_AppData.tls_version.data(), NULL); + mqttClient->tls_set(m_AppData.caFile.data()); + } + + if (m_AppData.QoS) + mqttClient->message_retry_set(3); + + //设置用户名和密码 + if (m_AppData.PasswordFlag) + mqttClient->username_pw_set(m_AppData.UserName.data(), m_AppData.Password.data()); + + //连接Broker服务器 + //m_ptrCFesChan->m_Param.NetRoute[0].NetDesc localhost + char ServerIp[CN_FesMaxNetDescSize]; //通道IP + memset(ServerIp, 0, CN_FesMaxNetDescSize); + strcpy(ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc); + ret = mqttClient->connect(ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo, m_AppData.KeepAlive);//IP + if (ret != MOSQ_ERR_SUCCESS) + { + m_AppData.mqttContFlag = false; + sprintf_s(slog, sizeof(slog),"MQTT %s:%d 连接失败!", ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("YxcloudmqttsDataProcThread.cpp ChanNo:%d MQTT %s:%d连接失败!", m_ptrCFesChan->m_Param.ChanNo, ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); + return; + } + + m_AppData.mqttContFlag = true; + sprintf_s(slog, sizeof(slog),"MQTT %s:%d 连接成功!", ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog,CN_SFesSimComFrameTypeSend); + LOGDEBUG("YxcloudmqttsDataProcThread.cpp ChanNo:%d MQTT %s:%d连接成功!", m_ptrCFesChan->m_Param.ChanNo, ServerIp, m_ptrCFesChan->m_Param.NetRoute[0].PortNo); +} + +bool CYxcloudmqttsDataProcThread::MqttPublish(std::string mqttTopic, std::string mqttPayload) +{ + //连接MQTT服务器 + //MqttConnect(); + if (!m_AppData.mqttContFlag) + return false; + + //主题和内容为空 + if ((mqttTopic.length() < 1) || (mqttPayload.length() < 1)) + return false; + + char slog[256]; + memset(slog, 0, 256); + + //发布主题数据 + int rc = mqttClient->publish(NULL, mqttTopic.data(), (int)mqttPayload.length(), mqttPayload.data(), m_AppData.QoS, m_AppData.Retain); + if (rc != MOSQ_ERR_SUCCESS) + { + sprintf_s(slog, sizeof(slog),"MQTT 上抛 %s 失败,断开连接!", mqttTopic.data()); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("YxcloudmqttsDataProcThread.cpp ChanNo:%d %s:%d %s", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo,slog); + mqttClient->disconnect(); + m_AppData.mqttContFlag = false; + return false; + } + + if (m_AppData.WillFlag > 0) + { + mqttClient->will_set(mqttTopic.data(), (int)mqttPayload.length(), mqttPayload.data(), m_AppData.WillQos, m_AppData.Retain); + } + //记下发送时间 单位毫秒 + publishTime = getMonotonicMsec(); + SleepmSec(m_AppData.mqttDelayTime); + return true; +} + +/** + * @brief CYxcloudmqttsDataProcThread::MqttSubscribe + * 根据当前通道中的每一个RTU下的设备序号(Rtu描述)订阅主题(仅针对与一个RTU对应一个设备) + */ +bool CYxcloudmqttsDataProcThread::MqttSubscribe() +{ + char slog[256]; + memset(slog, 0, 256); + bool ret = false; + + if (!m_AppData.mqttContFlag || m_allRtu.empty()) + return ret; + + //订阅主题数据 + std::map::const_iterator itor; + for( itor = m_allRtu.begin() ; itor != m_allRtu.end() ; itor++) + { + std::string subTopic = "up/" + itor->first; + mapLastRecvTime[subTopic] = getUTCTimeMsec(); + int rc = mqttClient->subscribe(NULL, subTopic.data()); + if( MOSQ_ERR_SUCCESS != rc) + { + sprintf_s(slog, sizeof(slog),"MQTT 订阅 %s 失败!", subTopic.data()); + ShowChanStrData(itor->second->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeRecv); + LOGINFO("subscribeRc != MOSQ_ERR_SUCCESS Error: %s" , mosquitto_strerror(rc)); + }else + { + ret = true; + } + } + + return ret; + +} + +bool CYxcloudmqttsDataProcThread::MqttSubscribe(string subTopic) +{ + char slog[256]; + memset(slog, 0, 256); + bool ret = false; + + if (!m_AppData.mqttContFlag || subTopic.empty()) + return ret; + + //订阅主题数据 + std::string topic = "up/" + subTopic; + int rc = mqttClient->subscribe(NULL, topic.data()); + if( MOSQ_ERR_SUCCESS != rc) + { + sprintf_s(slog, sizeof(slog),"MQTT 订阅 %s 失败!", topic.data()); + //ShowChanStrData(itor->second->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeRecv); + LOGINFO("subscribeRc != MOSQ_ERR_SUCCESS Error: %s" , mosquitto_strerror(rc)); + }else + { + ret = true; + } + + return ret; +} + +bool CYxcloudmqttsDataProcThread::MqttUnSubscribe(string unSubTopic) +{ + char slog[256]; + memset(slog, 0, 256); + bool ret = false; + + if (!m_AppData.mqttContFlag || unSubTopic.empty()) + return ret; + + //订阅主题数据 + std::string topic = "up/" + unSubTopic; + int rc = mqttClient->unsubscribe(NULL, topic.data()); + if( MOSQ_ERR_SUCCESS != rc) + { + sprintf_s(slog, sizeof(slog),"MQTT 取消订阅 %s 失败!", topic.data()); + //ShowChanStrData(itor->second->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeRecv); + LOGINFO("unsubscribeRc != MOSQ_ERR_SUCCESS Error: %s" , mosquitto_strerror(rc)); + }else + { + ret = true; + } + + return ret; +} + +void CYxcloudmqttsDataProcThread::getAllRTUByCurrChan() +{ + if( NULL == m_ptrCFesChan ) return; + m_allRtu.clear(); + int loopCount = 0; + while( loopCount < m_ptrCFesChan->m_RtuNum ) + { + CFesRtuPtr ptrCFesRtu = GetRtuDataByChanData(m_ptrCFesChan); + std::string str = ""; + if( NULL != ptrCFesRtu && !(str = ptrCFesRtu->m_Param.RtuDesc).empty()) + { + m_allRtu[str]=ptrCFesRtu; + m_customCmdAck[str] = boost::unordered_map(); + } + NextRtuIndex(m_ptrCFesChan); + loopCount++; + } + +} + +bool CYxcloudmqttsDataProcThread::switchRTUByTopic(std::string topic) +{ + bool ret = false; + if(!m_allRtu.empty() ) + { + //切割主题 目前协议规定为down/SN; + std::string sn = ""; + size_t last_slash_pos = topic.find_last_of('/'); + if( last_slash_pos != std::string::npos) + { + sn = topic.substr(last_slash_pos + 1); + } + + std::map::const_iterator it = m_allRtu.find(sn); + if( it != m_allRtu.end() && it->second) + { + //是否需要真正的切RTU + m_ptrCFesRtu = it->second; + ret = true; + } + } + + return ret; + +} + +//获取文件MD5 +std::string CYxcloudmqttsDataProcThread::GetFileMd5(const std::string &file) +{ + ifstream in(file.c_str(), ios::binary); + if (!in) + return ""; + + MD5 md5; + std::streamsize length; + char buffer[1024]; + while (!in.eof()) + { + in.read(buffer, 1024); + length = in.gcount(); + if (length > 0) + md5.update(buffer, length); + } + in.close(); + return md5.toString(); +} + +//获取字符串MD5 +std::string CYxcloudmqttsDataProcThread::GetStringMd5(const std::string &src_str) +{ + if (src_str.size() < 1) + return ""; + + MD5 md5; + int rsaNum = ((int)src_str.size() + 1023) / 1024; + for (int i = 0; i 0) + md5.update(tmps.c_str(), tmps.size()); + } + return md5.toString(); +} + +//清空topic列表 +void CYxcloudmqttsDataProcThread::ClearTopicStr() +{ +// for (int i = 0; i < MAX_TOPIC_NUM; i++) +// { +// m_AppData.sendTopicStr[i].jsonTimeList.clear(); +// m_AppData.sendTopicStr[i].jsonValueList.clear(); +// if (m_AppData.sendTopicStr[i].rootJson != NULL) +// { +// cJSON_Delete(m_AppData.sendTopicStr[i].rootJson); +// m_AppData.sendTopicStr[i].rootJson = NULL; +// } +// } + //memset(m_AppData.sendTopicStr, 0, sizeof(SEND_TOPIC_STR)*MAX_TOPIC_NUM); +} + +void CYxcloudmqttsDataProcThread::GetAlarmCfg() +{ + char filename[100]; + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_alarm_cfg%d.csv", m_ptrCFesRtu->m_Param.RtuNo); + char line[1024]; + FILE *fpin; + if ((fpin = fopen(filename, "r")) == NULL) + { + LOGDEBUG("yxcloud_mqtt_wn load mqtt_alarm_cfg.csv error"); + return; + } + LOGDEBUG("yxcloud_mqtt_wn load mqtt_alarm_cfg.csv ok"); + + if (fgets(line, 1024, fpin) == NULL) + { + fclose(fpin); + return; + } + + //先清空原来的list + m_AppData.alarmList.clear(); + while (fgets(line, 1024, fpin) != NULL) + { + char *token; + token = strtok(line, ","); + int j = 0; + Alarm_Value_Str alarmValStr; + //memset(&alarmValStr,0,sizeof(Alarm_Value_Str)); + while (token != NULL) + { + if (0 == j)//设备ID + { + if (strlen(token) <= 0) + break; + alarmValStr.devId = atoi(token); + } + else if (1 == j)//告警ID + { + if (strlen(token) <= 0) + break; + alarmValStr.alarmId = atoi(token); + } + else if (2 == j)//遥信转发远动号 + { + if (strlen(token) <= 0) + break; + alarmValStr.yxNo = atoi(token); + } + else if (3 == j)//告警描述 + { + if (strlen(token) <= 0) + break; + alarmValStr.alarmCode = GbkToUtf8(token); + m_AppData.alarmList.push_back(alarmValStr); + } + else + break; + token = strtok(NULL, ","); + j++; + } + } + fclose(fpin); +} + +void CYxcloudmqttsDataProcThread::GetTopicCfg( ) +{ + char filename[100]; + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_topic_cfg%d.csv", m_ptrCFesRtu->m_Param.RtuNo); + char line[1024]; + FILE *fpin; + if ((fpin = fopen(filename, "r")) == NULL) + { + LOGDEBUG("yxcloud_mqtt_wn load mqttconfig.csv error"); + return; + } + LOGDEBUG("yxcloud_mqtt_wn load mqttconfig.csv ok"); + + if (fgets(line, 1024, fpin) == NULL) + { + fclose(fpin); + return; + } + + //先清空原来的list + ClearTopicStr(); + m_AppData.sendTopicNum = 0; + int topicNum = 0; + while (fgets(line, 1024, fpin) != NULL) + { + char *token; + token = strtok(line, ","); + int j = 0; + while (token != NULL) + { + if (0 == j)//主题 + { + if (strlen(token) <= 0) + break; + m_AppData.sendTopicStr[topicNum].topic = token; + } + else if (1 == j)//sn名 + { + if (strlen(token) <= 0) + break; + m_AppData.sendTopicStr[topicNum].snName = token; + } + else if(2 == j)//sn下设备名合集 + { + if (strlen(token) <= 0) + break; + m_AppData.sendTopicStr[topicNum].snDeviceName = token; + } + else if (3 == j)//上传周期 + { + if (strlen(token) <= 0) + break; + m_AppData.sendTopicStr[topicNum].sendTime = atoi(token); + memset(filename, 0, 100); + sprintf(filename, "../../data/fes/mqtt_topic_cfg%s.csv", m_AppData.sendTopicStr[topicNum].jsonFileName.c_str()); + m_AppData.sendTopicStr[topicNum].fileMd5 = GetFileMd5(filename); + topicNum ++; + } + else + break; + token = strtok(NULL, ","); + j++; + } + + //超过上限的不处理 + if (topicNum >= MAX_TOPIC_NUM) + { + topicNum = MAX_TOPIC_NUM; + break; + } + } + fclose(fpin); + m_AppData.sendTopicNum = topicNum; + + //读取Topic关联的JSON文件 + //ReadTopic(); + for (int i = 0; i < m_AppData.sendTopicNum; i++) + { + m_AppData.sendTopicStr[i].JsonUpdataFlag = true; + m_AppData.sendTopicStr[i].TopicSendFlag = true; + } +} + + + + +void CYxcloudmqttsDataProcThread::OnSend(int ctlFuncode, int ctlValue) +{ + byte Data[256]; + bool sendFlag = false; + time_t currentTime = time(nullptr); + struct tm* st = localtime(¤tTime); + memset(Data,0,256); + int writex = 0; + Data[writex++] = HEAD_55; + Data[writex++] = HEAD_AA; + if (ctlFuncode == 0) + { + Data[writex++] = (mqttMsg.funcode>>8)&0x00ff; + Data[writex++] = mqttMsg.funcode&0x00ff; + } + else + { + Data[writex++] = (ctlFuncode>>8)&0x00ff; + Data[writex++] = ctlFuncode&0x00ff; + } + + switch(ctlFuncode) + { + case CMD_UPDATE_GATEWAY_RTC://更新网关RTC + Data[writex++] = 0x00; + Data[writex++] = 0x07; + Data[writex++] = ((st->tm_year+1900)>>8)&0x00ff; + Data[writex++] = (st->tm_year+1900)&0x00ff; + Data[writex++] = (st->tm_mon+1)&0x00ff; + Data[writex++] = (st->tm_mday)&0x00ff; + Data[writex++] = (st->tm_hour)&0x00ff; + Data[writex++] = (st->tm_min)&0x00ff; + Data[writex++] = (st->tm_sec)&0x00ff; + break; + case CMD_QUICK_REFRESH_RUNNING_INFO://快速刷新运行信息 + Data[writex++] = 0x00; + Data[writex++] = 0x00; + break; + case CMD_RESTORE_FACTORY_SETTINGS://恢复出厂设置 + Data[writex++] = 0x00; + Data[writex++] = 0x02; + Data[writex++] = ctlValue&0x01; + Data[writex++] = countryInfo&0xff; + break; +// case 0x0BBA://输入直流源模式 +// Data[writex++] = 0x00; +// Data[writex++] = 0x02; +// if(ctlValue == 1 )//直流源模式 +// { +// Data[writex++] = 0x00; +// Data[writex++] = 0xAA; +// } +// else//PV模式 +// { +// Data[writex++] = 0x00; +// Data[writex++] = 0xBB; +// } +// break; + case CMD_POWER_CONTROL://开关机 + Data[writex++] = 0x00; + Data[writex++] = 0x02; + if(ctlValue == 1)//开机 + { + Data[writex++] = 0x00; + Data[writex++] = 0x01; + } + else if(ctlValue == 0)//关机 + { + Data[writex++] = 0x00; + Data[writex++] = 0x00; + } + else if(ctlValue == 2)//快速关机 + { + memset(&Data[8], 0xFF, 4); + Data[writex++] = 0x00; + Data[writex++] = 0x00; + } + else if(ctlValue == 3)//快速开机 + { + memset(&Data[8], 0xFF, 4); + Data[writex++] = 0x00; + Data[writex++] = 0x01; + } + break; + case CMD_ACTIVE_POWER_ADJUSTMENT://指令有功调节 + Data[writex++] = 0x00; + Data[writex++] = 0x04; + if(ctlValue>0 && ctlValue<1000)//启用 + { + Data[writex++] = 0x00; + Data[writex++] = 0xAA; + Data[writex++] = (ctlValue>>8)&0xff; + Data[writex++] = ctlValue&0xff; + } + else + { + for(int n = 0;n<4;n++) + { + Data[writex++] = 0x00; + } + } + break; + case CMD_FIXED_ACTIVE_POWER_SETTING://固定有功设置 + Data[writex++] = 0x00; + Data[writex++] = 0x04; + if(ctlValue<1000)//启用 + { + Data[writex++] = 0x00; + Data[writex++] = 0x55; + Data[writex++] = (ctlValue>>8)&0xff; + Data[writex++] = ctlValue&0xff; + } + else + { + for(int n = 0;n<4;n++) + { + Data[writex++] = 0x00; + } + } + break; + case CMD_REFRESH_TIME_SETTING://刷新时间设置 + memset(&Data[8], 0, 4); + Data[writex++] = 0x00; + Data[writex++] = 0x02; + Data[writex++] = 0x00; + Data[writex++] = ctlValue&0xff; + break; +// case 0x0005://快速刷新运行信息 +// Data[writex++] = 0x00; +// Data[writex++] = 0x02; +// Data[writex++] = (ctlValue>>8)&0xff; +// Data[writex++] = ctlValue&0xff; +// break; +// case 0x0BBC://固定有功设置 +// Data[writex++] = 0x00; +// Data[writex++] = 0x02; +// Data[writex++] = (ctlValue>>8)&0xff; +// Data[writex++] = ctlValue&0xff; +// break; +// case 0x0BBD://保护参数设置 +// Data[writex++] = 0x00; +// Data[writex++] = 0x02; +// Data[writex++] = (ctlValue>>8)&0xff; +// Data[writex++] = ctlValue&0xff; +// break; + case CMD_SAFETY_STANDARD_PARAMETER_QUERY://安规参数查询 + case CMD_PROTECTION_PARAMETER_QUERY://保护参数查询 + Data[writex++] = 0x00; + Data[writex++] = 0x04; + Data[writex++] = 0x00; + Data[writex++] = 0x00; + break; + case CMD_UPDATE_INVERTER_FIRMWARE://功率因素调节 + Data[writex++] = 0x00; + Data[writex++] = 0x04; + if((ctlValue>=-1000 && ctlValue<=-900) || (ctlValue>=900 && ctlValue<=1000))//启用 + { + Data[writex++] = 0x00; + Data[writex++] = 0xAA; + Data[writex++] = (ctlValue>>8)&0xff; + Data[writex++] = ctlValue&0xff; + } + break; +// case 0x0BC4:// PI参数设置 +// Data[writex++] = 0x00; +// Data[writex++] = 0x04; +// Data[writex++] = (ctlValue>>24)&0xff; +// Data[writex++] = (ctlValue>>16)&0xff; +// Data[writex++] = (ctlValue>>8)&0xff; +// Data[writex++] = ctlValue&0xff; +// break; + default: + break; + } + if(ctlFuncode == 0) + { + switch(mqttMsg.funcode) + { + case CMD_UPLOAD_FAULT_INFO: + case CMD_UPDATE_GATEWAY_MCU: + break; + case CMD_FIRMWARE_INFORMATION://固件信息 + Data[writex++] = 0x00; + Data[writex++] = 0x02; + Data[writex++] = 0x00; + Data[writex++] = 0x01; + break; + case CMD_RUNTIME_INFORMATION://读取运行信息响应 + Data[writex++] = 0x00; + Data[writex++] = 0x04; + Data[writex++] = (mqttMsg.frameCode>>8)&0xFF; + Data[writex++] = (mqttMsg.frameCode)&0xFF; + Data[writex++] = 0x00; + Data[writex++] = 0x01; + break; + case CMD_ALL_DERATING_LOGIC_SETTING://保护设置 + break; + default: + break; + } + } + int crcval = CrcSum(&Data[0], writex); + Data[writex++] = crcval&0x00ff; + Data[writex++] = (crcval>>8)&0x00ff; + std::string sendMessage(reinterpret_cast(Data), writex); + std::string sendTopic = "down/"; + sendTopic.append(m_ptrCFesRtu->m_Param.RtuDesc); + if (MqttPublish(sendTopic, sendMessage) == true) sendFlag = true; + + char slog[256]; + memset(slog, 0, 256); + if(sendFlag) + sprintf_s(slog, sizeof(slog),"MQTT Publish:%s, Json:%s 上抛成功", sendTopic.c_str(), m_AppData.sendTopicStr[0].jsonFileName.c_str()); + else + sprintf_s(slog, sizeof(slog),"MQTT Publish:%s, Json:%s 上抛失败", sendTopic.c_str(), m_AppData.sendTopicStr[0].jsonFileName.c_str()); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + mqttClient->sendFrameFlag = false; + //free (Data); +} + + +void CYxcloudmqttsDataProcThread::MainThread() +{ + char fileName[100]; + std::string md5Str; + //系统启动后的运行的秒数 + int64 cursec = getMonotonicMsec() / 1000; + + if (m_AppData.startDelay > 0)//2021-05-06 thxiao 增加延时起动 + { + if ((cursec - mqttTime.startTime) < m_AppData.startDelay) + mqttTime.mqttStartFlag = false; + else + mqttTime.mqttStartFlag = true; + } + else + mqttTime.mqttStartFlag = true; + + if (m_AppData.ymStartDelay > 0) + { + if ((cursec - mqttTime.startTime) < m_AppData.ymStartDelay) + mqttTime.ymStartFlag = false; + else + mqttTime.ymStartFlag = true; + } + else + mqttTime.ymStartFlag = true; + + //周期检查文件是否修改 + if ((cursec - mqttTime.CycTime) > m_AppData.CycReadFileTime) + { + mqttTime.CycTime = cursec; + + //配置参数修改后,需要在线更新 + memset(fileName, 0, 100); + sprintf(fileName, "../../data/fes/mqtt_topic_cfg%d.csv", m_ptrCFesRtu->m_Param.RtuNo); + md5Str = GetFileMd5(fileName); + if (md5Str != m_AppData.TopicCfgMd5) + { + m_AppData.TopicCfgMd5 = md5Str; + //读取mqtt_topic_cfg.csv文件,并更新参数 + GetTopicCfg(); + } + } + //检查各个Topic的发送周期是否到了 + for (int i = 0; i < m_AppData.sendTopicNum; i++) + { + if (m_AppData.sendTopicStr[i].sendTime > 0) + { + //上传周期到,置上发送标志 + if (((cursec - m_AppData.sendTopicStr[i].TopicSendTime) >= m_AppData.sendTopicStr[i].sendTime) + /*&& (m_AppData.sendTopicStr[i].rootJson != NULL)*/) + { + m_AppData.sendTopicStr[i].TopicSendTime = cursec; + m_AppData.sendTopicStr[i].TopicSendFlag = true; + } + } + } + if (mqttTime.mqttSendEndFlag && m_AppData.mqttContFlag) + { + char slog[256]; + memset(slog, 0, 256); + mqttTime.mqttSendEndFlag = false; + //sprintf_s(slog, sizeof(slog),"MQTT 一轮上抛完毕!"); + ShowChanStrData(m_ptrCFesChan->m_Param.ChanNo, slog, CN_SFesSimComFrameTypeSend); + LOGDEBUG("YxcloudmqttsDataProcThread.cpp ChanNo:%d %s:%d %s", m_ptrCFesChan->m_Param.ChanNo, m_ptrCFesChan->m_Param.NetRoute[0].NetDesc, m_ptrCFesChan->m_Param.NetRoute[0].PortNo, slog); + } +} + +void CYxcloudmqttsDataProcThread::OnProcessReceive(byte *RecvMsg , std::string strSN) +{ + if( !mqttClient->sendFrameFlag ) return; //如果没收到信息 + //int funcode; + PCSSN = 0; + GDSN = 0; + + //切换RTU + switchRTUByTopic(strSN); + if(RecvMsg[0] == HEAD_AA && RecvMsg[1] == HEAD_55) + { + mapLastRecvTime[strSN] = getUTCTimeMsec(); + mqttMsg.dataLen = (RecvMsg[4]<<8)|RecvMsg[5]; + mqttMsg.frameCode = (RecvMsg[6]<<8)|RecvMsg[7]; + mqttMsg.funcode = (RecvMsg[2]<<8)|RecvMsg[3]; + switch (mqttMsg.funcode) { + case CMD_FIRMWARE_INFORMATION: + ProcessFirmwareFrame(RecvMsg , strSN); + OnSend(); + SleepmSec(100); + OnSend(CMD_UPDATE_GATEWAY_RTC,1); + break; + case CMD_RUNTIME_INFORMATION: + ProcessDataFrame(RecvMsg , strSN); + OnSend(); + break; + case CMD_SAFETY_STANDARD_PARAMETER_QUERY: + Server_MqttRecv_0BBF(RecvMsg); + break; + case CMD_SAFETY_STANDARD_PARAMETER_SETTING: //安规参数设置 + Server_MqttRecv_0BBE(RecvMsg); + break; + case CMD_PROTECTION_PARAMETER_QUERY: //保护参数查询 + Server_MqttRecv_0BC0(RecvMsg); + break; + case CMD_PROTECTION_PARAMETER_SETTING: //保护参数设置命令 + Server_MqttRecv_0BBD(RecvMsg); + break; + case CMD_ALL_DERATING_LOGIC_SETTING: //设置所有降载逻辑命令 + Server_MqttRecv_0BC2(RecvMsg); + break; + case CMD_ALL_DERATING_LOGIC_QUERY: //查询所有降载逻辑命令 + Server_MqttRecv_0BC3(RecvMsg); + break; + case CMD_PI_PARAMETER_SETTING: //设置PI参数命令 + Server_MqttRecv_0BC4(RecvMsg); + break; + case CMD_PI_PARAMETER_QUERY: //查询PI参数命令 + Server_MqttRecv_0BC5(RecvMsg); + break; + case CMD_MPPT_PARAMETER_SETTING: //设置MPPT参数命令 + Server_MqttRecv_0BC6(RecvMsg); + break; + case CMD_MPPT_PARAMETER_QUERY: //查询MPPT参数命令 + Server_MqttRecv_0BC7(RecvMsg); + break; + case CMD_CHANGE_SN_NUMBER: //修改sn命令 + Server_MqttRecv_0BC8(RecvMsg); + break; + case CMD_UPDATE_INVERTER_FIRMWARE: // 更新 PCS 固件命令 + Server_MqttRecv_0BC8(RecvMsg); + break; + default: + break; + } + memset(&mqttMsg,0,sizeof(mqttMsg)); + mqttClient->sendFrameFlag = false; + + } + +} + +void CYxcloudmqttsDataProcThread::ProcessDataFrame(byte *RecvMsg, std::string strSN) +{ + SFesAi *pAi = NULL; + SFesAcc *pAcc = NULL; + SFesDi *pDi = NULL; + SFesMi *pMi = NULL; + SFesRtuAiValue AiValue[256]; + SFesChgAi ChgAi[256]; + SFesRtuDiValue DiValue[256]; + SFesChgDi ChgDi[256]; + SFesRtuAccValue AccValue[256]; + SFesChgAcc ChgAcc[256]; + SFesRtuMiValue MiValue[256]; + SFesChgMi ChgMi[256]; + //CFesRtuPtr pRtu = NULL; + int ChgCount = 0 , ValueCount = 0; + int i, j, k, l, n = 0; + float aiValue,accValue,miValue; + int diValue; + int readIndex, pointNum; + uint16 uValue16; + uint32 uValue32; + uint64 mSec; + mSec = getUTCTimeMsec(); + readIndex = 8; //帧结构发生变化 + pointNum = 0; + pointNum = m_ptrCFesRtu->m_MaxAiPoints; + for (i = 0; i < pointNum; i++) + { + uValue32 = 0; + pAi = (m_ptrCFesRtu->m_pAi)+i; + if ( mqttMsg.funcode == CMD_RUNTIME_INFORMATION ) + { + bool isNegative = false; + for (n = 0; n < pAi->Param2; n++) + { + uValue32 |= (uint32)RecvMsg[readIndex+n+(pAi->Param1)] << ((pAi->Param2-1-n) * 8); + } + //判断符号位 + if( 1 == pAi->Param3 ) //代表最高位为符号位 + { + isNegative = (uValue32 & (1ULL << ( (8 * pAi->Param2) - 1 ) ) ) != 0; + uValue32 = uValue32 & ( (1ULL << ( (8 * pAi->Param2) - 1 ) ) - 1 ); + } + AiValue[i].PointNo = i; + AiValue[i].Status = 1; + AiValue[i].time = mSec; + aiValue = isNegative? -static_cast(uValue32):static_cast(uValue32); + AiValue[i].Value = aiValue; + if(pAi->Param1 == 0x20) + { + countryInfo = static_cast(aiValue); + } + } + } + for (j = 0; j < m_ptrCFesRtu->m_MaxDiPoints; j++) + { + pDi = (m_ptrCFesRtu->m_pDi)+j; + diValue = 0;//85 + diValue = (RecvMsg[ readIndex + (pDi->Param2)+( 3 - ((pDi->Param1)/8) )]>>((pDi->Param1)%8))&0x01; + if(diValue != pDi->Value) + { + memcpy(ChgDi[ChgCount].TableName,pDi->TableName,CN_FesMaxTableNameSize); + memcpy(ChgDi[ChgCount].ColumnName,pDi->ColumnName,CN_FesMaxColumnNameSize); + memcpy(ChgDi[ChgCount].TagName,pDi->TagName,CN_FesMaxTagSize); + ChgDi[ChgCount].Value = diValue; + ChgDi[ChgCount].Status = 1; + ChgDi[ChgCount].time = mSec; + ChgDi[ChgCount].RtuNo = m_ptrCFesRtu->m_Param.RtuNo; + ChgDi[ChgCount].PointNo = pDi->PointNo; + ChgCount++; + } + + DiValue[j].PointNo = j; + DiValue[j].Status = 1; + DiValue[j].time = mSec; + DiValue[j].Value = diValue; + ValueCount++; + } + for(k = 0; km_MaxAccPoints; k++) + { + uValue32 = 0; + pAcc = (m_ptrCFesRtu->m_pAcc)+k; + if(pAcc->Param2 == 0) + { + continue; + } + for (n = 0; n < pAcc->Param3; n++) + uValue32 |= (uint32)RecvMsg[readIndex+(pAcc->Param2) + n ] << ((pAcc->Param3 -1-n) * 8); + accValue = static_cast(uValue32); + AccValue[k].PointNo = k; + AccValue[k].Status = 1; + AccValue[k].time = mSec; + AccValue[k].Value = accValue; + } + for(l = 0; lm_MaxMiPoints; l++) + { + uValue32 = 0; + pMi = (m_ptrCFesRtu->m_pMi)+l; + for (n = 0; n < pMi->Param2; n++) + { + uValue32 |= (uint32)RecvMsg[readIndex+n+(pMi->Param1)] << ((pMi->Param2 -1-n) * 8); + } + MiValue[l].PointNo = l; + MiValue[l].Status = 1; + MiValue[l].time = mSec; + MiValue[l].Value = static_cast(uValue32); + } + + //LOGINFO("ProcessDataFrame WriteRtuDiValue ChgCount = %d",ChgCount); + if(ChgCount>0) + { + m_ptrCFesBase->WriteChgDiValue(m_ptrCFesRtu,ChgCount,&ChgDi[0]); + } + //LOGINFO("ProcessDataFrame WriteRtuDiValue ValueCount = %d",ValueCount); + if( ValueCount > 0 ) + { + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + } + + ChgCount = 0; + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(pointNum, &AiValue[0], &ChgCount, &ChgAi[0]); + //LOGINFO("ProcessDataFrame WriteRtuAiValueAndRetChg ChgCount = %d",ChgCount); + if(ChgCount>0) + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + ChgCount = 0; + } + + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(m_ptrCFesRtu->m_MaxAccPoints, &AccValue[0], &ChgCount, &ChgAcc[0]); + //LOGINFO("ProcessDataFrame WriteRtuAccValueAndRetChg ChgCount = %d",ChgCount); + if (ChgCount>0) + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(m_ptrCFesRtu->m_MaxMiPoints, &MiValue[0], &ChgCount, &ChgMi[0]); + //LOGINFO("ProcessDataFrame WriteRtuMiValueAndRetChg ChgCount = %d",ChgCount); + if (ChgCount>0) + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } + +} + +void CYxcloudmqttsDataProcThread::ProcessFirmwareFrame(byte *RecvMsg, std::string strSN) +{ + int readIndex = WN_FRAME_DATA; + FirmWareInfo msg; + + msg.DSPDevNum = std::string(reinterpret_cast(RecvMsg + readIndex), 40); + readIndex += 40; + + msg.DSPSoftVersion = std::string(reinterpret_cast(RecvMsg + readIndex), 50); + readIndex += 50; + + msg.DSPPVersion = std::string(reinterpret_cast(RecvMsg + readIndex), 4); + readIndex += 4; + + msg.DSPMCUPNum = std::string(reinterpret_cast(RecvMsg + readIndex), 4); + readIndex += 4; + + msg.MCUSoftVersion = std::string(reinterpret_cast(RecvMsg + readIndex), 16); + readIndex += 16; + + + + m_AllFirmWareInfo[m_ptrCFesRtu->m_Param.RtuDesc] = msg; +// LOGINFO("DSPDevNum = %s",DSPDevNum.c_str()); +// LOGINFO("DSPSoftVersion = %s",DSPSoftVersion.c_str()); +// LOGINFO("DSPPVersion = %s",DSPPVersion.c_str()); +// LOGINFO("DSPMCUPNum = %s",DSPMCUPNum.c_str()); +// LOGINFO("DSPSN = %s",DSPSN.c_str()); +// LOGINFO("MCUSoftVersion = %s",MCUSoftVersion.c_str()); +// LOGINFO("MCUSN = %s",MCUSN.c_str()); + +} + +void CYxcloudmqttsDataProcThread::AoCmdProcess(CFesRtuPtr ptrRtu) +{ + SFesRxAoCmd cmd; + SFesTxAoCmd retCmd; + SFesAo *pAo = NULL; + float fValue, tempValue; + int failed; + memset(&retCmd, 0, sizeof(retCmd)); + memset(&cmd, 0, sizeof(cmd)); + if (ptrRtu->ReadRxAoCmd(1, &cmd) == 1) + { + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + retCmd.CtrlActType=cmd.CtrlActType; + memcpy(retCmd.ColumnName,cmd.ColumnName, sizeof(cmd.ColumnName)); + memcpy(retCmd.TableName,cmd.TableName, sizeof(cmd.TableName)); + memcpy(retCmd.TagName,cmd.TagName, sizeof(cmd.TagName)); + if ((pAo = GetFesAoByPointNo(ptrRtu, cmd.PointID)) != NULL) + { + tempValue = cmd.fValue; + failed = 0; + if (pAo->Coeff != 0) + { + fValue = (tempValue - pAo->Base) / pAo->Coeff; + if (pAo->MaxRange > pAo->MinRange) + { + if ((fValue < pAo->MinRange) || (fValue > pAo->MaxRange)) + { + failed = 1; + } + } + else + { + failed = 1; + } + } + else + { + failed = 1; + } + + if (failed == 1) + { + strcpy(retCmd.TableName, cmd.TableName); + strcpy(retCmd.ColumnName, cmd.ColumnName); + strcpy(retCmd.TagName, cmd.TagName); + strcpy(retCmd.RtuName, cmd.RtuName); + retCmd.retStatus = CN_ControlPointErr; + retCmd.CtrlActType = cmd.CtrlActType; + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + else + { + mqttClient->sendFrameFlag = true; + OnSend(((pAo->Param1)<<8)|(pAo->Param2),static_cast(cmd.fValue)); + retCmd.retStatus = CN_ControlSuccess; + m_ptrCFesBase->WritexAoRespCmdBuf(1, &retCmd); + } + } + } +} + +void CYxcloudmqttsDataProcThread::DoCmdProcess(CFesRtuPtr ptrRtu) +{ + SFesRxDoCmd cmd; + SFesTxDoCmd retCmd; + SFesDo *pDo = NULL; + memset(&retCmd, 0, sizeof(retCmd)); + memset(&cmd, 0, sizeof(cmd)); + if (ptrRtu->ReadRxDoCmd(1, &cmd) == 1) + { + retCmd.CtrlDir = cmd.CtrlDir; + retCmd.RtuNo = cmd.RtuNo; + retCmd.PointID = cmd.PointID; + retCmd.FwSubSystem = cmd.FwSubSystem; + retCmd.FwRtuNo = cmd.FwRtuNo; + retCmd.FwPointNo = cmd.FwPointNo; + retCmd.SubSystem = cmd.SubSystem; + retCmd.CtrlActType=cmd.CtrlActType; + memcpy(retCmd.ColumnName,cmd.ColumnName, sizeof(cmd.ColumnName)); + memcpy(retCmd.TableName,cmd.TableName, sizeof(cmd.TableName)); + memcpy(retCmd.TagName,cmd.TagName, sizeof(cmd.TagName)); + if ((pDo = GetFesDoByPointNo(ptrRtu, cmd.PointID)) != NULL) + { + mqttClient->sendFrameFlag = true; + OnSend(((pDo->Param1)<<8)|(pDo->Param2),cmd.iValue); + retCmd.retStatus = CN_ControlSuccess; + m_ptrCFesBase->WritexDoRespCmdBuf(1, &retCmd); + } + } + +} + +void CYxcloudmqttsDataProcThread::DefCmdProcess(CFesRtuPtr ptrRtu) +{ + SFesRxDefCmd rxDefCmd; + SFesTxDefCmd txDefCmd; + + memset(&rxDefCmd, 0, sizeof(rxDefCmd)); + memset(&txDefCmd, 0, sizeof(txDefCmd)); + + if (ptrRtu->ReadRxDefCmd(1, &rxDefCmd) == 1) + { + strcpy(txDefCmd.TableName, rxDefCmd.TableName); + strcpy(txDefCmd.ColumnName, rxDefCmd.ColumnName); + strcpy(txDefCmd.TagName, rxDefCmd.TagName); + strcpy(txDefCmd.RtuName, rxDefCmd.RtuName); + txDefCmd.CmdNum = rxDefCmd.CmdNum; + txDefCmd.VecCmd = rxDefCmd.VecCmd; + bool flag = true; + + for ( int i = 0; i < txDefCmd.VecCmd.size(); i++) + { + + if( txDefCmd.VecCmd[i].name == "commType") + { + + int commTmp = atoi(txDefCmd.VecCmd[i].value.c_str()); + switch (commTmp) { + case CMD_SAFETY_STANDARD_PARAMETER_SETTING://安规参数设置 + Server_MqttProc_0BBE(ptrRtu , txDefCmd); + break; + case CMD_SAFETY_STANDARD_PARAMETER_QUERY://安规参数查询 + Server_MqttProc_0BBF(ptrRtu , txDefCmd); + break; + case CMD_FIRMWARE_INFORMATION://固件信息 + Server_MqttProc_0BB7(ptrRtu , txDefCmd); + break; + case CMD_PROTECTION_PARAMETER_QUERY://保护参数查询 + Server_MqttProc_0BC0(ptrRtu , txDefCmd); + break; + case CMD_PROTECTION_PARAMETER_SETTING://保护参数设置 + Server_MqttProc_0BBD(ptrRtu , txDefCmd); + break; + case CMD_ALL_DERATING_LOGIC_QUERY://读取全部降载逻辑 + Server_MqttProc_0BC3(ptrRtu , txDefCmd); + break; + case CMD_ALL_DERATING_LOGIC_SETTING: //设置全部降载逻辑 + Server_MqttProc_0BC2(ptrRtu , txDefCmd); + break; + case CMD_PI_PARAMETER_SETTING: + Server_MqttProc_0BC4(ptrRtu , txDefCmd);//设置PI参数 + break; + case CMD_PI_PARAMETER_QUERY: + Server_MqttProc_0BC5(ptrRtu , txDefCmd);//读取PI参数 + break; + case CMD_MPPT_PARAMETER_SETTING: + Server_MqttProc_0BC6(ptrRtu , txDefCmd);//设置mptt参数 + break; + case CMD_MPPT_PARAMETER_QUERY: + Server_MqttProc_0BC7(ptrRtu , txDefCmd);//读取mptt参数 + break; + case CMD_CHANGE_SN_NUMBER: + Server_MqttProc_0BC8(ptrRtu , txDefCmd);//设置sn序列号 + break; + default: + flag = false; + break; + } + + break; + } + + } + if( !flag ) + { + txDefCmd.retStatus = CN_ControlFailed; + ptrRtu->WriteTxDefCmdBuf(1, &txDefCmd); + } + } +} + +//GBK转化为UTF8格式 +std::string CYxcloudmqttsDataProcThread::GbkToUtf8(std::string src_str) +{ + return boost::locale::conv::to_utf(src_str,std::string("gb2312")); +} + +// UTF-8转为GBK2312 +std::string CYxcloudmqttsDataProcThread::Utf8ToGbk(std::string src_str) +{ + return boost::locale::conv::from_utf(src_str,std::string("gb2312")); +} + +void CYxcloudmqttsDataProcThread::checkAllPointStatus() +{ + //多个Rtu 进行更新 + for(auto it = mapLastRecvTime.begin(); it != mapLastRecvTime.end(); ++it) + { + //检测是否超时 + int64 lastTime = getUTCTimeMsec(); + if( CHECK_DIFF_TIME < std::abs(lastTime - it->second) ) + { + if ( switchRTUByTopic(it->first) ) + { + updatePointStatus(); + it->second = lastTime; + } + } + } +} + +void CYxcloudmqttsDataProcThread::updatePointStatus(/*CFesRtuPtr ptrRtu*/) +{ + SFesAi *pAi = NULL; + SFesAcc *pAcc = NULL; + SFesDi *pDi = NULL; + SFesMi *pMi = NULL; + SFesRtuAiValue AiValue[256]; + SFesChgAi ChgAi[256]; + SFesRtuDiValue DiValue[256]; + //SFesChgDi ChgDi[256]; + SFesRtuAccValue AccValue[256]; + SFesChgAcc ChgAcc[256]; + SFesRtuMiValue MiValue[256]; + SFesChgMi ChgMi[256]; + uint64 mSec = getUTCTimeMsec(); + int ValueCount = 0 , ChgCount = 0; + + int pointNum = m_ptrCFesRtu->m_MaxAiPoints; + for( int i = 0 ; i < pointNum ; i++) + { + pAi = (m_ptrCFesRtu->m_pAi)+i; + AiValue[i].PointNo = i; + AiValue[i].Status = 0; //状态未更新 + AiValue[i].time = mSec; + AiValue[i].Value = pAi->Value; + } + for( int j = 0; j < m_ptrCFesRtu->m_MaxDiPoints ; j++) + { + pDi = (m_ptrCFesRtu->m_pDi)+j; + DiValue[j].PointNo = j; + DiValue[j].Status = 0; + DiValue[j].time = mSec; + DiValue[j].Value = pDi->Value; + ValueCount++; + } + for( int k = 0; k < m_ptrCFesRtu->m_MaxAccPoints; k++) + { + pAcc = (m_ptrCFesRtu->m_pAcc)+k; + AccValue[k].PointNo = k; + AccValue[k].Status = 0; + AccValue[k].time = mSec; + AccValue[k].Value = pAcc->Value; + } + + for(int l = 0; lm_MaxMiPoints; l++) + { + pMi = (m_ptrCFesRtu->m_pMi)+l; + MiValue[l].PointNo = l; + MiValue[l].Status = 0; + MiValue[l].time = mSec; + MiValue[l].Value = pMi->Value; + } + + if( ValueCount > 0 ) + { + LOGINFO("Update RtuDiValue ValueCount = %d",ValueCount); + m_ptrCFesRtu->WriteRtuDiValue(ValueCount, &DiValue[0]); + } + + m_ptrCFesRtu->WriteRtuAiValueAndRetChg(pointNum, &AiValue[0], &ChgCount, &ChgAi[0]); + if(ChgCount>0) + { + m_ptrCFesBase->WriteChgAiValue(m_ptrCFesRtu, ChgCount, &ChgAi[0]); + ChgCount = 0; + } + + m_ptrCFesRtu->WriteRtuAccValueAndRetChg(m_ptrCFesRtu->m_MaxAccPoints, &AccValue[0], &ChgCount, &ChgAcc[0]); + if (ChgCount>0) + { + m_ptrCFesBase->WriteChgAccValue(m_ptrCFesRtu, ChgCount, &ChgAcc[0]); + ChgCount = 0; + } + m_ptrCFesRtu->WriteRtuMiValueAndRetChg(m_ptrCFesRtu->m_MaxMiPoints, &MiValue[0], &ChgCount, &ChgMi[0]); + if (ChgCount>0) + { + m_ptrCFesBase->WriteChgMiValue(m_ptrCFesRtu, ChgCount, &ChgMi[0]); + ChgCount = 0; + } +} + + +/** + * @brief CYxcloudmqttsDataProcThread::Server_Mqtt_SendFrame + * @param ctlFuncode cmd功能码 + * @param Lenth data长度 + * @param snNumber sn序号 用于发送主题拼接 + * @param sendInfo data字符串 + */ +bool CYxcloudmqttsDataProcThread::Server_Mqtt_SendFrame(int ctlFuncode , int Lenth, byte *sendInfo, std::string snNumber ) +{ + bool ret = true; + byte bySendBuff[512]; //这个长度是否需要扩展,考虑到有点小符合现在的需求 + memset(bySendBuff,0,512); + + int sendLen = 0; + //帧头结构 + bySendBuff[sendLen++] = HEAD_55; + bySendBuff[sendLen++] = HEAD_AA; + bySendBuff[sendLen++] = (ctlFuncode>>8)&0x00ff; + bySendBuff[sendLen++] = ctlFuncode&0x00ff; + bySendBuff[sendLen++] = (Lenth>>8) & 0xff; + bySendBuff[sendLen++] = Lenth & 0xff; + + //拷贝data内容 + memcpy(bySendBuff + sendLen , sendInfo , Lenth ); + sendLen += Lenth; + + //CRC校验码 + int crcval = CrcSum(&bySendBuff[0], sendLen); + bySendBuff[sendLen++] = crcval & 0xff; + bySendBuff[sendLen++] = (crcval>>8) & 0xff; + + + //发送相应的mqtt报文数据 + std::string sendMessage(reinterpret_cast(bySendBuff), sendLen); + std::string sendTopic = SEND_TOPIC_HEAD; + if( snNumber.empty() ) + { + //使用当前的RTU下的sn序列号 + sendTopic.append(m_ptrCFesRtu->m_Param.RtuDesc); + }else + { + sendTopic.append(snNumber); + } + + if( false == MqttPublish(sendTopic, sendMessage) ) + { + LOGERROR("wn_mqtt send message fail cmdCode: %#X , sendInfo: %s" , ctlFuncode ,sendMessage.c_str()); + ret = false; + } + mqttClient->sendFrameFlag = false; + + return ret; + +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttProc_0BBF + * 用于处理0x0BBF命令 + * @param ptrRtu 传入的Rtu + * @param cmd 相关命令 + */ +void CYxcloudmqttsDataProcThread::Server_MqttProc_0BBF(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd) +{ + if( NULL == ptrRtu) + { + LOGERROR("ptrRtu is NULL!"); + return; + } + + //需通过mqtt下发相应的报文命令 + int len = 0; + byte data[256]; + memset(data , 0 ,256); + + data[len++] = 0x00; + data[len++] = 0x00; + + if ( Server_Mqtt_SendFrame(CMD_SAFETY_STANDARD_PARAMETER_QUERY , len , data , ptrRtu->m_Param.RtuDesc ) ) + { + //存储相应待处理的命令 + CustomCmd cmdTmp; + cmdTmp.defCmd = cmd; + cmdTmp.timestamp = time(NULL); + m_customCmdAck[ptrRtu->m_Param.RtuDesc][CMD_SAFETY_STANDARD_PARAMETER_QUERY] = cmdTmp; + + }else + { + cmd.retStatus = CN_ControlFailed; + ptrRtu->WriteTxDefCmdBuf(1, &cmd); + } +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttRecv_0BBF + * 处理来自PCS上送的安规参数内容 + * @param RecvMsg + */ +void CYxcloudmqttsDataProcThread::Server_MqttRecv_0BBF(byte *RecvMsg) +{ + int readIndex = WN_FRAME_DATA; + + //解析长度 + int recvLen = RecvMsg[WN_FRAME_L]<<8 | RecvMsg[WN_FRAME_L + 1]; + if( recvLen != WN_0BBF_DATA_LEN) + { + LOGERROR("wn_mqtt receive 0x0BBF Msg length error:length = %d " , recvLen); + recvLen = recvLen > WN_0BBF_DATA_LEN?WN_0BBF_DATA_LEN:recvLen; + } + + InvFaultConfigParas data; //这个是否需要储存 现在是暂时未储存 + Byte2n byte2n; + Byte4n byte4n; + + //循环解析保护类型 + for(int i = 0 ; readIndex < recvLen && i < FAULT_COUNT_NUM ; i++ ) + { + InvSingleFaultConfig faultTmp; + + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + faultTmp.faultCode = byte2n.uNum; + + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + faultTmp.triggerThreshold = byte2n.uNum; + + byte4n.cByte[CN_DWB4_HH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_HL] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LL] = RecvMsg[readIndex++]; + faultTmp.triggerTime = byte4n.duNum; + + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + faultTmp.recoveryThreshold = byte2n.uNum; + + byte4n.cByte[CN_DWB4_HH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_HL] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LL] = RecvMsg[readIndex++]; + faultTmp.recoverTime = byte4n.duNum; + + data.fault[i] = faultTmp; + } + + //解析剩余部分 + byte4n.cByte[CN_DWB4_HH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_HL] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LL] = RecvMsg[readIndex++]; + data.mask1 = byte4n.duNum; + + byte4n.cByte[CN_DWB4_HH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_HL] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LL] = RecvMsg[readIndex++]; + data.mask2 = byte4n.duNum; + + byte4n.cByte[CN_DWB4_HH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_HL] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LL] = RecvMsg[readIndex++]; + data.mask3 = byte4n.duNum; + + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + data.countryCode = byte2n.uNum; + + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + data.checksum = byte2n.uNum; + + //找到待处理自定义命令 + auto outerIt = m_customCmdAck.find(m_ptrCFesRtu->m_Param.RtuDesc); + if (outerIt != m_customCmdAck.end()) + { + auto& innerMap = outerIt->second; + auto innerIt = innerMap.find(CMD_SAFETY_STANDARD_PARAMETER_QUERY); + if (innerIt != innerMap.end()) + { + SFesTxDefCmd tmp = innerIt->second.defCmd; + tmp.VecCmd.resize(16); //11+3+2 + int i = 0; + for( ; i < 11 ; i++) + { + tmp.VecCmd[i].name = (boost::format("fault%1%")%i).str(); + string strTmp = ""; + strTmp = (boost::format("%1%,%2%,%3%,%4%,%5%") + % data.fault[i].faultCode + % data.fault[i].triggerThreshold + % data.fault[i].triggerTime + % data.fault[i].recoveryThreshold + % data.fault[i].recoverTime).str(); + tmp.VecCmd[i].value = strTmp; + } + tmp.VecCmd[i].name = "mask1"; + tmp.VecCmd[i++].value = std::to_string(data.mask1); + tmp.VecCmd[i].name = "mask2"; + tmp.VecCmd[i++].value = std::to_string(data.mask2); + tmp.VecCmd[i].name = "mask3"; + tmp.VecCmd[i++].value = std::to_string(data.mask3); + + tmp.VecCmd[i].name = "wCountryCode"; + tmp.VecCmd[i++].value = std::to_string(data.countryCode); + + tmp.VecCmd[i].name = "CrcWode"; + tmp.VecCmd[i++].value = std::to_string(data.checksum); + tmp.retStatus = CN_ControlSuccess; + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &tmp); //发送给app + + //删除已处理的命令 + innerMap.erase(innerIt); + } + } + +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttProc_0BBE + * 接受到安规参数设置命令处理函数 + * @param ptrRtu 当前要发送的RTU结构 + * @param cmd 命令结构 + */ +void CYxcloudmqttsDataProcThread::Server_MqttProc_0BBE(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd) +{ + //解析来自总线的信息 + InvFaultConfigParas para; + std::string str = "fault"; + std::string value = ""; + std::vector tokens; + tokens.clear(); + + for( int i = 0; i < cmd.VecCmd.size(); i++ ) + { + std::string name = cmd.VecCmd[i].name; + if( 0 == name.find(str)) + { + tokens.clear(); + int index = atoi(name.substr(str.length()).c_str()); + index %= FAULT_COUNT_NUM; + InvSingleFaultConfig faultTmp; + value = cmd.VecCmd[i].value; + boost::split(tokens , value , boost::is_any_of(",") , boost::token_compress_on); + if( FAULT_CONFIG != tokens.size() ) continue; + else + { + faultTmp.faultCode = atoi( tokens[0].c_str()); + faultTmp.triggerThreshold = atoi( tokens[1].c_str()); + faultTmp.triggerTime = atoi( tokens[2].c_str()); + faultTmp.recoveryThreshold = atoi( tokens[3].c_str()); + faultTmp.recoverTime = atoi( tokens[4].c_str()); + } + + para.fault[index] = faultTmp; + + + }else if( name=="mask1") + { + value = cmd.VecCmd[i].value; + para.mask1 = atoi( value.c_str()); + + }else if( name=="mask2" ) + { + value = cmd.VecCmd[i].value; + para.mask2 = atoi( value.c_str()); + + }else if( name=="mask3") + { + value = cmd.VecCmd[i].value; + para.mask3 = atoi( value.c_str()); + }else if( name=="wCountryCode") + { + value = cmd.VecCmd[i].value; + para.countryCode = atoi( value.c_str()); + }else if( name=="CrcWode") + { + value = cmd.VecCmd[i].value; + para.checksum = atoi( value.c_str()); + } + } + + if( !Server_MqttSend_0BBE(para , ptrRtu->m_Param.RtuDesc)) + { + cmd.retStatus = CN_ControlFailed; + ptrRtu->WriteTxDefCmdBuf(1, &cmd); + }else + { + CustomCmd cmdTmp; + cmdTmp.defCmd = cmd; + cmdTmp.timestamp = time(NULL); + m_customCmdAck[ ptrRtu->m_Param.RtuDesc ][CMD_SAFETY_STANDARD_PARAMETER_SETTING] = cmdTmp; + } + +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttSend_0BBE + * 下发安规参数处理命令 + * @param paras 安规参数结构 + * @param ptrRtu 当前要发送的RTU结构 + */ +bool CYxcloudmqttsDataProcThread::Server_MqttSend_0BBE(InvFaultConfigParas ¶s, std::string sendTopic) +{ + //编码安规参数 + Byte2n byte2n; + Byte4n byte4n; + bool res = true; + int len = 0; + byte dataInfo[512]; + memset(dataInfo , 0 ,512); + + //编码保护类型 + for(int i = 0; i < FAULT_COUNT_NUM ; i++ ) + { + InvSingleFaultConfig faultTmp = paras.fault[i]; + + byte2n.uNum = faultTmp.faultCode; + dataInfo[len++] = byte2n.cByte[CN_BYTE_HI]; + dataInfo[len++] = byte2n.cByte[CN_BYTE_LO]; + + byte2n.uNum = faultTmp.triggerThreshold; + dataInfo[len++] = byte2n.cByte[CN_BYTE_HI]; + dataInfo[len++] = byte2n.cByte[CN_BYTE_LO]; + + byte4n.duNum = faultTmp.triggerTime; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HL]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LL]; + + byte2n.uNum = faultTmp.recoveryThreshold; + dataInfo[len++] = byte2n.cByte[CN_BYTE_HI]; + dataInfo[len++] = byte2n.cByte[CN_BYTE_LO]; + + byte4n.duNum = faultTmp.recoverTime; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HL]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LL]; + } + + //编码其他部分 + byte4n.duNum = paras.mask1; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HL]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LL]; + + byte4n.duNum = paras.mask2; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HL]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LL]; + + byte4n.duNum = paras.mask3; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HL]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LL]; + + byte2n.uNum = paras.countryCode; + dataInfo[len++] = byte2n.cByte[CN_BYTE_HI]; + dataInfo[len++] = byte2n.cByte[CN_BYTE_LO]; + + byte2n.uNum = paras.checksum; + dataInfo[len++] = byte2n.cByte[CN_BYTE_HI]; + dataInfo[len++] = byte2n.cByte[CN_BYTE_LO]; + + + if( Server_Mqtt_SendFrame(CMD_SAFETY_STANDARD_PARAMETER_SETTING , len , dataInfo , sendTopic ) ) + { + //do something 暂不知道要做什么 + }else + { + res = false; + } + + + return res; + +} +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttRecv_0BBE + * 用于处理来自设备的设置命令回复 + * @param RecvMsg + */ +void CYxcloudmqttsDataProcThread::Server_MqttRecv_0BBE(byte *RecvMsg) +{ + int readIndex = WN_FRAME_DATA; + + //解析应答状态 + uint16 ackState = 0; + Byte2n byte2n; + + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + ackState = byte2n.uNum; + + //找到待处理自定义命令 + auto outerIt = m_customCmdAck.find(m_ptrCFesRtu->m_Param.RtuDesc); + if (outerIt != m_customCmdAck.end()) + { + auto& innerMap = outerIt->second; + auto innerIt = innerMap.find(CMD_SAFETY_STANDARD_PARAMETER_SETTING); + if (innerIt != innerMap.end()) + { + SFesTxDefCmd &tmp = innerIt->second.defCmd; + tmp.retStatus = CN_ControlFailed; + if( 0x0002 == ackState ) + { + tmp.retStatus = CN_ControlSuccess; + } + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &tmp); + + //删除已处理的命令 + innerMap.erase(innerIt); + } + } +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttProc_0BBD + * 用于处理来自总线的保护参数设置命令 + * @param ptrRtu + * @param cmd + */ +void CYxcloudmqttsDataProcThread::Server_MqttProc_0BBD(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd) +{ + + if( !Server_MqttSend_0BBD(cmd ,ptrRtu->m_Param.RtuDesc) ) + { + cmd.retStatus = CN_ControlFailed; + ptrRtu->WriteTxDefCmdBuf(1, &cmd); + } + +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttSend_0BBD + * 用于下发保护参数设置命令 + * @param paras + * @param sendTopic + * @return + */ +bool CYxcloudmqttsDataProcThread::Server_MqttSend_0BBD(SFesTxDefCmd &cmd , string sendTopic) +{ //一次传送全部值 值与值之间通过,隔开 + std::vector tokens; + tokens.clear(); + ProtectPara tmp; + Byte2n byte2n; + Byte4n byte4n; + int len = 0; + byte dataInfo[512]; + memset(dataInfo , 0 ,512); + bool res = false; + + for( int i = 0; i < cmd.VecCmd.size(); i++) + { + std::string name = cmd.VecCmd[i].name; + if( name == "settingValues") + { + std::string value = cmd.VecCmd[i].value; + boost::split(tokens , value , boost::is_any_of(",") , boost::token_compress_off); + for(int j = 0; j < min(tokens.size(), m_AppData.protectparaList.size()); j++) + { + tmp = m_AppData.protectparaList.at(j); + double paraValue = atof(tokens[j].c_str()) / tmp.resolvingPower; + if( 2 == tmp.byteNum) + { + byte2n.uNum = static_cast(paraValue); + dataInfo[len++] = byte2n.cByte[CN_BYTE_HI]; + dataInfo[len++] = byte2n.cByte[CN_BYTE_LO]; + }else if( 4 == tmp.byteNum) + { + byte4n.duNum = static_cast(paraValue); + dataInfo[len++] = byte4n.cByte[CN_DWB4_HH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HL]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LL]; + } + } + + if( Server_Mqtt_SendFrame(CMD_PROTECTION_PARAMETER_SETTING , len , dataInfo , sendTopic ) ) + { + //存储相应待处理的命令 + CustomCmd cmdTmp; + cmdTmp.defCmd = cmd; + cmdTmp.timestamp = time(NULL); + m_customCmdAck[sendTopic][CMD_PROTECTION_PARAMETER_SETTING] = cmdTmp; + res = true; + } + + break; + } + + } + return res; +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttRecv_0BBD + * 用于处理保护参数设置命令的回复 + * @param RecvMsg + */ +void CYxcloudmqttsDataProcThread::Server_MqttRecv_0BBD(byte *RecvMsg) +{ + int readIndex = WN_FRAME_DATA; + + //解析应答状态 + uint16 ackState = 0; + Byte2n byte2n; + + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + ackState = byte2n.uNum; + + auto outerIt = m_customCmdAck.find(m_ptrCFesRtu->m_Param.RtuDesc); + if (outerIt != m_customCmdAck.end()) + { + auto& innerMap = outerIt->second; + auto innerIt = innerMap.find(CMD_PROTECTION_PARAMETER_SETTING); + if (innerIt != innerMap.end()) + { + SFesTxDefCmd &tmp = innerIt->second.defCmd; + tmp.retStatus = CN_ControlFailed; + if( 0x0002 == ackState ) + { + tmp.retStatus = CN_ControlSuccess; + } + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &tmp); + + //删除已处理的命令 + innerMap.erase(innerIt); + } + } + +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttProc_0BC0 + * 下发保护参数查询命令 + * @param ptrRtu + * @param cmd + */ +void CYxcloudmqttsDataProcThread::Server_MqttProc_0BC0(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd) +{ + if( NULL == ptrRtu) + { + LOGERROR("ptrRtu is NULL!"); + return; + } + + //需通过mqtt下发相应的报文命令 + int len = 0; + byte data[256]; + memset(data , 0 ,256); + + data[len++] = 0x00; + data[len++] = 0x00; + + if ( Server_Mqtt_SendFrame(CMD_PROTECTION_PARAMETER_QUERY , len , data , ptrRtu->m_Param.RtuDesc ) ) + { + //存储相应待处理的命令 + CustomCmd cmdTmp; + cmdTmp.defCmd = cmd; + cmdTmp.timestamp = time(NULL); + m_customCmdAck[ptrRtu->m_Param.RtuDesc][CMD_PROTECTION_PARAMETER_QUERY] = cmdTmp; + }else + { + cmd.retStatus = CN_ControlFailed; + ptrRtu->WriteTxDefCmdBuf(1, &cmd); + } +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC0 + * 接收保护参数查询命令 + * @param RecvMsg + */ +void CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC0(byte *RecvMsg) +{ + int readIndex = WN_FRAME_DATA; + + //解析长度 + int recvLen = RecvMsg[WN_FRAME_L]<<8 | RecvMsg[WN_FRAME_L + 1]; + + //找到待处理自定义命令 + auto outerIt = m_customCmdAck.find(m_ptrCFesRtu->m_Param.RtuDesc); + if (outerIt != m_customCmdAck.end()) + { + auto& innerMap = outerIt->second; + auto innerIt = innerMap.find(CMD_PROTECTION_PARAMETER_QUERY); + if (innerIt != innerMap.end()) + { + //找到了待保存的命令 + SFesTxDefCmd tmp = innerIt->second.defCmd; + tmp.VecCmd.resize(m_AppData.protectparaList.size()); + for(int i = 0; i< m_AppData.protectparaList.size() ; i++) + { + ProtectPara &tmpPara = m_AppData.protectparaList.at(i); + tmp.VecCmd[i].name = tmpPara.proParaDesc; + float value = 0; + if( 2 == tmpPara.byteNum) + { + Byte2n byte2n; + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + value = byte2n.uNum * tmpPara.resolvingPower; + }else if( 4 == tmpPara.byteNum) + { + Byte4n byte4n; + byte4n.cByte[CN_DWB4_HH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_HL] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LL] = RecvMsg[readIndex++]; + value = byte4n.duNum * tmpPara.resolvingPower; + } + std::string str = (boost::format("%1%,%2%,%3%")%to_string(value)%tmpPara.ppUnit%tmpPara.ppRange).str(); + //std::string str = to_string(value) + tmpPara.ppUnit; + tmp.VecCmd[i].value = str; + } + tmp.retStatus = CN_ControlSuccess; + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &tmp); //发送给app + + //删除已处理的命令 + innerMap.erase(innerIt); + } + } + +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttProc_0BC2 + * 处理设置全部降载逻辑 + * @param ptrRtu + * @param cmd + */ +void CYxcloudmqttsDataProcThread::Server_MqttProc_0BC2(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd) +{ + if( !Server_MqttSend_0BC2(cmd , ptrRtu->m_Param.RtuDesc)) + { + cmd.retStatus = CN_ControlFailed; + ptrRtu->WriteTxDefCmdBuf(1, &cmd); + } +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttSend_0BC2 + * 发送设置全部降载逻辑命令 + * @param cmd + * @param sendTopic + * @return + */ +bool CYxcloudmqttsDataProcThread::Server_MqttSend_0BC2(SFesTxDefCmd &cmd, string sendTopic) +{ + //一次性上送所有的值,值与值之间通过,隔开 + std::vector tokens; + tokens.clear(); + byte dataInfo[512]; + memset(dataInfo , 0 , 512); + int len = 0; + bool res = false; + Byte2n byte2n; + byte2n.uNum = 0; + Byte4n byte4n; + byte4n.duNum = 0; + ProtectPara_List list; + list.clear(); + + if( m_AppData.m_parasConfig.find(UNLOAD_LOGIC_SHEETNAME) != m_AppData.m_parasConfig.end()) + { + list = m_AppData.m_parasConfig[UNLOAD_LOGIC_SHEETNAME]; + } + + int i = 0 , j = 0 , index = 0; + while( i < cmd.VecCmd.size() && j < list.size() ) + { + if( cmd.VecCmd.at(i).name == list.at(j).parentDesc ) + { + index = 0; + tokens.clear(); + boost::split(tokens , cmd.VecCmd.at(i).value , boost::is_any_of(",") , boost::token_compress_off); + while( j < list.size() && index < tokens.size() && cmd.VecCmd.at(i).name == list.at(j).parentDesc ) + { + ProtectPara &tmpPara = list.at(j); + double paraValue = atof(tokens[index].c_str()) / tmpPara.resolvingPower; + if( 2 == tmpPara.byteNum) + { + byte2n.uNum = static_cast(paraValue); + dataInfo[len++] = byte2n.cByte[CN_BYTE_HI]; + dataInfo[len++] = byte2n.cByte[CN_BYTE_LO]; + }else if( 4 == tmpPara.byteNum) + { + byte4n.duNum = static_cast(paraValue); + dataInfo[len++] = byte4n.cByte[CN_DWB4_HH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HL]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LL]; + } + j++; + index ++; + } + }else + { + i++; + } + } + + if( Server_Mqtt_SendFrame(CMD_ALL_DERATING_LOGIC_SETTING , len , dataInfo , sendTopic ) ) + { + //存储相应待处理的命令 + CustomCmd cmdTmp; + cmdTmp.defCmd = cmd; + cmdTmp.timestamp = time(NULL); + m_customCmdAck[sendTopic][CMD_ALL_DERATING_LOGIC_SETTING] = cmdTmp; + + res = true; + } + + return res; +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC2 + * 接收 设置降载逻辑参数 状态回复 + * @param RecvMsg + */ +void CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC2(byte *RecvMsg) +{ + int readIndex = WN_FRAME_DATA; + + //解析应答状态 + uint16 ackState = 0; + Byte2n byte2n; + byte2n.uNum = 0; + + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + ackState = byte2n.uNum; + + auto outerIt = m_customCmdAck.find(m_ptrCFesRtu->m_Param.RtuDesc); + if (outerIt != m_customCmdAck.end()) + { + auto& innerMap = outerIt->second; + auto innerIt = innerMap.find(CMD_ALL_DERATING_LOGIC_SETTING); + if (innerIt != innerMap.end()) + { + SFesTxDefCmd tmp = innerIt->second.defCmd; + tmp.retStatus = CN_ControlFailed; + if( 0x0001 == ackState ) + { + tmp.retStatus = CN_ControlSuccess; + } + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &tmp); + + //删除已处理的命令 + innerMap.erase(innerIt); + } + } + +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttProc_0BC3 + * 处理全部降载逻辑读取发送 + * @param ptrRtu + * @param cmd + */ +void CYxcloudmqttsDataProcThread::Server_MqttProc_0BC3(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd) +{ + if( NULL == ptrRtu) + { + LOGERROR("ptrRtu is NULL!"); + return; + } + + //需通过mqtt下发相应的报文命令 + int len = 0; + byte data[256]; + memset(data , 0 ,256); + + data[len++] = 0x00; + data[len++] = 0x00; + + if ( Server_Mqtt_SendFrame(CMD_ALL_DERATING_LOGIC_QUERY , len , data , ptrRtu->m_Param.RtuDesc ) ) + { + //存储相应待处理的命令 + CustomCmd cmdTmp; + cmdTmp.defCmd = cmd; + cmdTmp.timestamp = time(NULL); + m_customCmdAck[ptrRtu->m_Param.RtuDesc][CMD_ALL_DERATING_LOGIC_QUERY] = cmdTmp; + + }else + { + cmd.retStatus = CN_ControlFailed; + ptrRtu->WriteTxDefCmdBuf(1, &cmd); + } + +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC3 + * 处理查询所有降载逻辑命令的回复 + * @param RecvMsg + */ +void CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC3(byte *RecvMsg) +{ + int readIndex = WN_FRAME_DATA; + //解析长度 + int recvLen = RecvMsg[WN_FRAME_L]<<8 | RecvMsg[WN_FRAME_L + 1]; + + Byte2n byte2n; + Byte4n byte4n; + byte2n.uNum = 0; + byte4n.duNum = 0; + + //找到待处理自定义命令 + auto outerIt = m_customCmdAck.find(m_ptrCFesRtu->m_Param.RtuDesc); + if (outerIt != m_customCmdAck.end()) + { + auto& innerMap = outerIt->second; + auto innerIt = innerMap.find(CMD_ALL_DERATING_LOGIC_QUERY); + if (innerIt != innerMap.end()) + { + SFesTxDefCmd tmp = innerIt->second.defCmd; + ProtectPara_List list; + list.clear(); + if( m_AppData.m_parasConfig.find(UNLOAD_LOGIC_SHEETNAME) != m_AppData.m_parasConfig.end()) + { + list = m_AppData.m_parasConfig[UNLOAD_LOGIC_SHEETNAME]; + } + tmp.VecCmd.clear(); + std::string oldstr = ""; + std::stringstream valueStr; + float value = 0; + FesDefCmd defCmd; + for( int i = 0 ; i < list.size() ;) + { + ProtectPara &tmpPara = list.at(i); + std::string newstr = tmpPara.parentDesc; + if( 2 == tmpPara.byteNum) + { + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + value = byte2n.uNum * tmpPara.resolvingPower; + } + else if( 4 == tmpPara.byteNum) + { + byte4n.cByte[CN_DWB4_HH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_HL] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LL] = RecvMsg[readIndex++]; + value = byte4n.duNum * tmpPara.resolvingPower; + } + + if( i ==0 || newstr == oldstr) + { + if (valueStr.tellp() > 0) { + valueStr << ", "; + } + valueStr << value; + i++; + } + else + { + + defCmd.name = oldstr; + defCmd.value = valueStr.str(); + tmp.VecCmd.push_back(defCmd); + valueStr.str(""); + readIndex -= tmpPara.byteNum; + } + + + if( i == list.size() ) + { + defCmd.name = oldstr; + defCmd.value = valueStr.str(); + tmp.VecCmd.push_back(defCmd); + } + oldstr = newstr; + } + + + tmp.retStatus = CN_ControlSuccess; + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &tmp); //发送给app + + //删除已处理的命令 + innerMap.erase(innerIt); + } + } +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttProc_0BC4 + * 处理 PI参数设置命令 + * @param ptrRtu + * @param cmd + */ +void CYxcloudmqttsDataProcThread::Server_MqttProc_0BC4(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd) +{ + if( !Server_MqttSend_0BC4(cmd , ptrRtu->m_Param.RtuDesc)) + { + cmd.retStatus = CN_ControlFailed; + ptrRtu->WriteTxDefCmdBuf(1, &cmd); + } +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttSend_0BC4 + * 发送 PI参数设置命令 + * @param cmd + * @param sendTopic + * @return + */ +bool CYxcloudmqttsDataProcThread::Server_MqttSend_0BC4(SFesTxDefCmd &cmd, string sendTopic) +{ + //一次性上送所有的值 , 值与值之间用,隔开 + std::vector tokens; + tokens.clear(); + byte dataInfo[512]; + memset(dataInfo , 0 , 512); + int len = 0; + bool res = false; + Byte2n byte2n; + byte2n.uNum = 0; + Byte4n byte4n; + byte4n.duNum = 0; + ProtectPara_List list; + + list.clear(); + if( m_AppData.m_parasConfig.find(PARA_PI_SHEETNAME) != m_AppData.m_parasConfig.end()) + { + list = m_AppData.m_parasConfig[PARA_PI_SHEETNAME]; + } + + int i = 0 , j = 0 , index = 0; + for(i = 0 ; i < cmd.VecCmd.size(); i++) + { + if(cmd.VecCmd.at(i).name == "settingValues") + { + index = 0; + tokens.clear(); + boost::split(tokens , cmd.VecCmd.at(i).value , boost::is_any_of(",") , boost::token_compress_off); + while( j < list.size() && index < tokens.size() ) + { + ProtectPara &tmpPara = list.at(j); + double paraValue = atof(tokens[index].c_str()) / tmpPara.resolvingPower; + if( 2 == tmpPara.byteNum) + { + byte2n.uNum = static_cast(paraValue); + dataInfo[len++] = byte2n.cByte[CN_BYTE_HI]; + dataInfo[len++] = byte2n.cByte[CN_BYTE_LO]; + }else if( 4 == tmpPara.byteNum) + { + byte4n.duNum = static_cast(paraValue); + dataInfo[len++] = byte4n.cByte[CN_DWB4_HH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HL]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LL]; + } + j++; + index ++; + } + } + } + + if( Server_Mqtt_SendFrame(CMD_PI_PARAMETER_SETTING , len , dataInfo , sendTopic ) ) + { + //存储相应待处理的命令 + CustomCmd cmdTmp; + cmdTmp.defCmd = cmd; + cmdTmp.timestamp = time(NULL); + m_customCmdAck[sendTopic][CMD_PI_PARAMETER_SETTING] = cmdTmp; + res = true; + } + + return res; +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC4 + * 接收处理 设置PI参数的回复 + * @param RecvMsg + */ +void CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC4(byte *RecvMsg) +{ + int readIndex = WN_FRAME_DATA; + + //解析应答状态 + uint16 ackState = 0; + Byte2n byte2n; + byte2n.uNum = 0; + + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + ackState = byte2n.uNum; + + //找到待处理自定义命令 + auto outerIt = m_customCmdAck.find(m_ptrCFesRtu->m_Param.RtuDesc); + if (outerIt != m_customCmdAck.end()) + { + auto& innerMap = outerIt->second; + auto innerIt = innerMap.find(CMD_PI_PARAMETER_SETTING); + if (innerIt != innerMap.end()) + { + SFesTxDefCmd tmp = innerIt->second.defCmd; + tmp.retStatus = CN_ControlFailed; + if( 0x0001 == ackState ) + { + tmp.retStatus = CN_ControlSuccess; + } + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &tmp); + + //删除已处理的命令 + innerMap.erase(innerIt); + } + } +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttProc_0BC5 + * 下发 PI参数读取命令 + * @param ptrRtu + * @param cmd + */ +void CYxcloudmqttsDataProcThread::Server_MqttProc_0BC5(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd) +{ + + if( NULL == ptrRtu) + { + LOGERROR("ptrRtu is NULL!"); + return; + } + + //需通过mqtt下发相应的报文命令 + int len = 0; + byte data[256]; + memset(data , 0 ,256); + + data[len++] = 0x00; + data[len++] = 0x00; + + if ( Server_Mqtt_SendFrame(CMD_PI_PARAMETER_QUERY , len , data , ptrRtu->m_Param.RtuDesc ) ) + { + //存储相应待处理的命令 + CustomCmd cmdTmp; + cmdTmp.defCmd = cmd; + cmdTmp.timestamp = time(NULL); + m_customCmdAck[ptrRtu->m_Param.RtuDesc][CMD_PI_PARAMETER_QUERY] = cmdTmp; + + }else + { + cmd.retStatus = CN_ControlFailed; + ptrRtu->WriteTxDefCmdBuf(1, &cmd); + } + +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC5 + * PI参数查询 命令回复 + * @param RecvMsg + */ +void CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC5(byte *RecvMsg) +{ + int readIndex = WN_FRAME_DATA; + //解析长度 + int recvLen = RecvMsg[WN_FRAME_L]<<8 | RecvMsg[WN_FRAME_L + 1]; + + Byte2n byte2n; + Byte4n byte4n; + byte2n.uNum = 0; + byte4n.duNum = 0; + + //找到待处理自定义命令 + auto outerIt = m_customCmdAck.find(m_ptrCFesRtu->m_Param.RtuDesc); + if (outerIt != m_customCmdAck.end()) + { + auto& innerMap = outerIt->second; + auto innerIt = innerMap.find(CMD_PI_PARAMETER_QUERY); + if (innerIt != innerMap.end()) + { + SFesTxDefCmd tmp = innerIt->second.defCmd; + ProtectPara_List list; + list.clear(); + if( m_AppData.m_parasConfig.find(PARA_PI_SHEETNAME) != m_AppData.m_parasConfig.end()) + { + list = m_AppData.m_parasConfig[PARA_PI_SHEETNAME]; + } + tmp.VecCmd.clear(); + float value = 0; + for( int i = 0; i< list.size() ; i++) + { + ProtectPara &tmpPara = list.at(i); + if( 2 == tmpPara.byteNum) + { + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + value = byte2n.uNum * tmpPara.resolvingPower; + } + else if( 4 == tmpPara.byteNum) + { + byte4n.cByte[CN_DWB4_HH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_HL] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LL] = RecvMsg[readIndex++]; + value = byte4n.duNum * tmpPara.resolvingPower; + } + + FesDefCmd defCmd; + defCmd.name = tmpPara.proParaDesc; + defCmd.value = std::to_string( value )+ tmpPara.ppUnit; + tmp.VecCmd.push_back(defCmd); + } + + tmp.retStatus = CN_ControlSuccess; + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &tmp); + + //删除已处理的命令 + innerMap.erase(innerIt); + } + } + +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttProc_0BC6 + * 处理 MPPT 参数设置 + * @param ptrRtu + * @param cmd + */ +void CYxcloudmqttsDataProcThread::Server_MqttProc_0BC6(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd) +{ + if( !Server_MqttSend_0BC6(cmd , ptrRtu->m_Param.RtuDesc)) + { + cmd.retStatus = CN_ControlFailed; + ptrRtu->WriteTxDefCmdBuf(1, &cmd); + } +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttSend_0BC6 + * 发送 MPPT 参数设置 + * @param cmd + * @param sendTopic + * @return + */ +bool CYxcloudmqttsDataProcThread::Server_MqttSend_0BC6(SFesTxDefCmd &cmd, string sendTopic) +{ + //一次性上送所有的值 , 值与值之间用,隔开 + std::vector tokens; + tokens.clear(); + byte dataInfo[512]; + memset(dataInfo , 0 , 512); + int len = 0; + bool res = false; + Byte2n byte2n; + byte2n.uNum = 0; + Byte4n byte4n; + byte4n.duNum = 0; + ProtectPara_List list; + list.clear(); + if( m_AppData.m_parasConfig.find(PARA_MPPT_SHEETNAME) != m_AppData.m_parasConfig.end()) + { + list = m_AppData.m_parasConfig[PARA_MPPT_SHEETNAME]; + } + + int i = 0 , j = 0 , index = 0; + for( i = 0 ; i < cmd.VecCmd.size(); i++) + { + if(cmd.VecCmd.at(i).name == "settingValues") + { + index = 0; + tokens.clear(); + boost::split(tokens , cmd.VecCmd.at(i).value , boost::is_any_of(",") , boost::token_compress_off); + while( j < list.size() && index < tokens.size() ) + { + ProtectPara &tmpPara = list.at(j); + double paraValue = atof(tokens[index].c_str()) / tmpPara.resolvingPower; + if( 2 == tmpPara.byteNum) + { + byte2n.uNum = static_cast(paraValue); + dataInfo[len++] = byte2n.cByte[CN_BYTE_HI]; + dataInfo[len++] = byte2n.cByte[CN_BYTE_LO]; + }else if( 4 == tmpPara.byteNum) + { + byte4n.duNum = static_cast(paraValue); + dataInfo[len++] = byte4n.cByte[CN_DWB4_HH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_HL]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LH]; + dataInfo[len++] = byte4n.cByte[CN_DWB4_LL]; + } + j++; + index ++; + } + } + } + + if( Server_Mqtt_SendFrame(CMD_MPPT_PARAMETER_SETTING , len , dataInfo , sendTopic ) ) + { + //存储相应待处理的命令 + CustomCmd cmdTmp; + cmdTmp.defCmd = cmd; + cmdTmp.timestamp = time(NULL); + m_customCmdAck[sendTopic][CMD_MPPT_PARAMETER_SETTING] = cmdTmp; + res = true; + } + + return res; +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC6 + * 接收处理 设置mppt参数的回复 + * @param RecvMsg + */ +void CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC6(byte *RecvMsg) +{ + int readIndex = WN_FRAME_DATA; + + //解析应答状态 + uint16 ackState = 0; + Byte2n byte2n; + byte2n.uNum = 0; + + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + ackState = byte2n.uNum; + + //找到待处理自定义命令 + auto outerIt = m_customCmdAck.find(m_ptrCFesRtu->m_Param.RtuDesc); + if (outerIt != m_customCmdAck.end()) + { + auto& innerMap = outerIt->second; + auto innerIt = innerMap.find(CMD_MPPT_PARAMETER_SETTING); + if (innerIt != innerMap.end()) + { + SFesTxDefCmd tmp = innerIt->second.defCmd; + tmp.retStatus = CN_ControlFailed; + if( 0x0001 == ackState ) + { + tmp.retStatus = CN_ControlSuccess; + } + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &tmp); + + //删除已处理的命令 + innerMap.erase(innerIt); + } + } +} +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttProc_0BC7 + * 下发 MPPT参数读取命令 + * @param ptrRtu + * @param cmd + */ +void CYxcloudmqttsDataProcThread::Server_MqttProc_0BC7(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd) +{ + if( NULL == ptrRtu) + { + LOGERROR("ptrRtu is NULL!"); + return; + } + + //需通过mqtt下发相应的报文命令 + int len = 0; + byte data[256]; + memset(data , 0 ,256); + + data[len++] = 0x00; + data[len++] = 0x00; + + if ( Server_Mqtt_SendFrame(CMD_MPPT_PARAMETER_QUERY , len , data , ptrRtu->m_Param.RtuDesc ) ) + { + //存储相应待处理的命令 + CustomCmd cmdTmp; + cmdTmp.defCmd = cmd; + cmdTmp.timestamp = time(NULL); + m_customCmdAck[ptrRtu->m_Param.RtuDesc][CMD_MPPT_PARAMETER_QUERY] = cmdTmp; + + }else + { + cmd.retStatus = CN_ControlFailed; + ptrRtu->WriteTxDefCmdBuf(1, &cmd); + } +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC7 + * MPPT参数查询 命令回复 + * @param RecvMsg + */ +void CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC7(byte *RecvMsg) +{ + int readIndex = WN_FRAME_DATA; + //解析长度 + int recvLen = RecvMsg[WN_FRAME_L]<<8 | RecvMsg[WN_FRAME_L + 1]; + + Byte2n byte2n; + Byte4n byte4n; + byte2n.uNum = 0; + byte4n.duNum = 0; + + //找到待处理自定义命令 + auto outerIt = m_customCmdAck.find(m_ptrCFesRtu->m_Param.RtuDesc); + if (outerIt != m_customCmdAck.end()) + { + auto& innerMap = outerIt->second; + auto innerIt = innerMap.find(CMD_MPPT_PARAMETER_QUERY); + if (innerIt != innerMap.end()) + { + SFesTxDefCmd tmp = innerIt->second.defCmd; + ProtectPara_List list; + list.clear(); + if( m_AppData.m_parasConfig.find(PARA_MPPT_SHEETNAME) != m_AppData.m_parasConfig.end()) + { + list = m_AppData.m_parasConfig[PARA_MPPT_SHEETNAME]; + } + tmp.VecCmd.clear(); + float value = 0; + for( int i = 0; i< list.size() ; i++) + { + ProtectPara &tmpPara = list.at(i); + if( 2 == tmpPara.byteNum) + { + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + value = byte2n.uNum * tmpPara.resolvingPower; + } + else if( 4 == tmpPara.byteNum) + { + byte4n.cByte[CN_DWB4_HH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_HL] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LH] = RecvMsg[readIndex++]; + byte4n.cByte[CN_DWB4_LL] = RecvMsg[readIndex++]; + value = byte4n.duNum * tmpPara.resolvingPower; + } + + FesDefCmd defCmd; + defCmd.name = tmpPara.proParaDesc; + defCmd.value = std::to_string( value ) + tmpPara.ppUnit; + tmp.VecCmd.push_back(defCmd); + } + + tmp.retStatus = CN_ControlSuccess; + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &tmp); + + //删除已处理的命令 + innerMap.erase(innerIt); + } + } + +} + +void CYxcloudmqttsDataProcThread::Server_MqttProc_0BC8(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd) +{ + byte dataInfo[512]; + memset(dataInfo , 0 ,512); + int len = 0; + + for( int i = 0; i < cmd.VecCmd.size(); i++) + { + if( "SN_Number" == cmd.VecCmd.at(i).name) + { + std::string snNumNew = cmd.VecCmd.at(i).value; + memcpy(dataInfo , snNumNew.c_str() , snNumNew.size()); + len += snNumNew.size(); + + if( Server_Mqtt_SendFrame(CMD_CHANGE_SN_NUMBER , len , dataInfo , ptrRtu->m_Param.RtuDesc ) ) + { + m_changeSnNumCmd[ptrRtu->m_Param.RtuDesc] = std::make_pair(snNumNew , cmd); + }else + { + cmd.retStatus = CN_ControlFailed; + ptrRtu->WriteTxDefCmdBuf(1, &cmd); + } + + break; + } + } + +} + +void CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC8(byte *RecvMsg) +{ + int readIndex = WN_FRAME_DATA; + + //解析应答状态 + uint16 ackState = 0; + Byte2n byte2n; + byte2n.uNum = 0; + + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + ackState = byte2n.uNum; + + auto it = m_changeSnNumCmd.find(m_ptrCFesRtu->m_Param.RtuDesc); + if( it != m_changeSnNumCmd.end()) + { + SFesTxDefCmd &tmp = it->second.second; + tmp.retStatus = CN_ControlFailed; + + if( 0x0001 == ackState && changeSnNumberByOldSN(it->second.first , m_ptrCFesRtu) ) + { + tmp.retStatus = CN_ControlSuccess; + // 设置成功 进行相应序列号的修改 + } + + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &tmp); + m_changeSnNumCmd.erase(it); + + } + +} + +void CYxcloudmqttsDataProcThread::Server_MqttRecv_0BC1(byte *RecvMsg) +{ + int readIndex = WN_FRAME_DATA - 2; + + //解析SubCMD + uint16 subCMD = 0, ackState = 0; + Byte2n byte2n; + byte2n.uNum = 0; + + byte2n.cByte[CN_BYTE_HI] = RecvMsg[readIndex++]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[readIndex++]; + subCMD = byte2n.uNum; + + switch (subCMD) + { + case 0x0000: + //解析ack + byte2n.cByte[CN_BYTE_HI] = RecvMsg[13]; + byte2n.cByte[CN_BYTE_LO] = RecvMsg[13]; + ackState = byte2n.uNum; + if( YXWN_NO_ERROR == ackState) + { + Server_MqttProc_updataCmd(); + } + break; + case 0xAAAA: //可以升级指令 + + break; + case 0xBBBB: + + break; + case 0xCCCC: + + break; + default: + break; + } +} + +void CYxcloudmqttsDataProcThread::Server_MqttProc_updataCmd() +{ + //在固定有功设置、保护参数设置、安规参数设置、降载逻辑设置、PI参数设置、MPPT参数设置,设置成功会触发DSP重启 + //10秒内收到可以升级指令(AA 55 0B C1 00 00 00 00 00 00 00 02 00 00 CRC)均认为设置成功,否则设置失败 + + //查找保存的命令 + auto outerIt = m_customCmdAck.find(m_ptrCFesRtu->m_Param.RtuDesc); + if (outerIt != m_customCmdAck.end()) + { + auto& innerMap = outerIt->second; + for (auto it = innerMap.begin(); it != innerMap.end(); ) + { + if( it->first == CMD_FIXED_ACTIVE_POWER_SETTING || it->first == CMD_PROTECTION_PARAMETER_SETTING || it->first == CMD_SAFETY_STANDARD_PARAMETER_SETTING || + it->first == CMD_ALL_DERATING_LOGIC_SETTING || it->first == CMD_PI_PARAMETER_SETTING || it->first == CMD_MPPT_PARAMETER_SETTING ) + { + SFesTxDefCmd tmp = it->second.defCmd; + time_t current_time = time(NULL); + double duration = difftime(current_time, it->second.timestamp); + if( duration <= 10) + { + tmp.retStatus = CN_ControlSuccess; + m_ptrCFesRtu->WriteTxDefCmdBuf(1, &tmp); + it = innerMap.erase(it); + break; + } + } + ++it; + } + } +} + +/** + * @brief CYxcloudmqttsDataProcThread::Server_MqttProc_0BB7 + * 用于处理0x0BB7命令 + * @param ptrRtu 传入的RTU + * @param cmd 相关命令 + */ +void CYxcloudmqttsDataProcThread::Server_MqttProc_0BB7(CFesRtuPtr ptrRtu ,SFesTxDefCmd &cmd) +{ + if( NULL == ptrRtu) + { + LOGERROR("ptrRtu is NULL"); + return; + } + + cmd.retStatus = CN_ControlFailed; + std::map::const_iterator it = m_AllFirmWareInfo.find(ptrRtu->m_Param.RtuDesc); + if( it != m_AllFirmWareInfo.end() ) + { + cmd.VecCmd.resize(5); + cmd.VecCmd[0].name = "DSPDevNum"; + cmd.VecCmd[0].value = it->second.DSPDevNum; + cmd.VecCmd[1].name = "DSPSoftVersion"; + cmd.VecCmd[1].value = it->second.DSPSoftVersion; + cmd.VecCmd[2].name = "DSPPVersion"; + cmd.VecCmd[2].value = it->second.DSPPVersion; + cmd.VecCmd[3].name = "DSPMCUPNum"; + cmd.VecCmd[3].value = it->second.DSPMCUPNum; + cmd.VecCmd[4].name = "MCUSoftVersion"; + cmd.VecCmd[4].value = it->second.MCUSoftVersion; + cmd.retStatus = CN_ControlSuccess; + } + ptrRtu->WriteTxDefCmdBuf(1, &cmd); + +} + +bool CYxcloudmqttsDataProcThread::changeSnNumberByOldSN(string newSn, CFesRtuPtr ptrRtu) +{ + bool res = true; + std::string oldSn = ptrRtu->m_Param.RtuDesc; + iot_dbms::CDbApi *m_pReadDb = new iot_dbms::CDbApi(DB_CONN_MODEL_WRITE); + if(m_pReadDb->open()) + { + QSqlQuery query; + QString sqlSequenceQuery = QString("UPDATE fes_rtu_para SET DESCRIPTION = '%1' WHERE DESCRIPTION = '%2';").arg(newSn.c_str()).arg(oldSn.c_str()); + if( m_pReadDb->execute(sqlSequenceQuery, query) == false) + { + res = false; + LOGINFO("modify fes_rtu_para DESCRIPTION error, dbInterface execute failed!"); + } + + sqlSequenceQuery = QString("UPDATE dev_group SET DESCRIPTION = '%1' WHERE DESCRIPTION = '%2';").arg(newSn.c_str()).arg(oldSn.c_str()); + if( m_pReadDb->execute(sqlSequenceQuery, query) == false) + { + res = false; + LOGINFO("modify dev_group DESCRIPTION error, dbInterface execute failed!"); + } + }else + { + LOGINFO("connot open sql , modify snNumber failed!"); + } + m_pReadDb->close(); + delete m_pReadDb; + m_pReadDb = NULL; + + if( !res ) return res; + + //订阅新主题 + MqttUnSubscribe(oldSn); + MqttSubscribe(newSn); + + //改对应关系 + //1.有一个映射表 2.关于命令存放的map 表是以键值对存储的 3.修改rtu的内存 + memcpy( ptrRtu->m_Param.RtuDesc , newSn.c_str() , newSn.size() ); + if( m_allRtu.find(oldSn) != m_allRtu.end()) + { + m_allRtu.erase(oldSn); + m_allRtu[newSn] = ptrRtu; + } + + auto outerIt = m_customCmdAck.find(oldSn); + if( outerIt != m_customCmdAck.end()) + { + m_customCmdAck[newSn] = outerIt->second; + m_customCmdAck.erase(outerIt); + } + + return res; + +} diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/YxcloudmqttsDataProcThread.h b/product/src/fes/protocol/yxcloud_mqtt_wn/YxcloudmqttsDataProcThread.h new file mode 100644 index 00000000..ec6524be --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/YxcloudmqttsDataProcThread.h @@ -0,0 +1,246 @@ +#pragma once +#include "FesDef.h" +#include "FesBase.h" +#include "ProtocolBase.h" +#include "mosquitto.h" +#include "mosquittopp.h" +#include "Md5/Md5.h" +#include "mqtts_wn_enum.h" +#include "boost/circular_buffer.hpp" +#include "boost/unordered_map.hpp" +#include "boost/format.hpp" +using namespace iot_public; + + +//本FES数据更新间隔 +const int CN_YxcloudmqttsStartUpateTime = 10000;//10s +const int CN_YxcloudmqttsNormalUpateTime = 60000;//60s + +class CMosquittoppFix : public mosqpp::mosquittopp +{ +public: + byte RecvMsg[512]; + bool sendFrameFlag = false; + std::string receivedTopic = ""; // 用于存储接收到的主题 + CMosquittoppFix(const char *id) : mosquittopp(id) {} + std::string voidPtrToHexString(void* data, size_t size) { + std::stringstream ss; + ss << std::hex << std::setfill('0'); + for (size_t i = 0; i < size; ++i) { + ss << std::setw(2) << static_cast(reinterpret_cast(data)[i]); + } + return ss.str(); + } + int8_t hexStringToUint8(const std::string& hexString) { + uint8_t result; + std::stringstream ss; + ss << std::hex << hexString; + ss >> result; + return result; + } + void on_message(const struct mosquitto_message *message) override + { + sendFrameFlag = true; + std::string StrMsg = voidPtrToHexString(message->payload,message->payloadlen); + if (message->topic) + { + receivedTopic = std::string(message->topic); + } + //hex_string_to_byte_array(charStr,RecvMsg); + + for (size_t i = 0, j = 0; i < StrMsg.size(); i += 2, j++) { + string temp = StrMsg.substr(i,2); + //strncpy(charStr, temp.c_str(), 2); + + int decimalValue; + std::stringstream ss; + ss << std::hex << temp; + ss >> decimalValue; + + uint8_t byteValue = static_cast(decimalValue); + RecvMsg[j] = byteValue; + } + LOGINFO("yxcloud_mqtt_wn receMsg:%s , receive topic: %s" , RecvMsg , receivedTopic.c_str()); + return; + + } + + // 连接成功的回调 + void on_connect(int rc) override { + if (rc == 0) { + LOGINFO("yxcloud_mqtt_wn Connected to the MQTT broker successfully"); + } else { + LOGINFO("yxcloud_mqtt_wn Failed to connect to the MQTT broker. Return code: %d" , rc); + } + } + + // 重载消息发布确认回调 + void on_publish(int mid) override { + LOGINFO("yxcloud_mqtt_wn Message published with mid"); + } + + // 订阅成功的回调 + void on_subscribe(int mid, int qos_count, const int *granted_qos) override { + LOGINFO("yxcloud_mqtt_wn Subscription successful! mid: %d" , mid); + } +}; + +class CYxcloudmqttsDataProcThread : public CTimerThreadBase,CProtocolBase +{ +public: + + CYxcloudmqttsDataProcThread(CFesBase *ptrCFesBase,CFesChanPtr ptrCFesChan,const vector vecAppParam); + virtual ~CYxcloudmqttsDataProcThread(); + + /* + @brief 执行execute函数前的处理 + */ + virtual int beforeExecute(); + /* + @brief 业务处理函数,必须继承实现自己的业务逻辑 + */ + virtual void execute(); + + virtual void beforeQuit(); + + CFesBase* m_ptrCFesBase; + CFesChanPtr m_ptrCFesChan; //主通道数据区。如果存在备通道,每次发送接收数据时需要得到当前使用的通道数据 + CFesRtuPtr m_ptrCFesRtu; //当前使用RTU数据区,Yxcloudmqtts tcp 每个通道对应一个RTU数据,所以不需要轮询处理。 + CFesChanPtr m_ptrCurrentChan; //当前使用通道数据区。如果存在备通,每次发送接收数据时需要得到当前使用的通道数据 + SYxcloudmqttsAppData m_AppData; //内部应用数据结构 + SFesFwSoeEvent *m_pSoeData; + + MqttPublishTime mqttTime; //MQTT上抛时间管理 + MqttRecvMsg mqttMsg; + CMosquittoppFix *mqttClient; +private: + int m_timerCount; + int m_timerCountReset; + + uint32 PCSSN; + uint32 GDSN; + int countryInfo; + int conFlag = 0; + int subFlag = 0; + std::map m_allRtu; + std::map m_AllFirmWareInfo; + std::mapm_safetyParas; //安培参数 <-key: SN序列号 value: 安规参数-> + std::map mapLastRecvTime; //key -订阅主题 value -接受消息时的最新时间 + +// boost::unordered_map m_safetyParasCmd; //用于处理安规查询命令的回复<-key: SN序列号 value: 保存待处理的安规参数-> +// boost::unordered_map m_safetyParasAckCmd; //用于处理安规设置命令的回复<-key: SN序列号 value: 保存待处理命令-> +// boost::unordered_map m_proTectParasAckCmd; //用于处理保护参数设置命令的回复<-key: SN序列号 value: 保存待处理命令-> +// boost::unordered_map m_proTectParasCmd; //用于处理保护参数查询命令的回复<-key: SN序列号 value: 保存待处理命令-> +// boost::unordered_map m_unloadParasAckCmd; //用于处理降载逻辑设置命令的回复<-key: SN序列号 value: 保存待处理命令-> +// boost::unordered_map m_unloadParasCmd; //用于处理降载逻辑查询命令的回复<-key: SN序列号 value: 保存待处理命令-> + +// boost::unordered_map m_piParasAckCmd; //用于处理PI参数设置命令的回复<-key: SN序列号 value: 保存待处理命令-> +// boost::unordered_map m_piParasCmd; //用于处理PI参数查询命令的回复<-key: SN序列号 value: 保存待处理命令-> + +// boost::unordered_map m_mpptParasAckCmd; //用于处理MPPT参数设置命令的回复<-key: SN序列号 value: 保存待处理命令-> +// boost::unordered_map m_mpptParasCmd; //用于处理MPPT参数查询命令的回复<-key: SN序列号 value: 保存待处理命令-> + + boost::unordered_map> m_changeSnNumCmd; //修改序列号 key - 新的序列号 value{旧的序列号,相关命令} + + boost::unordered_map> m_customCmdAck; // 记录需回复的命令 + + int InitConfigParam(); + + void TimerProcess(); + void YxcloudmqttsProcess(); + + void SendSoeDataFrame(); + int64 publishTime; + + void MqttConnect(); + bool MqttPublish(std::string mqttTopic, std::string mqttPayload); + void GetTopicCfg(); + void ReadTopic(); + bool MqttSubscribe(); + bool MqttSubscribe(std::string subTopic); + bool MqttUnSubscribe(std::string unSubTopic); + void getAllRTUByCurrChan(); //用于获取所有的RTU中的序列号(也就是描述,这里只针对与一个RTU对应一个设备的情况) + bool switchRTUByTopic(std::string topic); //根据获取的订阅主题up/SN序号 中的sn切Rtu + + void OnProcessReceive(byte *RecvMsg , std::string strSN); + void ProcessDataFrame(byte *RecvMsg, std::string strSN); + void ProcessFirmwareFrame(byte *RecvMsg, std::string strSN); + void AoCmdProcess(CFesRtuPtr ptrRtu); + void DoCmdProcess(CFesRtuPtr ptrRtu); + void DefCmdProcess(CFesRtuPtr ptrRtu); + //获取MD5 + std::string GetFileMd5(const std::string &file); + std::string GetStringMd5(const std::string &src_str); + + void OnSend(int ctlFuncode = 0, int ctlValue = 0); + void SendTopicData(const int topicNo); + + //主线程 + void MainThread(); + void ClearTopicStr(); + + //获取告警配置 + void GetAlarmCfg(); + int GetAlarmNo(const int RemoteNo); + + //获取保护参数配置 + void GetProtectParaCfg(); + void GetParaCfg(const char* filename); + + std::string GbkToUtf8(std::string src_str); + std::string Utf8ToGbk(std::string src_str); + + void checkAllPointStatus(); //十分钟未更新后刷新所有测点状态 + void updatePointStatus(/*CFesRtuPtr ptrRtu*/); //十分钟未更新后刷新所有测点状态 + + //相关命令处理 + bool Server_Mqtt_SendFrame(int ctlFuncode , int Lenth , byte *sendInfo , std::string snNumber = ""); //mqtt报文发送框架处理函数 + + void Server_MqttProc_0BBF(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd); //安规参数查询命令处理 + void Server_MqttRecv_0BBF(byte *RecvMsg); //安规参数查询命令PCS接收处理 + + void Server_MqttProc_0BBE(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd); //安规参数设置命令发送 + bool Server_MqttSend_0BBE(InvFaultConfigParas ¶s , std::string sendTopic = ""); //安规参数设置命令发送 sendTopic其实为SN序列号 + void Server_MqttRecv_0BBE(byte *RecvMsg); //安规参数设置命令回复接受处理 + + void Server_MqttProc_0BBD(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd); // 保护参数设置命令发送 + bool Server_MqttSend_0BBD(SFesTxDefCmd &cmd ,std::string sendTopic = ""); // 保护参数设置命令发送 sendTopic其实为SN序列号 + void Server_MqttRecv_0BBD(byte *RecvMsg); //保护参数设置命令回复接受处理 + + void Server_MqttProc_0BC0(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd); //保护参数查询命令发送 + void Server_MqttRecv_0BC0(byte *RecvMsg); //保护参数查询命令回复接受处理 + + void Server_MqttProc_0BC2(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd); // 全部降载逻辑设置命令发送 + bool Server_MqttSend_0BC2(SFesTxDefCmd &cmd ,std::string sendTopic = ""); // 全部降载逻辑设置命令发送 sendTopic其实为SN序列号 + void Server_MqttRecv_0BC2(byte *RecvMsg); //全部降载逻辑设置命令回复接受处理 + + void Server_MqttProc_0BC3(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd); //全部降载逻辑读取发送 + void Server_MqttRecv_0BC3(byte *RecvMsg); //全部降载逻辑读取命令回复接受处理 + + void Server_MqttProc_0BC4(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd); // PI 参数设置命令发送 + bool Server_MqttSend_0BC4(SFesTxDefCmd &cmd ,std::string sendTopic = ""); // PI 参数设置命令发送 sendTopic其实为SN序列号 + void Server_MqttRecv_0BC4(byte *RecvMsg); //PI 参数设置命令回复接受处理 + + void Server_MqttProc_0BC5(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd); //PI 参数读取发送 + void Server_MqttRecv_0BC5(byte *RecvMsg); //PI参数读取命令回复接受处理 + + void Server_MqttProc_0BC6(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd); // MPPT 参数设置 + bool Server_MqttSend_0BC6(SFesTxDefCmd &cmd ,std::string sendTopic = ""); + void Server_MqttRecv_0BC6(byte *RecvMsg); + + void Server_MqttProc_0BC7(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd); //MPPT 参数读取 + void Server_MqttRecv_0BC7(byte *RecvMsg); + + void Server_MqttProc_0BC8(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd); //更改SN序列号 + void Server_MqttRecv_0BC8(byte *RecvMsg); + + void Server_MqttRecv_0BC1(byte *RecvMsg); //更新PCS固件 + void Server_MqttProc_updataCmd(); //处理可以升级指令 + + void Server_MqttProc_0BB7(CFesRtuPtr ptrRtu, SFesTxDefCmd &cmd); //固件信息命令处理 + + bool changeSnNumberByOldSN(std::string newSn,CFesRtuPtr ptrRtu); //修改序列号 + +}; + +typedef boost::shared_ptr CYxcloudmqttsDataProcThreadPtr; diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/mosquitto.h b/product/src/fes/protocol/yxcloud_mqtt_wn/mosquitto.h new file mode 100644 index 00000000..83fb350f --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/mosquitto.h @@ -0,0 +1,3084 @@ +/* +Copyright (c) 2010-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_H +#define MOSQUITTO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(WIN32) && !defined(WITH_BROKER) && !defined(LIBMOSQUITTO_STATIC) +# ifdef libmosquitto_EXPORTS +# define libmosq_EXPORT __declspec(dllexport) +# else +# define libmosq_EXPORT __declspec(dllimport) +# endif +#else +# define libmosq_EXPORT +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# ifndef __cplusplus +# define bool char +# define true 1 +# define false 0 +# endif +#else +# ifndef __cplusplus +# include +# endif +#endif + +#include +#include + +#define LIBMOSQUITTO_MAJOR 1 +#define LIBMOSQUITTO_MINOR 6 +#define LIBMOSQUITTO_REVISION 10 +/* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ +#define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION) + +/* Log types */ +#define MOSQ_LOG_NONE 0 +#define MOSQ_LOG_INFO (1<<0) +#define MOSQ_LOG_NOTICE (1<<1) +#define MOSQ_LOG_WARNING (1<<2) +#define MOSQ_LOG_ERR (1<<3) +#define MOSQ_LOG_DEBUG (1<<4) +#define MOSQ_LOG_SUBSCRIBE (1<<5) +#define MOSQ_LOG_UNSUBSCRIBE (1<<6) +#define MOSQ_LOG_WEBSOCKETS (1<<7) +#define MOSQ_LOG_INTERNAL 0x80000000U +#define MOSQ_LOG_ALL 0xFFFFFFFFU + +/* Error values */ +enum mosq_err_t { + MOSQ_ERR_AUTH_CONTINUE = -4, + MOSQ_ERR_NO_SUBSCRIBERS = -3, + MOSQ_ERR_SUB_EXISTS = -2, + MOSQ_ERR_CONN_PENDING = -1, + MOSQ_ERR_SUCCESS = 0, + MOSQ_ERR_NOMEM = 1, + MOSQ_ERR_PROTOCOL = 2, + MOSQ_ERR_INVAL = 3, + MOSQ_ERR_NO_CONN = 4, + MOSQ_ERR_CONN_REFUSED = 5, + MOSQ_ERR_NOT_FOUND = 6, + MOSQ_ERR_CONN_LOST = 7, + MOSQ_ERR_TLS = 8, + MOSQ_ERR_PAYLOAD_SIZE = 9, + MOSQ_ERR_NOT_SUPPORTED = 10, + MOSQ_ERR_AUTH = 11, + MOSQ_ERR_ACL_DENIED = 12, + MOSQ_ERR_UNKNOWN = 13, + MOSQ_ERR_ERRNO = 14, + MOSQ_ERR_EAI = 15, + MOSQ_ERR_PROXY = 16, + MOSQ_ERR_PLUGIN_DEFER = 17, + MOSQ_ERR_MALFORMED_UTF8 = 18, + MOSQ_ERR_KEEPALIVE = 19, + MOSQ_ERR_LOOKUP = 20, + MOSQ_ERR_MALFORMED_PACKET = 21, + MOSQ_ERR_DUPLICATE_PROPERTY = 22, + MOSQ_ERR_TLS_HANDSHAKE = 23, + MOSQ_ERR_QOS_NOT_SUPPORTED = 24, + MOSQ_ERR_OVERSIZE_PACKET = 25, + MOSQ_ERR_OCSP = 26, +}; + +/* Option values */ +enum mosq_opt_t { + MOSQ_OPT_PROTOCOL_VERSION = 1, + MOSQ_OPT_SSL_CTX = 2, + MOSQ_OPT_SSL_CTX_WITH_DEFAULTS = 3, + MOSQ_OPT_RECEIVE_MAXIMUM = 4, + MOSQ_OPT_SEND_MAXIMUM = 5, + MOSQ_OPT_TLS_KEYFORM = 6, + MOSQ_OPT_TLS_ENGINE = 7, + MOSQ_OPT_TLS_ENGINE_KPASS_SHA1 = 8, + MOSQ_OPT_TLS_OCSP_REQUIRED = 9, + MOSQ_OPT_TLS_ALPN = 10, +}; + + +/* MQTT specification restricts client ids to a maximum of 23 characters */ +#define MOSQ_MQTT_ID_MAX_LENGTH 23 + +#define MQTT_PROTOCOL_V31 3 +#define MQTT_PROTOCOL_V311 4 +#define MQTT_PROTOCOL_V5 5 + +struct mosquitto_message{ + int mid; + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct mosquitto; +typedef struct mqtt5__property mosquitto_property; + +/* + * Topic: Threads + * libmosquitto provides thread safe operation, with the exception of + * which is not thread safe. + * + * If your application uses threads you must use to + * tell the library this is the case, otherwise it makes some optimisations + * for the single threaded case that may result in unexpected behaviour for + * the multi threaded case. + */ +/*************************************************** + * Important note + * + * The following functions that deal with network operations will return + * MOSQ_ERR_SUCCESS on success, but this does not mean that the operation has + * taken place. An attempt will be made to write the network data, but if the + * socket is not available for writing at that time then the packet will not be + * sent. To ensure the packet is sent, call mosquitto_loop() (which must also + * be called to process incoming network data). + * This is especially important when disconnecting a client that has a will. If + * the broker does not receive the DISCONNECT command, it will assume that the + * client has disconnected unexpectedly and send the will. + * + * mosquitto_connect() + * mosquitto_disconnect() + * mosquitto_subscribe() + * mosquitto_unsubscribe() + * mosquitto_publish() + ***************************************************/ + + +/* ====================================================================== + * + * Section: Library version, init, and cleanup + * + * ====================================================================== */ +/* + * Function: mosquitto_lib_version + * + * Can be used to obtain version information for the mosquitto library. + * This allows the application to compare the library version against the + * version it was compiled against by using the LIBMOSQUITTO_MAJOR, + * LIBMOSQUITTO_MINOR and LIBMOSQUITTO_REVISION defines. + * + * Parameters: + * major - an integer pointer. If not NULL, the major version of the + * library will be returned in this variable. + * minor - an integer pointer. If not NULL, the minor version of the + * library will be returned in this variable. + * revision - an integer pointer. If not NULL, the revision of the library will + * be returned in this variable. + * + * Returns: + * LIBMOSQUITTO_VERSION_NUMBER, which is a unique number based on the major, + * minor and revision values. + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_version(int *major, int *minor, int *revision); + +/* + * Function: mosquitto_lib_init + * + * Must be called before any other mosquitto functions. + * + * This function is *not* thread safe. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_UNKNOWN - on Windows, if sockets couldn't be initialized. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_init(void); + +/* + * Function: mosquitto_lib_cleanup + * + * Call to free resources associated with the library. + * + * Returns: + * MOSQ_ERR_SUCCESS - always + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_cleanup(void); + + +/* ====================================================================== + * + * Section: Client creation, destruction, and reinitialisation + * + * ====================================================================== */ +/* + * Function: mosquitto_new + * + * Create a new mosquitto client instance. + * + * Parameters: + * id - String to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Note that a client will never discard its own outgoing + * messages on disconnect. Calling or + * will cause the messages to be resent. + * Use to reset a client to its + * original state. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * Pointer to a struct mosquitto on success. + * NULL on failure. Interrogate errno to determine the cause for the failure: + * - ENOMEM on out of memory. + * - EINVAL on invalid input parameters. + * + * See Also: + * , , + */ +libmosq_EXPORT struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj); + +/* + * Function: mosquitto_destroy + * + * Use to free memory associated with a mosquitto client instance. + * + * Parameters: + * mosq - a struct mosquitto pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_destroy(struct mosquitto *mosq); + +/* + * Function: mosquitto_reinitialise + * + * This function allows an existing mosquitto client to be reused. Call on a + * mosquitto instance to close any open network connections, free memory + * and reinitialise the client with the new parameters. The end result is the + * same as the output of . + * + * Parameters: + * mosq - a valid mosquitto instance. + * id - string to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *obj); + + +/* ====================================================================== + * + * Section: Will + * + * ====================================================================== */ +/* + * Function: mosquitto_will_set + * + * Configure will information for a mosquitto instance. By default, clients do + * not have a will. This must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + */ +libmosq_EXPORT int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + +/* + * Function: mosquitto_will_set_v5 + * + * Configure will information for a mosquitto instance, with attached + * properties. By default, clients do not have a will. This must be called + * before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * properties - list of MQTT 5 properties. Can be NULL. On success only, the + * property list becomes the property of libmosquitto once this + * function is called and will be freed by the library. The + * property list must be freed by the application on error. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8. + * MOSQ_ERR_NOT_SUPPORTED - if properties is not NULL and the client is not + * using MQTT v5 + * MOSQ_ERR_PROTOCOL - if a property is invalid for use with wills. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + */ +libmosq_EXPORT int mosquitto_will_set_v5(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain, mosquitto_property *properties); + +/* + * Function: mosquitto_will_clear + * + * Remove a previously configured will. This must be called before calling + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_will_clear(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Username and password + * + * ====================================================================== */ +/* + * Function: mosquitto_username_pw_set + * + * Configure username and password for a mosquitto instance. By default, no + * username or password will be sent. For v3.1 and v3.1.1 clients, if username + * is NULL, the password argument is ignored. + * + * This is must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * username - the username to send as a string, or NULL to disable + * authentication. + * password - the password to send as a string. Set to NULL when username is + * valid in order to send just a username. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password); + + +/* ====================================================================== + * + * Section: Connecting, reconnecting, disconnecting + * + * ====================================================================== */ +/* + * Function: mosquitto_connect + * + * Connect to an MQTT broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter. Use this function + * if you need to restrict network communication over a particular interface. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_bind_v5 + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter and MQTT v5 + * properties. Use this function if you need to restrict network communication + * over a particular interface. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * properties - the MQTT 5 properties for the connect (not for the Will). + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with CONNECT. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_v5(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address, const mosquitto_property *properties); + +/* + * Function: mosquitto_connect_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * This extends the functionality of by adding the + * bind_address parameter. Use this function if you need to restrict network + * communication over a particular interface. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_async(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_srv + * + * Connect to an MQTT broker. + * + * If you set `host` to `example.com`, then this call will attempt to retrieve + * the DNS SRV record for `_secure-mqtt._tcp.example.com` or + * `_mqtt._tcp.example.com` to discover which actual host to connect to. + * + * DNS SRV support is not usually compiled in to libmosquitto, use of this call + * is not recommended. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname to search for an SRV record. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_srv(struct mosquitto *mosq, const char *host, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_reconnect + * + * Reconnect to a broker. + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * call. It must not be called before + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_reconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_reconnect_async + * + * Reconnect to a broker. Non blocking version of . + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * or calls. It must not be + * called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reconnect_async(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect + * + * Disconnect from the broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + */ +libmosq_EXPORT int mosquitto_disconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect_v5 + * + * Disconnect from the broker, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * reason_code - the disconnect reason code. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with DISCONNECT. + */ +libmosq_EXPORT int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Publishing, subscribing, unsubscribing + * + * ====================================================================== */ +/* + * Function: mosquitto_publish + * + * Publish a message on a given topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + + +/* + * Function: mosquitto_publish_v5 + * + * Publish a message on a given topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Requires the mosquitto instance to be connected with MQTT 5. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * topic - null terminated string of the topic to publish to. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with PUBLISH. + * MOSQ_ERR_QOS_NOT_SUPPORTED - if the QoS is greater than that supported by + * the broker. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_publish_v5( + struct mosquitto *mosq, + int *mid, + const char *topic, + int payloadlen, + const void *payload, + int qos, + bool retain, + const mosquitto_property *properties); + + +/* + * Function: mosquitto_subscribe + * + * Subscribe to a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos); + +/* + * Function: mosquitto_subscribe_v5 + * + * Subscribe to a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Requires the mosquitto instance to be connected with MQTT 5. + * + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * options - options to apply to this subscription, OR'd together. Set to 0 to + * use the default options, otherwise choose from the list: + * MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client + * publishes to a topic to which it is subscribed, the + * broker will not publish the message back to the + * client. + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages + * published for this subscription will keep the + * retain flag as was set by the publishing client. + * The default behaviour without this option set has + * the retain flag indicating whether a message is + * fresh/stale. + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set, + * pre-existing retained messages are sent as soon as + * the subscription is made, even if the subscription + * already exists. This is the default behaviour, so + * it is not necessary to set this option. + * MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing + * retained messages for this subscription will be + * sent when the subscription is made, but only if the + * subscription does not already exist. + * MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set, + * pre-existing retained messages will never be sent + * for this subscription. + * properties - a valid mosquitto_property list, or NULL. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with SUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_subscribe_multiple + * + * Subscribe to multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of subscriptions to be made + * sub - array of sub_count pointers, each pointing to a subscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * qos - the requested Quality of Service for each subscription. + * options - options to apply to this subscription, OR'd together. This + * argument is not used for MQTT v3 susbcriptions. Set to 0 to use + * the default options, otherwise choose from the list: + * MQTT_SUB_OPT_NO_LOCAL: with this option set, if this client + * publishes to a topic to which it is subscribed, the + * broker will not publish the message back to the + * client. + * MQTT_SUB_OPT_RETAIN_AS_PUBLISHED: with this option set, messages + * published for this subscription will keep the + * retain flag as was set by the publishing client. + * The default behaviour without this option set has + * the retain flag indicating whether a message is + * fresh/stale. + * MQTT_SUB_OPT_SEND_RETAIN_ALWAYS: with this option set, + * pre-existing retained messages are sent as soon as + * the subscription is made, even if the subscription + * already exists. This is the default behaviour, so + * it is not necessary to set this option. + * MQTT_SUB_OPT_SEND_RETAIN_NEW: with this option set, pre-existing + * retained messages for this subscription will be + * sent when the subscription is made, but only if the + * subscription does not already exist. + * MQTT_SUB_OPT_SEND_RETAIN_NEVER: with this option set, + * pre-existing retained messages will never be sent + * for this subscription. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos, int options, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe + * + * Unsubscribe from a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub); + +/* + * Function: mosquitto_unsubscribe_v5 + * + * Unsubscribe from a topic, with attached MQTT properties. + * + * Use e.g. and similar to create a list of + * properties, then attach them to this publish. Properties need freeing with + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid for use with UNSUBSCRIBE. + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, const mosquitto_property *properties); + +/* + * Function: mosquitto_unsubscribe_multiple + * + * Unsubscribe from multiple topics. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub_count - the count of unsubscriptions to be made + * sub - array of sub_count pointers, each pointing to an unsubscription string. + * The "char *const *const" datatype ensures that neither the array of + * pointers nor the strings that they point to are mutable. If you aren't + * familiar with this, just think of it as a safer "char **", + * equivalent to "const char *" for a simple string pointer. + * properties - a valid mosquitto_property list, or NULL. Only used with MQTT + * v5 clients. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_MALFORMED_UTF8 - if a topic is not valid UTF-8 + * MOSQ_ERR_OVERSIZE_PACKET - if the resulting packet would be larger than + * supported by the broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, const mosquitto_property *properties); + + +/* ====================================================================== + * + * Section: Struct mosquitto_message helper functions + * + * ====================================================================== */ +/* + * Function: mosquitto_message_copy + * + * Copy the contents of a mosquitto message to another message. + * Useful for preserving a message received in the on_message() callback. + * + * Parameters: + * dst - a pointer to a valid mosquitto_message struct to copy to. + * src - a pointer to a valid mosquitto_message struct to copy from. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src); + +/* + * Function: mosquitto_message_free + * + * Completely free a mosquitto_message struct. + * + * Parameters: + * message - pointer to a mosquitto_message pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_message_free(struct mosquitto_message **message); + +/* + * Function: mosquitto_message_free_contents + * + * Free a mosquitto_message struct contents, leaving the struct unaffected. + * + * Parameters: + * message - pointer to a mosquitto_message struct to free its contents. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_message_free_contents(struct mosquitto_message *message); + + +/* ====================================================================== + * + * Section: Network loop (managed by libmosquitto) + * + * The internal network loop must be called at a regular interval. The two + * recommended approaches are to use either or + * . is a blocking call and is + * suitable for the situation where you only want to handle incoming messages + * in callbacks. is a non-blocking call, it creates a + * separate thread to run the loop for you. Use this function when you have + * other tasks you need to run at the same time as the MQTT client, e.g. + * reading data from a sensor. + * + * ====================================================================== */ + +/* + * Function: mosquitto_loop_forever + * + * This function call loop() for you in an infinite blocking loop. It is useful + * for the case where you only want to run the MQTT client loop in your + * program. + * + * It handles reconnecting in case server connection is lost. If you call + * mosquitto_disconnect() in a callback it will return. + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets); + +/* + * Function: mosquitto_loop_start + * + * This is part of the threaded client interface. Call this once to start a new + * thread to process network traffic. This provides an alternative to + * repeatedly calling yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_start(struct mosquitto *mosq); + +/* + * Function: mosquitto_loop_stop + * + * This is part of the threaded client interface. Call this once to stop the + * network thread previously created with . This call + * will block until the network thread finishes. For the network thread to end, + * you must have previously called or have set the force + * parameter to true. + * + * Parameters: + * mosq - a valid mosquitto instance. + * force - set to true to force thread cancellation. If false, + * must have already been called. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_stop(struct mosquitto *mosq, bool force); + +/* + * Function: mosquitto_loop + * + * The main network loop for the client. This must be called frequently + * to keep communications between the client and broker working. This is + * carried out by and , which + * are the recommended ways of handling the network loop. You may also use this + * function if you wish. It must not be called inside a callback. + * + * If incoming data is present it will then be processed. Outgoing commands, + * from e.g. , are normally sent immediately that their + * function is called, but this is not always possible. will + * also attempt to send any remaining outgoing messages, which also includes + * commands that are part of the flow for messages with QoS>0. + * + * This calls select() to monitor the client network socket. If you want to + * integrate mosquitto client operation with your own select() call, use + * , , and + * . + * + * Threads: + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets); + +/* ====================================================================== + * + * Section: Network loop (for use in other event loops) + * + * ====================================================================== */ +/* + * Function: mosquitto_loop_read + * + * Carry out network read operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_read(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_write + * + * Carry out network write operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_write(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_misc + * + * Carry out miscellaneous operations required as part of the network loop. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * This function deals with handling PINGs and checking whether messages need + * to be retried, so should be called fairly frequently, around once per second + * is sufficient. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_misc(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: Network loop (helper functions) + * + * ====================================================================== */ +/* + * Function: mosquitto_socket + * + * Return the socket handle for a mosquitto instance. Useful if you want to + * include a mosquitto client in your own select() calls. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * The socket for the mosquitto client or -1 on failure. + */ +libmosq_EXPORT int mosquitto_socket(struct mosquitto *mosq); + +/* + * Function: mosquitto_want_write + * + * Returns true if there is data ready to be written on the socket. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * See Also: + * , , + */ +libmosq_EXPORT bool mosquitto_want_write(struct mosquitto *mosq); + +/* + * Function: mosquitto_threaded_set + * + * Used to tell the library that your application is using threads, but not + * using . The library operates slightly differently when + * not in threaded mode in order to simplify its operation. If you are managing + * your own threads and do not use this function you will experience crashes + * due to race conditions. + * + * When using , this is set automatically. + * + * Parameters: + * mosq - a valid mosquitto instance. + * threaded - true if your application is using threads, false otherwise. + */ +libmosq_EXPORT int mosquitto_threaded_set(struct mosquitto *mosq, bool threaded); + + +/* ====================================================================== + * + * Section: Client options + * + * ====================================================================== */ +/* + * Function: mosquitto_opts_set + * + * Used to set options for the client. + * + * This function is deprecated, the replacement and + * functions should be used instead. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_PROTOCOL_VERSION + * Value must be an int, set to either MQTT_PROTOCOL_V31 or + * MQTT_PROTOCOL_V311. Must be set before the client connects. + * Defaults to MQTT_PROTOCOL_V31. + * + * MOSQ_OPT_SSL_CTX + * Pass an openssl SSL_CTX to be used when creating TLS connections + * rather than libmosquitto creating its own. This must be called + * before connecting to have any effect. If you use this option, the + * onus is on you to ensure that you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS + * Value must be an int set to 1 or 0. If set to 1, then the user + * specified SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the + * default options applied to it. This means that you only need to + * change the values that are relevant to you. If you use this + * option then you must configure the TLS options as normal, i.e. + * you should use to configure the cafile/capath + * as a minimum. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_opts_set(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + +/* + * Function: mosquitto_int_option + * + * Used to set integer options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_PROTOCOL_VERSION - + * Value must be set to either MQTT_PROTOCOL_V31, + * MQTT_PROTOCOL_V311, or MQTT_PROTOCOL_V5. Must be set before the + * client connects. Defaults to MQTT_PROTOCOL_V311. + * + * MOSQ_OPT_RECEIVE_MAXIMUM - + * Value can be set between 1 and 65535 inclusive, and represents + * the maximum number of incoming QoS 1 and QoS 2 messages that this + * client wants to process at once. Defaults to 20. This option is + * not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the MQTT_PROP_RECEIVE_MAXIMUM property is in the + * proplist passed to mosquitto_connect_v5(), then that property + * will override this option. Using this option is the recommended + * method however. + * + * MOSQ_OPT_SEND_MAXIMUM - + * Value can be set between 1 and 65535 inclusive, and represents + * the maximum number of outgoing QoS 1 and QoS 2 messages that this + * client will attempt to have "in flight" at once. Defaults to 20. + * This option is not valid for MQTT v3.1 or v3.1.1 clients. + * Note that if the broker being connected to sends a + * MQTT_PROP_RECEIVE_MAXIMUM property that has a lower value than + * this option, then the broker provided value will be used. + * + * MOSQ_OPT_SSL_CTX_WITH_DEFAULTS - + * If value is set to a non zero value, then the user specified + * SSL_CTX passed in using MOSQ_OPT_SSL_CTX will have the default + * options applied to it. This means that you only need to change + * the values that are relevant to you. If you use this option then + * you must configure the TLS options as normal, i.e. you should + * use to configure the cafile/capath as a + * minimum. + * This option is only available for openssl 1.1.0 and higher. + * + * MOSQ_OPT_TLS_OCSP_REQUIRED - + * Set whether OCSP checking on TLS connections is required. Set to + * 1 to enable checking, or 0 (the default) for no checking. + */ +libmosq_EXPORT int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t option, int value); + + +/* + * Function: mosquitto_void_option + * + * Used to set void* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_SSL_CTX - + * Pass an openssl SSL_CTX to be used when creating TLS connections + * rather than libmosquitto creating its own. This must be called + * before connecting to have any effect. If you use this option, the + * onus is on you to ensure that you are using secure settings. + * Setting to NULL means that libmosquitto will use its own SSL_CTX + * if TLS is to be used. + * This option is only available for openssl 1.1.0 and higher. + */ +libmosq_EXPORT int mosquitto_void_option(struct mosquitto *mosq, enum mosq_opt_t option, void *value); + + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + +/* + * Function: mosquitto_max_inflight_messages_set + * + * This function is deprected. Use the function with the + * MOSQ_OPT_SEND_MAXIMUM option instead. + * + * Set the number of QoS 1 and 2 messages that can be "in flight" at one time. + * An in flight message is part way through its delivery flow. Attempts to send + * further messages with will result in the messages being + * queued until the number of in flight messages reduces. + * + * A higher number here results in greater message throughput, but if set + * higher than the maximum in flight messages on the broker may lead to + * delays in the messages being acknowledged. + * + * Set to 0 for no maximum. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_inflight_messages - the maximum number of inflight messages. Defaults + * to 20. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages); + +/* + * Function: mosquitto_message_retry_set + * + * This function now has no effect. + */ +libmosq_EXPORT void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry); + +/* + * Function: mosquitto_user_data_set + * + * When is called, the pointer given as the "obj" parameter + * will be passed to the callbacks as user data. The + * function allows this obj parameter to be updated at any time. This function + * will not modify the memory pointed to by the current user data pointer. If + * it is dynamically allocated memory you must free it yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * obj - A user pointer that will be passed as an argument to any callbacks + * that are specified. + */ +libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj); + +/* Function: mosquitto_userdata + * + * Retrieve the "userdata" variable for a mosquitto client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * A pointer to the userdata member variable. + */ +libmosq_EXPORT void *mosquitto_userdata(struct mosquitto *mosq); + + +/* ====================================================================== + * + * Section: TLS support + * + * ====================================================================== */ +/* + * Function: mosquitto_tls_set + * + * Configure the client for certificate based SSL/TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Define the Certificate Authority certificates to be trusted (ie. the server + * certificate must be signed with one of these certificates) using cafile. + * + * If the server you are connecting to requires clients to provide a + * certificate, define certfile and keyfile with your client certificate and + * private key. If your private key is encrypted, provide a password callback + * function or you will have to enter the password at the command line. + * + * Parameters: + * mosq - a valid mosquitto instance. + * cafile - path to a file containing the PEM encoded trusted CA + * certificate files. Either cafile or capath must not be NULL. + * capath - path to a directory containing the PEM encoded trusted CA + * certificate files. See mosquitto.conf for more details on + * configuring this directory. Either cafile or capath must not + * be NULL. + * certfile - path to a file containing the PEM encoded certificate file + * for this client. If NULL, keyfile must also be NULL and no + * client certificate will be used. + * keyfile - path to a file containing the PEM encoded private key for + * this client. If NULL, certfile must also be NULL and no + * client certificate will be used. + * pw_callback - if keyfile is encrypted, set pw_callback to allow your client + * to pass the correct password for decryption. If set to NULL, + * the password must be entered on the command line. + * Your callback must write the password into "buf", which is + * "size" bytes long. The return value must be the length of the + * password. "userdata" will be set to the calling mosquitto + * instance. The mosquitto userdata member variable can be + * retrieved using . + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , , + * , + */ +libmosq_EXPORT int mosquitto_tls_set(struct mosquitto *mosq, + const char *cafile, const char *capath, + const char *certfile, const char *keyfile, + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)); + +/* + * Function: mosquitto_tls_insecure_set + * + * Configure verification of the server hostname in the server certificate. If + * value is set to true, it is impossible to guarantee that the host you are + * connecting to is not impersonating your server. This can be useful in + * initial server testing, but makes it possible for a malicious third party to + * impersonate your server through DNS spoofing, for example. + * Do not use this function in a real system. Setting value to true makes the + * connection encryption pointless. + * Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * value - if set to false, the default, certificate hostname checking is + * performed. If set to true, no hostname checking is performed and + * the connection is insecure. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_insecure_set(struct mosquitto *mosq, bool value); + +/* + * Function: mosquitto_tls_opts_set + * + * Set advanced SSL/TLS options. Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * cert_reqs - an integer defining the verification requirements the client + * will impose on the server. This can be one of: + * * SSL_VERIFY_NONE (0): the server will not be verified in any way. + * * SSL_VERIFY_PEER (1): the server certificate will be verified + * and the connection aborted if the verification fails. + * The default and recommended value is SSL_VERIFY_PEER. Using + * SSL_VERIFY_NONE provides no security. + * tls_version - the version of the SSL/TLS protocol to use as a string. If NULL, + * the default value is used. The default value and the + * available values depend on the version of openssl that the + * library was compiled against. For openssl >= 1.0.1, the + * available options are tlsv1.2, tlsv1.1 and tlsv1, with tlv1.2 + * as the default. For openssl < 1.0.1, only tlsv1 is available. + * ciphers - a string describing the ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tls_version, const char *ciphers); + +/* + * Function: mosquitto_tls_psk_set + * + * Configure the client for pre-shared-key based TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Parameters: + * mosq - a valid mosquitto instance. + * psk - the pre-shared-key in hex format with no leading "0x". + * identity - the identity of this client. May be used as the username + * depending on the server settings. + * ciphers - a string describing the PSK ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers); + + +/* ====================================================================== + * + * Section: Callbacks + * + * ====================================================================== */ +/* + * Function: mosquitto_connect_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_connect_with_flags_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * flags - the connect flags. + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_with_flags_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int)); + +/* + * Function: mosquitto_connect_v5_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + * flags - the connect flags. + * props - list of MQTT 5 properties, or NULL + * + */ +libmosq_EXPORT void mosquitto_connect_v5_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int, int, const mosquitto_property *props)); + +/* + * Function: mosquitto_disconnect_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + */ +libmosq_EXPORT void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_disconnect_v5_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_disconnect_v5_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int, const mosquitto_property *)); + +/* + * Function: mosquitto_publish_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker successfully. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + */ +libmosq_EXPORT void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_publish_v5_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker. This callback will be + * called both if the message is sent successfully, or if the broker responded + * with an error, which will be reflected in the reason_code parameter. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + * reason_code - the MQTT 5 reason code + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_publish_v5_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int, int, const mosquitto_property *)); + +/* + * Function: mosquitto_message_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *)); + +/* + * Function: mosquitto_message_v5_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * props - list of MQTT 5 properties, or NULL + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_v5_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *, const mosquitto_property *)); + +/* + * Function: mosquitto_subscribe_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + */ +libmosq_EXPORT void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *)); + +/* + * Function: mosquitto_subscribe_v5_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_subscribe_v5_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *)); + +/* + * Function: mosquitto_unsubscribe_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + */ +libmosq_EXPORT void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_unsubscribe_v5_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + * props - list of MQTT 5 properties, or NULL + */ +libmosq_EXPORT void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, const mosquitto_property *)); + +/* + * Function: mosquitto_log_callback_set + * + * Set the logging callback. This should be used if you want event logging + * information from the client library. + * + * mosq - a valid mosquitto instance. + * on_log - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int level, const char *str) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * level - the log message level from the values: + * MOSQ_LOG_INFO + * MOSQ_LOG_NOTICE + * MOSQ_LOG_WARNING + * MOSQ_LOG_ERR + * MOSQ_LOG_DEBUG + * str - the message string. + */ +libmosq_EXPORT void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *)); + +/* + * Function: mosquitto_string_option + * + * Used to set const char* options for the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * option - the option to set. + * value - the option specific value. + * + * Options: + * MOSQ_OPT_TLS_ENGINE + * Configure the client for TLS Engine support. Pass a TLS Engine ID + * to be used when creating TLS connections. + * Must be set before . + * MOSQ_OPT_TLS_KEYFORM + * Configure the client to treat the keyfile differently depending + * on its type. Must be set before . + * Set as either "pem" or "engine", to determine from where the + * private key for a TLS connection will be obtained. Defaults to + * "pem", a normal private key file. + * MOSQ_OPT_TLS_KPASS_SHA1 + * Where the TLS Engine requires the use of a password to be + * accessed, this option allows a hex encoded SHA1 hash of the + * private key password to be passed to the engine directly. + * Must be set before . + * MOSQ_OPT_TLS_ALPN + * If the broker being connected to has multiple services available + * on a single TLS port, such as both MQTT and WebSockets, use this + * option to configure the ALPN option for the connection. + */ +libmosq_EXPORT int mosquitto_string_option(struct mosquitto *mosq, enum mosq_opt_t option, const char *value); + + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + + +/* ============================================================================= + * + * Section: SOCKS5 proxy functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_socks5_set + * + * Configure the client to use a SOCKS5 proxy when connecting. Must be called + * before connecting. "None" and "username/password" authentication is + * supported. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the SOCKS5 proxy host to connect to. + * port - the SOCKS5 proxy port to use. + * username - if not NULL, use this username when authenticating with the proxy. + * password - if not NULL and username is not NULL, use this password when + * authenticating with the proxy. + */ +libmosq_EXPORT int mosquitto_socks5_set(struct mosquitto *mosq, const char *host, int port, const char *username, const char *password); + + +/* ============================================================================= + * + * Section: Utility functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_strerror + * + * Call to obtain a const string description of a mosquitto error number. + * + * Parameters: + * mosq_errno - a mosquitto error number. + * + * Returns: + * A constant string describing the error. + */ +libmosq_EXPORT const char *mosquitto_strerror(int mosq_errno); + +/* + * Function: mosquitto_connack_string + * + * Call to obtain a const string description of an MQTT connection result. + * + * Parameters: + * connack_code - an MQTT connection result. + * + * Returns: + * A constant string describing the result. + */ +libmosq_EXPORT const char *mosquitto_connack_string(int connack_code); + +/* + * Function: mosquitto_reason_string + * + * Call to obtain a const string description of an MQTT reason code. + * + * Parameters: + * reason_code - an MQTT reason code. + * + * Returns: + * A constant string describing the reason. + */ +libmosq_EXPORT const char *mosquitto_reason_string(int reason_code); + +/* Function: mosquitto_string_to_command + * + * Take a string input representing an MQTT command and convert it to the + * libmosquitto integer representation. + * + * Parameters: + * str - the string to parse. + * cmd - pointer to an int, for the result. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - on an invalid input. + * + * Example: + * mosquitto_string_to_command("CONNECT", &cmd); + * // cmd == CMD_CONNECT + */ +libmosq_EXPORT int mosquitto_string_to_command(const char *str, int *cmd); + +/* + * Function: mosquitto_sub_topic_tokenise + * + * Tokenise a topic or subscription string into an array of strings + * representing the topic hierarchy. + * + * For example: + * + * subtopic: "a/deep/topic/hierarchy" + * + * Would result in: + * + * topics[0] = "a" + * topics[1] = "deep" + * topics[2] = "topic" + * topics[3] = "hierarchy" + * + * and: + * + * subtopic: "/a/deep/topic/hierarchy/" + * + * Would result in: + * + * topics[0] = NULL + * topics[1] = "a" + * topics[2] = "deep" + * topics[3] = "topic" + * topics[4] = "hierarchy" + * + * Parameters: + * subtopic - the subscription/topic to tokenise + * topics - a pointer to store the array of strings + * count - an int pointer to store the number of items in the topics array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_MALFORMED_UTF8 - if the topic is not valid UTF-8 + * + * Example: + * + * > char **topics; + * > int topic_count; + * > int i; + * > + * > mosquitto_sub_topic_tokenise("$SYS/broker/uptime", &topics, &topic_count); + * > + * > for(i=0; i printf("%d: %s\n", i, topics[i]); + * > } + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *count); + +/* + * Function: mosquitto_sub_topic_tokens_free + * + * Free memory that was allocated in . + * + * Parameters: + * topics - pointer to string array. + * count - count of items in string array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokens_free(char ***topics, int count); + +/* + * Function: mosquitto_topic_matches_sub + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * topic - topic to check. + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result); + + +/* + * Function: mosquitto_topic_matches_sub2 + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * sublen - length in bytes of sub string + * topic - topic to check. + * topiclen - length in bytes of topic string + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub2(const char *sub, size_t sublen, const char *topic, size_t topiclen, bool *result); + +/* + * Function: mosquitto_pub_topic_check + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check(const char *topic); + +/* + * Function: mosquitto_pub_topic_check2 + * + * Check whether a topic to be used for publishing is valid. + * + * This searches for + or # in a topic and checks its length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. It + * may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - length of the topic in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a #, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if sub or topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_pub_topic_check2(const char *topic, size_t topiclen); + +/* + * Function: mosquitto_sub_topic_check + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check(const char *topic); + +/* + * Function: mosquitto_sub_topic_check2 + * + * Check whether a topic to be used for subscribing is valid. + * + * This searches for + or # in a topic and checks that they aren't in invalid + * positions, such as with foo/#/bar, foo/+bar or foo/bar#, and checks its + * length. + * + * This check is already carried out in and + * , there is no need to call it directly before them. + * It may be useful if you wish to check the validity of a topic in advance of + * making a connection for example. + * + * Parameters: + * topic - the topic to check + * topiclen - the length in bytes of the topic + * + * Returns: + * MOSQ_ERR_SUCCESS - for a valid topic + * MOSQ_ERR_INVAL - if the topic contains a + or a # that is in an + * invalid position, or if it is too long. + * MOSQ_ERR_MALFORMED_UTF8 - if topic is not valid UTF-8 + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_check2(const char *topic, size_t topiclen); + + +/* + * Function: mosquitto_validate_utf8 + * + * Helper function to validate whether a UTF-8 string is valid, according to + * the UTF-8 spec and the MQTT additions. + * + * Parameters: + * str - a string to check + * len - the length of the string in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if str is NULL or len<0 or len>65536 + * MOSQ_ERR_MALFORMED_UTF8 - if str is not valid UTF-8 + */ +libmosq_EXPORT int mosquitto_validate_utf8(const char *str, int len); + + +/* ============================================================================= + * + * Section: One line client helper functions + * + * ============================================================================= + */ + +struct libmosquitto_will { + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct libmosquitto_auth { + char *username; + char *password; +}; + +struct libmosquitto_tls { + char *cafile; + char *capath; + char *certfile; + char *keyfile; + char *ciphers; + char *tls_version; + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata); + int cert_reqs; +}; + +/* + * Function: mosquitto_subscribe_simple + * + * Helper function to make subscribing to a topic and retrieving some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, waits for msg_count + * messages to be received, then returns after disconnecting cleanly. + * + * Parameters: + * messages - pointer to a "struct mosquitto_message *". The received + * messages will be returned here. On error, this will be set to + * NULL. + * msg_count - the number of messages to retrieve. + * want_retained - if set to true, stale retained messages will be treated as + * normal messages with regards to msg_count. If set to + * false, they will be ignored. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * >0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool want_retained, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* + * Function: mosquitto_subscribe_callback + * + * Helper function to make subscribing to a topic and processing some messages + * very straightforward. + * + * This connects to a broker, subscribes to a topic, then passes received + * messages to a user provided callback. If the callback returns a 1, it then + * disconnects cleanly and returns. + * + * Parameters: + * callback - a callback function in the following form: + * int callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * Note that this is the same as the normal on_message callback, + * except that it returns an int. + * userdata - user provided pointer that will be passed to the callback. + * topic - the subscription topic to use (wildcards are allowed). + * qos - the qos to use for the subscription. + * host - the broker to connect to. + * port - the network port the broker is listening on. + * client_id - the client id to use, or NULL if a random client id should be + * generated. + * keepalive - the MQTT keepalive value. + * clean_session - the MQTT clean session flag. + * username - the username string, or NULL for no username authentication. + * password - the password string, or NULL for an empty password. + * will - a libmosquitto_will struct containing will information, or NULL for + * no will. + * tls - a libmosquitto_tls struct containing TLS related parameters, or NULL + * for no use of TLS. + * + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * >0 - on error. + */ +libmosq_EXPORT int mosquitto_subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos, + const char *host, + int port, + const char *client_id, + int keepalive, + bool clean_session, + const char *username, + const char *password, + const struct libmosquitto_will *will, + const struct libmosquitto_tls *tls); + + +/* ============================================================================= + * + * Section: Properties + * + * ============================================================================= + */ + + +/* + * Function: mosquitto_property_add_byte + * + * Add a new byte property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_byte(&proplist, MQTT_PROP_PAYLOAD_FORMAT_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value); + +/* + * Function: mosquitto_property_add_int16 + * + * Add a new int16 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_RECEIVE_MAXIMUM) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_int16(&proplist, MQTT_PROP_RECEIVE_MAXIMUM, 1000); + */ +libmosq_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value); + +/* + * Function: mosquitto_property_add_int32 + * + * Add a new int32 property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_MESSAGE_EXPIRY_INTERVAL) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_int32(&proplist, MQTT_PROP_MESSAGE_EXPIRY_INTERVAL, 86400); + */ +libmosq_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_varint + * + * Add a new varint property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_SUBSCRIPTION_IDENTIFIER) + * value - integer value for the new property + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_varint(&proplist, MQTT_PROP_SUBSCRIPTION_IDENTIFIER, 1); + */ +libmosq_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value); + +/* + * Function: mosquitto_property_add_binary + * + * Add a new binary property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to the property data + * len - length of property data in bytes + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_binary(&proplist, MQTT_PROP_AUTHENTICATION_DATA, auth_data, auth_data_len); + */ +libmosq_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len); + +/* + * Function: mosquitto_property_add_string + * + * Add a new string property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_CONTENT_TYPE) + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - value is not valid UTF-8. + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_string(&proplist, MQTT_PROP_CONTENT_TYPE, "application/json"); + */ +libmosq_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value); + +/* + * Function: mosquitto_property_add_string_pair + * + * Add a new string pair property to a property list. + * + * If *proplist == NULL, a new list will be created, otherwise the new property + * will be appended to the list. + * + * Parameters: + * proplist - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_USER_PROPERTY) + * name - string name for the new property, must be UTF-8 and zero terminated + * value - string value for the new property, must be UTF-8 and zero terminated + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if identifier is invalid, if name or value is NULL, or if proplist is NULL + * MOSQ_ERR_NOMEM - on out of memory + * MOSQ_ERR_MALFORMED_UTF8 - if name or value are not valid UTF-8. + * + * Example: + * mosquitto_property *proplist = NULL; + * mosquitto_property_add_string_pair(&proplist, MQTT_PROP_USER_PROPERTY, "client", "mosquitto_pub"); + */ +libmosq_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value); + +/* + * Function: mosquitto_property_read_byte + * + * Attempt to read a byte property matching an identifier, from a property list + * or single property. This function can search for multiple entries of the + * same identifier by using the returned value and skip_first. Note however + * that it is forbidden for most properties to be duplicated. + * + * If the property is not found, *value will not be modified, so it is safe to + * pass a variable with a default value to be potentially overwritten: + * + * uint16_t keepalive = 60; // default value + * // Get value from property list, or keep default if not found. + * mosquitto_property_read_int16(proplist, MQTT_PROP_SERVER_KEEP_ALIVE, &keepalive, false); + * + * Parameters: + * proplist - mosquitto_property pointer, the list of properties or single property + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * // proplist is obtained from a callback + * mosquitto_property *prop; + * prop = mosquitto_property_read_byte(proplist, identifier, &value, false); + * while(prop){ + * printf("value: %s\n", value); + * prop = mosquitto_property_read_byte(prop, identifier, &value); + * } + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_byte( + const mosquitto_property *proplist, + int identifier, + uint8_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int16 + * + * Read an int16 property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int16( + const mosquitto_property *proplist, + int identifier, + uint16_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_int32 + * + * Read an int32 property value from a property. + * + * Parameters: + * property - pointer to mosquitto_property pointer, the list of properties + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int32( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_varint + * + * Read a varint property value from a property. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_varint( + const mosquitto_property *proplist, + int identifier, + uint32_t *value, + bool skip_first); + +/* + * Function: mosquitto_property_read_binary + * + * Read a binary property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to store the value, or NULL if the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_binary( + const mosquitto_property *proplist, + int identifier, + void **value, + uint16_t *len, + bool skip_first); + +/* + * Function: mosquitto_property_read_string + * + * Read a string property value from a property. + * + * On success, value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string( + const mosquitto_property *proplist, + int identifier, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_read_string_pair + * + * Read a string pair property value pair from a property. + * + * On success, name and value must be free()'d by the application. + * + * Parameters: + * property - property to read + * identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR) + * name - pointer to char* for the name property data to be stored in, or NULL + * if the name is not required. + * value - pointer to char*, for the property data to be stored in, or NULL if + * the value is not required. + * skip_first - boolean that indicates whether the first item in the list + * should be ignored or not. Should usually be set to false. + * + * Returns: + * A valid property pointer if the property is found + * NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred. + * + * Example: + * See + */ +libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string_pair( + const mosquitto_property *proplist, + int identifier, + char **name, + char **value, + bool skip_first); + +/* + * Function: mosquitto_property_free_all + * + * Free all properties from a list of properties. Frees the list and sets *properties to NULL. + * + * Parameters: + * properties - list of properties to free + * + * Example: + * mosquitto_properties *properties = NULL; + * // Add properties + * mosquitto_property_free_all(&properties); + */ +libmosq_EXPORT void mosquitto_property_free_all(mosquitto_property **properties); + +/* + * Function: mosquitto_property_copy_all + * + * Parameters: + * dest : pointer for new property list + * src : property list + * + * Returns: + * MOSQ_ERR_SUCCESS - on successful copy + * MOSQ_ERR_INVAL - if dest is NULL + * MOSQ_ERR_NOMEM - on out of memory (dest will be set to NULL) + */ +libmosq_EXPORT int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_property *src); + +/* + * Function: mosquitto_property_check_command + * + * Check whether a property identifier is valid for the given command. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * identifier - MQTT property (e.g. MQTT_PROP_USER_PROPERTY) + * + * Returns: + * MOSQ_ERR_SUCCESS - if the identifier is valid for command + * MOSQ_ERR_PROTOCOL - if the identifier is not valid for use with command. + */ +libmosq_EXPORT int mosquitto_property_check_command(int command, int identifier); + + +/* + * Function: mosquitto_property_check_all + * + * Check whether a list of properties are valid for a particular command, + * whether there are duplicates, and whether the values are valid where + * possible. + * + * Note that this function is used internally in the library whenever + * properties are passed to it, so in basic use this is not needed, but should + * be helpful to check property lists *before* the point of using them. + * + * Parameters: + * command - MQTT command (e.g. CMD_CONNECT) + * properties - list of MQTT properties to check. + * + * Returns: + * MOSQ_ERR_SUCCESS - if all properties are valid + * MOSQ_ERR_DUPLICATE_PROPERTY - if a property is duplicated where it is forbidden. + * MOSQ_ERR_PROTOCOL - if any property is invalid + */ +libmosq_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties); + +/* Function: mosquitto_string_to_property_info + * + * Parse a property name string and convert to a property identifier and data type. + * The property name is as defined in the MQTT specification, with - as a + * separator, for example: payload-format-indicator. + * + * Parameters: + * propname - the string to parse + * identifier - pointer to an int to receive the property identifier + * type - pointer to an int to receive the property type + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the string does not match a property + * + * Example: + * mosquitto_string_to_property_info("response-topic", &id, &type); + * // id == MQTT_PROP_RESPONSE_TOPIC + * // type == MQTT_PROP_TYPE_STRING + */ +libmosq_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/mosquitto_plugin.h b/product/src/fes/protocol/yxcloud_mqtt_wn/mosquitto_plugin.h new file mode 100644 index 00000000..e8fb1eaa --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/mosquitto_plugin.h @@ -0,0 +1,319 @@ +/* +Copyright (c) 2012-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_PLUGIN_H +#define MOSQUITTO_PLUGIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MOSQ_AUTH_PLUGIN_VERSION 4 + +#define MOSQ_ACL_NONE 0x00 +#define MOSQ_ACL_READ 0x01 +#define MOSQ_ACL_WRITE 0x02 +#define MOSQ_ACL_SUBSCRIBE 0x04 + +#include +#include + +struct mosquitto; + +struct mosquitto_opt { + char *key; + char *value; +}; + +struct mosquitto_auth_opt { + char *key; + char *value; +}; + +struct mosquitto_acl_msg { + const char *topic; + const void *payload; + long payloadlen; + int qos; + bool retain; +}; + +/* + * To create an authentication plugin you must include this file then implement + * the functions listed in the "Plugin Functions" section below. The resulting + * code should then be compiled as a shared library. Using gcc this can be + * achieved as follows: + * + * gcc -I -fPIC -shared plugin.c -o plugin.so + * + * On Mac OS X: + * + * gcc -I -fPIC -shared plugin.c -undefined dynamic_lookup -o plugin.so + * + * Authentication plugins can implement one or both of authentication and + * access control. If your plugin does not wish to handle either of + * authentication or access control it should return MOSQ_ERR_PLUGIN_DEFER. In + * this case, the next plugin will handle it. If all plugins return + * MOSQ_ERR_PLUGIN_DEFER, the request will be denied. + * + * For each check, the following flow happens: + * + * * The default password file and/or acl file checks are made. If either one + * of these is not defined, then they are considered to be deferred. If either + * one accepts the check, no further checks are made. If an error occurs, the + * check is denied + * * The first plugin does the check, if it returns anything other than + * MOSQ_ERR_PLUGIN_DEFER, then the check returns immediately. If the plugin + * returns MOSQ_ERR_PLUGIN_DEFER then the next plugin runs its check. + * * If the final plugin returns MOSQ_ERR_PLUGIN_DEFER, then access will be + * denied. + */ + +/* ========================================================================= + * + * Helper Functions + * + * ========================================================================= */ + +/* There are functions that are available for plugin developers to use in + * mosquitto_broker.h, including logging and accessor functions. + */ + + +/* ========================================================================= + * + * Plugin Functions + * + * You must implement these functions in your plugin. + * + * ========================================================================= */ + +/* + * Function: mosquitto_auth_plugin_version + * + * The broker will call this function immediately after loading the plugin to + * check it is a supported plugin version. Your code must simply return + * MOSQ_AUTH_PLUGIN_VERSION. + */ +int mosquitto_auth_plugin_version(void); + + +/* + * Function: mosquitto_auth_plugin_init + * + * Called after the plugin has been loaded and + * has been called. This will only ever be called once and can be used to + * initialise the plugin. + * + * Parameters: + * + * user_data : The pointer set here will be passed to the other plugin + * functions. Use to hold connection information for example. + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_plugin_cleanup + * + * Called when the broker is shutting down. This will only ever be called once + * per plugin. + * Note that will be called directly before + * this function. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count); + + +/* + * Function: mosquitto_auth_security_init + * + * This function is called in two scenarios: + * + * 1. When the broker starts up. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, will be called first, then + * this function will be called. In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_init(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_security_cleanup + * + * This function is called in two scenarios: + * + * 1. When the broker is shutting down. + * 2. If the broker is requested to reload its configuration whilst running. In + * this case, this function will be called, followed by + * . In this situation, the reload parameter + * will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * opts : Pointer to an array of struct mosquitto_opt, which + * provides the plugin options defined in the configuration file. + * opt_count : The number of elements in the opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count, bool reload); + + +/* + * Function: mosquitto_auth_acl_check + * + * Called by the broker when topic access must be checked. access will be one + * of: + * MOSQ_ACL_SUBSCRIBE when a client is asking to subscribe to a topic string. + * This differs from MOSQ_ACL_READ in that it allows you to + * deny access to topic strings rather than by pattern. For + * example, you may use MOSQ_ACL_SUBSCRIBE to deny + * subscriptions to '#', but allow all topics in + * MOSQ_ACL_READ. This allows clients to subscribe to any + * topic they want, but not discover what topics are in use + * on the server. + * MOSQ_ACL_READ when a message is about to be sent to a client (i.e. whether + * it can read that topic or not). + * MOSQ_ACL_WRITE when a message has been received from a client (i.e. whether + * it can write to that topic or not). + * + * Return: + * MOSQ_ERR_SUCCESS if access was granted. + * MOSQ_ERR_ACL_DENIED if access was not granted. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_acl_check(void *user_data, int access, struct mosquitto *client, const struct mosquitto_acl_msg *msg); + + +/* + * Function: mosquitto_auth_unpwd_check + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making basic username/password checks. + * + * Called by the broker when a username/password must be checked. + * + * Return: + * MOSQ_ERR_SUCCESS if the user is authenticated. + * MOSQ_ERR_AUTH if authentication failed. + * MOSQ_ERR_UNKNOWN for an application specific error. + * MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_unpwd_check(void *user_data, struct mosquitto *client, const char *username, const char *password); + + +/* + * Function: mosquitto_psk_key_get + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making TLS-PSK checks. + * + * Called by the broker when a client connects to a listener using TLS/PSK. + * This is used to retrieve the pre-shared-key associated with a client + * identity. + * + * Examine hint and identity to determine the required PSK (which must be a + * hexadecimal string with no leading "0x") and copy this string into key. + * + * Parameters: + * user_data : the pointer provided in . + * hint : the psk_hint for the listener the client is connecting to. + * identity : the identity string provided by the client + * key : a string where the hex PSK should be copied + * max_key_len : the size of key + * + * Return value: + * Return 0 on success. + * Return >0 on failure. + * Return MOSQ_ERR_PLUGIN_DEFER if your plugin does not wish to handle this check. + */ +int mosquitto_auth_psk_key_get(void *user_data, struct mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len); + +/* + * Function: mosquitto_auth_start + * + * This function is OPTIONAL. Only include this function in your plugin if you + * are making extended authentication checks. + * + * Parameters: + * user_data : the pointer provided in . + * method : the authentication method + * reauth : this is set to false if this is the first authentication attempt + * on a connection, set to true if the client is attempting to + * reauthenticate. + * data_in : pointer to authentication data, or NULL + * data_in_len : length of data_in, in bytes + * data_out : if your plugin wishes to send authentication data back to the + * client, allocate some memory using malloc or friends and set + * data_out. The broker will free the memory after use. + * data_out_len : Set the length of data_out in bytes. + * + * Return value: + * Return MOSQ_ERR_SUCCESS if authentication was successful. + * Return MOSQ_ERR_AUTH_CONTINUE if the authentication is a multi step process and can continue. + * Return MOSQ_ERR_AUTH if authentication was valid but did not succeed. + * Return any other relevant positive integer MOSQ_ERR_* to produce an error. + */ +int mosquitto_auth_start(void *user_data, struct mosquitto *client, const char *method, bool reauth, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + +int mosquitto_auth_continue(void *user_data, struct mosquitto *client, const char *method, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/mosquittopp.h b/product/src/fes/protocol/yxcloud_mqtt_wn/mosquittopp.h new file mode 100644 index 00000000..fd2f1793 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/mosquittopp.h @@ -0,0 +1,146 @@ +/* +Copyright (c) 2010-2019 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTOPP_H +#define MOSQUITTOPP_H + +#if defined(_WIN32) && !defined(LIBMOSQUITTO_STATIC) +# ifdef mosquittopp_EXPORTS +# define mosqpp_EXPORT __declspec(dllexport) +# else +# define mosqpp_EXPORT __declspec(dllimport) +# endif +#else +# define mosqpp_EXPORT +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define DEPRECATED __attribute__ ((deprecated)) +#else +# define DEPRECATED +#endif + +#include +#include +#include + +namespace mosqpp { + + +mosqpp_EXPORT const char * DEPRECATED strerror(int mosq_errno); +mosqpp_EXPORT const char * DEPRECATED connack_string(int connack_code); +mosqpp_EXPORT int DEPRECATED sub_topic_tokenise(const char *subtopic, char ***topics, int *count); +mosqpp_EXPORT int DEPRECATED sub_topic_tokens_free(char ***topics, int count); +mosqpp_EXPORT int DEPRECATED lib_version(int *major, int *minor, int *revision); +mosqpp_EXPORT int DEPRECATED lib_init(); +mosqpp_EXPORT int DEPRECATED lib_cleanup(); +mosqpp_EXPORT int DEPRECATED topic_matches_sub(const char *sub, const char *topic, bool *result); +mosqpp_EXPORT int DEPRECATED validate_utf8(const char *str, int len); +mosqpp_EXPORT int DEPRECATED subscribe_simple( + struct mosquitto_message **messages, + int msg_count, + bool retained, + const char *topic, + int qos=0, + const char *host="localhost", + int port=1883, + const char *client_id=NULL, + int keepalive=60, + bool clean_session=true, + const char *username=NULL, + const char *password=NULL, + const struct libmosquitto_will *will=NULL, + const struct libmosquitto_tls *tls=NULL); + +mosqpp_EXPORT int DEPRECATED subscribe_callback( + int (*callback)(struct mosquitto *, void *, const struct mosquitto_message *), + void *userdata, + const char *topic, + int qos=0, + bool retained=true, + const char *host="localhost", + int port=1883, + const char *client_id=NULL, + int keepalive=60, + bool clean_session=true, + const char *username=NULL, + const char *password=NULL, + const struct libmosquitto_will *will=NULL, + const struct libmosquitto_tls *tls=NULL); + +/* + * Class: mosquittopp + * + * A mosquitto client class. This is a C++ wrapper class for the mosquitto C + * library. Please see mosquitto.h for details of the functions. + */ +class mosqpp_EXPORT DEPRECATED mosquittopp { + private: + struct mosquitto *m_mosq; + public: + DEPRECATED mosquittopp(const char *id=NULL, bool clean_session=true); + virtual ~mosquittopp(); + + int DEPRECATED reinitialise(const char *id, bool clean_session); + int DEPRECATED socket(); + int DEPRECATED will_set(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int DEPRECATED will_clear(); + int DEPRECATED username_pw_set(const char *username, const char *password=NULL); + int DEPRECATED connect(const char *host, int port=1883, int keepalive=60); + int DEPRECATED connect_async(const char *host, int port=1883, int keepalive=60); + int DEPRECATED connect(const char *host, int port, int keepalive, const char *bind_address); + int DEPRECATED connect_async(const char *host, int port, int keepalive, const char *bind_address); + int DEPRECATED reconnect(); + int DEPRECATED reconnect_async(); + int DEPRECATED disconnect(); + int DEPRECATED publish(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int DEPRECATED subscribe(int *mid, const char *sub, int qos=0); + int DEPRECATED unsubscribe(int *mid, const char *sub); + void DEPRECATED reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + int DEPRECATED max_inflight_messages_set(unsigned int max_inflight_messages); + void DEPRECATED message_retry_set(unsigned int message_retry); + void DEPRECATED user_data_set(void *userdata); + int DEPRECATED tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL); + int DEPRECATED tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL); + int DEPRECATED tls_insecure_set(bool value); + int DEPRECATED tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL); + int DEPRECATED opts_set(enum mosq_opt_t option, void *value); + + int DEPRECATED loop(int timeout=-1, int max_packets=1); + int DEPRECATED loop_misc(); + int DEPRECATED loop_read(int max_packets=1); + int DEPRECATED loop_write(int max_packets=1); + int DEPRECATED loop_forever(int timeout=-1, int max_packets=1); + int DEPRECATED loop_start(); + int DEPRECATED loop_stop(bool force=false); + bool DEPRECATED want_write(); + int DEPRECATED threaded_set(bool threaded=true); + int DEPRECATED socks5_set(const char *host, int port=1080, const char *username=NULL, const char *password=NULL); + + // names in the functions commented to prevent unused parameter warning + virtual void on_connect(int /*rc*/) {return;} + virtual void on_connect_with_flags(int /*rc*/, int /*flags*/) {return;} + virtual void on_disconnect(int /*rc*/) {return;} + virtual void on_publish(int /*mid*/) {return;} + virtual void on_message(const struct mosquitto_message * /*message*/) {return;} + virtual void on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/) {return;} + virtual void on_unsubscribe(int /*mid*/) {return;} + virtual void on_log(int /*level*/, const char * /*str*/) {return;} + virtual void on_error() {return;} +}; + +} +#endif diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/mqtts_wn_enum.h b/product/src/fes/protocol/yxcloud_mqtt_wn/mqtts_wn_enum.h new file mode 100644 index 00000000..50ecb389 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/mqtts_wn_enum.h @@ -0,0 +1,322 @@ +#ifndef MQTTS_WN_ENUM_H +#define MQTTS_WN_ENUM_H + +#include "FesDef.h" +#include +/*******************************定义区***********************************************/ + +#define MAX_TOPIC_NUM 1000 +#define MAX_TXDEFCMD_NUM 1000 //是否太大 + + +#define CN_BYTE_LO ( 0 ) // 低字节 +#define CN_BYTE_HI ( 1 ) // 高字节 + +#define CN_DWB4_LL ( 0 ) // 最低字节 +#define CN_DWB4_LH ( 1 ) // 次低字节 +#define CN_DWB4_HL ( 2 ) // 次高字节 +#define CN_DWB4_HH ( 3 ) // 最高字节 + + +#define FAULT_COUNT_NUM ( 11 ) //安规参数中的保护类型数目 +#define FAULT_CONFIG (5) //安规参数中的保护类型参数种类数目 +#define WAIT_ACK_TIME (10) //等待回复信息时间 + +#define UNLOAD_LOGIC_GROUP_NUM (6) //降载逻辑参数一组6个 +#define SNNUMBER_LEN (12) //sn序列号编码长度 + + +#define SEND_TOPIC_HEAD ( "down/" ) //发送主题的开头固定字符 + +#define UNLOAD_LOGIC_SHEETNAME ("unload_logic") //降载逻辑配置文件中sheet名称 是否应该写进配置文件中 +#define PARA_PI_SHEETNAME ("pi_para") //降载逻辑配置文件中sheet名称 是否应该写进配置文件中 +#define PARA_MPPT_SHEETNAME ("mppt_para") //降载逻辑配置文件中sheet名称 是否应该写进配置文件中 + +#define CHECK_DIFF_TIME (10 * 60 * 1000) //10分钟检测一次 + +/********************************枚举区****************************************************/ + +enum _ENUM_WN_HEAD_TYPE_ +{ + HEAD_55 = 0x55, + HEAD_AA = 0xAA + +};//微逆帧结构开头命令码 + + +enum _ENUM_WM_FRAME_INDEX_ +{ + WN_FRAME_HEAD = 0, + WN_FRAME_CMD = 2, + WN_FRAME_L = 4, + WN_FRAME_DATA = 6 + +};//微逆帧各结构下标位置 + + +enum _ENUM_WM_DATA_LEN_ +{ + WN_0BBF_DATA_LEN = 170 + +};//微逆帧结构各命令data的长度 + + +enum _ENUM_WN_COMM_TYPE_ +{ + CMD_UPLOAD_FAULT_INFO = 0x0001, //网关上传故障信息(保留) + CMD_UPDATE_GATEWAY_MCU = 0x0002, //更新网关 MCU 固件 + CMD_UPDATE_GATEWAY_RTC = 0x0003, //更新网关 RTC + CMD_REFRESH_TIME_SETTING = 0x0004, //刷新时间设置 + CMD_QUICK_REFRESH_RUNNING_INFO = 0x0005, //快速刷新运行信息 + CMD_RESTORE_FACTORY_SETTINGS = 0x0BB9, //恢复出厂设置 + CMD_POWER_CONTROL = 0x0BBA, //开关机控制 + CMD_ACTIVE_POWER_ADJUSTMENT = 0x0BBB, //指令有功调节 + CMD_FIXED_ACTIVE_POWER_SETTING = 0x0BBC, //固定有功设置 + CMD_PROTECTION_PARAMETER_SETTING = 0x0BBD, //保护参数设置 + CMD_SAFETY_STANDARD_PARAMETER_SETTING = 0x0BBE, //安规参数设置 + CMD_SAFETY_STANDARD_PARAMETER_QUERY = 0x0BBF, //安规参数查询 + CMD_PROTECTION_PARAMETER_QUERY = 0x0BC0, //保护参数查询 + CMD_ALL_DERATING_LOGIC_SETTING = 0x0BC2, //全部降载逻辑设置 + CMD_ALL_DERATING_LOGIC_QUERY = 0x0BC3, //读取全部降载逻辑 + CMD_PI_PARAMETER_SETTING = 0x0BC4, //PI 参数设置 + CMD_PI_PARAMETER_QUERY = 0x0BC5, //PI 参数读取 + CMD_MPPT_PARAMETER_SETTING = 0x0BC6, //MPPT 参数设置 + CMD_MPPT_PARAMETER_QUERY = 0x0BC7, //MPPT 参数读取 + CMD_FIRMWARE_INFORMATION = 0x0BB7, //固件信息 + CMD_RUNTIME_INFORMATION = 0x0BB8, //运行信息 + CMD_UPDATE_INVERTER_FIRMWARE = 0x0BC1, //更新逆变器固件 + CMD_CHANGE_SN_NUMBER = 0x0BC8 //更改 SN 号 + +}; //微逆自定义命令码 + + +enum _ENUM_ACK_STATE_ +{ + ACK_STATE_FAL = 0x0000, //失败 + ACK_STATE_CHECKERR = 0x0001, //和校验错误 + ACK_STATE_SUCC = 0x0002 //成功 + +};//设备回应状态码 + +typedef enum +{ + YXWN_NO_ERROR = 0, + OK_CAN_DO_WORK = 50, + OK_ERASE_FLASH, + OK_WRITE_FLASH, + OK_COPY_FLASH, + ERROR_ERASE_FLASH = 100,//之后都是错误码 + ERROR_WRITE_FLASH, + ERROR_COPY_FLASH_CRC, + ERROR_COPY_FLASH_WRITE_ADDR, + ERROR_COPY_FLASH_WRITE_ADDR_CHECK, + ERROR_COPY_FLASH_ERASE_APP, + ERROR_LAST_PACKAGE_CRC, + ERROR_SUBCMD, + ERROR_CHECK_APP_DATA, + ERROR_PROCESS_ORDER = 150 +} RET_ERROR_OK_Type; + + +/***********************************结构区**************************************************/ +typedef struct +{ + int devId; //设备ID + int alarmId; //告警ID + int yxNo; //遥信转发远动号 + std::string alarmCode; //告警描述 +}Alarm_Value_Str; + +typedef std::vector Alarm_Value_List; + +typedef struct +{ + std::string proParaDesc; //点位名称 + int byteNum; //点位字节 + double resolvingPower; //点位分辨率 + std::string ppUnit; //点位单位 + std::string ppRange; //点位取值范围 + std::string parentDesc; //父节点名称 + +}ProtectPara;//保护参数 + +typedef std::vector ProtectPara_List; + +typedef struct +{ + int64 TopicSendTime; //主题发送时间,用于判断是否需要发送 + bool JsonUpdataFlag; //JSON文件更新标志 + bool TopicSendFlag; //发送标志 + + int sendTime; //上传周期,单位秒,0表示启动上传一次,后面变化上传,大于1的值表示间隔多少秒上传 + std::string topic; //topic + std::string jsonFileName; //JSON文件名 + std::string snName; //柜名 + std::string snDeviceName; //设备名 + std::string fileMd5; //文件MD5,用于判断文件内容是否改变 + +}SEND_TOPIC_STR; + +typedef struct{ + int RtuNo; + int mqttDelayTime; //每个主题上抛延时,单位毫秒 + int CycReadFileTime; //周期检查文件的时间,单位秒 + + int PasswordFlag; //是否启用密码 0不启用 1启用 默认0 + std::string ClientId; //客户端ID + std::string UserName; //用户名 + std::string Password; //密码 + + int KeepAlive; //心跳检测时间间隔 + bool Retain; //MQTT服务器是否保持消息 默认0 + int QoS; //服务质量 默认1 + int WillFlag; //遗愿消息标志 默认1 + int WillQos; //遗愿消息服务质量 默认1 + + //SSL加密配置参数 + int sslFlag; //SSL加密标志 0不加密 1单向加密 2双向加密 + std::string tls_version; //加密协议版本 + std::string caPath; //加密文件路径 + std::string caFile; //CA文件名 + std::string certFile; //证书文件名 + std::string keyFile; //私钥文件名 + std::string keyPassword; //私钥密码 + + std::string AlarmProjectType; //告警数据项目类型 + std::string AlarmTopic; //告警数据主题 + + int maxUpdateCount; //系统启动前,本FES数据每10S跟新一次全数据,直到该值到到达最大值,变为60S跟新全数据。 + int startDelay; //系统启动延时,单位秒 + int ymStartDelay; //遥脉启动延时,单位秒 + + std::string wnParaConPath; //微逆参数配置文件 + std::string wnParaConPath2; //微逆参数配置文件(内含保护参数和降载逻辑) + +}SYxcloudmqttsAppConfigParam; + +//Yxcloudmqtts 内部应用数据结构,个数和通道结构中m_RtuNum个数相同,且一一对应 +typedef struct{ + //配置参数 + int RtuNo; + int64 startDelay; + int64 ymStartDelay; //遥脉启动延时,单位秒 + int CycReadFileTime; //周期检查文件的时间,单位秒 + int maxUpdateCount; + int updateCount; //系统启动前,本FES数据没10S跟新一次全数据,直到该值到到达最大值,变为60S跟新全数据。 + + uint64 updateTime; + uint64 lastUpdateTime; + bool mqttContFlag; + + int mqttDelayTime; //每个主题上抛延时,单位毫秒 + int PasswordFlag; //是否启用密码 0不启用 1启用 默认0 + std::string ClientId; //客户端ID + std::string UserName; //用户名 + std::string Password; //密码 + std::string AlarmProjectType; //告警数据项目类型 + std::string AlarmTopic; //告警数据主题 + std::string wnParaConPath; //微逆参数配置文件路径 + std::string wnParaConPath2; //微逆参数配置文件(内含保护参数和降载逻辑) + + int KeepAlive; //心跳检测时间间隔 + bool Retain; //MQTT服务器是否保持消息 默认0 + int QoS; //品质 默认1 + int WillFlag; //遗愿消息标志 默认1 + int WillQos; //遗愿消息品质 默认1 + + //SSL加密配置参数 + int sslFlag; //SSL加密标志 0不加密 1单向加密 2双向加密 + std::string tls_version; //加密协议版本 + std::string caPath; //文件路径 + std::string caFile; //CA文件名 + std::string certFile; //证书文件名 + std::string keyFile; //私钥文件名 + std::string keyPassword; //私钥密码 + + + //mqtt_topic_cfg文件MD5 + std::string TopicCfgMd5; + + + //主题列表 + SEND_TOPIC_STR sendTopicStr[MAX_TOPIC_NUM]; + int sendTopicNum; + + //告警列表 + Alarm_Value_List alarmList; + ProtectPara_List protectparaList; + + std::mapm_parasConfig; //微逆参数配置存储 未写初始化代码 + +}SYxcloudmqttsAppData; + +typedef struct { + int64 startTime; //系统启动时间 + int64 CycTime; //周期检查文件时间 + int topicIndex; //已上抛主题索引 + bool mqttStartFlag; + bool ymStartFlag; //遥脉启动转发标志 + bool mqttSendEndFlag; //Mqtt发送结束标志 +}MqttPublishTime; + +typedef struct { + int funcode; + int dataLen ; + int frameCode ; + int PCSNum ; +// int countryInfo; + +}MqttRecvMsg; + + +typedef struct{ + std::string DSPDevNum; //DSP设备序列号 + std::string DSPSoftVersion; //软件版本说明 + std::string DSPPVersion; //DSP功率版本 + std::string DSPMCUPNum; //DSP MCU通信协议号 + std::string MCUSoftVersion; //MCU软件版本号 +}FirmWareInfo; + +typedef struct +{ + uint16 faultCode; //故障码 + uint16 triggerThreshold; //触发阈值 + uint32 triggerTime; //触发故障时间 + uint16 recoveryThreshold; //恢复阈值 + uint32 recoverTime; //恢复时间 +}InvSingleFaultConfig; //保护类型 + +typedef struct{ + InvSingleFaultConfig fault[FAULT_COUNT_NUM]; // 保护类型 fault[11],每个故障信息占用 14 字节,总计 154 字节 + uint32 mask1; // 故障屏蔽码-故障信息1 + uint32 mask2; // 故障屏蔽码-故障信息2 + uint32 mask3; // 故障屏蔽码-故障信息3 + uint16 countryCode; // 国家码,占用 2 字节 + uint16 checksum; // 校验码,占用 2 字节 (Sum16 校验) +}InvFaultConfigParas; + + +//用于报文解析的联合体 +typedef union +{ + uint16 uNum; + byte cByte[2]; + +}Byte2n; + +typedef union +{ + uint32 duNum; + uint16 uNum[2]; + byte cByte[4]; + +}Byte4n; + + +typedef struct +{ + SFesTxDefCmd defCmd; + time_t timestamp; +}CustomCmd; + +#endif // MQTTS_WN_ENUM_H diff --git a/product/src/fes/protocol/yxcloud_mqtt_wn/yxcloud_mqtt_wn.pro b/product/src/fes/protocol/yxcloud_mqtt_wn/yxcloud_mqtt_wn.pro new file mode 100644 index 00000000..e3987b95 --- /dev/null +++ b/product/src/fes/protocol/yxcloud_mqtt_wn/yxcloud_mqtt_wn.pro @@ -0,0 +1,61 @@ +# ARM板上资源有限,不会与云平台混用,不编译 +message("Compile only in x86 environment") +# requires(contains(QMAKE_HOST.arch, x86_64)) +requires(!contains(QMAKE_HOST.arch, aarch64):!linux-aarch64*) + +QT += core sql + +TARGET = yxcloud_mqtt_wn +TEMPLATE = lib + + +SOURCES += \ + Yxcloudmqtts.cpp \ + YxcloudmqttsDataProcThread.cpp \ + Md5/Md5.cpp \ + CMQTTDataThread.cpp \ + CMQTTClient.cpp + +HEADERS += \ + Yxcloudmqtts.h \ + YxcloudmqttsDataProcThread.h \ + mosquitto.h \ + mosquitto_plugin.h \ + mosquittopp.h \ + Md5/Md5.h \ + CMQTTDataThread.h \ + CMQTTClient.h \ + mqtts_wn_enum.h + + +INCLUDEPATH += \ + ../../include/ \ + ../../../include/ \ + ../../../3rd/include/ + +LIBS += -lboost_system -lboost_thread -lboost_locale -lboost_chrono -lboost_date_time +LIBS += -lpub_utility_api -lpub_logger_api -llog4cplus -lprotocolbase -ldb_api_ex +LIBS += -lmosquitto -lmosquittopp + +linux-* { + LIBS += -lxlsxio_read \ + -lxlsxio_write +} + +win32-msvc*{ + LIBS += -llibxlsxio_read \ + -llibxlsxio_write +} + + + +DEFINES += PROTOCOLBASE_API_EXPORTS +include($$PWD/../../../idl_files/idl_files.pri) + +#------------------------------------------------------------------- +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/GraphTool/GraphTool.pro b/product/src/gui/GraphTool/GraphTool.pro index ffa729f5..3272d705 100644 --- a/product/src/gui/GraphTool/GraphTool.pro +++ b/product/src/gui/GraphTool/GraphTool.pro @@ -1,3 +1,7 @@ TEMPLATE=subdirs CONFIG += ordered -SUBDIRS+= fileSync NavigationApi NavigationTool IconActTool +SUBDIRS+= \ +# fileSync \ + NavigationApi \ + NavigationTool \ + IconActTool diff --git a/product/src/gui/GraphTool/IconActTool/CIconActDialog.cpp b/product/src/gui/GraphTool/IconActTool/CIconActDialog.cpp index dbcd600b..240617e4 100644 --- a/product/src/gui/GraphTool/IconActTool/CIconActDialog.cpp +++ b/product/src/gui/GraphTool/IconActTool/CIconActDialog.cpp @@ -11,14 +11,18 @@ #include CIconActDialog::CIconActDialog(QWidget *parent) : - QDialog(parent), + CustomUiDialog(parent), ui(new Ui::CIconActDialog), m_pTableModel(Q_NULLPTR), m_pFileOpt(Q_NULLPTR) { + setWindowTitle(tr("图元动作")); + ui->setupUi(this); initialize(); + + CustomUiDialog::setAutoLayout(true); } CIconActDialog::~CIconActDialog() diff --git a/product/src/gui/GraphTool/IconActTool/CIconActDialog.h b/product/src/gui/GraphTool/IconActTool/CIconActDialog.h index e35c7de6..23a27a51 100644 --- a/product/src/gui/GraphTool/IconActTool/CIconActDialog.h +++ b/product/src/gui/GraphTool/IconActTool/CIconActDialog.h @@ -1,8 +1,8 @@ #ifndef CICONACTDIALOG_H #define CICONACTDIALOG_H -#include #include +#include "pub_widget/CustomDialog.h" namespace Ui { class CIconActDialog; @@ -10,7 +10,7 @@ class CIconActDialog; class CTableModel; class CFileOpt; -class CIconActDialog : public QDialog +class CIconActDialog : public CustomUiDialog { Q_OBJECT diff --git a/product/src/gui/GraphTool/IconActTool/CIconActDialog.ui b/product/src/gui/GraphTool/IconActTool/CIconActDialog.ui index e6691260..16ce7546 100644 --- a/product/src/gui/GraphTool/IconActTool/CIconActDialog.ui +++ b/product/src/gui/GraphTool/IconActTool/CIconActDialog.ui @@ -46,19 +46,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -109,6 +96,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + diff --git a/product/src/gui/GraphTool/IconActTool/IconActTool.pro b/product/src/gui/GraphTool/IconActTool/IconActTool.pro index e72679c1..1e11abad 100644 --- a/product/src/gui/GraphTool/IconActTool/IconActTool.pro +++ b/product/src/gui/GraphTool/IconActTool/IconActTool.pro @@ -45,7 +45,8 @@ FORMS += \ LIBS += \ -lpub_utility_api \ -llog4cplus \ - -lpub_logger_api + -lpub_logger_api \ + -lpub_widget COMMON_PRI=$$PWD/../../../common.pri exists($$COMMON_PRI) { diff --git a/product/src/gui/GraphTool/IconActTool/main.cpp b/product/src/gui/GraphTool/IconActTool/main.cpp index 52609ef1..eb3ce3ec 100644 --- a/product/src/gui/GraphTool/IconActTool/main.cpp +++ b/product/src/gui/GraphTool/IconActTool/main.cpp @@ -3,6 +3,7 @@ #include #include "common/QtAppGlobalSet.h" #include "CIconActDialog.h" +#include "pub_utility_api/FileStyle.h" int main(int argc, char *argv[]) { @@ -12,6 +13,34 @@ int main(int argc, char *argv[]) QTextCodec::setCodecForLocale(codec); QApplication a(argc, argv); + + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss","zh","light"); + + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("IconActTool.qss","zh","light"); + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + + if (!qss.isEmpty()) + { + qApp->setStyleSheet(qss); + } + +// qApp->setFont(QFont("Microsoft YaHei",10)); + CIconActDialog w; w.show(); diff --git a/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.cpp b/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.cpp index 5c814223..e2b595ea 100644 --- a/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.cpp +++ b/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.cpp @@ -13,10 +13,13 @@ const int Item_Role = Qt::UserRole + 1; CNavigationDialog::CNavigationDialog(QWidget *parent) : - QDialog(parent), + CustomUiMainWindow(parent), ui(new Ui::CNavigationDialog), m_itemIndex(0) { + setWindowTitle(tr("导航栏配置工具")); + CustomUiMainWindow::setAutoLayout(true); + ui->setupUi(this); initialize(); @@ -568,12 +571,12 @@ void CNavigationDialog::onConfirmClicked() QMessageBox::information(this, tr("提示"), tr("保存失败!"), QMessageBox::Ok); return; } - accept(); + } void CNavigationDialog::onCancelClicked() { - reject(); + } void CNavigationDialog::onExport() diff --git a/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.h b/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.h index e5287c0e..4844e7ea 100644 --- a/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.h +++ b/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.h @@ -1,9 +1,9 @@ #ifndef CNAVIGATIONDIALOG_H #define CNAVIGATIONDIALOG_H -#include #include "gui/GraphTool/NavigationApi/CJsonOpt.h" #include "model_excel/xlsx/xlsxdocument.h" +#include "pub_widget/CustomMainWindow.h" namespace Ui { class CNavigationDialog; @@ -12,7 +12,7 @@ class CNavigationDialog; extern const int Item_Role; //< 节点数-仅导入使用 class QTreeWidgetItem; -class CNavigationDialog : public QDialog +class CNavigationDialog : public CustomUiMainWindow { Q_OBJECT diff --git a/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.ui b/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.ui index 78529a16..9e2ddb8b 100644 --- a/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.ui +++ b/product/src/gui/GraphTool/NavigationTool/CNavigationDialog.ui @@ -1,288 +1,278 @@ - - - CNavigationDialog - - - - 0 - 0 - 1087 - 673 - - - - 导航栏配置工具 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Plain - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 添加节点 - - - + - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 添加子节点 - - - - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 删除节点 - - - - - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 清空节点 - - - × - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 上移节点 - - - - - - - - - - - 21 - 21 - - - - - 21 - 21 - - - - 下移节点 - - - - - - - - - - - - Qt::Horizontal - - - - 484 - 17 - - - - - - - - - - 导入 - - - - - - - 导出 - - - - - - - - - - 1 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 确认 - - - - - - - 取消 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - CTreeWidget - QTreeWidget -
CTreeWidget.h
-
-
- - -
+ + + CNavigationDialog + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + 1 + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 添加节点 + + + + + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 添加子节点 + + + + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 删除节点 + + + - + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 清空节点 + + + × + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 上移节点 + + + + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 下移节点 + + + + + + + + + + + + Qt::Horizontal + + + + 484 + 17 + + + + + + + + + + 导入 + + + + + + + 导出 + + + + + + + + + + 1 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 确认 + + + + + + + 取消 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + CTreeWidget + QTreeWidget +
CTreeWidget.h
+
+
+ + +
diff --git a/product/src/gui/GraphTool/NavigationTool/NavigationTool.pro b/product/src/gui/GraphTool/NavigationTool/NavigationTool.pro index 738a18b6..6b2f9efd 100644 --- a/product/src/gui/GraphTool/NavigationTool/NavigationTool.pro +++ b/product/src/gui/GraphTool/NavigationTool/NavigationTool.pro @@ -45,7 +45,8 @@ LIBS += \ -lpub_logger_api \ -lpub_utility_api \ -lmodel_excel \ - -lNavigationApi + -lNavigationApi \ + -lpub_widget COMMON_PRI=$$PWD/../../../common.pri exists($$COMMON_PRI) { diff --git a/product/src/gui/GraphTool/NavigationTool/main.cpp b/product/src/gui/GraphTool/NavigationTool/main.cpp index 2b0d9467..9fefa9b9 100644 --- a/product/src/gui/GraphTool/NavigationTool/main.cpp +++ b/product/src/gui/GraphTool/NavigationTool/main.cpp @@ -2,12 +2,40 @@ #include #include "common/QtAppGlobalSet.h" #include "CNavigationDialog.h" +#include "pub_utility_api/FileStyle.h" int main(int argc, char *argv[]) { iot_common::doQtAppGlobalSet(); QApplication a(argc, argv); + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss","zh","light"); + + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("NavigationTool.qss","zh","light"); + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + + if (!qss.isEmpty()) + { + qApp->setStyleSheet(qss); + } + +// qApp->setFont(QFont("Microsoft YaHei",10)); + CNavigationDialog w; w.show(); diff --git a/product/src/gui/gui.pro b/product/src/gui/gui.pro index 5d57b708..ac5efaac 100644 --- a/product/src/gui/gui.pro +++ b/product/src/gui/gui.pro @@ -8,3 +8,6 @@ SUBDIRS += \ GraphTool \ plugin +TRANSLATIONS += \ + product_en.ts\ + product_fr.ts diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.cpp b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.cpp index 9df0b069..bd220e56 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.cpp +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatistics.cpp @@ -87,7 +87,6 @@ CAlarmStatistics::~CAlarmStatistics() delete m_pProcessDialog; m_pProcessDialog = NULL; - m_pQueryThread->wait(); delete m_pQueryThread; m_pQueryThread = NULL; diff --git a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatisticsPluginWidget.h b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatisticsPluginWidget.h index cc1137c6..c0c69466 100644 --- a/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatisticsPluginWidget.h +++ b/product/src/gui/plugin/AlarmAnalyzeWidget/CAlarmStatisticsPluginWidget.h @@ -8,7 +8,7 @@ class CAlarmStatisticsPluginWidget : public QWidget, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/AlarmManageWidget/AlarmManagePluginWidget.h b/product/src/gui/plugin/AlarmManageWidget/AlarmManagePluginWidget.h index e6f327d8..59befa0d 100644 --- a/product/src/gui/plugin/AlarmManageWidget/AlarmManagePluginWidget.h +++ b/product/src/gui/plugin/AlarmManageWidget/AlarmManagePluginWidget.h @@ -8,7 +8,7 @@ class AlarmManagePluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/AlarmManageWidget/main.cpp b/product/src/gui/plugin/AlarmManageWidget/main.cpp index 51e2811d..1449ae4c 100644 --- a/product/src/gui/plugin/AlarmManageWidget/main.cpp +++ b/product/src/gui/plugin/AlarmManageWidget/main.cpp @@ -8,7 +8,7 @@ int main(int argc, char *argv[]) QApplication a(argc, argv); std::string name="admin"; - std::string password ="kbdct"; + std::string password ="admin"; iot_public::StartLogSystem("HMI", "hmi"); iot_net::initMsgBus("HMI", "HMI"); diff --git a/product/src/gui/plugin/AlarmShieldWidget/CAlarmShieldPluginWidget.h b/product/src/gui/plugin/AlarmShieldWidget/CAlarmShieldPluginWidget.h index 37f72455..54453fcb 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CAlarmShieldPluginWidget.h +++ b/product/src/gui/plugin/AlarmShieldWidget/CAlarmShieldPluginWidget.h @@ -7,7 +7,7 @@ class CAlarmShieldPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/AlarmShieldWidget/CDevTreeModel.cpp b/product/src/gui/plugin/AlarmShieldWidget/CDevTreeModel.cpp index c8fff837..5025b820 100644 --- a/product/src/gui/plugin/AlarmShieldWidget/CDevTreeModel.cpp +++ b/product/src/gui/plugin/AlarmShieldWidget/CDevTreeModel.cpp @@ -86,6 +86,8 @@ E_Tree_ItemType CDevTreeModel::currentType() QVariant CDevTreeModel::headerData(int section, Qt::Orientation orientation, int role) const { + Q_UNUSED(section); + if(role == Qt::DisplayRole) { if(orientation == Qt::Horizontal) diff --git a/product/src/gui/plugin/AlarmStatisWidget/CAlarmStatisPluginWidget.h b/product/src/gui/plugin/AlarmStatisWidget/CAlarmStatisPluginWidget.h index 1c0dbb16..07934679 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/CAlarmStatisPluginWidget.h +++ b/product/src/gui/plugin/AlarmStatisWidget/CAlarmStatisPluginWidget.h @@ -7,7 +7,7 @@ class CAlarmStatisPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: CAlarmStatisPluginWidget(QObject *parent = 0); diff --git a/product/src/gui/plugin/AlarmStatisWidget/main.cpp b/product/src/gui/plugin/AlarmStatisWidget/main.cpp index 9605fd59..9149701c 100644 --- a/product/src/gui/plugin/AlarmStatisWidget/main.cpp +++ b/product/src/gui/plugin/AlarmStatisWidget/main.cpp @@ -18,7 +18,7 @@ int main(int argc, char *argv[]) return -1; } - if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) + if(perm->SysLogin("admin", "admin", 1, 12*60*60, "hmi") != 0) { return -1; } diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmBaseData.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmBaseData.cpp index 5c6f1eca..68d4aeee 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmBaseData.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmBaseData.cpp @@ -2,7 +2,19 @@ #include "perm_mng_api/PermMngApi.h" #include "CAlarmCommon.h" #include "pub_logger_api/logger.h" + +//< 屏蔽xml_parser编译告警 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-copy" +#endif + #include "boost/property_tree/xml_parser.hpp" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "boost/typeof/typeof.hpp" #include "boost/filesystem.hpp" #include "pub_utility_api/FileUtil.h" diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeModel.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeModel.cpp index 4394bda1..208b3ed0 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeModel.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeModel.cpp @@ -37,6 +37,20 @@ void CAlarmDeviceTreeModel::setupModelData(const QMapsetData("", Qt::ItemDataRole(TagRole)); + sys_device->setData(TYPE_DEVGROUP, Qt::ItemDataRole(TypeRole)); + sys_device->setData(vec.at(nDevIndex).domain, Qt::ItemDataRole(DomainRole)); + sys_device->setData(vec.at(nDevIndex).location, Qt::ItemDataRole(LocationRole)); + sys_device->setData(vec.at(nDevIndex).sub_system, Qt::ItemDataRole(SubsystemRole)); + sys_device->setData(vec.at(nDevIndex).region, Qt::ItemDataRole(RegionRole)); + QModelIndex sys_modelIndex = createIndex(nDevIndex+1, 0, sys_device); + m_devTagIndex.insert("", sys_modelIndex); + m_devNameIndex.insert("", sys_modelIndex); + } } } } @@ -160,9 +174,11 @@ QVariant CAlarmDeviceTreeModel::data(const QModelIndex &index, int role) const if (Qt::DisplayRole == role) { const QString &deviceGroup = item->data(Qt::ItemDataRole(TagRole)).toString(); - if(deviceGroup.isEmpty()) + int nType = item->data(Qt::ItemDataRole(TypeRole)).toInt(); + if(deviceGroup.isEmpty() && nType == TYPE_LOCATION) { - return item->data(Qt::DisplayRole).toString(); + //区域后面不加数量 + return item->data(Qt::DisplayRole).toString(); } return item->data(Qt::DisplayRole).toString() + QString(" [%1]").arg(m_alarmDeviceGroupStatistical.value(deviceGroup,0)); } diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeView.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeView.cpp index 9b764b94..6c34ff49 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeView.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmDeviceTreeView.cpp @@ -10,6 +10,7 @@ CAlarmDeviceTreeView::CAlarmDeviceTreeView(QWidget *parent) } +/* void CAlarmDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) { CAlarmDeviceTreeModel * pModel = dynamic_cast(model()); @@ -33,25 +34,26 @@ void CAlarmDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) } return; } +*/ -//void CAlarmDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) -//{ -// CAlarmDeviceTreeModel * pModel = dynamic_cast(model()); -// if(Q_NULLPTR != pModel) -// { -// QMenu menu; -// CAlarmDeviceTreeItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); -// if (Q_NULLPTR == pItem) -// { -// menu.addAction(tr("全选"), [=](){ pModel->setAllDeviceCheckState(Qt::Checked); }); -// menu.addAction(tr("清空"), [=](){ pModel->setAllDeviceCheckState(Qt::Unchecked); }); -// } -// else if (Q_NULLPTR != pItem && pItem->childCount() > 0) -// { -// menu.addAction(tr("选择"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Checked); }); -// menu.addAction(tr("清除"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Unchecked); }); -// } -// menu.exec(event->globalPos()); -// } -// return; -//} +void CAlarmDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) +{ + CAlarmDeviceTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QMenu menu; + CAlarmDeviceTreeItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); + if (Q_NULLPTR == pItem) + { + menu.addAction(tr("全选"), [=](){ pModel->setAllDeviceCheckState(Qt::Checked); }); + menu.addAction(tr("清空"), [=](){ pModel->setAllDeviceCheckState(Qt::Unchecked); }); + } + else if (Q_NULLPTR != pItem && pItem->childCount() > 0) + { + menu.addAction(tr("选择"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Checked); }); + menu.addAction(tr("清除"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Unchecked); }); + } + menu.exec(event->globalPos()); + } + return; +} diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.ui b/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.ui index 697a1be9..a4d7d56e 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.ui +++ b/product/src/gui/plugin/AlarmWidget/CAlarmFilterDialog.ui @@ -6,13 +6,13 @@ 0 0 - 657 - 510 + 1000 + 546 - 530 + 1000 0 diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmForm.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmForm.cpp index 5e164ec3..283e6f26 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmForm.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmForm.cpp @@ -38,6 +38,7 @@ #include "CAlarmBaseData.h" #include "CAlarmShiledDialog.h" #include "CAccidentReviewDialog.h" +#include "pub_utility_api/FileStyle.h" CAlarmForm::CAlarmForm(QWidget *parent) : QWidget(parent), m_ptrSysInfo(Q_NULLPTR), @@ -63,7 +64,7 @@ CAlarmForm::CAlarmForm(QWidget *parent) : ui->alarmView->setObjectName("alarmView"); ui->splitter->setStretchFactor(0,1); ui->splitter->setStretchFactor(1,6); - + initStyle(); QHBoxLayout * pHBoxLayout = new QHBoxLayout(ui->deviceView->header()); m_pSearchTextEdit = new QLineEdit(ui->deviceView->header()); m_pSearchTextEdit->setObjectName("searchTextEdit"); @@ -132,6 +133,24 @@ CAlarmForm::CAlarmForm(QWidget *parent) : m_thread->start(); } +void CAlarmForm::initStyle(){ + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("alarmForm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + +} + + CAlarmForm::~CAlarmForm() { if(m_communicator != Q_NULLPTR) @@ -207,7 +226,7 @@ void CAlarmForm::initialize() //< lingdaoyaoqiu { - QSettings columFlags("KBD_HMI", "alarm config"); + QSettings columFlags("IOT_HMI", "alarm config"); if(!columFlags.contains(QString("alarm/colum_0"))) { columFlags.setValue(QString("alarm/colum_0"), false); //< 时间 @@ -216,8 +235,8 @@ void CAlarmForm::initialize() columFlags.setValue(QString("alarm/colum_3"), true); //< 责任区 columFlags.setValue(QString("alarm/colum_4"), true); //< 告警类型 columFlags.setValue(QString("alarm/colum_5"), false); //< 告警状态 - columFlags.setValue(QString("alarm/colum_6"), false); //< 确认状态 - columFlags.setValue(QString("alarm/colum_7"), false); //< + columFlags.setValue(QString("alarm/colum_6"), true); //< 确认状态 + columFlags.setValue(QString("alarm/colum_7"), true); //< } } ui->comboBox->setModel(m_pListWidget1->model()); @@ -692,7 +711,8 @@ void CAlarmForm::setAlarmModel(CAlarmItemModel *model,CAiAlarmTreeModel *treeMod connect(ui->alarmView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pModel, SLOT(sortColumn(int,Qt::SortOrder))); connect(ui->aiAlarmTreeView->header(),&QHeaderView::sortIndicatorChanged, m_treeModel,&CAiAlarmTreeModel::sortColumn); - connect(ui->aiAlarmTreeView,&CAiAlarmTreeView::doubleClicked, this,&CAlarmForm::aiAlmDoubleClicked); + //先注释掉,想启用的话可以通过脚本绑定 + //connect(ui->aiAlarmTreeView,&CAiAlarmTreeView::doubleClicked, this,&CAlarmForm::aiAlmDoubleClicked); ui->confirm->setEnabled(true); ui->remove->setEnabled(true); //原始告警窗 @@ -703,7 +723,7 @@ void CAlarmForm::setAlarmModel(CAlarmItemModel *model,CAiAlarmTreeModel *treeMod ui->alarmView->setColumnWidth(5, 150); ui->alarmView->setColumnWidth(6, 120); - QSettings columFlags("KBD_HMI", "alarm config"); + QSettings columFlags("IOT_HMI", "alarm config"); for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount() - 1; nColumnIndex++) { bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); @@ -761,7 +781,7 @@ void CAlarmForm::setAlarmModel(CAlarmItemModel *model) ui->alarmView->setColumnWidth(6, 120); - QSettings columFlags("KBD_HMI", "alarm config"); + QSettings columFlags("IOT_HMI", "alarm config"); for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount() - 1; nColumnIndex++) { bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); @@ -774,6 +794,7 @@ void CAlarmForm::setAlarmModel(CAlarmItemModel *model) { connect(m_pDeviceModel, &CAlarmDeviceTreeModel::itemCheckStateChanged, this, &CAlarmForm::deviceGroupFilterChanged); connect(m_pDeviceModel, &CAlarmDeviceTreeModel::inhibitDevGroupAlm, this, &CAlarmForm::slotInhibitDevGroupAlm); + connect(CAlarmDataCollect::instance(),&CAlarmDataCollect::sigDevTreeUpdate,m_pDeviceModel,&CAlarmDeviceTreeModel::slotDevTreeUpdate); } initFilter(); } @@ -1337,7 +1358,7 @@ void CAlarmForm::contextMenuStack0Event(QContextMenuEvent *event) connect(action, &QAction::triggered, [=](){ ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags("KBD_HMI", "alarm config"); + QSettings columFlags("IOT_HMI", "alarm config"); columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); }); } @@ -1460,7 +1481,7 @@ void CAlarmForm::contextMenuStack1Event(QContextMenuEvent *event) connect(action, &QAction::triggered, [=](){ ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags("KBD_HMI", "alarm config"); + QSettings columFlags("IOT_HMI", "alarm config"); columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); }); } @@ -2902,7 +2923,6 @@ void CAlarmForm::inhibitAlm(const AlarmMsgPtr &alm) msg.setSubject(alm->sub_system, CH_HMI_TO_OPT_OPTCMD_DOWN); SOptTagSet sOptTagSet; SOptTagQueue optTagQueue; - COptTagSet cOptTagSet; if(createReqHead(sOptTagSet.stHead,alm)!= iotSuccess) { @@ -2911,8 +2931,7 @@ void CAlarmForm::inhibitAlm(const AlarmMsgPtr &alm) QString keyIdTag = alm->key_id_tag; if(keyIdTag.endsWith(".value")) { - //禁止告警和实时数据代码一致,要不实时数据 插件取消告警会失败; - // keyIdTag.replace(QString(".value"),QString(".status")); + keyIdTag.replace(QString(".value"),QString(".status")); }else { return ; @@ -2927,7 +2946,7 @@ void CAlarmForm::inhibitAlm(const AlarmMsgPtr &alm) optTagQueue.nSubSystem = alm->sub_system; sOptTagSet.vecTagQueue.push_back(optTagQueue); - std::string content = cOptTagSet.generate(sOptTagSet); + std::string content = COptTagSet::generate(sOptTagSet); msg.setMsgType(MT_OPT_PINHIBIT_ALARM); diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmForm.h b/product/src/gui/plugin/AlarmWidget/CAlarmForm.h index fc7ada51..363d3552 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmForm.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmForm.h @@ -49,7 +49,7 @@ public: void initialize(); void init(); - + void initStyle(); void setAlarmModel(CAlarmItemModel * model, CAiAlarmTreeModel *treeModel); void setAlarmModel(CAlarmItemModel * model); diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmForm.ui b/product/src/gui/plugin/AlarmWidget/CAlarmForm.ui index bbceb998..ffb64146 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmForm.ui +++ b/product/src/gui/plugin/AlarmWidget/CAlarmForm.ui @@ -40,25 +40,55 @@ 0 - + + + 9 + 0 - + 9 - + 0 - - + + 0 + + + 6 + + + + + + 0 + 0 + + + + + 0 + 40 + + + + + 16777215 + 16777215 + + QFrame::StyledPanel QFrame::Raised - + + + 6 + 0 @@ -66,414 +96,141 @@ 0 - 9 + 0 0 - - 0 - - - - - 6 + + + + 0 + + + 0 - + + + 当前显示数量: + + + + + - 100 + 55 0 - - - 100 - 26 - - - 禁止列表 + 0 - - - - 0 - 0 - + + + 过滤告警数量: + + + + - 45 + 55 0 - - - 45 - 26 - - - 过滤 - - - - - - - - 0 - 0 - - - - - 45 - 0 - - - - - 45 - 26 - - - - 导出 - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - Qt::RightToLeft - - - 优先级: - - - - - - - - 125 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - Qt::RightToLeft - - - 位置: - - - - - - - - 113 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - Qt::RightToLeft - - - 告警状态: - - - - - - - - 138 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 时间: - - - - - - - - 0 - 0 - - - - - 200 - 0 - - - - - 200 - 26 - - - - - - - - 0 - - - 2 - - - 3 - - - - - - 55 - 0 - - - - 0 - - - - - - - 过滤告警数量: - - - - - - - 当前显示数量: - - - - - - - - 55 - 0 - - - - 0 - - - - - - - - - - 80 - 26 - - - - - 16777215 - 26 - - - - 智能告警 - - - true - - - false - - - - - - - Qt::Horizontal - - - - 13 - 20 - - - - - - - - false - - - - 45 - 26 - - - - - - - 确认 - - - - - - - false - - - - 45 - 26 - - - - 删除 - - - - - - - - 45 - 26 - - - - 禁止告警 - - - - - - - - 45 - 26 - - - - 设置 - - - - - - - - 45 - 26 - - - - 关闭 + 0 + + + + true + + + + 80 + 26 + + + + + 1000 + 26 + + + + 智能告警 + + + false + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 800 + 20 + + + + + + + + true + + + + 0 + 0 + + + + + 60 + 26 + + + + 设置 + + + + + + + + 60 + 26 + + + + 关闭 + + + - + @@ -503,7 +260,7 @@ - 1 + 0 @@ -522,7 +279,7 @@ 0 - + @@ -578,6 +335,332 @@ + + + + 0 + + + 9 + + + 0 + + + 9 + + + + + + 100 + 0 + + + + + 100 + 26 + + + + 禁止列表 + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + Qt::RightToLeft + + + 优先级: + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + Qt::RightToLeft + + + 位置: + + + + + + + + 0 + 0 + + + + + 65 + 0 + + + + + 65 + 26 + + + + 过滤 + + + + + + + + 0 + 0 + + + + + 65 + 0 + + + + + 65 + 26 + + + + 导出 + + + + + + + false + + + + 65 + 26 + + + + 删除 + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + + 1000 + 26 + + + + + + + + + 0 + 0 + + + + + 150 + 26 + + + + + 1000 + 26 + + + + + + + + + 45 + 26 + + + + 禁止告警 + + + + + + + false + + + + 65 + 26 + + + + + + + 确认 + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 200 + 20 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 时间: + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + Qt::RightToLeft + + + 告警状态: + + + + + + + + 0 + 0 + + + + + 150 + 26 + + + + + + + + + 250 + 0 + + + + + 16777215 + 26 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 40 + 20 + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmItemModel.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmItemModel.cpp index 3c530299..18481f86 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmItemModel.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmItemModel.cpp @@ -8,7 +8,19 @@ #include "CAlarmMsgManage.h" #include "perm_mng_api/PermMngApi.h" #include + +//< 屏蔽xml_parser编译告警 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-copy" +#endif + #include "boost/property_tree/xml_parser.hpp" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "boost/typeof/typeof.hpp" #include "boost/filesystem.hpp" #include "Common.h" @@ -351,11 +363,11 @@ void CAlarmItemModel::sortColumn(int column, Qt::SortOrder order) { if(order == Qt::AscendingOrder) { - m_order = Qt::DescendingOrder; + m_order = Qt::AscendingOrder; } else { - m_order = Qt::AscendingOrder; + m_order = Qt::DescendingOrder; } m_sortKey = (E_ALARM_SORTKEY)column; beginResetModel(); diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.cpp index e0550f88..49196297 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.cpp @@ -16,11 +16,6 @@ #include "CAlarmSetMng.h" #include "service/alarm_server_api/AlarmCommonDef.h" #include "CAlarmMsgManage.h" -#include -#include -#include -#include -#include using namespace iot_public; CAlarmMediaPlayer * CAlarmMediaPlayer::m_pInstance = NULL; @@ -183,40 +178,6 @@ void CAlarmMediaPlayer::initSpeech() } } } - //添加语音转文本处理条件 - QFile file(iot_public::CFileUtil::getPathOfCfgFile("alarmSpeechTextTrans.xml" , CN_DIR_PRODUCT).c_str()); - if (!file.open(QFile::ReadWrite)) - { - LOGERROR("打开语音文本转换文件失败,默认不进行语音转换"); - return; - } - - QDomDocument doc; - if (!doc.setContent(&file)) - { - file.close(); - LOGERROR("打开语音文本转换文件失败,默认不进行语音转换"); - return; - } - file.close(); - - QDomElement root = doc.documentElement(); - if(root.isElement()) - { - QDomNodeList nodeList = root.childNodes(); - for(int i = 0 ; i < nodeList.count() ; i++) - { - QDomNode node = nodeList.at(i); - if(node.isElement()) - { - QDomElement element = node.toElement(); - if(element.tagName() == "Condition" && element.attribute("enable") == "true") - { - m_mapSpeechTxtTrans.insert(element.attribute("key"),element.attribute("value")); - } - } - } - } } @@ -263,17 +224,6 @@ void CAlarmMediaPlayer::insertAudioCuesStop(const AlarmMsgPtr &info) } } -void CAlarmMediaPlayer::speechTextTrans(QString &strContent) -{ -// strContent = "110KV回路503弹簧开关10A保护A线"; - //文本转换处理 - auto iter = m_mapSpeechTxtTrans.begin(); - for(;iter != m_mapSpeechTxtTrans.end() ; iter++) - { - strContent.replace(QRegExp(iter.key() , Qt::CaseInsensitive) , iter.value()); - } -} - void CAlarmMediaPlayer::setVolumeEnable(bool bEnable) { if(bEnable) @@ -467,8 +417,6 @@ void CAlarmMediaPlayer::updateAudioCuesSpeech() if(!alarmContent.isEmpty()) { - //读取配置文件,更改读取方式 - speechTextTrans(alarmContent); m_pTextToSpeech->say(alarmContent); } } diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.h b/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.h index 199bb0eb..84e9dce5 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmMediaPlayer.h @@ -53,8 +53,6 @@ private: void insertAudioCuesStop(const AlarmMsgPtr &info); - void speechTextTrans(QString &strContent);//读取配置文件,调整文本语音输出 - private slots: /** * @brief playerStateChanged 播放器状态变化 @@ -92,7 +90,6 @@ private: QString m_engine; QString m_language; QString m_voiceName; - QMap m_mapSpeechTxtTrans; bool m_readFlag; diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.cpp index 8149218f..a58ff0bc 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.cpp @@ -8,7 +8,18 @@ #include #include "perm_mng_api/PermMngApi.h" +//< 屏蔽xml_parser编译告警 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-copy" +#endif + #include "boost/property_tree/xml_parser.hpp" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "boost/typeof/typeof.hpp" #include "boost/filesystem.hpp" #include "Common.h" @@ -201,12 +212,18 @@ void CAlarmMsgManage::updataDevGroupByDev(QString devGroup, QString device) } } -QHash > > CAlarmMsgManage::getLocNotConfirmAlmInfo() +const QHash > > &CAlarmMsgManage::getLocNotConfirmAlmInfo() const { QMutexLocker locker(mutex); return m_alarmLNCAlm; } +const QHash > > &CAlarmMsgManage::getLocPriorityNotConfirmAlmInfo() const +{ + QMutexLocker locker(mutex); + return m_alarmLNCPAlm; +} + void CAlarmMsgManage::getAllInhibitAlm(QList &almList) { QMutexLocker locker(mutex); @@ -929,42 +946,80 @@ void CAlarmMsgManage::locSubStats(const AlarmMsgPtr &msg) } } -void CAlarmMsgManage::addNotConfirmAlm(int locId, const QString &devg, const QString &uuid) +void CAlarmMsgManage::addNotConfirmAlm(const AlarmMsgPtr &msg) { - QHash > >::iterator it =m_alarmLNCAlm.find(locId); + //< 按设备组 + QHash > >::iterator it =m_alarmLNCAlm.find(msg->location_id); if(it != m_alarmLNCAlm.end()) { QMap > &devgMap = it.value(); - QMap >::iterator pos = devgMap.find(devg); + QMap >::iterator pos = devgMap.find(msg->dev_group_tag); if(pos != devgMap.end()) { - pos.value().insert(uuid); + pos.value().insert(msg->uuid_base64); }else { QSet uuidSet; - uuidSet.insert(uuid); - devgMap[devg] = uuidSet; + uuidSet.insert(msg->uuid_base64); + devgMap[msg->dev_group_tag] = uuidSet; } }else { QMap > devgMap; QSet uuidSet; - uuidSet.insert(uuid); - devgMap[devg] = uuidSet; - m_alarmLNCAlm[locId] = devgMap; + uuidSet.insert(msg->uuid_base64); + devgMap[msg->dev_group_tag] = uuidSet; + m_alarmLNCAlm[msg->location_id] = devgMap; + } + + //< 按告警等级 + QHash > >::iterator pIt =m_alarmLNCPAlm.find(msg->location_id); + if(pIt != m_alarmLNCPAlm.end()) + { + QMap > &pMap = pIt.value(); + QMap >::iterator pos = pMap.find(msg->priority); + if(pos != pMap.end()) + { + pos.value().insert(msg->uuid_base64); + }else + { + QSet uuidSet; + uuidSet.insert(msg->uuid_base64); + pMap[msg->priority] = uuidSet; + } + }else + { + QMap > pMap; + QSet uuidSet; + uuidSet.insert(msg->uuid_base64); + pMap[msg->priority] = uuidSet; + m_alarmLNCPAlm[msg->location_id] = pMap; } } -void CAlarmMsgManage::delNotConfirmAlm(int locId, const QString &devg, const QString &uuid) +void CAlarmMsgManage::delNotConfirmAlm(const AlarmMsgPtr &msg) { - QHash > >::iterator it =m_alarmLNCAlm.find(locId); + //< 按设备组 + QHash > >::iterator it =m_alarmLNCAlm.find(msg->location_id); if(it != m_alarmLNCAlm.end()) { QMap > &devgMap = it.value(); - QMap >::iterator pos = devgMap.find(devg); + QMap >::iterator pos = devgMap.find(msg->dev_group_tag); if(pos != devgMap.end()) { - pos.value().remove(uuid); + pos.value().remove(msg->uuid_base64); + } + } + + //< 按告警等级 + QHash > >::iterator pIt =m_alarmLNCPAlm.find(msg->location_id); + if(pIt != m_alarmLNCPAlm.end()) + { + QMap > &pMap = pIt.value(); + QMap >::iterator pos = pMap.find(msg->priority); + if(pos != pMap.end()) + { + pos.value().remove(msg->uuid_base64); } } } @@ -1080,7 +1135,7 @@ void CAlarmMsgManage::initAlarm() if(E_ALS_ALARM == (*itpos)->logic_state || E_ALS_RETURN == (*itpos)->logic_state )//未确认数量(界面显示未确认) { - addNotConfirmAlm((*itpos)->location_id,(*itpos)->dev_group_tag,(*itpos)->uuid_base64); + addNotConfirmAlm(*itpos); ++m_nNDelComAlarmCount; } updateMsgAction((*itpos)); @@ -1314,7 +1369,7 @@ void CAlarmMsgManage::addAlarmMsg(const QList &msgList) } if(E_ALS_ALARM == (*itpos)->logic_state || E_ALS_RETURN == (*itpos)->logic_state )//未确认数量(界面显示未确认) { - addNotConfirmAlm((*itpos)->location_id,(*itpos)->dev_group_tag,(*itpos)->uuid_base64); + addNotConfirmAlm(*itpos); ++m_nNDelComAlarmCount; } updateMsgAction(*itpos); @@ -1390,7 +1445,7 @@ void CAlarmMsgManage::confirmAlarmMsg(const QList &uuidList) oldMsg->logic_state = E_ALS_RETURN_CFM; --m_nNDelComAlarmCount; } - delNotConfirmAlm(oldMsg->location_id,oldMsg->dev_group_tag,oldMsg->uuid_base64); + delNotConfirmAlm(oldMsg); }else { AlarmMsgPtr oldMsg_ = m_all.value(uuid, NULL); @@ -1447,7 +1502,7 @@ int CAlarmMsgManage::removeAlarmMsg(const QList &uuidList) } if(E_ALS_ALARM == oldMsg->logic_state) { - delNotConfirmAlm(oldMsg->location_id,oldMsg->dev_group_tag,oldMsg->uuid_base64); + delNotConfirmAlm(oldMsg); --m_nNDelComAlarmCount; oldMsg->logic_state = E_ALS_ALARM_DEL; } @@ -1457,7 +1512,7 @@ int CAlarmMsgManage::removeAlarmMsg(const QList &uuidList) } else if(E_ALS_RETURN == oldMsg->logic_state) { - delNotConfirmAlm(oldMsg->location_id,oldMsg->dev_group_tag,oldMsg->uuid_base64); + delNotConfirmAlm(oldMsg); --m_nNDelComAlarmCount; oldMsg->logic_state = E_ALS_RETURN_DEL; } @@ -1574,7 +1629,7 @@ void CAlarmMsgManage::removeAlarmMsgByDomainID(const int &domainId) { if(E_ALS_ALARM == (*it)->logic_state || E_ALS_RETURN == (*it)->logic_state) { - delNotConfirmAlm((*it)->location_id,(*it)->dev_group_tag,(*it)->uuid_base64); + delNotConfirmAlm(*it); --m_nNDelComAlarmCount; } removeAudioCues(it.value()); @@ -1788,7 +1843,7 @@ void CAlarmMsgManage::msgArrived() if(E_ALS_ALARM == m_listMsgAddCache.at(num)->logic_state || E_ALS_RETURN == m_listMsgAddCache.at(num)->logic_state )//未删除未确认数量(界面显示未确认) { - addNotConfirmAlm(m_listMsgAddCache.at(num)->location_id,m_listMsgAddCache.at(num)->dev_group_tag,m_listMsgAddCache.at(num)->uuid_base64); + addNotConfirmAlm(m_listMsgAddCache.at(num)); ++m_nNDelComAlarmCount; } updateMsgAction(m_listMsgAddCache.at(num)); diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.h b/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.h index 8891cf22..16e198ed 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmMsgManage.h @@ -79,7 +79,8 @@ public: QHash > getLocAlmInfo(); void updataDevGroupByDev(QString devGroup, QString device); - QHash > > getLocNotConfirmAlmInfo(); + const QHash > > &getLocNotConfirmAlmInfo() const; + const QHash > > &getLocPriorityNotConfirmAlmInfo() const; void getAllInhibitAlm(QList &almList); signals: @@ -267,18 +268,14 @@ private: void locSubStats(const AlarmMsgPtr &msg); /** * @brief addNotConfirmAlm 添加未确认的告警uuid - * @param locId - * @param devg - * @param uuid + * @param msg */ - void addNotConfirmAlm(int locId,const QString &devg,const QString &uuid); + void addNotConfirmAlm(const AlarmMsgPtr &msg); /** * @brief delNotConfirmAlm 从未确认的告警uuid集合中删除(删除的不一定被确认 可能是数据重发) - * @param locId - * @param devg - * @param uuid + * @param msg */ - void delNotConfirmAlm(int locId,const QString &devg,const QString &uuid); + void delNotConfirmAlm(const AlarmMsgPtr &msg); signals: /** * @brief sigAiMsgRemove 通知智能告警模型删除智能告警 @@ -406,6 +403,7 @@ private: QHash > m_alarmLPAlm; //< <车站id,<告警等级,告警数量> > QHash > > m_alarmLNCAlm;//< <车站id,<设备组,<未确认告警uuid> > > + QHash > > m_alarmLNCPAlm;//< <车站id,<告警等级,<未确认告警uuid> > > QList m_delaydeal; //延迟处理的智能告警 diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.cpp b/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.cpp index 07113962..ec6cf4cd 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.cpp +++ b/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.cpp @@ -693,13 +693,13 @@ int CAlarmPlugin::getLocNotConfirmAlmCount(int loc) { return count; } - QHash > > locCountMap = CAlarmMsgManage::instance()->getLocNotConfirmAlmInfo(); + const QHash > > &locCountMap = CAlarmMsgManage::instance()->getLocNotConfirmAlmInfo(); - QHash > >::iterator it = locCountMap.find(loc); + QHash > >::const_iterator it = locCountMap.find(loc); if(it !=locCountMap.end()) { QMap > devgCountMap = it.value(); - QMap >::iterator pos = devgCountMap.begin(); + QMap >::const_iterator pos = devgCountMap.begin(); while (pos != devgCountMap.end()) { count += pos.value().count(); @@ -710,6 +710,28 @@ int CAlarmPlugin::getLocNotConfirmAlmCount(int loc) return count; } +QStringList CAlarmPlugin::getLocNotConfirmAlmInfo(int loc) +{ + QStringList result; + result.clear(); + if(loc < 0){ + return result; + } + const QHash > > &locCountMap = CAlarmMsgManage::instance()->getLocPriorityNotConfirmAlmInfo(); + QHash > >::const_iterator it = locCountMap.find(loc); + if(it != locCountMap.end()) + { + const QMap > &pMap = it.value(); + QMap >::const_iterator pos = pMap.constBegin(); + while (pos != pMap.constEnd()) + { + result.append( QString("%1_%2").arg(pos.key()).arg(pos.value().count()) ); + pos++; + } + } + return result; +} + int CAlarmPlugin::getDevgNotConfirmAlmCount(const QString &devg) { int count =0; @@ -717,13 +739,13 @@ int CAlarmPlugin::getDevgNotConfirmAlmCount(const QString &devg) { return count; } - QHash > > locCountMap = CAlarmMsgManage::instance()->getLocNotConfirmAlmInfo(); + const QHash > > &locCountMap = CAlarmMsgManage::instance()->getLocNotConfirmAlmInfo(); - QHash > >::iterator it = locCountMap.begin(); + QHash > >::const_iterator it = locCountMap.begin(); while (it !=locCountMap.end()) { QMap > devgCountMap = it.value(); - QMap >::iterator pos = devgCountMap.find(devg); + QMap >::const_iterator pos = devgCountMap.find(devg); if(pos != devgCountMap.end()) { count = pos.value().count(); @@ -903,6 +925,18 @@ void CAlarmPlugin::setDeviceGroup(const QString &deviceGroup) } + +void CAlarmPlugin::setPriorityFilter(int PriorityFilter) +{ + bool isCheck = true; + QList priorityList; + priorityList.append(PriorityFilter); + if(m_pModel) + { + m_pModel->setPriorityFilter(isCheck,priorityList); + } +} + void CAlarmPlugin::setPointTag(const QString &pointList) { if(m_bIsEditMode || E_Alarm_Pop != m_mode) diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.h b/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.h index 5b0ed371..caa54371 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmPlugin.h @@ -102,6 +102,12 @@ public slots: * @return 未确认告警条数 */ int getLocNotConfirmAlmCount(int loc); + /** + * @brief getLocNotConfirmAlmInfo 获取车站未确认告警数量(优先级分组) + * @param loc 位置id + * @return QString 格式为: 告警等级_告警数量 ex:1_23 含义为 告警等级为1的告警数量为23 + */ + QStringList getLocNotConfirmAlmInfo(int loc); /** * @brief getDevgNotConfirmAlmCount 获取设备组的未确认告警条数 * @param devg 设备组 @@ -207,11 +213,20 @@ public slots: * @param device 设备 */ void setDevice(const QString &device); + + /** * @brief setDeviceGroup 设置设备组显示 * @param deviceGroup 设备组 */ void setDeviceGroup(const QString &deviceGroup); + + /** + * @brief setPriorityFilter 设置优先级 + * @param deviceGroup 优先级 + */ + void setPriorityFilter(int PriorityFilter); + /** * @brief setPointTag 设置点过滤(已无效,保留只为兼容) * @param pointList 点集合 diff --git a/product/src/gui/plugin/AlarmWidget/CAlarmPluginWidget.h b/product/src/gui/plugin/AlarmWidget/CAlarmPluginWidget.h index d5c028c8..95196608 100644 --- a/product/src/gui/plugin/AlarmWidget/CAlarmPluginWidget.h +++ b/product/src/gui/plugin/AlarmWidget/CAlarmPluginWidget.h @@ -7,7 +7,7 @@ class CAlarmPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/AlarmWidget/main.cpp b/product/src/gui/plugin/AlarmWidget/main.cpp index 69546a1d..10043517 100644 --- a/product/src/gui/plugin/AlarmWidget/main.cpp +++ b/product/src/gui/plugin/AlarmWidget/main.cpp @@ -12,7 +12,7 @@ int main(int argc, char *argv[]) //<初始化消息总线 QStringList arguments=QCoreApplication::arguments(); std::string name="admin"; - std::string password ="kbdct"; + std::string password ="admin"; int group =1; for(int index(0);index +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CAccidentReviewDialog::CAccidentReviewDialog(const QString &path, QWidget *parent) + : QDialog(parent) +{ + resize(350,450); + getFilterNames(path); + initView(); + initTree(); +} + +CAccidentReviewDialog::~CAccidentReviewDialog() +{ + +} + +QString CAccidentReviewDialog::getCurrentGraph() +{ + if(m_treeWidget->currentItem()) + { + return m_treeWidget->currentItem()->data(0, Qt::UserRole).toString(); + } + return QString(); +} + +void CAccidentReviewDialog::initView() +{ + setWindowTitle(tr("事故追忆")); + m_treeWidget = new QTreeWidget(this); + m_treeWidget->headerItem()->setHidden(true); + + QSpacerItem * spacer = new QSpacerItem(10, 0, QSizePolicy::Preferred); + m_confirmBtn = new QPushButton(tr("确认"), this); + m_cancelBtn = new QPushButton(tr("取消"), this); + connect(m_confirmBtn, &QPushButton::clicked, this, &CAccidentReviewDialog::slotConfirm); + connect(m_cancelBtn, &QPushButton::clicked, this, &CAccidentReviewDialog::slotCancel); + + QGridLayout * layout = new QGridLayout(); + layout->addWidget(m_treeWidget, 0, 0, 1, 3); + layout->addItem(spacer, 1, 0); + layout->addWidget(m_confirmBtn, 1, 1); + layout->addWidget(m_cancelBtn, 1, 2); + setLayout(layout); +} + +void CAccidentReviewDialog::initTree() +{ + QMap>> m_mapNav; + readNavJson(QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + + QString("../../data/model/NavigationWidget.json"), m_mapNav); + QList> nodeList = m_mapNav.value(-1); + for(int nIndex=0; nIndexaddTopLevelItem(item); + + addChildLevelItem(item, nodeList[nIndex], m_mapNav); + } + treeFilter(); + m_treeWidget->expandAll(); +} + +void CAccidentReviewDialog::getFilterNames(const QString &path) +{ + QString filePath = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + + QString("../../data/pic/"); + m_fileNameList = getAllFile(filePath, filePath, path); +} + +QStringList CAccidentReviewDialog::getAllFile(const QString &path, const QString &relativePath, const QString &filter) +{ + QDir dir(path); + QDir relativeDir(relativePath); + QStringList allFile; + + QString fileName; + QFileInfoList fileList = dir.entryInfoList(QDir::Files | QDir::NoSymLinks); + for(QFileInfo &file : fileList) + { + fileName = relativeDir.relativeFilePath(file.filePath()); + if(fileName.contains(filter)) + { + allFile.append(fileName); + } + } + + QFileInfoList folderList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + for(QFileInfo &folder : folderList) + { + allFile.append(getAllFile(folder.absoluteFilePath(), relativePath, filter)); + } + + return allFile; +} + +void CAccidentReviewDialog::treeFilter() +{ + bool topShow,childShow,leafShow; + int nTopCount = m_treeWidget->topLevelItemCount(); + for(int nTopIndex(0); nTopIndextopLevelItem(nTopIndex); + topShow = m_fileNameList.contains(topItem->data(0, Qt::UserRole).toString()); + + int nChildCount = topItem->childCount(); + for(int nChildIndex(0); nChildIndexchild(nChildIndex); + childShow = m_fileNameList.contains(childItem->data(0, Qt::UserRole).toString()); + + int nLeafCount = childItem->childCount(); + for(int nLeafIndex(0); nLeafIndexchild(nLeafIndex); + leafShow = m_fileNameList.contains(leafItem->data(0, Qt::UserRole).toString()); + leafItem->setHidden(!leafShow); + if(leafShow) + { + childShow = true; + } + } + childItem->setHidden(!childShow); + if(childShow) + { + topShow = true; + } + } + topItem->setHidden(!topShow); + } +} + +void CAccidentReviewDialog::slotConfirm() +{ + if(m_treeWidget->currentItem() == NULL) + { + QMessageBox::information(this, tr("提示"), tr("请选择一张画面!"), QMessageBox::Ok); + return; + } + QString data = m_treeWidget->currentItem()->data(0, Qt::UserRole).toString(); + if(data.isEmpty() || !m_fileNameList.contains(data)) + { + QMessageBox::information(this, tr("提示"), tr("请选择其他画面!"), QMessageBox::Ok); + return; + } + accept(); +} + +void CAccidentReviewDialog::slotCancel() +{ + reject(); +} + +void CAccidentReviewDialog::addChildLevelItem(QTreeWidgetItem *item, const QPair &node, + const QMap > > &navMap) +{ + const QList > childList = navMap.value(node.first); + for(int nIndex=0; nIndexaddChild(childItem); + + addChildLevelItem(childItem, childList[nIndex], navMap); + } +} + +QTreeWidgetItem *CAccidentReviewDialog::getAddLevelItem(const ST_NODE &st_node) +{ + if(st_node.used == Disable) + { + return NULL; + } + + QTreeWidgetItem * childItem = new QTreeWidgetItem(); + childItem->setData(0, Qt::DisplayRole, st_node.name); + childItem->setData(0, Qt::UserRole, st_node.data); + return childItem; +} + +void CAccidentReviewDialog::readNavJson(const QString &path, QMap > > &map) +{ + QFile file(path); + QByteArray readJson; + if(file.open(QIODevice::ReadOnly)) + { + readJson = file.readAll(); + file.close(); + } + QJsonParseError readError; + QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); + if(readError.error != QJsonParseError::NoError) + { + LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); + return; + } + QJsonObject root = readJsonResponse.object(); + if(root.contains("items")) + { + QJsonArray itemArray = root.value("items").toArray(); + int nItemNumber = 0; + for(int nIndex(0); nIndex< itemArray.size(); nIndex++) + { + ST_NODE st_Node_Top; + QJsonObject topLevelObject = itemArray[nIndex].toObject(); + makeStButton(st_Node_Top, topLevelObject); + QPair topMap; + int nTopNumber = nItemNumber; + topMap.first = nItemNumber++; + topMap.second = st_Node_Top; + + QJsonArray childArray = topLevelObject.value("items").toArray(); + for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) + { + ST_NODE st_Node_Child; + QJsonObject childLevelObject = childArray[nChildIndex].toObject(); + makeStButton(st_Node_Child, childLevelObject); + QPair childMap; + int nChildNumber = nItemNumber; + childMap.first = nItemNumber++; + childMap.second = st_Node_Child; + + QJsonArray leafArray = childLevelObject.value("items").toArray(); + for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) + { + ST_NODE st_Node_Leaf; + QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); + makeStButton(st_Node_Leaf, leafLevelObject); + QPair leafMap; + leafMap.first = nItemNumber++; + leafMap.second = st_Node_Leaf; + map[nChildNumber].append(leafMap); + } + map[nTopNumber].append(childMap); + } + map[-1].append(topMap); + } + } +} + +void CAccidentReviewDialog::makeStButton(ST_NODE &st_Node, const QJsonObject &object) +{ + if(!object.value("name").isUndefined()) + { + st_Node.name = object.value("name").toString(); + } + if(!object.value("icon").isUndefined()) + { + st_Node.icon = object.value("icon").toString(); + } + if(!object.value("data").isUndefined()) + { + st_Node.data = object.value("data").toString(); + } + if(!object.value("opt").isUndefined()) + { + st_Node.type = object.value("opt").toInt(); + } + if(!object.value("used").isUndefined()) + { + st_Node.used = object.value("used").toInt(); + } + if(!object.value("web").isUndefined()) + { + st_Node.web = object.value("web").toInt(); + } + if(!object.value("webData").isUndefined()) + { + st_Node.webData = object.value("webData").toString(); + } +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAccidentReviewDialog.h b/product/src/gui/plugin/AlarmWidget_pad/CAccidentReviewDialog.h new file mode 100644 index 00000000..6d475f81 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAccidentReviewDialog.h @@ -0,0 +1,56 @@ +#ifndef CACCIDENTREVIEWDIALOG_H +#define CACCIDENTREVIEWDIALOG_H + +#include +#include +#include + +struct ST_NODE +{ + QString name; + int used; + int type; + QString icon; + int web; + QString data; + QString webData; +}; + +class QTreeWidget; +class QTreeWidgetItem; +class CAccidentReviewDialog : public QDialog +{ + Q_OBJECT +public: + enum Node_Enable{Enable = 1,Disable = 2}; + CAccidentReviewDialog(const QString &path, QWidget *parent = Q_NULLPTR); + ~CAccidentReviewDialog(); + + QString getCurrentGraph(); + +private slots: + void slotConfirm(); + void slotCancel(); + +private: + void initView(); + void initTree(); + void getFilterNames(const QString &path); + QStringList getAllFile(const QString &path, const QString &relativePath, + const QString &filter); + void treeFilter(); + + void addChildLevelItem(QTreeWidgetItem *item, const QPair &node, + const QMap > > &navMap); + QTreeWidgetItem* getAddLevelItem(const ST_NODE& st_node); + void readNavJson(const QString &path, QMap>>& map); + void makeStButton(ST_NODE &st_Node, const QJsonObject &object); + +private: + QTreeWidget * m_treeWidget; + QPushButton * m_confirmBtn; + QPushButton * m_cancelBtn; + QStringList m_fileNameList; +}; + +#endif // CACCIDENTREVIEWDIALOG_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmDataCollect.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmDataCollect.cpp new file mode 100644 index 00000000..8de3f444 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmDataCollect.cpp @@ -0,0 +1,239 @@ +#include "CAiAlarmDataCollect.h" +#include "pub_logger_api/logger.h" +#include "CAlarmMsgManage.h" +#include +#include "CAlarmDataCollect.h" +using namespace iot_service; +CAiAlarmDataCollect * CAiAlarmDataCollect::m_pInstance = NULL; +CAiAlarmDataCollect::CAiAlarmDataCollect() + : CIntelliAlmApi4Clt(), + m_referenceCount(0), + m_bFaultRecallState(false), + m_pAlternateTimer(Q_NULLPTR) +{ + m_rtdbMutex = new QMutex(); + m_rtdbPriorityOrderAccess = new iot_dbms::CRdbAccess(); + m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); +} + +CAiAlarmDataCollect::~CAiAlarmDataCollect() +{ + LOGDEBUG("CAiAlarmDataCollect::~CAiAlarmDataCollect()"); + qDebug() << "~CAiAlarmDataCollect()"; +} + +void CAiAlarmDataCollect::refrence() +{ + m_referenceCount++; +} + +int CAiAlarmDataCollect::getRefrenceCount() +{ + return m_referenceCount; +} + +CAiAlarmDataCollect *CAiAlarmDataCollect::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CAiAlarmDataCollect(); + } + return m_pInstance; +} + +void CAiAlarmDataCollect::initialize() +{ + resumeThread(); + if(!m_pAlternateTimer) + { + m_pAlternateTimer = new QTimer(); + m_pAlternateTimer->setInterval(1000); + connect(m_pAlternateTimer, &QTimer::timeout, this, &CAiAlarmDataCollect::slotAiAlarmStateChanged); + connect(this, &CAiAlarmDataCollect::sigTimerShot, this, &CAiAlarmDataCollect::slotTimerShot, Qt::QueuedConnection); + } + if(!m_bFaultRecallState) + { + emit sigTimerShot(true); + } +} + +void CAiAlarmDataCollect::release() +{ + emit sigTimerShot(false); + suspendThread(true); +} + +bool CAiAlarmDataCollect::isFaultRecallState() +{ + return m_bFaultRecallState; +} + +bool CAiAlarmDataCollect::requestDelAlm(iot_idl::SIntelliAlmDel &objDelAlm) +{ + LOGDEBUG("请求删除!"); + return iot_service::CIntelliAlmApi4Clt::requestDelAlm(objDelAlm); +} + +bool CAiAlarmDataCollect::requestSeprAlm(iot_idl::SIntelliAlmSepr &objSeprAlm) +{ + LOGDEBUG("请求分离!"); + return iot_service::CIntelliAlmApi4Clt::requestSeprAlm(objSeprAlm); +} + +bool CAiAlarmDataCollect::requestMergeAlm(iot_idl::SIntelliAlmMerge &objMergeAlm) +{ + LOGDEBUG("请求合并!"); + return iot_service::CIntelliAlmApi4Clt::requestMergeAlm(objMergeAlm); +} + +void CAiAlarmDataCollect::handleAllAlmMsg(int nDomainId, iot_idl::SIntelliAlmAdd &objAllAlm) +{ + LOGINFO("========== AiAlarmDataCollect handleAllAlmMsg =========="); + + //< 清空该域缓存 + QMutexLocker locker(m_rtdbMutex); + CAlarmMsgManage::instance()->removeAiAlarmMsgByDomainID(nDomainId); + //构建告警 + int nAlarmCount = objAllAlm.alm_info_size(); + QList almList; + for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) + { + iot_idl::SIntelliAlmInfo msg = objAllAlm.alm_info(nAddMsgIndex); + AiAlarmMsgPtr alm(new CAiAlarmMsgInfo()); + alm->initialize(msg); + alm->priorityOrder = queryPriorityOrder(alm->priority); + almList.append(alm); + } + CAlarmMsgManage::instance()->addAiAllAlarmMsg(almList);//添加全部完成后,通知model重新拉取数据 + LOGDEBUG("AiAlarmDataCollect handleAllAlmMsg():count[%d]",nAlarmCount); + emit sigMsgRefresh(); +} + +void CAiAlarmDataCollect::handleAddAlmMsg(iot_idl::SIntelliAlmAdd &objAddAlm) +{ + LOGINFO("========== AiAlarmDataCollect handleAddAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + //构建告警 + int nAlarmCount = objAddAlm.alm_info_size(); + QList almList; + for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) + { + iot_idl::SIntelliAlmInfo msg = objAddAlm.alm_info(nAddMsgIndex); + AiAlarmMsgPtr alm(new CAiAlarmMsgInfo()); + alm->initialize(msg); + alm->priorityOrder = queryPriorityOrder(alm->priority); + almList.append(alm); + } + CAlarmMsgManage::instance()->addAiAlarmMsg(almList); //单独添加的时候,来一条通知一次model添加 + LOGDEBUG("AiAlarmDataCollect handleAddAlmMsg():count[%d]",nAlarmCount); +} + +void CAiAlarmDataCollect::handleDelAlmMsg(iot_idl::SIntelliAlmDel &objDelAlm) +{ + LOGINFO("========== AiAlarmDataCollect handleDelAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + //构建告警 + int nAlarmCount = objDelAlm.uuid_base64_size(); + QList uuidList; + for(int nDelMsgIndex(0); nDelMsgIndex < nAlarmCount; nDelMsgIndex++) + { + QString uuid = QString::fromStdString(objDelAlm.uuid_base64(nDelMsgIndex)); + uuidList.append(uuid); + } + CAlarmMsgManage::instance()->delAiAlarmMsg(uuidList); + LOGDEBUG("AiAlarmDataCollect handleDelAlmMsg():count[%d]",nAlarmCount); +} + +void CAiAlarmDataCollect::handleBrokenAlmMsg(iot_idl::SIntelliAlmBroken &objBrokenAlm) +{ + //先保证能够编译通过 + LOGINFO("========== AiAlarmDataCollect handleBrokenAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + int nAlarmCount = objBrokenAlm.uuid_base64_size(); + QList uuidList; + for(int nBrokenMsgIndex(0); nBrokenMsgIndex < nAlarmCount; nBrokenMsgIndex++) + { + QString uuid = QString::fromStdString(objBrokenAlm.uuid_base64(nBrokenMsgIndex)); + uuidList.append(uuid); + } + CAlarmMsgManage::instance()->brokenAiAlarmMsg(uuidList); + LOGDEBUG("AiAlarmDataCollect handleBrokenAlmMsg():count[%d]",nAlarmCount); +} + +void CAiAlarmDataCollect::handleReleaseAlmMsg(iot_idl::SIntelliAlmRelease &objReleaseAlm) +{ + //先保证能够编译通过 + LOGINFO("========== AiAlarmDataCollect handleReleaseAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + int nAlarmCount = objReleaseAlm.uuid_base64_size(); + QList uuidList; + for(int nReleaseMsgIndex(0); nReleaseMsgIndex < nAlarmCount; nReleaseMsgIndex++) + { + QString uuid = QString::fromStdString(objReleaseAlm.uuid_base64(nReleaseMsgIndex)); + uuidList.append(uuid); + } + CAlarmMsgManage::instance()->releaseAiAlarmMsg(uuidList); + LOGDEBUG("AiAlarmDataCollect handleReleaseAlmMsg():count[%d]",nAlarmCount); +} + +void CAiAlarmDataCollect::destory() +{ + LOGINFO("退出时:CAiAlarmDataCollect::destory()打开窗口的个数m_referenceCount:[%d]",m_referenceCount); + if(--m_referenceCount > 0) + { + return; + } + slotTimerShot(false); + suspendThread(); + { + QMutexLocker locker(m_rtdbMutex); + if(Q_NULLPTR != m_pAlternateTimer) + { + m_pAlternateTimer->stop(); + m_pAlternateTimer->deleteLater(); + } + m_pAlternateTimer = Q_NULLPTR; + } + delete m_rtdbMutex; + delete m_rtdbPriorityOrderAccess; + m_pInstance = NULL; + delete this; +} + +void CAiAlarmDataCollect::slotTimerShot(const bool start) +{ + if(m_pAlternateTimer) + { + if(start) + { + m_pAlternateTimer->start(); + } + else + { + m_pAlternateTimer->stop(); + } + } +} + +void CAiAlarmDataCollect::slotSwitchFaultRecallState(bool bFaultRecallState) +{ + m_bFaultRecallState = bFaultRecallState; + release(); + m_pInstance->reinit(m_bFaultRecallState); + CAlarmMsgManage::instance()->release(); + //initialize(); +} + +int CAiAlarmDataCollect::queryPriorityOrder(int &id) +{ + iot_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); + iot_dbms::CVarType value = -1000; + m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); + return value.toInt(); +} + +void CAiAlarmDataCollect::slotAiAlarmStateChanged() +{ + QMutexLocker locker(m_rtdbMutex); + CAlarmMsgManage::instance()->dealDelayAi(); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmDataCollect.h b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmDataCollect.h new file mode 100644 index 00000000..ab56bf83 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmDataCollect.h @@ -0,0 +1,84 @@ +#ifndef CAIALARMDATACOLLECT_H +#define CAIALARMDATACOLLECT_H + +#include +#include +#include +#include +#include +#include "IntelliAlmMsg.pb.h" +#include "CAiAlarmMsgInfo.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dbms/rdb_api/CRdbAccess.h" + +class CAiAlarmDataCollect : public QObject, public iot_service::CIntelliAlmApi4Clt +{ + Q_OBJECT +public: + static CAiAlarmDataCollect *instance(); + + virtual ~CAiAlarmDataCollect(); + + void refrence(); + + int getRefrenceCount(); + + bool isFaultRecallState(); + + virtual bool requestDelAlm(iot_idl::SIntelliAlmDel &objDelAlm); + + virtual bool requestSeprAlm(iot_idl::SIntelliAlmSepr &objSeprAlm); + + virtual bool requestMergeAlm(iot_idl::SIntelliAlmMerge &objMergeAlm); + + virtual void handleAllAlmMsg(int nDomainId,iot_idl::SIntelliAlmAdd &objAllAlm); + + virtual void handleAddAlmMsg(iot_idl::SIntelliAlmAdd &objAddAlm); + + virtual void handleDelAlmMsg(iot_idl::SIntelliAlmDel &objDelAlm); + + virtual void handleBrokenAlmMsg(iot_idl::SIntelliAlmBroken &objBrokenAlm); + + virtual void handleReleaseAlmMsg(iot_idl::SIntelliAlmRelease &objReleaseAlm); +signals: + //< 启停定时器 + void sigTimerShot(const bool bStop); + + //< 定时更新,通知model刷新界面 + void sigUpdateAlarmView(); + + //< 通知所有告警插件禁用/使能告警操作 + void sigAlarmOperateEnable(const bool &bEnable); + + //< 通知model重新拉取告警消息 + void sigMsgRefresh(); + + +public slots: + + void initialize(); + + void release(); + + void destory(); + + void slotTimerShot(const bool start); + + void slotSwitchFaultRecallState(bool bFaultRecallState); + +private: + CAiAlarmDataCollect(); + + int queryPriorityOrder(int &id); +private slots: + void slotAiAlarmStateChanged(); +private: + int m_referenceCount; + bool m_bFaultRecallState; + QMutex *m_rtdbMutex; + QTimer * m_pAlternateTimer; + iot_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; + static CAiAlarmDataCollect * m_pInstance; +}; + +#endif // CAIALARMDATACOLLECT_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmDelegate.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmDelegate.cpp new file mode 100644 index 00000000..1d02cb41 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmDelegate.cpp @@ -0,0 +1,408 @@ +#include "CAiAlarmDelegate.h" +#include +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" +#include "pub_logger_api/logger.h" +#include +#include +#include +#include +#include + +CAiAlarmDelegate::CAiAlarmDelegate(CAiAlarmTreeModel *model, QObject *parent) + : QStyledItemDelegate(parent), + m_pModel(model), + m_enableTrend(true), + m_enableLevel(false), + m_enableVideo(true), + m_enableWave(true), + m_selectIsEmpty(false) +{ + slotLoadConfig(); +} + +void CAiAlarmDelegate::setEnableTrend(bool isNeed) +{ + m_enableTrend = isNeed; +} + +void CAiAlarmDelegate::setEnableLevel(bool isNeed) +{ + m_enableLevel = isNeed; +} + +void CAiAlarmDelegate::setEnableVideo(bool isNeed) +{ + m_enableVideo = isNeed; +} + +void CAiAlarmDelegate::setEnableWave(bool isNeed) +{ + m_enableWave = isNeed; +} + +void CAiAlarmDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if(!index.isValid()) + { + return; + } + CAiAlarmTreeItem *item = m_pModel->getItem(index); + + bool select = option.state & QStyle::State_Selected; + QColor fillColor; + QColor penColor; + if(item->isAi()) + { + AiAlarmMsgPtr aiptr = NULL; + if(item->getAiPtr(aiptr) && aiptr != NULL) + { + painter->save(); + + if(CAlarmMsgManage::instance()->ifhaveNotConfirmAlmByuuid(aiptr->uuid_base64)) //包含的原始告警没有全部被确认 + { + if(select) + { + fillColor = m_select_background_color; + if(m_selectIsEmpty) + { + penColor = m_colorMap.value(aiptr->priorityOrder).active_text_color; + }else + { + penColor = m_select_text_color; + } + + } + else + { + if(aiptr->main_state == E_ALS_RETURN || aiptr->main_state == E_ALS_RETURN_CFM + || aiptr->main_state == E_ALS_RETURN_DEL || aiptr->main_state == E_ALS_RETURN_CFM_DEL) + { + penColor = m_colorMap.value(aiptr->priorityOrder).resume_text_color; + }else + { + penColor = m_colorMap.value(aiptr->priorityOrder).active_text_color; + } + + fillColor = m_colorMap.value(aiptr->priorityOrder).background_color; + } + }else //此条智能告警可以删除(置灰) + { + if(select) + { + fillColor = m_select_background_color; + } + else + { + fillColor = m_colorMap.value(aiptr->priorityOrder).confirm_color; + } + penColor = m_colorMap.value(aiptr->priorityOrder).confirm_text_color; + } + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + if(m_enableVideo && BUTTON_COLUMN == index.column() && aiptr->m_needVideoAlm) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strVideoPath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + if(m_enableLevel && ICON_COLUMN == index.column()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(12, option.rect.height()/2-10, -(option.rect.width()-40), -(option.rect.height()/2-10)); + QString file = m_colorMap.value(aiptr->priorityOrder).icon; + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(file); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + if( m_enableTrend && BUTTON_COLUMN == index.column() && (aiptr->m_tagname_type == E_TAGNAME_ANA || aiptr->m_tagname_type == E_TAGNAME_ACC)) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40 -40, option.rect.height()/2-10, -12-40, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strTrendPath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); + painter->restore(); + }else + { + return ; + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) && ptr != NULL) + { + painter->save(); + if(ptr->logic_state == E_ALS_RETURN || ptr->logic_state == E_ALS_RETURN_DEL)//返回未确认 + { + if(select) + { + fillColor = m_select_background_color; + if(m_selectIsEmpty) + { + penColor = m_colorMap.value(ptr->priorityOrder).resume_text_color; + }else + { + penColor = m_select_text_color; + } + } + else + { + penColor = m_colorMap.value(ptr->priorityOrder).resume_text_color; + fillColor = m_colorMap.value(ptr->priorityOrder).background_color; + } + }else if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_ALARM_DEL)//告警未确认 + { + if(select) + { + fillColor = m_select_background_color; + if(m_selectIsEmpty) + { + penColor = m_colorMap.value(ptr->priorityOrder).active_text_color; + }else + { + penColor = m_select_text_color; + } + } + else + { + penColor = m_colorMap.value(ptr->priorityOrder).active_text_color; + fillColor = m_colorMap.value(ptr->priorityOrder).background_color; + } + }else + { + if(select) + { + fillColor = m_select_background_color; + } + else + { + fillColor = m_colorMap.value(ptr->priorityOrder).confirm_color; + } + penColor = m_colorMap.value(ptr->priorityOrder).confirm_text_color; + } + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + + if(m_enableVideo && BUTTON_COLUMN == index.column() && ptr->m_needVideoAlm) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strVideoPath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + if(m_enableLevel && ICON_COLUMN == index.column()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(12, option.rect.height()/2-10, -(option.rect.width()-40), -(option.rect.height()/2-10)); + QString file = m_colorMap.value(ptr->priorityOrder).icon; + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(file); + button.features = QStyleOptionButton::Flat; + + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + if( m_enableTrend && BUTTON_COLUMN == index.column() && (ptr->m_tagname_type == E_TAGNAME_ANA || ptr->m_tagname_type == E_TAGNAME_ACC)) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40 -40, option.rect.height()/2-10, -12-40, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strTrendPath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + if( m_enableWave && BUTTON_COLUMN == index.column() && !ptr->wave_file.isEmpty()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40 -40 -40, option.rect.height()/2-10, -12-40-40, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strWavePath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); + painter->restore(); + }else + { + return ; + } + } +} + +bool CAiAlarmDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if(!index.isValid()) + { + return false; + } + if(index.column() != BUTTON_COLUMN) + { + return false; + } + QMouseEvent *mouseEvent = static_cast(event); + CAiAlarmTreeItem *item = m_pModel->getItem(index); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) && ptr != NULL) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + if(m_enableVideo && ptr->m_needVideoAlm) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QString pointTag = ptr->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + emit openVideo(ptr->domain_id,ptr->app_id,pointTag,ptr->time_stamp-VIDEO_TIME,ptr->time_stamp+VIDEO_TIME); + } + } + if( m_enableTrend && (ptr->m_tagname_type == E_TAGNAME_ACC || ptr->m_tagname_type == E_TAGNAME_ANA)) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 82, option.rect.height()/2-10, -50, -(option.rect.height()/2-10)); + QRect rect = button.rect; + + if(rect.contains(mouseEvent->pos())) + { + QStringList trendList; + trendList.append(ptr->key_id_tag); + emit openTrend(ptr->time_stamp,trendList); + } + } + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) && ptr != NULL) + { + if(m_enableVideo && ptr->m_needVideoAlm) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); + QRect rect = button.rect; + QString pointTag = ptr->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + if(rect.contains(mouseEvent->pos())) + { + QString pointTag = ptr->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + emit openVideo(ptr->domain_id,ptr->app_id,pointTag,ptr->time_stamp-VIDEO_TIME,ptr->time_stamp+VIDEO_TIME); + } + } + } + if(m_enableTrend && (ptr->m_tagname_type == E_TAGNAME_ACC || ptr->m_tagname_type == E_TAGNAME_ANA)) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 82, option.rect.height()/2-10, -50, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QStringList trendList; + trendList.append(ptr->key_id_tag); + emit openTrend(ptr->time_stamp,trendList); + } + } + } + if(m_enableWave && !ptr->wave_file.isEmpty()) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 122, option.rect.height()/2-10, -90, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QString wave = ptr->wave_file; + wave = QString("%1%2%3").arg("\"").arg(wave).arg("\""); + LOGINFO("录波文件为:%s",wave.toStdString().c_str()); + + const std::string strProc = std::move(iot_public::CFileUtil::getPathOfBinFile( + std::string("WaveAnalyze") + iot_public::CFileUtil::getProcSuffix())); + if(strProc.empty()) + LOGERROR("未找到可执行文件WaveAnalyze"); + else + QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(wave)); + } + } + } + } + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +void CAiAlarmDelegate::slotLoadConfig() +{ + CAlarmSetMng::instance()->getColorMap(m_colorMap); + CAlarmSetMng::instance()->getSelectInfo(m_selectIsEmpty,m_select_background_color,m_select_text_color); + CAlarmSetMng::instance()->getEmptyInfo(m_emptyBackgroundColor,m_emptyTipColor,m_emptyTip); + //CAlarmColorMng::instance()->getActAndFunc(m_act,m_func); + + std::string style = iot_public::CFileStyle::getCurStyle(); + m_strTrendPath = iot_public::CFileUtil::getPathOfResFile("gui/icon/alarm/trend_"+style+".png").c_str(); + m_strVideoPath = iot_public::CFileUtil::getPathOfResFile("gui/icon/alarm/video_"+style+".png").c_str(); + m_strWavePath = iot_public::CFileUtil::getPathOfResFile("gui/icon/alarm/wave_"+style+".png").c_str(); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmDelegate.h b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmDelegate.h new file mode 100644 index 00000000..74a15e7f --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmDelegate.h @@ -0,0 +1,50 @@ +#ifndef CAIALARMDELEGATE_H +#define CAIALARMDELEGATE_H + +#include +#include +#include "CAiAlarmTreeModel.h" +#include "CAlarmSetMng.h" + +class CAiAlarmDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CAiAlarmDelegate(CAiAlarmTreeModel *model, QObject *parent = 0); + void setEnableTrend(bool isNeed); + void setEnableLevel(bool isNeed); + void setEnableVideo(bool isNeed); + void setEnableWave(bool isNeed); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); +signals: + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + void openTrend(quint64 time_stamp,QStringList tagList); + +public slots: + void slotLoadConfig(); + +private: + CAiAlarmTreeModel *m_pModel; + + bool m_enableTrend; + bool m_enableLevel; + bool m_enableVideo; + bool m_enableWave; + + QMap m_colorMap; + QColor m_select_background_color,m_select_text_color; //选中告警背景色和文字颜色 + bool m_selectIsEmpty; + + QColor m_emptyBackgroundColor,m_emptyTipColor; + QString m_emptyTip; + int m_act; + int m_func; + + QString m_strWavePath; + QString m_strVideoPath; + QString m_strTrendPath; +}; + +#endif // CAIALARMDELEGATE_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmMsgInfo.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmMsgInfo.cpp new file mode 100644 index 00000000..dadde560 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmMsgInfo.cpp @@ -0,0 +1,466 @@ +#include "CAiAlarmMsgInfo.h" +#include +#include "CAlarmDataCollect.h" +#include + +CAiAlarmMsgInfo::CAiAlarmMsgInfo() +{ + logic_state = E_AiALM_IALS_NORMAL; + main_state = E_ALS_BAD; + domain_id = -1; + priority = -1; + time_stamp = 1000; + + uuid_base64 = QString(); + content = QString(); + disposal_plan = QString(); + raw_alm_uuid.clear(); + + priorityOrder = -1; + deleteFlag = false; + brokenFlag = false; + releaseFlag = false; + m_needVideoAlm =false; + app_id = -1; + main_uuid_base64 = QString(); + key_id_tag = QString(); + m_tagname_type = E_TAGNAME_ERROR; +} + +CAiAlarmMsgInfo::CAiAlarmMsgInfo(const CAiAlarmMsgInfo &other): priority(0) +{ + logic_state = other.logic_state; + main_state = other.main_state; + domain_id = other.domain_id; + time_stamp = other.time_stamp; + + uuid_base64 = other.uuid_base64; + content = other.content; + disposal_plan = other.disposal_plan; + raw_alm_uuid = other.raw_alm_uuid; + + priorityOrder = other.priorityOrder; + deleteFlag = other.deleteFlag; + brokenFlag = other.brokenFlag; + releaseFlag = other.releaseFlag; + + m_needVideoAlm = other.m_needVideoAlm; + app_id = other.app_id; + main_uuid_base64 = other.main_uuid_base64; + key_id_tag = other.key_id_tag; + m_tagname_type = other.m_tagname_type; +} + +void CAiAlarmMsgInfo::initialize(const iot_idl::SIntelliAlmInfo &alarmInfo) +{ + + logic_state = (E_AiALARM_LOGICSTATE)alarmInfo.logic_state(); + domain_id = alarmInfo.domain_id(); + priority = alarmInfo.priority(); + time_stamp = alarmInfo.time_stamp(); + + uuid_base64 = QString::fromStdString(alarmInfo.uuid_base64()); + content = QString::fromStdString(alarmInfo.content()); + disposal_plan = QString::fromStdString(alarmInfo.disposal_plan()); + raw_alm_uuid.clear(); //< 关联的原始告警uuid + for(int x(0); x < alarmInfo.raw_alm_uuid_size(); x++) + { + if(x == 0) + { + main_uuid_base64 = QString::fromStdString(alarmInfo.raw_alm_uuid(x)); + } + raw_alm_uuid.append(QString::fromStdString(alarmInfo.raw_alm_uuid(x))); + } + + priorityOrder = -1; + if(logic_state == E_AIALM_IALS_DELETED) + { + deleteFlag = true; + }else + { + deleteFlag = false; + } + if(logic_state == E_AIALM_IALS_BROKEN) + { + brokenFlag = true; + }else + { + brokenFlag = false; + } + releaseFlag = false; + m_needVideoAlm =false; +} + +bool CAiAlarmMsgInfo::ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder > info->priorityOrder) + { + return true; + }else if(priorityOrder < info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp < info->time_stamp) + { + return true; + }else if(time_stamp > info->time_stamp) + { + return false; + }else + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return false; + break; + case E_SORT_REGION: + return false; + break; + case E_SORT_TYPE: + return false; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + return false; + case E_SORT_ALM_STATE: + return false; + break; + case E_SORT_STYLE: + return false; + break; + default: + break; + } + return false; +} + +bool CAiAlarmMsgInfo::aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder < info->priorityOrder) + { + return true; + }else if(priorityOrder > info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_TIME: + if(time_stamp > info->time_stamp) + { + return true; + }else if(time_stamp < info->time_stamp) + { + return false; + }else + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return true; + break; + case E_SORT_REGION: + return true; + break; + case E_SORT_TYPE: + return true; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content < info->content) + { + return false; + } + else if(content > info->content) + { + return true; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_LOGICSTATE: + return true; + break; + case E_SORT_ALM_STATE: + return true; + break; + case E_SORT_STYLE: + return true; + break; + default: + break; + } + return false; +} +//< 智能告警-前者小[不包含的字段进行比较排序] +bool CAiAlarmMsgInfo::ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder > info->priorityOrder) + { + return true; + }else if(priorityOrder < info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp < info->time_stamp) + { + return true; + }else if(time_stamp > info->time_stamp) + { + return false; + }else + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return true; + break; + case E_SORT_REGION: + return true; + break; + case E_SORT_TYPE: + return true; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + return true; + case E_SORT_ALM_STATE: + return true; + break; + case E_SORT_STYLE: + return true; + break; + default: + break; + } + return false; +} + +bool CAiAlarmMsgInfo::aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder < info->priorityOrder) + { + return true; + }else if(priorityOrder > info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_TIME: + if(time_stamp > info->time_stamp) + { + return true; + }else if(time_stamp < info->time_stamp) + { + return false; + }else + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return false; + break; + case E_SORT_REGION: + return false; + break; + case E_SORT_TYPE: + return false; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content < info->content) + { + return false; + } + else if(content > info->content) + { + return true; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_LOGICSTATE: + return false; + break; + case E_SORT_ALM_STATE: + return false; + break; + case E_SORT_STYLE: + return false; + break; + default: + break; + } + return false; +} + +bool operator==(const CAiAlarmMsgInfo &source, const CAiAlarmMsgInfo &target) +{ + if(source.uuid_base64 == target.uuid_base64) + { + return true; + } + return false; +// //替换式告警且车站、测点ID相同 +// if((0 == source.if_water_alm) && (0 == target.if_water_alm) && (source.location_id == target.location_id) && (source.key_id_tag == target.key_id_tag)) +// { +// return true; +// } +// //流水账告警且时标、告警内容相同 +// else if((1 == source.if_water_alm) && (1 == target.if_water_alm) && (source.location_id == target.location_id) && (source.time_stamp == target.time_stamp) && (source.content == target.content)) +// { +// return true; +// } +// return false; +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmMsgInfo.h b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmMsgInfo.h new file mode 100644 index 00000000..15d7996f --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmMsgInfo.h @@ -0,0 +1,60 @@ +#ifndef CAIALARMMSGINFO_H +#define CAIALARMMSGINFO_H + + +#include +#include +#include +#include "intelli_alm_api/CIntelliAlmApi4Clt.h" +#include +#include +#include +#include +enum E_AiALARM_LOGICSTATE +{ + E_AiALM_IALS_NORMAL = 1, //正常 + E_AIALM_IALS_DELETED = 2, //已删除 + E_AIALM_IALS_BROKEN = 3, //不完整的 +}; +class CAiAlarmMsgInfo +{ +public: + CAiAlarmMsgInfo(); + CAiAlarmMsgInfo(const CAiAlarmMsgInfo &other); + void initialize(const iot_idl::SIntelliAlmInfo &alarmInfo); + + //< [优先级越小表示越大]-智能告警窗调用 + bool ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + bool ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + E_AiALARM_LOGICSTATE logic_state; //< 状态 + E_ALARM_LOGICSTATE main_state; //< 主告警逻辑状态 + qint32 domain_id; //< 域ID + qint32 priority; //< 告警优先级id + quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) + QString uuid_base64; //< uuid 主键 + QString content; //< 告警内容 + QString disposal_plan; //< 处置预案 + QVector raw_alm_uuid; //< 关联的原始告警uuid + //< Extend + qint32 priorityOrder; //< 优先级 + bool deleteFlag; //< 是否被删除 + bool brokenFlag; //< 是否不完整 + bool releaseFlag; //< 是否被释放 + //和主原始告警相关 + bool m_needVideoAlm; //是否需要视频告警 + qint32 app_id; //主原始告警应用id + QString main_uuid_base64; //主原始告警uuid + QString key_id_tag; //主原始告警标签 + E_TAGNAME_TYPE m_tagname_type; +}; + +bool operator==(const CAiAlarmMsgInfo &source, const CAiAlarmMsgInfo &target); + +Q_DECLARE_METATYPE(CAiAlarmMsgInfo) +Q_DECLARE_METATYPE(AiAlarmMsgPtr) + +#endif // CAIALARMMSGINFO_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeItem.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeItem.cpp new file mode 100644 index 00000000..b4529706 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeItem.cpp @@ -0,0 +1,416 @@ +#include "CAiAlarmTreeItem.h" +#include "CAiAlarmMsgInfo.h" +#include "CAlarmMsgInfo.h" +#include "CAlarmCommon.h" +#include "pub_logger_api/logger.h" +#include +#include +#include "CAlarmBaseData.h" +CAiAlarmTreeItem::CAiAlarmTreeItem(const QVector &data, CAiAlarmTreeItem *parent) + : m_uuid(QString()), + m_bIsAi(false), + m_parent(parent), + m_data(data), + m_alarmPtr(NULL), + m_aialarmPtr(NULL) +{ + +} + +CAiAlarmTreeItem::~CAiAlarmTreeItem() +{ + qDeleteAll(m_child); + m_child.clear(); +} + +CAiAlarmTreeItem *CAiAlarmTreeItem::child(int row) +{ + return m_child.at(row); +} + +CAiAlarmTreeItem *CAiAlarmTreeItem::parent() +{ + return m_parent; +} + +int CAiAlarmTreeItem::childCount() const +{ + return m_child.count(); +} + +int CAiAlarmTreeItem::columnCount() const +{ + return m_data.count(); +} + +int CAiAlarmTreeItem::childNumber() const +{ + if(m_parent) + { + return m_parent->m_child.indexOf(const_cast(this)); + } + return 0; +} + +QVariant CAiAlarmTreeItem::data(int column, int role) +{ + if(E_DisplayRole == role) + { + if(m_bIsAi == true) + { + return aigetDataByColumn(column); + }else + { + return getDataByColumn(column); + } + } + else + { + return QVariant(); + } +} + +bool CAiAlarmTreeItem::setData(int column, const QVariant &value, int role) +{ + Q_UNUSED(role) + Q_UNUSED(value) + if (column < 0 || column >= m_data.size()) + return false; + return true; +} + +bool CAiAlarmTreeItem::setPtr(AlarmMsgPtr ptr) +{ + m_alarmPtr = ptr; + m_bIsAi = false; + m_uuid = ptr->uuid_base64; + return true; +} + +bool CAiAlarmTreeItem::setAiPtr(AiAlarmMsgPtr aiPtr) +{ + m_aialarmPtr = aiPtr; + m_bIsAi = true; + m_uuid = aiPtr->uuid_base64; + return true; +} + +bool CAiAlarmTreeItem::insertChildren(int position, int count, int columns) +{ + if (position < 0 || position > m_child.size()) + return false; + + for (int row = 0; row < count; ++row) { + QVector data(columns); + CAiAlarmTreeItem *item = new CAiAlarmTreeItem(data, this); + m_child.insert(position, item); + } + + return true; +} + +bool CAiAlarmTreeItem::removeChildren(int position, int count, int columns) +{ + Q_UNUSED(columns) + if (position < 0 || position + count > m_child.size()) + return false; + + for (int row = 0; row < count; ++row) + delete m_child.takeAt(position); + + return true; +} + +bool CAiAlarmTreeItem::isAi() +{ + return m_bIsAi; +} + +AlarmMsgPtr CAiAlarmTreeItem::ptr() +{ + if(m_alarmPtr == NULL) + return NULL; + else + return m_alarmPtr; +} + +bool CAiAlarmTreeItem::getPtr(AlarmMsgPtr &ptr) +{ + if(!m_bIsAi &&m_alarmPtr != NULL) + { + ptr = m_alarmPtr; + return true; + } + else + { + ptr = NULL; + return false; + } +} + +bool CAiAlarmTreeItem::getAiPtr(AiAlarmMsgPtr &aiPtr) +{ + if(m_bIsAi &&m_aialarmPtr != NULL) + { + aiPtr = m_aialarmPtr; + return true; + } + else + { + aiPtr = NULL; + return false; + } +} + +QList CAiAlarmTreeItem::getChildAlarmPtr() +{ + QList ptrList; + foreach (CAiAlarmTreeItem* item, m_child) { + if(item->ptr() != NULL) + { + ptrList.append(item->ptr()); + } + } + return ptrList; +} + +int CAiAlarmTreeItem::index(const QString uuid) +{ + for(int index(0);indexm_uuid == uuid) + { + return index; + } + } + return -1; +} + +bool CAiAlarmTreeItem::lessThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey) +{ + AiAlarmMsgPtr aiptr = NULL; + AlarmMsgPtr ptr= NULL; + if(m_bIsAi) + { + if(info->isAi()) + { + if(info->getAiPtr(aiptr) && aiptr != NULL) + return m_aialarmPtr->ailessThan(aiptr,sortkey); + }else + { + if(info->getPtr(ptr) && ptr != NULL) + return m_aialarmPtr->ailessThan(ptr,sortkey); + } + + }else + { + if(info->isAi()) + { + if(info->getAiPtr(aiptr) && aiptr != NULL) + return m_alarmPtr->ailessThan(aiptr,sortkey); + }else + { + if(info->getPtr(ptr) && ptr != NULL) + return m_alarmPtr->ailessThan(ptr,sortkey); + } + } + LOGERROR("lessThan():比较大小出错!"); + return false; +} + +bool CAiAlarmTreeItem::moreThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey) +{ + AiAlarmMsgPtr aiptr = NULL; + AlarmMsgPtr ptr= NULL; + if(m_bIsAi) + { + if(info->isAi()) + { + if(info->getAiPtr(aiptr) && aiptr != NULL) + return m_aialarmPtr->aimoreThan(aiptr,sortkey); + }else + { + if(info->getPtr(ptr) && ptr != NULL) + return m_aialarmPtr->aimoreThan(ptr,sortkey); + } + }else + { + if(info->isAi()) + { + if(info->getAiPtr(aiptr) && aiptr != NULL) + return m_alarmPtr->aimoreThan(aiptr,sortkey); + }else + { + if(info->getPtr(ptr) && ptr != NULL) + return m_alarmPtr->aimoreThan(ptr,sortkey); + } + } + LOGERROR("moreThan():比较大小出错!"); + return false; +} + +QList CAiAlarmTreeItem::getChild() +{ + return m_child; +} + +void CAiAlarmTreeItem::setChild(QList itemList) +{ + m_child.clear(); + m_child = itemList; +} + +QList CAiAlarmTreeItem::getChildItemList() +{ + return m_child; +} + +QVector CAiAlarmTreeItem::getContent() +{ + QVector vec; + for(int index(0);indextime_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); + return m_data[0]; + case PRIORITY: + m_data[1] = CAlarmBaseData::instance()->queryPriorityDesc(m_aialarmPtr->priority); + return m_data[1]; + case LOCATION: + m_data[2] = CAlarmMsgManage::instance()->queryLocationDesc(m_aialarmPtr->uuid_base64); + return m_data[2]; + case REGION: + m_data[3] ="-"; + return m_data[3]; + case TYPE: + m_data[4] ="-"; + return "-"; + case STATUS: + m_data[5] ="-"; + return "-"; + case RETURNSTATUS: + m_data[6] ="-"; + return "-"; + case CONFIRM: + m_data[7] = QString("%1/%2").arg(getConfirm()).arg(m_child.size()); + return m_data[7]; + case CONTENT: + m_data[8] = m_aialarmPtr->content; + return m_data[8]; + default: + break; + } + } + return QVariant(); +} + +QVariant CAiAlarmTreeItem::getDataByColumn(int column) +{ + if(m_alarmPtr != NULL) + { + switch (column) { + case TIME: + { + m_data[0] = QDateTime::fromMSecsSinceEpoch(m_alarmPtr->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); + return m_data[0]; + } + case PRIORITY: + { + m_data[1] = CAlarmBaseData::instance()->queryPriorityDesc(m_alarmPtr->priority); + return m_data[1]; + } + case LOCATION: + { + m_data[2] = CAlarmBaseData::instance()->queryLocationDesc(m_alarmPtr->location_id); + return m_data[2]; + } + case REGION: + { + m_data[3] = CAlarmBaseData::instance()->queryRegionDesc(m_alarmPtr->region_id); + return m_data[3]; + } + case TYPE: + { + m_data[4] = CAlarmBaseData::instance()->queryAlarmTypeDesc(m_alarmPtr->alm_type); + return m_data[4]; + } + case STATUS: + { + m_data[5] = CAlarmBaseData::instance()->queryAlarmStatusDesc(m_alarmPtr->alm_status); + return m_data[5]; + } + case RETURNSTATUS: + { + if(E_ALS_ALARM == m_alarmPtr->logic_state || E_ALS_ALARM_CFM == m_alarmPtr->logic_state || + E_ALS_ALARM_DEL == m_alarmPtr->logic_state || E_ALS_ALARM_CFM_DEL == m_alarmPtr->logic_state) //未复归 + { + m_data[6] = QObject::tr("未复归"); + return m_data[6]; + } + else if(E_ALS_RETURN == m_alarmPtr->logic_state || E_ALS_RETURN_CFM == m_alarmPtr->logic_state || + E_ALS_RETURN_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_CFM_DEL == m_alarmPtr->logic_state) + { + m_data[6] = QObject::tr("已复归"); + return m_data[6]; + }else + { + m_data[6] = QObject::tr("-"); + return m_data[6]; + } + } + case CONFIRM: + { + if(E_ALS_ALARM == m_alarmPtr->logic_state || E_ALS_RETURN == m_alarmPtr->logic_state + || E_ALS_ALARM_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_DEL == m_alarmPtr->logic_state) //< 未确认 + { + m_data[7] = QObject::tr("未确认"); + return m_data[7]; + } + else if(E_ALS_ALARM_CFM == m_alarmPtr->logic_state || E_ALS_RETURN_CFM == m_alarmPtr->logic_state || + E_ALS_ALARM_CFM_DEL == m_alarmPtr->logic_state || E_ALS_RETURN_CFM_DEL == m_alarmPtr->logic_state || + ALS_EVT_ONLY == m_alarmPtr->logic_state) + { + m_data[7] = QObject::tr("已确认"); + return m_data[7]; + } + } + case CONTENT: + { + m_data[8] = m_alarmPtr->content; + return m_data[8]; + } + default: + break; + } + } + return QVariant(); +} + +int CAiAlarmTreeItem::getConfirm() +{ + int size = 0; + QList::iterator it = m_child.begin(); + while (it != m_child.end()) { + AlarmMsgPtr ptr; + if((*it)->getPtr(ptr)) + { + if(ptr->logic_state == E_ALS_ALARM_CFM || ptr->logic_state == E_ALS_RETURN_CFM + || ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL || ptr->logic_state == ALS_EVT_ONLY) + { + size++; + } + } + it++; + } + return size; +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeItem.h b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeItem.h new file mode 100644 index 00000000..b15be0bb --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeItem.h @@ -0,0 +1,81 @@ +#ifndef CAIALARMTREEITEM_H +#define CAIALARMTREEITEM_H + +#include +#include +#include "CAlarmMsgManage.h" +enum E_ItemDataRole +{ + E_IfAiFlag =0x0101, //< 是否智能告警 + E_DisplayRole =0x0102, + E_UserRole = 0x0103, //< uuid + E_CheckStateRole = 0x0104 +}; +enum ColumnField +{ + TIME = 0, + PRIORITY, + LOCATION, + REGION, + TYPE, + STATUS, + RETURNSTATUS, + CONFIRM, + CONTENT +}; +class CAiAlarmTreeItem +{ +public: + explicit CAiAlarmTreeItem(const QVector &data,CAiAlarmTreeItem *parent = Q_NULLPTR); + ~CAiAlarmTreeItem(); + + CAiAlarmTreeItem *child(int row); + CAiAlarmTreeItem *parent(); + + int childCount() const; + int columnCount() const; + //返回行数 + int childNumber() const; + QVariant data(int column,int role = E_DisplayRole); + bool setData(int column,const QVariant &value,int role); + bool setPtr(AlarmMsgPtr ptr); + bool setAiPtr(AiAlarmMsgPtr aiPtr); + bool insertChildren(int position, int count, int columns); + bool removeChildren(int position, int count, int columns); + bool isAi(); + + //若确定是原始告警可以直接使用 + AlarmMsgPtr ptr(); + bool getPtr(AlarmMsgPtr &ptr); + bool getAiPtr(AiAlarmMsgPtr &aiPtr); + QList getChildAlarmPtr(); + + int index(const QString uuid); + + bool lessThan(CAiAlarmTreeItem *info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool moreThan(CAiAlarmTreeItem* info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + QList getChild(); + void setChild(QList itemList); + + QList getChildItemList(); + + QVector getContent(); +private: + QVariant aigetDataByColumn(int column); + QVariant getDataByColumn(int column); + int getConfirm(); +private: + QString m_uuid; + bool m_bIsAi; + QList m_child; + CAiAlarmTreeItem *m_parent; + + QVector m_data; + AlarmMsgPtr m_alarmPtr; + AiAlarmMsgPtr m_aialarmPtr; + + //Qt::CheckState m_checkState; +}; + +#endif // CAIALARMTREEITEM_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeModel.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeModel.cpp new file mode 100644 index 00000000..3618bf09 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeModel.cpp @@ -0,0 +1,1134 @@ +#include "CAiAlarmTreeModel.h" +#include "CAlarmMsgManage.h" +#include "CAiAlarmDataCollect.h" +#include "CAlarmDataCollect.h" +#include "pub_logger_api/logger.h" +#include +#include +#include "CAlarmBaseData.h" + +CAiAlarmTreeModel::CAiAlarmTreeModel(QObject *parent) + : QAbstractItemModel(parent), + m_sortKey(E_SORT_TIME), + m_order(Qt::DescendingOrder), + m_nShowNum(0), + m_nShowAiNum(0) +{ + m_header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("告警类型") << tr("告警状态") <)), this, SLOT(slotMsgArrived(QList)), Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAiMsgAdd,this,&CAiAlarmTreeModel::slotAiMsgAdd,Qt::QueuedConnection); + + connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAiMsgRemove,this,&CAiAlarmTreeModel::slotAiMsgRemove,Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigMsgRemove,this,&CAiAlarmTreeModel::slotMsgRemove,Qt::QueuedConnection); + + connect(CAlarmDataCollect::instance(),&CAlarmDataCollect::sigMsgRefresh,this,&CAiAlarmTreeModel::slotMsgRefresh,Qt::QueuedConnection); + connect(CAiAlarmDataCollect::instance(),&CAiAlarmDataCollect::sigMsgRefresh,this,&CAiAlarmTreeModel::slotMsgRefresh,Qt::QueuedConnection); + + slotMsgRefresh(); +} + +CAiAlarmTreeModel::~CAiAlarmTreeModel() +{ + m_listHorAlignmentFlags.clear(); + m_header.clear(); +} + +void CAiAlarmTreeModel::initialize() +{ + m_listHorAlignmentFlags.clear(); + for (int nIndex(0); nIndex < m_header.size(); nIndex++) + { + m_listHorAlignmentFlags.append(Qt::AlignHCenter); + } + + initFilter(); + + slotMsgRefresh(); +} + +QVariant CAiAlarmTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(m_header.at(section)); + } + return QVariant(); +} + +QModelIndex CAiAlarmTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + { + return QModelIndex(); + } + + CAiAlarmTreeItem *parentItem; + + if (!parent.isValid()) + { + parentItem = m_root; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + CAiAlarmTreeItem *childItem = parentItem->child(row); + if (childItem) + { + return createIndex(row, column, childItem); + } + else + { + return QModelIndex(); + } +} + +QModelIndex CAiAlarmTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + CAiAlarmTreeItem *childItem = static_cast(index.internalPointer()); + + CAiAlarmTreeItem *parentItem = childItem->parent(); + if (parentItem == m_root) + { + return QModelIndex(); + } + + return createIndex(parentItem->childNumber(), 0, parentItem); +} + +int CAiAlarmTreeModel::rowCount(const QModelIndex &parent) const +{ + CAiAlarmTreeItem *parentItem; + if (!parent.isValid()) + { + parentItem = m_root; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + return parentItem->childCount(); +} + +int CAiAlarmTreeModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + { + return static_cast(parent.internalPointer())->columnCount(); + } + else + { + return m_root->columnCount(); + } +} + +QVariant CAiAlarmTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + { + return QVariant(); + } + if(Qt::TextAlignmentRole == role) + { + if(index.column() == (int)CONTENT) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); + } + + }else if (Qt::DisplayRole == role) + { + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + return item->data(index.column(),E_DisplayRole); + }else if(Qt::ToolTipRole == role) + { + if(index.column() == (int)CONTENT) + { + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + QString tip = item->data(index.column(),E_DisplayRole).toString(); + return tip; + } + } + return QVariant(); +} + +bool CAiAlarmTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_UNUSED(value); + Q_UNUSED(role); + if (!index.isValid() || index.column()) + { + return false; + } + return true; +} + +bool CAiAlarmTreeModel::insertRows(int row, int count, const QModelIndex &parent) +{ + bool success; + CAiAlarmTreeItem *parentItem = getItem(parent); + beginInsertRows(parent, row, row + count - 1); + success = parentItem->insertChildren(row, count, m_root->columnCount()); + endInsertRows(); + return success; +} + +bool CAiAlarmTreeModel::removeRows(int row, int count, const QModelIndex &parent) +{ + bool success; + CAiAlarmTreeItem *parentItem = getItem(parent); + beginRemoveRows(parent, row, row + count - 1); + success = parentItem->removeChildren(row, count, m_root->columnCount()); + endRemoveRows(); + return success; +} + +void CAiAlarmTreeModel::setModel() +{ + setModelData(m_root); +} + +void CAiAlarmTreeModel::slotAiMsgAdd(const QList &aimsgList) +{ + QList::const_iterator itpos = aimsgList.begin(); + while (itpos != aimsgList.end()) { + if((*itpos)->deleteFlag == true ||(*itpos)->brokenFlag == true) + { + itpos++; + continue ; + } + QList almList; + conditionAiFilter(*itpos,almList); + int size = almList.size(); + + if(size > 0) + { + m_nShowNum += size; + m_nShowAiNum++; + insertAlarmMsg(*itpos,almList); + } + itpos++; + } +} + +void CAiAlarmTreeModel::slotAiMsgRemove(const QList &uuidList) +{ + QList::const_iterator itpos = uuidList.begin(); + while (itpos != uuidList.end()) { + int x= m_root->index(*itpos); + if(x != -1) + { + m_nShowNum -= m_root->child(x)->childCount(); + m_nShowAiNum--; + beginRemoveRows(QModelIndex(), x,x); + m_root->removeChildren(x, 1, m_root->columnCount()); + endRemoveRows(); + } + itpos++; + } +} + +void CAiAlarmTreeModel::slotMsgRefresh() +{ + if(m_root->childCount() > 0) + { + beginRemoveRows(QModelIndex(), 0, m_root->childCount()-1); + m_root->removeChildren(0, m_root->childCount(), m_root->columnCount()); + endRemoveRows(); + } + m_nShowNum = 0; + m_nShowAiNum = 0; + setModel(); +} + +void CAiAlarmTreeModel::sortColumn(int column, Qt::SortOrder order) +{ + if(order == Qt::AscendingOrder) + { + m_order = Qt::DescendingOrder; + } + else + { + m_order = Qt::AscendingOrder; + } + + switch ((ColumnField)column) + { + case TIME: + { + m_sortKey = E_SORT_TIME; + break; + } + case PRIORITY: + { + m_sortKey = E_SORT_PRIORITY; + break; + } + case LOCATION: + { + m_sortKey = E_SORT_LOCATION; + break; + } + case REGION: + { + m_sortKey = E_SORT_REGION; + break; + } + case TYPE: + { + m_sortKey = E_SORT_TYPE; + break; + } + case STATUS: + { + m_sortKey = E_SORT_ALM_STATE; + break; + } + case RETURNSTATUS: + { + m_sortKey = E_SORT_STYLE; + break; + } + case CONFIRM: + { + m_sortKey = E_SORT_LOGICSTATE; + break; + } + case CONTENT: + { + m_sortKey = E_SORT_CONTENT; + break; + } + default: + break; + } + + beginResetModel(); + sort(); + endResetModel(); +} + +void CAiAlarmTreeModel::slotMsgRemove(const QVector deluuid) +{ + if(deluuid.size()>=1000) + { + beginResetModel(); + for(int index(0);indexindex(deluuid.at(index)); + if(x != -1) + { + m_nShowNum--; + m_root->removeChildren(x, 1, m_root->columnCount()); + } + } + endResetModel(); + }else + { + for(int index(0);indexindex(deluuid.at(index)); + if(x != -1) + { + m_nShowNum--; + beginRemoveRows(QModelIndex(),x,x); + m_root->removeChildren(x, 1, m_root->columnCount()); + endRemoveRows(); + } + } + } +} + +void CAiAlarmTreeModel::setModelData(CAiAlarmTreeItem *parent) +{ + m_nShowNum = 0; + m_nShowAiNum = 0; + QList listAlarm; + QList listaiAlarm; + listAlarm.clear(); + listaiAlarm.clear(); + int columnCount = m_root->columnCount(); + CAlarmMsgManage::instance()->getAlarmInfo(listAlarm,listaiAlarm); + foreach (AlarmMsgPtr almPtr, listAlarm) { + if(almPtr == NULL) + { + continue; + } + if(almPtr->deleteFlag == true || almPtr->releaseFlag == true) + { + continue; + } + if(conditionFilter(almPtr)) + { + m_nShowNum++; + parent->insertChildren(parent->childCount(), 1, columnCount); + parent->child(parent->childCount() - 1)->setPtr(almPtr); + } + } + foreach (AiAlarmMsgPtr aialmPtr, listaiAlarm) { + if(aialmPtr == NULL) + { + continue; + } + if(aialmPtr->deleteFlag == true || aialmPtr->brokenFlag == true) + { + continue; + } + QList almList; + conditionAiFilter(aialmPtr,almList); + int size = almList.size(); + if(size > 0) + { + m_root->insertChildren(m_root->childCount(), 1, columnCount); + m_nShowAiNum++; + m_root->child(m_root->childCount() - 1)->setAiPtr(aialmPtr); + int childCount = m_root->childCount(); + CAiAlarmTreeItem *item = m_root->child(childCount- 1); + + for(int index(0);index < size; index++) + { + m_nShowNum++; + item->insertChildren(item->childCount(),1,columnCount); + item->child(item->childCount() - 1)->setPtr(almList.at(index)); + } + } + } + beginResetModel(); + sort(); + endResetModel(); +} + +void CAiAlarmTreeModel::sort() +{ + QMap mapTree1AlarmInfo; + //<分 + for(int nIndex(0); nIndex < m_root->childCount(); nIndex++) + { + CAiAlarmTreeItem *item = m_root->child(nIndex); + mapTree1AlarmInfo[nIndex / 1000].second.append(item); + } + //<快速排序1级节点 + for(int nMapIndex(0); nMapIndex < mapTree1AlarmInfo.count(); nMapIndex++) + { + qucikSort(mapTree1AlarmInfo[nMapIndex].second, 0, mapTree1AlarmInfo[nMapIndex].second.count() - 1); + } + PAIRLISTAIALARMINFO tempListTree1AlarmInfo = mapTree1AlarmInfo[0]; + for(int nPairIndex(1); nPairIndex < mapTree1AlarmInfo.count(); nPairIndex++) + { + //<归并 + tempListTree1AlarmInfo.first = 0; + mapTree1AlarmInfo[nPairIndex].first = 0; + while(mapTree1AlarmInfo[nPairIndex].first < mapTree1AlarmInfo[nPairIndex].second.count()) + { + if(tempListTree1AlarmInfo.first >= tempListTree1AlarmInfo.second.count()) + { + tempListTree1AlarmInfo.second.append(mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first)); + mapTree1AlarmInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListTree1AlarmInfo.second[tempListTree1AlarmInfo.first]->lessThan(mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListTree1AlarmInfo.second.insert(tempListTree1AlarmInfo.first, mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first)); + mapTree1AlarmInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListTree1AlarmInfo.second[tempListTree1AlarmInfo.first]->moreThan(mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListTree1AlarmInfo.second.insert(tempListTree1AlarmInfo.first, mapTree1AlarmInfo[nPairIndex].second.at(mapTree1AlarmInfo[nPairIndex].first)); + mapTree1AlarmInfo[nPairIndex].first += 1; + } + } + } + tempListTree1AlarmInfo.first += 1; + } + } + QList itemList = tempListTree1AlarmInfo.second; + for(int index(0);indexisAi()) + { + QList item = itemList.at(index)->getChild(); + //小于500才排序, + if(item.size()<500) + { + qucikSort(item,0,item.size()-1); + itemList.at(index)->setChild(item); + } + } + } + m_root->setChild(tempListTree1AlarmInfo.second); +} + +void CAiAlarmTreeModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CAiAlarmTreeModel::partitionAscendingOrder(QList &list, int start, int last) +{ + CAiAlarmTreeItem * info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(left < right && list[left]->lessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CAiAlarmTreeModel::partitionDescendingOrder(QList &list, int start, int last) +{ + CAiAlarmTreeItem * info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +void CAiAlarmTreeModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CAiAlarmTreeModel::partitionAscendingOrder(QList &list, int start, int last) +{ + AlarmMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftlessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CAiAlarmTreeModel::partitionDescendingOrder(QList &list, int start, int last) +{ + AlarmMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CAiAlarmTreeModel::calcLeft(const AiAlarmMsgPtr &info) +{ + int mid = -1; + int left = 0; + int right = m_root->childCount() - 1; + while(left <= right) + { + mid = (left + right) / 2; + + if (Qt::AscendingOrder == m_order) + { + CAiAlarmTreeItem *item =m_root->child(mid); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) &&ptr != NULL) + { + if(info->ailessThan(ptr, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) &&ptr != NULL) + { + if(info->ailessThan(ptr, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + } + else + { + CAiAlarmTreeItem *item =m_root->child(mid); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) &&ptr != NULL) + { + if(ptr->ailessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) &&ptr != NULL) + { + if(ptr->ailessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + } + } + return left; +} + +int CAiAlarmTreeModel::calcLeft(const AlarmMsgPtr &info) +{ + int mid = -1; + int left = 0; + int right = m_root->childCount() - 1; + while(left <= right) + { + mid = (left + right) / 2; + + if (Qt::AscendingOrder == m_order) + { + CAiAlarmTreeItem *item =m_root->child(mid); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) && ptr != NULL) + { + if(info->ailessThan(ptr, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) && ptr != NULL) + { + if(info->ailessThan(ptr, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + } + else + { + CAiAlarmTreeItem *item =m_root->child(mid); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr) && ptr != NULL) + { + if(ptr->ailessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr) && ptr != NULL) + { + if(ptr->ailessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + } + } + return left; +} + +CAiAlarmTreeItem *CAiAlarmTreeModel::getItem(const QModelIndex &index) const +{ + if (index.isValid()) { + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if (item) + return item; + } + return m_root; +} + +CAiAlarmTreeItem *CAiAlarmTreeModel::getItem() const +{ + return m_root; +} + +void CAiAlarmTreeModel::initFilter() +{ + m_isLevelFilterEnable = false; + m_isLocationFilterEnable = false; + m_isRegionFilterEnable = false; + m_isStatusFilterEnable = false; + m_isDeviceTypeFileter = false; + m_isKeywordEnable = false; + m_timeFilterEnable = false; + m_confirmFilterEnable = false; + m_returnFilterEnable = false; + removeDeviceGroupFilter(); +} + +void CAiAlarmTreeModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, const bool &isStationFilterEnable, const QList &stationFilter, const bool &isRegionFilterEnable, const QList ®ionFilter, const bool &isStatusFilterEnable, const QList &statusFilter, const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, const bool &isKeywordFilterEnable, const QString &keyword, const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, const bool &confirmFilterEnable, const bool &isConfirm, const bool &returnFilterEnable, const bool &isReturn) +{ + m_isLevelFilterEnable = isLevelFilterEnable; + m_levelFilter = levelFilter; + m_isLocationFilterEnable = isStationFilterEnable; + m_locationFilter = stationFilter; + m_isRegionFilterEnable = isRegionFilterEnable; + m_regionFilter = regionFilter; + m_isStatusFilterEnable = isStatusFilterEnable; + m_statusFilter2 = statusFilter; + m_statusFilter = statusFilter; + if(statusFilter.contains(OTHERSTATUS)) + { + QMap alarmOtherStatus = CAlarmBaseData::instance()->getAlarmOtherStatus(); + QMap::iterator it = alarmOtherStatus.begin(); + for(;it != alarmOtherStatus.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + m_isDeviceTypeFileter = isDeviceTypeFilter; + m_subSystem = subSystem; + m_deviceType = deviceType; + m_isKeywordEnable = isKeywordFilterEnable; + m_keyowrd = keyword; + m_timeFilterEnable = timeFilterEnable; + m_startTime = startTime; + m_endTime = endTime; + m_confirmFilterEnable = confirmFilterEnable; + m_isConfirm = isConfirm; + m_returnFilterEnable =returnFilterEnable; + m_isReturn = isReturn; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::addDeviceGroupFilter(const QString &deviceGroup) +{ + m_deviceGroupFilter.insert(deviceGroup); + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::removeDeviceGroupFilter() +{ + m_deviceGroupFilter.clear(); +} + +void CAiAlarmTreeModel::removeDeviceGroupFilter(const QString &deviceGroup) +{ + m_deviceGroupFilter.remove(deviceGroup); + slotMsgRefresh(); +} + +bool CAiAlarmTreeModel::conditionFilter(const AlarmMsgPtr ptr) +{ + //(满足所有条件就展示) + //判断是否被禁止 + if(CAlarmMsgManage::instance()->ifInhibit(ptr->key_id_tag)) + { + return false; + } + + //是否被释放 + if(ptr->releaseFlag) + { + return false; + } + + //< 车站 + if(m_isLocationFilterEnable && !m_locationFilter.contains(ptr->location_id)) + { + return false; + } + + //< 等级 + if(m_isLevelFilterEnable && !m_levelFilter.contains(ptr->priority)) + { + return false; + } + + //< 责任区 + if(m_isRegionFilterEnable && !m_regionFilter.contains(ptr->region_id)) + { + return false; + } + + //< 类型 + if(m_isStatusFilterEnable && !m_statusFilter.contains(ptr->alm_status)) + { + return false; + } + + //< 设备类型 + if(m_isDeviceTypeFileter) + { + int dev_type = CAlarmBaseData::instance()->queryDevTypeByDesc(m_deviceType); + if(dev_type != ptr->dev_type) + { + return false; + } + } + + //< 设备组 + if(m_deviceGroupFilter.contains(ptr->dev_group_tag)) + { + return false; + } + + //< 关键字 + if(m_isKeywordEnable && !ptr->content.contains(m_keyowrd)) + { + return false; + } + + //< 时间 + if(m_timeFilterEnable) + { + if(m_startTime.toMSecsSinceEpoch() >= (qint64)(ptr->time_stamp)) + { + return false; + } + if(m_endTime.toMSecsSinceEpoch() <= (qint64)(ptr->time_stamp)) + { + return false; + } + } + + //< 是否已确认 + if(m_confirmFilterEnable) + { + if(m_isConfirm) + { + if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_RETURN || + ptr->logic_state ==E_ALS_ALARM_DEL || ptr->logic_state == E_ALS_RETURN_DEL) + { + return false; + } + } + else + { + if(ptr->logic_state == E_ALS_ALARM_CFM || ptr->logic_state == E_ALS_RETURN_CFM || + ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL || ptr->logic_state == ALS_EVT_ONLY) + { + return false; + } + } + } + if(m_returnFilterEnable) + { + if(m_isReturn) + { + if(ptr->logic_state == E_ALS_ALARM || ptr->logic_state == E_ALS_ALARM_CFM || + ptr->logic_state ==E_ALS_ALARM_DEL || ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == ALS_EVT_ONLY) + { + return false; + } + } + else + { + if(ptr->logic_state == E_ALS_RETURN || ptr->logic_state == E_ALS_RETURN_CFM || + ptr->logic_state == E_ALS_RETURN_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL || ptr->logic_state == ALS_EVT_ONLY) + { + return false; + } + } + } + return true; +} + +void CAiAlarmTreeModel::conditionAiFilter(const AiAlarmMsgPtr ptr,QList &almList) +{ + //(满足一个条件就展示智能告警,但是原始告警该不展示的也不展示) + + QList almptrList = CAlarmMsgManage::instance()->getAlarmPtrByuuid(ptr->raw_alm_uuid); + for(int index(0);index < almptrList.size();index++) + { + if(conditionFilter(almptrList.at(index))) + { + almList.append(almptrList.at(index)); + } + } +} + +void CAiAlarmTreeModel::sortAlm(QList &almList) +{ + qucikSort(almList,0,almList.size()-1); +} + +void CAiAlarmTreeModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + m_isLevelFilterEnable = isCheck; + m_levelFilter = priorityFilter; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::setLocationFilter(bool &isCheck, QList &locationFilter) +{ + m_isLocationFilterEnable = isCheck; + m_locationFilter = locationFilter; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter, bool &other) +{ + m_isStatusFilterEnable = isCheck; + m_statusFilter2 = alarmTypeFilter; + m_statusFilter = alarmTypeFilter; + if(other == true) + { + QMap alarmOtherStatus = CAlarmBaseData::instance()->getAlarmOtherStatus(); + QMap::iterator it = alarmOtherStatus.begin(); + for(;it != alarmOtherStatus.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::setAlarmTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) +{ + m_timeFilterEnable = isCheck; + if(isCheck) + { + QTime time_1(0,0,0); + QTime time_2(23,59,59); + m_startTime.setDate(startTime); + m_startTime.setTime(time_1); + m_endTime.setDate(endTime); + m_endTime.setTime(time_2); + } + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::setAlarmTimeFilter(bool &isCheck) +{ + m_timeFilterEnable = isCheck; + slotMsgRefresh(); +} + +void CAiAlarmTreeModel::insertAlarmMsg(const QList &infoList) +{ + if(infoList.size() >= 1000) + { + beginResetModel(); + QList::const_iterator itpos = infoList.begin(); + while (itpos != infoList.end()) { + int left =calcLeft(*itpos); + m_root->insertChildren(left,1,m_root->columnCount()); + m_root->child(left)->setPtr(*itpos); + itpos++; + } + endResetModel(); + }else + { + QList::const_iterator itpos = infoList.begin(); + while (itpos != infoList.end()) { + int left =calcLeft(*itpos); + beginInsertRows(QModelIndex(), left, left); + m_root->insertChildren(left,1,m_root->columnCount()); + m_root->child(left)->setPtr(*itpos); + endInsertRows(); + itpos++; + } + } +} + +//过滤对智能告警下的原始告警同样起作用时修改 +void CAiAlarmTreeModel::insertAlarmMsg(const AiAlarmMsgPtr info,QList &almList) +{ + //当智能告警下的原始告警数小于500时,对此条智能告警下的原始告警排序,否则不排序 + if(almList.size()<500) + { + sortAlm(almList); + } + + if(almList.size()>=1000) + { + beginResetModel(); + int left = calcLeft(info); + m_root->insertChildren(left,1,m_root->columnCount()); + m_root->child(left)->setAiPtr(info); + + CAiAlarmTreeItem *item = m_root->child(left); + for(int num(0);numinsertChildren(num,1,m_root->columnCount()); + item->child(num)->setPtr(almList.at(num)); + } + endResetModel(); + }else + { + int left = calcLeft(info); + beginInsertRows(QModelIndex(), left, left); + m_root->insertChildren(left,1,m_root->columnCount()); + m_root->child(left)->setAiPtr(info); + endInsertRows(); + + CAiAlarmTreeItem *item = m_root->child(left); + for(int num(0);numinsertChildren(num,1,m_root->columnCount()); + item->child(num)->setPtr(almList.at(num)); + endInsertRows(); + } + } +} + +int CAiAlarmTreeModel::getShowNum() +{ + return m_nShowNum; +} + +int CAiAlarmTreeModel::getShowAi() +{ + return m_nShowAiNum; +} + +void CAiAlarmTreeModel::slotMsgArrived(QList listMsg) +{ + QList::const_iterator it = listMsg.constBegin(); + QList addMsgList; + while (it != listMsg.constEnd()) + { + if((*it)->deleteFlag != true) + { + if(conditionFilter(*it)) + { + m_nShowNum++; + addMsgList.append(*it); + } + } + ++it; + } + insertAlarmMsg(addMsgList); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeModel.h b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeModel.h new file mode 100644 index 00000000..2d0e7655 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeModel.h @@ -0,0 +1,310 @@ +#ifndef CAIALARMTREEMODEL_H +#define CAIALARMTREEMODEL_H + +#include +#include +#include + +#include +#include + +typedef QPair > PAIRLISTAIALARMINFO; +class CAiAlarmTreeModel : public QAbstractItemModel +{ + Q_OBJECT +public: + explicit CAiAlarmTreeModel(QObject *parent = nullptr); + ~CAiAlarmTreeModel(); + + void initialize(); + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + // Basic functionality: + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role); + // Add data: + bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + + // Remove data: + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + + void setModel(); + + CAiAlarmTreeItem *getItem(const QModelIndex &index) const; + + CAiAlarmTreeItem *getItem() const; + + void initFilter(); + + void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isStatusFilterEnable, const QList &statusFilter, + const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), + const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), + const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), + const QDateTime &endTime = QDateTime(), const bool &confirmFilterEnable = false, const bool &isConfirm = false, + const bool &returnFilterEnable = false, const bool &isReturn =false); + + /** + * @brief addDeviceGroupFilter 添加设备组过滤 + * @param deviceGroup 设备组名称 + */ + void addDeviceGroupFilter(const QString &deviceGroup); + void removeDeviceGroupFilter(); + /** + * @brief removeDeviceGroupFilter 移除设备组过滤 + * @param deviceGroup 设备组名称 + */ + void removeDeviceGroupFilter(const QString &deviceGroup); + + /** + * @brief conditionFilter 判断原始告警是否需要展示 + * @param ptr 原始告警智能指针 + * @return 允许返回true 否则返回false + */ + bool conditionFilter(const AlarmMsgPtr ptr); + + /** + * @brief conditionAiFilter 判断智能告警是否需要展示,并获取需要展示的原始告警 (当almList的size大于0时,则认为智能告警需要展示) + * @param ptr 智能告警智能指针 + * @param almList 获取的要展示的原始告警智能指针 + */ + void conditionAiFilter(const AiAlarmMsgPtr ptr, QList &almList); + + /** + * @brief sortAlm 对原始告警进行排序(此处是用在对智能告警二级节点上的原始告警排序) + * @param almList 需要排序的原始告警列表 + */ + void sortAlm(QList &almList); + +public: + /** + * @brief setPriorityFilter 设置优先级过滤 + * @param isCheck 是否设置 + * @param priorityFilter 过滤的条件集合 + */ + void setPriorityFilter(bool &isCheck, QList &priorityFilter); + + /** + * @brief setLocationFilter 设置车站过滤 + * @param isCheck 是否设置 + * @param locationFilter 过滤的条件集合 + */ + void setLocationFilter(bool &isCheck, QList &locationFilter); + + /** + * @brief setAlarmTypeFilter 设置告警类型过滤 + * @param isCheck 是否设置 + * @param alarmTypeFilter 过滤的条件集合 + * @param other 是否包含其他条件(此处只得是不属于下拉框中的告警类型) + */ + void setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter, bool &other); + + /** + * @brief setAlarmTimeFilter 设置告警时间过滤 + * @param isCheck 是否设置 + * @param startTime 开始时间 + * @param endTime 结束时间 + */ + void setAlarmTimeFilter(bool &isCheck, QDate &startTime,QDate &endTime); + + /** + * @brief setAlarmTimeFilter 设置是否需要时间过滤 (此处用法是告警大窗日历中点击取消调用) + * @param isCheck 是否设置 + */ + void setAlarmTimeFilter(bool &isCheck); + + /** + * @brief insertAlarmMsg 插入原始告警 + * @param infoList 原始告警智能指针集合 + */ + void insertAlarmMsg(const QList &infoList); + + /** + * @brief insertAlarmMsg 插入智能告警 + * @param info 智能告警智能指针 + * @param almList 智能告警包含的原始告警智能指针集合 + */ + void insertAlarmMsg(const AiAlarmMsgPtr info, QList &almList); + + /** + * @brief getShowNum 获取显示的原始告警数量 + * @return 原始告警数量 + */ + int getShowNum(); + + /** + * @brief getShowAi 获取显示的智能告警数量 + * @return 智能告警数量 + */ + int getShowAi(); + +public slots: + + /** + * @brief slotMsgArrived 接收原始告警 + * @param listMsg 原始告警智能智能集合 + */ + void slotMsgArrived(QList listMsg); + + /** + * @brief slotAiMsgAdd 接收智能告警 + * @param aimsgList 智能告警智能指针集合 + */ + void slotAiMsgAdd(const QList &aimsgList); + + /** + * @brief slotAiMsgRemove 接收要移除的智能告警 + * @param uuidList 要移除的智能告警uuid集合 + */ + void slotAiMsgRemove(const QList &uuidList); + + /** + * @brief slotMsgRefresh 重新获取告警数据 + */ + void slotMsgRefresh(); + + /** + * @brief sortColumn 根据列排序 + * @param column 列号 + * @param order 升序或者降序 + */ + void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); + + /** + * @brief slotMsgRemove 接收要删除的原始告警(一级节点上的) + * @param deluuid 原始告警uuid + */ + void slotMsgRemove(const QVector deluuid); + +private: + /** + * @brief setModelData 设置模型 + * @param parent 父节点指针 + */ + void setModelData(CAiAlarmTreeItem *parent); + + /** + * @brief sort 排序 + */ + void sort(); + + /** + * @brief qucikSort 快排 + * @param list 需要排序的集合 + * @param start 开始下标 + * @param last 结束下标 + */ + void qucikSort(QList &list, int start, int last); + + /** + * @brief partitionAscendingOrder 升序排序 + * @param list 排序列表 + * @param start 开始位置 + * @param last 结束位置 + * @return 排序位置 + */ + int partitionAscendingOrder(QList &list, int start, int last); + + /** + * @brief partitionAscendingOrder 降序排序 + * @param list 排序列表 + * @param start 开始位置 + * @param last 结束位置 + * @return 排序位置 + */ + int partitionDescendingOrder(QList &list, int start, int last); + + /** + * @brief qucikSort 快排 + * @param list 需要排序的集合 + * @param start 开始下标 + * @param last 结束下标 + */ + void qucikSort(QList &list, int start, int last); + + /** + * @brief partitionAscendingOrder 升序排序 + * @param list 排序列表 + * @param start 开始位置 + * @param last 结束位置 + * @return 排序位置 + */ + int partitionAscendingOrder(QList &list, int start, int last); + + /** + * @brief partitionAscendingOrder 降序排序 + * @param list 排序列表 + * @param start 开始位置 + * @param last 结束位置 + * @return 排序位置 + */ + int partitionDescendingOrder(QList &list, int start, int last); + + /** + * @brief calcLeft 计算位置 + * @param info 智能告警智能指针 + * @return 排序位置 + */ + int calcLeft(const AiAlarmMsgPtr &info); + + /** + * @brief calcLeft 计算位置 + * @param info 原始告警智能指针 + * @return 排序位置 + */ + int calcLeft(const AlarmMsgPtr &info); + +private: + + CAiAlarmTreeItem *m_root; + QVector m_header; + QList m_listHorAlignmentFlags; //< 水平对齐方式 + + //< Filter + bool m_isLevelFilterEnable; //是否按告警级别过滤 + QList m_levelFilter; //告警级别过滤 + bool m_isLocationFilterEnable; //是否按车站过滤 + QList m_locationFilter; //车站过滤 + bool m_isRegionFilterEnable; //是否按责任区过滤 + QList m_regionFilter; //责任区过滤 + bool m_isStatusFilterEnable; //是否按告警类型过滤 + QList m_statusFilter; //告警类型过滤(所有的要过滤告警状态--如果其他状态没有被勾选,则与下面的内容相同) + QList m_statusFilter2; //告警类型过滤(显示在过滤窗中的告警状态) + bool m_isDeviceTypeFileter; //设备类型过滤 + QString m_subSystem; //子系统 + QString m_deviceType; //设备类型 + bool m_isKeywordEnable; //关键字过滤 + QString m_keyowrd; //关键字 + bool m_timeFilterEnable; //是否根据时间过滤 + QDateTime m_startTime; //起始时间 + QDateTime m_endTime; //终止时间 + bool m_confirmFilterEnable; //是否根据状态确认过滤 + bool m_isConfirm; //状态是否确认 + + bool m_returnFilterEnable; //是否根据复归状态过滤 + bool m_isReturn; //是否已复归 + + + QSet m_deviceFilter; //< 设备过滤 + QSet m_pointFilter; //标签过滤 + QSet m_deviceGroupFilter; //<设备组过滤 + + E_ALARM_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + + int m_nShowNum; + int m_nShowAiNum; + +}; + +#endif // CAIALARMTREEMODEL_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeView.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeView.cpp new file mode 100644 index 00000000..2d66f53e --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeView.cpp @@ -0,0 +1,25 @@ +#include "CAiAlarmTreeView.h" +#include +#include +#include +CAiAlarmTreeView::CAiAlarmTreeView(QWidget *parent) + :QTreeView(parent) +{ + +} + +void CAiAlarmTreeView::initialize() +{ + setSortingEnabled(true); + setAlternatingRowColors(true); + header()->setDefaultAlignment(Qt::AlignCenter); + header()->setSectionResizeMode(QHeaderView::Interactive); + //header()->setSectionResizeMode(QHeaderView::ResizeToContents); + header()->setStretchLastSection(true); + //header()->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); + //header()->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + setSelectionBehavior(QAbstractItemView::SelectRows); + //setSelectionMode(QAbstractItemView::MultiSelection); + //setHorizontalScrollMode(ScrollPerPixel); + setUniformRowHeights(true); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeView.h b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeView.h new file mode 100644 index 00000000..77b60d21 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAiAlarmTreeView.h @@ -0,0 +1,15 @@ +#ifndef CAIALARMTREEVIEW_H +#define CAIALARMTREEVIEW_H + +#include + +class CAiAlarmTreeView : public QTreeView +{ + Q_OBJECT +public: + CAiAlarmTreeView(QWidget *parent = Q_NULLPTR); + + void initialize(); +}; + +#endif // CAIALARMTREEVIEW_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmBaseData.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmBaseData.cpp new file mode 100644 index 00000000..faf13bb9 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmBaseData.cpp @@ -0,0 +1,659 @@ +#include "CAlarmBaseData.h" +#include "perm_mng_api/PermMngApi.h" +#include "CAlarmCommon.h" +#include "pub_logger_api/logger.h" +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CharUtil.h" + +using namespace iot_public; +using namespace std; + +CAlarmBaseData *CAlarmBaseData::pInstance = NULL; +CAlarmBaseData *CAlarmBaseData::instance() +{ + if(pInstance == NULL) + { + pInstance = new CAlarmBaseData(); + } + return pInstance; +} + +CAlarmBaseData::~CAlarmBaseData() +{ + LOGDEBUG("~CAlarmBaseData()"); +} + +void CAlarmBaseData::destory() +{ + if(m_rtdbAccess) + { + delete m_rtdbAccess; + } + + m_rtdbAccess = Q_NULLPTR; + pInstance = NULL; + deleteLater(); +} + +void CAlarmBaseData::initData() +{ + loadPermInfo(); + loadAlarmInfoConfig(); +} + +QString CAlarmBaseData::queryPriorityDesc(int id) +{ + return m_priorityDescriptionMap.value(id,QString()); +} + +QString CAlarmBaseData::queryLocationDesc(int id) +{ + return m_locationDescriptionMap.value(id,QString()); +} + +QString CAlarmBaseData::queryRegionDesc(int id) +{ + return m_regionDescriptionMap.value(id,QString()); +} + +QString CAlarmBaseData::queryAlarmTypeDesc(int id) +{ + return m_alarmTypeDescriptionMap.value(id,QString()); +} + +QString CAlarmBaseData::queryAlarmStatusDesc(int id) +{ + return m_alarmStatusDescriptionMap.value(id,QString()); +} + +int CAlarmBaseData::queryDevTypeByDesc(QString &desc) +{ + return m_deviceTypeDescriptionMap.key(desc); +} + +QList CAlarmBaseData::getDevGroupTagList() +{ + return m_deviceGroupDescriptionMap.keys(); +} + +QMap CAlarmBaseData::getAlarmOtherStatus() +{ + return m_alarmOtherStatusDescriptionMap; +} + +CAlarmBaseData::CAlarmBaseData(QObject *parent) : + QObject(parent), + m_rtdbAccess(Q_NULLPTR) +{ + m_rtdbAccess = new iot_dbms::CRdbAccess(); + m_pWriteDb = new iot_dbms::CDbApi(DB_CONN_MODEL_WRITE); + m_pWriteDb->open(); + createSysInfoInstance(m_ptrSysInfo); + initData(); +} + +void CAlarmBaseData::loadPermInfo() +{ + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecRegionId; + std::vector vecLocationId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_VIEW, vecRegionId, vecLocationId)) + { + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + m_listPermLocationId.append(*location++); + } + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + m_listPermRegionId.append(*region++); + } + } + } +} + +void CAlarmBaseData::loadAlarmInfoConfig() +{ + loadPriorityDescription(); + loadLocationDescription(); + loadRegionDescription(); + loadAlarmTypeDescription(); + loadAlarmStatusDescription(); + loadDeviceTypeDescription(); + loadDeviceGroupDescription(); + loadAlarmShowStatusDescription(); + loadAlarmOtherStatusDescription(); +} + +int CAlarmBaseData::queryDomainIdByLocId(int loactionId) +{ + if(m_ptrSysInfo) + { + SLocationInfo stLocationInfo; + if(iotSuccess == m_ptrSysInfo->getLocationInfoById(loactionId, stLocationInfo)) + { + return stLocationInfo.nDomainId; + } + } + return CN_InvalidDomainId; +} + +bool CAlarmBaseData::queryAllPointDevGroup(int nDomainId, int nSubsystemId, const QString &strDevg, QList &pointList) +{ + if(!m_ptrSysInfo) + { + return false; + } + SAppInfo stAppInfo; + if(iotSuccess != m_ptrSysInfo->getAppInfoBySubsystemId(nSubsystemId, stAppInfo)) + { + LOGERROR("queryAllPointDevGroup 获取应用ID失败"); + return false; + } + iot_dbms::CRdbNetApi rdbNetApi; + rdbNetApi.connect(nDomainId, stAppInfo.nId); + + //< 查询所有设备 + QList devList; + if(!queryAllDeviceDevGroup(rdbNetApi, strDevg, devList)) + { + return false; + } + + //< 查询所有测点 + for(int n(0); n CAlarmBaseData::getPriorityMap() +{ + return m_priorityDescriptionMap; +} + +QMap CAlarmBaseData::getPermPriorityMap() +{ + return m_priorityPermDescriptionMap; +} + +QMap CAlarmBaseData::getPriorityOrderMap() +{ + return m_priorityOrderDescriptionMap; +} + +QMap CAlarmBaseData::getPermLocationMap() +{ + return m_locationPermDescriptionMap; +} + +QMap CAlarmBaseData::getPermRegionMap() +{ + return m_regionPermDescriptionMap; +} + +QMap CAlarmBaseData::getAlarmShowStatusMap() +{ + return m_alarmShowStatusDescriptionMap; +} + +QMap > CAlarmBaseData::getAreaLocMap() +{ + return m_areaLocMap; +} + +QMap CAlarmBaseData::getAreaInfoMap() +{ + return m_areaInfoMap; +} + +QList CAlarmBaseData::getPermLocationIdList() +{ + return m_listPermLocationId; +} + +QList CAlarmBaseData::getPermRegionIdList() +{ + return m_listPermRegionId; +} + +QList CAlarmBaseData::getPermLocationOrder() +{ + return m_listPermLocationOrder; +} + +QString CAlarmBaseData::getPermLocationDesc(const int &locationId) +{ + return m_locationPermDescriptionMap.value(locationId); +} + +void CAlarmBaseData::loadPriorityDescription() +{ + if(m_rtdbAccess->open("base", "alarm_level_define")) + { + m_priorityDescriptionMap.clear(); + m_priorityOrderDescriptionMap.clear(); + m_priorityPermDescriptionMap.clear(); + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("priority_id"); + columns.push_back("priority_order"); + columns.push_back("priority_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType order; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, order); + result.getColumnValue(nIndex, 2, value); + if(key.toInt() != 0 ) + { + m_priorityPermDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + m_priorityDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + m_priorityOrderDescriptionMap[order.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmBaseData::loadLocationDescription() +{ + m_areaInfoMap.clear(); + m_areaLocMap.clear(); + if(m_rtdbAccess->open("base", "sys_model_location_info")) + { + m_locationDescriptionMap.clear(); + m_locationPermDescriptionMap.clear(); + m_listPermLocationOrder.clear(); + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("location_id"); + columns.push_back("description"); + columns.push_back("tag_name"); + columns.push_back("location_type"); + columns.push_back("plocation_id"); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType id; + iot_dbms::CVarType desc; + iot_dbms::CVarType tag; + iot_dbms::CVarType type; + iot_dbms::CVarType pid; + result.getColumnValue(nIndex, 0, id); + result.getColumnValue(nIndex, 1, desc); + result.getColumnValue(nIndex, 2, tag); + result.getColumnValue(nIndex, 3, type); + result.getColumnValue(nIndex, 4, pid); + + if(m_listPermLocationId.contains(id.toInt())) + { + m_locationPermDescriptionMap[id.toInt()] = QString::fromStdString(desc.toStdString()); + m_listPermLocationOrder.push_back(id.toInt()); + } + m_locationDescriptionMap[id.toInt()] = QString::fromStdString(desc.toStdString()); + + + SAreaInfo info; + info.nId =id.toInt(); + info.stTag =QString::fromStdString(tag.toStdString()); + info.stDes =QString::fromStdString(desc.toStdString()); + if(type.toInt() != (int)E_LOCATION_NODE) + { + info.eType = E_LOCATION_AREA; + }else + { + info.eType = E_LOCATION_NODE; + } + + info.nPareaId =pid.toInt(); + m_areaInfoMap[info.nId] = info; + } + } + } + + QMap::iterator it= m_areaInfoMap.begin(); + while (it != m_areaInfoMap.end()) { + if(m_listPermLocationId.contains(it.key())) + { + if(it.value().eType == (int)E_LOCATION_NODE) + { + QMap >::iterator pos = m_areaLocMap.find(it.value().nPareaId); + if(pos == m_areaLocMap.end()) + { + QVector locVec; + locVec.append(it.value().nId); + m_areaLocMap.insert(it.value().nPareaId,locVec); + }else + { + QVector &locVec = pos.value(); + locVec.append(it.value().nId); + } + }else + { + QMap >::iterator pos = m_areaLocMap.find(it.key()); + if(pos == m_areaLocMap.end()) + { + QVector locVec; + locVec.append(it.value().nId); + m_areaLocMap.insert(it.key(),locVec); + }else + { + QVector &locVec = pos.value(); + locVec.append(it.value().nId); + } + } + } + it++; + } +} + +void CAlarmBaseData::loadRegionDescription() +{ + if(m_rtdbAccess->open("base", "region_info")) + { + m_regionDescriptionMap.clear(); + m_regionPermDescriptionMap.clear(); + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("region_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + if(m_listPermRegionId.contains(key.toInt())) + { + m_regionPermDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + m_regionDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + m_regionPermDescriptionMap[-1] = "无责任区";//QString(); + m_regionDescriptionMap[-1] = QString(); +} + +void CAlarmBaseData::loadAlarmTypeDescription() +{ + if(m_rtdbAccess->open("base", "alarm_type_define")) + { + m_alarmTypeDescriptionMap.clear(); + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("type_id"); + columns.push_back("type_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmBaseData::loadAlarmStatusDescription() +{ + if(m_rtdbAccess->open("base", "alarm_status_define")) + { + m_alarmStatusDescriptionMap.clear(); + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("status_value"); + columns.push_back("display_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmStatusDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmBaseData::loadDeviceTypeDescription() +{ + if(m_rtdbAccess->open("base", "dev_type_def")) + { + m_deviceTypeDescriptionMap.clear(); + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("dev_type_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmBaseData::loadDeviceGroupDescription() +{ + if(m_rtdbAccess->open("base", "dev_group")) + { + m_deviceGroupDescriptionMap.clear(); + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("tag_name"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceGroupDescriptionMap[QString::fromStdString(key.toStdString())] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CAlarmBaseData::loadAlarmShowStatusDescription() +{ + const std::string strConfFullPath = iot_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + m_alarmShowStatusDescriptionMap.clear(); + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + std::string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + if(StringToInt(strKey) != OTHERSTATUS) + { + m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; + }else + { + m_alarmShowStatusDescriptionMap[StringToInt(strKey)] = tr("其他"); + } + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CAlarmBaseData::loadAlarmOtherStatusDescription() +{ + const std::string strConfFullPath = iot_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + m_alarmOtherStatusDescriptionMap.clear(); + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + m_alarmOtherStatusDescriptionMap[StringToInt(strKey)] = m_alarmStatusDescriptionMap[StringToInt(strKey)]; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +bool CAlarmBaseData::queryAllDeviceDevGroup(iot_dbms::CRdbNetApi &rdbNetApi, const QString &devg, QList &devList) +{ + //< 查询设备组所有设备 + iot_idl::RdbQuery msgQuery; + msgQuery.set_strtablename("dev_info"); + msgQuery.add_strselectcolnamearr("tag_name"); + iot_idl::RdbCondition *pCondtion = msgQuery.add_msgcondition(); + pCondtion->set_enlogic(iot_idl::ENConditionLogic::enumCondAnd); + pCondtion->set_enrelation(iot_idl::ENConditionRelation::enumCondEqual); + pCondtion->set_strcolumnname("group_tag_name"); + iot_idl::SVariable *pCondValue = pCondtion->mutable_msgvalue(); + pCondValue->set_edatatype(iot_idl::DataType::CN_DATATYPE_STRING); + pCondValue->set_strvalue(devg.toStdString()); + + iot_idl::RdbRet retMsg; + bool bRet; + bRet = rdbNetApi.query(msgQuery, retMsg); + if (false == bRet) + { + LOGERROR("queryAllDeviceDevGroup,未查询到条目"); + return false; + } + else + { + for (int i = 0; i < retMsg.msgrecord_size(); ++i) + { + if(retMsg.msgrecord(i).msgvaluearray_size() != 1) + { + LOGERROR("queryAllDeviceDevGroup,查询结果不对"); + continue; + } + + devList.append(QString::fromStdString(retMsg.msgrecord(i).msgvaluearray(0).strvalue())); + } + } + return true; +} + +bool CAlarmBaseData::queryAllPointDevice(iot_dbms::CRdbNetApi &rdbNetApi, const QString &device, const QString &table, QList &pointList) +{ + iot_idl::RdbQuery msgQuery; + msgQuery.set_strtablename(table.toStdString().c_str()); + msgQuery.add_strselectcolnamearr("tag_name"); + iot_idl::RdbCondition *pCondtion = msgQuery.add_msgcondition(); + pCondtion->set_enlogic(iot_idl::ENConditionLogic::enumCondAnd); + pCondtion->set_enrelation(iot_idl::ENConditionRelation::enumCondEqual); + pCondtion->set_strcolumnname("device"); + iot_idl::SVariable *pCondValue = pCondtion->mutable_msgvalue(); + pCondValue->set_edatatype(iot_idl::DataType::CN_DATATYPE_STRING); + pCondValue->set_strvalue(device.toStdString().c_str()); + + iot_idl::RdbRet retMsg; + bool bRet; + bRet = rdbNetApi.query(msgQuery, retMsg); + if (false == bRet) + { + LOGERROR("queryAllPointDevice,未查询到条目"); + return false; + } + else + { + for (int i = 0; i < retMsg.msgrecord_size(); ++i) + { + if(retMsg.msgrecord(i).msgvaluearray_size() != 1) + { + LOGERROR("queryAllPointDevice,查询结果不对"); + continue; + } + + pointList.append(QString("%1.%2.%3").arg(table) + .arg(QString::fromStdString(retMsg.msgrecord(i).msgvaluearray(0).strvalue())) + .arg("value")); + } + } + return true; +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmBaseData.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmBaseData.h new file mode 100644 index 00000000..de8d32ee --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmBaseData.h @@ -0,0 +1,197 @@ +#ifndef CALARMBASEDATA_H +#define CALARMBASEDATA_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/rdb_net_api/CRdbNetApi.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include +#include "CAlarmCommon.h" +#include + +class CAlarmBaseData : public QObject +{ + Q_OBJECT +public: + static CAlarmBaseData * instance(); + + ~CAlarmBaseData(); + + void destory(); + +public: + /** + * @brief initData 初始化数据 + */ + void initData(); + /** + * @brief queryPriorityDesc 根据id查询优先级描述 + * @param id 优先级id + * @return 优先级描述 + */ + QString queryPriorityDesc(int id); + /** + * @brief queryLocationDesc 根据位置id查询位置描述 + * @param id 位置id + * @return 位置描述 + */ + QString queryLocationDesc(int id); + /** + * @brief queryRegionDesc 根据责任区id查询责任区描述 + * @param id 责任区id + * @return 责任区描述 + */ + QString queryRegionDesc(int id); + /** + * @brief queryAlarmTypeDesc 根据告警类型id查询告警类型描述 + * @param id 告警类型id + * @return 告警类型描述 + */ + QString queryAlarmTypeDesc(int id); + /** + * @brief queryAlarmStatusDesc 根据告警状态id查询告警状态描述 + * @param id 告警状态id + * @return 告警状态描述 + */ + QString queryAlarmStatusDesc(int id); + /** + * @brief queryDevTypeByDesc 根据设备类型描述查询设备类型id + * @param desc 设备描述 + * @return 设备id + */ + int queryDevTypeByDesc(QString &desc); + + QList getDevGroupTagList(); + /** + * @brief getAlarmOtherStatus 获取其他告警状态集合 + * @return 其他告警状态集合 + */ + QMap getAlarmOtherStatus(); + /** + * @brief loadAlarmInfoConfig 加载告警配置信息 + */ + void loadAlarmInfoConfig(); + + /** + * @brief queryDomainIdByLocId 通过车站ID得到域ID + * @param loactionId + */ + int queryDomainIdByLocId(int loactionId); + + bool queryAllPointDevGroup(int nDomainId, int nSubsystemId, const QString &strDevg, QList &pointList); + + QMap getPriorityMap(); + + QMap getPermPriorityMap(); + + QMap getPriorityOrderMap(); + + QMap getPermLocationMap(); + + QMap getPermRegionMap(); + + QMap getAlarmShowStatusMap(); + + QMap > getAreaLocMap(); + + QMap getAreaInfoMap(); + + QList getPermLocationIdList(); + + QList getPermRegionIdList(); + + QList getPermLocationOrder(); + + QString getPermLocationDesc(const int &locationId); + +private: + explicit CAlarmBaseData(QObject *parent = nullptr); + /** + * @brief loadPermInfo 加载权限 + */ + void loadPermInfo(); + + /** + * @brief loadPriorityDescription 加载优先级描述 + */ + void loadPriorityDescription(); + /** + * @brief loadLocationDescription 加载位置描述 + */ + void loadLocationDescription(); + /** + * @brief loadRegionDescription 加载责任区描述 + */ + void loadRegionDescription(); + /** + * @brief loadAlarmTypeDescription 加载告警类型 + */ + void loadAlarmTypeDescription(); + /** + * @brief loadAlarmStatusDescription 加载告警状态描述 + */ + void loadAlarmStatusDescription(); + /** + * @brief loadDeviceTypeDescription 加载设备类型描述 + */ + void loadDeviceTypeDescription(); + /** + * @brief loadDeviceGroupDescription 加载设备组描述 + */ + void loadDeviceGroupDescription(); + /** + * @brief loadAlarmShowStatusDescription 加载需要显示在告警窗下拉框中的告警状态描述 + */ + void loadAlarmShowStatusDescription(); + /** + * @brief loadAlarmOtherStatusDescription 加载其他告警状态描述 + */ + void loadAlarmOtherStatusDescription(); + + /** + * @brief queryAllDeviceDevGroup 查询设备组下所有设备 + * @param rdbNetApi + * @param devg + */ + bool queryAllDeviceDevGroup(iot_dbms::CRdbNetApi &rdbNetApi, const QString &devg, QList &devList); + /** + * @brief queryAllPointDevice 查询表中设备下所有测点 + * @param rdbNetApi + * @param device + * @param table + * @param pointList "digital.station.G01_dlq.r.value" + * @return + */ + bool queryAllPointDevice(iot_dbms::CRdbNetApi &rdbNetApi, const QString &device, const QString &table, QList &pointList); + +private: + static CAlarmBaseData * pInstance; + iot_dbms::CRdbAccess * m_rtdbAccess; + iot_dbms::CDbApi *m_pWriteDb; + iot_public::CSysInfoInterfacePtr m_ptrSysInfo; + QList m_listPermLocationId; //< 原始告警车站权限 + QList m_listPermRegionId; //< 原始告警责任区权限 + QList m_listPermLocationOrder; //< 有权限的loaction_id: 按location_no排序 + + QMap m_priorityDescriptionMap; + QMap m_priorityPermDescriptionMap; + QMap m_priorityOrderDescriptionMap; + QMap m_locationDescriptionMap; + QMap m_regionDescriptionMap; + QMap m_locationPermDescriptionMap; //有权限的 + QMap m_regionPermDescriptionMap; //有权限的 + QMap m_alarmTypeDescriptionMap; + QMap m_alarmStatusDescriptionMap; + QMap m_deviceTypeDescriptionMap; + QMap m_deviceGroupDescriptionMap; + QMap m_alarmShowStatusDescriptionMap; + QMap m_alarmOtherStatusDescriptionMap; + + + QMap m_areaInfoMap; //区域信息 + + QMap > m_areaLocMap; //区域映射 +}; + +#endif // CALARMBASEDATA_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorInfo.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorInfo.cpp new file mode 100644 index 00000000..023dd0cb --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorInfo.cpp @@ -0,0 +1,6 @@ +#include "CAlarmColorInfo.h" + +CAlarmColorInfo::CAlarmColorInfo() +{ + +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorInfo.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorInfo.h new file mode 100644 index 00000000..c50aeb2b --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorInfo.h @@ -0,0 +1,21 @@ +#ifndef CALARMCOLORINFO_H +#define CALARMCOLORINFO_H + +#include + +class CAlarmColorInfo +{ +public: + CAlarmColorInfo(); + + int priority; + QColor background_color; + QColor alternating_color; + QColor confirm_color; + QColor active_text_color; + QColor resume_text_color; + QColor confirm_text_color; + QString icon; +}; + +#endif // CALARMCOLORINFO_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorWidget.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorWidget.cpp new file mode 100644 index 00000000..828df000 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorWidget.cpp @@ -0,0 +1,129 @@ +#include "CAlarmColorWidget.h" +#include "ui_CAlarmColorWidget.h" +#include +#include "CAlarmSetMng.h" + +CAlarmColorWidget::CAlarmColorWidget(CAlarmColorInfo *info, QWidget *parent) : + QWidget(parent), + ui(new Ui::CAlarmColorWidget), + m_info(info) +{ + ui->setupUi(this); + ui->label_2->installEventFilter(this); + ui->label_4->installEventFilter(this); + ui->label_6->installEventFilter(this); + ui->label_9->installEventFilter(this); + + QString title = CAlarmSetMng::instance()->getPriorityDescByOrder(m_info->priority); + title+=":"; + ui->label_7->setText(title); + updateColorLabel(ui->label_2, m_info->active_text_color); + updateColorLabel(ui->label_4, m_info->resume_text_color); + updateColorLabel(ui->label_6, m_info->confirm_text_color); + updateColorLabel(ui->label_9, m_info->alternating_color); +} + +CAlarmColorWidget::~CAlarmColorWidget() +{ + delete ui; +} + +bool CAlarmColorWidget::eventFilter(QObject *watched, QEvent *event) +{ + if(watched == ui->label_2) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label_2, &(m_info->active_text_color)); + }else + { + return false; + } + }else + { + return false; + } + }else if(watched == ui->label_4) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label_4, &(m_info->resume_text_color)); + }else + { + return false; + } + }else + { + return false; + } + }else if(watched == ui->label_6) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label_6, &(m_info->confirm_text_color)); + }else + { + return false; + } + }else + { + return false; + } + }else if(watched == ui->label_9) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label_9, &(m_info->alternating_color)); + }else + { + return false; + } + }else + { + return false; + } + }else + { + return QWidget::eventFilter(watched,event); + } + return true; +} + +void CAlarmColorWidget::chooseColor(QLabel *label, QColor *color) +{ + QColor newColor=QColorDialog::getColor(*color,this); + if(newColor.isValid()){ + *color=newColor; + updateColorLabel(label,*color); + } +} + +void CAlarmColorWidget::updateColorLabel(QLabel *label, const QColor &color) +{ + label->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(color.red()).arg(color.green()).arg(color.blue())); + if(label == ui->label_2) + { + m_info->active_text_color = color; + }else if(label == ui->label_4) + { + m_info->resume_text_color = color; + }else if(label == ui->label_6) + { + m_info->confirm_text_color = color; + }else if(label == ui->label_9) + { + m_info->alternating_color = color; + } +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorWidget.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorWidget.h new file mode 100644 index 00000000..e1dfaed4 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorWidget.h @@ -0,0 +1,31 @@ +#ifndef CALARMCOLORWIDGET_H +#define CALARMCOLORWIDGET_H + +#include +#include +#include "CAlarmColorInfo.h" +#include + +namespace Ui { +class CAlarmColorWidget; +} + +class CAlarmColorWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CAlarmColorWidget(CAlarmColorInfo *info,QWidget *parent = 0); + ~CAlarmColorWidget(); + bool eventFilter(QObject *watched, QEvent *event); + +private: + void chooseColor(QLabel *label, QColor *color); + void updateColorLabel(QLabel *label, const QColor &color); + +private: + Ui::CAlarmColorWidget *ui; + CAlarmColorInfo *m_info; +}; + +#endif // CALARMCOLORWIDGET_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorWidget.ui b/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorWidget.ui new file mode 100644 index 00000000..6acb5c24 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmColorWidget.ui @@ -0,0 +1,151 @@ + + + CAlarmColorWidget + + + + 0 + 0 + 455 + 36 + + + + Form + + + + 0 + + + 0 + + + 9 + + + + + + + 动作颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + 恢复颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + 确认颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + 闪烁颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 40 + 16777215 + + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmCommon.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmCommon.h new file mode 100644 index 00000000..ec5d03b9 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmCommon.h @@ -0,0 +1,103 @@ +#ifndef CALARMCOMMON_H +#define CALARMCOMMON_H + +#include +class CAlarmMsgInfo; +class CAiAlarmMsgInfo; + +typedef QSharedPointer AlarmMsgPtr; +typedef QSharedPointer AiAlarmMsgPtr; +typedef QPair > PAIRLISTALARMINFO; + + +const QString fun_ia_edit = "FUNC_NOM_IA_EDIT"; //智能告警编辑权限 +#define FUNC_SPE_ALARM_VIEW ("FUNC_SPE_ALARM_VIEW") +#define OPT_FUNC_SPE_OPT_OVERRIDE ("FUNC_SPE_OPT_OVERRIDE") + +#define VIDEO_TIME 30*1000 +#define FAULT_RECORD_TIME 30*1000 +#define BUTTON_COLUMN 8 //按钮所在列 +#define ICON_COLUMN 1 //图标所在列 +const int OTHERSTATUS = 9999; +//窗口 +enum E_Alarm_Mode +{ + E_Alarm_Dock, + E_Alarm_Window, + E_Alarm_Pop +}; +enum E_TAGNAME_TYPE +{ + E_TAGNAME_ANA =0, + E_TAGNAME_ACC, + E_TAGNAME_MIX, + E_TAGNAME_DIG, + E_TAGNAME_ERROR +}; +//排序 +enum E_ALARM_SORTKEY +{ + E_SORT_TIME=0, //< 时间戳 + E_SORT_PRIORITY , //< 优先级 + E_SORT_LOCATION, //< 车站 + E_SORT_REGION, //< 责任区 + E_SORT_TYPE, //< 告警类型 + E_SORT_ALM_STATE, //< 告警状态 + E_SORT_STYLE, //< 复归状态 + E_SORT_LOGICSTATE, //< 逻辑状态 + E_SORT_CONTENT //< 告警内容 +}; +//告警动作 +enum E_ALARM_SOUND_VOICE +{ + E_ALARM_SOUND = 0, //声音告警 + E_ALARM_VOICE //语音告警 +}; +//告警方式 +enum E_ALARM_STYLE{ + E_STYLE_REPEAT_X = -2, + E_STYLE_REPEAT = -1, + E_STYLE_NO_ALARM = 0 +}; + +enum E_LOCATION_TYPE +{ + E_LOCATION_NODE = 0, + E_LOCATION_AREA +}; + +struct SAiConfirm +{ + int nConfirm; + int nTotal; + SAiConfirm() { + nConfirm = 0; + nTotal = 0; + } +}; + +struct SAreaInfo +{ + int nId; + QString stTag; + QString stDes; + E_LOCATION_TYPE eType; + int nPareaId; + SAreaInfo() { + nId = -1; + stTag = QString(); + stDes = QString(); + eType = E_LOCATION_NODE; + nPareaId = -1; + } +}; + +struct SDevGroupInfo{ + QString tag_name; + QString description; + int domain; + int location; + int sub_system; + int region; +}; +#endif // CALARMCOMMON_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmDataCollect.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDataCollect.cpp new file mode 100644 index 00000000..8edbd432 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDataCollect.cpp @@ -0,0 +1,356 @@ +#include "CAlarmDataCollect.h" +#include +#include "pub_logger_api/logger.h" +#include "CAlarmMsgManage.h" +#include +#include "CAiAlarmDataCollect.h" +#include "alarm_server_api/AlarmCommonDef.h" + +using namespace iot_service; +using namespace iot_dbms; +CAlarmDataCollect * CAlarmDataCollect::m_pInstance = NULL; + +CAlarmDataCollect::CAlarmDataCollect() + : CAlmApiForAlmClt(), + m_referenceCount(0), + m_bFaultRecallState(false), + m_pAlternateTimer(Q_NULLPTR), m_rtdbAlmLvlDefTab(nullptr), m_rtdbAlmActDefTab(nullptr), + m_bIsNeedUpdate(false), + m_bIsNeedRemove(false), m_bIsNeedRelease(false), + m_removeNum(0) +{ + m_rtdbMutex = new QMutex(); + m_rtdbAccess = new iot_dbms::CRdbAccess(); + m_rtdbAccess->open("base", "alarm_level_define"); +} + +CAlarmDataCollect::~CAlarmDataCollect() +{ + LOGINFO("CAlarmDataCollect::~CAlarmDataCollect()"); + qDebug() << "~CAlarmDataCollect()"; +} + +void CAlarmDataCollect::refrence() +{ + m_referenceCount++; +} + +CAlarmDataCollect *CAlarmDataCollect::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CAlarmDataCollect(); + } + return m_pInstance; +} + +void CAlarmDataCollect::initialize() +{ + resumeThread(); + if(!m_pAlternateTimer) + { + m_pAlternateTimer = new QTimer(); + m_pAlternateTimer->setInterval(1000); + connect(m_pAlternateTimer, &QTimer::timeout, this, &CAlarmDataCollect::slotAlarmStateChanged); + connect(this, &CAlarmDataCollect::sigTimerShot, this, &CAlarmDataCollect::slotTimerShot, Qt::QueuedConnection); + } + if(!m_bFaultRecallState) + { + emit sigTimerShot(true); + } +} + +void CAlarmDataCollect::release() +{ + LOGINFO("CAlarmDataCollect::release()"); + emit sigTimerShot(false); + suspendThread(true); + QMutexLocker locker(m_rtdbMutex); + m_bIsNeedUpdate = false; + m_bIsNeedRemove = false; + m_removeNum = 0; +} + + +int CAlarmDataCollect::getRefrenceCount() +{ + return m_referenceCount; +} + +bool CAlarmDataCollect::isFaultRecallState() +{ + return m_bFaultRecallState; +} + +void CAlarmDataCollect::destory() +{ + LOGINFO("退出时:CAlarmDataCollect::destory()打开窗口的个数m_referenceCount:[%d]",m_referenceCount); + if(--m_referenceCount > 0) + { + return; + } + slotTimerShot(false); + suspendThread(); + { + QMutexLocker locker(m_rtdbMutex); + if(Q_NULLPTR != m_pAlternateTimer) + { + m_pAlternateTimer->stop(); + m_pAlternateTimer->deleteLater(); + } + m_pAlternateTimer = Q_NULLPTR; + m_bIsNeedUpdate = false; + m_bIsNeedRemove = false; + } + delete m_rtdbMutex; + delete m_rtdbAccess; + m_pInstance = NULL; + delete this; +} + +void CAlarmDataCollect::slotTimerShot(const bool start) +{ + if(m_pAlternateTimer) + { + if(start) + { + m_pAlternateTimer->start(); + } + else + { + m_pAlternateTimer->stop(); + } + } +} + +void CAlarmDataCollect::slotSwitchFaultRecallState(bool bFaultRecallState) +{ + m_bFaultRecallState = bFaultRecallState; + release(); + m_pInstance->reinit(m_bFaultRecallState); + CAiAlarmDataCollect::instance()->slotSwitchFaultRecallState(bFaultRecallState); + emit sigAlarmStateChanged(0, 0); + emit sigMsgRefresh(); + + initialize(); + CAiAlarmDataCollect::instance()->initialize(); + + emit sigAlarmOperateEnable(!m_bFaultRecallState); +} + +bool CAlarmDataCollect::requestCfmAlm(iot_idl::SAlmCltCfmAlm &objCfmAlm) +{ + return iot_service::CAlmApiForAlmClt::requestCfmAlm(objCfmAlm); +} + +bool CAlarmDataCollect::requestDelAlm(iot_idl::SAlmCltDelAlm &objDelAlm) +{ + return iot_service::CAlmApiForAlmClt::requestDelAlm(objDelAlm); +} + +void CAlarmDataCollect::handleAllAlmMsg(int domainId, iot_idl::SAlmCltAddAlm &objAllAlm) +{ + if(!m_referenceCount) + { + return; + } + LOGINFO("========== AlarmDataCollect handleAllAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + //< 清空该域缓存 + + CAlarmMsgManage::instance()->removeAlarmMsgByDomainID(domainId); + + //< 构建告警 + int nAlarmCount = objAllAlm.alm_info_size(); + QList almList; + for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) + { + iot_idl::SAlmInfoToAlmClt msg = objAllAlm.alm_info(nAddMsgIndex); + AlarmMsgPtr alm(new CAlarmMsgInfo()); + alm->initialize(msg); + alm->priorityOrder = queryPriorityOrder(alm->priority); + //是否需要视频告警 + int alarmAction = queryAlarmAction(alm->priority); + if(!alm->m_camera.isEmpty() && !alm->m_preset.isEmpty() && (ALM_ACT_VIDEO_ALM == (alarmAction & ALM_ACT_VIDEO_ALM))) + { + alm->m_needVideoAlm = true; + }else + { + alm->m_needVideoAlm = false; + } + almList.append(alm); + } + CAlarmMsgManage::instance()->addAlarmMsg(almList); + emit sigDevTreeUpdate(); + emit sigMsgRefresh(); + + LOGDEBUG("handleAllAlmMsg END[%d] ",nAlarmCount); + if(m_bFaultRecallState) + { + int total = CAlarmMsgManage::instance()->getAlarmTotalSize(); + int unConfirm = CAlarmMsgManage::instance()->getUnConfirmSize(); + emit sigAlarmStateChanged(total, unConfirm); + emit sigUpdateAlarmView(); + } +} + +void CAlarmDataCollect::handleAddAlmMsg(iot_idl::SAlmCltAddAlm &objAddAlm) +{ + if(!m_referenceCount) + { + return; + } + LOGINFO("========== AlarmDataCollect handleAddAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + //< 构建告警 + int nAlarmCount = objAddAlm.alm_info_size(); + QList almList; + for(int nAddMsgIndex(0); nAddMsgIndex < nAlarmCount; nAddMsgIndex++) + { + iot_idl::SAlmInfoToAlmClt msg = objAddAlm.alm_info(nAddMsgIndex); + AlarmMsgPtr alm(new CAlarmMsgInfo()); + alm->initialize(msg); + alm->priorityOrder = queryPriorityOrder(alm->priority); + //是否需要视频告警 + int alarmAction = queryAlarmAction(alm->priority); + if(!alm->m_camera.isEmpty() && !alm->m_preset.isEmpty() && (ALM_ACT_VIDEO_ALM == (alarmAction & ALM_ACT_VIDEO_ALM))) + { + alm->m_needVideoAlm = true; + }else + { + alm->m_needVideoAlm = false; + } + almList.append(alm); + } + CAlarmMsgManage::instance()->addAlarmToAllInfo(almList); + CAlarmMsgManage::instance()->addAlarmCacheMsg(almList); + LOGINFO("handleAddAlmMsg END[%d] ",nAlarmCount); +} + +void CAlarmDataCollect::handleCfmAlmMsg(iot_idl::SAlmCltCfmAlm &objCfmAlm) +{ + if(!m_referenceCount) + { + return; + } + LOGINFO("========== AlarmDataCollect handleCfmAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + QList uuidList; + int nAlarmCount = objCfmAlm.uuid_base64_size(); + for(int nCfmMsgIndex(0); nCfmMsgIndex < nAlarmCount; nCfmMsgIndex++) + { + QString uuid = QString::fromStdString(objCfmAlm.uuid_base64(nCfmMsgIndex)); + uuidList.append(uuid); + } + CAlarmMsgManage::instance()->confirmAlarmMsg(uuidList); + m_bIsNeedUpdate = true; + LOGINFO("handleCfmAlmMsg END[%d] ",nAlarmCount); +} + +void CAlarmDataCollect::handleDelAlmMsg(iot_idl::SAlmCltDelAlm &objDelAlm) +{ + if(!m_referenceCount) + { + return; + } + + LOGINFO("========== AlarmDataCollect handleDelAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + QList uuidList; + int nAlarmCount = objDelAlm.uuid_base64_size(); + for(int nDelMsgIndex(0); nDelMsgIndex < nAlarmCount; nDelMsgIndex++) + { + QString uuid = QString::fromStdString(objDelAlm.uuid_base64(nDelMsgIndex)); + uuidList.append(uuid); + } + int size = CAlarmMsgManage::instance()->removeAlarmMsg(uuidList); + m_removeNum += size; + m_bIsNeedRemove = true; + LOGINFO("handleDelAlmMsg END[%d] ",nAlarmCount); +} + +void CAlarmDataCollect::handleReleaseAlmMsg(iot_idl::SAlmCltReleaseAlm &objRelAlm) +{ + if(!m_referenceCount) + { + return; + } + LOGINFO("========== AlarmDataCollect handleReleaseAlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + int nAlarmCount = objRelAlm.uuid_base64_size(); + QList uuidList; + for(int nRelMsgIndex(0); nRelMsgIndex < nAlarmCount; nRelMsgIndex++) + { + QString uuid = QString::fromStdString(objRelAlm.uuid_base64(nRelMsgIndex)); + uuidList.append(uuid); + } + int size = CAlarmMsgManage::instance()->removeAlarmMsg(uuidList); + m_removeNum += size; + m_bIsNeedRemove = true; + CAlarmMsgManage::instance()->releaseAlarmMsg(uuidList); + LOGINFO("handleReleaseAlmMsg END[%d] ",nAlarmCount); +} + +void CAlarmDataCollect::handleLinkWave2AlmMsg(iot_idl::SAlmCltLinkWave2Alm &objWave2Alm) +{ + if(!m_referenceCount) + { + return; + } + LOGINFO("========== CAlarmDataCollect handleLinkWave2AlmMsg =========="); + QMutexLocker locker(m_rtdbMutex); + QString waveFile = QString::fromStdString(objWave2Alm.wave_file()); + int nAlarmCount = objWave2Alm.uuid_base64_size(); + QList uuidList; + for(int nRelMsgIndex(0); nRelMsgIndex < nAlarmCount; nRelMsgIndex++) + { + QString uuid = QString::fromStdString(objWave2Alm.uuid_base64(nRelMsgIndex)); + uuidList.append(uuid); + } + CAlarmMsgManage::instance()->linkWave2AlmMsg(uuidList,waveFile); +} + +void CAlarmDataCollect::refresh() +{ + emit sigMsgRefresh(); +} + +void CAlarmDataCollect::slotAlarmStateChanged() +{ + QMutexLocker locker(m_rtdbMutex); + CAlarmMsgManage::instance()->msgArrived(); + if(m_bIsNeedUpdate) + { + emit sigMsgConfirm(); + m_bIsNeedUpdate = false; + } + + if(m_bIsNeedRemove) + { + emit sigMsgRemove(m_removeNum); + m_removeNum = 0; + m_bIsNeedRemove = false; + } + int total = CAlarmMsgManage::instance()->getAlarmTotalSize(); + int unConfirm = CAlarmMsgManage::instance()->getUnConfirmSize(); + //CAlarmMsgManage::instance()->output(); + emit sigAlarmStateChanged(total, unConfirm); + emit sigUpdateAlarmView(); + emit sigDevTreeUpdate(); +} + +int CAlarmDataCollect::queryPriorityOrder(int &id) +{ + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CVarType value = -1000; + m_rtdbAccess->getColumnValueByKey((void*)&id, "priority_order", value); + return value.toInt(); +} + +int CAlarmDataCollect::queryAlarmAction(const int &priority) +{ + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CVarType value; + m_rtdbAccess->getColumnValueByKey((void*)&priority, "alarm_actions",value); + return value.toInt(); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmDataCollect.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDataCollect.h new file mode 100644 index 00000000..42bdef11 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDataCollect.h @@ -0,0 +1,111 @@ +#ifndef CALARMDATACOLLECT_H +#define CALARMDATACOLLECT_H + +#include +#include +#include +#include +#include +#include "AlarmMessage.pb.h" +#include "CAlarmMsgInfo.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dbms/rdb_api/CRdbAccess.h" + +class CAlarmDataCollect : public QObject, public iot_service::CAlmApiForAlmClt +{ + Q_OBJECT +public: + static CAlarmDataCollect *instance(); + + virtual ~CAlarmDataCollect(); + + void refrence(); + + int getRefrenceCount(); + + bool isFaultRecallState(); + + virtual bool requestCfmAlm(iot_idl::SAlmCltCfmAlm &objCfmAlm); + + virtual bool requestDelAlm(iot_idl::SAlmCltDelAlm &objDelAlm); + + virtual void handleAllAlmMsg(int domainId, iot_idl::SAlmCltAddAlm &objAllAlm); + + virtual void handleAddAlmMsg(iot_idl::SAlmCltAddAlm &objAddAlm); + + virtual void handleCfmAlmMsg(iot_idl::SAlmCltCfmAlm &objCfmAlm); + + virtual void handleDelAlmMsg(iot_idl::SAlmCltDelAlm &objDelAlm); + + virtual void handleReleaseAlmMsg(iot_idl::SAlmCltReleaseAlm &objDelAlm); + + virtual void handleLinkWave2AlmMsg(iot_idl::SAlmCltLinkWave2Alm &objWave2Alm); + + void refresh(); +signals: + //< 启停定时器 + void sigTimerShot(const bool bStop); + + //< 定时更新,通知model刷新界面 + void sigUpdateAlarmView(); + + //< 通知所有告警插件禁用/使能告警操作 + void sigAlarmOperateEnable(const bool &bEnable); + + //< 通知model重新拉取告警消息 + void sigMsgRefresh(); + + //< 通知model告警消息到达 + //void sigMsgArrived(); + + //< 通知model告警消息确认 + void sigMsgConfirm(); + + //< 通知model告警消息删除(原始告警 删除数量) + void sigMsgRemove(int removeNum); + + //< 告警数量或状态改变时触发。 + void sigAlarmStateChanged(int total, int unConfirm); + + void sigDevTreeUpdate(); + +public slots: + + void initialize(); + + void release(); + + void destory(); + + void slotTimerShot(const bool start); + + void slotSwitchFaultRecallState(bool bFaultRecallState); + +private: + CAlarmDataCollect(); + + int queryPriorityOrder(int &id); + int queryAlarmAction(const int &priority); + +private slots: + void slotAlarmStateChanged(); + +private: + int m_referenceCount; + bool m_bFaultRecallState; //是否处于事故追忆 + QMutex * m_rtdbMutex; + QTimer * m_pAlternateTimer; + iot_dbms::CRdbAccess * m_rtdbAccess; + iot_dbms::CRdbAccess * m_rtdbAlmLvlDefTab; // 告警等级定义表 + iot_dbms::CRdbAccess * m_rtdbAlmActDefTab; // 告警动作定义表 + bool m_bIsNeedUpdate; //< 是否消息确认(每秒更新) + bool m_bIsNeedRemove; //< 是否需要删除(每秒更新) + bool m_bIsNeedRelease; //< 是否需要释放(每秒更新)- + static CAlarmDataCollect * m_pInstance; + + //1秒需要删除的条数 (在这里统计这个,原因是当删除大量数据时,一条一条删除没有重置模型效率高,此处当大于1000时,会重置模型,小于的话,则一条一条删) + //beginRemoveRows() 和beginResetModel() 没有深入研究临界值,目前先采用1000 + int m_removeNum; +}; + +#endif // CALARMDATACOLLECT_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmDelegate.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDelegate.cpp new file mode 100644 index 00000000..6fc50c49 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDelegate.cpp @@ -0,0 +1,307 @@ +#include +#include +#include +#include "CAlarmDelegate.h" +#include "CAlarmMsgInfo.h" +#include "CAlarmItemModel.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" +#include +#include +#include "pub_logger_api/logger.h" +#include + +CAlarmDelegate::CAlarmDelegate(CAlarmItemModel * model, QObject *parent) + : QStyledItemDelegate(parent), + m_pModel(model), + m_isFlash(false), + m_enableTrend(true), + m_enableLevel(false), + m_enableVideo(true), + m_enableWave(true), + m_selectIsEmpty(false) +{ + slotLoadConfig(); +} + +void CAlarmDelegate::setEnableTrend(bool isNeed) +{ + m_enableTrend = isNeed; +} + +void CAlarmDelegate::setEnableLevel(bool isNeed) +{ + m_enableLevel = isNeed; +} + +void CAlarmDelegate::setEnableVideo(bool isNeed) +{ + m_enableVideo = isNeed; +} + +void CAlarmDelegate::setEnableWave(bool isNeed) +{ + m_enableWave = isNeed; +} + +void CAlarmDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if(!index.isValid()) + { + return; + } + QColor fillColor; + QColor penColor; + bool select = option.state & QStyle::State_Selected; + //< Dock Empty + if(E_Alarm_Dock == m_pModel->getAlarmMode() && 0 == m_pModel->getShowAlarmCount()) + { + painter->fillRect(option.rect, m_emptyBackgroundColor); + if(CAlarmItemModel::CONTENT == index.column() && parent()) + { + QRect rt = option.rect; + QWidget * parentWidget = dynamic_cast(parent()); + if(parentWidget) + { + rt.setLeft(0); + rt.setWidth(parentWidget->width()); + painter->save(); + painter->setPen(m_emptyTipColor); + painter->drawText(rt, Qt::AlignHCenter | Qt::AlignVCenter, m_emptyTip); + painter->restore(); + } + } + return; + } + + //< Common + AlarmMsgPtr info = m_pModel->getAlarmInfo(index); + + + if(info != Q_NULLPTR) + { + painter->save(); + + if(E_ALS_RETURN == info->logic_state) + { + if(select) + { + fillColor = m_select_background_color; + if(m_selectIsEmpty) + { + penColor = m_colorMap.value(info->priorityOrder).resume_text_color; + }else + { + penColor = m_select_text_color; + } + } + else + { + if(m_isFlash && m_pModel->alternate()) + { + penColor = m_colorMap.value(info->priorityOrder).alternating_color; + } + else + { + penColor = m_colorMap.value(info->priorityOrder).resume_text_color; + } + fillColor = m_colorMap.value(info->priorityOrder).background_color; + } + }else if(E_ALS_ALARM == info->logic_state) + { + if(select) + { + fillColor = m_select_background_color; + if(m_selectIsEmpty) + { + penColor = m_colorMap.value(info->priorityOrder).active_text_color; + }else + { + penColor = m_select_text_color; + } + } + else + { + if(m_isFlash && m_pModel->alternate()) + { + penColor = m_colorMap.value(info->priorityOrder).alternating_color; + } + else + { + penColor = m_colorMap.value(info->priorityOrder).active_text_color; + } + fillColor = m_colorMap.value(info->priorityOrder).background_color; + } + }else + { + if(select) + { + fillColor = m_select_background_color; + } + else + { + fillColor = m_colorMap.value(info->priorityOrder).confirm_color; + } + penColor = m_colorMap.value(info->priorityOrder).confirm_text_color; + } + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + + if(m_enableLevel && ICON_COLUMN == index.column()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(12, option.rect.height()/2-10, -(option.rect.width()-40), -(option.rect.height()/2-10)); + QString file = m_colorMap.value(info->priorityOrder).icon; + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(file); + button.features = QStyleOptionButton::Flat; + + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + if(m_enableVideo && BUTTON_COLUMN == index.column() && info->m_needVideoAlm) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40, option.rect.height()/2-10, -12, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strVideoPath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + if( m_enableTrend && BUTTON_COLUMN == index.column() && (info->m_tagname_type == E_TAGNAME_ANA || info->m_tagname_type == E_TAGNAME_ACC)) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40 -40, option.rect.height()/2-10, -12-40, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strTrendPath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + if(m_enableWave && BUTTON_COLUMN == index.column() && !info->wave_file.isEmpty()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40-40-40, option.rect.height()/2-10, -12-40-40, -(option.rect.height()/2-10)); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(m_strWavePath); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + + painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); + painter->restore(); + } +} + +bool CAlarmDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if(!index.isValid()) + { + return false; + } + if(index.column() != BUTTON_COLUMN) + { + return false; + } + AlarmMsgPtr info = m_pModel->getAlarmInfo(index); + QMouseEvent *mouseEvent = static_cast(event); + if(info && m_enableVideo && info->m_needVideoAlm) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 42, option.rect.height()/2-10, -10, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QString pointTag = info->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + emit openVideo(info->domain_id,info->app_id,pointTag,info->time_stamp-VIDEO_TIME,info->time_stamp+VIDEO_TIME); + } + } + } + if(info && m_enableTrend && (info->m_tagname_type == E_TAGNAME_ACC || info->m_tagname_type == E_TAGNAME_ANA )) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 82, option.rect.height()/2-10, -50, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QStringList trendList; + trendList.append(info->key_id_tag); + emit openTrend(info->time_stamp,trendList); + } + } + } + if(info && m_enableWave && !info->wave_file.isEmpty()) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 122, option.rect.height()/2-10, -90, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QString wave = info->wave_file; + wave = QString("%1%2%3").arg("\"").arg(wave).arg("\""); + LOGINFO("录波文件为:%s",wave.toStdString().c_str()); + + const std::string strProc = std::move(iot_public::CFileUtil::getPathOfBinFile( + std::string("WaveAnalyze") + iot_public::CFileUtil::getProcSuffix())); + if(strProc.empty()) + LOGERROR("未找到可执行文件WaveAnalyze"); + else + QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(wave)); + } + } + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +void CAlarmDelegate::slotLoadConfig() +{ + CAlarmSetMng::instance()->getColorMap(m_colorMap); + CAlarmSetMng::instance()->getSelectInfo(m_selectIsEmpty,m_select_background_color,m_select_text_color); + CAlarmSetMng::instance()->getEmptyInfo(m_emptyBackgroundColor,m_emptyTipColor,m_emptyTip); + //CAlarmColorMng::instance()->getActAndFunc(m_act,m_func); + if(E_Alarm_Pop == m_pModel->getAlarmMode()) + { + m_isFlash = false; + } + else if(E_Alarm_Dock == m_pModel->getAlarmMode()) + { + m_isFlash = true; + } + else if(E_Alarm_Window == m_pModel->getAlarmMode()) + { + m_isFlash = false; + } + + std::string style = iot_public::CFileStyle::getCurStyle(); + m_strTrendPath = iot_public::CFileUtil::getPathOfResFile("gui/icon/alarm/trend_"+style+".png").c_str(); + m_strVideoPath = iot_public::CFileUtil::getPathOfResFile("gui/icon/alarm/video_"+style+".png").c_str(); + m_strWavePath = iot_public::CFileUtil::getPathOfResFile("gui/icon/alarm/wave_"+style+".png").c_str(); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmDelegate.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDelegate.h new file mode 100644 index 00000000..ab7fa038 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDelegate.h @@ -0,0 +1,53 @@ +#ifndef CALARMDELEGATE_H +#define CALARMDELEGATE_H + +#include +#include "CAlarmSetMng.h" + +class CAlarmItemModel; + +class CAlarmDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CAlarmDelegate(CAlarmItemModel *model, QObject *parent = 0); + void setEnableTrend(bool isNeed); + void setEnableLevel(bool isNeed); + void setEnableVideo(bool isNeed); + void setEnableWave(bool isNeed); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + bool editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; + +signals: + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + void openTrend(quint64 time_stamp,QStringList tagList); + +public slots: + void slotLoadConfig(); + +private: + CAlarmItemModel * m_pModel; + bool m_isFlash; + + bool m_enableTrend; + bool m_enableLevel; + bool m_enableVideo; + bool m_enableWave; + + QMap m_colorMap; + QColor m_select_background_color,m_select_text_color; //选中告警背景色和文字颜色 + bool m_selectIsEmpty; + + QColor m_emptyBackgroundColor,m_emptyTipColor; + QString m_emptyTip; + int m_act; + int m_func; + + QString m_strWavePath; + QString m_strVideoPath; + QString m_strTrendPath; +}; + +#endif diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeItem.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeItem.cpp new file mode 100644 index 00000000..f9575592 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeItem.cpp @@ -0,0 +1,159 @@ +#include +#include "CAlarmDeviceTreeItem.h" +#include "pub_logger_api/logger.h" +#include "Common.h" + +const int TypeRole = Qt::UserRole + 1; +const int TagRole = Qt::UserRole + 2; +const int DomainRole = Qt::UserRole + 3; +const int LocationRole = Qt::UserRole + 4; +const int SubsystemRole = Qt::UserRole + 5; +const int RegionRole = Qt::UserRole + 6; + +CAlarmDeviceTreeItem::CAlarmDeviceTreeItem(const QString &data, CAlarmDeviceTreeItem *parent) + : m_tag(QString()), + m_nDomain(CN_InvalidDomainId), + m_nLocation(CN_InvalidLocationId), + m_nSubsystem(CN_InvalidSubsystemId), + m_nType(0), + m_nRegion(0), + m_parentItem(parent) +{ + if(m_parentItem) + { + m_parentItem->m_childItems.append(this); + } + + m_data = data; + m_checkState = Qt::Checked; +} + +CAlarmDeviceTreeItem::~CAlarmDeviceTreeItem() +{ + qDeleteAll(m_childItems); + m_childItems.clear(); +} + +CAlarmDeviceTreeItem *CAlarmDeviceTreeItem::child(int row) +{ + return m_childItems.value(row); +} + +CAlarmDeviceTreeItem *CAlarmDeviceTreeItem::parentItem() +{ + return m_parentItem; +} + +int CAlarmDeviceTreeItem::row() const +{ + if (m_parentItem) + { + return m_parentItem->m_childItems.indexOf(const_cast(this)); + } + + return 0; +} + +int CAlarmDeviceTreeItem::childCount() const +{ + return m_childItems.count(); +} + +int CAlarmDeviceTreeItem::columnCount() const +{ + return 1; +} + +QVariant CAlarmDeviceTreeItem::data(Qt::ItemDataRole role) const +{ + if(Qt::DisplayRole == role) + { + return m_data; + } + else if(Qt::CheckStateRole == role) + { + return m_checkState; + } + else if(Qt::ItemDataRole(TypeRole) == role) + { + return m_nType; + } + else if(Qt::ItemDataRole(TagRole) == role) + { + return m_tag; + } + else if(Qt::ItemDataRole(DomainRole) == role) + { + return m_nDomain; + } + else if(Qt::ItemDataRole(LocationRole) == role) + { + return m_nLocation; + } + else if(Qt::ItemDataRole(SubsystemRole) == role) + { + return m_nSubsystem; + } + else if(Qt::ItemDataRole(RegionRole) == role) + { + return m_nRegion; + } + return QVariant(); +} + +bool CAlarmDeviceTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) +{ + if(Qt::DisplayRole == role) + { + m_data = value.toString(); + return true; + } + else if(Qt::CheckStateRole == role) + { + m_checkState = (Qt::CheckState)value.toInt(); + return true; + } + else if(TypeRole == role) + { + m_nType = value.toInt(); + return true; + } + else if(TagRole == role) + { + m_tag = value.toString(); + return true; + } + else if(DomainRole == role) + { + m_nDomain = value.toInt(); + return true; + } + else if(LocationRole == role) + { + m_nLocation = value.toInt(); + return true; + } + else if(SubsystemRole == role) + { + m_nSubsystem = value.toInt(); + return true; + } + else if(RegionRole == role) + { + m_nRegion = value.toInt(); + return true; + } + return false; +} + +bool CAlarmDeviceTreeItem::removeChildren(int position, int count, int columns) +{ + Q_UNUSED(columns) + if (position < 0 || position + count > m_childItems.size()) + return false; + + for (int row = 0; row < count; ++row) + delete m_childItems.takeAt(position); + + return true; +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeItem.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeItem.h new file mode 100644 index 00000000..d0e3c9ba --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeItem.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CALARMDEVICETREEITEM_H +#define CALARMDEVICETREEITEM_H + +#include +#include + +extern const int TypeRole; +extern const int TagRole; +extern const int DomainRole; +extern const int LocationRole; +extern const int SubsystemRole; +extern const int RegionRole; + +class CAlarmDeviceTreeItem +{ +public: + explicit CAlarmDeviceTreeItem(const QString &data = QString(), CAlarmDeviceTreeItem *parentItem = Q_NULLPTR); + ~CAlarmDeviceTreeItem(); + + CAlarmDeviceTreeItem *child(int row); + CAlarmDeviceTreeItem *parentItem(); + + int row() const; + + int childCount() const; + int columnCount() const; + + QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; + bool setData(const QVariant &value, Qt::ItemDataRole role); + bool removeChildren(int position, int count, int columns); +private: + QString m_tag; + int m_nDomain; + int m_nLocation; + int m_nSubsystem; + int m_nRegion; + int m_nType; + QString m_data; + Qt::CheckState m_checkState; + + QList m_childItems; + CAlarmDeviceTreeItem *m_parentItem; +}; + +#endif // CALARMDEVICETREEITEM_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeModel.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeModel.cpp new file mode 100644 index 00000000..f3347c6b --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeModel.cpp @@ -0,0 +1,312 @@ +#include "CAlarmDeviceTreeItem.h" +#include "CAlarmDeviceTreeModel.h" +#include "CAlarmMsgManage.h" +#include "CAlarmBaseData.h" +#include +#include "pub_logger_api/logger.h" +CAlarmDeviceTreeModel::CAlarmDeviceTreeModel(QObject *parent) + : QAbstractItemModel(parent) +{ + rootItem = new CAlarmDeviceTreeItem(); + m_sysInfoItem = NULL; +} + +CAlarmDeviceTreeModel::~CAlarmDeviceTreeModel() +{ + m_devTagIndex.clear(); + m_devNameIndex.clear(); + delete rootItem; +} + +void CAlarmDeviceTreeModel::setupModelData(const QMap > locationInfos, const QList &locationList) +{ + for(int nLocIndex(0); nLocIndexgetPermLocationDesc(locationList[nLocIndex]); + CAlarmDeviceTreeItem * location = new CAlarmDeviceTreeItem(locDesc, rootItem); + location->setData(TYPE_LOCATION,Qt::ItemDataRole(TypeRole)); + const QVector vec = locationInfos.value(locationList[nLocIndex]); + for(int nDevIndex(0); nDevIndex < vec.size(); ++nDevIndex) + { + CAlarmDeviceTreeItem * device = new CAlarmDeviceTreeItem(vec.at(nDevIndex).description, location); + device->setData(vec.at(nDevIndex).tag_name, Qt::ItemDataRole(TagRole)); + device->setData(TYPE_DEVGROUP, Qt::ItemDataRole(TypeRole)); + device->setData(vec.at(nDevIndex).domain, Qt::ItemDataRole(DomainRole)); + device->setData(vec.at(nDevIndex).location, Qt::ItemDataRole(LocationRole)); + device->setData(vec.at(nDevIndex).sub_system, Qt::ItemDataRole(SubsystemRole)); + device->setData(vec.at(nDevIndex).region, Qt::ItemDataRole(RegionRole)); + QModelIndex modelIndex = createIndex(nDevIndex, 0, device); + m_devTagIndex.insert(vec.at(nDevIndex).tag_name, modelIndex); + m_devNameIndex.insert(locDesc + "." + vec.at(nDevIndex).description, modelIndex); + } + } + + CAlarmDeviceTreeItem * location = new CAlarmDeviceTreeItem(QString(tr("系统信息")), rootItem); + location->setData(TYPE_SYSINFO, Qt::ItemDataRole(TypeRole)); + m_sysInfoItem = location; +} + +const HashIndex &CAlarmDeviceTreeModel::indexTagList() const +{ + return m_devTagIndex; +} + +const HashIndex &CAlarmDeviceTreeModel::indexNameList() const +{ + return m_devNameIndex; +} + +QModelIndex CAlarmDeviceTreeModel::indexOfDeviceTag(const QString &tag) +{ + return m_devTagIndex.value(tag, QModelIndex()); +} + +QModelIndex CAlarmDeviceTreeModel::indexOfDeviceName(const QString &name) +{ + return m_devNameIndex.value(name, QModelIndex()); +} + +QVariant CAlarmDeviceTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section) + Q_UNUSED(orientation) + Q_UNUSED(role) + return QVariant(); +} + +QModelIndex CAlarmDeviceTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + { + return QModelIndex(); + } + + CAlarmDeviceTreeItem *parentItem; + + if (!parent.isValid()) + { + parentItem = rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + CAlarmDeviceTreeItem *childItem = parentItem->child(row); + if (childItem) + { + return createIndex(row, column, childItem); + } + else + { + return QModelIndex(); + } +} + +QModelIndex CAlarmDeviceTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + CAlarmDeviceTreeItem *childItem = static_cast(index.internalPointer()); + + CAlarmDeviceTreeItem *parentItem = childItem->parentItem(); + if (parentItem == rootItem) + { + return QModelIndex(); + } + + return createIndex(parentItem->row(), 0, parentItem); +} + +int CAlarmDeviceTreeModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + { + return 0; + } + + CAlarmDeviceTreeItem *parentItem; + if (!parent.isValid()) + { + parentItem = rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + return parentItem->childCount(); +} + +int CAlarmDeviceTreeModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + { + return static_cast(parent.internalPointer())->columnCount(); + } + else + { + return rootItem->columnCount(); + } +} + + +QVariant CAlarmDeviceTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.column()) + { + return QVariant(); + } + + CAlarmDeviceTreeItem *item = static_cast(index.internalPointer()); + int itemType = item->data(Qt::ItemDataRole(TypeRole)).toInt(); + + if (Qt::DisplayRole == role) + { + const QString &deviceGroup = item->data(Qt::ItemDataRole(TagRole)).toString(); + if (itemType == enTreeNodeType::TYPE_LOCATION) + { + return item->data(Qt::DisplayRole).toString(); + } + else if (itemType == enTreeNodeType::TYPE_SYSINFO) + { + return QString(tr("系统信息")) + QString(" [%1]").arg(m_alarmDeviceGroupStatistical.value(deviceGroup, 0)); + } + else + { + if (deviceGroup.isEmpty()) + { + return item->data(Qt::DisplayRole).toString(); + } + else + { + return item->data(Qt::DisplayRole).toString() + QString(" [%1]").arg(m_alarmDeviceGroupStatistical.value(deviceGroup, 0)); + } + } + } + else if(Qt::CheckStateRole == role && itemType != enTreeNodeType::TYPE_LOCATION) + { + return item->data(Qt::CheckStateRole); + } + + return QVariant(); +} + +bool CAlarmDeviceTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() || index.column()) + { + return false; + } + if(Qt::CheckStateRole == role) + { + emit itemCheckStateChanged(static_cast(index.internalPointer())->data(Qt::ItemDataRole(TagRole)).toString(), value.toBool()); + } + return static_cast(index.internalPointer())->setData(value, (Qt::ItemDataRole)role); +} + +Qt::ItemFlags CAlarmDeviceTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + if(!index.column()) + { + return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable; + } + return QAbstractItemModel::flags(index); +} + +void CAlarmDeviceTreeModel::setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + CAlarmDeviceTreeItem * pItem = static_cast(index.internalPointer()); + if(pItem) + { + int nChildCount = pItem->childCount(); + for( int nIndex(0); nIndex < nChildCount; nIndex++) + { + pItem->child(nIndex)->setData(state, Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->child(nIndex)->data(Qt::ItemDataRole(TagRole)).toString(), state); + } + } +} + +void CAlarmDeviceTreeModel::setAllDeviceCheckState(const Qt::CheckState &state) +{ + HashIndex::const_iterator iter = m_devTagIndex.constBegin(); + while (iter != m_devTagIndex.constEnd()) + { + CAlarmDeviceTreeItem * pItem = static_cast(iter.value().internalPointer()); + if(pItem) + { + pItem->setData(state, Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->data(Qt::ItemDataRole(TagRole)).toString(), state); + } + ++iter; + } + + if(m_sysInfoItem) + { + m_sysInfoItem->setData(state, Qt::CheckStateRole); + emit itemCheckStateChanged(m_sysInfoItem->data(Qt::ItemDataRole(TagRole)).toString(), state); + } +} + +void CAlarmDeviceTreeModel::removeData() +{ + m_alarmDeviceGroupStatistical.clear(); + QModelIndex modelindex = QModelIndex(); + if(rootItem->childCount()>0) + { + beginRemoveRows(modelindex, 0, rootItem->childCount()-1); + rootItem->removeChildren(0, rootItem->childCount(), rootItem->columnCount()); + endRemoveRows(); + } +} + +QHash CAlarmDeviceTreeModel::getDeviceStatisticalInfo() +{ + return m_alarmDeviceGroupStatistical; +} + +void CAlarmDeviceTreeModel::slotDevTreeUpdate() +{ + m_alarmDeviceGroupStatistical.clear(); + m_alarmDeviceGroupStatistical = CAlarmMsgManage::instance()->getDeviceStatisticalInfo(); +} + +void CAlarmDeviceTreeModel::slotTreeCheckBoxState(const QModelIndex &index) +{ + if(!index.isValid()) + { + return; + } + CAlarmDeviceTreeItem *pItem = static_cast(index.internalPointer()); + if(pItem) + { + int itemType = pItem->data(Qt::ItemDataRole(TypeRole)).toInt(); + if (itemType == enTreeNodeType::TYPE_LOCATION) + { + return; + } + + if(data(index , Qt::CheckStateRole) == Qt::Unchecked) + { + pItem->setData(Qt::Checked , Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->data(Qt::ItemDataRole(TagRole)).toString(), true); + } + else + { + pItem->setData(Qt::Unchecked , Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->data(Qt::ItemDataRole(TagRole)).toString(), false); + } + } +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeModel.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeModel.h new file mode 100644 index 00000000..d6ccbeee --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeModel.h @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CALARMDEVICETREEMODEL_H +#define CALARMDEVICETREEMODEL_H + +#include "CAlarmCommon.h" +#include +#include +#include +#include + +enum enTreeNodeType{ + TYPE_LOCATION = 0, + TYPE_DEVGROUP, + TYPE_SYSINFO +}; +typedef QHash< QString, QModelIndex > HashIndex; //< Device + +class CAlarmDeviceTreeItem; + +class CAlarmDeviceTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit CAlarmDeviceTreeModel(QObject *parent = 0); + ~CAlarmDeviceTreeModel(); + + //< @param locationInfos [ locationDesc[ devTag, devDesc ] ] + void setupModelData(const QMap > locationInfos, const QList &locationList); + + const HashIndex &indexTagList() const; + + const HashIndex &indexNameList() const; + + QModelIndex indexOfDeviceTag(const QString &tag); + + QModelIndex indexOfDeviceName(const QString &name); + + QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override; + + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state); + + void setAllDeviceCheckState(const Qt::CheckState &state); + + void removeData(); + + QHash getDeviceStatisticalInfo(); + +signals: + void itemCheckStateChanged(const QString &device, const bool &checked); + + void inhibitDevGroupAlm(const QString &devGroup, int nDomain, int nLocation, int nSubsystem, int nRegion); + +public slots: + void slotDevTreeUpdate(); + + void slotTreeCheckBoxState(const QModelIndex & index); +private: + CAlarmDeviceTreeItem *rootItem; + HashIndex m_devTagIndex; + HashIndex m_devNameIndex; + HashIndex m_devGroupIndex; + CAlarmDeviceTreeItem* m_sysInfoItem; + QHash m_alarmDeviceGroupStatistical; //<设备组告警数量统计 +}; + +#endif // CALARMDEVICETREEMODEL_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeView.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeView.cpp new file mode 100644 index 00000000..de6567f3 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeView.cpp @@ -0,0 +1,57 @@ +#include "CAlarmDeviceTreeView.h" +#include "CAlarmDeviceTreeModel.h" +#include "CAlarmDeviceTreeItem.h" +#include +#include + +CAlarmDeviceTreeView::CAlarmDeviceTreeView(QWidget *parent) + : QTreeView(parent) +{ + +} + +void CAlarmDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) +{ + CAlarmDeviceTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QMenu menu(this); + CAlarmDeviceTreeItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); + if (pItem) + { + if(pItem->data(Qt::ItemDataRole(TypeRole)).toInt() == TYPE_DEVGROUP) + { + menu.addAction(tr("禁止告警"), [=](){ emit pModel->inhibitDevGroupAlm(pItem->data(Qt::ItemDataRole(TagRole)).toString(), + pItem->data(Qt::ItemDataRole(DomainRole)).toInt(), + pItem->data(Qt::ItemDataRole(LocationRole)).toInt(), + pItem->data(Qt::ItemDataRole(SubsystemRole)).toInt(), + pItem->data(Qt::ItemDataRole(RegionRole)).toInt()); }); + + menu.exec(event->globalPos()); + } + } + } + return; +} + +//void CAlarmDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) +//{ +// CAlarmDeviceTreeModel * pModel = dynamic_cast(model()); +// if(Q_NULLPTR != pModel) +// { +// QMenu menu; +// CAlarmDeviceTreeItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); +// if (Q_NULLPTR == pItem) +// { +// menu.addAction(tr("全选"), [=](){ pModel->setAllDeviceCheckState(Qt::Checked); }); +// menu.addAction(tr("清空"), [=](){ pModel->setAllDeviceCheckState(Qt::Unchecked); }); +// } +// else if (Q_NULLPTR != pItem && pItem->childCount() > 0) +// { +// menu.addAction(tr("选择"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Checked); }); +// menu.addAction(tr("清除"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Unchecked); }); +// } +// menu.exec(event->globalPos()); +// } +// return; +//} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeView.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeView.h new file mode 100644 index 00000000..ceab3799 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmDeviceTreeView.h @@ -0,0 +1,16 @@ +#ifndef CALARMDEVICETREEVIEW_H +#define CALARMDEVICETREEVIEW_H + +#include + +class CAlarmDeviceTreeView : public QTreeView +{ + Q_OBJECT +public: + CAlarmDeviceTreeView(QWidget *parent = Q_NULLPTR); + +protected: + void contextMenuEvent(QContextMenuEvent *event); +}; + +#endif // CALARMDEVICETREEVIEW_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmFilterDialog.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmFilterDialog.cpp new file mode 100644 index 00000000..9f1ffe87 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmFilterDialog.cpp @@ -0,0 +1,868 @@ +#include "CAlarmFilterDialog.h" +#include "ui_CAlarmFilterDialog.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_utility_api/FileStyle.h" +#include "pub_logger_api/logger.h" +#include +#include +#include +#include +#include +#include "CAlarmBaseData.h" + +int CAlarmFilterDialog::windowMinWidth() +{ + return m_nMinWidth; +} + +void CAlarmFilterDialog::setWindowMinWidth(int nWidth) +{ + m_nMinWidth = nWidth; + setMinimumWidth(m_nMinWidth); +} + +int CAlarmFilterDialog::windowMinHeigth() +{ + return m_nMinHeight; +} + +void CAlarmFilterDialog::setWindowMinHeigth(int nHeight) +{ + m_nMinHeight = nHeight; + setMinimumHeight(m_nMinHeight); +} + +CAlarmFilterDialog::CAlarmFilterDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CAlarmFilterDialog), + m_rtdbAccess(Q_NULLPTR), + m_nMinWidth(0), + m_nMinHeight(0) +{ + ui->setupUi(this); + setObjectName("alarm_dialog"); + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + /*隐藏多余 + *2023年1月5日08:43:47 修改 + */ + ui->levelFilter->hide(); + ui->locationFilter->hide(); + ui->regionFilter->hide(); + ui->returnFilterEnable->hide(); + ui->stateFilterEnable->hide(); + ui->alarmStatusFilter->hide(); + ui->keywordFilterEnable->hide(); + + + ui->startTime->setCalendarPopup(true); + ui->endTime->setCalendarPopup(true); + + ui->subSystem->setView(new QListView()); + ui->deviceType->setView(new QListView()); + m_priorityMap = CAlarmBaseData::instance()->getPermPriorityMap(); + m_locationMap = CAlarmBaseData::instance()->getPermLocationMap(); + m_regionMap = CAlarmBaseData::instance()->getPermRegionMap(); + m_alarmStatusMap = CAlarmBaseData::instance()->getAlarmShowStatusMap(); + m_areaLocMap = CAlarmBaseData::instance()->getAreaLocMap(); + m_areaInfoMap= CAlarmBaseData::instance()->getAreaInfoMap(); +} + +CAlarmFilterDialog::~CAlarmFilterDialog() +{ + if(m_rtdbAccess) + { + delete m_rtdbAccess; + } + m_rtdbAccess = Q_NULLPTR; + delete ui; +} + +void CAlarmFilterDialog::initialize() +{ +// if(nullptr == ui->gridLayout_5) +// return; +// int numcolumn = ui->gridLayout_5->columnCount(); +// int numrow = ui->gridLayout_5->rowCount(); +// for(int i=0;igridLayout_5->itemAtPosition(i,j); +// if(item) +// item->widget()->setEnabled(false); +// } +// } + + m_rtdbAccess = new iot_dbms::CRdbAccess(); + + ui->level->setSelectionMode(QAbstractItemView::MultiSelection); + //ui->location->setSelectionMode(QAbstractItemView::MultiSelection); + ui->region->setSelectionMode(QAbstractItemView::MultiSelection); + ui->status->setSelectionMode(QAbstractItemView::MultiSelection); + + foreach (QString value, m_priorityMap) + { + ui->level->addItem(value); + } + ui->area->clear(); + ui->area->setColumnCount(1); + bool isArea = false; + QMap >::iterator it = m_areaLocMap.begin(); + while (it != m_areaLocMap.end()) { + if(it.key()<= 0) + { + QVector locVec = it.value(); + for(int index(0);indexsetText(0,getDescByAreaId(locVec.at(index))); + firstItem->setData(0,Qt::UserRole,locVec.at(index)); + firstItem->setData(0,Qt::UserRole+1,it.key()); + firstItem->setCheckState(0,Qt::Unchecked); + firstItem->setToolTip(0,getDescByAreaId(locVec.at(index))); + ui->area->addTopLevelItem(firstItem); + } + }else + { + QTreeWidgetItem *firstItem = new QTreeWidgetItem(); + firstItem->setText(0,getDescByAreaId(it.key())); + firstItem->setData(0,Qt::UserRole,it.key()); + firstItem->setData(0,Qt::UserRole+1,-1); + firstItem->setCheckState(0,Qt::Unchecked); + firstItem->setToolTip(0,getDescByAreaId(it.key())); + QVector locVec = it.value(); + for(int index(0);indexsetText(0,getDescByAreaId(locVec.at(index))); + secondItem->setData(0,Qt::UserRole,locVec.at(index)); + secondItem->setData(0,Qt::UserRole+1,it.key()); + secondItem->setCheckState(0,Qt::Unchecked); + secondItem->setToolTip(0,getDescByAreaId(locVec.at(index))); + firstItem->addChild(secondItem); + } + ui->area->addTopLevelItem(firstItem); + isArea = true; + } + + it++; + } + //< 无区域配置时不缩进,尽可能展示完全 + if(!isArea) + { + ui->area->setIndentation(0); + } + foreach (QString value, m_regionMap) + { + ui->region->addItem(value); + } + + foreach (QString value, m_alarmStatusMap) + { + ui->status->addItem(value); + } + + iot_public::CSysInfoInterfacePtr spSysInfo; + if (iot_public::createSysInfoInstance(spSysInfo)) + { + std::vector vecSubsystemInfo; + spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); + foreach (iot_public::SSubsystemInfo info, vecSubsystemInfo) + { + if(info.nId <= CN_AppId_COMAPP) + { + continue; + } + ui->subSystem->addItem(QString::fromStdString(info.strDesc)); + } + } + ui->subSystem->setCurrentIndex(-1); + + + connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateFilter())); + connect(ui->cancle, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->checkLevel, SIGNAL(pressed()), this, SLOT(slot_checkLevelPressed())); + connect(ui->checkLevel, SIGNAL(stateChanged(int)), this, SLOT(slot_levelSelectChange(int))); + connect(ui->level, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLevelState())); + connect(ui->checkLocation, SIGNAL(pressed()), this, SLOT(slot_checkLocationPressed())); + connect(ui->checkLocation, SIGNAL(stateChanged(int)), this, SLOT(slot_locationSelectChange(int))); + connect(ui->area,&QTreeWidget::itemChanged, this, &CAlarmFilterDialog::slot_updateCheckLocationState); + connect(ui->checkRegion, SIGNAL(pressed()), this, SLOT(slot_checkRegionPressed())); + connect(ui->checkRegion, SIGNAL(stateChanged(int)), this, SLOT(slot_regionSelectChange(int))); + connect(ui->region, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckRegionState())); + connect(ui->checkStatus, SIGNAL(pressed()), this, SLOT(slot_checkStatusPressed())); + connect(ui->checkStatus, SIGNAL(stateChanged(int)), this, SLOT(slot_statusSelectChange(int))); + connect(ui->status, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckStatusState())); + connect(ui->subSystem, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_updateDevice(QString))); + if(ui->subSystem->count() > 0) + { + ui->subSystem->setCurrentIndex(0); + } +} + +void CAlarmFilterDialog::setLevelFilterEnable(const bool &isLevelFilterEnable) +{ + ui->levelFilter->setChecked(isLevelFilterEnable); +} + +void CAlarmFilterDialog::setLevelFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->level->count(); nIndex++) + { + int nLevelID = m_priorityMap.key(ui->level->item(nIndex)->text()); + if(filter.contains(nLevelID)) + { + ui->level->item(nIndex)->setSelected(true); + } + else + { + ui->level->item(nIndex)->setSelected(false); + } + } +} + +void CAlarmFilterDialog::setLocationFilterEnable(const bool &isLocationFilterEnable) +{ + ui->locationFilter->setChecked(isLocationFilterEnable); +} + +void CAlarmFilterDialog::setLocationFilter(const QList &filter) +{ + if(filter.isEmpty()) + { + return; + } + ui->area->blockSignals(true); + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index); + int areaId = firstItem->data(0,Qt::UserRole).toInt(); + if(filter.contains(areaId)) + { + firstItem->setCheckState(0,Qt::Checked); + } + int childCount = firstItem->childCount(); + + for(int locIndex(0);locIndex child(locIndex); + int locId = secondItem->data(0,Qt::UserRole).toInt(); + if(filter.contains(locId)) + { + secondItem->setCheckState(0,Qt::Checked); + } + } + } + int selectNum = 0; + int allNum = 0; + for(int index(0);indexarea->topLevelItem(index); + if(firstItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + int childNum = firstItem->childCount(); + for(int secIndex(0);secIndexchild(secIndex); + allNum++; + if(secondItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + } + } + + if(selectNum == 0) + { + ui->checkLocation->setCheckState(Qt::Unchecked); + }else if(selectNum == allNum) + { + ui->checkLocation->setCheckState(Qt::Checked); + }else + { + ui->checkLocation->setCheckState(Qt::PartiallyChecked); + } + ui->area->blockSignals(false); +} + +void CAlarmFilterDialog::setRegionFilterEnable(const bool &isRegionFilterEnable) +{ + ui->regionFilter->setChecked(isRegionFilterEnable); +} + +void CAlarmFilterDialog::setRegionFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->region->count(); nIndex++) + { + int nRegionID = m_regionMap.key(ui->region->item(nIndex)->text()); + if(filter.contains(nRegionID)) + { + ui->region->item(nIndex)->setSelected(true); + } + else + { + ui->region->item(nIndex)->setSelected(false); + } + } +} + +void CAlarmFilterDialog::setAlarmStatusFilterEnable(const bool &isAlarmStatusEnable) +{ + ui->alarmStatusFilter->setChecked(isAlarmStatusEnable); +} + +void CAlarmFilterDialog::setAlarmStatusFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->status->count(); nIndex++) + { + int nAlarmTypeID = m_alarmStatusMap.key(ui->status->item(nIndex)->text()); + if(filter.contains(nAlarmTypeID)) + { + ui->status->item(nIndex)->setSelected(true); + } + else + { + ui->status->item(nIndex)->setSelected(false); + } + } +} + +void CAlarmFilterDialog::setDeviceFilterEnable(const bool &filter) +{ + ui->deviceFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setSubSystem(const QString &subSystem) +{ + if(ui->deviceFilterEnable->isChecked()) + { + ui->subSystem->setCurrentText(subSystem); + } +} + +void CAlarmFilterDialog::setDeviceType(const QString &deviceType) +{ + if(ui->deviceFilterEnable->isChecked()) + { + ui->deviceType->setCurrentText(deviceType); + } +} + +void CAlarmFilterDialog::setTimeFilterEnable(const bool &filter) +{ + ui->timeFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setStartTimeFilter(const QDateTime &filter) +{ + if(ui->timeFilterEnable->isChecked()) + { + ui->startTime->setDateTime(filter); + } + else + { + QDateTime dataTime(QDateTime::currentDateTime()); +// dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().second(),0,0)); + dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().minute(),0,0)); + //dataTime.setTime(QTime(00,00,0,0)); + ui->startTime->setDateTime(dataTime); + } +} + +void CAlarmFilterDialog::setEndTimeFilter(const QDateTime &filter) +{ + if(ui->timeFilterEnable->isChecked()) + { + ui->endTime->setDateTime(filter); + } + else + { + QDateTime dataTime(QDateTime::currentDateTime()); +// dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().second(),59,999)); + dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().minute(),59,999)); + //dataTime.setTime(QTime(23,59,59,999)); + + ui->endTime->setDateTime(dataTime); + } +} + +void CAlarmFilterDialog::setStateFilterEnable(const bool &filter) +{ + ui->stateFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setStateFilter(const bool &filter) +{ + if(filter) + { + ui->confirm->setChecked(true); + } + else + { + ui->unConfirm->setChecked(true); + } +} + +void CAlarmFilterDialog::setkeyWordFilterEnable(const bool &filter) +{ + ui->keywordFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setkeyWordFilteContent(const QString &content) +{ + if(ui->keywordFilterEnable->isChecked()) + { + ui->keyWord->setText(content); + } +} + +void CAlarmFilterDialog::setReturnFilterEnable(const bool &filter) +{ + ui->returnFilterEnable->setChecked(filter); +} + +void CAlarmFilterDialog::setReturnFilter(const bool &filter) +{ + if(filter) + { + ui->hasReturn->setChecked(true); + } + else + { + ui->notReturn->setChecked(true); + } +} + +void CAlarmFilterDialog::slot_updateFilter() +{ + bool isLevelFilter = ui->levelFilter->isChecked(); + QList listLevel; + foreach (QListWidgetItem *item, ui->level->selectedItems()) + { + listLevel << m_priorityMap.key(item->text()); + } + + bool isLocationFilter = ui->locationFilter->isChecked(); + QList listLocation; + + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index); + if(firstItem->checkState(0) == Qt::Checked) + { + listLocation.append(firstItem->data(0,Qt::UserRole).toInt()); + } + int locCount = firstItem->childCount(); + for(int locIndex(0);locIndexchild(locIndex); + if(secondItem->checkState(0) == Qt::Checked) + { + listLocation.append(secondItem->data(0,Qt::UserRole).toInt()); + } + } + } + + bool isRegionFilter = ui->regionFilter->isChecked(); + QList listRegion; + foreach (QListWidgetItem *item, ui->region->selectedItems()) + { + listRegion << m_regionMap.key(item->text()); + } + + bool isAlarmStatusFilter = ui->alarmStatusFilter->isChecked(); + QList listAlarmStatus; + foreach (QListWidgetItem *item, ui->status->selectedItems()) + { + listAlarmStatus << m_alarmStatusMap.key(item->text()); + } + + bool isDeviceTypeFilter = ui->deviceFilterEnable->isChecked(); + QString subSystem = ui->subSystem->currentText(); + QString deviceType = ui->deviceType->currentText(); + + bool isKeyWordFilter = ui->keywordFilterEnable->isChecked(); + QString strKeyWord =ui->keyWord->text(); + + bool isTimeFilter = ui->timeFilterEnable->isChecked(); + QDateTime startTime = QDateTime(); + QDateTime endTime = QDateTime(); + if(isTimeFilter) + { + startTime = ui->startTime->dateTime(); + endTime = ui->endTime->dateTime(); + if(endTime.toTime_t() < startTime.toTime_t()) + { + QMessageBox::warning(this, tr("提示"), tr("结束时间大于开始时间!"), QMessageBox::Ok); + return; + } + } + + bool isConfirmFilter = ui->stateFilterEnable->isChecked(); + bool confirm = ui->confirm->isChecked(); + bool isReturnFilter =ui->returnFilterEnable->isChecked(); + bool breturn = ui->hasReturn->isChecked(); + + emit sig_updateFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmStatusFilter, listAlarmStatus, + isDeviceTypeFilter, subSystem, deviceType, isKeyWordFilter, strKeyWord, isTimeFilter, startTime, endTime, isConfirmFilter, confirm,isReturnFilter,breturn); + accept(); +} + +//Level +void CAlarmFilterDialog::slot_checkLevelPressed() +{ + if( Qt::Unchecked == ui->checkLevel->checkState()) + { + ui->checkLevel->setTristate(false); + } +} + +void CAlarmFilterDialog::slot_levelSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->level->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->level->selectAll(); + } +} + +void CAlarmFilterDialog::slot_updateCheckLevelState() +{ + if( ui->level->count() == ui->level->selectedItems().count() ) + { + if( Qt::Checked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->level->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Location +void CAlarmFilterDialog::slot_checkLocationPressed() +{ + if( Qt::Unchecked == ui->checkLocation->checkState()) + { + ui->checkLocation->setTristate(false); + } +} + +void CAlarmFilterDialog::slot_locationSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + clearTreeSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + allTreeSelection(); + } +} + +void CAlarmFilterDialog::slot_updateCheckLocationState(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column); + ui->area->blockSignals(true); + if(item->parent() == NULL) //父节点 + { + childItemSelection(item); + }else if(item->childCount()<= 0) //子节点 + { + //parentItemSelection(item); + } + + int selectNum = 0; + int count = ui->area->topLevelItemCount(); + int allNum = 0; + for(int index(0);indexarea->topLevelItem(index); + if(firstItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + int childNum = firstItem->childCount(); + for(int secIndex(0);secIndexchild(secIndex); + allNum++; + if(secondItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + } + } + + if(selectNum == 0) + { + ui->checkLocation->setCheckState(Qt::Unchecked); + }else if(selectNum == allNum) + { + ui->checkLocation->setCheckState(Qt::Checked); + }else + { + ui->checkLocation->setCheckState(Qt::PartiallyChecked); + } + + + ui->area->blockSignals(false); +} + +//Region +void CAlarmFilterDialog::slot_checkRegionPressed() +{ + if( Qt::Unchecked == ui->checkRegion->checkState()) + { + ui->checkRegion->setTristate(false); + } +} + +void CAlarmFilterDialog::slot_regionSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->region->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->region->selectAll(); + } +} + +void CAlarmFilterDialog::slot_updateCheckRegionState() +{ + if( ui->region->count() == ui->region->selectedItems().count() ) + { + if( Qt::Checked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->region->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Type +void CAlarmFilterDialog::slot_checkStatusPressed() +{ + if( Qt::Unchecked == ui->checkStatus->checkState()) + { + ui->checkStatus->setTristate(false); + } +} + +void CAlarmFilterDialog::slot_statusSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->status->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->status->selectAll(); + } +} + +void CAlarmFilterDialog::slot_updateCheckStatusState() +{ + if( ui->status->count() == ui->status->selectedItems().count() ) + { + if( Qt::Checked != ui->checkStatus->checkState() ) + { + ui->checkStatus->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->status->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkStatus->checkState() ) + { + ui->checkStatus->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkStatus->checkState() ) + { + ui->checkStatus->setCheckState(Qt::PartiallyChecked); + } + } +} + +void CAlarmFilterDialog::slot_updateDevice(const QString &subSystem) +{ + int nSubSystemId = -1; + iot_public::CSysInfoInterfacePtr spSysInfo; + if (iot_public::createSysInfoInstance(spSysInfo)) + { + std::vector vecSubsystemInfo; + spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); + foreach (iot_public::SSubsystemInfo info, vecSubsystemInfo) + { + if(subSystem.toStdString() == info.strDesc) + { + nSubSystemId = info.nId; + } + } + } + + ui->deviceType->clear(); + + QList values; + + if(nSubSystemId != -1) + { + iot_dbms::CVarType subSystemId = nSubSystemId; + if(m_rtdbAccess->open("base", "dev_type_def")) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CONDINFO condition; + condition.relationop = ATTRCOND_EQU; + memcpy(condition.name, "sub_system", strlen("sub_system") ); + condition.conditionval = subSystemId; + std::vector columns; + columns.push_back("description"); + + iot_dbms::CRdbQueryResult result; + if(m_rtdbAccess->select(condition, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, value); + values.append(value); + } + } + } + } + foreach (iot_dbms::CVarType value, values) + { + ui->deviceType->addItem(value.c_str()); + } +} + +QString CAlarmFilterDialog::getDescByAreaId(int areaId) +{ + SAreaInfo info; + return m_areaInfoMap.value(areaId,info).stDes; +} + +void CAlarmFilterDialog::clearTreeSelection() +{ + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index)->setCheckState(0,Qt::Unchecked); + slot_updateCheckLocationState(ui->area->topLevelItem(index),0); + } +} + +void CAlarmFilterDialog::childItemSelection(QTreeWidgetItem *item) +{ + Qt::CheckState status = item->checkState(0); + + int count = item->childCount(); + for(int index(0);indexchild(index)->setCheckState(0,status); + } +} + +void CAlarmFilterDialog::parentItemSelection(QTreeWidgetItem *item) +{ + QTreeWidgetItem *parent = item->parent(); + int count = parent->childCount(); + int checkNum = 0; + for(int index(0);indexchild(index)->checkState(0) == Qt::Checked) + { + checkNum += 1; + } + } + if(checkNum == count) + { + parent->setCheckState(0,Qt::Checked); + }else if(checkNum == 0) + { + parent->setCheckState(0,Qt::Unchecked); + }else + { + parent->setCheckState(0,Qt::PartiallyChecked); + } +} + +void CAlarmFilterDialog::allTreeSelection() +{ + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index)->setCheckState(0,Qt::Checked); + slot_updateCheckLocationState(ui->area->topLevelItem(index),0); + } +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmFilterDialog.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmFilterDialog.h new file mode 100644 index 00000000..b64aec96 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmFilterDialog.h @@ -0,0 +1,123 @@ +#ifndef CALARMFILTERDIALOG_H +#define CALARMFILTERDIALOG_H + +#include +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "CAlarmCommon.h" + +class QTreeWidgetItem; + +namespace Ui { +class CAlarmFilterDialog; +} + +class CAlarmFilterDialog : public QDialog +{ + Q_OBJECT + //Q_PROPERTY(int windowMinWidth READ windowMinWidth WRITE setWindowMinWidth) + //Q_PROPERTY(int windowMinHeigth READ windowMinHeigth WRITE setWindowMinHeigth) + +public slots: + int windowMinWidth(); + void setWindowMinWidth(int nWidth); + int windowMinHeigth(); + void setWindowMinHeigth(int nHeight); + +public: + explicit CAlarmFilterDialog(QWidget *parent = 0); + ~CAlarmFilterDialog(); + + void initialize(); + void setLevelFilterEnable(const bool &isLevelFilterEnable); + void setLevelFilter(const QList &filter); + void setLocationFilterEnable(const bool &isLocationFilterEnable); + void setLocationFilter(const QList &filter); + + void setRegionFilterEnable(const bool &isRegionFilterEnable); + void setRegionFilter(const QList &filter); + /** + * @brief setAlarmTypeFilterEnable 过滤窗新增告警状态代替告警类型 + * @param isAlarmTypeEnable + */ + void setAlarmStatusFilterEnable(const bool &isAlarmStatusEnable); + /** + * @brief setAlarmStatusFilter 过滤窗新增告警状态代替告警类型 + * @param filter + */ + void setAlarmStatusFilter(const QList &filter); + + void setDeviceFilterEnable(const bool &filter); + void setSubSystem(const QString &subSystem); + void setDeviceType(const QString &deviceType); + void setTimeFilterEnable(const bool &filter); + void setStartTimeFilter(const QDateTime &filter); + void setEndTimeFilter(const QDateTime &filter); + void setStateFilterEnable(const bool &filter); + void setStateFilter(const bool &filter); + void setkeyWordFilterEnable(const bool &filter); + void setkeyWordFilteContent(const QString &content); + void setReturnFilterEnable(const bool &filter); + void setReturnFilter(const bool &filter); +signals: + /** + * @brief sig_updateFilter + * @param List level location region alarmType isKeyWordFilterEnable, keyWord, isTimeFilter startTime endTime isConfirmFilter confirm + */ + void sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool,bool,bool); + +private slots: + void slot_updateFilter(); + + //Level + void slot_checkLevelPressed(); + void slot_levelSelectChange(const int &state); + void slot_updateCheckLevelState(); + + //Station + void slot_checkLocationPressed(); + void slot_locationSelectChange(const int &state); + void slot_updateCheckLocationState(QTreeWidgetItem *item, int column); + + //Region + void slot_checkRegionPressed(); + void slot_regionSelectChange(const int &state); + void slot_updateCheckRegionState(); + + //AlarmStatus + void slot_checkStatusPressed(); + void slot_statusSelectChange(const int &state); + void slot_updateCheckStatusState(); + + //DeviceType + void slot_updateDevice(const QString &subSystem); + +private: + QString getDescByAreaId(int areaId); + void clearTreeSelection(); + void childItemSelection(QTreeWidgetItem *item); + void parentItemSelection(QTreeWidgetItem *item); + void allTreeSelection(); +private: + Ui::CAlarmFilterDialog *ui; + + iot_dbms::CRdbAccess * m_rtdbAccess; + QMap m_priorityMap; + QMap m_locationMap; + QMap m_regionMap; + QMap m_alarmTypeMap; + /** + * @brief m_alarmStatusMap 过滤窗新增告警状态代替告警类型 + */ + QMap m_alarmStatusMap; + + QMap m_areaInfoMap; //区域信息 + + QMap > m_areaLocMap; //区域映射 + + int m_nMinWidth; + int m_nMinHeight; +}; + +#endif // ALARMFILTERDIALOG_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmFilterDialog.ui b/product/src/gui/plugin/AlarmWidget_pad/CAlarmFilterDialog.ui new file mode 100644 index 00000000..317bda4b --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmFilterDialog.ui @@ -0,0 +1,546 @@ + + + CAlarmFilterDialog + + + + 0 + 0 + 736 + 355 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + 过滤 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 设备类型 + + + true + + + false + + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 时间 + + + true + + + false + + + + + + + + 结束时间 + + + + + + + + 2018 + 1 + 1 + + + + + 2050 + 12 + 31 + + + + + 2000 + 1 + 1 + + + + yyyy/MM/dd hh:mm + + + true + + + + + + + + + + + + 0 + 0 + 0 + 2018 + 1 + 1 + + + + + 2018 + 1 + 1 + + + + + 23 + 59 + 59 + 2050 + 12 + 31 + + + + + 2050 + 12 + 31 + + + + + 2000 + 1 + 1 + + + + yyyy/MM/dd hh:mm + + + true + + + + + + + 开始时间 + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 281 + 20 + + + + + + + + 取消 + + + + + + + 确定 + + + + + + + + + + + + 0 + 0 + + + + 优先级 + + + true + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + + + + 全选 + + + true + + + true + + + + + + + + + + + 0 + 0 + + + + 位置 + + + true + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + QAbstractItemView::NoSelection + + + false + + + + 1 + + + + + + + + 全选 + + + true + + + + + + + + + + + 0 + 0 + + + + 责任区 + + + true + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + + + + 全选 + + + true + + + + + + + + + + + 0 + 0 + + + + 告警状态 + + + true + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 全选 + + + true + + + + + + + + + + + + + + 0 + 0 + + + + 告警内容关键字 + + + true + + + false + + + + + + + + + + + + + 0 + 0 + + + + 状态 + + + false + + + true + + + false + + + + + + 未确认 + + + + + + + 已确认 + + + true + + + + + + + + + + + 0 + 0 + + + + 复归 + + + true + + + false + + + + + + 已复归 + + + true + + + + + + + 未复归 + + + + + + + + stateFilterEnable + returnFilterEnable + regionFilter + locationFilter + levelFilter + keywordFilterEnable + alarmStatusFilter + + + + diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmForm.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmForm.cpp new file mode 100644 index 00000000..3c1bd4fa --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmForm.cpp @@ -0,0 +1,3370 @@ +#include "CAlarmForm.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ui_CAlarmForm.h" +#include "CAlarmDelegate.h" +#include "CAiAlarmDelegate.h" +#include "CAlarmItemModel.h" +#include "CAlarmFilterDialog.h" +#include "CAlarmMsgManage.h" +#include "CTableViewPrinter.h" +#include "CAlarmDataCollect.h" +#include "CAiAlarmDataCollect.h" +#include "CAlarmInhibitDialog.h" +#include "CAlarmDeviceTreeModel.h" +#include "CAlarmDeviceTreeItem.h" +#include "CAiAlarmTreeItem.h" +#include "CAiAlarmTreeModel.h" +#include "perm_mng_api/PermMngApi.h" +#include +#include +#include "CMyListWidget.h" +#include "CMyCheckBox.h" +#include "CDisposalPlanDialog.h" +#include "CTreeViewPrinter.h" +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileUtil.h" +#include +#include "CAlarmTaskMngDlg.h" +#include +#include "CAlarmSetDlg.h" +#include "CAlarmBaseData.h" +#include "CAlarmShiledDialog.h" +#include "CAccidentReviewDialog.h" +#include "perm_mng_api/PermMngApi.h" +#include "db_his_mng_api/CHisMngApi.h" +#include "db_api_ex/CDbApi.h" +#include "db_manager_api/db_opt.h" +#include "db_manager_api/db_opt_mysql.h" +#include "CAlarmDeviceTreeView.h" +#include "pub_utility_api/FileStyle.h" +#include + + +CAlarmForm::CAlarmForm(QWidget *parent) : + QWidget(parent), + m_ptrSysInfo(Q_NULLPTR), + m_pReadDb(Q_NULLPTR), + m_aiOptPerm(true), + m_pModel(Q_NULLPTR), + m_delegate(Q_NULLPTR), + m_aiDelegate(Q_NULLPTR), + m_treeModel(Q_NULLPTR), + m_communicator(Q_NULLPTR), + ui(new Ui::CAlarmForm), + m_isNormal(true), + m_isNeedAccidentReview(true), + m_strAccidenPath(QString()) +{ + m_communicator = new iot_net::CMbCommunicator(); + qRegisterMetaType("QItemSelection"); + qRegisterMetaType< QList > >("QList >"); + qRegisterMetaType >("QVector"); + qRegisterMetaType >("QVector"); + qRegisterMetaType >("QVector"); + ui->setupUi(this); + ui->alarmView->setObjectName("alarmView"); + ui->set->hide(); + //ui->widget->setStyleSheet("border:3px solid"); + ui->splitter->setStretchFactor(0,9); + ui->splitter->setStretchFactor(1,1); + + ui->splitter_2->setStretchFactor(0,1); + ui->splitter_2->setStretchFactor(1,5); + + //ui->splitter_2->setStretchFactor(0,1); + //ui->splitter_2->setStretchFactor(1,8); + + QHBoxLayout * pHBoxLayout = new QHBoxLayout(ui->deviceView->header()); + m_pSearchTextEdit = new QLineEdit(ui->deviceView->header()); + m_pSearchTextEdit->setObjectName("searchTextEdit"); + m_pSearchTextEdit->setTextMargins(0, 0, 21, 0); + m_pSearchTextEdit->setPlaceholderText(tr("按设备组关键字搜索")); + pHBoxLayout->addWidget(m_pSearchTextEdit); + pHBoxLayout->setContentsMargins(2,0,2,0); + pHBoxLayout->setSpacing(0); + ui->deviceView->header()->setLayout(pHBoxLayout); + ui->deviceView->header()->setObjectName("deviceHeader"); + //ui->deviceView->header()->setFixedHeight(30); + + m_pSearchButton = new QPushButton(this); + m_pSearchButton->setObjectName("searchButton"); + m_pSearchButton->setText(""); + m_pSearchButton->setMaximumSize(21, 22); + m_pSearchButton->setCursor(QCursor(Qt::ArrowCursor)); + + QHBoxLayout * pSearchLayout = new QHBoxLayout(); + pSearchLayout->setContentsMargins(1, 1, 1, 1); + pSearchLayout->addStretch(); + pSearchLayout->addWidget(m_pSearchButton); + m_pSearchTextEdit->setLayout(pSearchLayout); + + connect(m_pSearchTextEdit, &QLineEdit::returnPressed, this, &CAlarmForm::searchDeviceName); + connect(m_pSearchButton, &QPushButton::clicked, this, &CAlarmForm::searchDeviceName); + m_pListWidget1 = new CMyListWidget(this); + m_pListWidget2 = new CMyListWidget(this); + m_pListWidget3 = new CMyListWidget(this); + m_pLineEdit1 = new QLineEdit(this); + m_pLineEdit2 = new QLineEdit(this); + m_pLineEdit3 = new QLineEdit(this); + m_timeIcon = new QPushButton(this); + //时间过滤 + m_myCalendar = new CMyCalendar(this); + QWidgetAction *widgetAction=new QWidgetAction(this); + m_timeMenu = new QMenu(this); + widgetAction->setDefaultWidget(m_myCalendar); + m_timeMenu->addAction(widgetAction); + m_timeIcon->setObjectName("iconButton"); + m_timeIcon->setText(""); + m_timeIcon->setMaximumSize(21, 22); + m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); + QHBoxLayout * pTimeLayout = new QHBoxLayout(); + pTimeLayout->setContentsMargins(1, 1, 1, 1); + pTimeLayout->addStretch(); + pTimeLayout->addWidget(m_timeIcon); + ui->lineEdit->setLayout(pTimeLayout); + connect(m_timeIcon,&QPushButton::clicked,this,&CAlarmForm::myCalendarShow); + connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&CAlarmForm::myCalendarHide); + connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&CAlarmForm::cancleTimeFilter); + ui->lineEdit->setText(tr("请选择时间")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit->setObjectName("iconLineEdit"); + + m_pdfPrinter = new CPdfPrinter(); + m_thread = new QThread(); + m_pdfPrinter->moveToThread(m_thread); + connect(m_thread,&QThread::started,m_pdfPrinter,&CPdfPrinter::initialize); + connect(m_thread,&QThread::finished,m_pdfPrinter,&CPdfPrinter::deleteLater); + connect(this,&CAlarmForm::printExcel,m_pdfPrinter,&CPdfPrinter::printerByModel); + connect(this,&CAlarmForm::printExcelAlm,m_pdfPrinter,&CPdfPrinter::printerAlmByModel); + connect(m_pdfPrinter,&CPdfPrinter::printResult,this,&CAlarmForm::printMess); + ui->aiAlarmTreeView->setUpdatesEnabled(false); + ui->alarmView->setUpdatesEnabled(false); + m_thread->start(); + m_bPopWindow = true; +} + +CAlarmForm::~CAlarmForm() +{ + if(m_communicator != Q_NULLPTR) + { + delete m_communicator; + } + m_communicator =Q_NULLPTR; + + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + if(m_delegate) + { + delete m_delegate; + } + m_delegate = Q_NULLPTR; + + if(m_aiDelegate) + { + delete m_aiDelegate; + } + m_aiDelegate = Q_NULLPTR; + + if(m_pdfPrinter) + { + delete m_pdfPrinter; + } + m_pdfPrinter = Q_NULLPTR; + + if(m_thread) + { + m_thread->quit(); + m_thread->wait(); + } + + delete ui; + LOGDEBUG("CAlarmForm::~CAlarmForm()"); +} + +void CAlarmForm::modeConfirm(const int &x) +{ + modeAll=x; +} + +void CAlarmForm::initialize() +{ + if (!iot_public::createSysInfoInstance(m_ptrSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + } + if(m_pReadDb == NULL) + { + m_pReadDb = new iot_dbms::CDbApi(DB_CONN_MODEL_READ); + if(!m_pReadDb->open()) + { + LOGERROR("数据库打开失败,%s",m_pReadDb->getLastErrorString().toStdString().c_str()); + } + } + m_pDeviceModel = new CAlarmDeviceTreeModel(this); + ui->deviceView->setModel(m_pDeviceModel); + + + connect(ui->set,&QPushButton::clicked,this,&CAlarmForm::slot_showColorSet); + connect(ui->checkBox,SIGNAL(stateChanged(int)),this,SLOT(slot_changePage(int))); + connect(ui->filter, SIGNAL(clicked()), this, SLOT(updateFilter())); + connect(ui->remove, SIGNAL(clicked()), this, SLOT(slot_removeAlarm())); + connect(ui->confirm, SIGNAL(clicked()), this, SLOT(slot_confirmAlarm())); + + //添加全选,全不选 + connect(ui->selectAll, SIGNAL(clicked()), ui->alarmView, SLOT(selectAll())); + connect(ui->selectNone, SIGNAL(clicked()), ui->alarmView, SLOT(clearSelection())); + + // connect(selectAction, &QAction::triggered, [=](){ui->alarmView->selectAll();}); + // QAction * cancleAction = menu.addAction(tr("全不选")); + // connect(cancleAction,&QAction::triggered,[=](){ui->alarmView->clearSelection();}); + + //connect(ui->inhibit, SIGNAL(clicked()), this, SLOT(slot_showInhibitAlarm())); + connect(ui->inhibit, SIGNAL(clicked()), this, SLOT(slot_showShiledAlarm())); + + connect(ui->print, SIGNAL(clicked()), this, SLOT(print())); + connect(ui->closeBtn, &QPushButton::clicked, this, &CAlarmForm::closeBtnClicked); + connect(ui->inhiAlarm, &QPushButton::clicked, this, &CAlarmForm::slotInhibitAlarm,Qt::UniqueConnection); + + connect(ui->btn_tree_all_sel, &QPushButton::clicked, this, &CAlarmForm::slotALlSel); + connect(ui->btn_tree_none_sel, &QPushButton::clicked, this, &CAlarmForm::slotNoneSel); + + setHiddenInhiAlarmButton(true); + updateAlarmOperatePerm(); + + //< lingdaoyaoqiu + { + QSettings columFlags("IOT_HMI", "alarm config"); + if(!columFlags.contains(QString("alarm/colum_0"))) + { + columFlags.setValue(QString("alarm/colum_0"), false); //< 时间 + columFlags.setValue(QString("alarm/colum_1"), false); //< 优先级 + columFlags.setValue(QString("alarm/colum_2"), false); //< 位置 + columFlags.setValue(QString("alarm/colum_3"), true); //< 责任区 + columFlags.setValue(QString("alarm/colum_4"), true); //< 告警类型 + columFlags.setValue(QString("alarm/colum_5"), false); //< 告警状态 + columFlags.setValue(QString("alarm/colum_6"), false); //< 确认状态 + columFlags.setValue(QString("alarm/colum_7"), false); //< + } + } + ui->comboBox->setModel(m_pListWidget1->model()); + ui->comboBox->setView(m_pListWidget1); + ui->comboBox->setLineEdit(m_pLineEdit1); + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + m_pLineEdit1->setReadOnly(true); + connect(m_pLineEdit1, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged1(const QString &))); //为了解决点击下拉框白色部分导致lineedit无数据问题 + ui->comboBox_2->setModel(m_pListWidget2->model()); + ui->comboBox_2->setView(m_pListWidget2); + ui->comboBox_2->setLineEdit(m_pLineEdit2); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + m_pLineEdit2->setReadOnly(true); + connect(m_pLineEdit2, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged2(const QString &))); + ui->comboBox_3->setModel(m_pListWidget3->model()); + ui->comboBox_3->setView(m_pListWidget3); + ui->comboBox_3->setLineEdit(m_pLineEdit3); + m_strText3 = tr("请选择告警状态"); + m_pLineEdit3->setText(tr("请选择告警状态")); + m_pLineEdit3->setReadOnly(true); + // if(E_Alarm_Window == modeAll) + // { + // ui->btn_tree_all_sel->hide(); + // ui->btn_tree_none_sel->hide(); + // } + + connect(m_pLineEdit3, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged3(const QString &))); +} + +void CAlarmForm::init() +{ + reloadDevTree(); + initFilter(); +} + +void CAlarmForm::updateAlarmOperatePerm() +{ + m_listRegionOptId.clear(); + m_listLocationOptId.clear(); + m_listRegionDelId.clear(); + m_listLocationDelId.clear(); + iot_public::SNodeInfo stNodeInfo; + if (!m_ptrSysInfo) + { + if(!createSysInfoInstance(m_ptrSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return; + } + } + m_ptrSysInfo->getLocalNodeInfo(stNodeInfo); + m_nodeName = stNodeInfo.strName; + m_nDomainId = stNodeInfo.nDomainId; + + + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(PERM_NORMAL != permMngPtr->CurUser(m_userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + m_userId = -1; + LOGERROR("用户ID获取失败!"); + return; + } + std::vector vecRegionOptId; + std::vector vecLocationOptId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, vecRegionOptId, vecLocationOptId)) + { + std::vector ::iterator region = vecRegionOptId.begin(); + while (region != vecRegionOptId.end()) + { + m_listRegionOptId.append(*region++); + } + + std::vector ::iterator location = vecLocationOptId.begin(); + while (location != vecLocationOptId.end()) + { + m_listLocationOptId.append(*location++); + } + } + std::vector vecRegionDelId; + std::vector vecLocationDelId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_DELETE, vecRegionDelId, vecLocationDelId)) + { + std::vector ::iterator region = vecRegionDelId.begin(); + while (region != vecRegionDelId.end()) + { + m_listRegionDelId.append(*region++); + } + + std::vector ::iterator location = vecLocationDelId.begin(); + while (location != vecLocationDelId.end()) + { + m_listLocationDelId.append(*location++); + } + } + + std::string str = "FUNC_NOM_IA_EDIT"; + if(PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF,&str)) + { + m_aiOptPerm = false; + LOGINFO("无智能告警编辑权限"); + }else + { + m_aiOptPerm = true; + } + } +} + +void CAlarmForm::setAlarmOperateEnable(const bool &bEnable) +{ + ui->confirm->setEnabled(bEnable); + ui->remove->setEnabled(bEnable); + m_isNormal = bEnable; +} + +void CAlarmForm::setColumnWidth(const int &column, const int &width) +{ + if(ui->alarmView != Q_NULLPTR) + { + ui->alarmView->setColumnWidth(column, width); + } + if(ui->aiAlarmTreeView != Q_NULLPTR) + { + ui->aiAlarmTreeView->setColumnWidth(column, width); + } +} + +void CAlarmForm::setColumnVisible(const int &column, const bool &visible) +{ + if(ui->alarmView != Q_NULLPTR) + { + ui->alarmView->setColumnHidden(column, !visible); + } + if(ui->aiAlarmTreeView != Q_NULLPTR) + { + ui->aiAlarmTreeView->setColumnHidden(column, !visible); + } +} + +void CAlarmForm::setEnableAccidentReview(bool isNeed) +{ + m_isNeedAccidentReview = isNeed; +} + +void CAlarmForm::setEnableTrend(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableTrend(isNeed); + } + if(m_aiDelegate) + { + m_aiDelegate->setEnableTrend(isNeed); + } +} + +void CAlarmForm::setEnableVideo(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableVideo(isNeed); + } + if(m_aiDelegate) + { + m_aiDelegate->setEnableVideo(isNeed); + } +} + +void CAlarmForm::setEnableWave(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableWave(isNeed); + } + if(m_aiDelegate) + { + m_aiDelegate->setEnableWave(isNeed); + } +} + +void CAlarmForm::setEnableLevel(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableLevel(isNeed); + } + if(m_aiDelegate) + { + m_aiDelegate->setEnableLevel(isNeed); + } +} + +void CAlarmForm::setHiddenLocation(bool hide) +{ + ui->label_4->setHidden(hide); + ui->comboBox_2->setHidden(hide); +} + +void CAlarmForm::setHiddenTime(bool hide) +{ + ui->label_6->setHidden(hide); + ui->lineEdit->setHidden(hide); +} + +void CAlarmForm::setHiddenStatus(bool hide) +{ + ui->label_5->setHidden(hide); + ui->comboBox_3->setHidden(hide); +} + +void CAlarmForm::setHiddenPriority(bool hide) +{ + ui->label_3->setHidden(hide); + ui->comboBox->setHidden(hide); +} + +void CAlarmForm::setHiddenCheckBox(bool hide) +{ + ui->checkBox->setHidden(hide); +} + +void CAlarmForm::setHiddenSetConfig(bool hide) +{ + ui->set->setHidden(hide); +} + +void CAlarmForm::setHiddenCloseButton(bool hide) +{ + ui->closeBtn->setHidden(hide); +} + +void CAlarmForm::setHiddenInhiAlarmButton(bool hide) +{ + ui->inhiAlarm->setHidden(hide); +} + +void CAlarmForm::setHiddenSelectButton(bool hide) +{ + ui->selectAll->setHidden(hide); + ui->selectNone->setHidden(hide); +} + +void CAlarmForm::setHiddenLeftTree() +{ + ui->deviceView->hide(); + ui->filter->hide(); + + /*隐藏全选以及frame框架*/ + ui->btn_tree_all_sel->hide(); + ui->btn_tree_none_sel->hide(); + ui->widget->hide(); + + ui->label_2->hide(); + ui->showRow->hide(); + ui->label->hide(); + ui->filterRow->hide(); +} + +void CAlarmForm::setShowAiAlarmView(bool show) +{ + if(m_treeModel) + { + ui->checkBox->setHidden(false); + ui->checkBox->setChecked(show); + }else + { + ui->checkBox->setHidden(true); + } +} + +void CAlarmForm::setRowHeight(int height) +{ + if(ui->alarmView != Q_NULLPTR) + { + ui->alarmView->setDefaultRowHeight(height); + } +} + +void CAlarmForm::setAccidentReviewPath(const QString &path) +{ + m_strAccidenPath = path; +} + +void CAlarmForm::removeAllAlarm() +{ + //移除所有告警 + //清除所有历史事件 + //< 删除部分 界面本身不应该操作历史库,该项目强制要求,特殊处理,目前只考虑地铁电源监控项目应用,兼容性存在严重问题 + + + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setInformativeText(tr("确定删除所有事件?")); + //QPushButton *no = msgBox->addButton(tr("取消"), QMessageBox::AcceptRole); + QPushButton *yes = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + + msgBox->setDefaultButton(yes); + msgBox->exec(); + if (msgBox->clickedButton() == yes) + { + delete msgBox; + msgBox = NULL; + } + else + { + delete msgBox; + msgBox = NULL; + return; + } + + ui->alarmView->selectAll(); + //未选中不需要弹框; + m_bPopWindow =false; + slot_confirmAlarm(); + //确认服务端延时,再删除 + QThread::msleep(300); + slot_removeAlarm(); + + /* 为以后搜索方便,保留此注释 + * 使用当前连接参数,不再使用默认值 + iot_dbms::CDbPara objPara; + + objPara.setUserName("root"); + * objPara.setPassword(EMS_DEFAULT_PASSWD); + objPara.setPort(3306); + objPara.setHostName("127.0.0.1"); + * objPara.setDatabaseName(EMS_DEFAULT_DATABASE); + objPara.setDbType(iot_dbms::EDbType::DB_MYSQL); + */ + + iot_dbms::CDbBaseApi BaseApi(m_pReadDb->getCurrentDbPara()); + if(BaseApi.open()) + { + QSqlDatabase *conn = BaseApi.getDatabase(); + if(conn ==NULL) + { + // QMessageBox::warning(this,"1","数据库连接对象为空",QMessageBox::Ok); + return; + } + //HisMngApi.delHisDbAll(conn); + QMessageBox::warning(this, tr("提示"), tr("删除完成!"), QMessageBox::Ok); + } +} + +void CAlarmForm::initFilter() +{ + m_pListWidget1->clear(); + m_pListWidget2->clear(); + m_pListWidget3->clear(); + QMap priority = CAlarmBaseData::instance()->getPermPriorityMap(); + QMap alarmStatus = CAlarmBaseData::instance()->getAlarmShowStatusMap(); + for(QMap::iterator it1 = priority.begin();it1 != priority.end();++it1) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget1); + pItem->setData(Qt::UserRole, it1.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it1.value()); + m_pListWidget1->addItem(pItem); + m_pListWidget1->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged1(int))); + } + + QList locationList = CAlarmBaseData::instance()->getPermLocationOrder(); + foreach (const int locId, locationList) { + QString locDesc = CAlarmBaseData::instance()->getPermLocationDesc(locId); + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget2); + pItem->setData(Qt::UserRole, locId); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(locDesc); + m_pListWidget2->addItem(pItem); + m_pListWidget2->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged2(int))); + } + + for(QMap::iterator it3 = alarmStatus.begin();it3 != alarmStatus.end();++it3) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget3); + pItem->setData(Qt::UserRole, it3.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it3.value()); + m_pListWidget3->addItem(pItem); + m_pListWidget3->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged3(int))); + } + m_strText1 = tr("请选择优先级"); + m_strText2 = tr("请选择位置"); + m_strText3 = tr("请选择告警状态"); + m_pLineEdit1->setText(m_strText1); + m_pLineEdit2->setText(m_strText2); + m_pLineEdit3->setText(m_strText3); +} + +void CAlarmForm::setLevelComboBox(bool &isLevelFilter, QList &listLevel) +{ + if(isLevelFilter == true && listLevel.size() > 0) + { + QString strText(""); + for (int i = 0; i < m_pListWidget1->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listLevel.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText1 = strText; + m_pLineEdit1->setText(strText); + }else + { + for (int i = 0; i < m_pListWidget1->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + } +} + +void CAlarmForm::setLocationComboBox(bool &isLocationFilter,QList &listLocation) +{ + if(isLocationFilter == true && listLocation.size() > 0) + { + QString strText(""); + for (int i = 0; i < m_pListWidget2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listLocation.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText2 = strText; + m_pLineEdit2->setText(strText); + }else + { + for (int i = 0; i < m_pListWidget2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + } +} + +void CAlarmForm::setAlarmStatusComboBox(bool &isAlarmTypeFilter, QList &listAlarmStatus) +{ + if(isAlarmTypeFilter == true && listAlarmStatus.size() > 0) + { + QString strText(""); + for (int i = 0; i < m_pListWidget3->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listAlarmStatus.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText3 = strText; + m_pLineEdit3->setText(strText); + }else + { + for (int i = 0; i < m_pListWidget3->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText3 = tr("请选择告警状态"); + m_pLineEdit3->setText(tr("请选择告警状态")); + } +} + +void CAlarmForm::setAlarmTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime) +{ + if(isTimeFilter == true) + { + ui->lineEdit->setText(startTime.date().toString("yyyy-MM-dd")+"~"+endTime.date().toString("yyyy-MM-dd")); + }else + { + ui->lineEdit->setText(tr("请选择时间")); + } +} + +void CAlarmForm::setAlarmModel(CAlarmItemModel *model,CAiAlarmTreeModel *treeModel) +{ + ui->checkBox->setChecked(true); + slot_changePage(0); + ui->alarmView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); + ui->aiAlarmTreeView->header()->setSortIndicator(0, Qt::AscendingOrder); + +// ui->alarmView->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); +// ui->aiAlarmTreeView->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); + + m_pModel = model; + m_delegate = new CAlarmDelegate(m_pModel, ui->alarmView); + connect(m_delegate,&CAlarmDelegate::openVideo,this,&CAlarmForm::openVideo,Qt::QueuedConnection); + connect(m_delegate,&CAlarmDelegate::openTrend,this,&CAlarmForm::openTrend,Qt::QueuedConnection); + connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,m_delegate,&CAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); + + ui->alarmView->initialize(); + ui->aiAlarmTreeView->initialize(); + ui->alarmView->setItemDelegate(m_delegate); + ui->alarmView->setModel(m_pModel); + + + + m_treeModel = treeModel; + m_aiDelegate = new CAiAlarmDelegate(m_treeModel,ui->aiAlarmTreeView); + ui->aiAlarmTreeView->setItemDelegate(m_aiDelegate); + ui->aiAlarmTreeView->setModel(m_treeModel); + connect(m_aiDelegate,&CAiAlarmDelegate::openVideo,this,&CAlarmForm::openVideo,Qt::QueuedConnection); + connect(m_aiDelegate,&CAiAlarmDelegate::openTrend,this,&CAlarmForm::openTrend,Qt::QueuedConnection); + connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,m_aiDelegate,&CAiAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); + //< 性能损耗 + //connect(ui->alarmView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(slot_selectionChanged()), Qt::QueuedConnection); + + connect(ui->alarmView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pModel, SLOT(sortColumn(int,Qt::SortOrder))); + connect(ui->aiAlarmTreeView->header(),&QHeaderView::sortIndicatorChanged, m_treeModel,&CAiAlarmTreeModel::sortColumn); + connect(ui->aiAlarmTreeView,&CAiAlarmTreeView::doubleClicked, this,&CAlarmForm::aiAlmDoubleClicked); + ui->confirm->setEnabled(true); + ui->remove->setEnabled(true); + //原始告警窗 + + ui->alarmView->setColumnWidth(0, 230); + ui->alarmView->setColumnWidth(1, 120); + ui->alarmView->setColumnWidth(2, 150); + ui->alarmView->setColumnWidth(5, 150); + ui->alarmView->setColumnWidth(6, 120); + + QSettings columFlags("IOT_HMI", "alarm config"); + for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount() - 1; nColumnIndex++) + { + bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); + ui->alarmView->setColumnHidden(nColumnIndex, visible); + } + ui->alarmView->setColumnHidden(m_pModel->columnCount() - 1, false); + //智能告警窗 + ui->aiAlarmTreeView->setColumnWidth(0, 230); + ui->aiAlarmTreeView->setColumnWidth(1, 120); + ui->aiAlarmTreeView->setColumnWidth(2, 150); + ui->aiAlarmTreeView->setColumnWidth(5, 150); + ui->aiAlarmTreeView->setColumnWidth(6, 120); + + for(int nColumnIndex(0); nColumnIndex < m_treeModel->columnCount(); nColumnIndex++) + { + bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); + ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, visible); + } + + loadDeviceGroupFilterWidget(); + if(m_pDeviceModel) + { + connect(m_pDeviceModel, &CAlarmDeviceTreeModel::itemCheckStateChanged, this, &CAlarmForm::deviceGroupFilterChanged); + connect(m_pDeviceModel, &CAlarmDeviceTreeModel::inhibitDevGroupAlm, this, &CAlarmForm::slotInhibitDevGroupAlm); + connect(CAlarmDataCollect::instance(),&CAlarmDataCollect::sigDevTreeUpdate,m_pDeviceModel,&CAlarmDeviceTreeModel::slotDevTreeUpdate); + connect(ui->deviceView , &CAlarmDeviceTreeView::doubleClicked , m_pDeviceModel , &CAlarmDeviceTreeModel::slotTreeCheckBoxState); + } + initFilter(); +} + +void CAlarmForm::setAlarmModel(CAlarmItemModel *model) +{ + ui->checkBox->setChecked(false); + ui->checkBox->setHidden(true); + slot_changePage(0); + ui->alarmView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); + + m_pModel = model; + m_delegate = new CAlarmDelegate(m_pModel, ui->alarmView); + connect(m_delegate,&CAlarmDelegate::openVideo,this,&CAlarmForm::openVideo,Qt::QueuedConnection); + connect(m_delegate,&CAlarmDelegate::openTrend,this,&CAlarmForm::openTrend,Qt::QueuedConnection); + connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,m_delegate,&CAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); + ui->alarmView->initialize(); + ui->alarmView->setItemDelegate(m_delegate); + ui->alarmView->setModel(m_pModel); + + connect(ui->alarmView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pModel, SLOT(sortColumn(int,Qt::SortOrder))); + ui->confirm->setEnabled(true); + ui->remove->setEnabled(true); + //原始告警窗 + + ui->alarmView->setColumnWidth(0, 230); + ui->alarmView->setColumnWidth(1, 120); + ui->alarmView->setColumnWidth(2, 150); + ui->alarmView->setColumnWidth(5, 150); + ui->alarmView->setColumnWidth(6, 120); + + + QSettings columFlags("IOT_HMI", "alarm config"); + for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount() - 1; nColumnIndex++) + { + bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); + ui->alarmView->setColumnHidden(nColumnIndex, visible); + } + ui->alarmView->setColumnHidden(m_pModel->columnCount() - 1, false); + + loadDeviceGroupFilterWidget(); + if(m_pDeviceModel) + { + connect(m_pDeviceModel, &CAlarmDeviceTreeModel::itemCheckStateChanged, this, &CAlarmForm::deviceGroupFilterChanged); + connect(m_pDeviceModel, &CAlarmDeviceTreeModel::inhibitDevGroupAlm, this, &CAlarmForm::slotInhibitDevGroupAlm); + connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigDevTreeUpdate, m_pDeviceModel, &CAlarmDeviceTreeModel::slotDevTreeUpdate); + connect(ui->deviceView, &CAlarmDeviceTreeView::doubleClicked, m_pDeviceModel, &CAlarmDeviceTreeModel::slotTreeCheckBoxState); + } + initFilter(); +} + +void CAlarmForm::updateView() +{ + updateRowTips(); + updateDeviceGroupHiddenState(); +} + +void CAlarmForm::updateFilter() +{ + bool isLevelFilter; + QList levelFilter; + bool isLocationFilter; + QList locationFilter; + bool isRegionFilter; + QList regionFilter; + bool isAlarmStatusFilter; //告警状态过滤 + QList typeFilter; + bool deviceTypeFilter; + QString subSystem; + QString deviceType; + bool keywordFilter; + QString keyword; + bool isTimeFilterEnable; + QDateTime startTime; + QDateTime endTime; + bool isStateFilterEnable; + bool isConfirm; + bool isReturnFilterEnable; + bool isReturn; + + CAlarmFilterDialog filterDlg; + m_pModel->getFilter(isLevelFilter, levelFilter, + isLocationFilter, locationFilter, + isRegionFilter, regionFilter, + isAlarmStatusFilter, typeFilter, + deviceTypeFilter, subSystem, deviceType, + keywordFilter, keyword, + isTimeFilterEnable, startTime, endTime, + isStateFilterEnable, isConfirm, + isReturnFilterEnable,isReturn); + filterDlg.initialize(); + filterDlg.setLevelFilterEnable(isLevelFilter); + filterDlg.setLevelFilter(levelFilter); + filterDlg.setLocationFilterEnable(isLocationFilter); + filterDlg.setLocationFilter(locationFilter); + filterDlg.setRegionFilterEnable(isRegionFilter); + filterDlg.setRegionFilter(regionFilter); + filterDlg.setAlarmStatusFilterEnable(isAlarmStatusFilter); + filterDlg.setAlarmStatusFilter(typeFilter); + filterDlg.setDeviceFilterEnable(deviceTypeFilter); + filterDlg.setSubSystem(subSystem); + filterDlg.setDeviceType(deviceType); + filterDlg.setkeyWordFilterEnable(keywordFilter); + filterDlg.setkeyWordFilteContent(keyword); + filterDlg.setTimeFilterEnable(isTimeFilterEnable); + filterDlg.setStartTimeFilter(startTime); + filterDlg.setEndTimeFilter(endTime); + filterDlg.setStateFilterEnable(isStateFilterEnable); + filterDlg.setStateFilter(isConfirm); + filterDlg.setReturnFilterEnable(isReturnFilterEnable); + filterDlg.setReturnFilter(isReturn); + connect(&filterDlg, SIGNAL(sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool, bool, bool)), + this, SLOT(slot_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime, bool, bool, bool, bool))); + filterDlg.exec(); +} + +void CAlarmForm::deviceGroupFilterChanged(const QString &device, const bool &checked) +{ + if(checked) + { + m_pModel->removeDeviceGroupFilter(device); + if(m_treeModel) + { + m_treeModel->removeDeviceGroupFilter(device); + } + } + else + { + m_pModel->addDeviceGroupFilter(device); + if(m_treeModel) + { + m_treeModel->addDeviceGroupFilter(device); + } + } + ui->deviceView->viewport()->update(); +} + +void CAlarmForm::slot_changePage(int i) +{ + Q_UNUSED(i) + if(!ui->checkBox->isChecked()) + { + ui->stackedWidget->setCurrentIndex(0); + ui->aiAlarmTreeView->setUpdatesEnabled(false); + ui->alarmView->setUpdatesEnabled(true); + ui->inhiAlarm->setEnabled(true); + }else + { + ui->stackedWidget->setCurrentIndex(1); + ui->alarmView->setUpdatesEnabled(false); + ui->aiAlarmTreeView->setUpdatesEnabled(true); + ui->inhiAlarm->setEnabled(false); + } +} + +void CAlarmForm::slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isAlarmTypeFilter, QList listAlarmStatus, + bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isConfirmFilter, bool confirm, bool isReturnFilter, bool isReturn) +{ + m_pModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmStatus, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime, isConfirmFilter, confirm,isReturnFilter,isReturn); + if(m_treeModel) + { + m_treeModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmStatus, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime, isConfirmFilter, confirm,isReturnFilter,isReturn); + } + //设置下拉框的值 + setLevelComboBox(isLevelFilter,listLevel); + setLocationComboBox(isLocationFilter,listLocation); + setAlarmStatusComboBox(isAlarmTypeFilter,listAlarmStatus); + setAlarmTimeLineEdit(isTimeFilter, startTime, endTime); +} + +void CAlarmForm::slotALlSel() +{ + m_pDeviceModel->setAllDeviceCheckState(Qt::Checked); + ui->deviceView->repaint(); +} + +void CAlarmForm::slotNoneSel() +{ + m_pDeviceModel->setAllDeviceCheckState(Qt::Unchecked); + ui->deviceView->repaint(); + +} + +void CAlarmForm::slot_removeAlarm() +{ + updateAlarmOperatePerm(); + if(!ui->checkBox->isChecked()) + { + removeAlarm0(); + }else + { + removeAlarm1(); + } + +} + +void CAlarmForm::slot_confirmAlarm() +{ + updateAlarmOperatePerm(); + if(!ui->checkBox->isChecked()) + { + confirmAlarm0(); + }else + { + confirmAlarm1(); + } + + // QMessageBox::warning(this, tr("提示"), tr("确认完成!"), QMessageBox::Ok); +} + +void CAlarmForm::slot_showInhibitAlarm() +{ + CAlarmInhibitDialog dlg; + QList almList; + CAlarmMsgManage::instance()->getAllInhibitAlm(almList); + + dlg.setInhibitAlarmList(almList); + connect(&dlg, &CAlarmInhibitDialog::removeInhibitAlarmList, this, &CAlarmForm::removeInhibitAlarm); + dlg.exec(); + +} + +void CAlarmForm::slot_showShiledAlarm() +{ + CAlarmShiledDialog dlg; + dlg.exec(); +} + +void CAlarmForm::slot_showColorSet() +{ + CAlarmSetDlg dlg; + dlg.exec(); +} + +void CAlarmForm::removeInhibitAlarm(QList alarmList) +{ + foreach (AlarmMsgPtr alm, alarmList) + { + CAlarmMsgManage::instance()->removeInhibitTag(alm->key_id_tag); + } +} + +void CAlarmForm::searchDeviceName() +{ + m_searchDeviceName = m_pSearchTextEdit->text().trimmed(); + updateDeviceGroupHiddenState(); +} + +void CAlarmForm::updateRowTips() +{ + if(!ui->checkBox->isChecked()) + { + if(m_pModel) + { + ui->alarmView->viewport()->update(); + ui->showRow->setText(QString::number(m_pModel->rowCount())); + int nNumber = m_pModel->filterCount(); + if(nNumber<0) nNumber = 0 ; + ui->filterRow->setText(QString::number(nNumber)); + } + } + else + { + if(m_treeModel) + { + ui->aiAlarmTreeView->viewport()->update(); + int showNum = m_treeModel->getShowNum(); + int showAiNum = m_treeModel->getShowAi(); + int filterAi = CAlarmMsgManage::instance()->getAiCount() -showAiNum; + int showTotal = CAlarmMsgManage::instance()->getAlmTotal(); + ui->showRow->setText(QString("%1/%2").arg(showNum).arg(showAiNum)); + int nNumber = showTotal - showNum; + if(nNumber<0) nNumber = 0 ; + if(filterAi<0) filterAi = 0; + ui->filterRow->setText(QString("%1/%2").arg(nNumber).arg(filterAi)); + } + } +} + +void CAlarmForm::print() +{ + //QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"",tr("(*.pdf *)")); + QString fileName=QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"*.xlsx");//获取保存路径*.xls + if(!ui->checkBox->isChecked()) + { + print0(fileName); + }else + { + print1(fileName); + } +} + +void CAlarmForm::stateChanged1(int state) +{ + Q_UNUSED(state) + QString strText(""); + m_priorityList.clear(); + int nCount = m_pListWidget1->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_priorityList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText1 = strText; + m_pLineEdit1->setText(strText); + } + else + { + m_pLineEdit1->clear(); + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + } + bool isCheck = false; + if(m_priorityList.size() > 0) + { + isCheck = true; + } + if(m_pModel) + { + m_pModel->setPriorityFilter(isCheck,m_priorityList); + } + if(m_treeModel) + { + m_treeModel->setPriorityFilter(isCheck,m_priorityList); + } +} + +void CAlarmForm::stateChanged2(int state) +{ + Q_UNUSED(state) + QString strText(""); + m_locationList.clear(); + int nCount = m_pListWidget2->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_locationList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText2 = strText; + m_pLineEdit2->setText(strText); + } + else + { + m_pLineEdit2->clear(); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + } + bool isCheck = false; + if(m_locationList.size() > 0) + { + isCheck = true; + } + if(m_pModel) + { + m_pModel->setLocationFilter(isCheck,m_locationList); + } + if(m_treeModel) + { + m_treeModel->setLocationFilter(isCheck,m_locationList); + } +} + +void CAlarmForm::stateChanged3(int state) +{ + Q_UNUSED(state) + QString strText(""); + m_alarmStatusList.clear(); + bool other = false; + int nCount = m_pListWidget3->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + if(nData == OTHERSTATUS) + { + other = true; + } + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_alarmStatusList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText3 = strText; + m_pLineEdit3->setText(strText); + } + else + { + m_pLineEdit3->clear(); + m_strText3 = tr("请选择告警状态"); + m_pLineEdit3->setText(tr("请选择告警状态")); + } + bool isCheck = false; + if(m_alarmStatusList.size() > 0) + { + isCheck = true; + } + if(m_pModel) + { + m_pModel->setAlarmTypeFilter(isCheck,m_alarmStatusList,other); + } + if(m_treeModel) + { + m_treeModel->setAlarmTypeFilter(isCheck,m_alarmStatusList,other); + } +} + +void CAlarmForm::textChanged1(const QString &text) +{ + Q_UNUSED(text) + m_pLineEdit1->setText(m_strText1); +} + +void CAlarmForm::textChanged2(const QString &text) +{ + Q_UNUSED(text) + m_pLineEdit2->setText(m_strText2); +} + +void CAlarmForm::textChanged3(const QString &text) +{ + Q_UNUSED(text) + m_pLineEdit3->setText(m_strText3); +} + +void CAlarmForm::myCalendarHide(QDate startTime,QDate endTime) +{ + ui->lineEdit->setText(startTime.toString("yyyy-MM-dd") +"~"+endTime.toString("yyyy-MM-dd")); + //开始过滤 + bool isCheck = true; + if(m_pModel) + { + m_pModel->setAlarmTimeFilter(isCheck,startTime,endTime); + } + if(m_treeModel) + { + m_treeModel->setAlarmTimeFilter(isCheck,startTime,endTime); + } + m_timeMenu->hide(); +} + +void CAlarmForm::myCalendarShow() +{ + QPoint point(QCursor::pos().x()-500,QCursor::pos().y()+15); + m_timeMenu->move(point); + m_timeMenu->show(); +} + +void CAlarmForm::cancleTimeFilter() +{ + ui->lineEdit->setText(tr("请选择时间")); + //取消过滤 + bool isCheck = false; + if(m_pModel) + { + m_pModel->setAlarmTimeFilter(isCheck); + } + if(m_treeModel) + { + m_treeModel->setAlarmTimeFilter(isCheck); + } + + m_timeMenu->hide(); +} + +void CAlarmForm::aiAlmDoubleClicked(const QModelIndex &index) +{ + if(m_treeModel == NULL) + { + return ; + } + if(!index.isValid()) + { + return ; + } + CAiAlarmTreeItem *item =static_cast(index.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr aiPtr; + if(item->getAiPtr(aiPtr)) + { + CDisposalPlanDialog dialog(aiPtr); + dialog.exec(); + }else + { + LOGERROR("aiAlmDoubleClicked():标识符错误!"); + } + } +} + +void CAlarmForm::printMess(QString fileName) +{ + Q_UNUSED(fileName); + QMessageBox::information( 0, tr("提示"), tr("导出成功")); +} + +void CAlarmForm::slotInhibitDevGroupAlm(const QString &strDevg, int nDomainId, int nLocationId, int nSubsystemId, int nRegionId) +{ + if(!permCheck(nLocationId,nRegionId)) + { + return; + } + QList pointList; + if(!CAlarmBaseData::instance()->queryAllPointDevGroup(nDomainId, nSubsystemId, strDevg, pointList)) + { + QMessageBox::information(this, tr("提示"), tr("禁止告警失败,请检查实时库连接!")); + return; + } + for(int n(0); ndomain_id = nDomainId; + almMsgPtr->location_id = nLocationId; + almMsgPtr->sub_system = nSubsystemId; + almMsgPtr->key_id_tag = pointList[n]; + inhibitAlm(almMsgPtr); + } +} +/*原始*/ +//void CAlarmForm::slotInhibitAlarm() +//{ +// if(!m_pModel) +// { +// return; +// } +// QModelIndex index = ui->alarmView->currentIndex(); +// if(!index.isValid()) +// { +// QMessageBox::information(this, tr("提示"), tr("请选择一条告警!")); +// return; +// } +// AlarmMsgPtr alm = m_pModel->getAlarmInfo(index); +// if(!permCheck(alm->location_id,alm->region_id)) +// { +// return; +// } +// inhibitAlm(alm); +//} +/*修改后*/ +void CAlarmForm::slotInhibitAlarm() +{ + QItemSelectionModel *selectModel = ui->alarmView->selectionModel(); + QModelIndexList indexs = selectModel->selectedIndexes(); + if(indexs.count()>0) + { + for(auto index:indexs) + { + if(index.column() == 0) + { + bool flag = false; + slotInhibitAlarms(index,flag); + if(!flag) + continue; + } + } + indexs.clear(); + } + else + { + indexs.clear(); + QMessageBox::information(this, tr("提示"), tr("请选择至少一条告警!")); + return ; + } +} +void CAlarmForm::slotInhibitAlarms(QModelIndex a,bool &flag) +{ + if(!m_pModel) + { + return; + } + // QModelIndex index = ui->alarmView->currentIndex(); + QModelIndex index = a; + if(!index.isValid()) + { + QMessageBox::information(this, tr("提示"), tr("请选择至少一条告警!")); + return; + } + AlarmMsgPtr alm = m_pModel->getAlarmInfo(index); + if(!permCheck(alm->location_id,alm->region_id)) + { + return; + } + inhibitAlm(alm,flag); +} + +void CAlarmForm::contextMenuEvent(QContextMenuEvent *event) +{ + if(!m_isNormal) + { + return ; + } + updateAlarmOperatePerm(); + if(ui->stackedWidget->currentIndex() == 0) + { + contextMenuStack0Event(event); + }else if(ui->stackedWidget->currentIndex() == 1) + { + contextMenuStack1Event(event); + } +} + +void CAlarmForm::contextMenuStack0Event(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + if(!m_pModel) + { + return; + } + if(event->pos().x() < ui->alarmView->pos().x()) + { + return; + } + QRect headerRect = ui->alarmView->horizontalHeader()->rect(); + headerRect.moveTopLeft(ui->alarmView->mapTo(this, QPoint())); + if(headerRect.contains(event->pos())) + { + QMenu columnMenu(this); + + for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount()-1; nColumnIndex++) + { + QAction * action = columnMenu.addAction(m_pModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); + action->setCheckable(true); + action->setChecked(!ui->alarmView->isColumnHidden(nColumnIndex)); + connect(action, &QAction::triggered, [=](){ + ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); + ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); + QSettings columFlags("IOT_HMI", "alarm config"); + columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); + }); + } + columnMenu.exec(QCursor::pos()); + } + else + { + QModelIndex index_ = ui->alarmView->indexAt(ui->alarmView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index_.isValid()) + { + return; + } + QModelIndexList indexLists = ui->alarmView->selectionModel()->selectedIndexes(); + //判断右键位置是否在选中区 + QModelIndex index = ui->alarmView->currentIndex(); + if(!indexLists.contains(index)) + { + ui->alarmView->clearSelection(); + ui->alarmView->setCurrentIndex(index); + } + AlarmMsgPtr alm = m_pModel->getAlarmInfo(index); + QMenu menu(this); + QAction * selectAction = menu.addAction(tr("全选")); + connect(selectAction, &QAction::triggered, [=](){ui->alarmView->selectAll();}); + QAction * cancleAction = menu.addAction(tr("全不选")); + connect(cancleAction,&QAction::triggered,[=](){ui->alarmView->clearSelection();}); + menu.addSeparator(); + + QAction * confirmAction = menu.addAction(tr("确认")); + connect(confirmAction,&QAction::triggered,[=](){ + rightConfirm0(); + }); + QAction * removeAction = menu.addAction(tr("删除")); + connect(removeAction,&QAction::triggered,[=](){ + rightRemove0(); + }); + + menu.addSeparator(); + + // QAction * trendAction = menu.addAction(tr("趋势")); + + // connect(trendAction,&QAction::triggered,[=](){ + // rightTrend0(); + // }); + if(alm->m_needVideoAlm) + { + QAction * videoAction = menu.addAction(tr("视频")); + connect(videoAction,&QAction::triggered,[=](){ + rightVideo0(); + }); + } + // QAction * faultRecordAction = menu.addAction(tr("故障录播")); + // connect(faultRecordAction,&QAction::triggered,[=](){ + // rightFaultRecord0(); + // }); + + + if(m_isNeedAccidentReview) + { + QAction * accidentReviewAction = menu.addAction(tr("事故追忆")); + connect(accidentReviewAction,&QAction::triggered,[=](){ + rightAccidentReview0(); + }); + } + + QAction * InhibitAction = menu.addAction(tr("禁止告警")); + connect(InhibitAction, &QAction::triggered, [=](){ + // bool isContains = false; + // QList almList; + // CAlarmMsgManage::instance()->getAllInhibitAlm(almList); + if(!permCheck(alm->location_id,alm->region_id)) + { + return; + } + inhibitAlm(alm); + // foreach (AlarmMsgPtr alarm, almList) + // { + // if(alarm->key_id_tag == alm->key_id_tag) + // { + // isContains = true; + // break; + // } + // } + // if(isContains) + // { + // QMessageBox::warning(this, tr("警告"), tr("当前测点告警已禁止,无需重复禁止!"), QMessageBox::Ok); + // } + // else + // { + // CAlarmMsgManage::instance()->addInhibitAlm(alm); + // } + }); + + menu.exec(QCursor::pos()); + } +} + +void CAlarmForm::contextMenuStack1Event(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + if(!m_treeModel) + { + return; + } + if(event->pos().x() < ui->aiAlarmTreeView->pos().x()) + { + return; + } + QRect headerRect = ui->aiAlarmTreeView->header()->rect(); + headerRect.moveTopLeft(ui->aiAlarmTreeView->mapTo(this, QPoint())); + if(headerRect.contains(event->pos())) + { + QMenu columnMenu(this); + + for(int nColumnIndex(0); nColumnIndex < m_treeModel->columnCount()-1; nColumnIndex++) + { + QAction * action = columnMenu.addAction(m_treeModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); + action->setCheckable(true); + action->setChecked(!ui->aiAlarmTreeView->isColumnHidden(nColumnIndex)); + connect(action, &QAction::triggered, [=](){ + ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); + ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); + QSettings columFlags("IOT_HMI", "alarm config"); + columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); + }); + } + columnMenu.exec(QCursor::pos()); + }else + { + QModelIndex index_ = ui->aiAlarmTreeView->indexAt(ui->aiAlarmTreeView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index_.isValid()) + { + return; + } + QMenu menu(this); + QModelIndex index = ui->aiAlarmTreeView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QModelIndexList indexLists = ui->aiAlarmTreeView->selectionModel()->selectedIndexes(); + + //判断右键位置是否在选中区 + if(!indexLists.contains(index)) + { + ui->aiAlarmTreeView->clearSelection(); + ui->aiAlarmTreeView->setCurrentIndex(index); + } + QAction * selectAction = menu.addAction(tr("全选")); + connect(selectAction,&QAction::triggered,[=](){ui->aiAlarmTreeView->selectAll();}); + QAction * cancleAction = menu.addAction(tr("全不选")); + connect(cancleAction,&QAction::triggered,[=](){ui->aiAlarmTreeView->clearSelection();}); + menu.addSeparator(); + QAction * confirmAction = menu.addAction(tr("确认")); + connect(confirmAction,&QAction::triggered,[=](){ + rightConfirm1(); + }); + QAction * removeAction = menu.addAction(tr("删除")); + connect(removeAction,&QAction::triggered,[=](){ + rightRemove1(); + }); + menu.addSeparator(); + QAction * mergeAction = menu.addAction(tr("合并")); + connect(mergeAction,&QAction::triggered,[=](){ + rightMerge1(); + }); + QAction * seprAction = menu.addAction(tr("分离")); + connect(seprAction,&QAction::triggered,[=](){ + rightSepr1(); + }); + menu.addSeparator(); + //讨论删除右键趋势2020-6-17 jxd sjq zlx + + // QAction * trendAction = menu.addAction(tr("趋势")); + // connect(trendAction,&QAction::triggered,[=](){ + // rightTrend1(); + // }); + + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if(!item->isAi()) + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + if(ptr->m_needVideoAlm) + { + QAction * videoAction = menu.addAction(tr("视频")); + connect(videoAction,&QAction::triggered,[=](){ + rightVideo1(); + }); + } + } + } + // QAction * faultRecordAction = menu.addAction(tr("故障录播")); + // connect(faultRecordAction,&QAction::triggered,[=](){ + // rightFaultRecord1(); + // }); + if(m_isNeedAccidentReview) + { + QAction * accidentReviewAction = menu.addAction(tr("事故追忆")); + connect(accidentReviewAction,&QAction::triggered,[=](){ + rightAccidentReview1(); + }); + } + menu.exec(QCursor::pos()); + } +} + +void CAlarmForm::loadDeviceGroupFilterWidget() +{ + if(!m_pModel) + { + return; + } + QMap< int, QVector< SDevGroupInfo > > locationInfos; + + QList locationList = CAlarmBaseData::instance()->getPermLocationOrder(); + + if(m_pReadDb->isOpen()) + { + for(int nIndex(0); nIndex dev; + + QSqlQuery query; + QString sqlSequenceQuery = QString("select tag_name, description,sub_system,region_id from dev_group where location_id = %1;").arg(locationList[nIndex]); + if(m_pReadDb->execute(sqlSequenceQuery, query)) + { + while(query.next()) + { + SDevGroupInfo _stDevGroupInfo; + _stDevGroupInfo.tag_name = query.value(0).toString(); + _stDevGroupInfo.description = query.value(1).toString(); + _stDevGroupInfo.domain = CAlarmBaseData::instance()->queryDomainIdByLocId(locationList[nIndex]); + _stDevGroupInfo.location = locationList[nIndex]; + _stDevGroupInfo.sub_system = query.value(2).toInt(); + _stDevGroupInfo.region = query.value(3).toInt(); + dev.push_back(_stDevGroupInfo); + } + locationInfos.insert(locationList[nIndex], dev); + + + }else + { + LOGERROR("load device info error, dbInterface execute failed!"); + } + } + } + else + { + LOGERROR("load deviceGroup info error, database open failed!"); + } + m_pDeviceModel->removeData(); + m_pDeviceModel->setupModelData(locationInfos,locationList); + updateDeviceGroupHiddenState(); + ui->deviceView->expandAll(); +} + +void CAlarmForm::updateDeviceGroupHiddenState() +{ + QString content = m_searchDeviceName; + + QHash listDeviceStatisticalInfo = m_pDeviceModel->getDeviceStatisticalInfo(); + for(int nTopLevelRow(0); nTopLevelRow < m_pDeviceModel->rowCount(); nTopLevelRow++) + { + QModelIndex topLevelIndex = m_pDeviceModel->index(nTopLevelRow, 0); + for(int nChildRow(0); nChildRow < m_pDeviceModel->rowCount(topLevelIndex); nChildRow++) + { + QModelIndex devIndex = m_pDeviceModel->index(nChildRow, 0, topLevelIndex); + CAlarmDeviceTreeItem *item = static_cast(devIndex.internalPointer()); + bool isCountNo0 = !listDeviceStatisticalInfo.value(item->data(Qt::ItemDataRole(TagRole)).toString(), 0); + bool isHidden =false; + if(content.isEmpty()) + { + isHidden = isCountNo0; + } + else + { + QString devGroupStr = item->data(Qt::DisplayRole).toString(); + if(!devGroupStr.contains(content, Qt::CaseInsensitive)) + { + isHidden = true; + } + else + { + isHidden = isCountNo0; + } + } + + ui->deviceView->setRowHidden(nChildRow, topLevelIndex, isHidden); + } + } +} + +void CAlarmForm::print0(QString fileName) +{ + if(!fileName.isEmpty() && m_pModel) + { + if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) + fileName = fileName + ".xlsx"; + emit printExcelAlm(ui->alarmView,m_pModel,fileName); + } +} + +void CAlarmForm::print1(QString fileName) +{ + if(!fileName.isEmpty() && m_treeModel) + { + if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) + fileName = fileName + ".xlsx"; + emit printExcel(ui->aiAlarmTreeView,m_treeModel,fileName); + } +} + +void CAlarmForm::removeAlarm0() +{ + QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + if(m_bPopWindow) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + } + return; + } + + QList listInfo = m_pModel->getListShowAlarmInfo(); + //声明告警删除package + QMap pkgMap; //Domain-DelPkg; + int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 + int unConfirmSkip = -1; //< 未确认告警是否跳过: 0-单步跳过、1-全部跳过 + + if(!m_bPopWindow) + { + permSkip=1; + unConfirmSkip=1; + } + + QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); + for(;modelIndexIter != modelIndexList.end();modelIndexIter++) + { + AlarmMsgPtr info = listInfo.at(modelIndexIter->row()); + //< 权限过滤 + + if(!m_listLocationDelId.contains(info->location_id) || (!m_listRegionDelId.contains(info->region_id) && info->region_id != -1)) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + permSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + + //删除条件 + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) + { + if(1 != unConfirmSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含未确认告警!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + unConfirmSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + unConfirmSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + + //构建告警删除package + QMap::iterator it = pkgMap.find(info->domain_id); + if(it == pkgMap.end()) + { + iot_idl::SAlmCltDelAlm * pkg = new iot_idl::SAlmCltDelAlm(); + pkg->set_domain_id(info->domain_id); + pkgMap[info->domain_id] = pkg; + } + pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); + } + //请求删除 + foreach (iot_idl::SAlmCltDelAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestDelAlm(*pkg)!= true) + { + LOGERROR("请求删除原始告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + ui->alarmView->setFocus(); + // QMessageBox::warning(this, tr("提示"), tr("删除完成!"), QMessageBox::Ok); +} + +void CAlarmForm::removeAlarm1() +{ + if(!m_treeModel) + { + return ; + } + QModelIndexList modelIndexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QList aimsgList; //选中的智能告警 + QList msgList; //选中的原始告警 + //声明智能告警删除package + QMap aipkgMap; //Domain-DelPkg; ai + QMap pkgMap; //Domain-DelPkg; alarm + int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 + int unConfirmSkip = -1; //< 未确认告警是否跳过: 0-单步跳过、1-全部跳过 + QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); + for(;modelIndexIter != modelIndexList.end();modelIndexIter++) + { + if(!modelIndexIter->isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(modelIndexIter->internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + aimsgList.append(ptr); + } + }else + { + if(item->parent() == m_treeModel->getItem()) + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + msgList.append(ptr); + } + } + } + } + if(aimsgList.size() <= 0 && msgList.size() <= 0) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何智能告警和未聚类的原始告警!"), QMessageBox::Ok); + return; + } + //处理原始告警 + for(int alarm(0);alarmlocation_id) || (!m_listRegionDelId.contains(info->region_id) && info->region_id != -1)) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + permSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + //删除条件 + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) + { + if(1 != unConfirmSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含未确认告警!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + unConfirmSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + unConfirmSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + //构建告警删除package + QMap::iterator it = pkgMap.find(info->domain_id); + if(it == pkgMap.end()) + { + iot_idl::SAlmCltDelAlm * pkg = new iot_idl::SAlmCltDelAlm(); + pkg->set_domain_id(info->domain_id); + pkgMap[info->domain_id] = pkg; + } + pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); + } + //处理智能告警 + for(int aialarm(0);aialarmsetObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警删除操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + permSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(aipkgMap); + aipkgMap.clear(); + return; + } + } + else + { + continue; + } + } + if(CAlarmMsgManage::instance()->ifhaveNotConfirmAlmByuuid(aimsgList.at(aialarm)->uuid_base64)) + { + if(1 != unConfirmSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("包含未确认原始告警告警!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + unConfirmSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + unConfirmSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(aipkgMap); + aipkgMap.clear(); + return; + } + } + else + { + continue; + } + } + int domain_id = aimsgList.at(aialarm)->domain_id; + QString aiuuid = aimsgList.at(aialarm)->uuid_base64; + QMap::iterator it = aipkgMap.find(domain_id); + if(it == aipkgMap.end()) + { + iot_idl::SIntelliAlmDel * pkg = new iot_idl::SIntelliAlmDel(); + pkg->set_domain_id(domain_id); + aipkgMap[domain_id] = pkg; + } + aipkgMap.value(domain_id)->add_uuid_base64(aiuuid.toStdString()); + } + //请求删除 + foreach (iot_idl::SAlmCltDelAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestDelAlm(*pkg)!= true) + { + LOGDEBUG("请求删除原始告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + //请求删除 + foreach (iot_idl::SIntelliAlmDel * pkg, aipkgMap) + { + if(CAiAlarmDataCollect::instance()->requestDelAlm(*pkg) != true) + { + LOGDEBUG("请求删除智能告警失败!"); + } + } + qDeleteAll(aipkgMap); + aipkgMap.clear(); + ui->aiAlarmTreeView->setFocus(); + // QMessageBox::warning(this, tr("提示"), tr("删除完成!"), QMessageBox::Ok); +} + +void CAlarmForm::confirmAlarm0() +{ + LOGINFO("开始确认告警"); + QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty() ) + { + if(m_bPopWindow) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + } + return; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + if(listInfo.isEmpty()) + { + return; + } + + //构建告警确认package + QMap msgMap; //要确认的告警 + QMap pkgMap; //Domain-DelPkg; + + int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 + if(!m_bPopWindow) + { + permSkip =1; + } + + QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); + for(;modelIndexIter != modelIndexList.end();modelIndexIter++) + { + AlarmMsgPtr info = listInfo.at(modelIndexIter->row()); + if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || + info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL ) + { + continue; + } + msgMap[info->uuid_base64] = info; + } + QMap::iterator almIter = msgMap.begin(); + for(;almIter != msgMap.end();almIter++) + { + if(!m_listLocationOptId.contains(almIter.value()->location_id) || (!m_listRegionOptId.contains(almIter.value()->region_id) && almIter.value()->region_id != -1)) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + permSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + + QString key = QString("%1_%2_%3").arg(almIter.value()->domain_id).arg(almIter.value()->alm_type).arg(almIter.value()->app_id); + QMap::iterator it = pkgMap.find(key); + if(it == pkgMap.end()) + { + iot_idl::SAlmCltCfmAlm * pkg = new iot_idl::SAlmCltCfmAlm(); + pkg->set_node_name(m_nodeName); + pkg->set_user_id(m_userId); + pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); + pkg->set_domain_id(almIter.value()->domain_id); + pkg->set_app_id(almIter.value()->app_id); + pkg->set_alm_type(almIter.value()->alm_type); + pkgMap[key] = pkg; + } + pkgMap.value(key)->add_key_id_tag(almIter.value()->key_id_tag.toStdString()); + pkgMap.value(key)->add_time_stamp(almIter.value()->time_stamp); + pkgMap.value(key)->add_uuid_base64(almIter.value()->uuid_base64.toStdString()); + } + + //请求确认 + foreach (iot_idl::SAlmCltCfmAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestCfmAlm(*pkg) != true) + { + LOGERROR("请求确认告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + ui->alarmView->setFocus(); + LOGINFO("结束确认告警"); + // QMessageBox::warning(this, tr("提示"), tr("确认告警完成!"), QMessageBox::Ok); +} + +void CAlarmForm::confirmAlarm1() +{ + if(!m_treeModel) + { + return ; + } + QModelIndexList modelIndexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + if(m_bPopWindow) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + } + return; + } + QMap msgMap; //要确认的告警 + msgMap.clear(); + //构建告警确认package + QMap pkgMap; //Domain-DelPkg; + int permSkip = -1; //< 不具备确认权限时是否跳过: 0-单步跳过、1-全部跳过 + QModelIndexList::iterator modelIndexIter = modelIndexList.begin(); + for(;modelIndexIter != modelIndexList.end();modelIndexIter++) + { + if(!modelIndexIter->isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(modelIndexIter->internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + QList listPtr = item->getChildAlarmPtr(); + for(int x(0);xlogic_state == E_ALS_ALARM_CFM || listPtr.at(x)->logic_state == E_ALS_RETURN_CFM || + listPtr.at(x)->logic_state == E_ALS_ALARM_CFM_DEL || listPtr.at(x)->logic_state == E_ALS_RETURN_CFM_DEL ) + { + continue; + } + msgMap[listPtr.at(x)->uuid_base64] = listPtr.at(x); + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + if(ptr->logic_state == E_ALS_ALARM_CFM || ptr->logic_state == E_ALS_RETURN_CFM || + ptr->logic_state == E_ALS_ALARM_CFM_DEL || ptr->logic_state == E_ALS_RETURN_CFM_DEL ) + { + continue; + } + msgMap[ptr->uuid_base64] = ptr; + } + } + } + QMap::iterator almIter = msgMap.begin(); + for(;almIter != msgMap.end();almIter++) + { + if(!m_listLocationOptId.contains(almIter.value()->location_id) || (!m_listRegionOptId.contains(almIter.value()->region_id) && almIter.value()->region_id != -1)) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox = NULL; + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox = NULL; + permSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox = NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + else + { + continue; + } + } + QString key = QString("%1_%2_%3").arg(almIter.value()->domain_id).arg(almIter.value()->alm_type).arg(almIter.value()->app_id); + QMap::iterator it = pkgMap.find(key); + if(it == pkgMap.end()) + { + iot_idl::SAlmCltCfmAlm * pkg = new iot_idl::SAlmCltCfmAlm(); + pkg->set_node_name(m_nodeName); + pkg->set_user_id(m_userId); + pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); + pkg->set_domain_id(almIter.value()->domain_id); + pkg->set_app_id(almIter.value()->app_id); + pkg->set_alm_type(almIter.value()->alm_type); + pkgMap[key] = pkg; + } + pkgMap.value(key)->add_key_id_tag(almIter.value()->key_id_tag.toStdString()); + pkgMap.value(key)->add_time_stamp(almIter.value()->time_stamp); + pkgMap.value(key)->add_uuid_base64(almIter.value()->uuid_base64.toStdString()); + } + foreach (iot_idl::SAlmCltCfmAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestCfmAlm(*pkg) != true) + { + LOGERROR("请求确认告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + ui->aiAlarmTreeView->setFocus(); + // QMessageBox::warning(this, tr("提示"), tr("确认告警完成!"), QMessageBox::Ok); +} + +void CAlarmForm::rightConfirm0() +{ + confirmAlarm0(); +} + +void CAlarmForm::rightConfirm1() +{ + confirmAlarm1(); +} + +void CAlarmForm::rightRemove0() +{ + removeAlarm0(); +} + +void CAlarmForm::rightRemove1() +{ + removeAlarm1(); +} + +void CAlarmForm::rightMerge1() +{ + if(!m_treeModel) + { + return ; + } + QModelIndexList indexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + QList aimsgList; + QList msgList; + + foreach (QModelIndex modelIndex, indexList) + { + if(!modelIndex.isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(modelIndex.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + aimsgList.append(ptr); + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + msgList.append(ptr); + } + } + } + QMap pkgMap; + QList listPtr; + listPtr.clear(); + int permSkip = -1; + if(aimsgList.size() > 0) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含智能告警,无法合并!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含智能告警,无法合并!"), QMessageBox::Ok); + return ; + } + + for(int alarmIndex(0);alarmIndex < msgList.size();alarmIndex++) + { + if(msgList.at(alarmIndex) != NULL) + { + //判断此原始告警是否已经被聚类 + if(CAlarmMsgManage::instance()->isBelongAi(msgList.at(alarmIndex)->uuid_base64)) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含已经聚类的原始告警,无法合并!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含已经聚类的原始告警,无法合并!"), QMessageBox::Ok); + return ; + } + //判断权限 + if(!m_aiOptPerm) + { + if(1 != permSkip) + { + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setText(tr("当前用户无此条原始告警合并权限!")); + msgBox->setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox->addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox->addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + if (msgBox->clickedButton() == skip) + { + delete msgBox; + msgBox =NULL; + permSkip = 0; + continue; + } + else if (msgBox->clickedButton() == skipAll) + { + delete msgBox; + msgBox =NULL; + permSkip = 1; + continue; + } + else + { + delete msgBox; + msgBox =NULL; + qDeleteAll(pkgMap); + pkgMap.clear(); + return; + } + } + }else + { + listPtr.append(msgList.at(alarmIndex)); + } + } + } + //过滤后等于0直接返回 + if(listPtr.size() <= 0) + { + qDeleteAll(pkgMap); + pkgMap.clear(); + return ; + } + for(int x(0);xdomain_id; + if(!pkgMap.keys().contains(domain_id)) + { + iot_idl::SIntelliAlmMerge *pkg =new iot_idl::SIntelliAlmMerge(); + pkg->set_domain_id(domain_id); + pkgMap[domain_id] = pkg; + } + pkgMap.value(domain_id)->add_raw_alm_uuid(listPtr.at(x)->uuid_base64.toStdString()); + LOGINFO("UUID:%s",listPtr.at(x)->uuid_base64.toStdString().c_str()); + } + if(pkgMap.size() != 1) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含不同域的原始告警,无法合并!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含不同域的原始告警,无法合并!"), QMessageBox::Ok); + qDeleteAll(pkgMap); + pkgMap.clear(); + return ; + } + foreach (iot_idl::SIntelliAlmMerge * pkg, pkgMap) + { + if(CAiAlarmDataCollect::instance()->requestMergeAlm(*pkg) != true) + { + LOGERROR("请求合并告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + ui->aiAlarmTreeView->setFocus(); + LOGINFO("合并结束!"); +} + +void CAlarmForm::rightSepr1() +{ + if(!m_treeModel) + { + return ; + } + QModelIndexList indexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + QList aimsgList; + QList msgList; + + foreach (QModelIndex modelIndex, indexList) + { + if(!modelIndex.isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(modelIndex.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + aimsgList.append(ptr); + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + msgList.append(ptr); + } + } + } + if(aimsgList.size() != 0) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含智能告警,无法分离!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含智能告警,无法分离!"), QMessageBox::Ok); + return ; + } + if(msgList.size() <= 0) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("无原始告警,无法分离!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("无原始告警,无法分离!"), QMessageBox::Ok); + return ; + } + QString aiuuid = ""; + if(!CAlarmMsgManage::instance()->getAiuuid(msgList.at(0)->uuid_base64,aiuuid)) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含未聚类的原始告警,无法分离!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含未聚类的原始告警,无法分离!"), QMessageBox::Ok); + return ; + } + //权限过滤 + if(!m_aiOptPerm) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("无此条智能告警的编辑权限!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("无此条智能告警的编辑权限!"), QMessageBox::Ok); + return ; + } + //遍历所有原始告警 + for(int index(1);indexgetAiuuid(msgList.at(index)->uuid_base64,uuid)) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含未聚类的原始告警,无法分离!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含未聚类的原始告警,无法分离!"), QMessageBox::Ok); + return ; + } + if(uuid != aiuuid) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("包含不同智能告警下的原始告警,无法分离!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("包含不同智能告警下的原始告警,无法分离!"), QMessageBox::Ok); + return ; + } + } + //拼包 + int domain_id = msgList.at(0)->domain_id; + iot_idl::SIntelliAlmSepr *pkg = new iot_idl::SIntelliAlmSepr(); + pkg->set_domain_id(domain_id); + for(int index(0);indexadd_raw_alm_uuid(msgList.at(index)->uuid_base64.toStdString()); + } + //发送 + if(CAiAlarmDataCollect::instance()->requestSeprAlm(*pkg) != true) + { + LOGERROR("请求分离告警失败!"); + } + pkg = NULL; + delete pkg; +} + +void CAlarmForm::rightTrend0() +{ + quint64 time_stamp = 0; + QModelIndexList modelIndexList = ui->alarmView->selectionModel()->selectedRows(0); + if(modelIndexList.isEmpty()) + { + QMessageBox::warning(this, tr("提示"), tr("当前未选中任何项!"), QMessageBox::Ok); + return; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + QMap trendMap; + foreach (QModelIndex index, modelIndexList) + { + AlarmMsgPtr info = listInfo.at(index.row()); + if(info->m_tagname_type == E_TAGNAME_ANA || info->m_tagname_type == E_TAGNAME_ACC) + { + time_stamp = info->time_stamp; + trendMap[info->uuid_base64] = info->key_id_tag; + } + } + if(trendMap.size()<= 0) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("请选中含有趋势的告警(模拟量和累积量)!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("请选中含有趋势的告警(模拟量和累积量)!"), QMessageBox::Ok); + return ; + }else + { + //发出打开趋势的信号 + emit openTrend(time_stamp,trendMap.values()); + //test(trendMap.values()); + } +} + +void CAlarmForm::rightTrend1() +{ + if(!m_treeModel) + { + return ; + } + quint64 time_stamp = 0; + QModelIndexList indexList = ui->aiAlarmTreeView->selectionModel()->selectedRows(0); + QMap trendMap; + foreach (QModelIndex modelIndex, indexList) + { + if(!modelIndex.isValid()) + { + continue; + } + CAiAlarmTreeItem *item = static_cast(modelIndex.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + QList listPtr = item->getChildAlarmPtr(); + for(int index(0);indexm_tagname_type == E_TAGNAME_ANA || listPtr.at(index)->m_tagname_type == E_TAGNAME_ACC) + { + time_stamp = listPtr.at(index)->time_stamp; + trendMap[listPtr.at(index)->uuid_base64] = listPtr.at(index)->key_id_tag; + } + } + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + if(ptr->m_tagname_type == E_TAGNAME_ANA || ptr->m_tagname_type == E_TAGNAME_ACC) + { + time_stamp = ptr->time_stamp; + trendMap[ptr->uuid_base64] = ptr->key_id_tag; + } + } + } + } + if(trendMap.size()<= 0) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("请选中含有趋势的告警(模拟量和累积量)!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("请选中含有趋势的告警(模拟量和累积量)!"), QMessageBox::Ok); + return ; + }else + { + //发出打开趋势的信号 + emit openTrend(time_stamp,trendMap.values()); + //test(trendMap.values()); + } +} + +void CAlarmForm::rightVideo0() +{ + QModelIndex index = ui->alarmView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + AlarmMsgPtr info = listInfo.at(index.row()); + if(info != NULL) + { + if(info->m_needVideoAlm) + { + QString pointTag = info->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + emit openVideo(info->domain_id,info->app_id,pointTag,info->time_stamp-VIDEO_TIME,info->time_stamp+VIDEO_TIME); + }else + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("请选中具有视频的告警!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("请选中具有视频的告警!"), QMessageBox::Ok); + return ; + } + } +} + +void CAlarmForm::rightVideo1() +{ + if(!m_treeModel) + { + return; + } + QModelIndex index = ui->aiAlarmTreeView->currentIndex(); + if(!index.isValid()) + { + return ; + } + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if(item->isAi()) + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("请选中具有视频的告警!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("请选中具有视频的告警!"), QMessageBox::Ok); + return ; + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + if(ptr->m_needVideoAlm) + { + QString pointTag = ptr->key_id_tag; + pointTag.remove(pointTag.length()-6,6); + emit openVideo(ptr->domain_id,ptr->app_id,pointTag,ptr->time_stamp-VIDEO_TIME,ptr->time_stamp+VIDEO_TIME); + }else + { + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("请选中具有视频的告警!")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("请选中具有视频的告警!"), QMessageBox::Ok); + return ; + } + } + } +} + +void CAlarmForm::rightFaultRecord0() +{ + QModelIndex index = ui->alarmView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + AlarmMsgPtr info = listInfo.at(index.row()); + if(info != NULL) + { + //故障录播暂不实现 + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("故障录播暂不实现")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("故障录播暂不实现"), QMessageBox::Ok); + return ; + } +} + +void CAlarmForm::rightFaultRecord1() +{ + if(!m_treeModel) + { + return ; + } + QModelIndex index = ui->aiAlarmTreeView->currentIndex(); + if(!index.isValid()) + { + return ; + } + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + //故障录播暂时不实现 + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("故障录播暂不实现")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("故障录播暂不实现"), QMessageBox::Ok); + return ; + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + //故障录播暂时不实现 + // QMessageBox *msgBox = new QMessageBox(this); + // msgBox->setObjectName("msgbox"); + // msgBox->setText(tr("故障录播暂不实现")); + // QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + // msgBox->setDefaultButton(skip); + // msgBox->exec(); + QMessageBox::warning(this, tr("提示"), tr("故障录播暂不实现"), QMessageBox::Ok); + return ; + } + } +} + +void CAlarmForm::rightAccidentReview0() +{ + QModelIndex index = ui->alarmView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QList listInfo = m_pModel->getListShowAlarmInfo(); + AlarmMsgPtr info = listInfo.at(index.row()); + if(info != NULL) + { + if(!info->graph_name.isEmpty()) + { + emit openAccidentReview(info->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,info->graph_name); + } + else + { + CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); + if(dialog->exec() == QDialog::Accepted) + { + emit openAccidentReview(info->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,dialog->getCurrentGraph()); + } + delete dialog; + dialog = NULL; + } + } +} + +void CAlarmForm::rightAccidentReview1() +{ + if(!m_treeModel) + { + return ; + } + QModelIndex index = ui->aiAlarmTreeView->currentIndex(); + if(!index.isValid()) + { + return ; + } + CAiAlarmTreeItem *item = static_cast(index.internalPointer()); + if(item->isAi()) + { + AiAlarmMsgPtr ptr = NULL; + if(item->getAiPtr(ptr)) + { + CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); + if(dialog->exec() == QDialog::Accepted) + { + emit openAccidentReview(ptr->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,dialog->getCurrentGraph()); + } + delete dialog; + dialog = NULL; + } + }else + { + AlarmMsgPtr ptr = NULL; + if(item->getPtr(ptr)) + { + if(!ptr->graph_name.isEmpty()) + { + emit openAccidentReview(ptr->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,ptr->graph_name); + } + else + { + CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); + if(dialog->exec() == QDialog::Accepted) + { + emit openAccidentReview(ptr->time_stamp-FAULT_RECORD_TIME,FAULT_RECORD_TIME*2,dialog->getCurrentGraph()); + } + delete dialog; + dialog = NULL; + } + } + } +} +/** + * @brief CAlarmForm::test 测试输出 + * @param tagList + */ +void CAlarmForm::test(QStringList tagList) +{ + QString tag = QString(); + for(int index(0);indexsetObjectName("msgbox"); + msgBox->setText(tag); + QPushButton *skip = msgBox->addButton(tr("确定"), QMessageBox::ActionRole); + msgBox->setDefaultButton(skip); + msgBox->exec(); + return ; +} + +void CAlarmForm::inhibitAlm(const AlarmMsgPtr &alm) +{ + iot_net::CMbMessage msg; + msg.setSubject(alm->sub_system, CH_HMI_TO_OPT_OPTCMD_DOWN); + SOptTagSet sOptTagSet; + SOptTagQueue optTagQueue; + + if(createReqHead(sOptTagSet.stHead,alm)!= iotSuccess) + { + return ; + } + QString keyIdTag = alm->key_id_tag; + if(keyIdTag.endsWith(".value")) + { + keyIdTag.replace(QString(".value"),QString(".status")); + }else + { + return ; + } + + optTagQueue.strKeyIdTag = keyIdTag.toStdString(); + optTagQueue.nIsSet = 1;// 0:取消;1:设置; + optTagQueue.fSetValue = 1; + optTagQueue.strStateText = ""; + optTagQueue.bIsPointQuery = false; + optTagQueue.nLocationId = alm->location_id; + optTagQueue.nSubSystem = alm->sub_system; + + sOptTagSet.vecTagQueue.push_back(optTagQueue); + std::string content = COptTagSet::generate(sOptTagSet); + + msg.setMsgType(MT_OPT_PINHIBIT_ALARM); + + msg.setData(content); + LOGINFO("%s",QString::fromStdString(content).toStdString().c_str()); + if(m_communicator == Q_NULLPTR) + { + QMessageBox::warning(this, tr("提示"), tr("禁止告警失败!"), QMessageBox::Ok); + } + if(!m_communicator->sendMsgToDomain(msg, alm->domain_id)) + { + QMessageBox::warning(this, tr("提示"), tr("禁止告警失败!"), QMessageBox::Ok); + } +} + +void CAlarmForm::inhibitAlm(const AlarmMsgPtr &alm, bool &flag) +{ + iot_net::CMbMessage msg; + msg.setSubject(alm->sub_system, CH_HMI_TO_OPT_OPTCMD_DOWN); + SOptTagSet sOptTagSet; + SOptTagQueue optTagQueue; + + if(createReqHead(sOptTagSet.stHead,alm)!= iotSuccess) + { + flag = false; + return ; + } + QString keyIdTag = alm->key_id_tag; + if(keyIdTag.endsWith(".value")) + { + keyIdTag.replace(QString(".value"),QString(".status")); + }else + { + flag = false; + return ; + } + + optTagQueue.strKeyIdTag = keyIdTag.toStdString(); + optTagQueue.nIsSet = 1;// 0:取消;1:设置; + optTagQueue.fSetValue = 1; + optTagQueue.strStateText = ""; + optTagQueue.bIsPointQuery = false; + optTagQueue.nLocationId = alm->location_id; + optTagQueue.nSubSystem = alm->sub_system; + + sOptTagSet.vecTagQueue.push_back(optTagQueue); + std::string content = COptTagSet::generate(sOptTagSet); + + msg.setMsgType(MT_OPT_PINHIBIT_ALARM); + + msg.setData(content); + LOGINFO("%s",QString::fromStdString(content).toStdString().c_str()); + if(m_communicator == Q_NULLPTR) + { + flag = false; + QMessageBox::warning(this, tr("提示"), tr("禁止告警失败!"), QMessageBox::Ok); + } + if(!m_communicator->sendMsgToDomain(msg, alm->domain_id)) + { + flag = false; + QMessageBox::warning(this, tr("提示"), tr("禁止告警失败!"), QMessageBox::Ok); + } + flag = true; +} + +bool CAlarmForm::permCheck(int location, int region) +{ + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + int userId; + int type = permMngPtr->CurUser(userId, nUserGrpId, nLevel, nLoginSec, strInstanceName); + if(PERM_NORMAL != type) + { + userId = -1; + return false; + } + std::vector vecRegionOptId; + QList regList; + QList locList; + std::vector vecLocationOptId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(OPT_FUNC_SPE_OPT_OVERRIDE, vecRegionOptId, vecLocationOptId)) + { + + std::vector ::iterator region = vecRegionOptId.begin(); + while (region != vecRegionOptId.end()) + { + regList.append(*region++); + } + + std::vector ::iterator location = vecLocationOptId.begin(); + while (location != vecLocationOptId.end()) + { + locList.append(*location++); + } + } + if(locList.contains(location) && regList.contains(region)) + { + return true; + } + else + { + QMessageBox::warning(this, tr("警告"), tr("无禁止告警权限!"), QMessageBox::Ok); + return false; + } + } + QMessageBox::warning(this, tr("警告"), tr("初始化权限失败!"), QMessageBox::Ok); + return false; +} + +int CAlarmForm::createReqHead(SOptReqHead &head, const AlarmMsgPtr &alm) +{ + if(!m_ptrSysInfo) + { + if(!createSysInfoInstance(m_ptrSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return iotFailed; + } + } + + int userID = -1; + int usergID = -1; + int level; + int loginSec; + std::string instanceName; + + iot_service::CPermMngApiPtr permMng = iot_service::getPermMngInstance("base"); + if(permMng != NULL) + { + if(permMng->PermDllInit() != PERM_NORMAL) + { + LOGERROR("权限接口初始化失败!"); + return iotFailed; + }else + { + if(PERM_NORMAL != permMng->CurUser(userID, usergID, level, loginSec, instanceName)) + { + userID = -1; + return iotFailed; + } + } + } + head.strSrcTag = "alarm_window"; + head.nSrcDomainID = m_nDomainId; + head.nDstDomainID = alm->domain_id; + + if(m_ptrSysInfo != Q_NULLPTR) + { + iot_public::SAppInfo stAppInfo; + m_ptrSysInfo->getAppInfoBySubsystemId(alm->sub_system,stAppInfo); + head.nAppID = stAppInfo.nId; + }else + { + head.nAppID = alm->sub_system; + } + head.strHostName = m_nodeName; + head.strInstName = instanceName; + head.strCommName = m_communicator->getName(); + head.nUserID = userID; + head.nUserGroupID = usergID; + head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + return iotSuccess; +} + +void CAlarmForm::reloadDevTree() +{ + updateAlarmOperatePerm(); + loadDeviceGroupFilterWidget(); +} + +void CAlarmForm::on_confirm_clicked() +{ + +} + +void CAlarmForm::on_alarmView_doubleClicked(const QModelIndex &index) +{ + if(!index.isValid() || !m_pModel->headerData(index.column() , Qt::Horizontal , Qt::DisplayRole).toString().contains("告警内容") ) + { + return; + } + + QMessageBox msg; + msg.setWindowTitle("告警内容"); + msg.setText(index.data(Qt::DisplayRole).toString()); + msg.addButton("确认",QMessageBox::AcceptRole); + + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + if(!qss.isEmpty()) + { + msg.setStyleSheet(qss); + } + + ui->alarmView->verticalScrollBar()->setSliderPosition(0); + msg.exec(); + +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmForm.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmForm.h new file mode 100644 index 00000000..3f64f546 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmForm.h @@ -0,0 +1,296 @@ +#ifndef CALARMFORM_H +#define CALARMFORM_H + +#include +#include +#include +#include "CAlarmMsgInfo.h" +#include "CAiAlarmMsgInfo.h" +#include +#include +#include "CMyCalendar.h" +#include +#include +#include +#include +#include +#include +#include +#include "dbms/db_api_ex/CDbApi.h" + +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "net/net_msg_bus_api/CMbCommunicator.h" +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" +#include "common/MessageChannel.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" + +namespace Ui { +class CAlarmForm; +} + +class QLineEdit; +class QPushButton; +class QTreeWidgetItem; +class CAlarmItemModel; +class CAlarmDelegate; +class CAiAlarmDelegate; +class CAlarmDeviceTreeModel; +class CAiAlarmTreeModel; +class CAiAlarmTreeView; +class CAlarmView; +typedef QList QModelIndexList; + + +class CAlarmForm : public QWidget +{ + Q_OBJECT + +public: + explicit CAlarmForm(QWidget *parent = 0); + ~CAlarmForm(); + + void modeConfirm(const int &x); + + void initialize(); + + void init(); + + void setAlarmModel(CAlarmItemModel * model, CAiAlarmTreeModel *treeModel); + + void setAlarmModel(CAlarmItemModel * model); + void updateView(); + void updateAlarmOperatePerm(); //更新原始告警权限和智能告警操作权限 + + void setAlarmOperateEnable(const bool &bEnable); + + void setColumnWidth(const int &column, const int &width); + + void setColumnVisible(const int &column, const bool &visible); + + void setEnableAccidentReview(bool isNeed); + + void setEnableTrend(bool isNeed); + + void setEnableVideo(bool isNeed); + + void setEnableWave(bool isNeed); + + void setEnableLevel(bool isNeed); + + void setHiddenLocation(bool hide); + + void setHiddenTime(bool hide); + + void setHiddenStatus(bool hide); + + void setHiddenPriority(bool hide); + + void setHiddenCheckBox(bool hide); + + void setHiddenSetConfig(bool hide); + + void setHiddenCloseButton(bool hide); + + void setHiddenInhiAlarmButton(bool hide); + + void setHiddenSelectButton(bool hide); + + void setHiddenLeftTree(); + + void setShowAiAlarmView(bool show); + + void setRowHeight(int height); + + void setAccidentReviewPath(const QString& path); + + void removeAllAlarm(); + +public: + void initFilter(); + void setLevelComboBox(bool &isLevelFilter,QList &listLevel); + void setLocationComboBox(bool &isLocationFilter,QList &listLocation); + void setAlarmStatusComboBox(bool &isAlarmTypeFilter,QList &listAlarmStatus); + void setAlarmTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime); + void reloadDevTree(); +signals: + void sigAudioCuesEnable(bool bEnable); + + void closeBtnClicked(); + + void printer(QVector header,QList > data,QString fileName,QVector columnHidden,QVector columnWidth); + void printExcel(CAiAlarmTreeView* view,CAiAlarmTreeModel * model,QString fileName); + void printExcelAlm(CAlarmView* view ,CAlarmItemModel * model,QString fileName); + + void openTrend(quint64 time_stamp,QStringList tagList); + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + void openAccidentReview(quint64 starTime,quint64 keepTime,QString graph=QString()); +protected slots: + void updateFilter(); + void deviceGroupFilterChanged(const QString &device, const bool &checked); + void slot_changePage(int i); + void slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isAlarmTypeFilter, QList listAlarmType, + bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, + QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isConfirmFilter, bool confirm,bool isReturnFilter,bool isReturn); + + void slot_removeAlarm(); + void slot_confirmAlarm(); + + void slot_showInhibitAlarm(); + + void slot_showShiledAlarm(); + + void slot_showColorSet(); + void removeInhibitAlarm(QList alarmList); + + void searchDeviceName(); + + void updateRowTips(); + + void print(); + void stateChanged1(int state); + void stateChanged2(int state); + void stateChanged3(int state); + void textChanged1(const QString &text); + void textChanged2(const QString &text); + void textChanged3(const QString &text); + void myCalendarHide(QDate startTime, QDate endTime); + void myCalendarShow(); + void cancleTimeFilter(); + + void aiAlmDoubleClicked(const QModelIndex &index); + + void printMess(QString fileName); + + void slotInhibitDevGroupAlm(const QString &strDevg, int nDomainId, int nLocationId, int nSubsystemId, int nRegionId); + void slotInhibitAlarm(); + void slotInhibitAlarms(QModelIndex a,bool &flag); + + +protected: + void contextMenuEvent(QContextMenuEvent *event); + + void contextMenuStack0Event(QContextMenuEvent *event); + + void contextMenuStack1Event(QContextMenuEvent *event); + + void loadDeviceGroupFilterWidget(); + + void updateDeviceGroupHiddenState(); +private slots: + void on_confirm_clicked(); + + void slotALlSel(); + void slotNoneSel(); + + void on_alarmView_doubleClicked(const QModelIndex &index); + +private: + //原始告警窗点击打印(打印原始告警) + void print0(QString fileName); + //智能告警窗点击打印(打印智能和原始告警) + void print1(QString fileName); + //原始告警窗点击删除(删除原始告警) + void removeAlarm0(); + //智能告警窗点击删除(删除智能告警) + void removeAlarm1(); + //原始告警窗点击确认(确认原始告警) + void confirmAlarm0(); + //智能告警窗点击确认(确认原始告警) + void confirmAlarm1(); + + void rightConfirm0(); + + void rightConfirm1(); + + void rightRemove0(); + + void rightRemove1(); + + void rightMerge1(); + + void rightSepr1(); + + void rightTrend0(); + + void rightTrend1(); + + void rightVideo0(); + + void rightVideo1(); + + void rightFaultRecord0(); + + void rightFaultRecord1(); + + void rightAccidentReview0(); + + void rightAccidentReview1(); + + void test(QStringList tagList); + + void inhibitAlm(const AlarmMsgPtr &alm); + void inhibitAlm(const AlarmMsgPtr &alm,bool &flag); + + bool permCheck(int location ,int region); + + int createReqHead(SOptReqHead &head, const AlarmMsgPtr &alm); + +private: + iot_public::CSysInfoInterfacePtr m_ptrSysInfo; + iot_dbms::CDbApi *m_pReadDb; + + QLineEdit * m_pSearchTextEdit; + QPushButton * m_pSearchButton; + QList m_listRegionOptId; + QList m_listLocationOptId; + + QList m_listRegionDelId; + QList m_listLocationDelId; + bool m_aiOptPerm; //智能告警操作权限 + + CAlarmItemModel * m_pModel; + CAlarmDelegate * m_delegate; + CAiAlarmDelegate * m_aiDelegate; + CAlarmDeviceTreeModel * m_pDeviceModel; + CAiAlarmTreeModel *m_treeModel; + iot_net::CMbCommunicator *m_communicator; + int m_userId; + std::string m_nodeName; + int m_nDomainId; + + QListWidget *m_pListWidget1; + QListWidget *m_pListWidget2; + QListWidget *m_pListWidget3; + + QLineEdit *m_pLineEdit1; + QLineEdit *m_pLineEdit2; + QLineEdit *m_pLineEdit3; + QList m_priorityList; + QList m_locationList; + QList m_alarmStatusList; + QString m_strText1; + QString m_strText2; + QString m_strText3; + Ui::CAlarmForm *ui; + QPushButton *m_timeIcon; + + CMyCalendar * m_myCalendar; + QMenu *m_timeMenu; + + QThread *m_thread; //打印线程 + CPdfPrinter *m_pdfPrinter; + bool m_isNormal; //是否正常状态 否代表事故追忆状态 + bool m_isNeedAccidentReview; + + int modeAll; + + bool m_enableAi; + QString m_strAccidenPath; + bool m_bPopWindow; + + QString m_searchDeviceName; + +}; + +#endif // ALARMFORM_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmForm.ui b/product/src/gui/plugin/AlarmWidget_pad/CAlarmForm.ui new file mode 100644 index 00000000..f3a4d3a3 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmForm.ui @@ -0,0 +1,660 @@ + + + CAlarmForm + + + + 0 + 0 + 1994 + 631 + + + + Form + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 6 + + + + + 禁止列表 + + + + + + + + 0 + 0 + + + + 过滤 + + + + + + + + 0 + 0 + + + + 导出 + + + + + + + + + Qt::Horizontal + + + + 698 + 20 + + + + + + + + + + + 0 + 0 + + + + 当前显示数量: + + + + + + + + 0 + 0 + + + + + 55 + 0 + + + + 0 + + + + + + + + 0 + 0 + + + + 过滤告警数量: + + + + + + + + 0 + 0 + + + + + 55 + 0 + + + + 0 + + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + Qt::RightToLeft + + + 优先级: + + + + + + + + 125 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + Qt::RightToLeft + + + 位置: + + + + + + + + 113 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + Qt::RightToLeft + + + 告警状态: + + + + + + + + 138 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 时间: + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 200 + 26 + + + + + + + + + 80 + 26 + + + + + 16777215 + 26 + + + + 智能告警 + + + true + + + + + + + Qt::Horizontal + + + + 13 + 20 + + + + + + + + true + + + + + + 全选 + + + + + + + true + + + + + + 全不选 + + + + + + + false + + + + + + 确认 + + + + + + + false + + + 删除 + + + + + + + 禁止告警 + + + + + + + 设置 + + + + + + + 关闭 + + + + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + + 0 + 0 + + + + + 280 + 0 + + + + QFrame::Box + + + false + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 全勾选 + + + + + + + + 0 + 0 + + + + 全不选 + + + + + + + Qt::Horizontal + + + + + + + + + + + + + 0 + 0 + + + + 0 + + + + + QLayout::SetDefaultConstraint + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 600 + 0 + + + + QFrame::Sunken + + + Qt::ScrollBarAsNeeded + + + false + + + false + + + + + + + + + QLayout::SetDefaultConstraint + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::ScrollPerPixel + + + false + + + + + + + + + + + + + CAlarmView + QTableView +
CAlarmView.h
+
+ + CAlarmDeviceTreeView + QTreeView +
CAlarmDeviceTreeView.h
+
+ + CAiAlarmTreeView + QTreeView +
CAiAlarmTreeView.h
+
+
+ + + + updateFilter() + +
diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmInhibitDialog.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmInhibitDialog.cpp new file mode 100644 index 00000000..ccab6960 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmInhibitDialog.cpp @@ -0,0 +1,138 @@ +#include "CAlarmInhibitDialog.h" +#include "ui_CAlarmInhibitDialog.h" +#include +#include +#include +#include +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" +#include "CAlarmBaseData.h" + +CAlarmInhibitDialog::CAlarmInhibitDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CAlarmInhibitDialog) +{ + ui->setupUi(this); + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + connect(ui->ok, &QPushButton::clicked, this, &CAlarmInhibitDialog::onRemoveInhibit); + connect(ui->cancle, &QPushButton::clicked, [=](){ + reject(); + }); +} + +CAlarmInhibitDialog::~CAlarmInhibitDialog() +{ + delete ui; +} + +void CAlarmInhibitDialog::setInhibitAlarmList(const QList &alarmList) +{ + m_inhibitAlarmList = alarmList; + ui->tableWidget->setRowCount(m_inhibitAlarmList.size()); + ui->tableWidget->setColumnCount(7); + for(int nRow(0); nRow < m_inhibitAlarmList.size(); nRow++) + { + QTableWidgetItem *item; + QString time_stamp = QDateTime::fromMSecsSinceEpoch(m_inhibitAlarmList.at(nRow)->time_stamp).toString("yyyy-MM-dd hh:mm:ss"); + item = new QTableWidgetItem(time_stamp); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 0, item); + + QString priority = CAlarmBaseData::instance()->queryPriorityDesc(m_inhibitAlarmList.at(nRow)->priority); + item = new QTableWidgetItem(priority); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 1, item); + + QString location = CAlarmBaseData::instance()->queryLocationDesc(m_inhibitAlarmList.at(nRow)->location_id); + item = new QTableWidgetItem(location); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 2, item); + + QString region = CAlarmBaseData::instance()->queryRegionDesc(m_inhibitAlarmList.at(nRow)->region_id); + item = new QTableWidgetItem(region); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 3, item); + + QString type = CAlarmBaseData::instance()->queryAlarmTypeDesc(m_inhibitAlarmList.at(nRow)->alm_type); + item = new QTableWidgetItem(type); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 4, item); + + QString state; + if(E_ALS_ALARM == m_inhibitAlarmList.at(nRow)->logic_state || E_ALS_RETURN == m_inhibitAlarmList.at(nRow)->logic_state) //< 未确认 + { + state = tr("未确认"); + } + else + { + state = tr("已确认"); + } + item = new QTableWidgetItem(state); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 5, item); + + item = new QTableWidgetItem(m_inhibitAlarmList.at(nRow)->content); + item->setTextAlignment(Qt::AlignCenter); + ui->tableWidget->setItem(nRow, 6, item); + } + + ui->tableWidget->setColumnWidth(0, 230); + ui->tableWidget->setColumnWidth(1, 100); + ui->tableWidget->setColumnWidth(2, 150); + ui->tableWidget->setColumnWidth(3, 150); + ui->tableWidget->setColumnWidth(4, 120); + ui->tableWidget->setColumnWidth(5, 80); + +} + +void CAlarmInhibitDialog::onRemoveInhibit() +{ + QModelIndexList indexList = ui->tableWidget->selectionModel()->selectedRows(0); + if(indexList.isEmpty()) + { + QMessageBox::information(this, tr("警告"), tr("请选择取消禁止告警所在的行!"), QMessageBox::Ok); + return; + } + std::sort(indexList.begin(), indexList.end()); + QList removedInhibitAlarmList; + for(int nRow(indexList.size() - 1); nRow >= 0; nRow--) + { + removedInhibitAlarmList.append(m_inhibitAlarmList.takeAt(indexList.at(nRow).row())); + ui->tableWidget->removeRow(indexList.at(nRow).row()); + } + emit removeInhibitAlarmList(removedInhibitAlarmList); +} + +void CAlarmInhibitDialog::contextMenuEvent(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + QMenu menu(this); + QAction * InhibitAction = menu.addAction(tr("取消禁止告警")); + connect(InhibitAction, &QAction::triggered,this,&CAlarmInhibitDialog::onRemoveInhibit); + setUpdatesEnabled(false); + menu.exec(QCursor::pos()); + setUpdatesEnabled(true); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmInhibitDialog.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmInhibitDialog.h new file mode 100644 index 00000000..f79c84ea --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmInhibitDialog.h @@ -0,0 +1,36 @@ +#ifndef CALARMINHIBITDIALOG_H +#define CALARMINHIBITDIALOG_H + +#include +#include +#include "CAlarmMsgInfo.h" + +namespace Ui { +class CAlarmInhibitDialog; +} + +class CAlarmInhibitDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CAlarmInhibitDialog(QWidget *parent = 0); + ~CAlarmInhibitDialog(); + + void setInhibitAlarmList(const QList &alarmList); + +signals: + void removeInhibitAlarmList(QList alarmList); + +protected slots: + void onRemoveInhibit(); +protected: + void contextMenuEvent(QContextMenuEvent *event); + +private: + Ui::CAlarmInhibitDialog *ui; + + QList m_inhibitAlarmList; +}; + +#endif // CALARMINHIBITDIALOG_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmInhibitDialog.ui b/product/src/gui/plugin/AlarmWidget_pad/CAlarmInhibitDialog.ui new file mode 100644 index 00000000..f20df74a --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmInhibitDialog.ui @@ -0,0 +1,135 @@ + + + CAlarmInhibitDialog + + + + 0 + 0 + 1094 + 433 + + + + 禁止告警列表 + + + + 3 + + + 3 + + + 3 + + + 6 + + + 3 + + + 6 + + + + + 关闭 + + + + + + + 取消禁止告警 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QAbstractItemView::MultiSelection + + + QAbstractItemView::SelectRows + + + true + + + + 时间 + + + AlignLeading|AlignVCenter + + + + + 优先级 + + + AlignLeading|AlignVCenter + + + + + 位置 + + + AlignLeading|AlignVCenter + + + + + 责任区 + + + AlignLeading|AlignVCenter + + + + + 告警类型 + + + AlignLeading|AlignVCenter + + + + + 确认状态 + + + AlignLeading|AlignVCenter + + + + + 告警内容 + + + AlignLeading|AlignVCenter + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmItemModel.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmItemModel.cpp new file mode 100644 index 00000000..5fc6c97e --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmItemModel.cpp @@ -0,0 +1,926 @@ +#include "CAlarmItemModel.h" +#include "CAlarmMsgInfo.h" +#include +#include +#include +#include +#include "CAlarmDataCollect.h" +#include "CAlarmMsgManage.h" +#include "perm_mng_api/PermMngApi.h" +#include +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" +#include "Common.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CharUtil.h" +#include "pub_logger_api/logger.h" +#include +#include +#include +#include "CAlarmBaseData.h" + +#include + +using namespace iot_public; +using namespace std; +const int DOCK_ROW_COUNT = 3; +const int MAX_ROW_COUNT = 15000; +const int ALM_TYPE_SYSTEM = 5; //系统告警信息 + +CAlarmItemModel::CAlarmItemModel(E_Alarm_Mode mode, QObject *parent) + :QAbstractTableModel(parent), + m_mode(mode), + m_order(Qt::DescendingOrder) +{ + m_nTotalSize = 0; + m_alternateFlag = true; + m_isDevGroupFilterEnable = false; + //增加复归状态 + m_header <)), this, SLOT(slotMsgArrived(QList)), Qt::QueuedConnection); + connect(CAlarmDataCollect::instance(), SIGNAL(sigAlarmStateChanged(int, int)), this, SLOT(slotAlarmStateChanged(int, int)), Qt::QueuedConnection); + + connect(CAlarmDataCollect::instance(),&CAlarmDataCollect::sigMsgRemove,this,&CAlarmItemModel::slotMsgRemove,Qt::QueuedConnection); +} + +CAlarmItemModel::~CAlarmItemModel() +{ + m_listShowAlarmInfo.clear(); +} + +//登录或者注销或重新初始化model,或调用该初始化函数,会清空设备组过滤信息 +void CAlarmItemModel::initialize() +{ + m_listHorAlignmentFlags.clear(); + for (int nIndex(0); nIndex < m_header.size(); nIndex++) + { + m_listHorAlignmentFlags.append(Qt::AlignHCenter); + } + initFilter(); + + slotMsgRefresh(); +} +//设备组过滤使能;设备组过滤不显示系统信息 +void CAlarmItemModel::setDeviceGroupFilterEnable(bool bEnalbe) +{ + m_isDevGroupFilterEnable = bEnalbe ; +} + +void CAlarmItemModel::initFilter() +{ + m_isLevelFilterEnable = false; + m_isLocationFilterEnable = false; + m_isRegionFilterEnable = false; + m_isStatusFilterEnable = false; + m_isDeviceTypeFileter = false; + m_isKeywordEnable = false; + m_timeFilterEnable = false; + m_confirmFilterEnable = false; + m_returnFilterEnable = false; + //if(m_mode != E_Alarm_Pop) + //{ + // removeDeviceGroupFilter(); + //} +} + +E_Alarm_Mode CAlarmItemModel::getAlarmMode() const +{ + return m_mode; +} + +int CAlarmItemModel::getShowAlarmCount() const +{ + return m_listShowAlarmInfo.size(); +} + +AlarmMsgPtr CAlarmItemModel::getAlarmInfo(const QModelIndex &index) +{ + if(index.row() < m_listShowAlarmInfo.size()) + { + return m_listShowAlarmInfo.at(index.row()); + } + return AlarmMsgPtr(Q_NULLPTR); +} + +const QList CAlarmItemModel::getListShowAlarmInfo() const +{ + return m_listShowAlarmInfo; +} + +void CAlarmItemModel::setColumnAlign(const int &column, const int &alignFlag) +{ + Qt::AlignmentFlag flag = Qt::AlignHCenter; + if(Qt::AlignLeft == (Qt::AlignmentFlag)alignFlag || Qt::AlignRight == (Qt::AlignmentFlag)alignFlag) + { + flag = (Qt::AlignmentFlag)alignFlag; + } + m_listHorAlignmentFlags.replace(column, flag); +} + +void CAlarmItemModel::insertAlarmMsg(const QList &infoList) +{ + if(infoList.size() > 1000 || E_Alarm_Dock == m_mode) + { + beginResetModel(); + QList::const_iterator itpos = infoList.begin(); + while(itpos != infoList.end()) + { + int left = calcLeft(*itpos); + m_listShowAlarmInfo.insert(left, *itpos); + itpos++; + } + endResetModel(); + }else + { + QList::const_iterator itpos = infoList.begin(); + while(itpos != infoList.end()) + { + int left = calcLeft(*itpos); + beginInsertRows(QModelIndex(), left, left); + m_listShowAlarmInfo.insert(left, *itpos); + endInsertRows(); + itpos++; + } + } +} + +int CAlarmItemModel::calcLeft(const AlarmMsgPtr &info) +{ + int mid = -1; + int left = 0; + int right = m_listShowAlarmInfo.size() - 1; + while(left <= right) + { + mid = (left + right) / 2; + if (Qt::AscendingOrder == m_order) + { + if(info->lessThan(m_listShowAlarmInfo[mid], m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + else + { + if(m_listShowAlarmInfo[mid]->lessThan(info, m_sortKey)) + { + right = mid - 1; + } + else + { + left = mid + 1; + } + } + } + return left; +} + +bool CAlarmItemModel::alternate() const +{ + return m_alternateFlag; +} + +int CAlarmItemModel::filterCount() +{ + if (0 == m_nTotalSize) + { + return 0; + } + int nCount = m_nTotalSize - m_listShowAlarmInfo.size(); + if( nCount< 0) + { + return 0; + }else + { + return nCount; + } +} + +QVariant CAlarmItemModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(m_header.at(section)); + } + return QVariant(); +} + +QVariant CAlarmItemModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid() || index.row() >= m_listShowAlarmInfo.count()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == (int)CONTENT) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(m_listHorAlignmentFlags.at(index.column()) | Qt::AlignVCenter); + } + + } + else if(Qt::DisplayRole == role) + { + switch ( index.column() ) + { + case TIME : + { + return QDateTime::fromMSecsSinceEpoch(m_listShowAlarmInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + case PRIORITY : + { + return CAlarmBaseData::instance()->queryPriorityDesc(m_listShowAlarmInfo.at(index.row())->priority); + } + case LOCATION : + { + return CAlarmBaseData::instance()->queryLocationDesc(m_listShowAlarmInfo.at(index.row())->location_id); + } + case REGION : + { + return CAlarmBaseData::instance()->queryRegionDesc(m_listShowAlarmInfo.at(index.row())->region_id); + } + case TYPE : + { + return CAlarmBaseData::instance()->queryAlarmTypeDesc(m_listShowAlarmInfo.at(index.row())->alm_type); + } + case STATUS : + { + return CAlarmBaseData::instance()->queryAlarmStatusDesc(m_listShowAlarmInfo.at(index.row())->alm_status); + } + case RETURNSTATUS: + { + if(E_ALS_ALARM == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_ALARM_CFM == m_listShowAlarmInfo.at(index.row())->logic_state || + E_ALS_ALARM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_ALARM_CFM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state) //未复归 + { + return tr("未复归"); + } + else if(E_ALS_RETURN == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_CFM == m_listShowAlarmInfo.at(index.row())->logic_state || + E_ALS_RETURN_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_CFM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state) + { + return tr("已复归"); + }else + { + return tr("-"); + } + } + case CONFIRM : + { + if(E_ALS_ALARM == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN == m_listShowAlarmInfo.at(index.row())->logic_state || + E_ALS_ALARM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_DEL == m_listShowAlarmInfo.at(index.row())->logic_state) //< 未确认 + { + return tr("未确认"); + } + else if(E_ALS_ALARM_CFM == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_CFM == m_listShowAlarmInfo.at(index.row())->logic_state || + E_ALS_ALARM_CFM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || E_ALS_RETURN_CFM_DEL == m_listShowAlarmInfo.at(index.row())->logic_state || + ALS_EVT_ONLY == m_listShowAlarmInfo.at(index.row())->logic_state) //< 已确认 + { + return tr("已确认"); + } + } + case CONTENT : + { + return m_listShowAlarmInfo.at(index.row())->content; + } + default: + break; + } + } + + else if(Qt::ToolTipRole == role) + { + if(index.column() == (int)CONTENT && !QToolTip::isVisible()) + { + QString tip = m_listShowAlarmInfo.at(index.row())->content; + + return tip; + } + } + return QVariant(); +} + +int CAlarmItemModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + + return m_header.count(); +} + +int CAlarmItemModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + + if(E_Alarm_Dock == m_mode) + { + return DOCK_ROW_COUNT; + } + else + { + return m_listShowAlarmInfo.count(); + } +} + +Qt::ItemFlags CAlarmItemModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +void CAlarmItemModel::sortColumn(int column, Qt::SortOrder order) +{ + if(order == Qt::AscendingOrder) + { + m_order = Qt::AscendingOrder; + } + else + { + m_order = Qt::DescendingOrder; + } + m_sortKey = (E_ALARM_SORTKEY)column; + beginResetModel(); + sort(); + endResetModel(); +} + +//<归并排序 +void CAlarmItemModel::sort() +{ + QMap mapAlarmInfo; + //<分 + for(int nIndex(0); nIndex < m_listShowAlarmInfo.count(); nIndex++) + { + AlarmMsgPtr temp = m_listShowAlarmInfo.at(nIndex); + mapAlarmInfo[nIndex / 1000].second.append(temp); + } + + //<快速排序 + for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) + { + qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); + } + + PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; + for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) + { + //<归并 + tempListAlarmInfo.first = 0; + mapAlarmInfo[nPairIndex].first = 0; + while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) + { + if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) + { + tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + } + tempListAlarmInfo.first += 1; + } + } + m_listShowAlarmInfo = tempListAlarmInfo.second; +} + + +void CAlarmItemModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CAlarmItemModel::partitionAscendingOrder(QList &list, int start, int last) +{ + AlarmMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftlessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CAlarmItemModel::partitionDescendingOrder(QList &list, int start, int last) +{ + AlarmMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +void CAlarmItemModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + m_isLevelFilterEnable = isCheck; + m_levelFilter = priorityFilter; + slotMsgRefresh(); +} + +void CAlarmItemModel::setLocationFilter(bool &isCheck, QList &locationFilter) +{ + m_isLocationFilterEnable = isCheck; + m_locationFilter = locationFilter; + slotMsgRefresh(); +} + +void CAlarmItemModel::setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter,bool &other) +{ + m_isStatusFilterEnable = isCheck; + m_statusFilter2 = alarmTypeFilter; + m_statusFilter = alarmTypeFilter; + if(other == true) + { + QMap otherStatusMap = CAlarmBaseData::instance()->getAlarmOtherStatus(); + QMap::iterator it = otherStatusMap.begin(); + for(;it != otherStatusMap.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + slotMsgRefresh(); +} + +void CAlarmItemModel::setAlarmTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) +{ + m_timeFilterEnable = isCheck; + if(isCheck) + { + QTime time_1(0,0,0,0); + QTime time_2(23,59,59); + m_startTime.setDate(startTime); + m_startTime.setTime(time_1); + m_endTime.setDate(endTime); + m_endTime.setTime(time_2); + } + slotMsgRefresh(); +} + +void CAlarmItemModel::setAlarmTimeFilter(bool &isCheck) +{ + m_timeFilterEnable = isCheck; + slotMsgRefresh(); +} + +void CAlarmItemModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isStatusFilterEnable, const QList &statusFilter, + const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, + const bool &isKeywordFilterEnable, const QString &keyword, + const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, + const bool &confirmFilterEnable, const bool &isConfirm, + const bool &returnFilterEnable, const bool &isReturn) +{ + m_isLevelFilterEnable = isLevelFilterEnable; + m_levelFilter = levelFilter; + m_isLocationFilterEnable = isStationFilterEnable; + m_locationFilter = stationFilter; + m_isRegionFilterEnable = isRegionFilterEnable; + m_regionFilter = regionFilter; + m_isStatusFilterEnable = isStatusFilterEnable; + m_statusFilter2 = statusFilter; + m_statusFilter = statusFilter; + if(statusFilter.contains(OTHERSTATUS)) + { + QMap otherStatusMap = CAlarmBaseData::instance()->getAlarmOtherStatus(); + QMap::iterator it = otherStatusMap.begin(); + for(;it != otherStatusMap.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + m_isDeviceTypeFileter = isDeviceTypeFilter; + m_subSystem = subSystem; + m_deviceType = deviceType; + m_isKeywordEnable = isKeywordFilterEnable; + m_keyowrd = keyword; + m_timeFilterEnable = timeFilterEnable; + m_startTime = startTime; + m_endTime = endTime; + m_confirmFilterEnable = confirmFilterEnable; + m_returnFilterEnable = returnFilterEnable; + m_isConfirm = isConfirm; + m_isReturn = isReturn; + + slotMsgRefresh(); +} + +void CAlarmItemModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isStatusFilterEnable, QList &alarmStatusFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, + bool &confirmFilterEnable, bool &isConfirm, + bool &returnFilterEnable, bool &isReturn) +{ + isLevelFilterEnable = m_isLevelFilterEnable; + levelFilter = m_levelFilter; + isLocationFilterEnable = m_isLocationFilterEnable; + locationFilter = m_locationFilter; + isRegionFilterEnable = m_isRegionFilterEnable; + regionFilter = m_regionFilter; + isStatusFilterEnable = m_isStatusFilterEnable; + alarmStatusFilter = m_statusFilter2; + subSystem = m_subSystem; + deviceTypeFilter = m_isDeviceTypeFileter; + deviceType = m_deviceType; + keywordFilterEnable = m_isKeywordEnable; + keyword = m_keyowrd; + timeFilterEnable = m_timeFilterEnable; + startTime = m_startTime; + endTime = m_endTime; + confirmFilterEnable = m_confirmFilterEnable; + isConfirm = m_isConfirm; + returnFilterEnable = m_returnFilterEnable; + isReturn = m_isReturn; +} + +void CAlarmItemModel::addDeviceFilter(const QString &device) +{ + m_deviceFilter.insert(device); + //slotMsgRefresh(); +} + +void CAlarmItemModel::removeDeviceFilter(const QString &device) +{ + m_deviceFilter.remove(device); + //slotMsgRefresh(); +} + +void CAlarmItemModel::addPointTagFilter(const QList &pointList) +{ + for(int i =0;igetDevGroupTagList()) + { + m_deviceGroupFilter.insert(group); + } + slotMsgRefresh(); +} + +void CAlarmItemModel::removeDeviceGroupFilter() +{ + m_deviceGroupFilter.clear(); +} + +void CAlarmItemModel::addDeviceGroupFilter(const QString &device) +{ + QString deviceG = device; + QStringList devGList = deviceG.split(","); + foreach (QString devG, devGList) { + m_deviceGroupFilter.insert(devG); + } + slotMsgRefresh(); +} + +//device 需要过滤告警的设备 +void CAlarmItemModel::addDeviceGroupFilter2(const QString &device) +{ + addDeviceGroupFilter(); //增加所有设备组 + QString deviceG = device; + QStringList devGList = deviceG.split(","); + foreach (QString devG, devGList) + { + m_deviceGroupFilter.remove(devG); + } + slotMsgRefresh(); +} + +void CAlarmItemModel::removeDeviceGroupFilter(const QString &device) +{ + m_deviceGroupFilter.remove(device); //删除显示 + slotMsgRefresh(); +} + +bool CAlarmItemModel::conditionFilter(const AlarmMsgPtr &info) +{ + //===========================错误优先级、车站、责任区、告警类型将显示==============================// + //< 等级 + if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) + { + return false; + } + + //< 车站 + if(m_isLocationFilterEnable && !m_locationFilter.contains(info->location_id)) + { + return false; + } + //< 责任区 + if(m_isRegionFilterEnable && !m_regionFilter.contains(info->region_id)) + { + return false; + } + + //< 类型 + if(m_isStatusFilterEnable && !m_statusFilter.contains(info->alm_status)) + { + return false; + } + + //< 设备类型 + if(m_isDeviceTypeFileter) + { +// QString qita = QString("其他"); +// ofstream of("d:\\type.txt",ios::app); +// if(0 == strcmp(qita.toStdString().c_str(),m_deviceType.toStdString().c_str())) +// { +// if(CAlarmBaseData::instance()->queryDevTypeByDesc(m_deviceType) == info->dev_type +// ) +// { + +// } +// } +// else if(CAlarmBaseData::instance()->queryDevTypeByDesc(m_deviceType) != info->dev_type) +// { +// return false; +// } +// of<<"其他:"<queryDevTypeByDesc(qita)<<" "; //其他 5 +// qita = QString("配电柜"); +// of<<"配电柜"<queryDevTypeByDesc(qita)<<" "; //配电柜 1 +// qita = QString("UPS"); +// of<<"UPS:"<queryDevTypeByDesc(qita)<<" "; //UPS 2 +// qita = QString("BMS"); +// of<<"BMS:"<queryDevTypeByDesc(qita)<<" "; //BMS 4 +// qita = QString("高频开关电源"); //高频 3 +// of<<"高频开关电源:"<queryDevTypeByDesc(qita)<<" "; +// of<<"m_deviceType:"<dev_type<<" 内容:"<content.toStdString()<<" alm_type:"<alm_type<queryDevTypeByDesc(m_deviceType) != info->dev_type) + { + return false; + } + } + + //< 点-设备或设备组 + /* + if(E_Alarm_Pop == m_mode) + { + //点标签过滤 + if(info->device.isEmpty() || !m_deviceGroupFilter.contains(info->dev_group_tag)) + { + return false; + } + }*/ + //<< //如果告警信息info包含在队列m_deviceGroupFilter中 ->返回FASLE,不显示 + //<< //m_deviceGroupFilter 不显示告警的设备组需要放入到队列中 + if(m_deviceGroupFilter.contains(info->dev_group_tag)) + { + return false; //不显示 + } + //LOGERROR("conditionFilter::m_isDevGroupFilterEnable=%d,m_deviceGroupFilter=%d",m_isDevGroupFilterEnable,m_deviceGroupFilter.size());// + if((m_isDevGroupFilterEnable == true) && (info->alm_type == ALM_TYPE_SYSTEM) ) //设备组使能,不显示系统信息 + { + return false; + } + + //< 关键字 + if(m_isKeywordEnable && !info->content.contains(m_keyowrd) ) + { + return false; + } + + //< 时间 + if(m_timeFilterEnable) + { + if(m_startTime.toMSecsSinceEpoch() > (qint64)(info->time_stamp)) + { + return false; + } + if(m_endTime.toMSecsSinceEpoch() < (qint64)(info->time_stamp)) + { + return false; + } + } + + //< 是否已确认 + if(m_confirmFilterEnable) + { + if(m_isConfirm) + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) + { + return false; + } + } + else + { + if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM) + { + return false; + } + } + } + if(m_returnFilterEnable) + { + if(m_isReturn) + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_ALARM_CFM || info->logic_state == ALS_EVT_ONLY) + { + return false; + } + } + else + { + if(info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == ALS_EVT_ONLY) + { + return false; + } + } + } + return true; +} + +void CAlarmItemModel::updateAlternate() +{ + m_alternateFlag = !m_alternateFlag; +} + +void CAlarmItemModel::slotMsgRefresh() +{ + //ofstream of("d:\\msg.txt",ios::app); + beginResetModel(); + m_listShowAlarmInfo.clear(); + QList listAlarmInfo = CAlarmMsgManage::instance()->getListAlarmInfo(); + foreach (AlarmMsgPtr info, listAlarmInfo) + { + if(conditionFilter(info)) + { + m_listShowAlarmInfo.append(info); +// of<<"type:"<alm_type<< " "<< +// "app_id:"<app_id<< " "<< +// "priority:"<priority<< " "<< +// "content:"<content.toStdString()<< " "<< +// "alm_status:"<alm_status<< " "<< +// "dev_type:"<dev_type<< " "<< +// "priorityOrder:"<priorityOrder< listMsg) +{ + //处理新告警消息 + QList::const_iterator it = listMsg.constBegin(); + QList addMsgList; + while (it != listMsg.constEnd()) + { + if(conditionFilter(*it)) + { + addMsgList.append(*it); + } + ++it; + } + insertAlarmMsg(addMsgList); +} + +void CAlarmItemModel::slotMsgConfirm() +{ + if(E_Alarm_Dock == m_mode) + { + beginResetModel(); + for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) + { + E_ALARM_LOGICSTATE state = m_listShowAlarmInfo.at(nIndex)->logic_state; + if(state == E_ALS_ALARM_CFM || state == E_ALS_RETURN_CFM) + { + m_listShowAlarmInfo.removeAt(nIndex); + } + } + endResetModel(); + } +} + +void CAlarmItemModel::slotMsgRemove(int removeNum) +{ + if(removeNum >1000 || E_Alarm_Dock == m_mode) + { + beginResetModel(); + for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) + { + if(m_listShowAlarmInfo.at(nIndex)->deleteFlag) + { + m_listShowAlarmInfo.removeAt(nIndex); + } + } + endResetModel(); + }else + { + for(int nIndex = m_listShowAlarmInfo.size() - 1; nIndex >= 0; --nIndex) + { + if(m_listShowAlarmInfo.at(nIndex)->deleteFlag) + { + beginRemoveRows(QModelIndex(), nIndex, nIndex); + m_listShowAlarmInfo.removeAt(nIndex); + endRemoveRows(); + } + } + } +} + +void CAlarmItemModel::slotAlarmStateChanged(int total, int unConfirm) +{ + Q_UNUSED(unConfirm) + m_nTotalSize = total; +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmItemModel.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmItemModel.h new file mode 100644 index 00000000..deaffaec --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmItemModel.h @@ -0,0 +1,197 @@ +#ifndef CALARMITEMMODEL_H +#define CALARMITEMMODEL_H + +#include +#include +#include +#include +#include "CAlarmMsgInfo.h" +#include "CAlarmCommon.h" +extern const int DOCK_ROW_COUNT; +extern const int MAX_ROW_COUNT; + + + +class CAlarmView; +class CAlarmMsgInfo; + +class CAlarmItemModel : public QAbstractTableModel +{ + Q_OBJECT +public: + + enum ColumnField + { + TIME = 0, + PRIORITY, + LOCATION, + REGION, + TYPE, + STATUS, + RETURNSTATUS, + CONFIRM, + CONTENT + }; + + CAlarmItemModel(E_Alarm_Mode mode, QObject *parent = Q_NULLPTR); + ~CAlarmItemModel(); + + void initialize(); + + void initFilter(); + + E_Alarm_Mode getAlarmMode() const; + + int getShowAlarmCount() const; + + AlarmMsgPtr getAlarmInfo(const QModelIndex &index); + + const QList getListShowAlarmInfo() const; + + + void setColumnAlign(const int &column, const int &alignFlag); + + /** + * @brief insertAlarmMsg 数采通知模型告警到达 + * @param info + */ + void insertAlarmMsg(const QList & infoList); + + int calcLeft(const AlarmMsgPtr &info); + /** + * @brief alternate 闪烁状态切换 + * @return + */ + bool alternate() const; + + int filterCount(); + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + void sort(); + void qucikSort(QList &listAlarmInfo, int left, int right); + int partitionAscendingOrder(QList &list, int start, int last); + int partitionDescendingOrder(QList &list, int start, int last); + + void setPriorityFilter(bool &isCheck, QList &priorityFilter); + void setLocationFilter(bool &isCheck, QList &locationFilter); + void setAlarmTypeFilter(bool &isCheck, QList &alarmTypeFilter, bool &other); + void setAlarmTimeFilter(bool &isCheck, QDate &startTime,QDate &endTime); + void setAlarmTimeFilter(bool &isCheck); + /** + * 设置模型数据过滤条件,过滤显示数据 + */ + void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isStatusFilterEnable, const QList &statusFilter, + const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), + const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), + const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), + const QDateTime &endTime = QDateTime(), const bool &confirmFilterEnable = false, const bool &isConfirm = false,const bool &returnFilterEnable = false, const bool &isReturn= false); + + /** + * 获取模型数据过滤条件,用于初始化过滤对话框 + */ + void getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isStatusFilterEnable, QList &alarmStatusFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, + bool &confirmFilterEnable, bool &isConfirm, + bool &returnFilterEnable, bool &isReturn); + + + void addDeviceFilter(const QString &device); + void removeDeviceFilter(const QString &device); + + void addPointTagFilter(const QList &pointList); + + void setDeviceGroupFilterEnable(bool bEnalbe) ; //设备组过滤使能;设备组过滤不显示系统信息 + void addDeviceGroupFilter(); + void removeDeviceGroupFilter(); + void addDeviceGroupFilter(const QString &device); + void addDeviceGroupFilter2(const QString &device); + + void removeDeviceGroupFilter(const QString &device); + + bool conditionFilter(const AlarmMsgPtr &info); + + void updateAlternate(); + + + +public slots: + void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); + + /** + * @brief slotMsgRefresh 更新model,重新拉取数据 + */ + void slotMsgRefresh(); + +private slots: + /** + * @brief slotMsgArrived 告警消息到达 + * @param info + */ + void slotMsgArrived(QList listMsg); + + /** + * @brief slotMsgConfirm 告警消息确认 + */ + void slotMsgConfirm(); + + /** + * @brief slotMsgArrived 告警消息删除 + */ + void slotMsgRemove(int removeNum); + + void slotAlarmStateChanged(int total, int unConfirm); + +private: + E_Alarm_Mode m_mode; + QStringList m_header; + QList m_listShowAlarmInfo; + bool m_alternateFlag; //闪烁颜色切换 + E_ALARM_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + + int m_nTotalSize; + + QList m_listHorAlignmentFlags; //< 水平对齐方式 + + //< Filter + bool m_isLevelFilterEnable; //是否按告警级别过滤 + QList m_levelFilter; //告警级别过滤 + bool m_isLocationFilterEnable; //是否按车站过滤 + QList m_locationFilter; //车站过滤 + bool m_isRegionFilterEnable; //是否按责任区过滤 + QList m_regionFilter; //责任区过滤 + bool m_isStatusFilterEnable; //是否按告警类型过滤 + QList m_statusFilter; //告警类型过滤(所有的要过滤告警状态--如果其他状态没有被勾选,则与下面的内容相同) + QList m_statusFilter2; //告警类型过滤(显示在过滤窗中的告警状态) + bool m_isDeviceTypeFileter; //设备类型过滤 + QString m_subSystem; //子系统 + QString m_deviceType; //设备类型 + bool m_isKeywordEnable; //关键字过滤 + QString m_keyowrd; //关键字 + bool m_timeFilterEnable; //是否根据时间过滤 + QDateTime m_startTime; //起始时间 + QDateTime m_endTime; //终止时间 + bool m_confirmFilterEnable; //是否根据状态确认过滤 + bool m_isConfirm; //状态是否确认 + bool m_returnFilterEnable; //是否根据复归状态过滤 + bool m_isReturn; //是否已复归 + QSet m_deviceFilter; //< 设备过滤 + QSet m_pointFilter; //标签过滤 + bool m_isDevGroupFilterEnable ; //设备组过滤使能 + QSet m_deviceGroupFilter; //<设备组过滤 +}; + +#endif // ALARMITEMMODEL_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmMediaPlayer.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmMediaPlayer.cpp new file mode 100644 index 00000000..49196297 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmMediaPlayer.cpp @@ -0,0 +1,592 @@ + +#ifdef OS_WINDOWS +//< 为了检测可用声卡 +#include +#include +#endif + +#include +#include +#include +#include +#include "CAlarmMediaPlayer.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_logger_api/logger.h" +#include "pub_utility_api/I18N.h" +#include "CAlarmSetMng.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include "CAlarmMsgManage.h" + +using namespace iot_public; +CAlarmMediaPlayer * CAlarmMediaPlayer::m_pInstance = NULL; +CAlarmMediaPlayer *CAlarmMediaPlayer::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CAlarmMediaPlayer(); + } + return m_pInstance; +} + +CAlarmMediaPlayer::CAlarmMediaPlayer() + :m_bHaveValidAudioDev(true),m_pMediaPlayer(Q_NULLPTR),m_pTextToSpeech(Q_NULLPTR),m_pTimerCheckAudioDev(Q_NULLPTR),m_voice(100) +{ + m_readFlag = true; + QDir dir(QString::fromStdString(iot_public::CFileUtil::getCurModuleDir())); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + dir.cd("sound"); + initSetCfg(); + m_strMediaPath = dir.absolutePath() + QDir::separator(); + m_bChange = true; + m_pTimerCheckAudioDev = new QTimer(); + m_pTimerCheckAudioDev->setInterval(5000); + connect(m_pTimerCheckAudioDev, SIGNAL(timeout()), this, SLOT(checkAudioDev()),Qt::QueuedConnection); + m_pTimerCheckAudioStatus = new QTimer(); + m_pTimerCheckAudioStatus->setInterval(30000); + connect(m_pTimerCheckAudioStatus,&QTimer::timeout, this, &CAlarmMediaPlayer::checkAudioStatus,Qt::QueuedConnection); + checkAudioDev(); + checkAudioStatus(); + m_pTimerCheckAudioDev->start(); + m_pTimerCheckAudioStatus->start(); + + //< 需在checkAudioDev()之后调用 + + if(m_act == (int)E_ALARM_SOUND) + { + initPlayer(); + }else + { + initSpeech(); + } +} + +void CAlarmMediaPlayer::updateAudioCues() +{ + if(m_act == (int)E_ALARM_SOUND) + { + updateAudioCuesPlayer(); + }else + { + updateAudioCuesSpeech(); + } +} + +CAlarmMediaPlayer::~CAlarmMediaPlayer() +{ + if(Q_NULLPTR != m_pTimerCheckAudioDev) + { + m_pTimerCheckAudioDev->stop(); + m_pTimerCheckAudioDev->deleteLater(); + } + m_pTimerCheckAudioDev = NULL; + if(Q_NULLPTR != m_pTimerCheckAudioStatus) + { + m_pTimerCheckAudioStatus->stop(); + m_pTimerCheckAudioStatus->deleteLater(); + } + m_pTimerCheckAudioStatus = NULL; + if(Q_NULLPTR != m_pMediaPlayer) + { + if(QMediaPlayer::StoppedState != m_pMediaPlayer->state()) + { + m_pMediaPlayer->disconnect(); + m_pMediaPlayer->stop(); + } + delete m_pMediaPlayer; + } + m_pMediaPlayer = Q_NULLPTR; + + if(Q_NULLPTR != m_pTextToSpeech) + { + if(QTextToSpeech::Ready != m_pTextToSpeech->state()) + { + m_pTextToSpeech->disconnect(); + m_pTextToSpeech->stop(); + } + delete m_pTextToSpeech; + } + m_pTextToSpeech = Q_NULLPTR; + delete m_pInstance; + m_pInstance = Q_NULLPTR; +} + +void CAlarmMediaPlayer::initPlayer() +{ + if(Q_NULLPTR != m_pMediaPlayer) + { + return; + } + m_pMediaPlayer = new QMediaPlayer(); + m_pMediaPlayer->setVolume(m_voice); + connect(m_pMediaPlayer, &QMediaPlayer::stateChanged, this, &CAlarmMediaPlayer::playerStateChanged,Qt::QueuedConnection); + connect(m_pMediaPlayer, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(printError(QMediaPlayer::Error)),Qt::QueuedConnection); + + QMediaPlaylist *pPlayList = new QMediaPlaylist(this); + pPlayList->setPlaybackMode(QMediaPlaylist::Sequential); + pPlayList->clear(); + m_pMediaPlayer->setPlaylist(pPlayList); +} + +void CAlarmMediaPlayer::initSpeech() +{ + if(Q_NULLPTR != m_pTextToSpeech) + { + return; + } + + QStringList engineList = QTextToSpeech::availableEngines(); + + if(engineList.isEmpty()) + { + return ; + } + if(m_engine.isEmpty() || !engineList.contains(m_engine)) + { +#ifdef OS_LINUX + m_pTextToSpeech = Q_NULLPTR; + return; +#else + m_pTextToSpeech = new QTextToSpeech(this); +#endif + }else + { + m_pTextToSpeech = new QTextToSpeech(m_engine,this); + } + m_pTextToSpeech->setVolume(m_voice); + connect(m_pTextToSpeech, &QTextToSpeech::stateChanged, this, &CAlarmMediaPlayer::speechStateChanged,Qt::QueuedConnection); + QVector locales = m_pTextToSpeech->availableLocales(); + if(!m_language.isEmpty()) + { + foreach (const QLocale &locale, locales) { + if (locale.name() == m_language) + { + m_pTextToSpeech->setLocale(locale); + break; + } + } + } + QVector voices = m_pTextToSpeech->availableVoices(); + if(!m_voiceName.isEmpty()) + { + foreach (const QVoice &voice, voices) { + if (voice.name() == m_voiceName) + { + m_pTextToSpeech->setVoice(voice); + break; + } + } + } + +} + +void CAlarmMediaPlayer::initSetCfg() +{ + CAlarmSetMng::instance()->getActAndNum(m_act,m_num,m_style); + CAlarmSetMng::instance()->getEngine(m_engine,m_language,m_voiceName); + LOGDEBUG("获取当前语音引擎:%s-%s-%s",m_engine.toStdString().c_str(),m_language.toStdString().c_str(),m_voiceName.toStdString().c_str()); +} + +void CAlarmMediaPlayer::removeAudioCuesStop() +{ + if(m_act == (int)E_ALARM_SOUND) + { + if(m_pMediaPlayer != NULL) + { + m_pMediaPlayer->stop(); + } + }else + { + if(m_pTextToSpeech != NULL) + { + m_pTextToSpeech->stop(); + emit m_pTextToSpeech->stateChanged(m_pTextToSpeech->state()); + } + } +} + +void CAlarmMediaPlayer::insertAudioCuesStop(const AlarmMsgPtr &info) +{ + if(m_act == (int)E_ALARM_SOUND && ALM_ACT_SOUND == (info->m_alarmAction & ALM_ACT_SOUND)) + { + if(m_pMediaPlayer != NULL) + { + m_pMediaPlayer->stop(); + } + }else if(m_act == (int)E_ALARM_VOICE && ALM_ACT_VOICE == (info->m_alarmAction & ALM_ACT_VOICE)) + { + if(m_pTextToSpeech != NULL) + { + m_pTextToSpeech->stop(); + emit m_pTextToSpeech->stateChanged(m_pTextToSpeech->state()); + } + } +} + +void CAlarmMediaPlayer::setVolumeEnable(bool bEnable) +{ + if(bEnable) + { + m_voice = 100; + if(m_pMediaPlayer != Q_NULLPTR) + { + m_pMediaPlayer->setVolume(m_voice); + } + + if(m_pTextToSpeech != Q_NULLPTR) + { + m_pTextToSpeech->setVolume(m_voice); + } + + } + else + { + m_voice = 0; + if(m_pMediaPlayer != Q_NULLPTR) + { + m_pMediaPlayer->setVolume(m_voice); + } + + if(m_pTextToSpeech != Q_NULLPTR) + { + m_pTextToSpeech->setVolume(m_voice); + } + } +} + +void CAlarmMediaPlayer::release() +{ + LOGINFO("CAlarmMediaPlayer::release()"); + if(m_pMediaPlayer) + { + m_pMediaPlayer->stop(); + } + if(m_pTextToSpeech) + { + m_pTextToSpeech->stop(); + } +} + +void CAlarmMediaPlayer::destory() +{ + if(m_pMediaPlayer) + { + m_pMediaPlayer->disconnect(); + m_pMediaPlayer->stop(); + } + if(m_pTextToSpeech) + { + m_pTextToSpeech->disconnect(); + m_pTextToSpeech->stop(); + } + m_pInstance = NULL; + deleteLater(); +} + +void CAlarmMediaPlayer::slotLoadConfig() +{ + LOGINFO("CAlarmMediaPlayer::slotLoadConfig()"); + if(m_pMediaPlayer) + { + m_pMediaPlayer->disconnect(); + m_pMediaPlayer->stop(); + delete m_pMediaPlayer; + m_pMediaPlayer = Q_NULLPTR; + } + if(m_pTextToSpeech) + { + m_pTextToSpeech->disconnect(); + m_pTextToSpeech->stop(); + delete m_pTextToSpeech; + m_pTextToSpeech = Q_NULLPTR; + } + initSetCfg(); + + + if(m_act == (int)E_ALARM_SOUND) + { + initPlayer(); + updateAudioCuesPlayer(); + }else + { + initSpeech(); + updateAudioCuesSpeech(); + } +} + +void CAlarmMediaPlayer::slotReadFlag() +{ + LOGDEBUG("slotReadFlag"); + m_readFlag = true; + + if(m_style != E_STYLE_NO_ALARM) + { + updateAudioCues(); + } +} + +void CAlarmMediaPlayer::playerStateChanged(QMediaPlayer::State state) +{ + if(m_act != (int)E_ALARM_SOUND) + { + return ; + } + m_bChange = true; + if(state == QMediaPlayer::StoppedState) + { + updateAudioCuesPlayer(); + } +} + +void CAlarmMediaPlayer::speechStateChanged(QTextToSpeech::State state) +{ + if(m_act != (int)E_ALARM_VOICE) + { + return ; + } + if(state == QTextToSpeech::Ready) + { + updateAudioCuesSpeech(); + } +} + +void CAlarmMediaPlayer::updateAudioCuesPlayer() +{ + if(!m_bHaveValidAudioDev || !m_pMediaPlayer || !m_readFlag || m_pMediaPlayer->state() != QMediaPlayer::StoppedState) + { + LOGDEBUG("CAlarmMediaPlayer::updateAudioCuesPlayer(),return"); + return; + } + AlarmMsgPtr info; + if(m_style == E_STYLE_REPEAT) + { + info = CAlarmMsgManage::instance()->getOnePlayerAlm(-1); + } + else if(m_style == E_STYLE_REPEAT_X) + { + info = CAlarmMsgManage::instance()->getOnePlayerAlm(m_num); + } + if(info == Q_NULLPTR) + { + m_readFlag = false; + return ; + } + QStringList strAudioFileNames = info->sound_file; + + m_pMediaPlayer->playlist()->clear(); + foreach (QString fileName, strAudioFileNames) + { + if(!fileName.isEmpty()) + { + fileName = m_strMediaPath + fileName; + if(QFile::exists(fileName)) + { + m_pMediaPlayer->playlist()->addMedia(QUrl::fromLocalFile(fileName)); + } + } + } + if(!m_pMediaPlayer->playlist()->isEmpty()) + { + m_pMediaPlayer->play(); + } +} + +void CAlarmMediaPlayer::updateAudioCuesSpeech() +{ + if(!m_bHaveValidAudioDev || !m_pTextToSpeech || !m_readFlag || m_pTextToSpeech->state() != QTextToSpeech::Ready) + { + LOGDEBUG("CAlarmMediaPlayer::updateAudioCuesSpeech(),return"); + return; + } + AlarmMsgPtr info; + if(m_style == E_STYLE_REPEAT) + { + info = CAlarmMsgManage::instance()->getOneSpeechAlm(-1); + } + else if(m_style == E_STYLE_REPEAT_X) + { + info = CAlarmMsgManage::instance()->getOneSpeechAlm(m_num); + } + if(info == Q_NULLPTR) + { + m_readFlag = false; + return ; + } + QString alarmContent = info->content; + + if(!alarmContent.isEmpty()) + { + m_pTextToSpeech->say(alarmContent); + } +} + +void CAlarmMediaPlayer::printError(QMediaPlayer::Error error) +{ + if(m_pMediaPlayer) + { + LOGERROR("QMediaPlayer error == %d , errorString : %s",error,m_pMediaPlayer->errorString().toStdString().c_str()); + } +} + +void CAlarmMediaPlayer::checkAudioDev() +{ + //< 周期性检测音频设备有效性,因为: + //< 1、声卡是可以热拔插的,比如USB声卡 + //< 2、音频服务(比如Windows Audio系统服务)也是可以动态启停的 + + bool bHaveValidDev = false; + + //< 注意:在win系统,qt5.9.9以及5.12.9上测试,下面使用QAudioDeviceInfo检测的方法,本身会导致内存上涨 + { + // //< 测试结果:无论windows audio服务是否启动,defaultOutputDevice看上去都是对的,所以,不能用这个判断是否有效 + + // QList listDev(QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)); + + // //< 不能仅仅检测列表是否为空,还需要检测有效性 + // //< 当有声卡硬件,但是Windows Audio服务未启动时,设备列表不为空,但如果播放依然可能导致内存上涨问题 + // foreach (QAudioDeviceInfo objDev, listDev) + // { + // //< 当Window Audio服务未启动时,无法获取有效的格式信息,以此判断 + // if(objDev.preferredFormat().isValid()) + // { + // bHaveValidDev = true; + // break; + // } + // } + } + + //< 不得已,使用win系统原生API条件编译 +#ifdef OS_WINDOWS + { + //< 获取系统默认主设备的音量,如果成功则至少说明: + //< 1、有声卡; 2、Windows Audio服务正常 + + CoInitialize(NULL); + IMMDeviceEnumerator *pDevEnumerator = NULL; + CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDevEnumerator); + + if(NULL != pDevEnumerator) + { + IMMDevice *pDefaultDev = NULL; + pDevEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDefaultDev); + + pDevEnumerator->Release(); + pDevEnumerator = NULL; + + if(NULL != pDefaultDev) + { + IAudioEndpointVolume *pEndpointVol = NULL; + pDefaultDev->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&pEndpointVol); + + pDefaultDev->Release(); + pDefaultDev = NULL; + + if(NULL != pEndpointVol) + { + float fVol; + const HRESULT nResult = pEndpointVol->GetMasterVolumeLevelScalar(&fVol); + if(S_OK == nResult) + bHaveValidDev = true; + + pEndpointVol->Release(); + pEndpointVol = NULL; + } + } + } + + CoUninitialize(); + } +#else + //< 在Linux系统下测试,即使没有声卡也未见问题,暂时不做检测 + bHaveValidDev = true; +#endif + if(m_act == (int)E_ALARM_SOUND) // + { + if(m_bHaveValidAudioDev && !bHaveValidDev) + { + LOGERROR("No valid audio output device !"); + m_bHaveValidAudioDev = false; + if(m_pMediaPlayer != Q_NULLPTR) + { + m_pMediaPlayer->disconnect(); + m_pMediaPlayer->stop(); + delete m_pMediaPlayer; + m_pMediaPlayer = Q_NULLPTR; + } + } + else if(!m_bHaveValidAudioDev && bHaveValidDev) + { + LOGINFO("Valid audio output device detected !"); + + //< 不重新构造可能不能正常播放 + if(m_pMediaPlayer) + { + m_pMediaPlayer->disconnect(); + delete m_pMediaPlayer; + m_pMediaPlayer = Q_NULLPTR; + } + + m_bHaveValidAudioDev = true; + initPlayer(); + updateAudioCuesPlayer(); + } + }else + { + if(m_bHaveValidAudioDev && !bHaveValidDev) + { + LOGERROR("No valid audio output device !"); + m_bHaveValidAudioDev = false; + if(m_pTextToSpeech != Q_NULLPTR) + { + m_pTextToSpeech->disconnect(); + m_pTextToSpeech->stop(); + delete m_pTextToSpeech; + m_pTextToSpeech = Q_NULLPTR; + } + } + else if(!m_bHaveValidAudioDev && bHaveValidDev) + { + LOGINFO("Valid audio output device detected !"); + + //< 不重新构造可能不能正常播放 + if(m_pTextToSpeech) + { + m_pTextToSpeech->disconnect(); + m_pTextToSpeech->stop(); + delete m_pTextToSpeech; + m_pTextToSpeech = Q_NULLPTR; + } + m_bHaveValidAudioDev = true; + initSpeech(); + updateAudioCuesSpeech(); + } + } +} +//因QMediaPlayer自身bug问题 此处只检测QMediaPlayer +void CAlarmMediaPlayer::checkAudioStatus() +{ + if(!m_readFlag) + { + return ; + } + if(m_act == (int)E_ALARM_VOICE) //语音告警无需检测 + { + return ; + } + if(!m_bChange) + { + //< 不重新构造可能不能正常播放 + if(m_pMediaPlayer) + { + m_pMediaPlayer->disconnect(); + m_pMediaPlayer->stop(); + delete m_pMediaPlayer; + m_pMediaPlayer = Q_NULLPTR; + } + m_bHaveValidAudioDev = true; + initPlayer(); + updateAudioCuesPlayer(); + } + m_bChange = false; +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmMediaPlayer.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmMediaPlayer.h new file mode 100644 index 00000000..84e9dce5 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmMediaPlayer.h @@ -0,0 +1,99 @@ +#ifndef CALARMMEDIAPLAYER_H +#define CALARMMEDIAPLAYER_H + +#include +#include +#include +#include +#include "CAlarmMsgInfo.h" +#include + +//< 告警语音最大条数 +//extern const int MAX_AUDIO_COUNT; + +class CAlarmMediaPlayer : public QObject +{ + Q_OBJECT +public: + static CAlarmMediaPlayer * instance(); + ~CAlarmMediaPlayer(); + + /** + * @brief slotAudioCuesEnable 静音使能 + * @param bEnable + */ + void setVolumeEnable(bool bEnable); + + void release(); + +public slots: + void destory(); + void slotLoadConfig(); + + void slotReadFlag(); + +private: + CAlarmMediaPlayer(); + + void updateAudioCues(); + /** + * @brief updateAudioCuesPlayer 更新播放文件 + */ + void updateAudioCuesPlayer(); + + void updateAudioCuesSpeech(); + + void initPlayer(); + + void initSpeech(); + + void initSetCfg(); + + void removeAudioCuesStop(); + + void insertAudioCuesStop(const AlarmMsgPtr &info); + +private slots: + /** + * @brief playerStateChanged 播放器状态变化 + */ + void playerStateChanged(QMediaPlayer::State state); + + void speechStateChanged(QTextToSpeech::State state); + + void printError(QMediaPlayer::Error error); + + void checkAudioDev(); + + void checkAudioStatus(); +private: + //< 机器有有效的音频输出设备 + //< 如果没有输出设备,会导致内存上涨,在Windows Server 2016上实测如此 + bool m_bHaveValidAudioDev; + static CAlarmMediaPlayer * m_pInstance; + QString m_strMediaPath; + QMediaPlayer *m_pMediaPlayer; + QTextToSpeech *m_pTextToSpeech; + + //< 周期性检测音频设备有效性,因为: + //< 1、声卡是可以热拔插的,比如USB声卡 + //< 2、音频服务(比如Windows Audio系统服务)也是可以动态启停的 + QTimer *m_pTimerCheckAudioDev; + QTimer *m_pTimerCheckAudioStatus; + int m_voice; //语音大小 + bool m_bChange; + + int m_act; + int m_num; + int m_style; + + QString m_engine; + QString m_language; + QString m_voiceName; + + bool m_readFlag; + + +}; + +#endif // CALARMMEDIAPLAYER_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmMsgInfo.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmMsgInfo.cpp new file mode 100644 index 00000000..ec65ae81 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmMsgInfo.cpp @@ -0,0 +1,1189 @@ +#include "CAlarmMsgInfo.h" +#include +#include "CAlarmDataCollect.h" +#include +#include "CAiAlarmMsgInfo.h" +#include "pub_logger_api/logger.h" + +using namespace std; +CAlarmMsgInfo::CAlarmMsgInfo(): m_alarmAction(0) +{ + alm_type = -1; + alm_status = -1; + logic_state = E_ALS_ALARM; + time_stamp = 1000; + domain_id = -1; + + location_id = -1; + app_id = -1; + uuid_base64 = QString(); + content = QString(); + priority = -1; + + if_water_alm = -1; + sound_file = QStringList(); + sub_system = 0; + dev_type = -1; + region_id = -1; + dev_group_tag = QString(); + + key_id_tag = QString(); + graph_name = QString(); + priorityOrder = -1; + deleteFlag = false; + releaseFlag = false; + device = QString(); + m_needVideoAlm = false; + m_camera = QString(); + m_preset = QString(); + m_tagname_type = E_TAGNAME_ERROR; + m_playNum = 0; + wave_file = QString(); +} + +CAlarmMsgInfo::CAlarmMsgInfo(const CAlarmMsgInfo &other): m_alarmAction(0) +{ + alm_type = other.alm_type; + alm_status = other.alm_status; + logic_state = other.logic_state; + time_stamp = other.time_stamp; + domain_id = other.domain_id; + + location_id = other.location_id; + app_id = other.app_id; + uuid_base64 = other.uuid_base64; + content = other.content; + priority = other.priority; + + priorityOrder = other.priorityOrder; + if_water_alm = other.if_water_alm; + sound_file = other.sound_file; + sub_system = other.sub_system; + dev_type = other.dev_type; + region_id = other.region_id; + + dev_group_tag = other.dev_group_tag; + key_id_tag = other.key_id_tag; + graph_name = other.graph_name; + deleteFlag = other.deleteFlag; + releaseFlag = other.releaseFlag; + device = other.device; + m_needVideoAlm = other.m_needVideoAlm; + m_camera = other.m_camera; + m_preset = other.m_preset; + m_tagname_type = other.m_tagname_type; + m_playNum = other.m_playNum; + wave_file = other.wave_file; +} + +void CAlarmMsgInfo::initialize(const iot_idl::SAlmInfoToAlmClt &alarmInfo) +{ + alm_type = alarmInfo.alm_type(); + alm_status = alarmInfo.alm_status(); + logic_state = (E_ALARM_LOGICSTATE)alarmInfo.logic_state(); + time_stamp = alarmInfo.time_stamp(); + domain_id = alarmInfo.domain_id(); + + location_id = alarmInfo.location_id(); + app_id = alarmInfo.app_id(); + + uuid_base64 = QString::fromStdString(alarmInfo.uuid_base64()); + + + content = QString::fromStdString(alarmInfo.content()); + priority = alarmInfo.priority(); + + if_water_alm = alarmInfo.if_water_alm(); + sub_system = alarmInfo.sub_system(); + sound_file.clear(); + for(int nIndex(0); nIndex < alarmInfo.sound_file_size(); nIndex++) + { + sound_file << QString::fromStdString(alarmInfo.sound_file(nIndex)); + } + + dev_type = alarmInfo.dev_type(); + if(alarmInfo.has_region_id() && alarmInfo.region_id() > 0) + { + region_id = alarmInfo.region_id(); + } + else + { + region_id = -1; + } + + if(alarmInfo.has_dev_group_tag()) + { + dev_group_tag = QString::fromStdString(alarmInfo.dev_group_tag()); + } + + if(alarmInfo.has_key_id_tag()) + { + key_id_tag = QString::fromStdString(alarmInfo.key_id_tag()); + QStringList tagList = key_id_tag.split("."); + if(tagList.size() == 5) + { + device = tagList.at(1) + "." + tagList.at(2); + } + if(tagList.at(0) == "analog") + { + m_tagname_type = E_TAGNAME_ANA; + }else if(tagList.at(0) == "digital") + { + m_tagname_type = E_TAGNAME_DIG; + }else if(tagList.at(0) == "mix") + { + m_tagname_type = E_TAGNAME_MIX; + }else if(tagList.at(0) == "accuml") + { + m_tagname_type = E_TAGNAME_ACC; + }else + { + m_tagname_type = E_TAGNAME_ERROR; + } + } + + if(alarmInfo.has_graph_name()) + { + graph_name = QString::fromStdString(alarmInfo.graph_name()); + } + if(logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_ALARM_CFM_DEL || + logic_state == E_ALS_RETURN_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY) + { + deleteFlag = true; + }else + { + deleteFlag = false; + } + releaseFlag = false; + m_camera = QString::fromStdString(alarmInfo.camera_tag()); + m_preset = QString::fromStdString(alarmInfo.camera_preset()); + wave_file = QString::fromStdString(alarmInfo.wave_file()); + //wave_file = "D:\\Development_Repository\\ISCS6000_HOME\\data\\rec\\18-1-24-17-15-30587_1_S40_0"; +} + +bool CAlarmMsgInfo::lessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) + { + case E_SORT_PRIORITY: + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + else if(priorityOrder < info->priorityOrder) + { + return false; + } + else if(priorityOrder == info->priorityOrder) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_TIME: + { + if(time_stamp < info->time_stamp) + { + return true; + } + if(time_stamp > info->time_stamp) + { + return false; + } + else if(time_stamp == info->time_stamp) + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOCATION: + { + if(location_id < info->location_id) + { + return true; + } + else if(location_id > info->location_id) + { + return false; + } + else if(location_id == info->location_id) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_REGION: + { + if(region_id < info->region_id) + { + return true; + } + else if(region_id > info->region_id) + { + return false; + } + else if(region_id == info->region_id) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_TYPE: + { + if(alm_type < info->alm_type) + { + return true; + } + else if(alm_type > info->alm_type) + { + return false; + } + else if(alm_type == info->alm_type) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOGICSTATE://已确认小于未确认 + { + if(logic_state ==E_ALS_ALARM_CFM|| logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY)//等于已确认 + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL) //等于未确认 + { + return true; + } + } + if(logic_state == E_ALS_ALARM || logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL)//等于未确认 + { + if(info->logic_state ==E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL || info->logic_state == ALS_EVT_ONLY)//等于已确认 + { + return false; + } + } + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + break; + } + case E_SORT_STYLE://动作小于复归小于事件 + { + if(logic_state == E_ALS_ALARM ||logic_state == E_ALS_ALARM_CFM ||logic_state == E_ALS_ALARM_DEL ||logic_state == E_ALS_ALARM_CFM_DEL ) //等于动作 + { + if(info->logic_state != E_ALS_ALARM &&info->logic_state != E_ALS_ALARM_CFM && info->logic_state != E_ALS_ALARM_DEL && info->logic_state != E_ALS_ALARM_CFM_DEL )//不等于动作 + { + return true; + } + } + if(logic_state == E_ALS_RETURN ||logic_state == E_ALS_RETURN_CFM ||logic_state == E_ALS_RETURN_DEL ||logic_state == E_ALS_RETURN_CFM_DEL ) //等于复归 + { + if(info->logic_state == ALS_EVT_ONLY)//等于事件 + { + return true; + }else if(info->logic_state == E_ALS_ALARM ||info->logic_state == E_ALS_ALARM_CFM ||info->logic_state == E_ALS_ALARM_DEL ||info->logic_state == E_ALS_ALARM_CFM_DEL )//等于动作 + { + return false; + } + } + if(logic_state == ALS_EVT_ONLY)//等于事件 + { + if(info->logic_state != ALS_EVT_ONLY)//不等于事件 + { + return false; + } + } + + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + + break; + } + case E_SORT_ALM_STATE: + { + if(alm_status < info->alm_status) + { + return true; + } + else if(alm_status > info->alm_status) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_CONTENT: + { + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else if(content == info->content) + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + default: + break; + } + return false; +} + +bool CAlarmMsgInfo::moreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) + { + case E_SORT_PRIORITY: + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + else if(priorityOrder > info->priorityOrder) + { + return false; + } + else if(priorityOrder == info->priorityOrder) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TIME: + { + if(time_stamp > info->time_stamp) + { + return true; + } + if(time_stamp < info->time_stamp) + { + return false; + } + else if(time_stamp == info->time_stamp) + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOCATION: + { + if(location_id > info->location_id) + { + return true; + } + else if(location_id < info->location_id) + { + return false; + } + else if(location_id == info->location_id) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_REGION: + { + if(region_id > info->region_id) + { + return true; + } + else if(region_id < info->region_id) + { + return false; + } + else if(region_id == info->region_id) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TYPE: + { + if(alm_type > info->alm_type) + { + return true; + } + else if(alm_type < info->alm_type) + { + return false; + } + else if(alm_type == info->alm_type) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_LOGICSTATE: + { + if(logic_state ==E_ALS_ALARM|| logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL) //等于未确认 + { + if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL|| info->logic_state == ALS_EVT_ONLY) + { + return true; + } + } + if(logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY) + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL) + { + return false; + } + } + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + + break; + } + case E_SORT_STYLE://动作小于复归小于事件 + { + if(logic_state == E_ALS_ALARM ||logic_state == E_ALS_ALARM_CFM ||logic_state == E_ALS_ALARM_DEL ||logic_state == E_ALS_ALARM_CFM_DEL ) //等于动作 + { + if(info->logic_state != E_ALS_ALARM &&info->logic_state != E_ALS_ALARM_CFM && info->logic_state != E_ALS_ALARM_DEL && info->logic_state != E_ALS_ALARM_CFM_DEL )//不等于动作 + { + return false; + } + } + if(logic_state == E_ALS_RETURN ||logic_state == E_ALS_RETURN_CFM ||logic_state == E_ALS_RETURN_DEL ||logic_state == E_ALS_RETURN_CFM_DEL ) //等于复归 + { + if(info->logic_state == ALS_EVT_ONLY)//等于事件 + { + return false; + }else if(info->logic_state == E_ALS_ALARM ||info->logic_state == E_ALS_ALARM_CFM ||info->logic_state == E_ALS_ALARM_DEL ||info->logic_state == E_ALS_ALARM_CFM_DEL )//等于动作 + { + return true; + } + } + if(logic_state == ALS_EVT_ONLY)//等于事件 + { + if(info->logic_state != ALS_EVT_ONLY)//不等于事件 + { + return true; + } + } + + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + + break; + } + case E_SORT_ALM_STATE: + { + if(alm_status > info->alm_status) + { + return true; + } + else if(alm_status < info->alm_status) + { + return false; + } + else if(alm_status == info->alm_status) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_CONTENT: + { + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content > info->content) + { + return true; + } + else if(content < info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + default: + break; + } + return false; +} + +bool CAlarmMsgInfo::ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder > info->priorityOrder) + { + return true; + }else if(priorityOrder < info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp < info->time_stamp) + { + return true; + }else if(time_stamp > info->time_stamp) + { + return false; + }else + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + if(location_id < info->location_id) + { + return true; + }else if(location_id > info->location_id) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_REGION: + if(region_id < info->region_id) + { + return true; + }else if(region_id > info->region_id) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + + break; + case E_SORT_TYPE: + if(alm_type < info->alm_type) + { + return true; + }else if(alm_type > info->alm_type) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE://已确认小于未确认 + { + if(logic_state ==E_ALS_ALARM_CFM|| logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY)//等于已确认 + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL) //等于未确认 + { + return true; + } + } + if(logic_state == E_ALS_ALARM || logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL)//等于未确认 + { + if(info->logic_state ==E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL || info->logic_state == ALS_EVT_ONLY)//等于已确认 + { + return false; + } + } + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + break; + } + case E_SORT_STYLE://动作小于复归小于事件 + { + if(logic_state == E_ALS_ALARM ||logic_state == E_ALS_ALARM_CFM ||logic_state == E_ALS_ALARM_DEL ||logic_state == E_ALS_ALARM_CFM_DEL ) //等于动作 + { + if(info->logic_state != E_ALS_ALARM &&info->logic_state != E_ALS_ALARM_CFM && info->logic_state != E_ALS_ALARM_DEL && info->logic_state != E_ALS_ALARM_CFM_DEL )//不等于动作 + { + return true; + } + } + if(logic_state == E_ALS_RETURN ||logic_state == E_ALS_RETURN_CFM ||logic_state == E_ALS_RETURN_DEL ||logic_state == E_ALS_RETURN_CFM_DEL ) //等于复归 + { + if(info->logic_state == ALS_EVT_ONLY)//等于事件 + { + return true; + }else if(info->logic_state == E_ALS_ALARM ||info->logic_state == E_ALS_ALARM_CFM ||info->logic_state == E_ALS_ALARM_DEL ||info->logic_state == E_ALS_ALARM_CFM_DEL )//等于动作 + { + return false; + } + } + if(logic_state == ALS_EVT_ONLY)//等于事件 + { + if(info->logic_state != ALS_EVT_ONLY)//不等于事件 + { + return false; + } + } + + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + + break; + } + case E_SORT_ALM_STATE: + if(alm_status < info->alm_status) + { + return true; + }else if(alm_status > info->alm_status) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + default: + break; + } + return false; +} +//< 优先级小的大于优先级大的、时间大的大于时间小的、车站id大的大于车站id小的、责任区id大的大于责任区id小的、告警类型大的大于告警类型小的、 +//< 告警内容都为空,则前者小于后者、告警内容为空的小于告警内容不为空的、告警未确认的大于告警已确认的、告警状态大的大于告警状态小的 +bool CAlarmMsgInfo::aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder < info->priorityOrder) + { + return true; + }else if(priorityOrder > info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_TIME: + if(time_stamp > info->time_stamp) + { + return true; + }else if(time_stamp < info->time_stamp) + { + return false; + }else + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + if(location_id > info->location_id) + { + return true; + }else if(location_id < info->location_id) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_REGION: + if(region_id > info->region_id) + { + return true; + }else if(region_id < info->region_id) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + + break; + case E_SORT_TYPE: + if(alm_type > info->alm_type) + { + return true; + }else if(alm_type < info->alm_type) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content > info->content) + { + return true; + } + else if(content < info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_LOGICSTATE: + { + if(logic_state ==E_ALS_ALARM|| logic_state == E_ALS_RETURN || logic_state == E_ALS_ALARM_DEL || logic_state == E_ALS_RETURN_DEL) //等于未确认 + { + if(info->logic_state == E_ALS_ALARM_CFM || info->logic_state == E_ALS_RETURN_CFM || info->logic_state == E_ALS_ALARM_CFM_DEL || info->logic_state == E_ALS_RETURN_CFM_DEL|| info->logic_state == ALS_EVT_ONLY) + { + return true; + } + } + if(logic_state == E_ALS_ALARM_CFM || logic_state == E_ALS_RETURN_CFM || logic_state == E_ALS_ALARM_CFM_DEL || logic_state == E_ALS_RETURN_CFM_DEL || logic_state == ALS_EVT_ONLY) + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN || info->logic_state == E_ALS_ALARM_DEL || info->logic_state == E_ALS_RETURN_DEL) + { + return false; + } + } + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + + break; + } + case E_SORT_STYLE://动作小于复归小于事件 + { + if(logic_state == E_ALS_ALARM ||logic_state == E_ALS_ALARM_CFM ||logic_state == E_ALS_ALARM_DEL ||logic_state == E_ALS_ALARM_CFM_DEL ) //等于动作 + { + if(info->logic_state != E_ALS_ALARM &&info->logic_state != E_ALS_ALARM_CFM && info->logic_state != E_ALS_ALARM_DEL && info->logic_state != E_ALS_ALARM_CFM_DEL )//不等于动作 + { + return false; + } + } + if(logic_state == E_ALS_RETURN ||logic_state == E_ALS_RETURN_CFM ||logic_state == E_ALS_RETURN_DEL ||logic_state == E_ALS_RETURN_CFM_DEL ) //等于复归 + { + if(info->logic_state == ALS_EVT_ONLY)//等于事件 + { + return false; + }else if(info->logic_state == E_ALS_ALARM ||info->logic_state == E_ALS_ALARM_CFM ||info->logic_state == E_ALS_ALARM_DEL ||info->logic_state == E_ALS_ALARM_CFM_DEL )//等于动作 + { + return true; + } + } + if(logic_state == ALS_EVT_ONLY)//等于事件 + { + if(info->logic_state != ALS_EVT_ONLY)//不等于事件 + { + return true; + } + } + + if(time_stamp > info->time_stamp) + { + return true; + } + return false; + + break; + } + case E_SORT_ALM_STATE: + if(alm_status > info->alm_status) + { + return true; + }else if(alm_status < info->alm_status) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + default: + break; + } + return false; +} + +bool CAlarmMsgInfo::ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder > info->priorityOrder) + { + return true; + }else if(priorityOrder < info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_TIME: + if(time_stamp < info->time_stamp) + { + return true; + }else if(time_stamp > info->time_stamp) + { + return false; + }else + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + return false; + } + break; + case E_SORT_LOCATION: + return true; + break; + case E_SORT_REGION: + return true; + break; + case E_SORT_TYPE: + return true; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + case E_SORT_LOGICSTATE: + return true; + case E_SORT_STYLE: + return true; + case E_SORT_ALM_STATE: + return true; + break; + default: + break; + } + return false; +} + +bool CAlarmMsgInfo::aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) { + case E_SORT_PRIORITY: + if(priorityOrder < info->priorityOrder) + { + return true; + }else if(priorityOrder > info->priorityOrder) + { + return false; + }else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_TIME: + if(time_stamp > info->time_stamp) + { + return true; + }else if(time_stamp < info->time_stamp) + { + return false; + }else + { + if(priorityOrder < info->priorityOrder) + { + return false; + } + return true; + } + break; + case E_SORT_LOCATION: + return false; + break; + case E_SORT_REGION: + return false; + break; + case E_SORT_TYPE: + return false; + break; + case E_SORT_CONTENT: + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content > info->content) + { + return true; + } + else if(content < info->content) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + case E_SORT_LOGICSTATE: + return false; + break; + case E_SORT_STYLE: + return false; + break; + case E_SORT_ALM_STATE: + return false; + break; + default: + break; + } + return false; +} + +bool operator==(const CAlarmMsgInfo &source, const CAlarmMsgInfo &target) +{ + if(source.uuid_base64 == target.uuid_base64) + { + return true; + } + return false; + // //替换式告警且车站、测点ID相同 + // if((0 == source.if_water_alm) && (0 == target.if_water_alm) && (source.location_id == target.location_id) && (source.key_id_tag == target.key_id_tag)) + // { + // return true; + // } + // //流水账告警且时标、告警内容相同 + // else if((1 == source.if_water_alm) && (1 == target.if_water_alm) && (source.location_id == target.location_id) && (source.time_stamp == target.time_stamp) && (source.content == target.content)) + // { + // return true; + // } + // return false; +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmMsgInfo.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmMsgInfo.h new file mode 100644 index 00000000..f8b286fd --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmMsgInfo.h @@ -0,0 +1,88 @@ +#ifndef ALARMMSGINFO_H +#define ALARMMSGINFO_H + +#include +#include +#include +#include "alarm_server_api/CAlmApiForAlmClt.h" +#include "CAlarmCommon.h" +//< 告警操作 权限定义 +#define FUNC_SPE_ALARM_OPERATE ("FUNC_SPE_ALARM_OPERATE") +#define FUNC_SPE_ALARM_DELETE ("FUNC_SPE_ALARM_DELETE") +// 逻辑状态 +enum E_ALARM_LOGICSTATE +{ + E_ALS_ALARM = 0, // 告警状态 + E_ALS_ALARM_CFM =1, // 告警确认状态 + E_ALS_RETURN=2, // 告警返回状态 + E_ALS_RETURN_CFM=3, // 告警返回确认状态 + ALS_EVT_ONLY = 4, // 仅事件 + + //在原始告警窗删除后,可能还需要在智能告警窗展示 + E_ALS_ALARM_DEL = 20, // 告警状态,且在原始告警窗已删除,可能是达到数量上限而删除 + E_ALS_ALARM_CFM_DEL =21, // 告警确认状态,且在原始告警窗已删除 + E_ALS_RETURN_DEL=22, // 告警返回状态,且在原始告警窗已删除,可能是达到数量上限而删除 + E_ALS_RETURN_CFM_DEL=23, // 告警返回确认状态,且在原始告警窗已删除 + E_ALS_BAD = 100 +}; +class CAlarmMsgInfo +{ +public: + CAlarmMsgInfo(); + CAlarmMsgInfo(const CAlarmMsgInfo &other); + void initialize(const iot_idl::SAlmInfoToAlmClt &alarmInfo); + int getCameraInfoByTag(const QString &tag); + + //< [优先级越小表示越大]-原始告警窗调用 + bool lessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool moreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + //< [优先级越小表示越大]-智能告警窗调用 + bool ailessThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool aimoreThan(const AlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + + bool ailessThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool aimoreThan(const AiAlarmMsgPtr &info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + qint32 alm_type; //< 告警类型 + int alm_status; //< 告警状态 + E_ALARM_LOGICSTATE logic_state; //< 逻辑状态 + quint64 time_stamp; //< 时标(RFC1305、POSIX时标标准) + qint32 domain_id; //< 域ID + qint32 location_id; //< 位置ID + qint32 app_id; //< 应用号 + qint32 priority; //< 告警优先级id + qint32 if_water_alm; //< 是否流水账告警(0 替换式告警,1 流水账告警) + QString uuid_base64; //< uuid 主键 + QString content; //< 告警内容 + QStringList sound_file; //< 语音文件名 + //可选 + qint32 sub_system; //< 专业 + qint32 dev_type; //< 设备类型ID + qint32 region_id; //< 责任区ID + QString dev_group_tag; //< 设备组 + QString key_id_tag; //< 测点ID + QString graph_name; //< 告警关联画面名称 + QString wave_file; //< 录波画面 + //< Extend + qint32 priorityOrder; //< 优先级 + QString device; //< 设备 (保留) + bool deleteFlag; //< 是否被删除 + bool releaseFlag; //< 释放标志 + bool m_needVideoAlm; //< 是否需要视频告警 + QString m_camera; + QString m_preset; + E_TAGNAME_TYPE m_tagname_type; + + + //程序使用 + int m_playNum; // 播放次数 默认0次 + int m_alarmAction; //此告警对应的告警动作 + +}; + +bool operator==(const CAlarmMsgInfo &source, const CAlarmMsgInfo &target); + +Q_DECLARE_METATYPE(CAlarmMsgInfo) +Q_DECLARE_METATYPE(AlarmMsgPtr) + +#endif // ALARMMSGINFO_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmMsgManage.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmMsgManage.cpp new file mode 100644 index 00000000..66d2af3b --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmMsgManage.cpp @@ -0,0 +1,1896 @@ +#include "CAlarmMsgManage.h" +#include +#include +#include +#include +#include "CAlarmDataCollect.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include +#include "perm_mng_api/PermMngApi.h" + +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" +#include "Common.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CharUtil.h" +#include "pub_logger_api/logger.h" +#include "CAlarmBaseData.h" + +using namespace iot_public; +using namespace std; + +CAlarmMsgManage *CAlarmMsgManage::pInstance = NULL; +CAlarmMsgManage *CAlarmMsgManage::instance() +{ + if(pInstance == NULL) + { + pInstance = new CAlarmMsgManage(); + } + return pInstance; +} + +CAlarmMsgManage::CAlarmMsgManage() + : QObject(), + m_nNDelComAlarmCount(0), + m_nAlmNum(0), + m_nAlmTotal(0) +{ + mutex = new QMutex(); + QDir dir(QString::fromStdString(iot_public::CFileUtil::getCurModuleDir())); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + dir.cd("sound"); + m_strMediaPath = dir.absolutePath() + QDir::separator(); + + m_infos.clear(); + m_alarmDeviceStatistical.clear(); + m_alarmDeviceGroupStatistical.clear(); + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + m_listMsgAddCache.clear(); + m_inhibitFilter.clear(); + m_aiinfos.clear(); + m_aicount.clear(); + m_alarm.clear(); + m_idToid.clear(); + m_aitolocation.clear(); + //根据需求 + m_all.clear(); + m_aiall.clear(); + + m_rtdbAlarmActionAccess = new iot_dbms::CRdbAccess(); + m_rtdbAlarmActionAccess->open("base", "alarm_level_define"); + + m_rtdbLocationDescriptionAccess = new iot_dbms::CRdbAccess(); + m_rtdbLocationDescriptionAccess->open("base", "sys_model_location_info"); + + m_rtdbAppDescriptionAccess = new iot_dbms::CRdbAccess(); + m_rtdbAppDescriptionAccess->open("base", "sys_model_app_info"); + + loadPermInfo(); +} + +void CAlarmMsgManage::refreshCache() +{ + QMutexLocker locker(mutex); + m_listMsgAddCache.clear(); +} + +bool CAlarmMsgManage::ifInhibit(const QString &tag_name) +{ + QMutexLocker locker(mutex); + for(int index(0);indexkey_id_tag == tag_name) + { + return true; + } + } + return false; +} + +bool CAlarmMsgManage::isInhibit(const QString &tag_name) +{ + for(int index(0);indexkey_id_tag == tag_name) + { + return true; + } + } + return false; +} + +void CAlarmMsgManage::addInhibitAlm(const AlarmMsgPtr &info) +{ + QMutexLocker locker(mutex); + m_inhibitFilter.append(info); +} + +void CAlarmMsgManage::removeInhibitTag(const QString &tag_name) +{ + QMutexLocker locker(mutex); + for(int index(m_inhibitFilter.size()-1);index >= 0;index--) + { + if(m_inhibitFilter[index]->key_id_tag == tag_name) + { + m_inhibitFilter.removeAt(index); + } + } +} + +QMap CAlarmMsgManage::getDevAlarm(const QString &device) +{ + // QMutexLocker locker(mutex); + QMap alarm; + alarm.clear(); + return m_alarmDevPriority.value(device,alarm); +} + +QMap > CAlarmMsgManage::getDevGroupPriorityDevNum(const QString &deviceGroup) +{ + QMutexLocker locker(mutex); + QMap > alarm; + alarm.clear(); + + return m_alarmDGPDev.value(deviceGroup,alarm); +} + +QHash > CAlarmMsgManage::getLocAlmInfo() +{ + QMutexLocker locker(mutex); + return m_alarmLPAlm; +} + +void CAlarmMsgManage::updataDevGroupByDev(QString devGroup, QString device) +{ + QHash >::iterator it = m_alarmDevPriority.find(device); + int devMaxPriority =-1;//最高优先级 + if(it != m_alarmDevPriority.end()) + { + QMap::iterator itor= --it.value().end(); + + for(;itor!= --it.value().begin();itor--) + { + if(itor.value()>0) + { + devMaxPriority = itor.key(); + break; + } + } + } + QHash > >::iterator pos = m_alarmDGPDev.find(devGroup); + if(pos != m_alarmDGPDev.end()) + { + QMap > &priorityMap = pos.value(); + QMap >::iterator itor = priorityMap.begin(); + + while(itor != priorityMap.end()) { + QList &list = itor.value(); + if(list.contains(device)) + { + list.removeOne(device); + } + itor++; + } + if(devMaxPriority == -1) + return ; + itor =priorityMap.find(devMaxPriority); + if(itor != priorityMap.end()) + { + QList &devList = itor.value(); + if(!devList.contains(device)) + { + devList.append(device); + } + }else + { + QList list; + list.append(device); + priorityMap.insert(devMaxPriority,list); + } + }else + { + QList list; + list.append(device); + QMap > priorityMap; + priorityMap.insert(devMaxPriority,list); + m_alarmDGPDev.insert(devGroup,priorityMap); + } +} + +QHash > > CAlarmMsgManage::getLocNotConfirmAlmInfo() +{ + QMutexLocker locker(mutex); + return m_alarmLNCAlm; +} + +void CAlarmMsgManage::getAllInhibitAlm(QList &almList) +{ + QMutexLocker locker(mutex); + almList = m_inhibitFilter; +} + +void CAlarmMsgManage::slotLogin() +{ + QMutexLocker locker(mutex); + //emit sigClearAudioCues(); + m_playerList.clear(); + m_infos.clear(); + m_alarmDeviceStatistical.clear(); + m_alarmDeviceGroupStatistical.clear(); + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + m_listMsgAddCache.clear(); + m_inhibitFilter.clear(); + m_aiinfos.clear(); + m_aicount.clear(); + m_alarm.clear(); + m_idToid.clear(); + m_aitolocation.clear(); + + m_nNDelComAlarmCount = 0; + m_nAlmNum = 0; + m_nAlmTotal = 0; + m_alarmDevPriority.clear(); + m_alarmDGPDev.clear(); + m_alarmLPAlm.clear(); + m_delaydeal.clear(); + + //清空告警推图 + emit sigAlarmPushGraphClear(); + + loadPermInfo(); + initAlarm(); + initAiAlarm(); + + emit sigAllViewReload(); +} + +void CAlarmMsgManage::removeAiAlarmMsgByDomainID(const int &domainId) +{ + QMutexLocker locker(mutex); + /* 清除全缓存 + */ + QHash::iterator pos = m_aiall.begin(); + while(pos != m_aiall.end()) { + if(domainId == (*pos)->domain_id) + { + pos = m_aiall.erase(pos); + continue; + } + pos++; + } + /* 清除有权限和未禁止的缓存 + */ + QHash::iterator it = m_aiinfos.begin(); + while(it != m_aiinfos.end()) + { + if(domainId == (*it)->domain_id) + { + eraseaicount((*it)->uuid_base64); + eraseidtoid((*it)->uuid_base64); + eraseidtolocation((*it)->uuid_base64); + m_nAlmTotal -= (*it)->raw_alm_uuid.size(); + it = m_aiinfos.erase(it); + continue; + } + it++; + } + //清除延迟处理的智能告警 + QList::iterator itpos =m_delaydeal.begin(); + while(itpos !=m_delaydeal.end()) { + if(domainId == (*itpos)->domain_id) + { + + itpos = m_delaydeal.erase(itpos); + continue; + } + itpos++; + } +} + +void CAlarmMsgManage::addAiAllAlarmMsg(const QList &msgList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = msgList.begin(); + while(itpos != msgList.end()) { + m_aiall.insert((*itpos)->uuid_base64,*itpos); + QVector uuidVec = (*itpos)->raw_alm_uuid; + addidtoid(uuidVec,(*itpos)->uuid_base64); //记录原始告警uuid和智能告警uuid键值对 ,一直到release + QVector deluuidVec; + updatealarm(uuidVec,deluuidVec);//不可删除 //更新智能告警窗上的未聚类的原始告警,防止由于先后顺序导致显示出错 + if((*itpos)->deleteFlag || (*itpos)->brokenFlag) + { + itpos++; + continue; + } + //检查此智能告警下的原始告警是否完整 + //若完整则继续执行 + //不完整(此处指的是智能告警先到,原始告警未到的情况,并非告警服务通知的不完整)则延时处理 ,延时处理的不需要调用addidtoid()和updatealarm() + QList almInfoList;// 智能告警下的原始告警指针,检查完整性的时候获取,后面就不用再取了,提高性能 + if(!isHaveAlm(uuidVec,almInfoList)) + { + m_delaydeal.append(*itpos); //延后处理 + itpos++; + continue; + } + QHash::iterator it = m_all.find((*itpos)->main_uuid_base64); + if(it != m_all.end()) + { + (*itpos)->main_state = (*it)->logic_state; + } + //检查是否具有权限 + if(checkLookPerm(almInfoList)) + { + addaicount(almInfoList,(*itpos)->uuid_base64); + addaitolocation(almInfoList,(*itpos)->uuid_base64); + initaivideo(*itpos); + m_nAlmTotal += (*itpos)->raw_alm_uuid.size(); + m_aiinfos.insert((*itpos)->uuid_base64,*itpos); + } + itpos++; + } +} + +void CAlarmMsgManage::addAiAlarmMsg(const QList &msgList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = msgList.begin(); + QVector deluuidVec; + QList aiMsgList; + while(itpos != msgList.end()) { + m_aiall.insert((*itpos)->uuid_base64,*itpos); + QVector uuidVec = (*itpos)->raw_alm_uuid; + addidtoid(uuidVec,(*itpos)->uuid_base64); + updatealarm(uuidVec,deluuidVec); + if((*itpos)->deleteFlag || (*itpos)->brokenFlag) + { + itpos++; + continue; + } + QList almInfoList;// 智能告警下的原始告警指针,检查完整性的时候获取,后面就不用再取了,提高性能 + if(!isHaveAlm(uuidVec,almInfoList)) + { + m_delaydeal.append(*itpos); //延后处理 + itpos++; + continue; + } + QHash::iterator it = m_all.find((*itpos)->main_uuid_base64); + if(it != m_all.end()) + { + (*itpos)->main_state = (*it)->logic_state; + } + if(checkLookPerm(almInfoList)) + { + addaicount(almInfoList,(*itpos)->uuid_base64); + addaitolocation(almInfoList,(*itpos)->uuid_base64); + initaivideo(*itpos); + m_nAlmTotal += (*itpos)->raw_alm_uuid.size(); + m_aiinfos.insert((*itpos)->uuid_base64,*itpos); + aiMsgList.append(*itpos); + } + itpos++; + } + if(deluuidVec.size()>0) + { + emit sigMsgRemove(deluuidVec); + } + if(aiMsgList.size()>0) + { + emit sigAiMsgAdd(aiMsgList); + } +} + +void CAlarmMsgManage::delAiAlarmMsg(const QList &uuidList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = uuidList.begin(); + QList aiuuidList; + while (itpos != uuidList.end()) { + QString aiuuid = *itpos; + //先在有权限的里面找,若有则不用去全部里面找 + QHash::iterator itinfos = m_aiinfos.find(aiuuid); + if(itinfos != m_aiinfos.end()) + { + m_nAlmTotal -= itinfos.value()->raw_alm_uuid.size(); + itinfos.value()->deleteFlag = true; + m_aiinfos.erase(itinfos); + aiuuidList.append(aiuuid); + }else + { + QHash::iterator itall = m_aiall.find(aiuuid); + if(itall != m_aiall.end()) + { + itall.value()->deleteFlag = true; + } + } + + //清除延迟处理的智能告警 + QList::iterator pos =m_delaydeal.begin(); + while(pos !=m_delaydeal.end()) { + if(aiuuid == (*pos)->uuid_base64) + { + pos = m_delaydeal.erase(pos); + break; + } + pos++; + } + itpos++; + } + if(aiuuidList.size()>0) + { + emit sigAiMsgRemove(aiuuidList); + } +} + +void CAlarmMsgManage::brokenAiAlarmMsg(const QList &uuidList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = uuidList.begin(); + QList aiuuidList; + while(itpos != uuidList.end()) + { + QString aiuuid = *itpos; + //先在有权限的告警中找 + QHash::iterator itinfos = m_aiinfos.find(aiuuid); + if(itinfos != m_aiinfos.end()) + { + m_nAlmTotal -= itinfos.value()->raw_alm_uuid.size(); + itinfos.value()->brokenFlag = true; + m_aiinfos.erase(itinfos); + aiuuidList.append(aiuuid); + }else + { + QHash::iterator itall = m_aiall.find(aiuuid); + if(itall != m_aiall.end()) + { + itall.value()->brokenFlag = true; + } + } + + //清除延迟处理的智能告警 + QList::iterator pos =m_delaydeal.begin(); + while(pos !=m_delaydeal.end()) { + if(aiuuid == (*pos)->uuid_base64) + { + pos = m_delaydeal.erase(pos); + break; + } + pos++; + } + itpos++; + } + if(aiuuidList.size()>0) + { + emit sigAiMsgRemove(aiuuidList); + } +} + +void CAlarmMsgManage::releaseAiAlarmMsg(const QList &uuidList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = uuidList.begin(); + QList aiuuidList; + QList m_listMsg; + while (itpos != uuidList.end()) { + QString aiuuid = *itpos; + QVector uuidVec; + QHash::iterator itinfos = m_aiinfos.find(aiuuid); + if(itinfos != m_aiinfos.end()) + { + uuidVec = itinfos.value()->raw_alm_uuid; + m_nAlmTotal -= uuidVec.size(); + for(int index(0);indexdeleteFlag == true || almPtr->releaseFlag == true) + { + continue; + } + + if(!m_listPermLocationId.contains(almPtr->location_id) || (!m_listPermRegionId.contains(almPtr->region_id) && almPtr->region_id != -1)) + { + continue; + } + + if(isInhibit(almPtr->key_id_tag)) + { + continue; + } + m_alarm.insert(almPtr->uuid_base64,almPtr); + m_listMsg.append(almPtr); + } + m_aiinfos.erase(itinfos); + aiuuidList.append(aiuuid); + } + + QHash::iterator itall = m_aiall.find(aiuuid); + if(itall != m_aiall.end()) + { + eraseaicount(aiuuid); + eraseidtoid(aiuuid); + eraseidtolocation(aiuuid); + m_aiall.erase(itall); + } + + //清除延迟处理的智能告警 + QList::iterator pos =m_delaydeal.begin(); + while (pos !=m_delaydeal.end()) { + if(aiuuid == (*pos)->uuid_base64) + { + pos = m_delaydeal.erase(pos); + break; + } + pos++; + } + itpos++; + } + if(aiuuidList.size()>0) + { + emit sigAiMsgRemove(aiuuidList); + } + + if(m_listMsg.size() > 0) + { + emit sigMsgArrivedToAi(m_listMsg); + } +} + +bool CAlarmMsgManage::getAiuuid(const QString &uuid, QString &aiuuid) +{ + QMutexLocker locker(mutex); + aiuuid = m_idToid.value(uuid,""); + if(aiuuid.isEmpty()) + { + return false; + } + return true; +} + +bool CAlarmMsgManage::isBelongAi(const QString &uuid) +{ + QMutexLocker locker(mutex); + if(m_idToid.value(uuid,"").isEmpty()) + { + return false; + } + return true; +} + +AlarmMsgPtr CAlarmMsgManage::getOnePlayerAlm(int num) +{ + QMutexLocker locker(mutex); + QList::iterator it = m_playerList.begin(); + + QStringList strAudioFileNames; + while (it != m_playerList.end()) { + strAudioFileNames.clear(); + if((*it)->deleteFlag || (*it)->releaseFlag) + { + it = m_playerList.erase(it); + }else if(ALM_ACT_SOUND != ((*it)->m_alarmAction & ALM_ACT_SOUND)) + { + it = m_playerList.erase(it); + }else + { + strAudioFileNames = (*it)->sound_file; + if(strAudioFileNames.isEmpty()) + { + it = m_playerList.erase(it); + }else if(num >= 0 && (*it)->m_playNum >= num) + { + strAudioFileNames.clear(); + it = m_playerList.erase(it); + }else + { + int fileNum = 0; + foreach (QString fileName, strAudioFileNames) + { + if(!fileName.isEmpty()) + { + fileName = m_strMediaPath + fileName; + if(QFile::exists(fileName)) + { + fileNum++; + } + } + } + if(fileNum == 0) + { + it = m_playerList.erase(it); + }else if(num < 0) + { + return *it; + }else + { + (*it)->m_playNum++; + return *it; + } + } + } + } + return Q_NULLPTR; +} + +AlarmMsgPtr CAlarmMsgManage::getOneSpeechAlm(int num) +{ + QMutexLocker locker(mutex); + QList::iterator it = m_playerList.begin(); + + QString alarmContent; + while (it != m_playerList.end()) { + alarmContent = QString(); + if((*it)->deleteFlag || (*it)->releaseFlag) + { + it = m_playerList.erase(it); + }else if(ALM_ACT_VOICE != ((*it)->m_alarmAction & ALM_ACT_VOICE)) + { + it = m_playerList.erase(it); + }else + { + alarmContent = (*it)->content; + if(alarmContent.isEmpty()) + { + it = m_playerList.erase(it); + }else if(num >= 0 && (*it)->m_playNum >= num) + { + alarmContent.clear(); + it = m_playerList.erase(it); + }else if(num < 0) + { + return *it; + }else + { + (*it)->m_playNum++; + return *it; + } + } + } + return Q_NULLPTR; +} + +void CAlarmMsgManage::eraseaicount(const QString &aiuuid) +{ + QHash::iterator it = m_aicount.find(aiuuid); + if(it != m_aicount.end()) + { + m_aicount.erase(it); + } +} + +void CAlarmMsgManage::eraseidtoid(const QString &aiuuid) +{ + QHash::iterator it = m_idToid.begin(); + + while (it != m_idToid.end()) { + if(aiuuid == it.value()) + { + it = m_idToid.erase(it); + continue; + } + it++; + } +} + +void CAlarmMsgManage::eraseidtolocation(const QString &aiuuid) +{ + QHash >::iterator it = m_aitolocation.find(aiuuid); + if(it != m_aitolocation.end()) + { + m_aitolocation.erase(it); + } +} + +bool CAlarmMsgManage::isHaveAlm(const QVector &uuidVec, QList &almInfoList) +{ + for(int x(0);x < uuidVec.count(); x++) + { + QHash::iterator it = m_all.find(uuidVec.at(x)); + if(it == m_all.end()) + { + return false; + } + almInfoList.append(*it); + } + return true; +} + +bool CAlarmMsgManage::checkLookPerm(const QList &almInfoList) +{ + QList::const_iterator it = almInfoList.begin(); + while (it != almInfoList.end()) { + qint32 location_id = (*it)->location_id; + qint32 region_id = (*it)->region_id; + if(m_listPermLocationId.contains(location_id) && (m_listPermRegionId.contains(region_id) || region_id == -1)) + { + return true; + } + it++; + } + return false; +} + +void CAlarmMsgManage::addidtoid(const QVector &uuidVec,const QString &aiuuid) +{ + for(int x(0);x < uuidVec.count();x++) + { + m_idToid[uuidVec.value(x)] = aiuuid; + } +} + +void CAlarmMsgManage::addaicount(const QList &almInfoList,const QString &aiuuid) +{ + int confirm = 0; + QList::const_iterator it = almInfoList.begin(); + while (it != almInfoList.end()) { + + if((*it)->logic_state == E_ALS_ALARM_CFM || (*it)->logic_state == E_ALS_RETURN_CFM || + (*it)->logic_state == E_ALS_ALARM_CFM_DEL || (*it)->logic_state == E_ALS_RETURN_CFM_DEL || (*it)->logic_state == ALS_EVT_ONLY) + { + confirm++; + } + it++; + } + SAiConfirm aiConfirm; + aiConfirm.nConfirm = confirm; + aiConfirm.nTotal = almInfoList.size(); + m_aicount.insert(aiuuid,aiConfirm); +} + +void CAlarmMsgManage::addaitolocation(const QList &almInfoList,const QString &aiuuid) +{ + QHash >::iterator it =m_aitolocation.find(aiuuid); + if(it != m_aitolocation.end()) + { + m_aitolocation.erase(it); + } + QList locationList; + QList::const_iterator pos = almInfoList.begin(); + while (pos != almInfoList.end()) { + if(!locationList.contains((*pos)->location_id)) + { + locationList.append((*pos)->location_id); + } + pos++; + } + m_aitolocation.insert(aiuuid,locationList); +} + +void CAlarmMsgManage::initaivideo(AiAlarmMsgPtr msg) +{ + AlarmMsgPtr ptr = m_all.value(msg->main_uuid_base64,NULL); + if(ptr != NULL) + { + msg->m_needVideoAlm = ptr->m_needVideoAlm; + msg->app_id = ptr->app_id; + msg->key_id_tag = ptr->key_id_tag; + msg->m_tagname_type = ptr->m_tagname_type; + } +} + +//<添加智能告警时,需要删除此条智能告警下还存在一级节点上的原始告警 +void CAlarmMsgManage::updatealarm(QVector &uuidVec,QVector &deluuidVec) +{ + for(int index(0);index::iterator it =m_alarm.find(uuidVec.at(index)); + if(it != m_alarm.end()) + { + m_alarm.remove(uuidVec.at(index)); + deluuidVec.append(uuidVec.at(index)); + } + } +} + +void CAlarmMsgManage::almStats(const AlarmMsgPtr &msg, int addOrSub) +{ + if(addOrSub == 1) + { + almAddStats(msg); + }else + { + almSubStats(msg); + } +} + +void CAlarmMsgManage::almAddStats(const AlarmMsgPtr &msg) +{ + devDevGTotAlmAddStats(msg); + devDevGAddStats(msg); + locAddStats(msg); +} + +void CAlarmMsgManage::almSubStats(const AlarmMsgPtr &msg) +{ + devDevGTotAlmSubStats(msg); + devDevGSubStats(msg); + locSubStats(msg); +} + +void CAlarmMsgManage::devDevGTotAlmAddStats(const AlarmMsgPtr &msg) +{ + + int dCount = m_alarmDeviceStatistical.value(msg->device, 0);//设备告警数量 + int dgCount = m_alarmDeviceGroupStatistical.value(msg->dev_group_tag,0);//设备组告警数量 + + ++dgCount; // +1 + ++dCount; // +1 + + if(dCount <= 0) + { + m_alarmDeviceStatistical.remove(msg->device); + } + else + { + m_alarmDeviceStatistical.insert(msg->device, dCount); + } + if(dgCount <= 0) + { + m_alarmDeviceGroupStatistical.remove(msg->dev_group_tag); + } + else + { + m_alarmDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); + } +} + +void CAlarmMsgManage::devDevGTotAlmSubStats(const AlarmMsgPtr &msg) +{ + int dCount = m_alarmDeviceStatistical.value(msg->device, 0); //设备告警数量 + int dgCount = m_alarmDeviceGroupStatistical.value(msg->dev_group_tag,0);//设备组告警数量 + + --dgCount; + --dCount; + + if(dCount <= 0) + { + m_alarmDeviceStatistical.remove(msg->device); + } + else + { + m_alarmDeviceStatistical.insert(msg->device, dCount); + } + if(dgCount <= 0) + { + m_alarmDeviceGroupStatistical.remove(msg->dev_group_tag); + } + else + { + m_alarmDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); + } +} + +void CAlarmMsgManage::devDevGAddStats(const AlarmMsgPtr &msg) +{ + QHash >::iterator posit = m_alarmDevPriority.find(msg->device); + if(posit != m_alarmDevPriority.end()) + { + QMap &priority = posit.value(); + QMap::iterator itor =priority.find(msg->priority); + if(itor != priority.end()) + itor.value()++; + else + priority.insert(msg->priority,1); + }else + { + QMap priority; + priority.insert(msg->priority,1); + m_alarmDevPriority.insert(msg->device,priority); + } + updataDevGroupByDev(msg->dev_group_tag,msg->device); +} + +void CAlarmMsgManage::devDevGSubStats(const AlarmMsgPtr &msg) +{ + QHash >::iterator posit = m_alarmDevPriority.find(msg->device); + if(posit != m_alarmDevPriority.end()) + { + QMap &priority = posit.value(); + QMap::iterator itor =priority.find(msg->priority); + if(itor != priority.end()) + itor.value()--; + } + updataDevGroupByDev(msg->dev_group_tag,msg->device); +} + +void CAlarmMsgManage::locAddStats(const AlarmMsgPtr &msg) +{ + QHash >::iterator posit =m_alarmLPAlm.find(msg->location_id); + if(posit != m_alarmLPAlm.end()) + { + QMap &priority = posit.value(); + QMap::iterator itor =priority.find(msg->priority); + if(itor != priority.end()) + itor.value()++; + else + priority.insert(msg->priority,1); + }else + { + QMap priority; + priority.insert(msg->priority,1); + m_alarmLPAlm.insert(msg->location_id,priority); + } +} + +void CAlarmMsgManage::locSubStats(const AlarmMsgPtr &msg) +{ + QHash >::iterator posit =m_alarmLPAlm.find(msg->location_id); + if(posit != m_alarmLPAlm.end()) + { + QMap &priority = posit.value(); + QMap::iterator itor =priority.find(msg->priority); + if(itor != priority.end()) + { + itor.value()--; + } + } +} + +void CAlarmMsgManage::addNotConfirmAlm(int locId, const QString &devg, const QString &uuid) +{ + QHash > >::iterator it =m_alarmLNCAlm.find(locId); + if(it != m_alarmLNCAlm.end()) + { + QMap > &devgMap = it.value(); + QMap >::iterator pos = devgMap.find(devg); + if(pos != devgMap.end()) + { + pos.value().insert(uuid); + }else + { + QSet uuidSet; + uuidSet.insert(uuid); + devgMap[devg] = uuidSet; + } + }else + { + QMap > devgMap; + QSet uuidSet; + uuidSet.insert(uuid); + devgMap[devg] = uuidSet; + m_alarmLNCAlm[locId] = devgMap; + } +} + +void CAlarmMsgManage::delNotConfirmAlm(int locId, const QString &devg, const QString &uuid) +{ + QHash > >::iterator it =m_alarmLNCAlm.find(locId); + if(it != m_alarmLNCAlm.end()) + { + QMap > &devgMap = it.value(); + QMap >::iterator pos = devgMap.find(devg); + if(pos != devgMap.end()) + { + pos.value().remove(uuid); + } + } +} + +QString CAlarmMsgManage::queryLocationDesc(QString &aiuuid) +{ + QMutexLocker locker(mutex); + QString desc = QString(); + QList listLocationId = m_aitolocation.value(aiuuid); + for(int index(0);indexqueryLocationDesc(listLocationId.at(index)); + desc +=" "; + } + return desc; +} + +QString CAlarmMsgManage::queryConfirm(const QString &aiuuid) +{ + QMutexLocker locker(mutex); + SAiConfirm confirm = m_aicount.value(aiuuid); + QString st = QString("%1/%2").arg(confirm.nConfirm).arg(confirm.nTotal); + return st; +} + +int CAlarmMsgManage::queryAiTotal(const QString &aiuuid) +{ + QMutexLocker locker(mutex); + SAiConfirm confirm = m_aicount.value(aiuuid); + return confirm.nTotal; +} + +void CAlarmMsgManage::getAlarmInfo(QList &listAlarm, QList &listaiAlarm) +{ + QMutexLocker locker(mutex); + listAlarm = m_alarm.values(); + listaiAlarm = m_aiinfos.values(); +} + +QList CAlarmMsgManage::getAlarmPtrByuuid(const QVector &uuidVec) +{ + QMutexLocker locker(mutex); + QList list; + for(int index(0);index CAlarmMsgManage::getalmuuidByAiuuid(const QString &aiuuid) +{ + QList uuidList; + QHash::iterator it = m_idToid.begin(); + while(it != m_idToid.end()) { + if(it.value() == aiuuid) + { + uuidList.append(it.key()); + } + it++; + } + return uuidList; +} + +int CAlarmMsgManage::getAlmTotal() +{ + QMutexLocker locker(mutex); + return m_nAlmTotal + m_alarm.size(); +} + +int CAlarmMsgManage::getAiCount() +{ + QMutexLocker locker(mutex); + return m_aiinfos.size(); +} + +void CAlarmMsgManage::initAlarm() +{ + QHash::const_iterator itpos = m_all.begin(); + while (itpos != m_all.end()) { + + if(isInhibit((*itpos)->key_id_tag)) + { + itpos++; + continue; + } + if(!m_listPermLocationId.contains((*itpos)->location_id) || (!m_listPermRegionId.contains((*itpos)->region_id) && (*itpos)->region_id != -1)) + { + itpos++; + continue ; + } + if((*itpos)->deleteFlag == true || (*itpos)->releaseFlag == true) //已经删除的不会保存到中 + { + itpos++; + continue ; + } + + if(E_ALS_ALARM == (*itpos)->logic_state || E_ALS_RETURN == (*itpos)->logic_state )//未确认数量(界面显示未确认) + { + addNotConfirmAlm((*itpos)->location_id,(*itpos)->dev_group_tag,(*itpos)->uuid_base64); + ++m_nNDelComAlarmCount; + } + updateMsgAction((*itpos)); + m_infos.insert((*itpos)->uuid_base64, (*itpos)); + //更新告警统计 + almStats((*itpos),1); + //更新未聚类但是需要展示的原始告警 + QHash::iterator it = m_idToid.find((*itpos)->uuid_base64); + if(it == m_idToid.end()) + { + m_alarm.insert((*itpos)->uuid_base64,(*itpos)); + } + itpos++; + } +} + +void CAlarmMsgManage::initAiAlarm() +{ + QHash::const_iterator itpos = m_aiall.begin(); + while(itpos != m_aiall.end()) + { + QVector uuidVec = (*itpos)->raw_alm_uuid; + addidtoid(uuidVec,(*itpos)->uuid_base64); //记录原始告警uuid和智能告警uuid键值对 ,一直到release + QVector deluuidVec; + updatealarm(uuidVec,deluuidVec);//不可删除 //更新智能告警窗上的未聚类的原始告警,防止由于先后顺序导致显示出错 + if((*itpos)->deleteFlag || (*itpos)->brokenFlag) + { + itpos++; + continue; + } + //检查此智能告警下的原始告警是否完整 + //若完整则继续执行 + //不完整(此处指的是智能告警先到,原始告警未到的情况,并非告警服务通知的不完整)则延时处理 ,延时处理的不需要调用addidtoid()和updatealarm() + QList almInfoList;// 智能告警下的原始告警指针,检查完整性的时候获取,后面就不用再取了,提高性能 + if(!isHaveAlm(uuidVec,almInfoList)) + { + m_delaydeal.append(*itpos); //延后处理 + itpos++; + continue; + } + //检查是否具有权限 + if(checkLookPerm(almInfoList)) + { + addaicount(almInfoList,(*itpos)->uuid_base64); + addaitolocation(almInfoList,(*itpos)->uuid_base64); + initaivideo(*itpos); + m_nAlmTotal += (*itpos)->raw_alm_uuid.size(); + m_aiinfos.insert((*itpos)->uuid_base64,*itpos); + } + itpos++; + } +} + +void CAlarmMsgManage::insertAudioCues(const AlarmMsgPtr &info) +{ + bool insertResult = false; + //LOGDEBUG("insertAudioCues %s",info->content.toStdString().c_str()); + if(!m_playerList.isEmpty()) + { + for(int nIndex(m_playerList.size() - 1); nIndex >= 0; --nIndex) + { + if(info->priorityOrder > m_playerList[nIndex]->priorityOrder) + { + m_playerList.insert(nIndex + 1, info); + insertResult = true; + break; + } + } + } + if(!insertResult) + { + if(m_playerList.isEmpty()) + { + m_playerList.append(info); + } + else + { + m_playerList.prepend(info); + } + } + if(m_playerList.count() >= MAX_AUDIO_ALM_COUNT) + { + m_playerList.removeLast(); + } +} + +void CAlarmMsgManage::removeAudioCues(const AlarmMsgPtr &info) +{ + QList::iterator it = m_playerList.begin(); + while (it != m_playerList.end()) + { + if(info->uuid_base64 == (*it)->uuid_base64) + { + m_playerList.erase(it); + break; + } + ++it; + } +} + +void CAlarmMsgManage::setReadFlag() +{ + if(!m_playerList.isEmpty()) + { + emit sigReadFlag(); + } +} + +CAlarmMsgManage::~CAlarmMsgManage() +{ + LOGDEBUG("CAlarmMsgManage::~CAlarmMsgManage()"); +} + +void CAlarmMsgManage::destory() +{ + { + QMutexLocker locker(mutex); + m_infos.clear(); + m_all.clear(); + m_alarmDeviceStatistical.clear(); + m_alarmDeviceGroupStatistical.clear(); + delete m_rtdbAlarmActionAccess; + delete m_rtdbLocationDescriptionAccess; + delete m_rtdbAppDescriptionAccess; + } + delete mutex; + pInstance = NULL; + + deleteLater(); +} + +void CAlarmMsgManage::initialize() +{ + release(); +} + +void CAlarmMsgManage::release() +{ + QMutexLocker locker(mutex); + m_infos.clear(); + m_alarmDeviceStatistical.clear(); + m_alarmDeviceGroupStatistical.clear(); + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + m_listMsgAddCache.clear(); + m_inhibitFilter.clear(); + m_aiinfos.clear(); + m_aicount.clear(); + m_alarm.clear(); + m_idToid.clear(); + m_aitolocation.clear(); + //根据需求 + m_all.clear(); + m_aiall.clear(); + + m_nNDelComAlarmCount = 0; + m_nAlmNum = 0; + m_nAlmTotal = 0; + m_alarmDevPriority.clear(); + m_alarmDGPDev.clear(); + m_alarmLPAlm.clear(); + m_delaydeal.clear(); + m_playerList.clear(); + loadPermInfo(); +} + +QList CAlarmMsgManage::getListAlarmInfo() +{ + //不需要清空1秒缓存 + QMutexLocker locker(mutex); + return m_infos.values(); +} + +QHash CAlarmMsgManage::getDeviceStatisticalInfo() +{ + QMutexLocker locker(mutex); + + return m_alarmDeviceGroupStatistical; +} + +int CAlarmMsgManage::deviceGroupAlarmStatistical(const QString &deviceGroup) +{ + QMutexLocker locker(mutex); + if(deviceGroup.isEmpty()) + { + return 0; + } + return m_alarmDeviceGroupStatistical.value(deviceGroup, 0); +} + +int CAlarmMsgManage::getAlarmTotalSize() +{ + QMutexLocker locker(mutex); + return m_infos.size(); +} + +int CAlarmMsgManage::getUnConfirmSize() +{ + QMutexLocker locker(mutex); + return m_nNDelComAlarmCount; +} + +void CAlarmMsgManage::output() +{ + QMutexLocker locker(mutex); + LOGDEBUG("内存告警数量展示:所有原始告警:%d,所有展示的原始告警:%d,所有智能告警:%d,所有展示的智能告警:%d,所有未聚合的原始告警:%d",m_all.size(),m_infos.size(),m_aiall.size(),m_aiinfos.size(),m_alarm.size()); +} + + +void CAlarmMsgManage::addAlarmMsg(const QList &msgList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = msgList.begin(); + while (itpos != msgList.end()) { + m_all.insert((*itpos)->uuid_base64,(*itpos)); + if(isInhibit((*itpos)->key_id_tag)) + { + itpos++; + continue; + } + if(!m_listPermLocationId.contains((*itpos)->location_id) || (!m_listPermRegionId.contains((*itpos)->region_id) && (*itpos)->region_id != -1)) + { + itpos++; + continue ; + } + if((*itpos)->deleteFlag == true || (*itpos)->releaseFlag == true) //已经删除的不会保存到中 + { + itpos++; + continue ; + } + if(E_ALS_ALARM == (*itpos)->logic_state || E_ALS_RETURN == (*itpos)->logic_state )//未确认数量(界面显示未确认) + { + addNotConfirmAlm((*itpos)->location_id,(*itpos)->dev_group_tag,(*itpos)->uuid_base64); + ++m_nNDelComAlarmCount; + } + updateMsgAction(*itpos); + m_infos.insert((*itpos)->uuid_base64, (*itpos)); + //更新告警统计 + almStats((*itpos),1); + //更新未聚类但是需要展示的原始告警 + QHash::iterator it = m_idToid.find((*itpos)->uuid_base64); + if(it == m_idToid.end()) + { + m_alarm.insert((*itpos)->uuid_base64,(*itpos)); + } + itpos++; + } + //设置标志可读 + setReadFlag(); +} + + +void CAlarmMsgManage::addAlarmToAllInfo(const QList &msgList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = msgList.begin(); + while (itpos != msgList.end()) { + m_all.insert((*itpos)->uuid_base64,(*itpos)); + itpos++; + } + +} + +void CAlarmMsgManage::addAlarmCacheMsg(const QList &msgList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = msgList.begin(); + while (itpos != msgList.end()) { + if(isInhibit((*itpos)->key_id_tag)) + { + itpos++; + continue; + } + if(!m_listPermLocationId.contains((*itpos)->location_id) || (!m_listPermRegionId.contains((*itpos)->region_id) && (*itpos)->region_id != -1)) + { + itpos++; + continue ; + } + if((*itpos)->deleteFlag == true) + { + itpos++; + continue ; + } + m_listMsgAddCache.append(*itpos); + itpos++; + } +} +//不用考虑事件 因为事件不会发送过来 默认事件是已确认已删除状态 +void CAlarmMsgManage::confirmAlarmMsg(const QList &uuidList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = uuidList.begin(); + while (itpos != uuidList.end()) { + QString uuid = *itpos; + AlarmMsgPtr oldMsg = m_infos.value(uuid, NULL); + if(!oldMsg.isNull()) + { + removeAudioCues(oldMsg); + if(E_ALS_ALARM == oldMsg->logic_state) + { + oldMsg->logic_state = E_ALS_ALARM_CFM; + --m_nNDelComAlarmCount; + } + else if(E_ALS_RETURN == oldMsg->logic_state) + { + oldMsg->logic_state = E_ALS_RETURN_CFM; + --m_nNDelComAlarmCount; + } + delNotConfirmAlm(oldMsg->location_id,oldMsg->dev_group_tag,oldMsg->uuid_base64); + }else + { + AlarmMsgPtr oldMsg_ = m_all.value(uuid, NULL); + if(!oldMsg_.isNull()) + { + if(E_ALS_ALARM == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_ALARM_CFM; + } + else if(E_ALS_RETURN == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_RETURN_CFM; + } + else if(E_ALS_ALARM_DEL == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_ALARM_CFM_DEL; + } + else if(E_ALS_RETURN_DEL == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_RETURN_CFM_DEL; + } + } + } + //确认告警时更新告警确认数量(性能优化:事实证明,当数据量很大时,使用迭代器的效率是contains()的几十倍,随着数据量的增大倍数增大----数据很少可以忽略) + QHash::iterator it = m_idToid.find(uuid); + if(it != m_idToid.end()) + { + QString aiuuid = m_idToid.value(uuid); + SAiConfirm confirm = m_aicount.value(aiuuid); + confirm.nConfirm++; + m_aicount[aiuuid]=confirm; + } + itpos++; + } + //设置标志可读 + setReadFlag(); +} + +int CAlarmMsgManage::removeAlarmMsg(const QList &uuidList) +{ + QMutexLocker locker(mutex); + int size = 0;//删除的个数 + QVector deluuidVec; + QList::const_iterator itpos = uuidList.begin(); + while (itpos != uuidList.end()) { + QString uuid = *itpos; + AlarmMsgPtr oldMsg = m_infos.value(uuid, NULL); + if(!oldMsg.isNull()) + { + if(oldMsg->deleteFlag) + { + itpos++; + continue; + } + if(E_ALS_ALARM == oldMsg->logic_state) + { + delNotConfirmAlm(oldMsg->location_id,oldMsg->dev_group_tag,oldMsg->uuid_base64); + --m_nNDelComAlarmCount; + oldMsg->logic_state = E_ALS_ALARM_DEL; + } + else if(E_ALS_ALARM_CFM == oldMsg->logic_state) + { + oldMsg->logic_state = E_ALS_ALARM_CFM_DEL; + } + else if(E_ALS_RETURN == oldMsg->logic_state) + { + delNotConfirmAlm(oldMsg->location_id,oldMsg->dev_group_tag,oldMsg->uuid_base64); + --m_nNDelComAlarmCount; + oldMsg->logic_state = E_ALS_RETURN_DEL; + } + else if(E_ALS_RETURN_CFM == oldMsg->logic_state) + { + oldMsg->logic_state = E_ALS_RETURN_CFM_DEL; + } + + oldMsg->deleteFlag = true; + almStats(oldMsg,0); + m_infos.remove(uuid); + size++; + }else + { + AlarmMsgPtr oldMsg_ = m_all.value(uuid, NULL); + if(!oldMsg_.isNull()) + { + if(oldMsg_->deleteFlag) + { + itpos++; + continue; + } + if(E_ALS_ALARM == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_ALARM_DEL; + } + else if(E_ALS_ALARM_CFM == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_ALARM_CFM_DEL; + } + else if(E_ALS_RETURN == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_RETURN_DEL; + } + else if(E_ALS_RETURN_CFM == oldMsg_->logic_state) + { + oldMsg_->logic_state = E_ALS_RETURN_CFM_DEL; + } + oldMsg_->deleteFlag = true; + } + } + //从m_alarm中删除未聚类但有删除标志的告警 + QHash::iterator it = m_alarm.find(uuid); + if(it != m_alarm.end()) + { + m_alarm.erase(it); + deluuidVec.push_back(uuid); + } + itpos++; + } + if(deluuidVec.size()>0) + { + emit sigMsgRemove(deluuidVec);//通知智能告警模型删除1级节点上的未聚类原始告警 + } + //设置标志可读 + setReadFlag(); + return size; +} + +void CAlarmMsgManage::releaseAlarmMsg(const QList &uuidList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = uuidList.begin(); + while (itpos != uuidList.end()) { + QString uuid = *itpos; + AlarmMsgPtr oldMsg = m_all.value(uuid, NULL); + if(!oldMsg.isNull()) + { + oldMsg->releaseFlag =true; + m_all.remove(uuid); + } + itpos++; + } + //设置标志可读 + setReadFlag(); +} + +void CAlarmMsgManage::linkWave2AlmMsg(const QList &uuidList, const QString &waveFile) +{ + QMutexLocker locker(mutex); + for(int index(0);index::iterator it = m_all.find(uuidList.at(index)); + if(it != m_all.end()) + { + (*it)->wave_file = waveFile; + }else + { + LOGERROR("linkWave2AlmMsg()未找到uuid为[%s]的告警,链接录波文件为:[%s],请自主查看!",uuidList.at(index).toStdString().c_str(),waveFile.toStdString().c_str()); + } + } +} + +void CAlarmMsgManage::removeAlarmMsgByDomainID(const int &domainId) +{ + QMutexLocker locker(mutex); + /* 清除全缓存 + */ + QHash::iterator pos = m_all.begin(); + while (pos != m_all.end()) { + if(domainId == (*pos)->domain_id) + { + pos = m_all.erase(pos); + continue; + } + pos++; + } + /* 清除有权限和未禁止的缓存 + */ + QHash::iterator it = m_infos.begin(); + while (it != m_infos.end()) + { + if(domainId == (*it)->domain_id) + { + if(E_ALS_ALARM == (*it)->logic_state || E_ALS_RETURN == (*it)->logic_state) + { + delNotConfirmAlm((*it)->location_id,(*it)->dev_group_tag,(*it)->uuid_base64); + --m_nNDelComAlarmCount; + } + removeAudioCues(it.value()); + almStats((*it),0); + it = m_infos.erase(it); + continue; + } + it++; + } + //清空告警缓存(每秒更新) + QList::iterator itpos =m_listMsgAddCache.begin(); + while (itpos != m_listMsgAddCache.end()) { + if((*itpos)->domain_id == domainId) + { + itpos =m_listMsgAddCache.erase(itpos); + continue; + } + itpos++; + } + + //清空 有权限/未禁止/未聚类的原始告警(需要展示在智能告警窗) + QHash::iterator itor = m_alarm.begin(); + while(itor != m_alarm.end()) + { + if(domainId == (*itor)->domain_id) + { + itor = m_alarm.erase(itor); + continue; + } + itor++; + } +} + +void CAlarmMsgManage::updateMsgAction(const QList &msgList) +{ + QMutexLocker locker(mutex); + QList::const_iterator itpos = msgList.begin(); + while (itpos != msgList.end()) { + if(isInhibit((*itpos)->key_id_tag)) + { + itpos++; + continue ; + } + if(!m_listPermLocationId.contains((*itpos)->location_id) || (!m_listPermRegionId.contains((*itpos)->region_id) && (*itpos)->region_id != -1)) + { + itpos++; + continue ; + } + if((*itpos)->deleteFlag || (*itpos)->releaseFlag) + { + itpos++; + continue ; + } + if((*itpos)->logic_state == E_ALS_ALARM || (*itpos)->logic_state == E_ALS_RETURN) + { + int alarmAction = queryAlarmAction((*itpos)->priority); + (*itpos)->m_alarmAction = alarmAction; + if(ALM_ACT_PUSH_PIC == (alarmAction & ALM_ACT_PUSH_PIC) && !(*itpos)->graph_name.isEmpty()) + { + //第1位,推画面 + QString alarmInfo; + //< 等级 + alarmInfo.append(QString::number((*itpos)->priorityOrder) + QString(",")); + //< 时间 + alarmInfo.append(QDateTime::fromMSecsSinceEpoch((*itpos)->time_stamp).toString("yyyy-MM-dd hh:mm:ss") + QString(",")); + //< 车站 + alarmInfo.append(queryLocationDescription((*itpos)->location_id) + QString(",")); + //< 应用 + alarmInfo.append(queryAppDescription((*itpos)->app_id) + QString(",")); + //< 内容 + alarmInfo.append((*itpos)->content + QString(",")); + //< 画面名称 + alarmInfo.append((*itpos)->graph_name); + + pushGraphics(alarmInfo); + } + if(ALM_ACT_PRINT == (alarmAction & ALM_ACT_PRINT)) + { + //第2位,打印 + print(); + } + if(ALM_ACT_SHORT_MSG == (alarmAction & ALM_ACT_SHORT_MSG)) + { + //第3位,短消息 + shortMessage(); + } + if(ALM_ACT_SOUND == (alarmAction & ALM_ACT_SOUND) || ALM_ACT_VOICE == (alarmAction & ALM_ACT_VOICE)) + { + //第4位,声音告警 第9位 语音告警 + //emit sigInsertAudioCues(*itpos, (*itpos)->sound_file); + insertAudioCues(*itpos); + } + if(ALM_ACT_PA == (alarmAction & ALM_ACT_PA)) + { + //第5位,广播告警 + paNotify(); + } + } + itpos++; + } +} + +void CAlarmMsgManage::updateMsgAction(const AlarmMsgPtr &msg) +{ + if(msg->logic_state == E_ALS_ALARM) + { + int alarmAction = queryAlarmAction(msg->priority); + msg->m_alarmAction = alarmAction; + if(ALM_ACT_PUSH_PIC == (alarmAction & ALM_ACT_PUSH_PIC) && !msg->graph_name.isEmpty()) + { + //第1位,推画面 + QString alarmInfo; + //< 等级 + alarmInfo.append(QString::number(msg->priorityOrder) + QString(",")); + //< 时间 + alarmInfo.append(QDateTime::fromMSecsSinceEpoch(msg->time_stamp).toString("yyyy-MM-dd hh:mm:ss") + QString(",")); + //< 车站 + alarmInfo.append(queryLocationDescription(msg->location_id) + QString(",")); + //< 应用 + alarmInfo.append(queryAppDescription(msg->app_id) + QString(",")); + //< 内容 + alarmInfo.append(msg->content + QString(",")); + //< 画面名称 + alarmInfo.append(msg->graph_name); + + pushGraphics(alarmInfo); + } + if(ALM_ACT_PRINT == (alarmAction & ALM_ACT_PRINT)) + { + //第2位,打印 + print(); + } + if(ALM_ACT_SHORT_MSG == (alarmAction & ALM_ACT_SHORT_MSG)) + { + //第3位,短消息 + shortMessage(); + } + if(ALM_ACT_SOUND == (alarmAction & ALM_ACT_SOUND) || ALM_ACT_VOICE == (alarmAction & ALM_ACT_VOICE)) + { + //第4位,声音告警 第9位 语音告警 + //emit sigInsertAudioCues(msg, msg->sound_file); + insertAudioCues(msg); + } + if(ALM_ACT_PA == (alarmAction & ALM_ACT_PA)) + { + //第5位,广播告警 + paNotify(); + } + } +} + +void CAlarmMsgManage::pushGraphics(const QString &info) +{ + emit sigAlarmPushGraph(info); +} + +void CAlarmMsgManage::print() +{ + +} + +void CAlarmMsgManage::shortMessage() +{ + +} + +void CAlarmMsgManage::sounds(const AlarmMsgPtr info, const QStringList soundFileNames) +{ + //播放告警音频 + if(!soundFileNames.isEmpty()) + { + emit sigInsertAudioCues(info, soundFileNames); + } +} + +void CAlarmMsgManage::stopSounds(const AlarmMsgPtr info) +{ + removeAudioCues(info); +} + +void CAlarmMsgManage::paNotify() +{ + +} + +bool CAlarmMsgManage::isBindMediaPlayer() +{ + return isSignalConnected(QMetaMethod::fromSignal(&CAlarmMsgManage::sigReadFlag)); +} + +void CAlarmMsgManage::msgArrived() +{ + QMutexLocker locker(mutex); + QList m_ailistMsg; //需要在智能告警窗展示 + QList m_listMsg; //需要在原始告警窗展示 + m_listMsg.clear(); + for(int num(0);numkey_id_tag)) + { + continue ; + } + if(!m_listPermLocationId.contains(m_listMsgAddCache.at(num)->location_id) || (!m_listPermRegionId.contains(m_listMsgAddCache.at(num)->region_id) && m_listMsgAddCache.at(num)->region_id != -1)) + { + continue ; + } + if(m_listMsgAddCache.at(num)->deleteFlag || m_listMsgAddCache.at(num)->releaseFlag) + { + continue ; + } + + if(E_ALS_ALARM == m_listMsgAddCache.at(num)->logic_state || E_ALS_RETURN == m_listMsgAddCache.at(num)->logic_state )//未删除未确认数量(界面显示未确认) + { + addNotConfirmAlm(m_listMsgAddCache.at(num)->location_id,m_listMsgAddCache.at(num)->dev_group_tag,m_listMsgAddCache.at(num)->uuid_base64); + ++m_nNDelComAlarmCount; + } + updateMsgAction(m_listMsgAddCache.at(num)); + m_infos.insert(m_listMsgAddCache.at(num)->uuid_base64, m_listMsgAddCache.at(num)); + m_listMsg.append(m_listMsgAddCache.at(num)); + //更新告警数量 + almStats(m_listMsgAddCache.at(num),1); + //更新未聚类但是需要展示的原始告警 + QHash::iterator it = m_idToid.find(m_listMsgAddCache.at(num)->uuid_base64); + if(it == m_idToid.end()) + { + m_alarm.insert(m_listMsgAddCache.at(num)->uuid_base64,m_listMsgAddCache.at(num)); + m_ailistMsg.append(m_listMsgAddCache.at(num)); + } + } + m_listMsgAddCache.clear(); + if(m_listMsg.size()>0) + { + emit sigMsgArrived(m_listMsg); + m_listMsg.clear(); + } + if(m_ailistMsg.size()>0) + { + emit sigMsgArrivedToAi(m_ailistMsg); + m_ailistMsg.clear(); + } + //设置标志可读 + setReadFlag(); +} + +void CAlarmMsgManage::dealDelayAi() +{ + QMutexLocker locker(mutex); + QList delaydeal = m_delaydeal; + m_delaydeal.clear(); + //QVector deluuidVec; + QList aiMsgList; + if(delaydeal.size() > 0) + { + for(int index(0);index uuidVec = delaydeal.at(index)->raw_alm_uuid; + if(delaydeal.at(index)->deleteFlag || delaydeal.at(index)->brokenFlag) + { + continue; + } + QList almInfoList; + if(!isHaveAlm(uuidVec,almInfoList)) + { + m_delaydeal.append(delaydeal.at(index)); //延后处理 + continue; + } + QHash::iterator it = m_all.find(delaydeal.at(index)->main_uuid_base64); + if(it != m_all.end()) + { + delaydeal.at(index)->main_state = (*it)->logic_state; + } + if(checkLookPerm(almInfoList)) + { + addaicount(almInfoList,delaydeal.at(index)->uuid_base64); + addaitolocation(almInfoList,delaydeal.at(index)->uuid_base64); + initaivideo(delaydeal.at(index)); + if(delaydeal.at(index)->deleteFlag != true && delaydeal.at(index)->brokenFlag != true) + { + m_nAlmTotal += delaydeal.at(index)->raw_alm_uuid.size(); + m_aiinfos.insert(delaydeal.at(index)->uuid_base64,delaydeal.at(index)); + aiMsgList.append(delaydeal.at(index)); + } + } + } + if(aiMsgList.size()>0) + { + emit sigAiMsgAdd(aiMsgList); + } + } +} + +int CAlarmMsgManage::queryAlarmAction(const int &priority) +{ + iot_dbms::CTableLockGuard locker(*m_rtdbAlarmActionAccess); + iot_dbms::CVarType value; + m_rtdbAlarmActionAccess->getColumnValueByKey((void*)&priority, "alarm_actions",value); + return value.toInt(); +} + +QString CAlarmMsgManage::queryLocationDescription(int id) +{ + iot_dbms::CTableLockGuard locker(*m_rtdbLocationDescriptionAccess); + iot_dbms::CVarType value; + m_rtdbLocationDescriptionAccess->getColumnValueByKey((void*)&id, "description", value); + return value.c_str(); +} + +QString CAlarmMsgManage::queryAppDescription(int id) +{ + iot_dbms::CTableLockGuard locker(*m_rtdbAppDescriptionAccess); + iot_dbms::CVarType value; + m_rtdbAppDescriptionAccess->getColumnValueByKey((void*)&id, "description", value); + return value.c_str(); +} + +void CAlarmMsgManage::loadPermInfo() +{ + m_listPermLocationId = CAlarmBaseData::instance()->getPermLocationIdList(); + m_listPermRegionId = CAlarmBaseData::instance()->getPermRegionIdList(); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmMsgManage.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmMsgManage.h new file mode 100644 index 00000000..8891cf22 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmMsgManage.h @@ -0,0 +1,420 @@ +#ifndef CALARMMSGMANAGE_H +#define CALARMMSGMANAGE_H + +#include +#include +#include "CAlarmMsgInfo.h" +#include "CAiAlarmMsgInfo.h" +#include "dbms/rdb_api/CRdbAccess.h" + +#include "CAlarmCommon.h" +#include + +const int MAX_AUDIO_ALM_COUNT = 1000; + +class QMutex; +class CAlarmItemModel; +class CAlarmMsgManage : public QObject +{ + Q_OBJECT +public: + static CAlarmMsgManage * instance(); + + ~CAlarmMsgManage(); + + void destory(); + + void initialize(); + + void release(); + + QList getListAlarmInfo(); + + QHash getDeviceStatisticalInfo(); + + int deviceGroupAlarmStatistical(const QString &deviceGroup); + + int getAlarmTotalSize(); + + int getUnConfirmSize(); + + void output(); + + void addAlarmMsg(const QList &msgList); + + void addAlarmToAllInfo(const QList &msgList); + + void addAlarmCacheMsg(const QList &msgList); + + void confirmAlarmMsg(const QList &uuidList); + + int removeAlarmMsg(const QList &uuidList); + + void releaseAlarmMsg(const QList &uuidList); + + void linkWave2AlmMsg(const QList &uuidList,const QString &waveFile); + + void removeAlarmMsgByDomainID(const int &domainId); + + void updateMsgAction(const QList &msgList); + void updateMsgAction(const AlarmMsgPtr &msg); + //< 告警动作 + void pushGraphics(const QString &info); + void print(); + void shortMessage(); + void sounds(const AlarmMsgPtr info, const QStringList soundFileNames); + void stopSounds(const AlarmMsgPtr info); + void paNotify(); + + bool isBindMediaPlayer(); + void msgArrived(); + void dealDelayAi(); + + void addInhibitAlm(const AlarmMsgPtr &info); + void removeInhibitTag(const QString &tag_name); + QMap getDevAlarm(const QString &device); + + QMap >getDevGroupPriorityDevNum(const QString &deviceGroup); + + QHash > getLocAlmInfo(); + void updataDevGroupByDev(QString devGroup, QString device); + + QHash > > getLocNotConfirmAlmInfo(); + + void getAllInhibitAlm(QList &almList); +signals: + void sigInsertAudioCues(const AlarmMsgPtr &info, const QStringList &soundFileNames); + void sigStopAudioCues(const AlarmMsgPtr &info); + void sigAlarmPushGraph(const QString &alarmInfo); + void sigAlarmPushGraphClear(); + void sigAlarmReplaced(); + void sigMsgArrived(QList listMsg); //只通知表格模型 + /** + * @brief sigMsgArrivedToAi 通知树模型未聚类的原始告警到达 + * @param listMsg + */ + void sigMsgArrivedToAi(QList listMsg); //只通知树模型 + + void sigAllViewReload(); + + void sigReadFlag(); + +public slots: + void slotLogin(); + +private: + CAlarmMsgManage(); + int queryAlarmAction(const int &priority); + QString queryLocationDescription(int id); + QString queryAppDescription(int id); + + void loadPermInfo(); + + void refreshCache(); + +public: + bool ifInhibit(const QString &tag_name); + bool isInhibit(const QString &tag_name); + /** + * @brief removeAiAlarmMsgByDomainID 移除此域所有智能告警,并清除,维护相关结构 + * @param domainId 域id + */ + void removeAiAlarmMsgByDomainID(const int &domainId); + /** + * @brief addAiAllAlarmMsg 全数据时调用,不会通知模型,全部接收完会自动通知模型刷新(重新装载数据) + * @param msg 智能告警指针 + */ + void addAiAllAlarmMsg(const QList &msgList); + /** + * @brief addAiAlarmMsg 非全数据时调用,会通知模型添加智能告警,删除相关原始告警 + * @param msg 智能告警指针 + */ + void addAiAlarmMsg(const QList &msgList); + /** + * @brief delAiAlarmMsg 根据智能告警uuid删除智能告警 + * @param aiuuid 智能告警uuid + */ + void delAiAlarmMsg(const QList &uuidList); + /** + * @brief brokenAiAlarmMsg 处理不完整的智能告警 + * @param aiuuid + */ + void brokenAiAlarmMsg(const QList &uuidList); + /** + * @brief releaseAiAlarmMsg 根据智能告警uuid释放智能告警 + * @param aiuuid 智能告警uuid + */ + void releaseAiAlarmMsg(const QList &uuidList); + /** + * @brief getAiuuid 根据原始告警uuid获取智能告警uuid + * @param uuid 原始告警uuid + * @param aiuuid 智能告警uuid + * @return 成功返回true,失败返回false + */ + bool getAiuuid(const QString &uuid, QString &aiuuid); + /** + * @brief isBelongAi 是否属于某个智能告警(已经被某个智能告警聚类) + * @param uuid 原始告警uuid + * @return true-已经被聚类 false-还未被聚类 + */ + bool isBelongAi(const QString &uuid); + + AlarmMsgPtr getOnePlayerAlm(int num); + + AlarmMsgPtr getOneSpeechAlm(int num); +private: + /** + * @brief eraseaicount 删除key为aiuuid的键值对 (<智能告警id,SAiConfirm>) + * @param aiuuid 智能告警uuid + */ + void eraseaicount(const QString &aiuuid); + /** + * @brief eraseidtoid 删除值为aiuuid的所有键值对(<原始告警id,智能告警id>) + * @param aiuuid 智能告警uuid + */ + void eraseidtoid(const QString &aiuuid); + /** + * @brief eraseidtolocation 删除key为aiuuid的键值对 (<智能告警id,与此条智能告警相关的所有位置id>) + * @param aiuuid 智能告警uuid + */ + void eraseidtolocation(const QString &aiuuid); + /** + * @brief isHaveAlm 查询m_all中是否包含uuidVec中的告警(确保智能告警下的原始告警一定存在) + * @param uuidVec + * @return + */ + /** + * @brief isHaveAlm isHaveAlm 查询m_all中是否包含uuidVec中的告警(确保智能告警下的原始告警一定存在) + * @param uuidVec 原始告警uuid集合 + * @param almInfoList 原始告警智能指针集合 + * @return 全部包含返回true,否则返回false + */ + bool isHaveAlm(const QVector &uuidVec, QList &almInfoList); + /** + * @brief checkLookPerm 检查当前登陆用户是否具有此条智能告警的权限(若可以看到其中任意一条,则具有权限) + * @param uuidVec 智能告警下原始告警uuid集合 + * @return 有权限返回 true 否则返回false + */ + /** + * @brief checkLookPerm checkLookPerm 检查当前登陆用户是否具有此条智能告警的权限(若可以看到其中任意一条,则具有权限) + * @param almInfoList 原始告警智能指针集合 + * @return 具有权限返回true 否则返回false + */ + bool checkLookPerm(const QList &almInfoList); + /** + * @brief addidtoid 添加原始告警uuid和智能告警uuid的映射 + * @param uuidVec 原始告警uuid集合 + * @param aiuuid 智能告警uuid + */ + void addidtoid(const QVector &uuidVec, const QString &aiuuid); + /** + * @brief addaicount 添加智能告警下原始告警的已确认和总数 + * @param uuidVec 原始告警uuid集合 + * @param aiuuid 智能告警uuid + */ + /** + * @brief addaicount 添加智能告警下原始告警的已确认和总数 + * @param almInfoList 原始告警智能指针的集合 + * @param aiuuid 智能告警aiuuid + */ + void addaicount(const QList &almInfoList, const QString &aiuuid); + /** + * @brief addaitolocation addaitolocation 添加智能告警uuid和与此告警相关位置的id + * @param almInfoList 原始告警智能指针集合 + * @param aiuuid 智能告警aiuuid + */ + void addaitolocation(const QList &almInfoList, const QString &aiuuid); + /** + * @brief initaivideo initaivideo 初始化智能告警下原始告警的相关信息 + * @param msg + */ + void initaivideo(AiAlarmMsgPtr msg); + /** + * @brief updatealarm 更新需要展示在智能告警窗上未聚类的原始告警 + * @param uuidVec 某条智能告警下的所有原始告警的uuid + * @param deluuidVec 需要被删除的一级节点上的未聚类的原始告警uuid + */ + void updatealarm(QVector &uuidVec, QVector &deluuidVec); + /** + * @brief almStats 告警统计 + * @param msg 告警指针 + * @param addOrSub 1--add 0--sub(1添加,0删除) + */ + void almStats(const AlarmMsgPtr &msg,int addOrSub); + /** + * @brief almAddStats 告警添加统计 + * @param msg 告警指针 + */ + void almAddStats(const AlarmMsgPtr &msg); + /** + * @brief almSubStats 告警删除统计 + * @param msg 告警指针 + */ + void almSubStats(const AlarmMsgPtr &msg); + /** + * @brief devDevGTotAlmAddStats 设备设备组按优先级添加统计 + * @param msg 告警指针 + */ + void devDevGTotAlmAddStats(const AlarmMsgPtr &msg); + /** + * @brief devDevGTotAlmSubStats 设备设备组按优先级删除统计 + * @param msg 告警指针 + */ + void devDevGTotAlmSubStats(const AlarmMsgPtr &msg); + void devDevGAddStats(const AlarmMsgPtr &msg); + void devDevGSubStats(const AlarmMsgPtr &msg); + void locAddStats(const AlarmMsgPtr &msg); + void locSubStats(const AlarmMsgPtr &msg); + /** + * @brief addNotConfirmAlm 添加未确认的告警uuid + * @param locId + * @param devg + * @param uuid + */ + void addNotConfirmAlm(int locId,const QString &devg,const QString &uuid); + /** + * @brief delNotConfirmAlm 从未确认的告警uuid集合中删除(删除的不一定被确认 可能是数据重发) + * @param locId + * @param devg + * @param uuid + */ + void delNotConfirmAlm(int locId,const QString &devg,const QString &uuid); +signals: + /** + * @brief sigAiMsgRemove 通知智能告警模型删除智能告警 + * @param aiuuidList 智能告警aiuuid列表 + */ + void sigAiMsgRemove(const QList & aiuuidList); + /** + * @brief sigAiMsgAdd 通知智能告警模型添加某条智能告警 + * @param aimsgList 智能告警指针列表 + */ + void sigAiMsgAdd(const QList& aimsgList); + /** + * @brief sigMsgRemove 通知智能告警模型删除一级节点上的原始告警 + * @param deluuid 需要删除的原始告警uuid的集合 + */ + void sigMsgRemove(const QVector deluuid); +public: + /** + * @brief queryLocationDesc 根据智能告警uuid查询位置描述(可能包含多个位置) + * @param aiuuid 智能告警uuid + * @return 位置描述 + */ + QString queryLocationDesc(QString &aiuuid); + /** + * @brief queryConfirm 根据智能告警uuid查询确认数和总数 + * @param aiuuid 智能告警uuid + * @return 确认数/总数(ex:20/30) + */ + QString queryConfirm(const QString &aiuuid); + /** + * @brief queryAiTotal 根据智能告警uuid 查询原始告警条数 + * @param aiuuid 智能告警uuid + * @return 原始告警条数 + */ + int queryAiTotal(const QString &aiuuid); + /** + * @brief getAlarmInfo 获取所有有权限的原始告警和智能告警 (接口:给智能告警模型使用) + * @param listAlarm 原始告警指针集合 + * @param listaiAlarm 智能告警指针集合 + */ + void getAlarmInfo(QList &listAlarm,QList &listaiAlarm); + /** + * @brief getAlarmPtrByuuid 根据原始告警uuid获取原始告警指针 + * @param uuid 原始告警uuid列表 + * @return 原始告警指针列表 + */ + QList getAlarmPtrByuuid(const QVector &uuidVec); + /** + * @brief ifhaveNotConfirmAlmByuuid 根据智能告警uuid查询是否还有未确认的原始告警 + * @param aiuuid 智能告警uuid + * @return 如果包含未确认原始告警返回true,否则返回false + */ + bool ifhaveNotConfirmAlmByuuid(QString &aiuuid); + /** + * @brief getAiLocationList 根据智能告警uuid获取有关的位置集合 + * @param aiuuid 智能告警uuid + * @return 与之有关的位置集合 + */ + QList getAiLocationList(QString &aiuuid); + /** + * @brief getalmuuidByAiuuid 根据智能告警uuid获取相关原始告警uuid + * @param aiuuid 智能告警uuid + * @return 原始告警uuidList + */ + QList getalmuuidByAiuuid(const QString &aiuuid); + /** + * @brief getAlmTotal 获取智能告警窗显示原始告警总数 + * @return 数量 + */ + int getAlmTotal(); + /** + * @brief getAiCount 获取未过滤时的智能告警条数 + * @return + */ + int getAiCount(); + +private: + + void initAlarm(); + + void initAiAlarm(); + + void insertAudioCues(const AlarmMsgPtr &info); + + void removeAudioCues(const AlarmMsgPtr &info); + + void setReadFlag(); + +private: + static CAlarmMsgManage * pInstance; + + QMutex * mutex; + + iot_dbms::CRdbAccess * m_rtdbAlarmActionAccess; + iot_dbms::CRdbAccess * m_rtdbLocationDescriptionAccess; + iot_dbms::CRdbAccess * m_rtdbAppDescriptionAccess; + + int m_nNDelComAlarmCount; //< 未删除未确认数量 N--not Del--delete Com--confirm + QHash m_infos; + QHash m_all; + + + QList m_listPermLocationId; //< 原始告警车站权限 + QList m_listPermRegionId; //< 原始告警责任区权限 + + + //缓存从collect调整到mng + QList m_listMsgAddCache; //< 告警缓存(每秒更新) + QList m_inhibitFilter; //< 告警抑制[界面] + + //智能告警新加 + QHash m_alarm; //< 有权限/未禁止/未聚类的原始告警(需要展示在智能告警窗)(两个线程共同维护) + QHash m_aiinfos; //< 有权限的智能告警 + QHash m_aiall; //< 所有智能告警 + + QHash m_aicount; //< <智能告警uuid,已确认数/总数 > + QHash m_idToid; //< <原始告警uuid,智能告警uuid > 用于确认原始告警之后便于更新智能告警中的已确认总数 + + QHash > m_aitolocation;//< <智能告警uuid,包含的原始告警车站id> + + QHash m_alarmDeviceStatistical; //< 设备告警数量统计 + QHash m_alarmDeviceGroupStatistical; //<设备组告警数量统计 + QHash > m_alarmDevPriority; //< 设备告警等级数量统计 + QHash > > m_alarmDGPDev; //< <设备组,<告警等级,设备> > + QHash > m_alarmLPAlm; //< <车站id,<告警等级,告警数量> > + + QHash > > m_alarmLNCAlm;//< <车站id,<设备组,<未确认告警uuid> > > + + QList m_delaydeal; //延迟处理的智能告警 + + int m_nAlmNum; //智能告警窗原始告警个数 + int m_nAlmTotal; //智能告警窗原始告警总数 + + QList m_playerList; + + QString m_strMediaPath; +}; + +#endif // CALARMMSGMANAGE_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmPlugin.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmPlugin.cpp new file mode 100644 index 00000000..26d3167c --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmPlugin.cpp @@ -0,0 +1,1445 @@ +#include "CAlarmPlugin.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "CAlarmView.h" +#include "CAlarmForm.h" +#include "CAlarmWidget.h" +#include "CAlarmItemModel.h" +#include "CAlarmDelegate.h" +#include "CAiAlarmDataCollect.h" +#include "CAlarmDataCollect.h" +#include "CAlarmMsgManage.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" +#include +#include "CAlarmBaseData.h" + +QThread * CAlarmPlugin::m_pDataCollectThread = NULL; +QThread * CAlarmPlugin::m_pMediaPlayerThread = NULL; +CAlarmPlugin::CAlarmPlugin(QWidget *parent, bool editMode) + : QWidget(parent), + m_mode(E_Alarm_Window), + m_bIsEditMode(editMode), + m_alarmForm(Q_NULLPTR), + m_alarmWidget(Q_NULLPTR), + m_alarmView(Q_NULLPTR), + m_pModel(Q_NULLPTR), + m_pTreeModel(Q_NULLPTR), + m_enableAi(false) +{ + QString qss = QString(); +#ifdef OS_LINUX + QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + "/plugins"); +#endif + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + qRegisterMetaType< CAlarmMsgInfo >("CAlarmMsgInfo"); + qRegisterMetaType< AlarmMsgPtr >("AlarmMsgPtr"); + qRegisterMetaType< QList >("ListAlarmMsgPtr"); + + if(!m_bIsEditMode) + { + CAlarmBaseData::instance(); +// if(!m_pMediaPlayerThread) +// { +// m_pMediaPlayerThread = new QThread(); +// CAlarmMediaPlayer::instance()->moveToThread(m_pMediaPlayerThread); +// m_pMediaPlayerThread->start(); +// } + if(!m_pDataCollectThread) + { + m_pDataCollectThread = new QThread(); + CAlarmMsgManage::instance()->moveToThread(m_pDataCollectThread); + CAlarmSetMng::instance()->moveToThread(m_pDataCollectThread); + + connect(m_pDataCollectThread, &QThread::started, CAiAlarmDataCollect::instance(), &CAiAlarmDataCollect::initialize, Qt::QueuedConnection); + connect(m_pDataCollectThread, &QThread::started, CAlarmDataCollect::instance(), &CAlarmDataCollect::initialize, Qt::QueuedConnection); + connect(m_pDataCollectThread, &QThread::finished, m_pDataCollectThread, &QThread::deleteLater, Qt::QueuedConnection); + m_pDataCollectThread->start(); + } + connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigAlarmStateChanged, this, &CAlarmPlugin::recvAlarmNumChanged, Qt::QueuedConnection); + //connect(this, &CAlarmPlugin::sigSwitchFaultRecallState, CAiAlarmDataCollect::instance(), &CAiAlarmDataCollect::slotSwitchFaultRecallState, Qt::QueuedConnection); + connect(this, &CAlarmPlugin::sigSwitchFaultRecallState, CAlarmDataCollect::instance(), &CAlarmDataCollect::slotSwitchFaultRecallState, Qt::QueuedConnection); + CAlarmDataCollect::instance()->refrence(); + CAiAlarmDataCollect::instance()->refrence(); + connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigUpdateAlarmView, this, &CAlarmPlugin::slotUpdateAlarmView, Qt::QueuedConnection); + connect(CAlarmDataCollect::instance(), &CAlarmDataCollect::sigAlarmOperateEnable, this, &CAlarmPlugin::slotUpdateAlarmOperateEnable, Qt::QueuedConnection); + connect(this,&CAlarmPlugin::sigLogin,CAlarmMsgManage::instance(),&CAlarmMsgManage::slotLogin, Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(),&CAlarmMsgManage::sigAllViewReload,this,&CAlarmPlugin::slotAllViewReload, Qt::QueuedConnection); + } +} + +CAlarmPlugin::~CAlarmPlugin() +{ + if(!m_bIsEditMode) + { + + int almCount = CAlarmDataCollect::instance()->getRefrenceCount(); + int aialmCount = CAiAlarmDataCollect::instance()->getRefrenceCount(); + CAlarmDataCollect::instance()->destory(); + CAiAlarmDataCollect::instance()->destory(); + if(1 == almCount || aialmCount == 1) + { + //< 退出托管线程 + if(m_pDataCollectThread) + { + m_pDataCollectThread->quit(); + m_pDataCollectThread->wait(); + delete m_pDataCollectThread; + } + m_pDataCollectThread = Q_NULLPTR; + CAlarmMsgManage::instance()->destory(); + CAlarmSetMng::instance()->destory(); + +// if(m_pMediaPlayerThread) +// { +// m_pMediaPlayerThread->quit(); +// m_pMediaPlayerThread->wait(); +// delete m_pMediaPlayerThread; +// } +// m_pMediaPlayerThread = Q_NULLPTR; + CAlarmMediaPlayer::instance()->destory(); + CAlarmBaseData::instance()->destory(); + } + } + reset(); + int mode = (int)m_mode; + LOGDEBUG("CAlarmPlugin::~CAlarmPlugin()model[%d]",mode); +} + +void CAlarmPlugin::initialize(int mode) +{ + if(E_Alarm_Dock != mode && E_Alarm_Window != mode && E_Alarm_Pop != mode) + { + return; + } + reset(); + + updateAlarmOperatePerm(); + + m_mode = (E_Alarm_Mode)mode; + + //初始界面:视图、模型 + QHBoxLayout * layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setMargin(0); + if (E_Alarm_Window == mode) + { + loadConfig(); + m_alarmForm = new CAlarmForm(); + if(!m_bIsEditMode) + { + //m_alarmForm->modeConfirm(E_Alarm_Window); + m_alarmForm->initialize(); + m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); + if(m_enableAi) + { + m_pTreeModel = new CAiAlarmTreeModel(this); + m_alarmForm->setAlarmModel(m_pModel,m_pTreeModel); + }else + { + m_alarmForm->setAlarmModel(m_pModel); + } + + + connect(m_alarmForm, &CAlarmForm::closeBtnClicked, this, &CAlarmPlugin::closeBtnClicked, Qt::QueuedConnection); + connect(m_alarmForm,&CAlarmForm::openTrend,this,&CAlarmPlugin::openTrendDialog,Qt::QueuedConnection); + connect(m_alarmForm,&CAlarmForm::openVideo,this,&CAlarmPlugin::openVideoDialog,Qt::QueuedConnection); + connect(m_alarmForm,&CAlarmForm::openAccidentReview,this,&CAlarmPlugin::openAccidentReviewDialog,Qt::QueuedConnection); + } + else + { + m_alarmForm->setEnabled(false); + } + layout->addWidget(m_alarmForm); + } + else if (E_Alarm_Dock == mode) + { + m_alarmWidget = new CAlarmWidget(); + if(!m_bIsEditMode) + { + m_alarmWidget->initialize(); + m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); + m_alarmWidget->setAlarmModel(m_pModel); + + connect(m_alarmWidget, &CAlarmWidget::alarmWidgetDoubleClicked, this, &CAlarmPlugin::alarmDockDoubleClicked, Qt::QueuedConnection);// dock 双击 + connect(m_alarmWidget, &CAlarmWidget::openVideo, this, &CAlarmPlugin::openVideoDialog, Qt::QueuedConnection); + connect(m_alarmWidget, &CAlarmWidget::openTrend, this, &CAlarmPlugin::openTrendDialog, Qt::QueuedConnection); + if(!CAlarmMsgManage::instance()->isBindMediaPlayer())//判断信号是否被连接 + { + //connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigInsertAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::insertAudioCues, Qt::QueuedConnection); + //connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigStopAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::removeAudioCues, Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigReadFlag, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::slotReadFlag, Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigAlarmPushGraph, this, &CAlarmPlugin::alarmPush, Qt::QueuedConnection); + connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigAlarmPushGraphClear, this, &CAlarmPlugin::alarmPushClear, Qt::QueuedConnection); + //connect(CAlarmMsgManage::instance(), &CAlarmMsgManage::sigClearAudioCues, CAlarmMediaPlayer::instance(), &CAlarmMediaPlayer::clearAudioCues, Qt::QueuedConnection); + connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,CAlarmMediaPlayer::instance(),&CAlarmMediaPlayer::slotLoadConfig,Qt::QueuedConnection); + } +// if(!CAlarmSetMng::instance()->isBindMediaPlayer()) +// { +// connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,CAlarmMediaPlayer::instance(),&CAlarmMediaPlayer::slotLoadConfig,Qt::QueuedConnection); +// } + } + else + { + m_alarmWidget->initializeEdit(); + m_alarmWidget->setEnabled(false); + } + layout->addWidget(m_alarmWidget); + } + else if (E_Alarm_Pop == mode) + { + m_alarmView = new CAlarmView(this); + if(!m_bIsEditMode) + { + m_alarmView->initialize(); + m_alarmView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); + m_pModel = new CAlarmItemModel((E_Alarm_Mode)mode, this); + m_alarmView->setModel(m_pModel); + connect(m_alarmView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pModel, SLOT(sortColumn(int,Qt::SortOrder))); + m_alarmView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); + CAlarmDelegate * pDelegate = new CAlarmDelegate(m_pModel, this); + m_alarmView->setItemDelegate(pDelegate); + connect(pDelegate,&CAlarmDelegate::openVideo,this, &CAlarmPlugin::openVideoDialog, Qt::QueuedConnection); + connect(pDelegate,&CAlarmDelegate::openTrend,this, &CAlarmPlugin::openTrendDialog, Qt::QueuedConnection); + connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,pDelegate,&CAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); + } + else + { + m_alarmView->setEnabled(false); + } + layout->addWidget(m_alarmView); + } + setLayout(layout); + slotUpdateAlarmOperateEnable(!CAlarmDataCollect::instance()->isFaultRecallState()); +} + +void CAlarmPlugin::loadConfig() +{ + QFile file(iot_public::CFileUtil::getPathOfCfgFile("intelli_alm_cfg.xml",CN_DIR_PLATFORM).c_str()); + if (!file.open(QFile::ReadWrite)) + { + LOGERROR("打开智能告警配置文件失败,默认不启动"); + return; + } + + QDomDocument doc; + if (!doc.setContent(&file)) + { + file.close(); + LOGERROR("加载智能告警配置文件失败,默认不启动"); + return; + } + file.close(); + + QDomElement root = doc.documentElement(); //返回根节点 root + QDomNode node = root.firstChild(); //获得第一个子节点 + + while (!node.isNull()) //如果节点不空 + { + QDomElement element = node.toElement(); + if(element.tagName() == "intelli_alm_srv") + { + if(element.attribute("enable") == "true") + { + m_enableAi =true; + }else + { + m_enableAi =false; + } + break; + } + node = node.nextSibling(); + } +} + +void CAlarmPlugin::login() +{ + if(!m_bIsEditMode) + { + LOGINFO("CAlarmPlugin::login():"); + if(m_mode != E_Alarm_Dock && m_mode != E_Alarm_Pop) + { + return ; + } + if(m_pModel == NULL) + { + LOGERROR("登录出错,空指针!"); + return ; + } + CAlarmBaseData::instance()->initData(); + updateAlarmOperatePerm(); + emit sigLogin(); + } +} + +void CAlarmPlugin::logout() +{ +// if(!m_bIsEditMode) +// { +// updateAlarmOperatePerm(); +// CAiAlarmDataCollect::instance()->release(); +// CAlarmMediaPlayer::instance()->release(); +// } +} + +void CAlarmPlugin::switchFaultRecallState(bool bFaultRecallState) +{ + if(!m_bIsEditMode) + { + updateAlarmOperatePerm(); + CAlarmMediaPlayer::instance()->release(); + emit sigSwitchFaultRecallState(bFaultRecallState); + } +} + +int CAlarmPlugin::confirmAlarm(const QList &msgs) +{ + int cofirmNum = 0; + if(msgs.isEmpty()) + { + return cofirmNum; + } + + if(m_vecRegionOptId.empty() || m_vecLocationOptId.empty()) + { + return cofirmNum; + } + //< 可能有部分告警没有确认权限 + QMap pkgMap; //Domain-DelPkg; + for(int nIndex(0); nIndex < msgs.size(); nIndex++) + { + AlarmMsgPtr info = msgs.at(nIndex); + if(E_ALS_ALARM != info->logic_state && E_ALS_RETURN != info->logic_state) + { + continue; + } + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionOptId.begin(); + while (region != m_vecRegionOptId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationOptId.begin(); + while (location != m_vecLocationOptId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + QString key = QString("%1_%2_%3").arg(info->domain_id).arg(info->alm_type).arg(info->app_id); + QMap::iterator it = pkgMap.find(key); + if(it == pkgMap.end()) + { + iot_idl::SAlmCltCfmAlm * pkg = new iot_idl::SAlmCltCfmAlm(); + pkg->set_node_name(m_currentNodeName); + pkg->set_user_id(m_currentUsrId); + pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); + pkg->set_domain_id(info->domain_id); + pkg->set_app_id(info->app_id); + pkg->set_alm_type(info->alm_type); + pkgMap[key] = pkg; + } + cofirmNum++; + pkgMap.value(key)->add_time_stamp(info->time_stamp); + pkgMap.value(key)->add_uuid_base64(info->uuid_base64.toStdString()); + pkgMap.value(key)->add_key_id_tag(info->key_id_tag.toStdString()); + } + } + //请求确认 + foreach (iot_idl::SAlmCltCfmAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestCfmAlm(*pkg) != true) + { + cofirmNum = cofirmNum -pkg->uuid_base64_size(); + LOGERROR("请求告警确认失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + return cofirmNum; +} + +int CAlarmPlugin::removeAlarm(const QList &msgs) +{ + if(msgs.isEmpty()) + { + return -1; + } + + if(m_vecRegionDelId.empty() || m_vecLocationDelId.empty()) + { + return -1; + } + //< 可能有部分告警没有删除权限 + QMap pkgMap; + for(int nIndex(0); nIndex < msgs.size(); nIndex++) + { + AlarmMsgPtr info = msgs.at(nIndex); + + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionDelId.begin(); + while (region != m_vecRegionDelId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationDelId.begin(); + while (location != m_vecLocationDelId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + QMap::iterator it = pkgMap.find(info->domain_id); + if(it == pkgMap.end()) + { + iot_idl::SAlmCltDelAlm * pkg = new iot_idl::SAlmCltDelAlm(); + pkg->set_domain_id(info->domain_id); + pkgMap[info->domain_id] = pkg; + } + pkgMap.value(info->domain_id)->add_uuid_base64(info->uuid_base64.toStdString()); + } + } + //请求删除 + foreach (iot_idl::SAlmCltDelAlm * pkg, pkgMap) + { + if(CAlarmDataCollect::instance()->requestDelAlm(*pkg) != true) + { + LOGERROR("请求删除告警失败!"); + } + } + qDeleteAll(pkgMap); + pkgMap.clear(); + return 0; +} + + +void CAlarmPlugin::setVolumeEnable(bool bEnable) +{ + CAlarmMediaPlayer::instance()->setVolumeEnable(bEnable); +} + +void CAlarmPlugin::recvAlarmNumChanged(const int &total, const int &unConfirm) +{ + emit alarmNumChanged(total, unConfirm); +} + +void CAlarmPlugin::setColumnAlign(const int &column, const int &alignFlag) +{ + if(m_bIsEditMode) + { + return; + } + if(!m_pModel) + { + return; + } + m_pModel->setColumnAlign(column, alignFlag); +} + +void CAlarmPlugin::setEnableAccidentReview(bool isNeed) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setEnableAccidentReview(isNeed); + } +} + +void CAlarmPlugin::setAccidentReviewPath(const QString &path) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setAccidentReviewPath(path); + } +} + +void CAlarmPlugin::setShowAiAlarmView(bool show) +{ + if(m_bIsEditMode) + { + return; + } + + if(E_Alarm_Window != m_mode || m_alarmForm == Q_NULLPTR ) + { + return; + } + m_alarmForm->setShowAiAlarmView(show); +} + +void CAlarmPlugin::setEnableTrend(bool isNeed) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setEnableTrend(isNeed); + }else if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setEnableTrend(isNeed); + }else if(E_Alarm_Pop == m_mode) + { + ((CAlarmDelegate*)m_alarmView->itemDelegate())->setEnableTrend(isNeed); + } +} + +void CAlarmPlugin::setEnableVideo(bool isNeed) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setEnableVideo(isNeed); + }else if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setEnableVideo(isNeed); + }else if(E_Alarm_Pop == m_mode) + { + ((CAlarmDelegate*)m_alarmView->itemDelegate())->setEnableVideo(isNeed); + } +} + +void CAlarmPlugin::setEnableWave(bool isNeed) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setEnableWave(isNeed); + }else if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setEnableWave(isNeed); + }else if(E_Alarm_Pop == m_mode) + { + ((CAlarmDelegate*)m_alarmView->itemDelegate())->setEnableWave(isNeed); + } +} + +void CAlarmPlugin::setEnableLevel(bool isNeed) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setEnableLevel(isNeed); + }else if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setEnableLevel(isNeed); + }else if(E_Alarm_Pop == m_mode) + { + ((CAlarmDelegate*)m_alarmView->itemDelegate())->setEnableLevel(isNeed); + } +} + +void CAlarmPlugin::setDockRowHeight(const int &height) +{ + if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setRowHeight(height); + return ; + } + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->setRowHeight(height); + return ; + } + if(E_Alarm_Pop == m_mode && m_alarmView != Q_NULLPTR) + { + m_alarmView->setDefaultRowHeight(height); + return ; + } +} + +void CAlarmPlugin::setDockColumnVisible(const int &column, const bool &visbile) +{ + if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->setDockColumnVisible(column, visbile); + } +} + +int CAlarmPlugin::confirmAllPermAlarm(bool tips) +{ + int result = 0; + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + + if(m_bIsEditMode || E_Alarm_Dock != m_mode || bFaultRecallState) + { + return result; + } + if(!m_alarmWidget || !m_pModel) + { + return result; + } + QList msgs =CAlarmMsgManage::instance()->getListAlarmInfo(); + int confirmNum = confirmAlarm(msgs); + if(tips) + { + QMessageBox::information(this, tr("提示"), tr("此次一共确认")+QString::number(confirmNum)+tr("条告警"), QMessageBox::Ok); + } + return confirmNum; +} + +QStringList CAlarmPlugin::getDevAlmInfo(const QString device) +{ + QMap alarm = CAlarmMsgManage::instance()->getDevAlarm(device); + QStringList result; + result.clear(); + QMap::iterator it= alarm.begin(); + while (it!= alarm.end()) { + QString alarmNum= QString("%1_%2").arg(it.key()).arg(it.value()); + result.append(alarmNum); + it++; + } + return result; +} + +QStringList CAlarmPlugin::getDevGroupAlmInfo(const QString deviceGroup) +{ + QMap > listMap = CAlarmMsgManage::instance()->getDevGroupPriorityDevNum(deviceGroup); + QStringList result; + result.clear(); + QMap >::iterator it =listMap.begin(); + for(;it != listMap.end();it++) + { + //优先级_设备数量 + QString priDev= QString("%1_%2").arg(it.key()).arg(it.value().size()); + result.append(priDev); + } + return result; +} + +QStringList CAlarmPlugin::getLocAlmInfo() +{ + QHash > locAlm = CAlarmMsgManage::instance()->getLocAlmInfo(); + QStringList list; + list.clear(); + QHash >::iterator it = locAlm.begin(); + while (it != locAlm.end()) { + QMap &priAlmNum =it.value(); + QMap::iterator pos = priAlmNum.begin(); + while (pos != priAlmNum.end()) { + QString priAlm = QString("%1_%2_%3").arg(it.key()).arg(pos.key()).arg(pos.value()); + list.append(priAlm); + pos++; + } + it++; + } + return list; +} + +int CAlarmPlugin::getLocNotConfirmAlmCount(int loc) +{ + int count =0; + if(loc<0) + { + return count; + } + QHash > > locCountMap = CAlarmMsgManage::instance()->getLocNotConfirmAlmInfo(); + + QHash > >::iterator it = locCountMap.find(loc); + if(it !=locCountMap.end()) + { + QMap > devgCountMap = it.value(); + QMap >::iterator pos = devgCountMap.begin(); + while (pos != devgCountMap.end()) { + + count += pos.value().count(); + pos++; + } + } + + return count; +} + +int CAlarmPlugin::getDevgNotConfirmAlmCount(const QString &devg) +{ + int count =0; + if(devg.isEmpty()) + { + return count; + } + QHash > > locCountMap = CAlarmMsgManage::instance()->getLocNotConfirmAlmInfo(); + + QHash > >::iterator it = locCountMap.begin(); + while (it !=locCountMap.end()) + { + QMap > devgCountMap = it.value(); + QMap >::iterator pos = devgCountMap.find(devg); + if(pos != devgCountMap.end()) + { + count = pos.value().count(); + break; + } + it++; + } + + return count; +} + +void CAlarmPlugin::setHiddenLocation(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenLocation(hide); + } +} + +void CAlarmPlugin::setHiddenTime(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenTime(hide); + } +} + +void CAlarmPlugin::setHiddenStatus(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenStatus(hide); + } +} + +void CAlarmPlugin::setHiddenPriority(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenPriority(hide); + } +} + +void CAlarmPlugin::setHiddenCheckBox(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenCheckBox(hide); + } +} + +void CAlarmPlugin::setHiddenSetConfig(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenSetConfig(hide); + } +} + +void CAlarmPlugin::setHiddenCloseButton(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenCloseButton(hide); + } +} + +void CAlarmPlugin::setHiddenInhiAlarmButton(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenInhiAlarmButton(hide); + } +} + +void CAlarmPlugin::setHiddenSelectButton(bool hide) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setHiddenSelectButton(hide); + } +} + +void CAlarmPlugin::setFormColumnVisible(const int &column, const bool &visible) +{ + if(m_bIsEditMode || E_Alarm_Window != m_mode) + { + return; + } + if(!m_alarmForm) + { + return ; + }else + { + m_alarmForm->setColumnVisible(column, visible); + } +} + +void CAlarmPlugin::setDevice(const QString &device) +{ + if(m_bIsEditMode || E_Alarm_Pop != m_mode) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + m_pModel->addDeviceFilter(device); +} + +void CAlarmPlugin::setDeviceGroup(const QString &deviceGroup) +{ + //if(m_bIsEditMode || E_Alarm_Pop != m_mode) + if(m_bIsEditMode) + { + return; + } + + if(!m_alarmView || !m_pModel) //这个判断什么意思呢? + { + if(m_pModel) + { + m_pModel->addDeviceGroupFilter2(deviceGroup); + m_alarmForm->setHiddenLeftTree(); + m_pModel->setDeviceGroupFilterEnable(true) ; + +// QList priorityList; +// priorityList.append(0); +// priorityList.append(1); +// priorityList.append(2); +// priorityList.append(3); +// if(m_pModel) +// { +// bool isCheck=true; +// m_pModel->setPriorityFilter(isCheck,priorityList); +// } + } + return; + } + + if(deviceGroup.isEmpty()) + { + m_pModel->addDeviceGroupFilter(); //增加所有设备组,不显示任何告警信息 + } + else + { + m_pModel->addDeviceGroupFilter(deviceGroup); //增加需要过滤的设备 + } +} + + +void CAlarmPlugin::setPriorityFilter(int PriorityFilter) +{ + bool isCheck = true; + QList priorityList; + priorityList.append(PriorityFilter); + if(m_pModel) + { + m_pModel->setPriorityFilter(isCheck,priorityList); + } +} + +void CAlarmPlugin::setPointTag(const QString &pointList) +{ + if(m_bIsEditMode || E_Alarm_Pop != m_mode) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + QStringList s= pointList.split(","); + QList pointTagList; + for(int i = 0;iaddPointTagFilter(pointTagList); +} + +void CAlarmPlugin::setColumnVisible(const int &column, const bool &visible) +{ + if(m_bIsEditMode || E_Alarm_Pop != m_mode) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + m_alarmView->setColumnHidden(column, !visible); +} + +void CAlarmPlugin::confirmFirstAlarm(int index) +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Dock != m_mode || bFaultRecallState) + { + return; + } + if(!m_pModel) + { + return; + } + m_alarmWidget->confirmAlarm(index); +} + +void CAlarmPlugin::setColumnWidth(const int &column, const int &width) +{ + if(m_bIsEditMode) + { + return; + } + if(E_Alarm_Window == m_mode) + { + if(!m_alarmForm) + { + return; + } + m_alarmForm->setColumnWidth(column, width); + } + else if(E_Alarm_Dock == m_mode) + { + if(!m_alarmWidget) + { + return; + } + m_alarmWidget->setColumnWidth(column, width); + } + else if(E_Alarm_Pop == m_mode) + { + if(!m_alarmView || !m_pModel) + { + return; + } + m_alarmView->setColumnWidth(column, width); + } +} + +int CAlarmPlugin::currentSelectCount() +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) + { + return 0; + } + if(!m_alarmView || !m_pModel) + { + return 0; + } + QModelIndexList listModelIndex = m_alarmView->selectionModel()->selectedRows(); + return listModelIndex.size(); +} + +void CAlarmPlugin::confirmCurrentAlarm() +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) + { + return; + } + if(!m_alarmView || !m_pModel) + { + return; + } + QModelIndexList listModelIndex = m_alarmView->selectionModel()->selectedRows(0); + + bool permSkip = false; + QList msgs; + foreach (QModelIndex index, listModelIndex) + { + AlarmMsgPtr info = m_pModel->getAlarmInfo(index); + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionOptId.begin(); + while (region != m_vecRegionOptId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationOptId.begin(); + while (location != m_vecLocationOptId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + msgs.append(info); + } + else + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox.setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox.addButton(tr("取消"), QMessageBox::RejectRole); + msgBox.setDefaultButton(skip); + msgBox.exec(); + if (msgBox.clickedButton() == skip) + { + continue; + } + else if (msgBox.clickedButton() == skipAll) + { + permSkip = true; + continue; + } + else + { + return; + } + } + + } + + confirmAlarm(msgs); + m_alarmView->clearSelection(); +} + +void CAlarmPlugin::confirmAllAlarm() +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) + { + return; + } + + if(!m_alarmView || !m_pModel) + { + return; + } + + + + bool permSkip = false; + QList msgs; + for(int nRow(0); nRow < m_pModel->rowCount(); nRow++) + { + AlarmMsgPtr info = m_pModel->getAlarmInfo(m_pModel->index(nRow, 0)); + bool regionEnable = false; + bool locationEnable = false; + std::vector ::iterator region = m_vecRegionOptId.begin(); + while (region != m_vecRegionOptId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationOptId.begin(); + while (location != m_vecLocationOptId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + msgs.append(info); + } + else + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox.setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox.addButton(tr("取消"), QMessageBox::RejectRole); + msgBox.setDefaultButton(skip); + msgBox.exec(); + if (msgBox.clickedButton() == skip) + { + continue; + } + else if (msgBox.clickedButton() == skipAll) + { + permSkip = true; + continue; + } + else + { + return; + } + } + } + confirmAlarm(msgs); + m_alarmView->clearSelection(); +} + +void CAlarmPlugin::removeAllAlarm() +{ + bool bFaultRecallState = CAlarmDataCollect::instance()->isFaultRecallState(); + if(m_bIsEditMode || E_Alarm_Pop != m_mode || bFaultRecallState) + { + m_alarmForm->removeAllAlarm(); + return; + } + + if(!m_alarmView || !m_pModel) + { + return; + } + + bool permSkip = false; + bool unConfirmSkip = false; + QList msgs; + for(int nRow(0); nRow < m_pModel->rowCount(); nRow++) + { + AlarmMsgPtr info = m_pModel->getAlarmInfo(m_pModel->index(nRow, 0)); + bool regionEnable = false; + bool locationEnable = false; + + std::vector ::iterator region = m_vecRegionDelId.begin(); + while (region != m_vecRegionDelId.end()) + { + if(info->region_id == (*region++)) + { + regionEnable = true; + } + } + + std::vector ::iterator location = m_vecLocationDelId.begin(); + while (location != m_vecLocationDelId.end()) + { + if(info->location_id == (*location++)) + { + locationEnable = true; + } + } + if(regionEnable && locationEnable) + { + if(info->logic_state == E_ALS_ALARM || info->logic_state == E_ALS_RETURN) + { + if(!unConfirmSkip) + { + QMessageBox msgBox; + msgBox.setText(tr("包含未确认告警!")); + msgBox.setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox.addButton(tr("取消"), QMessageBox::RejectRole); + msgBox.setDefaultButton(skip); + msgBox.exec(); + if (msgBox.clickedButton() == skip) + { + continue; + } + else if (msgBox.clickedButton() == skipAll) + { + unConfirmSkip = true; + continue; + } + else + { + return; + } + } + else + { + continue; + } + } + else + { + msgs.append(info); + } + } + else + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警确认操作权限!")); + msgBox.setInformativeText(tr("是否跳过该项?")); + QPushButton *skip = msgBox.addButton(tr("跳过"), QMessageBox::ActionRole); + QPushButton *skipAll = msgBox.addButton(tr("全部跳过"), QMessageBox::AcceptRole); + msgBox.addButton(tr("取消"), QMessageBox::RejectRole); + msgBox.setDefaultButton(skip); + msgBox.exec(); + if (msgBox.clickedButton() == skip) + { + continue; + } + else if (msgBox.clickedButton() == skipAll) + { + permSkip = true; + continue; + } + else + { + return; + } + } + } + removeAlarm(msgs); + m_alarmView->clearSelection(); +} + +void CAlarmPlugin::slotUpdateAlarmView() +{ + if(E_Alarm_Dock == m_mode && m_alarmWidget != Q_NULLPTR) + { + m_alarmWidget->updateView(); + } + else if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->updateView(); + } + else if(E_Alarm_Pop == m_mode && m_alarmView != Q_NULLPTR) + { + m_alarmView->viewport()->update(); + } +} + +void CAlarmPlugin::slotUpdateAiAlarmView() +{ + if(E_Alarm_Window == m_mode && m_alarmForm != Q_NULLPTR) + { + m_alarmForm->updateView(); + } + +} + +void CAlarmPlugin::slotUpdateAlarmOperateEnable(const bool &bEnable) +{ + if(!m_bIsEditMode) + { + if (E_Alarm_Window == m_mode) + { + m_alarmForm->setAlarmOperateEnable(bEnable); + + } + else if (E_Alarm_Dock == m_mode) + { + m_alarmWidget->setAlarmOperateEnable(bEnable); + + } + else if (E_Alarm_Pop == m_mode) + { + //< 禁用确认、删除接口, 见E_Alarm_Pop模式接口 + } + } +} + +void CAlarmPlugin::slotAllViewReload() +{ + if(m_mode == E_Alarm_Dock) + { + m_pModel->initialize(); + }else if(m_mode == E_Alarm_Window) + { + m_pModel->initialize(); + if(m_enableAi) + { + m_pTreeModel->initialize(); + } + m_alarmForm->init(); + }else if(m_mode == E_Alarm_Pop) + { + m_pModel->initialize(); + } +} + +void CAlarmPlugin::reset() +{ + if(Q_NULLPTR != m_pModel) + { + m_pModel->disconnect(); + delete m_pModel; + } + m_pModel = Q_NULLPTR; + if(Q_NULLPTR != m_pTreeModel) + { + m_pTreeModel->disconnect(); + delete m_pTreeModel; + } + m_pTreeModel = Q_NULLPTR; + + if(Q_NULLPTR != m_alarmForm) + { + delete m_alarmForm; + } + m_alarmForm = Q_NULLPTR; + + if(Q_NULLPTR != m_alarmWidget) + { + delete m_alarmWidget; + } + m_alarmWidget = Q_NULLPTR; + + if(Q_NULLPTR != m_alarmView) + { + delete m_alarmView; + } + m_alarmView = Q_NULLPTR; + + QLayout * lyt = layout(); + if(Q_NULLPTR != lyt) + { + delete lyt; + } +} + +void CAlarmPlugin::updateAlarmOperatePerm() +{ + m_currentUsrId = -1; + m_currentNodeName = ""; + m_vecRegionOptId.clear(); + m_vecLocationOptId.clear(); + m_vecRegionDelId.clear(); + m_vecLocationDelId.clear(); + + iot_public::SNodeInfo stNodeInfo; + iot_public::CSysInfoInterfacePtr spSysInfo; + if (!iot_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + + m_currentNodeName = stNodeInfo.strName; + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(0 != permMngPtr->CurUser(m_currentUsrId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + LOGERROR("用户ID获取失败!"); + return; + } + if(PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, m_vecRegionOptId, m_vecLocationOptId)) + { + LOGERROR("用户不具备告警操作权限!"); + } + if(PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_DELETE, m_vecRegionDelId, m_vecLocationDelId)) + { + LOGERROR("用户不具备告警删除权限!"); + } + } +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmPlugin.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmPlugin.h new file mode 100644 index 00000000..7783ed6d --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmPlugin.h @@ -0,0 +1,361 @@ +#ifndef CALARMPLUGIN_H +#define CALARMPLUGIN_H + +#include +#include "CAlarmMsgInfo.h" +#include "CAlarmItemModel.h" +#include "CAlarmMediaPlayer.h" +#include "CAlarmSetMng.h" +#include "CAiAlarmTreeModel.h" +class CAlarmView; +class CAlarmForm; +class CAlarmWidget; +class CAlarmItemModel; + +class CAlarmPlugin : public QWidget +{ + Q_OBJECT +public: + CAlarmPlugin(QWidget *parent, bool editMode = false); + ~CAlarmPlugin(); + + int confirmAlarm(const QList &msgs); + + int removeAlarm(const QList &msgs); + +public slots: + /*************************以下接口为公共接口*****************************/ + /** + * @brief initialize 初始化模型 + * @param mode E_Alarm_Dock-小窗(0) E_Alarm_Window-大窗(1) E_Alarm_Pop-弹窗(2) + */ + void initialize(int mode); + /** + * @brief login 用户登录(用户登录时调用) + */ + void login(); + /** + * @brief logout 用户退出(用户退出时调用) + */ + void logout(); + /** + * @brief switchFaultRecallState 事故追忆切换 + * @param bFaultRecallState true-事故追忆 false-非事故追忆 + */ + void switchFaultRecallState(bool bFaultRecallState); + /** + * @brief setAudioVolumeEnable 音量使能(仅设置一次即可) + */ + void setVolumeEnable(bool bEnable); + /** + * @brief setColumnWidth 设置列宽 + * @param column 列 + * @param width 宽 + */ + void setColumnWidth(const int &column, const int &width); + /** + * @brief setColumnAlign 设置列对其方式 + * @param column 列 + * @param alignFlag 1-AlignLeft; 2-AlignRight; other-AlignHCenter + */ + void setColumnAlign(const int &column, const int &alignFlag); + /** + * @brief setEnableTrend 设置是否显示趋势图标 (程序默认显示) + * @param isNeed true-显示 false-不显示 + */ + void setEnableTrend(bool isNeed =true); + /** + * @brief setEnableVideo 设置是否显示视频图标 (程序默认显示) + * @param isNeed true-显示 false-不显示 + */ + void setEnableVideo(bool isNeed =true); + /** + * @brief setEnableWave 设置是否显示录波图标(程序默认显示) + * @param isNeed true-显示 false-不显示 + */ + void setEnableWave(bool isNeed = true); + /** + * @brief setEnableLevel 设置是否显示等级图标 (程序默认不显示) + * @param isNeed true-显示 false-不显示 + */ + void setEnableLevel(bool isNeed =true); + /** + * @brief getDevAlmInfo 获取设备告警信息 + * @param device 设备 + * @return QString 格式为: 告警等级_告警数量 ex:1_2 含义为 告警等级为1的告警数为2 + */ + QStringList getDevAlmInfo(const QString device); + /** + * @brief getDevGroupAlmInfo 获取设备组下每个告警等级的设备数量 + * @param deviceGroup 设备组 + * @return QString 格式为: 告警等级_设备数量 ex:1_23 含义为 告警等级为1的设备数量为23 + */ + QStringList getDevGroupAlmInfo(const QString deviceGroup); + /** + * @brief getLocAlmInfo 获取车站告警数量(优先级分组) + * @return QString 格式为: 车站id_告警等级_告警数量 ex:1_1_23 含义为 车站1告警等级为1的告警数量为23 + */ + QStringList getLocAlmInfo(); + /** + * @brief getLocNotConfirmAlmCount 获取位置的未确认告警条数 + * @param loc 位置id + * @return 未确认告警条数 + */ + int getLocNotConfirmAlmCount(int loc); + /** + * @brief getDevgNotConfirmAlmCount 获取设备组的未确认告警条数 + * @param devg 设备组 + * @return 未确认告警条数数 + */ + int getDevgNotConfirmAlmCount(const QString & devg); + /***************************************************************************/ + + /****************以下接口仅针对E_Alarm_Window模式[告警大窗]有效********************/ + /** + * @brief setEnableAccidentReview 设置告警大窗右键是否显示事故追忆 + * @param isNeed isNeed true-显示 false-不显示 (程序默认显示) + */ + void setEnableAccidentReview(bool isNeed = true); + /** + * @brief setAccidentReviewPath 设置事故追忆画面选择对话框路径 相对于pic + * @param path + */ + void setAccidentReviewPath(const QString& path); + /** + * @brief setShowAiAlarmView 设置第一次是否显示智能告警(根据是否启用智能告警,一般不需要调用) + * @param show true-显示 false-不显示 (根据是否启用智能告警) 不配置智能告警调用显示也无效 + */ + void setShowAiAlarmView(bool show = true); + /** + * @brief setHiddenLocation 设置是否在告警大窗顶部隐藏车站过滤 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenLocation(bool hide); + /** + * @brief setHiddenTime 设置是否在告警大窗顶部隐藏时间过滤 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenTime(bool hide); + /** + * @brief setHiddenStatus 设置是否在告警大窗顶部隐藏状态过滤 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenStatus(bool hide); + /** + * @brief setHiddenPriority 设置是否在告警大窗顶部隐藏优先级过滤 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenPriority(bool hide); + /** + * @brief setHiddenCheckBox 设置是否在告警大窗顶部隐藏智能告警勾选框 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenCheckBox(bool hide); + /** + * @brief setHiddenSetConfig 设置是否隐藏设置按钮 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenSetConfig(bool hide); + /** + * @brief setHiddenCloseButton 设置是否隐藏关闭按钮 + * @param hide true-隐藏 false-不隐藏(程序默认不隐藏) + */ + void setHiddenCloseButton(bool hide); + + /** + * @brief setHiddenInhiAlarmButton 设置是否隐藏禁止告警按钮 + * @param hide true-隐藏 false-不隐藏(程序默认隐藏) + */ + void setHiddenInhiAlarmButton(bool hide); + + /** + * @brief setHiddenSelectButton 设置是否隐藏全选,全不选按钮 + * @param hide true-隐藏 false-不隐藏(程序默认隐藏) + */ + void setHiddenSelectButton(bool hide); + + /** + * @brief setFormColumnVisible 设置列是否显示 + * @param column 列 + * @param visible true-显示 false-不显示 + */ + void setFormColumnVisible(const int &column, const bool &visible = true); + /***************************************************************************/ + + /****************以下接口仅针对E_Alarm_Dock模式[底部告警栏]有效********************/ + /** + * @brief confirmFirstAlarm 确认第一条告警 + * @param index 确认第几条(最大值为2) + */ + void confirmFirstAlarm(int index= 0); + /** + * @brief setDockRowHeight 设置行高 + * @param height 行高 + */ + void setDockRowHeight(const int &height); + /** + * @brief setDockColumnVisible 设置列是否显示 + * @param column 列 + * @param visbile true-显示 false-不显示 + */ + void setDockColumnVisible(const int &column, const bool &visbile = true); + /** + * @brief confirmAllPermAlarm 确认当前有权限的所有告警 + * @param tips true-确认后提示确认总数 false-确认后不需要提示确认总数 + * @return 确认总数 + */ + int confirmAllPermAlarm(bool tips = true); + /***************************************************************************/ + + /****************以下接口仅针对E_Alarm_Pop模式[设备对话框]有效********************/ + /** + * @brief setDevice 设置设备显示(已无效,保留只为兼容) + * @param device 设备 + */ + void setDevice(const QString &device); + + + /** + * @brief setDeviceGroup 设置设备组显示 + * @param deviceGroup 设备组 + */ + void setDeviceGroup(const QString &deviceGroup); + + /** + * @brief setPriorityFilter 设置优先级 + * @param deviceGroup 优先级 + */ + void setPriorityFilter(int PriorityFilter); + + /** + * @brief setPointTag 设置点过滤(已无效,保留只为兼容) + * @param pointList 点集合 + */ + void setPointTag(const QString &pointList); + /** + * @brief setColumnVisible 设置列是否显示 + * @param column 列 + * @param visible true-显示 false-不显示 + */ + void setColumnVisible(const int &column, const bool &visible); + /** + * @brief currentSelectCount 获取选中的告警条数 + * @return 告警条数 + */ + int currentSelectCount(); + /** + * @brief confirmCurrentAlarm 确认当前告警 + */ + void confirmCurrentAlarm(); + /** + * @brief confirmAllAlarm 确认所有告警 + */ + void confirmAllAlarm(); + /** + * @brief removeAllAlarm 删除所有告警 + */ + void removeAllAlarm(); + + /***************************************************************************/ + /** + * @brief recvAlarmNumChanged 告警数量变化 + * @param total 总数 + * @param unConfirm 未确认数 + */ + void recvAlarmNumChanged(const int &total, const int &unConfirm); + +signals: + /** + * @brief alarmNumChanged 告警数量变化 + */ + void alarmNumChanged(const int &total, const int &unConfirm); //脚本更新数量 + /** + * @brief alarmPush 告警推图 + */ + void alarmPush(const QString &info); + /** + * @brief alarmPushClear 清空告警推图 + */ + void alarmPushClear(); + /** + * @brief alarmDockDoubleClicked 告警窗[Dock] 双击信号 + */ + void alarmDockDoubleClicked(); + /** + * @brief closeBtnClicked 告警窗[Window] 关闭按钮点击信号 + */ + void closeBtnClicked(); + /** + * @brief openVideoDialog 打开视频窗 + * @param domainId 域id + * @param appId 应用id + * @param tag 点标签 + * @param startTime 开始时间 + * @param endTime 结束时间 + */ + void openVideoDialog(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + /** + * @brief openTrendDialog 打开趋势窗口 + * @param time_stamp 时间戳 + * @param tagList 标签集合 + */ + void openTrendDialog(quint64 time_stamp,QStringList tagList); + /** + * @brief openAccidentReviewDialog 开始进行事故追忆 + * @param starTime 开始时间 + * @param keepTime 保持时间 + */ + void openAccidentReviewDialog(quint64 starTime,quint64 keepTime,QString graph=QString()); + /** + * @brief sigSwitchFaultRecallState 触发事故追忆(非hmi使用) + * @param bFaultRecallState true-事故追忆 false-非事故追忆 + */ + void sigSwitchFaultRecallState(bool bFaultRecallState); + + void sigLogin(); + +private slots: + /** + * @brief slotUpdateAlarmView 更新视图 + */ + void slotUpdateAlarmView(); + void slotUpdateAiAlarmView(); + /** + * @brief slotUpdateAlarmOperateEnable 更新界面告警操作接口 + * @param bEnable + */ + void slotUpdateAlarmOperateEnable(const bool &bEnable); + + void slotAllViewReload(); + +private: + + void loadConfig(); + + void reset(); + + void updateAlarmOperatePerm(); + +private: + E_Alarm_Mode m_mode; + bool m_bIsEditMode; + CAlarmForm * m_alarmForm; + CAlarmWidget * m_alarmWidget; + CAlarmView * m_alarmView; + CAlarmItemModel * m_pModel; + CAiAlarmTreeModel * m_pTreeModel; + int m_currentUsrId{}; + std::string m_currentNodeName; + std::vector m_vecRegionOptId; //告警操作权限责任区 + std::vector m_vecLocationOptId;//告警操作权限车站 + + std::vector m_vecRegionDelId; //告警删除权限责任区 + std::vector m_vecLocationDelId;//告警删除权限车站 + + //static int m_number; + static QThread * m_pDataCollectThread; + static QThread * m_pMediaPlayerThread; + bool m_enableAi; +}; + +#endif // CALARMPLUGIN_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmPluginWidget.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmPluginWidget.cpp new file mode 100644 index 00000000..d16db7e0 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmPluginWidget.cpp @@ -0,0 +1,29 @@ +#include +#include "CAlarmPluginWidget.h" +#include "CAlarmPlugin.h" +#include "pub_logger_api/logger.h" + +CAlarmPluginWidget::CAlarmPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CAlarmPluginWidget::~CAlarmPluginWidget() +{ + +} + +bool CAlarmPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CAlarmPlugin *pWidget = new CAlarmPlugin(parent, editMode); + pWidget->initialize((int)E_Alarm_Dock); + *widget = (QWidget *)pWidget; + *alarmWidget = (IPluginWidget *)pWidget; + return true; +} + +void CAlarmPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmPluginWidget.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmPluginWidget.h new file mode 100644 index 00000000..95196608 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmPluginWidget.h @@ -0,0 +1,22 @@ +#ifndef CALARMPLUGINWIDGET_H +#define CALARMPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CAlarmPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) + Q_INTERFACES(CPluginWidgetInterface) + +public: + CAlarmPluginWidget(QObject *parent = 0); + ~CAlarmPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **alarmWidget, QVector ptrVec); + void release(); +}; + +#endif //CALARMPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetDlg.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetDlg.cpp new file mode 100644 index 00000000..4c9675e2 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetDlg.cpp @@ -0,0 +1,429 @@ +#include "CAlarmSetDlg.h" +#include "ui_CAlarmSetDlg.h" +#include +#include "pub_utility_api/FileUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CAlarmColorWidget.h" +#include +#include "pub_logger_api/logger.h" +#include "pub_utility_api/FileStyle.h" +#include +#include "CAlarmCommon.h" + +CAlarmSetDlg::CAlarmSetDlg(QWidget *parent) : + QDialog(parent), + ui(new Ui::CAlarmSetDlg), + m_pTextToSpeech(Q_NULLPTR) +{ + ui->setupUi(this); + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + init(); + ui->label->installEventFilter(this); + ui->label_2->installEventFilter(this); + ui->label_7->installEventFilter(this); + connect(ui->pushButton_20,&QPushButton::clicked,this,&CAlarmSetDlg::save); + connect(ui->pushButton_21,&QPushButton::clicked,this,&CAlarmSetDlg::cancle); + connect(ui->radioButton,&QRadioButton::clicked,this,&CAlarmSetDlg::soundClicked); + connect(ui->radioButton_2,&QRadioButton::clicked,this,&CAlarmSetDlg::voiceClicked); + ui->alarmStyle->setView(new QListView()); + ui->engine->setView(new QListView()); + ui->language->setView(new QListView()); + ui->voiceName->setView(new QListView()); +} + +CAlarmSetDlg::~CAlarmSetDlg() +{ + delete ui; +} + +void CAlarmSetDlg::engineSelected(int index) +{ + disconnect(ui->language, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::languageSelected); + ui->language->clear(); + disconnect(ui->voiceName, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::voiceSelected); + ui->voiceName->clear(); + + QString engineName = ui->engine->itemData(index).toString(); + if(m_pTextToSpeech != Q_NULLPTR) + { + delete m_pTextToSpeech; + m_pTextToSpeech = Q_NULLPTR; + } + + m_engine = engineName; + + if(m_engine == "default") + { +#ifdef OS_LINUX + m_pTextToSpeech = Q_NULLPTR; + return; +#else + m_pTextToSpeech = new QTextToSpeech(this); +#endif + }else + { + m_pTextToSpeech = new QTextToSpeech(m_engine,this); + } + +// disconnect(ui->language, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::languageSelected); +// ui->language->clear(); + QVector locales = m_pTextToSpeech->availableLocales(); + QLocale current = m_pTextToSpeech->locale(); + + foreach (const QLocale &locale, locales) { + QString name(QString("%1 (%2)") + .arg(QLocale::languageToString(locale.language())) + .arg(QLocale::countryToString(locale.country()))); + QVariant localeVariant(locale); + ui->language->addItem(name, locale.name()); + if (locale.name() == m_language) + current = locale; + } + + connect(ui->language, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::languageSelected); + localeChanged(current); +} + +void CAlarmSetDlg::languageSelected(int language) +{ + QLocale locale = ui->language->itemData(language).toLocale(); + m_pTextToSpeech->setLocale(locale); +} + +void CAlarmSetDlg::localeChanged(const QLocale &locale) +{ + QVariant localeVariant(locale); + ui->language->setCurrentIndex(ui->language->findData(QVariant(locale.name()))); + + disconnect(ui->voiceName, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::voiceSelected); + ui->voiceName->clear(); + + m_voices = m_pTextToSpeech->availableVoices(); + QVoice currentVoice = m_pTextToSpeech->voice(); + foreach (const QVoice &voice, m_voices) { + ui->voiceName->addItem(QString("%1 - %2 - %3").arg(voice.name()) + .arg(QVoice::genderName(voice.gender())) + .arg(QVoice::ageName(voice.age())),voice.name()); + if (voice.name() == m_voiceName) + ui->voiceName->setCurrentIndex(ui->voiceName->count() - 1); + } + connect(ui->voiceName, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::voiceSelected); +} + +void CAlarmSetDlg::voiceSelected(int index) +{ + m_pTextToSpeech->setVoice(m_voices.at(index)); +} + +void CAlarmSetDlg::init() +{ + CAlarmSetMng::instance()->getColorMap(m_colorMap); + CAlarmSetMng::instance()->getSelectInfo(m_selectIsEmpty,m_select_background_color,m_select_text_color); + CAlarmSetMng::instance()->getEmptyInfo(m_emptyBackgroundColor,m_emptyTipColor,m_emptyTip); + CAlarmSetMng::instance()->getActAndNum(m_act,m_num,m_style); + CAlarmSetMng::instance()->getEngine(m_engine,m_language,m_voiceName); + + ui->alarmStyle->addItem(tr("不报"), E_STYLE_NO_ALARM); + ui->alarmStyle->addItem(tr("重复"), E_STYLE_REPEAT); + ui->alarmStyle->addItem(tr("重复x次"), E_STYLE_REPEAT_X); + initView(); + connect(ui->alarmStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(styleChanged(int))); + emit ui->alarmStyle->currentIndexChanged(ui->alarmStyle->currentIndex()); +} + +void CAlarmSetDlg::initView() +{ + if(m_act == 0) + { + ui->radioButton->setChecked(true); + ui->radioButton_2->setChecked(false); + soundClicked(true); + }else + { + ui->radioButton->setChecked(false); + ui->radioButton_2->setChecked(true); + voiceClicked(true); + } + int style = ui->alarmStyle->findData(m_style); + if(style != -1) + { + ui->alarmStyle->setCurrentIndex(style); + } + ui->spinBox->setValue(m_num); + QMap::iterator it= m_colorMap.begin(); + QVBoxLayout *vlayout = new QVBoxLayout(ui->widget_2); + while (it!=m_colorMap.end()) { + CAlarmColorWidget *form = new CAlarmColorWidget(&(it.value()),this); + vlayout->addWidget(form); + it++; + } + ui->widget_2->setContentsMargins(0,0,0,0); + ui->widget_2->setLayout(vlayout); + + ui->label->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(m_select_text_color.red()).arg(m_select_text_color.green()).arg(m_select_text_color.blue())); + ui->label_2->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(m_emptyTipColor.red()).arg(m_emptyTipColor.green()).arg(m_emptyTipColor.blue())); + ui->label_7->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(m_select_background_color.red()).arg(m_select_background_color.green()).arg(m_select_background_color.blue())); + + ui->engine->addItem("default", QString("default")); + QStringList engineList; +#ifdef OS_LINUX + //< TODO: centos选择语音告警,打开QtAV相关程序(IpcPluginWidget等)卡死。暂时隐藏。 +#else + engineList = QTextToSpeech::availableEngines(); + if(engineList.isEmpty()) + { + return; + } + foreach (QString engine, engineList) + { + ui->engine->addItem(engine, engine); + } +#endif + + if(m_engine.isEmpty() || !engineList.contains(m_engine)) + { + m_engine = "default"; + } + ui->engine->setCurrentText(m_engine); + + int index= ui->engine->currentIndex(); + engineSelected(index); + connect(ui->engine, static_cast(&QComboBox::currentIndexChanged), this, &CAlarmSetDlg::engineSelected); + +} + +bool CAlarmSetDlg::eventFilter(QObject *obj, QEvent *event) +{ + if(obj == ui->label) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label, &m_select_text_color); + }else + { + return false; + } + }else + { + return false; + } + }else if(obj == ui->label_2) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label_2, &m_emptyTipColor); + }else + { + return false; + } + }else + { + return false; + } + }else if(obj == ui->label_7) + { + if(event->type() == QMouseEvent::MouseButtonPress) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + chooseColor(ui->label_7, &m_select_background_color); + }else + { + return false; + } + }else + { + return false; + } + }else + { + return QWidget::eventFilter(obj,event); + } + return true; +} + +void CAlarmSetDlg::chooseColor(QLabel *label, QColor *color) +{ + QColor newColor=QColorDialog::getColor(*color,this); + if(newColor.isValid()){ + *color=newColor; + updateColorLabel(label,*color); + } +} + +void CAlarmSetDlg::updateColorLabel(QLabel *label, const QColor &color) +{ + label->setStyleSheet(QString("background-color: rgb(%1, %2, %3);").arg(color.red()).arg(color.green()).arg(color.blue())); + if(label == ui->label) + { + m_select_text_color = color; + }else if(label == ui->label_2) + { + m_emptyTipColor = color; + }else if(label == ui->label_7) + { + m_select_background_color = color; + } +} + +bool CAlarmSetDlg::saveXML() +{ + m_engine = ui->engine->currentData().toString(); + m_language = ui->language->currentData().toString(); + m_voiceName = ui->voiceName->currentData().toString(); + //写文本 + QString sFileName = QCoreApplication::applicationDirPath() + "/../../data/model/alarm_color_define.xml"; + QFile oFile( sFileName ); + if ( !oFile.exists() ) + { + QMessageBox::critical( 0, "错误", QString("配置文件【%1】不存在,保存失败").arg(sFileName) ); + return false; + } + if ( !oFile.open(QIODevice::WriteOnly | QIODevice::Text) ) + { + QMessageBox::critical( 0, "错误", QString("配置文件【%1】打开失败,保存失败").arg(sFileName) ); + return false; + } + m_num = ui->spinBox->value(); + QXmlStreamWriter writer(&oFile); + writer.setAutoFormatting(true); + writer.writeStartDocument(); + writer.writeStartElement("profile"); + + writer.writeStartElement("Flash"); + writer.writeAttribute( "alternate" ,QString::number(0)); + writer.writeEndElement(); + + QMap::iterator it= m_colorMap.begin(); + + while (it!=m_colorMap.end()) { + writer.writeStartElement("Level"); + writer.writeAttribute( "priority" ,QString::number(it.key())); + writer.writeAttribute( "background_color" ,"transparent"); + writer.writeAttribute( "alternating_color" ,it.value().alternating_color.name()); + writer.writeAttribute( "confirm_color" ,"transparent"); + writer.writeAttribute( "active_text_color" ,it.value().active_text_color.name()); + writer.writeAttribute( "resume_text_color" ,it.value().resume_text_color.name()); + writer.writeAttribute( "confirm_text_color" ,it.value().confirm_text_color.name()); + writer.writeAttribute( "icon" ,it.value().icon); + writer.writeEndElement(); + it++; + } + writer.writeStartElement("Select"); + writer.writeAttribute( "background_color" ,m_select_background_color.name()); + writer.writeAttribute( "text_color" ,m_select_text_color.name()); + writer.writeEndElement(); + + writer.writeStartElement("NoItem"); + writer.writeAttribute( "background_color" ,"transparent"); + writer.writeAttribute( "tips_color" ,m_emptyTipColor.name()); + writer.writeAttribute( "tips" ,m_emptyTip); + writer.writeEndElement(); + + writer.writeStartElement("Alarm"); + writer.writeAttribute( "act" ,QString::number(m_act)); + writer.writeAttribute("actDesc","0-声音告警 1-语音告警"); + writer.writeAttribute( "num" ,QString::number(m_num)); + writer.writeAttribute("style",QString::number(m_style)); + writer.writeEndElement(); + + writer.writeStartElement("VoiceEngine"); + writer.writeAttribute( "engine" ,m_engine); + writer.writeAttribute( "language" ,m_language); + writer.writeAttribute( "voice_name" ,m_voiceName); + writer.writeEndElement(); + writer.writeEndElement(); + return true; +} + +void CAlarmSetDlg::soundClicked(bool checked) +{ + if(checked) + { + m_act = 0; + } + ui->engine->setEnabled(!checked); + ui->language->setEnabled(!checked); + ui->voiceName->setEnabled(!checked); +} + +void CAlarmSetDlg::voiceClicked(bool checked) +{ + if(checked) + { + m_act = 1; + } + ui->engine->setEnabled(checked); + ui->language->setEnabled(checked); + ui->voiceName->setEnabled(checked); +} + + +void CAlarmSetDlg::save() +{ + if(saveXML()) + { + CAlarmSetMng::instance()->setColorMap(m_colorMap); + m_selectIsEmpty = false; + CAlarmSetMng::instance()->setSelectInfo(m_selectIsEmpty,m_select_background_color,m_select_text_color); + CAlarmSetMng::instance()->setEmptyInfo(m_emptyBackgroundColor,m_emptyTipColor,m_emptyTip); + CAlarmSetMng::instance()->setActAndNum(m_act,m_num,m_style); + CAlarmSetMng::instance()->setEngine(m_engine,m_language,m_voiceName); + CAlarmSetMng::instance()->sigUpdateColor(); + accept(); + } +} + +void CAlarmSetDlg::cancle() +{ + reject(); +} + +void CAlarmSetDlg::styleChanged(int index) +{ + Q_UNUSED(index) + m_style = ui->alarmStyle->currentData().toInt(); + if(E_STYLE_REPEAT_X == m_style) + { + ui->spinBox->setEnabled(true); + } + else + { + ui->spinBox->setEnabled(false); + } +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetDlg.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetDlg.h new file mode 100644 index 00000000..0d043a34 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetDlg.h @@ -0,0 +1,72 @@ +#ifndef CALARMSETDLG_H +#define CALARMSETDLG_H + +#include +#include "CAlarmColorInfo.h" +#include "CAlarmSetMng.h" +#include +#include +namespace Ui { +class CAlarmSetDlg; +} + +class CAlarmSetDlg : public QDialog +{ + Q_OBJECT + +public: + explicit CAlarmSetDlg(QWidget *parent = 0); + ~CAlarmSetDlg(); + +public slots: + void engineSelected(int index); + + void languageSelected(int language); + void localeChanged(const QLocale &locale); + void voiceSelected(int index); + +private: + void init(); + void initView(); + + bool eventFilter(QObject *obj, QEvent *event); + +private: + void chooseColor(QLabel *label, QColor *color); + void updateColorLabel(QLabel *label, const QColor &color); + + bool saveXML(); + +private slots: + + void soundClicked(bool checked); + + void voiceClicked(bool checked); + + void save(); + + void cancle(); + + void styleChanged(int index); + +private: + Ui::CAlarmSetDlg *ui; + QTextToSpeech *m_pTextToSpeech; + QMap m_colorMap; + QColor m_select_background_color,m_select_text_color; //选中告警背景色和文字颜色 + bool m_selectIsEmpty; + + QColor m_emptyBackgroundColor,m_emptyTipColor; + QString m_emptyTip; + int m_act; + int m_num; + int m_style; + + QString m_engine; + QString m_language; + QString m_voiceName; + + QVector m_voices; +}; + +#endif // CALARMSETDLG_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetDlg.ui b/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetDlg.ui new file mode 100644 index 00000000..8cec9d25 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetDlg.ui @@ -0,0 +1,354 @@ + + + CAlarmSetDlg + + + + 0 + 0 + 699 + 406 + + + + 设置 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 动作选择 + + + + + + 声音告警 + + + + + + + 语音告警 + + + + + + + + + + 告警方式 + + + + + + 方式 + + + + + + + + 0 + 0 + + + + + + + + 次数 + + + + + + + + 0 + 0 + + + + -1 + + + -1 + + + + + + + + + + + + 优先级颜色选择 + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + + 0 + 0 + + + + + + + + + + + + + <html><head/><body><p>选中告警时,告警的文字颜色</p></body></html> + + + 选中文字颜色 + + + + + + 颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + + + + <html><head/><body><p>选中告警时,告警的背景颜色</p></body></html> + + + 选中背景颜色 + + + + + + 颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + + + + <html><head/><body><p>无告警时,告警小窗中&quot;当前无告警&quot;文字颜色</p></body></html> + + + 无告警文字颜色 + + + + + + 颜色 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + + + + + + + + + + + + + 语音引擎 + + + + + + + 0 + 0 + + + + 引擎 + + + + + + + 语言 + + + + + + + 语音名称 + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + + + Qt::Horizontal + + + + 220 + 20 + + + + + + + + 确定 + + + + + + + 取消 + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetMng.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetMng.cpp new file mode 100644 index 00000000..2d3d464b --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetMng.cpp @@ -0,0 +1,200 @@ +#include "CAlarmSetMng.h" +#include +#include "pub_logger_api/logger.h" +#include +#include "pub_utility_api/FileUtil.h" +#include "CAlarmBaseData.h" + +using namespace iot_public; +using namespace std; + +CAlarmSetMng *CAlarmSetMng::pInstance = NULL; + + +CAlarmSetMng *CAlarmSetMng::instance() +{ + if(pInstance == NULL) + { + pInstance = new CAlarmSetMng(); + } + return pInstance; +} + +CAlarmSetMng::~CAlarmSetMng() +{ + LOGDEBUG("CAlarmSetMng::~CAlarmSetMng()"); +} + +bool CAlarmSetMng::isBindMediaPlayer() +{ + return isSignalConnected(QMetaMethod::fromSignal(&CAlarmSetMng::sigLoadConfig)); +} + +CAlarmSetMng::CAlarmSetMng() + : QObject() +{ + mutex = new QMutex(); + m_priorityOrderDescriptionMap = CAlarmBaseData::instance()->getPriorityOrderMap(); + loadXMLCfg(); +} + +void CAlarmSetMng::loadXMLCfg() +{ + m_colorMap.clear(); + QString filePath = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/alarm_color_define.xml"); + QDomDocument document; + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement element = document.documentElement(); + QDomNode node = element.firstChild(); + while(!node.isNull()) + { + QDomElement attr = node.toElement(); + if(!attr.isNull()) + { + if(QString("Level") == attr.tagName()) + { + CAlarmColorInfo info; + info.priority = attr.attribute("priority").toInt(); + info.background_color = QColor(attr.attribute("background_color")); + info.alternating_color = QColor(attr.attribute("alternating_color")); + info.confirm_color = QColor(attr.attribute("confirm_color")); + + info.active_text_color = QColor(attr.attribute("active_text_color")); + info.confirm_text_color = QColor(attr.attribute("confirm_text_color")); + info.resume_text_color = QColor(attr.attribute("resume_text_color")); + info.icon = attr.attribute("icon"); + m_colorMap[info.priority] = info; + } + else if(QString("Select") == attr.tagName()) + { + m_select_background_color = QColor(attr.attribute("background_color")); + if(attr.attribute("text_color").isEmpty()) + { + m_selectIsEmpty = true; + }else + { + m_selectIsEmpty = false; + m_select_text_color = QColor(attr.attribute("text_color")); + } + } + else if(QString("NoItem") == attr.tagName()) + { + m_emptyBackgroundColor = QColor(attr.attribute("background_color")); + m_emptyTipColor = QColor(attr.attribute("tips_color")); + m_emptyTip = tr("当前无告警!"); + }else if(QString("Alarm") == attr.tagName()) + { + m_act =attr.attribute("act").toInt(); + m_actDesc = attr.attribute("actDesc"); + m_num =attr.attribute("num").toInt(); + m_style = attr.attribute("style").toInt(); + }else if(QString("VoiceEngine") == attr.tagName()) + { + m_engine = attr.attribute("engine"); + m_language = attr.attribute("language"); + m_voiceName = attr.attribute("voice_name"); + } + } + node = node.nextSibling(); + } +} + +void CAlarmSetMng::destory() +{ + pInstance = NULL; + deleteLater(); +} + +void CAlarmSetMng::getPriorityInfo(QMap &priorityOrderDescriptionMap) +{ + priorityOrderDescriptionMap.clear(); + priorityOrderDescriptionMap = m_priorityOrderDescriptionMap; +} + +void CAlarmSetMng::getColorMap(QMap &colorMap) +{ + colorMap.clear(); + colorMap = m_colorMap; +} + +void CAlarmSetMng::getSelectInfo(bool &selectIsEmpty, QColor &select_background_color, QColor &select_text_color) +{ + selectIsEmpty = m_selectIsEmpty; + select_background_color = m_select_background_color; + select_text_color = m_select_text_color; +} + +void CAlarmSetMng::getEmptyInfo(QColor &emptyBackgroundColor, QColor &emptyTipColor, QString &emptyTip) +{ + emptyBackgroundColor = m_emptyBackgroundColor; + emptyTipColor = m_emptyTipColor; + emptyTip = m_emptyTip; +} + +void CAlarmSetMng::getActAndNum(int &act, int &num, int &style) +{ + act = m_act; + num = m_num; + style = m_style; +} + +void CAlarmSetMng::getEngine(QString &engine, QString &language, QString &voiceName) +{ + engine = m_engine; + language = m_language; + voiceName = m_voiceName; +} + +QString CAlarmSetMng::getPriorityDescByOrder(int order) +{ + return m_priorityOrderDescriptionMap.value(order,tr("未知告警等级")); +} + +void CAlarmSetMng::setColorMap(const QMap &colorMap) +{ + m_colorMap = colorMap; +} + +void CAlarmSetMng::setSelectInfo(const bool &selectIsEmpty,const QColor &select_background_color,const QColor &select_text_color) +{ + m_selectIsEmpty = selectIsEmpty; + m_select_background_color = select_background_color; + m_select_text_color = select_text_color; +} + +void CAlarmSetMng::setEmptyInfo(const QColor &emptyBackgroundColor, const QColor &emptyTipColor, const QString &emptyTip) +{ + m_emptyBackgroundColor= emptyBackgroundColor; + m_emptyTipColor = emptyTipColor; + m_emptyTip = emptyTip; +} + +void CAlarmSetMng::setActAndNum(const int &act, const int &num, const int &style) +{ + m_act = act; + m_num = num; + m_style = style; +} + +void CAlarmSetMng::setEngine(const QString &engine, const QString &language, const QString &voiceName) +{ + m_engine = engine; + m_language = language; + m_voiceName = voiceName; +} + +void CAlarmSetMng::sigUpdateColor() +{ + emit sigLoadConfig(); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetMng.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetMng.h new file mode 100644 index 00000000..c5f33a8c --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmSetMng.h @@ -0,0 +1,90 @@ +#ifndef CALARMSETMNG_H +#define CALARMSETMNG_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include +#include +#include "CAlarmColorInfo.h" + +class CAlarmSetMng : public QObject +{ + Q_OBJECT +public: + static CAlarmSetMng * instance(); + ~CAlarmSetMng(); + + void initialize(); + + bool isBindMediaPlayer(); + +signals: + void sigLoadConfig(); + +private: + + CAlarmSetMng(); + + void loadXMLCfg(); + +public slots: + void destory(); + + void sigUpdateColor(); + +public: + + void getPriorityInfo(QMap &priorityOrderDescriptionMap); + + void getColorMap(QMap &colorMap); + + void getSelectInfo(bool &selectIsEmpty,QColor &select_background_color,QColor &select_text_color); + + void getEmptyInfo(QColor &emptyBackgroundColor, QColor &emptyTipColor, QString &emptyTip); + + void getActAndNum(int &act,int &num, int &style); + + void getEngine(QString &engine,QString &language,QString &voiceName); + + QString getPriorityDescByOrder(int order); + + void setColorMap(const QMap &colorMap); + + void setSelectInfo(const bool &selectIsEmpty,const QColor &select_background_color,const QColor &select_text_color); + + void setEmptyInfo(const QColor &emptyBackgroundColor, const QColor &emptyTipColor, const QString &emptyTip); + + void setActAndNum(const int &act,const int &num,const int &style); + + void setEngine(const QString &engine,const QString &language,const QString &voiceName); + + + + +private: + QMutex * mutex; + static CAlarmSetMng * pInstance; + + + iot_dbms::CRdbAccess * m_rtdbAccess; + + QMap m_priorityOrderDescriptionMap; + + QMap m_colorMap; + QColor m_select_background_color,m_select_text_color; //选中告警背景色和文字颜色 + bool m_selectIsEmpty; + + QColor m_emptyBackgroundColor,m_emptyTipColor; + QString m_emptyTip; + int m_act; + int m_num; + + QString m_actDesc; + int m_style; + + QString m_engine; + QString m_language; + QString m_voiceName; +}; + +#endif // CALARMSETMNG_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmShiledDialog.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmShiledDialog.cpp new file mode 100644 index 00000000..9c6e8ad9 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmShiledDialog.cpp @@ -0,0 +1,118 @@ +#include "CAlarmShiledDialog.h" +#include "ui_CAlarmShiledDialog.h" +#include +#include +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" +#include +#include + +CAlarmShiledDialog::CAlarmShiledDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CAlarmShiledDialog), + m_pWidget(Q_NULLPTR), + m_pPluginWidget(Q_NULLPTR) +{ + ui->setupUi(this); + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("alarm.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + m_pWidget = createCustomWidget("DataOptWidget"); + QGridLayout *layout = new QGridLayout(this); + layout->addWidget(m_pWidget); + layout->setContentsMargins(0,0,0,0); + ui->shield_frame->setLayout(layout); + +} + +CAlarmShiledDialog::~CAlarmShiledDialog() +{ + if(m_pWidget) + { + delete m_pWidget; + } + m_pWidget = Q_NULLPTR; + if(m_pPluginWidget) + { + + } + delete ui; +} + +QWidget *CAlarmShiledDialog::createCustomWidget(const QString &name) +{ + QWidget *customWidget = NULL; + QString fileName; + QString path; + + try + { +#ifdef OS_WINDOWS + fileName = name; + fileName += ".dll"; +#else + if (name.contains(QRegExp("^lib"))) + { + fileName = name; + } + else + { + fileName += "lib"; + fileName += name; + } + fileName += ".so"; +#endif + std::string filePath = iot_public::CFileUtil::getPathOfBinFile(fileName.toStdString()); + path = QString::fromStdString(filePath); + QPluginLoader loader(path); + QObject *plugin = loader.instance(); + if (plugin) + { + CPluginWidgetInterface *plugInInterface = qobject_cast(plugin); + if (plugInInterface) + { + QVector ptrVect/* = getScene()->getDataAccess()->getPtr()*/; + void *d= NULL; + ptrVect.push_back(d); + + plugInInterface->createWidget(this, false, &customWidget, + &m_pPluginWidget, ptrVect); + + } + + } + else + { + } + + if (!customWidget) + { + customWidget = new QPushButton(tr("未找到插件"), this); + } + + return customWidget; + } + catch (...) + { + customWidget = new QPushButton(tr("装载异常"), this); + return customWidget; + } +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmShiledDialog.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmShiledDialog.h new file mode 100644 index 00000000..8f51ead1 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmShiledDialog.h @@ -0,0 +1,28 @@ +#ifndef CALARMSHILEDDIALOG_H +#define CALARMSHILEDDIALOG_H + +#include +#include "../AlarmShieldWidget/CAlarmShield.h" +#include "GraphShape/CPluginWidget.h" +namespace Ui { +class CAlarmShiledDialog; +} + +class CAlarmShiledDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CAlarmShiledDialog(QWidget *parent = nullptr); + ~CAlarmShiledDialog(); + +private: + QWidget *createCustomWidget(const QString &name); +private: + Ui::CAlarmShiledDialog *ui; + + QWidget *m_pWidget ; + IPluginWidget *m_pPluginWidget; +}; + +#endif // CALARMSHILEDDIALOG_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmShiledDialog.ui b/product/src/gui/plugin/AlarmWidget_pad/CAlarmShiledDialog.ui new file mode 100644 index 00000000..1f469ad3 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmShiledDialog.ui @@ -0,0 +1,49 @@ + + + CAlarmShiledDialog + + + + 0 + 0 + 1261 + 542 + + + + 禁止告警 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmTaskMngDlg.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmTaskMngDlg.cpp new file mode 100644 index 00000000..24f64284 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmTaskMngDlg.cpp @@ -0,0 +1,134 @@ +#include "CAlarmTaskMngDlg.h" +#include "ui_CAlarmTaskMngDlg.h" +#include +#include +#include + + +const int viewTaskHeight = 500; +const int viewTaskWidth = 540; + +CAlarmTaskMngDlg::CAlarmTaskMngDlg(AlarmMsgPtr info, QWidget *parent) : + QDialog(parent), + ui(new Ui::CAlarmTaskMngDlg), + m_info(info) +{ + setWindowFlags (windowFlags () & (~Qt::WindowContextHelpButtonHint)); + ui->setupUi(this); + initUi(); +} + +CAlarmTaskMngDlg::~CAlarmTaskMngDlg() +{ + delete ui; + delete m_view; +} + +void CAlarmTaskMngDlg::initUi() +{ + this->resize(this->width(),ui->label->height()); + ui->btnCreat->setHidden(true); + ui->btnViewProp->setHidden(true); + ui->btnViewTsk->setHidden(true); + ui->widget->setHidden(true); + m_view = new QWebEngineView(this); + QGridLayout* layout = new QGridLayout; + ui->widget->setLayout(layout); + layout->setContentsMargins(0,0,0,0); + layout->addWidget(m_view); + + if(!m_idongSrvApi.isValid()) + { + QMessageBox::information(this,tr("提醒"),tr("艾动接口初始化失败")); + return; + } + + std::string templateUUid; + if(!m_idongSrvApi.getTaskTemplate(m_info->key_id_tag.toStdString(),templateUUid)) + { + ui->labelTskGrpSts->setText(tr("未关联作业组,请先关联作业组")); + ui->btnCreat->setHidden(true); + return; + } + showTaskGrpStatus(); +} + +void CAlarmTaskMngDlg::showTaskGrpStatus() +{ + int status; + if(!m_idongSrvApi.getTaskGrpStatus(m_info->uuid_base64.toStdString(),status)) + { + LOGERROR("cannot get task group status"); + ui->labelTskGrpSts->setText("未能获取到作业组状态信息,请先创建作业组"); + ui->btnCreat->setHidden(false); + return; + } + + if(status >= 2) + { + ui->btnViewTsk->setHidden(false); + } + switch (status) { + case 2: + ui->labelTskGrpSts->setText("已发布"); + break; + case 3: + ui->labelTskGrpSts->setText("已创建"); + break; + case 4: + ui->labelTskGrpSts->setText("已执行"); + break; + case 5: + ui->labelTskGrpSts->setText("已延期"); + break; + case 6: + ui->labelTskGrpSts->setText("已过期"); + break; + case 7: + ui->labelTskGrpSts->setText("已超时"); + break; + default: + break; + } + +} + + +void CAlarmTaskMngDlg::on_btnCreat_clicked() +{ + std::string templateUUid; + if(!m_idongSrvApi.getTaskTemplate(m_info->key_id_tag.toStdString(),templateUUid)) + { + ui->labelTskGrpSts->setText(tr("未关联作业组,请先关联作业组")); + return; + } + if(m_idongSrvApi.createTaskGroupEx(m_info->uuid_base64.toStdString(),templateUUid,(m_info->content + "__巡检").toStdString())) + { + QMessageBox::information(this,tr("提醒"),tr("创建作业组成功")); + + /** + 展示成功画面,状态显示,那七个状态,然后,显示展示按钮。 + **/ + showTaskGrpStatus(); + ui->btnCreat->setHidden(true); + }else + { + QMessageBox::information(this,tr("提醒"),tr("创建作业组失败")); + } +} + +void CAlarmTaskMngDlg::on_btnViewTsk_clicked() +{ + this->resize(viewTaskWidth,viewTaskHeight); + QString urlDst; + if(!m_idongSrvApi.getTaskGrpLink(m_info->uuid_base64.toStdString(),urlDst)) + { + QMessageBox::information(this,tr("提醒"),tr("获取作业组信息失败")); + return; + } + LOGINFO("作业组链接:%s",QUrl::fromPercentEncoding(urlDst.toStdString().c_str()).toStdString().c_str()); + m_view->load( urlDst ); + ui->widget->setHidden(false); + ui->btnViewTsk->setHidden(true); + +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmTaskMngDlg.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmTaskMngDlg.h new file mode 100644 index 00000000..24fe3b5e --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmTaskMngDlg.h @@ -0,0 +1,37 @@ +#ifndef CALARMTASKMNGDLG_H +#define CALARMTASKMNGDLG_H + +#include +#include "CAlarmCommon.h" +#include "application/idong_srv_api/CIDongSrvApi.h" +#include + + +namespace Ui { +class CAlarmTaskMngDlg; +} + +class CAlarmTaskMngDlg : public QDialog +{ + Q_OBJECT + +public: + explicit CAlarmTaskMngDlg(AlarmMsgPtr info,QWidget *parent = 0); + ~CAlarmTaskMngDlg(); + +private slots: + void on_btnCreat_clicked(); + + void on_btnViewTsk_clicked(); + +private: + void initUi(); + void showTaskGrpStatus(); + + Ui::CAlarmTaskMngDlg *ui; + AlarmMsgPtr m_info; + CIDongSrvApi m_idongSrvApi; + QWebEngineView *m_view; +}; + +#endif // CALARMTASKMNGDLG_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmTaskMngDlg.ui b/product/src/gui/plugin/AlarmWidget_pad/CAlarmTaskMngDlg.ui new file mode 100644 index 00000000..69f2e40c --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmTaskMngDlg.ui @@ -0,0 +1,76 @@ + + + CAlarmTaskMngDlg + + + + 0 + 0 + 427 + 211 + + + + 工单管理 + + + + + + + + 作业组状态: + + + + + + + + 0 + 0 + + + + 未创建 + + + + + + + 创建作业组 + + + + + + + 查看作业组 + + + + + + + 查看资产 + + + + + + + + + + 0 + 0 + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmView.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmView.cpp new file mode 100644 index 00000000..0d573232 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmView.cpp @@ -0,0 +1,50 @@ +#include +#include +#include "CAlarmView.h" +#include + +CAlarmView::CAlarmView(QWidget *parent) + : QTableView(parent) +{ + +} + +void CAlarmView::initialize() +{ + setSortingEnabled(true); + setAlternatingRowColors(true); + //horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + verticalHeader()->setSectionResizeMode(QHeaderView::Interactive); + //horizontalHeader()->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); + //horizontalHeader()->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + setSelectionBehavior(QAbstractItemView::SelectRows); + + //horizontalHeader()->setMaximumWidth(800); + +// resizeColumnsToContents(); +// resizeRowsToContents(); +// for(int i=0;icount()-1;i++) +// resizeColumnToContents(i); + + horizontalHeader()->setStretchLastSection(true); + + resizeColumnsToContents(); + resizeRowsToContents(); + //setSelectionMode(QAbstractItemView::MultiSelection); + //setHorizontalScrollMode(ScrollPerPixel); + setAutoScroll(true); + horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); +} + +void CAlarmView::setDefaultRowHeight(int height) +{ + verticalHeader()->setDefaultSectionSize(height); +} + + +void CAlarmView::mouseDoubleClickEvent(QMouseEvent *event) +{ + emit alarmViewDoubleClicked(); + QTableView::mouseDoubleClickEvent(event); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmView.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmView.h new file mode 100644 index 00000000..a9ec519d --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmView.h @@ -0,0 +1,26 @@ +#ifndef CALARMVIEW_H +#define CALARMVIEW_H + +#include + +class CAlarmView : public QTableView +{ + Q_OBJECT +public: + CAlarmView(QWidget *parent = Q_NULLPTR); + + void initialize(); + + void setDefaultRowHeight(int height); +signals: + void alarmViewDoubleClicked(); + + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + + void openTrend(quint64 time_stamp,QStringList tagList); +protected: + void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + +}; + +#endif // ALARMVIEW_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmWidget.cpp b/product/src/gui/plugin/AlarmWidget_pad/CAlarmWidget.cpp new file mode 100644 index 00000000..af6644a4 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmWidget.cpp @@ -0,0 +1,435 @@ +#include "CAlarmWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include "CAlarmForm.h" +#include "CAlarmView.h" +#include "CAlarmMsgInfo.h" +#include "CAlarmItemModel.h" +#include "CAlarmDataCollect.h" +#include "CAlarmDelegate.h" +#include "perm_mng_api/PermMngApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include +#include +#include "pub_logger_api/logger.h" + +CAlarmWidget::CAlarmWidget(QWidget *parent) + : QWidget(parent), + m_pView(Q_NULLPTR), + m_pModel(Q_NULLPTR), + m_delegate(Q_NULLPTR), m_userId(0), + m_pConfirmButtonRow0(Q_NULLPTR), + m_pConfirmButtonRow1(Q_NULLPTR), + m_pConfirmButtonRow2(Q_NULLPTR) +{ + //initialize(); +} + +CAlarmWidget::~CAlarmWidget() +{ + if(Q_NULLPTR != m_delegate) + { + delete m_delegate; + } + m_delegate = Q_NULLPTR; + qDebug() << "~CAlarmWidget()"; +} + +void CAlarmWidget::setAlarmModel(CAlarmItemModel *pModel) +{ + if(!pModel) + { + return; + } + m_pModel = pModel; + m_pView->setModel(m_pModel); + + if(!m_delegate) + { + m_delegate = new CAlarmDelegate(m_pModel, this); + m_pView->setItemDelegate(m_delegate); + connect(m_delegate,&CAlarmDelegate::openVideo,this,&CAlarmWidget::openVideo,Qt::QueuedConnection); + connect(m_delegate,&CAlarmDelegate::openTrend,this,&CAlarmWidget::openTrend,Qt::QueuedConnection); + connect(CAlarmSetMng::instance(),&CAlarmSetMng::sigLoadConfig,m_delegate,&CAlarmDelegate::slotLoadConfig,Qt::QueuedConnection); + } + + connect(m_pConfirmButtonRow0, SIGNAL(clicked()), this, SLOT(slotConfirmRow0())); + connect(m_pConfirmButtonRow1, SIGNAL(clicked()), this, SLOT(slotConfirmRow1())); + connect(m_pConfirmButtonRow2, SIGNAL(clicked()), this, SLOT(slotConfirmRow2())); + + + m_pView->setColumnHidden(0, false); + m_pView->setColumnHidden(1, false); + m_pView->setColumnHidden(2, false); + m_pView->setColumnHidden(3, true); + m_pView->setColumnHidden(4, true); + m_pView->setColumnHidden(5, false); + m_pView->setColumnHidden(6, false); + m_pView->setColumnHidden(7, false); + + + m_pView->setColumnWidth(0, 230); + m_pView->setColumnWidth(1, 120); + m_pView->setColumnWidth(2, 150); + m_pView->setColumnWidth(5, 150); + m_pView->setColumnWidth(6, 120); + + updateRowHeight(); +} + +void CAlarmWidget::setRowHeight(const int &height) +{ + if(m_pView) + { + m_pView->setRowHeight(0, height); + m_pView->setRowHeight(1, height); + m_pView->setRowHeight(2, height); + updateRowHeight(); + } +} + +void CAlarmWidget::setDockColumnVisible(const int &column, const bool &visbile) +{ + if(m_pView) + { + m_pView->setColumnHidden(column, !visbile); + } +} + +void CAlarmWidget::updateRowHeight() +{ + int nHeight = m_pView->rowHeight(0); + m_pConfirmButtonRow0->setMinimumHeight(nHeight); + m_pConfirmButtonRow1->setMinimumHeight(nHeight); + m_pConfirmButtonRow2->setMinimumHeight(nHeight); + setFixedHeight(nHeight * 3 + 1); +} + +void CAlarmWidget::updateView() +{ + if(m_pView != Q_NULLPTR) + { + m_pView->setShowGrid(m_pModel->getShowAlarmCount()); + m_pModel->updateAlternate(); + m_pView->viewport()->update(); + } +} + +void CAlarmWidget::setAlarmOperateEnable(const bool &bEnable) +{ + m_pConfirmButtonRow0->setEnabled(bEnable); + m_pConfirmButtonRow1->setEnabled(bEnable); + m_pConfirmButtonRow2->setEnabled(bEnable); +} + +void CAlarmWidget::setColumnWidth(const int &column, const int &width) +{ + if(m_pView != Q_NULLPTR) + { + m_pView->setColumnWidth(column, width); + } +} + +void CAlarmWidget::initialize() +{ + QHBoxLayout * pLayout = new QHBoxLayout(this); + pLayout->setMargin(0); + setLayout(pLayout); + + m_pView = new CAlarmView(this); + m_pView->setAlternatingRowColors(true); + m_pView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_pView->setSelectionMode(QAbstractItemView::NoSelection); + m_pView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_pView->horizontalHeader()->setStretchLastSection(true); + m_pView->horizontalHeader()->setVisible(false); + + m_pView->verticalHeader()->setVisible(false); + m_pView->setColumnWidth(0, 150); + pLayout->addWidget(m_pView); + QVBoxLayout * pConfirmBtnLayout = new QVBoxLayout(); + m_pConfirmButtonRow0 = new QPushButton(tr("确认")); + m_pConfirmButtonRow1 = new QPushButton(tr("确认")); + m_pConfirmButtonRow2 = new QPushButton(tr("确认")); + int nHeight = 23; + m_pConfirmButtonRow0->setMinimumHeight(nHeight); + m_pConfirmButtonRow1->setMinimumHeight(nHeight); + m_pConfirmButtonRow2->setMinimumHeight(nHeight); + setMinimumHeight(nHeight * 3); + + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow0); + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow1); + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow2); + + pConfirmBtnLayout->addStretch(); + pLayout->addLayout(pConfirmBtnLayout); + layout()->setSpacing(0); + + updateAlarmOperatePerm(); + + m_pConfirmButtonRow0->setVisible(false); + m_pConfirmButtonRow1->setVisible(false); + m_pConfirmButtonRow2->setVisible(false); + connect(m_pView, &CAlarmView::alarmViewDoubleClicked, this, &CAlarmWidget::alarmWidgetDoubleClicked); +} + +void CAlarmWidget::initializeEdit() +{ + QHBoxLayout * pLayout = new QHBoxLayout(this); + pLayout->setMargin(0); + setLayout(pLayout); + //m_header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("告警类型") << tr("告警状态") << tr("确认状态") << tr("告警内容"); + QStandardItemModel *model = new QStandardItemModel(); + model->setItem(0,0,new QStandardItem("2020-01-01 12:59:59.999")); + model->setItem(0,1,new QStandardItem("高")); + model->setItem(0,2,new QStandardItem("XX位置")); + model->setItem(0,3,new QStandardItem("-")); + model->setItem(0,4,new QStandardItem("系统信息")); + model->setItem(0,5,new QStandardItem("通道异常")); + model->setItem(0,6,new QStandardItem("未确认")); + model->setItem(0,7,new QStandardItem("通道:chanX,通道状态:通讯中断!")); + model->item(0,0)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,1)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,2)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,3)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,4)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,5)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,6)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + model->item(0,7)->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); + m_pView = new CAlarmView(this); + m_pView->setAlternatingRowColors(true); + m_pView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_pView->setSelectionMode(QAbstractItemView::NoSelection); + m_pView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_pView->horizontalHeader()->setStretchLastSection(true); + m_pView->horizontalHeader()->setVisible(false); + m_pView->verticalHeader()->setVisible(false); + + //m_pView->setColumnWidth(0, 150); + pLayout->addWidget(m_pView); + QVBoxLayout * pConfirmBtnLayout = new QVBoxLayout(); + m_pConfirmButtonRow0 = new QPushButton(tr("确认")); + m_pConfirmButtonRow1 = new QPushButton(tr("确认")); + m_pConfirmButtonRow2 = new QPushButton(tr("确认")); + int nHeight = 23; + m_pConfirmButtonRow0->setMinimumHeight(nHeight); + m_pConfirmButtonRow1->setMinimumHeight(nHeight); + m_pConfirmButtonRow2->setMinimumHeight(nHeight); + setMinimumHeight(nHeight * 3); + + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow0); + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow1); + pConfirmBtnLayout->addWidget(m_pConfirmButtonRow2); + + pConfirmBtnLayout->addStretch(); + pLayout->addLayout(pConfirmBtnLayout); + layout()->setSpacing(0); + + updateAlarmOperatePerm(); + + m_pConfirmButtonRow0->setVisible(false); + m_pConfirmButtonRow1->setVisible(false); + m_pConfirmButtonRow2->setVisible(false); + + + m_pView->setModel(model); + m_pView->setColumnHidden(0, false); + m_pView->setColumnHidden(1, false); + m_pView->setColumnHidden(2, false); + m_pView->setColumnHidden(3, true); + m_pView->setColumnHidden(4, true); + m_pView->setColumnHidden(5, false); + m_pView->setColumnHidden(6, false); + m_pView->setColumnHidden(7, false); + + + m_pView->setColumnWidth(0, 230); + m_pView->setColumnWidth(1, 120); + m_pView->setColumnWidth(2, 150); + m_pView->setColumnWidth(5, 150); + m_pView->setColumnWidth(6, 120); + + m_pView->setRowHeight(0,50); + + //connect(m_pView, &CAlarmView::alarmViewDoubleClicked, this, &CAlarmWidget::alarmWidgetDoubleClicked); +} + +void CAlarmWidget::closeEvent(QCloseEvent *event) +{ + Q_UNUSED(event) + if(Q_NULLPTR != m_pConfirmButtonRow0) + { + delete m_pConfirmButtonRow0; + m_pConfirmButtonRow0 = Q_NULLPTR; + } + if(Q_NULLPTR != m_pConfirmButtonRow1) + { + delete m_pConfirmButtonRow1; + m_pConfirmButtonRow1 = Q_NULLPTR; + } + if(Q_NULLPTR != m_pConfirmButtonRow2) + { + delete m_pConfirmButtonRow2; + m_pConfirmButtonRow2 = Q_NULLPTR; + } + QWidget::closeEvent(event); +} + +void CAlarmWidget::confirmAlarm(const int &row) +{ + //构建告警确认package + if(row >= m_pModel->getListShowAlarmInfo().count()) + { + return; + } + AlarmMsgPtr info = m_pModel->getListShowAlarmInfo().at(row); + + updateAlarmOperatePerm(); + if(!m_listLocationOptId.contains(info->location_id)) + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警所在位置的操作权限!")); + msgBox.exec(); + return; + } + if(!m_listRegionOptId.contains(info->region_id) && info->region_id != -1) + { + QMessageBox msgBox; + msgBox.setText(tr("当前用户不具备该告警所在责任区的操作权限!")); + msgBox.exec(); + return; + } + + iot_idl::SAlmCltCfmAlm * pkg = new iot_idl::SAlmCltCfmAlm(); + pkg->set_node_name(m_nodeName); + pkg->set_user_id(m_userId); + pkg->set_confirm_time(QDateTime::currentMSecsSinceEpoch()); + pkg->set_domain_id(info->domain_id); + pkg->set_app_id(info->app_id); + pkg->set_alm_type(info->alm_type); + pkg->add_key_id_tag(info->key_id_tag.toStdString()); + pkg->add_time_stamp(info->time_stamp); + pkg->add_uuid_base64(info->uuid_base64.toStdString()); + //请求确认 + CAlarmDataCollect::instance()->requestCfmAlm(*pkg); + + delete pkg; +} + +void CAlarmWidget::setEnableTrend(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableTrend(isNeed); + } +} + +void CAlarmWidget::setEnableVideo(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableVideo(isNeed); + } +} + +void CAlarmWidget::setEnableWave(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableWave(isNeed); + } +} + +void CAlarmWidget::setEnableLevel(bool isNeed) +{ + if(m_delegate) + { + m_delegate->setEnableLevel(isNeed); + } +} + +bool CAlarmWidget::updateAlarmOperatePerm() +{ + iot_public::SNodeInfo stNodeInfo; + iot_public::CSysInfoInterfacePtr spSysInfo; + if (!iot_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return false; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + m_nodeName = stNodeInfo.strName; + m_listLocationOptId.clear(); + m_listRegionOptId.clear(); + m_listLocationDelId.clear(); + m_listRegionDelId.clear(); + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + if(0 != permMngPtr->CurUser(m_userId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) + { + m_userId = -1; + LOGERROR("用户ID获取失败!"); + return false; + } + std::vector vecRegionOptId; + std::vector vecLocationOptId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, vecRegionOptId, vecLocationOptId)) + { + std::vector ::iterator region = vecRegionOptId.begin(); + while (region != vecRegionOptId.end()) + { + m_listRegionOptId.append(*region++); + } + + std::vector ::iterator location = vecLocationOptId.begin(); + while (location != vecLocationOptId.end()) + { + m_listLocationOptId.append(*location++); + } + } + std::vector vecRegionDelId; + std::vector vecLocationDelId; + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_DELETE, vecRegionDelId, vecLocationDelId)) + { + std::vector ::iterator region = vecRegionDelId.begin(); + while (region != vecRegionDelId.end()) + { + m_listRegionDelId.append(*region++); + } + + std::vector ::iterator location = vecLocationDelId.begin(); + while (location != vecLocationDelId.end()) + { + m_listLocationDelId.append(*location++); + } + } + return true; + } + return false; +} + +void CAlarmWidget::slotConfirmRow0() +{ + confirmAlarm(0); +} + +void CAlarmWidget::slotConfirmRow1() +{ + confirmAlarm(1); +} + +void CAlarmWidget::slotConfirmRow2() +{ + confirmAlarm(2); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CAlarmWidget.h b/product/src/gui/plugin/AlarmWidget_pad/CAlarmWidget.h new file mode 100644 index 00000000..bd50b909 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CAlarmWidget.h @@ -0,0 +1,79 @@ +#ifndef CALARMWINDOW_H +#define CALARMWINDOW_H + +#include + +class QPushButton; +class QMouseEvent; +class CAlarmView; +class CAlarmDelegate; +class CAlarmItemModel; + +class CAlarmWidget : public QWidget +{ + Q_OBJECT +public: + explicit CAlarmWidget(QWidget *parent = nullptr); + ~CAlarmWidget(); + + void setAlarmModel(CAlarmItemModel * pModel); + + void setRowHeight(const int &height); + + void setDockColumnVisible(const int &column, const bool &visbile); + + void updateRowHeight(); + + void updateView(); + + void setAlarmOperateEnable(const bool &bEnable); + + void setColumnWidth(const int &column, const int &width); + + void confirmAlarm(const int &row); + + void setEnableTrend(bool isNeed); + + void setEnableVideo(bool isNeed); + + void setEnableWave(bool isNeed); + + void setEnableLevel(bool isNeed); + +signals: + void alarmWidgetDoubleClicked(); + + void openVideo(int domainId,int appId,QString tag,quint64 startTime,quint64 endTime); + + void openTrend(quint64 time_stamp,QStringList tagList); +protected: + void closeEvent(QCloseEvent *event); + + bool updateAlarmOperatePerm(); + +public slots: + void initialize(); + + void initializeEdit(); + void slotConfirmRow0(); + void slotConfirmRow1(); + void slotConfirmRow2(); + + +private: + CAlarmView * m_pView; + CAlarmItemModel * m_pModel; + CAlarmDelegate * m_delegate; + int m_userId; + std::string m_nodeName; + QList m_listRegionOptId; + QList m_listLocationOptId; + + QList m_listRegionDelId; + QList m_listLocationDelId; + QPushButton * m_pConfirmButtonRow0; + QPushButton * m_pConfirmButtonRow1; + QPushButton * m_pConfirmButtonRow2; +}; + +#endif // ALARMWINDOW_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CDisposalPlanDialog.cpp b/product/src/gui/plugin/AlarmWidget_pad/CDisposalPlanDialog.cpp new file mode 100644 index 00000000..59ade39c --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CDisposalPlanDialog.cpp @@ -0,0 +1,28 @@ +#include "CDisposalPlanDialog.h" +#include "ui_CDisposalPlanDialog.h" +#include "CAiAlarmMsgInfo.h" +#include +CDisposalPlanDialog::CDisposalPlanDialog(const AiAlarmMsgPtr &aiptr, QWidget *parent) : + QDialog(parent), + ui(new Ui::CDisposalPlanDialog), + m_aiptr(aiptr) +{ + ui->setupUi(this); + setWindowTitle(tr("处置预案")); + Qt::WindowFlags flags=Qt::Dialog; + flags |=Qt::WindowCloseButtonHint; + setWindowFlags(flags); + + ui->time->setReadOnly(true); + ui->content->setReadOnly(true); + ui->displan->setReadOnly(true); + + ui->time->setText(QDateTime::fromMSecsSinceEpoch(m_aiptr->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz")); + ui->content->setText(m_aiptr->content); + ui->displan->setText(m_aiptr->disposal_plan); +} + +CDisposalPlanDialog::~CDisposalPlanDialog() +{ + delete ui; +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CDisposalPlanDialog.h b/product/src/gui/plugin/AlarmWidget_pad/CDisposalPlanDialog.h new file mode 100644 index 00000000..f2735e4f --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CDisposalPlanDialog.h @@ -0,0 +1,23 @@ +#ifndef CDISPOSALPLANDIALOG_H +#define CDISPOSALPLANDIALOG_H + +#include +#include "CAlarmCommon.h" +namespace Ui { +class CDisposalPlanDialog; +} + +class CDisposalPlanDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CDisposalPlanDialog(const AiAlarmMsgPtr &aiptr,QWidget *parent = 0); + ~CDisposalPlanDialog(); + +private: + Ui::CDisposalPlanDialog *ui; + AiAlarmMsgPtr m_aiptr; +}; + +#endif // CDISPOSALPLANDIALOG_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CDisposalPlanDialog.ui b/product/src/gui/plugin/AlarmWidget_pad/CDisposalPlanDialog.ui new file mode 100644 index 00000000..4e69345b --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CDisposalPlanDialog.ui @@ -0,0 +1,140 @@ + + + CDisposalPlanDialog + + + + 0 + 0 + 391 + 389 + + + + Dialog + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Vertical + + + + + + + 告警时间: + + + + + + + + + + + + 0 + 20 + + + + + 16777215 + 20 + + + + 告警内容: + + + + + + 0 + 50 + + + + + + + 0 + 20 + + + + + 16777215 + 20 + + + + 处置预案: + + + + + + 0 + 50 + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget_pad/CMyCalendar.cpp b/product/src/gui/plugin/AlarmWidget_pad/CMyCalendar.cpp new file mode 100644 index 00000000..9c72e0d7 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CMyCalendar.cpp @@ -0,0 +1,57 @@ +#include "CMyCalendar.h" +#include "ui_CMyCalendar.h" +#include +#include +#include +CMyCalendar::CMyCalendar(QWidget *parent) : + QWidget(parent), + ui(new Ui::CMyCalendar) +{ + ui->setupUi(this); + connect(ui->calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); + connect(ui->calendarWidget_2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); + connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_cancle())); + m_startTime = QDate::currentDate(); + m_endTime = QDate::currentDate(); + ui->lineEdit->setText(m_startTime.toString("yyyy-MM-dd")); + ui->lineEdit_2->setText(m_endTime.toString("yyyy-MM-dd")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit_2->setReadOnly(true); +} + +CMyCalendar::~CMyCalendar() +{ + delete ui; +} + +void CMyCalendar::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) + { + return ; + } + QWidget::keyPressEvent(event); +} + +void CMyCalendar::slot_endTime(QDate date) +{ + ui->lineEdit_2->setText(date.toString("yyyy-MM-dd")); + m_endTime = date; + if(m_startTime.isNull() || m_endTime < m_startTime) + { + //QMessageBox::information(this,tr("提示"),tr("开始时间为空或结束时间小于开始时间")); + return; + } + emit sig_endTimeClick(m_startTime,m_endTime); +} + +void CMyCalendar::slot_startTime(QDate date) +{ + m_startTime = date; + ui->lineEdit->setText(date.toString("yyyy-MM-dd")); +} + +void CMyCalendar::slot_cancle() +{ + emit sig_cancle(); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CMyCalendar.h b/product/src/gui/plugin/AlarmWidget_pad/CMyCalendar.h new file mode 100644 index 00000000..caa34e37 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CMyCalendar.h @@ -0,0 +1,34 @@ +#ifndef CMYCALENDAR_H +#define CMYCALENDAR_H + +#include +#include + +namespace Ui { +class CMyCalendar; +} + +class CMyCalendar : public QWidget +{ + Q_OBJECT +signals: + void sig_endTimeClick(QDate startDate,QDate endDate); + void sig_startTimeClick(QDate date); + void sig_cancle(); +public: + explicit CMyCalendar(QWidget *parent = 0); + ~CMyCalendar(); +protected: + virtual void keyPressEvent(QKeyEvent *event); + +public slots: + void slot_endTime(QDate date); + void slot_startTime(QDate date); + void slot_cancle(); +private: + Ui::CMyCalendar *ui; + QDate m_startTime; + QDate m_endTime; +}; + +#endif // CMYCALENDAR_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CMyCalendar.ui b/product/src/gui/plugin/AlarmWidget_pad/CMyCalendar.ui new file mode 100644 index 00000000..9610c481 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CMyCalendar.ui @@ -0,0 +1,140 @@ + + + CMyCalendar + + + + 0 + 0 + 538 + 270 + + + + Form + + + 1.000000000000000 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 0 + + + + + + + + + 20 + 0 + + + + + 20 + 16777215 + + + + Qt::NoContextMenu + + + Qt::LeftToRight + + + false + + + 0 + + + + + + Qt::AlignCenter + + + + + + + + + + 取消 + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/AlarmWidget_pad/CMyCheckBox.cpp b/product/src/gui/plugin/AlarmWidget_pad/CMyCheckBox.cpp new file mode 100644 index 00000000..0eb5dbda --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CMyCheckBox.cpp @@ -0,0 +1,21 @@ +#include "CMyCheckBox.h" +#include + +CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) + :QCheckBox(text,parent) +{ + +} + +CMyCheckBox::CMyCheckBox(QWidget *parent) + :QCheckBox(parent) +{ + +} + +void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) +{ + Q_UNUSED(e); + setChecked(!isChecked()); + emit clicked(isChecked()); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CMyCheckBox.h b/product/src/gui/plugin/AlarmWidget_pad/CMyCheckBox.h new file mode 100644 index 00000000..1dad82e3 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CMyCheckBox.h @@ -0,0 +1,16 @@ +#ifndef MYCHECKBOX_H +#define MYCHECKBOX_H + +#include + +class CMyCheckBox : public QCheckBox +{ +public: + CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); + CMyCheckBox(QWidget *parent = Q_NULLPTR); + +protected: + void mouseReleaseEvent(QMouseEvent *e); +}; + +#endif // MYCHECKBOX_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CMyListWidget.cpp b/product/src/gui/plugin/AlarmWidget_pad/CMyListWidget.cpp new file mode 100644 index 00000000..fa73a493 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CMyListWidget.cpp @@ -0,0 +1,12 @@ +#include "CMyListWidget.h" + +CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) +{ + +} + +void CMyListWidget::showEvent(QShowEvent *event) +{ + this->updateGeometries(); + QListWidget::showEvent(event); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CMyListWidget.h b/product/src/gui/plugin/AlarmWidget_pad/CMyListWidget.h new file mode 100644 index 00000000..728f308d --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CMyListWidget.h @@ -0,0 +1,15 @@ +#ifndef CMYLISTWIDGET_H +#define CMYLISTWIDGET_H + +#include + +class CMyListWidget : public QListWidget +{ +public: + explicit CMyListWidget(QWidget *parent = 0); + +protected: + void showEvent(QShowEvent *event); +}; + +#endif // CMYLISTWIDGET_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CPdfPrinter.cpp b/product/src/gui/plugin/AlarmWidget_pad/CPdfPrinter.cpp new file mode 100644 index 00000000..6b35c460 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CPdfPrinter.cpp @@ -0,0 +1,150 @@ +#include "CPdfPrinter.h" +#include +#include +#include +#include +#include "CAlarmView.h" +#include "CAiAlarmTreeView.h" + +CPdfPrinter::CPdfPrinter(QObject *parent) : QObject(parent) +{ + +} + +void CPdfPrinter::initialize() +{ + +} + +void CPdfPrinter::printerByModel(CAiAlarmTreeView* view, CAiAlarmTreeModel *treeModel, QString fileName) +{ + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "智能告警" ); + // 写横向表头 + QXlsx::Format formatheader; + formatheader.setFontBold(true); + formatheader.setFontColor(Qt::black); + + QXlsx::Format formatAi; + formatAi.setFontBold(true); + formatAi.setFontColor(Qt::red); + + QXlsx::Format formatMergedAlm; + formatMergedAlm.setFontBold(false); + formatMergedAlm.setFontColor(Qt::darkGreen); + QXlsx::Format formatAlm; + formatAlm.setFontBold(false); + formatAlm.setFontColor(Qt::darkYellow); + int colcount = treeModel->columnCount(); + + for(int i=0,excelCloumn=0;iisColumnHidden(i)) + { + continue; + } + + xlsx.write( 1, excelCloumn +1, treeModel->headerData(i, Qt::Horizontal).toString().trimmed(),formatheader); + excelCloumn++; + } + + // 写内容 + int rowNum = 1; + CAiAlarmTreeItem *item = treeModel->getItem(); + QList itemList = item->getChildItemList(); + for(int index(0);indexisAi()) + { + for(int j(0),excelCloumn(0);jisColumnHidden(j)) + { + continue; + } + QString sText=itemList.at(index)->data(j).toString(); + xlsx.write( rowNum +1, excelCloumn +1, sText,formatAi ); + ++excelCloumn; + } + rowNum++; + QList itemList_ =itemList.at(index)->getChildItemList(); + for(int indexAlm(0);indexAlmisColumnHidden(i)) + { + continue; + } + QString sText=itemList_.at(indexAlm)->data(i).toString(); + xlsx.write( rowNum +1, excelCloumn +1, sText,formatMergedAlm ); + ++excelCloumn; + } + rowNum++; + } + }else + { + for(int j(0),excelCloumn(0);jisColumnHidden(j)) + { + continue; + } + + QString sText=itemList.at(index)->data(j).toString(); + xlsx.write( rowNum +1, excelCloumn +1, sText,formatAlm ); + excelCloumn++; + } + rowNum++; + } + } + + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + + // 提示导出路径 + emit printResult(sExcelFileName); +} + +void CPdfPrinter::printerAlmByModel(CAlarmView* view, CAlarmItemModel *model, QString fileName) +{ + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "原始告警" ); + // 写横向表头 + int rowcount=model->rowCount(); + int colcount=model->columnCount(); + + for(int i=0,excelCloumn = 0;iisColumnHidden(i)) + { + continue; + } + xlsx.write( 1, excelCloumn +1, model->headerData(i, Qt::Horizontal).toString().trimmed()); + excelCloumn++; + } + + // 写内容 + for (int j = 0,excelCloumn = 0; j < colcount; j++) //列数 + { + if (view->isColumnHidden(j)) + { + continue; + } + + for (int i = 0; i < rowcount; i++) + { + QString sText= model->data(model->index(i, j)).toString(); + xlsx.write( i+2, excelCloumn +1, sText); + } + + excelCloumn++; + } + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + + // 提示导出路径 + emit printResult(sExcelFileName); +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CPdfPrinter.h b/product/src/gui/plugin/AlarmWidget_pad/CPdfPrinter.h new file mode 100644 index 00000000..5bd874b5 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CPdfPrinter.h @@ -0,0 +1,40 @@ +/** +* @file AlarmWidget 之前是做pdf打印,因需求修改,现在改为excel ,但是类名不变,维护请注意 +* @brief +* @author jxd +* @date 2020-01-08 +*/ +#ifndef CPDFPRINTER_H +#define CPDFPRINTER_H + +#include +#include +#include +#include +#include +#include "CAiAlarmTreeView.h" +#include "pub_excel/xlsx/xlsxdocument.h" +#include "pub_excel/xlsx/xlsxformat.h" + +class CPdfPrinter : public QObject +{ + Q_OBJECT +public: + explicit CPdfPrinter(QObject *parent = nullptr); + + void initialize(); + +signals: + void printResult(QString fileName); +public slots: + void printerByModel(CAiAlarmTreeView* view, CAiAlarmTreeModel *treeModel, QString fileName); + void printerAlmByModel(CAlarmView* view, CAlarmItemModel *model,QString fileName); +private: + QString m_fileName; + QVector m_columnHidden; + QVector m_columnWidth; + int m_headHeight; + int m_height; + int m_width; +}; +#endif // CPDFPRINTER_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CTableViewPrinter.cpp b/product/src/gui/plugin/AlarmWidget_pad/CTableViewPrinter.cpp new file mode 100644 index 00000000..9cd41cc1 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CTableViewPrinter.cpp @@ -0,0 +1,54 @@ +#include "CTableViewPrinter.h" +#include "CAlarmCommon.h" +#include "CAlarmBaseData.h" +CTableViewPrinter::CTableViewPrinter(CAlarmItemModel *model): + m_pModel(model) +{ + +} + +QVector CTableViewPrinter::getHead() +{ + int columnCount = m_pModel->columnCount(); + QVector header; + for(int index(0);index headerData(index,Qt::Horizontal).toString()); + } + return header; +} + +QList > CTableViewPrinter::getData() +{ + QList > data; + QList list = m_pModel->getListShowAlarmInfo(); + for(int index(0);index content; + //1.时间 + content.append(QDateTime::fromMSecsSinceEpoch(list.at(index)->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz")); + //2.优先级 + content.append(CAlarmBaseData::instance()->queryPriorityDesc(list.at(index)->priority)); + //3.位置 + content.append(CAlarmBaseData::instance()->queryLocationDesc(list.at(index)->location_id)); + //4.责任区 + content.append(CAlarmBaseData::instance()->queryRegionDesc(list.at(index)->region_id)); + //5.类型 + content.append(CAlarmBaseData::instance()->queryAlarmTypeDesc(list.at(index)->alm_type)); + //6.状态 + content.append(CAlarmBaseData::instance()->queryAlarmStatusDesc(list.at(index)->alm_status)); + //7.确认状态 + if(list.at(index)->logic_state == E_ALS_ALARM || list.at(index)->logic_state == E_ALS_RETURN) + { + content.append(QObject::tr("未确认")); + }else + { + content.append(QObject::tr("已确认")); + } + //8.内容 + content.append(list.at(index)->content); + data.append(content); + } + return data; +} + diff --git a/product/src/gui/plugin/AlarmWidget_pad/CTableViewPrinter.h b/product/src/gui/plugin/AlarmWidget_pad/CTableViewPrinter.h new file mode 100644 index 00000000..09e78694 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CTableViewPrinter.h @@ -0,0 +1,15 @@ +#ifndef CTABLEVIEWPRINTER_H +#define CTABLEVIEWPRINTER_H +#include "CAlarmItemModel.h" +class QVariant; +class CTableViewPrinter +{ +public: + CTableViewPrinter(CAlarmItemModel *model); + QVector getHead(); + QList > getData(); +private: + CAlarmItemModel * m_pModel; +}; + +#endif // CTABLEVIEWPRINTER_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/CTreeViewPrinter.cpp b/product/src/gui/plugin/AlarmWidget_pad/CTreeViewPrinter.cpp new file mode 100644 index 00000000..ae54c404 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CTreeViewPrinter.cpp @@ -0,0 +1,42 @@ +#include "CTreeViewPrinter.h" +#include "CAiAlarmTreeItem.h" +CTreeViewPrinter::CTreeViewPrinter(CAiAlarmTreeModel *model): + m_pModel(model) +{ + +} + +QVector CTreeViewPrinter::getHead() +{ + int columnCount = m_pModel->columnCount(); + QVector header; + for(int index(0);index headerData(index,Qt::Horizontal).toString()); + } + return header; +} + +QList > CTreeViewPrinter::getData() +{ + QList > data; + CAiAlarmTreeItem *item = ((CAiAlarmTreeModel*)m_pModel)->getItem(); + QList itemList = item->getChildItemList(); + for(int index(0);index content; + content = itemList.at(index)->getContent(); + data.append(content); + if(itemList.at(index)->isAi()) + { + QList itemlist = itemList.at(index)->getChildItemList(); + for(int dex(0);dex almInfo; + almInfo = itemlist.at(dex)->getContent(); + data.append(almInfo); + } + } + } + return data; +} diff --git a/product/src/gui/plugin/AlarmWidget_pad/CTreeViewPrinter.h b/product/src/gui/plugin/AlarmWidget_pad/CTreeViewPrinter.h new file mode 100644 index 00000000..d5745648 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/CTreeViewPrinter.h @@ -0,0 +1,15 @@ +#ifndef CTREEVIEWPRINTER_H +#define CTREEVIEWPRINTER_H +#include "CAiAlarmTreeModel.h" +class QVariant; +class CTreeViewPrinter +{ +public: + CTreeViewPrinter(CAiAlarmTreeModel *model); + QVector getHead(); + QList > getData(); +private: + CAiAlarmTreeModel * m_pModel; +}; + +#endif // CTREEVIEWPRINTER_H diff --git a/product/src/gui/plugin/AlarmWidget_pad/main.cpp b/product/src/gui/plugin/AlarmWidget_pad/main.cpp new file mode 100644 index 00000000..10043517 --- /dev/null +++ b/product/src/gui/plugin/AlarmWidget_pad/main.cpp @@ -0,0 +1,75 @@ +#include +#include "CAlarmPlugin.h" +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + //<初始化消息总线 + QStringList arguments=QCoreApplication::arguments(); + std::string name="admin"; + std::string password ="admin"; + int group =1; + for(int index(0);indexPermDllInit()) + { + return -1; + } + + if(perm->SysLogin(name, password, group, 12*60*60, "hmi") != 0) + { + return -1; + } + + { + CAlarmPlugin n(NULL, false); + n.initialize(E_Alarm_Dock); + //n.initialize(E_Alarm_Window); + + n.show(); + app.exec(); + } + + //<释放消息总线 + iot_net::releaseMsgBus(); + iot_public::StopLogSystem(); + + return 0; +} + diff --git a/product/src/gui/plugin/AssetWidget/CAssetPluginWidget.h b/product/src/gui/plugin/AssetWidget/CAssetPluginWidget.h index 230dee2e..5b737f69 100644 --- a/product/src/gui/plugin/AssetWidget/CAssetPluginWidget.h +++ b/product/src/gui/plugin/AssetWidget/CAssetPluginWidget.h @@ -7,7 +7,7 @@ class CAssetPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/BIWidget/CBIPluginWidget.h b/product/src/gui/plugin/BIWidget/CBIPluginWidget.h index 890381c6..32728413 100644 --- a/product/src/gui/plugin/BIWidget/CBIPluginWidget.h +++ b/product/src/gui/plugin/BIWidget/CBIPluginWidget.h @@ -7,7 +7,7 @@ class CBIPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/BatchOperation/BatchOperation.pro b/product/src/gui/plugin/BatchOperation/BatchOperation.pro new file mode 100644 index 00000000..c9bd0fbd --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/BatchOperation.pro @@ -0,0 +1,81 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2024-08-12T13:59:55 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += plugin + +TARGET = BatchOperation +TEMPLATE = lib + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + main.cpp \ + CBatchOperPluginWidget.cpp \ + CBatchOperation.cpp \ + CBatchOperationCollect.cpp \ + CustonHeadView.cpp \ + CBatchOperationModel.cpp \ + CDbInterface.cpp \ + CBatchOpeDelegate.cpp \ + CustomFilterModel.cpp \ + CInputDialog.cpp + +HEADERS += \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + CBatchOperPluginWidget.h \ + CBatchOperation.h \ + CBatchOperationCollect.h \ + BatchOperationComm.h \ + CustonHeadView.h \ + CBatchOperationModel.h \ + CDbInterface.h \ + CBatchOpeDelegate.h \ + CustomFilterModel.h \ + CInputDialog.h + +FORMS += \ + CBatchOperation.ui \ + CInputDialog.ui + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -lprotobuf \ + -lnet_msg_bus_api \ + -ldb_base_api \ + -ldb_api_ex \ + -lpub_sysinfo_api \ + -ldp_chg_data_api \ + -lrdb_api \ + -lrdb_net_api \ + -lpub_utility_api \ + -lperm_mng_api + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/BatchOperation/BatchOperationComm.h b/product/src/gui/plugin/BatchOperation/BatchOperationComm.h new file mode 100644 index 00000000..5c04f3a3 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/BatchOperationComm.h @@ -0,0 +1,92 @@ +#ifndef BATCHOPERATIONCOMM_H +#define BATCHOPERATIONCOMM_H + +#include +#include + +enum EPointType +{ + EN_ALL, + EN_ANALOG, + EN_DIGITAL, + EN_MIX, + EN_ACCUML, +}; + +struct DataPoint +{ + QString keyTag; + QString pointTag; + QString tableName; + QString tagDesc; + QString tableDesc; + QString stateTextName; + QString controStateName; + QString loctionName; + QString unit; + QString resText; + + int dataType; + int appId; + int region; + int locationId; + int domainId; + float value_ai; + int value_di; + double value_pi; + int value_mi; + double setValue; + bool isEnableContro; + QMap options; + QMap controlOpt; + + DataPoint() + { + keyTag = ""; + pointTag = ""; + tableName = ""; + tagDesc = ""; + tableDesc = ""; + stateTextName = ""; + controStateName = ""; + loctionName = ""; + unit = ""; + resText = "无"; + + appId = 0; + region = 0; + locationId = 0; + domainId = 0; + value_ai = 0; + value_di = 0; + value_pi = 0; + value_mi = 0; + setValue = 0; + dataType = -1; + isEnableContro = true; + options.clear(); + controlOpt.clear(); + } +}; + +struct STOptTagInfo +{ + QString keyIdTag; + int optType; + qint64 optTime; + int locationId; + int appId; + double setValue; + int nIsSet; + QString stateText; + QString hostName; + QString userName; + QString userGroup; + + QString tagName; + QString devName; + QString table; +}; + + +#endif // BATCHOPERATIONCOMM_H diff --git a/product/src/gui/plugin/BatchOperation/CBatchOpeDelegate.cpp b/product/src/gui/plugin/BatchOperation/CBatchOpeDelegate.cpp new file mode 100644 index 00000000..5b275185 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CBatchOpeDelegate.cpp @@ -0,0 +1,91 @@ +#include "CBatchOpeDelegate.h" +#include "BatchOperationComm.h" + +#include + +CBatchOpeDelegate::CBatchOpeDelegate(QObject *parent) + : QStyledItemDelegate (parent) +{ + +} + +QWidget *CBatchOpeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if(!index.isValid()) return nullptr; + + QModelIndex sourceIndex = index; + const QSortFilterProxyModel* proxyModel = qobject_cast(index.model()); + if (proxyModel) { + sourceIndex = proxyModel->mapToSource(index); + } + + if (sourceIndex.column() == 2) + { + QComboBox *comboBox; + QLineEdit *lineEdit; + QDoubleValidator *validator; + QMap options; + int type = sourceIndex.model()->data(sourceIndex,Qt::UserRole + 6).toInt(); + options.clear(); + switch (type) { + case EN_ANALOG: + lineEdit = new QLineEdit(parent); + validator = new QDoubleValidator(-1e10, 1e10, 6, lineEdit); + lineEdit->setValidator(validator); + return lineEdit; + case EN_DIGITAL: + case EN_MIX: + comboBox = new QComboBox(parent); + options = sourceIndex.model()->data(sourceIndex, Qt::UserRole + 11).value>(); + foreach(const int &str,options.keys()) + { + comboBox->addItem( options.value(str) ,str); + } + return comboBox; + default: + break; + } + }else if(sourceIndex.column() == 1 || sourceIndex.column() == 3 ||sourceIndex.column() == 0) + { + return nullptr; + } + return QStyledItemDelegate::createEditor(parent, option, sourceIndex); +} + +void CBatchOpeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + if(!index.isValid()) return; + + QModelIndex sourceIndex = index; + if (sourceIndex.column() == 2) { + int type = sourceIndex.model()->data(sourceIndex, Qt::UserRole + 6).toInt(); + if (type == EN_ANALOG || type == EN_ACCUML) { + QLineEdit *lineEdit = qobject_cast(editor); + lineEdit->setText(QString::number(sourceIndex.model()->data(sourceIndex, Qt::EditRole).toDouble() , 'f')); + } else if (type == EN_DIGITAL || type == EN_MIX) { + QComboBox *comboBox = qobject_cast(editor); + comboBox->setCurrentText(sourceIndex.model()->data(sourceIndex, Qt::EditRole).toString()); + } + } else { + QStyledItemDelegate::setEditorData(editor, sourceIndex); + } +} + +void CBatchOpeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + if(!index.isValid()) return; + + QModelIndex sourceIndex = index; + if (sourceIndex.column() == 2) { + int type = sourceIndex.model()->data(sourceIndex, Qt::UserRole + 6).toInt(); + if (type == EN_ANALOG || type == EN_ACCUML) { + QLineEdit *lineEdit = qobject_cast(editor); + model->setData(sourceIndex, lineEdit->text(), Qt::EditRole); + } else if (type == EN_DIGITAL || type == EN_MIX) { + QComboBox *comboBox = qobject_cast(editor); + model->setData(sourceIndex, comboBox->currentData(), Qt::EditRole); + } + } else { + QStyledItemDelegate::setModelData(editor, model, sourceIndex); + } +} diff --git a/product/src/gui/plugin/BatchOperation/CBatchOpeDelegate.h b/product/src/gui/plugin/BatchOperation/CBatchOpeDelegate.h new file mode 100644 index 00000000..d98f78b0 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CBatchOpeDelegate.h @@ -0,0 +1,20 @@ +#ifndef CBATCHOPEDELEGATE_H +#define CBATCHOPEDELEGATE_H + +#include +#include +#include +#include + +class CBatchOpeDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CBatchOpeDelegate(QObject *parent = nullptr); + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void setEditorData(QWidget *editor, const QModelIndex &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; + +}; + +#endif // CBATCHOPEDELEGATE_H diff --git a/product/src/gui/plugin/BatchOperation/CBatchOperPluginWidget.cpp b/product/src/gui/plugin/BatchOperation/CBatchOperPluginWidget.cpp new file mode 100644 index 00000000..a1039e4e --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CBatchOperPluginWidget.cpp @@ -0,0 +1,19 @@ +#include "CBatchOperPluginWidget.h" + +CBatchOperPluginWidget::CBatchOperPluginWidget(QObject *parent) : QObject(parent) +{ + +} + +bool CBatchOperPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CBatchOperation *pWidget = new CBatchOperation(parent, editMode); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CBatchOperPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/BatchOperation/CBatchOperPluginWidget.h b/product/src/gui/plugin/BatchOperation/CBatchOperPluginWidget.h new file mode 100644 index 00000000..06208104 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CBatchOperPluginWidget.h @@ -0,0 +1,21 @@ +#ifndef CPCSBATCHOPERPLUGINWIDGET_H +#define CPCSBATCHOPERPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" +#include "CBatchOperation.h" + +class CBatchOperPluginWidget : public QObject,public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) + Q_INTERFACES(CPluginWidgetInterface) + +public: + explicit CBatchOperPluginWidget(QObject *parent = nullptr); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CPCSBATCHOPERPLUGINWIDGET_H diff --git a/product/src/gui/plugin/BatchOperation/CBatchOperation.cpp b/product/src/gui/plugin/BatchOperation/CBatchOperation.cpp new file mode 100644 index 00000000..46644d9d --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CBatchOperation.cpp @@ -0,0 +1,618 @@ +#include "CBatchOperation.h" +#include "ui_CBatchOperation.h" +#include "pub_utility_api/FileStyle.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" + +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "BatchOperationComm.h" +#include "CustonHeadView.h" +#include "CBatchOpeDelegate.h" +#include "CustomFilterModel.h" +#include "CInputDialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace iot_dbms; +using namespace iot_public; +using namespace iot_service; + +CBatchOperation::CBatchOperation(QWidget *parent , bool editMode) : + QWidget(parent), + ui(new Ui::CBatchOperation), + m_communicator(NULL), + header(Q_NULLPTR), + filterModel(Q_NULLPTR), + m_BatchOpCollect(Q_NULLPTR), + m_pCollectThread(Q_NULLPTR), + m_Model(Q_NULLPTR) +{ + ui->setupUi(this); + + initStyleSheet(); + + if(!editMode) + { + if(!iot_public::createSysInfoInstance(m_sysInfoPtr)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return; + } + initMsg(); + readNodeInfo(); + initialize(); + } + +} + +CBatchOperation::~CBatchOperation() +{ + if( m_BatchOpCollect ) + { + emit releaseCollectThread(); + } + m_BatchOpCollect = Q_NULLPTR; + + if(m_pCollectThread) + { + m_pCollectThread->quit(); + m_pCollectThread->wait(); + } + m_pCollectThread = Q_NULLPTR; + + CDbInterface::instance()->destory(); + + if(m_Model) + { + delete m_Model; + } + m_Model = Q_NULLPTR; + + delete ui; +} + +int CBatchOperation::tableNameToEnum(const QString &tableName) +{ + if(tableName == "analog") + { + return EN_ANALOG; + } + else if(tableName == "digital") + { + return EN_DIGITAL; + } + else if(tableName == "accuml") + { + return EN_ACCUML; + } + else if(tableName == "mix") + { + return EN_MIX; + } + else + { + return -1; + } +} + +void CBatchOperation::setParaFromView( const int ®ionId , const QString &str) +{ + Q_UNUSED(regionId); + + //处理数据 + if( str.isEmpty() ) return; + QString data = str; + QStringList list = data.split(","); + if( !list.isEmpty() ) + { + emit updateData(list); + } + +} + +void CBatchOperation::initStyleSheet() +{ + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + qssfile1.close(); + + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("BatchOperation.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + qssfile2.close(); + + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void CBatchOperation::initMsg() +{ + if(m_communicator == NULL) + { + m_communicator = new iot_net::CMbCommunicator(); + } +} + +void CBatchOperation::readNodeInfo() +{ + if(m_sysInfoPtr->getLocalNodeInfo(m_nodeInfo) == iotFailed) + { + LOGERROR("获取本机节点信息失败!"); + } +} + +void CBatchOperation::initialize() +{ + QStringList list ; + list<m_typeCb->addItems(list); + ui->opertionBtn->setVisible(false); + + //初始化表格模型数据 + m_Model = new CBatchOperationModel(this); + filterModel = new CustomFilterModel(this); + filterModel->setSourceModel(m_Model); + ui->tableView->setModel(filterModel); + ui->tableView->setAlternatingRowColors(true); + + CBatchOpeDelegate *delegate = new CBatchOpeDelegate(ui->tableView); + ui->tableView->setItemDelegate(delegate); + + // 设置自定义的表头 + header = new CustonHeadView(Qt::Horizontal, ui->tableView); + header->setSectionResizeMode(QHeaderView::Interactive); + header->setStretchLastSection(true); + ui->tableView->setHorizontalHeader(header); + ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu); + ui->tableView->update(); + + connect(ui->tableView , &QTableView::customContextMenuRequested , this , &CBatchOperation::showContextMenu); + connect(header, &CustonHeadView::toggleCheckState, m_Model, &CBatchOperationModel::setAllChecked); + connect(m_Model, &CBatchOperationModel::itemChanged, [this](QStandardItem *item) { + if (item->column() == 0 && item->isCheckable()) { + bool allChecked = true; + + for (int row = 0; row < this->m_Model->rowCount(); ++row) { + QStandardItem *checkItem = this->m_Model->item(row, 0); + if ( (m_Model->flags(checkItem->index())& Qt::ItemIsUserCheckable) && (checkItem->checkState() == Qt::Unchecked)) { + allChecked = false; + break; + } + } + + this->header->setChecked(allChecked); + } + }); + connect(this , &CBatchOperation::updateData , this , &CBatchOperation::brushTableView); + connect(ui->m_typeCb, QOverload::of(&QComboBox::currentIndexChanged),filterModel , &CustomFilterModel::setFilterCriteria); + connect(ui->m_typeCb ,QOverload::of(&QComboBox::currentIndexChanged) , [=](int index){ + if( index == 0) + { + ui->opertionBtn->setVisible(false); + }else + { + ui->opertionBtn->setVisible(true); + } + }); + connect(ui->opertionBtn , &QPushButton::clicked , this , &CBatchOperation::slotOperationBtnClick); + connect(ui->exebtn , &QPushButton::clicked , this ,&CBatchOperation::slotExecuteBtnClick); + + connect( this , &CBatchOperation::updateTableRow , [=](int row , bool res){ + refreshData(row , res); + }); + + //初始化接受信息 + m_BatchOpCollect = new CBatchOperationCollect; + m_pCollectThread = new QThread(this); + m_BatchOpCollect->moveToThread(m_pCollectThread); + connect(m_pCollectThread, &QThread::finished, m_pCollectThread, &QThread::deleteLater); + connect(this, &CBatchOperation::releaseCollectThread, m_BatchOpCollect, &CBatchOperationCollect::release, Qt::BlockingQueuedConnection); + connect(m_BatchOpCollect , &CBatchOperationCollect::signal_updateRes , this , &CBatchOperation::slotUpdataRes); + m_pCollectThread->start(); + +} + +QString CBatchOperation::permCheck(int locationId, int regionId) +{ + + int level; + int loginSec; + CPermMngApiPtr permMng = getPermMngInstance("base"); + if(permMng != NULL) + { + if(permMng->PermDllInit() != PERM_NORMAL) + { + return tr("获取登录信息失败!"); + }else + { + std::string instanceName = "DevRealDataWidget"; + if(PERM_NORMAL != permMng->CurUser(m_userId, m_userGroupId, level, loginSec, instanceName)) + { + m_userId = -1; + return tr("获取登录账户失败!"); + } + SSpeFuncDef speFunc; + speFunc.location_id = locationId; + speFunc.region_id = regionId; + speFunc.func_define = "FUNC_SPE_OPT_OVERRIDE"; + if (permMng->PermCheck(PERM_SPE_FUNC_DEF, &speFunc) == PERM_PERMIT) + return ""; + else + { + QString mess = QString(tr("无标签操作权限!")); + return mess; + } + } + } + + return tr("获取登录信息失败!"); +} + +void CBatchOperation::brushTableView(const QStringList &strList) +{ + if( strList.isEmpty()) return; + m_dataPoint.clear(); + QMap searchMap; + searchMap.clear(); + searchMap = CDbInterface::instance()->searchPointInfo(strList); + foreach (QString var, strList) + { + int count = var.count("."); + QString keyTag = var; + QString pointTag = var.section('.', 3, count - 1); + if( searchMap.contains(pointTag)) + { + QString str = searchMap.value(pointTag); + DataPoint data; + data.keyTag = keyTag; + data.pointTag = pointTag; + data.tableName = var.section('.', 2, 2); + QString appName = var.section('.', 1, 1); + data.loctionName = var.section('.', 0, 0); + + data.tagDesc = str.section(',' , 0 ,0); + data.tableDesc = str.section(',',1 ,1); + data.dataType = tableNameToEnum(data.tableName); + if(data.dataType == EN_ANALOG) + data.unit = str.section(",", 2, 2); + else if(data.dataType == EN_DIGITAL || data.dataType == EN_MIX) + { + data.stateTextName = str.section(",", 2, 2); + data.controStateName = str.section(',' , 5); + CDbInterface::instance()->getStateTextList(data.stateTextName, data.options ); + CDbInterface::instance()->getControlList(data.controStateName, data.controlOpt ); + if( data.controlOpt.isEmpty()) data.isEnableContro = false; + else + data.setValue = data.controlOpt.firstKey(); + + } + else { + //其他类型均过滤 + continue; + } + data.region = str.section(',' , 3 ,3 ).toInt(); + data.locationId = str.section(',' , 4, 4).toInt(); + + data.appId = getAppIdByName(appName); + data.domainId = m_nodeInfo.nDomainId; + + QVariantList list = CDbInterface::instance()->rdbNetGetByKey(data.appId , data.tableName , data.pointTag , "value" , data.domainId); + if(list.size() < 2) continue; + switch (data.dataType) + { + case EN_ANALOG: + data.value_ai = list[1].toFloat(); + break; + case EN_ACCUML: + data.value_pi = list[1].toDouble(); + break; + case EN_DIGITAL: + data.value_di = list[1].toInt(); + break; + case EN_MIX: + data.value_mi = list[1].toInt(); + break; + default: + break; + } + + m_dataPoint.push_back(data); + } + } + m_Model->updateDataPoint(m_dataPoint); + +} + +int CBatchOperation::getAppIdByName(const QString &appName) +{ + SAppInfo stAppInfo; + if(m_sysInfoPtr) + m_sysInfoPtr->getAppInfoByName(appName.toStdString(), stAppInfo); + + return stAppInfo.nId; +} + +void CBatchOperation::slotExecuteBtnClick() +{ + recordSendMess.clear(); + sendCtrTagInfo(false); +} + +bool CBatchOperation::sendCtrTagInfo(bool isEnable) +{ + //获取所有勾选状态的item + CBatchOperationModel *sourceModel = qobject_cast(filterModel->sourceModel()); + if( !sourceModel ) return false; + + for (int row = 0; row < sourceModel->rowCount(); ++row) + { + QStandardItem *item = sourceModel->item(row, 0); + QModelIndex indexItem = sourceModel->index(row , 0); + if (item && item->isCheckable() && item->checkState() == Qt::Checked) + { + int location = sourceModel->data(indexItem , Qt::UserRole + 8).toInt(); + int region = sourceModel->data(indexItem , Qt::UserRole + 10).toInt(); + QString desc = sourceModel->data(indexItem , Qt::DisplayRole).toString(); + QString retStr = checkPerm(location, region); + if (!retStr.isEmpty()) + { + QString meg = QString(tr("测点“%1”,%2")).arg(desc).arg(retStr); + sourceModel->refreshRow(row , false , meg); + continue; + } + + STOptTagInfo info; + info.tagName = ""; + info.setValue = sourceModel->data(indexItem , Qt::UserRole + 12).toDouble(); + info.nIsSet = isEnable?1:0;// 0:取消;1:设置; + info.optType = MT_OPT_TAG_VALUE_SET; + info.tagName = sourceModel->data(indexItem , Qt::UserRole + 2).toString(); + info.keyIdTag = sourceModel->data(indexItem , Qt::UserRole + 1 ).toString().section('.' , 2); + info.appId = sourceModel->data(indexItem , Qt::UserRole + 7).toInt(); + info.locationId = location; + + if (!OptTagInfo(info)) + { + return false; + } + recordSendMess.insert(info.keyIdTag, indexItem.row()); + sourceModel->refreshRow(indexItem.row() , false , tr("控制进行中")); + + } + + } + + return true; +} + +bool CBatchOperation::createReqHead(SOptReqHead &head, const STOptTagInfo &info) +{ + std::string instanceName = "BatchOpeaWidget"; + SNodeInfo& nodeInfo = m_nodeInfo; + head.strSrcTag = "BatchOpeaWidget"; + head.nSrcDomainID = nodeInfo.nDomainId; + head.nDstDomainID = nodeInfo.nDomainId; + head.nAppID = info.appId; + head.strHostName = nodeInfo.strName; + head.strInstName = instanceName; + head.strCommName = m_communicator->getName(); + head.nUserID = m_userId; + head.nUserGroupID = m_userGroupId; + head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + return true; +} + +bool CBatchOperation::OptTagInfo(const STOptTagInfo &info) +{ + iot_net::CMbMessage msg; + msg.setMsgType(MT_OPT_CTRL_DOWN_EXECUTE); + msg.setSubject(info.appId, CH_HMI_TO_OPT_OPTCMD_DOWN); + + SOptCtrlRequest socReq; + SOptCtrlReqQueue sosRq; + + if(!createReqHead(socReq.stHead, info)) + { + return false; + } + + sosRq.strKeyIdTag = info.keyIdTag.toStdString(); + sosRq.nCtrlType = 1; + sosRq.dTargetValue = info.setValue; + socReq.vecOptCtrlQueue.push_back(sosRq); + + std::string content=COptCtrlRequest::generate(socReq); + msg.setData(content); + + LOGERROR("deviceControl():命令执行:%s" , content.c_str()); + + if (!m_communicator->sendMsgToDomain(msg, socReq.stHead.nDstDomainID)) + { + QString mess = QString(tr("下发取消命令失败")); + slotShowMess(mess); + + return false; + } + + return true; +} + + + +void CBatchOperation::slotShowMess(const QString &mess) +{ + QMessageBox::warning(this, tr("提示"), mess, QMessageBox::Ok); +} + +void CBatchOperation::showEvent(QShowEvent *event) +{ + QWidget::showEvent(event); + ui->tableView->horizontalHeader()->resizeSection(0, 360); //设置列宽在所有模型导入之后 +} + +QString CBatchOperation::checkPerm(int location, int region) +{ + int level; + int loginSec; + CPermMngApiPtr permMng = getPermMngInstance("base"); + if(permMng != NULL) + { + if(permMng->PermDllInit() != PERM_NORMAL) + { + return tr("获取登录信息失败!"); + }else + { + std::string instanceName = "BatchOperation"; + if(PERM_NORMAL != permMng->CurUser(m_userId, m_userGroupId, level, loginSec, instanceName)) + { + m_userId = -1; + return tr("获取登录账户失败!"); + } + SSpeFuncDef speFunc; + speFunc.location_id = location; + speFunc.region_id = region; + speFunc.func_define = "FUNC_SPE_OPT_CTRL"; + if (permMng->PermCheck(PERM_SPE_FUNC_DEF, &speFunc) == PERM_PERMIT) + return ""; + else + { + QString mess = QString(tr("无标签操作权限!")); + return mess; + } + } + } + + return tr("获取登录信息失败!"); +} +void CBatchOperation::refreshData(int rowNum, bool res) +{ + //获取对应的条目 + CBatchOperationModel *sourceModel = qobject_cast(filterModel->sourceModel()); + if( !sourceModel || rowNum > sourceModel->rowCount()) return; + + QStandardItem *item = sourceModel->item(rowNum, 0); + QModelIndex indexItem = sourceModel->index(rowNum , 0); + item->setCheckable(true); + QString resStr = res? tr("成功"):tr("失败"); + //sourceModel->setData( indexItem , resStr , Qt::TextColorRole); +} + +void CBatchOperation::slotUpdataRes(QMap res) +{ + if(res.isEmpty() || recordSendMess.isEmpty()) return; + QMap::iterator iter = res.begin(); + for( ; iter != res.end() ;iter++) + { + if( recordSendMess.contains(iter.key()) ) + { + int rowNum = recordSendMess.value(iter.key()); + QString resStr = iter.value().isEmpty()?QString(tr("成功")):QString(tr("失败:%1").arg(iter.value())); + CBatchOperationModel *sourceModel = qobject_cast(filterModel->sourceModel()); + sourceModel->refreshRow(rowNum , true , resStr); + } + } + ui->tableView->update(); + +} + +void CBatchOperation::showContextMenu(const QPoint &pos) +{ + QModelIndex index = ui->tableView->indexAt(pos); + int model = ui->m_typeCb->currentIndex(); + if (!index.isValid() || model <= 0) { + return; + } + + QMenu contextMenu; + QAction *editAction = new QAction(tr("批量编辑"), this); + connect(editAction, &QAction::triggered, [=]() { showDialog(model , index); }); + contextMenu.addAction(editAction); + contextMenu.exec(ui->tableView->viewport()->mapToGlobal(pos)); + +} + +void CBatchOperation::showDialog(int model, const QModelIndex &index) +{ + QMap ctrOptions; + ctrOptions.clear(); + CInputDialog dialog(model); + if( model > EN_ANALOG ) + { + QModelIndex sourceIndex = filterModel->mapToSource(index); + ctrOptions = sourceIndex.model()->data(sourceIndex , Qt::UserRole + 11).value>(); + int nextRow = index.row() + 1; + while(ctrOptions.isEmpty()) + { + if (nextRow >= filterModel->rowCount()) + { + QMessageBox::warning(this , tr("警告") , tr("暂不能批量操作!")); + return; + } + QModelIndex nextProxyIndex = ui->tableView->model()->index(nextRow, index.column()); + sourceIndex = filterModel->mapToSource(nextProxyIndex); + ctrOptions = sourceIndex.model()->data(sourceIndex , Qt::UserRole + 11).value>(); + nextRow ++; + } + dialog.setComBoxPara(ctrOptions); + } + if(QDialog::Accepted == dialog.exec() ) + { + double value = dialog.getValue(); + setAllColumnValue(value); + } +} + +void CBatchOperation::slotOperationBtnClick() +{ + int model = ui->m_typeCb->currentIndex(); + QModelIndex index = filterModel->index(0 ,2); + if( index.isValid() ) + { + showDialog(model , index); + }else + { + QMessageBox::warning(this , tr("警告") , tr("暂不能批量操作!")); + } +} + +void CBatchOperation::setAllColumnValue( double newValue) +{ + // 获取源模型 + CBatchOperationModel *sourceModel = qobject_cast(filterModel->sourceModel()); + if (!sourceModel) return; + int rowCount = filterModel->rowCount(); + + for (int row = 0; row < rowCount; ++row) { + QModelIndex proxyIndex = filterModel->index(row, 2); + QModelIndex sourceIndex = filterModel->mapToSource(proxyIndex); + QStandardItem *item = sourceModel->item(sourceIndex.row(), 0); + if (sourceIndex.isValid() && item && item->isCheckable() && item->checkState() == Qt::Checked) { + sourceModel->setData(sourceIndex, newValue, Qt::EditRole); + } + } +} + diff --git a/product/src/gui/plugin/BatchOperation/CBatchOperation.h b/product/src/gui/plugin/BatchOperation/CBatchOperation.h new file mode 100644 index 00000000..8ec36056 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CBatchOperation.h @@ -0,0 +1,108 @@ +#ifndef CPCSBATCHOPERATION_H +#define CPCSBATCHOPERATION_H + +#include +#include +#include +#include +#include +#include +#include + +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" +#include "CBatchOperationCollect.h" +#include "BatchOperationComm.h" +#include "CustonHeadView.h" +#include "CBatchOperationModel.h" +#include "CustomFilterModel.h" + +namespace Ui { +class CBatchOperation; +} + +class CBatchOperation : public QWidget +{ + Q_OBJECT + +public: + explicit CBatchOperation(QWidget *parent = 0 , bool editMode = true); + ~CBatchOperation(); + + int tableNameToEnum(const QString &tableName); + +public slots: + void setParaFromView( const int ®ionId , const QString &str); + + void slotShowMess(const QString &mess); + +signals: + void updateData(const QStringList &strList); + + void updateTableRow(int , bool); + + void releaseCollectThread(); + +protected: + void showEvent(QShowEvent *event) override; + +private: + void initStyleSheet(); + + void initMsg(); + + void readNodeInfo(); //获取本机节点信息 + + void initialize(); + + QString permCheck(int locationId, int regionId); + + int getAppIdByName(const QString &appName); + + bool sendCtrTagInfo(bool isEnable); + + QString checkPerm(int location, int region); + + bool createReqHead(SOptReqHead &head, const STOptTagInfo &info); + + bool OptTagInfo(const STOptTagInfo &info); + + void setAllColumnValue( double newValue); + +private slots: + void brushTableView(const QStringList &strList); + void slotExecuteBtnClick(); + void refreshData(int rowNum, bool res); + void slotUpdataRes(QMap res); + void showContextMenu(const QPoint &pos); + void showDialog(int model , const QModelIndex &index); + void slotOperationBtnClick(); + +private: + Ui::CBatchOperation *ui; + + iot_public::CSysInfoInterfacePtr m_sysInfoPtr; + iot_net::CMbCommunicator *m_communicator; //发送 + CBatchOperationCollect *m_BatchOpCollect; //接受信息订阅 + QThread *m_pCollectThread; + iot_public::SNodeInfo m_nodeInfo; //本机节点信息 + + CBatchOperationModel *m_Model; + QList m_dataPoint; + + + int m_regionId; + + int m_userId; + int m_userGroupId; + + CustonHeadView *header; //自定义表头 + + CustomFilterModel *filterModel;//自定义过滤器 + + QMap recordSendMess; +}; + +#endif // CPCSBATCHOPERATION_H diff --git a/product/src/gui/plugin/BatchOperation/CBatchOperation.ui b/product/src/gui/plugin/BatchOperation/CBatchOperation.ui new file mode 100644 index 00000000..7c8e28d8 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CBatchOperation.ui @@ -0,0 +1,139 @@ + + + CBatchOperation + + + + 0 + 0 + 1100 + 552 + + + + Dialog + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 测点类型 + + + + + + + + + + + 0 + 0 + + + + + 80 + 20 + + + + 批量操作 + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + 执行 + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/BatchOperation/CBatchOperationCollect.cpp b/product/src/gui/plugin/BatchOperation/CBatchOperationCollect.cpp new file mode 100644 index 00000000..59dd1ec1 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CBatchOperationCollect.cpp @@ -0,0 +1,134 @@ +#include "CBatchOperationCollect.h" +#include +#include "pub_logger_api/logger.h" + +CBatchOperationCollect::CBatchOperationCollect(/*int appID,*/QObject *parent): + QObject(parent), + m_pMbComm(NULL), + m_pTimer(NULL), + m_nTimeCount(0) +{ + initMsg(); + if(!addSub(0, CH_OPT_TO_HMI_OPTCMD_UP)) + { + return; + } + + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); + m_pTimer->start(100); +} + +CBatchOperationCollect::~CBatchOperationCollect() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + delSub(0, CH_OPT_TO_HMI_OPTCMD_UP); + closeMsg(); +} + +void CBatchOperationCollect::release() +{ + delete this; +} + +void CBatchOperationCollect::initMsg() +{ + if(m_pMbComm == NULL) + { + m_pMbComm = new iot_net::CMbCommunicator("BatchOperation"); + } +} +void CBatchOperationCollect::closeMsg() +{ + if(m_pMbComm != NULL) + { + delete m_pMbComm; + } + m_pMbComm = NULL; +} + +bool CBatchOperationCollect::addSub(int appID, int channel) +{ + if(m_pMbComm) + { + return m_pMbComm->addSub(appID, channel); + } + else + { + return false; + } +} + +bool CBatchOperationCollect::delSub(int appID, int channel) +{ + if(m_pMbComm) + { + return m_pMbComm->delSub(appID, channel); + } + else + { + return false; + } +} + +void CBatchOperationCollect::recvMessage() +{ + m_nTimeCount = (m_nTimeCount + 1) % 36000; + + if(m_nTimeCount % 10 == 0) + { + processChangeData(); + } + + try + { + iot_net::CMbMessage objMsg; + for(int i = 0; i < 6; i++) + { + if(m_pMbComm->recvMsg(objMsg, 0)) + { + if(objMsg.isValid()) + { + if(objMsg.getChannelID() == CH_OPT_TO_HMI_OPTCMD_UP + && objMsg.getMsgType() == MT_OPT_CTRL_UP_EXECUTE_REPLY) + { + std::string str((const char*)objMsg.getDataPtr(), objMsg.getDataSize()); + SOptCtrlReply socr; + if(!COptCtrlReply::parse(str,socr)) + { + return; + } + QString result = QString::fromStdString(str); + if(socr.stHead.nIsSuccess==1) + { + m_controRes.insert(QString::fromStdString(socr.stHead.strKeyIdTag) , ""); + }else + { + m_controRes.insert(QString::fromStdString(socr.stHead.strKeyIdTag) , QString::fromStdString( socr.stHead.strResultStr )); + } + LOGERROR("deviceControl():命令执行结果:%s" , result.toStdString().c_str()); + } + } + } + } + } + catch(...) + { + + } +} +void CBatchOperationCollect::processChangeData() +{ + if(!m_controRes.isEmpty()) + { + LOGINFO("emit signal_updateRes dataList:%d",m_controRes.count()); + emit signal_updateRes(m_controRes); + m_controRes.clear(); + } +} diff --git a/product/src/gui/plugin/BatchOperation/CBatchOperationCollect.h b/product/src/gui/plugin/BatchOperation/CBatchOperationCollect.h new file mode 100644 index 00000000..4f1471eb --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CBatchOperationCollect.h @@ -0,0 +1,44 @@ +#ifndef CBATCHOPERATIONCOLLECT_H +#define CBATCHOPERATIONCOLLECT_H + +#include +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" + +class QTimer; +class CBatchOperationCollect : public QObject +{ + Q_OBJECT +public: + explicit CBatchOperationCollect(/*int appID,*/QObject * parent = 0); + ~CBatchOperationCollect(); + +public slots: + void release(); + +private: + void initMsg(); + void closeMsg(); + bool addSub(int appID, int channel); + bool delSub(int appID, int channel); + +private slots: + void recvMessage(); + void processChangeData(); + +signals: + void signal_updateRes(QMap controRes); + + +private: + iot_net::CMbCommunicator *m_pMbComm; + QTimer * m_pTimer; + int m_nTimeCount; + QMap m_controRes; +}; + +#endif // CBATCHOPERATIONCOLLECT_H diff --git a/product/src/gui/plugin/BatchOperation/CBatchOperationModel.cpp b/product/src/gui/plugin/BatchOperation/CBatchOperationModel.cpp new file mode 100644 index 00000000..1d7b1a4b --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CBatchOperationModel.cpp @@ -0,0 +1,321 @@ +#include "CBatchOperationModel.h" + +#include + +CBatchOperationModel::CBatchOperationModel(QObject *parent) + : QStandardItemModel(parent) +{ + m_header<= m_dataList.size()) + return QVariant(); + + if(role == Qt::TextAlignmentRole) + { + return Qt::AlignCenter; + } + + QModelIndex sourceIndex = index; + + + const DataPoint &item = m_dataList.at(sourceIndex.row()); + + if ( !item.isEnableContro && role == Qt::ForegroundRole) { + return QBrush(QColor(169, 169, 169)); + } + else if (role == Qt::ForegroundRole) { + return QVariant(); + } + + + if (role == Qt::CheckStateRole && sourceIndex.column() == 0 ) + { + return this->item(sourceIndex.row(), 0)->checkState(); + } + else if (role == Qt::UserRole + 1) + { + return item.keyTag; + } + else if (role == Qt::UserRole + 2) + { + return item.pointTag; + } + else if (role == Qt::UserRole + 3) + { + return item.tableName; + } + else if (role == Qt::UserRole + 4) + { + return item.tagDesc; + } + else if (role == Qt::UserRole + 5) + { + return item.tableDesc; + } + else if (role == Qt::UserRole + 6) + { + return item.dataType; + } + else if (role == Qt::UserRole + 7) + { + return item.appId; + } + else if (role == Qt::UserRole + 8) + { + return item.locationId; + } + else if (role == Qt::UserRole + 9) + { + return item.domainId; + }else if (role == Qt::UserRole + 10) + { + return item.region; + }else if (role == Qt::UserRole + 11) + { + return QVariant::fromValue(item.controlOpt); + }else if (role == Qt::UserRole + 12) + { + return item.setValue; + } + + if (role == Qt::DisplayRole || role == Qt::EditRole) { + switch (sourceIndex.column()) { + case 0: + { + return item.tableDesc + " " +item.tagDesc + item.unit; + break; + } + case 1: + { + if(item.dataType == EN_ANALOG) + { + return QString::number(item.value_ai, 'f', 2); + } + else if(item.dataType == EN_DIGITAL) + { + return CDbInterface::instance()->getStateTextNameByValue(item.stateTextName, item.value_di); + } + else if(item.dataType == EN_ACCUML) + { + return QString::number(item.value_pi, 'f', 2); + } + else if(item.dataType == EN_MIX) + { + return CDbInterface::instance()->getStateTextNameByValue(item.stateTextName, item.value_mi); + } + break; + } + case 2: + if(item.dataType == EN_DIGITAL || item.dataType == EN_MIX) + { + return item.controlOpt.isEmpty()?QString(""):item.controlOpt.value(item.setValue , item.controlOpt.first()); + }else + { + return item.setValue; + } + case 3: + { + return item.resText; + } + default: + break; + } + + } + + return QVariant(); +} + +bool CBatchOperationModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount()) + return false; + + int type = index.model()->data(index, Qt::UserRole + 6).toInt(); + + QModelIndex sourceIndex = index; + + if (sourceIndex.column() == 0 && role == Qt::CheckStateRole) { + QStandardItem *item = this->item(sourceIndex.row(), 0); // 获取第一列的项 item + if (item) { + item->setCheckState(static_cast(value.toInt())); // 设置复选框的状态 + emit dataChanged(sourceIndex, sourceIndex, {role}); + return true; + } + } + + if (role == Qt::EditRole ) { + if( sourceIndex.column() == 0) + { + m_dataList[sourceIndex.row()].isEnableContro = value.toBool(); + emit dataChanged(sourceIndex, sourceIndex, {Qt::DisplayRole}); + return true; + } + if( sourceIndex.column() == 2 ) + { + if( EN_DIGITAL == type || EN_MIX == type) + { + if( !m_dataList[sourceIndex.row()].controlOpt.contains(value.toInt())) + { + return false; + } + } + m_dataList[sourceIndex.row()].setValue = value.toDouble(); + emit dataChanged(sourceIndex, sourceIndex, {Qt::DisplayRole}); + return true; + }else if( sourceIndex.column() == 3) + { + m_dataList[sourceIndex.row()].resText = value.toString(); + emit dataChanged(sourceIndex, sourceIndex, {Qt::DisplayRole}); + return true; + } + } + + if( sourceIndex.column() == 1) + { + if( role == Qt::UserRole + 1) + { + m_dataList[sourceIndex.row()].value_ai = value.toFloat(); + } + else if( role == Qt::UserRole + 2) + { + m_dataList[sourceIndex.row()].value_pi = value.toDouble(); + } + else if( role == Qt::UserRole + 3) + { + m_dataList[sourceIndex.row()].value_di = value.toInt(); + } + else if( role == Qt::UserRole + 4) + { + m_dataList[sourceIndex.row()].value_mi = value.toInt(); + } + } + + + return false; +} + +Qt::ItemFlags CBatchOperationModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + + + QModelIndex sourceIndex = index; + Qt::ItemFlags defaultFlags = QStandardItemModel::flags(sourceIndex); + + if (sourceIndex.column() == 0) + { + const DataPoint &item = m_dataList.at(sourceIndex.row()); + if (item.isEnableContro) { + return Qt::ItemIsUserCheckable | defaultFlags; + } else { + return defaultFlags & ~Qt::ItemIsEnabled & ~Qt::ItemIsUserCheckable; + } + } + + if( sourceIndex.column() == 1 || sourceIndex.column() == 3) + { + return Qt::ItemIsSelectable | Qt::ItemIsEnabled | defaultFlags; + } + + return defaultFlags; +} + + +void CBatchOperationModel::updateDataPoint(QList &dataList) +{ + beginResetModel(); + m_dataList = dataList; + populateModel(); + endResetModel(); +} + +void CBatchOperationModel::refreshRow(int rowNum, bool checkState, QString controStr) +{ + if( rowNum < 0 || rowNum >= m_dataList.size() ) return; + + m_dataList[rowNum].isEnableContro = checkState; + m_dataList[rowNum].resText = controStr; + + int appid = m_dataList[rowNum].appId; + QString tableName = m_dataList[rowNum].tableName; + QString point = m_dataList[rowNum].pointTag; + int domainid = m_dataList[rowNum].domainId; + int type = m_dataList[rowNum].dataType; + QVariantList list = CDbInterface::instance()->rdbNetGetByKey(appid , tableName , point , "value" , domainid); + if(list.size() >= 2) + { + switch (type) + { + case EN_ANALOG: + m_dataList[rowNum].value_ai = list[1].toFloat(); + break; + case EN_ACCUML: + m_dataList[rowNum].value_pi = list[1].toDouble(); + break; + case EN_DIGITAL: + m_dataList[rowNum].value_di = list[1].toInt(); + break; + case EN_MIX: + m_dataList[rowNum].value_mi = list[1].toInt(); + break; + default: + break; + } + } + QStandardItem *item = this->item(rowNum, 0); + if (item && !checkState) + { + item->setCheckState(Qt::Unchecked); + } + + + + emit dataChanged(index(rowNum, 0), index(rowNum, columnCount() - 1)); + +} + +void CBatchOperationModel::populateModel() +{ + clear(); // 清空模型 + setColumnCount(4); // 设置列数 + + for (const DataPoint &item : m_dataList) { + QList items; + QStandardItem * itemHead = new QStandardItem(""); + itemHead->setCheckable(item.isEnableContro?true:false); + items.append(itemHead); + items.append(new QStandardItem("")); + items.append(new QStandardItem("")); + items.append(new QStandardItem("")); + appendRow(items); + } +} + +void CBatchOperationModel::setAllChecked(bool checked) +{ + Qt::CheckState state = checked ? Qt::Checked : Qt::Unchecked; + for (int row = 0; row < rowCount(); ++row) { + QModelIndex index = this->index(row, 0); + if (flags(index) & Qt::ItemIsUserCheckable) { + setData(index, state, Qt::CheckStateRole); + } + } +} diff --git a/product/src/gui/plugin/BatchOperation/CBatchOperationModel.h b/product/src/gui/plugin/BatchOperation/CBatchOperationModel.h new file mode 100644 index 00000000..ed8cc92e --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CBatchOperationModel.h @@ -0,0 +1,39 @@ +#ifndef CBATCHOPERATIONMODEL_H +#define CBATCHOPERATIONMODEL_H + +#include +#include +#include "BatchOperationComm.h" +#include "CDbInterface.h" +#include + +class CBatchOperationModel : public QStandardItemModel +{ + Q_OBJECT + +public: + explicit CBatchOperationModel(QObject *parent = nullptr); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole) override; + + Qt::ItemFlags flags(const QModelIndex& index) const override; + void updateDataPoint(QList &dataList); + void refreshRow(int rowNum , bool checkState , QString controStr); + +private: + void populateModel(); + +public slots: + void setAllChecked(bool checked); + +private: + QStringList m_header; + QList m_dataList; +}; + +#endif // CBATCHOPERATIONMODEL_H diff --git a/product/src/gui/plugin/BatchOperation/CDbInterface.cpp b/product/src/gui/plugin/BatchOperation/CDbInterface.cpp new file mode 100644 index 00000000..53db66b5 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CDbInterface.cpp @@ -0,0 +1,806 @@ +#include "CDbInterface.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" +#include "../../idl_files/Public.pb.h" +#include +#include "BatchOperationComm.h" + +using namespace iot_dbms; +using namespace iot_public; +using namespace iot_idl; + +CDbInterface *CDbInterface::m_pInstance = NULL; + +CDbInterface::CDbInterface() +{ + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + + m_rtdbAccess = new iot_dbms::CRdbAccess(); + m_rdbNetAccess = new iot_dbms::CRdbNetApi(); + + readUnitInfo(); + readDiStatus(); + readAiStatus(); + loadRTLocation(); + loadDeviceInfo(); +} + +CDbInterface *CDbInterface::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CDbInterface(); + } + return m_pInstance; +} + +void CDbInterface::destory() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + if(m_rdbNetAccess != NULL) + { + delete m_rdbNetAccess; + } + m_rdbNetAccess = NULL; + + m_mapUnit.clear(); + m_mapAiStatus.clear(); + m_mapDiStatus.clear(); + m_pInstance = NULL; + delete this; +} + +QMap CDbInterface::locationInfo() +{ + return m_locationInfo; +} + +QString CDbInterface::getLocationDesc(const int &locId) +{ + return m_locationInfo.value(locId); +} + +QList CDbInterface::getLocationOrder() +{ + return m_locOrder; +} + +bool CDbInterface::queryDevGroupInfoList(const int &nLocId, const int &nSubId, QList > &devgList) +{ + if(nLocId == CN_InvalidLocationId) + { + return false; + } + QSqlQuery query; + QString sqlSequenceQuery; + if(nSubId == CN_InvalidSubsystemId) + { + //< 所有专业 + sqlSequenceQuery = QString("select tag_name, description from dev_group where location_id = %1 order by dev_group_no asc; ") + .arg(nLocId); + } + else + { + sqlSequenceQuery = QString("select tag_name, description from dev_group where location_id = %1 and sub_system = %2 order by dev_group_no asc; ") + .arg(nLocId).arg(nSubId); + } + if(!m_pReadDb->execute(sqlSequenceQuery, query)) + { + LOGINFO("查找位置[%d],专业[%d]下的设备组失败!",nLocId,nSubId); + return false; + } + while(query.next()) + { + QPair pair; + pair.first = query.value(0).toString(); + pair.second = query.value(1).toString(); + devgList.append(pair); + } + return true; +} + +QMap CDbInterface::deviceInfo(const QString &devGroupName) +{ + return m_devGDevInfoMap.value(devGroupName, QMap()); +} + +QList CDbInterface::deviceInfoByDevg(const QString &devGroupName) +{ + return m_devGDevInfoMap.value(devGroupName, QMap()).keys(); +} + +QMap CDbInterface::readDevGroupDesc(const QStringList &tagList) +{ + QMap map; + if(tagList.isEmpty()) + { + return map; + } + if(!m_pReadDb->isOpen()) + { + return map; + } + QSqlQuery query; + QString str = tagList.join("','"); + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION from dev_group where TAG_NAME in ('%1')").arg(str); + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + + map.insert(tag, desc); + } + return map; +} + +QMap CDbInterface::searchPointInfo(const QStringList &dataList) +{ + if( dataList.isEmpty()) {return QMap();} + if(!m_pReadDb->isOpen()) + { + return QMap(); + } + + QMap res; + res.clear(); + + + QSqlQuery query; + QStringList queries; + + foreach (QString var, dataList) + { + int count = var.count("."); + QString tagName = var.section('.', 3, count - 1); + QString tableName = var.section('.', 2, 2); + QString add = QString(); + QString joinStr = QString(); + QString add2 = QString(); + if(tableName == "analog" || tableName == "accuml") + { + add = ",t1.UNIT_ID"; + add2 = ", NULL AS CTRL_ACT_NAME"; + } + else if( tableName == "mix" ) + { + add = ",t1.STATE_TEXT_NAME"; + add2 = ", t4.CTRL_ACT_NAME"; + joinStr = "LEFT JOIN mix_control as t4 ON t1.TAG_NAME = t4.TAG_NAME "; + + }else if ( tableName == "digital" ) + { + add = ",t1.STATE_TEXT_NAME"; + add2 = ", t4.CTRL_ACT_NAME"; + joinStr = "LEFT JOIN digital_control as t4 ON t1.TAG_NAME = t4.TAG_NAME "; + } + QString sqlQuery = QString( + "SELECT t1.TAG_NAME, t1.DESCRIPTION,t3.DESCRIPTION%1, t1.REGION_ID, t1.LOCATION_ID ,'%2' AS table_name%3 " + "FROM %4 as t1 " + "LEFT JOIN dev_info as t2 ON t1.DEVICE = t2.TAG_NAME " + "LEFT JOIN dev_group as t3 ON t2.GROUP_TAG_NAME = t3.TAG_NAME " + "%5" + "WHERE t1.TAG_NAME = '%6'") + .arg(add) + .arg(tableName) + .arg(add2) + .arg(tableName) + .arg(joinStr) + .arg(tagName); + //qDebug()<execute(finalQuery, query); + //qDebug()< > CDbInterface::readPointInfo(const QStringList &strDev, const QStringList &listTableName) +{ + if(strDev.isEmpty()) + { + return QMap>(); + } + + QMap> map; + for(int nIndex=0; nIndex ret = readPointInfo(strDev, tableName); + if(!ret.isEmpty()) + { + map.insert(tableName, ret); + } + } + return map; +} + +QMap CDbInterface::readPointInfo(const QStringList &strDev, const QString &strTableName) +{ + if(strDev.isEmpty()) + { + return QMap(); + } + if(!m_pReadDb->isOpen()) + { + return QMap(); + } + + QMap map; + QSqlQuery query; + QString addQuery; + for(int nIndex = 0; nIndex < strDev.length(); ++nIndex) + { + addQuery += "'" + strDev[nIndex] + "'"; + if(nIndex != strDev.length() - 1) + { + addQuery += ","; + } + } + + QString add = QString(); + if(strTableName == "analog" || strTableName == "accuml") + { + add = ",t1.UNIT_ID"; + } + else if(strTableName == "digital" || strTableName == "mix") + { + add = ",t1.STATE_TEXT_NAME"; + } + QString sqlQuery = QString("select t1.TAG_NAME,t1.DESCRIPTION,t1.SEQ_NO,t2.DESCRIPTION%1,t1.REGION_ID,t1.LOCATION_ID,t1.SUB_SYSTEM from %2 as t1 left join dev_info as t2 on t1.DEVICE = t2.TAG_NAME where t1.DEVICE in (%3)").arg(add).arg(strTableName).arg(addQuery); + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + int seq = query.value(2).toInt(); + QString dev = query.value(3).toString(); + int region = query.value(5).toInt(); + int location = query.value(6).toInt(); + int subSystem = query.value(7).toInt(); + QString value; + if(strTableName == "analog" || strTableName == "accuml") + { + QString unitName = getUnitName(query.value(4).toInt()); + QString unit = QString(); + if(unitName != " ") + unit = " (" + unitName + ")"; + + value = QString("%1,%2,%3,%4,%5,%6,%7").arg(desc).arg(dev).arg(seq).arg(unit).arg(region).arg(location).arg(subSystem); + } + else if(strTableName == "digital" || strTableName == "mix") + { + QString stateTextName = query.value(4).toString(); + value = QString("%1,%2,%3,%4,%5,%6,%7").arg(desc).arg(dev).arg(seq).arg(stateTextName).arg(region).arg(location).arg(subSystem); + } + else + { + value = QString("%1,%2,%3,%4,%5,%6,%7").arg(desc).arg(dev).arg(seq).arg("").arg(region).arg(location).arg(subSystem); + } + + map.insert(tag, value); + } + return map; +} + +QString CDbInterface::getUnitName(int unitId) +{ + QMap::const_iterator iter = m_mapUnit.find(unitId); + if(iter != m_mapUnit.constEnd()) + { + return iter.value(); + } + return " "; +} + +QString CDbInterface::getStateTextNameByValue(const QString &textName, int value) +{ + QString ret = QString::number(value); + if(m_rtdbAccess->open("base", "dict_state_text_info")) + { + CONDINFO condition1; + memcpy(condition1.name, "state_text_name", strlen("state_text_name")); + condition1.logicalop = ATTRCOND_AND; + condition1.relationop = ATTRCOND_EQU; + condition1.conditionval = textName.toStdString().c_str(); + + CONDINFO condition2; + memcpy(condition2.name, "actual_value", strlen("actual_value")); + condition2.logicalop = ATTRCOND_AND; + condition2.relationop = ATTRCOND_EQU; + condition2.conditionval = value; + + std::vector vecCondInfo; + vecCondInfo.push_back(condition1); + vecCondInfo.push_back(condition2); + + CRdbQueryResult result; + std::vector columns; + columns.push_back("display_value"); + if(m_rtdbAccess->select(vecCondInfo, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + ret = QString::fromStdString(value.toStdString()); + } + } + m_rtdbAccess->close(); + } + return ret; +} + +bool CDbInterface::getStateTextList(const QString &textName, QMap& textMap) +{ + if (m_rtdbAccess->open("base", "dict_state_text_info")) + { + CONDINFO condition1; + memcpy(condition1.name, "state_text_name", strlen("state_text_name")); + condition1.logicalop = ATTRCOND_AND; + condition1.relationop = ATTRCOND_EQU; + condition1.conditionval = textName.toStdString().c_str(); + + std::vector vecCondInfo; + vecCondInfo.push_back(condition1); + + CRdbQueryResult result; + std::vector columns; + columns.push_back("state_text_name"); + columns.push_back("actual_value"); + columns.push_back("display_value"); + + if (m_rtdbAccess->select(vecCondInfo, result, columns)) + { + for (int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 1, value); + int realValue = value.toInt(); + result.getColumnValue(nIndex, 2, value); + QString display_value = QString::fromStdString(value.toStdString()); + textMap[realValue] = display_value; + } + } + else { + return false; + } + m_rtdbAccess->close(); + } + return true; +} + +bool CDbInterface::getControlList(const QString &textName, QMap& textMap) +{ + if( m_pReadDb->isOpen()) + { + QSqlQuery query; + QString sqlQuery = QString( + "SELECT CTRL_ACT_TYPE , CTRL_ACT_NAME " + "FROM opt_ctrl_act_define " + "WHERE CTRL_GRP_NAME = '%1'") + .arg(textName); + m_pReadDb->execute(sqlQuery, query); + + while (query.next()) + { + int seqNo = query.value(0).toInt(); + QString name = query.value(1).toString(); + textMap.insert(seqNo , name); + } + } + return true; +} + +QString CDbInterface::getStatusStr(int status, int table) +{ + QString ret = QString(); + int num = 0; + int temp = status; + while(temp != 0) + { + if((temp % 2) == 1) + { + if(table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) + ret += getAiStatusStr(num); + else if(table == EN_DIGITAL) + ret += getDiStatusStr(num); + ret += " "; + } + temp /= 2; + num += 1; + } + return ret; +} + +QString CDbInterface::getPointDesc(int point_type) +{ + QString ret = QString::number(point_type); + switch (point_type) { + case EN_ANALOG: + { + ret = QObject::tr("模拟量"); + break; + } + case EN_DIGITAL: + { + ret = QObject::tr("数字量"); + break; + } + case EN_ACCUML: + { + ret = QObject::tr("累积量"); + break; + } + case EN_MIX: + { + ret = QObject::tr("混合量"); + break; + } + default: + break; + } + return ret; +} + +bool CDbInterface::isAlarmEnable(int status, int table) +{ + + if (table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) + { + return isBitEnable(status, 21); + } + + else if (table == EN_DIGITAL) + { + return isBitEnable(status, 13); + } + return false; +} + +bool CDbInterface::isCtrlEnable(int status, int table) +{ + if (table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) + { + return isBitEnable(status, 22); + } + + else if (table == EN_DIGITAL) + { + return isBitEnable(status, 14); + } + return false; +} + +bool CDbInterface::isRefreshEnable(int status, int table) +{ + if (table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) + { + return isBitEnable(status, 20); + } + + else if (table == EN_DIGITAL) + { + return isBitEnable(status, 12); + } + return false; +} + +bool CDbInterface::isSetValueEnable(int status, int table) +{ + if (table == EN_ANALOG || table == EN_ACCUML || table == EN_MIX) + { + return isBitEnable(status, 10); + } + + else if (table == EN_DIGITAL) + { + return isBitEnable(status, 11); + } + return false; +} + +bool CDbInterface::isBitEnable(int status, int checkNum) +{ + return ((status >> (checkNum)) & 0x01) == 0x01; +} + +QString CDbInterface::getDiStatusStr(int status) +{ + QMap::const_iterator iter = m_mapDiStatus.find(status); + if(iter != m_mapDiStatus.constEnd()) + { + return iter.value(); + } + return " "; +} + +QString CDbInterface::getAiStatusStr(int status) +{ + QMap::const_iterator iter = m_mapAiStatus.find(status); + if(iter != m_mapAiStatus.constEnd()) + { + return iter.value(); + } + return " "; +} + +void CDbInterface::loadRTLocation() +{ + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return; + } + int level; + std::vector vecLocationId; + std::vector vecPermPic; + if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) + { + LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); + return; + } + + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + QPair id_value; + id_value.first = "location_id"; + id_value.second = "description"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back(id_value.first); + columns.push_back(id_value.second); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + m_locationInfo.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + + std::vector ::const_iterator it = vecLocationId.cbegin(); + while (it != vecLocationId.cend()) + { + if(key.toInt() == *it) + { + m_locationInfo[key.toInt()] = QString::fromStdString(value.toStdString()); + m_locOrder.push_back(key.toInt()); + } + ++it; + } + } + } + } + m_rtdbAccess->close(); +} + +void CDbInterface::loadDeviceInfo() +{ + if(!m_pReadDb->isOpen()) + { + return ; + } + QSqlQuery query; + QString sqlQuery = QString("select TAG_NAME,DESCRIPTION,GROUP_TAG_NAME from dev_info"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + QString tag = query.value(0).toString(); + QString desc = query.value(1).toString(); + QString devg = query.value(2).toString(); + QMap >::iterator iter = m_devGDevInfoMap.find(devg); + if(iter != m_devGDevInfoMap.end()) + { + m_devGDevInfoMap[devg].insert(tag,desc); + }else + { + QMap devMap; + devMap.insert(tag,desc); + m_devGDevInfoMap[devg] = devMap; + } + } +} + +void CDbInterface::readUnitInfo() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + m_mapUnit.clear(); + QSqlQuery query; + QString sqlQuery = QString("select UNIT_ID,UNIT_NAME from dict_unit_info"); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + int id = query.value(0).toInt(); + QString name = query.value(1).toString(); + + m_mapUnit.insert(id, name); + } +} + +void CDbInterface::readDiStatus() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + m_mapDiStatus.clear(); + QSqlQuery query; + QString sqlQuery = QString("select ACTUAL_VALUE,DISPLAY_VALUE from dict_menu_info where MENU_NAME='%1'").arg(DI_STATUS_MENU_NAME); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + int id = query.value(0).toInt(); + QString name = query.value(1).toString(); + + m_mapDiStatus.insert(id, name); + } +} + +void CDbInterface::readAiStatus() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + m_mapAiStatus.clear(); + QSqlQuery query; + QString sqlQuery = QString("select ACTUAL_VALUE,DISPLAY_VALUE from dict_menu_info where MENU_NAME='%1'").arg(AI_STATUS_MENU_NAME); + + m_pReadDb->execute(sqlQuery, query); + + while(query.next()) + { + int id = query.value(0).toInt(); + QString name = query.value(1).toString(); + + m_mapAiStatus.insert(id, name); + } +} + +QVariantList CDbInterface::rdbNetGetByKey(const int &appId, const QString &tableName, const QString &keyInfo, const QString &columnsName, const int &domainId, bool asyn) +{ + QVariantList result; + iot_idl::RdbQuery objQuery; + iot_idl::RdbRet objReply; + m_rdbNetAccess->connect(domainId, appId); + + objQuery.set_strtablename(tableName.toStdString()); + QStringList tmpList = columnsName.split(","); + for(int i = 0; i < tmpList.count(); i++) + { + std::string *pColName = objQuery.add_strselectcolnamearr(); + *pColName = tmpList[i].toStdString(); + } + + iot_idl::RdbCondition *pCondtion = objQuery.add_msgcondition(); + pCondtion->set_enrelation(ENConditionRelation::enumCondEqual); + pCondtion->set_strcolumnname("tag_name"); + SVariable *pCondValue = pCondtion->mutable_msgvalue(); + pCondValue->set_edatatype(DataType::CN_DATATYPE_STRING); + pCondValue->set_strvalue(keyInfo.toStdString()); + + bool ret = m_rdbNetAccess->query(objQuery, objReply, asyn); + if(!ret) + { + result.push_back(-1); + //LOGINFO("CRdbNetApi query %s %s %s failed", appName.toStdString().c_str(), tableName.toStdString().c_str(), keyInfo.toStdString().c_str()); + } + else if(!asyn) + { + QVariantList columnValueList; + int recordNum = objReply.msgrecord_size(); + int columnNum = 0; + result.push_back(recordNum); + + for (int i = 0; i < recordNum; ++i) + { + columnValueList.clear(); + columnNum = objReply.msgrecord(i).msgvaluearray_size(); + for (int j = 0; j < columnNum; ++j) + { + switch (objReply.msgrecord(i).msgvaluearray(j).edatatype()) + { + case DataType::CN_DATATYPE_BOOL: + columnValueList << QVariant::fromValue(objReply.msgrecord(i).msgvaluearray(j).bvalue()); + break; + case CN_DATATYPE_FLOAT: + columnValueList << QVariant::fromValue(objReply.msgrecord(i).msgvaluearray(j).fvalue()); + break; + case CN_DATATYPE_INT32: + columnValueList << QVariant::fromValue(objReply.msgrecord(i).msgvaluearray(j).nvalue()); + break; + case CN_DATATYPE_UINT32: + columnValueList << QVariant::fromValue(objReply.msgrecord(i).msgvaluearray(j).uvalue()); + break; + case CN_DATATYPE_INT64: + columnValueList << QVariant::fromValue(objReply.msgrecord(i).msgvaluearray(j).lvalue()); + break; + case CN_DATATYPE_UINT64: + columnValueList << QVariant::fromValue(objReply.msgrecord(i).msgvaluearray(j).ulvalue()); + break; + case CN_DATATYPE_DOUBLE: + columnValueList << QVariant::fromValue(objReply.msgrecord(i).msgvaluearray(j).dvalue()); + break; + case CN_DATATYPE_STRING: + { + std::string strValue = objReply.msgrecord(i).msgvaluearray(j).strvalue(); + columnValueList << QString::fromStdString(strValue); + } + default: + break; + } + } + + result << columnValueList; + } + } + else + {} + + return result; +} + diff --git a/product/src/gui/plugin/BatchOperation/CDbInterface.h b/product/src/gui/plugin/BatchOperation/CDbInterface.h new file mode 100644 index 00000000..fef38a80 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CDbInterface.h @@ -0,0 +1,75 @@ +#ifndef CDBINTERFACE_H +#define CDBINTERFACE_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "rdb_net_api/CRdbNetApi.h" + +#define DI_STATUS_MENU_NAME ("数字量状态") +#define AI_STATUS_MENU_NAME ("模拟量状态") + +class CDbInterface +{ +public: + static CDbInterface * instance(); + void destory(); + + QMap locationInfo(); + QString getLocationDesc(const int &locId); + QList getLocationOrder(); + bool queryDevGroupInfoList(const int& nLocId, const int &nSubId, QList> &devgList); + + QMap deviceInfo(const QString &devGroupName); + + QList deviceInfoByDevg(const QString &devGroupName); + + QMap readDevGroupDesc(const QStringList &tagList); + QMap> readPointInfo(const QStringList &strDev, const QStringList &listTableName); + QMap readPointInfo(const QStringList& strDev, const QString& strTableName); + + QString getUnitName(int unitId); + QString getStateTextNameByValue(const QString &textName, int value); + bool getStateTextList(const QString &textName,QMap& textMap); + QString getStatusStr(int status, int table); + QString getPointDesc(int point_type); + + bool isAlarmEnable(int status, int table); + bool isCtrlEnable(int status, int table); + bool isRefreshEnable(int status, int table); + bool isSetValueEnable(int status, int table); + bool isBitEnable(int status, int checkNum); + QMap searchPointInfo(const QStringList &dataList); + QVariantList rdbNetGetByKey(const int &appId, const QString &tableName, const QString &keyInfo, + const QString &columnsName, const int &domainId, bool asyn = false); + bool getControlList(const QString &textName, QMap &textMap); +private: + CDbInterface(); + + void readUnitInfo(); + void readDiStatus(); + void readAiStatus(); + + QString getDiStatusStr(int status); + QString getAiStatusStr(int status); + + void loadRTLocation(); + void loadDeviceInfo(); + +private: + static CDbInterface * m_pInstance; + iot_dbms::CDbApi * m_pReadDb; + iot_dbms::CRdbAccess * m_rtdbAccess; + iot_dbms::CRdbNetApi *m_rdbNetAccess; + QMap m_mapUnit; + QMap m_mapDiStatus; + QMap m_mapAiStatus; + + QMap m_locationInfo; //< LocationID-LocationDesc + QList m_locOrder; + + QMap m_devgInfoMap; + QMap > m_devGDevInfoMap; +}; + +#endif // CDBINTERFACE_H diff --git a/product/src/gui/plugin/BatchOperation/CInputDialog.cpp b/product/src/gui/plugin/BatchOperation/CInputDialog.cpp new file mode 100644 index 00000000..b58d9463 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CInputDialog.cpp @@ -0,0 +1,66 @@ +#include "CInputDialog.h" +#include "ui_CInputDialog.h" + +#include "BatchOperationComm.h" + +CInputDialog::CInputDialog(int model , QWidget *parent) : + QDialog(parent), + m_model(model), + ui(new Ui::CInputDialog) +{ + ui->setupUi(this); + initView(); + + connect(ui->okbtn, SIGNAL(clicked()), this, SLOT(accept())); + connect(ui->cancelbtn, SIGNAL(clicked()), this, SLOT(reject())); +} + +CInputDialog::~CInputDialog() +{ + delete ui; +} + +void CInputDialog::initView() +{ + QDoubleValidator *validator = new QDoubleValidator(-1e10, 1e10, 6, ui->lineEdit); + ui->lineEdit->setValidator(validator); + switch(m_model) + { + case EN_ANALOG: + case EN_ACCUML: + ui->stackedWidget->setCurrentIndex(0); + break; + case EN_MIX: + case EN_DIGITAL: + ui->stackedWidget->setCurrentIndex(1); + break; + default: + break; + + } +} + +void CInputDialog::setComBoxPara(const QMap &value) +{ + ui->comboBox->clear(); + QMap::const_iterator iter = value.begin(); + for (; iter !=value.end(); ++iter) + { + ui->comboBox->addItem(iter.value(), iter.key()); + } +} + +double CInputDialog::getValue() +{ + double value = 0; + QStackedWidget* sw = ui->stackedWidget; + if (sw->currentIndex() == 0) + { + value = ui->lineEdit->text().toDouble(); + } + else + { + value = ui->comboBox->currentData().toDouble(); + } + return value; +} diff --git a/product/src/gui/plugin/BatchOperation/CInputDialog.h b/product/src/gui/plugin/BatchOperation/CInputDialog.h new file mode 100644 index 00000000..55d37998 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CInputDialog.h @@ -0,0 +1,30 @@ +#ifndef CINPUTDIALOG_H +#define CINPUTDIALOG_H + +#include +#include + +namespace Ui { +class CInputDialog; +} + +class CInputDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CInputDialog(int model , QWidget *parent = 0); + ~CInputDialog(); + + void initView(); + + void setComBoxPara(const QMap &value); + + double getValue(); + +private: + Ui::CInputDialog *ui; + int m_model; //测点类型 +}; + +#endif // CINPUTDIALOG_H diff --git a/product/src/gui/plugin/BatchOperation/CInputDialog.ui b/product/src/gui/plugin/BatchOperation/CInputDialog.ui new file mode 100644 index 00000000..e513d9f4 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CInputDialog.ui @@ -0,0 +1,142 @@ + + + CInputDialog + + + + 0 + 0 + 314 + 219 + + + + 批量操作 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + + + + + 设置值: + + + + + + + + + + + + 0 + 0 + + + + 设置值 + + + + + + + + 0 + 0 + + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 30 + + + + + + + + + 0 + 0 + + + + + 60 + 30 + + + + 确定 + + + + + + + + 0 + 0 + + + + + 60 + 30 + + + + 取消 + + + + + + + + + + diff --git a/product/src/gui/plugin/BatchOperation/CustomFilterModel.cpp b/product/src/gui/plugin/BatchOperation/CustomFilterModel.cpp new file mode 100644 index 00000000..75a5beae --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CustomFilterModel.cpp @@ -0,0 +1,21 @@ +#include "CustomFilterModel.h" + + +CustomFilterModel::CustomFilterModel(QObject *parent) : QSortFilterProxyModel(parent), filterValue(-1) {} + +void CustomFilterModel::setFilterCriteria(int value) +{ + filterValue = value; + invalidateFilter(); +} + +bool CustomFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + if ( filterValue <= 0) { + return true; + } + + QModelIndex index = sourceModel()->index(source_row, 2, source_parent); + int dataValue = sourceModel()->data(index, Qt::UserRole + 6).toInt(); + return dataValue == filterValue; +} diff --git a/product/src/gui/plugin/BatchOperation/CustomFilterModel.h b/product/src/gui/plugin/BatchOperation/CustomFilterModel.h new file mode 100644 index 00000000..94b6ed04 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CustomFilterModel.h @@ -0,0 +1,20 @@ +#ifndef CUSTOMFILTERMODEL_H +#define CUSTOMFILTERMODEL_H + +#include + +class CustomFilterModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + CustomFilterModel(QObject *parent = nullptr); + + void setFilterCriteria(int value); + +protected: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; + +private: + int filterValue; +}; +#endif // CUSTOMFILTERMODEL_H diff --git a/product/src/gui/plugin/BatchOperation/CustonHeadView.cpp b/product/src/gui/plugin/BatchOperation/CustonHeadView.cpp new file mode 100644 index 00000000..bf776a55 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CustonHeadView.cpp @@ -0,0 +1,48 @@ +#include "CustonHeadView.h" + +#include + +CustonHeadView::CustonHeadView(Qt::Orientation orientation, QWidget *parent): + QHeaderView(orientation , parent), + m_isChecked(false) +{ + +} + +void CustonHeadView::setChecked(bool check) +{ + m_isChecked = check; + this->updateSection(0); +} + + +void CustonHeadView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const +{ + painter->save(); + QHeaderView::paintSection(painter, rect, logicalIndex); + painter->restore(); + + if (logicalIndex == 0) { // 只在第一列绘制复选框 + QStyleOptionButton option; + int checkboxSize = style()->pixelMetric(QStyle::PM_IndicatorWidth); + option.rect = QRect(rect.left() + 5, rect.center().y() - checkboxSize / 2, checkboxSize, checkboxSize); + option.state = QStyle::State_Enabled | (m_isChecked ? QStyle::State_On : QStyle::State_Off); + + // 绘制复选框 + style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter); + } +} + +void CustonHeadView::mousePressEvent(QMouseEvent *event) +{ + if (logicalIndexAt(event->pos()) == 0) { + m_isChecked = !m_isChecked; + emit toggleCheckState(m_isChecked); + updateSection(0); + } else { + QHeaderView::mousePressEvent(event); + } +} + + + diff --git a/product/src/gui/plugin/BatchOperation/CustonHeadView.h b/product/src/gui/plugin/BatchOperation/CustonHeadView.h new file mode 100644 index 00000000..94c3ee20 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/CustonHeadView.h @@ -0,0 +1,31 @@ +#ifndef CUSTONHEADVIEW_H +#define CUSTONHEADVIEW_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class CustonHeadView : public QHeaderView +{ + Q_OBJECT +public: + explicit CustonHeadView(Qt::Orientation orientation, QWidget *parent = nullptr); + void setChecked(bool check); + +signals: + void toggleCheckState(bool checked); + +protected: + void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const; + void mousePressEvent(QMouseEvent *event) override; + +private: + bool m_isChecked; +}; + +#endif // CUSTONHEADVIEW_H diff --git a/product/src/gui/plugin/BatchOperation/main.cpp b/product/src/gui/plugin/BatchOperation/main.cpp new file mode 100644 index 00000000..3cf20ac8 --- /dev/null +++ b/product/src/gui/plugin/BatchOperation/main.cpp @@ -0,0 +1,11 @@ +#include "CBatchOperation.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CBatchOperation w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbPluginWidget.h b/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbPluginWidget.h index 55901c88..a501d541 100644 --- a/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbPluginWidget.h +++ b/product/src/gui/plugin/BreadcrumbNavWidget/CBreadcrumbPluginWidget.h @@ -7,7 +7,7 @@ class CBreadcrumbPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/BriefReportWidget/BriefReportPluginWidget.h b/product/src/gui/plugin/BriefReportWidget/BriefReportPluginWidget.h index 947e78ab..cec2ba24 100644 --- a/product/src/gui/plugin/BriefReportWidget/BriefReportPluginWidget.h +++ b/product/src/gui/plugin/BriefReportWidget/BriefReportPluginWidget.h @@ -7,7 +7,7 @@ class BriefReportPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: BriefReportPluginWidget(QObject *parent = 0); diff --git a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupPluginWidget.h b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupPluginWidget.h index e9364d91..8779050a 100644 --- a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupPluginWidget.h +++ b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupPluginWidget.h @@ -7,7 +7,7 @@ class CButtonGroupPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.cpp b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.cpp index 9e397bad..f072814d 100644 --- a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.cpp +++ b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "pub_utility_api/FileStyle.h" CButtonGroupWidget::CButtonGroupWidget(QWidget *parent, bool editMode) : QWidget(parent), @@ -14,6 +15,7 @@ CButtonGroupWidget::CButtonGroupWidget(QWidget *parent, bool editMode) m_isEdit(editMode) { initView(); + initQss(); } CButtonGroupWidget::~CButtonGroupWidget() @@ -153,3 +155,21 @@ void CButtonGroupWidget::initView() layout->setMargin(0); setLayout(layout); } + +void CButtonGroupWidget::initQss() +{ + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("cButtonGroupWidget.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} diff --git a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.h b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.h index 79d0aa60..79be8b07 100644 --- a/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.h +++ b/product/src/gui/plugin/ButtonGroupWidget/CButtonGroupWidget.h @@ -52,7 +52,7 @@ private slots: private: void initView(); - + void initQss(); private: CJsonReader *m_pJsonReader; bool m_isEdit; diff --git a/product/src/gui/plugin/CNTPTimeWidget/CManualSet.cpp b/product/src/gui/plugin/CNTPTimeWidget/CManualSet.cpp new file mode 100644 index 00000000..e7a12de7 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CManualSet.cpp @@ -0,0 +1,174 @@ +#include "CManualSet.h" + +CManualSet::CManualSet(QObject *parent) + : QObject(parent) +{ + if(!iot_public::createSysInfoInstance(m_sysInfoPtr)) + { +// cout << "createSysInfoInstance fail" << endl; + } + + if(!m_sysInfoPtr->getLocalNodeInfo(m_nodeInfo) == 1) + { +// cout << "getLocalNodeInfo fail" << endl; + } + + m_communicator = new iot_net::CMbCommunicator; + + iot_service::CDpcdaForApp::initGlobalThread(); + m_pDpcdaForApp = new iot_service::CDpcdaForApp(); +} + +CManualSet::~CManualSet() +{ + if(m_communicator) + { + delete m_communicator; + m_communicator = nullptr; + } + + UnsubscribeAll(); + if(m_pDpcdaForApp) + { + delete m_pDpcdaForApp; + m_pDpcdaForApp = nullptr; + } +} + +void CManualSet::InitManualSet() +{ + QStringList manualTagList = m_sManulSetTag.split("."); + if(manualTagList.count() != 5) + { + return; + } + QString strTagName = manualTagList[1] + "." + manualTagList[2] + "." + manualTagList[3]; + m_strTagName = strTagName; + m_tableName = manualTagList[0]; + + Subscribe(); + + //接收实时数据信号槽 + connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateDi, this, &CManualSet::SlotUpdateDi); +} + +void CManualSet::SetData(const QString& strKeyIdTag) +{ + QStringList manualTagList = strKeyIdTag.split("."); + if(manualTagList.count() != 5) + { + return; + } + QString strTagName = manualTagList[1] + "." + manualTagList[2] + "." + manualTagList[3]; + + STOptTagInfo info; + info.setValue = m_dEnable; + info.nIsSet = int(1);// 0:取消;1:设置; + info.optType = MT_OPT_TAG_VALUE_SET; + info.tagName = strTagName; + info.keyIdTag = strKeyIdTag; + info.subSystem = E_nAppID; + info.locationId = int(1); + + if(OptTagInfo(info)) { + emit showMsg("设置控制信息成功"); + }else if(!OptTagInfo(info)){ + emit showMsg("设置控制信息失败"); + } +} + +bool CManualSet::OptTagInfo(const STOptTagInfo &info) +{ + iot_net::CMbMessage msg; + msg.setMsgType(MT_OPT_COMMON_DOWN); + msg.setSubject(info.subSystem, CH_HMI_TO_OPT_OPTCMD_DOWN); + + SOptTagSet sOptTagSet; + SOptTagQueue optTagQueue; + + if(!createReqHead(sOptTagSet.stHead, info)) + { + return false; + } + + optTagQueue.strKeyIdTag = info.keyIdTag.toStdString(); + optTagQueue.nIsSet = info.nIsSet;// 0:取消;1:设置; + optTagQueue.fSetValue = info.setValue; + optTagQueue.strStateText = info.stateText.toStdString(); + optTagQueue.bIsPointQuery = 1; + optTagQueue.nLocationId = info.locationId; + optTagQueue.nSubSystem = info.subSystem; + + sOptTagSet.vecTagQueue.push_back(optTagQueue); + std::string content = COptTagSet::generate(sOptTagSet); + + msg.setMsgType(info.optType); + + msg.setData(content); + if (!m_communicator->sendMsgToDomain(msg, sOptTagSet.stHead.nDstDomainID)) + { +// cout << "sendMsgToDomain fail" << endl; + return false; + } + + return true; +} + +void CManualSet::SlotUpdateDi(const QMap>& diMap) +{ + QMap>::const_iterator iter = diMap.constBegin(); + for(; iter != diMap.constEnd(); iter++) + { + if(iter.key().contains(m_strTagName)) + { + emit SendSurrenderSta(iter.value().first); +// cout << "diMap-->" << iter.key().toStdString() << " first:" << iter.value().first << endl; + } + } + QString di; +} + +bool CManualSet::createReqHead(SOptReqHead &head, const STOptTagInfo &info) +{ + SAppInfo stAppInfo; + if(iotSuccess != m_sysInfoPtr->getAppInfoBySubsystemId(info.subSystem, stAppInfo)) + { + return false; + } + std::string instanceName = "CManualSet"; + SNodeInfo& nodeInfo = m_nodeInfo; + head.strSrcTag = "CNTPTimeWidget"; + head.nSrcDomainID = nodeInfo.nDomainId; + head.nDstDomainID = nodeInfo.nDomainId; + head.nAppID = 4; + head.strHostName = nodeInfo.strName; + head.strInstName = instanceName; + head.strCommName = m_communicator->getName(); + head.nUserID = 11; + head.nUserGroupID = 1; + head.nOptTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + return true; +} + +void CManualSet::Subscribe() +{ + if(m_pDpcdaForApp == Q_NULLPTR) + { + return; + } + UnsubscribeAll(); + +// if(m_tableName != "" && m_strTagName != "") +// { + m_pDpcdaForApp->subscribe(m_tableName.toStdString(), m_strTagName.toStdString(), "value"); + m_pDpcdaForApp->subscribe(m_tableName.toStdString(), m_strTagName.toStdString(), "status"); +// } +} + +void CManualSet::UnsubscribeAll() +{ + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + } +} diff --git a/product/src/gui/plugin/CNTPTimeWidget/CManualSet.h b/product/src/gui/plugin/CNTPTimeWidget/CManualSet.h new file mode 100644 index 00000000..58d08611 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CManualSet.h @@ -0,0 +1,69 @@ +#ifndef CMANUALSET_H +#define CMANUALSET_H + +#include +#include +#include + +#include "PreDefine.h" +#include "CRealDataCollect.h" + +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include "net_msg_bus_api/CMbCommunicator.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "common/MessageChannel.h" +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" + +/******************/ +#include +using namespace std; +/******************/ + +using namespace iot_public; +using namespace iot_service; +using namespace iot_net; + +const int E_nAppID = 4; + +class CManualSet : public QObject +{ + Q_OBJECT +public: + explicit CManualSet(QObject *parent = nullptr); + ~CManualSet(); + + void SetData(const QString& strKeyIdTag); + void InitManualSet(); + +public: + double m_dEnable = 1; + QString m_sManulSetTag; + +signals: + void showMsg(const QString& msg); + void SendSurrenderSta(const int& status); + +private slots: + void SlotUpdateDi(const QMap>& diMap); + +private: + bool OptTagInfo(const STOptTagInfo &info); + bool createReqHead(SOptReqHead &head, const STOptTagInfo &info); + + void Subscribe(); + void UnsubscribeAll(); + +private: + iot_net::CMbCommunicator *m_communicator; + iot_public::CSysInfoInterfacePtr m_sysInfoPtr; + iot_public::SNodeInfo m_nodeInfo; + + iot_service::CDpcdaForApp* m_pDpcdaForApp; //读取实时库 + + QString m_strTagName; + QString m_tableName; +}; + +#endif // CMANUALSET_H diff --git a/product/src/gui/plugin/CNTPTimeWidget/CMsgDeal.cpp b/product/src/gui/plugin/CNTPTimeWidget/CMsgDeal.cpp new file mode 100644 index 00000000..62cf7446 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CMsgDeal.cpp @@ -0,0 +1,424 @@ +#include "CMsgDeal.h" +#include +#include + +CMsgDeal::CMsgDeal(QObject *parent) + : QObject(parent) +{ + m_sysInfo = NULL; + m_objSendCMb = new CMbCommunicator; + m_objRecvCMb = new CMbCommunicator; + m_filterNetWork = ""; + m_localHost = "localhost"; + m_strPassword = "kbdct@0755"; + InitMsgBus(); +} + +CMsgDeal::~CMsgDeal() +{ + delete m_objSendCMb; + m_objSendCMb = nullptr; + + m_objRecvCMb->delSub(E_APPID, CH_OPT_TO_HMI_OPTCMD_UP); + delete m_objRecvCMb; + m_objRecvCMb = nullptr; +} + +void CMsgDeal::setNetWorkName(const QString &networkName) +{ + m_filterNetWork = networkName; +} + +void CMsgDeal::setPasswd(const QString &pswd) +{ + m_strPassword = pswd.toStdString(); +} + +void CMsgDeal::InitMsgBus() +{ + if(!createSysInfoInstance(m_sysInfo)) + { + qDebug() << tr("创建系统信息访问库实例失败!"); + } + + m_permMng = getPermMngInstance("base"); + if(m_permMng != NULL) + { + if(m_permMng->PermDllInit() != PERM_NORMAL) + { +// cout << tr("权限接口初始化失败!").toStdString() << endl; + } + } + + if(!m_objRecvCMb->addSub(E_APPID, CH_OPT_TO_HMI_OPTCMD_UP)) + { +// cout << tr("总线订阅失败!").toStdString() << endl; + return; + } + + SNodeInfo sNodeInfo; + m_sysInfo->getLocalNodeInfo(sNodeInfo); + m_nDomainID = sNodeInfo.nDomainId; + m_localHost = QString::fromStdString(sNodeInfo.strName); +} + +void CMsgDeal::clearMsgBus() +{ + iot_net::CMbMessage msg; + while(true) + { + if(!m_objRecvCMb->recvMsg(msg, 0)) + { + break; + } + } +} + +QString CMsgDeal::NTPQuery(const QString& hostName) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Query_NTP_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated, hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Query_NTP_Message_Ack,hostName); +} + +QString CMsgDeal::TimeQuery(const QString& hostName) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Query_Time_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated, hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Query_Time_Message_Ack,hostName); +} + +QString CMsgDeal::IPQuery(const QString& hostName) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Query_IP_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated,hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Query_IP_Message_Ack,hostName); +} + +QString CMsgDeal::LedQuery(const QString& hostName) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Query_Led_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated,hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Query_Led_Message_Ack,hostName); +} + +QString CMsgDeal::RevNTPSet(const QString& hostName,const bool& sel, const QString& ntpIP) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Set_NTP_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + sReqHead.strPassword = m_strPassword; + + m_strNTPIP = ntpIP.toStdString(); + m_bNTPOn = sel; + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated,hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Set_NTP_Message_Ack,hostName); +} + +QString CMsgDeal::RevTimeSet(const QString& hostName,const QDateTime& dateTime) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Set_Time_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + + m_nSetTime = dateTime.toSecsSinceEpoch(); + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated,hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Set_Time_Message_Ack,hostName); +} + +QString CMsgDeal::RevIPSet(const QString& hostName,const QString& netWorkName, const QString& ip, + const QString& gatway, const QString& mask) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Set_IP_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + + m_strNetWorkName = netWorkName.toStdString(); + m_strIp = ip.toStdString(); + m_strGatway = gatway.toStdString(); + m_strMask = mask.toStdString(); + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated,hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Set_IP_Message_Ack,hostName); +} + +QString CMsgDeal::RevLedSet(const QString& hostName,const int& ledValue) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Set_Led_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + + m_nLedValue = ledValue; + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated,hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Set_Led_Message_Ack,hostName); +} + +QString CMsgDeal::RevMessage(int nMsgType, const QString &hostName) +{ + Q_UNUSED(nMsgType); + Q_UNUSED(hostName); + + iot_net::CMbMessage msg; + while(m_objRecvCMb->recvMsg(msg, 3000)) + { + if(msg.getMsgType() != MT_SYS_PARAMS_TO_HMI_UP) + { + continue; + } + + //字符串反序列化Json数据 + boost::property_tree::ptree pt; + std::string msgStr((char*)msg.getDataPtr(), (int)msg.getDataSize()); + try { + std::istringstream iss; + iss.str(msgStr.c_str()); + boost::property_tree::json_parser::read_json(iss, pt); + } + catch (boost::property_tree::ptree_error &pt_error) + { + Q_UNUSED(pt_error); + return tr("消息解析错误"); + } + //解析Json数据 + int msgType = pt.get("msgType"); + std::string ErroStr = pt.get("ErroStr"); + if(!ErroStr.empty()) + { + return QString::fromStdString(ErroStr); + } + + switch(msgType) { + case enum_Query_NTP_Message_Ack: { + QString strNTPIP = QString::fromStdString(pt.get("NTPIP")); + bool bNTPOn = pt.get("NTPOn"); + emit SendNTPQuery(strNTPIP,bNTPOn); + return ""; + } break; + case enum_Query_Time_Message_Ack: { + int64 nDateTime = pt.get("Time"); +// cout << "nDateTime: " << nDateTime << endl; + emit SendTimeQuery(nDateTime); + return ""; + } break; + case enum_Query_IP_Message_Ack: { + boost::property_tree::ptree ch_parser = pt.get_child("NetworkList"); + QString strNetWorkName, strIP, strGatway, strMask; + for(boost::property_tree::ptree::value_type &v : ch_parser) + { + boost::property_tree::ptree p = v.second; + QString temp = QString::fromStdString(p.get("NetworkName")); + if(!m_filterNetWork.isEmpty()) + { + if(temp.compare(m_filterNetWork) != 0) + { + continue; + } + } + strNetWorkName = temp; + strIP = QString::fromStdString(p.get("IP")); + strGatway = QString::fromStdString(p.get("Gatway")); + strMask = QString::fromStdString(p.get("Mask")); + break; + } + + emit SendIPQuery(strNetWorkName, strIP, strGatway, strMask); + return ""; + } break; + case enum_Query_Led_Message_Ack: { + int nLed = std::atoi(pt.get("LedValue").c_str()); + emit SendLedQuery(nLed); + return ""; + } break; + case enum_Set_NTP_Message_Ack: { + return ""; + } break; + case enum_Set_Time_Message_Ack: { + return ""; + } break; + case enum_Set_IP_Message_Ack: { + return ""; + } break; + case enum_Set_Led_Message_Ack: { + return ""; + } break; + default: + return tr("未知的命令"); + break; + } + } + + return tr("未接收到消息"); +} + +iot_net::CMbMessage CMsgDeal::CreateMsg(const SReqHead& sReqHead) +{ + m_jsonMap.clear(); + + //m_jsonMap初始化 + m_jsonMap["msgType"] = to_string(sReqHead.nMsgType); + m_jsonMap["strSrcTag"] = sReqHead.strSrcTag; + m_jsonMap["nSrcDomainID"] = to_string(sReqHead.nSrcDomainID); + m_jsonMap["nDstDomainID"] = to_string(sReqHead.nDstDomainID); + m_jsonMap["nAppID"] = to_string(sReqHead.nAppID); + m_jsonMap["strHostName"] = sReqHead.strHostName; + m_jsonMap["strInstName"] = sReqHead.strInstName; + m_jsonMap["strCommName"] = sReqHead.strCommName; + m_jsonMap["nUserID"] = to_string(sReqHead.nUserID); + m_jsonMap["nUserGroupID"] = to_string(sReqHead.nUserGroupID); + m_jsonMap["nOptTime"] = to_string(sReqHead.nOptTime); + m_jsonMap["strKeyIdTag"] = sReqHead.strKeyIdTag; + m_jsonMap["ErroStr"] = sReqHead.ErroStr; + m_jsonMap["Password"] = sReqHead.strPassword; + + switch(sReqHead.nMsgType) { + case enum_Set_NTP_Message: { + m_jsonMap["NTPIP"] = m_strNTPIP; + m_jsonMap["NTPOn"] = std::to_string(m_bNTPOn); + } + case enum_Set_Time_Message: { + m_jsonMap["Time"] = to_string(m_nSetTime); + } break; + case enum_Set_Led_Message: { + m_jsonMap["LedValue"] = to_string(m_nLedValue); + } break; +// case enum_Set_IP_Message: { +// } break; + default: break; + } + + //构建Json数据 + boost::property_tree::ptree pt; + QMap::iterator iter; + for(iter = m_jsonMap.begin(); iter != m_jsonMap.end(); iter++) { + pt.put(iter.key(), iter.value()); + } + + if(sReqHead.nMsgType == enum_Set_IP_Message) + { + boost::property_tree::ptree children; + boost::property_tree::ptree child; + pt.put("NetworkCount", to_string(4)); + child.put("NetworkName", m_strNetWorkName); + child.put("IP", m_strIp); + child.put("Gatway", m_strGatway); + child.put("Mask", m_strMask); + children.push_back(std::make_pair("", child)); + pt.add_child("NetworkList", children); + } + + //将Json数据序列化为字符串 + std::ostringstream jsonStrem; + boost::property_tree::write_json(jsonStrem, pt,false); + std::string jsonString = jsonStrem.str(); + + //构造消息 + iot_net::CMbMessage msg; + msg.setMsgType(MT_HMI_TO_SYS_PARAMS_DOWN); + msg.setSubject(E_APPID, CH_HMI_TO_OPT_OPTCMD_DOWN); + msg.setData(jsonString); + + return msg; +} diff --git a/product/src/gui/plugin/CNTPTimeWidget/CMsgDeal.h b/product/src/gui/plugin/CNTPTimeWidget/CMsgDeal.h new file mode 100644 index 00000000..67c886aa --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CMsgDeal.h @@ -0,0 +1,105 @@ +#ifndef CMSGDEAL_H +#define CMSGDEAL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PreDefine.h" + +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include "net_msg_bus_api/CMbCommunicator.h" +#include "common/MessageChannel.h" + +/** + * 只有这个功能用platform的Json构建和解析, + * CMsgDeal用boost构建和解析Json + */ +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" + +using namespace std; +using namespace iot_public; +using namespace iot_service; +using namespace iot_net; + +static const int E_APPID = 1; + +class CMsgDeal : public QObject +{ + Q_OBJECT +public: + explicit CMsgDeal(QObject *parent = nullptr); + ~CMsgDeal(); + + void setNetWorkName(const QString& networkName); + void setPasswd(const QString& pswd); + +signals: + void SendNTPQuery(const QString& ntpIP,bool ntpOn); + void SendTimeQuery(const int64& nDateTime); + void SendIPQuery(const QString& netWorkName, const QString& ip, + const QString& gatway, const QString& mask); + void SendLedQuery(const int& ledValue); + +public slots: + QString RevNTPSet(const QString& hostName,const bool& sel, const QString& ntpIP); + QString RevTimeSet(const QString& hostName,const QDateTime& dateTime); + QString RevIPSet(const QString& hostName,const QString& netWorkName, const QString& ip, + const QString& gatway, const QString& mask); + QString RevLedSet(const QString& hostName,const int& ledValue); + + QString NTPQuery(const QString& hostName); //查询初始NTP + QString TimeQuery(const QString& hostName); //查询初始NTP + QString IPQuery(const QString& hostName); //查询初始NTP + QString LedQuery(const QString& hostName); //查询初始NTP + +private slots: + QString RevMessage(int nMsgType,const QString& hostName); + +private: + void InitMsgBus(); + bool AddSub(int appID, int channel); + bool DelSub(int appID, int channel); + void clearMsgBus(); + iot_net::CMbMessage CreateMsg(const SReqHead& sReqHead); + +private: + iot_public::CSysInfoInterfacePtr m_sysInfo; + iot_service::CPermMngApiPtr m_permMng; + + iot_net::CMbCommunicator* m_objSendCMb;//发送 + iot_net::CMbCommunicator* m_objRecvCMb;//接收 + + std::string m_curRtu; + std::string m_strHostName; + std::string m_strInstName; + int m_nOptTime; + + QMap m_jsonMap; + int m_nDomainID; + std::string m_strPassword; + std::string m_strNTPIP; //设置NTPIP + bool m_bNTPOn; //设置NTPIP 是否启用 + int64 m_nSetTime; //设置时间 + std::string m_strNetWorkName; //网卡 + std::string m_strIp; //IP地址 + std::string m_strGatway; //网关 + std::string m_strMask; //子网掩码 + int64 m_nLedValue; //设置亮度 + + QString m_filterNetWork; + QString m_localHost; +}; + +#endif // CMSGDEAL_H diff --git a/product/src/gui/plugin/CNTPTimeWidget/CMsgHeadParse.cpp b/product/src/gui/plugin/CNTPTimeWidget/CMsgHeadParse.cpp new file mode 100644 index 00000000..f856c9c1 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CMsgHeadParse.cpp @@ -0,0 +1,43 @@ +#include "CMsgHeadParse.h" + +CMsgHeadParse::CMsgHeadParse() +{ + +} + +bool CMsgHeadParse::GenerateHead(const SReqHead &stHead, boost::property_tree::ptree &pt_root) +{ + pt_root.put("msgType", stHead.nMsgType); + pt_root.put("strSrcTag", stHead.strSrcTag ); + pt_root.put("nSrcDomainID",stHead.nSrcDomainID ); + pt_root.put("nDstDomainID",stHead.nDstDomainID ); + pt_root.put("nAppID" ,stHead.nAppID ); + pt_root.put("strHostName" ,stHead.strHostName ); + pt_root.put("strInstName" ,stHead.strInstName ); + pt_root.put("strCommName" ,stHead.strCommName ); + pt_root.put("nUserID" ,stHead.nUserID ); + pt_root.put("nUserGroupID",stHead.nUserGroupID ); + pt_root.put("nOptTime" ,stHead.nOptTime ); + pt_root.put("strKeyIdTag", stHead.strKeyIdTag); + pt_root.put("ErroStr", stHead.ErroStr); + + return true; +} + +bool CMsgHeadParse::ParseHead(const boost::property_tree::ptree& parser, SReqHead &stHead) +{ + stHead.nMsgType = parser.get("msgType"); + stHead.strSrcTag = parser.get("strSrcTag","hmi"); + stHead.nSrcDomainID = parser.get("nSrcDomainID"); + stHead.nDstDomainID = parser.get("nDstDomainID"); + stHead.nAppID = parser.get("nAppID"); + stHead.strHostName = parser.get("strHostName",""); + stHead.strInstName = parser.get("strInstName",""); + stHead.strCommName = parser.get("strCommName",""); + stHead.nUserID = parser.get("nUserID",-1); + stHead.nUserGroupID = parser.get("nUserGroupID",-1); + stHead.nOptTime = parser.get("nOptTime"); + stHead.strKeyIdTag = parser.get("strKeyIdTag", ""); + stHead.ErroStr = parser.get("ErroStr", ""); + return true; +} diff --git a/product/src/gui/plugin/CNTPTimeWidget/CMsgHeadParse.h b/product/src/gui/plugin/CNTPTimeWidget/CMsgHeadParse.h new file mode 100644 index 00000000..b23411e2 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CMsgHeadParse.h @@ -0,0 +1,20 @@ +#ifndef CMSGHEADPARSE_H +#define CMSGHEADPARSE_H + +#include +#include +#include + +#include "PreDefine.h" + +class CMsgHeadParse +{ +public: + CMsgHeadParse(); + + bool static GenerateHead(const SReqHead& stHead,boost::property_tree::ptree &pt_root ); + bool static ParseHead(const boost::property_tree::ptree& parser, SReqHead& stHead); + +}; + +#endif // CMSGHEADPARSE_H diff --git a/product/src/gui/plugin/CNTPTimeWidget/CNTPTimePluginWidget.cpp b/product/src/gui/plugin/CNTPTimeWidget/CNTPTimePluginWidget.cpp new file mode 100644 index 00000000..681035e5 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CNTPTimePluginWidget.cpp @@ -0,0 +1,25 @@ +#include "CNTPTimePluginWidget.h" + +CNTPTimePluginWidget::CNTPTimePluginWidget(QObject *parent) + : QObject(parent) +{ + +} + +CNTPTimePluginWidget::~CNTPTimePluginWidget() +{ + +} + +bool CNTPTimePluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CNTPTimeWidget *pWidget = new CNTPTimeWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CNTPTimePluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/CNTPTimeWidget/CNTPTimePluginWidget.h b/product/src/gui/plugin/CNTPTimeWidget/CNTPTimePluginWidget.h new file mode 100644 index 00000000..50b913c4 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CNTPTimePluginWidget.h @@ -0,0 +1,22 @@ +#ifndef CNTPTIMEPLUGINWIDGET_H +#define CNTPTIMEPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape +#include "CNTPTimeWidget.h" + +class CNTPTimePluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) + Q_INTERFACES(CPluginWidgetInterface) + +public: + CNTPTimePluginWidget(QObject *parent = 0); + ~CNTPTimePluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CNTPTIMEPLUGINWIDGET_H diff --git a/product/src/gui/plugin/CNTPTimeWidget/CNTPTimeWidget.cpp b/product/src/gui/plugin/CNTPTimeWidget/CNTPTimeWidget.cpp new file mode 100644 index 00000000..4b0f1b1a --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CNTPTimeWidget.cpp @@ -0,0 +1,408 @@ +#include "CNTPTimeWidget.h" +#include "ui_CNTPTimeWidget.h" + +#include +#include +CNTPTimeWidget::CNTPTimeWidget(QWidget *parent, bool isEditMode) : + QWidget(parent), + ui(new Ui::CNTPTimeWidget), + m_isEditMode(isEditMode) +{ + ui->setupUi(this); + + m_sPassword = "kbdct@0755"; + + m_ipHostName = "localhost"; + m_ledHostName = "localhost"; + m_ntpHostNames.push_back("localhost"); + m_timeHostNames.push_back("localhost"); + + //NTP选择按钮互斥,只能单选 + QButtonGroup* buttonGroupNTPSel = new QButtonGroup(ui->widget_selNTP); + buttonGroupNTPSel->addButton(ui->radioButton_yes, 0); + buttonGroupNTPSel->addButton(ui->radioButton_no, 1); + + //ui->lineEdit_NTPIP->setValidator(new QRegExpValidator(QRegExp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"))); + ui->lineEdit_IP->setValidator(new QRegExpValidator(QRegExp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"))); + ui->lineEdit_Gatway->setValidator(new QRegExpValidator(QRegExp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"))); +// ui->lineEdit_Mask->setValidator(new QRegExpValidator(QRegExp("(254|252|248|240|224|192|128|0)\\.0\\.0\\.0|255\\.(254|252|248|240|224|192|128|0)\\.0\\.0|255\\.255\\.(254|252|248|240|224|192|128|0)\\.0|255\\.255\\.255\\.(254|252|248|240|224|192|128|0)"))); + ui->lineEdit_Mask->setValidator(new QRegExpValidator(QRegExp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"))); + + //人工设置按钮互斥,只能单选 + QButtonGroup* buttonGroupManulSet = new QButtonGroup(ui->widget_manulSet); + buttonGroupManulSet->addButton(ui->radioButton_enable, 0); + buttonGroupManulSet->addButton(ui->radioButton_disable, 1); + + InitStyle(); + m_pCMsgDeal = new CMsgDeal; + m_pCManualSet = new CManualSet; + + connect(m_pCMsgDeal, &CMsgDeal::SendNTPQuery, this, &CNTPTimeWidget::RevNTPQuery); + connect(m_pCMsgDeal, &CMsgDeal::SendTimeQuery, this, &CNTPTimeWidget::RevTimeQuery); + connect(m_pCMsgDeal, &CMsgDeal::SendIPQuery, this, &CNTPTimeWidget::RevIPQuery); + connect(m_pCMsgDeal, &CMsgDeal::SendLedQuery, this, &CNTPTimeWidget::RevLedQuery); + connect(m_pCManualSet, &CManualSet::showMsg, this, &CNTPTimeWidget::showMsg); + + connect(m_pCManualSet, &CManualSet::SendSurrenderSta, this, &CNTPTimeWidget::RevSurrenderSta); + +// connect(ui->spinBox_LedSet, &QSpinBox::textChanged, this, &CNTPTimeWidget::); +} + +CNTPTimeWidget::~CNTPTimeWidget() +{ + if(m_pCManualSet) + { + delete m_pCManualSet; + m_pCManualSet = nullptr; + } + + if(m_pCMsgDeal) + { + delete m_pCMsgDeal; + m_pCMsgDeal = nullptr; + } + + delete ui; +} + +void CNTPTimeWidget::InitSet(const QString& password, const QString& manualTag) +{ + m_sPassword = password; + m_pCMsgDeal->setPasswd(password); + m_sManulSetTag = manualTag; + m_pCManualSet->m_sManulSetTag = manualTag; + m_pCManualSet->InitManualSet(); +} + +void CNTPTimeWidget::setNTPSetHosts(const QString &hostNames) +{ + m_ntpHostNames = hostNames.split(","); +} + +void CNTPTimeWidget::setTimeSetHosts(const QString &hostNames) +{ + m_timeHostNames = hostNames.split(","); +} + +void CNTPTimeWidget::setIpSetHost(const QString &hostName) +{ + m_ipHostName = hostName; +} + +void CNTPTimeWidget::setLedSetHost(const QString &hostName) +{ + m_ledHostName = hostName; +} + +void CNTPTimeWidget::setNetWorkName(const QString &networkName) +{ + m_pCMsgDeal->setNetWorkName(networkName); +} + +void CNTPTimeWidget::initViewData() +{ + QString ret; + ret = m_pCMsgDeal->NTPQuery(m_ntpHostNames.at(0)); + if(!ret.isEmpty()) + { + showMsg(QString("NTP信息查询失败:%1,主机名:%2").arg(ret).arg(m_ntpHostNames.at(0))); + return; + } + ret = m_pCMsgDeal->TimeQuery(m_timeHostNames.at(0)); + if(!ret.isEmpty()) + { + showMsg(QString("时间信息查询失败:%1,主机名:%2").arg(ret).arg(m_timeHostNames.at(0))); + return; + } + ret = m_pCMsgDeal->IPQuery(m_ipHostName); + if(!ret.isEmpty()) + { + showMsg(QString("网络信息查询失败:%1,主机名:%2").arg(ret).arg(m_ipHostName)); + return; + } + ret = m_pCMsgDeal->LedQuery(m_ledHostName); + if(!ret.isEmpty()) + { + showMsg(QString("亮度查询失败:%1,主机名:%2").arg(ret).arg(m_ledHostName)); + return; + } +} + +void CNTPTimeWidget::InitStyle() +{ + QString styleSheet; + std::string stylepath = iot_public::CFileStyle::getPathOfStyleFile("public.qss"); + QFile file(QString::fromStdString(stylepath)); + file.open(QFile::ReadOnly); + if (file.isOpen()) + { + styleSheet.append(file.readAll()); + file.close(); + } + stylepath = iot_public::CFileStyle::getPathOfStyleFile("CNTPTimeWidget.qss"); + QFile file1(QString::fromStdString(stylepath)); + file1.open(QFile::ReadOnly); + if (file1.isOpen()) + { + styleSheet.append(file1.readAll()); + file1.close(); + } + setStyleSheet(styleSheet); +} + +void CNTPTimeWidget::showMsg(const QString &msg) +{ +// if(ui->m_showMsgLabel->text().isEmpty()) +// QTimer::singleShot(3000,this,&CNTPTimeWidget::clearMsg); + +// ui->m_showMsgLabel->setText(msg); + + QMessageBox::information(this, "", msg); +} + +void CNTPTimeWidget::clearMsg() +{ +// ui->m_showMsgLabel->setText(""); +} + +void CNTPTimeWidget::RevNTPQuery(const QString& ntpIP,bool ntpOn) +{ +// cout << "CNTPTimeWidget::RevNTPQuery ntpIP: " << ntpIP.toStdString() << endl; + if(!ntpOn){ + ui->radioButton_yes->setCheckable(true); + ui->radioButton_no->setCheckable(true); + ui->radioButton_yes->setChecked(false); + ui->radioButton_no->setChecked(true); + m_bTimeSet = true; + } + else + { + ui->radioButton_yes->setCheckable(true); + ui->radioButton_no->setCheckable(true); + ui->radioButton_yes->setChecked(true); + ui->radioButton_no->setChecked(false); + m_bTimeSet = false; + } + ui->lineEdit_NTPIP->setText(ntpIP); +} + +void CNTPTimeWidget::RevTimeQuery(const int64& nDateTime) +{ +// cout << "CNTPTimeWidget::RevTimeQuery nDateTime: " << nDateTime << endl; + QDateTime dateTime; + dateTime.setTime_t(nDateTime); + ui->dateEdit_timeSet->setDate(dateTime.date()); + ui->timeEdit_timeSet->setTime(dateTime.time()); + + cout << "CNTPTimeWidget::RevTimeQuery nDateTime end" << endl; +} + +void CNTPTimeWidget::RevIPQuery(const QString& netWorkName, const QString& ip, + const QString& gatway, const QString& mask) +{ +// cout << "CNTPTimeWidget::RevIPQuery netWorkName: " << netWorkName.toStdString() << endl; +// cout << "CNTPTimeWidget::RevIPQuery ip: " << ip.toStdString() << endl; +// cout << "CNTPTimeWidget::RevIPQuery gatway: " << gatway.toStdString() << endl; +// cout << "CNTPTimeWidget::RevIPQuery mask: " << mask.toStdString() << endl; + + ui->lineEdit_NetWorkName->setText(netWorkName); + ui->lineEdit_IP->setText(ip); + ui->lineEdit_Gatway->setText(gatway); + ui->lineEdit_Mask->setText(mask); +} + +void CNTPTimeWidget::RevLedQuery(const int& ledValue) +{ +// cout << "CNTPTimeWidget::RevLedQuery ledValue: " << ledValue << endl; + + ui->spinBox_LedSet->setValue(ledValue); +} + +void CNTPTimeWidget::RevSurrenderSta(const int& status) +{ + if(status == 0) + { + ui->radioButton_enable->setCheckable(true); + ui->radioButton_disable->setCheckable(true); + ui->radioButton_enable->setChecked(false); + ui->radioButton_disable->setChecked(true); + } + else if(status == 1) + { + ui->radioButton_enable->setCheckable(true); + ui->radioButton_disable->setCheckable(true); + ui->radioButton_enable->setChecked(true); + ui->radioButton_disable->setChecked(false); + } + +} + +void CNTPTimeWidget::SelYes_Clicked(const bool& checked) +{ + if(checked) + { +// cout << "m_sSelect yes" << endl; + m_sSelect = true; + } +} + +void CNTPTimeWidget::SelNo_Clicked(const bool& checked) +{ + if(checked) + { + m_sSelect = false; +// cout << "m_sSelect no" << endl; + } +} + +void CNTPTimeWidget::NTPSet_Clicked() +{ + QString NTPIP = ui->lineEdit_NTPIP->text(); + if(NTPIP.isEmpty()) + { + showMsg(QString("NTP服务器IP不允许为空")); + return; + } + /* + QRegExp rx("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"); + if(!rx.exactMatch(NTPIP)) + { + showMsg(QString("NTP服务器:%1不符合规范,请检查").arg(NTPIP)); + return; + } + */ + + QStringList::iterator iter = m_ntpHostNames.begin(); + for(;iter!=m_ntpHostNames.end();++iter) + { + QString ret = m_pCMsgDeal->RevNTPSet(*iter, m_sSelect, NTPIP); + if(!ret.isEmpty()) + { + showMsg(QString(tr("NTP设置失败:%1,主机名:%2")).arg(ret).arg(*iter)); + return; + } + } + + if(!m_sSelect) + { + m_bTimeSet = true; + } + else + { + m_bTimeSet = false; + } + + showMsg(QString(tr("NTP设置成功"))); +} + +void CNTPTimeWidget::TimeSet_Clicked() +{ + if(m_bTimeSet) + { + QDate date = ui->dateEdit_timeSet->date(); + QTime time = ui->timeEdit_timeSet->time(); + QDateTime dateTime(date, time); + + QStringList::iterator iter = m_timeHostNames.begin(); + for(;iter!=m_timeHostNames.end();++iter) + { + QString ret = m_pCMsgDeal->RevTimeSet(*iter,dateTime); + if(!ret.isEmpty()) + { + showMsg(QString(tr("时间设置失败:%1,主机名:%2")).arg(ret).arg(*iter)); + return; + } + } + + showMsg(QString(tr("时间设置成功"))); + } + else + { + showMsg(QString(tr("设置时间失败,请先关闭NTP"))); + } +} + +void CNTPTimeWidget::IPSet_Clicked() +{ + QString strNetWorkName = ui->lineEdit_NetWorkName->text(); //网卡 + QString strIp = ui->lineEdit_IP->text(); //IP地址 + QString strGatway = ui->lineEdit_Gatway->text(); //网关 + QString strMask = ui->lineEdit_Mask->text(); //子网掩码 + if(strIp.isEmpty()) + { + showMsg(QString("IP地址不允许为空")); + return; + } + QRegExp rx("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"); + if(!rx.exactMatch(strIp)) + { + showMsg(QString("IP地址:%1不符合规范,请检查").arg(strIp)); + return; + } + if(strGatway.isEmpty()) + { + showMsg(QString("网关不允许为空")); + return; + } + if(!rx.exactMatch(strGatway)) + { + showMsg(QString("网关:%1不符合规范,请检查").arg(strGatway)); + return; + } + QRegExp rx1("(254|252|248|240|224|192|128|0)\\.0\\.0\\.0|255\\.(254|252|248|240|224|192|128|0)\\.0\\.0|255\\.255\\.(254|252|248|240|224|192|128|0)\\.0|255\\.255\\.255\\.(254|252|248|240|224|192|128|0)"); + if(strMask.isEmpty()) + { + showMsg(QString("子网掩码不允许为空")); + return; + } + if(!rx1.exactMatch(strMask)) + { + showMsg(QString("子网掩码:%1不符合规范,请检查").arg(strMask)); + return; + } + + QString ret = m_pCMsgDeal->RevIPSet(m_ipHostName,strNetWorkName, strIp, strGatway, strMask); + if(!ret.isEmpty()) + { + showMsg(QString(tr("IP设置失败:%1,主机名:%2")).arg(ret).arg(m_ipHostName)); + return; + } + + showMsg(QString(tr("IP设置成功"))); +} + +void CNTPTimeWidget::LedSet_Clicked() +{ + int nLedValue = ui->spinBox_LedSet->text().toInt(); + QString ret = m_pCMsgDeal->RevLedSet(m_ledHostName,nLedValue); + if(!ret.isEmpty()) + { + showMsg(QString(tr("亮度设置失败:%1,主机名:%2")).arg(ret).arg(m_ledHostName)); + return; + } + + showMsg(QString(tr("亮度设置成功"))); +} + +void CNTPTimeWidget::ManualEnable_Clicked(const bool& checked) +{ + if(checked) + { + m_pCManualSet->m_dEnable = 1; +// cout << "Manual Enable" << endl; + } +} + +void CNTPTimeWidget::ManualDisable_Clicked(const bool& checked) +{ + if(checked) + { + m_pCManualSet->m_dEnable = 0; +// cout << "Manual Disable" << endl; + } +} + +void CNTPTimeWidget::Manual_Clicked() +{ + m_pCManualSet->SetData(m_sManulSetTag); +} diff --git a/product/src/gui/plugin/CNTPTimeWidget/CNTPTimeWidget.h b/product/src/gui/plugin/CNTPTimeWidget/CNTPTimeWidget.h new file mode 100644 index 00000000..e8e6f613 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CNTPTimeWidget.h @@ -0,0 +1,88 @@ +#ifndef CNTPTIMEWIDGET_H +#define CNTPTIMEWIDGET_H + +#include +#include +#include +#include +#include + +#include "CMsgDeal.h" +#include "CManualSet.h" + +#include "public/pub_utility_api/FileStyle.h" +#include "net/net_msg_bus_api/MsgBusApi.h" + +namespace Ui { +class CNTPTimeWidget; +} + +class CNTPTimeWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CNTPTimeWidget(QWidget *parent = 0, bool isEditMode = true); + ~CNTPTimeWidget(); + +public slots: + /** + * @brief InitSet 设置初始化 + * @param password root密码传参,部分Linux设置需要root密码 + * @param manualTag 人工设置的测点 + */ + void InitSet(const QString& password, const QString& manualTag); + + void setNTPSetHosts(const QString& hostNames); + void setTimeSetHosts(const QString& hostNames); + + void setIpSetHost(const QString& hostName); + void setLedSetHost(const QString& hostName); + void setNetWorkName(const QString& networkName); + + void initViewData(); +private slots: + void SelYes_Clicked(const bool& checked); //NTP设置选择是 + void SelNo_Clicked(const bool& checked); //NTP设置选择否 + void NTPSet_Clicked(); //NTP设置 + void TimeSet_Clicked(); //时间设置 + void IPSet_Clicked(); //IP设置 + void LedSet_Clicked(); //屏幕亮度设置 + void ManualEnable_Clicked(const bool& checked); //启用人工设置 + void ManualDisable_Clicked(const bool& checked); //禁用人工设置 + void Manual_Clicked(); //人工置数 + + void RevNTPQuery(const QString& ntpIP,bool ntpOn); //初始化查询NTP + void RevTimeQuery(const int64& nDateTime); //初始化查询时间 + void RevIPQuery(const QString& netWorkName, const QString& ip, + const QString& gatway, const QString& mask); //初始化查询IP + void RevLedQuery(const int& ledValue); //初始化查询屏幕亮度 + + void RevSurrenderSta(const int& status); //查询控制投退状态 + +private: + void InitStyle(); + void showMsg(const QString& msg); + void clearMsg(); +private: + Ui::CNTPTimeWidget *ui; + bool m_isEditMode; + + CMsgDeal* m_pCMsgDeal; + + bool m_sSelect = false; + bool m_bTimeSet = true; + QString m_sPassword; + + CManualSet* m_pCManualSet; + + QString m_sManulSetTag; + + QStringList m_ntpHostNames; + QStringList m_timeHostNames; + QString m_ipHostName; + QString m_ledHostName; + +}; + +#endif // CNTPTIMEWIDGET_H diff --git a/product/src/gui/plugin/CNTPTimeWidget/CNTPTimeWidget.pro b/product/src/gui/plugin/CNTPTimeWidget/CNTPTimeWidget.pro new file mode 100644 index 00000000..e141f94b --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CNTPTimeWidget.pro @@ -0,0 +1,60 @@ +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += plugin + +TARGET = CNTPTimeWidget +TEMPLATE = lib + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + CManualSet.cpp \ + CMsgDeal.cpp \ + CNTPTimePluginWidget.cpp \ + main.cpp \ + CNTPTimeWidget.cpp \ + CRealDataCollect.cpp + +HEADERS += \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + CManualSet.h \ + CMsgDeal.h \ + CNTPTimePluginWidget.h \ + CNTPTimeWidget.h \ + PreDefine.h \ + CRealDataCollect.h + +FORMS += \ + CNTPTimeWidget.ui + +LIBS += -lprotobuf \ + -ldb_base_api \ + -ldb_api_ex \ + -lnet_msg_bus_api \ + -lpub_sysinfo_api \ + -lperm_mng_api \ + -llog4cplus \ + -lpub_logger_api \ + -ldp_chg_data_api \ + -lpub_utility_api + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target diff --git a/product/src/gui/plugin/CNTPTimeWidget/CNTPTimeWidget.ui b/product/src/gui/plugin/CNTPTimeWidget/CNTPTimeWidget.ui new file mode 100644 index 00000000..12e59303 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CNTPTimeWidget.ui @@ -0,0 +1,1631 @@ + + + CNTPTimeWidget + + + + 0 + 0 + 1316 + 893 + + + + CNTPTimeWidget + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 1208 + 6 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + IP设置 + + + + + + + + + + Qt::Horizontal + + + + 754 + 20 + + + + + + + + + + + 设置 + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + color: rgb(255, 255, 255); +background-color: #0E2861; + + + + 9 + + + 9 + + + 9 + + + 9 + + + 6 + + + + + 网卡 + + + Qt::AlignCenter + + + + + + + + + + + + + + 9 + + + 9 + + + 9 + + + 9 + + + 6 + + + + + false + + + + 300 + 0 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 100 + 0 + + + + + 16777215 + 16777215 + + + + color: rgb(255, 255, 255); +background-color: #0E2861; + + + + + + IP地址 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + 300 + 0 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + color: rgb(255, 255, 255); +background-color: #0E2861; + + + + + + 子网掩码 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + 300 + 0 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + color: rgb(255, 255, 255); +background-color: #0E2861; + + + + + + 网关 + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + 300 + 0 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 控制投退 + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + + 1010 + 18 + + + + + + + + + 9 + + + 9 + + + 9 + + + 6 + + + + + 设置 + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + color: rgb(255, 255, 255); +background-color: #0E2861; + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 100 + 0 + + + + 是否启用 + + + Qt::AlignCenter + + + + + + + + + + + 16777215 + 50 + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 启用 + + + false + + + false + + + + + + + 禁用 + + + false + + + + + + + + + + Qt::Horizontal + + + + 952 + 20 + + + + + + + + + + + + + + + + + + + + + 16777215 + 50 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + 300 + 0 + + + + + + + + + + 1 + + + 100 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 100 + 0 + + + + + 16777215 + 16777215 + + + + color: rgb(255, 255, 255); +background-color: #0E2861; + + + + + + 亮度调节 + + + Qt::AlignCenter + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + 亮度设置 + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + + 754 + 20 + + + + + + + + + + + 设置 + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 设置 + + + + + + + + + + Qt::Horizontal + + + + 1017 + 20 + + + + + + + + + + + + + + + + + 时间设置 + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + color: rgb(255, 255, 255); +background-color: #0E2861; + + + + 9 + + + 9 + + + 9 + + + 9 + + + 6 + + + + + 时间 + + + Qt::AlignCenter + + + + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + color: rgb(255, 255, 255); +background-color: #0E2861; + + + + 9 + + + 9 + + + 9 + + + 9 + + + 6 + + + + + 日期 + + + Qt::AlignCenter + + + + + + + + + + + + + + 9 + + + 9 + + + 9 + + + 9 + + + 6 + + + + + + 300 + 0 + + + + + 300 + 16777215 + + + + hh:mm:ss + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 9 + + + 9 + + + 9 + + + 9 + + + 6 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 300 + 0 + + + + + 16777215 + 16777215 + + + + + 0 + 0 + 0 + 2023 + 8 + 1 + + + + yyyy-MM-dd + + + + 2023 + 8 + 1 + + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 16777215 + 50 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + NTP设置 + + + + + + + + + + Qt::Horizontal + + + + 1058 + 38 + + + + + + + + + + + 设置 + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + color: rgb(255, 255, 255); +background-color: #0E2861; + + + + + + + + + 是否开启NTP + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + false + + + false + + + + + + + + + + + + + + + + + color: rgb(255, 255, 255); +background-color: #0E2861; + + + + + + NTP服务器 + + + + + + + + + + + + + + 300 + 16777215 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + Qt::Horizontal + + + + 0 + 20 + + + + + + + + Qt::Horizontal + + + + 0 + 20 + + + + + + + + + + pushButton_TimeSet + clicked() + CNTPTimeWidget + TimeSet_Clicked() + + + 803 + 242 + + + 303 + 229 + + + + + pushButton_LedSet + clicked() + CNTPTimeWidget + LedSet_Clicked() + + + 803 + 612 + + + 303 + 631 + + + + + pushButton_IPSet + clicked() + CNTPTimeWidget + IPSet_Clicked() + + + 803 + 429 + + + 303 + 399 + + + + + pushButton + clicked() + CNTPTimeWidget + NTPSet_Clicked() + + + 812 + 59 + + + 303 + 197 + + + + + radioButton_yes + toggled(bool) + CNTPTimeWidget + SelYes_Clicked(bool) + + + 159 + 115 + + + 152 + 82 + + + + + radioButton_no + toggled(bool) + CNTPTimeWidget + SelNo_Clicked(bool) + + + 203 + 115 + + + 245 + 81 + + + + + pushButton_manual + clicked() + CNTPTimeWidget + Manual_Clicked() + + + 824 + 749 + + + 785 + 781 + + + + + radioButton_enable + toggled(bool) + CNTPTimeWidget + ManualEnable_Clicked(bool) + + + 109 + 744 + + + 88 + 785 + + + + + radioButton_disable + toggled(bool) + CNTPTimeWidget + ManualDisable_Clicked(bool) + + + 170 + 741 + + + 229 + 715 + + + + + + TimeSet_Clicked() + IPSet_Clicked() + LedSet_Clicked() + NTPSet_Clicked() + SelYes_Clicked(bool) + SelNo_Clicked(bool) + Manual_Clicked() + ManualEnable_Clicked(bool) + ManualDisable_Clicked(bool) + + diff --git a/product/src/gui/plugin/CNTPTimeWidget/CRealDataCollect.cpp b/product/src/gui/plugin/CNTPTimeWidget/CRealDataCollect.cpp new file mode 100644 index 00000000..888fb5c8 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CRealDataCollect.cpp @@ -0,0 +1,248 @@ +#include "CRealDataCollect.h" + +#include + +#include +using namespace std; + +CRealDataCollect* CRealDataCollect::m_pInstance = NULL; + +CRealDataCollect::CRealDataCollect() + : m_pMbComm(NULL), + m_pTimer(NULL), + m_nTimeCount(0) +{ +// cout << "CRealDataCollect::CRealDataCollect" << endl; + initMsg(); + if(!addSub()) + { + return; + } + +// cout << "CRealDataCollect::CRealDataCollect addSub" << endl; + + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); + m_pTimer->start(100); +} + +CRealDataCollect *CRealDataCollect::instance() +{ + if(m_pInstance == NULL) + { + m_pInstance = new CRealDataCollect(); + } + return m_pInstance; +} + +void CRealDataCollect::release() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + delSub(); + closeMsg(); + m_pInstance = NULL; + delete this; +} + +void CRealDataCollect::initMsg() +{ + if(m_pMbComm == NULL) + { + m_pMbComm = new iot_net::CMbCommunicator("CNTPTimeWidget"); + } +} + +void CRealDataCollect::closeMsg() +{ + if(m_pMbComm != NULL) + { + delete m_pMbComm; + } + m_pMbComm = NULL; +} + +void CRealDataCollect::clearMsg() +{ + if(m_pMbComm) + { + iot_net::CMbMessage objMsg; + while(m_pMbComm->recvMsg(objMsg, 0)) + {} + } +} + +bool CRealDataCollect::addSub() +{ + if(m_pMbComm) + { + return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else + { + return false; + } +} + +bool CRealDataCollect::delSub() +{ + if(m_pMbComm) + { + return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else + { + return false; + } +} + +void CRealDataCollect::recvMessage() +{ + m_nTimeCount = (m_nTimeCount + 1) % 36000; + + if(m_nTimeCount % 10 == 0) + { +// cout << "CRealDataCollect::recvMessage processChangeData" << endl; + processChangeData(); + } + + try + { + iot_net::CMbMessage objMsg; + for(int i = 0; i < 6; i++) + { + if(m_pMbComm->recvMsg(objMsg, 0)) + { + if(objMsg.isValid()) + { + if(objMsg.getMsgType() != iot_idl::MT_DP_CHANGE_DATA) + { + continue; + } + if(objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) + { + continue; + } + parserMsg(objMsg); + } + } + } + } + catch(...) + { + + } +} + +void CRealDataCollect::processChangeData() +{ + if(!m_aiMap.isEmpty()) + { + emit signal_updateAi(m_aiMap); + m_aiMap.clear(); + } + + if(!m_diMap.isEmpty()) + { + emit signal_updateDi(m_diMap); + m_diMap.clear(); + } + + if(!m_piMap.isEmpty()) + { + emit signal_updatePi(m_piMap); + m_piMap.clear(); + } + + if(!m_miMap.isEmpty()) + { + emit signal_updateMi(m_miMap); + m_miMap.clear(); + } +} + +int CRealDataCollect::parserMsg(const iot_net::CMbMessage &msg) +{ + iot_idl::SRealTimeDataPkg changeDataPackage; + try + { + changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); + int aiSize = changeDataPackage.stairtd_size(); + if(aiSize > 0) + { + iot_idl::SAiRealTimeData aiStru; + QString tagName; + float value; + uint status; + for(int i = 0; i < aiSize;++i) + { + aiStru = changeDataPackage.stairtd(i); + tagName = QString::fromStdString(aiStru.strtagname()); + value = aiStru.fvalue(); + status = aiStru.ustatus(); + m_aiMap[tagName] = qMakePair(value, status); + } + } + + int diSize = changeDataPackage.stdirtd_size(); + if(diSize > 0) + { + iot_idl::SDiRealTimeData diStu; + QString tagName; + int value; + uint status; + for(int i = 0; i < diSize; ++i) + { + diStu = changeDataPackage.stdirtd(i); + tagName = QString::fromStdString(diStu.strtagname()); + value = diStu.nvalue(); + status = diStu.ustatus(); + m_diMap[tagName] = qMakePair(value, status); + } + } + + int piSize = changeDataPackage.stpirtd_size(); + if(piSize > 0) + { + iot_idl::SPiRealTimeData piStu; + QString tagName; + double value; + uint status; + for(int i = 0 ; i < piSize; ++i) + { + piStu = changeDataPackage.stpirtd(i); + tagName = QString::fromStdString(piStu.strtagname()); + value = piStu.dvalue(); + status = piStu.ustatus(); + m_piMap[tagName] = qMakePair(value, status); + } + } + + int miSize = changeDataPackage.stmirtd_size(); + if(miSize > 0) + { + iot_idl::SMiRealTimeData miStu; + QString tagName; + int value; + uint status; + for(int i = 0 ; i < miSize ; ++i) + { + miStu = changeDataPackage.stmirtd(i); + tagName = QString::fromStdString(miStu.strtagname()); + value = miStu.nvalue(); + status = miStu.ustatus(); + m_miMap[tagName] = qMakePair(value, status); + } + } + } + catch(...) + { + return 0; + } + return 1; +} diff --git a/product/src/gui/plugin/CNTPTimeWidget/CRealDataCollect.h b/product/src/gui/plugin/CNTPTimeWidget/CRealDataCollect.h new file mode 100644 index 00000000..4b72a5c7 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/CRealDataCollect.h @@ -0,0 +1,52 @@ +#ifndef CRealDataCollect_H +#define CRealDataCollect_H + +#include +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" + +class QTimer; +class CRealDataCollect : public QObject +{ + Q_OBJECT +public: + static CRealDataCollect * instance(); + + void release(); + +private: + CRealDataCollect(); + + void initMsg(); + void closeMsg(); + void clearMsg(); + bool addSub(); + bool delSub(); + + int parserMsg(const iot_net::CMbMessage &); + +private slots: + void recvMessage(); + void processChangeData(); + +signals: + void signal_updateAi(QMap> aiMap); + void signal_updateDi(QMap> diMap); + void signal_updatePi(QMap> piMap); + void signal_updateMi(QMap> miMap); + +private: + iot_net::CMbCommunicator *m_pMbComm; + QTimer * m_pTimer; + int m_nTimeCount; + QMap> m_aiMap; + QMap> m_diMap; + QMap> m_piMap; + QMap> m_miMap; + + static CRealDataCollect * m_pInstance; +}; + +#endif // CRealDataCollect_H diff --git a/product/src/gui/plugin/CNTPTimeWidget/PreDefine.h b/product/src/gui/plugin/CNTPTimeWidget/PreDefine.h new file mode 100644 index 00000000..1b0ec651 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/PreDefine.h @@ -0,0 +1,144 @@ +#ifndef PREDEFINE_H +#define PREDEFINE_H + +#include +#include +#include +#include "common/DataType.h" +#include "service/operate_server_api/JsonOptCommand.h" + +static const std::string APP_PROCESSNAME = "NTPimeWidget"; + +static const std::string CONFING_IS_CREATE_ALARM = "isGenAlarmToOpt"; +static const std::string CONFING_UI_TIMER_TO_SEND_SECONDS = "UiTimerToSendSeconds"; + +#define MT_SYS_PARAMS_TO_HMI_UP 10001 +#define MT_HMI_TO_SYS_PARAMS_DOWN 10002 + +#define MT_OPT_COMMON_DOWN 68 + +enum SysParams_MsgType +{ + enum_Set_IP_Message = 1, //设置IP地址 + enum_Set_IP_Message_Ack = 2, //设置IP 服务端应答结果 + enum_Set_Time_Message = 3, //设置时间 + enum_Set_Time_Message_Ack = 4, //设置时间 应答 + enum_Set_Led_Message = 5, //设置亮度 + enum_Set_Led_Message_Ack = 6,//设置亮度 应答 + enum_Reboot_Message = 7, //重启 + enum_Reboot_Message_Ack = 8,//重启 应答 + enum_Set_NTP_Message = 9, //设置NTP + enum_Set_NTP_Message_Ack = 10,//设置NTP 应答 + enum_Set_Process_Message = 11, //杀死进程 + enum_Set_Process_Message_Ack = 12,//杀死进程 应答 + enum_Query_IP_Message = 51, //查询IP地址 + enum_Query_IP_Message_Ack = 52, //查询IP 服务端应答结果 + enum_Query_Time_Message = 53, //查询时间 + enum_Query_Time_Message_Ack = 54, //查询时间 应答 + enum_Query_Led_Message = 55, //查询亮度 + enum_Query_Led_Message_Ack = 56,//查询亮度 应答 + enum_Query_Online_Message = 57, //查询是否在线 + enum_Query_Online_Message_Ack = 58,//是否在线 应答 + enum_Query_NTP_Message = 59, //查询NTP + enum_Query_NTP_Message_Ack = 60,//查询NTP 应答 +}; + +struct SReqHead +{ + int nMsgType; //!<消息类型 + std::string strSrcTag; //!< 源标签(即发送端进程名) + int nSrcDomainID; //!< 消息发送源域名 + int nDstDomainID; //!< 消息目标域名 + int nAppID; //!< 所属应用ID + std::string strHostName; //!< 发送端主机名 key1 + std::string strInstName; //!< 发送端实例名 key2 + std::string strCommName; //!< 发送端通讯器名 + int nUserID; //!< 发送端用户ID + int nUserGroupID; //!< 发送端用户组ID + int64 nOptTime; //!< 消息发送时间 key3 + std::string strKeyIdTag; + std::string strPassword;//linux权限的密码 + std::string ErroStr; + SReqHead() + { + nMsgType = 0; + strSrcTag = ""; + nSrcDomainID = 0; + nDstDomainID = 0; + nAppID = -1; + strHostName = ""; + strInstName = ""; + strCommName = ""; + nUserID = -1; + nUserGroupID = -1; + nOptTime = 0; + strKeyIdTag = ""; + strPassword= "kbdct@0755"; + } +}; + +//时间设置 +struct STimeSetRequest +{ + SReqHead stHead; + int64 nTime; +}; + +struct SOneIpObj +{ + std::string strNetWorkName; + std::string strIp; + std::string strGatway; + std::string strMask; +}; + +//IP设置 +struct SIpSetRequest +{ + SReqHead stHead; + int NetworkCount; + std::vector NetList; +}; + +//亮度调节 +struct SLedSetRequest +{ + SReqHead stHead; + int64 nLedValue; +}; + +//重启 +struct SRebootSetRequest +{ + SReqHead stHead; + int64 nTime; +}; + +//进程设置 +struct SProcessSetRequest +{ + SReqHead stHead; + std::string strProcessName; +}; + +//人工置数 +struct STOptTagInfo +{ + QString keyIdTag; + int optType; + qint64 optTime; + int locationId; + int subSystem; + double setValue; + int nIsSet; + QString stateText; + QString hostName; + QString userName; + QString userGroup; + + QString tagName; + QString devName; + QString table; +}; + +#endif // PREDEFINE_H diff --git a/product/src/gui/plugin/CNTPTimeWidget/main.cpp b/product/src/gui/plugin/CNTPTimeWidget/main.cpp new file mode 100644 index 00000000..0bac7bf4 --- /dev/null +++ b/product/src/gui/plugin/CNTPTimeWidget/main.cpp @@ -0,0 +1,11 @@ +#include "CNTPTimeWidget.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CNTPTimeWidget w; + w.show(); + return a.exec(); +} diff --git a/product/src/gui/plugin/ChanParaWidget/CMsgDeal.cpp b/product/src/gui/plugin/ChanParaWidget/CMsgDeal.cpp new file mode 100644 index 00000000..865af497 --- /dev/null +++ b/product/src/gui/plugin/ChanParaWidget/CMsgDeal.cpp @@ -0,0 +1,184 @@ +#include "CMsgDeal.h" +#include +#include + +CMsgDeal::CMsgDeal(QObject *parent) + : QObject(parent) +{ + m_sysInfo = NULL; + m_objSendCMb = new CMbCommunicator; + m_objRecvCMb = new CMbCommunicator; + m_localHost = "localhost"; + InitMsgBus(); +} + +CMsgDeal::~CMsgDeal() +{ + delete m_objSendCMb; + m_objSendCMb = nullptr; + + m_objRecvCMb->delSub(E_APPID, CH_OPT_TO_HMI_OPTCMD_UP); + delete m_objRecvCMb; + m_objRecvCMb = nullptr; +} + +QString CMsgDeal::RevProcessSet(const QString &hostName, const QString &procesName) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Set_Process_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + + m_strProcessName = procesName.toStdString(); + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated,hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Set_Process_Message_Ack,hostName); +} + +void CMsgDeal::InitMsgBus() +{ + if(!createSysInfoInstance(m_sysInfo)) + { + qDebug() << tr("创建系统信息访问库实例失败!"); + } + + m_permMng = getPermMngInstance("base"); + if(m_permMng != NULL) + { + if(m_permMng->PermDllInit() != PERM_NORMAL) + { + cout << tr("权限接口初始化失败!").toStdString() << endl; + } + } + + if(!m_objRecvCMb->addSub(E_APPID, CH_OPT_TO_HMI_OPTCMD_UP)) + { + cout << tr("总线订阅失败!").toStdString() << endl; + return; + } + + SNodeInfo sNodeInfo; + m_sysInfo->getLocalNodeInfo(sNodeInfo); + m_nDomainID = sNodeInfo.nDomainId; + m_localHost = QString::fromStdString(sNodeInfo.strName); +} + +void CMsgDeal::clearMsgBus() +{ + iot_net::CMbMessage msg; + while(true) + { + if(!m_objRecvCMb->recvMsg(msg, 0)) + { + break; + } + } +} + + +QString CMsgDeal::RevMessage(int nMsgType, const QString &hostName) +{ + Q_UNUSED(nMsgType); + Q_UNUSED(hostName); + + iot_net::CMbMessage msg; + while(m_objRecvCMb->recvMsg(msg, 3000)) + { + if(msg.getMsgType() != MT_SYS_PARAMS_TO_HMI_UP) + { + continue; + } + + //字符串反序列化Json数据 + boost::property_tree::ptree pt; + std::string msgStr((char*)msg.getDataPtr(), (int)msg.getDataSize()); + try { + std::istringstream iss; + iss.str(msgStr.c_str()); + boost::property_tree::json_parser::read_json(iss, pt); + } + catch (boost::property_tree::ptree_error &pt_error) + { + Q_UNUSED(pt_error); + return tr("消息解析错误"); + } + + //解析Json数据 + int msgType = pt.get("msgType"); + std::string ErroStr = pt.get("ErroStr"); + if(!ErroStr.empty()) + { + return QString::fromStdString(ErroStr); + } + + switch(msgType) { + case enum_Set_Process_Message_Ack: { + return ""; + } break; + default: + return tr("未知的命令"); + break; + } + } + + return tr("未接收到消息"); +} + +iot_net::CMbMessage CMsgDeal::CreateMsg(const SReqHead& sReqHead) +{ + m_jsonMap.clear(); + + //m_jsonMap初始化 + m_jsonMap["msgType"] = to_string(sReqHead.nMsgType); + m_jsonMap["strSrcTag"] = sReqHead.strSrcTag; + m_jsonMap["nSrcDomainID"] = to_string(sReqHead.nSrcDomainID); + m_jsonMap["nDstDomainID"] = to_string(sReqHead.nDstDomainID); + m_jsonMap["nAppID"] = to_string(sReqHead.nAppID); + m_jsonMap["strHostName"] = sReqHead.strHostName; + m_jsonMap["strInstName"] = sReqHead.strInstName; + m_jsonMap["strCommName"] = sReqHead.strCommName; + m_jsonMap["nUserID"] = to_string(sReqHead.nUserID); + m_jsonMap["nUserGroupID"] = to_string(sReqHead.nUserGroupID); + m_jsonMap["nOptTime"] = to_string(sReqHead.nOptTime); + m_jsonMap["strKeyIdTag"] = sReqHead.strKeyIdTag; + m_jsonMap["ErroStr"] = sReqHead.ErroStr; + m_jsonMap["Password"] = m_strPassword; + + switch(sReqHead.nMsgType) { + case enum_Set_Process_Message: { + m_jsonMap["ProcessName"] = m_strProcessName; + } + break; + default: break; + } + + //构建Json数据 + boost::property_tree::ptree pt; + QMap::iterator iter; + for(iter = m_jsonMap.begin(); iter != m_jsonMap.end(); iter++) { + pt.put(iter.key(), iter.value()); + } + + //将Json数据序列化为字符串 + std::ostringstream jsonStrem; + boost::property_tree::write_json(jsonStrem, pt,false); + std::string jsonString = jsonStrem.str(); + + //构造消息 + iot_net::CMbMessage msg; + msg.setMsgType(MT_HMI_TO_SYS_PARAMS_DOWN); + msg.setSubject(E_APPID, CH_HMI_TO_OPT_OPTCMD_DOWN); + msg.setData(jsonString); + + return msg; +} diff --git a/product/src/gui/plugin/ChanParaWidget/CMsgDeal.h b/product/src/gui/plugin/ChanParaWidget/CMsgDeal.h new file mode 100644 index 00000000..88f02899 --- /dev/null +++ b/product/src/gui/plugin/ChanParaWidget/CMsgDeal.h @@ -0,0 +1,77 @@ +#ifndef CMSGDEAL_H +#define CMSGDEAL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PreDefine.h" + +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include "net_msg_bus_api/CMbCommunicator.h" +#include "common/MessageChannel.h" + +/** + * 只有这个功能用platform的Json构建和解析, + * CMsgDeal用boost构建和解析Json + */ +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" + +using namespace std; +using namespace iot_public; +using namespace iot_service; +using namespace iot_net; + +static const int E_APPID = 1; + +class CMsgDeal : public QObject +{ + Q_OBJECT +public: + explicit CMsgDeal(QObject *parent = nullptr); + ~CMsgDeal(); + +public slots: + QString RevProcessSet(const QString& hostName,const QString& procesName); + +private slots: + QString RevMessage(int nMsgType,const QString& hostName); + +private: + void InitMsgBus(); + bool AddSub(int appID, int channel); + bool DelSub(int appID, int channel); + void clearMsgBus(); + iot_net::CMbMessage CreateMsg(const SReqHead& sReqHead); + +private: + iot_public::CSysInfoInterfacePtr m_sysInfo; + iot_service::CPermMngApiPtr m_permMng; + + iot_net::CMbCommunicator* m_objSendCMb;//发送 + iot_net::CMbCommunicator* m_objRecvCMb;//接收 + + std::string m_curRtu; + std::string m_strHostName; + std::string m_strInstName; + int m_nOptTime; + + QMap m_jsonMap; + int m_nDomainID; + std::string m_strProcessName; + std::string m_strPassword; + QString m_localHost; +}; + +#endif // CMSGDEAL_H diff --git a/product/src/gui/plugin/ChanParaWidget/ChanParaPluginWidget.cpp b/product/src/gui/plugin/ChanParaWidget/ChanParaPluginWidget.cpp new file mode 100644 index 00000000..7b80b727 --- /dev/null +++ b/product/src/gui/plugin/ChanParaWidget/ChanParaPluginWidget.cpp @@ -0,0 +1,26 @@ +#include "ChanParaPluginWidget.h" +#include "ChanParaWidget.h" + +ChanParaPluginWidget::ChanParaPluginWidget() +{ + +} + +ChanParaPluginWidget::~ChanParaPluginWidget() +{ + +} + +bool ChanParaPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **eventWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec); + ChanParaWidget *pWidget = new ChanParaWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *eventWidget = (IPluginWidget *)pWidget; + return true; +} + +void ChanParaPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/ChanParaWidget/ChanParaPluginWidget.h b/product/src/gui/plugin/ChanParaWidget/ChanParaPluginWidget.h new file mode 100644 index 00000000..0420f6ec --- /dev/null +++ b/product/src/gui/plugin/ChanParaWidget/ChanParaPluginWidget.h @@ -0,0 +1,20 @@ +#ifndef ChanParaPluginWidget_H +#define ChanParaPluginWidget_H + +#include +#include "GraphShape/CPluginWidget.h" + +class ChanParaPluginWidget:public QObject,public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) + Q_INTERFACES(CPluginWidgetInterface) +public: + ChanParaPluginWidget(); + ~ChanParaPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **eventWidget, QVector ptrVec); + void release(); +}; + +#endif // ChanParaPluginWidget_H diff --git a/product/src/gui/plugin/ChanParaWidget/ChanParaWidget.cpp b/product/src/gui/plugin/ChanParaWidget/ChanParaWidget.cpp new file mode 100644 index 00000000..4640ae28 --- /dev/null +++ b/product/src/gui/plugin/ChanParaWidget/ChanParaWidget.cpp @@ -0,0 +1,1020 @@ +#include "ui_ChanParaWidget.h" +#include "ChanParaWidget.h" +#include "pub_utility_api/FileStyle.h" + + + +using namespace iot_public; +using namespace iot_dbms; + +ChanParaWidget::ChanParaWidget(QWidget *parent, bool editMode) : + QWidget(parent),ui(new Ui::ChanParaWidget), + m_editMode(editMode) +{ + m_serverHost = "server"; + m_model = nullptr; + m_model1 = nullptr; + ui->setupUi(this); + sqlList.clear(); + AllLayout(); + //setAllLayout(); + m_SerialChanList<<"Chan1"<<"Chan2"<<"Chan3"<<"Chan4"<<"Chan5"<<"Chan6"; + m_NetChanList<<"Chan7"<<"Chan8"; + loadSerialAndNet(); + createListSerial(); + createListNet(); + + // 加载qss文件 + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + setStyleSheet(qss); + qssfile1.close(); + } + else + { + qDebug() << "public.qss 无法打开!"; + } +} + +ChanParaWidget::~ChanParaWidget() +{ + +} + +void ChanParaWidget::loadNetChan(const QString &ls) +{ + m_NetChanList = ls.split(","); +} + +void ChanParaWidget::loadSerialChan(const QString &ls) +{ + m_SerialChanList = ls.split(","); +} + +void ChanParaWidget::setNetChanHidden(bool isHidden) +{ + ui->m_NetSerialWidget->setHidden(isHidden); +} + +void ChanParaWidget::setSerialChanHidden(bool isHidden) +{ + ui->m_NetSerialWidget->setHidden(isHidden); +} + +void ChanParaWidget::reloadNetAndSerial() +{ + loadSerialAndNet(); + createListSerial(); + createListNet(); +} + +void ChanParaWidget::setServerHost(const QString &host) +{ + m_serverHost = host; +} + +void ChanParaWidget::AllLayout() +{ + connect(ui->b_return,&QPushButton::clicked,this,&ChanParaWidget::s_b_return); + connect(ui->b_reset,&QPushButton::clicked,this,&ChanParaWidget::s_shutdown); +} + +void ChanParaWidget::createListSerial() +{ + if(m_model != nullptr) + { + delete m_model; + m_model = nullptr; + } + + m_model = new QStandardItemModel(); + QStringList header; + header<setHorizontalHeaderLabels(header); + ui->t_tableview->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + //ui->t_tableview->horizontalHeader()->setStretchLastSection(true); + ui->t_tableview->verticalHeader()->setHidden(true); + ui->t_tableview->verticalHeader()->setDefaultSectionSize(50); + //t_tableview->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->t_tableview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->t_tableview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->t_tableview->setAutoScroll(false); + //t_tableview->setHorizontalScrollMode(QAbstractItemView::ScrollPerItem); + //t_tableview->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + ui->t_tableview->setModel(m_model); + + for(int i=0;isetItem(i,1,new QStandardItem(CSerialdata[i].chan_name)); + m_model->setItem(i,2,new QStandardItem(CSerialdata[i].description)); + m_model->setItem(i,3,new QStandardItem(CSerialdata[i].net_desc1)); + + m_model->item(i,1)->setEditable(false); + m_model->item(i,3)->setEditable(false); + QComboBox *alarm_enable = new QComboBox(); + QWidget *alarm_enable_widget = new QWidget(); + QHBoxLayout *alarm_enable_layout = new QHBoxLayout; + QStringList alarm_enable_list; + alarm_enable_list<<"是"<<"否"; + alarm_enable->addItems(alarm_enable_list); + if(CSerialdata[i].alarm_enable.toInt() == 1) + alarm_enable->setCurrentIndex(0); + else + alarm_enable->setCurrentIndex(1); + alarm_enable_layout->addWidget(alarm_enable); + alarm_enable_layout->setAlignment(Qt::AlignCenter); + alarm_enable_layout->setContentsMargins(0,0,0,0); + alarm_enable_widget->setLayout(alarm_enable_layout); + alarm_enable_widget->setContentsMargins(0,0,0,0); + + ui->t_tableview->setIndexWidget(m_model->index(i, 0), alarm_enable_widget); + + QComboBox *baud = new QComboBox(); + QWidget *baudwidget = new QWidget(); + QHBoxLayout *baudlayout = new QHBoxLayout; + baudlayout->addWidget(baud); + baudlayout->setAlignment(Qt::AlignCenter); + baudlayout->setContentsMargins(0,0,0,0); + baudwidget->setLayout(baudlayout); + baudwidget->setContentsMargins(0,0,0,0); + QStringList baud_list; + baud_list<<"600"<<"1200"<<"2400"<<"4800"<<"9600"<<"19200"<<"38400"<<"57600"<<"115200"; + baud->addItems(baud_list); + switch (CSerialdata[i].baud.toInt()) + { + case 600: + baud->setCurrentIndex(0); + break; + case 1200: + baud->setCurrentIndex(1); + break; + case 2400: + baud->setCurrentIndex(2); + break; + case 4800: + baud->setCurrentIndex(3); + break; + case 9600: + baud->setCurrentIndex(4); + break; + case 19200: + baud->setCurrentIndex(5); + break; + case 38400: + baud->setCurrentIndex(6); + break; + case 57600: + baud->setCurrentIndex(7); + case 115200: + baud->setCurrentIndex(8); + break; + default: + baud->setCurrentIndex(0); + break; + } + ui->t_tableview->setIndexWidget(m_model->index(i, 4), baudwidget); + + QComboBox *cmb = new QComboBox(); + + QStringList list; + list<<"0:NoParity"<<"2:EvenParity"<<"3:OddParity"<<"4:SpaceParity"<<"5:MarkParity"; + cmb->addItems(list); + QWidget *cmbwidget = new QWidget(); + QHBoxLayout *cmblayout = new QHBoxLayout; + cmblayout->addWidget(cmb); + cmblayout->setAlignment(Qt::AlignCenter); + cmblayout->setContentsMargins(0,0,0,0); + cmbwidget->setLayout(cmblayout); + cmbwidget->setContentsMargins(0,0,0,0); + switch (CSerialdata[i].parity.toInt()) + { + case 0: + cmb->setCurrentIndex(0); + break; + case 2: + cmb->setCurrentIndex(1); + break; + case 3: + cmb->setCurrentIndex(2); + break; + case 4: + cmb->setCurrentIndex(3); + break; + case 5: + cmb->setCurrentIndex(4); + break; + default: + cmb->setCurrentIndex(5); + break; + } + for(int j=0;jt_tableview->model()->columnCount());j++) + { + if(j==0||j==4||j==5) + {} + else + { + m_model->item(i,j)->setTextAlignment(Qt::AlignCenter); + } + } + ui->t_tableview->setIndexWidget(m_model->index(i, 5), cmbwidget); + connect(alarm_enable,SIGNAL(currentIndexChanged(int)),this,SLOT(currentIndexChangedEnable(int))); + connect(baud,SIGNAL(currentIndexChanged(int)),this,SLOT(currentIndexChangedbaud(int))); + connect(cmb,SIGNAL(currentIndexChanged(int)),this,SLOT(currentIndexChangedParity(int))); + } + connect(ui->t_tableview->itemDelegate(),&QAbstractItemDelegate::closeEditor,this,&ChanParaWidget::valueChangeTable1,Qt::UniqueConnection); +} + +void ChanParaWidget::createListNet() +{ + if(m_model1 != nullptr) + { + delete m_model1; + m_model1 = nullptr; + } + + m_model1 = new QStandardItemModel(); + QStringList header; + header<setHorizontalHeaderLabels(header); + ui->t_tableview1->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + //ui->t_tableview1->horizontalHeader()->setStretchLastSection(true); + ui->t_tableview1->setModel(m_model1); + ui->t_tableview1->verticalHeader()->setHidden(true); + //ui->t_tableview1->horizontalHeader()->setDefaultSectionSize(300); + ui->t_tableview1->verticalHeader()->setDefaultSectionSize(40); + ui->t_tableview1->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->t_tableview1->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->t_tableview1->setAutoScroll(false); + + for(int i=0;isetItem(i,1,new QStandardItem(CNetdata[i].chan_no)); + m_model1->setItem(i,1,new QStandardItem(CNetdata[i].chan_name)); + m_model1->setItem(i,2,new QStandardItem(CNetdata[i].description)); + m_model1->item(i,1)->setEditable(false); + + QComboBox *alarm_enable = new QComboBox(); + QWidget *alarm_enable_widget = new QWidget(); + QHBoxLayout *alarm_enable_layout = new QHBoxLayout; + alarm_enable_layout->addWidget(alarm_enable); + alarm_enable_layout->setAlignment(Qt::AlignCenter); + alarm_enable_layout->setContentsMargins(0,0,0,0); + alarm_enable_widget->setLayout(alarm_enable_layout); + alarm_enable_widget->setContentsMargins(0,0,0,0); + QStringList alarm_enable_list; + alarm_enable_list<<"是"<<"否"; + alarm_enable->addItems(alarm_enable_list); + + if(CNetdata[i].alarm_enable.toInt() == 1) + alarm_enable->setCurrentIndex(0); + else + alarm_enable->setCurrentIndex(1); + ui->t_tableview1->setIndexWidget(m_model1->index(i, 0), alarm_enable_widget); + m_model1->setItem(i,3,new QStandardItem(CNetdata[i].net_desc1)); + m_model1->setItem(i,4,new QStandardItem(CNetdata[i].port_no1)); + m_model1->setItem(i,5,new QStandardItem(CNetdata[i].net_desc2)); + m_model1->setItem(i,6,new QStandardItem(CNetdata[i].port_no2)); + m_model1->setItem(i,7,new QStandardItem(CNetdata[i].net_desc3)); + m_model1->setItem(i,8,new QStandardItem(CNetdata[i].port_no3)); + m_model1->setItem(i,9,new QStandardItem(CNetdata[i].net_desc4)); + m_model1->setItem(i,10,new QStandardItem(CNetdata[i].port_no4)); + m_model1->setItem(i,11,new QStandardItem(CNetdata[i].listen_no)); + connect(alarm_enable,SIGNAL(currentIndexChanged(int)),this,SLOT(currentIndexChangedEnable1(int))); + for(int j=0;jt_tableview1->model()->columnCount());j++) + { + if(j!=0) + { + m_model1->item(i,j)->setTextAlignment(Qt::AlignCenter); + } + } + } + connect(ui->t_tableview1->itemDelegate(),&QAbstractItemDelegate::closeEditor,this,&ChanParaWidget::valueChangeTable2,Qt::UniqueConnection); +} + +void ChanParaWidget::deleteListSerial() +{ + int num_sum = m_model->rowCount(); + if(num_sum>-1) + { + for(int i=num_sum;i>-1;i--) + m_model->removeRow(i); + } +} + +void ChanParaWidget::deleteListNet() +{ + int num_sum1 = m_model1->rowCount(); + if(num_sum1>-1) + { + for(int i=num_sum1;i>-1;i--) + m_model1->removeRow(i); + } +} + +void ChanParaWidget::loadSerialAndNet() +{ /* + * 通道名称 通道描述 通道使能 通道号(通道地址1)波特率 校验位 + * Chan1-Chan6 P1-P6 + * + * 通道名称 通道描述 通道使能 通道IP1 端口号1 通道IP2 端口号2 本地网络端口号 + * Chan7-Chan8 + */ + CSerialdata.clear(); + CNetdata.clear(); + reSerialData tempDataCSerial; + CDbApi dbRead(DB_CONN_MODEL_READ); + if(dbRead.open()) + { + QList columns; + columns.push_back("chan_name"); //通道名称 + columns.push_back("DESCRIPTION"); //通道描述 + columns.push_back("is_used"); //告警使能 + columns.push_back("CHAN_NO"); //通道号 + columns.push_back("baud"); //波特率 + columns.push_back("parity"); //校验位 + columns.push_back("NET_DESC1"); //通道IP1 + columns.push_back("PORT_NO1"); //端口号1 + columns.push_back("NET_DESC2"); //通道IP2 + columns.push_back("PORT_NO2"); //端口号2 + columns.push_back("RES_PARA_INT4"); //本地网络端口号 监听端口号 + columns.push_back("NET_DESC3"); //通道IP3 + columns.push_back("NET_DESC4"); //通道IP4 + columns.push_back("PORT_NO3"); //端口号3 + columns.push_back("PORT_NO4"); //端口号4 + columns.push_back("COMM_PROPERTY"); + columns.push_back("COMM_TYPE"); + if(dbRead.select("fes_channel_para", columns, query)) + { + while(query.next()) + { + CSerialtempData.chan_name = query.value(0).toString(); + CSerialtempData.description = query.value(1).toString(); + CSerialtempData.alarm_enable = query.value(2).toString(); + CSerialtempData.chan_no = query.value(3).toString(); + CSerialtempData.baud = query.value(4).toString(); + CSerialtempData.parity = query.value(5).toString(); + CSerialtempData.net_desc1 = query.value(6).toString(); + CSerialtempData.port_no1 = query.value(7).toString(); + CSerialtempData.net_desc2 = query.value(8).toString(); + CSerialtempData.port_no2 = query.value(9).toString(); + CSerialtempData.listen_no = query.value(10).toString(); + CSerialtempData.net_desc3 = query.value(11).toString(); + CSerialtempData.net_desc4 = query.value(12).toString(); + CSerialtempData.port_no3 = query.value(13).toString(); + CSerialtempData.port_no4 = query.value(14).toString(); + + //LOGINFO("loadSerialAndNet()--(0)=%d--(1)=%d", query.value(15).toInt(), query.value(16).toInt()); + + if (query.value(15).toInt()==1) + { + if (query.value(16).toInt() == 5) + { + CSerialdata.push_back(CSerialtempData); + } + else + { + CNetdata.push_back(CSerialtempData); + } + } + + + + + // if(!m_SerialChanList.isEmpty() && m_SerialChanList.contains(query.value(0).toString())) + // { + // CSerialdata.push_back(CSerialtempData); + // } + + // if(!m_NetChanList.isEmpty() && m_NetChanList.contains(query.value(0).toString())) + // { + // CNetdata.push_back(CSerialtempData); + // } + } + } + } +} + +void ChanParaWidget::WriteSql(const QString &sTableName, const QList &listColName, const QList &listVal) +{ + m_ptrModelCommit = new CDbApi(DB_CONN_MODEL_WRITE); + if (m_ptrModelCommit == NULL) + { + LOGERROR("COperateServerClass ::init(), new CDBApi(Write) fail!\n"); + return ; + } + + if(m_ptrModelCommit->open()) + { + m_ptrModelCommit->update(sTableName,listColName,listVal); + } + else + { + LOGERROR("COperateServerClass::setPlanShieldCfg m_ptrModelCommit->open() fail!\n"); + return ; + } +} + +bool ChanParaWidget::submitSql(QString &sql) +{ + bool flag = false; + m_ptrModelCommit = new CDbApi(DB_CONN_MODEL_WRITE); + if (m_ptrModelCommit == NULL) + { + LOGERROR("COperateServerClass ::init(), new CDBApi(Write) fail!\n"); + flag = false; + } + else + { + if(m_ptrModelCommit->open()) + { + if(m_ptrModelCommit->execute(sql)) + flag = true; + else + flag = false; + } + else + flag=false; + } + return flag; +} + +bool ChanParaWidget::permCheck() +{ + bool flag = false; + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + int nUserGrpId; + int nLevel; + int nLoginSec; + std::string strInstanceName; + int userId; + permMngPtr->CurUser(userId, nUserGrpId, nLevel, nLoginSec, strInstanceName); + if(PERM_NOM_FUNC_ID != nLevel) + { + sqlList.clear(); + QMessageBox::warning(this, tr("警告"), tr("无修改权限!"), QMessageBox::Ok); + deleteListSerial(); + deleteListNet(); + loadSerialAndNet(); + createListSerial(); + createListNet(); + flag = false; + } + else + flag = true; + } + else + { + QMessageBox::warning(this, tr("警告"), tr("初始化权限失败!"), QMessageBox::Ok); + flag = false; + } + return flag; +} + +bool ChanParaWidget::CompareQString(QString &str1, QString &str2) +{ + //sqlUpTag = QString("update %1 set description ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + QStringList arr1 ; + QStringList arr2 ; + arr1.clear(); + arr2.clear(); + bool flag1 = false; + bool flag3 = false; + arr1 = str1.split("="); + arr2 = str2.split("="); + QString temp1; + QString temp3; + int num = (int)arr1.size(); + for(int i=0;i &list) +{ + int num = list.size(); + if(num>0) + { +// for(int i=0;isize(); + int j = 0; + QSet seen; + seen.reserve(n); + int setSize = 0; + for (int i = 0; i < n; ++i) + { + const QString &s = that->at(i); + seen.insert(s); + if (setSize == seen.size()) // unchanged size => was already seen + continue; + ++setSize; + if (j != i) + that->swap(i, j); //将不重复项与重复项交换 + ++j; + } + if (n != j) + that->erase(that->begin() + j, that->end()); + return n - j; +} + +int ChanParaWidget::delectQListAll(QList &s) +{ + if(s.size()>0) + { + for(int i=s.size();i>=0;i--) + { + s.removeAt(i); + } + } + return (int)s.size(); +} + +void ChanParaWidget::s_b_return() +{ + if(!permCheck()) + { + return; + } + + QString errorStr = m_MsgDeal.RevProcessSet(m_serverHost,"fes"); + + if(errorStr.isEmpty()) + QMessageBox::warning(this, tr("提示"), tr("重启成功"), QMessageBox::Ok); + else + QMessageBox::warning(this, tr("提示"), errorStr, QMessageBox::Ok); + + /* + * 参数设置完成后,应用liunx指令killallfes,让FES被kill后,再次让进程管理程序重新拉起。 + */ +#ifdef OS_WINDOWS +// /*方法②*/ +// //获取pid +// QProcess cmd(this); +// QStringList argument; +// argument<< "/c" << "tasklist|findstr" <<"fes"; +// cmd.start("cmd.exe",argument);//这种方式最好,使用cmd程序,运行命令 +// cmd.waitForStarted();//必须加waitForStarted +// cmd.waitForFinished(); +// QString temp = cmd.readAll(); +// qDebug()<start(cmd.toStdString().c_str(),QIODevice::NotOpen); + // process->waitForStarted(); + // process->waitForFinished(); + // connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(finished(int,QProcess::ExitStatus))); + //system(cmd.toStdString().c_str()); +// sqlList.clear(); +// deleteListSerial(); +// deleteListNet(); +// loadSerialAndNet(); +// createListSerial(); +// createListNet(); +#else + //ps aux | grep tomcat | grep -v grep | awk '{print $2}' | xargs kill -9 //查找fes的pid并杀死。 +// QString sh = QString(tr("ps aux ")); +// sh += QString(tr("| ")); +// sh += QString(tr("grep fes ")); +// sh += QString(tr("| ")); +// sh += QString(tr("grep -v grep ")); +// sh += QString(tr("| ")); +// sh += QString(tr("awk '{print $2}' ")); +// sh += QString(tr("| ")); +// sh += QString(tr("xargs kill -9")); +// system(sh.toStdString().c_str()); +// QMessageBox::warning(this, tr("提示"), tr("重启完成"), QMessageBox::Ok); +// //或执行某脚本 +#endif + sqlList.clear(); + deleteListSerial(); + deleteListNet(); + loadSerialAndNet(); + createListSerial(); + createListNet(); + +} + +void ChanParaWidget::s_shutdown() +{ + if(!permCheck()) + { + if(delectQListAll(sqlList) == 0) + sqlList.clear(); + return ; + } + //sqlList.toSet().toList(); + // QStringList_removeDuplicates(&sqlList); + //removeDuplicatesList(sqlList); + int sum = (int)sqlList.size(); + if(sum>0) + { + //QString msg = "修改通道参数不可复原!确定要修改已选"; + QString msg = "修改通道参数不可复原!是否确认修改?"; + //msg += QString::number(sum); + //msg += tr("条记录吗?"); + QMessageBox *msgBox = new QMessageBox(this); + msgBox->setObjectName("msgbox"); + msgBox->setInformativeText(msg); + QPushButton *yes = msgBox->addButton(tr("确定"), QMessageBox::AcceptRole); + QPushButton *no = msgBox->addButton(tr("取消"), QMessageBox::RejectRole); + coordinates.clear(); + msgBox->setDefaultButton(no); + msgBox->exec(); + if (msgBox->clickedButton() == yes) + { + foreach (auto var, sqlList) + { + // QMessageBox::warning(this, tr("提示"), var, QMessageBox::Ok); + submitSql(var); + sqlList.removeOne(var); + } + sqlList.clear(); + deleteListSerial(); + deleteListNet(); + loadSerialAndNet(); + createListSerial(); + createListNet(); + delete msgBox; + msgBox = NULL; + QMessageBox::warning(this, tr("提示"), tr("修改完成"), QMessageBox::Ok); + } + else if(msgBox->clickedButton() == no) + { + delete msgBox; + msgBox = NULL; + return; + } + else + { + ; + } + } + else + { + coordinates.clear(); + QMessageBox::warning(this, tr("提示"), tr("没有修改数据记录!"), QMessageBox::Ok); + } +} + +void ChanParaWidget::valueChangeTable1() +{ + int row = ui->t_tableview->currentIndex().row(); + int colum = ui->t_tableview->currentIndex().column(); + QString content = ui->t_tableview->model()->index(row,colum).data().toString(); + QString chan_name = ui->t_tableview->model()->index(row,1).data().toString(); + if(permCheck()) + { + QList columns; + columns.clear(); + QString sqlUpTag = ""; + switch (colum) { + case 0: + break; + case 1: + break; + case 2: + sqlUpTag = QString("update %1 set description ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 3: + break; + default: + break; + } + if (!chanChange(row, colum)) + { + coordinates.push_back(make_pair(row, colum)); + sqlList.push_back(sqlUpTag); + } + } +} + +void ChanParaWidget::valueChangeTable2() +{ + if(!permCheck()) + { + return ; + } + int row = ui->t_tableview1->currentIndex().row(); + int colum = ui->t_tableview1->currentIndex().column(); + QString content = ""; + QString chan_name = ui->t_tableview1->model()->index(row,1).data().toString(); + QList columns; + columns.clear(); + QString sqlUpTag = ""; + switch (colum) + { + case 0: + break; + case 1: + break; + case 2: + content = ui->t_tableview1->model()->index(row,colum).data().toString(); + sqlUpTag = QString("update %1 set description ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 3: + content = ui->t_tableview1->model()->index(row,colum).data().toString(); + sqlUpTag =QString("update %1 set net_desc1 ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 4: + content = ui->t_tableview1->model()->index(row,colum).data().toString(); + sqlUpTag =QString("update %1 set port_no1 ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 5: + content = ui->t_tableview1->model()->index(row,colum).data().toString(); + sqlUpTag =QString("update %1 set net_desc2 ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 6: + content = ui->t_tableview1->model()->index(row,colum).data().toString(); + sqlUpTag =QString("update %1 set port_no2 ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 7: + content = ui->t_tableview1->model()->index(row,colum).data().toString(); + sqlUpTag =QString("update %1 set net_desc3 ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 8: + content = ui->t_tableview1->model()->index(row,colum).data().toString(); + sqlUpTag =QString("update %1 set port_no3 ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 9: + content = ui->t_tableview1->model()->index(row,colum).data().toString(); + sqlUpTag =QString("update %1 set net_desc4 ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 10: + content = ui->t_tableview1->model()->index(row,colum).data().toString(); + sqlUpTag =QString("update %1 set port_no4 ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 11: + content = ui->t_tableview1->model()->index(row,colum).data().toString(); + sqlUpTag =QString("update %1 set RES_PARA_INT4 ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + default: + break; + } + if (!chanChange(row, colum)) + { + coordinates.push_back(make_pair(row, colum)); + sqlList.push_back(sqlUpTag); + } + + +} + +void ChanParaWidget::currentIndexChangedEnable(int index) +{ + if(!permCheck()) + { + return ; + } + QComboBox *btn = (QComboBox*)sender(); + QWidget *w_parent = (QWidget*)btn->parent(); + int x = w_parent->mapToParent(QPoint(0,0)).x(); + int y = w_parent->mapToParent(QPoint(0,0)).y(); + QModelIndex index1 = ui->t_tableview->indexAt(QPoint(x,y)); + int pos_x = index1.row(); + QString content = ""; + QString chan_name = ui->t_tableview->model()->index(pos_x,1).data().toString(); + QList columns; + columns.clear(); + QString sqlUpTag = ""; + switch (index) { + case 0: + content = "1"; + sqlUpTag = QString("update %1 set IS_USED ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 1: + content = "0"; + sqlUpTag = QString("update %1 set IS_USED ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + default: + break; + } + + if (!chanChange(index1.row(), index1.column())) + { + coordinates.push_back(make_pair(index1.row(), index1.column())); + sqlList.push_back(sqlUpTag); + } +} + +void ChanParaWidget::currentIndexChangedbaud(int index) +{ + if(!permCheck()) + { + return ; + } + QComboBox *btn = (QComboBox*)sender(); + QWidget *w_parent = (QWidget*)btn->parent(); + int x = w_parent->mapToParent(QPoint(0,0)).x(); + int y = w_parent->mapToParent(QPoint(0,0)).y(); + QModelIndex index1 = ui->t_tableview->indexAt(QPoint(x,y)); + int pos_x = index1.row(); + QString content = ""; //t_tableview1->model()->index(row,colum).data().toString(); + QString chan_name = ui->t_tableview->model()->index(pos_x,1).data().toString(); + QList columns; + columns.clear(); + QString sqlUpTag = ""; + switch (index) { + case 0: + content = "600"; + sqlUpTag = QString("update %1 set baud ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 1: + content = "1200"; + sqlUpTag = QString("update %1 set baud ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(index).arg(chan_name); + break; + case 2: + content = "2400"; + sqlUpTag = QString("update %1 set baud ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 3: + content = "4800"; + sqlUpTag = QString("update %1 set baud ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 4: + content = "9600"; + sqlUpTag = QString("update %1 set baud ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 5: + content = "19200"; + sqlUpTag = QString("update %1 set baud ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 6: + content = "38400"; + sqlUpTag = QString("update %1 set baud ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 7: + content = "57600"; + sqlUpTag = QString("update %1 set baud ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 8: + content = "115200"; + sqlUpTag = QString("update %1 set baud ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + default: + break; + } + if (!chanChange(index1.row(), index1.column())) + { + coordinates.push_back(make_pair(index1.row(), index1.column())); + sqlList.push_back(sqlUpTag); + } +} + +void ChanParaWidget::currentIndexChangedParity(int index) +{ + if(permCheck()) + { + QComboBox *btn = (QComboBox*)sender(); + QWidget *w_parent = (QWidget*)btn->parent(); + int x = w_parent->mapToParent(QPoint(0,0)).x(); + int y = w_parent->mapToParent(QPoint(0,0)).y(); + QModelIndex index1 = ui->t_tableview->indexAt(QPoint(x,y)); + int pos_x = index1.row(); + QString content = ""; + QString chan_name = ui->t_tableview->model()->index(pos_x,1).data().toString(); + QList columns; + columns.clear(); + QString sqlUpTag = ""; + switch (index) { + case 0: + content = "0"; + sqlUpTag = QString("update %1 set parity ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 1: + content = "2"; + sqlUpTag = QString("update %1 set parity ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 2: + content = "3"; + sqlUpTag = QString("update %1 set parity ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 3: + content = "4"; + sqlUpTag = QString("update %1 set parity ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 4: + content = "5"; + sqlUpTag = QString("update %1 set parity ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 5: + content = ""; + sqlUpTag = QString("update %1 set parity ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + default: + break; + } + if (!chanChange(index1.row(), index1.column())) + { + coordinates.push_back(make_pair(index1.row(), index1.column())); + sqlList.push_back(sqlUpTag); + } + } +} + +void ChanParaWidget::currentIndexChangedEnable1(int index) +{ + if(permCheck()) + { + QComboBox *btn = (QComboBox*)sender(); + QWidget *w_parent = (QWidget*)btn->parent(); + int x = w_parent->mapToParent(QPoint(0,0)).x(); + int y = w_parent->mapToParent(QPoint(0,0)).y(); + QModelIndex index1 = ui->t_tableview1->indexAt(QPoint(x,y)); + int pos_x = index1.row(); + QString content = ""; + QString chan_name = ui->t_tableview1->model()->index(pos_x,1).data().toString(); + QList columns; + columns.clear(); + QString sqlUpTag = ""; + switch (index) { + case 0: + content = "1"; + sqlUpTag = QString("update %1 set IS_USED ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + case 1: + content = "0"; + sqlUpTag = QString("update %1 set IS_USED ='%2' where chan_name ='%3'").arg("fes_channel_para").arg(content).arg(chan_name); + break; + default: + break; + } + if (!chanChange(index1.row(), index1.column())) + { + coordinates.push_back(make_pair(index1.row(), index1.column())); + sqlList.push_back(sqlUpTag); + } + } +} + +bool ChanParaWidget::chanChange(int row, int column) +{ + pair target(row, column); + auto it = find_if(coordinates.begin(), coordinates.end(), [&](const pair& p) { + return p.first == target.first && p.second == target.second; + }); + if (it != coordinates.end()) { + return true; + } + else { + return false; + } +} diff --git a/product/src/gui/plugin/ChanParaWidget/ChanParaWidget.h b/product/src/gui/plugin/ChanParaWidget/ChanParaWidget.h new file mode 100644 index 00000000..b114fee7 --- /dev/null +++ b/product/src/gui/plugin/ChanParaWidget/ChanParaWidget.h @@ -0,0 +1,169 @@ +#ifndef CSERIALINFO_H +#define CSERIALINFO_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "db_api_ex/CDbApi.h" +#include "pub_logger_api/logger.h" +#include "perm_mng_api/PermMngApi.h" +#include "CMsgDeal.h" + +QT_BEGIN_NAMESPACE +namespace Ui { class ChanParaWidget; } +QT_END_NAMESPACE + +class ChanParaWidget : public QWidget +{ + Q_OBJECT +public: + explicit ChanParaWidget(QWidget *parent = nullptr,bool editMode = false); + ~ChanParaWidget(); + +public slots: + //加载网络通道配置 + //ls 为通道名列表,用逗号分割 ,例如"chan1,chan2,chan3" + void loadNetChan(const QString& ls); + + //加载串口通道配置 + //ls 为通道名列表,用逗号分割 ,例如"chan1,chan2,chan3" + void loadSerialChan(const QString& ls); + + //设置网络通道隐藏。默认是显示 + //isHidden:true:隐藏,false:显示 + void setNetChanHidden(bool isHidden); + + //设置串口通道隐藏。默认是显示 + //isHidden:true:隐藏,false:显示 + void setSerialChanHidden(bool isHidden); + + //重新加载页面 + void reloadNetAndSerial(); + + //设置服务端的主机名 + void setServerHost(const QString& host); + +public: + struct reSerialData + { + QString chan_name; //通道名称 + QString description; //通道描述 + QString net_desc1; //通道IP1 + QString net_desc2; //通道IP2 + QString port_no2; //端口号2 + QString listen_no; //本地网络端口号 监听端口号 + QString alarm_enable; //告警使能 + QString chan_no; //通道号 + QString baud; //波特率 + QString parity; //校验位 + QString port_no1; //端口号1 + QString net_desc3; //通道IP3 + QString net_desc4; //通道IP4 + QString port_no3; //端口号3 + QString port_no4; //端口号4 + + public: + reSerialData() + { + chan_name = ""; + description = ""; + alarm_enable = ""; + chan_no = ""; + baud = ""; + parity = ""; + net_desc1 = ""; + port_no1 = ""; + net_desc2 = ""; + port_no2 = ""; + listen_no = ""; + net_desc3 = ""; + net_desc4 = ""; + port_no3 = ""; + port_no4 = ""; + } + }ReSerialDatas; +public: + reSerialData CSerialtempData; + QVector CSerialdata; + QVector CNetdata; + QSqlQuery query; + iot_dbms::CDbApi* m_ptrModelCommit; //模型提交接口 + iot_dbms::CDbApi* m_pDb; // 数据库接口 + bool m_editMode; + +public: + void AllLayout(); + void setAllLayout(); + void createListSerial(); + void createListNet(); + + void deleteListSerial(); + void deleteListNet(); + + void loadSerialAndNet(); + void WriteSql(const QString& sTableName, const QList& listColName, const QList& listVal); + + void openSql(); + + bool submitSql(QString &sql); + bool permCheck(); + bool CompareQString(QString &str1,QString &str2); + void removeDuplicatesList(QList &list); + int QStringList_removeDuplicates(QStringList *that); + int delectQListAll(QList &s); + + vector> coordinates; + bool chanChange(int row,int colunm); + +private: + Ui::ChanParaWidget *ui; +private: + QList sqlList; + // QStringList sqlList; + QStandardItemModel *m_model; + QStandardItemModel *m_model1; + + QStringList m_NetChanList; + QStringList m_SerialChanList; + + QString m_serverHost; + CMsgDeal m_MsgDeal; + + + +public slots: + void s_b_return(); + // void finished(int exitCode, QProcess::ExitStatus exitStatus); + void s_shutdown(); + void valueChangeTable1(); + void valueChangeTable2(); + + void currentIndexChangedEnable(int index); + void currentIndexChangedbaud(int index); + void currentIndexChangedParity(int index); + void currentIndexChangedEnable1(int index); +signals: + + +}; +//} + +#endif // ChanParaWidget_H diff --git a/product/src/gui/plugin/ChanParaWidget/ChanParaWidget.pro b/product/src/gui/plugin/ChanParaWidget/ChanParaWidget.pro new file mode 100644 index 00000000..554ed3f0 --- /dev/null +++ b/product/src/gui/plugin/ChanParaWidget/ChanParaWidget.pro @@ -0,0 +1,52 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2022-12-31T14:20:18 +# +#------------------------------------------------- + +QT += core gui sql xml printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib +TARGET = ChanParaWidget + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. + +#DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +CONFIG += plugin + +SOURCES += \ + CMsgDeal.cpp \ + ChanParaWidget.cpp \ + ChanParaPluginWidget.cpp + +HEADERS += \ + CMsgDeal.h \ + ChanParaWidget.h \ + ChanParaPluginWidget.h \ + PreDefine.h + +LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api +LIBS += -lpub_sysinfo_api -lnet_msg_bus_api -lalarm_server_api -lpub_excel + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + +FORMS += \ + ChanParaWidget.ui diff --git a/product/src/gui/plugin/ChanParaWidget/ChanParaWidget.ui b/product/src/gui/plugin/ChanParaWidget/ChanParaWidget.ui new file mode 100644 index 00000000..0a6905c6 --- /dev/null +++ b/product/src/gui/plugin/ChanParaWidget/ChanParaWidget.ui @@ -0,0 +1,141 @@ + + + ChanParaWidget + + + + 0 + 0 + 1141 + 881 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + 0 + + + + 网口参数 + + + + + + + + + + + + + 串口参数 + + + + + + + + + + + + + + + + + + + + + + + 9 + + + 0 + + + 9 + + + 9 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 确认修改 + + + + + + + 重启通道 + + + + + + + + + + + diff --git a/product/src/gui/plugin/ChanParaWidget/PreDefine.h b/product/src/gui/plugin/ChanParaWidget/PreDefine.h new file mode 100644 index 00000000..5e9dcb33 --- /dev/null +++ b/product/src/gui/plugin/ChanParaWidget/PreDefine.h @@ -0,0 +1,66 @@ +#ifndef PREDEFINE_H +#define PREDEFINE_H + +#include +#include +#include +#include "common/DataType.h" +#include "service/operate_server_api/JsonOptCommand.h" + +static const std::string APP_PROCESSNAME = "NTPimeWidget"; + +static const std::string CONFING_IS_CREATE_ALARM = "isGenAlarmToOpt"; +static const std::string CONFING_UI_TIMER_TO_SEND_SECONDS = "UiTimerToSendSeconds"; + +#define MT_SYS_PARAMS_TO_HMI_UP 10001 +#define MT_HMI_TO_SYS_PARAMS_DOWN 10002 + +#define MT_OPT_COMMON_DOWN 68 + +enum SysParams_MsgType +{ + enum_Set_Process_Message = 11, //杀死进程 + enum_Set_Process_Message_Ack = 12,//杀死进程 应答 +}; + +struct SReqHead +{ + int nMsgType; //!<消息类型 + std::string strSrcTag; //!< 源标签(即发送端进程名) + int nSrcDomainID; //!< 消息发送源域名 + int nDstDomainID; //!< 消息目标域名 + int nAppID; //!< 所属应用ID + std::string strHostName; //!< 发送端主机名 key1 + std::string strInstName; //!< 发送端实例名 key2 + std::string strCommName; //!< 发送端通讯器名 + int nUserID; //!< 发送端用户ID + int nUserGroupID; //!< 发送端用户组ID + int64 nOptTime; //!< 消息发送时间 key3 + std::string strKeyIdTag; + std::string ErroStr; + SReqHead() + { + nMsgType = 0; + strSrcTag = ""; + nSrcDomainID = 0; + nDstDomainID = 0; + nAppID = -1; + strHostName = ""; + strInstName = ""; + strCommName = ""; + nUserID = -1; + nUserGroupID = -1; + nOptTime = 0; + strKeyIdTag = ""; + } +}; + +//进程设置 +struct SProcessSetRequest +{ + SReqHead stHead; + std::string strProcessName; +}; + + +#endif // PREDEFINE_H diff --git a/product/src/gui/plugin/ChanRealStatusWidget/CChanRealStatusPluginWidget.cpp b/product/src/gui/plugin/ChanRealStatusWidget/CChanRealStatusPluginWidget.cpp new file mode 100644 index 00000000..4b9188e1 --- /dev/null +++ b/product/src/gui/plugin/ChanRealStatusWidget/CChanRealStatusPluginWidget.cpp @@ -0,0 +1,27 @@ +#include "CChanRealStatusPluginWidget.h" +#include "CChanRealStatusWidget.h" +#include + +CPointRealPluginWidget::CPointRealPluginWidget() +{ + +} + +CPointRealPluginWidget::~CPointRealPluginWidget() +{ + +} + +bool CPointRealPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CChanRealStatusWidget *pWidget = new CChanRealStatusWidget(editMode, parent); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CPointRealPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/ChanRealStatusWidget/CChanRealStatusPluginWidget.h b/product/src/gui/plugin/ChanRealStatusWidget/CChanRealStatusPluginWidget.h new file mode 100644 index 00000000..88cd8c89 --- /dev/null +++ b/product/src/gui/plugin/ChanRealStatusWidget/CChanRealStatusPluginWidget.h @@ -0,0 +1,21 @@ +#ifndef CPOINTREALPLUGINWIDGET_H +#define CPOINTREALPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< RQEH6000_HOME/platform/src/include/gui/GraphShape + +class CPointRealPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) + Q_INTERFACES(CPluginWidgetInterface) + +public: + CPointRealPluginWidget(); + ~CPointRealPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CPOINTREALPLUGINWIDGET_H diff --git a/product/src/gui/plugin/ChanRealStatusWidget/CChanRealStatusWidget.cpp b/product/src/gui/plugin/ChanRealStatusWidget/CChanRealStatusWidget.cpp new file mode 100644 index 00000000..aa9384e0 --- /dev/null +++ b/product/src/gui/plugin/ChanRealStatusWidget/CChanRealStatusWidget.cpp @@ -0,0 +1,527 @@ +#include "CChanRealStatusWidget.h" +#include "CDbInterface.h" +#include "CRealTableModel.h" +#include "CRealDataCollect.h" +#include +#include +#include +#include "pub_utility_api/FileStyle.h" + +CChanRealStatusWidget::CChanRealStatusWidget(bool editMode, QWidget *parent) + : QWidget(parent), + m_isEditMode(editMode), + m_nGroupNo(1), + m_isRtdbNormal(true), + m_pTimer(NULL), + m_pDpcdaForApp(NULL) +{ + initialize(); +} + +CChanRealStatusWidget::~CChanRealStatusWidget() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + delete m_pDpcdaForApp; + } + m_pDpcdaForApp = NULL; + + if(!m_isEditMode) + { + CRealDataCollect::instance()->release(); + + CDbInterface::instance()->destory(); + } +} + +void CChanRealStatusWidget::initialize() +{ + if(m_isEditMode) + { + QTableView * tableView = new QTableView(); + QGridLayout * layout = new QGridLayout(this); + layout->addWidget(tableView); + layout->setMargin(0); + setLayout(layout); + return; + } + + setChannelText(tr("通讯状态"), tr("正常"), tr("异常")); + + qRegisterMetaType>>("QMap>"); + + m_objAppContext = RT_MODE; + CRealDataCollect::instance()->setAppContext(m_objAppContext); + connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateDi, this, &CChanRealStatusWidget::slotUpdateDi); + m_pDpcdaForApp = new iot_service::CDpcdaForApp(); + + m_pTimer = new QTimer(this); + connect(m_pTimer, &QTimer::timeout, this, &CChanRealStatusWidget::onTimer); + m_pTimer->start(1000); +} + +void CChanRealStatusWidget::initStyle() +{ + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("ChanRealStatusWidget.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +void CChanRealStatusWidget::switchAppcontext(int appContext) +{ + if(m_objAppContext == appContext) + { + return; + } + m_objAppContext = (EN_AppContext)appContext; + if(m_objAppContext == PDR_MODE) + { + m_pTimer->stop(); + } + else + { + m_pTimer->start(1000); + } + + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + } + + CRealDataCollect::instance()->setAppContext(m_objAppContext); + + QMap >::iterator iter = m_groupMap.begin(); + for(; iter != m_groupMap.end(); iter++) + { + QList &dataList = iter.value(); + QList::iterator it = dataList.begin(); + for(; it != dataList.end(); it++) + { + SRealData &data = *it; + data.isInit = false; + if(data.type == TYPE_POINT) + { + m_pDpcdaForApp->subscribe(data.table_name.toStdString(), data.tag_name.toStdString(), data.column.toStdString()); + } + } + } +} + +int CChanRealStatusWidget::addGroup(const QStringList &name, int row, int column) +{ + QTableView * tableView = new QTableView(); + tableView->setSelectionMode(QAbstractItemView::NoSelection); + tableView->horizontalHeader()->setStretchLastSection(true); + tableView->horizontalHeader()->setSectionsClickable(false); + tableView->setFocusPolicy(Qt::NoFocus); + tableView->setAlternatingRowColors(true); + tableView->verticalHeader()->setVisible(false); + tableView->setShowGrid(false); + tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + CRealTableModel * tableModel = new CRealTableModel(tableView, name); + tableModel->updateChannelText(m_channelTxList); + tableView->setModel(tableModel); + + if(!layout()) + { + QGridLayout *layout = new QGridLayout(this); + layout->setMargin(0); + layout->setSpacing(0); + setLayout(layout); + } + QGridLayout *gLayout = dynamic_cast(layout()); + gLayout->addWidget(tableView, row, column); + + m_groupMap.insert(m_nGroupNo, QList()); + m_tableMap.insert(m_nGroupNo, tableView); + + return m_nGroupNo++; +} + +QString CChanRealStatusWidget::addRealPoint(int GroupNo, const QString &strRealTagList) +{ + if(m_groupMap.find(GroupNo) == m_groupMap.constEnd()) + { + return tr("未找到组号%1!").arg(QString::number(GroupNo)); + } + + QStringList RealTagList = strRealTagList.split(";"); + if (RealTagList.count() == 0) + { + return ""; + } + + //< 得到所有可能的点标签 + QMap tagMap; + QString devGroup; + foreach (QString RealTag, RealTagList) { + if(RealTag.isEmpty() || RealTag.split(".").length() != 7) + { + continue; + } + if (devGroup.isEmpty()) + { + devGroup = truncTag(RealTag, "g"); + } + tagMap[devGroup].append(RealTag); + + QString tagName = RealTag; + SRealData realData; + QString temp; + QString table = truncTag(tagName, "t"); + temp = CDbInterface::instance()->readPointInfo(truncTag(tagName, "p"), table); + + if (temp.isEmpty()) + { + continue; + } + + + m_tagMap[GroupNo].append(QVariant::fromValue(tagName)); + realData.tag_name = truncTag(tagName, "p"); + realData.description = temp.section(",", 0, 0); + realData.table_name = table; + if (realData.table_name == "digital") + { + realData.stateTextName = temp.section(",", 1, 1); + } + + realData.nDomainId = CDbInterface::instance()->readDomainId(truncTag(tagName, "l")); + realData.nAppId = CDbInterface::instance()->readAppId(truncTag(tagName, "a")); + + m_groupMap[GroupNo].append(realData); + if (realData.type == TYPE_POINT) + { + m_pDpcdaForApp->subscribe(realData.table_name.toStdString(), realData.tag_name.toStdString(), realData.column.toStdString()); + } + } + + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + CRealTableModel *model = dynamic_cast(view->model()); + model->updateRealData(m_groupMap[GroupNo]); + } + return ""; +} + +QVariantList CChanRealStatusWidget::getPointList(int GroupNo) +{ + return m_tagMap.value(GroupNo); +} + +void CChanRealStatusWidget::setColumnWidth(int GroupNo, int column, int width) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + if(column == -1) + { + for(int nIndex(0); nIndexmodel()->columnCount(); nIndex++) + { + view->setColumnWidth(nIndex, width); + } + } + else + { + view->setColumnWidth(column, width); + } + } +} + +void CChanRealStatusWidget::setRowHeight(int GroupNo, int row, int height) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + if(row == -1) + { + for(int nIndex(0); nIndexmodel()->rowCount(); nIndex++) + { + view->setRowHeight(nIndex, height); + } + } + else + { + view->setRowHeight(row, height); + } + } +} + +void CChanRealStatusWidget::setColumnCount(int GroupNo, int count) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + CRealTableModel *model = dynamic_cast(view->model()); + model->setColumnCount(count); + } +} + +void CChanRealStatusWidget::setHeaderVisible(int GroupNo, int header, bool visible) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + if(header == Qt::Horizontal) + { + view->horizontalHeader()->setVisible(visible); + } + else if(header == Qt::Vertical) + { + view->verticalHeader()->setVisible(visible); + } + } +} + +void CChanRealStatusWidget::setHeaderDesc(int GroupNo, const QString& headerDescs) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(!view) + { + return; + } + + CRealTableModel *model = dynamic_cast(view->model()); + QStringList headerDescList = headerDescs.split(","); + model->setHeaderLabels(headerDescList); +} + +void CChanRealStatusWidget::setShowGrid(int GroupNo, bool isShow) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + view->setShowGrid(isShow); + } +} + +void CChanRealStatusWidget::setScrollBarOn(int GroupNo, int direct, bool on) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + if(direct == Qt::Horizontal) + { + view->setHorizontalScrollBarPolicy(on ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff); + } + else if(direct == Qt::Vertical) + { + view->setVerticalScrollBarPolicy(on ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff); + } + } +} + +void CChanRealStatusWidget::setAlternatingRowColors(int GroupNo, bool enable) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + view->setAlternatingRowColors(enable); + } +} + +void CChanRealStatusWidget::setChannelText(const QString &text, const QString &normal, const QString &abnormal) +{ + m_channelTxList.clear(); + m_channelTxList.append(text); + m_channelTxList.append(normal); + m_channelTxList.append(abnormal); + + QMap::const_iterator iter = m_tableMap.constBegin(); + for(; iter != m_tableMap.constEnd(); iter++) + { + QTableView * view = iter.value(); + if(view) + { + CRealTableModel *model = dynamic_cast(view->model()); + model->updateChannelText(m_channelTxList); + } + } +} + +void CChanRealStatusWidget::clear(int groupNo) +{ + QTableView *view = m_tableMap.value(groupNo); + if(view) + { + CRealTableModel *model = dynamic_cast(view->model()); + QList data; + model->updateRealData(data); + + m_tagMap[groupNo] = QVariantList(); + m_groupMap[groupNo] = data; + } +} + +void CChanRealStatusWidget::updatePointValue(const QSet &groupSet) +{ + foreach (const int &groupNo, groupSet) + { + QTableView *view = m_tableMap.value(groupNo); + if(view == NULL) + { + continue; + } + CRealTableModel *model = dynamic_cast(view->model()); + QList temp = m_groupMap.value(groupNo); + model->updateRealValue(temp); + } +} + +void CChanRealStatusWidget::updatePointValue(int groupNo, QList data) +{ + QTableView *view = m_tableMap.value(groupNo); + if(view == NULL) + { + return; + } + CRealTableModel *model = dynamic_cast(view->model()); + model->updateRealValue(data); +} + +void CChanRealStatusWidget::onTimer() +{ + if(m_objAppContext == PDR_MODE || !m_isRtdbNormal) + { + m_pTimer->stop(); + return; + } + + QMap >::iterator iter = m_groupMap.begin(); + for(; iter != m_groupMap.end(); iter++) + { + QList &listData = iter.value(); + bool change = false; + for(int nIndex(0); nIndexreadPointValue(sRealData)) + { + change = true; + } + else + { + m_isRtdbNormal = false; + } + } + if(change) + { + updatePointValue(iter.key(), listData); + } + } +} + +void CChanRealStatusWidget::slotUpdateDi(const QMap > &diMap) +{ + QSet groupSet; + QMap >::const_iterator iter = diMap.constBegin(); + for(; iter != diMap.constEnd(); iter++) + { + QMap >::iterator it = m_groupMap.begin(); + for(; it != m_groupMap.end(); it++) + { + QList &dataList = it.value(); + for(int i = 0; i < dataList.length(); i++) + { + SRealData &data = dataList[i]; + if(data.table_name != "digital") + { + continue; + } + if(data.tag_name != iter.key()) + { + continue; + } + data.isInit = true; + data.value = iter.value().first; + data.status = iter.value().second; + groupSet.insert(it.key()); + break; + } + } + } + if(!groupSet.isEmpty()) + { + updatePointValue(groupSet); + } +} + + +QString CChanRealStatusWidget::truncTag(const QString &tagName, const QString &format) +{ + QString ret = ""; + if(format == "l") + { + ret = tagName.section(".", 0, 0); + } + else if(format == "a") + { + ret = tagName.section(".", 1, 1); + } + else if(format == "t") + { + ret = tagName.section(".", 2, 2); + } + else if(format == "d") + { + ret = tagName.section(".", 3, 4); + } + else if(format == "g") + { + QStringList temp = tagName.section(".", 3, 4).split("_"); + temp.pop_back(); + ret = temp.join("_"); + } + else if(format == "p") + { + ret = tagName.section(".", 3, 5); + } + else if(format == "point") + { + ret = tagName.section(".", 5, 5); + } + else if(format == "v") + { + ret = tagName.section(".", -1, -1); + } + return ret; +} diff --git a/product/src/gui/plugin/ChanRealStatusWidget/CChanRealStatusWidget.h b/product/src/gui/plugin/ChanRealStatusWidget/CChanRealStatusWidget.h new file mode 100644 index 00000000..8eb9a0f6 --- /dev/null +++ b/product/src/gui/plugin/ChanRealStatusWidget/CChanRealStatusWidget.h @@ -0,0 +1,158 @@ +#ifndef CPOINTREALDATAWIDGET_H +#define CPOINTREALDATAWIDGET_H + +#include +#include +#include +#include +#include "CPointPublic.h" +#include "dp_chg_data_api/CDpcdaForApp.h" + +class QTableView; +class CRealDataCollect; +class CChanRealStatusWidget : public QWidget +{ + Q_OBJECT + +public: + CChanRealStatusWidget(bool editMode, QWidget *parent = 0); + ~CChanRealStatusWidget(); + + void initialize(); + + + +public slots: + + void initStyle(); + + /** + * @brief switchAppcontext 切换数据来源 + * @param appContext 1: 实时数据 2: 事故反演 + */ + void switchAppcontext(int appContext = 1); + + /** + * @brief addGroup 添加数据组 + * @param name 组名 为空不显示 + * @param row 行号 QGridLayout + * @param column 列号 QGridLayout + * @return 组号 + */ + int addGroup(const QStringList &name, int row, int column); + + + /** + * @brief addRealPoint 往组内添加测点,插入的列表是什么就是什么 + * @param GroupNo 组号 + * @param RealTagList 关联测点列表 "station1.PSCADA.digital.station1.NQ-G01_NRINC.OC1.value;station1.PSCADA.digital.station1.NQ-G01_NRINC.OC1.value" + * @return 成功返回空字符串,失败返回错误信息 + */ + QString addRealPoint(int GroupNo, const QString& strRealTagList); + + + /** + * @brief getPointList 获取组内测点列表 + * @param GroupNo 组号 + * @return 测点列表 + */ + QVariantList getPointList(int GroupNo); + + /** + * @brief setColumnWidth 设置组的列宽 + * @param GroupNo 组号 + * @param column 列号 -1代表所有列 + * @param width 宽度 + */ + void setColumnWidth(int GroupNo, int column, int width); + + /** + * @brief setRowHeight 设置组的行高 + * @param GroupNo 组号 + * @param row 行号 -1代表所有行 + * @param height 高度 + */ + void setRowHeight(int GroupNo, int row, int height); + + /** + * @brief setColumnCount 设置列数 + * @param GroupNo 组号 + * @param count 列数 + */ + void setColumnCount(int GroupNo, int count); + + /** + * @brief setHeaderVisible 设置表头是否显示 + * @param GroupNo 组号 + * @param header 1:水平 2:垂直 + * @param visible 是否显示 + */ + void setHeaderVisible(int GroupNo, int header = Qt::Horizontal, bool visible = true); + + /** + * @brief setHeaderVisible 设置表头描述 + * @param GroupNo 组号 + * @param header 1:水平 2:垂直 + * @param visible 是否显示 + */ + void setHeaderDesc(int GroupNo, const QString& headerDescs); + + /** + * @brief setShowGrid 设置是否显示表格网格线 + * @param GroupNo 组号 + * @param isShow 是否显示 + */ + void setShowGrid(int GroupNo, bool isShow = true); + + /** + * @brief setScrollBarOn 设置是否显示滚动条 + * @param GroupNo 组号 + * @param direct 1:水平 2:垂直 + * @param on 是否显示 + */ + void setScrollBarOn(int GroupNo, int direct = Qt::Horizontal, bool on = true); + + /** + * @brief setAlternatingRowColors 设置启用间隔色 + * @param GroupNo 组号 + * @param enable 是否启用 + */ + void setAlternatingRowColors(int GroupNo, bool enable = true); + + /** + * @brief setChannelText 设置通讯状态文本 + * @param text 显示名称 默认为通讯状态 + * @param normal 状态正常显示文本 默认为正常 + * @param abnormal 状态异常显示文本 默认为异常 + */ + void setChannelText(const QString& text, const QString &normal, const QString &abnormal); + + void clear(int groupNo); + +private slots: + void updatePointValue(const QSet &groupSet); + void updatePointValue(int groupNo, QList data); + + void onTimer(); + + void slotUpdateDi(const QMap>& diMap); + + +private: + QString truncTag(const QString &tagName, const QString &format); + +private: + bool m_isEditMode; + int m_nGroupNo; + bool m_isRtdbNormal; + EN_AppContext m_objAppContext; + QTimer * m_pTimer; + iot_service::CDpcdaForApp *m_pDpcdaForApp; + QMap m_tableMap; + QMap > m_groupMap; + QMap m_tagMap; + + QStringList m_channelTxList; +}; + +#endif // CPOINTREALDATAWIDGET_H diff --git a/product/src/gui/plugin/ChanRealStatusWidget/CDbInterface.cpp b/product/src/gui/plugin/ChanRealStatusWidget/CDbInterface.cpp new file mode 100644 index 00000000..0e0cc4a3 --- /dev/null +++ b/product/src/gui/plugin/ChanRealStatusWidget/CDbInterface.cpp @@ -0,0 +1,504 @@ +#include "CDbInterface.h" +#include "public/pub_logger_api/logger.h" + +using namespace iot_dbms; + +CDbInterface *CDbInterface::m_pInstance = NULL; + +CDbInterface::CDbInterface() +{ + m_pReadDb = new CDbApi(DB_CONN_MODEL_READ); + m_pReadDb->open(); + + m_rtdbAccess = new iot_dbms::CRdbAccess(); + m_rtdbNetAcs = new iot_dbms::CRdbNetApi(); + + readUnitInfo(); +} + +CDbInterface *CDbInterface::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CDbInterface(); + } + return m_pInstance; +} + +void CDbInterface::destory() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; + + if(m_rtdbNetAcs) + { + delete m_rtdbNetAcs; + } + m_rtdbNetAcs = NULL; + + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + m_mapDevGroup.clear(); + m_mapDevice.clear(); + m_mapUnit.clear(); + m_pInstance = NULL; + delete this; +} + +int CDbInterface::readDomainId(const QString &location) +{ + if(!m_pReadDb->isOpen()) + { + return -1; + } + QSqlQuery query; + QString tableName = "sys_model_location_info"; + QList listColName; + listColName.append("DOMAIN_ID"); + CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = location; + + QList listOrderBy; + listOrderBy << CDbOrder("location_no"); + + if(m_pReadDb->select(tableName, listColName, objCondition, listOrderBy, query)) + { + while(query.next()) + { + return query.value(0).toInt(); + } + } + return -1; +} + +int CDbInterface::readAppId(const QString &appName) +{ + if(!m_pReadDb->isOpen()) + { + return -1; + } + QSqlQuery query; + QString tableName = "sys_model_app_info"; + QList listColName; + listColName.append("APP_ID"); + CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = appName; + + if(m_pReadDb->select(tableName, listColName, objCondition, query)) + { + while(query.next()) + { + return query.value(0).toInt(); + } + } + return -1; +} + +bool CDbInterface::readDevice(const QString &devGroup, QStringList &device) +{ + QStringList tagList = m_mapDevice.value(devGroup); + if(!tagList.isEmpty()) + { + device.append(tagList); + return true; + } + + if(!m_pReadDb->isOpen()) + { + return false; + } + + QSqlQuery query; + QString tableName = "dev_info"; + QList listColName; + listColName.append("TAG_NAME"); + CDbCondition objCondition; + objCondition.m_sColName = "GROUP_TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = devGroup; + + QString tag; + if(m_pReadDb->select(tableName, listColName, objCondition, query)) + { + while(query.next()) + { + tag = query.value(0).toString(); + device.append(tag); + m_mapDevice[devGroup].append(tag); + } + return true; + } + return false; +} + +QString CDbInterface::readDevGroup(const QString &devGroup) +{ + QString desc = m_mapDevGroup.value(devGroup); + if(!desc.isEmpty()) + { + return desc; + } + + if(!m_pReadDb->isOpen()) + { + return QString(); + } + + QSqlQuery query; + QString tableName = "dev_group"; + QList listColName; + listColName.append("DESCRIPTION"); + CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = devGroup; + + if(m_pReadDb->select(tableName, listColName, objCondition, query)) + { + while(query.next()) + { + desc = query.value(0).toString(); + m_mapDevGroup.insert(devGroup, desc); + } + } + return desc; +} + +QString CDbInterface::readPointInfo(const QString &tagName, const QString &table) +{ + if(!m_pReadDb->isOpen()) + { + return QString(); + } + + QString ret; + QSqlQuery query; + QList listColName; + listColName.append("DESCRIPTION"); + if(table == "analog" || table == "accuml") + { + listColName.append("UNIT_ID"); + } + else if(table == "digital" || table == "mix") + { + listColName.append("STATE_TEXT_NAME"); + } + CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = tagName; + if(m_pReadDb->select(table, listColName, objCondition, query)) + { + while(query.next()) + { + QString desc = query.value(0).toString(); + QString temp; + if(table == "analog" || table == "accuml") + { + temp = getUnitName(query.value(1).toInt()); + } + else if(table == "digital" || table == "mix") + { + temp = query.value(1).toString(); + } + ret = desc + "," + temp; + } + } + return ret; +} + +QString CDbInterface::readChannelTag(const QString &device, const QString &table) +{ + if(!m_pReadDb->isOpen()) + { + return QString(); + } + + QString ret; + QSqlQuery query; + QList listColName; + listColName.append("RTU_TAG"); + CDbCondition objCondition; + objCondition.m_sColName = "DEVICE"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = device; + if(m_pReadDb->select(table, listColName, objCondition, query)) + { + while(query.next()) + { + ret = query.value(0).toString(); + break; + } + } + if(ret.isEmpty()) + { + return QString(); + } + listColName.clear(); + listColName.append("CHAN_TAG"); + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_value = ret; + if(m_pReadDb->select("fes_rtu_para", listColName, objCondition, query)) + { + while(query.next()) + { + ret = query.value(0).toString(); + } + } + return ret; +} + +bool CDbInterface::readPointValue(SRealData &sRealData) +{ + double value = qSqrt(-1); + m_rtdbNetAcs->connect(sRealData.nDomainId, sRealData.nAppId); + std::string sTable = sRealData.table_name.toStdString(); + std::string sKey = sRealData.tag_name.toStdString(); + std::string sColumn= sRealData.column.toStdString(); + iot_idl::RdbRet objRet; + + if(m_rtdbNetAcs->queryByKey(sTable, sKey, sColumn, objRet)) + { + int recordNum = objRet.msgrecord_size(); + for (int i = 0; i < recordNum; ++i) + { + if(sTable == "analog" || sTable == "accuml") + { + value = objRet.msgrecord(i).msgvaluearray(0).dvalue(); + } + else if(sTable == "digital" || sTable == "mix") + { + value = objRet.msgrecord(i).msgvaluearray(0).nvalue(); + } + else if(sTable == "fes_channel_para") + { + value = objRet.msgrecord(i).msgvaluearray(0).nvalue(); + } + } + if(!std::isnan(value)) + { + sRealData.isInit = true; + sRealData.value = value; + } + } + else + { + LOGERROR("readPointValue fail: %s, table: %s, key: %s", + m_rtdbNetAcs->getErr().c_str(), + sTable.c_str(), sKey.c_str()); + return false; + } + return true; +} + +QString CDbInterface::getUnitName(int unitId) +{ + QMap::const_iterator iter = m_mapUnit.find(unitId); + if(iter != m_mapUnit.constEnd()) + { + return iter.value(); + } + return QString(); +} + +QString CDbInterface::getStateTextNameByValue(const QString &textName, int value) +{ + QString ret = QString::number(value); + if(m_rtdbAccess->open("base", "dict_state_text_info")) + { + CONDINFO condition1; + memcpy(condition1.name, "state_text_name", strlen("state_text_name")); + condition1.logicalop = ATTRCOND_AND; + condition1.relationop = ATTRCOND_EQU; + condition1.conditionval = textName.toStdString().c_str(); + + CONDINFO condition2; + memcpy(condition2.name, "actual_value", strlen("actual_value")); + condition2.logicalop = ATTRCOND_AND; + condition2.relationop = ATTRCOND_EQU; + condition2.conditionval = value; + + std::vector vecCondInfo; + vecCondInfo.push_back(condition1); + vecCondInfo.push_back(condition2); + + CRdbQueryResult result; + std::vector columns; + columns.push_back("display_value"); + if(m_rtdbAccess->select(vecCondInfo, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType value; + result.getColumnValue(nIndex, 0, value); + ret = QString::fromStdString(value.toStdString()); + } + } + m_rtdbAccess->close(); + } + return ret; +} + +QString CDbInterface::getRtuTagByPointTag(const QString &tagName,const QString &table) +{ + if(!m_pReadDb->isOpen()) + { + return QString(); + } + + QString ret; + QSqlQuery query; + QList listColName; + listColName.append("RTU_TAG"); + CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = tagName; + if(m_pReadDb->select(table, listColName, objCondition, query)) + { + while(query.next()) + { + QString rtuTag = query.value(0).toString(); + ret = rtuTag; + } + } + return ret; +} + +QString CDbInterface::getChannelTagByRtuTag(const QString &tagName) +{ + if(!m_pReadDb->isOpen()) + { + return QString(); + } + + QString ret; + QSqlQuery query; + QList listColName; + QString tableName = "fes_rtu_para"; + listColName.append("CHAN_TAG"); + CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = tagName; + if(m_pReadDb->select(tableName, listColName, objCondition, query)) + { + while(query.next()) + { + QString channelTag = query.value(0).toString(); + ret = channelTag; + } + } + return ret; +} + +QString CDbInterface::getChannelInfoByChannelTag(const QString &tagName) +{ + if(!m_pReadDb->isOpen()) + { + return QString(); + } + + QString ret; + QSqlQuery query; + QList listColName; + QString tableName = "fes_channel_para"; + listColName.append("NET_DESC1"); + listColName.append("NET_DESC2"); + listColName.append("NET_DESC3"); + listColName.append("NET_DESC4"); + CDbCondition objCondition; + objCondition.m_sColName = "TAG_NAME"; + objCondition.m_eCompare = CDbCondition::COMPARE_EQ; + objCondition.m_eLogic = CDbCondition::LOGIC_AND; + objCondition.m_value = tagName; + if(m_pReadDb->select(tableName, listColName, objCondition, query)) + { + while(query.next()) + { + QString net_desc1 = query.value(0).toString(); + QString net_desc2 = query.value(1).toString(); + QString net_desc3 = query.value(2).toString(); + QString net_desc4 = query.value(3).toString(); + QString net_desc = net_desc1; + if(!net_desc2.isEmpty()) + { + net_desc += "/"; + net_desc += net_desc2; + } + if(!net_desc3.isEmpty()) + { + net_desc += "/"; + net_desc += net_desc3; + } + if(!net_desc4.isEmpty()) + { + net_desc += "/"; + net_desc += net_desc4; + } + ret=net_desc; + } + } + return ret; +} + +QString CDbInterface::getChannelInfoByPointTag(const QString &tagName,const QString &table) +{ + QString rtuTag=getRtuTagByPointTag(tagName,table); + if(rtuTag.isEmpty()) + { + return ""; + } + QString channelTag=getChannelTagByRtuTag(rtuTag); + if(channelTag.isEmpty()) + { + return ""; + } + QString channelInfo=getChannelInfoByChannelTag(channelTag); + + return channelInfo; +} + +void CDbInterface::readUnitInfo() +{ + if(!m_pReadDb->isOpen()) + { + return; + } + QSqlQuery query; + QString tableName = "dict_unit_info"; + QList listColName; + listColName.append("UNIT_ID"); + listColName.append("UNIT_NAME"); + + if(m_pReadDb->select(tableName, listColName, query)) + { + while(query.next()) + { + int id = query.value(0).toInt(); + QString name = query.value(1).toString(); + + m_mapUnit.insert(id, name); + } + } +} diff --git a/product/src/gui/plugin/ChanRealStatusWidget/CDbInterface.h b/product/src/gui/plugin/ChanRealStatusWidget/CDbInterface.h new file mode 100644 index 00000000..156829b8 --- /dev/null +++ b/product/src/gui/plugin/ChanRealStatusWidget/CDbInterface.h @@ -0,0 +1,44 @@ +#ifndef CDBINTERFACE_H +#define CDBINTERFACE_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/rdb_net_api/CRdbNetApi.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "CPointPublic.h" + +class CDbInterface +{ +public: + static CDbInterface * instance(); + void destory(); + + int readDomainId(const QString &location); + int readAppId(const QString &appName); + bool readDevice(const QString &devGroup, QStringList &device); + QString readDevGroup(const QString &devGroup); + QString readPointInfo(const QString &tagName, const QString &table); + QString readChannelTag(const QString &device, const QString &table); + bool readPointValue(SRealData &sRealData); + QString getUnitName(int unitId); + QString getStateTextNameByValue(const QString &textName, int value); + QString getRtuTagByPointTag(const QString &tagName,const QString &table); + QString getChannelTagByRtuTag(const QString &tagName); + QString getChannelInfoByChannelTag(const QString &tagName); + QString getChannelInfoByPointTag(const QString &tagName,const QString &table); + +private: + CDbInterface(); + void readUnitInfo(); + +private: + static CDbInterface * m_pInstance; + iot_dbms::CDbApi * m_pReadDb; + iot_dbms::CRdbAccess * m_rtdbAccess; + iot_dbms::CRdbNetApi * m_rtdbNetAcs; + QMap m_mapDevGroup; + QMap m_mapDevice; + QMap m_mapUnit; +}; + +#endif // CDBINTERFACE_H diff --git a/product/src/gui/plugin/ChanRealStatusWidget/CPointPublic.h b/product/src/gui/plugin/ChanRealStatusWidget/CPointPublic.h new file mode 100644 index 00000000..d47c21ed --- /dev/null +++ b/product/src/gui/plugin/ChanRealStatusWidget/CPointPublic.h @@ -0,0 +1,48 @@ +#ifndef CPOINTPUBLIC_H +#define CPOINTPUBLIC_H + +#include +#include + +enum EN_AppContext +{ + RT_MODE = 1, + PDR_MODE +}; + +enum EN_NodeType +{ + TYPE_POINT = 0, + TYPE_DEVGROUP, + TYPE_CHANNEL +}; + +struct SRealData +{ + QString tag_name; + QString description; + QString table_name; + double value; + uint status; + QString unit; + QString stateTextName; + int nDomainId; + int nAppId; + bool isInit; + char type; + QString column; + SRealData() + { + value = 0; + status = 0; + nDomainId = -1; + nAppId = -1; + isInit = false; + type = TYPE_POINT; + column = "value"; + } +}; + +typedef QSharedPointer SRealDataPtr; + +#endif // CPOINTPUBLIC_H diff --git a/product/src/gui/plugin/ChanRealStatusWidget/CRealDataCollect.cpp b/product/src/gui/plugin/ChanRealStatusWidget/CRealDataCollect.cpp new file mode 100644 index 00000000..50dcac88 --- /dev/null +++ b/product/src/gui/plugin/ChanRealStatusWidget/CRealDataCollect.cpp @@ -0,0 +1,216 @@ +#include "CRealDataCollect.h" +#include + +CRealDataCollect* CRealDataCollect::m_pInstance = NULL; + +CRealDataCollect::CRealDataCollect(EN_AppContext appContext) + : m_pMbComm(NULL), + m_pTimer(NULL), + m_nTimeCount(0), + m_objAppContext(appContext) +{ + initMsg(); + if(!addSub()) + { + return; + } + + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); + m_pTimer->start(100); +} + +CRealDataCollect *CRealDataCollect::instance() +{ + if(m_pInstance == NULL) + { + m_pInstance = new CRealDataCollect(RT_MODE); + } + return m_pInstance; +} + +void CRealDataCollect::setAppContext(EN_AppContext appContext) +{ + if(m_objAppContext == appContext) + { + return; + } + + delSub(); + clearMsg(); + m_diMap.clear(); + + m_objAppContext = appContext; + addSub(); +} + +void CRealDataCollect::release() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + delSub(); + closeMsg(); + m_pInstance = NULL; + delete this; +} + +void CRealDataCollect::initMsg() +{ + if(m_pMbComm == NULL) + { + m_pMbComm = new iot_net::CMbCommunicator("ChanRealStatusWidget"); + } +} + +void CRealDataCollect::closeMsg() +{ + if(m_pMbComm != NULL) + { + delete m_pMbComm; + } + m_pMbComm = NULL; +} + +void CRealDataCollect::clearMsg() +{ + if(m_pMbComm) + { + iot_net::CMbMessage objMsg; + while(m_pMbComm->recvMsg(objMsg, 0)) + {} + } +} + +bool CRealDataCollect::addSub() +{ + if(m_pMbComm) + { + if(m_objAppContext == RT_MODE) + { + return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else if(m_objAppContext == PDR_MODE) + { + return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE + CH_FAULT_RECALL_OFFSET); + } + else + { + return false; + } + } + else + { + return false; + } +} + +bool CRealDataCollect::delSub() +{ + if(m_pMbComm) + { + if(m_objAppContext == RT_MODE) + { + return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else if(m_objAppContext == PDR_MODE) + { + return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE + CH_FAULT_RECALL_OFFSET); + } + else + { + return false; + } + } + else + { + return false; + } +} + +void CRealDataCollect::recvMessage() +{ + m_nTimeCount = (m_nTimeCount + 1) % 36000; + + if(m_nTimeCount % 10 == 0) + { + processChangeData(); + } + + try + { + iot_net::CMbMessage objMsg; + for(int i = 0; i < 6; i++) + { + if(m_pMbComm->recvMsg(objMsg, 0)) + { + if(objMsg.isValid()) + { + if(objMsg.getMsgType() != iot_idl::MT_DP_CHANGE_DATA) + { + continue; + } + if((objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) + && (objMsg.getChannelID() != (CH_SCADA_TO_HMI_DATA_CHANGE + CH_FAULT_RECALL_OFFSET))) + { + continue; + } + parserMsg(objMsg); + } + } + } + } + catch(...) + { + + } +} + +void CRealDataCollect::processChangeData() +{ + + if(!m_diMap.isEmpty()) + { + emit signal_updateDi(m_diMap); + m_diMap.clear(); + } + +} + +int CRealDataCollect::parserMsg(const iot_net::CMbMessage &msg) +{ + Q_UNUSED(msg); + + iot_idl::SRealTimeDataPkg changeDataPackage; + try + { + int diSize = changeDataPackage.stdirtd_size(); + if(diSize > 0) + { + iot_idl::SDiRealTimeData diStu; + QString tagName; + int value; + uint status; + for(int i = 0; i < diSize; ++i) + { + diStu = changeDataPackage.stdirtd(i); + tagName = QString::fromStdString(diStu.strtagname()); + value = diStu.nvalue(); + status = diStu.ustatus(); +// emit signal_updateDi(tagName, value, status); + m_diMap[tagName] = qMakePair(value, status); + } + } + + + } + catch(...) + { + return 0; + } + return 1; +} diff --git a/product/src/gui/plugin/ChanRealStatusWidget/CRealDataCollect.h b/product/src/gui/plugin/ChanRealStatusWidget/CRealDataCollect.h new file mode 100644 index 00000000..28a3bd7a --- /dev/null +++ b/product/src/gui/plugin/ChanRealStatusWidget/CRealDataCollect.h @@ -0,0 +1,50 @@ +#ifndef CREALDATACOLLECT_H +#define CREALDATACOLLECT_H + +#include +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" +#include "CPointPublic.h" + +class QTimer; +class CRealDataCollect : public QObject +{ + Q_OBJECT +public: + static CRealDataCollect * instance(); + + void setAppContext(EN_AppContext appContext = RT_MODE); + + void release(); + +private: + CRealDataCollect(EN_AppContext appContext = RT_MODE); + + void initMsg(); + void closeMsg(); + void clearMsg(); + bool addSub(); + bool delSub(); + + int parserMsg(const iot_net::CMbMessage &); + +private slots: + void recvMessage(); + void processChangeData(); + +signals: + void signal_updateDi(QMap> diMap); + +private: + iot_net::CMbCommunicator *m_pMbComm; + QTimer * m_pTimer; + int m_nTimeCount; + EN_AppContext m_objAppContext; + QMap> m_diMap; + + static CRealDataCollect * m_pInstance; +}; + +#endif // CREALDATACOLLECT_H diff --git a/product/src/gui/plugin/ChanRealStatusWidget/CRealTableModel.cpp b/product/src/gui/plugin/ChanRealStatusWidget/CRealTableModel.cpp new file mode 100644 index 00000000..063daadf --- /dev/null +++ b/product/src/gui/plugin/ChanRealStatusWidget/CRealTableModel.cpp @@ -0,0 +1,130 @@ +#include "CRealTableModel.h" +#include "CDbInterface.h" + +CRealTableModel::CRealTableModel(QObject *parent, const QStringList &header) + : QAbstractTableModel(parent), + m_header(header), + nColumnCount(3) +{ + m_valueFont.setBold(true); +} + +void CRealTableModel::updateChannelText(const QStringList &textList) +{ + m_channelTxList = textList; +} + +void CRealTableModel::setColumnCount(int count) +{ + nColumnCount = count; +} + +void CRealTableModel::updateRealData(const QList &dataList) +{ + beginResetModel(); + m_listRealData = dataList; + endResetModel(); +} + +void CRealTableModel::updateRealValue(QList &dataList) +{ + m_listRealData.swap(dataList); + update(); +} + +void CRealTableModel::update() +{ + QModelIndex topLeft = createIndex(0, 1); + QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount() - 2); + emit dataChanged(topLeft, bottomRight); +} + +QVariant CRealTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(role == Qt::DisplayRole) + { + if(orientation == Qt::Horizontal) + { + return m_header.value(section, ""); + } + } + return QVariant(); +} + +void CRealTableModel::setHeaderLabels(const QStringList& headers) +{ + m_header = headers; +} + +int CRealTableModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return m_listRealData.size(); +} + +int CRealTableModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return nColumnCount; +} + +QVariant CRealTableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if(role == Qt::TextAlignmentRole) + { + if(index.column() == 0) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + } + else + { + return Qt::AlignCenter; + } + } + else if(role == Qt::ToolTipRole && index.column() == 0) + { + return m_listRealData.at(index.row()).description; + } + else if(role == Qt::FontRole && index.column() == 1) + { + return QVariant(m_valueFont); + } + + if(role != Qt::DisplayRole) + { + return QVariant(); + } + + switch (index.column()) { + case 0: + { + if(m_listRealData.at(index.row()).type == TYPE_DEVGROUP) + { + return m_listRealData.at(index.row()).description; + } + return " "+m_listRealData.at(index.row()).description; + break; + } + case 1: + { + return CDbInterface::instance()->getStateTextNameByValue(m_listRealData.at(index.row()).stateTextName, m_listRealData.at(index.row()).value); + break; + } + case 2: + { + return CDbInterface::instance()->getChannelInfoByPointTag(m_listRealData.at(index.row()).tag_name,m_listRealData.at(index.row()).table_name); + break; + } + default: + break; + } + + return QVariant(); +} diff --git a/product/src/gui/plugin/ChanRealStatusWidget/CRealTableModel.h b/product/src/gui/plugin/ChanRealStatusWidget/CRealTableModel.h new file mode 100644 index 00000000..99322a45 --- /dev/null +++ b/product/src/gui/plugin/ChanRealStatusWidget/CRealTableModel.h @@ -0,0 +1,42 @@ +#ifndef CREALTABLEMODEL_H +#define CREALTABLEMODEL_H + +#include +#include +#include "CPointPublic.h" + +class CRealTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CRealTableModel(QObject *parent = nullptr, const QStringList &header = QStringList()); + + void updateChannelText(const QStringList &textList); + + void setColumnCount(int count); + + void updateRealData(const QList &dataList); + + void updateRealValue(QList &dataList); + + void update(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + void setHeaderLabels(const QStringList& headers); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: + QStringList m_header; + int nColumnCount; + QList m_listRealData; + QStringList m_channelTxList; + QFont m_valueFont; +}; + +#endif // CREALTABLEMODEL_H diff --git a/product/src/gui/plugin/ChanRealStatusWidget/ChanRealStatusWidget.pro b/product/src/gui/plugin/ChanRealStatusWidget/ChanRealStatusWidget.pro new file mode 100644 index 00000000..476d26c1 --- /dev/null +++ b/product/src/gui/plugin/ChanRealStatusWidget/ChanRealStatusWidget.pro @@ -0,0 +1,62 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2024-05-20T18:52:07 +# +#------------------------------------------------- + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ChanRealStatusWidget +TEMPLATE = lib + + + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + CDbInterface.cpp \ + CChanRealStatusWidget.cpp \ + CChanRealStatusPluginWidget.cpp \ + CRealDataCollect.cpp \ + CRealTableModel.cpp + +HEADERS += \ + CDbInterface.h \ + CChanRealStatusWidget.h \ + CChanRealStatusPluginWidget.h \ + CPointPublic.h \ + CRealDataCollect.h \ + CRealTableModel.h + + +LIBS += \ + -ldb_base_api \ + -ldb_api_ex \ + -lrdb_api \ + -lrdb_net_api \ + -llog4cplus \ + -lpub_logger_api \ + -lprotobuf \ + -lnet_msg_bus_api \ + -ldp_chg_data_api \ + -lpub_utility_api + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/ChanStatusWidget/CRealDataCollect.cpp b/product/src/gui/plugin/ChanStatusWidget/CRealDataCollect.cpp index 80676375..072870a5 100644 --- a/product/src/gui/plugin/ChanStatusWidget/CRealDataCollect.cpp +++ b/product/src/gui/plugin/ChanStatusWidget/CRealDataCollect.cpp @@ -48,7 +48,7 @@ void CRealDataCollect::initMsg() { if(m_pMbComm == NULL) { - m_pMbComm = new iot_net::CMbCommunicator("ChanStatusWidget"); + m_pMbComm = new iot_net::CMbCommunicator(); } } diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanPluginWidget.h b/product/src/gui/plugin/ChanStatusWidget/ChanPluginWidget.h index 11bc70f5..25136129 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanPluginWidget.h +++ b/product/src/gui/plugin/ChanStatusWidget/ChanPluginWidget.h @@ -7,7 +7,7 @@ class ChanPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.cpp b/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.cpp index e0b24fa7..7a1a5fcf 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.cpp +++ b/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.cpp @@ -9,9 +9,6 @@ #include #include #include -#include -#include "model_excel/xlsx/xlsxdocument.h" -#include ChanStatusWidget::ChanStatusWidget(QWidget *parent, bool editMode) : QWidget(parent), @@ -112,25 +109,15 @@ void ChanStatusWidget::initView() m_pTreeWidget = new QTreeWidget; m_pTreeWidget->setColumnCount(1); m_pTreeWidget->setHeaderLabel(tr("位置")); - - - QSplitter * splitter = new QSplitter(Qt::Horizontal); - splitter->addWidget(m_pTreeWidget); - - QWidget *rightwidget = new QWidget(splitter); - m_btnExport = new QPushButton(tr("导出"), rightwidget); - m_pTableView = new QTableView(rightwidget); + m_pTableView = new QTableView; m_pTableView->setSelectionBehavior(QAbstractItemView::SelectRows); m_pTableView->setSelectionMode(QAbstractItemView::NoSelection); m_pTableView->horizontalHeader()->setStretchLastSection(true); m_pChanModel = new ChanTableModel; m_pTableView->setModel(m_pChanModel); - - QVBoxLayout *rightLayout = new QVBoxLayout(rightwidget); - rightLayout->addWidget(m_pTableView); - rightLayout->addWidget(m_btnExport); - - splitter->addWidget(rightwidget); + QSplitter * splitter = new QSplitter(Qt::Horizontal); + splitter->addWidget(m_pTreeWidget); + splitter->addWidget(m_pTableView); splitter->setStretchFactor(0, 1); splitter->setStretchFactor(1, 3); QHBoxLayout * layout = new QHBoxLayout; @@ -300,8 +287,6 @@ void ChanStatusWidget::initConnect() connect(m_pTreeWidget, &QTreeWidget::itemClicked, this, &ChanStatusWidget::slotItemClicked); connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateUi, this, &ChanStatusWidget::slotUpdateUi); - connect(m_btnExport, &QPushButton::clicked, this, &ChanStatusWidget::soltExportExcel); - if(m_pTreeWidget->topLevelItem(0)) { m_pTreeWidget->setCurrentItem(m_pTreeWidget->topLevelItem(0)); @@ -366,37 +351,3 @@ void ChanStatusWidget::slotItemClicked(QTreeWidgetItem *item, int column) dataList = iter.value(); m_pChanModel->updateRealData(dataList); } - -void ChanStatusWidget::soltExportExcel() -{ - QString sExcelFileName = QFileDialog::getSaveFileName(this, tr("保存"), QString(""), "*.xlsx"); - if(sExcelFileName.isEmpty()) - return; - - QXlsx::Document xlsx; - - int rowcount=m_pChanModel->rowCount(); - int colcount=m_pChanModel->columnCount(); - for(int i=0;iheaderData(i, Qt::Horizontal).toString()); - } - // 写内容 - for ( int i=0; idata(m_pChanModel->index(i, j)).toString(); - xlsx.write( i+2, j+1, sText ); - } - } - // 保存到文件 - if(xlsx.saveAs(sExcelFileName)) - { - QMessageBox::information(this,tr("提示"),tr("导出成功!")); - } - else - { - QMessageBox::information(this,tr("提示"),tr("保存失败")); - } -} diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.h b/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.h index ab503ba2..eec8c3a6 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.h +++ b/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.h @@ -6,14 +6,11 @@ #include #include #include -#include class QTreeWidget; class QTableView; class ChanTableModel; class QTreeWidgetItem; - - class ChanStatusWidget : public QWidget { Q_OBJECT @@ -36,11 +33,10 @@ private: private slots: void slotUpdateUi(QMap uiMap); void slotItemClicked(QTreeWidgetItem *item, int column); - void soltExportExcel(); + private: QTreeWidget * m_pTreeWidget; QTableView * m_pTableView; - QPushButton * m_btnExport; ChanTableModel * m_pChanModel; iot_service::CDpcdaForApp *m_pDpcdaForApp; QMap > m_locMap; //< ID, diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.pro b/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.pro index 21c030ed..840c322b 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.pro +++ b/product/src/gui/plugin/ChanStatusWidget/ChanStatusWidget.pro @@ -44,8 +44,7 @@ LIBS += \ -lprotobuf \ -lnet_msg_bus_api \ -ldp_chg_data_api \ - -lpub_utility_api \ - -lmodel_excel + -lpub_utility_api include($$PWD/../../../idl_files/idl_files.pri) diff --git a/product/src/gui/plugin/ChanStatusWidget/ChanTableModel.h b/product/src/gui/plugin/ChanStatusWidget/ChanTableModel.h index cafc6fce..bf4845a2 100644 --- a/product/src/gui/plugin/ChanStatusWidget/ChanTableModel.h +++ b/product/src/gui/plugin/ChanStatusWidget/ChanTableModel.h @@ -13,14 +13,18 @@ public: void updateRealData(const QList &dataList); void updateRealValue(QList &dataList); - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; + private: void update(); + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + private: QString getChanStatusDesc(const int &status) const; diff --git a/product/src/gui/plugin/ConstCurves/CConstPluginWidget.h b/product/src/gui/plugin/ConstCurves/CConstPluginWidget.h index 50040944..5cd75708 100644 --- a/product/src/gui/plugin/ConstCurves/CConstPluginWidget.h +++ b/product/src/gui/plugin/ConstCurves/CConstPluginWidget.h @@ -7,7 +7,7 @@ class CConstPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/ConstCurves/CMessageManage.cpp b/product/src/gui/plugin/ConstCurves/CMessageManage.cpp index 2d75e513..b0625a72 100644 --- a/product/src/gui/plugin/ConstCurves/CMessageManage.cpp +++ b/product/src/gui/plugin/ConstCurves/CMessageManage.cpp @@ -34,14 +34,13 @@ bool CMessageManage::sendMessage(const SReadQueue& queueList, int nDstDomainId) iot_net::CMbMessage msg; msg.setMsgType(MT_OPT_COMMON_DOWN); msg.setSubject(E_PSCADA_APPID, CH_HMI_TO_OPT_OPTCMD_DOWN); - COptCustCtrlRequest cOptCustCtrlRequest; SOptCustCtrlRequest sOptCustCtrlRequest; sOptCustCtrlRequest.stHead = createReqHead(nDstDomainId); sOptCustCtrlRequest.strKeyIdTag = QString("fes_const.%1.value").arg(queueList.tag_name).toStdString(); sOptCustCtrlRequest.strRtuTag = queueList.rtu_tag.toStdString(); sOptCustCtrlRequest.vecOptCustCtrlQueue = createCtrlQueue(queueList.dev_id); - std::string content = cOptCustCtrlRequest.generate(sOptCustCtrlRequest); + std::string content = COptCustCtrlRequest::generate(sOptCustCtrlRequest); msg.setData(content); if(!m_communicator->sendMsgToDomain(msg, nDstDomainId)) @@ -71,10 +70,9 @@ void CMessageManage::recvMessage() return; } - COptCustCtrlReply cOptCustCtrlReply; SOptCustCtrlReply sOptCustCtrlReply; std::string str((const char*)msg.getDataPtr(), msg.getDataSize()); - cOptCustCtrlReply.parse(str, sOptCustCtrlReply); + COptCustCtrlReply::parse(str, sOptCustCtrlReply); parseMsg(sOptCustCtrlReply); } diff --git a/product/src/gui/plugin/DataOptWidget/CDataOptPluginWidget.h b/product/src/gui/plugin/DataOptWidget/CDataOptPluginWidget.h index ff07c06a..b9f7c899 100644 --- a/product/src/gui/plugin/DataOptWidget/CDataOptPluginWidget.h +++ b/product/src/gui/plugin/DataOptWidget/CDataOptPluginWidget.h @@ -7,7 +7,7 @@ class CDataOptPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: CDataOptPluginWidget(QObject *parent = 0); diff --git a/product/src/gui/plugin/DataOptWidget/CDataOptWidget.cpp b/product/src/gui/plugin/DataOptWidget/CDataOptWidget.cpp index 609afe8c..a41ecd4e 100644 --- a/product/src/gui/plugin/DataOptWidget/CDataOptWidget.cpp +++ b/product/src/gui/plugin/DataOptWidget/CDataOptWidget.cpp @@ -575,7 +575,7 @@ void CDataOptWidget::setDefaultWidth() void CDataOptWidget::cancelSetValue() { - QString mess = QString(tr("当前未选中任何项!")); + QString mess = QString(tr("请至少选择一项人工置数信息!")); QList list = ui->treeWidget->selectedItems(); if (list.size() <= 0) { @@ -698,7 +698,6 @@ void CDataOptWidget::removeOptTagInfo(const STOptTagInfo &info) msg.setSubject(info.subSystem, CH_HMI_TO_OPT_OPTCMD_DOWN); SOptTagSet sOptTagSet; SOptTagQueue optTagQueue; - COptTagSet cOptTagSet; if(createReqHead(sOptTagSet.stHead)!= iotSuccess) { @@ -713,7 +712,7 @@ void CDataOptWidget::removeOptTagInfo(const STOptTagInfo &info) optTagQueue.nSubSystem = info.subSystem; sOptTagSet.vecTagQueue.push_back(optTagQueue); - std::string content = cOptTagSet.generate(sOptTagSet); + std::string content = COptTagSet::generate(sOptTagSet); int type = info.tagType; if(type == 1) { diff --git a/product/src/gui/plugin/DataOptWidget/main.cpp b/product/src/gui/plugin/DataOptWidget/main.cpp index 533c51ca..84dff7d5 100644 --- a/product/src/gui/plugin/DataOptWidget/main.cpp +++ b/product/src/gui/plugin/DataOptWidget/main.cpp @@ -19,7 +19,7 @@ int main(int argc, char *argv[]) return -1; } - if(perm->SysLogin("Test", "kbdct", 1, 12*60*60, "hmi") != 0) + if(perm->SysLogin("admin", "admin", 1, 12*60*60, "hmi") != 0) { return -1; } diff --git a/product/src/gui/plugin/DevHisDataWidget/CDevHisDataPluginWidget.h b/product/src/gui/plugin/DevHisDataWidget/CDevHisDataPluginWidget.h index 679cd737..367703af 100644 --- a/product/src/gui/plugin/DevHisDataWidget/CDevHisDataPluginWidget.h +++ b/product/src/gui/plugin/DevHisDataWidget/CDevHisDataPluginWidget.h @@ -7,7 +7,7 @@ class CDevHisDataPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/DevRealDataWidget/CDbInterface.cpp b/product/src/gui/plugin/DevRealDataWidget/CDbInterface.cpp index 7905abd4..66cf90c9 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CDbInterface.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/CDbInterface.cpp @@ -424,7 +424,7 @@ bool CDbInterface::isSetValueEnable(int status, int table) bool CDbInterface::isBitEnable(int status, int checkNum) { - return (status >> (checkNum)) & 0x01 == 0x01; + return ((status >> (checkNum)) & 0x01) == 0x01; } QString CDbInterface::getDiStatusStr(int status) diff --git a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataPluginWidget.h b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataPluginWidget.h index 92240733..d41c413c 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataPluginWidget.h +++ b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataPluginWidget.h @@ -7,7 +7,7 @@ class CDevRealDataPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.cpp b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.cpp index 33a438e4..7f358afb 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.cpp @@ -129,10 +129,16 @@ void CDevRealDataWidget::setTableColumnWidth(int column, int width) ui->m_tableView->setColumnWidth(column, width); } +void CDevRealDataWidget::setTableColumnName(int column, const QString &name) +{ + CRealTableModel* model = (CRealTableModel*)ui->m_tableView->model(); + model->setTableColumnName(column,name); +} + void CDevRealDataWidget::resetDeviceGroup(const QStringList &tagList) { - ui->widget->setHidden(true); - ui->frame_5->setVisible(true); + // ui->widget->setHidden(true); + // ui->frame_5->setVisible(true); ui->m_devGroupComb->blockSignals(true); ui->m_devGroupComb->clear(); @@ -141,12 +147,17 @@ void CDevRealDataWidget::resetDeviceGroup(const QStringList &tagList) { return; } + + //非其他设备组 + QMap::const_iterator iter = devGroup.constBegin(); for(; iter != devGroup.constEnd(); ++iter) { ui->m_devGroupComb->addItem(iter.value(), iter.key()); } + updateTreeWidgetFromGroup(tagList); + ui->m_devGroupComb->blockSignals(false); emit ui->m_devGroupComb->currentIndexChanged(0); } @@ -237,9 +248,16 @@ void CDevRealDataWidget::initialize() m_pCollectThread->start(); //< 初始化表格模型 - m_realModel = new CRealTableModel(this); + m_realModel = new CRealTableModel(ui->m_tableView); + ui->m_tableView->setModel(m_realModel); + ui->m_tableView->horizontalHeader()->setDefaultSectionSize(350); ui->m_tableView->horizontalHeader()->setStretchLastSection(true); + ui->m_tableView->setAlternatingRowColors(true); + ui->m_tableView->setHorizontalHeader(new CustomHeaderView(Qt::Horizontal,ui->m_tableView)); + ui->m_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + connect(ui->m_tableView->horizontalHeader(),&QHeaderView::sectionCountChanged,ui->m_tableView,&CTableView::adjustHeaderWidth); + connect(ui->m_tableView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, @@ -251,8 +269,7 @@ void CDevRealDataWidget::initialize() SLOT(slotDataChanged(const QModelIndex &, const QModelIndex &))); ui->treeWidget->setColumnCount(1); - setTableColumnWidth(0,300); - setTableColumnWidth(2,300); + connect(ui->m_subCb, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTreeWidget())); connect(ui->m_locCb, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTreeWidget())); connect(ui->m_devGroupComb, SIGNAL(currentIndexChanged(int)), this, SLOT(slotDeviceUpdate())); @@ -299,6 +316,8 @@ void CDevRealDataWidget::updateTreeWidget() slotShowMess(tr("查询设备组信息失败!")); return; } + + for(int nIndex(0);nIndex devInfo = CDbInterface::instance()->deviceInfo(devgList.at(nIndex).first); QMap::iterator pos = devInfo.begin(); - while (pos != devInfo.end()) { + while (pos != devInfo.end()) + { QTreeWidgetItem *devItem = new QTreeWidgetItem(); devItem->setText(0,pos.value()); devItem->setData(0,Qt::UserRole,(int)EN_TREE_DEV);//类型 @@ -317,7 +337,66 @@ void CDevRealDataWidget::updateTreeWidget() devgItem->addChild(devItem); pos++; } + devgItem->sortChildren(0,Qt::SortOrder::AscendingOrder); + } + + if(ui->treeWidget->topLevelItem(0)) + { + emit ui->treeWidget->itemClicked(ui->treeWidget->topLevelItem(0), 0); + } +} + +void CDevRealDataWidget::updateTreeWidgetFromGroup(const QStringList &tagList) +{ + ui->mSearchLineEdit->clear(); + cleanTreeWidget(); + int nLocId = ui->m_locCb->currentData().toInt(); + int nSubId = ui->m_subCb->currentData().toInt(); + QList> devgList; + if(!CDbInterface::instance()->queryDevGroupInfoList(nLocId,nSubId,devgList)) + { + slotShowMess(tr("查询设备组信息失败!")); + return; + } + + QMap devGroup = CDbInterface::instance()->readDevGroupDesc(tagList); + if(devGroup.isEmpty()) + { + return; + } + + for(int nIndex(0);nIndex::const_iterator iterGroup = devGroup.constBegin(); + for(; iterGroup != devGroup.constEnd(); ++iterGroup) + { + // ui->m_devGroupComb->addItem(iterGroup.value(), iterGroup.key()); + + if(devgList.at(nIndex).first ==iterGroup.key()) + { + QTreeWidgetItem *devgItem = new QTreeWidgetItem(); + devgItem->setText(0,devgList.at(nIndex).second); + devgItem->setData(0,Qt::UserRole,(int)EN_TREE_DEVG);//类型 + devgItem->setData(0,Qt::UserRole+1,devgList.at(nIndex).first);//值 + ui->treeWidget->addTopLevelItem(devgItem); + + QMap devInfo = CDbInterface::instance()->deviceInfo(devgList.at(nIndex).first); + QMap::iterator pos = devInfo.begin(); + while (pos != devInfo.end()) + { + QTreeWidgetItem *devItem = new QTreeWidgetItem(); + devItem->setText(0,pos.value()); + devItem->setData(0,Qt::UserRole,(int)EN_TREE_DEV);//类型 + devItem->setData(0,Qt::UserRole+1,pos.key());//值 + devgItem->addChild(devItem); + pos++; + } + } + } + } + if(ui->treeWidget->topLevelItem(0)) { emit ui->treeWidget->itemClicked(ui->treeWidget->topLevelItem(0), 0); @@ -772,6 +851,7 @@ void CDevRealDataWidget::slotUpdateAi(QMap > aiMap) } } QList dataList = m_realData.values(); + LOGINFO("slotUpdateAi dataList:%d",dataList.count()); m_realModel->updateRealValue(dataList); } @@ -845,6 +925,7 @@ void CDevRealDataWidget::slotUpdatePi(QMap > piMap) void CDevRealDataWidget::slotUpdateMi(QMap > miMap) { + QMap >::iterator iter = miMap.begin(); for(; iter != miMap.end(); iter++) { @@ -903,6 +984,9 @@ void CDevRealDataWidget::treeItemClicked(QTreeWidgetItem *item, int column) brush(); return; } + + LOGINFO("点击树节点"); + if(item->data(0,Qt::UserRole).toInt() == EN_TREE_LOC) { return ; @@ -931,7 +1015,7 @@ void CDevRealDataWidget::brush() m_piMap.clear(); m_miMap.clear(); m_pDpcdaForApp->unsubscribeAll(); -// LOGINFO("DEVREAL slotPointTableUpdate --unsubscribeAll()"); + LOGINFO("DEVREAL slotPointTableUpdate --unsubscribeAll()"); QMap> pointMap = CDbInterface::instance()->readPointInfo(m_devList, curPointTable().split(",", QString::SkipEmptyParts)); QMap>::const_iterator fIter = pointMap.constBegin(); @@ -996,6 +1080,8 @@ void CDevRealDataWidget::brush() // LOGINFO("DEVREAL subscribe value,status tag_name: %s", iter.key().toStdString().c_str()); } } + + LOGINFO("m_realData count:%d" +m_realData.count()); m_realModel->updateRealData(m_realData.values()); emit ui->m_filterBtn->click(); } @@ -1080,7 +1166,6 @@ bool CDevRealDataWidget::OptTagInfo(const STOptTagInfo &info) msg.setSubject(info.subSystem, CH_HMI_TO_OPT_OPTCMD_DOWN); SOptTagSet sOptTagSet; SOptTagQueue optTagQueue; - COptTagSet cOptTagSet; if(!createReqHead(sOptTagSet.stHead, info)) { @@ -1096,7 +1181,7 @@ bool CDevRealDataWidget::OptTagInfo(const STOptTagInfo &info) optTagQueue.nSubSystem = info.subSystem; sOptTagSet.vecTagQueue.push_back(optTagQueue); - std::string content = cOptTagSet.generate(sOptTagSet); + std::string content = COptTagSet::generate(sOptTagSet); msg.setMsgType(info.optType); diff --git a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.h b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.h index 399d217a..d2fe3457 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.h +++ b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.h @@ -44,6 +44,7 @@ signals: public slots: void setTableColumnHidden(int column, bool hide); void setTableColumnWidth(int column, int width); + void setTableColumnName(int column,const QString &name); void resetDeviceGroup(const QStringList& tagList); void setShowSubSystem(bool isShow); @@ -89,6 +90,7 @@ private slots: void treeItemClicked(QTreeWidgetItem *item, int column); void updateTreeWidget(); + void updateTreeWidgetFromGroup(const QStringList &tagList); void brush(); void slotEnableRefreshBtnClick();//禁止刷新 diff --git a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.ui b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.ui index 32d57653..2f458604 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.ui +++ b/product/src/gui/plugin/DevRealDataWidget/CDevRealDataWidget.ui @@ -397,7 +397,7 @@ - 关键字查询 + 测点关键字查询 diff --git a/product/src/gui/plugin/DevRealDataWidget/CRealDataCollect.cpp b/product/src/gui/plugin/DevRealDataWidget/CRealDataCollect.cpp index e7b9601e..4f27cab7 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CRealDataCollect.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/CRealDataCollect.cpp @@ -1,5 +1,6 @@ #include "CRealDataCollect.h" #include +#include "pub_logger_api/logger.h" CRealDataCollect::CRealDataCollect(QObject *parent) : QObject(parent), @@ -114,6 +115,7 @@ void CRealDataCollect::processChangeData() { if(!m_aiMap.isEmpty()) { + LOGINFO("emit signal_updateAi dataList:%d",m_aiMap.count()); emit signal_updateAi(m_aiMap); m_aiMap.clear(); } diff --git a/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.cpp b/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.cpp index f560b18b..60f3142b 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.cpp @@ -39,6 +39,14 @@ QVariant CRealTableModel::headerData(int section, Qt::Orientation orientation, i return QVariant(); } +void CRealTableModel::setTableColumnName(int column, const QString &name) +{ + //if(column < m_header.length()) + { + m_header.replace(column,name); + } +} + int CRealTableModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) @@ -178,3 +186,29 @@ QVariant CRealTableModel::data(const QModelIndex &index, int role) const return QVariant(); } + +CustomHeaderView::CustomHeaderView(Qt::Orientation orientation ,QWidget *parent) +:QHeaderView(orientation,parent) +{ +} +CustomHeaderView::~CustomHeaderView() +{ +} + +void CustomHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const +{ + //就简单几句 + //拿到text数据,在写数据的时候,设置textwordwrap,居中。 + QString textstr = model()->headerData(visualIndex(logicalIndex),Qt::Horizontal).toString(); + painter->save(); + // 从当前样式中获取边框颜色 + QStyleOptionHeader opt; + initStyleOption(&opt); + opt.rect = rect; + opt.section = logicalIndex; + + // 使用样式绘制边框 + style()->drawControl(QStyle::CE_HeaderSection, &opt, painter, this); + painter->drawText(rect,Qt::TextWordWrap | Qt::AlignCenter, textstr); + painter->restore(); +} diff --git a/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.h b/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.h index eded73b5..36227d37 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.h +++ b/product/src/gui/plugin/DevRealDataWidget/CRealTableModel.h @@ -2,6 +2,8 @@ #define CREALTABLEMODEL_H #include +#include +#include #include "CDbInterface.h" struct SortKey @@ -77,6 +79,7 @@ public: QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + void setTableColumnName(int column, const QString &name); int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; @@ -87,4 +90,17 @@ private: QList m_listRealData; }; + +class CustomHeaderView : public QHeaderView +{ + Q_OBJECT + +public: + CustomHeaderView(Qt::Orientation orientation = Qt::Horizontal,QWidget *parent = nullptr); //这里为了省事,给默认值为水平表头,因为我正好使用水平的表头 + ~CustomHeaderView(); + +protected: + virtual void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const; +}; + #endif // CREALTABLEMODEL_H diff --git a/product/src/gui/plugin/DevRealDataWidget/CTableView.cpp b/product/src/gui/plugin/DevRealDataWidget/CTableView.cpp index c7c43ee5..35b3121d 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CTableView.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/CTableView.cpp @@ -1,5 +1,6 @@ #include "CTableView.h" #include +#include CTableView::CTableView(QWidget *parent) : QTableView(parent) @@ -30,3 +31,50 @@ void CTableView::setTableRowHeight(const int &nHeight) verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); } + +// 自动调整表头宽度以适应文本 +void CTableView::adjustHeaderWidth() { + QHeaderView *header = horizontalHeader(); + int sections = header->count(); + int maxWidth = 0; + QFontMetrics fm(header->font()); + int maxWidthThreshold = 200; + + + for (int i = 0; i < sections; ++i) { + QString text = model()->headerData(i, Qt::Horizontal).toString(); + int width = fm.width(text) + 10; // 加上一些额外空间 + maxWidth = qMax(maxWidth, width); + } + + int heightBase=30; + int heightCount=1; + for (int i = 0; i < sections; ++i) { + QString text = model()->headerData(i, Qt::Horizontal).toString(); + int width = fm.width(text) + 20; // 加上一些额外空间 + // 如果宽度超过阈值,则换行 + if (width > maxWidthThreshold) { + header->resizeSection(i, maxWidthThreshold); + qreal tmpHeightCount=qreal(width)/qreal(maxWidthThreshold); + if(tmpHeightCount>heightCount){ + heightCount=qCeil(tmpHeightCount); + } + } else { + if(i==0) + { + maxWidth=210; + } + header->resizeSection(i, maxWidth); + heightCount=2; + } + } + header->setFixedHeight(heightCount*heightBase); +} + + + +void CTableView::showEvent(QShowEvent *event){ + QTableView::showEvent(event); + adjustHeaderWidth(); +} + diff --git a/product/src/gui/plugin/DevRealDataWidget/CTableView.h b/product/src/gui/plugin/DevRealDataWidget/CTableView.h index 2758f072..9af04653 100644 --- a/product/src/gui/plugin/DevRealDataWidget/CTableView.h +++ b/product/src/gui/plugin/DevRealDataWidget/CTableView.h @@ -17,6 +17,10 @@ public: int tableRowHeight(); void setTableRowHeight(const int &nHeight); + void adjustHeaderWidth(); + +protected: + void showEvent(QShowEvent *event) override ; private: int m_nTableColWidth; diff --git a/product/src/gui/plugin/DevRealDataWidget/main.cpp b/product/src/gui/plugin/DevRealDataWidget/main.cpp index c458e485..7227eb23 100644 --- a/product/src/gui/plugin/DevRealDataWidget/main.cpp +++ b/product/src/gui/plugin/DevRealDataWidget/main.cpp @@ -17,7 +17,7 @@ int main(int argc, char *argv[]) return -1; } - if(perm->SysLogin("Test", "kbdct", 1, 12*60*60, "hmi") != 0) + if(perm->SysLogin("Test", "Test", 1, 12*60*60, "hmi") != 0) { return -1; } diff --git a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointPluginWidget.h b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointPluginWidget.h index 5f12780b..bd90ee77 100644 --- a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointPluginWidget.h +++ b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointPluginWidget.h @@ -7,7 +7,7 @@ class CDevSpePointPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.cpp b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.cpp index f1348ce0..7ed173fb 100644 --- a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.cpp +++ b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.cpp @@ -42,11 +42,6 @@ void CDevSpePointWidget::setCornerName(const QString &name) m_pTableModel->setHeader(m_columnNameList); } -void CDevSpePointWidget::showNameType(int labelType) -{ - deviceOrGroupShowType = labelType; -} - QString CDevSpePointWidget::addRow(const QString &pointTag) { if(pointTag.isEmpty()) @@ -60,256 +55,60 @@ QString CDevSpePointWidget::addRow(const QString &pointTag) return tr("数据库连接打开失败!"); } - QStringList pointList = pointTag.split(","); QString error = QString(); int i=0; - - if(deviceOrGroupShowType == 0) //行标题默认模式-->0 + foreach (QString point, pointList) { - foreach (QString point, pointList) + //< 检查标签是否合法 + QStringList list = point.split("."); + if(list.length() != 7) { - //< 检查标签是否合法 - QStringList list = point.split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - //< 检查是否重复添加 - QString device =list[3] + "." + list[4];//occ.PDBD22_PDGKC1 - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - //< 添加第一列数据(设备描述) - QString deviceName = queryDeviceDesc(device, objReader); - if(deviceName.isEmpty()) - { - error += tr("查询设备描述失败!\n"); - continue; - } - - //添加排序 - device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } + error += tr("测点标签不合法!\n"); + continue; + } + //< 检查是否重复添加 + QString device =list[3] + "." + list[4];//occ.PDBD22_PDGKC1 + QMap>::iterator iter = m_dataMap.find(device); + if(iter != m_dataMap.end()) + { + error += tr("重复添加!\n"); + continue; + } + //< 添加第一列数据(设备描述) + QString deviceName = queryDeviceDesc(device, objReader); + if(deviceName.isEmpty()) + { + error += tr("查询设备描述失败!\n"); + continue; } - } - else if(deviceOrGroupShowType == 1) //行标题按设备组显示-->1(每行参数取该组全部设备存在的第一个值) - { - foreach (QString point, pointList) + //添加排序 + device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; + ST_RealData devData; + devData.description = deviceName; + devData.isInit = false; + devData.type = TYPE_DESC; + m_dataMap[device].append(devData); + //< 添加点标签列数据 + if(m_columnTagList.isEmpty()) { - //< 检查标签是否合法 - QStringList list = point.split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - - //< 检查是否重复添加 - QString device =list[3] + "." + list[4].split("_")[0]; //S12.6102 - qDebug() << "deviceOrGroupShowType(1) device: " << device; - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - - //< 添加第一列数据(设备描述) - QString deviceName = queryGetGroupDescription(device, objReader); //设备组名,如:6102柜17变1#变压器 - - if(deviceName.isEmpty()) - { - error += tr("查询设备描述失败!\n"); - continue; - } - - //添加排序 - device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; //000.S12.6102 - qDebug() << "deviceOrGroupShowType(1) device(1): " << device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - - qDebug() << "deviceOrGroupShowType(1) m_columnTagList.isEmpty()"; - - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - qDebug() << "realData-->" << realData.tag_name << realData.table_name; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } + continue; } - } - else if(deviceOrGroupShowType == 2) //行标题按设备名显示-->2 - { - foreach (QString point, pointList) + + for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; + ST_RealData realData; + realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; + realData.table_name = pair.second; + realData.isInit = false; + realData.type = TYPE_POINT; + if(realData.table_name == "digital") { - error += tr("测点标签不合法!\n"); - continue; + realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); } - //< 检查是否重复添加 - QString device =list[3] + "." + list[4].split("_")[0]; //kxg.KXG1Meter1 - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - - //< 添加第一列数据(设备描述) - QString valueType = list[5]; - device = queryGetDevInfoTagName(valueType, device, objReader); - - iot_dbms::CDbApi descriptionReader(DB_CONN_MODEL_READ); - if(!descriptionReader.open()) - { - return tr("数据库连接打开失败!"); - } - QString deviceName = queryGetDevInfoDescription(device, descriptionReader); - - - if(deviceName.isEmpty()) - { - error += tr("查询设备描述失败!\n"); - continue; - } - - //添加排序 - device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } - } - } - else if(deviceOrGroupShowType == 3) //行标题按设备组名显示,取该组第一个设备和它的值 - { - foreach (QString point, pointList) - { - QStringList list = point.split("."); - //< 检查标签是否合法 - if(list.length() != 7) - { - error += ("测点标签不合法!\n"); - continue; - } - - //< 检查是否重复添加 - QString device = list[3] + "." + list[4].split("_")[0]; - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - - //< 添加第一列数据(设备描述) - QString deviceName = queryGetGroupDescription(device, objReader); - if(deviceName.isEmpty()) - { - error += tr("查询设备描述失败!\n"); - continue; - } - device = list[3] + "." + list[4]; - device = QString("%1").arg(i++, 3, 10, QChar('0')) + "." + device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - qDebug() << "realData-->" << realData.tag_name << realData.table_name; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } - + m_dataMap[device].append(realData); } } @@ -327,11 +126,10 @@ QString CDevSpePointWidget::addRowName(const QString &pointTag, const QString &D QStringList pointList = pointTag.split(","); QStringList DevNameList = DevName.split(","); - if(pointList.count() != DevNameList.count()) + if(pointList.count() !=DevNameList.count()) { - //转化为字符串 - QString str = QString("%1:%2").arg(pointList.count(), 2, 10, QLatin1Char('0')).arg(DevNameList.count(), 2, 10, QLatin1Char('0')); - return str; + QString str = QString("%1:%2").arg(pointList.count(), 2, 10, QLatin1Char('0')).arg(DevNameList.count(), 2, 10, QLatin1Char('0')); + return str; } iot_dbms::CDbApi objReader(DB_CONN_MODEL_READ); @@ -342,172 +140,54 @@ QString CDevSpePointWidget::addRowName(const QString &pointTag, const QString &D QString error = QString(); int i=0; - - if(deviceOrGroupShowType == 0) //行标题默认模式-->0 + foreach (QString point, pointList) { - foreach (QString point, pointList) + //< 检查标签是否合法 + QStringList list = point.split("."); + if(list.length() != 7) { - //< 检查标签是否合法 - QStringList list = point.split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - //< 检查是否重复添加 - QString device =list[3] + "." + list[4]; //occ.PDBD22_PDGKC1 - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - //< 添加第一列数据(设备描述) - QString deviceName = DevNameList[i];//queryDeviceDesc(device, objReader); - - - //添加排序 - device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } + error += tr("测点标签不合法!\n"); + continue; } - } - else if(deviceOrGroupShowType == 1 || deviceOrGroupShowType == 3) //行标题按设备组显示-->1(每行参数取该组全部设备存在的第一个值) - { - foreach (QString point, pointList) + //< 检查是否重复添加 + QString device =list[3] + "." + list[4];//occ.PDBD22_PDGKC1 + QMap>::iterator iter = m_dataMap.find(device); + if(iter != m_dataMap.end()) { - //< 检查标签是否合法 - QStringList list = point.split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - //< 检查是否重复添加 - QString device =list[3] + "." + list[4].split("_")[0]; //S12.6102 - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - //< 添加第一列数据(设备描述) - QString deviceName = DevNameList[i]; - device = queryGetGroupDescription(device, objReader); - - - //添加排序 - device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } + error += tr("重复添加!\n"); + continue; } - } - else if(deviceOrGroupShowType == 2) //行标题按设备名显示-->2 - { - foreach (QString point, pointList) + //< 添加第一列数据(设备描述) + QString deviceName = DevNameList[i];//queryDeviceDesc(device, objReader); + + + //添加排序 + device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; + ST_RealData devData; + devData.description = deviceName; + devData.isInit = false; + devData.type = TYPE_DESC; + m_dataMap[device].append(devData); + //< 添加点标签列数据 + if(m_columnTagList.isEmpty()) { - //< 检查标签是否合法 - QStringList list = point.split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - //< 检查是否重复添加 - QString device =list[3] + "." + list[4].split("_")[0]; //kxg.KXG1Meter1 - QMap>::iterator iter = m_dataMap.find(device); - if(iter != m_dataMap.end()) - { - error += tr("重复添加!\n"); - continue; - } - - //< 添加第一列数据(设备描述) - QString valueType = list[5]; - device = queryGetDevInfoTagName(valueType, device, objReader); - - iot_dbms::CDbApi descriptionReader(DB_CONN_MODEL_READ); - if(!descriptionReader.open()) - { - return tr("数据库连接打开失败!"); - } - QString deviceName = queryGetDevInfoDescription(device, descriptionReader); - - //添加排序 - device= QString("%1").arg(i++, 3, 10, QChar('0')) +"." +device; - ST_RealData devData; - devData.description = deviceName; - devData.isInit = false; - devData.type = TYPE_DESC; - m_dataMap[device].append(devData); - //< 添加点标签列数据 - if(m_columnTagList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; - ST_RealData realData; - realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; - realData.table_name = pair.second; - realData.isInit = false; - realData.type = TYPE_POINT; - if(realData.table_name == "digital") - { - realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); - } - m_dataMap[device].append(realData); - } + continue; } + for(int nIndex(0); nIndex &pair = m_columnTagList[nIndex]; + ST_RealData realData; + realData.tag_name = device.mid(device.indexOf(".")+1) + "." + pair.first; + realData.table_name = pair.second; + realData.isInit = false; + realData.type = TYPE_POINT; + if(realData.table_name == "digital") + { + realData.stateTextName = queryDigitalStateText(realData.tag_name, objReader); + } + m_dataMap[device].append(realData); + } } m_pTableModel->updateRealData(m_dataMap); @@ -533,152 +213,51 @@ QString CDevSpePointWidget::addColumn(const QString &title, const QString &point return tr("传入参数个数不一致!"); } QString error = QString(); - - - if(deviceOrGroupShowType == 0 || deviceOrGroupShowType == 2) + for(int i(0); i < pointList.length(); i++) { - for(int i(0); i < pointList.length(); i++) + //< 检查标签是否合法 + QStringList list = QString(pointList[i]).split("."); + if(list.length() != 7) { - //< 检查标签是否合法 - QStringList list = QString(pointList[i]).split("."); - if(list.length() != 7) - { - error += tr("测点标签不合法!\n"); - continue; - } - //< 添加列头 - QString table = list[2]; - QString tag = list[5]; - m_columnTagList.append(qMakePair(tag, table)); - m_columnNameList.append(titleList[i]); - m_pTableModel->setHeader(m_columnNameList); - //< 添加点标签列数据 - QStringList devList = m_dataMap.keys(); - if(devList.isEmpty()) - { - continue; - } + error += tr("测点标签不合法!\n"); + continue; + } + //< 添加列头 + QString table = list[2]; + QString tag = list[5]; + m_columnTagList.append(qMakePair(tag, table)); + m_columnNameList.append(titleList[i]); + m_pTableModel->setHeader(m_columnNameList); + //< 添加点标签列数据 + QStringList devList = m_dataMap.keys(); + if(devList.isEmpty()) + { + continue; + } + for(int nIndex(0); nIndex(tag, table)); //VA、analog - m_columnNameList.append(titleList[i]); //列标题栏 - m_pTableModel->setHeader(m_columnNameList); - - - //< 添加点标签列数据 - QStringList devList = m_dataMap.keys(); - //000.S12.6102", "001.S12.6342", "002.S12.6343", "003.S12.6344", "004.S12.6345", "005.S12.6346", "006.S12.6111 - - if(devList.isEmpty()) - { - continue; - } - - int groupNum = 0; - for(int nIndex(0); nIndex(tag, table)); - m_columnNameList.append(titleList[i]); - m_pTableModel->setHeader(m_columnNameList); - //< 添加点标签列数据 - QStringList devList = m_dataMap.keys(); - if(devList.isEmpty()) - { - continue; - } - - for(int nIndex(0); nIndexupdateRealData(m_dataMap); + return error; } void CDevSpePointWidget::subscribe() { - qDebug() << "subscribe start!"; if(m_pDpcdaForApp == Q_NULLPTR) { return; @@ -690,7 +269,6 @@ void CDevSpePointWidget::subscribe() { const QList &list = iter.value(); foreach (const ST_RealData &data, list) { - qDebug() << "subscribe data-->" << data.table_name << data.tag_name; if(data.type != TYPE_POINT) { continue; @@ -701,7 +279,6 @@ void CDevSpePointWidget::subscribe() } m_pDpcdaForApp->subscribe(data.table_name.toStdString(), data.tag_name.toStdString(), "value"); m_pDpcdaForApp->subscribe(data.table_name.toStdString(), data.tag_name.toStdString(), "status"); - qDebug() << "subscribe-->" << data.table_name << data.tag_name; } } } @@ -916,28 +493,25 @@ void CDevSpePointWidget::initialize() void CDevSpePointWidget::initStyle() { + QString qss = QString(); - std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss"); - qDebug() << "strFullPath-->" << QString::fromStdString(strFullPath); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; QFile qssfile1(QString::fromStdString(strFullPath)); qssfile1.open(QFile::ReadOnly); if (qssfile1.isOpen()) { - qDebug() << "load public.qss"; qss += QLatin1String(qssfile1.readAll()); qssfile1.close(); } qssfile1.close(); std::string style = iot_public::CFileStyle::getPathOfStyleFile("devSpePoint.qss") ; - qDebug() << "Style Path-->" << QString::fromStdString(style); QFile file(QString::fromStdString(style)); file.open(QFile::ReadOnly); if (file.isOpen()) { setStyleSheet(QLatin1String(file.readAll())); file.close(); - qDebug() << "load devSpePoint.qss"; } } @@ -991,109 +565,3 @@ QString CDevSpePointWidget::queryDigitalStateText(const QString &point, iot_dbms } return QString(); } - -//获取设备组名,仅deviceOrGroupType==1时使用 -QString CDevSpePointWidget::queryGetGroupDescription(const QString &tagName, iot_dbms::CDbApi &objReader) const -{ - if(!objReader.isOpen()) - { - return QString(); - } - - QList listColName; - listColName.append("DESCRIPTION"); //需要取的值 - iot_dbms::CDbCondition objCondition; - objCondition.m_sColName = "TAG_NAME"; //比较的组名 - objCondition.m_value = tagName; // 比较的值 - objCondition.m_eCompare = iot_dbms::CDbCondition::COMPARE_EQ; // 比较条件 - objCondition.m_eLogic = iot_dbms::CDbCondition::LOGIC_AND; // 两个比较条件之间的关系 - - QSqlQuery objQuery; - if(objReader.select("dev_group", listColName, objCondition, objQuery)) - { - while(objQuery.next()) - { - return objQuery.value(0).toString(); - } - } - return QString(); -} - -//获取设备组里第1个存在的列标题值的设备名,仅deviceOrGroupType==1时使用 -QString CDevSpePointWidget::queryGetCollumnDevInfoTagName(const QString &measureType, const QString &valueType, const QString &groupName, iot_dbms::CDbApi &objReader) const -{ - if(!objReader.isOpen()) - { - return QString(); - } - - QString mysqlExecute; - mysqlExecute = QString("SELECT %1.TAG_NAME FROM %2 JOIN dev_info ON dev_info.TAG_NAME = %3.DEVICE WHERE dev_info.GROUP_TAG_NAME = '%4'") - .arg(measureType).arg(measureType).arg(measureType).arg(groupName); - QSqlQuery objQuery; - if(objReader.execute(mysqlExecute, objQuery)) - { - qDebug() << "queryGetCollumnDevInfoTagName"; - while(objQuery.next()) - { - qDebug() << "queryGetCollumnDevInfoTagName-->" << objQuery.value(0).toString(); - if(objQuery.value(0).toString().contains(valueType)) - { - return objQuery.value(0).toString(); - } - } - } - return QString(); -} - -//以第1个存在VA值的设备名为列标题时,仅deviceOrGroupType==2时使用 -QString CDevSpePointWidget::queryGetDevInfoTagName(const QString &valueType, const QString &groupTagName, iot_dbms::CDbApi &objReader) const -{ - if(!objReader.isOpen()) - { - return QString(); - } - - QString mysqlExecute; - mysqlExecute = QString("SELECT analog.TAG_NAME FROM analog JOIN dev_info ON analog.DEVICE = dev_info.TAG_NAME WHERE dev_info.GROUP_TAG_NAME = '%1'").arg(groupTagName); - QSqlQuery objQuery; - if(objReader.execute(mysqlExecute, objQuery)) - { - while(objQuery.next()) - { - qDebug() << "queryGetGroupDescription-->" << objQuery.value(0).toString(); - if(objQuery.value(0).toString().contains(valueType)) - { - return objQuery.value(0).toString().replace("." + valueType, ""); - } - } - } - return QString(); -} - -//获取某组设备里的设备名,仅deviceOrGroupType==2时使用 -QString CDevSpePointWidget::queryGetDevInfoDescription(const QString &deviceTagName, iot_dbms::CDbApi &objReader) const -{ - if(!objReader.isOpen()) - { - return QString(); - } - - QList listColName; - listColName.append("DESCRIPTION"); //是objCondition.m_value的组名 - iot_dbms::CDbCondition objCondition; - objCondition.m_sColName = "TAG_NAME"; //比较的字段名 - objCondition.m_value = deviceTagName; //比较的值 - objCondition.m_eCompare = iot_dbms::CDbCondition::COMPARE_EQ; //比较条件 - objCondition.m_eLogic = iot_dbms::CDbCondition::LOGIC_AND; //两个比较条件之间的关系 - - QSqlQuery objQuery; - if(objReader.select("dev_info", listColName, objCondition, objQuery)) - { - while(objQuery.next()) - { - return objQuery.value(0).toString(); - } - } - return QString(); -} diff --git a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.h b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.h index 62ba0984..74a5398f 100644 --- a/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.h +++ b/product/src/gui/plugin/DevSpePointWidget/CDevSpePointWidget.h @@ -82,16 +82,6 @@ public slots: */ void setColumnStateText(int column, const QString &stateText); - /** - * @brief 设置支路和电量行标题显示模式 - * @param labelType - * 行标题默认模式-->0 - * 行标题按设备组名显示-->1(每行数据取该组全部设备存在的第一个值) - * 行标题按设备名显示-->2(取该组设备中第一个存在VA值的设备及它的其它项数据) - * 行标题按设备组名显示-->3(取该组第一个设备和它的值) - */ - void showNameType(int labelType); - private slots: void slotUpdateAi(const QMap>& aiMap); void slotUpdateDi(const QMap>& diMap); @@ -104,12 +94,6 @@ private: QString queryDeviceDesc(const QString &devTag, iot_dbms::CDbApi &objReader) const; QString queryDigitalStateText(const QString &point, iot_dbms::CDbApi &objReader) const; - QString queryGetGroupDescription(const QString &tagName, iot_dbms::CDbApi &objReader) const; - QString queryGetCollumnDevInfoTagName(const QString &measureType, const QString &valueType, - const QString &groupTagName, iot_dbms::CDbApi &objReader) const; - QString queryGetDevInfoTagName(const QString &valueType, const QString &groupTagName, iot_dbms::CDbApi &objReader) const; - QString queryGetAnalogTagName(const QString &valueType, const QString &deviceName, iot_dbms::CDbApi &objReader) const; - QString queryGetDevInfoDescription(const QString &deviceTagName, iot_dbms::CDbApi &objReader) const; private: iot_service::CDpcdaForApp *m_pDpcdaForApp; @@ -121,7 +105,6 @@ private: QStringList m_columnNameList; QMap> m_dataMap; - int deviceOrGroupShowType = 0; //列标题显示模式 }; #endif // CDEVSPEPOINTWIDGET_H diff --git a/product/src/gui/plugin/DevSpePointWidget/DevSpePointWidget.pro b/product/src/gui/plugin/DevSpePointWidget/DevSpePointWidget.pro index c9056aef..40cc8b50 100644 --- a/product/src/gui/plugin/DevSpePointWidget/DevSpePointWidget.pro +++ b/product/src/gui/plugin/DevSpePointWidget/DevSpePointWidget.pro @@ -57,5 +57,3 @@ exists($$COMMON_PRI) { }else { error("FATAL error: can not find common.pri") } - -FORMS += diff --git a/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.cpp b/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.cpp index 39f87c83..4a1580a4 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.cpp +++ b/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.cpp @@ -3,7 +3,7 @@ CDocumentManagePlugin::CDocumentManagePlugin(QObject *parent) { - + Q_UNUSED(parent); } CDocumentManagePlugin::~CDocumentManagePlugin() diff --git a/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.h b/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.h index de21759e..26173f04 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.h +++ b/product/src/gui/plugin/DocumentManageWidget/CDocumentManagePlugin.h @@ -2,12 +2,12 @@ #define CDOCUMENTMANAGEPLUGIN_H #include -#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape +#include "GraphShape/CPluginWidget.h" //< RQEH6000_HOME/platform/src/include/gui/GraphShape class CDocumentManagePlugin : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.cpp b/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.cpp index 0df7a921..ff8018f1 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.cpp +++ b/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.cpp @@ -33,6 +33,11 @@ CDocumentManageWidget::~CDocumentManageWidget() delete ui; } +void CDocumentManageWidget::setFileTableColumnWidth(int colum, int value) +{ + ui->m_tableWidget->setColumnWidth(colum,value); +} + void CDocumentManageWidget::initStyle() { QString qss = QString(); diff --git a/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.h b/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.h index 83ffa5b4..c04186e2 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.h +++ b/product/src/gui/plugin/DocumentManageWidget/CDocumentManageWidget.h @@ -15,12 +15,16 @@ public: explicit CDocumentManageWidget(QWidget *parent = 0, bool isEditMode = true); ~CDocumentManageWidget(); +public slots: + void setFileTableColumnWidth(int colum, int value); + private: void initStyle(); private slots: void slotSearch(); + private: Ui::CDocumentManageWidget *ui; }; diff --git a/product/src/gui/plugin/DocumentManageWidget/CFileFolderTree.cpp b/product/src/gui/plugin/DocumentManageWidget/CFileFolderTree.cpp index b902ce33..6ce248c4 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CFileFolderTree.cpp +++ b/product/src/gui/plugin/DocumentManageWidget/CFileFolderTree.cpp @@ -210,6 +210,7 @@ void CFileFolderTree::slotModify() { currentItem()->setText(0, newName); currentItem()->setData(0, Qt::UserRole, newModuleDir); + emit fileItemClicked(newModuleDir); } } @@ -264,7 +265,7 @@ void CFileFolderTree::contextMenuEvent(QContextMenuEvent *event) QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); if(Q_NULLPTR != pItem) { - QMenu menu; + QMenu menu(this); menu.addAction(tr("添加"), [=](){ slotAdd(); }); menu.addAction(tr("修改"), [=](){ slotModify(); }); menu.addAction(tr("删除"), [=](){ slotDelete(); }); @@ -272,7 +273,7 @@ void CFileFolderTree::contextMenuEvent(QContextMenuEvent *event) } else { - QMenu menu; + QMenu menu(this); menu.addAction(tr("添加"), [=](){ slotAdd(); }); menu.exec(event->globalPos()); } diff --git a/product/src/gui/plugin/DocumentManageWidget/CFileTableWidget.cpp b/product/src/gui/plugin/DocumentManageWidget/CFileTableWidget.cpp index f06d4ff1..696c428a 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CFileTableWidget.cpp +++ b/product/src/gui/plugin/DocumentManageWidget/CFileTableWidget.cpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include "pub_utility_api/I18N.h" + CFileTableWidget::CFileTableWidget(QWidget *parent) : QTableWidget(parent) @@ -250,16 +253,22 @@ void CFileTableWidget::setTableRowHeight(const int &nHeight) void CFileTableWidget::initialize() { setColumnCount(4); - setColumnWidth(COLUMN_SEQ, 50); - setColumnWidth(COLUMN_NAME, 350); - setColumnWidth(COLUMN_DATE, 190); +// setColumnWidth(COLUMN_SEQ, 50); +// setColumnWidth(COLUMN_NAME, 350); +// setColumnWidth(COLUMN_DATE, 190); setHorizontalHeaderLabels(QStringList() << tr("序号") << tr("文档名称") << tr("文档修改时间") << tr("文档路径")); + horizontalHeader()->setDefaultSectionSize(200); setSelectionBehavior(QAbstractItemView::SelectRows); setSelectionMode(QAbstractItemView::ExtendedSelection); setEditTriggers(QAbstractItemView::NoEditTriggers); horizontalHeader()->setStretchLastSection(true); setAlternatingRowColors(true); verticalHeader()->setHidden(true); + + resizeRowsToContents(); + horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + setWordWrap(true); } void CFileTableWidget::makeTable(const QString &path) diff --git a/product/src/gui/plugin/DocumentManageWidget/CInputDialog.cpp b/product/src/gui/plugin/DocumentManageWidget/CInputDialog.cpp index f2fd6a87..be963fdc 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CInputDialog.cpp +++ b/product/src/gui/plugin/DocumentManageWidget/CInputDialog.cpp @@ -4,17 +4,19 @@ #include #include +const QString CN_BtnObjName = "CInputDialog#QDialogButtonBox"; + CInputDialog::CInputDialog(QWidget *parent) - : QDialog(parent), + : CustomDialog(parent), m_nInputId(0) { - QVBoxLayout * layout = new QVBoxLayout(this); + m_pMainLayout = new QVBoxLayout(this); QDialogButtonBox * buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - layout->addWidget(buttonBox); - layout->setMargin(3); - layout->setSpacing(3); - setLayout(layout); + m_pMainLayout->addWidget(buttonBox); + m_pMainLayout->setMargin(3); + m_pMainLayout->setSpacing(3); + setLayout(m_pMainLayout); connect(buttonBox, &QDialogButtonBox::accepted, [=]{accept();}); connect(buttonBox, &QDialogButtonBox::rejected, [=]{reject();}); } @@ -31,7 +33,7 @@ void CInputDialog::setTitle(const QString &title) int CInputDialog::addOneInput(const QString &text, const QString &value) { - QVBoxLayout *gLayout = dynamic_cast(this->layout()); + QVBoxLayout *gLayout = dynamic_cast(m_pMainLayout); if(gLayout) { QVBoxLayout * layout = new QVBoxLayout; diff --git a/product/src/gui/plugin/DocumentManageWidget/CInputDialog.h b/product/src/gui/plugin/DocumentManageWidget/CInputDialog.h index 5d92c1c8..f5103825 100644 --- a/product/src/gui/plugin/DocumentManageWidget/CInputDialog.h +++ b/product/src/gui/plugin/DocumentManageWidget/CInputDialog.h @@ -2,11 +2,11 @@ #define CINPUTDIALOG_H #include -#include #include +#include "pub_widget/CustomDialog.h" class QLineEdit; -class CInputDialog : public QDialog +class CInputDialog : public CustomDialog { Q_OBJECT public: @@ -22,7 +22,7 @@ public: private: int m_nInputId; QMap m_inputMap; - + QVBoxLayout *m_pMainLayout; }; #endif // CINPUTDIALOG_H diff --git a/product/src/gui/plugin/DocumentManageWidget/DocumentManageWidget.pro b/product/src/gui/plugin/DocumentManageWidget/DocumentManageWidget.pro index 36344f9f..3b0c2a21 100644 --- a/product/src/gui/plugin/DocumentManageWidget/DocumentManageWidget.pro +++ b/product/src/gui/plugin/DocumentManageWidget/DocumentManageWidget.pro @@ -43,7 +43,8 @@ FORMS += \ LIBS += \ -lpub_utility_api \ - -lperm_mng_api + -lperm_mng_api \ + -lpub_widget COMMON_PRI=$$PWD/../../../common.pri exists($$COMMON_PRI) { diff --git a/product/src/gui/plugin/EventWidget/CEventDataCollect.cpp b/product/src/gui/plugin/EventWidget/CEventDataCollect.cpp index 74218e2b..fa719b7b 100644 --- a/product/src/gui/plugin/EventWidget/CEventDataCollect.cpp +++ b/product/src/gui/plugin/EventWidget/CEventDataCollect.cpp @@ -8,7 +8,18 @@ #include "perm_mng_api/PermMngApi.h" #include "CEventMsgManage.h" +//< 屏蔽xml_parser编译告警 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-copy" +#endif + #include "boost/property_tree/xml_parser.hpp" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "boost/typeof/typeof.hpp" #include "boost/filesystem.hpp" #include "Common.h" @@ -123,7 +134,6 @@ void CEventDataCollect::loadEventConfig() loadEventOtherStatusDescription(); loadUserName(); loadDeviceGroupDescription(); - loadSubSystemDescription(); } int CEventDataCollect::priorityId(const QString &description) @@ -181,11 +191,6 @@ QString CEventDataCollect::deviceTypeDescription(const int &id) return m_deviceTypeDescriptionMap.value(id, QString()); } -QString CEventDataCollect::deviceGroupDescription(const QString &id) -{ - return m_deviceGroupDescriptionMap.value(id, QString()); -} - QString CEventDataCollect::alarmStatusDescription(const int &id) { return m_alarmStatusMap.value(id, QString()); @@ -201,11 +206,6 @@ QString CEventDataCollect::eventShowStatusDescription(const int &id) return m_eventShowStatusMap.value(id, QString()); } -QString CEventDataCollect::subSystemDescription(const int &id) -{ - return m_subSystemDescriptionMap.value(id, QString()); -} - QList CEventDataCollect::priorityList() { return m_priorityDescriptionMap.keys(); @@ -307,35 +307,6 @@ void CEventDataCollect::loadPriorityDescription() } } -void CEventDataCollect::loadSubSystemDescription() -{ - m_subSystemDescriptionMap.clear(); - if(m_rtdbAccess->open("base", "sys_model_sub_system_info")) - { - LOGERROR("open sys_model_sub_system_info success"); - iot_dbms::CTableLockGuard locker(*m_rtdbAccess); - iot_dbms::CRdbQueryResult result; - std::vector columns; - columns.push_back("sub_system_id"); - columns.push_back("description"); - - if(m_rtdbAccess->select(result, columns)) - { - LOGERROR("select columns success"); - LOGERROR(QString::number( result.getRecordCount()).toStdString().c_str()); - for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) - { - iot_dbms::CVarType key; - iot_dbms::CVarType value; - result.getColumnValue(nIndex, 0, key); - result.getColumnValue(nIndex, 1, value); - m_subSystemDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); - - } - } - } -} - void CEventDataCollect::loadLocationDescription() { m_areaInfoMap.clear(); diff --git a/product/src/gui/plugin/EventWidget/CEventDataCollect.h b/product/src/gui/plugin/EventWidget/CEventDataCollect.h index 8368d07f..5436b5b4 100644 --- a/product/src/gui/plugin/EventWidget/CEventDataCollect.h +++ b/product/src/gui/plugin/EventWidget/CEventDataCollect.h @@ -39,10 +39,9 @@ public: QString regionDescription(const int & id); QString alarmTypeDescription(const int & id); QString deviceTypeDescription(const int & id); - QString deviceGroupDescription(const QString &id); QString alarmStatusDescription(const int & id); QString userNameDescription(const int & id); - QString subSystemDescription(const int &id); + QString eventShowStatusDescription(const int & id); QList priorityList(); @@ -113,7 +112,7 @@ private: void loadDeviceTypeDescription(); void loadAlarmStatusDescription(); void loadUserName(); - void loadSubSystemDescription(); + void loadEventShowStatusDescription(); void loadEventOtherStatusDescription(); @@ -137,7 +136,6 @@ private: QMap m_subSystemDescriptionMap; QMap m_alarmStatusMap; QMap m_userNameMap; - QMap m_DescriptionMap; static CEventDataCollect * m_pInstance; QMap m_eventShowStatusMap; // diff --git a/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.cpp b/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.cpp index 89cfcf73..f588358f 100644 --- a/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.cpp +++ b/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.cpp @@ -1,5 +1,7 @@ #include "CEventDeviceTreeItem.h" +const int TypeRole = Qt::UserRole + 1; + CEventDeviceTreeItem::CEventDeviceTreeItem(const QString &data, CEventDeviceTreeItem *parent) : m_tag(QString()), m_parentItem(parent) @@ -11,6 +13,7 @@ CEventDeviceTreeItem::CEventDeviceTreeItem(const QString &data, CEventDeviceTree m_data = data; m_checkState = Qt::Checked; + m_nType = 0; } CEventDeviceTreeItem::~CEventDeviceTreeItem() @@ -63,6 +66,11 @@ QVariant CEventDeviceTreeItem::data(Qt::ItemDataRole role) const { return m_checkState; } + else if(Qt::ItemDataRole(TypeRole) == role) + { + return m_nType; + } + return QVariant(); } @@ -83,6 +91,12 @@ bool CEventDeviceTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) m_checkState = (Qt::CheckState)value.toInt(); return true; } + else if(TypeRole == role) + { + m_nType = value.toInt(); + return true; + } + return false; } diff --git a/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.h b/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.h index 8458b573..57b29106 100644 --- a/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.h +++ b/product/src/gui/plugin/EventWidget/CEventDeviceTreeItem.h @@ -54,6 +54,8 @@ #include #include +extern const int TypeRole; + class CEventDeviceTreeItem { public: @@ -75,6 +77,7 @@ private: QString m_data; QString m_tag; Qt::CheckState m_checkState; + int m_nType; QList m_childItems; CEventDeviceTreeItem *m_parentItem; diff --git a/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.cpp b/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.cpp index a5e4754b..db841156 100644 --- a/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.cpp +++ b/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.cpp @@ -22,14 +22,27 @@ void CEventDeviceTreeModel::setupModelData(const QMaplocationDescription(locationList[nLocIndex]); CEventDeviceTreeItem * location = new CEventDeviceTreeItem(locDesc, rootItem); + location->setData(TYPE_LOCATION,Qt::ItemDataRole(TypeRole)); + const QVector > vec = locationInfos.value(locationList[nLocIndex]); for(int nDevIndex(0); nDevIndex < vec.size(); ++nDevIndex) { CEventDeviceTreeItem * device = new CEventDeviceTreeItem(vec.at(nDevIndex).second, location); device->setData(vec.at(nDevIndex).first, Qt::UserRole); + device->setData(TYPE_DEVGROUP,Qt::ItemDataRole(TypeRole)); QModelIndex modelIndex = createIndex(nDevIndex, 0, device); m_devTagIndex.insert(vec.at(nDevIndex).first, modelIndex); m_devNameIndex.insert(locDesc + "." + vec.at(nDevIndex).second, modelIndex); + + if(nDevIndex == vec.size() - 1) + { + CEventDeviceTreeItem * sys_device = new CEventDeviceTreeItem(tr(".系统"), location); + sys_device->setData("", Qt::UserRole); + sys_device->setData(TYPE_DEVGROUP,Qt::ItemDataRole(TypeRole)); + QModelIndex sys_modelIndex = createIndex(nDevIndex+1, 0, sys_device); + m_devTagIndex.insert("", sys_modelIndex); + m_devNameIndex.insert("", sys_modelIndex); + } } } } @@ -153,7 +166,8 @@ QVariant CEventDeviceTreeModel::data(const QModelIndex &index, int role) const if (Qt::DisplayRole == role) { const QString &deviceGroup = item->data(Qt::UserRole).toString(); - if(deviceGroup.isEmpty()) + int nType = item->data(Qt::ItemDataRole(TypeRole)).toInt(); + if(deviceGroup.isEmpty() && nType == TYPE_LOCATION) { return item->data(Qt::DisplayRole).toString(); } diff --git a/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.h b/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.h index 28f43a2f..b640a485 100644 --- a/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.h +++ b/product/src/gui/plugin/EventWidget/CEventDeviceTreeModel.h @@ -57,6 +57,11 @@ #include #include "CEventMsgInfo.h" +enum enTreeNodeType{ + TYPE_LOCATION = 0, + TYPE_DEVGROUP +}; + typedef QHash< QString, QModelIndex > HashIndex; //< Device class CEventDeviceTreeItem; diff --git a/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.cpp b/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.cpp index f85d3eaf..9084f63c 100644 --- a/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.cpp +++ b/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.cpp @@ -1,7 +1,33 @@ #include "CEventDeviceTreeView.h" +#include "CEventDeviceTreeModel.h" +#include "CEventDeviceTreeItem.h" +#include +#include CEventDeviceTreeView::CEventDeviceTreeView(QWidget *parent) : QTreeView(parent) { } + +void CEventDeviceTreeView::contextMenuEvent(QContextMenuEvent *event) +{ + CEventDeviceTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QMenu menu; + CEventDeviceTreeItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); + if (Q_NULLPTR == pItem) + { + menu.addAction(tr("全选"), [=](){ pModel->setAllDeviceCheckState(Qt::Checked); }); + menu.addAction(tr("清空"), [=](){ pModel->setAllDeviceCheckState(Qt::Unchecked); }); + } + else if (Q_NULLPTR != pItem && pItem->childCount() > 0) + { + menu.addAction(tr("选择"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Checked); }); + menu.addAction(tr("清除"), [=](){ pModel->setDeviceCheckState(indexAt(event->pos()), Qt::Unchecked); }); + } + menu.exec(event->globalPos()); + } + return; +} diff --git a/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.h b/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.h index 8c388b02..b443978c 100644 --- a/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.h +++ b/product/src/gui/plugin/EventWidget/CEventDeviceTreeView.h @@ -9,6 +9,8 @@ class CEventDeviceTreeView : public QTreeView public: CEventDeviceTreeView(QWidget *parent = Q_NULLPTR); +protected: + void contextMenuEvent(QContextMenuEvent *event); }; #endif // CEVENTDEVICETREEVIEW_H diff --git a/product/src/gui/plugin/EventWidget/CEventFilterDialog.ui b/product/src/gui/plugin/EventWidget/CEventFilterDialog.ui index ce477fac..af873231 100644 --- a/product/src/gui/plugin/EventWidget/CEventFilterDialog.ui +++ b/product/src/gui/plugin/EventWidget/CEventFilterDialog.ui @@ -6,13 +6,13 @@ 0 0 - 570 - 421 + 1000 + 469 - 530 + 1000 0 diff --git a/product/src/gui/plugin/EventWidget/CEventForm.cpp b/product/src/gui/plugin/EventWidget/CEventForm.cpp index 5d846916..b551bdb6 100644 --- a/product/src/gui/plugin/EventWidget/CEventForm.cpp +++ b/product/src/gui/plugin/EventWidget/CEventForm.cpp @@ -242,37 +242,31 @@ void CEventForm::initilize() { //< lingdaoyaoqiu { - QSettings columFlags1("KBD_HMI", "eventReal config"); + QSettings columFlags1("IOT_HMI", "eventReal config"); if(!columFlags1.contains(QString("eventReal/colum_0"))) { columFlags1.setValue(QString("eventReal/colum_0"), false); //< 时间 columFlags1.setValue(QString("eventReal/colum_1"), false); //< 优先级 columFlags1.setValue(QString("eventReal/colum_2"), false); //< 位置 columFlags1.setValue(QString("eventReal/colum_3"), true); //< 责任区 - columFlags1.setValue(QString("eventReal/colum_4"), true); //< 事件类型 - columFlags1.setValue(QString("eventReal/colum_5"), false); //< 事件状态 + columFlags1.setValue(QString("eventReal/colum_4"), false); //< 事件类型 + columFlags1.setValue(QString("eventReal/colum_5"), true); //< 事件状态 columFlags1.setValue(QString("eventReal/colum_6"), false); //< 复归状态 } } { - QSettings columFlags2("KBD_HMI", "eventHis config"); + QSettings columFlags2("IOT_HMI", "eventHis config"); if(!columFlags2.contains(QString("eventHis/colum_0"))) { - // tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型")<< tr("事件状态")<< tr("复归状态")<< tr("专业")<< tr("设备组")<< tr("确认人")<< tr("确认时间")<< tr("点标签")<< tr("事件内容") ; - columFlags2.setValue(QString("eventHis/colum_0"), false); //< 时间 columFlags2.setValue(QString("eventHis/colum_1"), false); //< 优先级 columFlags2.setValue(QString("eventHis/colum_2"), false); //< 位置 columFlags2.setValue(QString("eventHis/colum_3"), true); //< 责任区 - columFlags2.setValue(QString("eventHis/colum_4"), true); //< 事件类型 - columFlags2.setValue(QString("eventHis/colum_5"), false); //< 事件状态 + columFlags2.setValue(QString("eventHis/colum_4"), false); //< 事件类型 + columFlags2.setValue(QString("eventHis/colum_5"), true); //< 事件状态 columFlags2.setValue(QString("eventHis/colum_6"), false); //< 复归状态 - columFlags2.setValue(QString("eventHis/colum_7"), true); // - columFlags2.setValue(QString("eventHis/colum_8"), true); // - columFlags2.setValue(QString("eventHis/colum_9"), true); // - columFlags2.setValue(QString("eventHis/colum_10"),true); // - columFlags2.setValue(QString("eventHis/colum_11"),true); // - columFlags2.setValue(QString("eventHis/colum_12"),true); // + columFlags2.setValue(QString("eventHis/colum_7"), true); //< 确认人 + columFlags2.setValue(QString("eventHis/colum_8"), true); //< 确认时间 } } m_pListWidget1 = new CMyListWidget(this); @@ -339,7 +333,7 @@ void CEventForm::initHisModel() ui->eventView_2->setModel(m_pHistoryModel); m_pHistoryDelegate->setHisEventModel(m_pHistoryModel); ui->eventView_2->setColumnWidth(8, 250); - QSettings columFlags2("KBD_HMI", "eventHis config"); + QSettings columFlags2("IOT_HMI", "eventHis config"); for(int nColumnIndex(0); nColumnIndex < m_pHistoryModel->columnCount() - 1; nColumnIndex++) { bool visible = columFlags2.value(QString("eventHis/colum_%1").arg(nColumnIndex)).toBool(); @@ -354,11 +348,6 @@ void CEventForm::initHisModel() ui->eventView_2->setColumnWidth(5, 150); ui->eventView_2->setColumnWidth(6, 150); ui->eventView_2->setColumnWidth(7, 150); - ui->eventView_2->setColumnWidth(8, 150); - ui->eventView_2->setColumnWidth(9, 150); - ui->eventView_2->setColumnWidth(10, 150); - ui->eventView_2->setColumnWidth(11, 250); - ui->eventView_2->setColumnWidth(12, 350); slotUpdateHISTips(); if(m_pDeviceHisModel == NULL) @@ -386,11 +375,11 @@ void CEventForm::initRealModel() { m_pRealTimeModel = new CEventItemModel(this); connect(ui->eventView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pRealTimeModel, SLOT(sortColumn(int,Qt::SortOrder))); - ui->eventView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); + ui->eventView->horizontalHeader()->setSortIndicator(0, Qt::DescendingOrder); } ui->eventView->setModel(m_pRealTimeModel); m_pRealDelegate->setEventModel(m_pRealTimeModel); - QSettings columFlags1("KBD_HMI", "eventReal config"); + QSettings columFlags1("IOT_HMI", "eventReal config"); for(int nColumnIndex(0); nColumnIndex < m_pRealTimeModel->columnCount() - 1; nColumnIndex++) { bool visible = columFlags1.value(QString("eventReal/colum_%1").arg(nColumnIndex)).toBool(); @@ -907,7 +896,7 @@ void CEventForm::slotUpdateRTTips() ui->typeLabel->setText(tr("实时事件总数:")); if(m_pRealTimeModel) { - ui->eventCount->setText(QString::number(CEventMsgManage::instance()->getListEventCount())); + ui->eventCount->setText(QString::number(m_pRealTimeModel->rowCount())); } } @@ -1025,6 +1014,9 @@ void CEventForm::stateChanged1(int state) isCheck = true; m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); } + + slotUpdateRTTips(); + updateDeviceGroupHiddenState(); } else if(ui->hisEventButton->isChecked()) { @@ -1081,6 +1073,9 @@ void CEventForm::stateChanged2(int state) isCheck = true; m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); } + + slotUpdateRTTips(); + updateDeviceGroupHiddenState(); } else if(ui->hisEventButton->isChecked()) { @@ -1142,6 +1137,9 @@ void CEventForm::stateChanged3(int state) isCheck = true; m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventStatusList,other); } + + slotUpdateRTTips(); + updateDeviceGroupHiddenState(); } else if(ui->hisEventButton->isChecked()) { @@ -1312,7 +1310,7 @@ void CEventForm::contextMenuRealEvent(QContextMenuEvent *event) connect(action, &QAction::triggered, [=](){ ui->eventView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags1("KBD_HMI", "eventReal config"); + QSettings columFlags1("IOT_HMI", "eventReal config"); columFlags1.setValue(QString("eventReal/colum_%1").arg(nColumnIndex), !action->isChecked()); }); } @@ -1368,7 +1366,7 @@ void CEventForm::contextMenuHisEvent(QContextMenuEvent *event) action->setChecked(!ui->eventView_2->isColumnHidden(nColumnIndex)); connect(action, &QAction::triggered, [=](){ ui->eventView_2->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags2("KBD_HMI", "eventHis config"); + QSettings columFlags2("IOT_HMI", "eventHis config"); columFlags2.setValue(QString("eventHis/colum_%1").arg(nColumnIndex), !action->isChecked()); }); } @@ -1459,6 +1457,8 @@ void CEventForm::loadDeviceGroupFilterWidget() void CEventForm::updateDeviceGroupHiddenState() { + m_pDeviceModel->slotHisDevTreeUpdate(m_pRealTimeModel->getListShowAlarmInfo()); + QHash listDeviceStatisticalInfo = m_pDeviceModel->getDeviceStatisticalInfo(); for(int nTopLevelRow(0); nTopLevelRow < m_pDeviceModel->rowCount(); nTopLevelRow++) { diff --git a/product/src/gui/plugin/EventWidget/CEventForm.ui b/product/src/gui/plugin/EventWidget/CEventForm.ui index fdd997b3..e8b97b60 100644 --- a/product/src/gui/plugin/EventWidget/CEventForm.ui +++ b/product/src/gui/plugin/EventWidget/CEventForm.ui @@ -37,7 +37,7 @@ 0 - + 9 @@ -124,135 +124,17 @@ 0 - - - 6 - + - 5 + 3 - 5 + 3 - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 优先级: - - - - - - - - 125 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 位置: - - - - - - - - 125 - 0 - - - - - 16777215 - 26 - - - - - - - - - 0 - 0 - - - - - 16777215 - 26 - - - - 事件状态: - - - - - - - - 137 - 0 - - - - - 16777215 - 26 - - - - - + + 0 + + @@ -271,38 +153,13 @@ - - - - - 0 - 0 - - - - - 200 - 26 - - - - - 200 - 26 - - - - - - - - - + + Qt::Horizontal - QSizePolicy::Fixed + QSizePolicy::Preferred @@ -312,11 +169,27 @@ - + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 40 + 20 + + + + + - 45 + 70 26 @@ -325,24 +198,17 @@ - - - + + + - 45 - 26 + 70 + 0 - - 过滤 - - - - - - 45 + 70 26 @@ -351,11 +217,11 @@ - + - 45 + 70 26 @@ -364,6 +230,155 @@ + + + + + 70 + 26 + + + + 过滤 + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 位置: + + + + + + + + 0 + 0 + + + + + 125 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 125 + 26 + + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 优先级: + + + + + + + + 0 + 0 + + + + + 125 + 0 + + + + + 16777215 + 26 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 事件状态: + + + + + + + + 125 + 0 + + + + + 16777215 + 26 + + + + diff --git a/product/src/gui/plugin/EventWidget/CEventHisThread.cpp b/product/src/gui/plugin/EventWidget/CEventHisThread.cpp index 2f6ca25a..d32f1cbc 100644 --- a/product/src/gui/plugin/EventWidget/CEventHisThread.cpp +++ b/product/src/gui/plugin/EventWidget/CEventHisThread.cpp @@ -501,7 +501,7 @@ void CEventHisThread::doReturnFilterEnable() qint64 startStamp = m_stFilter.startTime.toMSecsSinceEpoch(); qint64 endStamp = m_stFilter.endTime.toMSecsSinceEpoch(); - sql = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag,SUB_SYSTEM from his_event"); + sql = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag from his_event"); //先查询标签和时间 然后根据时间和标签再次查询 @@ -557,7 +557,7 @@ void CEventHisThread::doReturnFilterEnable() return ; } //第2次查询结果 - QString sqlBase = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag,SUB_SYSTEM from his_event"); + QString sqlBase = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag from his_event"); int counter = 0; QString cond = QString(); for(int index(0);indexisOpen()) - { - QSqlQuery query; - try - { - m_pReadDb->execute(sql,query); - } - catch(...) - { - qDebug() << "Query Error!"; - } - search(sql,historyEventList); - } + search(sql,historyEventList); emit sigUpdateHisEvent(historyEventList); } @@ -679,9 +667,6 @@ void CEventHisThread::search(const QString &sql, QList &eventList) info->priorityOrder = queryPriorityOrder(info->priority); info->wave_file = query.value(12).toString(); info->dev_group_tag = query.value(13).toString(); - info->sub_system = query.value(14).toInt(); - - eventList.append(info); } } diff --git a/product/src/gui/plugin/EventWidget/CEventHistoryModel.cpp b/product/src/gui/plugin/EventWidget/CEventHistoryModel.cpp index 22b1c010..f37ad560 100644 --- a/product/src/gui/plugin/EventWidget/CEventHistoryModel.cpp +++ b/product/src/gui/plugin/EventWidget/CEventHistoryModel.cpp @@ -18,8 +18,8 @@ CEventHistoryModel::CEventHistoryModel(QObject *parent) m_sortKey(E_SORT_TIME), m_order(Qt::DescendingOrder) { - header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型")<< tr("事件状态")<< tr("复归状态")<< tr("专业")<< tr("设备组")<< tr("确认人")<< tr("确认时间")<< tr("点标签")<< tr("事件内容") ; - initialize(); + header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型")<< tr("事件状态")<< tr("复归状态")<< tr("确认人")<< tr("确认时间") << tr("事件内容"); + initialize(); } CEventHistoryModel::~CEventHistoryModel() @@ -433,7 +433,13 @@ QVariant CEventHistoryModel::data(const QModelIndex &index, int role) const if(Qt::TextAlignmentRole == role) { - return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + if(index.column() == 9) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } } else if(Qt::DisplayRole == role) { @@ -477,29 +483,8 @@ QVariant CEventHistoryModel::data(const QModelIndex &index, int role) const return QString("-"); } } - case 7 : { - return CEventDataCollect::instance()->subSystemDescription(m_listShowEventInfo.at(index.row())->sub_system); - - - } - case 8 : - { - QString dev_group_name = CEventDataCollect::instance()->deviceGroupDescription(m_listShowEventInfo.at(index.row())->dev_group_tag); - if(dev_group_name.isEmpty()) - { - return QString("-"); - }else - { - return dev_group_name; - } - - - } - case 9 : - { - QString userName = CEventDataCollect::instance()->userNameDescription(m_listShowEventInfo.at(index.row())->cfm_user); if(userName.isEmpty()) { @@ -509,9 +494,8 @@ QVariant CEventHistoryModel::data(const QModelIndex &index, int role) const return userName; } } - case 10 : + case 8 : { - if(m_listShowEventInfo.at(index.row())->cfm_time == 0) { return QString("-"); @@ -520,22 +504,10 @@ QVariant CEventHistoryModel::data(const QModelIndex &index, int role) const return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->cfm_time).toString("yyyy-MM-dd hh:mm:ss.zzz"); } } - case 11 : + case 9 : { - if(m_listShowEventInfo.at(index.row())->key_id_tag =="") - { - return QString("-"); - }else - { - return m_listShowEventInfo.at(index.row())->key_id_tag; - } - } case 12 : - { - return m_listShowEventInfo.at(index.row())->content; - } - default: return QVariant(); } @@ -944,7 +916,7 @@ void CEventHistoryModel::updateShowEvents() QList::iterator it = m_listAllEventInfo.begin(); while (it != m_listAllEventInfo.end()) { //< 设备组 - if((*it)->dev_group_tag.isEmpty() || m_deviceGroupFilter.contains((*it)->dev_group_tag)) + if(/*(*it)->dev_group_tag.isEmpty() ||*/ m_deviceGroupFilter.contains((*it)->dev_group_tag)) { m_listShowEventInfo.append(*it); } diff --git a/product/src/gui/plugin/EventWidget/CEventItemModel.cpp b/product/src/gui/plugin/EventWidget/CEventItemModel.cpp index 382e60d8..eeee69e6 100644 --- a/product/src/gui/plugin/EventWidget/CEventItemModel.cpp +++ b/product/src/gui/plugin/EventWidget/CEventItemModel.cpp @@ -16,7 +16,7 @@ typedef QPair > PAIRLISTALARMINFO; CEventItemModel::CEventItemModel(QObject *parent) :QAbstractTableModel(parent), m_sortKey(E_SORT_TIME), - m_order(Qt::AscendingOrder) + m_order(Qt::DescendingOrder) { header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型") << tr("事件状态") << tr("复归状态") << tr("事件内容"); initialize(); @@ -235,26 +235,12 @@ void CEventItemModel::sortColumn(int column, Qt::SortOrder order) { if(order == Qt::AscendingOrder) { - m_order = Qt::DescendingOrder; + m_order = Qt::AscendingOrder; } else { - m_order = Qt::AscendingOrder; + m_order = Qt::DescendingOrder; } - - if(column ==E_SORT_PRIORITY) - { - if(order == Qt::AscendingOrder) - { - m_order = Qt::AscendingOrder; - } - else - { - m_order = Qt::DescendingOrder; - } - } - - m_sortKey = (E_ALARM_SORTKEY)column; beginResetModel(); @@ -507,7 +493,8 @@ bool CEventItemModel::conditionFilter(EventMsgPtr info) } //< 设备组 - if(!info->dev_group_tag.isEmpty() && !m_deviceGroupFilter.contains(info->dev_group_tag)) + //因为系统告警也就是非设备告警的设备组字段为空,所以把为空判断取消 + if(/*!info->dev_group_tag.isEmpty() &&*/ !m_deviceGroupFilter.contains(info->dev_group_tag)) { return false; } diff --git a/product/src/gui/plugin/EventWidget/CEventMsgInfo.cpp b/product/src/gui/plugin/EventWidget/CEventMsgInfo.cpp index f40b69e8..d269f08d 100644 --- a/product/src/gui/plugin/EventWidget/CEventMsgInfo.cpp +++ b/product/src/gui/plugin/EventWidget/CEventMsgInfo.cpp @@ -15,7 +15,6 @@ CEventMsgInfo::CEventMsgInfo(): alm_status(0), cfm_user(0), cfm_time(0) priority = -1; dev_type = -1; region_id = -1; - sub_system = -1; key_id_tag = QString(); uuid_base64 = QString(); priorityOrder = -1; @@ -23,7 +22,6 @@ CEventMsgInfo::CEventMsgInfo(): alm_status(0), cfm_user(0), cfm_time(0) filterDelete = false; wave_file = QString(); dev_group_tag = QString(); - dev_group_tag = QString(); } CEventMsgInfo::CEventMsgInfo(const CEventMsgInfo &other): alm_status(0), cfm_user(0), cfm_time(0), priorityOrder(0) @@ -44,7 +42,6 @@ CEventMsgInfo::CEventMsgInfo(const CEventMsgInfo &other): alm_status(0), cfm_use filterDelete = other.filterDelete; wave_file = other.wave_file; dev_group_tag = other.dev_group_tag; - dev_group_tag = other.dev_group_tag; } void CEventMsgInfo::initialize(const iot_idl::SEvtInfoToEvtClt &eventInfo) diff --git a/product/src/gui/plugin/EventWidget/CEventMsgInfo.h b/product/src/gui/plugin/EventWidget/CEventMsgInfo.h index 8463f4e9..d8151b9b 100644 --- a/product/src/gui/plugin/EventWidget/CEventMsgInfo.h +++ b/product/src/gui/plugin/EventWidget/CEventMsgInfo.h @@ -156,7 +156,6 @@ public: uint cfm_user; //确认人 uint64 cfm_time; //确认时间 QString dev_group_tag; //< 设备组 - qint32 sub_system; //专业号 //Extend qint32 priorityOrder; diff --git a/product/src/gui/plugin/EventWidget/CEventPluginWidget.h b/product/src/gui/plugin/EventWidget/CEventPluginWidget.h index f2542479..6ef08a0c 100644 --- a/product/src/gui/plugin/EventWidget/CEventPluginWidget.h +++ b/product/src/gui/plugin/EventWidget/CEventPluginWidget.h @@ -7,7 +7,7 @@ class CEventPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/EventWidget/main.cpp b/product/src/gui/plugin/EventWidget/main.cpp index 45528df9..52c03481 100644 --- a/product/src/gui/plugin/EventWidget/main.cpp +++ b/product/src/gui/plugin/EventWidget/main.cpp @@ -17,7 +17,7 @@ int main(int argc, char *argv[]) iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); permMngPtr->PermDllInit(); - if(permMngPtr->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) + if(permMngPtr->SysLogin("admin", "admin", 1, 12*60*60, "hmi") != 0) { iot_net::releaseMsgBus(); iot_public::StopLogSystem(); diff --git a/product/src/gui/plugin/EventWidget_pad/CAccidentReviewDialog.cpp b/product/src/gui/plugin/EventWidget_pad/CAccidentReviewDialog.cpp new file mode 100644 index 00000000..430d4f7a --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CAccidentReviewDialog.cpp @@ -0,0 +1,289 @@ +#include "CAccidentReviewDialog.h" +#include "public/pub_utility_api/FileUtil.h" +#include "public/pub_logger_api/logger.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CAccidentReviewDialog::CAccidentReviewDialog(const QString &path, QWidget *parent) + : QDialog(parent) +{ + resize(350,450); + getFilterNames(path); + initView(); + initTree(); +} + +CAccidentReviewDialog::~CAccidentReviewDialog() +{ + +} + +QString CAccidentReviewDialog::getCurrentGraph() +{ + if(m_treeWidget->currentItem()) + { + return m_treeWidget->currentItem()->data(0, Qt::UserRole).toString(); + } + return QString(); +} + +void CAccidentReviewDialog::initView() +{ + setWindowTitle(tr("事故追忆")); + m_treeWidget = new QTreeWidget(this); + m_treeWidget->headerItem()->setHidden(true); + + QSpacerItem * spacer = new QSpacerItem(10, 0, QSizePolicy::Preferred); + m_confirmBtn = new QPushButton(tr("确认"), this); + m_cancelBtn = new QPushButton(tr("取消"), this); + connect(m_confirmBtn, &QPushButton::clicked, this, &CAccidentReviewDialog::slotConfirm); + connect(m_cancelBtn, &QPushButton::clicked, this, &CAccidentReviewDialog::slotCancel); + + QGridLayout * layout = new QGridLayout(); + layout->addWidget(m_treeWidget, 0, 0, 1, 3); + layout->addItem(spacer, 1, 0); + layout->addWidget(m_confirmBtn, 1, 1); + layout->addWidget(m_cancelBtn, 1, 2); + setLayout(layout); +} + +void CAccidentReviewDialog::initTree() +{ + QMap>> m_mapNav; + readNavJson(QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + + QString("../../data/model/NavigationWidget.json"), m_mapNav); + QList> nodeList = m_mapNav.value(-1); + for(int nIndex=0; nIndexaddTopLevelItem(item); + + addChildLevelItem(item, nodeList[nIndex], m_mapNav); + } + treeFilter(); + m_treeWidget->expandAll(); +} + +void CAccidentReviewDialog::getFilterNames(const QString &path) +{ + QString filePath = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + + QString("../../data/pic/"); + m_fileNameList = getAllFile(filePath, filePath, path); +} + +QStringList CAccidentReviewDialog::getAllFile(const QString &path, const QString &relativePath, const QString &filter) +{ + QDir dir(path); + QDir relativeDir(relativePath); + QStringList allFile; + + QString fileName; + QFileInfoList fileList = dir.entryInfoList(QDir::Files | QDir::NoSymLinks); + for(QFileInfo &file : fileList) + { + fileName = relativeDir.relativeFilePath(file.filePath()); + if(fileName.contains(filter)) + { + allFile.append(fileName); + } + } + + QFileInfoList folderList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + for(QFileInfo &folder : folderList) + { + allFile.append(getAllFile(folder.absoluteFilePath(), relativePath, filter)); + } + + return allFile; +} + +void CAccidentReviewDialog::treeFilter() +{ + bool topShow,childShow,leafShow; + int nTopCount = m_treeWidget->topLevelItemCount(); + for(int nTopIndex(0); nTopIndextopLevelItem(nTopIndex); + topShow = m_fileNameList.contains(topItem->data(0, Qt::UserRole).toString()); + + int nChildCount = topItem->childCount(); + for(int nChildIndex(0); nChildIndexchild(nChildIndex); + childShow = m_fileNameList.contains(childItem->data(0, Qt::UserRole).toString()); + + int nLeafCount = childItem->childCount(); + for(int nLeafIndex(0); nLeafIndexchild(nLeafIndex); + leafShow = m_fileNameList.contains(leafItem->data(0, Qt::UserRole).toString()); + leafItem->setHidden(!leafShow); + if(leafShow) + { + childShow = true; + } + } + childItem->setHidden(!childShow); + if(childShow) + { + topShow = true; + } + } + topItem->setHidden(!topShow); + } +} + +void CAccidentReviewDialog::slotConfirm() +{ + if(m_treeWidget->currentItem() == NULL) + { + QMessageBox::information(this, tr("提示"), tr("请选择一张画面!"), QMessageBox::Ok); + return; + } + QString data = m_treeWidget->currentItem()->data(0, Qt::UserRole).toString(); + if(data.isEmpty() || !m_fileNameList.contains(data)) + { + QMessageBox::information(this, tr("提示"), tr("请选择其他画面!"), QMessageBox::Ok); + return; + } + accept(); +} + +void CAccidentReviewDialog::slotCancel() +{ + reject(); +} + +void CAccidentReviewDialog::addChildLevelItem(QTreeWidgetItem *item, const QPair &node, + const QMap > > &navMap) +{ + const QList > childList = navMap.value(node.first); + for(int nIndex=0; nIndexaddChild(childItem); + + addChildLevelItem(childItem, childList[nIndex], navMap); + } +} + +QTreeWidgetItem *CAccidentReviewDialog::getAddLevelItem(const ST_NODE &st_node) +{ + if(st_node.used == Disable) + { + return NULL; + } + + QTreeWidgetItem * childItem = new QTreeWidgetItem(); + childItem->setData(0, Qt::DisplayRole, st_node.name); + childItem->setData(0, Qt::UserRole, st_node.data); + return childItem; +} + +void CAccidentReviewDialog::readNavJson(const QString &path, QMap > > &map) +{ + QFile file(path); + QByteArray readJson; + if(file.open(QIODevice::ReadOnly)) + { + readJson = file.readAll(); + file.close(); + } + QJsonParseError readError; + QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); + if(readError.error != QJsonParseError::NoError) + { + LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); + return; + } + QJsonObject root = readJsonResponse.object(); + if(root.contains("items")) + { + QJsonArray itemArray = root.value("items").toArray(); + int nItemNumber = 0; + for(int nIndex(0); nIndex< itemArray.size(); nIndex++) + { + ST_NODE st_Node_Top; + QJsonObject topLevelObject = itemArray[nIndex].toObject(); + makeStButton(st_Node_Top, topLevelObject); + QPair topMap; + int nTopNumber = nItemNumber; + topMap.first = nItemNumber++; + topMap.second = st_Node_Top; + + QJsonArray childArray = topLevelObject.value("items").toArray(); + for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) + { + ST_NODE st_Node_Child; + QJsonObject childLevelObject = childArray[nChildIndex].toObject(); + makeStButton(st_Node_Child, childLevelObject); + QPair childMap; + int nChildNumber = nItemNumber; + childMap.first = nItemNumber++; + childMap.second = st_Node_Child; + + QJsonArray leafArray = childLevelObject.value("items").toArray(); + for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) + { + ST_NODE st_Node_Leaf; + QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); + makeStButton(st_Node_Leaf, leafLevelObject); + QPair leafMap; + leafMap.first = nItemNumber++; + leafMap.second = st_Node_Leaf; + map[nChildNumber].append(leafMap); + } + map[nTopNumber].append(childMap); + } + map[-1].append(topMap); + } + } +} + +void CAccidentReviewDialog::makeStButton(ST_NODE &st_Node, const QJsonObject &object) +{ + if(!object.value("name").isUndefined()) + { + st_Node.name = object.value("name").toString(); + } + if(!object.value("icon").isUndefined()) + { + st_Node.icon = object.value("icon").toString(); + } + if(!object.value("data").isUndefined()) + { + st_Node.data = object.value("data").toString(); + } + if(!object.value("opt").isUndefined()) + { + st_Node.type = object.value("opt").toInt(); + } + if(!object.value("used").isUndefined()) + { + st_Node.used = object.value("used").toInt(); + } + if(!object.value("web").isUndefined()) + { + st_Node.web = object.value("web").toInt(); + } + if(!object.value("webData").isUndefined()) + { + st_Node.webData = object.value("webData").toString(); + } +} diff --git a/product/src/gui/plugin/EventWidget_pad/CAccidentReviewDialog.h b/product/src/gui/plugin/EventWidget_pad/CAccidentReviewDialog.h new file mode 100644 index 00000000..6d475f81 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CAccidentReviewDialog.h @@ -0,0 +1,56 @@ +#ifndef CACCIDENTREVIEWDIALOG_H +#define CACCIDENTREVIEWDIALOG_H + +#include +#include +#include + +struct ST_NODE +{ + QString name; + int used; + int type; + QString icon; + int web; + QString data; + QString webData; +}; + +class QTreeWidget; +class QTreeWidgetItem; +class CAccidentReviewDialog : public QDialog +{ + Q_OBJECT +public: + enum Node_Enable{Enable = 1,Disable = 2}; + CAccidentReviewDialog(const QString &path, QWidget *parent = Q_NULLPTR); + ~CAccidentReviewDialog(); + + QString getCurrentGraph(); + +private slots: + void slotConfirm(); + void slotCancel(); + +private: + void initView(); + void initTree(); + void getFilterNames(const QString &path); + QStringList getAllFile(const QString &path, const QString &relativePath, + const QString &filter); + void treeFilter(); + + void addChildLevelItem(QTreeWidgetItem *item, const QPair &node, + const QMap > > &navMap); + QTreeWidgetItem* getAddLevelItem(const ST_NODE& st_node); + void readNavJson(const QString &path, QMap>>& map); + void makeStButton(ST_NODE &st_Node, const QJsonObject &object); + +private: + QTreeWidget * m_treeWidget; + QPushButton * m_confirmBtn; + QPushButton * m_cancelBtn; + QStringList m_fileNameList; +}; + +#endif // CACCIDENTREVIEWDIALOG_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventDataCollect.cpp b/product/src/gui/plugin/EventWidget_pad/CEventDataCollect.cpp new file mode 100644 index 00000000..d7a247b5 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventDataCollect.cpp @@ -0,0 +1,750 @@ +#include "CEventDataCollect.h" +#include +#include +#include +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include "CEventMsgManage.h" + +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" +#include "Common.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/CharUtil.h" +using namespace std; +using namespace iot_public; +CEventDataCollect * CEventDataCollect::m_pInstance = NULL; + +CEventDataCollect * CEventDataCollect::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CEventDataCollect(); + } + return m_pInstance; +} + +CEventDataCollect::CEventDataCollect() + : m_pTimer(NULL) +{ + msgMutex = new QMutex(); + + m_rtdbPriorityOrderAccess = new iot_dbms::CRdbAccess(); + m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); + + m_rtdbAccess = new iot_dbms::CRdbAccess(); + m_pTimer = new QTimer(); + m_pTimer->setInterval(1000); + connect(m_pTimer, &QTimer::timeout, this, &CEventDataCollect::slotUpdateEvent); + + initialize(); +} + +int CEventDataCollect::queryPriorityOrder(int &id) +{ + iot_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); + iot_dbms::CVarType value; + m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); + return value.toInt(); +} + +CEventDataCollect::~CEventDataCollect() +{ + if(m_pTimer != NULL) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + suspendThread(); + + m_priorityOrderMap.clear(); + m_priorityDescriptionMap.clear(); + m_locationDescriptionMap.clear(); + m_regionInfoDescriptionMap.clear(); + m_alarmTypeDescriptionMap.clear(); + m_deviceTypeDescriptionMap.clear(); + m_subSystemDescriptionMap.clear(); + m_locationOrderList.clear(); + + delete msgMutex; + delete m_rtdbAccess; + m_pInstance = NULL; +} + +bool CEventDataCollect::initialize() +{ + m_pTimer->start(); + iot_public::CSysInfoInterfacePtr spSysInfo; + if (iot_public::createSysInfoInstance(spSysInfo)) + { + iot_public::SNodeInfo stNodeInfo; + spSysInfo->getLocalNodeInfo(stNodeInfo); + iot_public::SLocationInfo stLocationInfo; + spSysInfo->getLocationInfoById(stNodeInfo.nLocationId, stLocationInfo); + m_nLocationID = stNodeInfo.nLocationId; + } + loadEventConfig(); + return resumeThread(); +} + +void CEventDataCollect::release() +{ + m_pTimer->stop(); + suspendThread(true); + m_priorityOrderMap.clear(); + m_priorityDescriptionMap.clear(); + m_locationDescriptionMap.clear(); + m_regionInfoDescriptionMap.clear(); + m_alarmTypeDescriptionMap.clear(); + m_deviceTypeDescriptionMap.clear(); + m_subSystemDescriptionMap.clear(); + m_areaInfoMap.clear(); + m_areaLocMap.clear(); + m_locationOrderList.clear(); + + CEventMsgManage::instance()->clearRTMsg(); +} + +void CEventDataCollect::loadEventConfig() +{ + loadPermInfo(); + loadPriorityDescription(); + loadLocationDescription(); + loadRegionInfoDescription(); + loadAlarmTypeDescription(); + loadDeviceTypeDescription(); + loadAlarmStatusDescription(); + loadEventShowStatusDescription(); + loadEventOtherStatusDescription(); + loadUserName(); + loadDeviceGroupDescription(); +} + +int CEventDataCollect::priorityId(const QString &description) +{ + return m_priorityDescriptionMap.key(description, -1); +} + +int CEventDataCollect::locationId(const QString &description) +{ + return m_locationDescriptionMap.key(description, -1); +} + +int CEventDataCollect::regionId(const QString &description) +{ + return m_regionInfoDescriptionMap.key(description, -1); +} + +int CEventDataCollect::alarmTypeId(const QString &description) +{ + return m_alarmTypeDescriptionMap.key(description, -1); +} + +int CEventDataCollect::eventStatusId(const QString &description) +{ + return m_eventShowStatusMap.key(description, -1); +} + +int CEventDataCollect::deviceTypeId(const QString &description) +{ + return m_deviceTypeDescriptionMap.key(description, -1); +} + +QString CEventDataCollect::priorityDescription(const int &id) +{ + return m_priorityDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::locationDescription(const int &id) +{ + return m_locationDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::regionDescription(const int &id) +{ + return m_regionInfoDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::alarmTypeDescription(const int &id) +{ + return m_alarmTypeDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::deviceTypeDescription(const int &id) +{ + return m_deviceTypeDescriptionMap.value(id, QString()); +} + +QString CEventDataCollect::alarmStatusDescription(const int &id) +{ + return m_alarmStatusMap.value(id, QString()); +} + +QString CEventDataCollect::userNameDescription(const int &id) +{ + return m_userNameMap.value(id, QString()); +} + +QString CEventDataCollect::eventShowStatusDescription(const int &id) +{ + return m_eventShowStatusMap.value(id, QString()); +} + +QList CEventDataCollect::priorityList() +{ + return m_priorityDescriptionMap.keys(); +} + +QList CEventDataCollect::locationList() +{ + return m_listPermLocationId; +} + +QList CEventDataCollect::regionList() +{ + return m_listPermRegionId; +} + +QList CEventDataCollect::alarmTypeList() +{ + return m_alarmTypeDescriptionMap.keys(); +} + +QList CEventDataCollect::alarmStatusList() +{ + return m_eventShowStatusMap.keys(); +} + +QList CEventDataCollect::alarmOtherList() +{ + return m_eventOtherStatusMap.keys(); +} + +QMap CEventDataCollect::areaInfoMap() +{ + return m_areaInfoMap; +} + +QMap > CEventDataCollect::areaLocMap() +{ + return m_areaLocMap; +} + +QList CEventDataCollect::locationOrderList() +{ + return m_locationOrderList; +} + +QList CEventDataCollect::getDevGroupTagList() +{ + return m_deviceGroupDescriptionMap.keys(); +} + +void CEventDataCollect::loadPermInfo() +{ + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecRegionId; + std::vector vecLocationId; + m_listPermLocationId.clear(); + m_listPermRegionId.clear(); + if(PERM_NORMAL == permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + m_listPermLocationId.append(*location++); + } + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + m_listPermRegionId.append(*region++); + } + } + } +} + +void CEventDataCollect::loadPriorityDescription() +{ + m_priorityDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "alarm_level_define")) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("priority_id"); + columns.push_back("priority_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_priorityDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CEventDataCollect::loadLocationDescription() +{ + m_areaInfoMap.clear(); + m_areaLocMap.clear(); + if(m_rtdbAccess->open("base", "sys_model_location_info")) + { + m_locationDescriptionMap.clear(); + m_locationOrderList.clear(); + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("location_id"); + columns.push_back("tag_name"); + columns.push_back("description"); + columns.push_back("location_type"); + columns.push_back("plocation_id"); + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType area_id; + iot_dbms::CVarType tag_name; + iot_dbms::CVarType description; + iot_dbms::CVarType area_type; + iot_dbms::CVarType parea_id; + result.getColumnValue(nIndex, 0, area_id); + result.getColumnValue(nIndex, 1, tag_name); + result.getColumnValue(nIndex, 2, description); + result.getColumnValue(nIndex, 3, area_type); + result.getColumnValue(nIndex, 4, parea_id); + SAreaInfo info; + info.nId =area_id.toInt(); + info.stTag =QString::fromStdString(tag_name.toStdString()); + info.stDes =QString::fromStdString(description.toStdString()); + if(area_type.toInt() != (int)E_LOCATION_NODE) + { + info.eType = E_LOCATION_AREA; + }else + { + info.eType = E_LOCATION_NODE; + } + info.nPareaId =parea_id.toInt(); + m_areaInfoMap[info.nId] = info; + if(m_listPermLocationId.contains(info.nId)) + { + m_locationOrderList.push_back(info.nId); + m_locationDescriptionMap[info.nId] = info.stDes; + } + } + } + } + QMap::iterator it= m_areaInfoMap.begin(); + while (it != m_areaInfoMap.end()) { + if(m_listPermLocationId.contains(it.key())) + { + if(it.value().eType == (int)E_LOCATION_NODE) + { + QMap >::iterator pos = m_areaLocMap.find(it.value().nPareaId); + if(pos == m_areaLocMap.end()) + { + QVector locVec; + locVec.append(it.value().nId); + m_areaLocMap.insert(it.value().nPareaId,locVec); + }else + { + QVector &locVec = pos.value(); + locVec.append(it.value().nId); + } + }else + { + QMap >::iterator pos = m_areaLocMap.find(it.key()); + if(pos == m_areaLocMap.end()) + { + QVector locVec; + locVec.append(it.value().nId); + m_areaLocMap.insert(it.key(),locVec); + }else + { + QVector &locVec = pos.value(); + locVec.append(it.value().nId); + } + } + + } + it++; + } +} + +void CEventDataCollect::loadRegionInfoDescription() +{ + m_regionInfoDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "region_info")) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("region_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + if(m_listPermRegionId.contains(key.toInt())) + { + m_regionInfoDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + } +} + +void CEventDataCollect::loadAlarmTypeDescription() +{ + m_alarmTypeDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "alarm_type_define")) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("type_id"); + columns.push_back("type_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CEventDataCollect::loadDeviceTypeDescription() +{ + m_deviceTypeDescriptionMap.clear(); + if(m_rtdbAccess->open("base", "dev_type_def")) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("dev_type_id"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceTypeDescriptionMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CEventDataCollect::loadAlarmStatusDescription() +{ + m_alarmStatusMap.clear(); + if(m_rtdbAccess->open("base", "alarm_status_define")) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("status_value"); + columns.push_back("display_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmStatusMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CEventDataCollect::loadUserName() +{ + m_userNameMap.clear(); + if(m_rtdbAccess->open("base", "rm_user_def")) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("perm_id"); + columns.push_back("perm_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_userNameMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } +} + +void CEventDataCollect::loadEventShowStatusDescription() +{ + const std::string strConfFullPath = iot_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + if(StringToInt(strKey) != OTHERSTATUS) + { + m_eventShowStatusMap[StringToInt(strKey)] = m_alarmStatusMap[StringToInt(strKey)]; + }else + { + m_eventShowStatusMap[StringToInt(strKey)] = tr("其他"); + } + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CEventDataCollect::loadEventOtherStatusDescription() +{ + m_eventOtherStatusMap.clear(); + const std::string strConfFullPath = iot_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + //string strValue = pParamIter->second.get(".value"); + m_eventOtherStatusMap[StringToInt(strKey)] = m_alarmStatusMap[StringToInt(strKey)]; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CEventDataCollect::loadDeviceGroupDescription() +{ + if(m_rtdbAccess->open("base", "dev_group")) + { + m_deviceGroupDescriptionMap.clear(); + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back("tag_name"); + columns.push_back("description"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_deviceGroupDescriptionMap[QString::fromStdString(key.toStdString())] = QString::fromStdString(value.toStdString()); + } + } + + m_deviceGroupDescriptionMap.insert(QString(), QString(tr("系统信息"))); + + } +} + +QMap CEventDataCollect::priorityDescriptionMap() +{ + return m_priorityDescriptionMap; +} + +QMap CEventDataCollect::locationDescriptionMap() +{ + return m_locationDescriptionMap; +} + +QMap CEventDataCollect::regionInfoDescriptionMap() +{ + return m_regionInfoDescriptionMap; +} + +QMap CEventDataCollect::alarmTypeDescriptionMap() +{ + return m_alarmTypeDescriptionMap; +} + +QMap CEventDataCollect::deviceTypeDescriptionMap() +{ + return m_deviceTypeDescriptionMap; +} + +QMap CEventDataCollect::alarmStatusMap() +{ + return m_alarmStatusMap; +} + +QMap CEventDataCollect::userNameMap() +{ + return m_userNameMap; +} + +QMap CEventDataCollect::eventShowStatusDescriptionMap() +{ + return m_eventShowStatusMap; +} + +QMap CEventDataCollect::eventOtherStatusDescriptionMap() +{ + return m_eventOtherStatusMap; +} + +void CEventDataCollect::slotUpdateEvent() +{ + //loadEventConfig(); + + QMutexLocker locker(msgMutex); + + if(!m_listEventCache.isEmpty()) + { + emit sigMsgArrived(m_listEventCache); + m_listEventCache.clear(); + } + emit sigDevTreeUpdate(); +} + +void CEventDataCollect::handleAllEvtMsg(int nDomainID, iot_idl::SEvtCltAddEvt &objAllEvt) +{ + QMutexLocker locker(msgMutex); + LOGINFO("-------------------------handleAllEvtMsg-------------------------"); + CEventMsgManage::instance()->removeEventMsgByDomainID(nDomainID); + removeCache(nDomainID); + for(int nAddMsgIndex(0); nAddMsgIndex < objAllEvt.evt_info_size(); nAddMsgIndex++) + { + iot_idl::SEvtInfoToEvtClt msg = objAllEvt.evt_info(nAddMsgIndex); + EventMsgPtr event(new CEventMsgInfo()); + event->initialize(msg); + event->priorityOrder = queryPriorityOrder(event->priority); + if(!m_listPermLocationId.contains(event->location_id)) + { + continue; + } + if(!m_listPermRegionId.contains(event->region_id) && event->region_id != -1) + { + continue; + } + CEventMsgManage::instance()->addEventMsg(event); + } + emit sigMsgRefresh(); + emit sigEventStateChanged(); + emit sigDevTreeUpdate(); +} + +void CEventDataCollect::handleAddEvtMsg(iot_idl::SEvtCltAddEvt &objAddEvt) +{ + QMutexLocker locker(msgMutex); + LOGINFO("-------------------------handleAddEvtMsg-------------------------"); + for(int nAddMsgIndex(0); nAddMsgIndex < objAddEvt.evt_info_size(); nAddMsgIndex++) + { + iot_idl::SEvtInfoToEvtClt msg = objAddEvt.evt_info(nAddMsgIndex); + EventMsgPtr event(new CEventMsgInfo()); + event->initialize(msg); + event->priorityOrder = queryPriorityOrder(event->priority); + if(!m_listPermRegionId.contains(event->region_id) && event->region_id != -1) + { + continue; + } + CEventMsgManage::instance()->addEventMsg(event); + m_listEventCache.append(event); + } + emit sigEventStateChanged(); +} + +void CEventDataCollect::handleLinkWave2EvtMsg(iot_idl::SAlmCltLinkWave2Alm &objWave2Evt) +{ + QMutexLocker locker(msgMutex); + QList uuidList; + LOGINFO("-------------------------handleAddEvtMsg-------------------------"); + QString waveFile = QString::fromStdString(objWave2Evt.wave_file()); + for(int nAddMsgIndex(0); nAddMsgIndex < objWave2Evt.uuid_base64_size(); nAddMsgIndex++) + { + QString uuid = QString::fromStdString(objWave2Evt.uuid_base64(nAddMsgIndex)); + uuidList.append(uuid); + } + CEventMsgManage::instance()->linkWave2EvtMsg(uuidList,waveFile); +} + +void CEventDataCollect::handleClearRTEvent() +{ + QMutexLocker locker(msgMutex); + CEventMsgManage::instance()->clearRTMsg(); + emit sigMsgRefresh(); + emit sigEventStateChanged(); +} + +void CEventDataCollect::removeCache(int nDomain) +{ + QList::iterator it = m_listEventCache.begin(); + while (it != m_listEventCache.end()) + { + if(nDomain == (*it)->domain_id) + { + it = m_listEventCache.erase(it); + continue; + } + it++; + } +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventDataCollect.h b/product/src/gui/plugin/EventWidget_pad/CEventDataCollect.h new file mode 100644 index 00000000..5436b5b4 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventDataCollect.h @@ -0,0 +1,152 @@ +#ifndef CEventDataCollect_H +#define CEventDataCollect_H + +#include +#include +#include +#include "AlarmMessage.pb.h" +#include "CEventMsgInfo.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dbms/rdb_api/CRdbAccess.h" +#include +#include + +#define FUNC_SPE_EVENT_VIEW ("FUNC_SPE_EVENT_VIEW") + +const int OTHERSTATUS = 9999; +class CEventDataCollect : public QObject, public iot_service::CAlmApiForEvtClt +{ + Q_OBJECT +public: + static CEventDataCollect * instance(); + + virtual ~CEventDataCollect(); + + bool initialize(); + + void release(); + + void loadEventConfig(); + int priorityId(const QString &description); + int locationId(const QString &description); + int regionId(const QString &description); + int alarmTypeId(const QString &description); + int eventStatusId(const QString &description); + int deviceTypeId(const QString &description); + + QString priorityDescription(const int & id); + QString locationDescription(const int & id); + QString regionDescription(const int & id); + QString alarmTypeDescription(const int & id); + QString deviceTypeDescription(const int & id); + QString alarmStatusDescription(const int & id); + QString userNameDescription(const int & id); + + QString eventShowStatusDescription(const int & id); + + QList priorityList(); + QList locationList(); + QList regionList(); + QList alarmTypeList(); + QList alarmStatusList(); + QList alarmOtherList(); + QMap areaInfoMap(); + QMap > areaLocMap(); + QList locationOrderList(); + QList getDevGroupTagList(); + + QMap priorityDescriptionMap(); + QMap locationDescriptionMap(); + QMap regionInfoDescriptionMap(); + QMap alarmTypeDescriptionMap(); + QMap deviceTypeDescriptionMap(); + QMap alarmStatusMap(); + QMap userNameMap(); + + QMap eventShowStatusDescriptionMap(); + QMap eventOtherStatusDescriptionMap(); + + virtual void handleAllEvtMsg(int nDomainID, iot_idl::SEvtCltAddEvt &objAllEvt); + + virtual void handleAddEvtMsg(iot_idl::SEvtCltAddEvt &objAddEvt); + + virtual void handleLinkWave2EvtMsg( iot_idl::SAlmCltLinkWave2Alm &objWave2Evt); + + void handleClearRTEvent(); + +signals: + /** + * @brief sigMsgRefresh 在handleAllAlmMsg时触发,通知model重新拉取报警消息 + */ + void sigMsgRefresh(); + + /** + * @brief sigMsgArrived 在handleAddAlmMsg时触发,通知model新报警消息到达 + */ + void sigMsgArrived(QList listEvents); + + /** + * @brief sigEventStateChanged 事件数量或状态改变时触发。 + */ + void sigEventStateChanged(); + + /** + * @brief sigDevTreeUpdate 通知设备树更新设备组事件数 + */ + void sigDevTreeUpdate(); + +public slots: + //void queryHistoryEvent(const QStringList &tables, QList typeFilter, const QString &condition); + void slotUpdateEvent(); + +private: + CEventDataCollect(); + int queryPriorityOrder(int &id); + void removeCache(int nDomain); + + void loadPermInfo(); + void loadPriorityDescription(); + void loadLocationDescription(); + void loadRegionInfoDescription(); + void loadAlarmTypeDescription(); + void loadDeviceTypeDescription(); + void loadAlarmStatusDescription(); + void loadUserName(); + + void loadEventShowStatusDescription(); + void loadEventOtherStatusDescription(); + + void loadDeviceGroupDescription(); + +private: + QMutex * msgMutex; + QTimer * m_pTimer; + int m_nLocationID; + QList m_listEventCache; + iot_dbms::CRdbAccess * m_rtdbAccess; + iot_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; + QList m_listPermLocationId; + QList m_listPermRegionId; + QMap m_priorityOrderMap; + QMap m_priorityDescriptionMap; + QMap m_locationDescriptionMap; + QMap m_regionInfoDescriptionMap; + QMap m_alarmTypeDescriptionMap; + QMap m_deviceTypeDescriptionMap; + QMap m_subSystemDescriptionMap; + QMap m_alarmStatusMap; + QMap m_userNameMap; + static CEventDataCollect * m_pInstance; + + QMap m_eventShowStatusMap; // + QMap m_eventOtherStatusMap; //其他报警状态 + + + QMap m_areaInfoMap; //区域信息 + QMap > m_areaLocMap; //区域映射 + + QList m_locationOrderList; //< location_id: 按location_no排序 + QMap m_deviceGroupDescriptionMap; +}; + +#endif // CEventDataCollect_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventDelegate.cpp b/product/src/gui/plugin/EventWidget_pad/CEventDelegate.cpp new file mode 100644 index 00000000..3de1161c --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventDelegate.cpp @@ -0,0 +1,306 @@ +#include "CEventDelegate.h" +#include +#include +#include +#include "CEventMsgInfo.h" +#include "CEventItemModel.h" +#include "CEventHistoryModel.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" +#include "pub_logger_api/logger.h" +#include +#include +#include +CEventDelegate::CEventDelegate(QObject *parent) + : QStyledItemDelegate(parent), + m_pModel(Q_NULLPTR), + m_pHisModel(Q_NULLPTR), + m_selectIsEmpty(false), + m_enableWave(true) +{ + loadColorConfig(); +} + +void CEventDelegate::setEnableWave(bool isNeed) +{ + m_enableWave = isNeed; +} + +void CEventDelegate::setEventModel(CEventItemModel *model) +{ + m_pHisModel = NULL; + m_pModel = model; +} + +void CEventDelegate::setHisEventModel(CEventHistoryModel *model) +{ + m_pModel = NULL; + m_pHisModel = model; +} + +void CEventDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + if(!index.isValid()) + { + return; + } + QColor fillColor; + QColor penColor; + bool select = option.state & QStyle::State_Selected; + + //< Common + if(m_pModel != NULL) + { + EventMsgPtr info = m_pModel->getAlarmInfo(index); + + if(info != Q_NULLPTR) + { + painter->save(); + if(AS_ALARM_RTN == info->alm_style) + { + if(select) + { + fillColor = m_selectBackgroundColor; + if(m_selectIsEmpty) + { + penColor = m_activeTextMap[info->priorityOrder]; + }else + { + penColor = m_selectTextColor; + } + } + else + { + penColor = m_resumeTextMap[info->priorityOrder]; + fillColor = m_backgroundMap[info->priorityOrder]; + } + }else + { + if(select) + { + fillColor = m_selectBackgroundColor; + if(m_selectIsEmpty) + { + penColor = m_activeTextMap[info->priorityOrder]; + }else + { + penColor = m_selectTextColor; + } + } + else + { + penColor = m_activeTextMap[info->priorityOrder]; + fillColor = m_backgroundMap[info->priorityOrder]; + } + } + + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + if(m_enableWave && REAL_BUTTON_COLUMN == index.column() && !info->wave_file.isEmpty()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40-40-40, option.rect.height()/2-10, -12-40-40, -(option.rect.height()/2-10)); + std::string style = iot_public::CFileStyle::getCurStyle(); + QString file = iot_public::CFileUtil::getPathOfResFile("gui/icon/alarm/wave_"+style+".png").c_str(); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(file); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + painter->drawText(option.rect, m_pModel->data(index, Qt::TextAlignmentRole).toInt(), m_pModel->data(index).toString()); + painter->restore(); + } + }else if(m_pHisModel != NULL) + { + EventMsgPtr info = m_pHisModel->getAlarmInfo(index); + + if(info != Q_NULLPTR) + { + painter->save(); + if(AS_ALARM_RTN == info->alm_style) + { + if(select) + { + fillColor = m_selectBackgroundColor; + if(m_selectIsEmpty) + { + penColor = m_activeTextMap[info->priorityOrder]; + }else + { + penColor = m_selectTextColor; + } + } + else + { + penColor = m_resumeTextMap[info->priorityOrder]; + fillColor = m_backgroundMap[info->priorityOrder]; + } + }else + { + if(select) + { + fillColor = m_selectBackgroundColor; + if(m_selectIsEmpty) + { + penColor = m_activeTextMap[info->priorityOrder]; + }else + { + penColor = m_selectTextColor; + } + } + else + { + penColor = m_activeTextMap[info->priorityOrder]; + fillColor = m_backgroundMap[info->priorityOrder]; + } + } + painter->setPen(penColor); + painter->fillRect(option.rect, fillColor); + if(m_enableWave && HIS_BUTTON_COLUMN == index.column() && !info->wave_file.isEmpty()) + { + painter->save(); + QStyleOptionButton button; + button.state |= QStyle::State_Enabled; + button.rect = option.rect; + + button.rect.adjust(option.rect.width() - 40-40-40, option.rect.height()/2-10, -12-40-40, -(option.rect.height()/2-10)); + std::string style = iot_public::CFileStyle::getCurStyle(); + QString file = iot_public::CFileUtil::getPathOfResFile("gui/icon/alarm/wave_"+style+".png").c_str(); + button.iconSize = QSize(button.rect.width()+2,button.rect.height()+2); + button.icon = QIcon(file); + button.features = QStyleOptionButton::Flat; + QApplication::style()->drawControl(QStyle::CE_PushButton,&button,painter); + painter->restore(); + } + painter->drawText(option.rect, m_pHisModel->data(index, Qt::TextAlignmentRole).toInt(), m_pHisModel->data(index).toString()); + painter->restore(); + } + } +} + +bool CEventDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if(!index.isValid()) + { + return false; + } + if(m_pModel != NULL) + { + if(index.column() != REAL_BUTTON_COLUMN) + { + return false; + } + EventMsgPtr info = m_pModel->getAlarmInfo(index); + QMouseEvent *mouseEvent = static_cast(event); + if(info && m_enableWave && !info->wave_file.isEmpty()) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 122, option.rect.height()/2-10, -90, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QString wave = info->wave_file; + wave = QString("%1%2%3").arg("\"").arg(wave).arg("\""); + LOGINFO("录波文件为:%s",wave.toStdString().c_str()); + + const std::string strProc = std::move(iot_public::CFileUtil::getPathOfBinFile( + std::string("WaveAnalyze") + iot_public::CFileUtil::getProcSuffix())); + if(strProc.empty()) + LOGERROR("未找到可执行文件WaveAnalyze"); + else + QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(wave)); + } + } + } + }else + { + if(index.column() != HIS_BUTTON_COLUMN) + { + return false; + } + EventMsgPtr info = m_pHisModel->getAlarmInfo(index); + QMouseEvent *mouseEvent = static_cast(event); + if(info && m_enableWave && !info->wave_file.isEmpty()) + { + if(mouseEvent != NULL && mouseEvent->button() == Qt::LeftButton && mouseEvent->type() == QMouseEvent::MouseButtonPress) + { + QStyleOptionButton button; + button.rect = option.rect; + button.rect.adjust(option.rect.width() - 122, option.rect.height()/2-10, -90, -(option.rect.height()/2-10)); + QRect rect = button.rect; + if(rect.contains(mouseEvent->pos())) + { + QString wave = info->wave_file; + wave = QString("%1%2%3").arg("\"").arg(wave).arg("\""); + LOGINFO("录波文件为:%s",wave.toStdString().c_str()); + + const std::string strProc = std::move(iot_public::CFileUtil::getPathOfBinFile( + std::string("WaveAnalyze") + iot_public::CFileUtil::getProcSuffix())); + if(strProc.empty()) + LOGERROR("未找到可执行文件WaveAnalyze"); + else + QProcess::startDetached(QString("%1 %2").arg(strProc.c_str()).arg(wave)); + } + } + } + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} +void CEventDelegate::loadColorConfig() +{ + QString filePath = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/alarm_color_define.xml"); + QDomDocument document; + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) + { + LOGINFO("loadColorConfig Failed!"); + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement element = document.documentElement(); + QDomNode node = element.firstChild(); + while(!node.isNull()) + { + QDomElement attr = node.toElement(); + if(!attr.isNull()) + { + if(QString("Level") == attr.tagName()) + { + int priority = attr.attribute("priority").toInt(); + m_backgroundMap[priority] = QColor(attr.attribute("background_color")); + m_alternatingMap[priority] = QColor(attr.attribute("alternating_color")); + m_confirmMap[priority] = QColor(attr.attribute("confirm_color")); + + m_activeTextMap[priority] = QColor(attr.attribute("active_text_color")); + m_confirmTextMap[priority] = QColor(attr.attribute("confirm_text_color")); + m_resumeTextMap[priority] = QColor(attr.attribute("resume_text_color")); + } + else if(QString("Select") == attr.tagName()) + { + m_selectBackgroundColor = QColor(attr.attribute("background_color")); + if(attr.attribute("text_color").isEmpty()) + { + m_selectIsEmpty = true; + }else + { + m_selectTextColor = QColor(attr.attribute("text_color")); + } + } + } + node = node.nextSibling(); + } +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventDelegate.h b/product/src/gui/plugin/EventWidget_pad/CEventDelegate.h new file mode 100644 index 00000000..185c06ae --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventDelegate.h @@ -0,0 +1,50 @@ +#ifndef CEVENTDELEGATE_H +#define CEVENTDELEGATE_H + +#include +class CEventItemModel; +class CEventHistoryModel; + +class CEventDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CEventDelegate(QObject *parent = 0); + + void setEnableWave(bool isNeed); + + void setEventModel(CEventItemModel *model); + void setHisEventModel(CEventHistoryModel *model); + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + bool editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; +private: + void loadColorConfig(); +private: + CEventItemModel *m_pModel; + CEventHistoryModel *m_pHisModel; + //< background color + QMap m_backgroundMap; + QMap m_alternatingMap; + QMap m_confirmMap; + + //< text color + QMap m_activeTextMap; + QMap m_confirmTextMap; + QMap m_resumeTextMap; + + //< select color + QColor m_selectBackgroundColor; + QColor m_selectTextColor; + + //< no item + QColor m_emptyBackgroundColor; + QColor m_emptyTipColor; + QString m_emptyTip; + + bool m_selectIsEmpty; + + bool m_enableWave; +}; + +#endif // CEVENTDELEGATE_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeItem.cpp b/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeItem.cpp new file mode 100644 index 00000000..20db83b3 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeItem.cpp @@ -0,0 +1,109 @@ +#include "CEventDeviceTreeItem.h" + +const int TypeRole = Qt::UserRole + 1; +CEventDeviceTreeItem::CEventDeviceTreeItem(const QString &data, CEventDeviceTreeItem *parent) + : m_tag(QString()), m_nType(0), + m_parentItem(parent) +{ + if(m_parentItem) + { + m_parentItem->m_childItems.append(this); + } + + m_data = data; + m_checkState = Qt::Checked; +} + +CEventDeviceTreeItem::~CEventDeviceTreeItem() +{ + qDeleteAll(m_childItems); + m_childItems.clear(); +} + +CEventDeviceTreeItem *CEventDeviceTreeItem::child(int row) +{ + return m_childItems.value(row); +} + +CEventDeviceTreeItem *CEventDeviceTreeItem::parentItem() +{ + return m_parentItem; +} + +int CEventDeviceTreeItem::row() const +{ + if (m_parentItem) + { + return m_parentItem->m_childItems.indexOf(const_cast(this)); + } + + return 0; +} + +int CEventDeviceTreeItem::childCount() const +{ + return m_childItems.count(); +} + +int CEventDeviceTreeItem::columnCount() const +{ + return 1; +} + +QVariant CEventDeviceTreeItem::data(Qt::ItemDataRole role) const +{ + if(Qt::DisplayRole == role) + { + return m_data; + } + else if(Qt::UserRole == role) + { + return m_tag; + } + else if(Qt::CheckStateRole == role) + { + return m_checkState; + } + else if (Qt::ItemDataRole(TypeRole) == role) + { + return m_nType; + } + return QVariant(); +} + +bool CEventDeviceTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) +{ + if(Qt::DisplayRole == role) + { + m_data = value.toString(); + return true; + } + else if(Qt::UserRole == role) + { + m_tag = value.toString(); + return true; + } + else if(Qt::CheckStateRole == role) + { + m_checkState = (Qt::CheckState)value.toInt(); + return true; + } + else if (TypeRole == role) + { + m_nType = value.toInt(); + return true; + } + return false; +} + +bool CEventDeviceTreeItem::removeChildren(int position, int count, int columns) +{ + Q_UNUSED(columns) + if (position < 0 || position + count > m_childItems.size()) + return false; + + for (int row = 0; row < count; ++row) + delete m_childItems.takeAt(position); + + return true; +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeItem.h b/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeItem.h new file mode 100644 index 00000000..edda0d44 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeItem.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CEVENTDEVICETREEITEM_H +#define CEVENTDEVICETREEITEM_H + +#include +#include + +extern const int TypeRole; +class CEventDeviceTreeItem +{ +public: + explicit CEventDeviceTreeItem(const QString &data = QString(), CEventDeviceTreeItem *parentItem = Q_NULLPTR); + ~CEventDeviceTreeItem(); + + CEventDeviceTreeItem *child(int row); + CEventDeviceTreeItem *parentItem(); + + int row() const; + + int childCount() const; + int columnCount() const; + + QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; + bool setData(const QVariant &value, Qt::ItemDataRole role); + bool removeChildren(int position, int count, int columns); +private: + QString m_data; + QString m_tag; + int m_nType; + Qt::CheckState m_checkState; + + QList m_childItems; + CEventDeviceTreeItem *m_parentItem; +}; + +#endif // CEVENTDEVICETREEITEM_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeModel.cpp b/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeModel.cpp new file mode 100644 index 00000000..9e61faf1 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeModel.cpp @@ -0,0 +1,322 @@ +#include "CEventDeviceTreeItem.h" +#include "CEventDeviceTreeModel.h" +#include "CEventMsgManage.h" +#include "CEventDataCollect.h" +#include + +CEventDeviceTreeModel::CEventDeviceTreeModel(QObject *parent) + : QAbstractItemModel(parent) +{ + rootItem = new CEventDeviceTreeItem(); + m_sysInfoItem = NULL; +} + +CEventDeviceTreeModel::~CEventDeviceTreeModel() +{ + m_devTagIndex.clear(); + m_devNameIndex.clear(); + delete rootItem; +} + +void CEventDeviceTreeModel::setupModelData(const QMap > > locationInfos, const QList &locationList) +{ + for(int nLocIndex(0); nLocIndexlocationDescription(locationList[nLocIndex]); + CEventDeviceTreeItem * location = new CEventDeviceTreeItem(locDesc, rootItem); + location->setData(TYPE_LOCATION,Qt::ItemDataRole(TypeRole)); + const QVector > vec = locationInfos.value(locationList[nLocIndex]); + for(int nDevIndex(0); nDevIndex < vec.size(); ++nDevIndex) + { + CEventDeviceTreeItem * device = new CEventDeviceTreeItem(vec.at(nDevIndex).second, location); + device->setData(TYPE_DEVGROUP, Qt::ItemDataRole(TypeRole)); + device->setData(vec.at(nDevIndex).first, Qt::UserRole); + QModelIndex modelIndex = createIndex(nDevIndex, 0, device); + m_devTagIndex.insert(vec.at(nDevIndex).first, modelIndex); + m_devNameIndex.insert(locDesc + "." + vec.at(nDevIndex).second, modelIndex); + } + } + + CEventDeviceTreeItem * location = new CEventDeviceTreeItem(QString(tr("系统信息")), rootItem); + location->setData(TYPE_SYSINFO, Qt::ItemDataRole(TypeRole)); + m_sysInfoItem = location; +} + +const HashIndex &CEventDeviceTreeModel::indexTagList() const +{ + return m_devTagIndex; +} + +const HashIndex &CEventDeviceTreeModel::indexNameList() const +{ + return m_devNameIndex; +} + +QModelIndex CEventDeviceTreeModel::indexOfDeviceTag(const QString &tag) +{ + return m_devTagIndex.value(tag, QModelIndex()); +} + +QModelIndex CEventDeviceTreeModel::indexOfDeviceName(const QString &name) +{ + return m_devNameIndex.value(name, QModelIndex()); +} + +QVariant CEventDeviceTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section) + Q_UNUSED(orientation) + Q_UNUSED(role) + return QVariant(); +} + +QModelIndex CEventDeviceTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + { + return QModelIndex(); + } + + CEventDeviceTreeItem *parentItem; + + if (!parent.isValid()) + { + parentItem = rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + CEventDeviceTreeItem *childItem = parentItem->child(row); + if (childItem) + { + return createIndex(row, column, childItem); + } + else + { + return QModelIndex(); + } +} + +QModelIndex CEventDeviceTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + CEventDeviceTreeItem *childItem = static_cast(index.internalPointer()); + + CEventDeviceTreeItem *parentItem = childItem->parentItem(); + if (parentItem == rootItem) + { + return QModelIndex(); + } + + return createIndex(parentItem->row(), 0, parentItem); +} + +int CEventDeviceTreeModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + { + return 0; + } + + CEventDeviceTreeItem *parentItem; + if (!parent.isValid()) + { + parentItem = rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + return parentItem->childCount(); +} + +int CEventDeviceTreeModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + { + return static_cast(parent.internalPointer())->columnCount(); + } + else + { + return rootItem->columnCount(); + } +} + + +QVariant CEventDeviceTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.column()) + { + return QVariant(); + } + + CEventDeviceTreeItem *item = static_cast(index.internalPointer()); + int itemType = item->data(Qt::ItemDataRole(TypeRole)).toInt(); + + if (Qt::DisplayRole == role) + { + const QString &deviceGroup = item->data(Qt::UserRole).toString(); + if (itemType == enTreeNodeType::TYPE_LOCATION) + { + return item->data(Qt::DisplayRole).toString(); + } + else if (itemType == enTreeNodeType::TYPE_SYSINFO) + { + return QString(tr("系统信息")) + QString(" [%1]").arg(m_eventDeviceGroupStatistical.value(deviceGroup,0)); + } + else{ + if(deviceGroup.isEmpty()) + { + return item->data(Qt::DisplayRole).toString(); + } + else{ + return item->data(Qt::DisplayRole).toString() + QString(" [%1]").arg(m_eventDeviceGroupStatistical.value(deviceGroup,0)); + } + } + } + else if(Qt::CheckStateRole == role && itemType != enTreeNodeType::TYPE_LOCATION) + { + return item->data(Qt::CheckStateRole); + } + + return QVariant(); +} + +bool CEventDeviceTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() || index.column()) + { + return false; + } + if(Qt::CheckStateRole == role) + { + emit itemCheckStateChanged(static_cast(index.internalPointer())->data(Qt::UserRole).toString(), value.toBool()); + } + return static_cast(index.internalPointer())->setData(value, (Qt::ItemDataRole)role); +} + +Qt::ItemFlags CEventDeviceTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + + if(!index.column()) + { + return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable; + } + + return QAbstractItemModel::flags(index); +} + +void CEventDeviceTreeModel::setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + CEventDeviceTreeItem * pItem = static_cast(index.internalPointer()); + if(pItem) + { + int nChildCount = pItem->childCount(); + for( int nIndex(0); nIndex < nChildCount; nIndex++) + { + pItem->child(nIndex)->setData(state, Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->child(nIndex)->data(Qt::UserRole).toString(), state); + } + } +} + +void CEventDeviceTreeModel::setAllDeviceCheckState(const Qt::CheckState &state) +{ + HashIndex::const_iterator iter = m_devTagIndex.constBegin(); + while (iter != m_devTagIndex.constEnd()) + { + CEventDeviceTreeItem * pItem = static_cast(iter.value().internalPointer()); + if(pItem) + { + pItem->setData(state, Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->data(Qt::UserRole).toString(), state); + } + ++iter; + } + + if(m_sysInfoItem) + { + m_sysInfoItem->setData(state, Qt::CheckStateRole); + emit itemCheckStateChanged(m_sysInfoItem->data(Qt::UserRole).toString(), state); + } +} + +void CEventDeviceTreeModel::removeData() +{ + m_eventDeviceGroupStatistical.clear(); + QModelIndex modelindex = QModelIndex(); + if(rootItem->childCount()>0) + { + beginRemoveRows(modelindex, 0, rootItem->childCount()-1); + rootItem->removeChildren(0, rootItem->childCount(), rootItem->columnCount()); + endRemoveRows(); + } +} + +QHash CEventDeviceTreeModel::getDeviceStatisticalInfo() +{ + return m_eventDeviceGroupStatistical; +} + +void CEventDeviceTreeModel::slotDevTreeUpdate() +{ + m_eventDeviceGroupStatistical.clear(); + m_eventDeviceGroupStatistical = CEventMsgManage::instance()->getDevGStatisticalInfo(); +} + +void CEventDeviceTreeModel::slotHisDevTreeUpdate(QList eventList) +{ + m_eventDeviceGroupStatistical.clear(); + + QList::const_iterator iter = eventList.constBegin(); + for(; iter != eventList.constEnd(); iter++) + { + m_eventDeviceGroupStatistical[(*iter)->dev_group_tag] += 1; + } +} +void CEventDeviceTreeModel::slotTreeCheckBoxState(const QModelIndex & index) +{ + if(!index.isValid()) + { + return; + } + CEventDeviceTreeItem *pItem = static_cast(index.internalPointer()); + if(pItem) + { + int itemType = pItem->data(Qt::ItemDataRole(TypeRole)).toInt(); + if (itemType == enTreeNodeType::TYPE_LOCATION) + { + return; + } + + if(data(index , Qt::CheckStateRole) == Qt::Checked) + { + pItem->setData(Qt::Unchecked , Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->data(Qt::UserRole).toString(), false); + } + else + { + pItem->setData(Qt::Checked , Qt::CheckStateRole); + emit itemCheckStateChanged(pItem->data(Qt::UserRole).toString(), true); + } + } + //beginResetModel(); + sort(0); + //endResetModel(); + +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeModel.h b/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeModel.h new file mode 100644 index 00000000..fa39712e --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeModel.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CEVENTDEVICETREEMODEL_H +#define CEVENTDEVICETREEMODEL_H + +#include +#include +#include +#include +#include "CEventMsgInfo.h" + +typedef QHash< QString, QModelIndex > HashIndex; //< Device + +class CEventDeviceTreeItem; + +enum enTreeNodeType{ + TYPE_LOCATION = 0, + TYPE_DEVGROUP, + TYPE_SYSINFO +}; + +class CEventDeviceTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit CEventDeviceTreeModel(QObject *parent = 0); + ~CEventDeviceTreeModel(); + + //< @param locationInfos [ locationDesc[ devTag, devDesc ] ] + void setupModelData(const QMap > > locationInfos, const QList &locationList); + + const HashIndex &indexTagList() const; + + const HashIndex &indexNameList() const; + + QModelIndex indexOfDeviceTag(const QString &tag); + + QModelIndex indexOfDeviceName(const QString &name); + + QVariant headerData(int section, Qt::Orientation orientation,int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column,const QModelIndex &parent = QModelIndex()) const override; + + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void setDeviceCheckState(const QModelIndex &index, const Qt::CheckState &state); + + void setAllDeviceCheckState(const Qt::CheckState &state); + + void removeData(); + + QHash getDeviceStatisticalInfo(); + +signals: + void itemCheckStateChanged(const QString &device, const bool &checked); + +public slots: + /** + * @brief slotDevTreeUpdate 实时事件 + */ + void slotDevTreeUpdate(); + + /** + * @brief slotDevTreeUpdate 历史事件 + * @param eventList + */ + void slotHisDevTreeUpdate(QList eventList); + void slotTreeCheckBoxState(const QModelIndex & index); +private: + CEventDeviceTreeItem *rootItem; + HashIndex m_devTagIndex; + HashIndex m_devNameIndex; + CEventDeviceTreeItem* m_sysInfoItem; + QHash m_eventDeviceGroupStatistical; //<设备组告警数量统计 +}; + +#endif // CEVENTDEVICETREEMODEL_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeView.cpp b/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeView.cpp new file mode 100644 index 00000000..f85d3eaf --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeView.cpp @@ -0,0 +1,7 @@ +#include "CEventDeviceTreeView.h" + +CEventDeviceTreeView::CEventDeviceTreeView(QWidget *parent) + : QTreeView(parent) +{ + +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeView.h b/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeView.h new file mode 100644 index 00000000..8c388b02 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventDeviceTreeView.h @@ -0,0 +1,14 @@ +#ifndef CEVENTDEVICETREEVIEW_H +#define CEVENTDEVICETREEVIEW_H + +#include + +class CEventDeviceTreeView : public QTreeView +{ + Q_OBJECT +public: + CEventDeviceTreeView(QWidget *parent = Q_NULLPTR); + +}; + +#endif // CEVENTDEVICETREEVIEW_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventFilterDialog.cpp b/product/src/gui/plugin/EventWidget_pad/CEventFilterDialog.cpp new file mode 100644 index 00000000..2d6f1c9c --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventFilterDialog.cpp @@ -0,0 +1,823 @@ +#include "CEventFilterDialog.h" +#include "ui_CEventFilterDialog.h" +#include "CEventDataCollect.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include + +int CEventFilterDialog::windowMinWidth() +{ + return m_nMinWidth; +} + +void CEventFilterDialog::setWindowMinWidth(int nWidth) +{ + m_nMinWidth = nWidth; + setMinimumWidth(m_nMinWidth); +} + +int CEventFilterDialog::windowMinHeigth() +{ + return m_nMinHeight; +} + +void CEventFilterDialog::setWindowMinHeigth(int nHeight) +{ + m_nMinHeight = nHeight; + setMinimumHeight(m_nMinHeight); +} + +CEventFilterDialog::CEventFilterDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CEventFilterDialog), + m_rtdbAccess(Q_NULLPTR), + m_nMinHeight(0), + m_nMinWidth(0) +{ + + ui->setupUi(this); + + ui->subSystem->setView(new QListView()); + ui->deviceType->setView(new QListView()); + + + /* + * 2023年1月5日08:48:28 + * 异常不需要的 + */ + ui->alarmTypeFilter->hide(); + ui->keywordFilterEnable->hide(); + ui->levelFilter->hide(); + ui->locationFilter->hide(); + ui->regionFilter->hide(); + ui->regionFilter->hide(); + + ui->startTime->setCalendarPopup(true); + ui->endTime->setCalendarPopup(true); + ui->alarmTypeFilter->setHidden(true); +} + +CEventFilterDialog::~CEventFilterDialog() +{ + if(m_rtdbAccess) + { + delete m_rtdbAccess; + } + m_rtdbAccess = Q_NULLPTR; + delete ui; +} + +void CEventFilterDialog::initialize(E_ALARM_VIEW view) +{ + m_view=view; + m_rtdbAccess = new iot_dbms::CRdbAccess(); + ui->level->setSelectionMode(QAbstractItemView::MultiSelection); + //ui->location->setSelectionMode(QAbstractItemView::MultiSelection); + ui->region->setSelectionMode(QAbstractItemView::MultiSelection); + ui->type->setSelectionMode(QAbstractItemView::MultiSelection); + + QList priorityList = CEventDataCollect::instance()->priorityList(); + foreach (int priority, priorityList) + { + ui->level->addItem(CEventDataCollect::instance()->priorityDescription(priority)); + } + + // QList locationList = CEventDataCollect::instance()->locationList(); + + // foreach (int location, locationList) + // { + // ui->location->addItem(CEventDataCollect::instance()->locationDescription(location)); + // } + m_areaInfoMap = CEventDataCollect::instance()->areaInfoMap(); + m_areaLocMap = CEventDataCollect::instance()->areaLocMap(); + ui->area->clear(); + ui->area->setColumnCount(1); + bool isArea = false; + QMap >::iterator it = m_areaLocMap.begin(); + while (it != m_areaLocMap.end()) { + if(it.key()<=0) + { + QVector locVec = it.value(); + for(int index(0);indexsetText(0,getDescByAreaId(locVec.at(index))); + firstItem->setData(0,Qt::UserRole,locVec.at(index)); + firstItem->setData(0,Qt::UserRole+1,it.key()); + firstItem->setCheckState(0,Qt::Unchecked); + firstItem->setToolTip(0,getDescByAreaId(locVec.at(index))); + ui->area->addTopLevelItem(firstItem); + } + }else + { + QTreeWidgetItem *firstItem = new QTreeWidgetItem(); + firstItem->setText(0,getDescByAreaId(it.key())); + firstItem->setData(0,Qt::UserRole,it.key()); + firstItem->setData(0,Qt::UserRole+1,-1); + firstItem->setCheckState(0,Qt::Unchecked); + firstItem->setToolTip(0,getDescByAreaId(it.key())); + QVector locVec = it.value(); + for(int index(0);indexsetText(0,getDescByAreaId(locVec.at(index))); + secondItem->setData(0,Qt::UserRole,locVec.at(index)); + secondItem->setData(0,Qt::UserRole+1,it.key()); + secondItem->setCheckState(0,Qt::Unchecked); + secondItem->setToolTip(0,getDescByAreaId(locVec.at(index))); + firstItem->addChild(secondItem); + } + ui->area->addTopLevelItem(firstItem); + isArea = true; + } + + it++; + } + //< 无区域配置时不缩进,尽可能展示完全 + if(!isArea) + { + ui->area->setIndentation(0); + } + QList regionList = CEventDataCollect::instance()->regionList(); + foreach (int region, regionList) + { + ui->region->addItem(CEventDataCollect::instance()->regionDescription(region)); + } + + QList alarmStatusList = CEventDataCollect::instance()->alarmStatusList(); + foreach (int alarmStatus, alarmStatusList) + { + ui->type->addItem(CEventDataCollect::instance()->eventShowStatusDescription(alarmStatus)); + } + + iot_public::CSysInfoInterfacePtr spSysInfo; + if (iot_public::createSysInfoInstance(spSysInfo)) + { + std::vector vecSubsystemInfo; + spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); + foreach (iot_public::SSubsystemInfo info, vecSubsystemInfo) + { + if(info.nId <= CN_AppId_COMAPP) + { + continue; + } + ui->subSystem->addItem(QString::fromStdString(info.strDesc)); + } + } + + ui->subSystem->setCurrentIndex(-1); + + connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateFilter())); + connect(ui->cancle, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->checkLevel, SIGNAL(pressed()), this, SLOT(slot_checkLevelPressed())); + connect(ui->checkLevel, SIGNAL(stateChanged(int)), this, SLOT(slot_levelSelectChange(int))); + connect(ui->level, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckLevelState())); + connect(ui->checkLocation, SIGNAL(pressed()), this, SLOT(slot_checkLocationPressed())); + connect(ui->checkLocation, SIGNAL(stateChanged(int)), this, SLOT(slot_locationSelectChange(int))); + connect(ui->area, &QTreeWidget::itemChanged, this, &CEventFilterDialog::slot_updateCheckLocationState); + connect(ui->checkRegion, SIGNAL(pressed()), this, SLOT(slot_checkRegionPressed())); + connect(ui->checkRegion, SIGNAL(stateChanged(int)), this, SLOT(slot_regionSelectChange(int))); + connect(ui->region, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckRegionState())); + connect(ui->checkType, SIGNAL(pressed()), this, SLOT(slot_checkTypePressed())); + connect(ui->checkType, SIGNAL(stateChanged(int)), this, SLOT(slot_typeSelectChange(int))); + connect(ui->type, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateCheckTypeState())); + connect(ui->subSystem, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_updateDevice(QString))); + ui->subSystem->setCurrentIndex(0); +} + +void CEventFilterDialog::setLevelFilterEnable(const bool &isLevelFilterEnable) +{ + ui->levelFilter->setChecked(isLevelFilterEnable); +} + +void CEventFilterDialog::setLevelFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->level->count(); nIndex++) + { + int nLevelID = CEventDataCollect::instance()->priorityId(ui->level->item(nIndex)->text()); + if(filter.contains(nLevelID)) + { + ui->level->item(nIndex)->setSelected(true); + } + else + { + ui->level->item(nIndex)->setSelected(false); + } + } +} + +void CEventFilterDialog::setLocationFilterEnable(const bool &isLocationFilterEnable) +{ + ui->locationFilter->setChecked(isLocationFilterEnable); +} + +void CEventFilterDialog::setLocationFilter(const QList &filter) +{ + if(filter.isEmpty()) + { + return; + } + ui->area->blockSignals(true); + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index); + int areaId = firstItem->data(0,Qt::UserRole).toInt(); + if(filter.contains(areaId)) + { + firstItem->setCheckState(0,Qt::Checked); + } + int childCount = firstItem->childCount(); + + for(int locIndex(0);locIndex child(locIndex); + int locId = secondItem->data(0,Qt::UserRole).toInt(); + if(filter.contains(locId)) + { + secondItem->setCheckState(0,Qt::Checked); + } + } + } + int selectNum = 0; + int allNum = 0; + for(int index(0);indexarea->topLevelItem(index); + if(firstItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + int childNum = firstItem->childCount(); + for(int secIndex(0);secIndexchild(secIndex); + allNum++; + if(secondItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + } + } + + if(selectNum == 0) + { + ui->checkLocation->setCheckState(Qt::Unchecked); + }else if(selectNum == allNum) + { + ui->checkLocation->setCheckState(Qt::Checked); + }else + { + ui->checkLocation->setCheckState(Qt::PartiallyChecked); + } + ui->area->blockSignals(false); +} + +void CEventFilterDialog::setRegionFilterEnable(const bool &isRegionFilterEnable) +{ + ui->regionFilter->setChecked(isRegionFilterEnable); +} + +void CEventFilterDialog::setRegionFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->region->count(); nIndex++) + { + int nRegionID = CEventDataCollect::instance()->regionId(ui->region->item(nIndex)->text()); + if(filter.contains(nRegionID)) + { + ui->region->item(nIndex)->setSelected(true); + } + else + { + ui->region->item(nIndex)->setSelected(false); + } + } +} + +void CEventFilterDialog::setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable) +{ + ui->alarmTypeFilter->setChecked(isAlarmTypeEnable); +} + +void CEventFilterDialog::setAlarmTypeFilter(const QList &filter) +{ + for(int nIndex(0); nIndex < ui->type->count(); nIndex++) + { + int nAlarmTypeID = CEventDataCollect::instance()->eventStatusId(ui->type->item(nIndex)->text()); + if(filter.contains(nAlarmTypeID)) + { + ui->type->item(nIndex)->setSelected(true); + } + else + { + ui->type->item(nIndex)->setSelected(false); + } + } +} + +void CEventFilterDialog::setDeviceFilterEnable(const bool &filter) +{ + ui->deviceFilterEnable->setChecked(filter); +} + +void CEventFilterDialog::setSubSystem(const QString &subSystem) +{ + if(ui->deviceFilterEnable->isChecked()) + { + ui->subSystem->setCurrentText(subSystem); + } +} + +void CEventFilterDialog::setDeviceType(const QString &deviceType) +{ + if(ui->deviceFilterEnable->isChecked()) + { + ui->deviceType->setCurrentText(deviceType); + } +} + +void CEventFilterDialog::setTimeFilterEnable(const bool &filter) +{ + ui->timeFilterEnable->setChecked(filter); +} + +void CEventFilterDialog::setStartTimeFilter(const QDateTime &filter) +{ + if(ui->timeFilterEnable->isChecked()) + { + ui->startTime->setDateTime(filter); + } + else + { + QDateTime dataTime(QDateTime::currentDateTime()); + dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().minute(),0,0)); + ui->startTime->setDateTime(dataTime); + } +} + +void CEventFilterDialog::setEndTimeFilter(const QDateTime &filter) +{ + if(ui->timeFilterEnable->isChecked()) + { + ui->endTime->setDateTime(filter); + } + else + { + QDateTime dataTime(QDateTime::currentDateTime()); + dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().minute(),59,999)); + ui->endTime->setDateTime(QDateTime::currentDateTime()); + } +} + + +void CEventFilterDialog::setkeyWordFilterEnable(const bool &filter) +{ + ui->keywordFilterEnable->setChecked(filter); +} + +void CEventFilterDialog::setkeyWordFilteContent(const QString &content) +{ + if(ui->keywordFilterEnable->isChecked()) + { + ui->keyWord->setText(content); + } +} + +void CEventFilterDialog::setReturnFilterEnable(bool &filter) +{ + ui->returnFilterEnable->setChecked(filter); +} + +void CEventFilterDialog::setReturnFilter(bool &filter) +{ + if(filter) + { + ui->hasReturn->setChecked(true); + } + else + { + ui->notReturn->setChecked(true); + } +} + +void CEventFilterDialog::slot_updateFilter() +{ + bool isTimeFilter = ui->timeFilterEnable->isChecked(); + QDateTime startTime = QDateTime(); + QDateTime endTime = QDateTime(); + if(isTimeFilter) + { + startTime = ui->startTime->dateTime(); + endTime = ui->endTime->dateTime(); + } + if(startTime.toMSecsSinceEpoch() > endTime.toMSecsSinceEpoch()) + { + QMessageBox::information( 0, tr("提示"), tr("开始时间不能大于结束时间!")); + return; + } + if(m_view == E_ALARM_HIS_EVENT ) + { + if(!isTimeFilter) + { + QMessageBox::information( 0, tr("提示"), tr("历史事件过滤必须选择时间!")); + return; + } + + if((endTime.toMSecsSinceEpoch()-startTime.toMSecsSinceEpoch())/1000/3600/24 >= 90 ) + { + QMessageBox::information( 0, tr("提示"), tr("时间间隔不得超过90天!")); + return; + } + } + bool isLevelFilter = ui->levelFilter->isChecked(); + QList listLevel; + foreach (QListWidgetItem *item, ui->level->selectedItems()) + { + listLevel << CEventDataCollect::instance()->priorityId(item->text()); + } + + bool isLocationFilter = ui->locationFilter->isChecked(); + QList listLocation; + // foreach (QListWidgetItem *item, ui->location->selectedItems()) + // { + // listLocation << CEventDataCollect::instance()->locationId(item->text()); + // } + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index); + if(firstItem->checkState(0) == Qt::Checked) + { + listLocation.append(firstItem->data(0,Qt::UserRole).toInt()); + } + int locCount = firstItem->childCount(); + for(int locIndex(0);locIndexchild(locIndex); + if(secondItem->checkState(0) == Qt::Checked) + { + listLocation.append(secondItem->data(0,Qt::UserRole).toInt()); + } + } + } + + bool isRegionFilter = ui->regionFilter->isChecked(); + QList listRegion; + foreach (QListWidgetItem *item, ui->region->selectedItems()) + { + listRegion << CEventDataCollect::instance()->regionId(item->text()); + } + + bool isAlarmTypeFilter = ui->alarmTypeFilter->isChecked(); + QList listAlarmType; + foreach (QListWidgetItem *item, ui->type->selectedItems()) + { + listAlarmType << CEventDataCollect::instance()->eventStatusId(item->text()); + } + + bool isDeviceTypeFilter = ui->deviceFilterEnable->isChecked(); + QString subSystem = ui->subSystem->currentText(); + QString deviceType = ui->deviceType->currentText(); + + bool isKeyWordFilter = ui->keywordFilterEnable->isChecked(); + QString strKeyWord =ui->keyWord->text(); + + + bool isReturnFilter = ui->returnFilterEnable->isChecked(); + bool isReturn = ui->hasReturn->isChecked(); + emit sig_updateFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isAlarmTypeFilter, listAlarmType, + isDeviceTypeFilter, subSystem, deviceType, isKeyWordFilter, strKeyWord, isTimeFilter, startTime, endTime,isReturnFilter, isReturn); + accept(); +} + +//Level +void CEventFilterDialog::slot_checkLevelPressed() +{ + if( Qt::Unchecked == ui->checkLevel->checkState()) + { + ui->checkLevel->setTristate(false); + } +} + +void CEventFilterDialog::slot_levelSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->level->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->level->selectAll(); + } +} + +void CEventFilterDialog::slot_updateCheckLevelState() +{ + if( ui->level->count() == ui->level->selectedItems().count() ) + { + if( Qt::Checked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->level->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkLevel->checkState() ) + { + ui->checkLevel->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Location +void CEventFilterDialog::slot_checkLocationPressed() +{ + if( Qt::Unchecked == ui->checkLocation->checkState()) + { + ui->checkLocation->setTristate(false); + } +} + +void CEventFilterDialog::slot_locationSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + clearTreeSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + allTreeSelection(); + } +} + +void CEventFilterDialog::slot_updateCheckLocationState(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column); + ui->area->blockSignals(true); + if(item->parent() == NULL) //父节点 + { + childItemSelection(item); + }else if(item->childCount()<= 0) //子节点 + { + //parentItemSelection(item); + } + + int selectNum = 0; + int count = ui->area->topLevelItemCount(); + int allNum = 0; + for(int index(0);indexarea->topLevelItem(index); + if(firstItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + int childNum = firstItem->childCount(); + for(int secIndex(0);secIndexchild(secIndex); + allNum++; + if(secondItem->checkState(0) == Qt::Checked) + { + selectNum += 1; + } + } + } + + if(selectNum == 0) + { + ui->checkLocation->setCheckState(Qt::Unchecked); + }else if(selectNum == allNum) + { + ui->checkLocation->setCheckState(Qt::Checked); + }else + { + ui->checkLocation->setCheckState(Qt::PartiallyChecked); + } + + + ui->area->blockSignals(false); +} + +//Region +void CEventFilterDialog::slot_checkRegionPressed() +{ + if( Qt::Unchecked == ui->checkRegion->checkState()) + { + ui->checkRegion->setTristate(false); + } +} + +void CEventFilterDialog::slot_regionSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->region->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->region->selectAll(); + } +} + +void CEventFilterDialog::slot_updateCheckRegionState() +{ + if( ui->region->count() == ui->region->selectedItems().count() ) + { + if( Qt::Checked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->region->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkRegion->checkState() ) + { + ui->checkRegion->setCheckState(Qt::PartiallyChecked); + } + } +} + +//Type +void CEventFilterDialog::slot_checkTypePressed() +{ + if( Qt::Unchecked == ui->checkType->checkState()) + { + ui->checkType->setTristate(false); + } +} + +void CEventFilterDialog::slot_typeSelectChange(const int &state) +{ + if( Qt::Unchecked == (Qt::CheckState)state ) + { + ui->type->clearSelection(); + } + else if( Qt::Checked == (Qt::CheckState)state) + { + ui->type->selectAll(); + } +} + +void CEventFilterDialog::slot_updateCheckTypeState() +{ + if( ui->type->count() == ui->type->selectedItems().count() ) + { + if( Qt::Checked != ui->checkType->checkState() ) + { + ui->checkType->setCheckState(Qt::Checked); + } + + } + else if( 0 == ui->type->selectedItems().count() ) + { + if( Qt::Unchecked != ui->checkType->checkState() ) + { + ui->checkType->setCheckState(Qt::Unchecked); + } + } + else + { + if( Qt::PartiallyChecked != ui->checkType->checkState() ) + { + ui->checkType->setCheckState(Qt::PartiallyChecked); + } + } +} + +void CEventFilterDialog::slot_updateDevice(const QString &subSystem) +{ + int nSubSystemId = -1; + iot_public::CSysInfoInterfacePtr spSysInfo; + if (iot_public::createSysInfoInstance(spSysInfo)) + { + std::vector vecSubsystemInfo; + spSysInfo->getAllSubsystemInfo(vecSubsystemInfo); + foreach (iot_public::SSubsystemInfo info, vecSubsystemInfo) + { + if(subSystem.toStdString() == info.strDesc) + { + nSubSystemId = info.nId; + } + } + } + + ui->deviceType->clear(); + QList values; + + if(nSubSystemId != -1) + { + iot_dbms::CVarType subSystemId = nSubSystemId; + if(m_rtdbAccess->open("base", "dev_type_def")) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CONDINFO condition; + condition.relationop = ATTRCOND_EQU; + memcpy(condition.name, "sub_system",strlen("sub_system")); + condition.conditionval = subSystemId; + std::vector columns; + columns.push_back("description"); + + iot_dbms::CRdbQueryResult result; + if(m_rtdbAccess->select(condition, result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, value); + values.append(value); + } + } + } + } + foreach (iot_dbms::CVarType value, values) + { + ui->deviceType->addItem(value.c_str()); + } +} + +QString CEventFilterDialog::getDescByAreaId(int areaId) +{ + SAreaInfo info; + return m_areaInfoMap.value(areaId,info).stDes; +} + +void CEventFilterDialog::clearTreeSelection() +{ + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index)->setCheckState(0,Qt::Unchecked); + slot_updateCheckLocationState(ui->area->topLevelItem(index),0); + } +} + +void CEventFilterDialog::childItemSelection(QTreeWidgetItem *item) +{ + Qt::CheckState status = item->checkState(0); + + int count = item->childCount(); + for(int index(0);indexchild(index)->setCheckState(0,status); + } +} + +void CEventFilterDialog::parentItemSelection(QTreeWidgetItem *item) +{ + QTreeWidgetItem *parent = item->parent(); + int count = parent->childCount(); + int checkNum = 0; + for(int index(0);indexchild(index)->checkState(0) == Qt::Checked) + { + checkNum += 1; + } + } + if(checkNum == count) + { + parent->setCheckState(0,Qt::Checked); + }else if(checkNum == 0) + { + parent->setCheckState(0,Qt::Unchecked); + }else + { + parent->setCheckState(0,Qt::PartiallyChecked); + } +} + +void CEventFilterDialog::allTreeSelection() +{ + int count = ui->area->topLevelItemCount(); + for(int index(0);indexarea->topLevelItem(index)->setCheckState(0,Qt::Checked); + slot_updateCheckLocationState(ui->area->topLevelItem(index),0); + } +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventFilterDialog.h b/product/src/gui/plugin/EventWidget_pad/CEventFilterDialog.h new file mode 100644 index 00000000..fb19ffa8 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventFilterDialog.h @@ -0,0 +1,105 @@ +#ifndef CEVENTFILTERDIALOG_H +#define CEVENTFILTERDIALOG_H + +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "CEventMsgInfo.h" +#include +#include +#include + +namespace Ui { +class CEventFilterDialog; +} + +class CEventFilterDialog : public QDialog +{ + Q_OBJECT + //Q_PROPERTY(int windowMinWidth READ windowMinWidth WRITE setWindowMinWidth) + //Q_PROPERTY(int windowMinHeigth READ windowMinHeigth WRITE setWindowMinHeigth) + +public slots: + int windowMinWidth(); + void setWindowMinWidth(int nWidth); + int windowMinHeigth(); + void setWindowMinHeigth(int nHeight); + +public: + explicit CEventFilterDialog(QWidget *parent = 0); + ~CEventFilterDialog(); + + void initialize(E_ALARM_VIEW view); + + void setLevelFilterEnable(const bool &isLevelFilterEnable); + void setLevelFilter(const QList &filter); + void setLocationFilterEnable(const bool &isLocationFilterEnable); + void setLocationFilter(const QList &filter); + void setRegionFilterEnable(const bool &isRegionFilterEnable); + void setRegionFilter(const QList &filter); + void setAlarmTypeFilterEnable(const bool &isAlarmTypeEnable); + void setAlarmTypeFilter(const QList &filter); + void setDeviceFilterEnable(const bool &filter); + void setSubSystem(const QString &subSystem); + void setDeviceType(const QString &deviceType); + void setTimeFilterEnable(const bool &filter); + void setStartTimeFilter(const QDateTime &filter); + void setEndTimeFilter(const QDateTime &filter); + void setkeyWordFilterEnable(const bool &filter); + void setkeyWordFilteContent(const QString &content); + void setReturnFilterEnable(bool &filter); + void setReturnFilter(bool &filter); +signals: + /** + * @brief sig_updateFilter + * @param List level location region alarmType isKeyWordFilterEnable, keyWord, isTimeFilter startTime endTime isConfirmFilter confirm + */ + void sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime,bool,bool); + +private slots: + void slot_updateFilter(); + + //Level + void slot_checkLevelPressed(); + void slot_levelSelectChange(const int &state); + void slot_updateCheckLevelState(); + + //Station + void slot_checkLocationPressed(); + void slot_locationSelectChange(const int &state); + void slot_updateCheckLocationState(QTreeWidgetItem *item, int column); + + //Region + void slot_checkRegionPressed(); + void slot_regionSelectChange(const int &state); + void slot_updateCheckRegionState(); + + //AlarmType + void slot_checkTypePressed(); + void slot_typeSelectChange(const int &state); + void slot_updateCheckTypeState(); + + //DeviceType + void slot_updateDevice(const QString &subSystem); + +private: + QString getDescByAreaId(int areaId); + void clearTreeSelection(); + void childItemSelection(QTreeWidgetItem *item); + void parentItemSelection(QTreeWidgetItem *item); + void allTreeSelection(); + +private: + Ui::CEventFilterDialog *ui; + iot_dbms::CRdbAccess * m_rtdbAccess; + + QMap m_areaInfoMap; //区域信息 + + QMap > m_areaLocMap; //区域映射 + E_ALARM_VIEW m_view; + + int m_nMinWidth; + int m_nMinHeight; +}; + +#endif // CEVENTFILTERDIALOG_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventFilterDialog.ui b/product/src/gui/plugin/EventWidget_pad/CEventFilterDialog.ui new file mode 100644 index 00000000..d5bfc2a7 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventFilterDialog.ui @@ -0,0 +1,536 @@ + + + CEventFilterDialog + + + + 0 + 0 + 637 + 365 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + 过滤 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 设备类型 + + + true + + + false + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 时间 + + + true + + + false + + + + + + + + 结束时间 + + + + + + + false + + + + 2018 + 1 + 1 + + + + + 0 + 0 + 0 + 2000 + 1 + 1 + + + + + 2050 + 12 + 31 + + + + yyyy/MM/dd hh:mm + + + true + + + + + + + + + + + 开始时间 + + + + + + + + 2018 + 1 + 1 + + + + + 0 + 0 + 0 + 2000 + 1 + 1 + + + + + 2050 + 12 + 31 + + + + QDateTimeEdit::YearSection + + + yyyy/MM/dd hh:mm + + + true + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 确定 + + + + + + + 取消 + + + + + + + + + + + + 10 + 17 + 0 + 0 + + + + + 0 + 0 + + + + 优先级 + + + true + + + + + + 全选 + + + true + + + true + + + + + + + + + + + + 16 + 17 + 0 + 0 + + + + + 0 + 0 + + + + 位置 + + + true + + + + + + 全选 + + + true + + + + + + + + 200 + 0 + + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectItems + + + QAbstractItemView::ScrollPerPixel + + + QAbstractItemView::ScrollPerPixel + + + false + + + + 1 + + + + + + + + + + 22 + 17 + 0 + 0 + + + + + 0 + 0 + + + + 责任区 + + + true + + + + + + 全选 + + + true + + + + + + + + + + + true + + + + 28 + 17 + 0 + 0 + + + + + 0 + 0 + + + + 事件状态 + + + true + + + + + + 全选 + + + true + + + + + + + + + + + + 190 + 230 + 0 + 0 + + + + + 0 + 0 + + + + 事件内容关键字 + + + true + + + false + + + + + + + 0 + 0 + + + + + + + + + + 332 + 230 + 0 + 0 + + + + + 0 + 0 + + + + + 0 + 0 + + + + 复归 + + + true + + + false + + + + + + + 0 + 0 + + + + 已复归 + + + + + + + + 0 + 0 + + + + 未复归 + + + + + + + + + diff --git a/product/src/gui/plugin/EventWidget_pad/CEventForm.cpp b/product/src/gui/plugin/EventWidget_pad/CEventForm.cpp new file mode 100644 index 00000000..d0c3da2a --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventForm.cpp @@ -0,0 +1,1730 @@ +#include "CEventForm.h" +#include "ui_CEventForm.h" +#include "CEventMsgInfo.h" +#include +#include "CEventItemModel.h" +#include "CEventHistoryModel.h" +#include "CEventFilterDialog.h" +#include "CEventMsgManage.h" +#include "CEventDataCollect.h" +#include "CTableViewPrinter.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CEventDelegate.h" +#include "pub_utility_api/FileStyle.h" +#include +#include "pub_logger_api/logger.h" +#include "CAccidentReviewDialog.h" +#include "CEventDeviceTreeModel.h" +#include "CEventDeviceTreeItem.h" +#include + +CEventForm::CEventForm(QWidget *parent, bool editMode) : + QWidget(parent), + ui(new Ui::CEventForm), + m_pRealDelegate(NULL), + m_pHistoryDelegate(NULL), + m_pRealTimeModel(NULL), + m_pHistoryModel(NULL), + m_pDeviceModel(NULL), + m_pDeviceHisModel(NULL), + m_isEditMode(editMode), + m_thread(NULL), + m_hisSearch(NULL), + m_enableWave(false), + m_isNeedAccidentReview(true), + m_buttonGroup(Q_NULLPTR), + m_ncurIndex(0), + m_strAccidenPath(QString()) +{ + qRegisterMetaType("CEventMsgInfo"); + qRegisterMetaType("EventMsgPtr"); + qRegisterMetaType >("SetEventMsgPtr"); + qRegisterMetaType("ST_FILTER"); + + ui->setupUi(this); + initilize(); + if(!m_isEditMode) + { + m_hisSearch = new QThread(); + m_hisWork = new CEventHisThread(); + m_hisWork->moveToThread(m_hisSearch); + connect(m_hisSearch,&QThread::started,m_hisWork,&CEventHisThread::init,Qt::QueuedConnection); + connect(m_hisSearch,&QThread::finished,m_hisWork,&CEventHisThread::deleteLater,Qt::QueuedConnection); + m_buttonGroup = new QButtonGroup; + m_buttonGroup->setExclusive(true); + m_buttonGroup->addButton(ui->realEventButton,0); + m_buttonGroup->addButton(ui->hisEventButton,1); + connect(m_buttonGroup,SIGNAL(buttonClicked(int)),this,SLOT(updateStack(int))); + m_hisSearch->start(); + initModel(); + updateStack(0); + SetHideReal(); + + //< 放到构造函数中(打开两个窗口,关闭其中一个有问题) +// CEventDataCollect::instance()->initialize(); + + initFilter(); + ui->btn_tree_all_sel->resize(QSize(100,80)); + ui->btn_tree_none_sel->resize(QSize(100,80)); + + connect(CEventDataCollect::instance(), SIGNAL(sigEventStateChanged()), this, SLOT(slotRTEventStateChanged()), Qt::QueuedConnection); + connect(ui->clear, &QPushButton::clicked, this, &CEventForm::slotClearRTEvent); + connect(ui->closeBtn, &QPushButton::clicked, this, &CEventForm::closeBtnClicked); + connect(ui->flash, &QPushButton::clicked, this, &CEventForm::slotbtnFlash); + + connect(ui->btn_tree_all_sel, &QPushButton::clicked, this, &CEventForm::slotALlSel); + connect(ui->btn_tree_none_sel, &QPushButton::clicked, this, &CEventForm::slotNoneSel); + } + + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("event.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } + + { + //< 初始化实时设备树搜索框 + QHBoxLayout * pHBoxLayout = new QHBoxLayout(ui->treeView->header()); + m_pRealSearchEdit = new QLineEdit(ui->treeView->header()); + m_pRealSearchEdit->setObjectName("realSearchEdit"); + m_pRealSearchEdit->setTextMargins(0, 0, 21, 0); + m_pRealSearchEdit->setPlaceholderText(tr("按设备组关键字搜索")); + pHBoxLayout->addWidget(m_pRealSearchEdit); + pHBoxLayout->setContentsMargins(2,0,2,0); + pHBoxLayout->setSpacing(0); + ui->treeView->header()->setLayout(pHBoxLayout); + ui->treeView->header()->setObjectName("realDeviceHeader"); + m_pRealSearchButton = new QPushButton(this); + m_pRealSearchButton->setObjectName("realSearchButton"); + m_pRealSearchButton->setText(""); + m_pRealSearchButton->setMaximumSize(21, 22); + m_pRealSearchButton->setCursor(QCursor(Qt::ArrowCursor)); + QHBoxLayout * pSearchLayout = new QHBoxLayout(); + pSearchLayout->setContentsMargins(1, 1, 1, 1); + pSearchLayout->addStretch(); + pSearchLayout->addWidget(m_pRealSearchButton); + m_pRealSearchEdit->setLayout(pSearchLayout); + connect(m_pRealSearchEdit,SIGNAL(textChanged(QString)),this,SLOT(searchRealDeviceNamechange(QString))); + connect(m_pRealSearchEdit, &QLineEdit::returnPressed, this, &CEventForm::searchRealDeviceName); + connect(m_pRealSearchButton, &QPushButton::clicked, this, &CEventForm::searchRealDeviceName); + } + { + //< 初始化历史设备树搜索框 + QHBoxLayout * pHBoxLayout = new QHBoxLayout(ui->treeView_2->header()); + m_pHistorySearchEdit = new QLineEdit(ui->treeView_2->header()); + m_pHistorySearchEdit->setObjectName("hisSearchEdit"); + m_pHistorySearchEdit->setTextMargins(0, 0, 21, 0); + m_pHistorySearchEdit->setPlaceholderText(tr("按设备组关键字搜索")); + pHBoxLayout->addWidget(m_pHistorySearchEdit); + pHBoxLayout->setContentsMargins(2,0,2,0); + pHBoxLayout->setSpacing(0); + ui->treeView_2->header()->setLayout(pHBoxLayout); + ui->treeView_2->header()->setObjectName("hisDeviceHeader"); + m_pHistorySearchButton = new QPushButton(this); + m_pHistorySearchButton->setObjectName("hisSearchButton"); + m_pHistorySearchButton->setText(""); + m_pHistorySearchButton->setMaximumSize(21, 22); + m_pHistorySearchButton->setCursor(QCursor(Qt::ArrowCursor)); + QHBoxLayout * pSearchLayout = new QHBoxLayout(); + pSearchLayout->setContentsMargins(1, 1, 1, 1); + pSearchLayout->addStretch(); + pSearchLayout->addWidget(m_pHistorySearchButton); + m_pHistorySearchEdit->setLayout(pSearchLayout); + connect(m_pHistorySearchEdit, &QLineEdit::returnPressed, this, &CEventForm::searchHistoryDeviceName); + connect(m_pHistorySearchButton, &QPushButton::clicked, this, &CEventForm::searchHistoryDeviceName); + } + + m_timeIcon = new QPushButton(this); + m_myCalendar = new CMyCalendar(this); + QWidgetAction *widgetAction=new QWidgetAction(this); + m_timeMenu = new QMenu(this); + widgetAction->setDefaultWidget(m_myCalendar); + m_timeMenu->addAction(widgetAction); + m_timeIcon->setObjectName("iconButton"); + m_timeIcon->setText(""); + m_timeIcon->setMaximumSize(21, 22); + m_timeIcon->setCursor(QCursor(Qt::ArrowCursor)); + QHBoxLayout * pTimeLayout = new QHBoxLayout(); + pTimeLayout->setContentsMargins(1, 1, 1, 1); + pTimeLayout->addStretch(); + pTimeLayout->addWidget(m_timeIcon); + ui->lineEdit->setLayout(pTimeLayout); + connect(m_timeIcon,&QPushButton::clicked,this,&CEventForm::myCalendarShow); + connect(m_myCalendar,&CMyCalendar::sig_endTimeClick,this,&CEventForm::myCalendarHide); + connect(m_myCalendar,&CMyCalendar::sig_cancle,this,&CEventForm::cancleTimeFilter); + ui->lineEdit->setText(tr("请选择时间")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit->setObjectName("iconLineEdit"); + ui->splitter->setStretchFactor(0,9); + ui->splitter->setStretchFactor(1,1); + ui->splitter_2->setStretchFactor(0,1); + ui->splitter_2->setStretchFactor(1,5); + + //ui->splitter_2->setStretchFactor(0,1); + //ui->splitter_2->setStretchFactor(1,8); + + //ui->verticalLayout_2->setStretchFactor(ui->horizontalLayout_4,5); + //ui->verticalLayout_2->setStretchFactor(ui->splitter_2,1); + + + m_excelPrinter = new CExcelPrinter(); + m_thread = new QThread(); + m_excelPrinter->moveToThread(m_thread); + connect(m_thread,&QThread::started,m_excelPrinter,&CExcelPrinter::initialize); + connect(m_thread,&QThread::finished,m_excelPrinter,&CExcelPrinter::deleteLater); + connect(this,&CEventForm::printExcel,m_excelPrinter,&CExcelPrinter::printerByModel); + connect(this,&CEventForm::printExcelHis,m_excelPrinter,&CExcelPrinter::printerHisByModel); + connect(m_excelPrinter,&CExcelPrinter::sigShowResult,this,&CEventForm::slotShowResult); + m_thread->start(); +} + +CEventForm::~CEventForm() +{ + CEventDataCollect::instance()->release(); + if(m_pRealTimeModel) + { + delete m_pRealTimeModel; + } + m_pRealTimeModel = Q_NULLPTR; + + if(m_pHistoryModel) + { + delete m_pHistoryModel; + } + m_pHistoryModel = Q_NULLPTR; + if(m_pRealDelegate) + { + delete m_pRealDelegate; + } + m_pRealDelegate = Q_NULLPTR; + if(m_pHistoryDelegate) + { + delete m_pHistoryDelegate; + } + m_pHistoryDelegate = Q_NULLPTR; + if(m_excelPrinter) + { + delete m_excelPrinter; + } + m_excelPrinter = Q_NULLPTR; + if(m_thread) + { + m_thread->quit(); + m_thread->wait(); + } + if(m_hisSearch) + { + m_hisSearch->quit(); + m_hisSearch->wait(); + } + + delete CEventDataCollect::instance(); + delete CEventMsgManage::instance(); + delete ui; + + qDebug() << "~CEventForm()"; +} + +void CEventForm::initilize() +{ + //< lingdaoyaoqiu + { + QSettings columFlags1("IOT_HMI", "eventReal config"); + if(!columFlags1.contains(QString("eventReal/colum_0"))) + { + columFlags1.setValue(QString("eventReal/colum_0"), false); //< 时间 + columFlags1.setValue(QString("eventReal/colum_1"), false); //< 优先级 + columFlags1.setValue(QString("eventReal/colum_2"), false); //< 位置 + columFlags1.setValue(QString("eventReal/colum_3"), true); //< 责任区 + columFlags1.setValue(QString("eventReal/colum_4"), true); //< 事件类型 + columFlags1.setValue(QString("eventReal/colum_5"), false); //< 事件状态 + columFlags1.setValue(QString("eventReal/colum_6"), false); //< 复归状态 + } + } + { + QSettings columFlags2("IOT_HMI", "eventHis config"); + if(!columFlags2.contains(QString("eventHis/colum_0"))) + { + columFlags2.setValue(QString("eventHis/colum_0"), false); //< 时间 + columFlags2.setValue(QString("eventHis/colum_1"), false); //< 优先级 + columFlags2.setValue(QString("eventHis/colum_2"), false); //< 位置 + columFlags2.setValue(QString("eventHis/colum_3"), true); //< 责任区 + columFlags2.setValue(QString("eventHis/colum_4"), true); //< 事件类型 + columFlags2.setValue(QString("eventHis/colum_5"), false); //< 事件状态 + columFlags2.setValue(QString("eventHis/colum_6"), false); //< 复归状态 + columFlags2.setValue(QString("eventHis/colum_7"), true); //< 确认人 + columFlags2.setValue(QString("eventHis/colum_8"), true); //< 确认时间 + } + } + m_pListWidget1 = new CMyListWidget(this); + m_pListWidget2 = new CMyListWidget(this); + m_pListWidget3 = new CMyListWidget(this); + m_pLineEdit1 = new QLineEdit(this); + m_pLineEdit2 = new QLineEdit(this); + m_pLineEdit3 = new QLineEdit(this); + + ui->comboBox->setModel(m_pListWidget1->model()); + ui->comboBox->setView(m_pListWidget1); + ui->comboBox->setLineEdit(m_pLineEdit1); + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + m_pLineEdit1->setReadOnly(true); + connect(m_pLineEdit1, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged1(const QString &))); //为了解决点击下拉框白色部分导致lineedit无数据问题 + ui->comboBox_2->setModel(m_pListWidget2->model()); + ui->comboBox_2->setView(m_pListWidget2); + ui->comboBox_2->setLineEdit(m_pLineEdit2); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + m_pLineEdit2->setReadOnly(true); + connect(m_pLineEdit2, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged2(const QString &))); + ui->comboBox_3->setModel(m_pListWidget3->model()); + ui->comboBox_3->setView(m_pListWidget3); + ui->comboBox_3->setLineEdit(m_pLineEdit3); + m_strText3 = tr("请选择告警状态"); + m_pLineEdit3->setText(tr("请选择告警状态")); + m_pLineEdit3->setReadOnly(true); + connect(m_pLineEdit3, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged3(const QString &))); + +} + +void CEventForm::SetHideReal() +{ + updateStack(1); + ui->realEventButton->setVisible(false); + ui->hisEventButton->setVisible(false); + ui->clear->setVisible(false); +} + +void CEventForm::initModel() +{ + initHisModel(); + initRealModel(); + loadDeviceGroupFilterWidget(); +} + +void CEventForm::initHisModel() +{ + if(m_pHistoryDelegate == NULL) + { + m_pHistoryDelegate = new CEventDelegate(ui->eventView_2); + } + ui->eventView_2->setItemDelegate(m_pHistoryDelegate); + ui->eventView_2->setSortingEnabled(false); + if(NULL == m_pHistoryModel) + { + m_pHistoryModel = new CEventHistoryModel(this); + connect(m_pHistoryModel, &CEventHistoryModel::sigPermInvalid, this, &CEventForm::slotPermInvalid,Qt::QueuedConnection); + connect(m_pHistoryModel, &CEventHistoryModel::sigHisEventRequesting, this, &CEventForm::slotUpdateHISTipsRequesting,Qt::QueuedConnection); + if(m_hisSearch != NULL) + { + connect(m_pHistoryModel, &CEventHistoryModel::requestHistory, m_hisWork,&CEventHisThread::doWork,Qt::QueuedConnection); + connect(m_hisWork, &CEventHisThread::sigUpdateHisEvent, m_pHistoryModel, &CEventHistoryModel::updateEvents, Qt::QueuedConnection); + } + connect(m_pHistoryModel, &CEventHistoryModel::sigHisEventSizeChanged, this, &CEventForm::slotUpdateHISTips,Qt::QueuedConnection); + connect(m_pHistoryModel, &CEventHistoryModel::sigHISRecordOutOfRangeTips, this, &CEventForm::slotHISRecordOutOfRangeTips,Qt::QueuedConnection); + connect(m_pHistoryModel, &CEventHistoryModel::sigOutOfRangeTips, this, &CEventForm::slotHisOutOfRangeTips,Qt::QueuedConnection); + + } + ui->eventView_2->setModel(m_pHistoryModel); + m_pHistoryDelegate->setHisEventModel(m_pHistoryModel); + ui->eventView_2->setColumnWidth(8, 250); + QSettings columFlags2("IOT_HMI", "eventHis config"); + for(int nColumnIndex(0); nColumnIndex < m_pHistoryModel->columnCount() - 1; nColumnIndex++) + { + bool visible = columFlags2.value(QString("eventHis/colum_%1").arg(nColumnIndex)).toBool(); + ui->eventView_2->setColumnHidden(nColumnIndex, visible); + } + ui->eventView_2->setColumnHidden(m_pHistoryModel->columnCount() - 1, false); + ui->eventView_2->setColumnWidth(0, 250); + ui->eventView_2->setColumnWidth(1, 150); + ui->eventView_2->setColumnWidth(2, 150); + ui->eventView_2->setColumnWidth(3, 150); + ui->eventView_2->setColumnWidth(4, 150); + ui->eventView_2->setColumnWidth(5, 150); + ui->eventView_2->setColumnWidth(6, 150); + ui->eventView_2->setColumnWidth(7, 150); + slotUpdateHISTips(); + + if(m_pDeviceHisModel == NULL) + { + m_pDeviceHisModel = new CEventDeviceTreeModel(this); + ui->treeView_2->setModel(m_pDeviceHisModel); + + connect(m_pDeviceHisModel, &CEventDeviceTreeModel::itemCheckStateChanged, this, &CEventForm::hisDeviceGroupFilterChanged); + connect(ui->treeView_2 , &CEventDeviceTreeView::doubleClicked , m_pDeviceHisModel , &CEventDeviceTreeModel::slotTreeCheckBoxState); + if(m_hisSearch != NULL) + { + connect(m_hisWork, &CEventHisThread::sigUpdateHisEvent, this, &CEventForm::updateHisDeviceGroupHiddenState, Qt::QueuedConnection); + } + } + + /* + //过滤开关变为,状态变为,数字量变为 + { + bool isCheck = true; + bool other = true; + + QList StatusList; + QList alarmStatusList = CEventDataCollect::instance()->alarmStatusList(); + + for (int i = 0; i < alarmStatusList.count(); ++i) + { + int nData = alarmStatusList[i]; + if( !(nData == 11 || nData == 12 || nData == 13) ) + { + StatusList.append(nData); + } + } + setEventStatusComboBox(isCheck,StatusList); + m_pHistoryModel->setEventTypeFilter(isCheck,StatusList,other); + m_pHistoryModel->loadEventHistoryData(); + } + */ + +} + +void CEventForm::initRealModel() +{ + if(m_pRealDelegate == NULL) + { + m_pRealDelegate = new CEventDelegate(this); + ui->eventView->setItemDelegate(m_pRealDelegate); + } + ui->eventView->setSortingEnabled(true); + if(NULL == m_pRealTimeModel) + { + m_pRealTimeModel = new CEventItemModel(this); + connect(ui->eventView->horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), m_pRealTimeModel, SLOT(sortColumn(int,Qt::SortOrder))); + ui->eventView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); + } + ui->eventView->setModel(m_pRealTimeModel); + m_pRealDelegate->setEventModel(m_pRealTimeModel); + QSettings columFlags1("IOT_HMI", "eventReal config"); + for(int nColumnIndex(0); nColumnIndex < m_pRealTimeModel->columnCount() - 1; nColumnIndex++) + { + bool visible = columFlags1.value(QString("eventReal/colum_%1").arg(nColumnIndex)).toBool(); + ui->eventView->setColumnHidden(nColumnIndex, visible); + } + ui->eventView->setColumnHidden(m_pRealTimeModel->columnCount() - 1, false); + ui->eventView->setColumnWidth(0, 250); + ui->eventView->setColumnWidth(1, 150); + ui->eventView->setColumnWidth(2, 150); + ui->eventView->setColumnWidth(3, 150); + ui->eventView->setColumnWidth(4, 150); + ui->eventView->setColumnWidth(5, 150); + slotUpdateRTTips(); + + if(m_pDeviceModel == NULL) + { + m_pDeviceModel = new CEventDeviceTreeModel(this); + ui->treeView->setModel(m_pDeviceModel); + + connect(m_pDeviceModel, &CEventDeviceTreeModel::itemCheckStateChanged, this, &CEventForm::deviceGroupFilterChanged); + connect(CEventDataCollect::instance(),&CEventDataCollect::sigDevTreeUpdate,m_pDeviceModel,&CEventDeviceTreeModel::slotDevTreeUpdate); + connect(CEventDataCollect::instance(),&CEventDataCollect::sigDevTreeUpdate,this,&CEventForm::updateDeviceGroupHiddenState); + } +} + +void CEventForm::login() +{ + if(!m_isEditMode) + { + CEventDataCollect::instance()->release(); + if(m_pRealTimeModel) + { + m_pRealTimeModel->initialize(); + } + if(m_pHistoryModel) + { + m_pHistoryModel->initialize(); + } + if(m_pRealDelegate == NULL) + { + m_pRealDelegate = new CEventDelegate(ui->eventView); + m_pRealDelegate->setEventModel(m_pRealTimeModel); + } + if(m_pHistoryDelegate == NULL) + { + m_pHistoryDelegate = new CEventDelegate(ui->eventView_2); + m_pHistoryDelegate->setHisEventModel(m_pHistoryModel); + } + CEventDataCollect::instance()->initialize(); + initFilter(); + if(ui->hisEventButton->isChecked()) + { + m_pHistoryModel->loadEventHistoryData(); + slotUpdateHISTips(); + } + } +} + +void CEventForm::logout() +{ + if(!m_isEditMode) + { + CEventDataCollect::instance()->release(); + } +} + +void CEventForm::slotShowResult(QString result) +{ + Q_UNUSED(result); + QMessageBox::information( 0, tr("提示"), tr("导出成功")); +} + +void CEventForm::setHiddenLocation(bool hide) +{ + ui->label_2->setHidden(hide); + ui->comboBox_2->setHidden(hide); +} + +void CEventForm::setHiddenTime(bool hide) +{ + ui->label_4->setHidden(hide); + ui->lineEdit->setHidden(hide); +} + +void CEventForm::setHiddenStatus(bool hide) +{ + ui->label_3->setHidden(hide); + ui->comboBox_3->setHidden(hide); +} + +void CEventForm::setHiddenPriority(bool hide) +{ + ui->label->setHidden(hide); + ui->comboBox->setHidden(hide); +} + +void CEventForm::setHiddenCloseButton(bool hide) +{ + ui->closeBtn->setHidden(hide); +} + +void CEventForm::setRowHeight(int height) +{ + if(ui->eventView != Q_NULLPTR) + { + ui->eventView->setDefaultRowHeight(height); + } + if(ui->eventView_2 != Q_NULLPTR) + { + ui->eventView_2->setDefaultRowHeight(height); + } +} + +void CEventForm::setColumnWidth(const int &column, const int &width) +{ + if(column<0 ||column >=9) + { + return ; + } + + if(column < 7) + { + if(ui->eventView != Q_NULLPTR) + { + ui->eventView->setColumnWidth(column, width); + } + if(ui->eventView_2 != Q_NULLPTR) + { + ui->eventView_2->setColumnWidth(column, width); + } + }else if(column >= 7) + { + if(ui->eventView_2 != Q_NULLPTR) + { + ui->eventView_2->setColumnWidth(column, width); + } + } +} + +void CEventForm::setColumnVisible(const int &column, const bool &visible) +{ + if(ui->eventView != Q_NULLPTR) + { + ui->eventView->setColumnHidden(column, !visible); + } +} + +void CEventForm::setHisColumnWidth(const int &column, const int &width) +{ + if(ui->eventView_2 != Q_NULLPTR) + { + ui->eventView_2->setColumnWidth(column, width); + } +} + +void CEventForm::setHisColumnVisible(const int &column, const bool &visible) +{ + if(ui->eventView_2 != Q_NULLPTR) + { + ui->eventView_2->setColumnHidden(column, !visible); + } +} + +void CEventForm::setEnableAccidentReview(bool isNeed) +{ + m_isNeedAccidentReview = isNeed; +} + +void CEventForm::setEnableWave(bool isNeed) +{ + if(m_pRealDelegate) + { + m_pRealDelegate->setEnableWave(isNeed); + } + if(m_pHistoryDelegate) + { + m_pHistoryDelegate->setEnableWave(isNeed); + } +} + +void CEventForm::setAccidentReviewPath(const QString &path) +{ + m_strAccidenPath = path; +} + +void CEventForm::initFilter() +{ + m_pListWidget1->clear(); + m_pListWidget2->clear(); + m_pListWidget3->clear(); + QMap priority = CEventDataCollect::instance()->priorityDescriptionMap(); + QMap alarmStatus = CEventDataCollect::instance()->eventShowStatusDescriptionMap(); + for(QMap::iterator it1 = priority.begin();it1 != priority.end();++it1) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget1); + pItem->setData(Qt::UserRole, it1.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it1.value()); + m_pListWidget1->addItem(pItem); + m_pListWidget1->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged1(int))); + } + QList locOrder = CEventDataCollect::instance()->locationOrderList(); + foreach (const int &locId, locOrder) { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget2); + pItem->setData(Qt::UserRole, locId); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(CEventDataCollect::instance()->locationDescription(locId)); + m_pListWidget2->addItem(pItem); + m_pListWidget2->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged2(int))); + } + for(QMap::iterator it3 = alarmStatus.begin();it3 != alarmStatus.end();++it3) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget3); + pItem->setData(Qt::UserRole, it3.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it3.value()); + m_pListWidget3->addItem(pItem); + m_pListWidget3->setItemWidget(pItem, pCheckBox); + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged3(int))); + } + if(m_pDeviceModel) + { + m_pDeviceModel->setAllDeviceCheckState(Qt::Checked); + } + if(m_pDeviceHisModel) + { + m_pDeviceHisModel->setAllDeviceCheckState(Qt::Checked); + } +} + +void CEventForm::setLevelComboBox(bool &isLevelFilter, QList &listLevel) +{ + if(isLevelFilter == true && listLevel.size() > 0) + { + QString strText(""); + for (int i = 0; i < ui->comboBox->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listLevel.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText1 = strText; + m_pLineEdit1->setText(strText); + }else + { + for (int i = 0; i < ui->comboBox->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + } +} + +void CEventForm::setLocationComboBox(bool &isLocationFilter, QList &listLocation) +{ + if(isLocationFilter == true && listLocation.size() > 0) + { + QString strText(""); + for (int i = 0; i < ui->comboBox_2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listLocation.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText2 = strText; + m_pLineEdit2->setText(strText); + }else + { + for (int i = 0; i < ui->comboBox_2->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + } +} + +void CEventForm::setEventStatusComboBox(bool &isEventStatusFilter, QList &listEventStatus) +{ + if(isEventStatusFilter == true && listEventStatus.size() > 0) + { + QString strText(""); + for (int i = 0; i < ui->comboBox_3->count(); ++i) + { + + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + int nData = pItem->data(Qt::UserRole).toInt(); + if(listEventStatus.contains(nData)) + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(true); + strText.append(pCheckBox->text()).append(" "); + pCheckBox->blockSignals(false); + }else + { + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + } + m_strText3 = strText; + m_pLineEdit3->setText(strText); + }else + { + for (int i = 0; i < ui->comboBox_3->count(); ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + pCheckBox->blockSignals(true); + pCheckBox->setChecked(false); + pCheckBox->blockSignals(false); + } + m_strText3 = tr("请选择事件状态"); + m_pLineEdit3->setText(tr("请选择事件状态")); + } +} + +void CEventForm::setEventTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime) +{ + if(isTimeFilter == true) + { + ui->lineEdit->setText(startTime.date().toString("yyyy-MM-dd")+"~"+endTime.date().toString("yyyy-MM-dd")); + }else + { + ui->lineEdit->setText(tr("请选择时间")); + } +} + + + +void CEventForm::slotClearRTEvent() +{ + CEventDataCollect::instance()->handleClearRTEvent(); +} + +void CEventForm::slotALlSel() +{ + m_pDeviceHisModel->setAllDeviceCheckState(Qt::Checked); + ui->treeView_2->repaint(); +} + +void CEventForm::slotNoneSel() +{ + + m_pDeviceHisModel->setAllDeviceCheckState(Qt::Unchecked); + ui->treeView_2->repaint(); + + +} + + +void CEventForm::slotbtnFlash() +{ + // CEventDataCollect::instance()->handleClearRTEvent(); + m_pHistoryModel->loadEventHistoryData(); +} + +void CEventForm::deviceGroupFilterChanged(const QString &device, const bool &checked) +{ + if(checked) + { + if(m_pRealTimeModel) + { + m_pRealTimeModel->addDeviceGroupFilter(device); + } + } + else + { + if(m_pRealTimeModel) + { + m_pRealTimeModel->removeDeviceGroupFilter(device); + } + } +} + +void CEventForm::hisDeviceGroupFilterChanged(const QString &device, const bool &checked) +{ + if(checked) + { + if(m_pHistoryModel) + { + m_pHistoryModel->addDeviceGroupFilter(device); + m_pHistoryModel->updateShowEvents(); + } + } + else + { + if(m_pHistoryModel) + { + m_pHistoryModel->removeDeviceGroupFilter(device); + m_pHistoryModel->updateShowEvents(); + } + } + ui->treeView_2->viewport()->update(); +} + +void CEventForm::updateFilter() +{ + CEventFilterDialog filterDlg(this); + bool isLevelFilter; + QList levelFilter; + bool isLocationFilter; + QList locationFilter; + bool isRegionFilter; + QList regionFilter; + bool isAlarmTypeFilter; + QList typeFilter; + bool deviceTypeFilter; + QString subSystem; + QString deviceType; + bool keywordFilter; + QString keyword; + bool isTimeFilterEnable; + QDateTime startTime; + QDateTime endTime; + bool isReturnFilterEnable; + bool isReturn; + if(ui->realEventButton->isChecked()) + { + m_pRealTimeModel->getFilter(isLevelFilter, levelFilter, + isLocationFilter, locationFilter, + isRegionFilter, regionFilter, + isAlarmTypeFilter, typeFilter, + deviceTypeFilter, subSystem, deviceType, + keywordFilter, keyword, + isTimeFilterEnable, startTime, endTime,isReturnFilterEnable,isReturn); + filterDlg.initialize(E_ALARM_REAL_EVENT); + } + else if(ui->hisEventButton->isChecked()) + { + m_pHistoryModel->getFilter(isLevelFilter, levelFilter, + isLocationFilter, locationFilter, + isRegionFilter, regionFilter, + isAlarmTypeFilter, typeFilter, + deviceTypeFilter, subSystem, deviceType, + keywordFilter, keyword, + isTimeFilterEnable, startTime, endTime,isReturnFilterEnable,isReturn); + filterDlg.initialize(E_ALARM_HIS_EVENT); + } + + filterDlg.setLevelFilterEnable(isLevelFilter); + filterDlg.setLevelFilter(levelFilter); + filterDlg.setLocationFilterEnable(isLocationFilter); + filterDlg.setLocationFilter(locationFilter); + filterDlg.setRegionFilterEnable(isRegionFilter); + filterDlg.setRegionFilter(regionFilter); + filterDlg.setAlarmTypeFilterEnable(isAlarmTypeFilter); + filterDlg.setAlarmTypeFilter(typeFilter); + filterDlg.setDeviceFilterEnable(deviceTypeFilter); + filterDlg.setSubSystem(subSystem); + filterDlg.setDeviceType(deviceType); + filterDlg.setkeyWordFilterEnable(keywordFilter); + filterDlg.setkeyWordFilteContent(keyword); + filterDlg.setTimeFilterEnable(isTimeFilterEnable); + filterDlg.setStartTimeFilter(startTime); + filterDlg.setEndTimeFilter(endTime); + filterDlg.setReturnFilterEnable(isReturnFilterEnable);; + filterDlg.setReturnFilter(isReturn); + connect(&filterDlg, SIGNAL(sig_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime,bool,bool)), + this, SLOT(slot_updateFilter(bool, QList, bool, QList, bool, QList, bool, QList, bool, QString, QString, bool, QString, bool, QDateTime, QDateTime,bool,bool))); + filterDlg.exec(); +} + +void CEventForm::slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isEventStatusFilter, QList listEventStatus, + bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime, bool isReturnFilter, bool isReturn) +{ + if(ui->realEventButton->isChecked()) + { + m_pRealTimeModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isEventStatusFilter, listEventStatus, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime,isReturnFilter,isReturn); + setLevelComboBox(isLevelFilter,listLevel); + setLocationComboBox(isLocationFilter,listLocation); + setEventStatusComboBox(isEventStatusFilter,listEventStatus); + setEventTimeLineEdit(isTimeFilter, startTime, endTime); + slotUpdateRTTips(); + } + else if(ui->hisEventButton->isChecked()) + { + m_pHistoryModel->setFilter(isLevelFilter, listLevel, isLocationFilter, listLocation, isRegionFilter, listRegion, isEventStatusFilter, listEventStatus, isDeviceTypeFilter, subSystem, deviceType, isKeywordFilterEnable, keyword, isTimeFilter, startTime, endTime,isReturnFilter,isReturn); + setLevelComboBox(isLevelFilter,listLevel); + setLocationComboBox(isLocationFilter,listLocation); + setEventStatusComboBox(isEventStatusFilter,listEventStatus); + setEventTimeLineEdit(isTimeFilter, startTime, endTime); + m_pHistoryModel->loadEventHistoryData(); + } +} + +void CEventForm::slotRTEventStateChanged() +{ + if(dynamic_cast(ui->eventView->model())) + { + slotUpdateRTTips(); + } +} + +void CEventForm::slotUpdateRTTips() +{ + ui->typeLabel->setText(tr("实时事件总数:")); + if(m_pRealTimeModel) + { + ui->eventCount->setText(QString::number(CEventMsgManage::instance()->getListEventCount())); + } +} + +void CEventForm::slotUpdateHISTipsRequesting() +{ + ui->typeLabel_2->setText(tr("正在查询历史事件...")); + ui->eventCount_2->setText(""); + ui->label_his_tip->setText(""); +} + +void CEventForm::slotPermInvalid() +{ + QMessageBox::critical(this, tr("错误"), tr("当前用户不具备事件浏览权限"), QMessageBox::Ok); +} + +void CEventForm::slotUpdateHISTips() +{ + ui->typeLabel_2->setText(tr("历史事件数量:")); + if(m_pHistoryModel) + { + int count = m_pHistoryModel->rowCount(); + ui->eventCount_2->setText(QString::number(count)); + if(count >= LIMIT_HIS_RECORD) + { + ui->label_his_tip->setText(tr("历史事件数量超出10000条,超出部分不显示")); + }else + { + ui->label_his_tip->setText(""); + } + + } +} + +void CEventForm::slotHISRecordOutOfRangeTips(QStringList stDescList) +{ + QString stMess = ""; + for( int index(0);index!=stDescList.size() ; ++index ) + { + stMess += stDescList.at(index); + if(index != stDescList.size()-1) + stMess += "/"; + } + if(stDescList.size() != 0) + { + QMessageBox::information(this, tr("提示"), + QString(tr("历史事件数量超出%1条,未予显示!")).arg(LIMIT_HIS_RECORD), + QMessageBox::Ok); + } +} + +void CEventForm::slotHisOutOfRangeTips() +{ + QMessageBox::information(this, tr("提示"), + QString(tr("历史事件数量超出%1条,未予显示!")).arg(LIMIT_HIS_RECORD), + QMessageBox::Ok); +} + +void CEventForm::print() +{ + QString fileName=QFileDialog::getSaveFileName(this,tr("Save File"),QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),"*.xlsx");//获取保存路径*.xls + if(!fileName.isEmpty()) + { + if(ui->realEventButton->isChecked()) + { + if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) + fileName = fileName + ".xlsx"; + emit printExcel(ui->eventView,m_pRealTimeModel,fileName); + }else if(ui->hisEventButton->isChecked()) + { + if(!fileName.endsWith(".xlsx",Qt::CaseInsensitive)) + fileName = fileName + ".xlsx"; + emit printExcelHis(ui->eventView_2,m_pHistoryModel,fileName); + } + } +} + +void CEventForm::stateChanged1(int state) +{ + Q_UNUSED(state); + QString strText(""); + m_priorityList.clear(); + int nCount = m_pListWidget1->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget1->item(i); + QWidget *pWidget = m_pListWidget1->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_priorityList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText1 = strText; + m_pLineEdit1->setText(strText); + } + else + { + m_pLineEdit1->clear(); + m_strText1 = tr("请选择优先级"); + m_pLineEdit1->setText(tr("请选择优先级")); + } + bool isCheck = false; + if(ui->realEventButton->isChecked()) + { + if(m_priorityList.size() == 0) + { + m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); + }else + { + isCheck = true; + m_pRealTimeModel->setPriorityFilter(isCheck,m_priorityList); + } + } + else if(ui->hisEventButton->isChecked()) + { + if(m_priorityList.size() == 0) + { + m_pHistoryModel->setPriorityFilter(isCheck,m_priorityList); + }else + { + isCheck = true; + m_pHistoryModel->setPriorityFilter(isCheck,m_priorityList); + } + m_pHistoryModel->loadEventHistoryData(); + } +} + +void CEventForm::stateChanged2(int state) +{ + Q_UNUSED(state); + QString strText(""); + m_locationList.clear(); + int nCount = m_pListWidget2->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget2->item(i); + QWidget *pWidget = m_pListWidget2->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_locationList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText2 = strText; + m_pLineEdit2->setText(strText); + } + else + { + m_pLineEdit2->clear(); + m_strText2 = tr("请选择位置"); + m_pLineEdit2->setText(tr("请选择位置")); + } + bool isCheck = false; + if(ui->realEventButton->isChecked()) + { + if(m_locationList.size() == 0) + { + m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); + }else + { + isCheck = true; + m_pRealTimeModel->setLocationFilter(isCheck,m_locationList); + } + } + else if(ui->hisEventButton->isChecked()) + { + if(m_locationList.size() == 0) + { + m_pHistoryModel->setLocationFilter(isCheck,m_locationList); + }else + { + isCheck = true; + m_pHistoryModel->setLocationFilter(isCheck,m_locationList); + } + m_pHistoryModel->loadEventHistoryData(); + } +} + +void CEventForm::stateChanged3(int state) +{ + Q_UNUSED(state); + QString strText(""); + m_eventStatusList.clear(); + bool other = false; + int nCount = m_pListWidget3->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget3->item(i); + QWidget *pWidget = m_pListWidget3->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + int nData = pItem->data(Qt::UserRole).toInt(); + if(nData == OTHERSTATUS) + { + other = true; + } + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_eventStatusList.append(nData); + } + } + if (!strText.isEmpty()) + { + m_strText3 = strText; + m_pLineEdit3->setText(strText); + } + else + { + m_pLineEdit3->clear(); + m_strText3 = tr("请选择事件状态"); + m_pLineEdit3->setText(tr("请选择事件状态")); + } + bool isCheck = false; + if(ui->realEventButton->isChecked()) + { + if(m_eventStatusList.size() == 0) + { + m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventStatusList,other); + }else + { + isCheck = true; + m_pRealTimeModel->setEventTypeFilter(isCheck,m_eventStatusList,other); + } + } + else if(ui->hisEventButton->isChecked()) + { + if(m_eventStatusList.size() == 0) + { + m_pHistoryModel->setEventTypeFilter(isCheck,m_eventStatusList,other); + }else + { + isCheck = true; + m_pHistoryModel->setEventTypeFilter(isCheck,m_eventStatusList,other); + } + m_pHistoryModel->loadEventHistoryData(); + } +} + +void CEventForm::textChanged1(const QString &text) +{ + Q_UNUSED(text); + m_pLineEdit1->setText(m_strText1); +} + +void CEventForm::textChanged2(const QString &text) +{ + Q_UNUSED(text); + m_pLineEdit2->setText(m_strText2); +} + +void CEventForm::textChanged3(const QString &text) +{ + Q_UNUSED(text); + m_pLineEdit3->setText(m_strText3); +} + +void CEventForm::myCalendarHide(QDate startTime, QDate endTime) +{ + ui->lineEdit->setText(startTime.toString("yyyy-MM-dd") +"~"+endTime.toString("yyyy-MM-dd")); + //开始过滤 + bool isCheck = false; + if(ui->realEventButton->isChecked()) + { + isCheck = true; + m_pRealTimeModel->setEventTimeFilter(isCheck,startTime,endTime); + }else if(ui->hisEventButton->isChecked()) + { + isCheck = true; + m_pHistoryModel->setEventTimeFilter(isCheck,startTime,endTime); + m_pHistoryModel->loadEventHistoryData(); + } + m_timeMenu->hide(); +} + +void CEventForm::myCalendarShow() +{ + QPoint point(QCursor::pos().x()-500,QCursor::pos().y()+15); + if(ui->realEventButton->isChecked()) + { + m_myCalendar->setView(E_ALARM_REAL_EVENT); + }else if(ui->hisEventButton->isChecked()) + { + m_myCalendar->setView(E_ALARM_HIS_EVENT); + } + + m_timeMenu->move(point); + m_timeMenu->show(); +} + +void CEventForm::cancleTimeFilter() +{ + ui->lineEdit->setText(tr("请选择时间")); + //取消过滤 + bool isCheck = false; + if(ui->realEventButton->isChecked()) + { + m_pRealTimeModel->setEventTimeFilter(isCheck); + }else if(ui->hisEventButton->isChecked()) + { + m_pHistoryModel->setEventTimeFilter(isCheck); + m_pHistoryModel->loadEventHistoryData(); + } + m_timeMenu->hide(); +} + +void CEventForm::searchRealDeviceNamechange(const QString &s) +{ + QItemSelection selection; + QString content = s; + ui->treeView->selectionModel()->select(selection, QItemSelectionModel::Clear); + if(content.isEmpty()) + { + return; + } + const QHash< QString, QModelIndex > &indexNameList = m_pDeviceModel->indexNameList(); + QHash< QString, QModelIndex >::const_iterator iter = indexNameList.constBegin(); + while (iter != indexNameList.constEnd()) + { + if(ui->treeView->isRowHidden(iter.value().row(), iter.value().parent())) + { + iter++; + continue; + } + if(iter.key().section(".", 1).contains(content, Qt::CaseInsensitive)) + { + selection.append(QItemSelectionRange(iter.value(), iter.value())); + selection.append(QItemSelectionRange(iter.value().parent(), iter.value().parent())); + } + iter++; + } + ui->treeView->selectionModel()->select(selection, QItemSelectionModel::Select);} + +void CEventForm::searchRealDeviceName() +{ + m_searchRealDeviceName = m_pRealSearchEdit->text(); + updateDeviceGroupHiddenState(); +} + +void CEventForm::searchHistoryDeviceName() +{ + m_searchHisDeviceName = m_pHistorySearchEdit->text(); + QList eventList; + updateHisDeviceGroupHiddenStateRefesh(eventList,false); +} + +void CEventForm::contextMenuEvent(QContextMenuEvent *event) +{ + QWidget::contextMenuEvent(event); + if(ui->realEventButton->isChecked()) + { + contextMenuRealEvent(event); + }else if(ui->hisEventButton->isChecked()) + { + contextMenuHisEvent(event); + } +} + +void CEventForm::contextMenuRealEvent(QContextMenuEvent *event) +{ + if(event->pos().x() < ui->eventView->pos().x()) + { + return; + } + QRect headerRect = ui->eventView->horizontalHeader()->rect(); + headerRect.moveTopLeft(ui->eventView->mapTo(this, QPoint())); + if(headerRect.contains(event->pos())) + { + QMenu columnMenu(this); + for(int nColumnIndex(0); nColumnIndex < m_pRealTimeModel->columnCount()-1; nColumnIndex++) + { + QAction * action = columnMenu.addAction(m_pRealTimeModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); + action->setCheckable(true); + action->setChecked(!ui->eventView->isColumnHidden(nColumnIndex)); + + connect(action, &QAction::triggered, [=](){ + + ui->eventView->setColumnHidden(nColumnIndex, !action->isChecked()); + QSettings columFlags1("IOT_HMI", "eventReal config"); + columFlags1.setValue(QString("eventReal/colum_%1").arg(nColumnIndex), !action->isChecked()); + }); + } + + if(columnMenu.actions().size()>0) + { + columnMenu.exec(QCursor::pos()); + } + }else + { + QModelIndex index_ = ui->eventView->indexAt(ui->eventView->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index_.isValid()) + { + return; + } + QMenu menu(this); + QModelIndex index = ui->eventView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QModelIndexList indexLists = ui->eventView->selectionModel()->selectedIndexes(); + + //判断右键位置是否在选中区 + if(!indexLists.contains(index)) + { + ui->eventView->clearSelection(); + ui->eventView->setCurrentIndex(index); + } + + if(m_isNeedAccidentReview) + { + QAction * accidentReviewAction = menu.addAction(tr("事故追忆")); + connect(accidentReviewAction,&QAction::triggered,[=](){ + rightAccidentReviewReal(); + }); + } + + if(menu.actions().size()>0) + { + menu.exec(QCursor::pos()); + } + } +} + +void CEventForm::contextMenuHisEvent(QContextMenuEvent *event) +{ + if(event->pos().x() < ui->eventView_2->pos().x()) + { + return; + } + QRect headerRect = ui->eventView_2->horizontalHeader()->rect(); + headerRect.moveTopLeft(ui->eventView_2->mapTo(this, QPoint())); + if(headerRect.contains(event->pos())) + { + QMenu columnMenu(this); + for(int nColumnIndex(0); nColumnIndex < m_pHistoryModel->columnCount()-1; nColumnIndex++) + { + QAction * action = columnMenu.addAction(m_pHistoryModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); + action->setCheckable(true); + action->setChecked(!ui->eventView_2->isColumnHidden(nColumnIndex)); + connect(action, &QAction::triggered, [=](){ + ui->eventView_2->setColumnHidden(nColumnIndex, !action->isChecked()); + QSettings columFlags2("IOT_HMI", "eventHis config"); + columFlags2.setValue(QString("eventHis/colum_%1").arg(nColumnIndex), !action->isChecked()); + }); + } + if(columnMenu.actions().size()>0) + { + columnMenu.exec(QCursor::pos()); + } + }else + { + QModelIndex index_ = ui->eventView_2->indexAt(ui->eventView_2->mapFromGlobal(event->globalPos() - QPoint(0, headerRect.height()))); + if(!index_.isValid()) + { + return; + } + QMenu menu(this); + QModelIndex index = ui->eventView_2->currentIndex(); + if(!index.isValid()) + { + return ; + } + QModelIndexList indexLists = ui->eventView_2->selectionModel()->selectedIndexes(); + + //判断右键位置是否在选中区 + if(!indexLists.contains(index)) + { + ui->eventView_2->clearSelection(); + ui->eventView_2->setCurrentIndex(index); + } + + if(m_isNeedAccidentReview) + { + QAction * accidentReviewAction = menu.addAction(tr("事故追忆")); + connect(accidentReviewAction,&QAction::triggered,[=](){ + rightAccidentReviewHis(); + }); + } + if(menu.actions().size()>0) + { + menu.exec(QCursor::pos()); + } + } +} + +void CEventForm::loadDeviceGroupFilterWidget() +{ + if(!m_pDeviceModel && !m_pDeviceHisModel) + { + return; + } + + iot_dbms::CDbApi objReader(DB_CONN_MODEL_READ); + if(!objReader.open()) + { + LOGERROR("load deviceGroup info error, database open failed, %s", objReader.getLastErrorString().toStdString().c_str()); + return; + } + + QMap< int, QVector< QPair< QString, QString > > > locationInfos; + + QList locationList = CEventDataCollect::instance()->locationOrderList(); + for(int nIndex(0); nIndex > dev; + + QSqlQuery query; + QString sqlSequenceQuery = QString("select tag_name, description from dev_group where location_id = %1;").arg(locationList[nIndex]); + if(objReader.execute(sqlSequenceQuery, query)) + { + while(query.next()) + { + dev.append(qMakePair(query.value(0).toString(), query.value(1).toString())); + } + locationInfos.insert(locationList[nIndex], dev); + }else + { + LOGERROR("load device info error, dbInterface execute failed!"); + } + } + if(m_pDeviceModel) + { + m_pDeviceModel->removeData(); + m_pDeviceModel->setupModelData(locationInfos,locationList); + updateDeviceGroupHiddenState(); + ui->treeView->expandAll(); + } + if(m_pDeviceHisModel) + { + m_pDeviceHisModel->removeData(); + m_pDeviceHisModel->setupModelData(locationInfos,locationList); + updateHisDeviceGroupHiddenState(QList()); + ui->treeView_2->expandAll(); + } +} + +void CEventForm::updateDeviceGroupHiddenState() +{ + QString content = m_searchRealDeviceName; + QHash listDeviceStatisticalInfo = m_pDeviceModel->getDeviceStatisticalInfo(); + for(int nTopLevelRow(0); nTopLevelRow < m_pDeviceModel->rowCount(); nTopLevelRow++) + { + QModelIndex topLevelIndex = m_pDeviceModel->index(nTopLevelRow, 0); + for(int nChildRow(0); nChildRow < m_pDeviceModel->rowCount(topLevelIndex); nChildRow++) + { + QModelIndex devIndex = m_pDeviceModel->index(nChildRow, 0, topLevelIndex); + CEventDeviceTreeItem *item = static_cast(devIndex.internalPointer()); + bool isCountNo0 = !listDeviceStatisticalInfo.value(item->data(Qt::UserRole).toString(), 0); + bool isHidden =false; + if(content.isEmpty()) + { + isHidden = isCountNo0; + } + else + { + QString devGroupStr = item->data(Qt::DisplayRole).toString(); + if(!devGroupStr.contains(content, Qt::CaseInsensitive)) + { + isHidden = true; + } + else + { + isHidden = isCountNo0; + } + } + ui->treeView->setRowHidden(nChildRow, topLevelIndex, isHidden); + } + } +} +void CEventForm::updateHisDeviceGroupHiddenState(QList eventList) +{ + updateHisDeviceGroupHiddenStateRefesh(eventList,true); +} + +void CEventForm::updateHisDeviceGroupHiddenStateRefesh(QList eventList,bool refeshEvent) +{ + QString content = m_searchHisDeviceName; + if(refeshEvent) + { + m_pDeviceHisModel->slotHisDevTreeUpdate(eventList); + } + + QHash listDeviceStatisticalInfo = m_pDeviceHisModel->getDeviceStatisticalInfo(); + for(int nTopLevelRow(0); nTopLevelRow < m_pDeviceHisModel->rowCount(); nTopLevelRow++) + { + QModelIndex topLevelIndex = m_pDeviceHisModel->index(nTopLevelRow, 0); + for(int nChildRow(0); nChildRow < m_pDeviceHisModel->rowCount(topLevelIndex); nChildRow++) + { + QModelIndex devIndex = m_pDeviceHisModel->index(nChildRow, 0, topLevelIndex); + + CEventDeviceTreeItem *item = static_cast(devIndex.internalPointer()); + bool isCountNo0 = !listDeviceStatisticalInfo.value(item->data(Qt::UserRole).toString(), 0); + bool isHidden =false; + if(content.isEmpty()) + { + isHidden = isCountNo0; + } + else + { + QString devGroupStr = item->data(Qt::DisplayRole).toString(); + if(!devGroupStr.contains(content, Qt::CaseInsensitive)) + { + isHidden = true; + } + else + { + isHidden = isCountNo0; + } + } + + ui->treeView_2->setRowHidden(nChildRow, topLevelIndex,isHidden); + } + } +} + +void CEventForm::updateStack(int index) +{ + if(m_ncurIndex == index) + { + return ; + } + if(index==0) + { + bool isLevelFilterEnable = false; + QList priorityFilterList; + m_pRealTimeModel->getPriorityFilter(isLevelFilterEnable,priorityFilterList); + + bool isLocationFilterEnable = false; + QList locationFilterList; + m_pRealTimeModel->getLocationFilter(isLocationFilterEnable,locationFilterList); + + bool isStatusFilterEnable = false; + QList statusFilterList; + m_pRealTimeModel->getEventStatusFilter(isStatusFilterEnable,statusFilterList); + + bool timeFilterEnable = false; + QDateTime startTime; + QDateTime endTime; + m_pRealTimeModel->getEventTimeFilter(timeFilterEnable,startTime,endTime); + + setLevelComboBox(isLevelFilterEnable,priorityFilterList); + setLocationComboBox(isLocationFilterEnable,locationFilterList); + setEventStatusComboBox(isStatusFilterEnable,statusFilterList); + setEventTimeLineEdit(timeFilterEnable, startTime, endTime); + ui->clear->setEnabled(true); + m_ncurIndex = index; + ui->eventStackWidget->setCurrentIndex(0); + }else if(index == 1) + { + bool isLevelFilterEnable = false; + QList priorityFilterList; + m_pHistoryModel->getPriorityFilter(isLevelFilterEnable,priorityFilterList); + + bool isLocationFilterEnable = false; + QList locationFilterList; + m_pHistoryModel->getLocationFilter(isLocationFilterEnable,locationFilterList); + + bool isStatusFilterEnable = false; + QList statusFilterList; + m_pHistoryModel->getEventStatusFilter(isStatusFilterEnable,statusFilterList); + + setLevelComboBox(isLevelFilterEnable,priorityFilterList); + setLocationComboBox(isLocationFilterEnable,locationFilterList); + setEventStatusComboBox(isStatusFilterEnable,statusFilterList); + QDate startData = QDate::currentDate().addDays(-6); + QDate endData = QDate::currentDate(); + bool check = true; + m_pHistoryModel->setEventTimeFilter(check,startData,endData); + ui->lineEdit->setText(startData.toString("yyyy-MM-dd")+"~"+endData.toString("yyyy-MM-dd")); + m_pHistoryModel->loadEventHistoryData(); + ui->clear->setEnabled(false); + m_ncurIndex = index; + ui->eventStackWidget->setCurrentIndex(1); + } +} + +void CEventForm::rightAccidentReviewReal() +{ + QModelIndex index = ui->eventView->currentIndex(); + if(!index.isValid()) + { + return ; + } + QList listInfo = m_pRealTimeModel->getListEventInfo(); + EventMsgPtr info = listInfo.at(index.row()); + if(info != NULL) + { + CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); + if(dialog->exec() == QDialog::Accepted) + { + emit openAccidentReviewDialog(info->time_stamp-30000,30000*2,dialog->getCurrentGraph()); + } + delete dialog; + dialog = NULL; + } +} + +void CEventForm::rightAccidentReviewHis() +{ + QModelIndex index = ui->eventView_2->currentIndex(); + if(!index.isValid()) + { + return ; + } + QList listInfo = m_pHistoryModel->getListEventInfo(); + EventMsgPtr info = listInfo.at(index.row()); + if(info != NULL) + { + CAccidentReviewDialog *dialog = new CAccidentReviewDialog(m_strAccidenPath, this); + if(dialog->exec() == QDialog::Accepted) + { + emit openAccidentReviewDialog(info->time_stamp-30000,30000*2,dialog->getCurrentGraph()); + } + delete dialog; + dialog = NULL; + } +} + +void CEventForm::on_eventView_2_doubleClicked(const QModelIndex &index) +{ + if(!index.isValid() || !m_pHistoryModel->headerData(index.column() , Qt::Horizontal , Qt::DisplayRole).toString().contains("事件内容")) + { + return; + } + + QMessageBox msg; + msg.setWindowTitle("事件内容"); + msg.setText(index.data(Qt::DisplayRole).toString()); + msg.addButton("确认",QMessageBox::AcceptRole); + + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + if(!qss.isEmpty()) + { + msg.setStyleSheet(qss); + } + msg.exec(); +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventForm.h b/product/src/gui/plugin/EventWidget_pad/CEventForm.h new file mode 100644 index 00000000..c908a7d0 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventForm.h @@ -0,0 +1,179 @@ +#ifndef CEventForm_H +#define CEventForm_H + +#include +#include +#include +#include +#include +#include "CMyCalendar.h" +#include "CExcelPrinter.h" +#include "CEventHisThread.h" +namespace Ui { +class CEventForm; +} + +class CEventDelegate; +class CEventItemModel; +class CEventHistoryModel; +class QAbstractTableModel; +class CEventDeviceTreeModel; +class CEventView; +typedef QList QModelIndexList; + +class CEventForm : public QWidget +{ + Q_OBJECT + +public: + explicit CEventForm(QWidget *parent, bool editMode); + ~CEventForm(); + void initilize(); + void SetHideReal(); + void initModel(); + + void initHisModel(); + + void initRealModel(); + +signals: + void closeBtnClicked(); + void printExcel(CEventView* view,CEventItemModel *model,QString fileName); + void printExcelHis(CEventView* view,CEventHistoryModel *model,QString fileName); + + void openAccidentReviewDialog(quint64 starTime,quint64 keepTime,QString graph = QString()); +public slots: + void login(); + + void logout(); + void slotbtnFlash(); + void slotShowResult(QString result); + + void setHiddenLocation(bool hide); + void setHiddenTime(bool hide); + void setHiddenStatus(bool hide); + void setHiddenPriority(bool hide); + void setHiddenCloseButton(bool hide); + void setRowHeight(int height); + void setColumnWidth(const int &column, const int &width); + void setColumnVisible(const int &column, const bool &visible = true); + void setHisColumnWidth(const int &column, const int &width); + void setHisColumnVisible(const int &column, const bool &visible = true); + void setEnableAccidentReview(bool isNeed = true); + void setEnableWave(bool isNeed); + + //< pic子路径 + void setAccidentReviewPath(const QString& path); +public: + void initFilter(); + void setLevelComboBox(bool &isLevelFilter,QList &listLevel); + void setLocationComboBox(bool &isLocationFilter,QList &listLocation); + void setEventStatusComboBox(bool &isEventStatusFilter,QList &listEventStatus); + void setEventTimeLineEdit(bool &isTimeFilter, QDateTime &startTime, QDateTime &endTime); + +protected slots: + void slotClearRTEvent(); + + void slotALlSel(); + void slotNoneSel(); + void deviceGroupFilterChanged(const QString &device, const bool &checked); + void hisDeviceGroupFilterChanged(const QString &device, const bool &checked); + void updateFilter(); + void slot_updateFilter(bool isLevelFilter, QList listLevel, bool isLocationFilter, QList listLocation, bool isRegionFilter, QList listRegion, bool isEventStatusFilter, QList listEventStatus, + bool isDeviceTypeFilter, QString subSystem, QString deviceType, bool isKeywordFilterEnable, + QString keyword, bool isTimeFilter, QDateTime startTime, QDateTime endTime,bool isReturnFilter,bool isReturn); + void slotRTEventStateChanged(); + void slotUpdateRTTips(); //< 更新实时数据文本提示 + //< 更新历史数据文本提示 + void slotUpdateHISTipsRequesting(); + void slotPermInvalid(); + void slotUpdateHISTips(); + void slotHISRecordOutOfRangeTips(QStringList stDescList); + void slotHisOutOfRangeTips(); + void print(); + void stateChanged1(int state); + void stateChanged2(int state); + void stateChanged3(int state); + void textChanged1(const QString &text); + void textChanged2(const QString &text); + void textChanged3(const QString &text); + + void myCalendarHide(QDate startTime, QDate endTime); + void myCalendarShow(); + void cancleTimeFilter(); + + void searchRealDeviceNamechange(const QString &s); + void searchRealDeviceName(); + void searchHistoryDeviceName(); +protected: + void contextMenuEvent(QContextMenuEvent *event); + + void contextMenuRealEvent(QContextMenuEvent *event); + + void contextMenuHisEvent(QContextMenuEvent *event); + + void loadDeviceGroupFilterWidget(); + +private slots: + void updateDeviceGroupHiddenState(); + void updateHisDeviceGroupHiddenState(QList eventList); + void updateHisDeviceGroupHiddenStateRefesh(QList eventList,bool refeshEvent); + + void updateStack(int index); + void on_eventView_2_doubleClicked(const QModelIndex &index); + +private: + void rightAccidentReviewReal(); + void rightAccidentReviewHis(); +private: + Ui::CEventForm *ui; + CEventDelegate *m_pRealDelegate; + CEventDelegate *m_pHistoryDelegate; + CEventItemModel * m_pRealTimeModel; + CEventHistoryModel * m_pHistoryModel; + CEventDeviceTreeModel * m_pDeviceModel; + CEventDeviceTreeModel * m_pDeviceHisModel; + int m_nIsModel; + bool m_isEditMode; + + QLineEdit *m_pRealSearchEdit; + QPushButton *m_pRealSearchButton; + QLineEdit *m_pHistorySearchEdit; + QPushButton *m_pHistorySearchButton; + QListWidget *m_pListWidget1; + QListWidget *m_pListWidget2; + QListWidget *m_pListWidget3; + + QLineEdit *m_pLineEdit1; + QLineEdit *m_pLineEdit2; + QLineEdit *m_pLineEdit3; + QList m_priorityList; + QList m_locationList; + QList m_eventStatusList; + QString m_strText1; + QString m_strText2; + QString m_strText3; + + QPushButton *m_timeIcon; + + CMyCalendar * m_myCalendar; + QMenu *m_timeMenu; + + QThread *m_thread; //打印线程 + CExcelPrinter * m_excelPrinter; + + QThread *m_hisSearch; + CEventHisThread *m_hisWork; + + bool m_enableWave; + bool m_isNeedAccidentReview; + + QButtonGroup *m_buttonGroup; + int m_ncurIndex; + QString m_strAccidenPath; + + QString m_searchRealDeviceName; + QString m_searchHisDeviceName; +}; + +#endif // CEventForm_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventForm.ui b/product/src/gui/plugin/EventWidget_pad/CEventForm.ui new file mode 100644 index 00000000..a407c1d7 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventForm.ui @@ -0,0 +1,698 @@ + + + CEventForm + + + + 0 + 0 + 1665 + 654 + + + + + 0 + 0 + + + + 事件 + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + 0 + + + + + + 0 + 32 + + + + 实时事件 + + + true + + + false + + + + + + + + 0 + 32 + + + + 历史事件 + + + true + + + true + + + + + + + QLayout::SetDefaultConstraint + + + + + + 100 + 0 + + + + 0 + + + + + + + + 0 + 0 + + + + 历史事件总数: + + + Qt::AutoText + + + false + + + + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 6 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 优先级: + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 位置: + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 事件状态: + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 26 + + + + 时间: + + + + + + + + 0 + 0 + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + 清空 + + + + + + + 刷新 + + + + + + + 过滤 + + + + + + + 导出 + + + + + + + 关闭 + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + QFrame::Panel + + + QFrame::Raised + + + 1 + + + + 0 + + + 0 + + + 0 + + + 6 + + + + + Qt::Vertical + + + + + 280 + 0 + + + + QFrame::Sunken + + + 1 + + + + + + 5 + + + 0 + + + + + 全勾选 + + + + + + + 全不选 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + 0 + 0 + + + + 1 + + + + + QLayout::SetDefaultConstraint + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + 600 + 300 + + + + QFrame::Sunken + + + false + + + false + + + + + + 210 + 0 + + + + + + + + + + + + + 0 + 0 + + + + 实时事件总数: + + + Qt::AutoText + + + false + + + + + + + + + + 100 + 0 + + + + 0 + + + + + + + Qt::Horizontal + + + + 493 + 20 + + + + + + + + + + + + + + QLayout::SetDefaultConstraint + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 600 + 0 + + + + true + + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + 1 + + + Qt::ScrollBarAsNeeded + + + QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed + + + true + + + false + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + false + + + + + + + + + + + + + CEventView + QTableView +
CEventView.h
+
+ + CEventDeviceTreeView + QTreeView +
CEventDeviceTreeView.h
+
+
+ + + + filter + clicked() + CEventForm + updateFilter() + + + 650 + 25 + + + 599 + 0 + + + + + print + clicked() + CEventForm + print() + + + 722 + 21 + + + 743 + 21 + + + + + + updateFilter() + print() + +
diff --git a/product/src/gui/plugin/EventWidget_pad/CEventHisThread.cpp b/product/src/gui/plugin/EventWidget_pad/CEventHisThread.cpp new file mode 100644 index 00000000..455e8802 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventHisThread.cpp @@ -0,0 +1,686 @@ +#include "CEventHisThread.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_logger_api/logger.h" +#include +#include "CEventDataCollect.h" +#include "perm_mng_api/PermMngApi.h" + +using namespace std; + +CEventHisThread::CEventHisThread(QObject *parent) : QObject(parent), + m_pReadDb(Q_NULLPTR), m_rtdbPriorityOrderAccess(nullptr) +{ +} + +CEventHisThread::~CEventHisThread() +{ + if(m_pReadDb) + { + m_pReadDb->close(); + delete m_pReadDb; + } + m_pReadDb = NULL; +} + +void CEventHisThread::init() +{ + m_pReadDb = new iot_dbms::CDbApi(DB_CONN_HIS_READ); + if(!m_pReadDb->open()) + { + LOGERROR("打开数据库失败,error:%s",m_pReadDb->getLastErrorString().toStdString().c_str()); + } + + m_rtdbPriorityOrderAccess = new iot_dbms::CRdbAccess(); + m_rtdbPriorityOrderAccess->open("base", "alarm_level_define"); +} + +int CEventHisThread::queryPriorityOrder(int &id) +{ + iot_dbms::CTableLockGuard locker(*m_rtdbPriorityOrderAccess); + iot_dbms::CVarType value; + m_rtdbPriorityOrderAccess->getColumnValueByKey((void*)&id, "priority_order", value); + return value.toInt(); +} + +void CEventHisThread::condition(QList &showEventList, QList &listEvents) +{ + QList::iterator it = listEvents.begin(); + int count = 0; + while (it != listEvents.end()) { + if(conditionFilter(*it)) + { + showEventList.append(*it); + count++; + } + + if(count == LIMIT_HIS_RECORD) + { + break; + } + it++; + } +} + +bool CEventHisThread::conditionFilter(const EventMsgPtr info) +{ + if(m_stFilter.isLevelFilterEnable && !m_stFilter.levelFilter.contains(info->priority)) + { + return false; + } + // if(m_stFilter.isLocationFilterEnable && !m_stFilter.locationFilter.contains(info->location_id)) + // { + // return false; + // } + + // if(m_stFilter.isRegionFilterEnable) + // { + // if(!m_stFilter.regionFilter.contains(info->region_id)) + // { + // return false; + // } + // } + // else + // { + // if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 + // { + // return false; + // } + // } + //事件状态过滤 +// if(m_stFilter.isStatusFilterEnable && !m_stFilter.statusFilter.contains(info->alm_status)) +// { +// return false; +// } +// if(m_stFilter.isDeviceTypeFileter) +// { +// if(CEventDataCollect::instance()->deviceTypeId(m_stFilter.deviceType) != info->dev_type) +// { +// return false; +// } +// } +// if(m_stFilter.isKeywordEnable) +// { +// if(!info->content.contains(m_stFilter.keyword)) +// { +// return false; +// } +// } + //不再需要时间过滤 + if(m_stFilter.isReturnFilterEnable) + { + if(m_stFilter.isReturn) + { + if(info->alm_style != AS_ALARM_RTN ) + { + return false; + } + } + else + { + if(info->alm_style != AS_ALARM) + { + return false; + } + } + } + + return true; +} + +QString CEventHisThread::buildCondition() +{ + QString conditionFilter; + //< 内容 + QString content = buildConditionPartContent(); + if(!content.isEmpty()) + { + conditionFilter += content; + } + + //< 等级 + QString priority = buildConditionPartPriority(); + if(!conditionFilter.isEmpty() && !priority.isEmpty()) + { + conditionFilter += " AND "; + } + if(!priority.isEmpty()) + { + conditionFilter += priority; + } + //< 告警状态 + QString status = buildConditionPartStatus(); + if(!conditionFilter.isEmpty() && !status.isEmpty()) + { + conditionFilter += " AND "; + } + if(!status.isEmpty()) + { + conditionFilter += status; + } + + + //< 设备类型 + QString device_type = buildConditionPartDeviceType(); + if(!conditionFilter.isEmpty() && !device_type.isEmpty()) + { + conditionFilter += " AND "; + } + if(!device_type.isEmpty()) + { + conditionFilter += device_type; + } + + return conditionFilter; +} + +QString CEventHisThread::buildLocAndRegion() +{ + QString conditionFilter = QString(); + //< 车站 + + QString location_id = buildConditionPartLocation(); + if(location_id.isEmpty()) + { + return QString(); + }else + { + conditionFilter += location_id; + } + + //< 责任区 + QString region_id = buildConditionPartRegion(); + if(region_id.isEmpty()) + { + return QString(); + }else + { + conditionFilter += " AND "; + conditionFilter +=region_id; + } + return conditionFilter; +} + +QString CEventHisThread::buildConditionPartPriority() +{ + if(m_stFilter.isLevelFilterEnable) + { + QString strFilter; + for(int nIndex = 0; nIndex < m_stFilter.levelFilter.size(); nIndex++) + { + strFilter.append(QString::number(m_stFilter.levelFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("priority").arg(strFilter); + } + return strFilter; + } + return QString(); +} + +QString CEventHisThread::buildConditionPartStatus() +{ + if(m_stFilter.isStatusFilterEnable) + { + QString strFilter; + for(int nIndex = 0; nIndex < m_stFilter.statusFilter.size(); nIndex++) + { + strFilter.append(QString::number(m_stFilter.statusFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("alm_status").arg(strFilter); + } + return strFilter; + } + return QString(); +} + +QString CEventHisThread::buildConditionPartLocation() +{ + QList locationFilter; + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + if(m_stFilter.isLocationFilterEnable) + { + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + if(m_stFilter.locationFilter.contains(*location)) + { + locationFilter.append(*location); + } + location++; + } + } + else + { + locationFilter = QVector::fromStdVector(vecLocationId).toList(); + } + } + else + { + LOGERROR("获取当前用户事件权限失败!"); + return QString(); + } + } + + QString strFilter; + for(int nIndex = 0; nIndex < locationFilter.size(); nIndex++) + { + strFilter.append(QString::number(locationFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); + } + return strFilter; +} + +QString CEventHisThread::buildConditionPartRegion() +{ + QList regionFilter; + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + if(m_stFilter.isRegionFilterEnable) + { + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + if(m_stFilter.regionFilter.contains(*region)) + { + regionFilter.append(*region); + } + region++; + } + } + else + { + regionFilter = QVector::fromStdVector(vecRegionId).toList(); + } + } + else + { + LOGERROR("获取当前用户事件权限失败!"); + return QString(); + } + } + + + QString strFilter; + for(int nIndex = 0; nIndex < regionFilter.size(); nIndex++) + { + strFilter.append(QString::number(regionFilter.at(nIndex)) + ", "); + } + strFilter.append(QString::number(0) + ", ");//防止责任区为空 + strFilter.append(QString::number(-1) + ", ");//防止责任区为空 + + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); + return strFilter; +} + +QString CEventHisThread::buildConditionPartDeviceType() +{ + if(m_stFilter.isDeviceTypeFileter) + { + return QString("(%1 = %2)").arg("dev_type").arg(CEventDataCollect::instance()->deviceTypeId(m_stFilter.deviceType)); + } + return QString(); +} + +QString CEventHisThread::buildConditionPartContent() +{ + if(m_stFilter.isKeywordEnable && !m_stFilter.keyword.isEmpty()) + { + QString strFilter = QString("(%1 like '%" ).arg("content") + m_stFilter.keyword + QString("%')"); + return strFilter; + } + return QString(); +} + +void CEventHisThread::doWork(ST_FILTER stFilter) +{ + m_stFilter = stFilter; + if(m_stFilter.isReturnFilterEnable) + { + doReturnFilterEnable(); + }else + { + doReturnFilterDisenable(); + } + +// if(m_stFilter.isReturnFilterEnable) +// { + + +// }else +// { +// sql = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file from his_event"); +// sql= QString("%1 where (time_stamp between %2 and %3) ").arg(sql).arg(startStamp).arg(endStamp); + +// QString locAndRegionFilter = buildLocAndRegion(); +// if(locAndRegionFilter.isEmpty()) +// { +// emit sigUpdateHisEvent(showEventList); +// LOGERROR("doWork()无所属车站或责任区,停止查询!"); +// return ; +// } +// sql = QString("%1 and %2 ").arg(sql).arg(locAndRegionFilter); + +// QString conditionFilter = buildCondition(); +// if(!conditionFilter.isEmpty()) +// { +// sql = QString("%1 and %2 ").arg(sql).arg(conditionFilter); +// } +// sql = QString("%1 order by time_stamp desc limit %2").arg(sql).arg(LIMIT_HIS_RECORD); +// } + +// LOGDEBUG("his sql:%s",sql.toStdString().c_str()); +// if(m_pReadDb->isOpen()) +// { +// QSqlQuery query; +// try +// { +// m_pReadDb->execute(sql,query); +// } +// catch(...) +// { +// qDebug() << "Query Error!"; +// } +// if(m_stFilter.isReturnFilterEnable) +// { +// QMap exitTagMap; +// if(query.isActive()) +// { +// while(query.next()) +// { +// EventMsgPtr info(new CEventMsgInfo); +// info->time_stamp = query.value(0).toULongLong(); +// info->priority = query.value(1).toInt(); +// info->location_id = query.value(2).toInt(); +// info->region_id = query.value(3).toInt(); +// info->content = query.value(4).toString(); +// info->alm_type = query.value(5).toInt(); +// info->alm_status = query.value(6).toInt(); +// int logic = query.value(7).toInt(); +// if(logic == 0) +// { +// info->alm_style = AS_ALARM; +// }else if(logic ==1) +// { +// info->alm_style = AS_ALARM_RTN; +// }else +// { +// info->alm_style = AS_EVENT_ONLY; +// } +// info->dev_type = query.value(8).toInt(); +// info->cfm_user = query.value(9).toUInt(); +// info->cfm_time = query.value(10).toULongLong(); +// info->key_id_tag = query.value(11).toString(); +// info->priorityOrder = queryPriorityOrder(info->priority); +// info->wave_file = query.value(12).toString(); +// if(exitTagMap.find(info->key_id_tag) == exitTagMap.end()) +// { +// historyEventList.append(info); +// exitTagMap[info->key_id_tag] = true; +// } +// } +// } +// exitTagMap.clear(); +// }else +// { +// if(query.isActive()) +// { +// while(query.next()) +// { +// EventMsgPtr info(new CEventMsgInfo); +// info->time_stamp = query.value(0).toULongLong(); +// info->priority = query.value(1).toInt(); +// info->location_id = query.value(2).toInt(); +// info->region_id = query.value(3).toInt(); +// info->content = query.value(4).toString(); +// info->alm_type = query.value(5).toInt(); +// info->alm_status = query.value(6).toInt(); +// int logic = query.value(7).toInt(); +// if(logic == 0) +// { +// info->alm_style = AS_ALARM; +// }else if(logic ==1) +// { +// info->alm_style = AS_ALARM_RTN; +// }else +// { +// info->alm_style = AS_EVENT_ONLY; +// } +// info->dev_type = query.value(8).toInt(); +// info->cfm_user = query.value(9).toUInt(); +// info->cfm_time = query.value(10).toULongLong(); +// info->key_id_tag = query.value(11).toString(); +// info->priorityOrder = queryPriorityOrder(info->priority); +// info->wave_file = query.value(12).toString(); +// historyEventList.append(info); +// } +// } +// } +// } + +// if(m_stFilter.isReturnFilterEnable) +// { +// condition(showEventList,historyEventList); +// }else +// { +// showEventList.swap(historyEventList); +// } +// emit sigUpdateHisEvent(showEventList); +} + +void CEventHisThread::doReturnFilterEnable() +{ + QList historyEventList;//查询到的所有 + QString sql; + QList showEventList; + qint64 startStamp = m_stFilter.startTime.toMSecsSinceEpoch(); + qint64 endStamp = m_stFilter.endTime.toMSecsSinceEpoch(); + + sql = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag from his_event"); + + + //先查询标签和时间 然后根据时间和标签再次查询 + sql = QString("select max(time_stamp),key_id_tag from his_event"); + sql= QString("%1 where (time_stamp between %2 and %3) ").arg(sql).arg(startStamp).arg(endStamp); + QString locAndRegionFilter = buildLocAndRegion(); + if(locAndRegionFilter.isEmpty()) + { + emit sigUpdateHisEvent(showEventList); + LOGERROR("doWork()无所属车站或责任区,停止查询!"); + return ; + } + sql = QString("%1 and %2 ").arg(sql).arg(locAndRegionFilter); + QString conditionFilter = buildCondition(); + if(!conditionFilter.isEmpty()) + { + sql = QString("%1 and %2 ").arg(sql).arg(conditionFilter); + } + sql = QString("%1 group by key_id_tag order by max(time_stamp) desc limit %2").arg(sql).arg(LIMIT_HIS_RECORD); + + LOGDEBUG("his sql:%s",sql.toStdString().c_str()); + + QList keyList; + if(m_pReadDb->isOpen()) + { + QSqlQuery query; + try + { + m_pReadDb->execute(sql,query); + } + catch(...) + { + qDebug() << "Query Error!"; + } + + if(query.isActive()) + { + while(query.next()) + { + STimeKeyIdTag keyInfo; + keyInfo.time_stamp = query.value(0).toULongLong(); + keyInfo.key_id_tag = query.value(1).toString(); + if(!keyInfo.key_id_tag.isEmpty()) + { + keyList.append(keyInfo); + } + } + } + } + if(keyList.isEmpty()) + { + emit sigUpdateHisEvent(showEventList); + return ; + } + //第2次查询结果 + QString sqlBase = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag from his_event"); + int counter = 0; + QString cond = QString(); + for(int index(0);index historyEventList;//查询到的所有 + QString sql; + QList showEventList; + qint64 startStamp = m_stFilter.startTime.toMSecsSinceEpoch(); + qint64 endStamp = m_stFilter.endTime.toMSecsSinceEpoch(); + + sql = QString("select time_stamp,priority,location_id,region_id,content,alm_type,alm_status,alm_style,dev_type,confirm_user_id,confirm_time,key_id_tag,wave_file,dev_group_tag from his_event"); + sql= QString("%1 where (time_stamp between %2 and %3) ").arg(sql).arg(startStamp).arg(endStamp); + + QString locAndRegionFilter = buildLocAndRegion(); + if(locAndRegionFilter.isEmpty()) + { + emit sigUpdateHisEvent(showEventList); + LOGERROR("doWork()无所属车站或责任区,停止查询!"); + return ; + } + sql = QString("%1 and %2 ").arg(sql).arg(locAndRegionFilter); + + QString conditionFilter = buildCondition(); + if(!conditionFilter.isEmpty()) + { + sql = QString("%1 and %2 ").arg(sql).arg(conditionFilter); + } + sql = QString("%1 order by time_stamp desc limit %2").arg(sql).arg(LIMIT_HIS_RECORD); + + LOGDEBUG("his sql:%s",sql.toStdString().c_str()); + if(m_pReadDb->isOpen()) + { + QSqlQuery query; + try + { + m_pReadDb->execute(sql,query); + } + catch(...) + { + qDebug() << "Query Error!"; + } + search(sql,historyEventList); + } + + emit sigUpdateHisEvent(historyEventList); +} + +void CEventHisThread::search(const QString &sql, QList &eventList) +{ + if(m_pReadDb->isOpen()) + { + QSqlQuery query; + try + { + m_pReadDb->execute(sql,query); + } + catch(...) + { + qDebug() << "Query Error!"; + } + + if(query.isActive()) + { + while(query.next()) + { + EventMsgPtr info(new CEventMsgInfo); + info->time_stamp = query.value(0).toULongLong(); + info->priority = query.value(1).toInt(); + info->location_id = query.value(2).toInt(); + info->region_id = query.value(3).toInt(); + info->content = query.value(4).toString(); + info->alm_type = query.value(5).toInt(); + info->alm_status = query.value(6).toInt(); + int logic = query.value(7).toInt(); + if(logic == 0) + { + info->alm_style = AS_ALARM; + }else if(logic ==1) + { + info->alm_style = AS_ALARM_RTN; + }else + { + info->alm_style = AS_EVENT_ONLY; + } + info->dev_type = query.value(8).toInt(); + info->cfm_user = query.value(9).toUInt(); + info->cfm_time = query.value(10).toULongLong(); + info->key_id_tag = query.value(11).toString(); + info->priorityOrder = queryPriorityOrder(info->priority); + info->wave_file = query.value(12).toString(); + info->dev_group_tag = query.value(13).toString(); + eventList.append(info); + } + } + } +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventHisThread.h b/product/src/gui/plugin/EventWidget_pad/CEventHisThread.h new file mode 100644 index 00000000..0f495ec4 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventHisThread.h @@ -0,0 +1,50 @@ +#ifndef CEVENTHISTHREAD_H +#define CEVENTHISTHREAD_H + +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "CEventMsgInfo.h" +#include "db_api_ex/CDbApi.h" +#include + +class CEventHisThread : public QObject +{ + Q_OBJECT +public: + explicit CEventHisThread(QObject *parent = nullptr); + ~CEventHisThread(); + void init(); +private: + int queryPriorityOrder(int &id); + + void condition(QList &showEventList,QList &listEvents); + bool conditionFilter(const EventMsgPtr info); + + QString buildCondition(); + QString buildLocAndRegion(); + QString buildConditionPartPriority(); + QString buildConditionPartStatus(); + QString buildConditionPartLocation(); + QString buildConditionPartRegion(); + QString buildConditionPartDeviceType(); + QString buildConditionPartContent(); + +public slots: + void doWork(ST_FILTER stFilter); + + void doReturnFilterEnable(); + + void doReturnFilterDisenable(); + + void search(const QString &sql, QList &eventList); + +signals: + void sigUpdateHisEvent(QList eventSet); + +private: + iot_dbms::CDbApi * m_pReadDb; + iot_dbms::CRdbAccess * m_rtdbPriorityOrderAccess; + ST_FILTER m_stFilter; +}; + +#endif // CEVENTHISTHREAD_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventHistoryModel.cpp b/product/src/gui/plugin/EventWidget_pad/CEventHistoryModel.cpp new file mode 100644 index 00000000..867ccdd1 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventHistoryModel.cpp @@ -0,0 +1,961 @@ +#include "CEventHistoryModel.h" +#include "CEventMsgInfo.h" +#include +#include +#include +#include +#include "CEventDataCollect.h" +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "pub_logger_api/logger.h" +#include "perm_mng_api/PermMngApi.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include "CEventMsgManage.h" +///////////////////////////////////////////////////////////////////////////// + +typedef QPair > PAIRLISTALARMINFO; + +CEventHistoryModel::CEventHistoryModel(QObject *parent) + :QAbstractTableModel(parent), + m_sortKey(E_SORT_TIME), + m_order(Qt::DescendingOrder) +{ + header << tr("时间") << tr("优先级") + << tr("位置") << tr("责任区") << tr("事件类型")<< tr("事件状态")<< tr("复归状态")<< tr("确认人")<< tr("确认时间") + << tr(" 事件内容"); + initialize(); +} + +CEventHistoryModel::~CEventHistoryModel() +{ + m_listShowEventInfo.clear(); + m_listAllEventInfo.clear(); +} + +void CEventHistoryModel::initialize() +{ + beginResetModel(); + m_listShowEventInfo.clear(); + m_listAllEventInfo.clear(); + endResetModel(); + initFilter(); + +} + +void CEventHistoryModel::initFilter() +{ + m_isLevelFilterEnable = false; + m_levelFilter.clear(); + m_isLocationFilterEnable = false; + m_locationFilter.clear(); + m_isRegionFilterEnable = false; + m_regionFilter.clear(); + m_isStatusFilterEnable = false; + m_statusFilter.clear(); + m_statusFilter2.clear(); + m_isDeviceTypeFileter = false; + m_subSystem = QString(); + m_deviceType = QString(); + m_isKeywordEnable = false; + m_keyword = QString(); + m_timeFilterEnable = false; + + m_isReturnFilterEnable = false; + m_isReturn = false; + addDeviceGroupFilter(); + + // m_isLevelFilterEnable = false; + // m_levelFilter = CEventDataCollect::instance()->priorityList(); + // m_isLocationFilterEnable = false; + // m_locationFilter = CEventDataCollect::instance()->locationList(); + // m_isRegionFilterEnable = false; + // m_regionFilter = CEventDataCollect::instance()->regionList(); + // m_isTypeFilterEnable = false; + // m_typeFilter = CEventDataCollect::instance()->alarmTypeList(); + // setFilter(m_isLevelFilterEnable, m_levelFilter, m_isLocationFilterEnable, m_locationFilter, m_isRegionFilterEnable, m_regionFilter, m_isTypeFilterEnable, m_typeFilter); +} + +void CEventHistoryModel::loadEventHistoryData() +{ + //< 权限判断 + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if( PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + emit sigPermInvalid(); + return; + } + } + + //< 报警类型 + QStringList listHistoryEventTableName; + listHistoryEventTableName.append("his_event"); + emit sigHisEventRequesting(); + + ST_FILTER stFilter; + setStFilter(stFilter); + emit requestHistory(stFilter); +} + +QString CEventHistoryModel::bulidCondition() +{ + QString conditionFilter; + + //< 内容 + QString content = bulidConditionPartContent(); + if(!content.isEmpty()) + { + conditionFilter += content; + } + + //< 等级 + QString priority = bulidConditionPartPriority(); + if(!conditionFilter.isEmpty() && !priority.isEmpty()) + { + conditionFilter += " AND "; + } + if(!priority.isEmpty()) + { + conditionFilter += priority; + } + //< 告警状态 + QString status = bulidConditionPartStatus(); + if(!conditionFilter.isEmpty() && !status.isEmpty()) + { + conditionFilter += " AND "; + } + if(!status.isEmpty()) + { + conditionFilter += status; + } + //< 复归状态 + QString returnStatus = buildConditionParaReturnStatus(); + if(!conditionFilter.isEmpty() && !returnStatus.isEmpty()) + { + conditionFilter += " AND "; + } + if(!returnStatus.isEmpty()) + { + conditionFilter += returnStatus; + } + //LOGDEBUG("bulidConditionPartStatus():[%s]",status.toStdString().c_str()); + //< 车站 + + // iot_public::SNodeInfo stNodeInfo; + // iot_public::SLocationInfo stLocationInfo; + // iot_public::CSysInfoInterfacePtr spSysInfo; + // if (iot_public::createSysInfoInstance(spSysInfo)) + // { + // spSysInfo->getLocalNodeInfo(stNodeInfo); + // spSysInfo->getLocationInfoById(stNodeInfo.nLocationId, stLocationInfo); + // } + // else + // { + // LOGERROR("历史事件-无法获取位置信息...") + + // } + // bool bIsCenter = stLocationInfo.bIsCenter; + // int nLocationId = stNodeInfo.nLocationId; + + // QString location_id; + // if(bIsCenter) + // { + // location_id = bulidConditionPartInteger(m_isLocationFilterEnable, "location_id", m_locationFilter); + // } + // else + // { + // QList location; + // location.append(nLocationId); + // location_id = bulidConditionPartInteger(true, "location_id", location); + // } + QString location_id = bulidConditionPartLocation(); + if(!conditionFilter.isEmpty() && !location_id.isEmpty()) + { + conditionFilter += " AND "; + } + if(!location_id.isEmpty()) + { + conditionFilter += location_id; + } + + //< 责任区 + QString region_id = bulidConditionPartRegion(); + if(!conditionFilter.isEmpty() && !region_id.isEmpty()) + { + conditionFilter += " AND "; + } + if(!region_id.isEmpty()) + { + conditionFilter += region_id; + } + + //< 设备类型 + QString device_type = bulidConditionPartDeviceType(); + if(!conditionFilter.isEmpty() && !device_type.isEmpty()) + { + conditionFilter += " AND "; + } + if(!device_type.isEmpty()) + { + conditionFilter += device_type; + } + + //< 时标 + QString time_stamp = bulidConditionPartDateTime(); + if(!conditionFilter.isEmpty() && !time_stamp.isEmpty()) + { + conditionFilter += " AND "; + } + if(!time_stamp.isEmpty()) + { + conditionFilter += time_stamp; + } + + return conditionFilter; +} + +QString CEventHistoryModel::bulidConditionPartPriority() +{ + if(m_isLevelFilterEnable) + { + QString strFilter; + for(int nIndex = 0; nIndex < m_levelFilter.size(); nIndex++) + { + strFilter.append(QString::number(m_levelFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("priority").arg(strFilter); + } + return strFilter; + } + return QString(); +} + +QString CEventHistoryModel::bulidConditionPartStatus() +{ + if(m_isStatusFilterEnable) + { + QString strFilter; + for(int nIndex = 0; nIndex < m_statusFilter.size(); nIndex++) + { + strFilter.append(QString::number(m_statusFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("alm_status").arg(strFilter); + } + return strFilter; + } + return QString(); +} + +QString CEventHistoryModel::buildConditionParaReturnStatus() +{ + if(m_isReturnFilterEnable) + { + QString strFilter; + if(m_isReturn) + { + strFilter = QString("%1 = %2").arg("alm_style").arg(1);//返回状态 返回确认状态 返回删除状态 返回确认删除状态 + }else + { + strFilter = QString("%1 = %2").arg("alm_style").arg(0); + } + return strFilter; + } + return QString(); +} + +QString CEventHistoryModel::bulidConditionPartLocation() +{ + QList locationFilter; + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + if(m_isLocationFilterEnable) + { + std::vector ::iterator location = vecLocationId.begin(); + while (location != vecLocationId.end()) + { + if(m_locationFilter.contains(*location)) + { + locationFilter.append(*location); + } + location++; + } + } + else + { + locationFilter = QVector::fromStdVector(vecLocationId).toList(); + } + } + else + { + return QString(); + } + } + + QString strFilter; + for(int nIndex = 0; nIndex < locationFilter.size(); nIndex++) + { + strFilter.append(QString::number(locationFilter.at(nIndex)) + ", "); + } + + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); + }else + { + strFilter = QString("(%1 in (%2))").arg("location_id").arg(strFilter); + } + return strFilter; +} + +QString CEventHistoryModel::bulidConditionPartRegion() +{ + QList regionFilter; + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + permMngPtr->PermDllInit(); + std::vector vecLocationId; + std::vector vecRegionId; + if(0 <= permMngPtr->GetSpeFunc(FUNC_SPE_EVENT_VIEW, vecRegionId, vecLocationId)) + { + if(m_isRegionFilterEnable) + { + std::vector ::iterator region = vecRegionId.begin(); + while (region != vecRegionId.end()) + { + if(m_regionFilter.contains(*region)) + { + regionFilter.append(*region); + } + region++; + } + } + else + { + regionFilter = QVector::fromStdVector(vecRegionId).toList(); + } + } + else + { + return QString(); + } + } + + + QString strFilter; + for(int nIndex = 0; nIndex < regionFilter.size(); nIndex++) + { + strFilter.append(QString::number(regionFilter.at(nIndex)) + ", "); + } + strFilter.append(QString::number(0) + ", ");//防止责任区为空 + strFilter.append(QString::number(-1) + ", ");//防止责任区为空 + if(!strFilter.isEmpty()) + { + strFilter.resize(strFilter.size() - 2); + strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); + }else + { + strFilter = QString("(%1 in (%2) or %3 is Null)").arg("region_id").arg(strFilter).arg("region_id"); + } + return strFilter; +} + +QString CEventHistoryModel::bulidConditionPartDeviceType() +{ + if(m_isDeviceTypeFileter) + { + return QString("(%1 = %2)").arg("dev_type").arg(CEventDataCollect::instance()->deviceTypeId(m_deviceType)); + } + return QString(); +} + +QString CEventHistoryModel::bulidConditionPartContent() +{ + if(m_isKeywordEnable && !m_keyword.isEmpty()) + { + QString strFilter = QString("(%1 like '%" ).arg("content") + m_keyword + QString("%')"); + return strFilter; + } + return QString(); +} + +QString CEventHistoryModel::bulidConditionPartDateTime() +{ + if(m_timeFilterEnable) + { + qint64 start_timeStamp = m_startTime.toMSecsSinceEpoch(); + qint64 end_timeStamp = m_endTime.toMSecsSinceEpoch(); + QString strFilter = QString("(%1 between %2 AND %3)").arg("time_stamp").arg(start_timeStamp).arg(end_timeStamp); + return strFilter; + } + return QString(); +} + +EventMsgPtr CEventHistoryModel::getAlarmInfo(const QModelIndex &index) const +{ + if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) + { + return NULL; + } + + return m_listShowEventInfo.at(index.row()); +} + +QVariant CEventHistoryModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(header.at(section)); + } + return QVariant(); +} + +QVariant CEventHistoryModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == 9) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + } + else if(Qt::DisplayRole == role) + { + + switch ( index.column() ) + { + case 0 : + { + return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->time_stamp).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + case 1 : + { + return CEventDataCollect::instance()->priorityDescription(m_listShowEventInfo.at(index.row())->priority); + } + case 2 : + { + return CEventDataCollect::instance()->locationDescription(m_listShowEventInfo.at(index.row())->location_id); + } + case 3 : + { + return CEventDataCollect::instance()->regionDescription(m_listShowEventInfo.at(index.row())->region_id); + } + case 4 : + { + return CEventDataCollect::instance()->alarmTypeDescription(m_listShowEventInfo.at(index.row())->alm_type); + } + case 5 : + { + return CEventDataCollect::instance()->alarmStatusDescription(m_listShowEventInfo.at(index.row())->alm_status); + } + case 6 : + { + if(m_listShowEventInfo.at(index.row())->alm_style == AS_ALARM) //未复归 + { + return tr("未复归"); + } + else if(m_listShowEventInfo.at(index.row())->alm_style == AS_ALARM_RTN) //已复归 + { + return tr("已复归"); + }else{ + return QString("-"); + } + } + case 7 : + { + QString userName = CEventDataCollect::instance()->userNameDescription(m_listShowEventInfo.at(index.row())->cfm_user); + if(userName.isEmpty()) + { + return QString("-"); + }else + { + return userName; + } + } + case 8 : + { + if(m_listShowEventInfo.at(index.row())->cfm_time == 0) + { + return QString("-"); + }else + { + return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->cfm_time).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + } + case 9 : + { + return m_listShowEventInfo.at(index.row())->content; + } + default: + return QVariant(); + } + } + return QVariant(); +} + +int CEventHistoryModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + + return header.count(); +} + +int CEventHistoryModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + return m_listShowEventInfo.count(); +} + +Qt::ItemFlags CEventHistoryModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +void CEventHistoryModel::sort() +{ + QMap mapAlarmInfo; + //<分 + for(int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) + { + EventMsgPtr temp = m_listShowEventInfo.at(nIndex); + mapAlarmInfo[nIndex / 1000].second.append(temp); + } + + //<快速排序 + for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) + { + qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); + } + + //<治 + PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; + for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) + { + //<归并 + tempListAlarmInfo.first = 0; + mapAlarmInfo[nPairIndex].first = 0; + while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) + { + if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) + { + tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + } + tempListAlarmInfo.first += 1; + } + } + m_listShowEventInfo = tempListAlarmInfo.second; +} + +void CEventHistoryModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CEventHistoryModel::partitionAscendingOrder(QList &list, int start, int last) +{ + EventMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftlessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CEventHistoryModel::partitionDescendingOrder(QList &list, int start, int last) +{ + EventMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +void CEventHistoryModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, + const bool &isKeywordFilterEnable, const QString &keyword, + const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime, const bool &isReturnFilterEnable, const bool &isReturn) +{ + m_isLevelFilterEnable = isLevelFilterEnable; + m_levelFilter = levelFilter; + m_isLocationFilterEnable = isStationFilterEnable; + m_locationFilter = stationFilter; + m_isRegionFilterEnable = isRegionFilterEnable; + m_regionFilter = regionFilter; + + + m_isStatusFilterEnable = isTypeFilterEnable; + m_statusFilter = typeFilter; + m_statusFilter2 = typeFilter; + + m_isReturnFilterEnable = isReturnFilterEnable; + m_isReturn = isReturn; + if(typeFilter.contains(OTHERSTATUS)) + { + QMap alarmOtherMap = CEventDataCollect::instance()->eventOtherStatusDescriptionMap(); + QMap::iterator it = alarmOtherMap.begin(); + for(;it != alarmOtherMap.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + m_isDeviceTypeFileter = isDeviceTypeFilter; + m_subSystem = subSystem; + m_deviceType = deviceType; + m_isKeywordEnable = isKeywordFilterEnable; + m_keyword = keyword; + m_timeFilterEnable = timeFilterEnable; + m_startTime = startTime; + m_endTime = endTime; +} + +void CEventHistoryModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, + bool &returnFilterEnable,bool &isReturn) +{ + isLevelFilterEnable = m_isLevelFilterEnable; + levelFilter = m_levelFilter; + isLocationFilterEnable = m_isLocationFilterEnable; + locationFilter = m_locationFilter; + isRegionFilterEnable = m_isRegionFilterEnable; + regionFilter = m_regionFilter; + isTypeFilterEnable = m_isStatusFilterEnable; + alarmTypeFilter = m_statusFilter2; + subSystem = m_subSystem; + deviceTypeFilter = m_isDeviceTypeFileter; + deviceType = m_deviceType; + keywordFilterEnable = m_isKeywordEnable; + keyword = m_keyword; + timeFilterEnable = m_timeFilterEnable; + startTime = m_startTime; + endTime = m_endTime; + returnFilterEnable = m_isReturnFilterEnable; + isReturn = m_isReturn; +} + +bool CEventHistoryModel::conditionFilter(EventMsgPtr info) +{ + if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) + { + return false; + } + if(m_isLocationFilterEnable && !m_locationFilter.contains(info->location_id)) + { + return false; + } + + if(m_isRegionFilterEnable) + { + if(!m_regionFilter.contains(info->region_id)) + { + return false; + } + } + else + { + if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 + { + return false; + } + } + //事件状态过滤 + if(m_isStatusFilterEnable && !m_statusFilter.contains(info->alm_status)) + { + return false; + } + if(m_isDeviceTypeFileter) + { + if(CEventDataCollect::instance()->deviceTypeId(m_deviceType) != info->dev_type) + { + return false; + } + } + if(m_isKeywordEnable) + { + if(!info->content.contains(m_keyword)) + { + return false; + } + } + if(m_timeFilterEnable) + { + if(m_startTime.toMSecsSinceEpoch() >= (qint64)info->time_stamp) + { + return false; + } + if(m_endTime.toMSecsSinceEpoch() <= (qint64)info->time_stamp) + { + return false; + } + } + if(m_isReturnFilterEnable) + { + if(m_isReturn) + { + if(info->alm_style != AS_ALARM_RTN ) + { + return false; + } + } + else + { + if(info->alm_style != AS_ALARM) + { + return false; + } + } + } + + return true; +} + +void CEventHistoryModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + m_isLevelFilterEnable = isCheck; + m_levelFilter = priorityFilter; +} + +void CEventHistoryModel::setLocationFilter(bool &isCheck, QList &locationFilter) +{ + m_isLocationFilterEnable = isCheck; + m_locationFilter = locationFilter; +} + +void CEventHistoryModel::setEventTypeFilter(bool &isCheck, QList &eventTypeFilter, bool &other) +{ + m_isStatusFilterEnable = isCheck; + m_statusFilter = eventTypeFilter; + m_statusFilter2 = eventTypeFilter; + if(other == true) + { + QMap otherEventStatus = CEventDataCollect::instance()->eventOtherStatusDescriptionMap(); + QMap::iterator it = otherEventStatus.begin(); + for(;it != otherEventStatus.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } +} + +void CEventHistoryModel::setEventTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) +{ + m_timeFilterEnable = isCheck; + if(isCheck) + { + QTime time_1(0,0,0); + QTime time_2(23,59,59); + m_startTime.setDate(startTime); + m_startTime.setTime(time_1); + m_endTime.setDate(endTime); + m_endTime.setTime(time_2); + } +} + +void CEventHistoryModel::setEventTimeFilter(bool &isCheck) +{ + m_timeFilterEnable = isCheck; +} + +void CEventHistoryModel::getPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + isCheck = m_isLevelFilterEnable; + priorityFilter = m_levelFilter; +} + +void CEventHistoryModel::getLocationFilter(bool &isCheck, QList &locationFilter) +{ + isCheck = m_isLocationFilterEnable; + locationFilter = m_locationFilter; +} + +void CEventHistoryModel::getEventStatusFilter(bool &isCheck, QList &eventStatusFilter) +{ + isCheck = m_isStatusFilterEnable; + eventStatusFilter = m_statusFilter2; +} + +QList CEventHistoryModel::getListEventInfo() +{ + return m_listShowEventInfo; +} + +void CEventHistoryModel::addDeviceGroupFilter() +{ + for(QString group : CEventDataCollect::instance()->getDevGroupTagList()) + { + m_deviceGroupFilter.insert(group); + } + +} + +void CEventHistoryModel::removeDeviceGroupFilter() +{ + m_deviceGroupFilter.clear(); +} + +void CEventHistoryModel::addDeviceGroupFilter(const QString &device) +{ + QString deviceG = device; + QStringList devGList = deviceG.split(","); + foreach (QString devG, devGList) { + m_deviceGroupFilter.insert(devG); + } +} + +void CEventHistoryModel::removeDeviceGroupFilter(const QString &device) +{ + m_deviceGroupFilter.remove(device); +} + +void CEventHistoryModel::updateEvents(QList eventList) +{ + m_listAllEventInfo = eventList; + + updateShowEvents(); +} + +void CEventHistoryModel::updateShowEvents() +{ + beginResetModel(); + m_listShowEventInfo.clear(); + QList::iterator it = m_listAllEventInfo.begin(); + while (it != m_listAllEventInfo.end()) { + //< 设备组 + if(m_deviceGroupFilter.contains((*it)->dev_group_tag)) + { + m_listShowEventInfo.append(*it); + } + it++; + } + endResetModel(); + emit sigHisEventSizeChanged(); +} + +void CEventHistoryModel::setStFilter(ST_FILTER &stFilter) +{ + stFilter.isLevelFilterEnable = m_isLevelFilterEnable; + stFilter.levelFilter = m_levelFilter; + stFilter.isLocationFilterEnable = m_isLocationFilterEnable; + stFilter.locationFilter = m_locationFilter; + stFilter.isRegionFilterEnable = m_isRegionFilterEnable; + stFilter.regionFilter = m_regionFilter; + stFilter.isStatusFilterEnable = m_isStatusFilterEnable; + stFilter.statusFilter = m_statusFilter; + stFilter.statusFilter2 = m_statusFilter2; + stFilter.isDeviceTypeFileter = m_isDeviceTypeFileter; + + stFilter.subSystem = m_subSystem; + stFilter.deviceType = m_deviceType; + stFilter.isKeywordEnable = m_isKeywordEnable; + stFilter.keyword = m_keyword; + stFilter.timeFilterEnable = m_timeFilterEnable; + stFilter.startTime = m_startTime; + stFilter.endTime = m_endTime; + + stFilter.isReturnFilterEnable = m_isReturnFilterEnable; + stFilter.isReturn = m_isReturn; + +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventHistoryModel.h b/product/src/gui/plugin/EventWidget_pad/CEventHistoryModel.h new file mode 100644 index 00000000..ade99bd9 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventHistoryModel.h @@ -0,0 +1,148 @@ +#ifndef CEVENTHISTORYMODEL_H +#define CEVENTHISTORYMODEL_H + +#include +#include +#include +#include "CEventMsgInfo.h" +#include "CEventDataCollect.h" + +#define Row_Full (15000) +#define MAX_HIS_ROWCOUNT (10000) + +class CEventMsgInfo; + +class CEventHistoryModel : public QAbstractTableModel +{ + Q_OBJECT +public: + CEventHistoryModel(QObject *parent = Q_NULLPTR); + ~CEventHistoryModel(); + + void initialize(); + void initFilter(); + + void loadEventHistoryData(); + + QString bulidCondition(); + QString bulidConditionPartPriority(); + QString bulidConditionPartStatus(); + QString buildConditionParaReturnStatus(); + QString bulidConditionPartLocation(); + QString bulidConditionPartRegion(); + QString bulidConditionPartDeviceType(); + QString bulidConditionPartContent(); + QString bulidConditionPartDateTime(); + + EventMsgPtr getAlarmInfo(const QModelIndex &index) const; + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + void sort(); + void qucikSort(QList &list, int start, int last); + int partitionAscendingOrder(QList &list, int start, int last); + int partitionDescendingOrder(QList &list, int start, int last); + /** + * 设置模型数据过滤条件,过滤显示数据 + */ + void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), + const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), + const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), + const QDateTime &endTime = QDateTime(),const bool &isReturnFilterEnable = false, const bool &isReturn = false); + + /** + * 获取模型数据过滤条件,用于初始化过滤对话框 + */ + void getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, bool &returnFilterEnable, bool &isReturn); + + bool conditionFilter(EventMsgPtr info); + + void setPriorityFilter(bool &isCheck, QList &priorityFilter); + void setLocationFilter(bool &isCheck, QList &locationFilter); + void setEventTypeFilter(bool &isCheck, QList &eventTypeFilter, bool &other); + void setEventTimeFilter(bool &isCheck,QDate &startTime,QDate &endTime); + void setEventTimeFilter(bool &isCheck); + + void getPriorityFilter(bool &isCheck,QList &priorityFilter); + + void getLocationFilter(bool &isCheck,QList &locationFilter); + + void getEventStatusFilter(bool &isCheck, QList &eventStatusFilter); + + QList getListEventInfo(); + + void addDeviceGroupFilter(); + void removeDeviceGroupFilter(); + void addDeviceGroupFilter(const QString &device); + void removeDeviceGroupFilter(const QString &device); +signals: + //void requestHistoryEvents(const QStringList &listHistoryEventTableName,QList typeFilter, const QString &conditionFilter); + void requestHistoryEvents(const QStringList &listHistoryEventTableName, const QString &conditionFilter); + void sigPermInvalid(); + void sigHisEventRequesting(); + void sigHisEventSizeChanged(); + void sigHISRecordOutOfRangeTips(QStringList stDescList); + void sigOutOfRangeTips(); + + void requestHistory(ST_FILTER stFilter); + +public slots: + void updateEvents(QList eventList); + void updateShowEvents(); + +private: + + void setStFilter(ST_FILTER &stFilter); + +private: + QStringList header; + QList m_listShowEventInfo; + QList m_listAllEventInfo; + QList m_listPermLocationId; + QList m_listPermRegionId; + + E_ALARM_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + + //Filter + bool m_isLevelFilterEnable; //是否按报警级别过滤 + QList m_levelFilter; //报警级别过滤 + bool m_isLocationFilterEnable; //是否按车站过滤 + QList m_locationFilter; //车站过滤 + bool m_isRegionFilterEnable; //是否按责任区过滤 + QList m_regionFilter; //责任区过滤 + bool m_isStatusFilterEnable; //是否按报警类型过滤 + QList m_statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) + QList m_statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) + bool m_isDeviceTypeFileter; //设备类型过滤 + QString m_subSystem; //子系统 + QString m_deviceType; //设备类型 + bool m_isKeywordEnable; //关键字过滤 + QString m_keyword; //关键字 + bool m_timeFilterEnable; //是否根据时间过滤 + QDateTime m_startTime; //起始时间 + QDateTime m_endTime; //终止时间 + + bool m_isReturnFilterEnable; //是否根据复归状态过滤 + bool m_isReturn; + + QMap m_areaInfoMap; //区域信息 + + QMap > m_areaLocMap; //区域映射 + QSet m_deviceGroupFilter; //<设备组过滤 +}; + +#endif // CEVENTHISTORYMODEL_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventItemModel.cpp b/product/src/gui/plugin/EventWidget_pad/CEventItemModel.cpp new file mode 100644 index 00000000..58e8ab92 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventItemModel.cpp @@ -0,0 +1,745 @@ +#include "CEventItemModel.h" +#include "CEventMsgInfo.h" +#include +#include +#include +#include +#include "CEventDataCollect.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include "CEventMsgManage.h" +#include "pub_logger_api/logger.h" + +///////////////////////////////////////////////////////////////////////////// + +typedef QPair > PAIRLISTALARMINFO; + +CEventItemModel::CEventItemModel(QObject *parent) + :QAbstractTableModel(parent), + m_sortKey(E_SORT_TIME), + m_order(Qt::AscendingOrder) +{ + header << tr("时间") << tr("优先级") << tr("位置") << tr("责任区") << tr("事件类型") << tr("事件状态") << tr("复归状态") << tr("事件内容"); + initialize(); + connect(CEventDataCollect::instance(), SIGNAL(sigMsgRefresh()), + this, SLOT(slotMsgRefresh()), Qt::QueuedConnection); + + connect(CEventDataCollect::instance(), SIGNAL(sigMsgArrived(QList)), + this, SLOT(slotMsgArrived(QList))); +} + +CEventItemModel::~CEventItemModel() +{ + m_listShowEventInfo.clear(); +} + +void CEventItemModel::initialize() +{ + beginResetModel(); + m_listShowEventInfo.clear(); + endResetModel(); + + initFilterAndReloadData(); +} + +void CEventItemModel::initFilter() +{ + m_isLevelFilterEnable = false; + m_levelFilter.clear(); + m_isLocationFilterEnable = false; + m_locationFilter.clear(); + m_isRegionFilterEnable = false; + m_regionFilter.clear(); + m_isStatusFilterEnable = false; + m_statusFilter.clear(); + m_statusFilter2.clear(); + m_isDeviceTypeFileter = false; + m_subSystem = QString(); + m_deviceType = QString(); + m_isKeywordEnable = false; + m_keyword = QString(); + m_timeFilterEnable = false; + m_isReturnFilterEnable = false; + m_isReturn = false; + addDeviceGroupFilter(); +} + +void CEventItemModel::initFilterAndReloadData() +{ + initFilter(); + slotMsgRefresh(); +} + +EventMsgPtr CEventItemModel::getAlarmInfo(const QModelIndex &index) const +{ + if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) + { + return NULL; + } + + return m_listShowEventInfo.at(index.row()); +} + +const QList CEventItemModel::getListShowAlarmInfo() const +{ + return m_listShowEventInfo; +} + +void CEventItemModel::insertAlarmMsg(EventMsgPtr info) +{ + int nInsertRowIndex = -1; + if (Qt::AscendingOrder == m_order) + { + for (int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) + { + EventMsgPtr msg(m_listShowEventInfo.at(nIndex)); + if (!msg->lessThan(info, m_sortKey)) + { + nInsertRowIndex = nIndex; + break; + } + } + } + else + { + for (int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) + { + EventMsgPtr msg(m_listShowEventInfo.at(nIndex)); + if (!msg->moreThan(info, m_sortKey)) + { + nInsertRowIndex = nIndex; + break; + } + } + } + if (-1 == nInsertRowIndex) + { + nInsertRowIndex = m_listShowEventInfo.count(); + } + + + beginInsertRows(QModelIndex(), nInsertRowIndex, nInsertRowIndex); + m_listShowEventInfo.insert(nInsertRowIndex, info); + endInsertRows(); + + return; +} + +QVariant CEventItemModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role && Qt::Horizontal == orientation) + { + return QVariant(header.at(section)); + } + return QVariant(); +} + +QVariant CEventItemModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid() || index.row() >= m_listShowEventInfo.count()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == (int)E_SORT_CONTENT) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + }else + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + } + else if(Qt::DisplayRole == role) + { + switch (index.column()) + { + case E_SORT_TIME : + { + return QDateTime::fromMSecsSinceEpoch(m_listShowEventInfo.at(index.row())->time_stamp, Qt::LocalTime).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + case E_SORT_PRIORITY : + { + return CEventDataCollect::instance()->priorityDescription(m_listShowEventInfo.at(index.row())->priority); + } + case E_SORT_LOCATION : + { + return CEventDataCollect::instance()->locationDescription(m_listShowEventInfo.at(index.row())->location_id); + } + case E_SORT_REGION : + { + return CEventDataCollect::instance()->regionDescription(m_listShowEventInfo.at(index.row())->region_id); + } + case E_SORT_TYPE : + { + return CEventDataCollect::instance()->alarmTypeDescription(m_listShowEventInfo.at(index.row())->alm_type); + } + case E_SORT_STATUS : + { + return CEventDataCollect::instance()->alarmStatusDescription(m_listShowEventInfo.at(index.row())->alm_status); + } + case E_SORT_STYLE : + { + if(AS_ALARM == m_listShowEventInfo.at(index.row())->alm_style) //未复归 + { + return tr("未复归"); + } + else if(AS_ALARM_RTN == m_listShowEventInfo.at(index.row())->alm_style ) //已复归 + { + return tr("已复归"); + }else{ + return QString("-"); + } + } + case E_SORT_CONTENT : + { + return m_listShowEventInfo.at(index.row())->content; + } + default: + return QVariant(); + } + } + return QVariant(); +} + +int CEventItemModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + + return header.count(); +} + +int CEventItemModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + { + return 0; + } + return m_listShowEventInfo.count(); +} + +Qt::ItemFlags CEventItemModel::flags(const QModelIndex &index) const +{ + // return Qt::NoItemFlags; + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +void CEventItemModel::sortColumn(int column, Qt::SortOrder order) +{ + if(order == Qt::AscendingOrder) + { + m_order = Qt::DescendingOrder; + } + else + { + m_order = Qt::AscendingOrder; + } + m_sortKey = (E_ALARM_SORTKEY)column; + + beginResetModel(); + sort(); + endResetModel(); +} + +//<归并排序 +void CEventItemModel::sort() +{ + QMap mapAlarmInfo; + //<分 + for(int nIndex(0); nIndex < m_listShowEventInfo.count(); nIndex++) + { + EventMsgPtr temp = m_listShowEventInfo.at(nIndex); + mapAlarmInfo[nIndex / 1000].second.append(temp); + } + + //<快速排序 + for(int nMapIndex(0); nMapIndex < mapAlarmInfo.count(); nMapIndex++) + { + qucikSort(mapAlarmInfo[nMapIndex].second, 0, mapAlarmInfo[nMapIndex].second.count() - 1); + } + + //<治 + PAIRLISTALARMINFO tempListAlarmInfo = mapAlarmInfo[0]; + for(int nPairIndex(1); nPairIndex < mapAlarmInfo.count(); nPairIndex++) + { + //<归并 + tempListAlarmInfo.first = 0; + mapAlarmInfo[nPairIndex].first = 0; + while(mapAlarmInfo[nPairIndex].first < mapAlarmInfo[nPairIndex].second.count()) + { + if(tempListAlarmInfo.first >= tempListAlarmInfo.second.count()) + { + tempListAlarmInfo.second.append(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + else + { + if(Qt::AscendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->lessThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + else if(Qt::DescendingOrder == m_order) + { + if(!tempListAlarmInfo.second[tempListAlarmInfo.first]->moreThan(mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first), m_sortKey)) + { + tempListAlarmInfo.second.insert(tempListAlarmInfo.first, mapAlarmInfo[nPairIndex].second.at(mapAlarmInfo[nPairIndex].first)); + mapAlarmInfo[nPairIndex].first += 1; + } + } + } + tempListAlarmInfo.first += 1; + } + } + m_listShowEventInfo = tempListAlarmInfo.second; +} + + +void CEventItemModel::qucikSort(QList &list, int start, int last) +{ + int index; + while(start < last) + { + if(Qt::AscendingOrder == m_order) + { + index = partitionAscendingOrder(list, start, last); + } + else if(Qt::DescendingOrder == m_order) + { + index = partitionDescendingOrder(list, start, last); + } + qucikSort(list, start, index - 1); + start=index+1; //<尾优化 + } +} + +int CEventItemModel::partitionAscendingOrder(QList &list, int start, int last) +{ + EventMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->lessThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftlessThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +int CEventItemModel::partitionDescendingOrder(QList &list, int start, int last) +{ + EventMsgPtr info = list[start]; + int left = start; + int right = last; + while(left < right) + { + while(left < right && !list[right]->moreThan(info, m_sortKey)) + { + --right; + } + list[left] = list[right]; + + while(leftmoreThan(info, m_sortKey)) + { + ++left; + } + list[right] = list[left]; + } + list[left] = info; + return left; +} + +void CEventItemModel::setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter, const QString &subSystem, const QString &deviceType, + const bool &isKeywordFilterEnable, const QString &keyword, + const bool &timeFilterEnable, const QDateTime &startTime, const QDateTime &endTime,const bool &isReturnFilterEnable,const bool &isReturn) +{ + m_isLevelFilterEnable = isLevelFilterEnable; + m_levelFilter = levelFilter; + m_isLocationFilterEnable = isStationFilterEnable; + m_locationFilter = stationFilter; + m_isRegionFilterEnable = isRegionFilterEnable; + m_regionFilter = regionFilter; + m_isStatusFilterEnable = isTypeFilterEnable; + m_statusFilter = typeFilter; + m_statusFilter2 = typeFilter; + if(typeFilter.contains(OTHERSTATUS)) + { + QMap alarmOtherMap = CEventDataCollect::instance()->eventOtherStatusDescriptionMap(); + QMap::iterator it = alarmOtherMap.begin(); + for(;it != alarmOtherMap.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + m_isDeviceTypeFileter = isDeviceTypeFilter; + m_subSystem = subSystem; + m_deviceType = deviceType; + m_isKeywordEnable = isKeywordFilterEnable; + m_keyword = keyword; + m_timeFilterEnable = timeFilterEnable; + m_startTime = startTime; + m_endTime = endTime; + m_isReturnFilterEnable = isReturnFilterEnable; + m_isReturn = isReturn; + slotMsgRefresh(); +} + +void CEventItemModel::getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, + bool &returnFilterEnable,bool &isReturn) +{ + isLevelFilterEnable = m_isLevelFilterEnable; + levelFilter = m_levelFilter; + isLocationFilterEnable = m_isLocationFilterEnable; + locationFilter = m_locationFilter; + isRegionFilterEnable = m_isRegionFilterEnable; + regionFilter = m_regionFilter; + isTypeFilterEnable = m_isStatusFilterEnable; + alarmTypeFilter = m_statusFilter2; + subSystem = m_subSystem; + deviceTypeFilter = m_isDeviceTypeFileter; + deviceType = m_deviceType; + keywordFilterEnable = m_isKeywordEnable; + keyword = m_keyword; + timeFilterEnable = m_timeFilterEnable; + startTime = m_startTime; + endTime = m_endTime; + returnFilterEnable = m_isReturnFilterEnable; + isReturn = m_isReturn; +} + +bool CEventItemModel::conditionFilter(EventMsgPtr info) +{ + //< 等级 + if(m_isLevelFilterEnable && !m_levelFilter.contains(info->priority)) + { + return false; + } + + //< 车站 + if(m_isLocationFilterEnable) + { + if(!m_locationFilter.contains(info->location_id)) + { + return false; + } + } + else + { + if(!CEventDataCollect::instance()->locationList().contains(info->location_id)) + { + return false; + } + } + + //< 责任区 + if(m_isRegionFilterEnable) + { + if(!m_regionFilter.contains(info->region_id)) + { + return false; + } + } + else + { + if(!CEventDataCollect::instance()->regionList().contains(info->region_id) && info->region_id != -1) //< 未配置责任区的报警同样显示 + { + return false; + } + } + + //< 状态 + if(m_isStatusFilterEnable && !m_statusFilter.contains(info->alm_status)) + { + return false; + } + + //< 设备类型 + if(m_isDeviceTypeFileter) + { + if(CEventDataCollect::instance()->deviceTypeId(m_deviceType) != info->dev_type) + { + return false; + } + } + + //< 设备组 + if(!m_deviceGroupFilter.contains(info->dev_group_tag)) + { + return false; + } + + //< 关键字 + if(m_isKeywordEnable) + { + if(!info->content.contains(m_keyword)) + { + return false; + } + } + + //< 时间 + if(m_timeFilterEnable) + { + if((quint64)m_startTime.toMSecsSinceEpoch() >= info->time_stamp) + { + return false; + } + if((quint64)m_endTime.toMSecsSinceEpoch() <= info->time_stamp) + { + return false; + } + } + if(m_isReturnFilterEnable) + { + if(m_isReturn) + { + if(info->alm_style != AS_ALARM_RTN) + { + return false; + } + } + else + { + if(info->alm_style != AS_ALARM ) + { + return false; + } + } + } + return true; +} + +void CEventItemModel::setPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + m_isLevelFilterEnable = isCheck; + m_levelFilter = priorityFilter; + + slotMsgRefresh(); +} + +void CEventItemModel::setLocationFilter(bool &isCheck, QList &locationFilter) +{ + m_isLocationFilterEnable = isCheck; + m_locationFilter = locationFilter; + + slotMsgRefresh(); +} + +void CEventItemModel::setEventTypeFilter(bool &isCheck, QList &eventTypeFilter, bool &other) +{ + m_isStatusFilterEnable = isCheck; + m_statusFilter = eventTypeFilter; + m_statusFilter2 = eventTypeFilter; + if(other == true) + { + QMap otherEventStatus = CEventDataCollect::instance()->eventOtherStatusDescriptionMap(); + QMap::iterator it = otherEventStatus.begin(); + for(;it != otherEventStatus.end(); ++it) + { + m_statusFilter.append(it.key()); + } + } + slotMsgRefresh(); +} + +void CEventItemModel::setEventTimeFilter(bool &isCheck, QDate &startTime, QDate &endTime) +{ + m_timeFilterEnable = isCheck; + if(isCheck) + { + QTime time_1(0,0,0); + QTime time_2(23,59,59); + m_startTime.setDate(startTime); + m_startTime.setTime(time_1); + m_endTime.setDate(endTime); + m_endTime.setTime(time_2); + } + slotMsgRefresh(); +} + +void CEventItemModel::setEventTimeFilter(bool &isCheck) +{ + m_timeFilterEnable = isCheck; + slotMsgRefresh(); +} + +void CEventItemModel::getPriorityFilter(bool &isCheck, QList &priorityFilter) +{ + isCheck = m_isLevelFilterEnable; + priorityFilter = m_levelFilter; +} + +void CEventItemModel::getLocationFilter(bool &isCheck, QList &locationFilter) +{ + isCheck = m_isLocationFilterEnable; + locationFilter = m_locationFilter; +} + +void CEventItemModel::getEventStatusFilter(bool &isCheck, QList &eventStatusFilter) +{ + isCheck = m_isStatusFilterEnable; + eventStatusFilter = m_statusFilter2; +} + +void CEventItemModel::getEventTimeFilter(bool &isCheck, QDateTime &startTime, QDateTime &endTime) +{ + isCheck = m_timeFilterEnable; + startTime = m_startTime; + endTime = m_endTime; +} + +QList CEventItemModel::getListEventInfo() +{ + return m_listShowEventInfo; +} + +void CEventItemModel::addDeviceGroupFilter() +{ + for(QString group : CEventDataCollect::instance()->getDevGroupTagList()) + { + m_deviceGroupFilter.insert(group); + } +} + +void CEventItemModel::removeDeviceGroupFilter() +{ + m_deviceGroupFilter.clear(); +} + +void CEventItemModel::addDeviceGroupFilter(const QString &device) +{ + QString deviceG = device; + QStringList devGList = deviceG.split(","); + foreach (QString devG, devGList) { + m_deviceGroupFilter.insert(devG); + } + slotMsgRefresh(); +} + +void CEventItemModel::removeDeviceGroupFilter(const QString &device) +{ + m_deviceGroupFilter.remove(device); + slotMsgRefresh(); +} + +void CEventItemModel::slotMsgRefresh() +{ + //需要先过滤 + m_listAllEventInfo = CEventMsgManage::instance()->getListEventInfo(); + //根据复归过滤 + QList listFilterInfo; + firstFilterByReturn(listFilterInfo); + m_listAllEventInfo.clear(); + beginResetModel(); + m_listShowEventInfo.clear(); + QList::iterator it = listFilterInfo.begin(); + while (it != listFilterInfo.end()) { + if(conditionFilter(*it)) + { + m_listShowEventInfo.append(*it); + } + it++; + } + sort(); + endResetModel(); +} + +void CEventItemModel::slotMsgArrived(QList listEvents) +{ + if(m_isReturnFilterEnable) + { + slotMsgRefresh(); + }else + { + QList::iterator itPos = listEvents.begin(); + while(itPos != listEvents.end()) + { + if(conditionFilter(*itPos)) + { + insertAlarmMsg(*itPos); + } + itPos++; + } + } + + for(int nIndex = m_listShowEventInfo.size() - 1; nIndex >= 0; --nIndex) + { + if(m_listShowEventInfo.at(nIndex)->deleted) + { + beginRemoveRows(QModelIndex(), nIndex, nIndex); + m_listShowEventInfo.removeAt(nIndex); + endRemoveRows(); + } + } +} + +void CEventItemModel::firstFilterByReturn(QList &filterList) +{ + if(!m_isReturnFilterEnable) + { + filterList = m_listAllEventInfo; + return; + } + + QHash filerHash; + + QList::iterator it = m_listAllEventInfo.begin(); + while (it != m_listAllEventInfo.end()) { + if((*it)->key_id_tag.isEmpty()) + { + it++; + continue; + } + //< 动作和复归 + if((*it)->alm_style == AS_ALARM || (*it)->alm_style == AS_ALARM_RTN) + { + EventMsgPtr ptr = filerHash.value((*it)->key_id_tag,NULL); + if(ptr != NULL) + { + if((*it)->time_stamp >ptr->time_stamp) + { + filerHash[(*it)->key_id_tag] = (*it); + } + }else + { + filerHash[(*it)->key_id_tag] = (*it); + } + } + it++; + } + QHash::iterator pos = filerHash.begin(); + while (pos != filerHash.end()) { + filterList.append(pos.value()); + pos++; + } +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventItemModel.h b/product/src/gui/plugin/EventWidget_pad/CEventItemModel.h new file mode 100644 index 00000000..c1b3c08a --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventItemModel.h @@ -0,0 +1,150 @@ +#ifndef CEVENTITEMMODEL_H +#define CEVENTITEMMODEL_H + +#include +#include +#include +#include +#include "CEventMsgInfo.h" +#include "CEventDataCollect.h" + +#define Row_Full (15000) + +class CEventMsgInfo; +class QTimer; + +class CEventItemModel : public QAbstractTableModel +{ + Q_OBJECT +public: + CEventItemModel(QObject *parent = Q_NULLPTR); + ~CEventItemModel(); + + void initialize(); + void initFilter(); + + void initFilterAndReloadData(); + + EventMsgPtr getAlarmInfo(const QModelIndex &index) const; + + const QList getListShowAlarmInfo() const; + + /** + * @brief insertAlarmMsg 数采通知模型报警到达 + * @param info + */ + void insertAlarmMsg(EventMsgPtr info); + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + void sort(); + void qucikSort(QList &listAlarmInfo, int left, int right); + int partitionAscendingOrder(QList &list, int start, int last); + int partitionDescendingOrder(QList &list, int start, int last); + + /** + * 设置模型数据过滤条件,过滤显示数据 + */ + void setFilter(const bool &isLevelFilterEnable, const QList &levelFilter, + const bool &isStationFilterEnable, const QList &stationFilter, + const bool &isRegionFilterEnable, const QList ®ionFilter, + const bool &isTypeFilterEnable, const QList &typeFilter, + const bool &isDeviceTypeFilter = false, const QString &subSystem = QString(), const QString &deviceType = QString(), + const bool &isKeywordFilterEnable = false, const QString &keyword = QString(), + const bool &timeFilterEnable = false, const QDateTime &startTime = QDateTime(), + const QDateTime &endTime = QDateTime(),const bool &isReturnFilterEnable = false,const bool &isReturn = false); + + /** + * 获取模型数据过滤条件,用于初始化过滤对话框 + */ + void getFilter(bool &isLevelFilterEnable, QList &levelFilter, + bool &isLocationFilterEnable, QList &locationFilter, + bool &isRegionFilterEnable, QList ®ionFilter, + bool &isTypeFilterEnable, QList &alarmTypeFilter, + bool &deviceTypeFilter, QString &subSystem, QString &deviceType, + bool &keywordFilterEnable, QString &keyword, + bool &timeFilterEnable, QDateTime &startTime, QDateTime &endTime, + bool &returnFilterEnable,bool &isReturn); + + bool conditionFilter(EventMsgPtr info); + + void setPriorityFilter(bool &isCheck, QList &priorityFilter); + void setLocationFilter(bool &isCheck, QList &locationFilter); + void setEventTypeFilter(bool &isCheck, QList &eventTypeFilter, bool &other); + void setEventTimeFilter(bool &isCheck,QDate &startTime,QDate &endTime); + void setEventTimeFilter(bool &isCheck); + + void getPriorityFilter(bool &isCheck,QList &priorityFilter); + + void getLocationFilter(bool &isCheck,QList &locationFilter); + + void getEventStatusFilter(bool &isCheck, QList &eventStatusFilter); + + void getEventTimeFilter(bool &isCheck,QDateTime &startTime, QDateTime &endTime); + + QList getListEventInfo(); + + void addDeviceGroupFilter(); + void removeDeviceGroupFilter(); + void addDeviceGroupFilter(const QString &device); + void removeDeviceGroupFilter(const QString &device); +signals: + void sigRowChanged(); + +public slots: + void sortColumn(int column, Qt::SortOrder order = Qt::AscendingOrder); + +private slots: + /** + * @brief slotMsgRefresh 更新model,重新拉取数据 + */ + void slotMsgRefresh(); + + /** + * @brief slotMsgArrived 报警消息到达 + * @param info + */ + void slotMsgArrived(QList listEvents); +private: + void firstFilterByReturn(QList &filterSet); + +private: + QStringList header; + QList m_listShowEventInfo; + QList m_listAllEventInfo; + + E_ALARM_SORTKEY m_sortKey; //排序规则 + Qt::SortOrder m_order; + + //Filter + bool m_isLevelFilterEnable; //是否按报警级别过滤 + QList m_levelFilter; //报警级别过滤 + bool m_isLocationFilterEnable; //是否按车站过滤 + QList m_locationFilter; //车站过滤 + bool m_isRegionFilterEnable; //是否按责任区过滤 + QList m_regionFilter; //责任区过滤 + bool m_isStatusFilterEnable; //是否按事件状态过滤 + QList m_statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) + QList m_statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) + bool m_isDeviceTypeFileter; //设备类型过滤 + QString m_subSystem; //子系统 + QString m_deviceType; //设备类型 + bool m_isKeywordEnable; //关键字过滤 + QString m_keyword; //关键字 + bool m_timeFilterEnable; //是否根据时间过滤 + QDateTime m_startTime; //起始时间 + QDateTime m_endTime; //终止时间 + + bool m_isReturnFilterEnable; //是否根据复归状态过滤 + bool m_isReturn; + + QMap m_areaInfoMap; //区域信息 + + QMap > m_areaLocMap; //区域映射 + QSet m_deviceGroupFilter; //<设备组过滤 +}; + +#endif // CEVENTITEMMODEL_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventMsgInfo.cpp b/product/src/gui/plugin/EventWidget_pad/CEventMsgInfo.cpp new file mode 100644 index 00000000..d269f08d --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventMsgInfo.cpp @@ -0,0 +1,454 @@ +#include "CEventMsgInfo.h" +#include +#include "CEventDataCollect.h" +#include + +CEventMsgInfo::CEventMsgInfo(): alm_status(0), cfm_user(0), cfm_time(0) +{ + alm_type = -1; + alm_style = AS_EVENT_ONLY; + time_stamp = 1000; + domain_id = -1; + location_id = -1; + app_id = -1; + content = QString(""); + priority = -1; + dev_type = -1; + region_id = -1; + key_id_tag = QString(); + uuid_base64 = QString(); + priorityOrder = -1; + deleted = false; + filterDelete = false; + wave_file = QString(); + dev_group_tag = QString(); +} + +CEventMsgInfo::CEventMsgInfo(const CEventMsgInfo &other): alm_status(0), cfm_user(0), cfm_time(0), priorityOrder(0) +{ + alm_type = other.alm_type; + alm_style = other.alm_style; + time_stamp = other.time_stamp; + domain_id = other.domain_id; + location_id = other.location_id; + app_id = other.app_id; + content = other.content; + priority = other.priority; + dev_type = other.dev_type; + key_id_tag = other.key_id_tag; + uuid_base64 = other.uuid_base64; + region_id = other.region_id; + deleted = other.deleted; + filterDelete = other.filterDelete; + wave_file = other.wave_file; + dev_group_tag = other.dev_group_tag; +} + +void CEventMsgInfo::initialize(const iot_idl::SEvtInfoToEvtClt &eventInfo) +{ + alm_type = eventInfo.alm_type(); + E_ALARM_LOGICSTATE logic = (E_ALARM_LOGICSTATE)eventInfo.logic_state(); + if(logic == E_ALS_ALARM || logic == E_ALS_ALARM_CFM || + logic == E_ALS_ALARM_DEL || logic == E_ALS_ALARM_CFM_DEL) + { + alm_style = AS_ALARM; + }else if(logic == E_ALS_RETURN || logic == E_ALS_RETURN_CFM || + logic == E_ALS_RETURN_DEL || logic == E_ALS_RETURN_CFM_DEL) + { + alm_style = AS_ALARM_RTN; + }else{ + alm_style = AS_EVENT_ONLY; + } + time_stamp = eventInfo.time_stamp(); + alm_status = eventInfo.alm_status(); + domain_id = eventInfo.domain_id(); + location_id = eventInfo.location_id(); + app_id = eventInfo.app_id(); + content = QString::fromStdString(eventInfo.content()); + priority = eventInfo.priority(); + dev_type = eventInfo.dev_type(); + key_id_tag = QString::fromStdString(eventInfo.key_id_tag()); + uuid_base64 = QString::fromStdString(eventInfo.uuid_base64()); + if(eventInfo.has_region_id() && eventInfo.region_id() > 0) + { + region_id = eventInfo.region_id(); + } + else + { + region_id = -1; + } + wave_file = QString::fromStdString(eventInfo.wave_file()); + if(eventInfo.has_dev_group_tag()) + { + dev_group_tag = QString::fromStdString(eventInfo.dev_group_tag()); + } +} + +bool CEventMsgInfo::lessThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) + { + case E_SORT_PRIORITY: + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + else if(priorityOrder > info->priorityOrder) + { + return false; + } + else if(priorityOrder == info->priorityOrder) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TIME: + { + if(time_stamp < info->time_stamp) + { + return true; + } + if(time_stamp > info->time_stamp) + { + return false; + } + else if(time_stamp == info->time_stamp) + { + if(priorityOrder <= info->priorityOrder) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOCATION: + { + if(location_id < info->location_id) + { + return true; + } + else if(location_id > info->location_id) + { + return false; + } + else if(location_id == info->location_id) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_REGION: + { + if(region_id < info->region_id) + { + return true; + } + else if(region_id > info->region_id) + { + return false; + } + else if(region_id == info->region_id) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TYPE: + { + if(alm_type < info->alm_type) + { + return true; + } + else if(alm_type > info->alm_type) + { + return false; + } + else if(alm_type == info->alm_type) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_STATUS: + { + if(alm_status < info->alm_status) + { + return true; + } + else if(alm_status > info->alm_status) + { + return false; + } + else if(alm_status == info->alm_status) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_STYLE: + { + if(alm_style alm_style) + { + return true; + } + else if(alm_style >info->alm_style) + { + return false; + } + else + { + if(time_stamp < info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_CONTENT: + { + if(content.isEmpty() && info->content.isEmpty()) + { + return false; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return true; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return false; + } + else if(content < info->content) + { + return true; + } + else if(content > info->content) + { + return false; + } + else if(content == info->content) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + default: + break; + } + return false; +} + +bool CEventMsgInfo::moreThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey) +{ + switch (sortkey) + { + case E_SORT_PRIORITY: + { + if(priorityOrder > info->priorityOrder) + { + return true; + } + else if(priorityOrder < info->priorityOrder) + { + return false; + } + else if(priorityOrder == info->priorityOrder) + { + if(time_stamp >= info->time_stamp) + { + return true; + } + return false; + } + break; + } + case E_SORT_TIME: + { + if(time_stamp > info->time_stamp) + { + return true; + } + if(time_stamp < info->time_stamp) + { + return false; + } + else if(time_stamp == info->time_stamp) + { + if(priorityOrder < info->priorityOrder) + { + return true; + } + return false; + } + break; + } + case E_SORT_LOCATION: + { + if(location_id > info->location_id) + { + return true; + } + else if(location_id < info->location_id) + { + return false; + } + else if(location_id == info->location_id) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_REGION: + { + if(region_id > info->region_id) + { + return true; + } + else if(region_id < info->region_id) + { + return false; + } + else if(region_id == info->region_id) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_TYPE: + { + if(alm_type > info->alm_type) + { + return true; + } + else if(alm_type < info->alm_type) + { + return false; + } + else if(alm_type == info->alm_type) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_STATUS: + { + if(alm_status > info->alm_status) + { + return true; + } + else if(alm_status < info->alm_status) + { + return false; + } + else if(alm_status == info->alm_status) + { + if(time_stamp <= info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_STYLE: + { + if(alm_style alm_style) + { + return false; + } + else if(alm_style >info->alm_style) + { + return true; + } + else + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + case E_SORT_CONTENT: + { + if(content.isEmpty() && info->content.isEmpty()) + { + return true; + } + else if(content.isEmpty() && (!info->content.isEmpty())) + { + return false; + } + else if((!content.isEmpty()) && info->content.isEmpty()) + { + return true; + } + else if(content > info->content) + { + return true; + } + else if(content < info->content) + { + return false; + } + else if(content == info->content) + { + if(time_stamp < info->time_stamp) + { + return false; + } + return true; + } + break; + } + default: + break; + } + return false; +} + +bool CEventMsgInfo::operator==(const EventMsgPtr &target) +{ + return uuid_base64 == target->uuid_base64; +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventMsgInfo.h b/product/src/gui/plugin/EventWidget_pad/CEventMsgInfo.h new file mode 100644 index 00000000..d8151b9b --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventMsgInfo.h @@ -0,0 +1,169 @@ +#ifndef ALARMMSGINFO_H +#define ALARMMSGINFO_H + +#include +#include +#include +#include "alarm_server_api/CAlmApiForEvtClt.h" +#include "common/DataType.h" +#include + +#define LIMIT_HIS_RECORD 10000 +#define REAL_BUTTON_COLUMN 7 //按钮所在列 +#define HIS_BUTTON_COLUMN 9 //按钮所在列 +//排序 +enum E_ALARM_VIEW +{ + E_ALARM_REAL_EVENT = 0, + E_ALARM_HIS_EVENT =1 +}; +enum E_ALARM_SORTKEY +{ + E_SORT_TIME = 0, //时间戳 + E_SORT_PRIORITY, //优先级 + E_SORT_LOCATION, //车站 + E_SORT_REGION, //责任区 + E_SORT_TYPE, //事件类型 + E_SORT_STATUS, //事件状态 + E_SORT_STYLE, //复归状态 + E_SORT_CONTENT //告警内容 +}; + +enum E_ALARM_STYLE +{ + AS_ALARM = 0, // 告警动作 + AS_ALARM_RTN = 1, // 告警恢复 + AS_EVENT_ONLY = 2, // 仅产生事件 + AS_DO_NOTHING = 3, // 无 +}; +// 报警状态 +enum E_ALARM_LOGICSTATE +{ + E_ALS_ALARM = 0, // 报警状态 + E_ALS_ALARM_CFM=1, // 报警确认状态 + E_ALS_RETURN=2, // 报警返回状态 + E_ALS_RETURN_CFM=3, // 报警返回确认状态 + ALS_EVT_ONLY = 4, // 仅事件 + + //在原始告警窗删除后,可能还需要在智能告警窗展示 + E_ALS_ALARM_DEL = 20, // 告警状态,且在原始告警窗已删除,可能是达到数量上限而删除 + E_ALS_ALARM_CFM_DEL =21, // 告警确认状态,且在原始告警窗已删除 + E_ALS_RETURN_DEL=22, // 告警返回状态,且在原始告警窗已删除,可能是达到数量上限而删除 + E_ALS_RETURN_CFM_DEL=23, // 告警返回确认状态,且在原始告警窗已删除 + E_ALS_BAD = 100 +}; + +enum E_LOCATION_TYPE +{ + E_LOCATION_NODE = 0, + E_LOCATION_AREA +}; + +struct STimeKeyIdTag +{ + quint64 time_stamp; + QString key_id_tag; +}; + +struct SAreaInfo +{ + int nId; + QString stTag; + QString stDes; + E_LOCATION_TYPE eType; + int nPareaId; + SAreaInfo() { + nId = -1; + stTag = QString(); + stDes = QString(); + eType = E_LOCATION_NODE; + nPareaId = -1; + } +}; +struct ST_FILTER +{ + + bool isLevelFilterEnable; + QList levelFilter; //报警级别过滤 + bool isLocationFilterEnable; //是否按车站过滤 + QList locationFilter; //车站过滤 + bool isRegionFilterEnable; //是否按责任区过滤 + QList regionFilter; //责任区过滤 + bool isStatusFilterEnable; //是否按报警类型过滤 + QList statusFilter; //事件状态过滤(所有的要过滤事件状态--如果其他状态没有被勾选,则与下面的内容相同) + QList statusFilter2; //事件状态过滤(显示在过滤窗中的事件状态) + bool isDeviceTypeFileter; //设备类型过滤 + QString subSystem; //子系统 + QString deviceType; //设备类型 + bool isKeywordEnable; //关键字过滤 + QString keyword; //关键字 + bool timeFilterEnable; //是否根据时间过滤 + QDateTime startTime; //起始时间 + QDateTime endTime; //终止时间 + + bool isReturnFilterEnable; //是否根据复归状态过滤 + bool isReturn; + ST_FILTER() { + isLevelFilterEnable = false; + isLocationFilterEnable = false; + isRegionFilterEnable = false; + + isStatusFilterEnable = false; + + isDeviceTypeFileter = false; + subSystem = QString(); + deviceType = QString(); + isKeywordEnable = false; + keyword = QString(); + timeFilterEnable = false; + QDateTime dataTime(QDateTime::currentDateTime()); + dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().second(),0,0)); + startTime = dataTime; + dataTime.setTime(QTime(dataTime.time().hour(),dataTime.time().second(),59,999)); + endTime = dataTime; + + isReturnFilterEnable =false; + isReturn = false; + } +}; +class CEventMsgInfo; +typedef QSharedPointer EventMsgPtr; + +class CEventMsgInfo +{ +public: + CEventMsgInfo(); + CEventMsgInfo(const CEventMsgInfo &other); + void initialize(const iot_idl::SEvtInfoToEvtClt &eventInfo); + bool lessThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool moreThan(EventMsgPtr info, E_ALARM_SORTKEY sortkey = E_SORT_PRIORITY); + bool operator==(const EventMsgPtr &target); + qint32 alm_type; //报警类型 + E_ALARM_STYLE alm_style; //< 告警类型 + quint64 time_stamp; //时标(RFC1305、POSIX时标标准) + qint32 domain_id; //域ID + qint32 location_id; //位置ID + qint32 app_id; //应用号 + QString content; //报警内容 + qint32 priority; //报警优先级id + qint32 dev_type; //设备类型ID + qint32 region_id; //责任区ID + bool deleted; //实时事件删除标志 + bool filterDelete; //过滤删除 + QString uuid_base64; //< uuid 主键 + QString key_id_tag; //< 测点ID + int32 alm_status; //事件状态 + uint cfm_user; //确认人 + uint64 cfm_time; //确认时间 + QString dev_group_tag; //< 设备组 +//Extend + qint32 priorityOrder; + + QString wave_file; +}; + + +Q_DECLARE_METATYPE(CEventMsgInfo) +Q_DECLARE_METATYPE(EventMsgPtr) + +#endif // ALARMMSGINFO_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventMsgManage.cpp b/product/src/gui/plugin/EventWidget_pad/CEventMsgManage.cpp new file mode 100644 index 00000000..a50b4314 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventMsgManage.cpp @@ -0,0 +1,155 @@ +#include "CEventMsgManage.h" +#include +#include +CEventMsgManage * CEventMsgManage::m_pInstance = Q_NULLPTR; + +CEventMsgManage *CEventMsgManage::instance() +{ + if(m_pInstance == Q_NULLPTR) + { + m_pInstance = new CEventMsgManage(); + } + return m_pInstance; +} + + +CEventMsgManage::CEventMsgManage() + : QObject() +{ + mutex = new QMutex(); +} + +CEventMsgManage::~CEventMsgManage() +{ + m_listEventInfo.clear(); + m_eventDeviceGroupStatistical.clear(); + delete mutex; + m_pInstance = Q_NULLPTR; +} + +QList CEventMsgManage::getListEventInfo() +{ + QMutexLocker locker(mutex); + return m_listEventInfo; +} + +int CEventMsgManage::getListEventCount() +{ + if(m_listEventInfo.isEmpty()) + { + return 0; + } + + return m_listEventInfo.count(); +} + +void CEventMsgManage::addEventMsg(const EventMsgPtr msg) +{ + QMutexLocker locker(mutex); + if(!m_listEventInfo.isEmpty()) + { + bool inserted = false; + QList::iterator iter = m_listEventInfo.begin(); + while (iter != m_listEventInfo.end()) + { + if(msg->time_stamp >= (*iter)->time_stamp) + { + m_listEventInfo.insert(iter, msg); + inserted = true; + break; + } + iter++; + } + if (!inserted) + { + m_listEventInfo.append(msg); + } + } + else + { + m_listEventInfo.append(msg); + } + if(m_listEventInfo.size() > 10000) + { + EventMsgPtr info = m_listEventInfo.takeLast(); + info->deleted = true; + } + else + { + devDevGTotEvtAddStats(msg); + } +} + +void CEventMsgManage::linkWave2EvtMsg(const QList &uuidList, const QString &waveFile) +{ + QMutexLocker locker(mutex); + for(int index(0);index::iterator it = m_listEventInfo.begin(); + while (it != m_listEventInfo.end()) { + if((*it)->uuid_base64 == uuidList.at(index)) + { + (*it)->wave_file = waveFile; + break; + } + it++; + } + } +} + +void CEventMsgManage::removeEventMsgByDomainID(const int domainId) +{ + QMutexLocker locker(mutex); + QList::iterator it = m_listEventInfo.begin(); + while (it != m_listEventInfo.end()) + { + if(domainId == (*it)->domain_id) + { + it = m_listEventInfo.erase(it); + continue; + } + it++; + } +} + +void CEventMsgManage::clearRTMsg() +{ + QMutexLocker locker(mutex); + m_listEventInfo.clear(); + m_eventDeviceGroupStatistical.clear(); +} + +QHash CEventMsgManage::getDevGStatisticalInfo() +{ + QMutexLocker locker(mutex); + + return m_eventDeviceGroupStatistical; +} + +int CEventMsgManage::deviceGroupAlarmStatistical(const QString &deviceGroup) +{ + QMutexLocker locker(mutex); + + if(deviceGroup.isEmpty()) + { + return 0; + } + + return m_eventDeviceGroupStatistical.value(deviceGroup, 0); +} + +void CEventMsgManage::devDevGTotEvtAddStats(const EventMsgPtr &msg) +{ + int dgCount = m_eventDeviceGroupStatistical.value(msg->dev_group_tag,0); + + ++dgCount; + + if(dgCount <= 0) + { + m_eventDeviceGroupStatistical.remove(msg->dev_group_tag); + } + else + { + m_eventDeviceGroupStatistical.insert(msg->dev_group_tag,dgCount); + } +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventMsgManage.h b/product/src/gui/plugin/EventWidget_pad/CEventMsgManage.h new file mode 100644 index 00000000..90219158 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventMsgManage.h @@ -0,0 +1,46 @@ +#ifndef CEventMsgManage_H +#define CEventMsgManage_H + +#include +#include "CEventMsgInfo.h" + +class QMutex; + +class CEventMsgManage : public QObject +{ + Q_OBJECT +public: + static CEventMsgManage * instance(); + + ~CEventMsgManage(); + + QList getListEventInfo(); + + int getListEventCount(); + + void addEventMsg(const EventMsgPtr msg); + + void linkWave2EvtMsg(const QList &uuidList,const QString &waveFile); + + void removeEventMsgByDomainID(const int domainId); + + void clearRTMsg(); + + QHash getDevGStatisticalInfo(); + + int deviceGroupAlarmStatistical(const QString &deviceGroup); + +private: + CEventMsgManage(); + + void devDevGTotEvtAddStats(const EventMsgPtr &msg); + +private: + QMutex * mutex; + QList m_listEventInfo; + QList m_historyEventInfo; + QHash m_eventDeviceGroupStatistical; //<设备组事件数量统计 + static CEventMsgManage * m_pInstance; +}; + +#endif // CEventMsgManage_H diff --git a/product/src/gui/plugin/EventWidget_pad/CEventPluginWidget.cpp b/product/src/gui/plugin/EventWidget_pad/CEventPluginWidget.cpp new file mode 100644 index 00000000..eae75162 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventPluginWidget.cpp @@ -0,0 +1,26 @@ +#include +#include "CEventPluginWidget.h" +#include "CEventForm.h" + +CEventPluginWidget::CEventPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CEventPluginWidget::~CEventPluginWidget() +{ + +} + +bool CEventPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **eventWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec); + CEventForm *pWidget = new CEventForm(parent, editMode); + *widget = (QWidget *)pWidget; + *eventWidget = (IPluginWidget *)pWidget; + return true; +} + +void CEventPluginWidget::release() +{ +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventPluginWidget.h b/product/src/gui/plugin/EventWidget_pad/CEventPluginWidget.h new file mode 100644 index 00000000..6ef08a0c --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventPluginWidget.h @@ -0,0 +1,22 @@ +#ifndef CEVENTPLUGINWIDGET_H +#define CEVENTPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CEventPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) + Q_INTERFACES(CPluginWidgetInterface) + +public: + CEventPluginWidget(QObject *parent = 0); + ~CEventPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **eventWidget, QVector ptrVec); + void release(); +}; + +#endif //CEVENTPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/EventWidget_pad/CEventView.cpp b/product/src/gui/plugin/EventWidget_pad/CEventView.cpp new file mode 100644 index 00000000..c500efcb --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventView.cpp @@ -0,0 +1,40 @@ +#include +#include "CEventView.h" +#include + +CEventView::CEventView(QWidget *parent) + :QTableView(parent) +{ + setSortingEnabled(true); + setAlternatingRowColors(true); + horizontalHeader()->setStretchLastSection(true); + //setSelectionBehavior(QAbstractItemView::SelectRows); + //setSelectionMode(QAbstractItemView::MultiSelection); + horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); +// horizontalScrollBar()->setDisabled(true); +// setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); +} + +QModelIndexList CEventView::selectedItems() const +{ + QModelIndexList indexList; + foreach(QModelIndex index, selectedIndexes()) + { + if(index.column() == 0) + { + indexList.append(index); + } + } + return indexList; +} + +void CEventView::setDefaultRowHeight(int height) +{ + verticalHeader()->setDefaultSectionSize(height); +} + +void CEventView::selectionChanged(const QItemSelection &selected, const QItemSelection &deSelected) +{ + QTableView::selectionChanged(selected, deSelected); + emit sig_selectionChanged(selectedIndexes()); +} diff --git a/product/src/gui/plugin/EventWidget_pad/CEventView.h b/product/src/gui/plugin/EventWidget_pad/CEventView.h new file mode 100644 index 00000000..24779826 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CEventView.h @@ -0,0 +1,22 @@ +#ifndef CEventView_H +#define CEventView_H + +#include + +class CEventView : public QTableView +{ + Q_OBJECT +public: + CEventView(QWidget *parent = Q_NULLPTR); + + QModelIndexList selectedItems() const; + + void setDefaultRowHeight(int height); +signals: + void sig_selectionChanged(const QModelIndexList &list); + +protected slots: + virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deSelected); +}; + +#endif // ALARMVIEW_H diff --git a/product/src/gui/plugin/EventWidget_pad/CExcelPrinter.cpp b/product/src/gui/plugin/EventWidget_pad/CExcelPrinter.cpp new file mode 100644 index 00000000..c0efd4fc --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CExcelPrinter.cpp @@ -0,0 +1,87 @@ +#include "CExcelPrinter.h" +#include "CEventView.h" +CExcelPrinter::CExcelPrinter(QObject *parent) : QObject(parent) +{ + +} + +void CExcelPrinter::initialize() +{ + +} + +void CExcelPrinter::printerByModel(CEventView* view,CEventItemModel *model, const QString fileName) +{ + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "实时事件" ); + int rowcount=model->rowCount(); + int colcount=model->columnCount(); + for(int i=0,excelCloumn = 0;iisColumnHidden(i)) + { + continue; + } + xlsx.write( 1, excelCloumn+1, model->headerData(i, Qt::Horizontal).toString().trimmed()); + excelCloumn++; + } + // 写内容 + for ( int i=0; iisColumnHidden(j)) + { + continue; + } + QString sText=model->data(model->index(i, j)).toString(); + xlsx.write( i+2, excelCloumn+1, sText ); + excelCloumn++; + } + + } + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + // 提示导出路径 + QString result = QString("导出完成\n文件为:%1").arg(sExcelFileName); + emit sigShowResult(result); +} + +void CExcelPrinter::printerHisByModel(CEventView* view,CEventHistoryModel *model, const QString fileName) +{ + QString sExcelFileName = fileName; + QXlsx::Document xlsx; + xlsx.addSheet( "历史事件" ); + // 写横向表头 + int rowcount=model->rowCount(); + int colcount=model->columnCount(); + for(int i=0,excelCloumn=0;iisColumnHidden(i)) + { + continue; + } + xlsx.write( 1, excelCloumn+1, model->headerData(i, Qt::Horizontal).toString().trimmed()); + excelCloumn++; + } + // 写内容 + for ( int i=0; iisColumnHidden(j)) + { + continue; + } + QString sText=model->data(model->index(i, j)).toString(); + xlsx.write( i+2, excelCloumn+1, sText ); + excelCloumn++; + } + } + // 保存到文件 + xlsx.saveAs( sExcelFileName ); + // 提示导出路径 + QString result = QString("导出完成\n文件为:%1").arg(sExcelFileName); + emit sigShowResult(result); +} diff --git a/product/src/gui/plugin/EventWidget_pad/CExcelPrinter.h b/product/src/gui/plugin/EventWidget_pad/CExcelPrinter.h new file mode 100644 index 00000000..970979b4 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CExcelPrinter.h @@ -0,0 +1,22 @@ +#ifndef CEXCELPRINTER_H +#define CEXCELPRINTER_H + +#include +#include +#include +#include "pub_excel/xlsx/xlsxdocument.h" +class CEventView; +class CExcelPrinter : public QObject +{ + Q_OBJECT +public: + explicit CExcelPrinter(QObject *parent = nullptr); + void initialize(); +signals: + void sigShowResult(QString result); +public slots: + void printerByModel(CEventView* view,CEventItemModel *model,const QString fileName); + void printerHisByModel(CEventView* view,CEventHistoryModel *model,const QString fileName); +}; + +#endif // CEXCELPRINTER_H diff --git a/product/src/gui/plugin/EventWidget_pad/CMyCalendar.cpp b/product/src/gui/plugin/EventWidget_pad/CMyCalendar.cpp new file mode 100644 index 00000000..94a15135 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CMyCalendar.cpp @@ -0,0 +1,93 @@ +#include "CMyCalendar.h" +#include "ui_CMyCalendar.h" +#include +#include +#include + +CMyCalendar::CMyCalendar(QWidget *parent) : + QWidget(parent), + ui(new Ui::CMyCalendar) +{ + ui->setupUi(this); + connect(ui->calendarWidget,SIGNAL(clicked(QDate)),this,SLOT(slot_startTime(QDate))); + connect(ui->calendarWidget_2,SIGNAL(clicked(QDate)),this,SLOT(slot_endTime(QDate))); + connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_cancle())); + m_startTime = QDate::currentDate(); + m_endTime = QDate::currentDate(); + ui->lineEdit->setText(m_startTime.toString("yyyy-MM-dd")); + ui->lineEdit_2->setText(m_endTime.toString("yyyy-MM-dd")); + ui->lineEdit->setReadOnly(true); + ui->lineEdit_2->setReadOnly(true); +} + +CMyCalendar::~CMyCalendar() +{ + delete ui; +} + +void CMyCalendar::setView(E_ALARM_VIEW view) +{ + m_view = view; + if(m_view == E_ALARM_HIS_EVENT) + { + ui->pushButton->setEnabled(false); + }else + { + ui->pushButton->setEnabled(true); + } +} + +void CMyCalendar::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) + { + return ; + } + QWidget::keyPressEvent(event); +} + +void CMyCalendar::slot_endTime(QDate date) +{ + ui->lineEdit_2->setText(date.toString("yyyy-MM-dd")); + m_endTime = date; + if(m_startTime.isNull() ) + { + return; + } + if(m_endTime < m_startTime) + { + return ; + } + if(m_view == E_ALARM_HIS_EVENT) + { + QTime time_1(0,0,0); + QTime time_2(23,59,59); + QDateTime startTime; + QDateTime endTime; + startTime.setDate(m_startTime); + startTime.setTime(time_1); + + endTime.setDate(m_endTime); + endTime.setTime(time_2); + if((endTime.toMSecsSinceEpoch()-startTime.toMSecsSinceEpoch())/1000/3600/24 >= 90 ) + { + return; + } + } + emit sig_endTimeClick(m_startTime,m_endTime); +} + +void CMyCalendar::slot_startTime(QDate date) +{ + m_startTime = date; + ui->lineEdit->setText(date.toString("yyyy-MM-dd")); +} + +void CMyCalendar::slot_cancle() +{ + if(m_view == E_ALARM_HIS_EVENT) + { + return; + } + emit sig_cancle(); +} diff --git a/product/src/gui/plugin/EventWidget_pad/CMyCalendar.h b/product/src/gui/plugin/EventWidget_pad/CMyCalendar.h new file mode 100644 index 00000000..44625bbf --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CMyCalendar.h @@ -0,0 +1,38 @@ +#ifndef CMYCALENDAR_H +#define CMYCALENDAR_H + +#include +#include +#include +#include "CEventMsgInfo.h" + +namespace Ui { +class CMyCalendar; +} + +class CMyCalendar : public QWidget +{ + Q_OBJECT +signals: + void sig_endTimeClick(QDate startDate,QDate endDate); + void sig_startTimeClick(QDate date); + void sig_cancle(); +public: + explicit CMyCalendar(QWidget *parent = 0); + ~CMyCalendar(); + void setView(E_ALARM_VIEW view); +protected: + void keyPressEvent(QKeyEvent *event); + +public slots: + void slot_endTime(QDate date); + void slot_startTime(QDate date); + void slot_cancle(); +private: + Ui::CMyCalendar *ui; + QDate m_startTime; + QDate m_endTime; + E_ALARM_VIEW m_view; +}; + +#endif // CMYCALENDAR_H diff --git a/product/src/gui/plugin/EventWidget_pad/CMyCalendar.ui b/product/src/gui/plugin/EventWidget_pad/CMyCalendar.ui new file mode 100644 index 00000000..98fb3b2c --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CMyCalendar.ui @@ -0,0 +1,119 @@ + + + CMyCalendar + + + + 0 + 0 + 538 + 264 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 20 + 0 + + + + + + + Qt::AlignCenter + + + + + + + + + + 取消 + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + diff --git a/product/src/gui/plugin/EventWidget_pad/CMyCheckBox.cpp b/product/src/gui/plugin/EventWidget_pad/CMyCheckBox.cpp new file mode 100644 index 00000000..09398cd4 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CMyCheckBox.cpp @@ -0,0 +1,22 @@ +#include "CMyCheckBox.h" +#include + +CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) + :QCheckBox(text,parent) +{ + +} + +CMyCheckBox::CMyCheckBox(QWidget *parent) + :QCheckBox(parent) +{ + +} + +void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) +{ + Q_UNUSED(e); + setChecked(!isChecked()); + emit clicked(isChecked()); + +} diff --git a/product/src/gui/plugin/EventWidget_pad/CMyCheckBox.h b/product/src/gui/plugin/EventWidget_pad/CMyCheckBox.h new file mode 100644 index 00000000..1dad82e3 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CMyCheckBox.h @@ -0,0 +1,16 @@ +#ifndef MYCHECKBOX_H +#define MYCHECKBOX_H + +#include + +class CMyCheckBox : public QCheckBox +{ +public: + CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); + CMyCheckBox(QWidget *parent = Q_NULLPTR); + +protected: + void mouseReleaseEvent(QMouseEvent *e); +}; + +#endif // MYCHECKBOX_H diff --git a/product/src/gui/plugin/EventWidget_pad/CMyListWidget.cpp b/product/src/gui/plugin/EventWidget_pad/CMyListWidget.cpp new file mode 100644 index 00000000..fa73a493 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CMyListWidget.cpp @@ -0,0 +1,12 @@ +#include "CMyListWidget.h" + +CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) +{ + +} + +void CMyListWidget::showEvent(QShowEvent *event) +{ + this->updateGeometries(); + QListWidget::showEvent(event); +} diff --git a/product/src/gui/plugin/EventWidget_pad/CMyListWidget.h b/product/src/gui/plugin/EventWidget_pad/CMyListWidget.h new file mode 100644 index 00000000..728f308d --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CMyListWidget.h @@ -0,0 +1,15 @@ +#ifndef CMYLISTWIDGET_H +#define CMYLISTWIDGET_H + +#include + +class CMyListWidget : public QListWidget +{ +public: + explicit CMyListWidget(QWidget *parent = 0); + +protected: + void showEvent(QShowEvent *event); +}; + +#endif // CMYLISTWIDGET_H diff --git a/product/src/gui/plugin/EventWidget_pad/CTableViewPrinter.cpp b/product/src/gui/plugin/EventWidget_pad/CTableViewPrinter.cpp new file mode 100644 index 00000000..c9a7e6e8 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CTableViewPrinter.cpp @@ -0,0 +1,122 @@ +#include "CTableViewPrinter.h" +#include +#include +#include +#include +#include + +CTableViewPrinter::CTableViewPrinter(QTableView *view) + : m_pView(view) +{ + m_pModel = view->model(); +} + +void CTableViewPrinter::print(QPrinter * printer) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + + qreal marginHorizontal = 20; + qreal marginVertical = 20; + + QRectF pageRect = printer->pageRect().adjusted(0, 0, -marginHorizontal * 2, -marginVertical * 2); + printer->setPageMargins(QMarginsF(marginHorizontal,marginVertical,marginHorizontal,marginVertical)); + + int length = 0; + horizontalHeader->resize(pageRect.width(), horizontalHeader->height()); + for(int nSection(0); nSection < horizontalHeader->count() - 1; nSection++) + { + length += horizontalHeader->sectionSize(nSection); + } + horizontalHeader->resizeSection(horizontalHeader->count() - 1, horizontalHeader->width() - length); + + QPainter painter(printer); + + renderHeader(painter); + + int offset = 0; + int currentPage = 0; + int horizontalHeaderHeight = horizontalHeader->height(); + for(int row(0); row < m_pModel->rowCount(); row++) + { + if(row > 0 && verticalHeader->sectionPosition(row - 1) + horizontalHeaderHeight < pageRect.height() && verticalHeader->sectionPosition(row) > pageRect.height()) + { + horizontalHeaderHeight = 0; + } + + + if((int)(((verticalHeader->sectionPosition(row) + horizontalHeaderHeight) / pageRect.height())) != currentPage) + { + printer->newPage(); + currentPage++; + offset = verticalHeader->sectionPosition(row) + horizontalHeaderHeight; + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + } + + for(int column(0); column < m_pModel->columnCount(); column++) + { + int rowPosition = (verticalHeader->sectionPosition(row) + horizontalHeaderHeight) - offset; + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + int rowHeight = m_pView->rowHeight(row); + int columnWidth = m_pView->columnWidth(column); + + //< draw item + QStyleOptionViewItem opt; + opt.rect = QRect(columnPosition, rowPosition, columnWidth, rowHeight); + painter.save(); + painter.drawText(opt.rect, Qt::AlignCenter, m_pModel->data(m_pModel->index(row, column)).toString()); + painter.restore(); + + //< Vertical Line + if(column == 0) + { + QPoint top(columnPosition, verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition, verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + QPoint top(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) - offset + horizontalHeaderHeight); + QPoint bottom(columnPosition + horizontalHeader->sectionSize(column), verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) - offset + horizontalHeaderHeight); + drawGridLine(&painter, top, bottom); + } + //< Horizontal Line + int rowPosition = verticalHeader->sectionPosition(row) + verticalHeader->sectionSize(row) + horizontalHeaderHeight - offset; + QPoint left(verticalHeader->width(), rowPosition); + QPoint right(verticalHeader->width() + horizontalHeader->sectionPosition(m_pModel->columnCount() - 1) + horizontalHeader->sectionSize(m_pModel->columnCount() - 1), rowPosition); + drawGridLine(&painter, left, right); + + } +} + +void CTableViewPrinter::renderHeader(QPainter &painter) +{ + QHeaderView * horizontalHeader = m_pView->horizontalHeader(); + QHeaderView * verticalHeader = m_pView->verticalHeader(); + for(int column(0); column < horizontalHeader->count(); column++) + { + painter.save(); + int columnPosition = horizontalHeader->sectionPosition(column) + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + QRect rect = QRect(columnPosition, 0, horizontalHeader->sectionSize(column) , horizontalHeader->height()); + painter.drawText(rect, m_pModel->headerData(column, Qt::Horizontal).toString(), QTextOption(Qt::AlignCenter)); + painter.restore(); + } + int columnPosition = horizontalHeader->width() + verticalHeader->width(); + QPoint top(columnPosition, 0); + QPoint bottom(columnPosition, horizontalHeader->height()); + drawGridLine(&painter, top, bottom); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5)); + drawGridLine(&painter, QPoint(verticalHeader->width(), 0.5 + horizontalHeader->height()), QPoint(horizontalHeader->width() + verticalHeader->width(), 0.5 + horizontalHeader->height())); +} + +void CTableViewPrinter::drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2) +{ + painter->save(); + QStyleOptionViewItem opt; + const int gridHint = m_pView->style()->styleHint(QStyle::SH_Table_GridLineColor, &opt, m_pView); + const QColor gridColor = static_cast(gridHint); + painter->setPen(gridColor); + painter->drawLine(p1, p2); + painter->restore(); +} diff --git a/product/src/gui/plugin/EventWidget_pad/CTableViewPrinter.h b/product/src/gui/plugin/EventWidget_pad/CTableViewPrinter.h new file mode 100644 index 00000000..cb595560 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/CTableViewPrinter.h @@ -0,0 +1,24 @@ +#ifndef CTABLEVIEWPRINTER_H +#define CTABLEVIEWPRINTER_H + +class QPointF; +class QPainter; +class QPrinter; +class QTableView; +class QAbstractItemModel; + +class CTableViewPrinter +{ +public: + explicit CTableViewPrinter(QTableView * view); + + void print(QPrinter *printer); + void renderHeader(QPainter &painter); + void drawGridLine(QPainter *painter, const QPointF &p1, const QPointF &p2); + +private: + QTableView * m_pView; + QAbstractItemModel * m_pModel; +}; + +#endif // CTABLEVIEWPRINTER_H diff --git a/product/src/gui/plugin/EventWidget_pad/EventWidget_pad.pro b/product/src/gui/plugin/EventWidget_pad/EventWidget_pad.pro new file mode 100644 index 00000000..d02db39b --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/EventWidget_pad.pro @@ -0,0 +1,71 @@ +QT += core sql xml printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = lib +TARGET = EventWidget_pad + +CONFIG += plugin + +HEADERS = \ + CEventMsgInfo.h \ + CEventDataCollect.h \ + CEventView.h \ + CEventMsgManage.h \ + CEventItemModel.h \ + CEventHistoryModel.h \ + CEventFilterDialog.h \ + CEventForm.h \ + CEventPluginWidget.h \ + CTableViewPrinter.h \ + CMyListWidget.h \ + CMyCalendar.h \ + CMyCheckBox.h \ + CExcelPrinter.h \ + CEventDelegate.h \ + CEventHisThread.h \ + CAccidentReviewDialog.h \ + CEventDeviceTreeItem.h \ + CEventDeviceTreeModel.h \ + CEventDeviceTreeView.h + +SOURCES = \ + CEventMsgInfo.cpp \ + CEventDataCollect.cpp \ + CEventView.cpp \ + CEventMsgManage.cpp \ + CEventItemModel.cpp \ + CEventHistoryModel.cpp \ + CEventFilterDialog.cpp \ + CEventForm.cpp \ + CEventPluginWidget.cpp \ + CTableViewPrinter.cpp \ + CMyListWidget.cpp \ + CMyCalendar.cpp \ + CMyCheckBox.cpp \ + CExcelPrinter.cpp \ + CEventDelegate.cpp \ + CEventHisThread.cpp \ + CAccidentReviewDialog.cpp \ + CEventDeviceTreeItem.cpp \ + CEventDeviceTreeModel.cpp \ + CEventDeviceTreeView.cpp + +FORMS += \ + CEventFilterDialog.ui \ + CEventForm.ui \ + CMyCalendar.ui + +LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -ldb_base_api -ldb_api_ex -lpub_utility_api -lrdb_api -lperm_mng_api +LIBS += -lpub_sysinfo_api -lnet_msg_bus_api -lalarm_server_api -lpub_excel + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + + diff --git a/product/src/gui/plugin/EventWidget_pad/main.cpp b/product/src/gui/plugin/EventWidget_pad/main.cpp new file mode 100644 index 00000000..52c03481 --- /dev/null +++ b/product/src/gui/plugin/EventWidget_pad/main.cpp @@ -0,0 +1,42 @@ +#include +//#include "CEventPlugin.h" +#include "CEventForm.h" +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "CEventDataCollect.h" +#include "perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + + + //<初始化消息总线 + //iot_public::StartLogSystem(NULL, "HMI", "Alarm_Client"); + iot_public::StartLogSystem(NULL, "HMI"); + iot_net::initMsgBus("Event_Client", "1", true); + + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + permMngPtr->PermDllInit(); + if(permMngPtr->SysLogin("admin", "admin", 1, 12*60*60, "hmi") != 0) + { + iot_net::releaseMsgBus(); + iot_public::StopLogSystem(); + return -1; + } + // CEventPlugin p; + { + QApplication app(argc, argv); + CEventForm n(NULL,false); + n.show(); + + app.exec(); + } + + + + //<释放消息总线 + iot_net::releaseMsgBus(); + iot_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordPluginWidget.h b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordPluginWidget.h index e5e5c81f..760ab2e4 100644 --- a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordPluginWidget.h +++ b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordPluginWidget.h @@ -7,7 +7,7 @@ class CFaultRecallRecordPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: CFaultRecallRecordPluginWidget(QObject *parent = 0); diff --git a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.cpp b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.cpp index 27800ac0..a4fa9c16 100644 --- a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.cpp +++ b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.cpp @@ -469,6 +469,9 @@ void CFaultRecallRecordWidget::setRecordStatus(int status) void CFaultRecallRecordWidget::slotItemDoubleClicked(QTreeWidgetItem *item, int cl) { + Q_UNUSED(item); + Q_UNUSED(cl); + slotPlayBtn(); } diff --git a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.h b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.h index b8bc4908..dc675d25 100644 --- a/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.h +++ b/product/src/gui/plugin/FaultRecallRecordWidget/CFaultRecallRecordWidget.h @@ -65,7 +65,7 @@ public slots: void setColumnHidden(int column,bool hide); void setColumnWidth(int column,int width); -signals: +Q_SIGNALS: void sigPlay(const QString& file,qint64 startTime, qint64 endTime); private: diff --git a/product/src/gui/plugin/FaultRecallRecordWidget/main.cpp b/product/src/gui/plugin/FaultRecallRecordWidget/main.cpp index 482b78d5..5cd2676f 100644 --- a/product/src/gui/plugin/FaultRecallRecordWidget/main.cpp +++ b/product/src/gui/plugin/FaultRecallRecordWidget/main.cpp @@ -19,7 +19,7 @@ int main(int argc, char *argv[]) return -1; } - if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) + if(perm->SysLogin("admin", "admin", 1, 12*60*60, "hmi") != 0) { return -1; } diff --git a/product/src/gui/plugin/FaultRecordWidget/FaultRecordPluginWidget.h b/product/src/gui/plugin/FaultRecordWidget/FaultRecordPluginWidget.h index aac23c53..fa977f75 100644 --- a/product/src/gui/plugin/FaultRecordWidget/FaultRecordPluginWidget.h +++ b/product/src/gui/plugin/FaultRecordWidget/FaultRecordPluginWidget.h @@ -7,7 +7,7 @@ class FaultRecordPluginWidget : public QObject , public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: FaultRecordPluginWidget(QObject *parent = nullptr); diff --git a/product/src/gui/plugin/FbdEditorWidget/FbdEditorPluginWidget.h b/product/src/gui/plugin/FbdEditorWidget/FbdEditorPluginWidget.h index b4baf16c..c8242254 100644 --- a/product/src/gui/plugin/FbdEditorWidget/FbdEditorPluginWidget.h +++ b/product/src/gui/plugin/FbdEditorWidget/FbdEditorPluginWidget.h @@ -7,7 +7,7 @@ class CFbdEditorPluginWidget: public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.cpp b/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.cpp index af028ed5..194d21b4 100644 --- a/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.cpp +++ b/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.cpp @@ -1,6 +1,8 @@ #include "FbdEditorWidget.h" #include "fbd_designer/fbd_editor/CFBDMainWindow.h" #include "fbd_designer/fbd_editor/CFBDMainWindow_global.h" +#include "public/pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" #include FbdEditorWidget::FbdEditorWidget(bool editMode, QWidget *parent) : @@ -20,10 +22,14 @@ FbdEditorWidget::FbdEditorWidget(bool editMode, QWidget *parent) : else { m_ptrWindow = new CFBDMainWindow(parent); + m_ptrWindow->setObjectName("fbdEditorWindow"); + m_ptrWindow->slotInit(); QGridLayout *layout = new QGridLayout(this); layout->addWidget(m_ptrWindow); layout->setMargin(0); setLayout(layout); + + initStyle(); } } @@ -36,6 +42,34 @@ FbdEditorWidget::~FbdEditorWidget() m_ptrWindow = NULL; } +void FbdEditorWidget::initStyle() +{ + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("fbd_designer.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + void FbdEditorWidget::slotHideMenu(bool bHide) { if(m_ptrWindow) diff --git a/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.h b/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.h index 429c26a3..7c80338d 100644 --- a/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.h +++ b/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.h @@ -11,6 +11,8 @@ class FbdEditorWidget : public QWidget public: explicit FbdEditorWidget(bool editMode, QWidget *parent = 0); ~FbdEditorWidget(); +private: + void initStyle(); public slots: void slotHideMenu(bool bHide); diff --git a/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.pro b/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.pro index 44dbb0bd..19e53956 100644 --- a/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.pro +++ b/product/src/gui/plugin/FbdEditorWidget/FbdEditorWidget.pro @@ -33,7 +33,9 @@ HEADERS += \ FbdEditorPluginWidget.h \ FbdEditorWidget.h -LIBS += -lfbd_editor +LIBS += -lfbd_editor -lpub_widget +LIBS += -lpub_utility_api + exists($$PWD/../../../common.pri) { include($$PWD/../../../common.pri) diff --git a/product/src/gui/plugin/HangPanelWidget/CHangPanelPluginWidget.h b/product/src/gui/plugin/HangPanelWidget/CHangPanelPluginWidget.h index 3889afcd..96b75ad4 100644 --- a/product/src/gui/plugin/HangPanelWidget/CHangPanelPluginWidget.h +++ b/product/src/gui/plugin/HangPanelWidget/CHangPanelPluginWidget.h @@ -7,7 +7,7 @@ class CHangPanelPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: CHangPanelPluginWidget(QObject *parent = 0); diff --git a/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.cpp b/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.cpp index 10fc90a9..72efb030 100644 --- a/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.cpp +++ b/product/src/gui/plugin/HangPanelWidget/CHangPanelWidget.cpp @@ -272,7 +272,7 @@ void CHangPanelWidget::loadHangType() { int nTokenId = query.value(0).toInt(); QString sDesc = query.value(1).toString(); - int nTokenProp = query.value(2).toInt(); + //int nTokenProp = query.value(2).toInt(); m_typeMap.insert(nTokenId, sDesc); } return; @@ -481,6 +481,8 @@ int CHangPanelWidget::createReqHead(SOptReqHead &head) void CHangPanelWidget::filter(const QString &content) { Q_UNUSED(content); + + /* 没看出实际作用,注释掉 int locId = ui->cLocation->currentData().toInt(); int row = ui->tableWidget->rowCount(); for(int index(0);indextableWidget->item(index,0)->data(Qt::UserRole).toInt(); int type = ui->tableWidget->item(index,4)->data(Qt::UserRole).toInt(); } + */ } void CHangPanelWidget::slotShowMess(const QString &mess) @@ -540,10 +543,10 @@ void CHangPanelWidget::cancelHangePanel() slotShowMess(mess); return; } - int row = ui->tableWidget->currentRow(); - QString tagName= ui->tableWidget->item(row,10)->data(Qt::UserRole).toString(); //标签 - QString descName= ui->tableWidget->item(row,10)->text(); //标签 - int tagType = ui->tableWidget->item(row,3)->data(Qt::UserRole).toInt(); //挂牌类型 + //int row = ui->tableWidget->currentRow(); + //QString tagName= ui->tableWidget->item(row,10)->data(Qt::UserRole).toString(); //标签 + //QString descName= ui->tableWidget->item(row,10)->text(); //标签 + //int tagType = ui->tableWidget->item(row,3)->data(Qt::UserRole).toInt(); //挂牌类型 struct itemData { @@ -607,7 +610,6 @@ void CHangPanelWidget::removeHangInfo(const SHangPanelInfo &info) msg.setSubject(info.subSystem, CH_HMI_TO_OPT_OPTCMD_DOWN); STokenSet sOptHangSet; STokenQueue optHangQueue; - CTokenSet cTokenSet; if(createReqHead(sOptHangSet.stHead)!= iotSuccess){ return ; } @@ -617,7 +619,7 @@ void CHangPanelWidget::removeHangInfo(const SHangPanelInfo &info) optHangQueue.nSubSystem = info.subSystem; sOptHangSet.vecTokenQueue.push_back(optHangQueue); - std::string content = cTokenSet.generate(sOptHangSet); + std::string content = CTokenSet::generate(sOptHangSet); msg.setMsgType(MT_OPT_TOKEN_DELETE); msg.setData(content); diff --git a/product/src/gui/plugin/HangPanelWidget/main.cpp b/product/src/gui/plugin/HangPanelWidget/main.cpp index 08a7e14e..032ab4c3 100644 --- a/product/src/gui/plugin/HangPanelWidget/main.cpp +++ b/product/src/gui/plugin/HangPanelWidget/main.cpp @@ -19,7 +19,7 @@ int main(int argc, char *argv[]) return -1; } - if(perm->SysLogin("Test", "kbdct", 1, 12*60*60, "hmi") != 0) + if(perm->SysLogin("Test", "admin", 1, 12*60*60, "hmi") != 0) { //return -1; } diff --git a/product/src/gui/plugin/HmiRollWidget/CHmiRollPlugin.h b/product/src/gui/plugin/HmiRollWidget/CHmiRollPlugin.h index 715acdea..e2fffbf0 100644 --- a/product/src/gui/plugin/HmiRollWidget/CHmiRollPlugin.h +++ b/product/src/gui/plugin/HmiRollWidget/CHmiRollPlugin.h @@ -7,7 +7,7 @@ class CHmiRollPlugin : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/HmiRollWidget/CRollSwitchWidget.cpp b/product/src/gui/plugin/HmiRollWidget/CRollSwitchWidget.cpp index 054f7f99..17b14d82 100644 --- a/product/src/gui/plugin/HmiRollWidget/CRollSwitchWidget.cpp +++ b/product/src/gui/plugin/HmiRollWidget/CRollSwitchWidget.cpp @@ -95,7 +95,7 @@ void CRollSwitchWidget::initWidget() cLayout->addWidget(m_timeSpin); QGridLayout *gLayout = new QGridLayout(this); - gLayout->addLayout(hLayout, 0, 0, 1, 1); + gLayout->addLayout(hLayout, 0, 0, 1,3); gLayout->addWidget(m_TableWidget, 1, 0, 1, 3); gLayout->addLayout(cLayout, 2, 0, 1, 3); diff --git a/product/src/gui/plugin/HmiRollWidget/ConfigWidget.cpp b/product/src/gui/plugin/HmiRollWidget/ConfigWidget.cpp index 942bf1e2..65b8911b 100644 --- a/product/src/gui/plugin/HmiRollWidget/ConfigWidget.cpp +++ b/product/src/gui/plugin/HmiRollWidget/ConfigWidget.cpp @@ -8,6 +8,7 @@ #include #include #include +#include "pub_widget/MessageBox.h" ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) @@ -233,6 +234,16 @@ void ConfigWidget::slotDelClick() if(m_GroupComb->currentText().isEmpty()) return; QList selectList = m_TableWidget->selectedRanges(); + + if( selectList.isEmpty() ) + { + N_MessageBox::warning(this, tr("警告"), tr("请选择任意一条记录")); + return; + } + int button = N_MessageBox::information( this, tr("提示"), tr("确认删除?"), N_MessageBox::Yes, N_MessageBox::No ); + if ( button != N_MessageBox::Yes ) + return; + for(int nIndex=selectList.count()-1; nIndex>=0; nIndex--) { int bottomRow = selectList.at(nIndex).bottomRow(); @@ -251,7 +262,8 @@ void ConfigWidget::slotMoveUpClick() QList selectList = m_TableWidget->selectedRanges(); if(selectList.isEmpty() || selectList.first().topRow() == 0) { - return; + N_MessageBox::warning(this, tr("警告"), tr("请选择任意一条记录")); + return; } int insertRow = selectList.first().topRow() - 1; @@ -271,7 +283,8 @@ void ConfigWidget::slotMoveDownClick() QList selectList = m_TableWidget->selectedRanges(); if(selectList.isEmpty() || selectList.last().bottomRow() == m_TableWidget->rowCount()-1) { - return; + N_MessageBox::warning(this, tr("警告"), tr("请选择任意一条记录")); + return; } int insertRow = selectList.last().bottomRow() + 2; diff --git a/product/src/gui/plugin/HmiRollWidget/HmiRollWidget.pro b/product/src/gui/plugin/HmiRollWidget/HmiRollWidget.pro index 4686237b..3dac311c 100644 --- a/product/src/gui/plugin/HmiRollWidget/HmiRollWidget.pro +++ b/product/src/gui/plugin/HmiRollWidget/HmiRollWidget.pro @@ -46,7 +46,8 @@ HEADERS += \ CHmiRollPlugin.h LIBS += \ - -lpub_utility_api + -lpub_utility_api\ + -lpub_widget COMMON_PRI=$$PWD/../../../common.pri diff --git a/product/src/gui/plugin/HtmlBrowserWidget/CBrowserPluginWidget.h b/product/src/gui/plugin/HtmlBrowserWidget/CBrowserPluginWidget.h index 1d519d88..a1485778 100644 --- a/product/src/gui/plugin/HtmlBrowserWidget/CBrowserPluginWidget.h +++ b/product/src/gui/plugin/HtmlBrowserWidget/CBrowserPluginWidget.h @@ -7,7 +7,7 @@ class CBrowserPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.cpp index 18bc4fed..a5f2b0a9 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmForm.cpp @@ -159,7 +159,7 @@ void CAlarmForm::initialize() //< lingdaoyaoqiu { - QSettings columFlags("KBD_HMI", "alarm config"); + QSettings columFlags("IOT_HMI", "alarm config"); if(!columFlags.contains(QString("alarm/colum_0"))) { columFlags.setValue(QString("alarm/colum_0"), false); //< 时间 @@ -505,7 +505,7 @@ void CAlarmForm::setAlarmModel(CAlarmItemModel *model) ui->alarmView->setColumnWidth(6, 120); ui->alarmView->horizontalHeader()->setSortIndicator(1, Qt::AscendingOrder); - QSettings columFlags("KBD_HMI", "alarm config"); + QSettings columFlags("IOT_HMI", "alarm config"); for(int nColumnIndex(0); nColumnIndex < m_pModel->columnCount(); nColumnIndex++) { bool visible = columFlags.value(QString("alarm/colum_%1").arg(nColumnIndex)).toBool(); @@ -1029,7 +1029,7 @@ void CAlarmForm::contextMenuStack0Event(QContextMenuEvent *event) connect(action, &QAction::triggered, [=](){ ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags("KBD_HMI", "alarm config"); + QSettings columFlags("IOT_HMI", "alarm config"); columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); }); } @@ -1099,7 +1099,7 @@ void CAlarmForm::contextMenuStack1Event(QContextMenuEvent *event) connect(action, &QAction::triggered, [=](){ ui->alarmView->setColumnHidden(nColumnIndex, !action->isChecked()); ui->aiAlarmTreeView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags("KBD_HMI", "alarm config"); + QSettings columFlags("IOT_HMI", "alarm config"); columFlags.setValue(QString("alarm/colum_%1").arg(nColumnIndex), !action->isChecked()); }); } @@ -1372,7 +1372,7 @@ void CAlarmForm::loadDeviceGroupFilterWidget() QString sqlSequenceQuery = QString("select tag_name, description from dev_group where location_id = %1;").arg(iter.key()); if(false == m_pReadDb->execute(sqlSequenceQuery, query)) { - LOGINFO("load device info error, dbInterface execute failed!") + LOGINFO("load device info error, dbInterface execute failed!"); } while(query.next()) @@ -1385,7 +1385,7 @@ void CAlarmForm::loadDeviceGroupFilterWidget() } else { - LOGINFO("load deviceGroup info error, database open failed!") + LOGINFO("load deviceGroup info error, database open failed!"); } m_pReadDb->close(); delete m_pReadDb; diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPlugin.cpp b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPlugin.cpp index 7e97aa36..b42f9420 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPlugin.cpp +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPlugin.cpp @@ -885,7 +885,7 @@ void CAlarmPlugin::updateAlarmOperatePerm() iot_public::CSysInfoInterfacePtr spSysInfo; if (!iot_public::createSysInfoInstance(spSysInfo)) { - LOGERROR("创建系统信息访问库实例失败!") + LOGERROR("创建系统信息访问库实例失败!"); return; } spSysInfo->getLocalNodeInfo(stNodeInfo); @@ -901,12 +901,12 @@ void CAlarmPlugin::updateAlarmOperatePerm() std::string strInstanceName; if(0 != permMngPtr->CurUser(m_currentUsrId, nUserGrpId, nLevel, nLoginSec, strInstanceName)) { - LOGERROR("用户ID获取失败!") + LOGERROR("用户ID获取失败!"); return; } if(PERM_NORMAL != permMngPtr->GetSpeFunc(FUNC_SPE_ALARM_OPERATE, m_vecRegionId, m_vecLocationId)) { - LOGERROR("用户不具备告警操作权限!") + LOGERROR("用户不具备告警操作权限!"); return; } } diff --git a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPluginWidget.h b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPluginWidget.h index d5c028c8..95196608 100644 --- a/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPluginWidget.h +++ b/product/src/gui/plugin/ISCSAlarmWidget/CAlarmPluginWidget.h @@ -7,7 +7,7 @@ class CAlarmPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventForm.cpp b/product/src/gui/plugin/ISCSEventWidget/CEventForm.cpp index 88d5f5a0..94d7ea17 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventForm.cpp +++ b/product/src/gui/plugin/ISCSEventWidget/CEventForm.cpp @@ -140,7 +140,7 @@ void CEventForm::initilize() { //< lingdaoyaoqiu { - QSettings columFlags1("KBD_HMI", "eventReal config"); + QSettings columFlags1("IOT_HMI", "eventReal config"); if(!columFlags1.contains(QString("eventReal/colum_0"))) { columFlags1.setValue(QString("eventReal/colum_0"), false); //< 时间 @@ -153,7 +153,7 @@ void CEventForm::initilize() } } { - QSettings columFlags2("KBD_HMI", "eventHis config"); + QSettings columFlags2("IOT_HMI", "eventHis config"); if(!columFlags2.contains(QString("eventHis/colum_0"))) { columFlags2.setValue(QString("eventHis/colum_0"), false); //< 时间 @@ -487,7 +487,7 @@ void CEventForm::slotUpdateModel() connect(m_pHistoryModel, &CEventHistoryModel::sigHISRecordOutOfRangeTips, this, &CEventForm::slotHISRecordOutOfRangeTips); } ui->eventView->setModel(m_pHistoryModel); - QSettings columFlags2("KBD_HMI", "eventHis config"); + QSettings columFlags2("IOT_HMI", "eventHis config"); for(int nColumnIndex(0); nColumnIndex < m_pHistoryModel->columnCount(); nColumnIndex++) { bool visible = columFlags2.value(QString("eventHis/colum_%1").arg(nColumnIndex)).toBool(); @@ -512,7 +512,7 @@ void CEventForm::slotUpdateModel() ui->eventView->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder); } ui->eventView->setModel(m_pRealTimeModel); - QSettings columFlags1("KBD_HMI", "eventReal config"); + QSettings columFlags1("IOT_HMI", "eventReal config"); for(int nColumnIndex(0); nColumnIndex < m_pRealTimeModel->columnCount(); nColumnIndex++) { bool visible = columFlags1.value(QString("eventReal/colum_%1").arg(nColumnIndex)).toBool(); @@ -935,13 +935,13 @@ void CEventForm::contextMenuEvent(QContextMenuEvent *event) { QAction * action = columnMenu.addAction(m_pRealTimeModel->headerData(nColumnIndex, Qt::Horizontal, Qt::DisplayRole).toString()); action->setCheckable(true); - QSettings columFlags1_1("KBD_HMI", "eventReal config"); + QSettings columFlags1_1("IOT_HMI", "eventReal config"); action->setChecked(!columFlags1_1.value(QString("eventReal/colum_%1").arg(nColumnIndex)).toBool()); connect(action, &QAction::triggered, [=](){ ui->eventView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags1("KBD_HMI", "eventReal config"); + QSettings columFlags1("IOT_HMI", "eventReal config"); columFlags1.setValue(QString("eventReal/colum_%1").arg(nColumnIndex), !action->isChecked()); }); } @@ -954,7 +954,7 @@ void CEventForm::contextMenuEvent(QContextMenuEvent *event) action->setChecked(!ui->eventView->isColumnHidden(nColumnIndex)); connect(action, &QAction::triggered, [=](){ ui->eventView->setColumnHidden(nColumnIndex, !action->isChecked()); - QSettings columFlags2("KBD_HMI", "eventHis config"); + QSettings columFlags2("IOT_HMI", "eventHis config"); columFlags2.setValue(QString("eventHis/colum_%1").arg(nColumnIndex), !action->isChecked()); }); } diff --git a/product/src/gui/plugin/ISCSEventWidget/CEventPluginWidget.h b/product/src/gui/plugin/ISCSEventWidget/CEventPluginWidget.h index f2542479..6ef08a0c 100644 --- a/product/src/gui/plugin/ISCSEventWidget/CEventPluginWidget.h +++ b/product/src/gui/plugin/ISCSEventWidget/CEventPluginWidget.h @@ -7,7 +7,7 @@ class CEventPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/ISCSTrendCurves/CTrendPluginWidget.h b/product/src/gui/plugin/ISCSTrendCurves/CTrendPluginWidget.h index 55a26a86..06c92ce7 100644 --- a/product/src/gui/plugin/ISCSTrendCurves/CTrendPluginWidget.h +++ b/product/src/gui/plugin/ISCSTrendCurves/CTrendPluginWidget.h @@ -7,7 +7,7 @@ class CTrendPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/InverseTimeLimit/CInversetimelimitPluginWidget.h b/product/src/gui/plugin/InverseTimeLimit/CInversetimelimitPluginWidget.h index 7e4dbd13..e3b4f482 100644 --- a/product/src/gui/plugin/InverseTimeLimit/CInversetimelimitPluginWidget.h +++ b/product/src/gui/plugin/InverseTimeLimit/CInversetimelimitPluginWidget.h @@ -8,7 +8,7 @@ class CInversetimelimitPluginWidge : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: CInversetimelimitPluginWidge(QObject *parent = 0); diff --git a/product/src/gui/plugin/IpcPlusWidget/IpcPlusPluginWidget.h b/product/src/gui/plugin/IpcPlusWidget/IpcPlusPluginWidget.h index 80f36680..c15eb6d4 100644 --- a/product/src/gui/plugin/IpcPlusWidget/IpcPlusPluginWidget.h +++ b/product/src/gui/plugin/IpcPlusWidget/IpcPlusPluginWidget.h @@ -7,7 +7,7 @@ class IpcPlusPluginWidget : public QObject,public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: IpcPlusPluginWidget(QObject *parent=0); diff --git a/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.cpp b/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.cpp index bccf148b..7af5e48a 100644 --- a/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.cpp +++ b/product/src/gui/plugin/IpcPlusWidget/IpcPlusWidget.cpp @@ -507,8 +507,7 @@ bool IpcPlusWidget::sendOptContinuousMove(int cmd, double cmd_speed) stOptKeyValue.strKeyValue = QString::number(cmd_speed).toStdString() ; stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); + std::string strMsg = COptCustCtrlRequest::generate(stCustomCmd); if (strMsg.empty()) { LOGERROR("生成控制命令失败"); @@ -556,8 +555,7 @@ bool IpcPlusWidget::sendOptStopMove() stOptKeyValue.strKeyValue = m_caminfo.camTag() ; stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); + std::string strMsg = COptCustCtrlRequest::generate(stCustomCmd); if (strMsg.empty()) { LOGERROR("生成控制命令失败"); @@ -610,8 +608,7 @@ bool IpcPlusWidget::sendOptGotopreset(const std::string &preset_tag) stOptKeyValue.strKeyValue = preset_tag; stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); + std::string strMsg = COptCustCtrlRequest::generate(stCustomCmd); if (strMsg.empty()) { LOGERROR("生成控制命令失败"); diff --git a/product/src/gui/plugin/IpcPlusWidget/main.cpp b/product/src/gui/plugin/IpcPlusWidget/main.cpp index 2482f1f1..fff3ee84 100644 --- a/product/src/gui/plugin/IpcPlusWidget/main.cpp +++ b/product/src/gui/plugin/IpcPlusWidget/main.cpp @@ -13,7 +13,7 @@ int main(int argc, char *argv[]) { IpcPlusWidget w(false,NULL); w.setNodeInfo(1,4); - w.setNodeName("kbdctrd-jxd"); + w.setNodeName("node_test"); w.setAppName("hmi"); w.setStreamInfo("analog.syx.ZLQR2_jgxh.WD"); w.show(); diff --git a/product/src/gui/plugin/IpcViewerWidget/en.ts b/product/src/gui/plugin/IpcViewerWidget/en.ts index 5a48b95b..f4e5d374 100644 --- a/product/src/gui/plugin/IpcViewerWidget/en.ts +++ b/product/src/gui/plugin/IpcViewerWidget/en.ts @@ -2,16 +2,137 @@ - IpcViwerWidget + IpcViewerWidget - - IpcViwerWidget - + + Form + - + + + 实时视频 - Streaming + Streaming + + + + ptz + + + + + 移动速度 + + + + + + + - + + + + + 调焦 + + + + + + + + + + + + + 聚焦 + + + + + 光圈 + + + + + 预置位: + + + + + 调用 + + + + + + 录像回放 + + + + + 选择日期 + + + + + 开始时间 + + + + + + H:mm:ss + + + + + 结束时间 + + + + + 查询 + + + + + 播放器配置错误 + + + + + + QtAV error:Can not create video renderer + + + + + 请检查摄像头设备建模是否正确 + + + + + 无法查询到该段时间录像或者请关闭其他回放窗口 + + + + + 请开始时间小于结束时间 + + + + + 间隔时间请大于等于20s + + + + + IpcViwerWidget + + 实时视频 + Streaming diff --git a/product/src/gui/plugin/IpcViewerWidget/ipcviewerpluginwidget.h b/product/src/gui/plugin/IpcViewerWidget/ipcviewerpluginwidget.h index 3b783a45..f08e03bd 100644 --- a/product/src/gui/plugin/IpcViewerWidget/ipcviewerpluginwidget.h +++ b/product/src/gui/plugin/IpcViewerWidget/ipcviewerpluginwidget.h @@ -8,7 +8,7 @@ class IpcViewerPluginWidget: public QObject,public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: IpcViewerPluginWidget(QObject *parent=0); diff --git a/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.cpp b/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.cpp index e9779bf6..473b1387 100644 --- a/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.cpp +++ b/product/src/gui/plugin/IpcViewerWidget/ipcviewerwidget.cpp @@ -731,8 +731,7 @@ bool IpcViewerWidget::sendOptContinuousMove(int cmd, double cmd_speed) stOptKeyValue.strKeyValue = QString::number(cmd_speed).toStdString() ; stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); + std::string strMsg = COptCustCtrlRequest::generate(stCustomCmd); if (strMsg.empty()) { LOGERROR("生成控制命令失败"); @@ -773,8 +772,7 @@ bool IpcViewerWidget::sendOptStopMove() stOptKeyValue.strKeyValue = m_caminfo->camTag() ; stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); + std::string strMsg = COptCustCtrlRequest::generate(stCustomCmd); if (strMsg.empty()) { LOGERROR("生成控制命令失败"); @@ -820,8 +818,7 @@ bool IpcViewerWidget::sendOptGotopreset(const std::string &preset_tag) stOptKeyValue.strKeyValue = preset_tag; stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); + std::string strMsg = COptCustCtrlRequest::generate(stCustomCmd); if (strMsg.empty()) { LOGERROR("生成控制命令失败"); diff --git a/product/src/gui/plugin/IpcWallWidget/VideoWall.cpp b/product/src/gui/plugin/IpcWallWidget/VideoWall.cpp index 15237e91..16a3db0b 100644 --- a/product/src/gui/plugin/IpcWallWidget/VideoWall.cpp +++ b/product/src/gui/plugin/IpcWallWidget/VideoWall.cpp @@ -926,8 +926,7 @@ bool VideoWall::sendOptContinuousMove(int cmd, double cmd_speed) stOptKeyValue.strKeyValue = QString::number(cmd_speed).toStdString() ; stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); + std::string strMsg = COptCustCtrlRequest::generate(stCustomCmd); if (strMsg.empty()) { LOGERROR("生成控制命令失败"); @@ -975,8 +974,7 @@ bool VideoWall::sendOptStopMove() stOptKeyValue.strKeyValue = m_camInfoVec[curNo].camTag() ; stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); + std::string strMsg = COptCustCtrlRequest::generate(stCustomCmd); if (strMsg.empty()) { LOGERROR("生成控制命令失败"); @@ -1029,8 +1027,7 @@ bool VideoWall::sendOptGotopreset(const std::string &preset_tag) stOptKeyValue.strKeyValue = preset_tag; stCustomCmd.vecOptCustCtrlQueue.push_back(stOptKeyValue); - COptCustCtrlRequest objReq; - std::string strMsg = objReq.generate(stCustomCmd); + std::string strMsg = COptCustCtrlRequest::generate(stCustomCmd); if (strMsg.empty()) { LOGERROR("生成控制命令失败"); diff --git a/product/src/gui/plugin/IpcWallWidget/en.ts b/product/src/gui/plugin/IpcWallWidget/en.ts new file mode 100644 index 00000000..8a250e13 --- /dev/null +++ b/product/src/gui/plugin/IpcWallWidget/en.ts @@ -0,0 +1,90 @@ + + + + + VideoWall + + + ptz + + + + + 调焦 + + + + + 聚焦 + + + + + 光圈 + + + + + 缩 + + + + + 伸 + + + + + 近 + + + + + 远 + + + + + 大 + + + + + 小 + + + + + 预置点 + + + + + 调用 + + + + + 请检查计算机内存资源是否足够,无法开辟足够的线程 + + + + + 错误提醒 + + + + + VoiceSlider + + + Form + + + + + 0 + + + + diff --git a/product/src/gui/plugin/IpcWallWidget/ipcWallPluginWidge.h b/product/src/gui/plugin/IpcWallWidget/ipcWallPluginWidge.h index 3b783a45..f08e03bd 100644 --- a/product/src/gui/plugin/IpcWallWidget/ipcWallPluginWidge.h +++ b/product/src/gui/plugin/IpcWallWidget/ipcWallPluginWidge.h @@ -8,7 +8,7 @@ class IpcViewerPluginWidget: public QObject,public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: IpcViewerPluginWidget(QObject *parent=0); diff --git a/product/src/gui/plugin/IpcWallWidget/main.cpp b/product/src/gui/plugin/IpcWallWidget/main.cpp index 3eb3ac30..9baf2ea2 100644 --- a/product/src/gui/plugin/IpcWallWidget/main.cpp +++ b/product/src/gui/plugin/IpcWallWidget/main.cpp @@ -74,7 +74,7 @@ int main(int argc, char *argv[]) wall.showUi(); wall.loadCamInfo(); wall.showErrMsg(); - // QString file = "rtsp://admin:kbdct123@192.168.79.231:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1"; + // QString file = "rtsp://admin:admin123@192.168.79.231:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1"; // wall.play(file); int result ; diff --git a/product/src/gui/plugin/LimitOptWidget/CLimitOptWork.cpp b/product/src/gui/plugin/LimitOptWidget/CLimitOptWork.cpp index f157650a..3431dce2 100644 --- a/product/src/gui/plugin/LimitOptWidget/CLimitOptWork.cpp +++ b/product/src/gui/plugin/LimitOptWidget/CLimitOptWork.cpp @@ -142,7 +142,6 @@ bool CLimitOptWork::updateLimitPara(const QMap, QList, QListsendMsgToDomain(msg, iter.key().first)) diff --git a/product/src/gui/plugin/LimitOptWidget/CLimitPluginWidget.h b/product/src/gui/plugin/LimitOptWidget/CLimitPluginWidget.h index b6a2e05c..8bd267fb 100644 --- a/product/src/gui/plugin/LimitOptWidget/CLimitPluginWidget.h +++ b/product/src/gui/plugin/LimitOptWidget/CLimitPluginWidget.h @@ -7,7 +7,7 @@ class CLimitPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlMessageHandle.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlMessageHandle.h index f5340d4c..77f70182 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlMessageHandle.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlMessageHandle.h @@ -5,7 +5,7 @@ class CLinkCtrlDataManage; -class CLinkCtrlMessageHandle : public iot_application::CLinkageForHmiApi +class CLinkCtrlMessageHandle : public iot_app::CLinkageForHmiApi { public: CLinkCtrlMessageHandle(CLinkCtrlDataManage * linkCtrlDataManage); diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlPluginWidget.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlPluginWidget.h index 513290c9..e52cffae 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlPluginWidget.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlPluginWidget.h @@ -7,7 +7,7 @@ class CLinkCtrlPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.cpp index 9a76132d..2f53e537 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkCtrlWidget.cpp @@ -18,7 +18,19 @@ #include "pub_utility_api/FileUtil.h" #include "pub_utility_api/CommonConfigParse.h" #include "pub_utility_api/FileStyle.h" + +//< 屏蔽xml_parser编译告警 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-copy" +#endif + #include "boost/property_tree/xml_parser.hpp" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "boost/typeof/typeof.hpp" #include "boost/filesystem.hpp" #include diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApi.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApi.cpp index ca66335a..037749c6 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApi.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApi.cpp @@ -1,7 +1,7 @@ #include "application/linkage_server_api/CLinkageForHmiApi.h" #include "CLinkageForHmiApiImpl.h" -using namespace iot_application; +using namespace iot_app; CLinkageForHmiApi::CLinkageForHmiApi(int appid) { diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.cpp b/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.cpp index 469ee722..b0fcf1ed 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.cpp +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.cpp @@ -4,10 +4,10 @@ #include "CLinkageForHmiApiImpl.h" -using namespace iot_application; +using namespace iot_app; using namespace iot_idl::linkage; -iot_application::CLinkageForHmiApiImpl::CLinkageForHmiApiImpl( +iot_app::CLinkageForHmiApiImpl::CLinkageForHmiApiImpl( int appid, CLinkageForHmiApi* api) : CTimerThreadBase("CLinkageForHmiApiImpl thread", 100), @@ -87,8 +87,7 @@ bool CLinkageForHmiApiImpl::recvMsgLink( case enumStatusMessage: { StatusChangeMessage dataMsg; - if (!dataMsg.ParseFromArray(msg.getDataPtr(), - msg.getDataSize())) + if (!dataMsg.ParseFromArray(msg.getDataPtr(),static_cast(msg.getDataSize()) )) { BOOST_ASSERT(false); return false; @@ -99,8 +98,7 @@ bool CLinkageForHmiApiImpl::recvMsgLink( case enumLinkStartRequestMessage: { LinkStartRequestMessage dataMsg; - if (!dataMsg.ParseFromArray(msg.getDataPtr(), - msg.getDataSize())) + if (!dataMsg.ParseFromArray(msg.getDataPtr(),static_cast(msg.getDataSize()) )) { BOOST_ASSERT(false); } @@ -110,8 +108,7 @@ bool CLinkageForHmiApiImpl::recvMsgLink( case enumLinkOperateMessageAck: { LinkOperateMessageAck dataMsg; - if (!dataMsg.ParseFromArray(msg.getDataPtr(), - msg.getDataSize())) + if (!dataMsg.ParseFromArray(msg.getDataPtr(),static_cast(msg.getDataSize()) )) { BOOST_ASSERT(false); } @@ -121,8 +118,7 @@ bool CLinkageForHmiApiImpl::recvMsgLink( case enumUiRequestMessage: { UiRequestMessage dataMsg; - if (!dataMsg.ParseFromArray(msg.getDataPtr(), - msg.getDataSize())) + if (!dataMsg.ParseFromArray(msg.getDataPtr(),static_cast(msg.getDataSize()) )) { BOOST_ASSERT(false); } diff --git a/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.h b/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.h index 105079af..9e7d37c1 100644 --- a/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.h +++ b/product/src/gui/plugin/LinkCtrlWidget/CLinkageForHmiApiImpl.h @@ -6,7 +6,7 @@ #include "net/net_msg_bus_api/CMbCommunicator.h" #include "application/linkage_server_api/CLinkageForHmiApi.h" -namespace iot_application { +namespace iot_app { using namespace iot_idl::linkage; class CLinkageForHmiApiImpl diff --git a/product/src/gui/plugin/LoadStatWidget/LoadStatPluginWidget.h b/product/src/gui/plugin/LoadStatWidget/LoadStatPluginWidget.h index 9ec9b4ab..13b7b6b9 100644 --- a/product/src/gui/plugin/LoadStatWidget/LoadStatPluginWidget.h +++ b/product/src/gui/plugin/LoadStatWidget/LoadStatPluginWidget.h @@ -7,7 +7,7 @@ class LoadStatPluginWidget : public QObject,public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/MediaWidget/CMediaPluginWidget.h b/product/src/gui/plugin/MediaWidget/CMediaPluginWidget.h index 42f54b92..c62bbfe4 100644 --- a/product/src/gui/plugin/MediaWidget/CMediaPluginWidget.h +++ b/product/src/gui/plugin/MediaWidget/CMediaPluginWidget.h @@ -7,7 +7,7 @@ class CMediaPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: CMediaPluginWidget(QObject *parent = nullptr); diff --git a/product/src/gui/plugin/NavigationWidget/CNavigationDelegate.cpp b/product/src/gui/plugin/NavigationWidget/CNavigationDelegate.cpp index 556e69b0..2042349e 100644 --- a/product/src/gui/plugin/NavigationWidget/CNavigationDelegate.cpp +++ b/product/src/gui/plugin/NavigationWidget/CNavigationDelegate.cpp @@ -202,6 +202,10 @@ void CNavigationDelegate::drawItem(QPainter *painter, const QStyleOptionViewItem rt.adjust(delta, 0, 0, 0); painter->setPen(std::move(pen)); QFont font = option.font; + if (option.state & QStyle::State_Selected) + { + font.setBold(true); + } font.setPixelSize(std::get<2>(m_pItemProxy->vecItemStyle[level])); painter->setFont(std::move(font)); painter->drawText(rt, index.data().toString(), textOpiton); diff --git a/product/src/gui/plugin/NavigationWidget/CNavigationPluginWidget.h b/product/src/gui/plugin/NavigationWidget/CNavigationPluginWidget.h index fac1ad7a..bb43c2b3 100644 --- a/product/src/gui/plugin/NavigationWidget/CNavigationPluginWidget.h +++ b/product/src/gui/plugin/NavigationWidget/CNavigationPluginWidget.h @@ -7,7 +7,7 @@ class CNavigationPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/NavigationWidget/CNavigationWidget.cpp b/product/src/gui/plugin/NavigationWidget/CNavigationWidget.cpp index 1406e0ed..80afa9d8 100644 --- a/product/src/gui/plugin/NavigationWidget/CNavigationWidget.cpp +++ b/product/src/gui/plugin/NavigationWidget/CNavigationWidget.cpp @@ -51,7 +51,7 @@ CNavigationWidget::~CNavigationWidget() void CNavigationWidget::initialize() { - setStyleSheet("background-color:transparent;QLineEdit:edit-focus{background-color:white}"); + //setStyleSheet("background-color:transparent;QLineEdit:edit-focus{background-color:white}"); setMouseTracking(true); setRootIsDecorated(false); header()->setVisible(false); @@ -70,12 +70,20 @@ void CNavigationWidget::initialize() QString strItemConfigFile = m_strFileHomePath + QString("model%1NavigationWidget.json").arg(QDir::separator()); read(strItemConfigFile); + initStyleSheet(); if(EDIT_MODE != m_navigationMode) { expandAll(); } } +void CNavigationWidget::initStyleSheet() +{ + QString br=QString("background: #%1;").arg(QString::number(m_pItemProxy->backgroundColor, 16).toUpper()); + QString qss=QString("CNavigationWidget {%1}").arg(br);; + setStyleSheet(qss); +} + void CNavigationWidget::setNavigationMode(const CNavigationWidget::Navigation_Mode &navigationMode) { m_navigationMode = navigationMode; @@ -161,8 +169,8 @@ void CNavigationWidget::setItemSelected(const QString &data) void CNavigationWidget::paintEvent(QPaintEvent *event) { - QPainter painter(viewport()); - painter.fillRect(viewport()->rect(), m_pItemProxy->backgroundColor); + //QPainter painter(viewport()); + //painter.fillRect(viewport()->rect(), QColor::fromRgba(m_pItemProxy->backgroundColor).rgba()); QTreeView::paintEvent(event); } @@ -746,7 +754,7 @@ void CNavigationWidget::drawRow(QPainter *painter, const QStyleOptionViewItem &o } } -void CNavigationWidget::setTreeBackgroundColor(const rgb &color) +void CNavigationWidget::setTreeBackgroundColor(const rgba &color) { if(m_pItemProxy) { @@ -754,7 +762,7 @@ void CNavigationWidget::setTreeBackgroundColor(const rgb &color) } } -void CNavigationWidget::setItemHoverBackgroundColor(const rgb &color) +void CNavigationWidget::setItemHoverBackgroundColor(const rgba &color) { if(m_pItemProxy) { @@ -762,7 +770,7 @@ void CNavigationWidget::setItemHoverBackgroundColor(const rgb &color) } } -void CNavigationWidget::setItemSelectedBackgroundColor(const rgb &color) +void CNavigationWidget::setItemSelectedBackgroundColor(const rgba &color) { if(m_pItemProxy) { @@ -770,7 +778,7 @@ void CNavigationWidget::setItemSelectedBackgroundColor(const rgb &color) } } -void CNavigationWidget::setTextColor(const rgb &color) +void CNavigationWidget::setTextColor(const rgba &color) { if(m_pItemProxy) { @@ -778,7 +786,7 @@ void CNavigationWidget::setTextColor(const rgb &color) } } -void CNavigationWidget::setTextHoverColor(const rgb &color) +void CNavigationWidget::setTextHoverColor(const rgba &color) { if(m_pItemProxy) { @@ -786,7 +794,7 @@ void CNavigationWidget::setTextHoverColor(const rgb &color) } } -void CNavigationWidget::setTextSelectedColor(const rgb &color) +void CNavigationWidget::setTextSelectedColor(const rgba &color) { if(m_pItemProxy) { @@ -794,7 +802,7 @@ void CNavigationWidget::setTextSelectedColor(const rgb &color) } } -void CNavigationWidget::setItemBackgroundColor(const rgb &color, const Node_Level &level) +void CNavigationWidget::setItemBackgroundColor(const rgba &color, const Node_Level &level) { if(m_pItemProxy) { @@ -835,33 +843,33 @@ void CNavigationWidget::read(const QString &strFileName) if(root.contains("configure")) { QJsonObject configObject = root.value("configure").toObject(); - m_pItemProxy->backgroundColor = QColor(configObject["backgroundColor"].toString()).rgb(); + m_pItemProxy->backgroundColor = QColor(configObject["backgroundColor"].toString()).rgba(); m_pItemProxy->indicatorWidth = configObject["indicatorWidth"].toInt(); m_pItemProxy->iconMargin = configObject["iconMargin"].toInt(); m_pItemDelegate->m_rowHeight = configObject["rowHeight"].toInt(); - std::get<0>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = QColor(configObject["levelTopItemBgColor"].toString()).rgb(); - std::get<1>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = QColor(configObject["levelTopItemTextColor"].toString()).rgb(); + std::get<0>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = QColor(configObject["levelTopItemBgColor"].toString()).rgba(); + std::get<1>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = QColor(configObject["levelTopItemTextColor"].toString()).rgba(); std::get<2>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = configObject["levelTopItemTextSize"].toInt(); std::get<3>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = configObject["levelTopItemIconSize"].toInt(); std::get<4>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = configObject["levelTopItemIndentation"].toInt(); - std::get<0>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = QColor(configObject["levelChildItemBgColor"].toString()).rgb(); - std::get<1>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = QColor(configObject["levelChildItemTextColor"].toString()).rgb(); + std::get<0>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = QColor(configObject["levelChildItemBgColor"].toString()).rgba(); + std::get<1>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = QColor(configObject["levelChildItemTextColor"].toString()).rgba(); std::get<2>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = configObject["levelChildItemTextSize"].toInt(); std::get<3>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = configObject["levelChildItemIconSize"].toInt(); std::get<4>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = configObject["levelChildItemIndentation"].toInt(); - std::get<0>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = QColor(configObject["levelLeafItemBgColor"].toString()).rgb(); - std::get<1>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = QColor(configObject["levelLeafItemTextColor"].toString()).rgb(); + std::get<0>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = QColor(configObject["levelLeafItemBgColor"].toString()).rgba(); + std::get<1>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = QColor(configObject["levelLeafItemTextColor"].toString()).rgba(); std::get<2>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = configObject["levelLeafItemTextSize"].toInt(); std::get<3>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = configObject["levelLeafItemIconSize"].toInt(); std::get<4>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = configObject["levelLeafItemIndentation"].toInt(); - m_pItemProxy->itemHoveredColor = QColor(configObject["itemHoveredBgColor"].toString()).rgb(); - m_pItemProxy->itemSelectedColor = QColor(configObject["itemSelectedColor"].toString()).rgb(); - m_pItemProxy->itemHoveredTextColor = QColor(configObject["itemHoveredTextColor"].toString()).rgb(); - m_pItemProxy->itemSelectedTextColor = QColor(configObject["itemSelectedTextColor"].toString()).rgb(); + m_pItemProxy->itemHoveredColor = QColor(configObject["itemHoveredBgColor"].toString()).rgba(); + m_pItemProxy->itemSelectedColor = QColor(configObject["itemSelectedColor"].toString()).rgba(); + m_pItemProxy->itemHoveredTextColor = QColor(configObject["itemHoveredTextColor"].toString()).rgba(); + m_pItemProxy->itemSelectedTextColor = QColor(configObject["itemSelectedTextColor"].toString()).rgba(); } if(root.contains("items")) diff --git a/product/src/gui/plugin/NavigationWidget/CNavigationWidget.h b/product/src/gui/plugin/NavigationWidget/CNavigationWidget.h index 1f1b61a4..4f008452 100644 --- a/product/src/gui/plugin/NavigationWidget/CNavigationWidget.h +++ b/product/src/gui/plugin/NavigationWidget/CNavigationWidget.h @@ -7,9 +7,9 @@ class CNavigationDelegate; -typedef unsigned int rgb; +typedef unsigned int rgba; -typedef std::tuple NodeInfo; //< 节点背景颜色、节点字体颜色、节点字体大小、图标大小、偏移像素 +typedef std::tuple NodeInfo; //< 节点背景颜色、节点字体颜色、节点字体大小、图标大小、偏移像素 extern const int Level_Role; //< 节点层级 extern const int Corner_Role; //< 活动根节点 @@ -26,14 +26,14 @@ struct ITEM_STYLE_PROXY int iconMargin; //< 填充颜色 - rgb backgroundColor; - rgb itemHoveredColor; - rgb itemSelectedColor; + rgba backgroundColor; + rgba itemHoveredColor; + rgba itemSelectedColor; //< 文字颜色 - rgb itemTextColor; - rgb itemHoveredTextColor; - rgb itemSelectedTextColor; + rgba itemTextColor; + rgba itemHoveredTextColor; + rgba itemSelectedTextColor; std::vector< NodeInfo > vecItemStyle; }; @@ -120,15 +120,15 @@ public Q_SLOTS: void getNodeTypeMap(QMap &map); /******************** 样式设置-[begin] ************************/ - void setTreeBackgroundColor(const rgb &color); - void setItemHoverBackgroundColor(const rgb &color); - void setItemSelectedBackgroundColor(const rgb &color); + void setTreeBackgroundColor(const rgba &color); + void setItemHoverBackgroundColor(const rgba &color); + void setItemSelectedBackgroundColor(const rgba &color); - void setTextColor(const rgb &color); - void setTextHoverColor(const rgb &color); - void setTextSelectedColor(const rgb &color); + void setTextColor(const rgba &color); + void setTextHoverColor(const rgba &color); + void setTextSelectedColor(const rgba &color); - void setItemBackgroundColor(const rgb &color, const Node_Level &level); + void setItemBackgroundColor(const rgba &color, const Node_Level &level); void setItemTextSize(const int &size, const Node_Level &level); /******************** 样式设置-[end] *************************/ @@ -141,6 +141,7 @@ Q_SIGNALS: private: void initialize(); + void initStyleSheet(); void loadItemDelegate(); void updateItems(const CNavigationWidget * pNavigation); diff --git a/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.cpp b/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.cpp index 0ad08a02..3789e28b 100644 --- a/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.cpp +++ b/product/src/gui/plugin/OrderManageWidget/COperationOrderForm.cpp @@ -414,8 +414,7 @@ bool COperationOrderForm::updateDbModelData() for (int row = 0; row < ui->m_table->rowCount(); ++row) { - int seq = ui->m_table->item(row, 0)->text().toInt(); - + //int seq = ui->m_table->item(row, 0)->text().toInt(); SOrderPreStoreInfo info = getOrderInfo(row, order_id); ret = dbCtrl.insertOneOrderInfoData(info); if (ret == false) diff --git a/product/src/gui/plugin/OrderManageWidget/COperationOrderPluginWidget.h b/product/src/gui/plugin/OrderManageWidget/COperationOrderPluginWidget.h index cd7d2998..91a68204 100644 --- a/product/src/gui/plugin/OrderManageWidget/COperationOrderPluginWidget.h +++ b/product/src/gui/plugin/OrderManageWidget/COperationOrderPluginWidget.h @@ -7,7 +7,7 @@ class COperationOrderPluginWidget: public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/OrderManageWidget/main.cpp b/product/src/gui/plugin/OrderManageWidget/main.cpp index 1be4da3c..cea10571 100644 --- a/product/src/gui/plugin/OrderManageWidget/main.cpp +++ b/product/src/gui/plugin/OrderManageWidget/main.cpp @@ -21,7 +21,7 @@ int main(int argc, char *argv[]) return -1; } - if(perm->SysLogin("Admin", "kbdct", 1, 12*60*60, "hmi") != 0) + if(perm->SysLogin("Admin", "admin", 1, 12*60*60, "hmi") != 0) { return -1; } diff --git a/product/src/gui/plugin/PointLockWidget/CPointLockPluginWidget.h b/product/src/gui/plugin/PointLockWidget/CPointLockPluginWidget.h index 1dcac76a..7afa459d 100644 --- a/product/src/gui/plugin/PointLockWidget/CPointLockPluginWidget.h +++ b/product/src/gui/plugin/PointLockWidget/CPointLockPluginWidget.h @@ -7,7 +7,7 @@ class CPointLockPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.cpp b/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.cpp index 4173b497..44012e81 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.cpp +++ b/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "pub_utility_api/FileStyle.h" CPointRealDataWidget::CPointRealDataWidget(bool editMode, QWidget *parent) : QWidget(parent), @@ -72,6 +73,34 @@ void CPointRealDataWidget::initialize() m_pTimer->start(1000); } +void CPointRealDataWidget::initStyle() +{ + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("PointRealDataWidget.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + void CPointRealDataWidget::switchAppcontext(int appContext) { if(m_objAppContext == appContext) @@ -272,6 +301,167 @@ QString CPointRealDataWidget::addPoint(int GroupNo, const QStringList &RealTagLi return ""; } +QString CPointRealDataWidget::addRealPoint(int GroupNo, const QString &strRealTagList) +{ + if(m_groupMap.find(GroupNo) == m_groupMap.constEnd()) + { + return tr("未找到组号%1!").arg(QString::number(GroupNo)); + } + + QStringList RealTagList = strRealTagList.split(";"); + if (RealTagList.count() == 0) + { + return ""; + } + + //< 得到所有可能的点标签 + QMap tagMap; + QString devGroup; + foreach (QString RealTag, RealTagList) { + if(RealTag.isEmpty() || RealTag.split(".").length() != 7) + { + continue; + } + if (devGroup.isEmpty()) + { + devGroup = truncTag(RealTag, "g"); + } + tagMap[devGroup].append(RealTag); + + QString tagName = RealTag; + SRealData realData; + QString temp; + QString table = truncTag(tagName, "t"); + QString vlast = truncTag(tagName, "v"); + if (vlast == "channel") + { + temp = CDbInterface::instance()->readChannelTag(truncTag(tagName, "d"), table); + } + else + { + temp = CDbInterface::instance()->readPointInfo(truncTag(tagName, "p"), table); + } + if (temp.isEmpty()) + { + continue; + } + if (vlast == "channel") + { + realData.tag_name = temp; + realData.description = m_channelTxList[0]; + realData.table_name = "fes_channel_para"; + realData.column = "status"; + realData.type = TYPE_CHANNEL; + } + else + { + m_tagMap[GroupNo].append(QVariant::fromValue(tagName)); + realData.tag_name = truncTag(tagName, "p"); + realData.description = temp.section(",", 0, 0); + realData.table_name = table; + if (realData.table_name == "analog" || realData.table_name == "accuml") + { + realData.unit = temp.section(",", 1, 1); + } + else if (realData.table_name == "digital" || realData.table_name == "mix") + { + realData.stateTextName = temp.section(",", 1, 1); + } + } + realData.nDomainId = CDbInterface::instance()->readDomainId(truncTag(tagName, "l")); + realData.nAppId = CDbInterface::instance()->readAppId(truncTag(tagName, "a")); + + m_groupMap[GroupNo].append(realData); + if (realData.type == TYPE_POINT) + { + m_pDpcdaForApp->subscribe(realData.table_name.toStdString(), realData.tag_name.toStdString(), realData.column.toStdString()); + } + } + + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + CRealTableModel *model = dynamic_cast(view->model()); + model->updateRealData(m_groupMap[GroupNo]); + } + return ""; +} + +QString CPointRealDataWidget::addCommPoint(int GroupNo, const QString &strRealTagList) +{ + if(m_groupMap.find(GroupNo) == m_groupMap.constEnd()) + { + return tr("未找到组号%1!").arg(QString::number(GroupNo)); + } + + QStringList RealTagList = strRealTagList.split(";"); + if (RealTagList.count() == 0) + { + return ""; + } + + //< 得到所有可能的点标签 + QMap tagMap; + QString devGroup; + foreach (QString RealTag, RealTagList) { + if(RealTag.isEmpty() || RealTag.split(".").length() != 7) + { + continue; + } + if (devGroup.isEmpty()) + { + devGroup = truncTag(RealTag, "g"); + } + tagMap[devGroup].append(RealTag); + + QString tagName = RealTag; + SRealData realData; + QString temp; + QString table = truncTag(tagName, "t"); + + temp = CDbInterface::instance()->readPointInfo(truncTag(tagName, "p"), table); + + if (temp.isEmpty()) + { + continue; + } + + m_tagMap[GroupNo].append(QVariant::fromValue(tagName)); + realData.tag_name = truncTag(tagName, "p"); + realData.description = temp.section(",", 0, 0); + realData.table_name = table; + if (realData.table_name == "digital") + { + realData.stateTextName = temp.section(",", 1, 1); + } + else + { + continue; + } + + realData.nDomainId = CDbInterface::instance()->readDomainId(truncTag(tagName, "l")); + realData.nAppId = CDbInterface::instance()->readAppId(truncTag(tagName, "a")); + + m_groupMap[GroupNo].append(realData); + if (realData.type == TYPE_POINT) + { + m_pDpcdaForApp->subscribe(realData.table_name.toStdString(), realData.tag_name.toStdString(), realData.column.toStdString()); + } + } + + QTableView *view = m_tableMap.value(GroupNo); + if(view) + { + CRealTableModel *model = dynamic_cast(view->model()); + model->setColumnCount(4); + model->setShowCommunicationsDetail(true); + model->updateRealData(m_groupMap[GroupNo]); + } + return ""; + + +} + QVariantList CPointRealDataWidget::getPointList(int GroupNo) { return m_tagMap.value(GroupNo); @@ -341,6 +531,19 @@ void CPointRealDataWidget::setHeaderVisible(int GroupNo, int header, bool visibl } } +void CPointRealDataWidget::setHeaderDesc(int GroupNo, const QString& headerDescs) +{ + QTableView *view = m_tableMap.value(GroupNo); + if(!view) + { + return; + } + + CRealTableModel *model = dynamic_cast(view->model()); + QStringList headerDescList = headerDescs.split(","); + model->setHeaderLabels(headerDescList); +} + void CPointRealDataWidget::setShowGrid(int GroupNo, bool isShow) { QTableView *view = m_tableMap.value(GroupNo); @@ -394,6 +597,20 @@ void CPointRealDataWidget::setChannelText(const QString &text, const QString &no } } +void CPointRealDataWidget::clear(int groupNo) +{ + QTableView *view = m_tableMap.value(groupNo); + if(view) + { + CRealTableModel *model = dynamic_cast(view->model()); + QList data; + model->updateRealData(data); + + m_tagMap[groupNo] = QVariantList(); + m_groupMap[groupNo] = data; + } +} + void CPointRealDataWidget::updatePointValue(const QSet &groupSet) { foreach (const int &groupNo, groupSet) diff --git a/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.h b/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.h index 7d408317..4d24f270 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.h +++ b/product/src/gui/plugin/PointRealDataWidget/CPointRealDataWidget.h @@ -20,7 +20,12 @@ public: void initialize(); + + public slots: + + void initStyle(); + /** * @brief switchAppcontext 切换数据来源 * @param appContext 1: 实时数据 2: 事故反演 @@ -37,7 +42,7 @@ public slots: int addGroup(const QStringList &name, int row, int column); /** - * @brief addPoint 往组内添加测点 + * @brief addPoint 往组内添加测点,根据这个关联的测点所属的组找到所有的相关测点列表进行显示 * @param GroupNo 组号 * @param RealTagList 关联测点列表 "station1.PSCADA.digital.station1.NQ-G01_NRINC.OC1.value" * @param PointList 测点列表 "digital.OC1.value" @@ -45,6 +50,22 @@ public slots: */ QString addPoint(int GroupNo, const QStringList &RealTagList, const QStringList &PointList); + /** + * @brief addRealPoint 往组内添加测点,插入的列表是什么就是什么 + * @param GroupNo 组号 + * @param RealTagList 关联测点列表 "station1.PSCADA.digital.station1.NQ-G01_NRINC.OC1.value;station1.PSCADA.digital.station1.NQ-G01_NRINC.OC1.value" + * @return 成功返回空字符串,失败返回错误信息 + */ + QString addRealPoint(int GroupNo, const QString& strRealTagList); + + /** + * @brief addRealPoint 往组内添加通讯测点,插入的列表是什么就是什么,额外显示通讯参数 + * @param GroupNo 组号 + * @param RealTagList 关联测点列表 "station1.PSCADA.digital.station1.NQ-G01_NRINC.OC1.value;station1.PSCADA.digital.station1.NQ-G01_NRINC.OC1.value" + * @return 成功返回空字符串,失败返回错误信息 + */ + QString addCommPoint(int GroupNo, const QString& strRealTagList); + /** * @brief getPointList 获取组内测点列表 * @param GroupNo 组号 @@ -83,6 +104,14 @@ public slots: */ void setHeaderVisible(int GroupNo, int header = Qt::Horizontal, bool visible = true); + /** + * @brief setHeaderVisible 设置表头描述 + * @param GroupNo 组号 + * @param header 1:水平 2:垂直 + * @param visible 是否显示 + */ + void setHeaderDesc(int GroupNo, const QString& headerDescs); + /** * @brief setShowGrid 设置是否显示表格网格线 * @param GroupNo 组号 @@ -113,6 +142,8 @@ public slots: */ void setChannelText(const QString& text, const QString &normal, const QString &abnormal); + void clear(int groupNo); + private slots: void updatePointValue(const QSet &groupSet); void updatePointValue(int groupNo, QList data); diff --git a/product/src/gui/plugin/PointRealDataWidget/CPointRealPluginWidget.h b/product/src/gui/plugin/PointRealDataWidget/CPointRealPluginWidget.h index 6b00e12b..874b07f4 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CPointRealPluginWidget.h +++ b/product/src/gui/plugin/PointRealDataWidget/CPointRealPluginWidget.h @@ -7,7 +7,7 @@ class CPointRealPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.cpp b/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.cpp index b7ab375c..b9620e2f 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.cpp +++ b/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.cpp @@ -51,6 +51,11 @@ QVariant CRealTableModel::headerData(int section, Qt::Orientation orientation, i return QVariant(); } +void CRealTableModel::setHeaderLabels(const QStringList& headers) +{ + m_header = headers; +} + int CRealTableModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) @@ -145,4 +150,9 @@ QVariant CRealTableModel::data(const QModelIndex &index, int role) const } return QVariant(); + } + +void CRealTableModel::setShowCommunicationsDetail(bool showCommunicationsDetail) +{ + m_showCommunicationsDetail = showCommunicationsDetail; } diff --git a/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.h b/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.h index 6aab386c..2ed4349e 100644 --- a/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.h +++ b/product/src/gui/plugin/PointRealDataWidget/CRealTableModel.h @@ -24,17 +24,22 @@ public: QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + void setHeaderLabels(const QStringList& headers); + int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + void setShowCommunicationsDetail(bool showCommunicationsDetail); + private: QStringList m_header; int nColumnCount; QList m_listRealData; QStringList m_channelTxList; QFont m_valueFont; + bool m_showCommunicationsDetail; }; #endif // CREALTABLEMODEL_H diff --git a/product/src/gui/plugin/PointRealDataWidget/PointRealDataWidget.pro b/product/src/gui/plugin/PointRealDataWidget/PointRealDataWidget.pro index 848d20d4..fd4ee292 100644 --- a/product/src/gui/plugin/PointRealDataWidget/PointRealDataWidget.pro +++ b/product/src/gui/plugin/PointRealDataWidget/PointRealDataWidget.pro @@ -47,7 +47,8 @@ LIBS += \ -lpub_logger_api \ -lprotobuf \ -lnet_msg_bus_api \ - -ldp_chg_data_api + -ldp_chg_data_api \ + -lpub_utility_api include($$PWD/../../../idl_files/idl_files.pri) diff --git a/product/src/gui/plugin/PointsLockWidget/CPointsLockPluginWidget.h b/product/src/gui/plugin/PointsLockWidget/CPointsLockPluginWidget.h index 753120d8..b2018e73 100644 --- a/product/src/gui/plugin/PointsLockWidget/CPointsLockPluginWidget.h +++ b/product/src/gui/plugin/PointsLockWidget/CPointsLockPluginWidget.h @@ -7,7 +7,7 @@ class CPointsLockPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: CPointsLockPluginWidget(QObject *parent = 0); diff --git a/product/src/gui/plugin/RelaySettingWidget/CDbMng.cpp b/product/src/gui/plugin/RelaySettingWidget/CDbMng.cpp index 33fee81d..e0ac17b4 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CDbMng.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/CDbMng.cpp @@ -346,6 +346,12 @@ QList CDbMng::getSetting() relaySetting.locDesc = query.value(22).toString(); relaySetting.keyIdTag = QString("%1.%2.%3").arg("fes_const").arg(relaySetting.tagName).arg("value"); + if(relaySetting.valueText.compare("Null", Qt::CaseInsensitive) == 0) + { + relaySetting.valueText = ""; + } + relaySetting.valueText = relaySetting.valueText.replace(".ini",""); + iot_public::SAppInfo stAppInfo; if(iotSuccess != sysInfoPtr->getAppInfoBySubsystemId(relaySetting.subSystem, stAppInfo)) { diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingMsgMng.cpp b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingMsgMng.cpp index 04d988c9..14828aec 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingMsgMng.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingMsgMng.cpp @@ -44,14 +44,13 @@ void CRelaySettingMsgMng::slotcmd(const QList &keyList, const QListsendMsgToDomain(msg, relaySetting.domainId)) { @@ -79,10 +78,9 @@ void CRelaySettingMsgMng::recvMessage() return; } - COptCustCtrlReply cOptCustCtrlReply; SOptCustCtrlReply sOptCustCtrlReply; std::string str((const char*)msg.getDataPtr(), msg.getDataSize()); - cOptCustCtrlReply.parse(str, sOptCustCtrlReply); + COptCustCtrlReply::parse(str, sOptCustCtrlReply); if(parseMsg(sOptCustCtrlReply)) { diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingPluginWidget.h b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingPluginWidget.h index dcac799f..3789135a 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingPluginWidget.h +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingPluginWidget.h @@ -8,7 +8,7 @@ class CRelaySettingPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: CRelaySettingPluginWidget(QObject *parent = 0); diff --git a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.cpp b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.cpp index 3a11b986..144d6bf2 100644 --- a/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/CRelaySettingWidget.cpp @@ -752,7 +752,7 @@ void CRelaySettingWidget::setEnableBtnList(bool isSuccess) void CRelaySettingWidget::setCtrlBtnEnable(bool isEnable) { - // ui->comboBox->setEnabled(isEnable); + ui->comboBox->setEnabled(isEnable); ui->change->setEnabled(isEnable); ui->edit->setEnabled(isEnable); ui->confirm->setEnabled(isEnable); @@ -911,7 +911,7 @@ QString CRelaySettingWidget::getDisplayValue(RelaySetting &relaySetting, float & return QString::number(value); } - QString display_value = QString::number(value); //设置默认值 + QString display_value = ""; QMap >::const_iterator it = m_dictMap.find(relaySetting.valueText); if(it != m_dictMap.end()) { @@ -940,7 +940,7 @@ QString CRelaySettingWidget::getDisplayValue(RelaySetting &relaySetting, float & bool CRelaySettingWidget::checkPermCtrl() { std::string str = "FUNC_NOM_CONST_CTRL"; - if(PERM_PERMIT != m_permMng->PermCheck(PERM_NOM_FUNC_DEF,(char*)&str)) + if(PERM_PERMIT != m_permMng->PermCheck(PERM_NOM_FUNC_DEF,&str)) { QMessageBox::warning(this,tr("提示"),tr("无保护定值操作权限!")); return false; @@ -1620,6 +1620,8 @@ void CRelaySettingWidget::slotRecvOuttime() void CRelaySettingWidget::slotCurrentIndexChanged(int curIndex) { + Q_UNUSED(curIndex); + QString indexDev = ui->mGroupCb->currentData().toString(); int filterType = EN_RELAY_DEV; if(indexDev.isEmpty()) diff --git a/product/src/gui/plugin/RelaySettingWidget/main.cpp b/product/src/gui/plugin/RelaySettingWidget/main.cpp index a53b4757..cb6436eb 100644 --- a/product/src/gui/plugin/RelaySettingWidget/main.cpp +++ b/product/src/gui/plugin/RelaySettingWidget/main.cpp @@ -19,7 +19,7 @@ int main(int argc, char *argv[]) return -1; } - if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) + if(perm->SysLogin("admin", "admin", 1, 12*60*60, "hmi") != 0) { return -1; } diff --git a/product/src/gui/plugin/ReportApp/CReportPluginWidget.h b/product/src/gui/plugin/ReportApp/CReportPluginWidget.h index 67cf59ee..1679e58b 100644 --- a/product/src/gui/plugin/ReportApp/CReportPluginWidget.h +++ b/product/src/gui/plugin/ReportApp/CReportPluginWidget.h @@ -7,7 +7,7 @@ class CReportPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/ReportApp/ReportEdit.ico b/product/src/gui/plugin/ReportApp/ReportEdit.ico index 9ce1c9a9..6b2dbdc2 100644 Binary files a/product/src/gui/plugin/ReportApp/ReportEdit.ico and b/product/src/gui/plugin/ReportApp/ReportEdit.ico differ diff --git a/product/src/gui/plugin/ReportWidget/CReportPluginWidget.h b/product/src/gui/plugin/ReportWidget/CReportPluginWidget.h index 67cf59ee..1679e58b 100644 --- a/product/src/gui/plugin/ReportWidget/CReportPluginWidget.h +++ b/product/src/gui/plugin/ReportWidget/CReportPluginWidget.h @@ -7,7 +7,7 @@ class CReportPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/RobotCtrlWidget/CRobotPluginWidget.h b/product/src/gui/plugin/RobotCtrlWidget/CRobotPluginWidget.h index 51659803..9c502670 100644 --- a/product/src/gui/plugin/RobotCtrlWidget/CRobotPluginWidget.h +++ b/product/src/gui/plugin/RobotCtrlWidget/CRobotPluginWidget.h @@ -7,7 +7,7 @@ class CRobotPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: CRobotPluginWidget(QObject *parent = nullptr); diff --git a/product/src/gui/plugin/RobotWidget/CRobotPluginWidget.h b/product/src/gui/plugin/RobotWidget/CRobotPluginWidget.h index 51659803..9c502670 100644 --- a/product/src/gui/plugin/RobotWidget/CRobotPluginWidget.h +++ b/product/src/gui/plugin/RobotWidget/CRobotPluginWidget.h @@ -7,7 +7,7 @@ class CRobotPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: CRobotPluginWidget(QObject *parent = nullptr); diff --git a/product/src/gui/plugin/ScheduleWidget/CDutySettingPluginWidget.h b/product/src/gui/plugin/ScheduleWidget/CDutySettingPluginWidget.h index b811093f..ba3e2a04 100644 --- a/product/src/gui/plugin/ScheduleWidget/CDutySettingPluginWidget.h +++ b/product/src/gui/plugin/ScheduleWidget/CDutySettingPluginWidget.h @@ -8,7 +8,7 @@ class CDutySettingPluginWidget : public QWidget, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/SecondButtonGroupWidget/CButton.cpp b/product/src/gui/plugin/SecondButtonGroupWidget/CButton.cpp new file mode 100644 index 00000000..774dcf19 --- /dev/null +++ b/product/src/gui/plugin/SecondButtonGroupWidget/CButton.cpp @@ -0,0 +1,41 @@ +#include "CButton.h" +#include +#include +#include +#include +#include + +CButton::CButton(const QIcon& icon, const QString &text, QWidget *parent) : QPushButton(icon, text,parent) { + +} + +void CButton::paintEvent(QPaintEvent *event) { + Q_UNUSED(event); + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + QStyleOptionButton option; + initStyleOption(&option); + QRectF rect = QRectF(option.rect); + painter.setPen(Qt::NoPen); + painter.setBrush(palette().button()); + + // 绘制平行四边形形状 + QPainterPath path; + qreal c=0.4; + path.moveTo(rect.left() + rect.width() * c, rect.top()); + path.lineTo(rect.right(), rect.top()); + path.lineTo(rect.right() - rect.width() * c, rect.bottom()); + path.lineTo(rect.left(), rect.bottom()); + path.lineTo(rect.left() + rect.width() * c, rect.top()); + painter.drawPath(path); + + // 绘制按钮的文本 + painter.setPen(Qt::black); + painter.drawText(rect, Qt::AlignCenter, text()); + + // 绘制按钮的状态 + if (isDown() || isChecked()) { + painter.fillRect(rect, QColor(0, 0, 0, 20)); // 按下或选中状态时添加半透明效果 + } +} diff --git a/product/src/gui/plugin/SecondButtonGroupWidget/CButton.h b/product/src/gui/plugin/SecondButtonGroupWidget/CButton.h new file mode 100644 index 00000000..a3bd4428 --- /dev/null +++ b/product/src/gui/plugin/SecondButtonGroupWidget/CButton.h @@ -0,0 +1,23 @@ +#ifndef CBUTTON_H +#define CBUTTON_H +#include + +class CButton: public QPushButton +{ +public: + CButton(const QIcon& icon, const QString &text, QWidget *parent = Q_NULLPTR); +protected: + void paintEvent(QPaintEvent *event) override; + void enterEvent(QEvent *event) override { + setStyleSheet("background-color: yellow;"); // 鼠标悬浮时改变背景颜色为黄色 + QPushButton::enterEvent(event); + } + + void leaveEvent(QEvent *event) override { + setStyleSheet(""); // 鼠标离开时恢复原来的样式表 + QPushButton::leaveEvent(event); + } + +}; + +#endif // CBUTTON_H diff --git a/product/src/gui/plugin/SecondButtonGroupWidget/CButtonGroupPluginWidget.cpp.autosave b/product/src/gui/plugin/SecondButtonGroupWidget/CButtonGroupPluginWidget.cpp.autosave new file mode 100644 index 00000000..e1d227ca --- /dev/null +++ b/product/src/gui/plugin/SecondButtonGroupWidget/CButtonGroupPluginWidget.cpp.autosave @@ -0,0 +1,27 @@ +#include "CSecondButtonGroupPluginWidget.h" +#include "CButtonGroupWidget.h" + +CButtonGroupPluginWidget::CButtonGroupPluginWidget(QObject *parent) + : QObject(parent) +{ + +} + +CButtonGroupPluginWidget::~CButtonGroupPluginWidget() +{ + +} + +bool CButtonGroupPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CButtonGroupWidget *pWidget = new CButtonGroupWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pNavigationWidget = (IPluginWidget *)pWidget; + return true; +} + +void CButtonGroupPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/SecondButtonGroupWidget/CJsonReader.cpp b/product/src/gui/plugin/SecondButtonGroupWidget/CJsonReader.cpp new file mode 100644 index 00000000..adc8aa7d --- /dev/null +++ b/product/src/gui/plugin/SecondButtonGroupWidget/CJsonReader.cpp @@ -0,0 +1,104 @@ +#include "CJsonReader.h" +#include "public/pub_utility_api/FileUtil.h" +#include "public/pub_logger_api/logger.h" +#include +#include +#include +#include + +CJsonReader::CJsonReader(QObject *parent) + : QObject(parent) +{ + m_btnWidth = 0; + m_btnHeight = 0; + m_baseX = 0; + + std::string currentPath = iot_public::CFileUtil::getCurModuleDir(); + QDir dir(QString::fromStdString(currentPath)); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + dir.cd("model"); + + readJson(dir.filePath("ButtonGroupWidget.json")); +} + +QString CJsonReader::getSeparatorPath() +{ + return m_strSeparator; +} + +int CJsonReader::getBtnWidth() +{ + return m_btnWidth; +} + +int CJsonReader::getBtnHeight() +{ + return m_btnHeight; +} + +int CJsonReader::getBaseX() +{ + return m_baseX; +} + +QMap CJsonReader::getButtonMap() +{ + return m_mapButton; +} + +ST_BUTTON CJsonReader::getStButton(const QString &key) +{ + return m_mapButton.value(key); +} + +void CJsonReader::readJson(const QString &path) +{ + QFile file(path); + QByteArray readJson; + if(file.open(QIODevice::ReadOnly)) + { + readJson = file.readAll(); + file.close(); + } + QJsonParseError readError; + QJsonDocument readJsonResponse = QJsonDocument::fromJson(readJson, &readError); + if(readError.error != QJsonParseError::NoError) + { + LOGERROR("CJsonReader error: %d, string: %s", readError.error, readError.errorString().toStdString().c_str()); + return; + } + QJsonObject root = readJsonResponse.object(); + QJsonObject::const_iterator rootIter = root.constBegin(); + for(; rootIter != root.constEnd(); rootIter++) + { + if(rootIter.key() == "separator") + { + m_strSeparator = rootIter.value().toString(); + continue; + }else if( rootIter.key() == "btnWidth") + { + m_btnWidth = rootIter.value().toInt(); + continue; + }else if( rootIter.key() == "btnHeight") + { + m_btnHeight = rootIter.value().toInt(); + continue; + }else if( rootIter.key() == "baseX") + { + m_baseX = rootIter.value().toInt(); + continue; + } + QJsonObject item = rootIter.value().toObject(); + ST_BUTTON st_Button; + st_Button.name = item["name"].toString(); + st_Button.used = item["used"].toInt(); + st_Button.type = item["opt"].toInt(); + st_Button.icon = item["icon"].toString(); + st_Button.web = item["web"].toInt(); + st_Button.data = item["data"].toString(); + st_Button.webData = item["webData"].toString(); + m_mapButton.insert(rootIter.key(), st_Button); + } +} diff --git a/product/src/gui/plugin/SecondButtonGroupWidget/CJsonReader.h b/product/src/gui/plugin/SecondButtonGroupWidget/CJsonReader.h new file mode 100644 index 00000000..0895d48f --- /dev/null +++ b/product/src/gui/plugin/SecondButtonGroupWidget/CJsonReader.h @@ -0,0 +1,48 @@ +#ifndef CJSONREADER_H +#define CJSONREADER_H + +#include +#include + +struct ST_BUTTON +{ + QString name; + int used; + int type; + QString icon; + int web; + QString data; + QString webData; +}; + +class CJsonReader : public QObject +{ + Q_OBJECT + +public: + CJsonReader(QObject *parent = 0); + + QString getSeparatorPath(); + + int getBtnWidth(); + + int getBtnHeight(); + + int getBaseX(); + + QMap getButtonMap(); + + ST_BUTTON getStButton(const QString &key); + +private: + void readJson(const QString &path); + +private: + QString m_strSeparator; + QMap m_mapButton; + int m_btnWidth; + int m_btnHeight; + int m_baseX; +}; + +#endif // CJSONREADER_H diff --git a/product/src/gui/plugin/SecondButtonGroupWidget/CSecondButtonGroupPluginWidget.cpp b/product/src/gui/plugin/SecondButtonGroupWidget/CSecondButtonGroupPluginWidget.cpp new file mode 100644 index 00000000..033246df --- /dev/null +++ b/product/src/gui/plugin/SecondButtonGroupWidget/CSecondButtonGroupPluginWidget.cpp @@ -0,0 +1,27 @@ +#include "CSecondButtonGroupPluginWidget.h" +#include "CSecondButtonGroupWidget.h" + +CSecondButtonGroupPluginWidget::CSecondButtonGroupPluginWidget(QObject *parent) + : QObject(parent) +{ + +} + +CSecondButtonGroupPluginWidget::~CSecondButtonGroupPluginWidget() +{ + +} + +bool CSecondButtonGroupPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CSecondButtonGroupWidget *pWidget = new CSecondButtonGroupWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pNavigationWidget = (IPluginWidget *)pWidget; + return true; +} + +void CSecondButtonGroupPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/SecondButtonGroupWidget/CSecondButtonGroupPluginWidget.h b/product/src/gui/plugin/SecondButtonGroupWidget/CSecondButtonGroupPluginWidget.h new file mode 100644 index 00000000..d52c8c35 --- /dev/null +++ b/product/src/gui/plugin/SecondButtonGroupWidget/CSecondButtonGroupPluginWidget.h @@ -0,0 +1,21 @@ +#ifndef CBUTTONGROUPPLUGINWIDGET_H +#define CBUTTONGROUPPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CSecondButtonGroupPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) + Q_INTERFACES(CPluginWidgetInterface) + +public: + CSecondButtonGroupPluginWidget(QObject *parent = 0); + ~CSecondButtonGroupPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec); + void release(); +}; + +#endif // CBUTTONGROUPPLUGINWIDGET_H diff --git a/product/src/gui/plugin/SecondButtonGroupWidget/CSecondButtonGroupWidget.cpp b/product/src/gui/plugin/SecondButtonGroupWidget/CSecondButtonGroupWidget.cpp new file mode 100644 index 00000000..23438177 --- /dev/null +++ b/product/src/gui/plugin/SecondButtonGroupWidget/CSecondButtonGroupWidget.cpp @@ -0,0 +1,165 @@ +#include "CSecondButtonGroupWidget.h" +#include "CJsonReader.h" +#include "public/pub_utility_api/FileUtil.h" +#include +#include +#include +#include +#include +#include +#include "pub_utility_api/FileStyle.h" +#include "CButton.h" + +CSecondButtonGroupWidget::CSecondButtonGroupWidget(QWidget *parent, bool editMode) + : QWidget(parent), + m_pJsonReader(NULL), + m_isEdit(editMode) +{ + initView(); + initQss(); +} + +CSecondButtonGroupWidget::~CSecondButtonGroupWidget() +{ + if(m_pJsonReader) + { + delete m_pJsonReader; + } + m_pJsonReader = NULL; +} + +void CSecondButtonGroupWidget::onButtonClicked(int index) +{ + QList buttonList = this->findChildren(); + if(index < buttonList.length()) + { + emit buttonList[index]->clicked(); + buttonList[index]->setChecked(true); + } + else if(buttonList.length() > 0) + { + emit buttonList[0]->clicked(); + buttonList[0]->setChecked(true); + } +} + +int CSecondButtonGroupWidget::getCheckedButton() +{ + QButtonGroup *group = this->findChild(); + if(group) + { + if(group->checkedButton()) + { + return group->id(group->checkedButton()); + } + } + return 0; +} + +void CSecondButtonGroupWidget::setCheckedButton(int index) +{ + QList buttonList = this->findChildren(); + if(index < buttonList.length()) + { + buttonList[index]->setChecked(true); + } + else if(buttonList.length() > 0) + { + buttonList[0]->setChecked(true); + } +} + +void CSecondButtonGroupWidget::slotButtonClicked() +{ + QString obj = sender()->objectName(); + ST_BUTTON stButton = m_pJsonReader->getStButton(obj); + switch (stButton.type) + { + case SWITCH_GRAPH: + { + emit onGraphClicked(stButton.name, stButton.data); + break; + } + case SWITCH_NAV: + { + stButton.data.replace("2", "0"); + emit onNavigationClicked(stButton.name, stButton.data); + break; + } + case EXTERN_PRO: + { + emit onExternClicked(stButton.name, stButton.data); + break; + } + default: + break; + } +} + +void CSecondButtonGroupWidget::initView() +{ + m_pJsonReader = new CJsonReader(this); + QMap buttonMap = m_pJsonReader->getButtonMap(); + QString separator = m_pJsonReader->getSeparatorPath(); + if(buttonMap.isEmpty()) + { + QGridLayout *layout = new QGridLayout(this); + layout->addWidget(new QPushButton(tr("配置错误!"))); + setLayout(layout); + return; + } + + std::string currentPath = iot_public::CFileUtil::getCurModuleDir(); + QDir dir(QString::fromStdString(currentPath)); + dir.cdUp(); + dir.cdUp(); + dir.cd("data"); + dir.cd("back_pixmap"); + + QButtonGroup *buttonGroup = new QButtonGroup(this); + int id = 0; + QMap::const_iterator iter + = buttonMap.constBegin(); + + int btnWidth= m_pJsonReader->getBtnWidth()>0?m_pJsonReader->getBtnWidth():195; + int btnHeight= m_pJsonReader->getBtnHeight()>0?m_pJsonReader->getBtnHeight():45; + int baseX=m_pJsonReader->getBaseX()>0?m_pJsonReader->getBaseX():160; + + for(; iter != buttonMap.constEnd(); iter++) + { + if(iter.value().used == 2) + { + continue; + } + QPushButton *button = new QPushButton(QIcon(dir.absoluteFilePath(iter.value().icon)), iter.value().name,this); + button->setObjectName(iter.key()); + button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + button->setCheckable(true); + buttonGroup->addButton(button, id++); + if(!m_isEdit) + { + connect(button, &QPushButton::clicked, this, &CSecondButtonGroupWidget::slotButtonClicked); + } + + button->setGeometry((id-1)*baseX, 5, btnWidth, btnHeight); + } + +} + +void CSecondButtonGroupWidget::initQss() +{ + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("SecondButtonGroupWidget.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} diff --git a/product/src/gui/plugin/SecondButtonGroupWidget/CSecondButtonGroupWidget.h b/product/src/gui/plugin/SecondButtonGroupWidget/CSecondButtonGroupWidget.h new file mode 100644 index 00000000..ae213423 --- /dev/null +++ b/product/src/gui/plugin/SecondButtonGroupWidget/CSecondButtonGroupWidget.h @@ -0,0 +1,62 @@ +#ifndef CBUTTONGROUPWIDGET_H +#define CBUTTONGROUPWIDGET_H + +#include + +class CJsonReader; +class CSecondButtonGroupWidget : public QWidget +{ + Q_OBJECT + +public: + enum EN_BUTTON_TYPE + { + NONE = 0, //< 无操作 + SWITCH_GRAPH, //< 切换画面 + SWITCH_NAV, //< 切换导航 + EXTERN_PRO, //< 调用程序 + }; + + CSecondButtonGroupWidget(QWidget *parent = 0, bool editMode = true); + ~CSecondButtonGroupWidget(); + +public slots: + void onButtonClicked(int index = 0); + int getCheckedButton(); + void setCheckedButton(int index = 0); + +signals: + /** + * @brief onNavigationClicked + * @param objName 按钮名称 + * @param naviNode 导航栏显示节点 “1,1,1,1,0,1,0,1” + */ + void onNavigationClicked(QString objName, QString naviNode); + + /** + * @brief onGraphClicked + * @param objName 按钮名称 + * @param graph 画面名称 “主接线图.glx” + */ + void onGraphClicked(QString objName, QString graph); + + /** + * @brief onExternClicked + * @param objName 按钮名称 + * @param program 执行程序 “sys_starup” + */ + void onExternClicked(QString objName, QString program); + +private slots: + void slotButtonClicked(); + +private: + void initView(); + void initQss(); +private: + CJsonReader *m_pJsonReader; + bool m_isEdit; + +}; + +#endif // CBUTTONGROUPWIDGET_H diff --git a/product/src/gui/plugin/SecondButtonGroupWidget/SecondButtonGroupWidget.pro b/product/src/gui/plugin/SecondButtonGroupWidget/SecondButtonGroupWidget.pro new file mode 100644 index 00000000..127e9d5e --- /dev/null +++ b/product/src/gui/plugin/SecondButtonGroupWidget/SecondButtonGroupWidget.pro @@ -0,0 +1,52 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2021-07-02T15:52:44 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = SecondButtonGroupWidget +TEMPLATE = lib + +CONFIG += plugin + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ +# main.cpp \ + CJsonReader.cpp \ + CSecondButtonGroupPluginWidget.cpp \ + CSecondButtonGroupWidget.cpp \ + CButton.cpp + +HEADERS += \ + CJsonReader.h \ + CSecondButtonGroupPluginWidget.h \ + CSecondButtonGroupWidget.h \ + CButton.h + +LIBS += \ + -llog4cplus \ + -lpub_logger_api \ + -lpub_utility_api + + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/SecondButtonGroupWidget/main.cpp b/product/src/gui/plugin/SecondButtonGroupWidget/main.cpp new file mode 100644 index 00000000..fdd5fd9a --- /dev/null +++ b/product/src/gui/plugin/SecondButtonGroupWidget/main.cpp @@ -0,0 +1,11 @@ +#include "CButtonGroupWidget.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CButtonGroupWidget w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/SecondNavigationWidget/CColorLabel.cpp b/product/src/gui/plugin/SecondNavigationWidget/CColorLabel.cpp new file mode 100644 index 00000000..392f0a14 --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/CColorLabel.cpp @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include "CColorLabel.h" + +CColorLabel::CColorLabel(QWidget *parent) + : QLabel(parent) +{ + color = Qt::transparent; +} + +const QColor CColorLabel::getColor() const +{ + return color; +} + +void CColorLabel::setColor(const QColor &color) +{ + this->color = color; +} + +void CColorLabel::paintEvent(QPaintEvent *pEvent) +{ + Q_UNUSED(pEvent) + QPainter painter(this); + painter.setPen(Qt::darkGray); + painter.drawRect(rect().adjusted(0, 0, -1, -1)); + + painter.setPen(Qt::white); + painter.setBrush(color); + painter.drawRect(rect().adjusted(1, 1, -2, -2)); +} + +void CColorLabel::mousePressEvent(QMouseEvent *pEvent) +{ + QLabel::mousePressEvent(pEvent); + showColorPickDialog(); +} + +void CColorLabel::showColorPickDialog() +{ + QColor c = QColorDialog::getColor(color, this, QString()); + if(c.isValid()) + { + color = c; + emit colorChanged(color); + } +} diff --git a/product/src/gui/plugin/SecondNavigationWidget/CColorLabel.h b/product/src/gui/plugin/SecondNavigationWidget/CColorLabel.h new file mode 100644 index 00000000..ccbb92e3 --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/CColorLabel.h @@ -0,0 +1,29 @@ +#ifndef CCOLORLABEL_H +#define CCOLORLABEL_H + +#include + +class CColorLabel : public QLabel +{ + Q_OBJECT +public: + explicit CColorLabel(QWidget *parent = nullptr); + + const QColor getColor() const; + void setColor(const QColor &color); + +signals: + void colorChanged(const QColor &color); + +protected: + void paintEvent(QPaintEvent *pEvent); + void mousePressEvent(QMouseEvent *pEvent); + +private: + void showColorPickDialog(); + +private: + QColor color; +}; + +#endif // CCOLORLABEL_H diff --git a/product/src/gui/plugin/SecondNavigationWidget/CNavigationConfigDialog.cpp b/product/src/gui/plugin/SecondNavigationWidget/CNavigationConfigDialog.cpp new file mode 100644 index 00000000..c8670436 --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/CNavigationConfigDialog.cpp @@ -0,0 +1,433 @@ +#include +#include "CNavigationConfigDialog.h" +#include "CSecondNavigationWidget.h" +#include "CColorLabel.h" +#include "ui_NavigationConfigDialog.h" +#include "public/pub_utility_api/FileUtil.h" + +CNavigationConfigDialog::CNavigationConfigDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::NavigationConfigDialog), + m_itemIndex(0) +{ + ui->setupUi(this); + initialize(); +} + +CNavigationConfigDialog::~CNavigationConfigDialog() +{ + delete ui; +} + +void CNavigationConfigDialog::initialize() +{ + ui->navigationWidget->setNavigationMode(CSecondNavigationWidget::CONFIG_MODE); + + QMap nodeMap; + ui->navigationWidget->getNodeTypeMap(nodeMap); + QMap::const_iterator iter = nodeMap.constBegin(); + for(; iter != nodeMap.constEnd(); iter++) + { + ui->itemOptTypeComb->addItem(iter.value(), iter.key()); + } + + auto sigValueChanged = static_cast(&QSpinBox::valueChanged); + + //< initialize color + ui->navigationBgColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->backgroundColor)); + connect(ui->navigationBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateNavigationWidgetColor); + + ui->itemTopLevelBgColor->setColor(QColor::fromRgba(std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::TOP_LEVEL]))); + connect(ui->itemTopLevelBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemTopLevelBgColor); + + ui->itemTopLevelTextColor->setColor(QColor::fromRgba(std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::TOP_LEVEL]))); + connect(ui->itemTopLevelTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemTopLevelTextColor); + + ui->itemTopLevelIndentation->setValue(std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::TOP_LEVEL])); + connect(ui->itemTopLevelIndentation, sigValueChanged, this, &CNavigationConfigDialog::updateItemTopLevelIndentation); + + ui->itemChildLevelBgColor->setColor(QColor::fromRgba(std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::CHILD_LEVEL]))); + connect(ui->itemChildLevelBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemChildLevelBgColor); + + ui->itemChildLevelTextColor->setColor(QColor::fromRgba(std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::CHILD_LEVEL]))); + connect(ui->itemChildLevelTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemChildLevelTextColor); + + ui->itemChildLevelIndentation->setValue(std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::CHILD_LEVEL])); + connect(ui->itemChildLevelIndentation, sigValueChanged, this, &CNavigationConfigDialog::updateItemChildLevelIndentation); + + ui->itemLeafLevelBgColor->setColor(QColor::fromRgba(std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::LEAF_LEVEL]))); + connect(ui->itemLeafLevelBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemLeafLevelBgColor); + + ui->itemLeafLevelTextColor->setColor(QColor::fromRgba(std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::LEAF_LEVEL]))); + connect(ui->itemLeafLevelTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemLeafLevelTextColor); + + ui->itemLeafLevelIndentation->setValue(std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::LEAF_LEVEL])); + connect(ui->itemLeafLevelIndentation, sigValueChanged, this, &CNavigationConfigDialog::updateItemLeafLevelIndentation); + + ui->itemFocusBgColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->itemSelectedColor)); + connect(ui->itemFocusBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemFocusBgColor); + + ui->itemFocusTextColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->itemSelectedTextColor)); + connect(ui->itemFocusTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemFocusTextColor); + + ui->itemHoverBgColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->itemHoveredColor)); + connect(ui->itemHoverBgColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemHoverBgColor); + + ui->itemHoverTextColor->setColor(QColor::fromRgba(ui->navigationWidget->m_pItemProxy->itemHoveredTextColor)); + connect(ui->itemHoverTextColor, &CColorLabel::colorChanged, this, &CNavigationConfigDialog::updateItemHoverTextColor); + + connect(ui->itemIconPathButton, &QPushButton::clicked, this, &CNavigationConfigDialog::updateItemIconPath); + connect(ui->itemIconPathEditor, &QLineEdit::textChanged, this, &CNavigationConfigDialog::updateItemIconPathManual); + + connect(ui->itemDataPathButton, &QPushButton::clicked, this, &CNavigationConfigDialog::updateItemDataPath); + connect(ui->itemDataPathEditor, &QLineEdit::textChanged, this, &CNavigationConfigDialog::updateItemDataPathManual); + + connect(ui->itemEnableBox, &QCheckBox::toggled, this, &CNavigationConfigDialog::updateItemEnable); + connect(ui->itemWebBox, &QCheckBox::toggled, this, &CNavigationConfigDialog::updateItemWeb); + connect(ui->itemOptTypeComb, &QComboBox::currentTextChanged, this, &CNavigationConfigDialog::updateItemOptType); + + connect(ui->insertItemButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onInsertTopLevelItem); + connect(ui->insertChildButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onInsertChildItem); + connect(ui->insertLevelItemButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onInsertLevelItem); + connect(ui->removeItemButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onRemoveLevelItem); + connect(ui->importBtn, &QPushButton::clicked, this, &CNavigationConfigDialog::onImport); + connect(ui->exportBtn, &QPushButton::clicked, this, &CNavigationConfigDialog::onExport); + connect(ui->clearButton, &QPushButton::clicked, this, &CNavigationConfigDialog::onClearItem); + + connect(ui->navigationWidget, &CSecondNavigationWidget::itemSelectionChanged, this, &CNavigationConfigDialog::updateButtonState); + + ui->iconFrame->setEnabled(false); + ui->clearButton->setEnabled(false); + ui->removeItemButton->setEnabled(false); + ui->insertChildButton->setEnabled(false); + ui->insertLevelItemButton->setEnabled(false); + + onClearItem(); +} + +const CSecondNavigationWidget *CNavigationConfigDialog::NavigationWidegt() const +{ + return ui->navigationWidget; +} + +void CNavigationConfigDialog::updateItems(const CSecondNavigationWidget *pNavigation) +{ + ui->navigationWidget->updateItems(pNavigation); + for(int nIndex(0); nIndex < pNavigation->topLevelItemCount(); nIndex++) + { + m_itemIndex++; + QTreeWidgetItem * item = pNavigation->topLevelItem(nIndex); + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + m_itemIndex++; + QTreeWidgetItem * childItem = item->child(nChildIndex); + for(int nLeafIndex(0); nLeafIndex < childItem->childCount(); nLeafIndex++) + { + m_itemIndex++; + } + } + } + updateButtonState(); +} + +void CNavigationConfigDialog::updateNavigationWidgetColor(const QColor &color) +{ + ui->navigationWidget->m_pItemProxy->backgroundColor = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemTopLevelBgColor(const QColor &color) +{ + std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::TOP_LEVEL]) = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemTopLevelTextColor(const QColor &color) +{ + std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::TOP_LEVEL]) = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemTopLevelIndentation(const int &indentation) +{ + std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::TOP_LEVEL]) = indentation; + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemChildLevelBgColor(const QColor &color) +{ + std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::CHILD_LEVEL]) = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemChildLevelTextColor(const QColor &color) +{ + std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::CHILD_LEVEL]) = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemChildLevelIndentation(const int &indentation) +{ + std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::CHILD_LEVEL]) = indentation; + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemLeafLevelBgColor(const QColor &color) +{ + std::get<0>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::LEAF_LEVEL]) = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemLeafLevelTextColor(const QColor &color) +{ + std::get<1>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::LEAF_LEVEL]) = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemLeafLevelIndentation(const int &indentation) +{ + std::get<4>(ui->navigationWidget->m_pItemProxy->vecItemStyle[CSecondNavigationWidget::LEAF_LEVEL]) = indentation; + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemFocusBgColor(const QColor &color) +{ + ui->navigationWidget->m_pItemProxy->itemSelectedColor = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemFocusTextColor(const QColor &color) +{ + ui->navigationWidget->m_pItemProxy->itemSelectedTextColor = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemHoverBgColor(const QColor &color) +{ + ui->navigationWidget->m_pItemProxy->itemHoveredColor = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemHoverTextColor(const QColor &color) +{ + ui->navigationWidget->m_pItemProxy->itemHoveredTextColor = color.rgba(); + updateNavigationWidget(); +} + +void CNavigationConfigDialog::updateItemIconPath() +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + std::string defaultPath = iot_public::CFileUtil::getCurModuleDir(); + QString strIconFilePath = QString::fromStdString(defaultPath) + QString("..%1..%1data%1back_pixmap%1").arg(QDir::separator()); + QString strFileName = QFileDialog::getOpenFileName(this, tr("打开"), strIconFilePath, "*.jpg; *.png"); + if(strFileName.isEmpty()) + { + return; + } + ui->itemIconPathEditor->setText(strFileName); + item->setData(0, IconPath_Role, strFileName); + item->setIcon(0, QIcon(strFileName)); + } +} + +void CNavigationConfigDialog::updateItemIconPathManual() +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + item->setData(0, IconPath_Role, ui->itemIconPathEditor->text()); + item->setIcon(0, QIcon(ui->itemIconPathEditor->text())); + } +} + +void CNavigationConfigDialog::updateItemDataPath() +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + QString strGraphFilePath = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()); + QString filter = ""; + if(ui->itemOptTypeComb->currentData().toInt() == CSecondNavigationWidget::SWITCH_GRAPH) + { + strGraphFilePath += QString("..%1..%1data%1pic%1").arg(QDir::separator()); + filter = "*.glx"; + } + QString strFileName = QFileDialog::getOpenFileName(this, tr("打开"), strGraphFilePath, filter); + if(strFileName.isEmpty()) + { + return; + } + if(strFileName.right(4) == ".exe") + strFileName.remove(-4, 4); + //QDir dir(strGraphFilePath); + ui->itemDataPathEditor->setText(strFileName); + item->setData(0, Qt::UserRole, strFileName); + } +} + +void CNavigationConfigDialog::updateItemDataPathManual() +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + item->setData(0, Qt::UserRole, ui->itemDataPathEditor->text()); + } +} + +void CNavigationConfigDialog::updateItemEnable(bool checked) +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + item->setData(0, Enable_Role, checked ? CSecondNavigationWidget::Enable : CSecondNavigationWidget::Disable); + } +} + +void CNavigationConfigDialog::updateItemWeb(bool checked) +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + item->setData(0, Web_Role, checked ? CSecondNavigationWidget::Enable : CSecondNavigationWidget::Disable); + } +} + +void CNavigationConfigDialog::updateItemOptType(const QString &text) +{ + Q_UNUSED(text) + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + item->setData(0, Opt_Role, ui->itemOptTypeComb->currentData().toInt()); + } +} + +void CNavigationConfigDialog::onInsertTopLevelItem() +{ + ui->navigationWidget->addTopLevelItem(m_itemIndex, tr("新建项目_") + QString::number(m_itemIndex)); + m_itemIndex++; +} + +void CNavigationConfigDialog::onInsertChildItem() +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + QList parents; + if(CSecondNavigationWidget::TOP_LEVEL == item->data(0, Level_Role).toInt()) + { + parents << item->data(0, Item_Role).toInt(); + } + else if(CSecondNavigationWidget::CHILD_LEVEL == item->data(0, Level_Role).toInt()) + { + parents << item->parent()->data(0, Item_Role).toInt(); + parents << item->data(0, Item_Role).toInt(); + } + else + { + return; + } + + ui->navigationWidget->addChildItem(m_itemIndex, parents, tr("新建项目_") + QString::number(m_itemIndex)); + m_itemIndex++; + item->setExpanded(true); + } +} + +void CNavigationConfigDialog::onInsertLevelItem() +{ + QTreeWidgetItem * item = ui->navigationWidget->currentItem(); + if(item) + { + QList parents; + if(CSecondNavigationWidget::TOP_LEVEL == item->data(0, Level_Role).toInt()) + { + parents << item->data(0, Item_Role).toInt(); + } + else if(CSecondNavigationWidget::CHILD_LEVEL == item->data(0, Level_Role).toInt()) + { + parents << item->parent()->data(0, Item_Role).toInt(); + parents << item->data(0, Item_Role).toInt(); + } + else if(CSecondNavigationWidget::LEAF_LEVEL == item->data(0, Level_Role).toInt()) + { + parents << item->parent()->parent()->data(0, Item_Role).toInt(); + parents << item->parent()->data(0, Item_Role).toInt(); + parents << item->data(0, Item_Role).toInt(); + } + else + { + return; + } + + ui->navigationWidget->addLevelItem(m_itemIndex, parents, tr("新建项目_") + QString::number(m_itemIndex)); + m_itemIndex++; + } +} + +void CNavigationConfigDialog::onRemoveLevelItem() +{ + if(ui->navigationWidget->currentItem()) + { + ui->navigationWidget->removeItem(ui->navigationWidget->currentItem()); + updateButtonState(); + } +} + +void CNavigationConfigDialog::onImport() +{ + int row = ui->navigationWidget->slotImport(); + if(row != -1) + { + m_itemIndex = row; + } +} + +void CNavigationConfigDialog::onExport() +{ + ui->navigationWidget->slotExport(); +} + +void CNavigationConfigDialog::onClearItem() +{ + ui->navigationWidget->clearItems(); + updateButtonState(); + m_itemIndex = 0; +} + + +void CNavigationConfigDialog::updateButtonState() +{ + QTreeWidgetItem * current = ui->navigationWidget->currentItem(); + ui->insertChildButton->setEnabled(Q_NULLPTR != current); + ui->insertLevelItemButton->setEnabled(Q_NULLPTR != current); + ui->removeItemButton->setEnabled(Q_NULLPTR != current); + ui->clearButton->setEnabled(ui->navigationWidget->topLevelItemCount()); + ui->iconFrame->setEnabled(Q_NULLPTR != current); + if(Q_NULLPTR != current) + { + CSecondNavigationWidget::Node_Level level = (CSecondNavigationWidget::Node_Level)ui->navigationWidget->currentItem()->data(0, Level_Role).toInt(); + ui->insertChildButton->setEnabled(CSecondNavigationWidget::LEAF_LEVEL != level); + ui->itemIconPathEditor->setText(current->data(0, IconPath_Role).toString()); + ui->itemDataPathEditor->setText(current->data(0, Qt::UserRole).toString()); + ui->itemEnableBox->setChecked(current->data(0, Enable_Role).toInt() == CSecondNavigationWidget::Enable? true:false); + ui->itemWebBox->setChecked(current->data(0, Web_Role).toInt() == CSecondNavigationWidget::Enable? true:false); + ui->itemOptTypeComb->setCurrentIndex(ui->itemOptTypeComb->findData(current->data(0, Opt_Role).toInt())); + } + else + { + ui->itemIconPathEditor->setText(""); + ui->itemDataPathEditor->setText(""); + ui->itemEnableBox->setChecked(false); + ui->itemWebBox->setChecked(false); + ui->itemOptTypeComb->setCurrentIndex(0); + } +} + +void CNavigationConfigDialog::updateNavigationWidget() +{ + ui->navigationWidget->setFocus(); + ui->navigationWidget->update(); +} diff --git a/product/src/gui/plugin/SecondNavigationWidget/CNavigationConfigDialog.h b/product/src/gui/plugin/SecondNavigationWidget/CNavigationConfigDialog.h new file mode 100644 index 00000000..4f016041 --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/CNavigationConfigDialog.h @@ -0,0 +1,75 @@ +#ifndef CNAVIGATIONCONFIGDIALOG_H +#define CNAVIGATIONCONFIGDIALOG_H + +#include + +namespace Ui { +class NavigationConfigDialog; +} + +class CSecondNavigationWidget; + +class CNavigationConfigDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CNavigationConfigDialog(QWidget *parent = 0); + ~CNavigationConfigDialog(); + + void initialize(); + + const CSecondNavigationWidget * NavigationWidegt() const; + + void updateItems(const CSecondNavigationWidget *pNavigation); + +private: + void updateNavigationWidgetColor(const QColor &color); + + void updateItemTopLevelBgColor(const QColor &color); + void updateItemTopLevelTextColor(const QColor &color); + void updateItemTopLevelIndentation(const int &indentation); + + void updateItemChildLevelBgColor(const QColor &color); + void updateItemChildLevelTextColor(const QColor &color); + void updateItemChildLevelIndentation(const int &indentation); + + void updateItemLeafLevelBgColor(const QColor &color); + void updateItemLeafLevelTextColor(const QColor &color); + void updateItemLeafLevelIndentation(const int &indentation); + + void updateItemFocusBgColor(const QColor &color); + void updateItemFocusTextColor(const QColor &color); + + void updateItemHoverBgColor(const QColor &color); + void updateItemHoverTextColor(const QColor &color); + + void updateItemIconPath(); + void updateItemIconPathManual(); + + void updateItemDataPath(); + void updateItemDataPathManual(); + + void updateItemEnable(bool checked); + void updateItemWeb(bool checked); + void updateItemOptType(const QString &text); + + void onInsertTopLevelItem(); + void onInsertChildItem(); + void onInsertLevelItem(); + void onRemoveLevelItem(); + void onImport(); + void onExport(); + void onClearItem(); + + void updateButtonState(); + + void updateNavigationWidget(); + +private: + Ui::NavigationConfigDialog *ui; + + int m_itemIndex; +}; + +#endif // CNAVIGATIONCONFIGDIALOG_H diff --git a/product/src/gui/plugin/SecondNavigationWidget/CNavigationDelegate.cpp b/product/src/gui/plugin/SecondNavigationWidget/CNavigationDelegate.cpp new file mode 100644 index 00000000..fddf6c5e --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/CNavigationDelegate.cpp @@ -0,0 +1,209 @@ +#include "CNavigationDelegate.h" +#include "CSecondNavigationWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include + +CNavigationDelegate::CNavigationDelegate(ITEM_STYLE_PROXY *proxy, QObject *parent) + : QStyledItemDelegate(parent), + m_pTreeView(Q_NULLPTR), + m_pixmapWidth(16), + m_pixmapHeight(16), + m_rowHeight(36), + m_currentHoverIndex(QModelIndex()), + m_pItemProxy(proxy) +{ + m_strExpandIconName = QString("://image/arrowExpand.png"); + m_strCollapseIconName = QString("://image/arrowCollapse.png"); + m_strExpandIconHoverName = QString("://image/arrowExpandHover.png"); + m_strCollapseIconHoverName = QString("://image/arrowCollapseHover.png"); +} + +CNavigationDelegate::~CNavigationDelegate() +{ + +} + +void CNavigationDelegate::setView(QTreeView *pTreeView) +{ + m_pTreeView = pTreeView; +} + +void CNavigationDelegate::setBranchIconSize(const QSize &size) +{ + m_pixmapHeight = size.height(); + m_pixmapWidth = size.width(); +} + +void CNavigationDelegate::setExpandIcon(const QString &iconName) +{ + m_strExpandIconName = iconName; +} + +void CNavigationDelegate::setCollapseIcon(const QString &iconName) +{ + m_strCollapseIconName = iconName; +} + +QWidget *CNavigationDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option) + if(!index.isValid()) + { + return Q_NULLPTR; + } + QTreeWidgetItem * item = reinterpret_cast(index.internalPointer()); + if(item) + { + if(0 == index.column()) + { + QLineEdit * pLineEdit = new QLineEdit(parent); + pLineEdit->setText(item->text(0)); + return pLineEdit; + } + } + return Q_NULLPTR; +} + +void CNavigationDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + int level = index.data(Level_Role).toInt(); + int delta = m_pItemProxy->indicatorWidth + m_pItemProxy->iconMargin * 2 + std::get<3>(m_pItemProxy->vecItemStyle[CSecondNavigationWidget::TOP_LEVEL]) + std::get<4>(m_pItemProxy->vecItemStyle[level]); + QRect rt = editor->geometry(); + rt.setLeft(delta); + editor->setGeometry(std::move(rt)); + return; +} + +//void CNavigationDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +//{ +// QStyleOptionViewItem viewOption(option); +// if (viewOption.state & QStyle::State_HasFocus) +// { +// viewOption.state = viewOption.state ^ QStyle::State_HasFocus; +// } + +// if(!index.isValid()) +// { +// if (m_pTreeView) +// { +// painter->fillRect(m_pTreeView->rect(), QColor::fromRgba(m_pItemProxy->backgroundColor)); +// } +// return; +// } +// drawItem(painter, viewOption, index); + +// bool bExpanded = false; +// if (m_pTreeView != NULL) +// { +// const QAbstractItemModel *model = index.model(); +// if (!model->hasChildren(index)) +// { +// return; +// } +// bExpanded = m_pTreeView->isExpanded(index); +// } + +// int height = (viewOption.rect.height() - m_pixmapWidth) / 2; +// QPixmap pixmap; +// if(index == m_currentHoverIndex) +// { +// pixmap = bExpanded ? QPixmap(m_strExpandIconHoverName) : QPixmap(m_strCollapseIconHoverName); +// } +// else +// { +// pixmap = bExpanded ? QPixmap(m_strExpandIconName) : QPixmap(m_strCollapseIconName); +// } +// QRect decorationRect = QRect(viewOption.rect.left() + viewOption.rect.width() - ((m_rowHeight + m_pixmapWidth) / 2), viewOption.rect.top() + height, m_pixmapWidth, m_pixmapHeight); +// painter->drawPixmap(decorationRect, pixmap); +//} + +bool CNavigationDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ +// int height = (option.rect.height() - m_pixmapWidth) / 2; +// QRect decorationRect = QRect(option.rect.left() + option.rect.width() - ((m_rowHeight + m_pixmapWidth) / 2), option.rect.top() + height, m_pixmapWidth, m_pixmapHeight); + + QMouseEvent * pEvent = dynamic_cast(event); + if (pEvent) + { + if(m_currentHoverIndex != index) + { + m_currentHoverIndex = index; + return true; + } + + if (pEvent->button() == Qt::LeftButton && event->type() == QEvent::MouseButtonPress) + { + m_pTreeView->setExpanded(index, !m_pTreeView->isExpanded(index)); + } + } + else + { + m_currentHoverIndex = QModelIndex(); + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +QSize CNavigationDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QSize size = QStyledItemDelegate::sizeHint(option, index); + return QSize(size.width(), m_rowHeight); +} + +void CNavigationDelegate::drawItem(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, true); + QTextOption textOpiton; + textOpiton.setAlignment(option.displayAlignment); + + QRect rt(m_pTreeView->rect().left(), option.rect.top(), m_pTreeView->rect().width(), option.rect.height()); + + int level = index.data(Level_Role).toInt(); + + QPen pen(QColor::fromRgba(std::get<1>(m_pItemProxy->vecItemStyle[level]))); + QBrush brush(QColor::fromRgba(std::get<0>(m_pItemProxy->vecItemStyle[level]))); + if (option.state & QStyle::State_MouseOver) + { + pen.setColor(QColor::fromRgba(m_pItemProxy->itemHoveredTextColor)); + brush.setColor(QColor::fromRgba(m_pItemProxy->itemHoveredColor)); + } + if (option.state & QStyle::State_Selected) + { + pen.setColor(QColor::fromRgba(m_pItemProxy->itemSelectedTextColor)); + brush.setColor(QColor::fromRgba(m_pItemProxy->itemSelectedColor)); + } + painter->fillRect(rt, std::move(brush)); + + + int delta = m_pItemProxy->indicatorWidth + m_pItemProxy->iconMargin + std::get<4>(m_pItemProxy->vecItemStyle[level]); + + //< draw Icon + int iconSize = std::get<3>(m_pItemProxy->vecItemStyle[level]); + QTreeWidgetItem * item = reinterpret_cast(index.internalPointer()); + if(item) + { + QPixmap pixmap = item->icon(0).pixmap(iconSize, iconSize); + if(!pixmap.isNull()) + { + QRect iconRect(delta + level, option.rect.top() + (option.rect.height() - iconSize) / 2., iconSize, iconSize); + painter->drawPixmap(iconRect, pixmap); + } + } + + //< draw Text + delta += std::get<3>(m_pItemProxy->vecItemStyle[CSecondNavigationWidget::TOP_LEVEL]); + delta += m_pItemProxy->iconMargin; + rt.adjust(delta, 0, 0, 0); + painter->setPen(std::move(pen)); + QFont font = option.font; + font.setPixelSize(std::get<2>(m_pItemProxy->vecItemStyle[level])); + painter->setFont(std::move(font)); + painter->drawText(rt, index.data().toString(), textOpiton); + painter->restore(); +} diff --git a/product/src/gui/plugin/SecondNavigationWidget/CNavigationDelegate.h b/product/src/gui/plugin/SecondNavigationWidget/CNavigationDelegate.h new file mode 100644 index 00000000..1d5ba541 --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/CNavigationDelegate.h @@ -0,0 +1,56 @@ +#ifndef CNAVIGATIONDELEGATE_H +#define CNAVIGATIONDELEGATE_H + +#include +#include + +struct ITEM_STYLE_PROXY; + +class CNavigationDelegate : public QStyledItemDelegate +{ + Q_OBJECT + + friend class CSecondNavigationWidget; + +public: + CNavigationDelegate(ITEM_STYLE_PROXY * proxy, QObject *parent = Q_NULLPTR); + + virtual ~CNavigationDelegate(); + + void setView(QTreeView *pTreeView); + + void setBranchIconSize(const QSize &size); + + void setExpandIcon(const QString &iconName); + void setCollapseIcon(const QString &iconName); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; + + void setEditorData(QWidget *editor, const QModelIndex &index) const; + + //void paint(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const Q_DECL_OVERRIDE; + + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) Q_DECL_OVERRIDE; + + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; + +protected: + void drawItem(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const; + +private: + QTreeView * m_pTreeView; + + int m_pixmapWidth; + int m_pixmapHeight; + int m_rowHeight; + + QModelIndex m_currentHoverIndex; + QString m_strExpandIconName; + QString m_strCollapseIconName; + QString m_strExpandIconHoverName; + QString m_strCollapseIconHoverName; + + ITEM_STYLE_PROXY * m_pItemProxy; +}; + +#endif // CNAVIGATIONDELEGATE_H diff --git a/product/src/gui/plugin/SecondNavigationWidget/CSecondNavigationPluginWidget.cpp b/product/src/gui/plugin/SecondNavigationWidget/CSecondNavigationPluginWidget.cpp new file mode 100644 index 00000000..dc46180d --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/CSecondNavigationPluginWidget.cpp @@ -0,0 +1,27 @@ +#include +#include "CSecondNavigationPluginWidget.h" +#include "CSecondNavigationWidget.h" + +CSecondNavigationPluginWidget::CSecondNavigationPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CSecondNavigationPluginWidget::~CSecondNavigationPluginWidget() +{ + +} + +bool CSecondNavigationPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec) +{ + Q_UNUSED(ptrVec) + CSecondNavigationWidget *pWidget = new CSecondNavigationWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pNavigationWidget = (IPluginWidget *)pWidget; + return true; +} + +void CSecondNavigationPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/SecondNavigationWidget/CSecondNavigationPluginWidget.h b/product/src/gui/plugin/SecondNavigationWidget/CSecondNavigationPluginWidget.h new file mode 100644 index 00000000..4d15334b --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/CSecondNavigationPluginWidget.h @@ -0,0 +1,22 @@ +#ifndef CNAVIGATIONPLUGINWIDGET_H +#define CNAVIGATIONPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< RQEH6000_HOME/platform/src/include/gui/GraphShape + +class CSecondNavigationPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) + Q_INTERFACES(CPluginWidgetInterface) + +public: + CSecondNavigationPluginWidget(QObject *parent = 0); + ~CSecondNavigationPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pNavigationWidget, QVector ptrVec); + void release(); +}; + +#endif //CNAVIGATIONPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/SecondNavigationWidget/CSecondNavigationWidget.cpp b/product/src/gui/plugin/SecondNavigationWidget/CSecondNavigationWidget.cpp new file mode 100644 index 00000000..b7c01af8 --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/CSecondNavigationWidget.cpp @@ -0,0 +1,1241 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CSecondNavigationWidget.h" +#include "CNavigationDelegate.h" +#include "CNavigationConfigDialog.h" +#include "public/pub_utility_api/FileUtil.h" +#include "public/pub_utility_api/FileStyle.h" +#include "pub_excel/xlsx/xlsxdocument.h" + +const int Level_Role = Qt::UserRole + 1; +const int Corner_Role = Qt::UserRole + 2; +const int IconPath_Role = Qt::UserRole + 3; +const int Item_Role = Qt::UserRole + 4; +const int Enable_Role = Qt::UserRole + 5; +const int Web_Role = Qt::UserRole + 6; +const int Opt_Role = Qt::UserRole + 7; +const int Url_Role = Qt::UserRole + 8; + +CSecondNavigationWidget::CSecondNavigationWidget(QWidget *parent, bool editMode) + : QTreeWidget(parent), + m_pItemProxy(Q_NULLPTR), + m_pItemDelegate(Q_NULLPTR), + m_navigationMode(EXPLORER_MODE) +{ + if(editMode) + { + m_navigationMode = EDIT_MODE; + } + initialize(); +} + +CSecondNavigationWidget::~CSecondNavigationWidget() +{ + if(m_pItemProxy) + { + delete m_pItemProxy; + } + m_pItemProxy = Q_NULLPTR; +} + +void CSecondNavigationWidget::initialize() +{ + initStyle(); + + //setStyleSheet("background-color:transparent;QLineEdit:edit-focus{background-color:white}"); + setMouseTracking(true); + setRootIsDecorated(false); + header()->setVisible(false); + connect(this, &CSecondNavigationWidget::currentItemChanged, this, &CSecondNavigationWidget::itemSelectedChanged); + connect(this, &CSecondNavigationWidget::itemClicked, this, &CSecondNavigationWidget::itemSelected); + + std::string currentPath = iot_public::CFileUtil::getCurModuleDir(); + m_strFileHomePath = QString::fromStdString(currentPath) + QString("..%1..%1data%1").arg(QDir::separator()); + m_mapEnable.insert(Enable, tr("是")); + m_mapEnable.insert(Disable, tr("否")); + m_mapNodeType.insert(SWITCH_GRAPH, tr("切换画面")); + m_mapNodeType.insert(EXTERN_PRO, tr("调用程序")); + + initStyleProxy(); + loadItemDelegate(); + + QString strItemConfigFile = m_strFileHomePath + QString("model%1NavigationWidget.json").arg(QDir::separator()); + read(strItemConfigFile); + if(EDIT_MODE != m_navigationMode) + { + expandAll(); + } +} + +void CSecondNavigationWidget::initStyle() +{ + QString sQss = QString(); + std::string sFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile objFile0(QString::fromStdString(sFullPath)); + objFile0.open(QFile::ReadOnly); + if ( objFile0.isOpen() ) + { + sQss += QLatin1String(objFile0.readAll()); + objFile0.close(); + } + else + { + qDebug() << "public.qss 无法打开!"; + } + + sFullPath = iot_public::CFileStyle::getPathOfStyleFile("secondNavigation.qss") ; + QFile objFile1(QString::fromStdString(sFullPath)); + objFile1.open(QFile::ReadOnly); + if (objFile1.isOpen()) + { + sQss += QLatin1String(objFile1.readAll()); + QString test=QLatin1String(objFile1.readAll()); + objFile1.close(); + } + else + { + qDebug() << "navigation.qss 无法打开!"; + } + + if ( !sQss.isEmpty() ) + { + this->setStyleSheet(sQss); + } +} + +void CSecondNavigationWidget::setNavigationMode(const CSecondNavigationWidget::Navigation_Mode &navigationMode) +{ + m_navigationMode = navigationMode; + if(CONFIG_MODE == m_navigationMode) + { + connect(this, &CSecondNavigationWidget::itemDoubleClicked, this, &CSecondNavigationWidget::editItem); + setEditTriggers(DoubleClicked); + } +} + +void CSecondNavigationWidget::config() +{ + return; //< 1.4.1 统一到菜单配置 + CNavigationConfigDialog cfg; + cfg.updateItems(this); + int res = cfg.exec(); + if(QDialog::Accepted == res) + { + clear(); + const CSecondNavigationWidget * pNavigation = cfg.NavigationWidegt(); + updateItems(pNavigation); + updateStyleProxy(pNavigation->m_pItemProxy); + QString strItemConfigFile = m_strFileHomePath + QString("model%1NavigationWidget.json").arg(QDir::separator()); + write(strItemConfigFile); + } +} + +void CSecondNavigationWidget::setTopLevelIndexes(const QString &strIndexes) +{ + QList indexVisibleList; + QStringList listIndex = strIndexes.split(","); + foreach (QString strIndex, listIndex) + { + indexVisibleList.append(strIndex.toInt()); + } + + bool isFirstItem = true; + for(int nIndex(0); nIndex < topLevelItemCount(); ++nIndex) + { + if(nIndex < indexVisibleList.size()) + { + bool isHidden = (0 == indexVisibleList.at(nIndex)); + topLevelItem(nIndex)->setHidden(isHidden); + QTreeWidgetItem *item = topLevelItem(nIndex); + while(!isHidden && isFirstItem && item) + { + if(item->data(0,Qt::UserRole).toString() != QString()) + { + isFirstItem = false; + setCurrentIndex(indexFromItem(item)); + emit itemClicked(item,0); + break; + } + item = item->child(0); + } + } + else + { + topLevelItem(nIndex)->setHidden(true); + } + } +} + +void CSecondNavigationWidget::setItemSelected(const QString &data) +{ + QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); + QString dataPath = dataDir.absoluteFilePath(data); + for(int nIndex(0); nIndex < topLevelItemCount(); ++nIndex) + { + if(topLevelItem(nIndex)->isHidden()) + { + continue; + } + QTreeWidgetItem * item = findItem(dataPath, topLevelItem(nIndex)); + if(item) + { + this->clearSelection(); + item->setSelected(true); + break; + } + } +} + +void CSecondNavigationWidget::paintEvent(QPaintEvent *event) +{ + QPainter painter(viewport()); + //painter.fillRect(viewport()->rect(), m_pItemProxy->backgroundColor); + QTreeView::paintEvent(event); +} + +void CSecondNavigationWidget::initStyleProxy() +{ + m_pItemProxy = new ITEM_STYLE_PROXY(); + m_pItemProxy->indicatorWidth = 3; + m_pItemProxy->iconMargin = 5; + + m_pItemProxy->backgroundColor = 0x000C17; + m_pItemProxy->itemHoveredColor = 0x002C53; + m_pItemProxy->itemSelectedColor = 0x022C53; + + m_pItemProxy->itemTextColor = 0xBFC8D5; + m_pItemProxy->itemHoveredTextColor = 0xFFFFFF; + m_pItemProxy->itemSelectedTextColor = 0x1890FF; + + NodeInfo topNodeInfo(0x002140, 0xBFC8D5, 15, 21, 0); + NodeInfo childNodeInfo(0x000C17, 0xBFC8D5, 14, 16, 0); + NodeInfo leafNodeInfo(0x000C17, 0xBFC8D5, 12, 14, 0); + m_pItemProxy->vecItemStyle.push_back(std::move(topNodeInfo)); + m_pItemProxy->vecItemStyle.push_back(std::move(childNodeInfo)); + m_pItemProxy->vecItemStyle.push_back(std::move(leafNodeInfo)); +} + +void CSecondNavigationWidget::getNodeTypeMap(QMap &map) +{ + map = m_mapNodeType; +} + +void CSecondNavigationWidget::addTopLevelItem(const int &number, const QString &caption, const QString &data, const QString &icon, + const int &enable, const int &web, const int &type, const QString &url) +{ + if(caption.isEmpty()) + { + return; + } + QTreeWidgetItem * topLevelItem = new QTreeWidgetItem(QStringList() << caption); + topLevelItem->setData(0, Level_Role, TOP_LEVEL); + topLevelItem->setData(0, Corner_Role, false); + topLevelItem->setData(0, IconPath_Role, icon); + topLevelItem->setData(0, Item_Role, number); + topLevelItem->setData(0, Enable_Role, enable); + topLevelItem->setData(0, Web_Role, web); + topLevelItem->setData(0, Opt_Role, type); + topLevelItem->setData(0, Url_Role, url); + + if(!data.isEmpty()) + { + topLevelItem->setData(0, Qt::UserRole, data); + } + + if(!icon.isEmpty()) + { + topLevelItem->setIcon(0, QIcon(icon)); + } + + QTreeWidget::addTopLevelItem(topLevelItem); + if(CONFIG_MODE == m_navigationMode) + { + topLevelItem->setFlags(topLevelItem->flags() | Qt::ItemIsEditable); + topLevelItem->setExpanded(true); + setCurrentItem(topLevelItem); + } +} + +void CSecondNavigationWidget::addChildItem(const int &number, const QList &parents, const QString &caption, const QString &data, const QString &icon, + const int &enable, const int &web, const int &type, const QString &url) +{ + if(parents.isEmpty() || caption.isEmpty()) + { + return; + } + + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + if(topLevelItem(nIndex)->data(0, Item_Role).toInt() == parents.first()) + { + QTreeWidgetItem * parent = topLevelItem(nIndex); + //< 查找二级节点 + if(1 < parents.size()) + { + //< 查找失败则添加到二级节点 + for(int nChildIndex(0); nChildIndex < parent->childCount(); nChildIndex++) + { + if(parent->child(nChildIndex)->data(0, Item_Role).toInt() == parents.at(1)) + { + parent = parent->child(nChildIndex); + break; + } + } + } + QTreeWidgetItem * item = new QTreeWidgetItem(parent, QStringList() << caption); + item->setData(0, Level_Role, parent->data(0, Level_Role).toInt() + 1); + item->setData(0, Corner_Role, false); + item->setData(0, IconPath_Role, icon); + item->setData(0, Item_Role, number); + item->setData(0, Enable_Role, enable); + item->setData(0, Web_Role, web); + item->setData(0, Opt_Role, type); + item->setData(0, Url_Role, url); + if(!data.isEmpty()) + { + item->setData(0, Qt::UserRole, data); + } + + if(!icon.isEmpty()) + { + item->setIcon(0, QIcon(icon)); + } + + if(CONFIG_MODE == m_navigationMode) + { + item->setFlags(item->flags() | Qt::ItemIsEditable); + item->parent()->setExpanded(true); + item->parent()->setSelected(true); + } + } + } +} + +void CSecondNavigationWidget::addLevelItem(const int &number, const QList &parents, const QString &caption, const QString &data, const QString &icon, + const int &enable, const int &web, const int &type, const QString &url) +{ + if(parents.isEmpty() || caption.isEmpty()) + { + return; + } + + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + if(topLevelItem(nIndex)->data(0, Item_Role).toInt() == parents.at(0)) + { + QTreeWidgetItem * item = new QTreeWidgetItem(QStringList() << caption); + item->setData(0, Corner_Role, false); + item->setData(0, IconPath_Role, icon); + item->setData(0, Item_Role, number); + item->setData(0, Enable_Role, enable); + item->setData(0, Web_Role, web); + item->setData(0, Opt_Role, type); + item->setData(0, Url_Role, url); + if(!data.isEmpty()) + { + item->setData(0, Qt::UserRole, data); + } + if(!icon.isEmpty()) + { + item->setIcon(0, QIcon(icon)); + } + + QTreeWidgetItem * top = topLevelItem(nIndex); + //< 查找二级节点 + if(1 < parents.size()) + { + for(int nChildIndex(0); nChildIndex < top->childCount(); nChildIndex++) + { + if(top->child(nChildIndex)->data(0, Item_Role).toInt() == parents.at(1)) + { + QTreeWidgetItem * child = top->child(nChildIndex); + //< 查找三级节点 + if(2 < parents.size()) + { + for(int nLeafIndex(0); nLeafIndex < child->childCount(); nLeafIndex++) + { + if(child->child(nLeafIndex)->data(0, Item_Role).toInt() == parents.at(2)) + { + item->setData(0, Level_Role, child->data(0, Level_Role).toInt() + 1); + child->insertChild(nLeafIndex, item); + if(CONFIG_MODE == m_navigationMode) + { + item->setFlags(item->flags() | Qt::ItemIsEditable); + item->setSelected(true); + setCurrentItem(item); + } + return; + } + } + } + item->setData(0, Level_Role, top->data(0, Level_Role).toInt() + 1); + top->insertChild(nChildIndex, item); + if(CONFIG_MODE == m_navigationMode) + { + item->setFlags(item->flags() | Qt::ItemIsEditable); + item->setSelected(true); + setCurrentItem(item); + } + return; + } + } + } + item->setData(0, Level_Role, TOP_LEVEL); + QTreeWidget::insertTopLevelItem(nIndex, item); + if(CONFIG_MODE == m_navigationMode) + { + item->setFlags(item->flags() | Qt::ItemIsEditable); + item->setSelected(true); + setCurrentItem(item); + } + return; + } + } +} + +void CSecondNavigationWidget::removeItem(QTreeWidgetItem *item) +{ + if(item->parent()) + { + item->parent()->removeChild(item); + } + else + { + takeTopLevelItem(indexFromItem(item).row()); + } +} + +int CSecondNavigationWidget::slotImport() +{ + QString filePath = QFileDialog::getOpenFileName(this, tr("导入"), "", "*.xlsx"); + if(filePath.isEmpty()) + return -1; + + clear(); + QXlsx::Document xlsx(filePath); + QXlsx::CellRange cellRange = xlsx.currentWorksheet()->dimension(); + QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); + QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); + QDir exeDir(QString::fromStdString(iot_public::CFileUtil::getCurModuleDir())); + QMultiMap numberMap; + int nItemNumber = 0; + for(int row=cellRange.firstRow()+1; row<=cellRange.lastRow(); row++) + { + QString firName = xlsx.read(row, 1).toString().trimmed(); + if(firName.isEmpty()) + { + continue; + } + QString name; + QString secName = xlsx.read(row, 2).toString().trimmed(); + QString trdName = xlsx.read(row, 3).toString().trimmed(); + int used = getEnable(xlsx.read(row, 4).toString()); + int opt = getNodeType(xlsx.read(row, 5).toString()); + QString icon = xlsx.read(row, 6).toString(); + QString data = xlsx.read(row, 7).toString(); + int web = getEnable(xlsx.read(row, 8).toString()); + if(!data.isEmpty()) + { + if(opt == EXTERN_PRO) + { + data = exeDir.absoluteFilePath(data); + } + else + { + data = dataDir.absoluteFilePath(data); + } + } + if(!icon.isEmpty()) + { + icon = iconDir.absoluteFilePath(icon); + } + if(secName.isEmpty()) + { + name = firName; + addTopLevelItem(nItemNumber, firName, data, icon, used, web, opt); + } + else if(!secName.isEmpty() && trdName.isEmpty()) + { + QList list; + list.append(findValue(numberMap, firName)); + name = secName; + addChildItem(nItemNumber, list, secName, data, icon, used, web, opt); + } + else + { + QList list; + list.append(findValue(numberMap, firName)); + list.append(findValue(numberMap, secName)); + name = trdName; + addChildItem(nItemNumber, list, trdName, data, icon, used, web, opt); + } + + numberMap.insert(name, nItemNumber++); + } + return nItemNumber; +} + +void CSecondNavigationWidget::slotExport() +{ + QString filePath = QFileDialog::getSaveFileName(this, tr("导出"), "nav.xlsx", "*.xlsx"); + if(filePath.isEmpty()) + return; + + QXlsx::Document xlsx; + + xlsx.write(hexTo26(0)+"1", tr("一级")); + xlsx.write(hexTo26(1)+"1", tr("二级")); + xlsx.write(hexTo26(2)+"1", tr("三级")); + xlsx.write(hexTo26(3)+"1", tr("是否使用")); + xlsx.write(hexTo26(4)+"1", tr("操作")); + xlsx.write(hexTo26(5)+"1", tr("图标")); + xlsx.write(hexTo26(6)+"1", tr("数据")); + xlsx.write(hexTo26(7)+"1", tr("web发布")); + xlsx.setColumnWidth(1, 8, 30); + + QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); + QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); + QDir exeDir(QString::fromStdString(iot_public::CFileUtil::getCurModuleDir())); + int row = 2; + for (int nIndex(0); nIndex < topLevelItemCount(); ++nIndex) + { + //< Top_Level_Item + QTreeWidgetItem * item_top_level = topLevelItem(nIndex); + QString tName = item_top_level->data(0, Qt::DisplayRole).toString(); + QString tData = dataDir.relativeFilePath(item_top_level->data(0, Qt::UserRole).toString()); + if(item_top_level->data(0, Opt_Role).toInt() == EXTERN_PRO) + { + tData = exeDir.relativeFilePath(item_top_level->data(0, Qt::UserRole).toString()); + } + QString tIcon = iconDir.relativeFilePath(item_top_level->data(0, IconPath_Role).toString()); + QString tUsed = getEnableStr(item_top_level->data(0, Enable_Role).toInt()); + QString tOpt = getNodeTypeStr(item_top_level->data(0, Opt_Role).toInt()); + QString tWeb = getEnableStr(item_top_level->data(0, Web_Role).toInt()); + xlsx.write(hexTo26(0)+QString::number(row), tName); + xlsx.write(hexTo26(3)+QString::number(row), tUsed); + xlsx.write(hexTo26(4)+QString::number(row), tOpt); + xlsx.write(hexTo26(5)+QString::number(row), tIcon); + xlsx.write(hexTo26(6)+QString::number(row), tData); + xlsx.write(hexTo26(7)+QString::number(row++), tWeb); + for (int nChildIndex(0); nChildIndex < item_top_level->childCount(); ++nChildIndex) + { + //< Child_Level_Item + QTreeWidgetItem * item_child_level = item_top_level->child(nChildIndex); + QString cName = item_child_level->data(0, Qt::DisplayRole).toString(); + QString cData = dataDir.relativeFilePath(item_child_level->data(0, Qt::UserRole).toString()); + if(item_child_level->data(0, Opt_Role).toInt() == EXTERN_PRO) + { + cData = exeDir.relativeFilePath(item_child_level->data(0, Qt::UserRole).toString()); + } + QString cIcon = iconDir.relativeFilePath(item_child_level->data(0, IconPath_Role).toString()); + QString cUsed = getEnableStr(item_child_level->data(0, Enable_Role).toInt()); + QString cOpt = getNodeTypeStr(item_child_level->data(0, Opt_Role).toInt()); + QString cWeb = getEnableStr(item_child_level->data(0, Web_Role).toInt()); + xlsx.write(hexTo26(0)+QString::number(row), tName); + xlsx.write(hexTo26(1)+QString::number(row), cName); + xlsx.write(hexTo26(3)+QString::number(row), cUsed); + xlsx.write(hexTo26(4)+QString::number(row), cOpt); + xlsx.write(hexTo26(5)+QString::number(row), cIcon); + xlsx.write(hexTo26(6)+QString::number(row), cData); + xlsx.write(hexTo26(7)+QString::number(row++), cWeb); + for (int nLeafIndex(0); nLeafIndex < item_child_level->childCount(); ++nLeafIndex) + { + //< Leaf_Level_Item + QTreeWidgetItem * item_leaf_level = item_child_level->child(nLeafIndex); + QString lName = item_leaf_level->data(0, Qt::DisplayRole).toString(); + QString lData = dataDir.relativeFilePath(item_leaf_level->data(0, Qt::UserRole).toString()); + if(item_leaf_level->data(0, Opt_Role).toInt() == EXTERN_PRO) + { + lData = exeDir.relativeFilePath(item_leaf_level->data(0, Qt::UserRole).toString()); + } + QString lIcon = iconDir.relativeFilePath(item_leaf_level->data(0, IconPath_Role).toString()); + QString lUsed = getEnableStr(item_leaf_level->data(0, Enable_Role).toInt()); + QString lOpt = getNodeTypeStr(item_leaf_level->data(0, Opt_Role).toInt()); + QString lWeb = getEnableStr(item_leaf_level->data(0, Web_Role).toInt()); + xlsx.write(hexTo26(0)+QString::number(row), tName); + xlsx.write(hexTo26(1)+QString::number(row), cName); + xlsx.write(hexTo26(2)+QString::number(row), lName); + xlsx.write(hexTo26(3)+QString::number(row), lUsed); + xlsx.write(hexTo26(4)+QString::number(row), lOpt); + xlsx.write(hexTo26(5)+QString::number(row), lIcon); + xlsx.write(hexTo26(6)+QString::number(row), lData); + xlsx.write(hexTo26(7)+QString::number(row++), lWeb); + } + } + } + + if(xlsx.saveAs(filePath)) + { + QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+filePath); + } + else + { + QMessageBox::information(this,tr("提示"),tr("保存失败")); + } +} + +void CSecondNavigationWidget::clearItems() +{ + clear(); +} + +void CSecondNavigationWidget::loadItemDelegate() +{ + m_pItemDelegate = new CNavigationDelegate(m_pItemProxy, this); + m_pItemDelegate->setView(this); + setItemDelegate(m_pItemDelegate); +} + +void CSecondNavigationWidget::updateItems(const CSecondNavigationWidget *pNavigation) +{ + if(Q_NULLPTR == pNavigation) + { + return; + } + + for(int nIndex(0); nIndex < pNavigation->topLevelItemCount(); nIndex++) + { + QTreeWidgetItem * item = pNavigation->topLevelItem(nIndex); + QTreeWidgetItem * newItem = buildNewItem(item); + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + QTreeWidgetItem * childItem = item->child(nChildIndex); + QTreeWidgetItem * newChildItem = buildNewItem(childItem); + for(int nLeafIndex(0); nLeafIndex < childItem->childCount(); nLeafIndex++) + { + newChildItem->addChild(buildNewItem(childItem->child(nLeafIndex))); + } + newItem->addChild(newChildItem); + } + QTreeWidget::addTopLevelItem(newItem); + } +} + +QTreeWidgetItem *CSecondNavigationWidget::buildNewItem(const QTreeWidgetItem *parent) +{ + QTreeWidgetItem * item = new QTreeWidgetItem(*parent); + item->setData(0, Corner_Role, false); + if(CONFIG_MODE == m_navigationMode) + { + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable); + } + else + { + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + } + return item; +} + +void CSecondNavigationWidget::updateStyleProxy(const ITEM_STYLE_PROXY *proxy) +{ + if(Q_NULLPTR == proxy) + { + return; + } + m_pItemProxy->backgroundColor = proxy->backgroundColor; + m_pItemProxy->itemHoveredColor = proxy->itemHoveredColor; + m_pItemProxy->itemSelectedColor = proxy->itemSelectedColor; + m_pItemProxy->itemTextColor = proxy->itemTextColor; + m_pItemProxy->itemHoveredTextColor = proxy->itemHoveredTextColor; + m_pItemProxy->itemSelectedTextColor = proxy->itemSelectedTextColor; + m_pItemProxy->vecItemStyle = proxy->vecItemStyle; +} + +void CSecondNavigationWidget::contextMenuEvent(QContextMenuEvent *e) +{ + if(EDIT_MODE == m_navigationMode) + { + QMenu menu; + QAction * pActionCfg = new QAction(tr("属性配置")); + connect(pActionCfg, &QAction::triggered, this, &CSecondNavigationWidget::config); + menu.addAction(pActionCfg); + menu.exec(e->globalPos()); + } + else if(EXPLORER_MODE == m_navigationMode) + { + QMenu menu; + QAction * pActionExp = new QAction(tr("全部展开")); + QAction * pActionCol = new QAction(tr("全部收缩")); + connect(pActionExp, &QAction::triggered, this, [=](){expandAll();}); + connect(pActionCol, &QAction::triggered, this, [=](){collapseAll();}); + menu.addAction(pActionExp); + menu.addAction(pActionCol); + menu.exec(e->globalPos()); + } +} + +void CSecondNavigationWidget::itemSelectedChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) +{ + setFocus(); + update(); + if(previous) + { + if(TOP_LEVEL == previous->data(0, Level_Role)) + { + previous->setData(0, Corner_Role, false); + } + else if(CHILD_LEVEL == previous->data(0, Level_Role)) + { + previous->parent()->setData(0, Corner_Role, false); + } + else if(LEAF_LEVEL == previous->data(0, Level_Role)) + { + previous->parent()->parent()->setData(0, Corner_Role, false); + } + } + + if(current) + { + if(TOP_LEVEL == current->data(0, Level_Role)) + { + current->setData(0, Corner_Role, true); + } + else if(CHILD_LEVEL == current->data(0, Level_Role)) + { + current->parent()->setData(0, Corner_Role, true); + } + else if(LEAF_LEVEL == current->data(0, Level_Role)) + { + current->parent()->parent()->setData(0, Corner_Role, true); + } + +// QFileInfo info(current->data(0, Qt::UserRole).toString()); +// emit graphItemClicked(current->data(0, Qt::DisplayRole).toString(), info.fileName()); + } +} + +void CSecondNavigationWidget::itemSelected(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column) + if(item) + { + if(TOP_LEVEL == item->data(0, Level_Role)) + { + item->setData(0, Corner_Role, true); + } + else if(CHILD_LEVEL == item->data(0, Level_Role)) + { + item->parent()->setData(0, Corner_Role, true); + } + else if(LEAF_LEVEL == item->data(0, Level_Role)) + { + item->parent()->parent()->setData(0, Corner_Role, true); + } + + QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); + QString fileName = dataDir.relativeFilePath(item->data(0, Qt::UserRole).toString()); + emit graphItemClicked(item->data(0, Qt::DisplayRole).toString(), fileName, + item->data(0, Opt_Role).toInt(), item->data(0, Url_Role).toString()); + } +} + +void CSecondNavigationWidget::setIconSize(const int &width, const int &height) +{ + QTreeWidget::setIconSize(QSize(width, height)); +} + +void CSecondNavigationWidget::setBranchIconSize(const int &width, const int &height) +{ + if(m_pItemDelegate) + { + m_pItemDelegate->setBranchIconSize(QSize(width, height)); + } +} + +void CSecondNavigationWidget::setRowHeight(const int &rowHeight) +{ + if(m_pItemDelegate) + { + m_pItemDelegate->m_rowHeight = rowHeight; + } + resize(size()); +} + +void CSecondNavigationWidget::setIndentation(const int &indentation) +{ + QTreeWidget::setIndentation(indentation); +} + +void CSecondNavigationWidget::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const +{ + if(!index.isValid()) + { + return; + } + QTreeWidget::drawRow(painter, options, index); + + if(index.data(Corner_Role).toBool()) + { + QRect rt = visualRect(index); + painter->setPen(Qt::transparent); + painter->setBrush(QColor(m_pItemProxy->itemSelectedTextColor)); + painter->drawRect(QRectF(rt.x(), rt.y() + 0.5, m_pItemProxy->indicatorWidth, rt.height() - 0.5)); + } +} + +void CSecondNavigationWidget::setTreeBackgroundColor(const rgb &color) +{ + if(m_pItemProxy) + { + m_pItemProxy->backgroundColor = color; + } +} + +void CSecondNavigationWidget::setItemHoverBackgroundColor(const rgb &color) +{ + if(m_pItemProxy) + { + m_pItemProxy->itemHoveredColor = color; + } +} + +void CSecondNavigationWidget::setItemSelectedBackgroundColor(const rgb &color) +{ + if(m_pItemProxy) + { + m_pItemProxy->itemSelectedColor = color; + } +} + +void CSecondNavigationWidget::setTextColor(const rgb &color) +{ + if(m_pItemProxy) + { + m_pItemProxy->itemTextColor = color; + } +} + +void CSecondNavigationWidget::setTextHoverColor(const rgb &color) +{ + if(m_pItemProxy) + { + m_pItemProxy->itemHoveredTextColor = color; + } +} + +void CSecondNavigationWidget::setTextSelectedColor(const rgb &color) +{ + if(m_pItemProxy) + { + m_pItemProxy->itemSelectedTextColor = color; + } +} + +void CSecondNavigationWidget::setItemBackgroundColor(const rgb &color, const Node_Level &level) +{ + if(m_pItemProxy) + { + std::get<0>(m_pItemProxy->vecItemStyle[level]) = color; + } +} + +void CSecondNavigationWidget::setItemTextSize(const int &size, const Node_Level &level) +{ + if(m_pItemProxy) + { + std::get<2>(m_pItemProxy->vecItemStyle[level]) = size; + } +} + +void CSecondNavigationWidget::read(const QString &strFileName) +{ + QFile loadFile(strFileName); + if(!loadFile.open(QIODevice::ReadOnly)) + { + qDebug() << "could't open file 'NavigationWidget.json'!"; + return; + } + + QByteArray data = loadFile.readAll(); + loadFile.close(); + + QJsonParseError json_error; + QJsonDocument jsonDoc(QJsonDocument::fromJson(data, &json_error)); + + if(json_error.error != QJsonParseError::NoError) + { + qDebug() << "'NavigationWidget.json' parse Error!"; + return; + } + + QJsonObject root = jsonDoc.object(); + if(root.contains("configure")) + { + QJsonObject configObject = root.value("configure").toObject(); + m_pItemProxy->backgroundColor = QColor(configObject["backgroundColor"].toString()).rgb(); + m_pItemProxy->indicatorWidth = configObject["indicatorWidth"].toInt(); + m_pItemProxy->iconMargin = configObject["iconMargin"].toInt(); + m_pItemDelegate->m_rowHeight = configObject["rowHeight"].toInt(); + + std::get<0>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = QColor(configObject["levelTopItemBgColor"].toString()).rgb(); + std::get<1>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = QColor(configObject["levelTopItemTextColor"].toString()).rgb(); + std::get<2>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = configObject["levelTopItemTextSize"].toInt(); + std::get<3>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = configObject["levelTopItemIconSize"].toInt(); + std::get<4>(m_pItemProxy->vecItemStyle[TOP_LEVEL]) = configObject["levelTopItemIndentation"].toInt(); + + std::get<0>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = QColor(configObject["levelChildItemBgColor"].toString()).rgb(); + std::get<1>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = QColor(configObject["levelChildItemTextColor"].toString()).rgb(); + std::get<2>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = configObject["levelChildItemTextSize"].toInt(); + std::get<3>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = configObject["levelChildItemIconSize"].toInt(); + std::get<4>(m_pItemProxy->vecItemStyle[CHILD_LEVEL]) = configObject["levelChildItemIndentation"].toInt(); + + std::get<0>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = QColor(configObject["levelLeafItemBgColor"].toString()).rgb(); + std::get<1>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = QColor(configObject["levelLeafItemTextColor"].toString()).rgb(); + std::get<2>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = configObject["levelLeafItemTextSize"].toInt(); + std::get<3>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = configObject["levelLeafItemIconSize"].toInt(); + std::get<4>(m_pItemProxy->vecItemStyle[LEAF_LEVEL]) = configObject["levelLeafItemIndentation"].toInt(); + + m_pItemProxy->itemHoveredColor = QColor(configObject["itemHoveredBgColor"].toString()).rgb(); + m_pItemProxy->itemSelectedColor = QColor(configObject["itemSelectedColor"].toString()).rgb(); + m_pItemProxy->itemHoveredTextColor = QColor(configObject["itemHoveredTextColor"].toString()).rgb(); + m_pItemProxy->itemSelectedTextColor = QColor(configObject["itemSelectedTextColor"].toString()).rgb(); + } + + if(root.contains("items")) + { + QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); + QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); + QDir exeDir(QString::fromStdString(iot_public::CFileUtil::getCurModuleDir())); + QJsonArray itemArray = root.value("items").toArray(); + int nItemNumber = 0; + for(int nIndex(0); nIndex< itemArray.size(); nIndex++) + { + QJsonObject topLevelObject = itemArray[nIndex].toObject(); + QTreeWidgetItem * item_top_level = new QTreeWidgetItem(this); + item_top_level->setData(0, Qt::DisplayRole, topLevelObject.value("name").toString()); + item_top_level->setData(0, Level_Role, TOP_LEVEL); + item_top_level->setData(0, Item_Role, nItemNumber++); + item_top_level->setData(0, Enable_Role, topLevelObject.value("used").toInt(Enable)); + item_top_level->setData(0, Web_Role, topLevelObject.value("web").toInt(Enable)); + item_top_level->setData(0, Opt_Role, topLevelObject.value("opt").toInt(SWITCH_GRAPH)); + item_top_level->setData(0, Url_Role, topLevelObject.value("url").toString()); + if(!topLevelObject.value("data").toString().isEmpty()) + { + if(topLevelObject.value("opt").toInt(SWITCH_GRAPH) == EXTERN_PRO) + { + item_top_level->setData(0, Qt::UserRole, exeDir.absoluteFilePath(topLevelObject.value("data").toString())); + } + else + { + item_top_level->setData(0, Qt::UserRole, dataDir.absoluteFilePath(topLevelObject.value("data").toString())); + } + } + QString topLevelIconName = topLevelObject.value("icon").toString(); + if(!topLevelIconName.isEmpty()) + { + item_top_level->setData(0, IconPath_Role, iconDir.absoluteFilePath(topLevelIconName)); + item_top_level->setIcon(0, QIcon(iconDir.absoluteFilePath(topLevelIconName))); + } + + QJsonArray childArray = topLevelObject.value("items").toArray(); + for(int nChildIndex(0); nChildIndex< childArray.size(); nChildIndex++) + { + QJsonObject childLevelObject = childArray[nChildIndex].toObject(); + QTreeWidgetItem * item_child_level = new QTreeWidgetItem(item_top_level); + item_child_level->setData(0, Qt::DisplayRole, childLevelObject.value("name").toString()); + item_child_level->setData(0, Level_Role, CHILD_LEVEL); + item_child_level->setData(0, Item_Role, nItemNumber++); + item_child_level->setData(0, Enable_Role, childLevelObject.value("used").toInt(Enable)); + item_child_level->setData(0, Web_Role, childLevelObject.value("web").toInt(Enable)); + item_child_level->setData(0, Opt_Role, childLevelObject.value("opt").toInt(SWITCH_GRAPH)); + item_child_level->setData(0, Url_Role, childLevelObject.value("url").toString()); + if(!childLevelObject.value("data").toString().isEmpty()) + { + if(childLevelObject.value("opt").toInt(SWITCH_GRAPH) == EXTERN_PRO) + { + item_child_level->setData(0, Qt::UserRole, exeDir.absoluteFilePath(childLevelObject.value("data").toString())); + } + else + { + item_child_level->setData(0, Qt::UserRole, dataDir.absoluteFilePath(childLevelObject.value("data").toString())); + } + } + QString childLevelIconName = childLevelObject.value("icon").toString(); + if(!childLevelIconName.isEmpty()) + { + item_child_level->setData(0, IconPath_Role, iconDir.absoluteFilePath(childLevelIconName)); + item_child_level->setIcon(0, QIcon(iconDir.absoluteFilePath(childLevelIconName))); + } + + QJsonArray leafArray = childLevelObject.value("items").toArray(); + for(int nLeafIndex(0); nLeafIndex< leafArray.size(); nLeafIndex++) + { + QJsonObject leafLevelObject = leafArray[nLeafIndex].toObject(); + QTreeWidgetItem * item_leaf_level = new QTreeWidgetItem(item_child_level); + item_leaf_level->setData(0, Qt::DisplayRole, leafLevelObject.value("name").toString()); + item_leaf_level->setData(0, Level_Role, LEAF_LEVEL); + item_leaf_level->setData(0, Item_Role, nItemNumber++); + item_leaf_level->setData(0, Enable_Role, leafLevelObject.value("used").toInt(Enable)); + item_leaf_level->setData(0, Web_Role, leafLevelObject.value("web").toInt(Enable)); + item_leaf_level->setData(0, Opt_Role, leafLevelObject.value("opt").toInt(SWITCH_GRAPH)); + item_leaf_level->setData(0, Url_Role, leafLevelObject.value("url").toString()); + if(!leafLevelObject.value("data").toString().isEmpty()) + { + if(leafLevelObject.value("opt").toInt(SWITCH_GRAPH) == EXTERN_PRO) + { + item_leaf_level->setData(0, Qt::UserRole, exeDir.absoluteFilePath(leafLevelObject.value("data").toString())); + } + else + { + item_leaf_level->setData(0, Qt::UserRole, dataDir.absoluteFilePath(leafLevelObject.value("data").toString())); + } + } + QString leafLevelIconName = leafLevelObject.value("icon").toString(); + if(!leafLevelIconName.isEmpty()) + { + item_leaf_level->setData(0, IconPath_Role, iconDir.absoluteFilePath(leafLevelIconName)); + item_leaf_level->setIcon(0, QIcon(iconDir.absoluteFilePath(leafLevelIconName))); + } + item_child_level->addChild(item_leaf_level); + if(EXPLORER_MODE == m_navigationMode) + { + item_leaf_level->setHidden(item_leaf_level->data(0, Enable_Role).toInt()==Enable?false:true); + } + } + item_top_level->addChild(item_child_level); + if(EXPLORER_MODE == m_navigationMode) + { + item_child_level->setHidden(item_child_level->data(0, Enable_Role).toInt()==Enable?false:true); + } + } + QTreeWidget::addTopLevelItem(item_top_level); + if(EXPLORER_MODE == m_navigationMode) + { + item_top_level->setHidden(item_top_level->data(0, Enable_Role).toInt()==Enable?false:true); + } + } + } +} + +void CSecondNavigationWidget::write(const QString &strFileName) +{ + QFile file(strFileName); + //< 不存在则创建 + if(!file.exists()) + { + file.setFileName(strFileName); + } + + if(file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + // 清空文件中的原有内容 + file.resize(0); + + //< Configure + QJsonObject object; + QJsonObject configObject; + configObject.insert("backgroundColor", QColor(m_pItemProxy->backgroundColor).name().toUpper()); + configObject.insert("indicatorWidth", (int)m_pItemProxy->indicatorWidth); + configObject.insert("iconMargin", (int)m_pItemProxy->iconMargin); + configObject.insert("rowHeight", (int)m_pItemDelegate->m_rowHeight); + + configObject.insert("levelTopItemBgColor", QColor(std::get<0>(m_pItemProxy->vecItemStyle[TOP_LEVEL])).name().toUpper()); + configObject.insert("levelTopItemTextColor", QColor(std::get<1>(m_pItemProxy->vecItemStyle[TOP_LEVEL])).name().toUpper()); + configObject.insert("levelTopItemTextSize", (int)std::get<2>(m_pItemProxy->vecItemStyle[TOP_LEVEL])); + configObject.insert("levelTopItemIconSize", (int)std::get<3>(m_pItemProxy->vecItemStyle[TOP_LEVEL])); + configObject.insert("levelTopItemIndentation", (int)std::get<4>(m_pItemProxy->vecItemStyle[TOP_LEVEL])); + + configObject.insert("levelChildItemBgColor", QColor(std::get<0>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])).name().toUpper()); + configObject.insert("levelChildItemTextColor", QColor(std::get<1>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])).name().toUpper()); + configObject.insert("levelChildItemTextSize", (int)std::get<2>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])); + configObject.insert("levelChildItemIconSize", (int)std::get<3>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])); + configObject.insert("levelChildItemIndentation",(int)std::get<4>(m_pItemProxy->vecItemStyle[CHILD_LEVEL])); + + configObject.insert("levelLeafItemBgColor", QColor(std::get<0>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])).name().toUpper()); + configObject.insert("levelLeafItemTextColor", QColor(std::get<1>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])).name().toUpper()); + configObject.insert("levelLeafItemTextSize", (int)std::get<2>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])); + configObject.insert("levelLeafItemIconSize", (int)std::get<3>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])); + configObject.insert("levelLeafItemIndentation", (int)std::get<4>(m_pItemProxy->vecItemStyle[LEAF_LEVEL])); + + configObject.insert("itemHoveredBgColor", QColor(m_pItemProxy->itemHoveredColor).name().toUpper()); + configObject.insert("itemSelectedColor", QColor(m_pItemProxy->itemSelectedColor).name().toUpper()); + configObject.insert("itemHoveredTextColor", QColor(m_pItemProxy->itemHoveredTextColor).name().toUpper()); + configObject.insert("itemSelectedTextColor", QColor(m_pItemProxy->itemSelectedTextColor).name().toUpper()); + + //< Items + QDir iconDir(m_strFileHomePath + "back_pixmap" + QDir::separator()); + QDir dataDir(m_strFileHomePath + "pic" + QDir::separator()); + QDir exeDir(QString::fromStdString(iot_public::CFileUtil::getCurModuleDir())); + QJsonArray itemsArray; + for (int nIndex(0); nIndex < topLevelItemCount(); ++nIndex) + { + //< Top_Level_Item + QJsonObject topLevelObject; + QJsonArray topLevelArray; + QTreeWidgetItem * item_top_level = topLevelItem(nIndex); + topLevelObject.insert("name", item_top_level->data(0, Qt::DisplayRole).toString()); + if(item_top_level->data(0, Opt_Role).toInt() == EXTERN_PRO) + { + topLevelObject.insert("data", exeDir.relativeFilePath(item_top_level->data(0, Qt::UserRole).toString())); + } + else + { + topLevelObject.insert("data", dataDir.relativeFilePath(item_top_level->data(0, Qt::UserRole).toString())); + } + topLevelObject.insert("icon", iconDir.relativeFilePath(item_top_level->data(0, IconPath_Role).toString())); + topLevelObject.insert("used", item_top_level->data(0, Enable_Role).toInt()); + topLevelObject.insert("web", item_top_level->data(0, Web_Role).toInt()); + topLevelObject.insert("opt", item_top_level->data(0, Opt_Role).toInt()); + topLevelObject.insert("url", item_top_level->data(0, Url_Role).toString()); + for (int nChildIndex(0); nChildIndex < item_top_level->childCount(); ++nChildIndex) + { + //< Child_Level_Item + QJsonObject childLevelObject; + QJsonArray childLevelArray; + QTreeWidgetItem * item_child_level = item_top_level->child(nChildIndex); + childLevelObject.insert("name", item_child_level->data(0, Qt::DisplayRole).toString()); + if(item_child_level->data(0, Opt_Role).toInt() == EXTERN_PRO) + { + childLevelObject.insert("data", exeDir.relativeFilePath(item_child_level->data(0, Qt::UserRole).toString())); + } + else + { + childLevelObject.insert("data", dataDir.relativeFilePath(item_child_level->data(0, Qt::UserRole).toString())); + } + childLevelObject.insert("icon", iconDir.relativeFilePath(item_child_level->data(0, IconPath_Role).toString())); + childLevelObject.insert("used", item_child_level->data(0, Enable_Role).toInt()); + childLevelObject.insert("web", item_child_level->data(0, Web_Role).toInt()); + childLevelObject.insert("opt", item_child_level->data(0, Opt_Role).toInt()); + childLevelObject.insert("url", item_child_level->data(0, Url_Role).toString()); + for (int nLeafIndex(0); nLeafIndex < item_child_level->childCount(); ++nLeafIndex) + { + //< Leaf_Level_Item + QJsonObject LeafLevelObject; + QTreeWidgetItem * item_leaf_level = item_child_level->child(nLeafIndex); + LeafLevelObject.insert("name", item_leaf_level->data(0, Qt::DisplayRole).toString()); + if(item_leaf_level->data(0, Opt_Role).toInt() == EXTERN_PRO) + { + LeafLevelObject.insert("data", exeDir.relativeFilePath(item_leaf_level->data(0, Qt::UserRole).toString())); + } + else + { + LeafLevelObject.insert("data", dataDir.relativeFilePath(item_leaf_level->data(0, Qt::UserRole).toString())); + } + LeafLevelObject.insert("icon", iconDir.relativeFilePath(item_leaf_level->data(0, IconPath_Role).toString())); + LeafLevelObject.insert("used", item_leaf_level->data(0, Enable_Role).toInt()); + LeafLevelObject.insert("web", item_leaf_level->data(0, Web_Role).toInt()); + LeafLevelObject.insert("opt", item_leaf_level->data(0, Opt_Role).toInt()); + LeafLevelObject.insert("url", item_leaf_level->data(0, Url_Role).toString()); + childLevelArray.append(LeafLevelObject); + } + childLevelObject.insert("items", childLevelArray); + topLevelArray.append(childLevelObject); + } + topLevelObject.insert("items", topLevelArray); + itemsArray.append(topLevelObject); + } + + QJsonDocument doc; + object.insert("configure", configObject); + object.insert("items", itemsArray); + doc.setObject(object); + file.write(doc.toJson()); + } +} + +QString CSecondNavigationWidget::hexTo26(int number) +{ + int p = 26; //进制 + int c = 0; //取余后的数字 + QString temp; + + while (true) { + c = number % p; + number = number / p; + if(number != 0) + { + temp.prepend(QString(QChar(0x41 + c))); + } + else + { + temp.prepend(QString(QChar(0x41 + c))); + break; + } + number--; + } + + return temp; +} + +int CSecondNavigationWidget::findValue(const QMap &map, const QString &key) +{ + QMap::const_iterator iter = --map.constEnd(); + for(; iter != --map.constBegin(); iter--) + { + if(iter.key() == key) + { + return iter.value(); + } + } + return -1; +} + +QString CSecondNavigationWidget::getNodeTypeStr(int type) +{ + return m_mapNodeType.value(type, ""); +} + +int CSecondNavigationWidget::getNodeType(const QString &str) +{ + QMap::const_iterator iter = m_mapNodeType.constBegin(); + for(; iter != m_mapNodeType.constEnd(); iter++) + { + if(iter.value() == str) + { + return iter.key(); + } + } + return 1; +} + +QString CSecondNavigationWidget::getEnableStr(int enable) +{ + return m_mapEnable.value(enable, ""); +} + +int CSecondNavigationWidget::getEnable(const QString &str) +{ + QMap::const_iterator iter = m_mapEnable.constBegin(); + for(; iter != m_mapEnable.constEnd(); iter++) + { + if(iter.value() == str) + { + return iter.key(); + } + } + return 1; +} + +QTreeWidgetItem *CSecondNavigationWidget::findItem(const QString &data, QTreeWidgetItem *parent) +{ + if(parent->data(0, Qt::UserRole).toString() == data) + { + return parent; + } + for(int nIndex(0); nIndex < parent->childCount(); ++nIndex) + { + QTreeWidgetItem * item = parent->child(nIndex); + if(!item) + { + continue; + } + QTreeWidgetItem * find = findItem(data, item); + if(find) + { + return find; + } + } + return NULL; +} diff --git a/product/src/gui/plugin/SecondNavigationWidget/CSecondNavigationWidget.h b/product/src/gui/plugin/SecondNavigationWidget/CSecondNavigationWidget.h new file mode 100644 index 00000000..858bc5d2 --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/CSecondNavigationWidget.h @@ -0,0 +1,190 @@ +#ifndef CNAVIGATIONWIDGET_H +#define CNAVIGATIONWIDGET_H + +#include +#include "CNavigationConfigDialog.h" +#include "GraphShape/CPluginWidget.h" //< RQEH6000_HOME/platform/src/include/gui/GraphShape + +class CNavigationDelegate; + +typedef unsigned int rgb; + +typedef std::tuple NodeInfo; //< 节点背景颜色、节点字体颜色、节点字体大小、图标大小、偏移像素 + +extern const int Level_Role; //< 节点层级 +extern const int Corner_Role; //< 活动根节点 +extern const int IconPath_Role; //< 节点图标路径 +extern const int Item_Role; //< 节点数 +extern const int Enable_Role; //< 是否启用 +extern const int Web_Role; //< 是否web发布 +extern const int Opt_Role; //< 操作类型 +extern const int Url_Role; //< 加载网页url + +struct ITEM_STYLE_PROXY +{ + int indicatorWidth; + int iconMargin; + + //< 填充颜色 + rgb backgroundColor; + rgb itemHoveredColor; + rgb itemSelectedColor; + + //< 文字颜色 + rgb itemTextColor; + rgb itemHoveredTextColor; + rgb itemSelectedTextColor; + + std::vector< NodeInfo > vecItemStyle; +}; + +class CSecondNavigationWidget : public QTreeWidget, public IPluginWidget +{ + Q_OBJECT + friend class CNavigationConfigDialog; +public: + enum Navigation_Mode + { + EXPLORER_MODE = 0, + EDIT_MODE, + CONFIG_MODE, + }; + + enum Node_Level + { + TOP_LEVEL = 0, + CHILD_LEVEL, + LEAF_LEVEL + }; + + enum Node_Type + { + NONE = 0, //< 无操作 + SWITCH_GRAPH, //< 切换画面 + SWITCH_NAV, //< 切换导航 + EXTERN_PRO, //< 调用程序 + }; + + enum Node_Enable + { + Enable = 1, + Disable = 2, + }; + + explicit CSecondNavigationWidget(QWidget *parent = Q_NULLPTR, bool editMode = true); + + ~CSecondNavigationWidget(); + + void setNavigationMode(const Navigation_Mode &navigationMode); + + virtual void config(); + virtual void release(){} + virtual bool read(CGStream &ios) { Q_UNUSED(ios); return false; } + virtual bool write(CGStream &ios) { Q_UNUSED(ios); return false; } + virtual void setProperty(const QString &propertyName, QVariant value) { Q_UNUSED(propertyName); Q_UNUSED(value);} + virtual void getProperty(QList< QPair > &propertyList) { Q_UNUSED(propertyList); } + +/************************************ 脚本接口-[begin] ****************************************/ + +public Q_SLOTS: + void setTopLevelIndexes(const QString &strIndexes); + + void setItemSelected(const QString &data); + + void addTopLevelItem(const int &number, const QString &caption, const QString &data = QString(), const QString &icon = QString(), + const int &enable = Enable, const int &web = Enable, const int &type = SWITCH_GRAPH, const QString &url = QString()); + + void addChildItem(const int &number, const QList &parents, const QString &caption, const QString &data = QString(), const QString &icon = QString(), + const int &enable = Enable, const int &web = Enable, const int &type = SWITCH_GRAPH, const QString &url = QString()); + + void addLevelItem(const int &number, const QList &parents, const QString &caption, const QString &data = QString(), const QString &icon = QString(), + const int &enable = Enable, const int &web = Enable, const int &type = SWITCH_GRAPH, const QString &url = QString()); + + void removeItem(QTreeWidgetItem *item); + + int slotImport(); + + void slotExport(); + + void clearItems(); + + void setIconSize(const int &width, const int &height); + void setBranchIconSize(const int &width, const int &height); + + void setRowHeight(const int &rowHeight); + + void setIndentation(const int &indentation); + + void initStyleProxy(); + + void getNodeTypeMap(QMap &map); + + /******************** 样式设置-[begin] ************************/ + void setTreeBackgroundColor(const rgb &color); + void setItemHoverBackgroundColor(const rgb &color); + void setItemSelectedBackgroundColor(const rgb &color); + + void setTextColor(const rgb &color); + void setTextHoverColor(const rgb &color); + void setTextSelectedColor(const rgb &color); + + void setItemBackgroundColor(const rgb &color, const Node_Level &level); + void setItemTextSize(const int &size, const Node_Level &level); + /******************** 样式设置-[end] *************************/ + +Q_SIGNALS: + void graphItemClicked(const QString &caption, const QString &data, const int &type, const QString &url); + +/************************************* 脚本接口-[end] ********************************************/ + + +private: + void initialize(); + + void initStyle(); + + void loadItemDelegate(); + + void updateItems(const CSecondNavigationWidget * pNavigation); + + QTreeWidgetItem * buildNewItem(const QTreeWidgetItem * parent); + + void updateStyleProxy(const ITEM_STYLE_PROXY * proxy); + + void paintEvent(QPaintEvent *event); + + void drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const; + + void contextMenuEvent(QContextMenuEvent *e); + + void read(const QString &strFileName); + + void write(const QString &strFileName); + + QString hexTo26(int number); + + int findValue(const QMap &map, const QString &key); + + QString getNodeTypeStr(int type); + int getNodeType(const QString &str); + + QString getEnableStr(int enable); + int getEnable(const QString &str); + + QTreeWidgetItem * findItem(const QString &data, QTreeWidgetItem * parent); + +protected slots: + void itemSelectedChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); + void itemSelected(QTreeWidgetItem *item, int column); + +private: + ITEM_STYLE_PROXY * m_pItemProxy; + CNavigationDelegate * m_pItemDelegate; + Navigation_Mode m_navigationMode; + + QString m_strFileHomePath; + QMap m_mapEnable; + QMap m_mapNodeType; +}; + +#endif // CNAVIGATIONWIDGET_H diff --git a/product/src/gui/plugin/SecondNavigationWidget/NavigationConfigDialog.ui b/product/src/gui/plugin/SecondNavigationWidget/NavigationConfigDialog.ui new file mode 100644 index 00000000..393268d1 --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/NavigationConfigDialog.ui @@ -0,0 +1,1095 @@ + + + NavigationConfigDialog + + + + 0 + 0 + 610 + 575 + + + + 导航栏配置 + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + 3 + + + + + + 60 + 21 + + + + + 60 + 21 + + + + 导入 + + + 导入 + + + false + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 添加节点 + + + + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 删除节点 + + + + + + false + + + + + + + + 18 + 18 + + + + + 21 + 21 + + + + + false + + + + 清空 + + + × + + + false + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 添加子节点 + + + + + + false + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + 插入节点 + + + | + + + false + + + + + + + true + + + false + + + + 导航栏 + + + + + + + + + 60 + 21 + + + + + 60 + 21 + + + + 导出 + + + 导出 + + + false + + + + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + QFrame::Box + + + QFrame::Sunken + + + + + + 背景颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 文字颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + + + 背景颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 文字颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + + + + 鼠标选中: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + 鼠标悬停: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 启用: + + + + + + + + + + + + + + web发布: + + + + + + + + + + + + + + 图标: + + + + + + + 0 + + + + + + 24 + 22 + + + + + 24 + 22 + + + + ... + + + false + + + + + + + + + + + + 操作: + + + + + + + 数据: + + + + + + + 0 + + + 6 + + + + + + 24 + 22 + + + + + 24 + 22 + + + + ... + + + false + + + + + + + + + + + + + + + + + + 项属性: + + + + + + + 节点层级属性: + + + + + + + 节点状态属性: + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + + + + 70 + 21 + + + + + + + + + + + + + + 背景颜色: + + + + + + + + + + 窗口配置: + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 0 + + + + 一级节点 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 级别背景颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 级别文字颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 级别缩进距离: + + + + + + + px + + + + + + + + + + + 二级节点 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 级别背景颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 级别文字颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 级别缩进距离: + + + + + + + px + + + + + + + + + + + 三级节点 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 级别背景颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 级别文字颜色: + + + + + + + + 70 + 21 + + + + + + + + + + + + + + 级别缩进距离: + + + + + + + px + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 246 + 20 + + + + + + + + + 50 + 0 + + + + 取消 + + + false + + + + + + + + 50 + 0 + + + + 确定 + + + false + + + + + + + + + + CColorLabel + QLabel +
CColorLabel.h
+
+ + CSecondNavigationWidget + QTreeWidget +
CSecondNavigationWidget.h
+
+
+ + + + ok + clicked() + NavigationConfigDialog + accept() + + + 485 + 549 + + + 457 + 606 + + + + + cancle + clicked() + NavigationConfigDialog + reject() + + + 568 + 543 + + + 577 + 623 + + + + +
diff --git a/product/src/gui/plugin/SecondNavigationWidget/SecondNavigationResource.qrc b/product/src/gui/plugin/SecondNavigationWidget/SecondNavigationResource.qrc new file mode 100644 index 00000000..78593735 --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/SecondNavigationResource.qrc @@ -0,0 +1,8 @@ + + + image/arrowCollapse.png + image/arrowCollapseHover.png + image/arrowExpand.png + image/arrowExpandHover.png + + diff --git a/product/src/gui/plugin/SecondNavigationWidget/SecondNavigationWidget.pro b/product/src/gui/plugin/SecondNavigationWidget/SecondNavigationWidget.pro new file mode 100644 index 00000000..605a2384 --- /dev/null +++ b/product/src/gui/plugin/SecondNavigationWidget/SecondNavigationWidget.pro @@ -0,0 +1,46 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2018-12-09T00:12:34 +# +#------------------------------------------------- + +QT += core gui printsupport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = SecondNavigationWidget +TEMPLATE = lib + +CONFIG += plugin + +SOURCES += \ + CNavigationDelegate.cpp \ + CColorLabel.cpp \ + CSecondNavigationPluginWidget.cpp \ + CSecondNavigationWidget.cpp \ + CNavigationConfigDialog.cpp + +HEADERS += \ + CNavigationDelegate.h \ + CColorLabel.h \ + CSecondNavigationPluginWidget.h \ + CSecondNavigationWidget.h \ + CNavigationConfigDialog.h + +FORMS += \ + NavigationConfigDialog.ui + +RESOURCES += \ + SecondNavigationResource.qrc + +LIBS += -lpub_utility_api \ + -lpub_excel + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/SecondNavigationWidget/image/arrowCollapse.png b/product/src/gui/plugin/SecondNavigationWidget/image/arrowCollapse.png new file mode 100644 index 00000000..6ec824f4 Binary files /dev/null and b/product/src/gui/plugin/SecondNavigationWidget/image/arrowCollapse.png differ diff --git a/product/src/gui/plugin/SecondNavigationWidget/image/arrowCollapseHover.png b/product/src/gui/plugin/SecondNavigationWidget/image/arrowCollapseHover.png new file mode 100644 index 00000000..6c42ad7f Binary files /dev/null and b/product/src/gui/plugin/SecondNavigationWidget/image/arrowCollapseHover.png differ diff --git a/product/src/gui/plugin/SecondNavigationWidget/image/arrowExpand.png b/product/src/gui/plugin/SecondNavigationWidget/image/arrowExpand.png new file mode 100644 index 00000000..3bbffd97 Binary files /dev/null and b/product/src/gui/plugin/SecondNavigationWidget/image/arrowExpand.png differ diff --git a/product/src/gui/plugin/SecondNavigationWidget/image/arrowExpandHover.png b/product/src/gui/plugin/SecondNavigationWidget/image/arrowExpandHover.png new file mode 100644 index 00000000..4b37825f Binary files /dev/null and b/product/src/gui/plugin/SecondNavigationWidget/image/arrowExpandHover.png differ diff --git a/product/src/gui/plugin/SecondReportWidget/CHeaderView.cpp b/product/src/gui/plugin/SecondReportWidget/CHeaderView.cpp new file mode 100644 index 00000000..dc87ca46 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CHeaderView.cpp @@ -0,0 +1,27 @@ +#include "CHeaderView.h" + +CHeaderView::CHeaderView(Qt::Orientation orientation ,QWidget *parent) +:QHeaderView(orientation,parent) +{ +} +CHeaderView::~CHeaderView() +{ +} + +void CHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const +{ + //就简单几句 + //拿到text数据,在写数据的时候,设置textwordwrap,居中。 + QString textstr = model()->headerData(visualIndex(logicalIndex),Qt::Horizontal).toString(); + painter->save(); + // 从当前样式中获取边框颜色 + QStyleOptionHeader opt; + initStyleOption(&opt); + opt.rect = rect; + opt.section = logicalIndex; + + // 使用样式绘制边框 + style()->drawControl(QStyle::CE_HeaderSection, &opt, painter, this); + painter->drawText(rect,Qt::TextWordWrap | Qt::AlignCenter, textstr); + painter->restore(); +} diff --git a/product/src/gui/plugin/SecondReportWidget/CHeaderView.h b/product/src/gui/plugin/SecondReportWidget/CHeaderView.h new file mode 100644 index 00000000..42d342d2 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CHeaderView.h @@ -0,0 +1,18 @@ +#ifndef CHEADERVIEW_H +#define CHEADERVIEW_H +#include +#include + +class CHeaderView: public QHeaderView +{ + Q_OBJECT + +public: + CHeaderView(Qt::Orientation orientation = Qt::Horizontal,QWidget *parent = nullptr); //这里为了省事,给默认值为水平表头,因为我正好使用水平的表头 + ~CHeaderView(); + +protected: + virtual void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const; +}; + +#endif // CHEADERVIEW_H diff --git a/product/src/gui/plugin/SecondReportWidget/CHisDataManage.cpp b/product/src/gui/plugin/SecondReportWidget/CHisDataManage.cpp new file mode 100644 index 00000000..06b37e63 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CHisDataManage.cpp @@ -0,0 +1,152 @@ +#include "CHisDataManage.h" +#include "public/pub_logger_api/logger.h" +#include + +CHisDataManage::CHisDataManage(QObject *parent) + : QObject(parent) +{ + m_tsdbQuery = new CTsdbQuery(); +} + +void CHisDataManage::release() +{ + if (m_tsdbQuery) + { + delete m_tsdbQuery; + m_tsdbQuery = nullptr; + } +} + +CHisDataManage::~CHisDataManage() +{ + release(); +} + +bool CHisDataManage::queryHisEventByTagNameOriginal(QStringList tagNameList, qint64 timeMsecs, EN_STATIS_MODE mode, std::vector& data) +{ + Q_UNUSED(tagNameList); + Q_UNUSED(timeMsecs); + Q_UNUSED(mode); + Q_UNUSED(data); + + /*QTime time; + time.start(); + iot_dbms::CTsdbConnPtr tsdbConnPtr; + if (!getValidTsdbConnPtr(tsdbConnPtr)) + { + LOGERROR("CHisDataManage: 未获取到有效的TSDB连接!"); + return false; + } + + m_tsdbQuery->SetTagList(tagNameList); + m_tsdbQuery->SetTsdbConnPtr(tsdbConnPtr); + if (!m_tsdbQuery->queryEventByPeriod(startTime, endTime, mode, data)) + { + LOGERROR("CHisDataManage: 查询失败!"); + return false; + } + + LOGINFO("CHisDataManage::queryHisEventStatis() time:%I64u", time.elapsed());*/ + return true; +} + +bool CHisDataManage::queryHisEventByTagNameExtreme(QStringList tagNameList, qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector&data) +{ + QTime time; + time.start(); + iot_dbms::CTsdbConnPtr tsdbConnPtr; + if (!getValidTsdbConnPtr(tsdbConnPtr)) + { + LOGERROR("CHisDataManage: 未获取到有效的TSDB连接!"); + return false; + } + + m_tsdbQuery->SetTagList(tagNameList); + m_tsdbQuery->SetTsdbConnPtr(tsdbConnPtr); + if (!m_tsdbQuery->queryEventByPeriod(startTime, endTime, mode, data)) + { + LOGERROR("CHisDataManage: 查询失败!"); + return false; + } + + LOGINFO("CHisDataManage::queryHisEventStatis() time:%I64u", time.elapsed()); + return true; +} + +bool CHisDataManage::queryHisEventByTagNameExtreme(QStringList tagNameList, qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector>&data) +{ + QTime time; + time.start(); + iot_dbms::CTsdbConnPtr tsdbConnPtr; + if (!getValidTsdbConnPtr(tsdbConnPtr)) + { + LOGERROR("CHisDataManage: 未获取到有效的TSDB连接!"); + return false; + } + + m_tsdbQuery->SetTagList(tagNameList); + m_tsdbQuery->SetTsdbConnPtr(tsdbConnPtr); + if (!m_tsdbQuery->queryEventByPeriod(startTime, endTime, mode, data)) + { + LOGERROR("CHisDataManage: 查询失败!"); + return false; + } + + LOGINFO("CHisDataManage::queryHisEventStatis() time:%I64u", time.elapsed()); + return true; +} + + +bool CHisDataManage::queryHisEventByTagName(QStringList tagNameList, qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector>>&record) +{ + QTime time; + time.start(); + iot_dbms::CTsdbConnPtr tsdbConnPtr; + if (!getValidTsdbConnPtr(tsdbConnPtr)) + { + LOGERROR("CHisDataManage: 未获取到有效的TSDB连接!"); + return false; + } + + m_tsdbQuery->SetTagList(tagNameList); + m_tsdbQuery->SetTsdbConnPtr(tsdbConnPtr); + if (!m_tsdbQuery->queryEventByPeriod(startTime, endTime, mode, record)) + { + LOGERROR("CHisDataManage: 查询失败!"); + return false; + } + + LOGINFO("CHisDataManage::queryHisEventStatis() time:%I64u", time.elapsed()); + return true; +} + +bool CHisDataManage::getValidTsdbConnPtr(iot_dbms::CTsdbConnPtr &ptr) +{ + if (m_tsdbConnPtr != NULL) + { + if (m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + } + else + { + m_tsdbConnPtr = getOneUseableConn(true); + if (m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + else + { + m_tsdbConnPtr = getOneUseableConn(false); + if (m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + } + } + return false; +} diff --git a/product/src/gui/plugin/SecondReportWidget/CHisDataManage.h b/product/src/gui/plugin/SecondReportWidget/CHisDataManage.h new file mode 100644 index 00000000..3e60b0b5 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CHisDataManage.h @@ -0,0 +1,33 @@ +#ifndef CHISEVENTMANAGE_H +#define CHISEVENTMANAGE_H + +#include +#include "CTsdbQuery.h" +#include "CStatisCommon.h" + +class CHisDataManage : public QObject +{ + Q_OBJECT +public: + CHisDataManage(QObject *parent = Q_NULLPTR); + ~CHisDataManage(); + + public slots: + void release(); + //查询某个时间点的原始数据 + bool queryHisEventByTagNameOriginal(QStringList tagNameList, qint64 timeMsecs, EN_STATIS_MODE mode, std::vector&data); + //查询时间段内的最大值、最小值、平均值 + bool queryHisEventByTagNameExtreme(QStringList tagNameList, qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector&data); + bool queryHisEventByTagNameExtreme(QStringList tagNameList, qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector>&data); + //查询时间段内的时间点和对应的数据 + bool queryHisEventByTagName(QStringList tagNameList, qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector>>&record); + +private: + bool getValidTsdbConnPtr(iot_dbms::CTsdbConnPtr &ptr); + +private: + iot_dbms::CTsdbConnPtr m_tsdbConnPtr; + CTsdbQuery* m_tsdbQuery; +}; + +#endif // CHISEVENTMANAGE_H diff --git a/product/src/gui/plugin/SecondReportWidget/CMainWindow.cpp b/product/src/gui/plugin/SecondReportWidget/CMainWindow.cpp new file mode 100644 index 00000000..10f007ef --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CMainWindow.cpp @@ -0,0 +1,276 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CMainWindow.h" +#include "CTrendTreeItem.h" +#include "CTrendTreeView.h" +#include "CTrendTreeModel.h" +#include "CTrendInfoManage.h" +#include "CReportFavTreeWidget.h" +#include "CSecondReportWidget.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" +#include + +CMainWindow::CMainWindow(bool editMode, QWidget *parent) + : QWidget(parent), + ui(new Ui::CMainWindow), + m_bEditMode(editMode), + m_pTagWidget(Q_NULLPTR), + m_pSecReportWidget(Q_NULLPTR), + m_pTagTreeView(Q_NULLPTR), + m_pTrendTreeModel(Q_NULLPTR), + m_pSearchButton(Q_NULLPTR), + m_pSearchTextEdit(Q_NULLPTR) +{ + ui->setupUi(this); + this->showMaximized(); + + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss"); + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("trendCurves.qss"); + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + qssfile2.close(); + } + + setStyleSheet(qss); + + clearChildren(); + initWindow(); +} + +CMainWindow::~CMainWindow() +{ + delete ui; +} + +void CMainWindow::initialize(const int& mode) +{ + Q_UNUSED(mode); +} + +void CMainWindow::slotTagCheckedChanged(const QString & strTagName, const int & checkedState) +{ + if (Qt::Checked == (Qt::CheckState)checkedState) + { + m_pSecReportWidget->addTag(strTagName); + } + else if (Qt::Unchecked == (Qt::CheckState)checkedState) + { + m_pSecReportWidget->removeTag(strTagName); + } +} + +void CMainWindow::slotRefreshTagInfo() +{ + m_pTrendTreeModel->initTrendTagInfo(); +} + +void CMainWindow::login() +{ + if(m_pTrendTreeModel) + { + m_pTrendTreeModel->initTrendTagInfo(); + } +} + +void CMainWindow::logout() +{ + if(m_pTrendTreeModel) + { + m_pTrendTreeModel->clearTrendTagInfo(); + } +} + +bool CMainWindow::isFavQueryAction() +{ + + if(m_pTagWidget->currentIndex()==1) + { + if(ui->pFavoritesTreeWidget->selectedItems().isEmpty()) + { + QMessageBox::information(this, "提示", "请先选择要查询的报表"); + } + else + { + ui->pFavoritesTreeWidget->slotShowReport(); + } + + return true; + } + else + { + return false; + } + +} + +void CMainWindow::judgeQuery() +{ + if(!isFavQueryAction()) + { + ui->m_pSecReportWidget->slotSearchBtnClicked(); + } +} + +void CMainWindow::initWindow() +{ + m_pTagWidget = ui->m_pTagWidget; + m_pTagWidget->setTabPosition(QTabWidget::North); + + m_pTagTreeView = ui->m_pTagTreeView; + m_pTagTreeView->header()->hide(); + connect(m_pTagTreeView, &CTrendTreeView::refreshTagInfo, this, &CMainWindow::slotRefreshTagInfo); + + m_pTrendTreeModel = new CTrendTreeModel(this, m_pTagTreeView); + m_pTagTreeView->setModel(m_pTrendTreeModel); + m_pTagTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_pTagTreeView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + + m_pSearchTextEdit = ui->searchTextEdit; + m_pSearchTextEdit->setObjectName("searchTextEdit"); + m_pSearchButton = ui->searchButton; + m_pSearchButton->setObjectName("searchButton"); + m_pClearButton = ui->clearButton; + m_pClearButton->setObjectName("clearButton"); + connect(m_pSearchTextEdit, &QLineEdit::returnPressed, this, &CMainWindow::FindTagName); + connect(m_pSearchButton, &QPushButton::clicked, this, &CMainWindow::FindTagName); + + + CReportFavTreeWidget * pFavoritesTreeWidget = ui->pFavoritesTreeWidget; + pFavoritesTreeWidget->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + m_pTagWidget->setCurrentIndex(0); + + m_pSecReportWidget = ui->m_pSecReportWidget; + m_pSecReportWidget->initialize(); + + QSplitter * m_pSplitter = ui->m_pSplitter; + m_pSplitter->setStretchFactor(0, 2); + m_pSplitter->setStretchFactor(1, 3); + //m_pSplitter->setContentsMargins(6, 6, 6, 6); + m_pSplitter->setHandleWidth(10); + + connect(m_pClearButton, &QPushButton::clicked, m_pSecReportWidget, &CSecondReportWidget::removeAllTag); + connect(m_pClearButton, &QPushButton::clicked, m_pTrendTreeModel, &CTrendTreeModel::clearCheckState); + //connect(pFavoritesTreeWidget, &CReportFavTreeWidget::showReport, m_pSecReportWidget, &CSecondReportWidget::slotShowReport); + connect(pFavoritesTreeWidget, &CReportFavTreeWidget::showMsg, m_pSecReportWidget, &CSecondReportWidget::slotShowMsg); + connect(m_pSecReportWidget, &CSecondReportWidget::sigDetectReport, pFavoritesTreeWidget, &CReportFavTreeWidget::collectReport); + connect(m_pSecReportWidget, &CSecondReportWidget::sigUpdateTagCheckState, m_pTrendTreeModel, &CTrendTreeModel::updateTagCheckState); + connect(m_pSecReportWidget, &CSecondReportWidget::sigClearCheckState, m_pTrendTreeModel, &CTrendTreeModel::clearCheckState); + connect(m_pTrendTreeModel, &CTrendTreeModel::itemCheckStateChanged, this, &CMainWindow::slotTagCheckedChanged); + connect(pFavoritesTreeWidget, &CReportFavTreeWidget::showReport, m_pSecReportWidget, &CSecondReportWidget::slotShowReport); //显示收藏夹中收藏的趋势图 + connect(pFavoritesTreeWidget, &CReportFavTreeWidget::clearReport, m_pSecReportWidget, &CSecondReportWidget::slotClearReport); + + connect(m_pSecReportWidget,&CSecondReportWidget::sigSearchBtnClicked,this,&CMainWindow::judgeQuery); + + + if(!m_bEditMode) + { + m_pTagWidget->installEventFilter(this); + m_pTagWidget->tabBar()->installEventFilter(this); + m_pTagTreeView->viewport()->installEventFilter(this); + m_pTagTreeView->header()->viewport()->installEventFilter(this); + m_pSearchTextEdit->installEventFilter(this); + m_pSearchButton->installEventFilter(this); + pFavoritesTreeWidget->viewport()->installEventFilter(this); + pFavoritesTreeWidget->header()->viewport()->installEventFilter(this); + } + + qRegisterMetaType("SReport"); +} + +void CMainWindow::initWidget() +{ + clearChildren(); + if(m_pTrendTreeModel) + { + m_pTrendTreeModel->clearTrendTagInfo(); + } +} + +void CMainWindow::clearChildren() +{ + if (m_pTrendTreeModel) + { + delete m_pTrendTreeModel; + } + m_pTrendTreeModel = Q_NULLPTR; +} + +void CMainWindow::itemCheckStateChanged(const QString & strTagName, const int & checkedState) +{ + Q_UNUSED(strTagName); + + if (Qt::Checked == (Qt::CheckState)checkedState) + { + //m_plotWidget->insertTag(strTagName); + } + else if (Qt::Unchecked == (Qt::CheckState)checkedState) + { + //m_plotWidget->removeTag(strTagName); + } +} + +//void CMainWindow::updateTrendName(const QString & title) +//{ +// //m_plotWidget->setTitle(title); +//} + +//void CMainWindow::showTrendGraph(CTrendGraph * graph, const QString & name) +//{ +//} + +void CMainWindow::FindTagName() +{ + QString content = m_pSearchTextEdit->text(); + m_pTagTreeView->collapseAll(); + m_pTagTreeView->selectionModel()->clear(); + QItemSelection selection; + m_pTrendTreeModel->updateNodeVisualState(content, selection); + m_pTagTreeView->selectionModel()->select(selection, QItemSelectionModel::Select); + + if (content.isEmpty()) + { + m_pTagTreeView->collapseAll(); + } + else + { + m_pTagTreeView->expandAll(); + } +} + +void CMainWindow::mousePressEvent(QMouseEvent * event) +{ + Q_UNUSED(event); +} + +bool CMainWindow::eventFilter(QObject * watched, QEvent * event) +{ + Q_UNUSED(watched); + Q_UNUSED(event); + + return false; +} + + diff --git a/product/src/gui/plugin/SecondReportWidget/CMainWindow.h b/product/src/gui/plugin/SecondReportWidget/CMainWindow.h new file mode 100644 index 00000000..e241edab --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CMainWindow.h @@ -0,0 +1,68 @@ +#pragma once +#include +#include "ui_CMainWindow.h" + +class QSplitter; +class QTreeView; +class QLineEdit; +class QTabWidget; +class CSecondReportWidget; +class CTrendGraph; +class QPushButton; +class CTrendTreeView; +class CTrendTreeModel; + +enum E_Trend_Mode +{ + E_Trend_Window = 0, + E_Trend_Widget = 1 +}; + +namespace Ui { +class CMainWindow; +} + +class CMainWindow : public QWidget +{ + Q_OBJECT + +public: + explicit CMainWindow(bool editMode, QWidget *parent = 0); + ~CMainWindow(); + +public slots: + void initialize(const int& mode); + void slotTagCheckedChanged(const QString &strTagName, const int &checkedState); + void slotRefreshTagInfo(); + void login(); + void logout(); + + bool isFavQueryAction(); + void judgeQuery(); +protected: + void initWindow(); + void initWidget(); + + void clearChildren(); + + void itemCheckStateChanged(const QString &strTagName, const int &checkedState); + //void updateTrendName(const QString &title); + //void showTrendGraph(CTrendGraph * graph, const QString &name = QString()); + void FindTagName(); + + void mousePressEvent(QMouseEvent *event); + bool eventFilter(QObject *watched, QEvent *event); + + +private: + Ui::CMainWindow* ui; + bool m_bEditMode; + + QTabWidget * m_pTagWidget; + CSecondReportWidget * m_pSecReportWidget; + CTrendTreeView * m_pTagTreeView; + CTrendTreeModel * m_pTrendTreeModel; + QPushButton * m_pSearchButton; + QLineEdit * m_pSearchTextEdit; + QPushButton * m_pClearButton; +}; diff --git a/product/src/gui/plugin/SecondReportWidget/CMainWindow.ui b/product/src/gui/plugin/SecondReportWidget/CMainWindow.ui new file mode 100644 index 00000000..d340ab6f --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CMainWindow.ui @@ -0,0 +1,136 @@ + + + CMainWindow + + + + 0 + 0 + 849 + 524 + + + + CMainWindow + + + + + + Qt::Horizontal + + + + 0 + + + + 设备/点 + + + + + + + 0 + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + + + + 清除测点 + + + + + + + + 收藏夹 + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + 0 + 0 + + + + + + + + + + CTrendTreeView + QWidget +
CTrendTreeView.h
+ 1 +
+ + CReportFavTreeWidget + QWidget +
CReportFavTreeWidget.h
+ 1 +
+ + CSecondReportWidget + QWidget +
CSecondReportWidget.h
+ 1 +
+
+ + +
diff --git a/product/src/gui/plugin/SecondReportWidget/CProcessManage.cpp b/product/src/gui/plugin/SecondReportWidget/CProcessManage.cpp new file mode 100644 index 00000000..8bf7754d --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CProcessManage.cpp @@ -0,0 +1,364 @@ +#include "CProcessManage.h" +#include "CTrendInfoManage.h" + +CProcessManage::CProcessManage(QObject *parent) + : QObject(parent) +{ + m_pHisDataManage = new CHisDataManage(this); +} + +CProcessManage::~CProcessManage() +{ + m_pHisDataManage->release(); + m_pHisDataManage->deleteLater(); +} + +void CProcessManage::setTimeList(QList> timeList) +{ + m_timeList = timeList; +} + +void CProcessManage::setSearchFlag(bool flag) +{ + m_bSearchFlag = flag; +} + +void CProcessManage::searchReportByUserDefined(QStringList tagList, QDateTime startTime, QDateTime endTime, int timeLag, bool isSum) +{ + if (timeLag == LAG_ALL) + { + qint64 startTimeInt = startTime.toMSecsSinceEpoch(); + qint64 endTimeInt = endTime.toMSecsSinceEpoch(); + int length = tagList.size(); + std::vector>record; + + //查询测点在时间段内的历史数据原始值 + std::vector>>oriData; + bool ret = m_pHisDataManage->queryHisEventByTagName(tagList, startTimeInt, endTimeInt, MODE_NULL, oriData); + if (!ret) + { + emit updateResult((int)ERROR_QUERY_INFLUXDB_FAILD, record); + return; + } + + std::vector> oriDataMap; + QSet timesTampSet; + convertVectorToMap(oriData,oriDataMap,timesTampSet); + std::vector timesTampVec(timesTampSet.begin(), timesTampSet.end()); + std::sort(timesTampVec.begin(), timesTampVec.end()); + //查询测点在时间段内的历史数据最大值 + std::vector>maxData; + maxData.resize(length); + ret = m_pHisDataManage->queryHisEventByTagNameExtreme(tagList, startTimeInt, endTimeInt, MODE_MAX, maxData); + if (!ret) + { + emit updateResult((int)ERROR_QUERY_INFLUXDB_FAILD, record); + return; + } + + //查询测点在时间段内的历史数据最小值 + std::vector>minData; + minData.resize(length); + ret = m_pHisDataManage->queryHisEventByTagNameExtreme(tagList, startTimeInt, endTimeInt, MODE_MIN, minData); + if (!ret) + { + emit updateResult((int)ERROR_QUERY_INFLUXDB_FAILD, record); + return; + } + + //查询测点在时间段内的历史数据平均值 + std::vector>meanData; + meanData.resize(length); + ret = m_pHisDataManage->queryHisEventByTagNameExtreme(tagList, startTimeInt, endTimeInt, MODE_MEAN, meanData); + if (!ret) + { + emit updateResult((int)ERROR_QUERY_INFLUXDB_FAILD, record); + return; + } + + //获取数据最多的测点的数据数量 +// int max = 0; +// int max_index = 0; +// for (int i = 0; i < oriData.size(); i++) +// { +// if (max < oriData[i].size()) +// { +// max = oriData[i].size(); +// max_index = i; +// } +// } + + if(timesTampVec.size() == 0) + { + emit updateResult((int)ERROR_NO_DATA, record); + return; + } + + //表格列数为测点数+1,行数为最大测点数据数量+3 + int rowCount = static_cast(timesTampVec.size() + 3); + int colCount = length + 1; + + record.resize(rowCount); + for (int i = 0; i < rowCount; i++) + { + record[i].resize(colCount); + } + + //填充数据 + for (int col = 0; col < colCount; col++) + { + for (int row = 0; row < rowCount; row++) + { + QString str = ""; + //第一列为表头,显示时间,后面的显示数据 + if (col == 0) + { + if (row < rowCount - 3) + { + //取数据最多的测点的数据对应的时间点作为每一行的开头 + QDateTime time_temp = QDateTime::fromMSecsSinceEpoch(timesTampVec[row]); + str = time_temp.toString("yyyy-MM-dd HH:mm:ss"); + } + else if (row == rowCount - 3) + { + //最后三行为 最大值、最小值、平均值 + str = tr("最大值"); + } + else if (row == rowCount - 2) + { + str = tr("最小值"); + } + else if (row == rowCount - 1) + { + str = tr("平均值"); + } + } + else + { + if (row < rowCount - 3) + { + //str = QString::number(oriData[col - 1][row].second, 'f', 2); + auto it=oriDataMap[col - 1].find(timesTampVec[row]); + if(it!=oriDataMap[col - 1].end()) + { + str = QString::number(it->second, 'f', 2); + } + else + { + str = QString("-"); + } + + } + else if (row == rowCount - 3) + { + //最后三行为 最大值、最小值、平均值 + if(maxData[col - 1].first==VALID_VS) + { + str = QString::number(maxData[col - 1].second, 'f', 2); + } + else + { + str = QString("-"); + } + + } + else if (row == rowCount - 2) + { + if (minData[col - 1].first == VALID_VS) + { + str = QString::number(minData[col - 1].second, 'f', 2); + } + else + { + str = QString("-"); + } + } + else if (row == rowCount - 1) + { + if (meanData[col - 1].first == VALID_VS) + { + str = QString::number(meanData[col - 1].second, 'f', 2); + } + else + { + str = QString("-"); + } + } + //else + //{ + // str = "--"; + //} + } + + record[row][col] = str; + } + } + emit updateResult((int)ERROR_OK, record); + } + else + { + searchReportByTimeList(tagList, m_timeList, isSum); + } +} + +void CProcessManage::searchReportByTradType(QStringList tagList, int type, QDate date, bool isSum) +{ + Q_UNUSED(type); + Q_UNUSED(date); + + searchReportByTimeList(tagList, m_timeList, isSum); +} + +void CProcessManage::searchReportByTimeList(QStringList tagList, QList> timeList, bool isSum) +{ + + std::vector>record; + qint64 start = 0; //查询开始时间 + qint64 end = 0; //查询结束时间 + int length = m_timeList.length(); //时间列表长度 + bool ret = false; + + if (length < 3) + { + emit updateResult((int)ERROR_NO_DATA, record); + return; + } + + std::vector>> allData; + + for (int row = 0; row < length - 3; row++) + { + if(m_bSearchFlag == false) + { + emit updateResult((int)ERROR_SEARCH_TERMINATED, record); + return; + } + + start = m_timeList[row].first.toMSecsSinceEpoch(); + end = m_timeList[row].second.toMSecsSinceEpoch(); + + std::vector>data; + data.resize(tagList.size()); + ret = m_pHisDataManage->queryHisEventByTagNameExtreme(tagList, start, end, MODE_NULL, data); + if (ret) + { + allData.push_back(data); + } + else + { + emit updateResult((int)ERROR_QUERY_INFLUXDB_FAILD, record); + return; + } + } + + std::vector minValue(tagList.size(), 0.0); + std::vector maxValue(tagList.size(), 0.0); + std::vector lastValue(tagList.size(), 0.0); + std::vector sumValue(tagList.size(), 0.0); + std::vectorrecord_temp; + for (int row = 0; row < length-3; row++) + { + start = m_timeList[row].first.toMSecsSinceEpoch(); + end = m_timeList[row].second.toMSecsSinceEpoch(); + + record_temp.clear(); + record_temp.push_back(m_timeList[row].first.addSecs(5 * 30).toString("yyyy-MM-dd HH:mm:ss")); + for (int i = 0; i < allData[row].size(); i++) + { + if(allData[row][i].first==VALID_VS) + { + double curData = allData[row][i].second; + double maxData = maxValue[i]; + double minData = minValue[i]; + double lastData = lastValue[i]; + double sumData = sumValue[i]; + + double retData; + if (!isSum) + { + retData = curData; + } + else + { + if (row == 0) + { + lastData = curData; + } + + retData = curData - lastData; + lastValue[i] = curData; + } + + if (row == 0) + { + maxValue[i] = retData; + minValue[i] = retData; + } + else + { + if (retData > maxData) + { + maxValue[i] = retData; + } + + if (retData < minData) + { + minValue[i] = retData; + } + } + + sumValue[i] = sumData + retData; + + record_temp.push_back(QString::number(retData, 'f', 2)); + } + else + { + record_temp.push_back(QString("-")); + } + + } + + record.push_back(record_temp); + } + + record_temp.clear(); + record_temp.push_back(tr("最大值")); + for (int i = 0; i < maxValue.size(); i++) + { + record_temp.push_back(QString::number(maxValue[i], 'f', 2)); + } + record.push_back(record_temp); + + record_temp.clear(); + record_temp.push_back(tr("最小值")); + for (int i = 0; i < minValue.size(); i++) + { + record_temp.push_back(QString::number(minValue[i], 'f', 2)); + } + record.push_back(record_temp); + + record_temp.clear(); + record_temp.push_back(tr("平均值")); + for (int i = 0; i < sumValue.size(); i++) + { + record_temp.push_back(QString::number(sumValue[i]/ (length - 3), 'f', 2)); + } + record.push_back(record_temp); + + emit updateResult((int)ERROR_OK, record); +} + +void CProcessManage::convertVectorToMap(const std::vector>> &record, std::vector> &result, QSet ×Tamp ) +{ + //第一维度的record和result等同索引 + + for (const auto& innerVector : record) { + std::map currentTable; + for (const auto& pair : innerVector) { + currentTable[pair.first]=pair.second; + timesTamp.insert(pair.first); + } + result.push_back(currentTable); + } + +} diff --git a/product/src/gui/plugin/SecondReportWidget/CProcessManage.h b/product/src/gui/plugin/SecondReportWidget/CProcessManage.h new file mode 100644 index 00000000..52c38607 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CProcessManage.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +class CProcessManage : public QObject +{ + Q_OBJECT + +public: + CProcessManage(QObject *parent = Q_NULLPTR); + ~CProcessManage(); + + //设置查询时间列表 + void setTimeList(QList> timeList); + void setSearchFlag(bool flag); + +public slots: + //按照自定义方式查询报表(测点列表、开始时间、结束时间、时间间隔、表格对应model + void searchReportByUserDefined(QStringList tagList, QDateTime startTime, QDateTime endTime, int timeLag, bool isSum); + + //按照传统方式查询报表(测点列表、查询方式、查询时间、表格对应model + void searchReportByTradType(QStringList tagList, int type, QDate date, bool isSum); + +private: + void searchReportByTimeList(QStringList tagList, QList>timeList,bool isSum); + void convertVectorToMap(const std::vector>>& record,std::vector>& result, QSet ×Tamp); + + +signals: + void updateResult(int errorCode, std::vector>record); + +private: + CHisDataManage* m_pHisDataManage; + QList> m_timeList; + + bool m_bSearchFlag = true; + + + +}; diff --git a/product/src/gui/plugin/SecondReportWidget/CReportFavTreeWidget.cpp b/product/src/gui/plugin/SecondReportWidget/CReportFavTreeWidget.cpp new file mode 100644 index 00000000..0414ebb0 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CReportFavTreeWidget.cpp @@ -0,0 +1,385 @@ +#include "CReportFavTreeWidget.h" +//#include "CReportEditDialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "perm_mng_api/PermMngApi.h" +#include "pub_utility_api/FileUtil.h" + +//< 趋势编辑 权限定义 +#define FUNC_NOM_Report_EDIT ("FUNC_NOM_Report_EDIT") + +CReportFavTreeWidget::CReportFavTreeWidget(QWidget *parent) + : QTreeWidget(parent) +{ + setColumnCount(1); + setHeaderLabel(tr("收藏夹")); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setEditTriggers(EditKeyPressed); + connect(this, &CReportFavTreeWidget::doubleClicked, this, &CReportFavTreeWidget::slotShowReport); + connect(this, &CReportFavTreeWidget::itemChanged, this, &CReportFavTreeWidget::slotItemChanged); + setObjectName("CReportFavTreeWidget"); + loadReport(); + setEditTriggers(NoEditTriggers); +} + +CReportFavTreeWidget::~CReportFavTreeWidget() +{ + saveReport(); + qDeleteAll(m_reportMap); + m_reportMap.clear(); +} + +void CReportFavTreeWidget::collectReport(SReport *report) +{ + bool ok; + QString title = QInputDialog::getText(this, tr("报表管理"), tr("请输入收藏报表名称"), QLineEdit::Normal, getNewValidTitle(), &ok); + if(ok) + { + if(title.isEmpty()) + { + emit showMsg(tr("报表名不能为空!")); + return; + } + + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + if(topLevelItem(nIndex)->text(0) == title ) + { + //QMessageBox::warning(this, tr("错误"), tr("当前收藏报表名称已存在!"), QMessageBox::Ok); + emit showMsg(tr("当前收藏报表名称已存在!")); + delete report; + report = Q_NULLPTR; + return; + } + } + + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << title, Item_REPORT_Type); + item->setFlags(item->flags() | Qt::ItemIsEditable); + addTopLevelItem(item); + m_reportMap.insert(item, report); + saveReport(); + } +} + +void CReportFavTreeWidget::contextMenuEvent(QContextMenuEvent *event) +{ + //< 权限处理--暂不处理 +// bool bIsEditable = false; +// iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); +// if(permMngPtr == NULL) +// { +// return; +// } + +// permMngPtr->PermDllInit(); +// std::string tmp = FUNC_NOM_Report_EDIT; +// if (PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) +// { +// bIsEditable = true; +// } + + QMenu menu; + QTreeWidgetItem * item = itemAt(event->pos()); + + if(!item) + { +// QAction * importAction = new QAction(tr("导入"), &menu); +// menu.addAction(importAction); +// connect(importAction, SIGNAL(triggered()), this, SLOT(slotImport())); + } + else + { + if(Item_REPORT_Type == item->type()) + { +// QAction * showAction = new QAction(tr("显示"), &menu); +// menu.addAction(showAction); +// connect(showAction, SIGNAL(triggered()), this, SLOT(slotShowReport())); + +// QAction * editAction = new QAction(tr("编辑"), &menu); +// menu.addAction(editAction); +// connect(editAction, SIGNAL(triggered()), this, SLOT(slotEditReportEdit())); + + QAction * renameAction = new QAction(tr("重命名"), &menu); + menu.addAction(renameAction); + connect(renameAction, &QAction::triggered, this, [&]() { + m_strEditItemContent = item->text(0); + if(m_strEditItemContent.isEmpty()) + { + emit showMsg(tr("报表名不能为空!")); + } + else + { + editItem(item); + } + }); + + QAction * deleteAction = new QAction(tr("删除"), &menu); + menu.addAction(deleteAction); + connect(deleteAction, SIGNAL(triggered()), this, SLOT(slotRemoveReportEdit())); + +// QAction * exportAction = new QAction(tr("导出"), &menu); +// menu.addAction(exportAction); +// connect(exportAction, SIGNAL(triggered()), this, SLOT(slotExport())); + } + } + + menu.exec(event->globalPos()); +} + +void CReportFavTreeWidget::mouseDoubleClickEvent(QMouseEvent *event) +{ + QModelIndex index = indexAt(event->pos()); + QTreeWidgetItem * pItem = static_cast(index.internalPointer()); + if(Q_NULLPTR == pItem) + { + return; + } + + if(Item_REPORT_Type != pItem->type()) + { + return; + } + + slotShowReport(); +} + +//void CReportFavTreeWidget::slotNewReportEdit() +//{ +// QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << getNewValidTitle(), Item_REPORT_Type); +// item->setFlags(item->flags() | Qt::ItemIsEditable); +// addTopLevelItem(item); +// editItem(item); +// saveReport(); +//} + +void CReportFavTreeWidget::slotShowReport() +{ + if(m_reportMap.contains(currentItem())) + { + emit showReport(m_reportMap.value(currentItem())); + } +} + +//void CReportFavTreeWidget::slotEditReportEdit() +//{ +// CReportEditDialog *dlg = new CReportEditDialog(this); + +// if(m_reportMap.contains(currentItem())) +// { +// dlg->setReport(m_reportMap.value(currentItem())); +// } +// if(QDialog::Accepted == dlg->exec()) +// { +// SReport * report = dlg->Report(); +// m_reportMap.insert(currentItem(), report); +// saveReport(); +// } + +// delete dlg; +// dlg = NULL; +//} + +void CReportFavTreeWidget::slotRemoveReportEdit() +{ + QList selectItem = selectedItems(); + foreach (QTreeWidgetItem *item, selectItem) { + int index = indexOfTopLevelItem(item); + takeTopLevelItem(index); + } + saveReport(); + emit clearReport(); +} + +void CReportFavTreeWidget::slotItemChanged(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column) + QString content = item->text(0); + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + QTreeWidgetItem *temp = topLevelItem(nIndex); + if( temp != item && temp->text(0) == content ) + { + //QMessageBox::warning(this, tr("错误"), tr("当前报表名称已存在!"), QMessageBox::Ok); + emit showMsg(tr("当前报表名称已存在!")); + item->setText(0, m_strEditItemContent); + return; + } + } +} + +void CReportFavTreeWidget::slotImport() +{ + QString filePath = QFileDialog::getOpenFileName(this, tr("选择报表收藏文件"), QString(), "*.xml"); + if(filePath.isEmpty()) + { + return; + } + loadReport(filePath); + saveReport(); +} + +void CReportFavTreeWidget::slotExport() +{ + QString filePath = QFileDialog::getSaveFileName(this, tr("保存报表收藏文件"), QString("ReportFav.xml"), "*.xml"); + if(filePath.isEmpty()) + { + return; + } + + QList selectItem = selectedItems(); + if(selectItem.isEmpty()) + { + return; + } + + saveReport(filePath, selectItem); +} + +QString CReportFavTreeWidget::getNewValidTitle() +{ + QString title = QString(tr("收藏报表_")); + QStringList listItemText; + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + listItemText << topLevelItem(nIndex)->text(0); + } + int serial = 0; + while(listItemText.contains(title + QString::number(serial))) + { + serial++; + } + return title + QString::number(serial); +} + +void CReportFavTreeWidget::loadReport(const QString &filePath) +{ + QDomDocument document; + QString strFileName; + if(filePath.isEmpty()) + { + strFileName = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/Report.xml"); + } + else + { + strFileName = filePath; + } + QFile file(strFileName); + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement root = document.documentElement(); + if(!root.isNull()) + { + QDomNodeList NodeList = root.elementsByTagName("report"); + for(int Index(0); Index < NodeList.size(); Index++) + { + QDomNode Node = NodeList.at(Index); + if(!Node.isNull()) + { + QDomElement Element = Node.toElement(); + if(!Element.isNull()) + { + QString name = Element.attribute("name", QString()); + QTreeWidgetItem * Item = new QTreeWidgetItem(QStringList() << name, Item_REPORT_Type); + Item->setFlags(Item->flags() | Qt::ItemIsEditable); + + SReport* report = new SReport(); + QDomNodeList tagNodeList = Element.elementsByTagName("tag"); + for(int nTagIndex(0); nTagIndex < tagNodeList.size(); nTagIndex++) + { + QDomNode tagNode = tagNodeList.at(nTagIndex); + QDomElement tagElement = tagNode.toElement(); + if(!tagElement.isNull()) + { + report->tagList.append(tagElement.attribute("tag_name")); + } + } + + report->startTime = QDateTime::fromString(Element.attribute("start_time", QString()), "yyyy-MM-dd hh:mm:ss"); + report->endTime = QDateTime::fromString(Element.attribute("end_time", QString()), "yyyy-MM-dd hh:mm:ss"); + report->statType = Element.attribute("stat_type").toInt(); + report->timeLag = Element.attribute("time_lag").toInt(); + report->isSum = Element.attribute("sum_state").toInt() == 1; + + m_reportMap.insert(Item, report); + addTopLevelItem(Item); + } + } + } + } +} + +void CReportFavTreeWidget::saveReport(const QString &filePath, const QList &itemList) +{ + QFile file; + if(!filePath.isEmpty()) + { + file.setFileName(filePath); + } + else + { + QString strReportDir = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + QString("../../data/model"); + QDir dir; + if(!dir.exists(strReportDir)) + { + dir.mkdir(strReportDir); + } + QString strReportFile = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/Report.xml"); + file.setFileName(strReportFile); + } + + if(file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + QDomDocument document; + + QString strHeader("version='1.0' encoding='utf-8'"); + document.appendChild(document.createProcessingInstruction("xml", strHeader)); + QDomElement root = document.createElement("Profile"); + int nCount = itemList.isEmpty()? topLevelItemCount():itemList.length(); + for(int nIndex(0); nIndex < nCount; nIndex++) + { + QTreeWidgetItem * item = itemList.isEmpty()? topLevelItem(nIndex):itemList.at(nIndex); + QDomElement Node = document.createElement("report"); + Node.setAttribute("name", item->text(0)); + + if(m_reportMap.contains(item)) + { + QStringList tagList = m_reportMap.value(item)->tagList; + for(int nTagIndex(0); nTagIndex < tagList.size(); nTagIndex++) + { + QDomElement tag = document.createElement("tag"); + tag.setAttribute("tag_name", tagList.at(nTagIndex)); + Node.appendChild(tag); + } + + Node.setAttribute("start_time", m_reportMap.value(item)->startTime.toString("yyyy-MM-dd hh:mm:ss")); + Node.setAttribute("end_time", m_reportMap.value(item)->endTime.toString("yyyy-MM-dd hh:mm:ss")); + Node.setAttribute("time_lag", QString::number(m_reportMap.value(item)->timeLag)); + Node.setAttribute("stat_type", QString::number(m_reportMap.value(item)->statType)); + Node.setAttribute("sum_state", QString::number(m_reportMap.value(item)->isSum)); + } + root.appendChild(Node); + } + document.appendChild(root); + + QTextStream content(&file); + document.save(content, 4); + } + file.close(); +} diff --git a/product/src/gui/plugin/SecondReportWidget/CReportFavTreeWidget.h b/product/src/gui/plugin/SecondReportWidget/CReportFavTreeWidget.h new file mode 100644 index 00000000..886fb01a --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CReportFavTreeWidget.h @@ -0,0 +1,52 @@ +#ifndef CREPORTFAVTREEWIDGET_H +#define CREPORTFAVTREEWIDGET_H + +#include +#include "CStatisCommon.h" + +enum E_Tree_ItemType +{ + Item_REPORT_Type = QTreeWidgetItem::UserType + 1, + Item_TAG_Type, +}; + +class CReportFavTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + explicit CReportFavTreeWidget(QWidget *parent = nullptr); + ~CReportFavTreeWidget(); + +signals: + void showReport(SReport *report); + void showMsg(QString msg); + void clearReport(); + +public slots: + void collectReport(SReport *report); + //void detectReport(SReport& report); + void slotShowReport(); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + +protected slots: + //void slotNewReportEdit(); + //void slotEditReportEdit(); + void slotRemoveReportEdit(); + void slotItemChanged(QTreeWidgetItem *item, int column); + void slotImport(); + void slotExport(); + +private: + QString getNewValidTitle(); + void loadReport(const QString& filePath = QString()); + void saveReport(const QString& filePath = QString(), const QList& itemList = QList()); + +private: + QMap m_reportMap; + QString m_strEditItemContent; + +}; +#endif // CREPORTFAVTREEWIDGET_H diff --git a/product/src/gui/plugin/SecondReportWidget/CReportTableView.cpp b/product/src/gui/plugin/SecondReportWidget/CReportTableView.cpp new file mode 100644 index 00000000..71217967 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CReportTableView.cpp @@ -0,0 +1,88 @@ +#include "CReportTableView.h" +#include +#include "pub_utility_api/I18N.h" +#include + +CReportTableView::CReportTableView(QWidget *parent) + : QTableView(parent) +{ + + +} + +int CReportTableView::tableColumnWidth() +{ + return m_nTableColWidth; +} + +void CReportTableView::setTableColumnWidth(const int &nWidth) +{ + m_nTableColWidth = nWidth; + + horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); +} + +int CReportTableView::tableRowHeight() +{ + return m_nTableRowHeight; +} + +void CReportTableView::setTableRowHeight(const int &nHeight) +{ + m_nTableRowHeight = nHeight; + + verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); +} +void CReportTableView::showEvent(QShowEvent *event){ + QTableView::showEvent(event); + adjustHeaderWidth(); +} + + +// 自动调整表头宽度以适应文本 +void CReportTableView::adjustHeaderWidth() { + QHeaderView *header = horizontalHeader(); + int sections = header->count(); + int maxWidth = 0; + QFontMetrics fm(header->font()); + const std::string strLanguage = std::move( iot_public::getCurLanguage()); + int maxWidthThreshold; + if(strLanguage == "zh") + { + maxWidthThreshold = 200; // 设置换行的阈值 + } + else if(strLanguage == "en") + { + maxWidthThreshold = 400; // 设置换行的阈值 + } + + + for (int i = 0; i < sections; ++i) { + QString text = model()->headerData(i, Qt::Horizontal).toString(); + int width = fm.width(text) + 10; // 加上一些额外空间 + maxWidth = qMax(maxWidth, width); + } + + int heightBase=30; + int heightCount=1; + for (int i = 0; i < sections; ++i) { + QString text = model()->headerData(i, Qt::Horizontal).toString(); + int width = fm.width(text) + 20; // 加上一些额外空间 + // 如果宽度超过阈值,则换行 + if (width > maxWidthThreshold) { + header->resizeSection(i, maxWidthThreshold); + qreal tmpHeightCount=qreal(width)/qreal(maxWidthThreshold); + if(tmpHeightCount>heightCount){ + heightCount=qCeil(tmpHeightCount); + } + } else { + if(i==0) + { + maxWidth=210; + } + header->resizeSection(i, maxWidth); + heightCount=2; + } + } + header->setFixedHeight(heightCount*heightBase); +} diff --git a/product/src/gui/plugin/SecondReportWidget/CReportTableView.h b/product/src/gui/plugin/SecondReportWidget/CReportTableView.h new file mode 100644 index 00000000..22a5b24d --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CReportTableView.h @@ -0,0 +1,29 @@ +#ifndef CREPORTTABLEVIEW_H +#define CREPORTTABLEVIEW_H +#include + +class CReportTableView: public QTableView +{ + Q_OBJECT + Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) + Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) + +public: + CReportTableView(QWidget *parent = Q_NULLPTR); + + int tableColumnWidth(); + void setTableColumnWidth(const int &nWidth); + + int tableRowHeight(); + void setTableRowHeight(const int &nHeight); + void adjustHeaderWidth(); + +protected: + void showEvent(QShowEvent *event) override ; + +private: + int m_nTableColWidth; + int m_nTableRowHeight; +}; + +#endif // CREPORTTABLEVIEW_H diff --git a/product/src/gui/plugin/SecondReportWidget/CSecondReportPluginWidget.cpp b/product/src/gui/plugin/SecondReportWidget/CSecondReportPluginWidget.cpp new file mode 100644 index 00000000..c2da7aa4 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CSecondReportPluginWidget.cpp @@ -0,0 +1,29 @@ +#include "CMainWindow.h" +#include "CSecondReportPluginWidget.h" + +CSecondReportPluginWidget::CSecondReportPluginWidget(QObject* parent) : QObject(parent) +{ + +} + + +CSecondReportPluginWidget::~CSecondReportPluginWidget() +{ + +} + +bool CSecondReportPluginWidget::createWidget(QWidget * parent, bool editMode, QWidget ** widget, IPluginWidget ** pMainWindow, QVector ptrVec) +{ + Q_UNUSED(ptrVec); + CMainWindow *pWidget = new CMainWindow(editMode, parent); + pWidget->initialize(E_Trend_Window); + *widget = (QWidget *)pWidget; + *pMainWindow = (IPluginWidget *)pWidget; + return true; +} + +void CSecondReportPluginWidget::release() +{ + +} + diff --git a/product/src/gui/plugin/SecondReportWidget/CSecondReportPluginWidget.h b/product/src/gui/plugin/SecondReportWidget/CSecondReportPluginWidget.h new file mode 100644 index 00000000..1da1f70d --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CSecondReportPluginWidget.h @@ -0,0 +1,16 @@ +#include +#include "GraphShape/CPluginWidget.h" + +class CSecondReportPluginWidget :public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) + Q_INTERFACES(CPluginWidgetInterface) + +public: + CSecondReportPluginWidget(QObject* parent = 0); + ~CSecondReportPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pSecondReportWidget, QVector ptrVec); + void release(); +}; diff --git a/product/src/gui/plugin/SecondReportWidget/CSecondReportWidget.cpp b/product/src/gui/plugin/SecondReportWidget/CSecondReportWidget.cpp new file mode 100644 index 00000000..4b9928e7 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CSecondReportWidget.cpp @@ -0,0 +1,1900 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CSecondReportWidget.h" +#include "public/pub_logger_api/logger.h" +#include "pub_utility_api/I18N.h" +#include "CTrendInfoManage.h" +#include "CStatisCommon.h" +#include "CHeaderView.h" + +CSecondReportWidget::CSecondReportWidget(QWidget *parent) + : QWidget(parent), + ui(new Ui::CSecondReportWidgetClass), + m_pHisDataManage(Q_NULLPTR), + m_pReportModel(Q_NULLPTR), +// m_pStartLabel(Q_NULLPTR), +// m_pEndLabel(Q_NULLPTR), +// m_pOriLabel(Q_NULLPTR), +// m_pTimeLagLabel(Q_NULLPTR), +// m_pStartDate(Q_NULLPTR), +// m_pEndDate(Q_NULLPTR), +// m_pOriDate(Q_NULLPTR), +// m_pTimeLag(Q_NULLPTR), +// m_pPage1Btn(Q_NULLPTR), +// m_pPage2Btn(Q_NULLPTR), +// m_pPage3Btn(Q_NULLPTR), +// m_pPage4Btn(Q_NULLPTR), +// m_pPage5Btn(Q_NULLPTR), +// m_pPageUpBtn(Q_NULLPTR), +// m_pPageDownBtn(Q_NULLPTR), + m_pSearchProgress(Q_NULLPTR), + m_pWaittingDlg(Q_NULLPTR) +{ + ui->setupUi(this); + setLayout(ui->verticalLayout); + +// m_nCurPageIndex = 0; +// m_nReportCount = 0; +// m_nPageCount = 0; +// m_nReportCountPerPage = 0; +// m_nSearchIndexStart = 0; +// m_nSearchIndexEnd = 0; +// m_nBtnStartIndex = 0; + m_nSearchSeconds = 0; +} + +CSecondReportWidget::~CSecondReportWidget() +{ + if (m_pProcessManage) + { + m_pProcessManage->deleteLater(); + m_pProcessManage = Q_NULLPTR; + } + + if (m_pThread) + { + m_pThread->quit(); + m_pThread->wait(); + m_pThread->deleteLater(); + m_pThread = Q_NULLPTR; + } +} + +void CSecondReportWidget::initialize() +{ + m_pBtnGroup = new QButtonGroup(this); + m_pBtnGroup->addButton(ui->btnYear, 0); + m_pBtnGroup->addButton(ui->btnMonth, 1); + m_pBtnGroup->addButton(ui->btnDay, 2); + m_pBtnGroup->addButton(ui->btnUser, 3); + connect(m_pBtnGroup, SIGNAL(buttonToggled(int, bool)), this, SLOT(slotReportTypeChanged(int,bool))); + + QDate date = QDate::currentDate(); + for(int i = 0; i <= 10; i++) + { + ui->box_start_year->addItem(QString::number(date.year() - i)); + ui->box_end_year->addItem(QString::number(date.year() - i)); + } + + for(int i = 1; i <= 12; i++) + { + ui->box_start_month->addItem(QString::number(i)); + ui->box_end_month->addItem(QString::number(i)); + } + + for(int i = 1; i <= 31; i++) + { + ui->box_start_day->addItem(QString::number(i)); + ui->box_end_day->addItem(QString::number(i)); + } + + for(int i = 0; i <= 23; i++) + { + ui->box_start_hour->addItem(QString::number(i)); + ui->box_end_hour->addItem(QString::number(i)); + } + + for(int i = 0; i <= 59; i++) + { + ui->box_start_minute->addItem(QString::number(i)); + ui->box_end_minute->addItem(QString::number(i)); + } + + connect(ui->box_start_year, SIGNAL(activated(int)), this, SLOT(slotStartYearActivated(int))); + connect(ui->box_start_month, SIGNAL(activated(int)), this, SLOT(slotStartMonthActivated(int))); + connect(ui->box_start_day, SIGNAL(activated(int)), this, SLOT(slotStartDayActivated(int))); + connect(ui->box_start_hour, SIGNAL(activated(int)), this, SLOT(slotStartHourActivated(int))); + connect(ui->box_end_year, SIGNAL(activated(int)), this, SLOT(slotEndYearActivated(int))); + connect(ui->box_end_month, SIGNAL(activated(int)), this, SLOT(slotEndMonthActivated(int))); + connect(ui->box_end_day, SIGNAL(activated(int)), this, SLOT(slotEndDayActivated(int))); + connect(ui->box_end_hour, SIGNAL(activated(int)), this, SLOT(slotEndHourActivated(int))); + + ui->btnDay->setChecked(true); + ui->box_start_year->setCurrentText(QString::number(date.year())); + ui->box_end_year->setCurrentText(QString::number(date.year())); + setStartDateTimeToUi(QDateTime::currentDateTime()); + setEndDateTimeToUi(QDateTime::currentDateTime()); + + ui->timeLag->setCurrentIndex(3); + + m_pReportModel = new QStandardItemModel(ui->report); + ui->report->setModel(m_pReportModel); + ui->report->horizontalHeader()->setDefaultSectionSize(350); + ui->report->verticalHeader()->setVisible(false); + ui->report->setAlternatingRowColors(true); + + ui->report->setHorizontalHeader(new CHeaderView(Qt::Horizontal,ui->report)); + ui->report->horizontalHeader()->setVisible(true); + connect(ui->report->horizontalHeader(),&QHeaderView::sectionCountChanged,ui->report,&CReportTableView::adjustHeaderWidth); + + + //connect(ui->serach, &QPushButton::clicked, this, &CSecondReportWidget::slotSearchBtnClicked); + connect(ui->serach, &QPushButton::clicked, this, &CSecondReportWidget::slotSpreadOutSide); +// m_pPageUpBtn = new QPushButton("<"); +// m_pPageDownBtn = new QPushButton(">"); +// m_pPage1Btn = new QPushButton("1"); +// m_pPage2Btn = new QPushButton("2"); +// m_pPage3Btn = new QPushButton("3"); +// m_pPage4Btn = new QPushButton("4"); +// m_pPage5Btn = new QPushButton("5"); +// ui->pageBtns->addWidget(m_pPageUpBtn); +// ui->pageBtns->addWidget(m_pPage1Btn); +// ui->pageBtns->addWidget(m_pPage2Btn); +// ui->pageBtns->addWidget(m_pPage3Btn); +// ui->pageBtns->addWidget(m_pPage4Btn); +// ui->pageBtns->addWidget(m_pPage5Btn); +// ui->pageBtns->addWidget(m_pPageDownBtn); + +// connect(m_pPageUpBtn, &QPushButton::clicked, this, &CSecondReportWidget::slotPageUpBtnClicked); +// connect(m_pPageDownBtn, &QPushButton::clicked, this, &CSecondReportWidget::slotPageDownBtnClicked); +// connect(m_pPage1Btn, &QPushButton::clicked, this, &CSecondReportWidget::slotPage1BtnClicked); +// connect(m_pPage2Btn, &QPushButton::clicked, this, &CSecondReportWidget::slotPage2BtnClicked); +// connect(m_pPage3Btn, &QPushButton::clicked, this, &CSecondReportWidget::slotPage3BtnClicked); +// connect(m_pPage4Btn, &QPushButton::clicked, this, &CSecondReportWidget::slotPage4BtnClicked); +// connect(m_pPage5Btn, &QPushButton::clicked, this, &CSecondReportWidget::slotPage5BtnClicked); +// connect(ui->curPage, &QSpinBox::editingFinished, this, &CSecondReportWidget::slotPageJump); + +// ui->numPerPage->setCurrentIndex(0); +// connect(ui->numPerPage, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCountPerPageChanged(int))); + +// updatePageBtns(); + +// 查询时间超过三秒时显示 查询中...标签 +// m_pSearchProgress = new QLabel(this); +// QRect rect = ui->report->geometry(); +// int x = rect.x() + rect.width() / 2 - 150; +// int y = rect.y() + rect.height() / 2 - 20; +// m_pSearchProgress->setGeometry(QRect(x, y, 300, 40)); +// m_pSearchProgress->setText(""); +// QFont font; +// font.setPointSize(20); +// m_pSearchProgress->setFont(font); +// m_pSearchProgress->hide(); + +// ui->curPage->hide(); +// ui->label_2->hide(); +// ui->label_5->hide(); +// ui->numPerPage->hide(); +// m_pPageUpBtn->hide(); +// m_pPageDownBtn->hide(); +// m_pPage1Btn->hide(); +// m_pPage2Btn->hide(); +// m_pPage3Btn->hide(); +// m_pPage4Btn->hide(); +// m_pPage5Btn->hide(); +// ui->numPerPage->setCurrentIndex(3); + + iot_dbms::initTsdbApi(); + m_pHisDataManage = new CHisDataManage(this); + + connect(ui->detect, &QPushButton::clicked, this, &CSecondReportWidget::slotDetectReport); + connect(ui->exportHeader, &QPushButton::clicked, this, &CSecondReportWidget::slotExportHeader); + connect(ui->exportTable, &QPushButton::clicked, this, &CSecondReportWidget::slotExportReport); + connect(ui->importHeader, &QPushButton::clicked, this, &CSecondReportWidget::slotImportHeader); + + ui->msgText->setStyleSheet("border:2px solid;border-color:rgb(2,60,101);font:微软雅黑 12pt;"); + ui->msgText->hide(); + + initProcessManage(); + + //信号和槽函数的参数过于复杂可能无法响应 + qRegisterMetaType>>(); + qRegisterMetaType>>(); +} + +ReportType CSecondReportWidget::getCurReportType() +{ + if (ui->btnYear->isChecked()) + return REPORT_YEAR; + + if (ui->btnMonth->isChecked()) + return REPORT_MONTH; + + if (ui->btnDay->isChecked()) + return REPORT_DAY; + + if (ui->btnUser->isChecked()) + return REPORT_USER_DEFINED; + + return static_cast(-1); +} + +void CSecondReportWidget::addTag(const QString & tag, const bool & resetTitle) +{ + Q_UNUSED(resetTitle); + + m_tagList.push_back(tag); +} + +void CSecondReportWidget::addTag(const QStringList & listTag, const bool & resetTitle) +{ + foreach(QString tag, listTag) + { + addTag(tag, resetTitle); + } +} + +void CSecondReportWidget::removeTag(const QString & tag, const bool & resetTitle) +{ + Q_UNUSED(resetTitle); + + int index = m_tagList.indexOf(tag); + m_tagList.removeAt(index); +} + +void CSecondReportWidget::removeAllTag() +{ + for (int i = m_tagList.size() - 1; i >= 0; --i) + { + m_tagList.removeAt(i); + } +} + +void CSecondReportWidget::initProcessManage() +{ + iot_dbms::initTsdbApi(); + + m_pProcessManage = new CProcessManage(); + m_pThread = new QThread(); + m_pProcessManage->moveToThread(m_pThread); + + connect(m_pThread, &QThread::finished, m_pThread, &QObject::deleteLater); + connect(this, &CSecondReportWidget::sigQueryByUserDef, m_pProcessManage, &CProcessManage::searchReportByUserDefined); + connect(this, &CSecondReportWidget::sigQueryByTradType, m_pProcessManage, &CProcessManage::searchReportByTradType); + connect(m_pProcessManage, &CProcessManage::updateResult, this, &CSecondReportWidget::slotUpdateResult); + + m_pThread->start(); +} + +bool CSecondReportWidget::getTimeList() +{ + m_timeList.clear(); + + QPairtime_temp; + switch (getCurReportType()) + { + case REPORT_YEAR: + { + //获取用户输入的查询日期 + QDate date = getDateFromUi(); + //从1月-12月 + QDateTime date_time; + for (int i = 1; i <= 12; i++) + { + //取每月1号0时作为查询点 + date_time.setDate(QDate(date.year(), i, 1)); + date_time.setTime(QTime(0, 0, 0, 0)); + time_temp.first = date_time.addSecs(-5 * 30); + time_temp.second = date_time.addSecs(5 * 30); + m_timeList.append(time_temp); + } + + //时间段的起始时间 + date_time.setDate(QDate(date.year(), 1, 1)); + date_time.setTime(QTime(0, 0, 0, 0)); + time_temp.first = date_time; + + //时间段的结束时间 + date_time.setDate(QDate(date.year(), 12, date.daysInMonth())); + date_time.setTime(QTime(23, 59, 59, 999)); + time_temp.second = date_time; + } + break; + case REPORT_MONTH: + { + QDate date = getDateFromUi(); + //从1号到本月最后一天 + QDateTime date_time; + for (int i = 1; i <= date.daysInMonth(); i++) + { + date_time.setDate(QDate(date.year(), date.month(), i)); + date_time.setTime(QTime(0, 0, 0, 0)); + time_temp.first = date_time.addSecs(-5 * 30); + time_temp.second = date_time.addSecs(5 * 30); + m_timeList.append(time_temp); + } + + //时间段的起始时间 + date_time.setDate(QDate(date.year(), date.month(), 1)); + date_time.setTime(QTime(0, 0, 0, 0)); + time_temp.first = date_time; + + //时间段的结束时间 + date_time.setDate(QDate(date.year(), date.month(), date.daysInMonth())); + date_time.setTime(QTime(23, 59, 59, 999)); + time_temp.second = date_time; + } + break; + case REPORT_DAY: + { + QDate date = getDateFromUi(); + //从0时到23时 + QDateTime date_time; + for (int i = 0; i < 24; i++) + { + date_time.setDate(date); + date_time.setTime(QTime(i, 0, 0, 0)); + time_temp.first = date_time.addSecs(-5 * 30); + time_temp.second = date_time.addSecs(5 * 30); + m_timeList.append(time_temp); + } + + //时间段的起始时间 + date_time.setDate(date); + date_time.setTime(QTime(0, 0, 0, 0)); + time_temp.first = date_time; + + //时间段的结束时间 + date_time.setDate(date); + date_time.setTime(QTime(23, 59, 59, 999)); + time_temp.second = date_time; + } + break; + case REPORT_USER_DEFINED: + { + QDateTime time_start = getStartDateTimeFromUi(); + QDateTime time_end = getEndDateTimeFromUi(); + qint64 time_start_int64 = time_start.toSecsSinceEpoch(); + qint64 time_end_int64 = time_end.toSecsSinceEpoch(); + if (time_start_int64 > time_end_int64) + { + slotShowMsg(tr("结束时间晚于开始时间,请调整时间之后再查询!")); + return false; + } + + qint64 lag_secs = 0; + switch (ui->timeLag->currentIndex()) + { + case LAG_YEAR: + { + lag_secs = 24 * 60 * 60 * time_start.date().daysInYear(); + break; + } + case LAG_MONTH: + { + lag_secs = 24 * 60 * 60 * time_start.date().daysInMonth(); + break; + } + case LAG_DAY: + { + lag_secs = 24 * 60 * 60; + break; + } + case LAG_HOUR: + { + lag_secs = 60 * 60; + break; + } + case LAG_30_MIN: + { + lag_secs = 30 * 60; + break; + } + case LAG_15_MIN: + { + lag_secs = 15 * 60; + break; + } + case LAG_ALL: + { + lag_secs = 5 * 60; + break; + } + default: + { + lag_secs = 60 * 60; + break; + } + } + + QDateTime time_t = time_start; + while (time_start_int64 <= time_end_int64) + { + time_temp.first = time_t.addSecs(-5 * 30); + time_temp.second = time_t.addSecs(5 * 30); + m_timeList.append(time_temp); + time_t = time_t.addSecs(lag_secs); + time_start_int64 = time_t.toSecsSinceEpoch(); + } + + //时间段的起始时间 + time_temp.first = time_start; + + //时间段的结束时间 + time_temp.second = time_end; + } + break; + default: + { + break; + } + } + + //最大值\最小值\平均值 + m_timeList.append(time_temp); + m_timeList.append(time_temp); + m_timeList.append(time_temp); + + //m_nPageCount = m_timeList.size(); + //ui->curPage->setMinimum(1); + //ui->curPage->setMaximum(m_nPageCount); + + return true; +} + +//int CSecondReportWidget::getDataCountPerPage() +//{ +// int count = 0; +// switch (ui->numPerPage->currentIndex()) +// { +// case 0:count = 10; break; +// case 1:count = 50; break; +// case 2:count = 100; break; +// case 3:count = 1000; break; +// default:count = 1000; break; +// } + +// return count; +//} + +void CSecondReportWidget::showData(QStringList & rowNames, QStringList & header, std::vector>& data) +{ + m_pReportModel->clear(); + m_pReportModel->setColumnCount(header.size() + 1); + m_pReportModel->setRowCount(rowNames.size()); + const std::string strLanguage = std::move( iot_public::getCurLanguage()); + + //设置横向表头 + m_pReportModel->setHeaderData(0, Qt::Horizontal, ""); + for (int i = 0; i < header.size(); i++) + { + //表头标题用测点描述填充 + m_pReportModel->setHeaderData(i + 1, Qt::Horizontal, CTrendInfoManage::instance()->getTagDescription(header[i])); + } + + for (int r = 0; r < m_pReportModel->rowCount(); r++) + { + QStandardItem* item = new QStandardItem(rowNames[r]); + item->setTextAlignment(Qt::AlignHCenter); + item->setEditable(false); + m_pReportModel->setItem(r, 0, item); + + for (int c = 1; c < m_pReportModel->columnCount(); c++) + { + QStandardItem* item_ = new QStandardItem(QString::number(data.at(r).at(c - 1), 'f', 2)); + if(strLanguage == "en" && c == 1) + item_->setTextAlignment(Qt::AlignLeft); + else + item_->setTextAlignment(Qt::AlignHCenter); + item_->setEditable(false); + m_pReportModel->setItem(r, c, item_); + } + } + + ui->report->update(); +} + +//void CSecondReportWidget::updatePageCountUI() +//{ +// ui->pageCount->setText("共" + QString::number(m_nPageCount) + "页"); +//} + +//void CSecondReportWidget::updatePageBtns() +//{ +// switch (m_nPageCount) +// { +// case 1: +// { +// m_pPageUpBtn->hide(); +// m_pPageDownBtn->hide(); +// m_pPage1Btn->hide(); +// m_pPage2Btn->hide(); +// m_pPage3Btn->hide(); +// m_pPage4Btn->hide(); +// m_pPage5Btn->hide(); +// break; +// } +// case 2: +// { +// m_pPageUpBtn->hide(); +// m_pPageDownBtn->hide(); +// m_pPage1Btn->show(); +// m_pPage2Btn->show(); +// m_pPage3Btn->hide(); +// m_pPage4Btn->hide(); +// m_pPage5Btn->hide(); +// break; +// } +// case 3: +// { +// m_pPageUpBtn->hide(); +// m_pPageDownBtn->hide(); +// m_pPage1Btn->show(); +// m_pPage2Btn->show(); +// m_pPage3Btn->show(); +// m_pPage4Btn->hide(); +// m_pPage5Btn->hide(); +// break; +// } +// case 4: +// { +// m_pPageUpBtn->hide(); +// m_pPageDownBtn->hide(); +// m_pPage1Btn->show(); +// m_pPage2Btn->show(); +// m_pPage3Btn->show(); +// m_pPage4Btn->show(); +// m_pPage5Btn->hide(); +// break; +// } +// case 5: +// { +// m_pPageUpBtn->hide(); +// m_pPageDownBtn->hide(); +// m_pPage1Btn->show(); +// m_pPage2Btn->show(); +// m_pPage3Btn->show(); +// m_pPage4Btn->show(); +// m_pPage5Btn->show(); +// break; +// } +// default: +// { +// m_pPageUpBtn->hide(); +// m_pPageDownBtn->hide(); +// m_pPage1Btn->hide(); +// m_pPage2Btn->hide(); +// m_pPage3Btn->hide(); +// m_pPage4Btn->hide(); +// m_pPage5Btn->hide(); +// break; +// } +// } +//} + +//void CSecondReportWidget::updatePageBtnsText() +//{ +// m_pPage1Btn->setText(QString::number(m_nBtnStartIndex)); +// m_pPage2Btn->setText(QString::number(m_nBtnStartIndex + 1)); +// m_pPage3Btn->setText(QString::number(m_nBtnStartIndex + 2)); +// m_pPage4Btn->setText(QString::number(m_nBtnStartIndex + 3)); +// m_pPage5Btn->setText(QString::number(m_nBtnStartIndex + 4)); +//} + +//void CSecondReportWidget::searchData() +//{ +// QStringList time_list_str; //表格第一列,时间点 +// std::vector>data; +// std::vectordata_temp; +// qint64 start = 0; //查询开始时间 +// qint64 end = 0; //查询结束时间 +// int length = m_timeList.length(); //时间列表长度 +// bool ret = false; +// for (int row = m_nSearchIndexStart; row <= m_nSearchIndexEnd; row++) +// { +// start = m_timeList[row].first.toMSecsSinceEpoch(); +// end = m_timeList[row].second.toMSecsSinceEpoch(); +// data_temp.clear(); +// data_temp.resize(m_tagList.size()); + +// if (row < length - 3) +// { +// ret = m_pHisDataManage->queryHisEventByTagName(m_tagList, start, end, MODE_NULL, data_temp); +// time_list_str.append(m_timeList[row].first.addSecs(5 * 30).toString("yyyy-MM-dd HH:mm:ss")); +// } +// else if (row == length - 3) +// { +// ret = m_pHisDataManage->queryHisEventByTagName(m_tagList, start, end, MODE_MAX, data_temp); +// time_list_str.append("最大值"); +// } +// else if (row == length - 2) +// { +// ret = m_pHisDataManage->queryHisEventByTagName(m_tagList, start, end, MODE_MIN, data_temp); +// time_list_str.append("最小值"); +// } +// else if (row == length - 1) +// { +// ret = m_pHisDataManage->queryHisEventByTagName(m_tagList, start, end, MODE_MEAN, data_temp); +// time_list_str.append("平均值"); +// } + +// if (ret) +// { +// data.push_back(data_temp); +// } +// else +// { +// QMessageBox::warning(this, "查询提示", "查询数据失败"); +// } +// } + +// showData(time_list_str, m_tagList, data); +//} + +//void CSecondReportWidget::pageBtnProcess(int btnIndex) +//{ +// if (m_nCurPageIndex == m_nBtnStartIndex + btnIndex) +// { +// return; +// } + +// //getTimeList(); + +// int count = getDataCountPerPage(); +// int length = m_timeList.length(); +// //显示全部数据,则只有一页 +// if (count == 1000) +// { +// m_nSearchIndexStart = 0; +// m_nSearchIndexEnd = length - 1; +// m_nPageCount = 1; +// m_nBtnStartIndex = 1; +// m_nCurPageIndex = 1; +// } +// else +// { +// //如果count由变大了,页数也会发生变化,如果当前页不存在,则显示第一页 +// if (count * ((m_nBtnStartIndex + btnIndex) - 1) > length) +// { +// m_nCurPageIndex = 1; +// m_nBtnStartIndex = 1; +// } +// else +// { +// m_nCurPageIndex = m_nBtnStartIndex + btnIndex; +// } + +// //起始序号为当前区的第一页 +// m_nSearchIndexStart = count * ((m_nBtnStartIndex + btnIndex) - 1); +// //结束序号如果超过了数据列表长度,则取列表长度 +// if (count * (m_nBtnStartIndex + btnIndex) <= length) +// { +// m_nSearchIndexEnd = count * (m_nBtnStartIndex + btnIndex) - 1; +// } +// else +// { +// m_nSearchIndexEnd = length - 1; +// } + +// //计算总页数,向上取整 +// if (length%count == 0) +// { +// m_nPageCount = length / count; +// } +// else +// { +// m_nPageCount = length / count + 1; +// } +// } + +// searchData(); + +// updatePageCountUI(); +// updatePageBtns(); +// updatePageBtnsText(); +//} + +QDate CSecondReportWidget::getDateFromUi() +{ + int year = ui->box_start_year->currentText().toInt(); + int month = ui->box_start_month->currentText().toInt(); + int day = ui->box_start_day->currentText().toInt(); + + return QDate (year, month, day); +} + +void CSecondReportWidget::setDateToUi(QDate date) +{ + if(date > QDate::currentDate()) + { + return; + } + + if(date.year() < QDate::currentDate().year() - 10) + { + return; + } + + ui->box_start_year->setCurrentText(QString::number(date.year())); + ui->box_start_month->setCurrentText(QString::number(date.month())); + ui->box_start_day->setCurrentText(QString::number(date.day())); +} + +QDateTime CSecondReportWidget::getStartDateTimeFromUi() +{ + int year = ui->box_start_year->currentText().toInt(); + int month = ui->box_start_month->currentText().toInt(); + int day = ui->box_start_day->currentText().toInt(); + int hour = ui->box_start_hour->currentText().toInt(); + int minute = ui->box_start_minute->currentText().toInt(); + + QDateTime time; + time.setDate(QDate(year, month, day)); + time.setTime(QTime(hour, minute, 0)); + return time; +} + +void CSecondReportWidget::setStartDateTimeToUi(QDateTime time) +{ + QDateTime cTime = QDateTime::currentDateTime(); + if(time > cTime) + { + return; + } + + if(time.date().year() < cTime.date().year() - 10) + { + return; + } + +// if(time > getEndDateTimeFromUi()) +// { +// return; +// } + + ui->box_start_year->setCurrentText(QString::number(time.date().year())); + ui->box_start_month->setCurrentText(QString::number(time.date().month())); + ui->box_start_day->setCurrentText(QString::number(time.date().day())); + ui->box_start_hour->setCurrentText(QString::number(time.time().hour())); + ui->box_start_minute->setCurrentText(QString::number(time.time().minute())); +} + +QDateTime CSecondReportWidget::getEndDateTimeFromUi() +{ + int year = ui->box_end_year->currentText().toInt(); + int month = ui->box_end_month->currentText().toInt(); + int day = ui->box_end_day->currentText().toInt(); + int hour = ui->box_end_hour->currentText().toInt(); + int minute = ui->box_end_minute->currentText().toInt(); + + QDateTime time; + time.setDate(QDate(year, month, day)); + time.setTime(QTime(hour, minute, 0)); + return time; +} + +void CSecondReportWidget::setEndDateTimeToUi(QDateTime time) +{ + QDateTime cTime = QDateTime::currentDateTime(); + if(time > cTime) + { + return; + } + + if(time.date().year() < cTime.date().year() - 10) + { + return; + } + +// if(time < getStartDateTimeFromUi()) +// { +// return; +// } + + ui->box_end_year->setCurrentText(QString::number(time.date().year())); + ui->box_end_month->setCurrentText(QString::number(time.date().month())); + ui->box_end_day->setCurrentText(QString::number(time.date().day())); + ui->box_end_hour->setCurrentText(QString::number(time.time().hour())); + ui->box_end_minute->setCurrentText(QString::number(time.time().minute())); +} + +void CSecondReportWidget::slotSearchBtnClicked() +{ + m_pReportModel->clear(); + + if(m_tagList.empty()) + { + //QMessageBox::information(this, tr("报表管理"), tr("未选择测点,请选择测点之后再查询报表!")); + slotShowMsg(tr("未选择测点,请选择测点之后再查询报表!")); + return; + } + + if(!getTimeList()) + { + return; + } + + if(m_timeList.size() > 10000) + { + slotShowMsg(tr("暂不支持10000条以上数据的查询,请调整查询时间或时间间隔之后再查询!")); + return; + } + + m_pProcessManage->setTimeList(m_timeList); + m_pProcessManage->setSearchFlag(true); + + m_pTimer = new QTimer(this); + m_pTimer->setInterval(300); + m_pTimer->setSingleShot(true); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(slotSearchTimeout())); + m_pTimer->start(); + m_bIsSearching = true; + ui->serach->setEnabled(false); + + bool isSum = ui->sumCheck->isChecked(); + + if (getCurReportType() == REPORT_USER_DEFINED) + { + emit sigQueryByUserDef( + m_tagList, + getStartDateTimeFromUi(), + getEndDateTimeFromUi(), + (int)ui->timeLag->currentIndex(), + isSum + ); + } + else + { + emit sigQueryByTradType( + m_tagList, + (int)getCurReportType(), + getDateFromUi(), + isSum + ); + } + + ////查询时间段内全部数据 + //if (getCurReportType() == REPORT_USER_DEFINED && m_pTimeLag->currentIndex()==6) + //{ + // QDateTime startTime = m_pStartDate->dateTime(); + // QDateTime endTime = m_pEndDate->dateTime(); + // qint64 startTimeInt = startTime.toMSecsSinceEpoch(); + // qint64 endTimeInt = endTime.toMSecsSinceEpoch(); + // int length = m_tagList.size(); + + // //查询测点在时间段内的历史数据原始值 + // std::vector>>record; + // bool ret = m_pHisDataManage->queryHisEventByTagName(m_tagList, startTimeInt, endTimeInt, MODE_NULL, record); + // if (!ret) + // { + // QMessageBox::warning(this, "查询提示", "查询失败"); + // return; + // } + + // //查询测点在时间段内的历史数据最大值 + // std::vectormaxData; + // maxData.resize(length); + // ret = m_pHisDataManage->queryHisEventByTagName(m_tagList, startTimeInt, endTimeInt, MODE_MAX, maxData); + // if (!ret) + // { + // QMessageBox::warning(this, "查询提示", "查询失败"); + // return; + // } + + // //查询测点在时间段内的历史数据最小值 + // std::vectorminData; + // minData.resize(length); + // ret = m_pHisDataManage->queryHisEventByTagName(m_tagList, startTimeInt, endTimeInt, MODE_MIN, minData); + // if (!ret) + // { + // QMessageBox::warning(this, "查询提示", "查询失败"); + // return; + // } + + // //查询测点在时间段内的历史数据平均值 + // std::vectormeanData; + // meanData.resize(length); + // ret = m_pHisDataManage->queryHisEventByTagName(m_tagList, startTimeInt, endTimeInt, MODE_MEAN, meanData); + // if (!ret) + // { + // QMessageBox::warning(this, "查询提示", "查询失败"); + // return; + // } + + // //获取数据最多的测点的数据数量 + // int max = 0; + // int max_index = 0; + // for (int i = 0; i < record.size(); i++) + // { + // if (max < record[i].size()) + // { + // max = record[i].size(); + // max_index = i; + // } + // } + + // //表格列数为测点数+1,行数为最大测点数据数量+3 + // int rowCount = max + 3; + // int colCount = length + 1; + // m_pReportModel->clear(); + // m_pReportModel->setColumnCount(colCount); + // m_pReportModel->setRowCount(rowCount); + + // //填充表头 + // m_pReportModel->setHeaderData(0, Qt::Horizontal, ""); + // for (int i = 0; i < m_tagList.size(); i++) + // { + // //表头标题用测点描述填充 + // m_pReportModel->setHeaderData(i + 1, Qt::Horizontal, CTrendInfoManage::instance()->getTagDescription(m_tagList[i])); + // } + + // //填充数据 + // for (int col = 0; col < colCount; col++) + // { + // for (int row = 0; row < rowCount; row++) + // { + // QStandardItem* item_temp = Q_NULLPTR; + // //第一列为表头,显示时间,后面的显示数据 + // if (col == 0) + // { + // if (row < rowCount - 3) + // { + // //取数据最多的测点的数据对应的时间点作为每一行的开头 + // QDateTime time_temp = QDateTime::fromMSecsSinceEpoch(record[max_index][row].first); + // item_temp = new QStandardItem(time_temp.toString("yyyy-MM-dd HH:mm:ss")); + // } + // else if (row == rowCount - 3) + // { + // //最后三行为 最大值、最小值、平均值 + // item_temp = new QStandardItem("最大值"); + // } + // else if (row == rowCount - 2) + // { + // item_temp = new QStandardItem("最小值"); + // } + // else if (row == rowCount - 1) + // { + // item_temp = new QStandardItem("平均值"); + // } + // } + // else + // { + // if (row < record[col - 1].size()) + // { + // item_temp = new QStandardItem(QString::number(record[col - 1][row].second, 'f', 2)); + // } + // else if (row == rowCount - 3) + // { + // //最后三行为 最大值、最小值、平均值 + // item_temp = new QStandardItem(QString::number(maxData[col - 1], 'f', 2)); + // } + // else if (row == rowCount - 2) + // { + // item_temp = new QStandardItem(QString::number(minData[col - 1], 'f', 2)); + // } + // else if (row == rowCount - 1) + // { + // item_temp = new QStandardItem(QString::number(meanData[col - 1], 'f', 2)); + // } + // else + // { + // item_temp = new QStandardItem("--"); + // } + // } + + // item_temp->setTextAlignment(Qt::AlignHCenter); + // item_temp->setEditable(false); + // m_pReportModel->setItem(row, col, item_temp); + // } + // } + //} + //else + //{ + // getTimeList(); + + // //去掉分页功能后,默认显示全部,但是分页机制保留了,代码并没有去掉 + // int count = getDataCountPerPage(); + // int length = m_timeList.length(); + // if (count == 1000) + // { + // m_nSearchIndexStart = 0; + // m_nSearchIndexEnd = length - 1; + // m_nPageCount = 1; + // } + // else + // { + // m_nSearchIndexStart = 0; + // m_nSearchIndexEnd = count - 1; + // if (length%count == 0) + // { + // m_nPageCount = length / count; + // } + // else + // { + // m_nPageCount = length / count + 1; + // } + // } + + // m_nCurPageIndex = 1; + // m_nBtnStartIndex = 1; + + // searchData(); + //} + + ////updatePageCountUI(); + ////updatePageBtns(); + ////updatePageBtnsText(); +} + +void CSecondReportWidget::slotReportTypeChanged(int index, bool state) +{ + if(state) + { + if(index == REPORT_USER_DEFINED) + { + ui->label_startTime->setText(tr("开始时间")); + + ui->box_start_year->show(); + ui->label_start_year->show(); + ui->box_start_month->show(); + ui->label_start_month->show(); + ui->box_start_day->show(); + ui->label_start_day->show(); + ui->box_start_hour->show(); + ui->box_start_minute->show(); + ui->label_start_hour->show(); + ui->label_start_minute->show(); + + ui->label_endTime->show(); + ui->box_end_year->show(); + ui->box_end_month->show(); + ui->box_end_day->show(); + ui->box_end_hour->show(); + ui->box_end_minute->show(); + ui->label_end_year->show(); + ui->label_end_month->show(); + ui->label_end_day->show(); + ui->label_end_hour->show(); + ui->label_end_minute->show(); + + ui->timeLag->show(); + ui->label_timeLag->show(); + + ui->box_start_year->setCurrentText(ui->box_start_year->currentText()); + ui->box_end_year->setCurrentText(ui->box_end_year->currentText()); + ui->sumCheck->hide(); + } + else + { + ui->label_startTime->setText(tr("查询时间")); + switch(index) + { + case REPORT_YEAR: + { + //只显示开始年份作为查询时间 + ui->box_start_year->show(); + ui->label_start_year->show(); + + //其他时间相关控件全部隐藏 + ui->box_start_month->hide(); + ui->label_start_month->hide(); + ui->box_start_day->hide(); + ui->label_start_day->hide(); + break; + } + case REPORT_MONTH: + { + //只显示开始年份、月份作为查询时间 + ui->box_start_year->show(); + ui->label_start_year->show(); + ui->box_start_month->show(); + ui->label_start_month->show(); + + //其他时间相关控件全部隐藏 + ui->box_start_day->hide(); + ui->label_start_day->hide(); + break; + } + case REPORT_DAY: + { + //只显示开始年份、月份作为查询时间 + ui->box_start_year->show(); + ui->label_start_year->show(); + ui->box_start_month->show(); + ui->label_start_month->show(); + ui->box_start_day->show(); + ui->label_start_day->show(); + break; + } + } + + //其他时间相关控件全部隐藏 + ui->label_endTime->hide(); + ui->box_start_hour->hide(); + ui->box_start_minute->hide(); + ui->label_start_hour->hide(); + ui->label_start_minute->hide(); + + ui->box_end_year->hide(); + ui->box_end_month->hide(); + ui->box_end_day->hide(); + ui->box_end_hour->hide(); + ui->box_end_minute->hide(); + ui->label_end_year->hide(); + ui->label_end_month->hide(); + ui->label_end_day->hide(); + ui->label_end_hour->hide(); + ui->label_end_minute->hide(); + + ui->timeLag->hide(); + ui->label_timeLag->hide(); + ui->sumCheck->show(); + } + + this->repaint(); + this->update(); + } +} + +void CSecondReportWidget::slotShowMsg(QString msg) +{ + ui->msgText->setText(msg); + ui->msgText->show(); + + QTimer::singleShot(2000, this, [this]() + { + ui->msgText->setText(""); + ui->msgText->hide(); + }); + + //QMessageBox::information(this, tr("报表管理"), msg); +} + +void CSecondReportWidget::slotStartYearActivated(int index) +{ + Q_UNUSED(index); + + QDateTime time = QDateTime::currentDateTime(); + int year = ui->box_start_year->currentText().toInt(); + int month = ui->box_start_month->currentText().toInt(); + int endMonth = 12; + if(time.date().year() == year) + { + endMonth = time.date().month(); + } + + ui->box_start_month->clear(); + for(int i = 1; i <= endMonth; i++) + { + ui->box_start_month->addItem(QString::number(i)); + } + + if(month >endMonth) + { + //ui->box_start_month->activated(1); + ui->box_start_month->setCurrentText(QString::number(1)); + } + else + { + //ui->box_start_month->activated(month); + ui->box_start_month->setCurrentText(QString::number(month)); + } +} + +void CSecondReportWidget::slotStartMonthActivated(int index) +{ + Q_UNUSED(index); + + QDateTime time_c = QDateTime::currentDateTime(); + int year = ui->box_start_year->currentText().toInt(); + int month = ui->box_start_month->currentText().toInt(); + int day = ui->box_start_day->currentText().toInt(); + QDate date; + date.setDate(year, month, 1); + + int endDay = 28; + if(time_c.date().year() == year && time_c.date().month() == month) + { + endDay = time_c.date().day(); + } + else + { + endDay = date.daysInMonth(); + } + + ui->box_start_day->clear(); + for(int i = 1; i <= endDay; i++) + { + ui->box_start_day->addItem(QString::number(i)); + } + + if(day > endDay) + { + //ui->box_start_day->activated(1); + ui->box_start_day->setCurrentText(QString::number(1)); + } + else + { + //ui->box_start_day->activated(day); + ui->box_start_day->setCurrentText(QString::number(day)); + } +} + +void CSecondReportWidget::slotStartDayActivated(int index) +{ + Q_UNUSED(index); + + QDateTime time = QDateTime::currentDateTime(); + int year = ui->box_start_year->currentText().toInt(); + int month = ui->box_start_month->currentText().toInt(); + int day = ui->box_start_day->currentText().toInt(); + int hour = ui->box_start_hour->currentText().toInt(); + + int endHour = 23; + if(time.date().year() == year && time.date().month() == month && time.date().day() == day) + { + endHour = time.time().hour(); + } + + ui->box_start_hour->clear(); + for(int i = 0; i <= endHour; i++) + { + ui->box_start_hour->addItem(QString::number(i)); + } + + if(hour > endHour) + { + //ui->box_start_hour->activated(1); + ui->box_start_hour->setCurrentText(QString::number(0)); + } + else + { + //ui->box_start_hour->activated(hour); + ui->box_start_hour->setCurrentText(QString::number(hour)); + } +} + +void CSecondReportWidget::slotStartHourActivated(int index) +{ + Q_UNUSED(index); + + QDateTime time = QDateTime::currentDateTime(); + int year = ui->box_start_year->currentText().toInt(); + int month = ui->box_start_month->currentText().toInt(); + int day = ui->box_start_day->currentText().toInt(); + int hour = ui->box_start_hour->currentText().toInt(); + int minute = ui->box_start_minute->currentText().toInt(); + + int endMinute = 59; + if(time.date().year() == year && time.date().month() == month && time.date().day() == day && time.time().hour() == hour) + { + endMinute = time.time().minute(); + } + + ui->box_start_minute->clear(); + for(int i = 0; i <= endMinute; i++) + { + ui->box_start_minute->addItem(QString::number(i)); + } + + if(minute > endMinute) + { + ui->box_start_minute->setCurrentText(QString::number(0)); + } + else + { + ui->box_start_minute->setCurrentText(QString::number(minute)); + } +} + +void CSecondReportWidget::slotEndYearActivated(int index) +{ + Q_UNUSED(index); + + QDateTime time = QDateTime::currentDateTime(); + int year = ui->box_end_year->currentText().toInt(); + int month = ui->box_end_month->currentText().toInt(); + int endMonth = 12; + if(time.date().year() == year) + { + endMonth = time.date().month(); + } + + ui->box_end_month->clear(); + for(int i = 1; i <= endMonth; i++) + { + ui->box_end_month->addItem(QString::number(i)); + } + + if(month > endMonth) + { + //ui->box_end_month->activated(1); + ui->box_end_month->setCurrentText(QString::number(1)); + } + else + { + //ui->box_end_month->activated(month); + ui->box_end_month->setCurrentText(QString::number(month)); + } +} + +void CSecondReportWidget::slotEndMonthActivated(int index) +{ + Q_UNUSED(index); + + QDateTime time_c = QDateTime::currentDateTime(); + int year = ui->box_end_year->currentText().toInt(); + int month = ui->box_end_month->currentText().toInt(); + int day = ui->box_end_day->currentText().toInt(); + QDate date; + date.setDate(year, month, 1); + + int endDay = 28; + if(time_c.date().year() == year && time_c.date().month() == month) + { + endDay = time_c.date().day(); + } + else + { + endDay = date.daysInMonth(); + } + + ui->box_end_day->clear(); + for(int i = 1; i <= endDay; i++) + { + ui->box_end_day->addItem(QString::number(i)); + } + + if(day > endDay) + { + //ui->box_end_day->activated(1); + ui->box_end_day->setCurrentText(QString::number(1)); + } + else + { + //ui->box_end_day->activated(day); + ui->box_end_day->setCurrentText(QString::number(day)); + } +} + +void CSecondReportWidget::slotEndDayActivated(int index) +{ + Q_UNUSED(index); + + QDateTime time = QDateTime::currentDateTime(); + int year = ui->box_end_year->currentText().toInt(); + int month = ui->box_end_month->currentText().toInt(); + int day = ui->box_end_day->currentText().toInt(); + int hour = ui->box_end_hour->currentText().toInt(); + + int endHour = 23; + if(time.date().year() == year && time.date().month() == month && time.date().day() == day) + { + endHour = time.time().hour(); + } + + ui->box_end_hour->clear(); + for(int i = 0; i <= endHour; i++) + { + ui->box_end_hour->addItem(QString::number(i)); + } + + if(hour > endHour) + { + //ui->box_end_hour->activated(1); + ui->box_end_day->setCurrentText(QString::number(0)); + } + else + { + //ui->box_end_hour->activated(hour); + ui->box_end_day->setCurrentText(QString::number(hour)); + } +} + +void CSecondReportWidget::slotEndHourActivated(int index) +{ + Q_UNUSED(index); + + QDateTime time = QDateTime::currentDateTime(); + int year = ui->box_end_year->currentText().toInt(); + int month = ui->box_end_month->currentText().toInt(); + int day = ui->box_end_day->currentText().toInt(); + int hour = ui->box_end_hour->currentText().toInt(); + int minute = ui->box_end_minute->currentText().toInt(); + + int endMinute = 59; + if(time.date().year() == year && time.date().month() == month && time.date().day() == day && time.time().hour() == hour) + { + endMinute = time.time().minute(); + } + + ui->box_end_minute->clear(); + for(int i = 0; i <= endMinute; i++) + { + ui->box_end_minute->addItem(QString::number(i)); + } + + if(minute > endMinute) + { + ui->box_end_minute->setCurrentText(QString::number(0)); + } + else + { + ui->box_end_minute->setCurrentText(QString::number(minute)); + } +} + +//void CSecondReportWidget::slotPage1BtnClicked() +//{ +// pageBtnProcess(0); +//} + +//void CSecondReportWidget::slotPage2BtnClicked() +//{ +// pageBtnProcess(1); +//} + +//void CSecondReportWidget::slotPage3BtnClicked() +//{ +// pageBtnProcess(2); +//} + +//void CSecondReportWidget::slotPage4BtnClicked() +//{ +// pageBtnProcess(3); +//} + +//void CSecondReportWidget::slotPage5BtnClicked() +//{ +// pageBtnProcess(4); +//} + +//void CSecondReportWidget::slotPageUpBtnClicked() +//{ +// if (m_nBtnStartIndex == 1) +// { +// return; +// } +// else if (m_nBtnStartIndex == 2) +// { +// m_nBtnStartIndex -= 1; +// } +// else +// { +// m_nBtnStartIndex -= 2; +// } +// updatePageBtnsText(); +//} + +//void CSecondReportWidget::slotPageDownBtnClicked() +//{ +// if (m_nBtnStartIndex + 4 == m_nPageCount) +// { +// return; +// } +// else if (m_nBtnStartIndex + 4 == m_nPageCount - 1) +// { +// m_nBtnStartIndex += 1; +// } +// else +// { +// m_nBtnStartIndex += 2; +// } +// updatePageBtnsText(); +//} + +//void CSecondReportWidget::slotPageJump() +//{ +// int index = ui->curPage->value(); +// if (m_nPageCount <= 5) +// { +// m_nBtnStartIndex = 1; +// switch (index) +// { +// case 1:slotPage1BtnClicked(); break; +// case 2:slotPage2BtnClicked(); break; +// case 3:slotPage3BtnClicked(); break; +// case 4:slotPage4BtnClicked(); break; +// case 5:slotPage5BtnClicked(); break; +// default: +// break; +// } +// } +// else +// { +// if (index == m_nPageCount) +// { +// m_nBtnStartIndex = index - 4; +// slotPage5BtnClicked(); +// } +// else if (index == m_nPageCount - 1) +// { +// m_nBtnStartIndex = index - 3; +// slotPage4BtnClicked(); +// } +// else if (index == 1) +// { +// m_nBtnStartIndex = 1; +// slotPage1BtnClicked(); +// } +// else if (index == 2) +// { +// m_nBtnStartIndex = 1; +// slotPage2BtnClicked(); +// } +// else +// { +// m_nBtnStartIndex = index - 2; +// slotPage3BtnClicked(); +// } +// } +//} + +void CSecondReportWidget::slotExportHeader() +{ + if (!checkDeletePerm()) + { + slotShowMsg(tr("当前登录用户无运维管理功能权限!")); + return; + } + + QDir dir; + QString path = "../../data/cache/ReportManage/header/"; + if(!dir.exists(path)) + { + dir.mkpath(path); + } + + QString fileName = QFileDialog::getSaveFileName(this, "报表管理", QDir::current().absoluteFilePath(path + "hearder.csv"), "CSV文件(*.csv)"); + if (fileName.isEmpty()) + { + return; + } + + if(!fileName.endsWith(".csv")) + { + fileName += ".csv"; + } + + + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + slotShowMsg(tr("导出表头失败:\n无法打开文件!")); + return; + } + + //解决导出汉字乱码 + QTextCodec* codec = QTextCodec::codecForName("GBK"); + QTextStream outTableWidget(&file); + outTableWidget.setCodec(codec); + + //导出表头 + QStringList headers; + for (int column = 0; column < m_pReportModel->columnCount(); column++) + { + headers << m_pReportModel->horizontalHeaderItem(column)->text(); + } + outTableWidget << headers.join(",") << "\n"; + + file.close(); + + slotShowMsg(tr("导出表头至:\n") + fileName); +} + +void CSecondReportWidget::slotImportHeader() +{ + if (!checkDeletePerm()) + { + slotShowMsg(tr("当前登录用户无运维管理功能权限!")); + return; + } + + QString fileName = QFileDialog::getOpenFileName(this, tr("报表管理"), QDir::current().absoluteFilePath("../../data/cache/ReportManage/header/header.csv"), "CSV文件(*.csv)"); + if (fileName.isEmpty()) + { + return; + } + + if(!fileName.endsWith(".csv")) + { + slotShowMsg(tr("导入表头失败:\n导入格式错误,仅支持csv文件!")); + return; + } + + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) + { + slotShowMsg(tr("导入表头失败:\n无法打开导入的文件!")); + return; + } + + QTextStream in(&file); + in.setCodec("GB2312"); + QString header = in.readLine(); + file.close(); + QStringList headerList = header.split(","); + + if (headerList.size() != m_pReportModel->columnCount()) + { + slotShowMsg(tr("导入表头失败:\n表头长度与现有表头长度不一致!")); + return; + } + + //导入文件后重新设置表格 + for (int i = 0; i < headerList.size(); i++) + { + //表头标题用测点描述填充 + m_pReportModel->setHeaderData(i, Qt::Horizontal,headerList[i]); + } + + //导入表格成功提示 + slotShowMsg(tr("导入表头成功!")); + ui->report->update(); +} + +void CSecondReportWidget::slotExportReport() +{ + if (!checkDeletePerm()) + { + slotShowMsg(tr("当前登录用户无运维管理功能权限!")); + return; + } + + if (m_pReportModel->columnCount() == 0 || m_pReportModel->rowCount() == 0) + { + slotShowMsg(tr("报表数据为空,请先查询报表数据!")); + return; + } + + QString fileName = QFileDialog::getSaveFileName(this, tr("报表管理"), QDir::current().absoluteFilePath("../../data/ReportManage/reports/report.csv"), "CSV文件(*.csv)"); + if (fileName.isEmpty()) + { + return; + } + + if(!fileName.endsWith(".csv")) + { + fileName += ".csv"; + } + + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + slotShowMsg(tr("导出报表失败:\n无法打开文件!")); + return; + } + + //解决导出汉字乱码 + QTextCodec* codec = QTextCodec::codecForName("GBK"); + QTextStream outTableWidget(&file); + outTableWidget.setCodec(codec); + + //导出表头 + QStringList headers; + for (int column = 0; column < m_pReportModel->columnCount(); column++) + { + headers << m_pReportModel->horizontalHeaderItem(column)->text(); + } + outTableWidget << headers.join(",") << "\n"; + + //导出表格正文内容 + + //不分页则直接导出model中的内容即可 + for (int row = 0; row < m_pReportModel->rowCount(); row++) + { + QStringList rowData; + for (int col = 0; col < m_pReportModel->columnCount(); col++) + { + rowData.append(m_pReportModel->item(row, col)->text()); + } + outTableWidget << rowData.join(",") << "\n"; + } + + + //分页时需要导出整个表就需要查询所有数据 + //QStringList rowData; + //std::vectordata_temp; + //qint64 start = 0; //查询开始时间 + //qint64 end = 0; //查询结束时间 + //int length = m_timeList.length(); //时间列表长度 + //for (int row = 0; row < m_timeList.size(); row++) + //{ + // start = m_timeList[row].first.toMSecsSinceEpoch(); + // end = m_timeList[row].second.toMSecsSinceEpoch(); + // data_temp.clear(); + // data_temp.resize(m_tagList.size()); + // rowData.clear(); + + // if (row < length - 3) + // { + // m_pHisDataManage->queryHisEventByTagName(m_tagList, start, end, MODE_NULL, data_temp); + // rowData.append(m_timeList[row].first.addSecs(5 * 60).toString("yyyy-MM-dd HH:mm:ss")); + // } + // else if (row == length - 3) + // { + // m_pHisDataManage->queryHisEventByTagName(m_tagList, start, end, MODE_MAX, data_temp); + // rowData.append("最大值"); + // } + // else if (row == length - 2) + // { + // m_pHisDataManage->queryHisEventByTagName(m_tagList, start, end, MODE_MIN, data_temp); + // rowData.append("最小值"); + // } + // else if (row == length - 1) + // { + // m_pHisDataManage->queryHisEventByTagName(m_tagList, start, end, MODE_MEAN, data_temp); + // rowData.append("平均值"); + // } + + // for(int i=0;itagList=m_tagList; + report->statType=getCurReportType(); + report->isSum = ui->sumCheck->isChecked(); + if(report->statType == 3) + { + report->startTime=getStartDateTimeFromUi(); + report->endTime=getEndDateTimeFromUi(); + report->timeLag=ui->timeLag->currentIndex(); + } + else + { + report->startTime=getStartDateTimeFromUi(); + report->endTime=getEndDateTimeFromUi(); + report->timeLag=0; + } + emit sigDetectReport(report); +} + +//void CSecondReportWidget::slotCountPerPageChanged(int index) +//{ +// if (m_timeList.size() == 0) +// { +// return; +// } + +// if (m_nBtnStartIndex == m_nCurPageIndex) +// { +// m_nCurPageIndex++; +// } + +// slotPage1BtnClicked(); +//} + +void CSecondReportWidget::slotSearchTimeout() +{ + if(m_bIsSearching) + { + m_pWaittingDlg = new CWaittingDlg(); + m_pWaittingDlg->setModal(true); + connect(m_pWaittingDlg, &CWaittingDlg::sigStopSearching, this, &CSecondReportWidget::slotStopSearching); + m_pWaittingDlg->show(); + } +} + +void CSecondReportWidget::slotSearchFinished() +{ + if(m_pWaittingDlg) + { + m_pWaittingDlg->close(); + delete m_pWaittingDlg; + m_pWaittingDlg = NULL; + } + + ui->serach->setEnabled(true); +} + +void CSecondReportWidget::slotStopSearching() +{ + m_pProcessManage->setSearchFlag(false); +} + +void CSecondReportWidget::slotUpdateResult(int code, std::vector>record) +{ + m_pReportModel->clear(); + + if (code != ERROR_OK) + { + QString msg; + switch(code) + { + case ERROR_SEARCH_TERMINATED:msg = tr("查询终止!");break; + case ERROR_NO_DATA:msg = tr("该时间段无数据!");break; + default:msg = tr("生成报表失败!");break; + } + + m_bIsSearching = false; + slotSearchFinished(); + slotShowMsg(msg); + return; + } + + + m_pReportModel->setColumnCount(m_tagList.size() + 1); + m_pReportModel->setRowCount(static_cast(record.size())); + //填充表头 + m_pReportModel->setHeaderData(0, Qt::Horizontal, tr("时间")); + for (int i = 0; i < m_tagList.size(); i++) + { + m_pReportModel->setHeaderData(i + 1, Qt::Horizontal, CTrendInfoManage::instance()->getTagDescription(m_tagList[i])); + } + + ui->report->adjustHeaderWidth(); + //填充数据 + for (int row = 0; row < m_pReportModel->rowCount(); row++) + { + for (int col = 0; col < m_pReportModel->columnCount(); col++) + { + QStandardItem* item = new QStandardItem(record[row][col]); + item->setTextAlignment(Qt::AlignHCenter); + item->setEditable(false); + m_pReportModel->setItem(row, col, item); + } + } + + m_bIsSearching = false; + slotSearchFinished(); + + ui->report->update(); +} + +void CSecondReportWidget::slotShowReport(SReport *report) +{ + if(report) + { + //m_pBtnGroup->button(report->statType)->setChecked(true); + if(report->statType == REPORT_USER_DEFINED) + { + //setStartDateTimeToUi(report->startTime); + //setEndDateTimeToUi(report->endTime); + //ui->timeLag->setCurrentIndex(report->timeLag); + } + else + { + //setDateToUi(report->startTime.date()); + } + + emit sigClearCheckState(); + m_tagList = report->tagList; + for(int i = 0; i < m_tagList.size(); i++) + { + emit sigUpdateTagCheckState(m_tagList.at(i), true); + } + + ui->sumCheck->setChecked(report->isSum); + slotSearchBtnClicked(); + } +} + + +void CSecondReportWidget::slotClearReport() +{ + m_pReportModel->clear(); + +} + +void CSecondReportWidget::slotSpreadOutSide() +{ + emit sigSearchBtnClicked(); +} diff --git a/product/src/gui/plugin/SecondReportWidget/CSecondReportWidget.h b/product/src/gui/plugin/SecondReportWidget/CSecondReportWidget.h new file mode 100644 index 00000000..7428584d --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CSecondReportWidget.h @@ -0,0 +1,167 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include "CHisDataManage.h" +#include "CProcessManage.h" +#include "CStatisCommon.h" +#include "CWaittingDlg.h" +#include "ui_CSecondReportWidget.h" + +class CSecondReportWidget : public QWidget +{ + Q_OBJECT + +public: + CSecondReportWidget(QWidget *parent = 0); + ~CSecondReportWidget(); + + void initialize(); + + //获取当前报表类型 + ReportType getCurReportType(); + + //插入新的测点 + void addTag(const QString &tag, const bool &resetTitle = true); + + //插入新的测点列表 + void addTag(const QStringList &listTag, const bool &resetTitle = true); + + //移除测点 + void removeTag(const QString &tag, const bool &resetTitle = true); + + //移除所有测点 + void removeAllTag(); + +private: + void initProcessManage(); + + //获取当前报表查询时间列表 + bool getTimeList(); + + //获取每一页的数据条数 + //int getDataCo波哦啦untPerPage(); + + //填充表格数据 + void showData(QStringList& rowNames, QStringList& header, std::vector>&data); + + //更新页数 + //void updatePageCountUI(); + + //更新页面控制按钮 + //void updatePageBtns(); + + //更新页面控制按钮文本 + //void updatePageBtnsText(); + + //查询数据 + //void searchData(); + + //1、2、3、4、5按钮处理 +// void pageBtnProcess(int btnIndex); + + //获取查询日期 + QDate getDateFromUi(); + void setDateToUi(QDate date); + + //获取开始时间 + QDateTime getStartDateTimeFromUi(); + void setStartDateTimeToUi(QDateTime time); + + //获取结束时间 + QDateTime getEndDateTimeFromUi(); + void setEndDateTimeToUi(QDateTime time); + +signals: + void sigQueryByUserDef(QStringList tagList, QDateTime startTime, QDateTime endTime, int timeLag , bool isSum); + void sigQueryByTradType(QStringList tagList, int type, QDate date, bool isSum); + void sigDetectReport(SReport* report); + void sigUpdateTagCheckState(const QString &tag, const bool &checked); + void sigClearCheckState(); + void sigSearchBtnClicked(); + +public slots: + void slotSearchBtnClicked(); + void slotReportTypeChanged(int index, bool state); + void slotShowMsg(QString msg); + + void slotStartYearActivated(int index); + void slotStartMonthActivated(int index); + void slotStartDayActivated(int index); + void slotStartHourActivated(int index); + void slotEndYearActivated(int index); + void slotEndMonthActivated(int index); + void slotEndDayActivated(int index); + void slotEndHourActivated(int index); + +// void slotPage1BtnClicked(); //按钮1 +// void slotPage2BtnClicked(); //按钮2 +// void slotPage3BtnClicked(); //按钮3 +// void slotPage4BtnClicked(); //按钮4 +// void slotPage5BtnClicked(); //按钮5 +// void slotPageUpBtnClicked(); //上一分区 +// void slotPageDownBtnClicked(); //下一分区 +// void slotPageJump(); //跳到指定页 +// void slotCountPerPageChanged(int index); + + void slotExportHeader(); //导出表头 + void slotImportHeader(); //导入表头 + void slotExportReport(); //导出表格 + void slotDetectReport(); //收藏报表 + void slotSearchTimeout(); + void slotSearchFinished(); + void slotStopSearching(); + void slotUpdateResult(int code, std::vector>record); + void slotShowReport(SReport * report); + void slotClearReport(); + void slotSpreadOutSide(); +private: + Ui::CSecondReportWidgetClass* ui; + +// QLabel* m_pStartLabel; //“开始时间”标签 +// QLabel* m_pEndLabel; //“结束时间”标签 +// QLabel* m_pOriLabel; //“查询时间”标签 +// QLabel* m_pTimeLagLabel; //“查询间隔”标签 +// QDateTimeEdit* m_pStartDate; //开始时间编辑框 +// QDateTimeEdit* m_pEndDate; //结束时间编辑框 +// QDateEdit* m_pOriDate; //查询时间编辑框 +// QComboBox* m_pTimeLag; //查询间隔下拉框 + +// QPushButton* m_pPageUpBtn; //“上一页”按钮 +// QPushButton* m_pPageDownBtn; //“下一页”按钮 +// QPushButton* m_pPage1Btn; //“第一页”按钮 +// QPushButton* m_pPage2Btn; //“第二页”按钮 +// QPushButton* m_pPage3Btn; //“第三页”按钮 +// QPushButton* m_pPage4Btn; //“第四页”按钮 +// QPushButton* m_pPage5Btn; //“第五页”按钮 + + QButtonGroup* m_pBtnGroup; + CWaittingDlg* m_pWaittingDlg; + + CHisDataManage* m_pHisDataManage; + QStandardItemModel* m_pReportModel; + QList>m_timeList; + QStringList m_tagList; + +// int m_nCurPageIndex; //当前页序号 +// int m_nReportCount; //总的数据条数 +// int m_nPageCount; //总的页数 +// int m_nReportCountPerPage; //每一页的数据条数 +// int m_nSearchIndexStart; //查询时开始序号 +// int m_nSearchIndexEnd; //查询时结束序号 +// int m_nBtnStartIndex; //1、2、3、4、5页面按钮的开始序号 + + QLabel* m_pSearchProgress; + int m_nSearchSeconds; + + CProcessManage* m_pProcessManage; + QThread* m_pThread; + QTimer* m_pTimer; + bool m_bIsSearching; +}; diff --git a/product/src/gui/plugin/SecondReportWidget/CSecondReportWidget.qrc b/product/src/gui/plugin/SecondReportWidget/CSecondReportWidget.qrc new file mode 100644 index 00000000..3a50b17c --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CSecondReportWidget.qrc @@ -0,0 +1,4 @@ + + + + diff --git a/product/src/gui/plugin/SecondReportWidget/CSecondReportWidget.ui b/product/src/gui/plugin/SecondReportWidget/CSecondReportWidget.ui new file mode 100644 index 00000000..59dc56df --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CSecondReportWidget.ui @@ -0,0 +1,345 @@ + + + CSecondReportWidgetClass + + + + 0 + 0 + 1362 + 798 + + + + test + + + + 0 + + + + + 6 + + + + + 日报表 + + + + + + + 月报表 + + + + + + + 年报表 + + + + + + + 自定义 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 是否统计 + + + + + + + 查询 + + + + + + + 收藏 + + + + + + + 导出表头 + + + + + + + 导入表头 + + + + + + + 导出表格 + + + + + + + + + 6 + + + 6 + + + + + 开始时间 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 6 + + + 6 + + + + + 结束时间 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 时间间隔 + + + + + + + + 1年 + + + + + 1个月 + + + + + 1天 + + + + + 1小时 + + + + + 30分钟 + + + + + 15分钟 + + + + + 全部 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 6 + + + + + + + + + + + + + + + + + + + CReportTableView + QTableView +
CReportTableView.h
+
+
+ + +
diff --git a/product/src/gui/plugin/SecondReportWidget/CStatisCommon.h b/product/src/gui/plugin/SecondReportWidget/CStatisCommon.h new file mode 100644 index 00000000..9a9b962f --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CStatisCommon.h @@ -0,0 +1,110 @@ +#ifndef CSTATISCOMMON_H +#define CSTATISCOMMON_H + +#include +#include +#include + +#include "public/pub_utility_api/FileUtil.h" + +#include "perm_mng_api/PermMngApi.h" + +const std::string CN_AppName_PSCADA = "PSCADA"; +const int CN_AppId_PSCADA = 4; +const int LINE_X_MAX_TICK = 32; +const int SERIOUS_DEV_NUM = 5; + +enum ReportType +{ + REPORT_YEAR = 0, + REPORT_MONTH, + REPORT_DAY, + REPORT_USER_DEFINED +}; + +enum TimeLag +{ + LAG_YEAR = 0, + LAG_MONTH, + LAG_DAY, + LAG_HOUR, + LAG_30_MIN, + LAG_15_MIN, + LAG_ALL +}; + +enum NumPerPage +{ + NUM_10 = 0, + NUM_50, + NUM_100, + NUM_ALL +}; + +enum EN_STATIS_MODE +{ + MODE_NULL = 0, //查询原始值 + MODE_MAX, //查询最大值 + MODE_MIN, //查询最小值 + MODE_MEAN, //查询均值 + MODE_NUM //查询个数 +}; + +enum EN_STATIS_STYLE +{ + STYLE_LOCATION = 0, + STYLE_DEVTYPE +}; + +enum ReportViewErrorCode +{ + ERROR_OK = 0, + ERROR_QUERY_INFLUXDB_FAILD = 0x10001, + ERROR_NO_DATA = 0x10002, + ERROR_SEARCH_TERMINATED = 0x10003 + +}; + +struct SHisData +{ + qint64 time; + EN_STATIS_MODE mode; + QString location; + QString devType; + QList number; +}; + +static bool checkDeletePerm() +{ + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if (permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + return false; + } + std::string tmpStr = "FUNC_NOM_OM"; + if (PERM_PERMIT != permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmpStr)) + { + return false; + } + return true; +}; + +struct SReport +{ + QStringList tagList; + int statType; + long timeLag; + QDateTime startTime; + QDateTime endTime; + bool isSum; + + SReport() + { + statType = 0; + timeLag = 0; + startTime = QDateTime::currentDateTime().addSecs(-300); + endTime = QDateTime::currentDateTime(); + isSum = false; + } +}; +#endif // CSTATISCOMMON_H diff --git a/product/src/gui/plugin/SecondReportWidget/CTableView.cpp b/product/src/gui/plugin/SecondReportWidget/CTableView.cpp new file mode 100644 index 00000000..c7c43ee5 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTableView.cpp @@ -0,0 +1,32 @@ +#include "CTableView.h" +#include + +CTableView::CTableView(QWidget *parent) + : QTableView(parent) +{ + +} + +int CTableView::tableColumnWidth() +{ + return m_nTableColWidth; +} + +void CTableView::setTableColumnWidth(const int &nWidth) +{ + m_nTableColWidth = nWidth; + + horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); +} + +int CTableView::tableRowHeight() +{ + return m_nTableRowHeight; +} + +void CTableView::setTableRowHeight(const int &nHeight) +{ + m_nTableRowHeight = nHeight; + + verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); +} diff --git a/product/src/gui/plugin/SecondReportWidget/CTableView.h b/product/src/gui/plugin/SecondReportWidget/CTableView.h new file mode 100644 index 00000000..2758f072 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTableView.h @@ -0,0 +1,26 @@ +#ifndef CTABLEVIEW_H +#define CTABLEVIEW_H + +#include + +class CTableView : public QTableView +{ + Q_OBJECT + Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) + Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) + +public: + CTableView(QWidget *parent = Q_NULLPTR); + + int tableColumnWidth(); + void setTableColumnWidth(const int &nWidth); + + int tableRowHeight(); + void setTableRowHeight(const int &nHeight); + +private: + int m_nTableColWidth; + int m_nTableRowHeight; +}; + +#endif // CTABLEVIEW_H diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendEditDialog.cpp b/product/src/gui/plugin/SecondReportWidget/CTrendEditDialog.cpp new file mode 100644 index 00000000..c15a1f74 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendEditDialog.cpp @@ -0,0 +1,149 @@ +#include +#include "CTrendEditDialog.h" +#include "ui_CTrendEditDialog.h" +#include "CTrendEditModel.h" +#include "GraphTool/Retriever/CRetriever.h" +#include "pub_utility_api/FileUtil.h" + +using namespace iot_dbms; + +CTrendEditDialog::CTrendEditDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CTrendEditDialog), + m_graph(nullptr), + m_pRretriever(nullptr) +{ + ui->setupUi(this); + ui->m_retrieverWidget->setWindowFlags(Qt::Widget); + ui->m_retrieverWidget->setMultVisible(false); + //setWindowModality(Qt::WindowModal); + initialize(); + connect(ui->addCurve, SIGNAL(clicked()), this, SLOT(slot_addCureve())); + connect(ui->removeCurve, SIGNAL(clicked()), this, SLOT(slot_removeCureve())); + connect(ui->clearCurve, SIGNAL(clicked()), this, SLOT(slot_clearCureve())); + connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateTrend())); + connect(ui->cancle, SIGNAL(clicked()), this, SLOT(close())); +} + +CTrendEditDialog::~CTrendEditDialog() +{ + if(m_pRretriever != NULL) + { + delete m_pRretriever; + } + m_pRretriever = NULL; + delete ui; +} + +void CTrendEditDialog::initialize() +{ + + initTrendView(); + + m_pRretriever = new CRetriever(this); +} + +void CTrendEditDialog::initTrendView() +{ + m_model = new CTrendEditModel(this); + ui->trendView->setModel(m_model); + ui->trendView->horizontalHeader()->setStretchLastSection(true); + CTrendDelegate * delegate = new CTrendDelegate(this); + ui->trendView->setItemDelegate(delegate); + ui->trendView->setAlternatingRowColors(true); + ui->trendView->horizontalHeader()->setStretchLastSection(true); + + connect(ui->m_retrieverWidget, &CRetriever::itemTagTriggered, ui->trendView, &CTrendEditView::appendTagName); +} + +void CTrendEditDialog::showEvent(QShowEvent *event) +{ + QDialog::showEvent(event); + updateTrendViewColumnWidth(); +} + +void CTrendEditDialog::resizeEvent(QResizeEvent *event) +{ + QDialog::resizeEvent(event); + updateTrendViewColumnWidth(); +} + + +void CTrendEditDialog::updateTrendViewColumnWidth() +{ + int nTrendViewWidth = ui->trendView->width(); + ui->trendView->setColumnWidth(0, nTrendViewWidth / 3 * 2); +} + + +void CTrendEditDialog::setTrendGraph(CTrendGraph *graph) +{ + if( Q_NULLPTR == graph ) + { + return; + } + m_graph = graph; + m_model->setTrendCurves(m_graph->curves()); +} + +CTrendGraph *CTrendEditDialog::trendGraph() const +{ + return m_graph; +} + +void CTrendEditDialog::slot_updateTrend() +{ + if(m_model->rowCount() == 0) + { + QMessageBox::warning(this, tr("警告"), tr("测点数量不允许为空!")); + return; + } + + for(int nIndex(0); nIndex < m_model->rowCount(); ++nIndex) + { + if(m_model->curves().at(nIndex).tag == "") + { + QMessageBox::warning(this, tr("警告"), tr("测点名称不允许存在空值!")); + return; + } + } + if(nullptr == m_graph) + { + m_graph = new CTrendGraph(); + } + m_graph->setCurves(m_model->curves()); + accept(); +} + +void CTrendEditDialog::slot_addCureve() +{ + m_model->addTrendCurve(); +} + +void CTrendEditDialog::slot_removeCureve() +{ + if(!ui->trendView->currentIndex().isValid()) + { + QMessageBox::information(this, tr("提示"), tr("当前未选中行!")); + return; + } + QItemSelectionModel *itemSelection = ui->trendView->selectionModel(); + QModelIndexList indexList = itemSelection->selectedRows(); + m_model->removeTrendCurve(indexList); +} + +void CTrendEditDialog::slot_clearCureve() +{ + m_model->clearTrendCurves(); +} + +void CTrendEditDialog::slot_showRetriever() +{ + if(nullptr == m_pRretriever) + { + m_pRretriever = new CRetriever(this); + } + m_pRretriever->show(); +} + + diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendEditDialog.h b/product/src/gui/plugin/SecondReportWidget/CTrendEditDialog.h new file mode 100644 index 00000000..d6e6001a --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendEditDialog.h @@ -0,0 +1,49 @@ +#ifndef CTRENDEDITDIALOG_H +#define CTRENDEDITDIALOG_H + +#include +#include "CTrendGraph.h" + +namespace Ui { +class CTrendEditDialog; +} + +class CRetriever; +class CTrendEditModel; + +class CTrendEditDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CTrendEditDialog(QWidget *parent = 0); + ~CTrendEditDialog(); + + void initialize(); + void initTrendView(); + + void setTrendGraph(CTrendGraph * data); + CTrendGraph * trendGraph() const; + +protected: + void showEvent(QShowEvent *event); + void resizeEvent(QResizeEvent *event); + +protected slots: + void slot_updateTrend(); + void slot_addCureve(); + void slot_removeCureve(); + void slot_clearCureve(); + void slot_showRetriever(); + +private: + void updateTrendViewColumnWidth(); + +private: + Ui::CTrendEditDialog *ui; + CTrendGraph * m_graph; + CTrendEditModel * m_model; + CRetriever * m_pRretriever; +}; + +#endif // CTRENDEDITDIALOG_H diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendEditDialog.ui b/product/src/gui/plugin/SecondReportWidget/CTrendEditDialog.ui new file mode 100644 index 00000000..16901664 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendEditDialog.ui @@ -0,0 +1,193 @@ + + + CTrendEditDialog + + + + 0 + 0 + 1047 + 566 + + + + 趋势编辑 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 取消 + + + + + + + 确定 + + + + + + + Qt::Horizontal + + + + 500 + 20 + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + QFrame::NoFrame + + + QFrame::Sunken + + + 1 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 3 + + + + + 2 + + + 0 + + + + + 添加 + + + + + + + 删除 + + + + + + + 清空 + + + + + + + Qt::Horizontal + + + + 408 + 20 + + + + + + + + + + + + + + + + + + + + + + CTrendEditView + QTableView +
CTrendEditView.h
+
+ + CRetriever + QWidget +
GraphTool/Retriever/CRetriever.h
+ 1 +
+
+ + + + onAddCureve() + +
diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendEditModel.cpp b/product/src/gui/plugin/SecondReportWidget/CTrendEditModel.cpp new file mode 100644 index 00000000..08fcc893 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendEditModel.cpp @@ -0,0 +1,267 @@ +#include +#include +#include +#include "CTrendGraph.h" +#include "CTrendEditModel.h" + +CTrendDelegate::CTrendDelegate(QWidget *parent) + : QStyledItemDelegate(parent), + m_parent(parent) +{ + +} + +QWidget *CTrendDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option) + if(!index.isValid() || !const_cast(index.model())) + { + return parent; + } + if( 2 == index.column() ) + { + QSpinBox * spin = new QSpinBox(parent); + spin->setMinimum(1); + spin->setMaximum(10); + spin->setSingleStep(1); + return spin; + } + return Q_NULLPTR; +} + +void CTrendDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyledItemDelegate::paint(painter, option, index); + if (!index.isValid()) + { + return; + } + if (!const_cast(index.model())) + { + return; + } + CTrendEditModel * model = dynamic_cast(const_cast(index.model())); + if (!model) + { + return; + } + if (1 == index.column()) + { + painter->save(); + painter->fillRect(option.rect.adjusted(2,1,-2,-1), model->color(index)); + painter->restore(); + } +} + +void CTrendDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + QStyledItemDelegate::setEditorData(editor, index); +} + +void CTrendDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + QStyledItemDelegate::setModelData(editor, model, index); +} + +void CTrendDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index) + editor->setGeometry(option.rect.adjusted(3,3,-3,-3)); +} + +bool CTrendDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if(1 == index.column()) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + if(const_cast(index.model())) + { + CTrendEditModel * dataModel = dynamic_cast(model); + if(dataModel) + { + QColor color = dataModel->color(index); + color = QColorDialog::getColor(color, m_parent, tr("颜色选择"), QColorDialog::DontUseNativeDialog); + if(color.isValid()) + { + dataModel->setData(index, color); + } + } + } + } + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +CTrendEditModel::CTrendEditModel(QObject *parent) + :QAbstractTableModel(parent) +{ + m_header << tr("测点名称") << tr("颜色"); +} + +CTrendEditModel::~CTrendEditModel() +{ + m_listCurve.clear(); +} + +void CTrendEditModel::addTrendCurve() +{ + beginResetModel(); + Curve curve; + curve.tag = QString(""); + curve.desc = QString(""); + curve.color = QColor(qrand() % 255, qrand() % 255, qrand() % 255); + m_listCurve.append(curve); + endResetModel(); +} + +void CTrendEditModel::removeTrendCurve(const QModelIndexList & indexList) +{ + beginResetModel(); + int cof = 0; + foreach (QModelIndex index, indexList) { + m_listCurve.removeAt(index.row() - cof); + cof++; + } + endResetModel(); +} + +void CTrendEditModel::clearTrendCurves() +{ + beginResetModel(); + m_listCurve.clear(); + endResetModel(); +} + +void CTrendEditModel::setTrendCurves(QList curves) +{ + beginResetModel(); + m_listCurve = curves; + endResetModel(); +} + +QList CTrendEditModel::curves() +{ + return m_listCurve; +} + +QColor CTrendEditModel::color(const QModelIndex &index) const +{ + if(index.isValid() && 1 == index.column() ) + { + return m_listCurve.at(index.row()).color; + } + return QColor(); +} + +QVariant CTrendEditModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + return m_header.at(section); + } + } + return QVariant(); + +} + +QVariant CTrendEditModel::data(const QModelIndex &index, int role) const +{ + if(Qt::DisplayRole != role || !index.isValid()) + { + return QVariant(); + } + Curve curve = m_listCurve.at(index.row()); + switch (index.column()) + { + case 0: + { + return QString("%1").arg(curve.tag); + } + case 1: + { + return curve.color; + } + default: + break; + } + return QVariant(); +} + +bool CTrendEditModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_UNUSED(role) + if(!index.isValid()) + { + return false; + } + switch (index.column()) + { + case 0: + { + QStringList list = value.toString().split("."); + m_listCurve[index.row()].tag = list.at(3) + QString(".") + list.at(4) + QString(".") + list.at(5); + m_listCurve[index.row()].type = list.at(2); + break; + } + case 1: + { + m_listCurve[index.row()].color = value.value(); + break; + } + default: + break; + } + emit dataChanged(index, index); + return true; +} + +int CTrendEditModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + return 0; + return m_header.size(); +} + +int CTrendEditModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + return 0; + return m_listCurve.count(); +} + +Qt::ItemFlags CTrendEditModel::flags(const QModelIndex &index) const +{ + if(!index.isValid()) + { + return Qt::NoItemFlags; + } + return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; +} + +QString CTrendEditModel::checkAppendData(const QString &tag) +{ + QStringList list = tag.split("."); + if(list.length() != 7) + { + return tr("点标签非法"); + } + QString tagName = list.at(3) + QString(".") + list.at(4) + QString(".") + list.at(5); + QString type = list.at(2); + if(type != "analog" && type != "accuml") + { + return tr("只能添加模拟量和累积量!"); + } + + foreach (Curve curve, m_listCurve) { + if(curve.tag == tagName) + { + return tr("该测点已存在!"); + } + } + return ""; +} + diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendEditModel.h b/product/src/gui/plugin/SecondReportWidget/CTrendEditModel.h new file mode 100644 index 00000000..17089c63 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendEditModel.h @@ -0,0 +1,99 @@ +#ifndef CTRENDEDITMODEL_H +#define CTRENDEDITMODEL_H + +/***************************************** +/ * + * 趋势曲线设置视图模型 + * + * ***************************************/ + +#include +#include +#include +#include +#include +#include +#include "CTrendGraph.h" + +//Delegate Label +class CColorLabel : public QLabel +{ + Q_OBJECT +public: + CColorLabel(QWidget * parent = Q_NULLPTR) : QLabel(parent){} + + void setColor(const QColor &color) { m_color = color; } + QColor color() const { return m_color; } + +protected: + virtual void mousePressEvent(QMouseEvent *event) + { + QLabel::mousePressEvent(event); + QColor color = QColorDialog::getColor(m_color, this, tr("颜色选择"), QColorDialog::DontUseNativeDialog); + if(color.isValid()) + { + m_color = color; + } + } + + virtual void paintEvent(QPaintEvent * event) + { + QPainter p(this); + p.fillRect(rect(), QBrush(m_color)); + QLabel::paintEvent(event); + } + +private: + QColor m_color; +}; + +class CTrendDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CTrendDelegate(QWidget *parent = 0); + + virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + virtual void setEditorData(QWidget *editor, const QModelIndex &index) const; + virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; + +protected: + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); + +private: + QWidget * m_parent; +}; + +class CTrendEditModel : public QAbstractTableModel +{ + Q_OBJECT +public: + CTrendEditModel(QObject *parent = Q_NULLPTR); + ~CTrendEditModel(); + + void addTrendCurve(); + void removeTrendCurve(const QModelIndexList &indexList); + void clearTrendCurves(); + + void setTrendCurves(QList curves); + QList curves(); + + QColor color(const QModelIndex &index) const; + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + QString checkAppendData(const QString& tag); + +private: + QStringList m_header; + QList m_listCurve; +}; + +#endif // CTRENDEDITMODEL_H diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendEditView.cpp b/product/src/gui/plugin/SecondReportWidget/CTrendEditView.cpp new file mode 100644 index 00000000..41e6c5f3 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendEditView.cpp @@ -0,0 +1,98 @@ +#include "CTrendEditView.h" +#include +#include +#include +#include +#include +#include +#include "CTrendEditModel.h" + +CTrendEditView::CTrendEditView(QWidget *parent) + : CTableView(parent) +{ + setAcceptDrops(true); + setDropIndicatorShown(true); + setDragEnabled(true); + setDragDropMode(QAbstractItemView::DragDrop); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setSelectionBehavior(QAbstractItemView::SelectRows); +} + +void CTrendEditView::appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti) +{ + Q_UNUSED(strTagDesc); + if(dynamic_cast(model())) + { + CTrendEditModel * curveDataModel = dynamic_cast(model()); + + QString ret = curveDataModel->checkAppendData(strTagName); + if(ret != "") + { + QMessageBox::warning(this, tr("提示"), ret); + return; + } + + if(!isMulti) + { + if(currentIndex() == QModelIndex()) + { + QMessageBox::warning(this, tr("提示"), tr("请选中一行!")); + return; + } + + curveDataModel->setData(currentIndex().sibling(currentIndex().row(), 0), strTagName); + } + else + { + curveDataModel->addTrendCurve(); + curveDataModel->setData(model()->sibling(model()->rowCount()-1, 0, currentIndex()), strTagName); + } + } +} + +void CTrendEditView::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasText()) + { + event->acceptProposedAction(); + event->setDropAction(Qt::CopyAction); + } + else + { + event->setAccepted(false); + } +} + +void CTrendEditView::dragMoveEvent(QDragMoveEvent *event) +{ + if (event->mimeData()->hasText()) + { + event->acceptProposedAction(); + event->setDropAction(Qt::CopyAction); + } + else + { + event->setAccepted(false); + } +} + +void CTrendEditView::dropEvent(QDropEvent *event) +{ + const QMimeData *mimeData = event->mimeData(); + if (mimeData->hasText()) + { + QString content = mimeData->text(); + if(dynamic_cast(model())) + { + CTrendEditModel * curveDataModel = dynamic_cast(model()); + QPoint pt = mapFromGlobal(QCursor::pos()); + pt.setY(pt.y() - horizontalHeader()->height()); + QModelIndex index = indexAt(pt); + if(!curveDataModel->setData(index.sibling(index.row(), 0), content)) + { + QMessageBox::warning(this, tr("警告"), tr("该测点已存在!")); + } + } + } + event->accept(); +} diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendEditView.h b/product/src/gui/plugin/SecondReportWidget/CTrendEditView.h new file mode 100644 index 00000000..e4d1b92c --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendEditView.h @@ -0,0 +1,21 @@ +#ifndef CTRENDEDITVIEW_H +#define CTRENDEDITVIEW_H + +#include "CTableView.h" + +class CTrendEditView : public CTableView +{ + Q_OBJECT +public: + CTrendEditView(QWidget *parent = Q_NULLPTR); + +public slots: + void appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti); + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); +}; + +#endif // CTRENDEDITVIEW_H diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendFavTreeWidget.cpp b/product/src/gui/plugin/SecondReportWidget/CTrendFavTreeWidget.cpp new file mode 100644 index 00000000..a785f958 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendFavTreeWidget.cpp @@ -0,0 +1,396 @@ +#include "CTrendFavTreeWidget.h" +#include "CTrendEditDialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "perm_mng_api/PermMngApi.h" +#include "pub_utility_api/FileUtil.h" + +//< 趋势编辑 权限定义 +#define FUNC_NOM_TREND_EDIT ("FUNC_NOM_TREND_EDIT") + +CTrendFavTreeWidget::CTrendFavTreeWidget(QWidget *parent) + : QTreeWidget(parent) +{ + setColumnCount(1); + setHeaderLabel(tr("收藏夹")); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setEditTriggers(EditKeyPressed); + //connect(this, &CTrendFavTreeWidget::doubleClicked, this, &CTrendFavTreeWidget::slotShowTrendGraph); + //connect(this, &CTrendFavTreeWidget::itemChanged, this, &CTrendFavTreeWidget::slotItemChanged); + setObjectName("CTrendFavTreeWidget"); + //loadTrendGraph(); + setEditTriggers(NoEditTriggers); +} + +CTrendFavTreeWidget::~CTrendFavTreeWidget() +{ + savaTrendGraph(); + qDeleteAll(m_trendGraphMap); + m_trendGraphMap.clear(); +} + +void CTrendFavTreeWidget::collectGraph(const QString &title, const CTrendGraph &graph) +{ + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + if(topLevelItem(nIndex)->text(0) == title ) + { + QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); + return; + } + } + + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << title, Item_GRAPH_Type); + item->setFlags(item->flags() | Qt::ItemIsEditable); + addTopLevelItem(item); + CTrendGraph * tmp = new CTrendGraph(); + tmp->setCurves(graph.curves()); + tmp->removeCurve("curve.tag"); + m_trendGraphMap.insert(item, tmp); + savaTrendGraph(); +} + +void CTrendFavTreeWidget::detectReport(SReport &report) +{ + bool ok; + QString str = tr("收藏报表_") + QString::number(topLevelItemCount() + 1); + QString title = QInputDialog::getText(this, tr("输入收藏报表名称"), tr("请输入收藏报表名称"), QLineEdit::Normal, str, &ok); + if(!ok) + { + return; + } + + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + if(topLevelItem(nIndex)->text(0) == title ) + { + QMessageBox::warning(this, tr("错误"), tr("当前报表名称已存在!"), QMessageBox::Ok); + return; + } + } + + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << title, Item_GRAPH_Type); + item->setFlags(item->flags() | Qt::ItemIsEditable); + addTopLevelItem(item); + m_reportMap.insert(item, &report); + //savaTrendGraph(); +} + +void CTrendFavTreeWidget::contextMenuEvent(QContextMenuEvent *event) +{ + //< 权限处理--暂不处理 +// bool bIsEditable = false; +// iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); +// if(permMngPtr == NULL) +// { +// return; +// } + +// permMngPtr->PermDllInit(); +// std::string tmp = FUNC_NOM_TREND_EDIT; +// if (PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) +// { +// bIsEditable = true; +// } + + QMenu menu; + QTreeWidgetItem * item = itemAt(event->pos()); + +// if(!item) +// { +// QAction * newAction = new QAction(tr("添加趋势"), &menu); +// menu.addAction(newAction); +// connect(newAction, SIGNAL(triggered()), this, SLOT(slotNewTrendEdit())); + +// QAction * importAction = new QAction(tr("导入"), &menu); +// menu.addAction(importAction); +// connect(importAction, SIGNAL(triggered()), this, SLOT(slotImport())); +// } +// else +// { +// if(Item_GRAPH_Type == item->type()) +// { +// QAction * showAction = new QAction(tr("显示"), &menu); +// menu.addAction(showAction); +// connect(showAction, SIGNAL(triggered()), this, SLOT(slotShowTrendGraph())); + +// QAction * editAction = new QAction(tr("编辑"), &menu); +// menu.addAction(editAction); +// connect(editAction, SIGNAL(triggered()), this, SLOT(slotEditTrendEdit())); + +// QAction * renameAction = new QAction(tr("重命名"), &menu); +// menu.addAction(renameAction); +// connect(renameAction, &QAction::triggered, this, [&]() { +// m_strEditItemContent = item->text(0); +// editItem(item);}); + +// QAction * deleteAction = new QAction(tr("删除"), &menu); +// menu.addAction(deleteAction); +// connect(deleteAction, SIGNAL(triggered()), this, SLOT(slotRemoveTrendEdit())); + +// QAction * exportAction = new QAction(tr("导出"), &menu); +// menu.addAction(exportAction); +// connect(exportAction, SIGNAL(triggered()), this, SLOT(slotExport())); +// } +// } + + menu.exec(event->globalPos()); +} + +void CTrendFavTreeWidget::slotNewTrendEdit() +{ + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << getNewValidTitle(), Item_GRAPH_Type); + item->setFlags(item->flags() | Qt::ItemIsEditable); + addTopLevelItem(item); + editItem(item); +} + +void CTrendFavTreeWidget::slotShowTrendGraph() +{ + if(!m_trendGraphMap.contains(currentItem())) + { + CTrendGraph * graph = new CTrendGraph; + m_trendGraphMap.insert(currentItem(), graph); + } + emit showTrendGraph(m_trendGraphMap.value(currentItem()), currentItem()->text(0)); +} + +void CTrendFavTreeWidget::slotEditTrendEdit() +{ + CTrendEditDialog *dlg = new CTrendEditDialog(this); + + if(m_trendGraphMap.contains(currentItem())) + { + dlg->setTrendGraph(m_trendGraphMap.value(currentItem())); + } + if(QDialog::Accepted == dlg->exec()) + { + CTrendGraph * graph = dlg->trendGraph(); + + m_trendGraphMap.insert(currentItem(), graph); + savaTrendGraph(); + } + + delete dlg; + dlg = NULL; +} + +void CTrendFavTreeWidget::slotRemoveTrendEdit() +{ + QList selectItem = selectedItems(); + foreach (QTreeWidgetItem *item, selectItem) { + int index = indexOfTopLevelItem(item); + takeTopLevelItem(index); + } + savaTrendGraph(); +} + +void CTrendFavTreeWidget::slotItemChanged(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column) + QString content = item->text(0); + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + QTreeWidgetItem *temp = topLevelItem(nIndex); + if( temp != item && temp->text(0) == content ) + { + QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); + item->setText(0, m_strEditItemContent); + return; + } + } +} + +void CTrendFavTreeWidget::slotImport() +{ + QString filePath = QFileDialog::getOpenFileName(this, tr("选择趋势收藏文件"), QString(), "*.xml"); + if(filePath.isEmpty()) + { + return; + } + loadTrendGraph(filePath); + savaTrendGraph(); +} + +void CTrendFavTreeWidget::slotExport() +{ + QString filePath = QFileDialog::getSaveFileName(this, tr("保存趋势收藏文件"), QString("trendFav.xml"), "*.xml"); + if(filePath.isEmpty()) + { + return; + } + + QList selectItem = selectedItems(); + if(selectItem.isEmpty()) + { + return; + } + + savaTrendGraph(filePath, selectItem); +} + +QString CTrendFavTreeWidget::getNewValidTitle() +{ + QString title = QString("自定义趋势_"); + QStringList listItemText; + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + listItemText << topLevelItem(nIndex)->text(0); + } + int serial = 0; + while(listItemText.contains(title + QString::number(serial))) + { + serial++; + } + return title + QString::number(serial); +} + +void CTrendFavTreeWidget::loadTrendGraph(const QString &filePath) +{ + QDomDocument document; + QString strFileName; + if(filePath.isEmpty()) + { + strFileName = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trendgraph.xml"); + } + else + { + strFileName = filePath; + } + QFile file(strFileName); + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement root = document.documentElement(); + if(!root.isNull()) + { + QDomNodeList graphNodeList = root.elementsByTagName("graph"); + for(int graphIndex(0); graphIndex < graphNodeList.size(); graphIndex++) + { + QDomNode graphNode = graphNodeList.at(graphIndex); + if(!graphNode.isNull()) + { + QDomElement graphElement = graphNode.toElement(); + if(!graphElement.isNull()) + { + QString name = graphElement.attribute("name", QString()); + QTreeWidgetItem * graphItem = new QTreeWidgetItem(QStringList() << name, Item_GRAPH_Type); + graphItem->setFlags(graphItem->flags() | Qt::ItemIsEditable); + + QList curves; + QDomNodeList curveNodeList = graphElement.elementsByTagName("curve"); + for(int nCurveIndex(0); nCurveIndex < curveNodeList.size(); nCurveIndex++) + { + QDomNode curveNode = curveNodeList.at(nCurveIndex); + QDomElement curveElement = curveNode.toElement(); + if(!curveElement.isNull()) + { + QDomNodeList itemList = curveElement.elementsByTagName("item"); + for(int itemIndex(0); itemIndex < itemList.size(); itemIndex++) + { + QDomNode itemNode = itemList.at(itemIndex); + + if(!itemNode.isNull()) + { + while(!itemNode.isNull()) + { + QDomElement item = itemNode.toElement(); + if(!item.isNull()) + { + Curve curve; + curve.tag = item.attribute("tag"); + curve.color = QColor(item.attribute("color").toUInt() & 0x00ffffff); + curves.append(curve); + } + itemNode = curveNode.nextSibling(); + } + } + } + } + } + CTrendGraph * graph = new CTrendGraph(); + graph->setCurves(curves); + m_trendGraphMap.insert(graphItem, graph); + addTopLevelItem(graphItem); + } + } + } + } +} + +void CTrendFavTreeWidget::savaTrendGraph(const QString &filePath, const QList &itemList) +{ + QFile file; + if(!filePath.isEmpty()) + { + file.setFileName(filePath); + } + else + { + QString strTrendDir = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + QString("../../data/model"); + QDir dir; + if(!dir.exists(strTrendDir)) + { + dir.mkdir(strTrendDir); + } + QString strTrendFile = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trendgraph.xml"); + file.setFileName(strTrendFile); + } + + if(file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + QDomDocument document; + + QString strHeader("version='1.0' encoding='utf-8'"); + document.appendChild(document.createProcessingInstruction("xml", strHeader)); + QDomElement root = document.createElement("Profile"); + int nCount = itemList.isEmpty()? topLevelItemCount():itemList.length(); + for(int nIndex(0); nIndex < nCount; nIndex++) + { + QTreeWidgetItem * item = itemList.isEmpty()? topLevelItem(nIndex):itemList.at(nIndex); + QDomElement graphNode = document.createElement("graph"); + graphNode.setAttribute("name", item->text(0)); + + QDomElement curveNode = document.createElement("curve"); + if(m_trendGraphMap.contains(item)) + { + const QList listCurve = m_trendGraphMap.value(item)->curves(); + for(int nCurveIndex(0); nCurveIndex < listCurve.size(); nCurveIndex++) + { + Curve curve = listCurve.at(nCurveIndex); + if(curve.curveType != enRealCurve) + { + continue; + } + QDomElement item = document.createElement("item"); + item.setAttribute("tag", curve.tag); + item.setAttribute("color", curve.color.rgb()); + curveNode.appendChild(item); + } + } + graphNode.appendChild(curveNode); + root.appendChild(graphNode); + } + document.appendChild(root); + + QTextStream content(&file); + document.save(content, 4); + } + file.close(); +} diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendFavTreeWidget.h b/product/src/gui/plugin/SecondReportWidget/CTrendFavTreeWidget.h new file mode 100644 index 00000000..18560ae5 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendFavTreeWidget.h @@ -0,0 +1,52 @@ +#ifndef CTRENDFAVTREEWIDGET_H +#define CTRENDFAVTREEWIDGET_H + +#include +#include "CStatisCommon.h" + +enum E_Tree_ItemType +{ + Item_GRAPH_Type = QTreeWidgetItem::UserType + 1, + Item_TAG_Type, +}; + +class CTrendGraph; + +class CTrendFavTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + explicit CTrendFavTreeWidget(QWidget *parent = nullptr); + ~CTrendFavTreeWidget(); + +signals: + void showTrendGraph(CTrendGraph * graph, QString name); + +public slots: + void collectGraph(const QString &title, const CTrendGraph &graph); + void detectReport(SReport& report); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + +protected slots: + void slotNewTrendEdit(); + void slotShowTrendGraph(); + void slotEditTrendEdit(); + void slotRemoveTrendEdit(); + void slotItemChanged(QTreeWidgetItem *item, int column); + void slotImport(); + void slotExport(); + +private: + QString getNewValidTitle(); + void loadTrendGraph(const QString& filePath = QString()); + void savaTrendGraph(const QString& filePath = QString(), const QList& itemList = QList()); + +private: + QMap m_trendGraphMap; + QMap m_reportMap; + QString m_strEditItemContent; +}; + +#endif // CTRENDFAVTREEWIDGET_H diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendGraph.cpp b/product/src/gui/plugin/SecondReportWidget/CTrendGraph.cpp new file mode 100644 index 00000000..03b7f79c --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendGraph.cpp @@ -0,0 +1,255 @@ +#include "CTrendGraph.h" +#include +//#include "plot/qcustomplot.h" + +const double _EPSILON_ = 1e-5; + +CTrendGraph::CTrendGraph() +{ + +} + +CTrendGraph::~CTrendGraph() +{ + clear(); +} + +const QList CTrendGraph::curves() const +{ + return m_listCurve; +} + +void CTrendGraph::setCurves(QList listCurve) +{ + m_listCurve.swap(listCurve); +} + +const QList CTrendGraph::curveColors() const +{ + QList list; + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + list.append(m_listCurve[nIndex].color); + } + return list; +} + +const Curve &CTrendGraph::curve(const QString &tag, const int &curType) const +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + return m_listCurve.at(nIndex); + } + } + + Q_ASSERT_X(false, "CTrendGraph::curve", "curve is not exists"); +} + +int CTrendGraph::index(const QString &tag, const int &curType) const +{ + //< TODO 性能 + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + return nIndex; + } + } + return -1; +} + +void CTrendGraph::clear() +{ + m_listCurve.clear(); +} + +void CTrendGraph::addCurve(const Curve &curve) +{ + m_listCurve.append(curve); +} + +QList CTrendGraph::removeCurve(const QString &tag) +{ + QList removeList; + for(int nIndex(m_listCurve.size() - 1); nIndex >= 0; nIndex--) + { + if(m_listCurve.at(nIndex).tag == tag) + { + m_listCurve.removeAt(nIndex); + removeList.append(nIndex); + } + } + return removeList; +} + +bool CTrendGraph::removeCurve(const int &nIndex) +{ + if(nIndex < 0 || nIndex >= m_listCurve.size()) + { + return false; + } + m_listCurve.removeAt(nIndex); + return true; +} + +void CTrendGraph::setCurveVisible(const int &nIndex, const bool &visible) +{ + m_listCurve[nIndex].visible = visible; +} + +void CTrendGraph::setCurveColor(const int &nIndex, const QColor &color) +{ + m_listCurve[nIndex].color = color; +} + +void CTrendGraph::setCurveFactor(const int &nIndex, const double &factor) +{ + m_listCurve[nIndex].factor = factor; +} + +void CTrendGraph::setCurveOffset(const int &nIndex, const double &offset) +{ + m_listCurve[nIndex].offset = offset; +} + +void CTrendGraph::setCurveGraphFactor(const int &nIndex, const double &factor) +{ + m_listCurve[nIndex].graphFactor = factor; +} + +void CTrendGraph::setCurveGraphOffset(const int &nIndex, const double &offset) +{ + m_listCurve[nIndex].graphOffset = offset; +} + +void CTrendGraph::setCurveHisDataValue(const QString &tag, const int &curType, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + m_listCurve[nIndex].hisMax = max; + m_listCurve[nIndex].hisMin = min; + m_listCurve[nIndex].hisAverage = average; + m_listCurve[nIndex].hisAccuml = accuml; + m_listCurve[nIndex].hisPlotRange = range; + m_listCurve[nIndex].hisMaxTime = maxTime; + m_listCurve[nIndex].hisMinTime = minTime; + } + } +} + +void CTrendGraph::pushCurveRTDataValue(const QString &tag, const double &key, const double &value, const int &status) +{ + //< 保留20min实时数据 + int nIndex = m_listCurve.indexOf(tag); //< 实时数据索引一定在前面 + if (-1 == nIndex || qIsNaN(value)) + { + return; + } + + Curve &curve = m_listCurve[nIndex]; + curve.values.append(qMakePair>( + key, qMakePair(value, status))); + QVector< QPair > > &values = curve.values; + if (values.first().first < (key - (20 * 60 * 1000))) + { + values.removeFirst(); + } +} + +void CTrendGraph::setCurveStatisMax(const QString &tag, const int &curType, const double &max, const double &maxTime) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + m_listCurve[nIndex].sHisMax = max; + m_listCurve[nIndex].sHisMaxTime = maxTime; + } + } +} + +void CTrendGraph::setCurveStatisMin(const QString &tag, const int &curType, const double &min, const double &minTime) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + m_listCurve[nIndex].sHisMin = min; + m_listCurve[nIndex].sHisMinTime = minTime; + } + } +} + +void CTrendGraph::resetCurveStatisMax(const QString &tag, const int &curType) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + m_listCurve[nIndex].sHisMax = -DBL_MAX; + m_listCurve[nIndex].sHisMaxTime = -DBL_MAX; + } + } +} + +void CTrendGraph::resetCurveStatisMin(const QString &tag, const int &curType) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + m_listCurve[nIndex].sHisMin = DBL_MAX; + m_listCurve[nIndex].sHisMinTime = DBL_MAX; + } + } +} + +void CTrendGraph::updateRTCurveStatisticsInfo(const QString &strTagName, const int &curType) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == strTagName && m_listCurve.at(nIndex).curveType == curType) + { + updateRTCurveStatisticsInfo(m_listCurve[nIndex]); + return; + } + } +} + +void CTrendGraph::updateRTCurveStatisticsInfo(Curve &curve) +{ + //< 计算10min内实时数据最大值、最小值、累计值、平均值 + /*qreal rtMax = -DBL_MAX; + qreal rtMin = DBL_MAX; + qreal rtMaxTime = -DBL_MAX; + qreal rtMinTime = DBL_MAX; + qreal rtAccuml = 0; + int nIndex = curve.values.size(); + double validKey = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()) - (10 * 60 * 1000); + while (--nIndex >= 0 && curve.values.at(nIndex).first >= validKey) + { + if (curve.values.at(nIndex).second.first <= rtMin) + { + rtMin = curve.values.at(nIndex).second.first; + rtMinTime = curve.values.at(nIndex).first; + } + if(curve.values.at(nIndex).second.first >= rtMax) + { + rtMax = curve.values.at(nIndex).second.first; + rtMaxTime = curve.values.at(nIndex).first; + } + rtAccuml += curve.values.at(nIndex).second.first; + } + + curve.rtMin = rtMin; + curve.rtMax = rtMax; + curve.rtMinTime = rtMinTime; + curve.rtMaxTime = rtMaxTime; + curve.rtAccuml = rtAccuml; + curve.rtAverage = rtAccuml / (curve.values.size() - (nIndex + 1)); + */ +} diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendGraph.h b/product/src/gui/plugin/SecondReportWidget/CTrendGraph.h new file mode 100644 index 00000000..1563aa0f --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendGraph.h @@ -0,0 +1,161 @@ +#ifndef CTRENDGRAPH_H +#define CTRENDGRAPH_H + +#include +#include +#include +#include +#include +#include + +/******************************趋势图形************************** + * 此类包含趋势静态配置属性 + **************************************************************/ +extern const double _EPSILON_; + +struct Range +{ + Range() + : min(DBL_MAX), + max(-DBL_MAX) + {} + + Range(double _min, double _max) + : min(_min), + max(_max) + {} + double min; + double max; +}; + +enum Type +{ + enRealCurve = 0, //< 实际测点曲线 + enPrevCurve //< 昨日曲线 +}; + +struct Curve +{ + Curve(const QString &strTagName = QString(), Type type = enRealCurve) + : visible(true), + rtMax(-DBL_MAX), + rtMin(DBL_MAX), + rtAverage(-DBL_MAX), + rtAccuml(0), + hisMax(-DBL_MAX), + hisMin(DBL_MAX), + hisAverage(-DBL_MAX), + hisAccuml(0), + graphFactor(1.), + graphOffset(0.), + factor(1.), + offset(0.), + rtMaxTime(-DBL_MAX), + rtMinTime(DBL_MAX), + hisMaxTime(-DBL_MAX), + hisMinTime(DBL_MAX), + sHisMax(-DBL_MAX), + sHisMin(DBL_MAX), + sHisMaxTime(-DBL_MAX), + sHisMinTime(DBL_MAX), + tag(strTagName), + desc(QString()), + type(QString()), + unit(QString()), + color(QColor()), + curveType(type){} + + inline bool operator==(const Curve &curve) const + { + return ((tag == curve.tag) && (curveType == curve.curveType)); + } + + inline bool operator==(const QString &strTagName) const + { + return tag == strTagName; + } + + bool visible; + double rtMax; + double rtMin; + double rtAverage; + double rtAccuml; + double hisMax; + double hisMin; + double hisAverage; + double hisAccuml; + double graphFactor; + double graphOffset; + double factor; + double offset; + double rtMaxTime; + double rtMinTime; + double hisMaxTime; + double hisMinTime; + double sHisMax; //< 实际的最大值(influx统计),仅用于显示 + double sHisMin; //< 实际的最小值(influx统计),仅用于显示 + double sHisMaxTime; //< 实际的最大值时间(influx统计),仅用于显示 + double sHisMinTime; //< 实际的最小值时间(influx统计),仅用于显示 + + Range hisPlotRange; //< hisPlotRange > Range(hisMin, hisMax) [趋势对比计算刻度] + + QString tag; + QString desc; + QString type; + QString unit; + QColor color; + Type curveType; + + QVector< QPair > > values; +}; + +class CTrendGraph +{ +public: + CTrendGraph(); + + ~CTrendGraph(); + + const QList curves() const; + void setCurves(QList listCurve); + + const QList curveColors() const; + + const Curve &curve(const QString &tag, const int &curType) const; + int index(const QString &tag, const int &curType = enRealCurve) const; + + void clear(); + + void addCurve(const Curve &curve); + QList removeCurve(const QString &tag); + bool removeCurve(const int &nIndex); + + void setCurveVisible(const int &nIndex, const bool &visible); + + void setCurveColor(const int &nIndex, const QColor &color); + void setCurveFactor(const int &nIndex, const double &factor); + void setCurveOffset(const int &nIndex, const double &offset); + + void setCurveHisDataValue(const QString &tag, const int &curType, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range); + void pushCurveRTDataValue(const QString &tag, const double &key, const double &value, const int &status); + + void setCurveStatisMax(const QString &tag, const int &curType, const double &max, const double &maxTime); + void setCurveStatisMin(const QString &tag, const int &curType, const double &min, const double &minTime); + + void resetCurveStatisMax(const QString &tag, const int &curType); + void resetCurveStatisMin(const QString &tag, const int &curType); + + void setCurveGraphFactor(const int &nIndex, const double &factor); + void setCurveGraphOffset(const int &nIndex, const double &offset); + + //< 更新实时曲线统计信息 + void updateRTCurveStatisticsInfo(const QString &strTagName, const int &curType); + void updateRTCurveStatisticsInfo(Curve &curve); + +private: + QList m_listCurve; +}; + +#endif // CTRENDGRAPH_H + + diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendInfoManage.cpp b/product/src/gui/plugin/SecondReportWidget/CTrendInfoManage.cpp new file mode 100644 index 00000000..f3edf4ad --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendInfoManage.cpp @@ -0,0 +1,704 @@ +#include "CTrendInfoManage.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "pub_utility_api/CharUtil.h" +#include "pub_utility_api/FileUtil.h" +#include "perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" + +using namespace iot_dbms; +using namespace iot_public; +using namespace std; + +CTrendInfoManage *CTrendInfoManage::m_pInstance = NULL; + + +CTrendInfoManage *CTrendInfoManage::instance() +{ + if (NULL == m_pInstance) + { + m_pInstance = new CTrendInfoManage(); + } + + return m_pInstance; +} + +CTrendInfoManage::CTrendInfoManage() +{ + m_rtdbAccess = NULL; + initialize(); +} + +void CTrendInfoManage::destory() +{ + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + m_locationInfo.clear(); + m_devGroupInfo.clear(); + m_deviceInfo.clear(); + m_listTagName.clear(); + m_listTagInfo.clear(); + m_listTagUnit.clear(); + m_menuState.clear(); + m_alarmShowStatus.clear(); + m_alarmOtherStatus.clear(); + m_alarmStatusDefineMap.clear(); + m_locationOrderList.clear(); + m_pInstance = NULL; + delete this; +} + +QMap CTrendInfoManage::locationInfo() +{ + return m_locationInfo; +} + +QString CTrendInfoManage::getLocationDesc(const int &locId) +{ + return m_locationInfo.value(locId); +} + +QList CTrendInfoManage::locationOrderList() +{ + if(m_locationOrderList.size() == 0) + { + initialize(); + } + return m_locationOrderList; +} + +QMap CTrendInfoManage::devGroupInfo(const int &location) +{ + return m_devGroupInfo.value(location, QMap()); +} + +QList > CTrendInfoManage::devGroupInfoList(const int &location) +{ + return m_devGroupInfoMap.value(location, QList >()); +} + +QMap CTrendInfoManage::deviceInfo(const QString &devGroupName) +{ + return m_deviceInfo.value(devGroupName, QMap()); +} + +QStringList CTrendInfoManage::queryTagListDevGroup(const QString &devGroup) +{ + QStringList tagList = QStringList(); + QMap devMap = m_deviceInfo.value(devGroup); + if(devMap.isEmpty()) + { + return tagList; + } + QStringList deviceList = devMap.keys(); + foreach (QString device, deviceList) { + tagList.append(m_listTagName.value(device, QStringList())); + } + return tagList; +} + +QStringList CTrendInfoManage::queryTagList(const QString &device) +{ + QStringList result = m_listTagName.value(device, QStringList()); + for(int nIndex = 0; nIndex < result.length(); ++nIndex) + { + if(getTagType(result.at(nIndex)) == "digital") + { + result.removeAt(nIndex); + nIndex--; + } + } + return result; +} + +QString CTrendInfoManage::queryDeviceGroup(const QString &device) +{ + QMap >::const_iterator iter = m_deviceInfo.begin(); + for(; iter != m_deviceInfo.end(); ++iter) + { + QStringList deviceList = iter.value().keys(); + if(deviceList.indexOf(device) != -1) + { + return iter.key(); + } + } + return QString(); +} + +QString CTrendInfoManage::getTagDescription(const QString &tag) +{ + QStringList values = m_listTagInfo.value(tag, QStringList()); + if(values.isEmpty()) + { + return QString(); + } + return values.at(0); +} + +QString CTrendInfoManage::getTagType(const QString &tag) +{ + QStringList values = m_listTagInfo.value(tag, QStringList()); + if(values.isEmpty()) + { + return QString(); + } + return values.at(1); +} + +QString CTrendInfoManage::getTagUnit(const QString &tag) +{ + QStringList values = m_listTagInfo.value(tag, QStringList()); + if(values.isEmpty()) + { + return QString(); + } + return values.at(2); +} + +bool CTrendInfoManage::checkTrendEditPerm() +{ + iot_public::SNodeInfo stNodeInfo; + iot_public::CSysInfoInterfacePtr spSysInfo; + if (!iot_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return false; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + if(0 == permMngPtr->PermDllInit()) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + std::string strTendEdit = FUNC_NOM_TREND_EDIT; + if(PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &strTendEdit)) + { + return true; + } + } + return false; +} + +int CTrendInfoManage::getStateActualValue(const QString &state) +{ + if(state.isEmpty()) + { + return 0; + } + return m_menuState.value(state); +} + +int CTrendInfoManage::getInvalidStatus(E_Point_Type pointType, int status) +{ + switch (pointType) + { + case E_ANALOG:{ + if(0 != (status & m_nInvalidAnalog)) + { + return 1; + } + break; + } + case E_DIGITAL:{ + if(0 != (status & m_nInvalidDigital)) + { + return 1; + } + break; + } + case E_MIX:{ + break; + } + case E_ACCUML:{ + break; + } + default: + break; + } + return 0; +} + +QMap > CTrendInfoManage::getAlarmShowStatus() +{ + return m_alarmShowStatus; +} + +QMap CTrendInfoManage::getAlarmOtherStatus() +{ + return m_alarmOtherStatus; +} + +void CTrendInfoManage::initialize() +{ + m_bLoadTagInfoWhenInit=false; + //< 实时库 + if(m_rtdbAccess == Q_NULLPTR) + { + m_rtdbAccess = new iot_dbms::CRdbAccess(); + } + else + { + delete m_rtdbAccess; + m_rtdbAccess = new iot_dbms::CRdbAccess(); + } + + m_listTagInfo.reserve(30097); // 保证三万点测试的素数 + + CDbApi * pReadDb = new CDbApi(DB_CONN_MODEL_READ); + if(!pReadDb->open()) + { + delete pReadDb; + pReadDb = Q_NULLPTR; + return; + } + + loadUnit(pReadDb); + loadRTLocation(); + loadDevGroupInfo(pReadDb); + loadDeviceInfo(pReadDb); + //loadTagInfo(pReadDb); + //通过setEnableDynamicLoadTag函数加载了,默认不加载测点,防止测点太多打开趋势页面太慢 + //loadAllTagInfo(pReadDb); + if(m_bLoadTagInfoWhenInit) + { + loadAllTagInfo(pReadDb); + } + initInvalidStatus(); + + delete pReadDb; + pReadDb = Q_NULLPTR; +} + +void CTrendInfoManage::loadRTLocation() +{ + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return; + } + int level; + std::vector vecLocationId; + std::vector vecPermPic; + if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) + { + LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); + return; + } + + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + QPair id_value; + id_value.first = "location_id"; + id_value.second = "description"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back(id_value.first); + columns.push_back(id_value.second); + + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + m_locationInfo.clear(); + m_locationOrderList.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + + std::vector ::const_iterator it = vecLocationId.cbegin(); + while (it != vecLocationId.cend()) + { + if(key.toInt() == *it) + { + m_locationInfo[key.toInt()] = value.toStdString().c_str(); + m_locationOrderList << key.toInt(); + } + ++it; + } + } + } + } + m_rtdbAccess->close(); +} + +void CTrendInfoManage::loadDevGroupInfo(CDbApi *pReadDb) +{ + QSqlQuery query; + + QString strLoctionFilter; + if(!m_locationInfo.keys().isEmpty()) + { + QStringList listLocation; + foreach (int nLocationID, m_locationInfo.keys()) + { + listLocation.append(QString::number(nLocationID)); + } + strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); + } + else + { + return ; + } + + QString sqlSequenceQuery = QStringLiteral("select tag_name, description, location_id from dev_group where sub_system > 3 "); + if(!strLoctionFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" and %1 order by dev_group_no asc;").arg(strLoctionFilter)); + } + else + { + sqlSequenceQuery.append(QStringLiteral(" order by dev_group_no asc;")); + } + query.setForwardOnly(true); + pReadDb->execute(sqlSequenceQuery, query); + + m_devGroupInfoMap.clear(); + m_devGroupInfo.clear(); + while(query.next()) + { + const QString &tag_name = query.value(0).toString(); + const QString &description = query.value(1).toString(); + const int location_id = query.value(2).toInt(); + + m_devGroupInfoMap[location_id].append(QPair(tag_name,description)); + m_devGroupInfo[location_id].insert(tag_name, description); + } +} + +void CTrendInfoManage::loadDeviceInfo(CDbApi *pReadDb) +{ + QSqlQuery query; + + QString strLoctionFilter; + QList > listDevGroup = m_devGroupInfo.values(); + if(!listDevGroup.isEmpty()) + { + QStringList listLocation; + for(int i=0; iexecute(sqlSequenceQuery, query); + + m_deviceInfo.clear(); + while(query.next()) + { + //const QString &tag_name = query.value(0).toString(); + //const QString &description = query.value(1).toString(); + //const QString &group_tag_name = query.value(2).toString(); + + m_deviceInfo[query.value(2).toString()].insert(query.value(0).toString(), query.value(1).toString()); + } +} + +bool CTrendInfoManage::loadTagInfo(CDbApi *pReadDb, const QStringList &listDevice) +{ + if(listDevice.isEmpty()) + { + return false; + } + QSqlQuery query; + QStringList listType; + listType.append(QStringLiteral("analog")); + listType.append(QStringLiteral("digital")); + listType.append(QStringLiteral("accuml")); + // listType.append(QString("mix")); + +// QString strDeviceFilter; +// if(!m_deviceInfo.isEmpty()) +// { +// QStringList listDevice; +// QMap >::const_iterator iter = m_deviceInfo.constBegin(); +// while (iter != m_deviceInfo.constEnd()) +// { +// listDevice.append(iter.value().keys()); +// ++iter; +// } +// strDeviceFilter = "'" % listDevice.join("', '") % "'"; +// strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); +// } + + QString strDeviceFilter = "'" % listDevice.join("', '") % "'"; + strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); + +// m_listTagInfo.clear(); +// m_listTagName.clear(); +// m_listTagUnit.clear(); + query.setForwardOnly(true); + for(int nIndex(0); nIndex < listType.size(); nIndex++) + { + const QString strCurType = listType.at(nIndex); + QString strUnitField; + if(QStringLiteral("analog") == strCurType || QStringLiteral("accuml") == strCurType) + { + strUnitField = QStringLiteral(", t1.unit_id "); + } + QString sqlSequenceQuery = QString("SELECT t2.group_tag_name, t1.tag_name, t1.description, t1.device, t1.location_id, t2.DESCRIPTION %1 \ +FROM %2 as t1 left join dev_info as t2 on t1.device = t2.tag_name").arg(strUnitField).arg(strCurType); + if(!strDeviceFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" WHERE %1 ORDER BY SEQ_NO asc;").arg(strDeviceFilter)); + } + pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + //const QString group = query.value(0).toString(); + const QString &tagName = query.value(1).toString(); + //const QString tagDesc = query.value(2).toString(); + const QString &device = query.value(3).toString(); + const int location = query.value(4).toInt(); + //const QString devDesc = query.value(5).toString(); + const QString strDescription = m_locationInfo[location] % QChar('.') % m_devGroupInfo[location][query.value(0).toString()] % QChar('.') % query.value(5).toString() % QChar('.') % query.value(2).toString(); + m_listTagName[device] << tagName; + + QString strUnitDesc = QString(); + if(query.value(6).isValid()) + { + strUnitDesc = m_listTagUnit.value(query.value(6).toInt(), QString()); + } + m_listTagInfo[tagName] = QStringList() << strDescription << strCurType << strUnitDesc; + } + } + return true; +} + +void CTrendInfoManage::loadAllTagInfo(iot_dbms::CDbApi *pReadDb) +{ + QStringList listDevice; + QMap >::const_iterator iter = m_deviceInfo.constBegin(); + while (iter != m_deviceInfo.constEnd()) + { + listDevice.append(iter.value().keys()); + ++iter; + } + + loadTagInfo(pReadDb,listDevice); +} +void CTrendInfoManage::loadUnit(CDbApi *pReadDb) +{ + QSqlQuery query; + QString sqlSequenceQuery = QStringLiteral("select unit_id, unit_name from dict_unit_info"); + query.setForwardOnly(true); + pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + m_listTagUnit[query.value(0).toInt()] = query.value(1).toString(); + } +} + +void CTrendInfoManage::loadStateDefine() +{ + if(m_rtdbAccess->open("base", "dict_menu_info")) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + + CRdbQueryResult result; + std::vector columns; + columns.emplace_back("menu_macro_name"); + columns.emplace_back("actual_value"); + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType name; + CVarType value; + result.getColumnValue(nIndex, 0, name); + result.getColumnValue(nIndex, 1, value); + m_menuState.insert(name.toStdString().c_str(), value.toInt()); + } + } + } + m_rtdbAccess->close(); +} + +void CTrendInfoManage::loadAlarmStatusDefine() +{ + if(m_rtdbAccess->open("base", "alarm_status_define")) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.emplace_back("status_value"); + columns.emplace_back("display_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmStatusDefineMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + m_rtdbAccess->close(); +} + +void CTrendInfoManage::loadAlarmStatus() +{ + const std::string strConfFullPath = iot_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + string strCheck = pParamIter->second.get(".check"); + QPair value; + if(StringToInt(strKey) != 9999) + { + value.first = m_alarmStatusDefineMap[StringToInt(strKey)]; + }else + { + value.first = QObject::tr("其他"); + } + value.second = StringToInt(strCheck); + m_alarmShowStatus[StringToInt(strKey)] = value; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CTrendInfoManage::loadAlarmOtherStatus() +{ + const std::string strConfFullPath = iot_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + m_alarmOtherStatus[StringToInt(strKey)] = m_alarmStatusDefineMap[StringToInt(strKey)]; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CTrendInfoManage::initInvalidStatus() +{ + int temp = 0x01; + m_nInvalidAnalog = 0; + m_nInvalidDigital = 0; + + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_INVALID")); //< 无效 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_GK_OFF")); //< 工况退出 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_NOT_CHANGE")); //< 不刷新 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_BAD_DATA")); //< 坏数据 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_TB")); //< 突变 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_GET_CAL")); //< 计算值 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_NOT_REAL")); //< 非实测值 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_NOT_INIT")); //< 未初始化 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_SET_DATA")); //< 人工置数 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_PINHIBIT_REF")); //< 点禁止刷新 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_DINHIBIT_REF")); //< 挂牌禁止刷新 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_SINHIBIT_REF")); //< 屏蔽禁止刷新 + + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_GK_OFF")); //< 工况退出 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_INVALID")); //< 无效 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_NOT_REAL")); //< 非实测值 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_GET_CAL")); //< 计算值 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_PART_ABNORMAL")); //< 分量不正常 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SET_DATA")); //< 人工置数 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_PINHIBIT_REF")); //< 点禁止刷新 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_DINHIBIT_REF")); //< 挂牌禁止刷新 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SINHIBIT_REF")); //< 屏蔽禁止刷新 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SOURCE_ABNORMAL"));//< 数据来源不正常 +} + +void CTrendInfoManage::setBLoadTagInfoWhenInit(bool bLoadTagInfoWhenInit) +{ + m_bLoadTagInfoWhenInit = bLoadTagInfoWhenInit; +} +bool CTrendInfoManage::loadTagInfoByDevGroup(const QString &strDevGrpTag) +{ + auto iter = m_deviceInfo.find(strDevGrpTag); + if(iter == m_deviceInfo.end()) + { + return false; + } + + return loadTagInfoByDevTag(iter.value().keys()); +} +bool CTrendInfoManage::loadTagInfoByDevTag(const QStringList &listDevTag) +{ + QStringList queryDevTag; + foreach (QString strCur, listDevTag) + { + if(m_listTagName.contains(strCur)) //已经加载过了就不再加载了 + { + continue; + } + queryDevTag.push_back(strCur); + } + + if(queryDevTag.isEmpty()) + { + return false; + } + + CDbApi * pReadDb = new CDbApi(DB_CONN_MODEL_READ); + if(!pReadDb->open()) + { + delete pReadDb; + pReadDb = Q_NULLPTR; + return false; + } + + bool bRet = loadTagInfo(pReadDb,listDevTag); + + delete pReadDb; + pReadDb = Q_NULLPTR; + + return bRet; +} diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendInfoManage.h b/product/src/gui/plugin/SecondReportWidget/CTrendInfoManage.h new file mode 100644 index 00000000..d5c7ec20 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendInfoManage.h @@ -0,0 +1,107 @@ +#ifndef CTRENDINFOMANAGE_H +#define CTRENDINFOMANAGE_H + +#include +#include +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" + +#define FUNC_NOM_TREND_EDIT "FUNC_NOM_TREND_EDIT" + +enum E_Point_Type +{ + E_ANALOG, //< 模拟量 + E_DIGITAL, //< 数字量 + E_MIX, //< 混合量 + E_ACCUML, //< 累计量 +}; + +class CTrendInfoManage +{ +public: + static CTrendInfoManage * instance(); + + void destory(); + + QMap locationInfo(); + + QString getLocationDesc(const int &locId); + + QList locationOrderList(); + + QMap devGroupInfo(const int& location); //新增设备组 + + QList > devGroupInfoList(const int& location); + + QMap deviceInfo(const QString &devGroupName); //新增设备组时修改 + + QStringList queryTagListDevGroup(const QString &devGroup); + + QStringList queryTagList(const QString &device); + + QString queryDeviceGroup(const QString &device); + + QString getTagDescription(const QString &tag); + + QString getTagType(const QString &tag); + + QString getTagUnit(const QString &tag); + + bool checkTrendEditPerm(); + + int getStateActualValue(const QString &state); + + int getInvalidStatus(E_Point_Type pointType, int status); + + QMap > getAlarmShowStatus(); + + QMap getAlarmOtherStatus(); + //加载指定设备组下测点的信息,为空代表加载所有设备组的测点 + bool loadTagInfoByDevGroup(const QString &strDevGrpTag); + //加载指定设备下的测点信息,为空代表加载所有设备 + bool loadTagInfoByDevTag(const QStringList &listDevTag); + void setBLoadTagInfoWhenInit(bool bLoadTagInfoWhenInit); + +private: + CTrendInfoManage(); + void initialize(); + + void loadRTLocation(); + void loadDevGroupInfo(iot_dbms::CDbApi *pReadDb); //新增设备组 + void loadDeviceInfo(iot_dbms::CDbApi *pReadDb); //新增设备组时修改 + //strDevGrpTag为空加载所有设备组,如果不为空加载指定的设备组 + bool loadTagInfo(iot_dbms::CDbApi *pReadDb,const QStringList &listDevice = QStringList()); + void loadAllTagInfo(iot_dbms::CDbApi *pReadDb); + void loadUnit(iot_dbms::CDbApi *pReadDb); + void loadStateDefine(); + void loadAlarmStatusDefine(); + void loadAlarmStatus(); + void loadAlarmOtherStatus(); + void initInvalidStatus(); + +private: + iot_dbms::CRdbAccess * m_rtdbAccess; + QMap m_locationInfo; //< LocationID-LocationDesc + QMap > m_devGroupInfo; //< LocationID- 新增设备组 + QMap > > m_devGroupInfoMap; + QMap > m_deviceInfo; //< DevGroupName- 新增设备组时修改 + QMap m_listTagName; //< DeviceName-list + QHash m_listTagInfo; //< TagName-TagInfo + QMap m_listTagUnit; + QMap m_menuState; + QMap > m_alarmShowStatus; + QMap m_alarmOtherStatus; + QMap m_alarmStatusDefineMap; + QList m_locationOrderList; //< location_id: 按location_no排序 + int m_nInvalidAnalog; + int m_nInvalidDigital; + bool m_bLoadTagInfoWhenInit; //第一次是否加载所有的测点数据,默认加载 + static CTrendInfoManage * m_pInstance; +}; + +#endif // CTRENDINFOMANAGE_H diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendTreeItem.cpp b/product/src/gui/plugin/SecondReportWidget/CTrendTreeItem.cpp new file mode 100644 index 00000000..73f90895 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendTreeItem.cpp @@ -0,0 +1,117 @@ +#include +#include "CTrendTreeItem.h" + +CTrendTreeItem::CTrendTreeItem(int type) + : m_parentItem(Q_NULLPTR), + m_data(QString()), + m_tag(QString()), + m_type(type), + m_checkState(Qt::Unchecked) +{ + +} + +CTrendTreeItem::CTrendTreeItem(CTrendTreeItem *parent, const QString &data, const int &type) + : m_parentItem(parent), + m_data(data), + m_tag(QString()), + m_type(type), + m_checkState(Qt::Unchecked) +{ + if(m_parentItem) + { + m_parentItem->m_childItems.append(this); + } +} + +CTrendTreeItem::~CTrendTreeItem() +{ + qDeleteAll(m_childItems); + m_childItems.clear(); +} + +int CTrendTreeItem::type() const +{ + return m_type; +} + +int CTrendTreeItem::indexOfChild(const CTrendTreeItem *item) const +{ + for(int nIndex(0); nIndex < m_childItems.size(); ++nIndex) + { + if(item == m_childItems[nIndex]) + { + return nIndex; + } + } + return -1; +} + +CTrendTreeItem *CTrendTreeItem::child(int row) const +{ + return m_childItems.value(row); +} + +CTrendTreeItem *CTrendTreeItem::parent() const +{ + return m_parentItem; +} + +int CTrendTreeItem::row() const +{ + if (m_parentItem) + { + return m_parentItem->m_childItems.indexOf(const_cast(this)); + } + + return 0; +} + +int CTrendTreeItem::childCount() const +{ + return m_childItems.count(); +} + +int CTrendTreeItem::columnCount() const +{ + return 1; +} + +QVariant CTrendTreeItem::data(Qt::ItemDataRole role) const +{ + if(Qt::DisplayRole == role) + { + return m_data; + } + else if(Qt::UserRole == role) + { + return m_tag; + } + else if(Qt::CheckStateRole == role) + { + return m_checkState; + } + + QVariant invalidVar; + return invalidVar; +} + +bool CTrendTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) +{ + if(Qt::DisplayRole == role) + { + m_data = value.toString(); + return true; + } + else if(Qt::UserRole == role) + { + m_tag = value.toString(); + return true; + } + else if(Qt::CheckStateRole == role) + { + m_checkState = (Qt::CheckState)value.toInt(); + return true; + } + return false; +} diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendTreeItem.h b/product/src/gui/plugin/SecondReportWidget/CTrendTreeItem.h new file mode 100644 index 00000000..7737f5a4 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendTreeItem.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CTRENDTREEITEM_H +#define CTRENDTREEITEM_H + +#include +#include + +enum NodeType +{ + ROOT_TYPE = 10000, + LOCATION_TYPE, + DEV_GROUP_TYPE, + DEV_TYPE, + TAG_TYPE +}; + +class CTrendTreeItem +{ +public: + CTrendTreeItem(int type); + CTrendTreeItem(CTrendTreeItem *parent, const QString &data, const int &type); + ~CTrendTreeItem(); + + int type() const; + + int indexOfChild(const CTrendTreeItem * item) const; + + CTrendTreeItem *child(int row) const; + CTrendTreeItem *parent() const; + + int row() const; + + int childCount() const; + int columnCount() const; + + QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; + bool setData(const QVariant &value, Qt::ItemDataRole role); + +private: + CTrendTreeItem *m_parentItem; + QString m_data; + QString m_tag; + int m_type; + Qt::CheckState m_checkState; + + QList m_childItems; + +}; + +#endif // CTRENDTREEITEM_H diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendTreeModel.cpp b/product/src/gui/plugin/SecondReportWidget/CTrendTreeModel.cpp new file mode 100644 index 00000000..a24df7f0 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendTreeModel.cpp @@ -0,0 +1,560 @@ +#include "CTrendTreeModel.h" +#include "CTrendInfoManage.h" +#include +#include +#include "pub_logger_api/logger.h" + +const int ItemTagRole = Qt::UserRole + 1; + +CTrendTreeModel::CTrendTreeModel(QObject *parent, QTreeView *view) + : QAbstractItemModel(parent), + m_pView(view), + m_rootItem(Q_NULLPTR) +{ + QTimer::singleShot(300, this, [=](){initTrendTagInfo();}); +} + +CTrendTreeModel::~CTrendTreeModel() +{ + if(Q_NULLPTR != m_rootItem) + { + delete m_rootItem; + } + m_rootItem = Q_NULLPTR; + + CTrendInfoManage::instance()->destory(); +} + +void CTrendTreeModel::initTrendTagInfo() +{ + beginResetModel(); + + if (Q_NULLPTR != m_rootItem) + { + delete m_rootItem; + } + m_rootItem = new QTreeWidgetItem(ROOT_TYPE); + + QTime time; + time.start(); + //< load location + QList locList = CTrendInfoManage::instance()->locationOrderList(); + LOGINFO("locationOrderList time:%I64u", time.elapsed()); + + foreach(const int &locId, locList) { + + time.restart(); + bool isItemShow = isFilterShow(LOCATION_TYPE, QString::number(locId)); + if (!isItemShow) + { + continue; + } + LOGINFO("isFilterShow time:%I64u", time.elapsed()); + + time.restart(); + QString desc = CTrendInfoManage::instance()->getLocationDesc(locId); + LOGINFO("getLocationDesc time:%I64u", time.elapsed()); + + time.restart(); + QList > devGroupInfoList = CTrendInfoManage::instance()->devGroupInfoList(locId); + if (devGroupInfoList.isEmpty()) + { + continue; + } + LOGINFO("devGroupInfoList time:%I64u", time.elapsed()); + + QString locationStr = desc; + QTreeWidgetItem * locationItem = new QTreeWidgetItem(m_rootItem, QStringList() << locationStr, LOCATION_TYPE); + locationItem->setToolTip(0, locationStr); + locationItem->setData(0, ItemTagRole, locId); + QList >::const_iterator iter_devGroup = devGroupInfoList.constBegin(); + while (iter_devGroup != devGroupInfoList.constEnd()) + { + //< load device + + time.restart(); + QMap devInfo = CTrendInfoManage::instance()->deviceInfo((*iter_devGroup).first); + if (devInfo.isEmpty()) + { + ++iter_devGroup; + continue; + } + QString devGroupStr = (*iter_devGroup).second; + LOGINFO("deviceinfo time:%I64u", time.elapsed()); + + + isItemShow = isFilterShow(DEV_GROUP_TYPE, (*iter_devGroup).first); + if (!isItemShow) + { + continue; + } + QTreeWidgetItem * devGroupItem = new QTreeWidgetItem(locationItem, QStringList() << devGroupStr, DEV_GROUP_TYPE); + devGroupItem->setData(0, ItemTagRole, (*iter_devGroup).first); + devGroupItem->setToolTip(0, devGroupStr); + QMap::const_iterator iter_device = devInfo.constBegin(); + while (iter_device != devInfo.constEnd()) + { + //< load tag + QStringList listTagName = CTrendInfoManage::instance()->queryTagList(iter_device.key()); + if (listTagName.isEmpty()) + { + ++iter_device; + continue; + } + + isItemShow = isFilterShow(DEV_TYPE, iter_device.key()); + if (!isItemShow) + { + continue; + } + + QString devStr = iter_device.value(); + QTreeWidgetItem * devItem = new QTreeWidgetItem(devGroupItem, QStringList() << devStr, DEV_TYPE); + devItem->setToolTip(0, iter_device.value()); + devItem->setData(0, ItemTagRole, iter_device.key()); + QStringList::const_iterator iter_tag = listTagName.constBegin(); + while (iter_tag != listTagName.constEnd()) + { + isItemShow = isFilterShow(TAG_TYPE, *iter_tag); + if (!isItemShow) + { + continue; + } + + QString tagStr = CTrendInfoManage::instance()->getTagDescription(*iter_tag).section(".", -1); + QTreeWidgetItem * tagItem = new QTreeWidgetItem(devItem, QStringList() << tagStr, TAG_TYPE); + tagItem->setData(0, ItemTagRole, *iter_tag); + QString toolStr = QString("%1(%2)").arg(tagStr).arg(*iter_tag); + tagItem->setToolTip(0, toolStr); + ++iter_tag; + } + ++iter_device; + } + ++iter_devGroup; + } + } + endResetModel(); + + if (m_pView == Q_NULLPTR) + { + return; + } +// for (int n = 0; nchildCount(); n++) +// { +// m_pView->expand(index(n, 0)); +// } +} + +void CTrendTreeModel::clearTrendTagInfo() +{ + CTrendInfoManage::instance()->destory(); + beginResetModel(); + if(Q_NULLPTR != m_rootItem) + { + delete m_rootItem; + } + m_rootItem = Q_NULLPTR; + endResetModel(); +} + +QVariant CTrendTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section) + Q_UNUSED(orientation) + Q_UNUSED(role) + return QVariant(); +} + +QModelIndex CTrendTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if(!hasIndex(row, column, parent) || Q_NULLPTR == m_rootItem) + { + return QModelIndex(); + } + + QTreeWidgetItem * parentItem; + if(!parent.isValid()) + { + parentItem = m_rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + if(parentItem) + { + QTreeWidgetItem *childItem = parentItem->child(row); + if(childItem) + { + return createIndex(row,0,childItem); + } + } + + return QModelIndex(); +} + +QModelIndex CTrendTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + QTreeWidgetItem *childItem = static_cast(index.internalPointer()); + if (!childItem) + { + return QModelIndex(); + } + + QTreeWidgetItem *parentItem = childItem->parent(); + + if (parentItem == m_rootItem) + { + return QModelIndex(); + } + + int row = parentItem->parent()->indexOfChild(parentItem); + return createIndex(row, 0, parentItem); +} + +int CTrendTreeModel::rowCount(const QModelIndex &parent) const +{ + if(!parent.isValid()) + { + if (NULL != m_rootItem) + { + return m_rootItem->childCount(); + } + else + { + return 0; + } + } + else + { + QTreeWidgetItem * parentItem = static_cast(parent.internalPointer()); + return parentItem->childCount(); + } +} + +int CTrendTreeModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return 1; +} + +QVariant CTrendTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item) + { + if(TAG_TYPE == item->type() && Qt::CheckStateRole == role && 0 == index.column()) + { + return item->checkState(index.column()); + } + return item->data(index.column(), role); + } + return QVariant(); +} + +bool CTrendTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + + if(!index.isValid()) + { + return false; + } + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item) + { + if(Qt::CheckStateRole == role) + { + emit itemCheckStateChanged(item->data(0, ItemTagRole).toString(), value.toInt()); + } + item->setData(index.column(), role, value); + } + + return true; +} + +Qt::ItemFlags CTrendTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item && TAG_TYPE == item->type()) + { + return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; + } + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +void CTrendTreeModel::setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return; + } + if(DEV_TYPE == item->type()) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + if(m_pView->isRowHidden(nChildIndex, index)) + { + continue; + } + setData(index.child(nChildIndex, 0), state, Qt::CheckStateRole); + } + m_pView->update(); + } +} + +void CTrendTreeModel::updateNodeVisualState(const QString &content, QItemSelection &selection) +{ + for(int nRow(0); nRow < m_rootItem->childCount(); nRow++) + { + QModelIndex topLevelIndex = createIndex(nRow, 0, m_rootItem->child(nRow)); + bool hit = traverNode(content, topLevelIndex, selection); + m_pView->setRowHidden(topLevelIndex.row(), topLevelIndex.parent(), !hit); + } +} + +void CTrendTreeModel::setFilterWhiteList(int itemType, const QStringList &tags) +{ + m_whiteList[itemType] = tags; +} + +void CTrendTreeModel::setFilterBlackList(int itemType, const QStringList &tags) +{ + m_blackList[itemType] = tags; +} + +QStringList CTrendTreeModel::getFilterWhiteList(int itemType) +{ + std::map::iterator iter = m_whiteList.find(itemType); + if(iter != m_whiteList.end()) + { + return iter->second; + } + + return QStringList(); +} + +QStringList CTrendTreeModel::getFilterBlackList(int itemType) +{ + std::map::iterator iter = m_blackList.find(itemType); + if(iter != m_blackList.end()) + { + return iter->second; + } + + return QStringList(); +} + +bool CTrendTreeModel::isFilterShow(int itemType, const QString &tag) +{ + QStringList wlist = getFilterWhiteList(itemType); + QStringList blist = getFilterBlackList(itemType); + + if(!wlist.isEmpty()) + { + foreach (const QString &str, wlist) { + if (str.compare(tag) == 0) + return true; + } + + return false; + } + + if(!blist.isEmpty()) + { + foreach (const QString &str, blist) { + if (str.compare(tag) == 0) + return false; + } + + return true; + } + + return true; +} + +void CTrendTreeModel::loadTagInfoByDevGroup(const QString &strDevGrpTag) +{ + if(CTrendInfoManage::instance()->loadTagInfoByDevGroup(strDevGrpTag)) + { + initTrendTagInfo(); + } +} + +bool CTrendTreeModel::traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection) +{ + if(!index.isValid()) + { + return false; + } + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return false; + } + + bool isContains = false; + if(content.isEmpty()) + { + isContains = true; + } + else + { + isContains = item->text(index.column()).contains(content); + if(isContains) + { + selection.append(QItemSelectionRange(index)); + } + } + + if(TAG_TYPE == item->type()) + { + m_pView->setRowHidden(index.row(), index.parent(), !isContains); + return isContains; + } + + bool hasHit = false; + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + if(isContains) + { + break; + } + if(traverNode(content, index.child(nChildIndex, 0), selection)) + { + hasHit = true; + } + } + + if(DEV_TYPE == item->type()) + { + if(isContains) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + m_pView->setRowHidden(nChildIndex, index, false); + } + } + m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); + } + + if(DEV_GROUP_TYPE == item->type()) + { + if(isContains) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + m_pView->setRowHidden(nChildIndex, index, false); + for(int n(0); n < item->child(nChildIndex)->childCount(); n++) + { + m_pView->setRowHidden(n, createIndex(n, 0, item->child(nChildIndex)), false); + } + } + } + m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); + } + + if(LOCATION_TYPE == item->type()) + { + if(isContains) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + m_pView->setRowHidden(nChildIndex, index, false); + for(int n(0); n < item->child(nChildIndex)->childCount(); n++) + { + m_pView->setRowHidden(n, createIndex(n, 0, item->child(nChildIndex)), false); + for(int tag(0); tag < item->child(nChildIndex)->child(n)->childCount(); tag++) + { + m_pView->setRowHidden(tag, createIndex(tag, 0, item->child(nChildIndex)->child(n)), false); + } + } + } + } + m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); + } + + return hasHit | isContains; +} + +void CTrendTreeModel::clearCheckState() +{ + if(!m_rootItem) + { + return; + } + blockSignals(true); + for(int nRow(0); nRow < m_rootItem->childCount(); nRow++) + { + QModelIndex topLevelIndex = createIndex(nRow, 0, m_rootItem->child(nRow)); + updateChildCheckState(topLevelIndex, Qt::Unchecked); + } + blockSignals(false); + m_pView->update(); +} + +void CTrendTreeModel::updateTagCheckState(const QString &tag, const bool &checked) +{ + for(int nLocationRow(0); nLocationRow < m_rootItem->childCount(); nLocationRow++) + { + QTreeWidgetItem * locationItem = m_rootItem->child(nLocationRow); + for(int nDeviceGroupRow(0); nDeviceGroupRow < locationItem->childCount(); nDeviceGroupRow++) + { + QTreeWidgetItem * deviceGroupItem = locationItem->child(nDeviceGroupRow); + for(int nDeviceRow(0); nDeviceRow < deviceGroupItem->childCount(); nDeviceRow++) + { + QTreeWidgetItem * deviceItem = deviceGroupItem->child(nDeviceRow); + for(int nTagRow(0); nTagRow < deviceItem->childCount(); nTagRow++) + { + QTreeWidgetItem * tagItem = deviceItem->child(nTagRow); + if(tag == tagItem->data(0, ItemTagRole).toString()) + { + tagItem->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked); + return; + } + } + } + } + } +} + +void CTrendTreeModel::updateChildCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return; + } + if(TAG_TYPE == item->type()) + { + item->setCheckState(0, state); + } + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + updateChildCheckState(index.child(nChildIndex, 0), state); + } +} + diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendTreeModel.h b/product/src/gui/plugin/SecondReportWidget/CTrendTreeModel.h new file mode 100644 index 00000000..af4bcadd --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendTreeModel.h @@ -0,0 +1,76 @@ +#ifndef CTRENDTREEMODEL_H +#define CTRENDTREEMODEL_H + +#include "CTrendTreeItem.h" +#include +#include +#include +#include + + + +extern const int ItemTagRole; + +class CTrendTreeModel : public QAbstractItemModel +{ + Q_OBJECT +public: + CTrendTreeModel(QObject *parent = Q_NULLPTR, QTreeView *view = Q_NULLPTR); + + ~CTrendTreeModel(); + + void initTrendTagInfo(); + + void clearTrendTagInfo(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state); + + void updateNodeVisualState(const QString &content, QItemSelection &selection); + + void setFilterWhiteList(int itemType,const QStringList &tags); + + void setFilterBlackList(int itemType,const QStringList &tags); + + QStringList getFilterWhiteList(int itemType); + + QStringList getFilterBlackList(int itemType); + + bool isFilterShow(int itemType,const QString& tag); + + //加载指定设备组下测点的信息,为空代表加载所有设备组的测点 + void loadTagInfoByDevGroup(const QString &strDevGrpTag); +signals: + void itemCheckStateChanged(const QString &strTagName, const int &checkedState); + +public slots: + void clearCheckState(); + void updateTagCheckState(const QString &tag, const bool &checked); + +protected: + bool traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection); + + void updateChildCheckState(const QModelIndex &index, const Qt::CheckState &state); + +private: + QTreeView * m_pView; + QStringList m_header; + QTreeWidgetItem * m_rootItem; + std::map m_whiteList; + std::map m_blackList; +}; + +#endif // CTRENDTREEMODEL_H diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendTreeView.cpp b/product/src/gui/plugin/SecondReportWidget/CTrendTreeView.cpp new file mode 100644 index 00000000..9b072f2c --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendTreeView.cpp @@ -0,0 +1,70 @@ +#include "CTrendTreeView.h" +#include "CTrendTreeModel.h" +#include +#include +#include + +CTrendTreeView::CTrendTreeView(QWidget *parent) + : QTreeView(parent) +{ + +} + +void CTrendTreeView::contextMenuEvent(QContextMenuEvent *event) +{ + CTrendTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); + if(Q_NULLPTR != pItem) + { + if(DEV_TYPE == pItem->type()) + { + QMenu menu; + menu.addAction(tr("全选"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Checked); }); + menu.addAction(tr("清空"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Unchecked); }); + menu.exec(event->globalPos()); + } + } + else + { + QMenu menu; + menu.addAction(tr("刷新"), [=](){emit refreshTagInfo();}); + menu.exec(event->globalPos()); + } + } + return; +} + +void CTrendTreeView::mouseDoubleClickEvent(QMouseEvent *event) +{ + CTrendTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QModelIndex index = indexAt(event->pos()); + QTreeWidgetItem * pItem = static_cast(index.internalPointer()); + if(Q_NULLPTR != pItem) + { + if(TAG_TYPE == pItem->type()) + { + Qt::CheckState state = pItem->data(0, Qt::CheckStateRole).value(); + if (Qt::Checked == state) + { + state = Qt::Unchecked; + } + else + { + state = Qt::Checked; + } + pModel->setData(index, state, Qt::CheckStateRole); + update(); + }else if(DEV_GROUP_TYPE == pItem->type()) + { + int row=pModel->parent(index).row(); + pModel->loadTagInfoByDevGroup(pItem->data(0,ItemTagRole).toString()); + expand(pModel->index(row,0)); + } + } + } + return QTreeView::mouseDoubleClickEvent(event); +} diff --git a/product/src/gui/plugin/SecondReportWidget/CTrendTreeView.h b/product/src/gui/plugin/SecondReportWidget/CTrendTreeView.h new file mode 100644 index 00000000..8a8fd42b --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTrendTreeView.h @@ -0,0 +1,20 @@ +#ifndef CTRENDTREEVIEW_H +#define CTRENDTREEVIEW_H + +#include + +class CTrendTreeView : public QTreeView +{ + Q_OBJECT +public: + CTrendTreeView(QWidget *parent = Q_NULLPTR); + +signals: + void refreshTagInfo(); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); +}; + +#endif // CTRENDTREEVIEW_H diff --git a/product/src/gui/plugin/SecondReportWidget/CTsdbQuery.cpp b/product/src/gui/plugin/SecondReportWidget/CTsdbQuery.cpp new file mode 100644 index 00000000..67fcab08 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTsdbQuery.cpp @@ -0,0 +1,341 @@ +#include "CTsdbQuery.h" +#include "db_his_query_api/DbHisQueryApi.h" +#include "public/pub_logger_api/logger.h" +#include "db_api_ex/CDbApi.h" +#include "CTrendInfoManage.h" +#include + +CTsdbQuery::CTsdbQuery() +{ + m_pVecMpKey = new std::vector(); + m_pVecResult = new std::vector *>(); +} + +CTsdbQuery::~CTsdbQuery() +{ + +} + +void CTsdbQuery::SetTagList(QStringList & tagList) +{ + m_tagList = tagList; + + for (int i = 0; i < m_tagList.length(); i++) + { + SMeasPointKey key; + + //时序库的测点标签样式为 byq.BYQ_LDB10.ATemp + std::string tag_tmp = m_tagList[i].toStdString(); + char * tag = (char*)malloc(tag_tmp.size() + 1); + memset(tag, 0, tag_tmp.size() + 1); + memcpy(tag, tag_tmp.c_str(), tag_tmp.size()); + key.m_pszTagName = tag; + + //时序库的测点类型 + key.m_enType = getMeasType(CTrendInfoManage::instance()->getTagType(m_tagList[i])); + + m_pVecMpKey->push_back(key); + } +} + +void CTsdbQuery::SetTsdbConnPtr(CTsdbConnPtr & tsdbConnPtr) +{ + m_tsdbConnPtr = tsdbConnPtr; +} + +bool CTsdbQuery::queryEventByPeriod(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector &record) +{ + QTime time; + time.start(); + + for (size_t nIndex(0); nIndex < m_pVecMpKey->size(); nIndex++) + { + m_pVecResult->push_back(new std::vector()); + } + int msec1 = time.elapsed(); + + EnComputeMethod method = CM_NULL; + switch (mode) + { + case MODE_NULL:method = CM_NULL; break; + case MODE_MAX:method = CM_MAX; break; + case MODE_MIN:method = CM_MIN; break; + case MODE_MEAN:method = CM_MEAN; break; + default:method = CM_NULL; break; + } + std::vector vecStatusNotHave = getVecStatusNotHave(m_pVecMpKey->size()); + if (!getHisValue(*m_tsdbConnPtr, 10000, *m_pVecMpKey, startTime, endTime, NULL, &vecStatusNotHave, method, 0, FM_NULL_METHOD, *m_pVecResult)) + { + LOGERROR("CTsdbQuery::queryEventByPeriod: 查询超时!Lower: %I64u, Upper: %I64u", startTime, endTime); + return false; + } + int msec2 = time.elapsed(); + LOGINFO("CTsdbQuery::queryEventByPeriod() Lower: %I64u, Upper: %I64u size: %d influx begin: %d end: %d", + startTime, endTime, m_pVecMpKey->size(), msec1, msec2); + + parseResult(startTime, endTime, mode, record); + + releaseMem(); + + return true; +} + +bool CTsdbQuery::queryEventByPeriod(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector>& record) +{ + QTime time; + time.start(); + + for (size_t nIndex(0); nIndex < m_pVecMpKey->size(); nIndex++) + { + m_pVecResult->push_back(new std::vector()); + } + int msec1 = time.elapsed(); + + EnComputeMethod method = CM_NULL; + switch (mode) + { + case MODE_NULL:method = CM_NULL; break; + case MODE_MAX:method = CM_MAX; break; + case MODE_MIN:method = CM_MIN; break; + case MODE_MEAN:method = CM_MEAN; break; + default:method = CM_NULL; break; + } + std::vector vecStatusNotHave = getVecStatusNotHave(m_pVecMpKey->size()); + if (!getHisValue(*m_tsdbConnPtr, 10000, *m_pVecMpKey, startTime, endTime, NULL, &vecStatusNotHave, method, 0, FM_NULL_METHOD, *m_pVecResult)) + { + LOGERROR("CTsdbQuery::queryEventByPeriod: 查询超时!Lower: %I64u, Upper: %I64u", startTime, endTime); + return false; + } + int msec2 = time.elapsed(); + LOGINFO("CTsdbQuery::queryEventByPeriod() Lower: %I64u, Upper: %I64u size: %d influx begin: %d end: %d", + startTime, endTime, m_pVecMpKey->size(), msec1, msec2); + + parseResult(startTime, endTime, mode, record); + + releaseMem(); + + return true; +} + + +bool CTsdbQuery::queryEventByPeriod(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector>>& record) +{ + QTime time; + time.start(); + + for (size_t nIndex(0); nIndex < m_pVecMpKey->size(); nIndex++) + { + m_pVecResult->push_back(new std::vector()); + } + int msec1 = time.elapsed(); + + std::vector vecStatusNotHave = getVecStatusNotHave(m_pVecMpKey->size()); + + if (!getHisValue(*m_tsdbConnPtr, 10000, *m_pVecMpKey, startTime, endTime, NULL, &vecStatusNotHave, CM_NULL, 0, FM_NULL_METHOD, *m_pVecResult)) + { + LOGERROR("CTsdbQuery::queryEventByPeriod: 查询超时!Lower: %I64u, Upper: %I64u", startTime, endTime); + return false; + } + int msec2 = time.elapsed(); + LOGINFO("CTsdbQuery::queryEventByPeriod() Lower: %I64u, Upper: %I64u size: %d influx begin: %d end: %d", + startTime, endTime, m_pVecMpKey->size(), msec1, msec2); + + parseResult(startTime, endTime, mode, record); + + releaseMem(); + + return true; +} + +void CTsdbQuery::releaseMem() +{ + //< 释放结果集 + std::vector *>::iterator res = m_pVecResult->begin(); + while (res != m_pVecResult->end()) + { + delete (*res); + ++res; + } + m_pVecResult->clear(); + + //< 释放测点信息 + std::vector::iterator key = m_pVecMpKey->begin(); + while (m_pVecMpKey->end() != key) + { + free((char*)key->m_pszTagName); + ++key; + } + m_pVecMpKey->clear(); +} + +EnMeasPiontType CTsdbQuery::getMeasType(const QString &type) +{ + if ("analog" == type) + { + return MPT_AI; //< 模拟量 + } + else if ("digital" == type) + { + return MPT_DI; //< 数字量 + } + else if ("mix" == type) + { + return MPT_MIX; //< 混合量 + } + else if ("accuml" == type) + { + return MPT_ACC; //< 累计(电度)量 + } + return MPT_AI; //< INVALID +} + +//EnMeasPiontType CTsdbQuery::getMeasType(const QString &tagName) +//{ +// iot_dbms::CDbApi reader(DB_CONN_MODEL_READ); +// if (!reader.open()) +// { +// return MPT_AI; +// } +// +// QString mysql_str; +// mysql_str = QString("SELECT DESCRIPTION FROM analog WHERE TAG_NAME = '%1'").arg(tagName); +// +// QSqlQuery query; +// if (reader.execute(mysql_str, query)) +// { +// if (query.next()) +// { +// reader.close(); +// return MPT_AI; +// } +// } +// +// mysql_str = QString("SELECT DESCRIPTION FROM digital WHERE TAG_NAME = '%1'").arg(tagName); +// if (reader.execute(mysql_str, query)) +// { +// if (query.next()) +// { +// reader.close(); +// return MPT_DI; +// } +// } +// +// mysql_str = QString("SELECT DESCRIPTION FROM mix WHERE TAG_NAME = '%1'").arg(tagName); +// if (reader.execute(mysql_str, query)) +// { +// if (query.next()) +// { +// reader.close(); +// return MPT_MIX; +// } +// } +// +// mysql_str = QString("SELECT DESCRIPTION FROM accuml WHERE TAG_NAME = '%1'").arg(tagName); +// if (reader.execute(mysql_str, query)) +// { +// if (query.next()) +// { +// reader.close(); +// return MPT_ACC; +// } +// } +// +// return MPT_AI; +//} + +void CTsdbQuery::parseResult(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector &record) +{ + Q_UNUSED(startTime); + Q_UNUSED(endTime); + Q_UNUSED(mode); + + for (size_t nIndex(0); nIndex < m_pVecResult->size(); nIndex++) + { + if (m_pVecResult->at(nIndex)->size() == 0) + { + record[nIndex] = 0; + } + else + { + if (m_pVecMpKey->at(nIndex).m_enType == MPT_AI || m_pVecMpKey->at(nIndex).m_enType == MPT_ACC) + { + record[nIndex] = m_pVecResult->at(nIndex)->at(0).m_uniValue.m_float64Val; + } + else + { + record[nIndex] = m_pVecResult->at(nIndex)->at(0).m_uniValue.m_int32Val; + } + } + } +} + +void CTsdbQuery::parseResult(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector> &record) +{ + Q_UNUSED(startTime); + Q_UNUSED(endTime); + Q_UNUSED(mode); + + for (size_t nIndex(0); nIndex < m_pVecResult->size(); nIndex++) + { + if (m_pVecResult->at(nIndex)->size() == 0) + { + record[nIndex].first = INVALID_VS; + record[nIndex].second = -1; + } + else + { + record[nIndex].first = VALID_VS; + if (m_pVecMpKey->at(nIndex).m_enType == MPT_AI || m_pVecMpKey->at(nIndex).m_enType == MPT_ACC) + { + record[nIndex].second = m_pVecResult->at(nIndex)->at(0).m_uniValue.m_float64Val; + } + else + { + record[nIndex].second = m_pVecResult->at(nIndex)->at(0).m_uniValue.m_int32Val; + } + } + } +} + +//所有查询的量的状态,模拟量和累计量两个正常的状态目前都是2(2024年4月26日) +std::vector CTsdbQuery::getVecStatusNotHave(size_t cnt) +{ + std::vector vecNotStatusHave(cnt); + for (size_t nIndex(0); nIndex >>& record) +{ + Q_UNUSED(startTime); + Q_UNUSED(endTime); + Q_UNUSED(mode); + + for (int i = 0; i < m_pVecResult->size(); i++) + { + std::vector>record_temp; + if (m_pVecResult->at(i)->size() > 0) + { + for (int j = 0; j < m_pVecResult->at(i)->size(); j++) + { + QPairpair_temp; + pair_temp.first = m_pVecResult->at(i)->at(j).m_nTime; + + if (m_pVecMpKey->at(i).m_enType == MPT_AI || m_pVecMpKey->at(i).m_enType == MPT_ACC) + { + pair_temp.second= m_pVecResult->at(i)->at(j).m_uniValue.m_float64Val; + } + else + { + pair_temp.second = m_pVecResult->at(i)->at(j).m_uniValue.m_int32Val; + } + record_temp.push_back(pair_temp); + } + } + record.push_back(record_temp); + } +} diff --git a/product/src/gui/plugin/SecondReportWidget/CTsdbQuery.h b/product/src/gui/plugin/SecondReportWidget/CTsdbQuery.h new file mode 100644 index 00000000..bd1bbe91 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CTsdbQuery.h @@ -0,0 +1,40 @@ +#ifndef CTSDBQUERY_H +#define CTSDBQUERY_H + +#include "CStatisCommon.h" +#include "tsdb_api/TsdbApi.h" +#include "db_his_query_api/DbHisQueryBase.h" + +#define STAUS_NOT_HAVE 4 +using namespace iot_dbms; +enum VALUE_STATUS { INVALID_VS = 0, VALID_VS=1}; +class CTsdbQuery +{ +public: + CTsdbQuery(); + ~CTsdbQuery(); + + void SetTagList(QStringList &tagList); + void SetTsdbConnPtr(CTsdbConnPtr &tsdbConnPtr); + bool queryEventByPeriod(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector& record); + bool queryEventByPeriod(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector>>& record); + bool queryEventByPeriod(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector>& record); + +private: + void releaseMem(); + EnMeasPiontType getMeasType(const QString &tagName); + void parseResult(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector &record); + void parseResult(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector>>& record); + void parseResult(qint64 startTime, qint64 endTime, EN_STATIS_MODE mode, std::vector> &record); + std::vector getVecStatusNotHave(size_t cnt); + +private: + std::vector * m_pVecMpKey; + std::vector *> *m_pVecResult; + +private: + iot_dbms::CTsdbConnPtr m_tsdbConnPtr; + QStringList m_tagList; +}; + +#endif // CTSDBQUERY_H diff --git a/product/src/gui/plugin/SecondReportWidget/CWaittingDlg.cpp b/product/src/gui/plugin/SecondReportWidget/CWaittingDlg.cpp new file mode 100644 index 00000000..c2de24f4 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CWaittingDlg.cpp @@ -0,0 +1,42 @@ +#include "CWaittingDlg.h" +#include "ui_CWaittingDlg.h" +#include "pub_utility_api/FileUtil.h" +#include "pub_utility_api/FileStyle.h" + +CWaittingDlg::CWaittingDlg(QWidget *parent) : + QDialog(parent), + ui(new Ui::CWaittingDlg) +{ + ui->setupUi(this); + connect(ui->stopBtn, &QPushButton::clicked, this, &CWaittingDlg::slotStopBtnClicked); + + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss"); + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + setStyleSheet(qss); +} + +CWaittingDlg::~CWaittingDlg() +{ + delete ui; +} + +void CWaittingDlg::slotStopBtnClicked() +{ + emit sigStopSearching(); +} + +void CWaittingDlg::closeEvent(QCloseEvent *event) +{ + Q_UNUSED(event); + + emit sigStopSearching(); + this->close(); +} diff --git a/product/src/gui/plugin/SecondReportWidget/CWaittingDlg.h b/product/src/gui/plugin/SecondReportWidget/CWaittingDlg.h new file mode 100644 index 00000000..dfdcae93 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CWaittingDlg.h @@ -0,0 +1,32 @@ +#ifndef CWAITTINGDLG_H +#define CWAITTINGDLG_H + +#include +#include + +namespace Ui { +class CWaittingDlg; +} + +class CWaittingDlg : public QDialog +{ + Q_OBJECT + +public: + explicit CWaittingDlg(QWidget *parent = nullptr); + ~CWaittingDlg(); + +signals: + void sigStopSearching(); + +public slots: + void slotStopBtnClicked(); + +protected: + void closeEvent(QCloseEvent* event); + +private: + Ui::CWaittingDlg *ui; +}; + +#endif // CWAITTINGDLG_H diff --git a/product/src/gui/plugin/SecondReportWidget/CWaittingDlg.ui b/product/src/gui/plugin/SecondReportWidget/CWaittingDlg.ui new file mode 100644 index 00000000..1d4bdd97 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/CWaittingDlg.ui @@ -0,0 +1,45 @@ + + + CWaittingDlg + + + + 0 + 0 + 458 + 226 + + + + 报表管理 + + + + + + + + + 查询中,请等待或终止查询 . . . +(退出窗口默认终止查询) + + + Qt::AlignCenter + + + + + + + 终止查询 + + + + + + + + + + + diff --git a/product/src/gui/plugin/SecondReportWidget/SecondReportWidget.pro b/product/src/gui/plugin/SecondReportWidget/SecondReportWidget.pro new file mode 100644 index 00000000..bd7662b6 --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/SecondReportWidget.pro @@ -0,0 +1,82 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2019-11-07T15:25:58 +# +#------------------------------------------------- + +QT += core gui sql printsupport charts xml + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = SecondReportWidget +TEMPLATE = lib + +CONFIG += plugin +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +HEADERS += \ + ./CStatisCommon.h \ + ./CTrendInfoManage.h \ + ./CTsdbQuery.h \ + ./CHisDataManage.h \ + ./CMainWindow.h \ + ./CProcessManage.h \ + ./CSecondReportPluginWidget.h \ + ./CSecondReportWidget.h \ + ./CTableView.h \ + ./CReportFavTreeWidget.h \ + ./CTrendTreeModel.h \ + ./CTrendTreeView.h \ + ./CTrendTreeItem.h \ + CHeaderView.h \ + CReportTableView.h \ + CWaittingDlg.h + +SOURCES += \ + #main.cpp \ + ./CHisDataManage.cpp \ + ./CMainWindow.cpp \ + ./CTrendInfoManage.cpp \ + ./CProcessManage.cpp \ + ./CSecondReportPluginWidget.cpp \ + ./CSecondReportWidget.cpp \ + ./CTableView.cpp \ + ./CTsdbQuery.cpp \ + ./CReportFavTreeWidget.cpp \ + ./CTrendTreeItem.cpp \ + ./CTrendTreeModel.cpp \ + ./CTrendTreeView.cpp \ + CHeaderView.cpp \ + CReportTableView.cpp \ + CWaittingDlg.cpp + + +FORMS += ./CSecondReportWidget.ui \ + CMainWindow.ui \ + CWaittingDlg.ui + +RESOURCES += CSecondReportWidget.qrc + +LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -lpub_excel +LIBS += -lpub_utility_api -lpub_sysinfo_api +LIBS += -ldb_base_api -ldb_api_ex -lrdb_api -lrdb_net_api -ltsdb_api -ldb_his_query_api +LIBS += -lnet_msg_bus_api -lperm_mng_api -ldp_chg_data_api -lRetriever + +#include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/SecondReportWidget/main.cpp b/product/src/gui/plugin/SecondReportWidget/main.cpp new file mode 100644 index 00000000..277b293f --- /dev/null +++ b/product/src/gui/plugin/SecondReportWidget/main.cpp @@ -0,0 +1,75 @@ +#include +#include "CMainWindow.h" +#include "pub_logger_api/logger.h" +#include "net_msg_bus_api/MsgBusApi.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + //<初始化消息总线 + QStringList arguments=QCoreApplication::arguments(); + std::string name="Admin"; + std::string password ="1"; + int group =1; + for(int index(0);indexPermDllInit()) + { + return -1; + } + + if(perm->SysLogin(name, password, group, 12*60*60, "hmi") != 0) + { + return -1; + } + + { + CMainWindow n(false,NULL); + n.initialize(E_Trend_Window); + //n.initialize(E_Alarm_Window); + + n.show(); + app.exec(); + } + + //<释放消息总线 + iot_net::releaseMsgBus(); + iot_public::StopLogSystem(); + + return 0; +} + diff --git a/product/src/gui/plugin/SequenceManageWidget/CSequenceDBInterface.cpp b/product/src/gui/plugin/SequenceManageWidget/CSequenceDBInterface.cpp index 0f2768cf..81d9dad0 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CSequenceDBInterface.cpp +++ b/product/src/gui/plugin/SequenceManageWidget/CSequenceDBInterface.cpp @@ -281,7 +281,7 @@ QList CSequenceDBInterface::queryRunSequenceNodeList() } //<查询顺控 QSqlQuery query; - QString sqlSequenceQuery = QString("select name, description, seq_type, location_id, timeflag from %1").arg(SEQUENCE_SETTING); + QString sqlSequenceQuery = QString("select name, description, seq_type, location_id, timeflag from %1 order by name").arg(SEQUENCE_SETTING); m_pReadDb->execute(sqlSequenceQuery, query); if(query.isActive()) { diff --git a/product/src/gui/plugin/SequenceManageWidget/CSequenceManagePluginWidget.h b/product/src/gui/plugin/SequenceManageWidget/CSequenceManagePluginWidget.h index 10c2e3fd..77c7192e 100644 --- a/product/src/gui/plugin/SequenceManageWidget/CSequenceManagePluginWidget.h +++ b/product/src/gui/plugin/SequenceManageWidget/CSequenceManagePluginWidget.h @@ -7,7 +7,7 @@ class CSequenceManagePluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/SequenceWidget/CSeqForHmiApi.cpp b/product/src/gui/plugin/SequenceWidget/CSeqForHmiApi.cpp index 7f773be6..fd33d666 100644 --- a/product/src/gui/plugin/SequenceWidget/CSeqForHmiApi.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSeqForHmiApi.cpp @@ -1,7 +1,7 @@ #include "application/sequence_server_api/CSeqForHmiApi.h" #include "CSeqForHmiApiImpl.h" -using namespace iot_application; +using namespace iot_app; using namespace iot_idl::sequence; CSeqForHmiApi::CSeqForHmiApi(int appid) { diff --git a/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.cpp b/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.cpp index 3cbac5b0..f4005a7a 100644 --- a/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.cpp @@ -4,9 +4,9 @@ #include "CSeqForHmiApiImpl.h" -using namespace iot_application; +using namespace iot_app; using namespace iot_idl::sequence; -iot_application::CSeqForHmiApiImpl::CSeqForHmiApiImpl( +iot_app::CSeqForHmiApiImpl::CSeqForHmiApiImpl( int appid, CSeqForHmiApi* api) : CTimerThreadBase("CSeqForHmiApiImpl thread", 100), diff --git a/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.h b/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.h index 2ab4cf27..d35e9e87 100644 --- a/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.h +++ b/product/src/gui/plugin/SequenceWidget/CSeqForHmiApiImpl.h @@ -6,7 +6,7 @@ #include "net/net_msg_bus_api/CMbCommunicator.h" #include "application/sequence_server_api/CSeqForHmiApi.h" -namespace iot_application { +namespace iot_app { using namespace iot_idl::sequence; class CSeqForHmiApiImpl : public iot_public::CTimerThreadBase diff --git a/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.cpp b/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.cpp index 9c7f5881..08def238 100644 --- a/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSeqPermDialog.cpp @@ -282,6 +282,8 @@ void CSeqPermDialog::slotGuardUserGrpChange(int index) void CSeqPermDialog::slotGuardUserChange(int index) { + Q_UNUSED(index); + slotGuardUserChange(); } diff --git a/product/src/gui/plugin/SequenceWidget/CSequenceDataManage.cpp b/product/src/gui/plugin/SequenceWidget/CSequenceDataManage.cpp index db74ff26..239e4aad 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequenceDataManage.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSequenceDataManage.cpp @@ -269,37 +269,39 @@ QList CSequenceDataManage::querySequenceList(const QStringList &seqNam return sequenceList; } - QStringList strLoaclDomainSequenceName; if(!m_pReadDb->isOpen()) { return sequenceList; } + + QString strSeqNameFilter = QString("in('%1')").arg(seqNameList.join("','")); //<查询顺控 QSqlQuery query; - QString sqlSequenceQuery = QString("select name, description, seq_type, location_id, timeflag from %1").arg(SEQUENCE_SETTING); + QString sqlSequenceQuery = QString("select name, description, seq_type, location_id, timeflag from %1 where name %2 order by name asc").arg(SEQUENCE_SETTING).arg(strSeqNameFilter); m_pReadDb->execute(sqlSequenceQuery, query); if(query.isActive()) { while(query.next()) { QString seqName = query.value(0).toString(); - if(seqNameList.contains(seqName)) - { - Sequence sequence; - sequence.seqName = seqName; - sequence.seqDescription = query.value(1).toString(); - sequence.seqType = query.value(2).toInt(); - sequence.locationID = query.value(3).toInt(); - sequence.location = queryLocationName(sequence.locationID); - sequence.timeFlag = query.value(4).toULongLong(); - sequence.nodeType = E_Node_Sequence; - sequenceList.append(sequence); - strLoaclDomainSequenceName.append(seqName); - } + Sequence sequence; + sequence.seqName = seqName; + sequence.seqDescription = query.value(1).toString(); + sequence.seqType = query.value(2).toInt(); + sequence.locationID = query.value(3).toInt(); + sequence.location = queryLocationName(sequence.locationID); + sequence.timeFlag = query.value(4).toULongLong(); + sequence.nodeType = E_Node_Sequence; + sequenceList.append(sequence); } } - //<查询功能 + if(sequenceList.empty()) + { + return sequenceList; + } + + //<查询功能 QList functionList; QString sqlFunctionQuery = QString("SELECT DISTINCT\ %1.seq_name, \ @@ -307,115 +309,94 @@ QList CSequenceDataManage::querySequenceList(const QStringList &seqNam %2.description, \ %1.func_no, \ %1.timeflag \ - FROM \ - %1 LEFT JOIN %2 ON \ - %1.func_name = %2.name").arg(SEQUENCE_DEFINE).arg(SEQUENCE_FUNCTION); + FROM \ + %1 INNER JOIN %2 ON \ + %1.seq_name %3 AND \ + %1.func_name = %2.name \ + ORDER BY seq_name ASC,func_no ASC").arg(SEQUENCE_DEFINE).arg(SEQUENCE_FUNCTION).arg(strSeqNameFilter); m_pReadDb->execute(sqlFunctionQuery, query); if(query.isActive()) { while(query.next()) { - QString seqName = query.value(0).toString(); - if(seqNameList.contains(seqName) && strLoaclDomainSequenceName.contains(seqName)) - { - Sequence function; - function.seqName = seqName; - function.funcName = query.value(1).toString(); - function.funcDescription = query.value(2).toString(); - function.funcNo = query.value(3).toInt(); - function.timeFlag = query.value(4).toULongLong(); - function.nodeType = E_Node_Function; + QString seqName = query.value(0).toString(); + Sequence function; + function.seqName = seqName; + function.funcName = query.value(1).toString(); + function.funcDescription = query.value(2).toString(); + function.funcNo = query.value(3).toInt(); + function.timeFlag = query.value(4).toULongLong(); + function.nodeType = E_Node_Function; - bool result = false; - for (int nIndex(0); nIndex < functionList.size(); nIndex++) - { - if (function.funcNo < functionList[nIndex].funcNo) - { - functionList.insert(nIndex, function); - result = true; - break; - } - } - if (!result) - { - functionList.append(function); - } - } + functionList.append(function); } sequenceList.append(functionList); } - //<查询动作 - for(int functionIndex(0); functionIndex < functionList.size(); functionIndex++) - { - QList actionList; - QString sqlActionQuery = QString("SELECT \ - %1.seq_name, \ - %1.func_name, \ - %1.func_no, \ - %2.action_name, \ - %2.action_no, \ - %2.delaytime, \ - %3.key_id_tag, \ - %3.timeflag, \ - %3.target_value, \ - %3.location_id, \ - %3.sub_system, \ - %3.description \ - FROM \ - %1, %2, %3 \ - WHERE \ - %1.func_name = '%4' \ - AND %1.func_name = %2.name \ - AND %2.action_name = %3.name").arg(SEQUENCE_DEFINE).arg(SEQUENCE_FUNCTION).arg(SEQUENCE_ACTION).arg(functionList[functionIndex].funcName); + if(functionList.empty()) + { + return sequenceList; + } - m_pReadDb->execute(sqlActionQuery, query); - if(query.isActive()) - { - while(query.next()) - { - QString seqName = query.value(0).toString(); - if(seqNameList.contains(seqName) && strLoaclDomainSequenceName.contains(seqName)) - { - Sequence action; - action.seqName = seqName; - action.funcName = query.value(1).toString(); - action.funcNo = query.value(2).toInt(); - action.actionName = query.value(3).toString(); - action.actionNo = query.value(4).toInt(); - action.delay = query.value(5).toInt(); - action.tagInfo = query.value(6).toString(); - QStringList strListTagInfo = action.tagInfo.split("."); - action.tagName = queryTagName(strListTagInfo.first(), action.tagInfo.section(".", 1, strListTagInfo.size() - 2)); - action.timeFlag = query.value(7).toULongLong(); - QString strTagTextName = queryTagTextName(strListTagInfo.first(), action.tagInfo.section(".", 1, strListTagInfo.size() - 2)); - action.targetState = queryStateName(strTagTextName, query.value(8).toInt()); - action.locationID = query.value(9).toInt(); - action.location = queryLocationName(action.locationID); - action.subSystemID = query.value(10).toInt(); - action.actionDescription = query.value(11).toString(); - action.nodeType = E_Node_Action; + //查询动作 + QStringList listFuncName; + foreach(Sequence seq , functionList) + { + listFuncName << seq.funcName; + } + + QString strFuncNameFilter = QString("in('%1')").arg(listFuncName.join("','")); + QList actionList; + QString sqlActionQuery = QString("SELECT \ + %1.seq_name, \ + %1.func_name, \ + %1.func_no, \ + %2.action_name, \ + %2.action_no, \ + %2.delaytime, \ + %3.key_id_tag, \ + %3.timeflag, \ + %3.target_value, \ + %3.location_id, \ + %3.sub_system, \ + %3.description \ + FROM \ + %1, %2, %3 \ + WHERE \ + %1.func_name %4 \ + AND %1.func_name = %2.name \ + AND %2.action_name = %3.name \ + ORDER BY func_no ASC,action_no ASC").arg(SEQUENCE_DEFINE).arg(SEQUENCE_FUNCTION).arg(SEQUENCE_ACTION).arg(strFuncNameFilter); + + m_pReadDb->execute(sqlActionQuery, query); + if(query.isActive()) + { + while(query.next()) + { + QString seqName = query.value(0).toString(); + Sequence action; + action.seqName = seqName; + action.funcName = query.value(1).toString(); + action.funcNo = query.value(2).toInt(); + action.actionName = query.value(3).toString(); + action.actionNo = query.value(4).toInt(); + action.delay = query.value(5).toInt(); + action.tagInfo = query.value(6).toString(); + QStringList strListTagInfo = action.tagInfo.split("."); + action.tagName = queryTagName(strListTagInfo.first(), action.tagInfo.section(".", 1, strListTagInfo.size() - 2)); + action.timeFlag = query.value(7).toULongLong(); + QString strTagTextName = queryTagTextName(strListTagInfo.first(), action.tagInfo.section(".", 1, strListTagInfo.size() - 2)); + action.targetState = queryStateName(strTagTextName, query.value(8).toInt()); + action.locationID = query.value(9).toInt(); + action.location = queryLocationName(action.locationID); + action.subSystemID = query.value(10).toInt(); + action.actionDescription = query.value(11).toString(); + action.nodeType = E_Node_Action; + + actionList.append(action); + } + sequenceList.append(actionList); + } - bool result = false; - for (int nIndex(0); nIndex < actionList.size(); nIndex++) - { - if (action.actionNo < actionList[nIndex].actionNo) - { - actionList.insert(nIndex, action); - result = true; - break; - } - } - if (!result) - { - actionList.append(action); - } - } - } - sequenceList.append(actionList); - } - } return sequenceList; } - - diff --git a/product/src/gui/plugin/SequenceWidget/CSequenceMsgHandle.h b/product/src/gui/plugin/SequenceWidget/CSequenceMsgHandle.h index 642047e3..d1ab88b6 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequenceMsgHandle.h +++ b/product/src/gui/plugin/SequenceWidget/CSequenceMsgHandle.h @@ -5,7 +5,7 @@ class CSequenceDataManage; -class CSequenceMsgHandle : public iot_application::CSeqForHmiApi +class CSequenceMsgHandle : public iot_app::CSeqForHmiApi { public: CSequenceMsgHandle(); diff --git a/product/src/gui/plugin/SequenceWidget/CSequencePluginWidget.h b/product/src/gui/plugin/SequenceWidget/CSequencePluginWidget.h index 9e2737f8..5aec4b05 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequencePluginWidget.h +++ b/product/src/gui/plugin/SequenceWidget/CSequencePluginWidget.h @@ -7,7 +7,7 @@ class CSequencePluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/SequenceWidget/CSequenceStateManage.cpp b/product/src/gui/plugin/SequenceWidget/CSequenceStateManage.cpp index 144f0ee2..7847d045 100644 --- a/product/src/gui/plugin/SequenceWidget/CSequenceStateManage.cpp +++ b/product/src/gui/plugin/SequenceWidget/CSequenceStateManage.cpp @@ -308,7 +308,7 @@ QString CSequenceStateManage::queryTagTextName(const QString &strTableName, cons return QString(); } QSqlQuery query; - QString sqlQuery = QString("select state_text_name from %1 where tag_name = '%2'").arg(strTableName.toLower()).arg(strTaginfo.toLower()); + QString sqlQuery = QString("select state_text_name from %1 where tag_name = '%2'").arg(strTableName.toLower()).arg(strTaginfo); m_pReadDb->execute(sqlQuery, query); if(query.isActive()) { diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevPluginWidget.h b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevPluginWidget.h index dc85b134..a3bf6c73 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevPluginWidget.h +++ b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevPluginWidget.h @@ -7,7 +7,7 @@ class CSeriaDevPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevTableModel.h b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevTableModel.h index 8c987505..69f76537 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevTableModel.h +++ b/product/src/gui/plugin/SerialDevStatusWidget/CSeriaDevTableModel.h @@ -17,15 +17,18 @@ public: void setInterrupteDesc(const QString &text); void setNormalDesc(const QString &text); - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; private: void update(); + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + private: QString getComStatusDesc(const int &status) const; diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.cpp b/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.cpp index e9ac5cc8..2a4f0d88 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.cpp +++ b/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.cpp @@ -9,10 +9,6 @@ #include #include #include -#include -#include -#include "model_excel/xlsx/xlsxdocument.h" -#include CSerialDevStatusWidget::CSerialDevStatusWidget(QWidget *parent, bool editMode) : QWidget(parent), @@ -103,41 +99,6 @@ void CSerialDevStatusWidget::setNormalDesc(const QString &text) } } -void CSerialDevStatusWidget::soltExportExcel() -{ - - QString sExcelFileName = QFileDialog::getSaveFileName(this, tr("保存"), QString(""), "*.xlsx"); - if(sExcelFileName.isEmpty()) - return; - - QXlsx::Document xlsx; - - int rowcount=m_pTableModel->rowCount(); - int colcount=m_pTableModel->columnCount(); - for(int i=0;iheaderData(i, Qt::Horizontal).toString()); - } - // 写内容 - for ( int i=0; idata(m_pTableModel->index(i, j)).toString(); - xlsx.write( i+2, j+1, sText ); - } - } - // 保存到文件 - if(xlsx.saveAs(sExcelFileName)) - { - QMessageBox::information(this,tr("提示"),tr("导出成功!")); - } - else - { - QMessageBox::information(this,tr("提示"),tr("保存失败")); - } -} - void CSerialDevStatusWidget::initStyle() { QString qss = QString(); @@ -166,31 +127,18 @@ void CSerialDevStatusWidget::initStyle() void CSerialDevStatusWidget::initView() { - QSplitter * splitter = new QSplitter(Qt::Horizontal); - QWidget *rightwidget = new QWidget(splitter); - m_btnExport = new QPushButton(tr("导出"), rightwidget); - m_pTreeWidget = new QTreeWidget; m_pTreeWidget->setColumnCount(1); m_pTreeWidget->setHeaderLabel(tr("RTU/端口")); - - m_pTableView = new QTableView(rightwidget); + m_pTableView = new QTableView; m_pTableView->setSelectionBehavior(QAbstractItemView::SelectRows); m_pTableView->setSelectionMode(QAbstractItemView::NoSelection); m_pTableView->horizontalHeader()->setStretchLastSection(true); - m_pTableModel = new CSeriaDevTableModel; m_pTableView->setModel(m_pTableModel); - + QSplitter * splitter = new QSplitter(Qt::Horizontal); splitter->addWidget(m_pTreeWidget); - // splitter->addWidget(m_pTableView); - - QVBoxLayout *rightLayout = new QVBoxLayout(rightwidget); - rightLayout->addWidget(m_pTableView); - rightLayout->addWidget(m_btnExport); - - splitter->addWidget(rightwidget); - + splitter->addWidget(m_pTableView); splitter->setStretchFactor(0, 1); splitter->setStretchFactor(1, 3); QHBoxLayout * layout = new QHBoxLayout; @@ -250,7 +198,6 @@ void CSerialDevStatusWidget::initConnect() connect(m_pTreeWidget, &QTreeWidget::itemClicked, this, &CSerialDevStatusWidget::slotItemClicked); connect(CRealDataCollect::instance(), &CRealDataCollect::signal_updateDi, this, &CSerialDevStatusWidget::slotUpdateDi); - connect(m_btnExport, &QPushButton::clicked, this, &CSerialDevStatusWidget::soltExportExcel); if(m_pTreeWidget->topLevelItem(0)) { m_pTreeWidget->setCurrentItem(m_pTreeWidget->topLevelItem(0)); diff --git a/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.h b/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.h index ab1af11b..8469df69 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.h +++ b/product/src/gui/plugin/SerialDevStatusWidget/CSerialDevStatusWidget.h @@ -5,7 +5,6 @@ #include #include "dp_chg_data_api/CDpcdaForApp.h" #include "CSeriaCommon.h" -#include class QTreeWidget; class QTableView; @@ -32,7 +31,6 @@ public slots: void setNormalDesc(const QString &text); - void soltExportExcel(); private: void initStyle(); void initView(); @@ -47,7 +45,6 @@ private: QTreeWidget * m_pTreeWidget; QTableView * m_pTableView; CSeriaDevTableModel * m_pTableModel; - QPushButton * m_btnExport; iot_service::CDpcdaForApp *m_pDpcdaForApp; QMap m_serialStatusMap; }; diff --git a/product/src/gui/plugin/SerialDevStatusWidget/SerialDevStatusWidget.pro b/product/src/gui/plugin/SerialDevStatusWidget/SerialDevStatusWidget.pro index b7cd949f..51f71aeb 100644 --- a/product/src/gui/plugin/SerialDevStatusWidget/SerialDevStatusWidget.pro +++ b/product/src/gui/plugin/SerialDevStatusWidget/SerialDevStatusWidget.pro @@ -47,8 +47,7 @@ LIBS += \ -lprotobuf \ -lnet_msg_bus_api \ -ldp_chg_data_api \ - -lpub_utility_api \ - -lmodel_excel + -lpub_utility_api include($$PWD/../../../idl_files/idl_files.pri) diff --git a/product/src/gui/plugin/ShiftWidget/CShiftPluginWidget.h b/product/src/gui/plugin/ShiftWidget/CShiftPluginWidget.h index 6d2dea00..f7e7a9e4 100644 --- a/product/src/gui/plugin/ShiftWidget/CShiftPluginWidget.h +++ b/product/src/gui/plugin/ShiftWidget/CShiftPluginWidget.h @@ -6,7 +6,7 @@ class CShiftPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: CShiftPluginWidget(QObject *parent = 0); diff --git a/product/src/gui/plugin/SimOptWidget/CSimOptPluginWidget.h b/product/src/gui/plugin/SimOptWidget/CSimOptPluginWidget.h index 7af15490..8b6940ee 100644 --- a/product/src/gui/plugin/SimOptWidget/CSimOptPluginWidget.h +++ b/product/src/gui/plugin/SimOptWidget/CSimOptPluginWidget.h @@ -7,7 +7,7 @@ class CSimOptPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: CSimOptPluginWidget(QObject *parent = 0); diff --git a/product/src/gui/plugin/SimOptWidget/CSimOptWidget.cpp b/product/src/gui/plugin/SimOptWidget/CSimOptWidget.cpp index 65bc2cd6..d8349551 100644 --- a/product/src/gui/plugin/SimOptWidget/CSimOptWidget.cpp +++ b/product/src/gui/plugin/SimOptWidget/CSimOptWidget.cpp @@ -73,6 +73,9 @@ void CSimOptWidget::initView() bool CSimOptWidget::permCheck(int location, int region) { + Q_UNUSED(location); + Q_UNUSED(region); + // iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); // QString mess; // if(permMngPtr != NULL) @@ -233,6 +236,9 @@ void CSimOptWidget::slotAddFilter(const QString &path) void CSimOptWidget::slotItemDoubleClicked(QTreeWidgetItem *item, int cl) { + Q_UNUSED(item); + Q_UNUSED(cl); + slotStartBtn(); } diff --git a/product/src/gui/plugin/SimOptWidget/main.cpp b/product/src/gui/plugin/SimOptWidget/main.cpp index 87b39849..6fc89e44 100644 --- a/product/src/gui/plugin/SimOptWidget/main.cpp +++ b/product/src/gui/plugin/SimOptWidget/main.cpp @@ -19,7 +19,7 @@ int main(int argc, char *argv[]) return -1; } - if(perm->SysLogin("admin", "kbdct", 1, 12*60*60, "hmi") != 0) + if(perm->SysLogin("admin", "admin", 1, 12*60*60, "hmi") != 0) { return -1; } diff --git a/product/src/gui/plugin/StrategyControlWidget/CDispatchCalendarWidget.cpp b/product/src/gui/plugin/StrategyControlWidget/CDispatchCalendarWidget.cpp new file mode 100644 index 00000000..8bf90c19 --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/CDispatchCalendarWidget.cpp @@ -0,0 +1,275 @@ +#include "CDispatchCalendarWidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CStrategyDefine.h" + +CDispatchCalendarWidget::CDispatchCalendarWidget(QWidget* parent) + : QWidget(parent), + m_dbApi(new CStrategySqlApi()) +{ + initUI(); + reloadDataByDb(); +} + +void CDispatchCalendarWidget::initUI() +{ + // + QHBoxLayout* mainLayout = new QHBoxLayout(this); + + m_calendarWidget = new CCalendarWidget(); + m_calendarWidget->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader); + connect(m_calendarWidget, &CCalendarWidget::clicked, this, &CDispatchCalendarWidget::onCalendarClicked); + + // + QVBoxLayout* rightLayout = new QVBoxLayout(); + + QHBoxLayout* buttonLayout = new QHBoxLayout(); + + QPushButton* saveButton = new QPushButton(tr("保存")); + connect(saveButton, &QPushButton::clicked, this, &CDispatchCalendarWidget::onSaveButtonClicked); + + QPushButton* refreshButton = new QPushButton(tr("刷新")); + connect(refreshButton, &QPushButton::clicked, this, &CDispatchCalendarWidget::onRefreshButtonClicked); + + buttonLayout->addWidget(new QPushButton(tr("设为默认"))); + buttonLayout->addWidget(saveButton); + buttonLayout->addWidget(refreshButton); + + // + QGroupBox* runStrategyGroupBox = new QGroupBox(tr("运行策略")); + m_runStrategyLayout = new QVBoxLayout(runStrategyGroupBox); + + m_peakValleyTemplateLayout = new QHBoxLayout(); + + m_peakValleyTemplateBox = new QComboBox(); + connect(m_peakValleyTemplateBox, &QComboBox::currentTextChanged, this, &CDispatchCalendarWidget::onPeakValleyTemplateBoxCurrentTextChange); + + m_peakValleyTemplateLayout->addWidget(new QLabel(tr(iot_service::CStrategyDefine::PeakValleyTemplateName))); + m_peakValleyTemplateLayout->addWidget(m_peakValleyTemplateBox); + + // + m_hcRemoteTemplateLayout = new QHBoxLayout(); + + m_hcRemoteTemplateBox = new QComboBox(); + connect(m_hcRemoteTemplateBox, &QComboBox::currentTextChanged, this, &CDispatchCalendarWidget::onHcRemoteTemplateBoxCurrentTextChange); + + m_hcRemoteTemplateLayout->addWidget(new QLabel(tr(iot_service::CStrategyDefine::HcRemoteTemplateName))); + m_hcRemoteTemplateLayout->addWidget(m_hcRemoteTemplateBox); + + // + m_realTimeControlTemplateLayout = new QHBoxLayout(); + + m_realTimeControlTemplateBox = new QComboBox(); + connect(m_realTimeControlTemplateBox, &QComboBox::currentTextChanged, this, &CDispatchCalendarWidget::onRealTimeControlTemplateBoxCurrentTextChange); + + m_realTimeControlTemplateLayout->addWidget(new QLabel(tr(iot_service::CStrategyDefine::RealTimeControlTemplateName))); + m_realTimeControlTemplateLayout->addWidget(m_realTimeControlTemplateBox); + + m_runStrategyLayout->insertLayout(0, m_peakValleyTemplateLayout); + m_runStrategyLayout->insertLayout(1, m_hcRemoteTemplateLayout); + m_runStrategyLayout->insertLayout(2, m_realTimeControlTemplateLayout); + m_runStrategyLayout->addStretch(); + + // + QGroupBox* appendStrategyGroupBox = new QGroupBox(tr("附加策略")); + m_appendStrategyLayout = new QVBoxLayout(appendStrategyGroupBox); + + m_demandRefluxStrategyLayout = new QHBoxLayout(); + + m_demandRefluxTemplateBox= new QComboBox(); + + m_demandRefluxStrategyLayout->addWidget(new QLabel(tr("需量/防逆流策略: "))); + m_demandRefluxStrategyLayout->addWidget(m_demandRefluxTemplateBox); + + m_appendStrategyLayout->insertLayout(0, m_demandRefluxStrategyLayout); + m_appendStrategyLayout->addStretch(); + + rightLayout->addLayout(buttonLayout); + rightLayout->addSpacing(25); + rightLayout->addWidget(runStrategyGroupBox); + rightLayout->addSpacing(25); + rightLayout->addWidget(appendStrategyGroupBox); + + // + mainLayout->addWidget(m_calendarWidget); + mainLayout->addLayout(rightLayout); +} + +bool CDispatchCalendarWidget::reloadDataByDb() +{ + bool ret = true; + + m_dispatchCalendarMap = m_dbApi->getDispatchCalendar(); + m_calendarWidget->setStrategyDispatch(m_dispatchCalendarMap); + m_calendarWidget->update(); + + m_peakValleyTemplateBox->clear(); + m_peakValleyTemplateBox->addItems(QStringList() << "" << m_dbApi->getStrategyNameByTemplateName(iot_service::CStrategyDefine::PeakValleyTemplateName)); + + m_hcRemoteTemplateBox->clear(); + m_hcRemoteTemplateBox->addItems(QStringList() << "" << m_dbApi->getStrategyNameByTemplateName(iot_service::CStrategyDefine::HcRemoteTemplateName)); + + m_realTimeControlTemplateBox->clear(); + m_realTimeControlTemplateBox->addItems(QStringList() << "" << m_dbApi->getStrategyNameByTemplateName(iot_service::CStrategyDefine::RealTimeControlTemplateName)); + + onCalendarClicked(m_calendarWidget->selectedDate()); + + return ret; +} + +void CDispatchCalendarWidget::onCalendarClicked(const QDate& date) +{ + QStringList list = m_dispatchCalendarMap[date]; + + if( list.isEmpty() ) + { + m_peakValleyTemplateBox->setCurrentText(""); + m_hcRemoteTemplateBox->setCurrentText(""); + m_realTimeControlTemplateBox->setCurrentText(""); + } + else + { + for( const QString& strategyName : list ) + { + if( m_peakValleyTemplateBox->findText(strategyName) != -1 ) + { + m_peakValleyTemplateBox->setCurrentText(strategyName); + } + else if( m_hcRemoteTemplateBox->findText(strategyName) != -1 ) + { + m_hcRemoteTemplateBox->setCurrentText(strategyName); + } + else if( m_realTimeControlTemplateBox->findText(strategyName) != -1 ) + { + m_realTimeControlTemplateBox->setCurrentText(strategyName); + } + else + {} + } + } +} + +void CDispatchCalendarWidget::onTemplateNumChanged() +{ + reloadDataByDb(); +} + +void CDispatchCalendarWidget::onSaveButtonClicked() +{ + QDate date = m_calendarWidget->selectedDate(); + + QStringList strategyList; + QList strategyIdList; + QList belongTemplateList; + + if( m_peakValleyTemplateBox->currentText() != "" ) + { + QString strategyName = m_peakValleyTemplateBox->currentText(); + int strategyId = -1; + int templateId = -1; + + m_dbApi->getStrategyIdByName(strategyName, strategyId); + m_dbApi->getTemplateIdByName(iot_service::CStrategyDefine::PeakValleyTemplateName, templateId); + + strategyList.append(strategyName); + strategyIdList.append(strategyId); + belongTemplateList.append(templateId); + } + else if( m_hcRemoteTemplateBox->currentText() != "" ) + { + QString strategyName = m_hcRemoteTemplateBox->currentText(); + int strategyId = -1; + int templateId = -1; + + m_dbApi->getStrategyIdByName(strategyName, strategyId); + m_dbApi->getTemplateIdByName(iot_service::CStrategyDefine::HcRemoteTemplateName, templateId); + + strategyList.append(strategyName); + strategyIdList.append(strategyId); + belongTemplateList.append(templateId); + } + else if( m_realTimeControlTemplateBox->currentText() != "" ) + { + QString strategyName = m_realTimeControlTemplateBox->currentText(); + int strategyId = -1; + int templateId = -1; + + m_dbApi->getStrategyIdByName(strategyName, strategyId); + m_dbApi->getTemplateIdByName(iot_service::CStrategyDefine::RealTimeControlTemplateName, templateId); + + strategyList.append(strategyName); + strategyIdList.append(strategyId); + belongTemplateList.append(templateId); + } + else + { + + } + + // 暂时不使用 +// if( m_demandRefluxTemplateBox->currentText() != "" ) +// { +// strategyList.append(m_demandRefluxTemplateBox->currentText()); +// } + + bool result = false; + + if( strategyList.isEmpty() ) + { + result = m_dbApi->deleteStrategyCalendar(date); + } + else + { + result = m_dbApi->addStrategyCalendar(date, strategyList, strategyIdList, belongTemplateList); + } + + if( result ) + { + QMessageBox::information(this, tr("提示"), tr("保存成功")); + reloadDataByDb(); + } + else + { + QMessageBox::information(this, tr("提示"), tr("保存失败")); + } +} + +void CDispatchCalendarWidget::onRefreshButtonClicked() +{ + reloadDataByDb(); +} + +void CDispatchCalendarWidget::onPeakValleyTemplateBoxCurrentTextChange(const QString &text) +{ + if( !text.isEmpty() ) + { + m_hcRemoteTemplateBox->setCurrentText(""); + m_realTimeControlTemplateBox->setCurrentText(""); + } +} + +void CDispatchCalendarWidget::onHcRemoteTemplateBoxCurrentTextChange(const QString &text) +{ + if( !text.isEmpty() ) + { + m_peakValleyTemplateBox->setCurrentText(""); + m_realTimeControlTemplateBox->setCurrentText(""); + } +} + +void CDispatchCalendarWidget::onRealTimeControlTemplateBoxCurrentTextChange(const QString &text) +{ + if( !text.isEmpty() ) + { + m_peakValleyTemplateBox->setCurrentText(""); + m_hcRemoteTemplateBox->setCurrentText(""); + } +} diff --git a/product/src/gui/plugin/StrategyControlWidget/CDispatchCalendarWidget.h b/product/src/gui/plugin/StrategyControlWidget/CDispatchCalendarWidget.h new file mode 100644 index 00000000..aee4d38d --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/CDispatchCalendarWidget.h @@ -0,0 +1,57 @@ +#ifndef CDISPATCHCALENDARWIDGET_H +#define CDISPATCHCALENDARWIDGET_H + +#include +#include +#include + +#include "CStrategySqlApi.h" +#include "custom_widget/CCalendarWidget.h" + +class CDispatchCalendarWidget : public QWidget +{ + Q_OBJECT + +public: + CDispatchCalendarWidget(QWidget* parent = NULL); + + bool reloadDataByDb(); + +private: + void initUI(); + + QVBoxLayout* m_runStrategyLayout; + + QHBoxLayout* m_peakValleyTemplateLayout; + QComboBox* m_peakValleyTemplateBox; + + QHBoxLayout* m_hcRemoteTemplateLayout; + QComboBox* m_hcRemoteTemplateBox; + + QHBoxLayout* m_realTimeControlTemplateLayout; + QComboBox* m_realTimeControlTemplateBox; + + QVBoxLayout* m_appendStrategyLayout; + + QHBoxLayout* m_demandRefluxStrategyLayout; + QComboBox* m_demandRefluxTemplateBox; + + CCalendarWidget* m_calendarWidget; + + boost::scoped_ptr m_dbApi; + + QMap m_dispatchCalendarMap; + +public slots: + void onTemplateNumChanged(); + void onSaveButtonClicked(); + void onRefreshButtonClicked(); + void onPeakValleyTemplateBoxCurrentTextChange(const QString& text); + void onHcRemoteTemplateBoxCurrentTextChange(const QString& text); + void onRealTimeControlTemplateBoxCurrentTextChange(const QString& text); + +private slots: + void onCalendarClicked(const QDate& date); +}; + +#endif // CDISPATCHCALENDARWIDGET_H diff --git a/product/src/gui/plugin/StrategyControlWidget/CMbApi.cpp b/product/src/gui/plugin/StrategyControlWidget/CMbApi.cpp new file mode 100644 index 00000000..4df1bef1 --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/CMbApi.cpp @@ -0,0 +1,7 @@ +#include "CMbApi.h" + +CMbApi::CMbApi() + : m_mbCommPtr(new iot_net::CMbCommunicator()) +{ + +} diff --git a/product/src/gui/plugin/StrategyControlWidget/CMbApi.h b/product/src/gui/plugin/StrategyControlWidget/CMbApi.h new file mode 100644 index 00000000..4d7e3a0a --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/CMbApi.h @@ -0,0 +1,17 @@ +#ifndef CMBAPI_H +#define CMBAPI_H + +#include "boost/scoped_ptr.hpp" + +#include "net_msg_bus_api/CMbCommunicator.h" + +class CMbApi +{ +public: + CMbApi(); + +private: + boost::scoped_ptr m_mbCommPtr; +}; + +#endif // CMBAPI_H diff --git a/product/src/gui/plugin/StrategyControlWidget/CStrategyControlPluginWidget.cpp b/product/src/gui/plugin/StrategyControlWidget/CStrategyControlPluginWidget.cpp new file mode 100644 index 00000000..cd775a8c --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/CStrategyControlPluginWidget.cpp @@ -0,0 +1,27 @@ +#include "CStrategyControlPluginWidget.h" + +#include "CStrategyControlWidget.h" + +CStrategyControlPluginWidget::CStrategyControlPluginWidget(QObject *parent) + : QObject(parent) +{ + +} + +CStrategyControlPluginWidget::~CStrategyControlPluginWidget() +{ + +} + +bool CStrategyControlPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CStrategyControlWidget* pWidget = new CStrategyControlWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CStrategyControlPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/StrategyControlWidget/CStrategyControlPluginWidget.h b/product/src/gui/plugin/StrategyControlWidget/CStrategyControlPluginWidget.h new file mode 100644 index 00000000..aeb67aa9 --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/CStrategyControlPluginWidget.h @@ -0,0 +1,22 @@ +#ifndef CSTRATEGYCONTROLPLUGINWIDGET_H +#define CSTRATEGYCONTROLPLUGINWIDGET_H + +#include + +#include "GraphShape/CPluginWidget.h" + +class CStrategyControlPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) + Q_INTERFACES(CPluginWidgetInterface) + +public: + CStrategyControlPluginWidget(QObject *parent = nullptr); + ~CStrategyControlPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CSTRATEGYCONTROLPLUGINWIDGET_H diff --git a/product/src/gui/plugin/StrategyControlWidget/CStrategyControlWidget.cpp b/product/src/gui/plugin/StrategyControlWidget/CStrategyControlWidget.cpp new file mode 100644 index 00000000..d2a841a8 --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/CStrategyControlWidget.cpp @@ -0,0 +1,204 @@ +#include "CStrategyControlWidget.h" + +#include +#include +#include +#include + +#include "pub_logger_api/logger.h" +#include "public/pub_utility_api/FileStyle.h" + +#include "CTemplateManagerWidget.h" +#include "CDispatchCalendarWidget.h" +#include "template/CPeakValleyTemplateWidget.h" +#include "template/CHcRemoteTemplateWidget.h" +#include "template/CRealTimeControlTemplateWidget.h" + +CStrategyControlWidget::CStrategyControlWidget(QWidget *parent, bool isEditMode) + : QWidget(parent), + m_dbApi(new CStrategySqlApi()) +{ + (void)isEditMode; + + m_modeMap.insert(iot_service::LOCAL_MODEL, iot_service::CStrategyDefine::GetModelNameById(iot_service::LOCAL_MODEL)); + m_modeMap.insert(iot_service::REMOTE_MODEL, iot_service::CStrategyDefine::GetModelNameById(iot_service::REMOTE_MODEL)); + m_modeMap.insert(iot_service::APPEND_MODEL, iot_service::CStrategyDefine::GetModelNameById(iot_service::APPEND_MODEL)); + + m_templateIndexMap.insert(tr(iot_service::CStrategyDefine::PeakValleyTemplateName), PEAK_VALLEY_TEMPLATE); + m_templateIndexMap.insert(tr(iot_service::CStrategyDefine::HcRemoteTemplateName), HC_REMOTE_TEMPLATE); + m_templateIndexMap.insert(tr(iot_service::CStrategyDefine::RealTimeControlTemplateName), REAL_TIME_CONTROL_TEMPLATE); + + m_templateNameMap.insert(PEAK_VALLEY_TEMPLATE, tr(iot_service::CStrategyDefine::PeakValleyTemplateName)); + m_templateNameMap.insert(HC_REMOTE_TEMPLATE, tr(iot_service::CStrategyDefine::HcRemoteTemplateName)); + m_templateNameMap.insert(REAL_TIME_CONTROL_TEMPLATE, tr(iot_service::CStrategyDefine::RealTimeControlTemplateName)); + + initUI(); +} + +CStrategyControlWidget::~CStrategyControlWidget() +{ +} + +void CStrategyControlWidget::initUI() +{ + loadStyle(); + + // + QHBoxLayout* mainLayout = new QHBoxLayout(this); + + // + QVBoxLayout* leftLayout = new QVBoxLayout(); + + m_modelTreeWidget = new QTreeWidget(); + + QTreeWidgetItem* root = m_modelTreeWidget->invisibleRootItem(); + + root->insertChild(DISPATCH_CALENDAR_INDEX, new QTreeWidgetItem(QStringList() << "调度日历")); + root->insertChild(iot_service::LOCAL_MODEL, new QTreeWidgetItem(QStringList() << m_modeMap[iot_service::LOCAL_MODEL])); + root->insertChild(iot_service::REMOTE_MODEL, new QTreeWidgetItem(QStringList() << m_modeMap[iot_service::REMOTE_MODEL])); + root->insertChild(iot_service::APPEND_MODEL, new QTreeWidgetItem(QStringList() << m_modeMap[iot_service::APPEND_MODEL])); + + treeAddChild(root->child(DISPATCH_CALENDAR_INDEX), QStringList() << "调度日历"); + treeAddChild(root->child(iot_service::LOCAL_MODEL), m_dbApi->getTemplateNameByModel(iot_service::LOCAL_MODEL)); + treeAddChild(root->child(iot_service::REMOTE_MODEL), m_dbApi->getTemplateNameByModel(iot_service::REMOTE_MODEL)); + treeAddChild(root->child(iot_service::APPEND_MODEL), m_dbApi->getTemplateNameByModel(iot_service::APPEND_MODEL)); + + m_modelTreeWidget->setHeaderHidden(true); + m_modelTreeWidget->setItemsExpandable(true); + m_modelTreeWidget->expandAll(); + m_modelTreeWidget->setRootIsDecorated(false); + m_modelTreeWidget->setFixedWidth(250); + + connect(m_modelTreeWidget, &QTreeWidget::itemClicked, this, &CStrategyControlWidget::onTreeWidgetItemClicked); + + QPushButton* tempLateManagerButton = new QPushButton(tr("模板管理")); + connect(tempLateManagerButton, &QPushButton::clicked, this, &CStrategyControlWidget::onTemplateManagerButtonClicked); + + leftLayout->addWidget(m_modelTreeWidget); + leftLayout->addSpacing(200); + leftLayout->addWidget(tempLateManagerButton); + + // + m_templateStackedWidget = new QStackedWidget(); + + CTemplateManagerWidget* templateManagerWidget = new CTemplateManagerWidget(); + connect(templateManagerWidget, &CTemplateManagerWidget::templateNumChanged, this, &CStrategyControlWidget::reloadDataByDb); + + CDispatchCalendarWidget* dispatchCalendarWidget = new CDispatchCalendarWidget(); + connect(templateManagerWidget, &CTemplateManagerWidget::templateNumChanged, dispatchCalendarWidget, &CDispatchCalendarWidget::onTemplateNumChanged); + + CPeakValleyTemplateWidget* peakValleyTemplateWidget = new CPeakValleyTemplateWidget(m_templateNameMap[PEAK_VALLEY_TEMPLATE]); + connect(templateManagerWidget, &CTemplateManagerWidget::templateNumChanged, peakValleyTemplateWidget, &CPeakValleyTemplateWidget::reloadDataFromDB); + + CHcRemoteTemplateWidget* hcRemoteTemplateWidget = new CHcRemoteTemplateWidget(m_templateNameMap[HC_REMOTE_TEMPLATE]); + connect(templateManagerWidget, &CTemplateManagerWidget::templateNumChanged, hcRemoteTemplateWidget, &CHcRemoteTemplateWidget::reloadDataByDB); + + CRealTimeControlTemplateWidget* realTimeControlTemplateWidget = new CRealTimeControlTemplateWidget(m_templateNameMap[REAL_TIME_CONTROL_TEMPLATE]); + connect(templateManagerWidget, &CTemplateManagerWidget::templateNumChanged, realTimeControlTemplateWidget, &CRealTimeControlTemplateWidget::reloadDataByDB); + + m_templateStackedWidget->insertWidget(DISPATCH_CALENDAR_INDEX, dispatchCalendarWidget); + m_templateStackedWidget->insertWidget(PEAK_VALLEY_TEMPLATE, peakValleyTemplateWidget); + m_templateStackedWidget->insertWidget(HC_REMOTE_TEMPLATE, hcRemoteTemplateWidget); + m_templateStackedWidget->insertWidget(REAL_TIME_CONTROL_TEMPLATE, realTimeControlTemplateWidget); + m_templateStackedWidget->insertWidget(TEMPLATE_MANAGER_INDEX, templateManagerWidget); + + // + mainLayout->addLayout(leftLayout); + mainLayout->addWidget(m_templateStackedWidget); +} + + +void CStrategyControlWidget::loadStyle() +{ + QString filePath = QString::fromStdString(iot_public::CFileStyle::getPathOfStyleFile("public.qss")); + + QFile file(filePath); + if( file.open(QIODevice::ReadOnly) ) + { + setStyleSheet(file.readAll()); + + file.close(); + } + else + { + LOGWARN("load public.qss error"); + } +} + +void CStrategyControlWidget::reloadDataByDb() +{ + QTreeWidgetItem* root = m_modelTreeWidget->invisibleRootItem(); + + treeDeleteChild(root->child(iot_service::LOCAL_MODEL)); + treeAddChild(root->child(iot_service::LOCAL_MODEL), m_dbApi->getTemplateNameByModel(iot_service::LOCAL_MODEL)); + + treeDeleteChild(root->child(iot_service::REMOTE_MODEL)); + treeAddChild(root->child(iot_service::REMOTE_MODEL), m_dbApi->getTemplateNameByModel(iot_service::REMOTE_MODEL)); + + treeDeleteChild(root->child(iot_service::APPEND_MODEL)); + treeAddChild(root->child(iot_service::APPEND_MODEL), m_dbApi->getTemplateNameByModel(iot_service::APPEND_MODEL)); +} + +void CStrategyControlWidget::treeAddChild(QTreeWidgetItem* parent, const QStringList& childs) +{ + if( parent != NULL ) + { + for( int i=0; iaddChild(new QTreeWidgetItem(QStringList() << childs[i])); + } + } +} + +void CStrategyControlWidget::treeDeleteChild(QTreeWidgetItem *parent) +{ + if( parent != NULL ) + { + while( parent->childCount() > 0 ) + { + parent->removeChild(parent->child(0)); + } + } +} + +#include +void CStrategyControlWidget::onTreeWidgetItemClicked(QTreeWidgetItem* item, int column) +{ + if( item != NULL ) + { + // TODO item的parent item为root时的处理 + + QString text = item->text(column); + if( text == "调度日历" ) + { + m_templateStackedWidget->setCurrentIndex(DISPATCH_CALENDAR_INDEX); + + CDispatchCalendarWidget* widget = qobject_cast(m_templateStackedWidget->currentWidget()); + if( widget != NULL ) + { + widget->reloadDataByDb(); + } + + return; + } + + if( m_templateIndexMap.contains(text) ) + { + m_templateStackedWidget->setCurrentIndex(m_templateIndexMap[text]); + } + + if( text == "实时控制" ) + { + CRealTimeControlTemplateWidget* widget = qobject_cast(m_templateStackedWidget->currentWidget()); + if( widget != NULL ) + { + widget->reloadDataByDB(); + } + } + } +} + +void CStrategyControlWidget::onTemplateManagerButtonClicked() +{ + m_templateStackedWidget->setCurrentIndex(TEMPLATE_MANAGER_INDEX); +} diff --git a/product/src/gui/plugin/StrategyControlWidget/CStrategyControlWidget.h b/product/src/gui/plugin/StrategyControlWidget/CStrategyControlWidget.h new file mode 100644 index 00000000..51aa637e --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/CStrategyControlWidget.h @@ -0,0 +1,54 @@ +#ifndef CSTRATEGYCONTROLWIDGET_H +#define CSTRATEGYCONTROLWIDGET_H + +#include +#include +#include + +#include + +#include "CStrategyDefine.h" +#include "CStrategySqlApi.h" + +class CStrategyControlWidget : public QWidget +{ + Q_OBJECT + + enum StrategyTemplate + { + PEAK_VALLEY_TEMPLATE = 1, + HC_REMOTE_TEMPLATE, + REAL_TIME_CONTROL_TEMPLATE, + PLACEHOLDER_LAST //占位下标 + }; + +public: + explicit CStrategyControlWidget(QWidget *parent = nullptr, bool isEditMode = true); + ~CStrategyControlWidget(); + +private: + void initUI(); + + void loadStyle(); + + void treeAddChild(QTreeWidgetItem* parent, const QStringList& childs); + void treeDeleteChild(QTreeWidgetItem* parent); + + QTreeWidget* m_modelTreeWidget; + QStackedWidget* m_templateStackedWidget; + + boost::scoped_ptr m_dbApi; + QMap m_modeMap; + QMap m_templateIndexMap; + QMap m_templateNameMap; + + const int DISPATCH_CALENDAR_INDEX = iot_service::PLACEHOLDER_FIRST; // 调度日历界面在QStackedWidget中下标 + const int TEMPLATE_MANAGER_INDEX = PLACEHOLDER_LAST; // 模板管理界面在QStackedWidget中下标 + +private slots: + void reloadDataByDb(); + void onTreeWidgetItemClicked(QTreeWidgetItem* item, int column); + void onTemplateManagerButtonClicked(); +}; + +#endif // CSTRATEGYCONTROLWIDGET_H diff --git a/product/src/gui/plugin/StrategyControlWidget/CTemplateManagerWidget.cpp b/product/src/gui/plugin/StrategyControlWidget/CTemplateManagerWidget.cpp new file mode 100644 index 00000000..314275de --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/CTemplateManagerWidget.cpp @@ -0,0 +1,513 @@ +#include "CTemplateManagerWidget.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "net_msg_bus_api/CMbCommunicator.h" +#include "common/Common.h" +#include "common/MessageChannel.h" + +#include "CStrategyDefine.h" + +CTemplateManagerWidget::CTemplateManagerWidget(QWidget* parent) + : QWidget(parent), + m_dbApi(new CStrategySqlApi()), + m_mbCommPtr(new iot_net::CMbCommunicator()), + m_isAdding(false) +{ + m_retrieverDialog = new CRetriever(this); + + initUI(); + reloadDataByDb(); + + connect(m_retrieverDialog, &CRetriever::itemTagTriggered, this, &CTemplateManagerWidget::onRetriveDialogItemTagTriggered); +} + +void CTemplateManagerWidget::initUI() +{ + QHBoxLayout* mainLayout = new QHBoxLayout(this); + + m_templateNameListWidget = new QListWidget(); + m_templateNameListWidget->setFixedWidth(200); + connect(m_templateNameListWidget, &QListWidget::itemClicked, this, &CTemplateManagerWidget::onTemplateNameListItemClicked); + + // + QVBoxLayout* rightLayout = new QVBoxLayout(); + + // + QHBoxLayout* buttonLayout = new QHBoxLayout(); + + QPushButton* addTemplateButton = new QPushButton(tr("新增")); + connect(addTemplateButton, &QPushButton::clicked, this, &CTemplateManagerWidget::onAddTemplateButtonClicked); + + QPushButton* saveTemplateButton = new QPushButton(tr("保存")); + connect(saveTemplateButton, &QPushButton::clicked, this, &CTemplateManagerWidget::onSaveTemplateButtonClicked); + + QPushButton* deleteTemplateButton = new QPushButton(tr("删除")); + connect(deleteTemplateButton, &QPushButton::clicked, this, &CTemplateManagerWidget::onDeleteTemplateButtonClicked); + + buttonLayout->addStretch(); + buttonLayout->addWidget(addTemplateButton); + buttonLayout->addWidget(deleteTemplateButton); + buttonLayout->addWidget(saveTemplateButton); + + // + QHBoxLayout* settingLayout = new QHBoxLayout(); + + m_templateNameEdit = new QLineEdit(); + m_templateNameEdit->setReadOnly(true); + connect(m_templateNameEdit, &QLineEdit::textChanged, this, &CTemplateManagerWidget::onTemplateNameEditChange); + + m_modelComboBox = new QComboBox(); + m_modelComboBox->addItem(iot_service::CStrategyDefine::GetModelNameById(iot_service::LOCAL_MODEL)); + m_modelComboBox->addItem(iot_service::CStrategyDefine::GetModelNameById(iot_service::REMOTE_MODEL)); + m_modelComboBox->addItem(iot_service::CStrategyDefine::GetModelNameById(iot_service::APPEND_MODEL)); + + settingLayout->addWidget(new QLabel(tr("模板名: "))); + settingLayout->addWidget(m_templateNameEdit); + settingLayout->addWidget(new QLabel(tr("所属模式: "))); + settingLayout->addWidget(m_modelComboBox); + settingLayout->addStretch(); + + // + QVBoxLayout* argLayout = new QVBoxLayout(); + + m_argTableWidget = new QTableWidget(0, 8); + m_argTableWidget->setHorizontalHeaderLabels(QStringList() << tr("") << tr("参数标签") << tr("参数名称") << tr("数据类型") << tr("值类型") << tr("默认值") << tr("值单位") << tr("参数类型")); + m_argTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + + m_argTableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); + m_argTableWidget->setColumnWidth(0, 20); + + QHBoxLayout* argButtonLayout = new QHBoxLayout(); + + m_addArgButton = new QPushButton(tr("新增参数")); + connect(m_addArgButton, &QPushButton::clicked, this, &CTemplateManagerWidget::onAddArgButtonClicked); + + m_deleteArgButton = new QPushButton(tr("删除参数")); + connect(m_deleteArgButton, &QPushButton::clicked, this, &CTemplateManagerWidget::onDeleteArgButtonClicked); + + argButtonLayout->addWidget(m_addArgButton); + argButtonLayout->addWidget(m_deleteArgButton); + argButtonLayout->addStretch(); + + argLayout->addWidget(m_argTableWidget); + argLayout->addLayout(argButtonLayout); + + rightLayout->addLayout(buttonLayout); + rightLayout->addLayout(settingLayout); + rightLayout->addSpacing(20); + rightLayout->addLayout(argLayout); + + // + mainLayout->addWidget(m_templateNameListWidget); + mainLayout->addLayout(rightLayout); +} + +bool CTemplateManagerWidget::reloadDataByDb() +{ + bool ret = true; + + m_templateNameListWidget->clear(); + m_templateNameListWidget->addItems(m_dbApi->getTemplateNameAll()); + + if( m_templateNameListWidget->count() >= 0 ) + { + m_templateNameListWidget->setCurrentRow(0); + onTemplateNameListItemClicked(m_templateNameListWidget->currentItem()); + } + + return ret; +} + +void CTemplateManagerWidget::addArgTableOneRow() +{ + int newRow = m_argTableWidget->rowCount(); + + m_argTableWidget->insertRow(newRow); + m_argTableWidget->setCellWidget(newRow, 0, new QCheckBox()); + + for( int i=1; icolorCount(); i++ ) + { + QLineEdit* edit = new QLineEdit(); + + m_argTableWidget->setCellWidget(newRow, i, edit); + } +} + +void CTemplateManagerWidget::updateArgTableRowData(int row, const QList& rowValue) +{ + if( (row < m_argTableWidget->rowCount()) && (rowValue.size() >= 7) ) + { + QLineEdit* paraTagEdit = qobject_cast(m_argTableWidget->cellWidget(row, 1)); + if( paraTagEdit != NULL ) + { + paraTagEdit->setText(rowValue[0].toString()); + } + + QLineEdit* paraNameEdit = qobject_cast(m_argTableWidget->cellWidget(row, 2)); + if( paraNameEdit != NULL ) + { + paraNameEdit->setText(rowValue[1].toString()); + } + + QLineEdit* dataTypeEdit = qobject_cast(m_argTableWidget->cellWidget(row, 3)); + if( dataTypeEdit != NULL ) + { + dataTypeEdit->setText(rowValue[2].toString()); + } + + QLineEdit* valueTypeEdit = qobject_cast(m_argTableWidget->cellWidget(row, 4)); + if( valueTypeEdit != NULL ) + { + valueTypeEdit->setText(rowValue[3].toString()); + } + + QLineEdit* valueEdit = qobject_cast(m_argTableWidget->cellWidget(row, 5)); + if( valueEdit != NULL ) + { + valueEdit->setText(rowValue[4].toString()); + } + + QLineEdit* unitEdit = qobject_cast(m_argTableWidget->cellWidget(row, 6)); + if( unitEdit != NULL ) + { + unitEdit->setText(rowValue[5].toString()); + } + + QLineEdit* paraTypeEdit = qobject_cast(m_argTableWidget->cellWidget(row, 7)); + if( paraTypeEdit != NULL ) + { + int paraType = rowValue[6].toInt(); + if( paraType == 1 ) + { + paraTypeEdit->setText("输入参数"); + } + else if( paraType == 2 ) + { + paraTypeEdit->setText("输出参数"); + } + } + } +} + +bool CTemplateManagerWidget::sendMsgToDomain(const QJsonObject& sendJson) +{ + iot_net::CMbMessage msg; + msg.setSubject(CN_AppId_COMAPP, CH_HMI_TO_OPT_OPTCMD_DOWN); + msg.setData(QJsonDocument(sendJson).toJson(QJsonDocument::Compact).toStdString()); + + return m_mbCommPtr->sendMsgToDomain(msg); +} + +void CTemplateManagerWidget::onTemplateNameListItemClicked(QListWidgetItem* item) +{ + if( item != NULL ) + { + QString templateName = item->text(); + + m_templateNameEdit->setText(templateName); + + int belongModel = -1; + if( m_dbApi->getTemplateBelongModel(templateName, belongModel) ) + { + m_modelComboBox->setCurrentText(iot_service::CStrategyDefine::GetModelNameById(belongModel)); + } + + while( m_argTableWidget->rowCount() != 0 ) + { + m_argTableWidget->removeRow(0); + } + + int templateId = -1; + if( m_dbApi->getTemplateIdByName(templateName, templateId) ) + { + QList> rowValueList = m_dbApi->getTemplateParaById(templateId); + + for( int i=0; i& valueList = rowValueList[i]; + + updateArgTableRowData(i, valueList); + } + } + } +} + +void CTemplateManagerWidget::onAddTemplateButtonClicked() +{ + bool ok = false; + + QStringList templateNameList; + templateNameList.append(iot_service::CStrategyDefine::PeakValleyTemplateName); + templateNameList.append(iot_service::CStrategyDefine::HcRemoteTemplateName); + templateNameList.append(iot_service::CStrategyDefine::RealTimeControlTemplateName); + + QString templateName = QInputDialog::getItem(this, tr("策略模板"), tr("请选择策略模板"), templateNameList, 0, false, &ok); + + if( !ok ) + { + return; + } + + if( templateName.isEmpty() ) + { + QMessageBox::information(this, tr("提示"), tr("策略模板名不允许为空")); + return; + } + + if( !m_templateNameListWidget->findItems(templateName, Qt::MatchFixedString).isEmpty() ) + { + QMessageBox::information(this, tr("提示"), tr("策略模板重复添加")); + return; + } + + m_templateNameEdit->setText(templateName); + + while(m_argTableWidget->rowCount() != 0 ) + { + m_argTableWidget->removeRow(0); + } + + if( templateName == iot_service::CStrategyDefine::PeakValleyTemplateName ) + { + addArgTableOneRow(); + updateArgTableRowData(0, {"analog.byq.AMC_AMC.PvPower.value", "功率", "策略内容", "int", "0", "kw", "2"}); + } + else if( templateName == iot_service::CStrategyDefine::HcRemoteTemplateName ) + { + addArgTableOneRow(); + updateArgTableRowData(0, {"analog.byq.AMC_AMC.HcPower.value", "功率", "策略内容", "int", "0", "kw", "2"}); + } + else if( templateName == iot_service::CStrategyDefine::RealTimeControlTemplateName ) + { + + } + else + { + + } + + m_isAdding = true; +} + +void CTemplateManagerWidget::onDeleteTemplateButtonClicked() +{ + if( QMessageBox::information(this, tr("提示"), tr("是否删除[%1]模板?").arg(m_templateNameEdit->text()),QMessageBox::Yes, QMessageBox::Cancel) != QMessageBox::Yes ) + { + return; + } + + if( m_isAdding ) + { + m_isAdding = false; + + if( m_templateNameListWidget->count() > 0 ) + { + m_templateNameListWidget->setCurrentRow(0); + onTemplateNameListItemClicked(m_templateNameListWidget->item(0)); + } + else + { + m_templateNameEdit->clear(); + + while(m_argTableWidget->rowCount() != 0 ) + { + m_argTableWidget->removeRow(0); + } + } + + QMessageBox::information(this, tr("提示"), tr("策略模板删除成功!")); + } + else + { + QString templateName = m_templateNameEdit->text(); + if( !templateName.isEmpty() ) + { + QJsonObject contentJson; + contentJson["strategyTemplateName"] = templateName; + + QJsonObject sendJson; + sendJson["type"] = "strategyTemplateDelete"; + sendJson["content"] = contentJson; + + if( sendMsgToDomain(sendJson) ) + { + m_templateNameEdit->clear(); + + while(m_argTableWidget->rowCount() != 0 ) + { + m_argTableWidget->removeRow(0); + } + + QMessageBox::information(this, tr("提示"), tr("策略模板删除成功!")); + + emit templateNumChanged(); + + reloadDataByDb(); + } + else + { + QMessageBox::information(this, tr("提示"), tr("策略模板删除失败!")); + } + } + } +} + +void CTemplateManagerWidget::onSaveTemplateButtonClicked() +{ + QString templateName = m_templateNameEdit->text(); + + if( templateName.isEmpty() ) + { + QMessageBox::information(this, tr("提示"), tr("模板名不允许为空")); + return; + } + + QString belongModel = m_modelComboBox->currentText(); + + QJsonArray paraTagArray; + QJsonArray argJsonArray; + for( int i=0; irowCount(); i++ ) + { + QJsonObject argJson; + + QLineEdit* paraTagEdit = qobject_cast(m_argTableWidget->cellWidget(i, 1)); + if( paraTagEdit != NULL ) + { + argJson["paraTag"] = paraTagEdit->text(); + paraTagArray.append(paraTagEdit->text()); + } + + QLineEdit* paraNameEdit = qobject_cast(m_argTableWidget->cellWidget(i, 2)); + if( paraNameEdit != NULL ) + { + argJson["paraName"] = paraNameEdit->text(); + } + + QLineEdit* dataTypeEdit = qobject_cast(m_argTableWidget->cellWidget(i, 3)); + if( dataTypeEdit != NULL ) + { + argJson["dataType"] = dataTypeEdit->text(); + } + + QLineEdit* valueTypeEdit = qobject_cast(m_argTableWidget->cellWidget(i, 4)); + if( valueTypeEdit != NULL ) + { + argJson["valueType"] = valueTypeEdit->text(); + } + + QLineEdit* valueEdit = qobject_cast(m_argTableWidget->cellWidget(i, 5)); + if( valueEdit != NULL ) + { + argJson["value"] = valueEdit->text(); + } + + QLineEdit* unitEdit = qobject_cast(m_argTableWidget->cellWidget(i, 6)); + if( unitEdit != NULL ) + { + argJson["unit"] = unitEdit->text(); + } + + QLineEdit* argTypeEdit = qobject_cast(m_argTableWidget->cellWidget(i, 7)); + if( argTypeEdit != NULL ) + { + QString argType = argTypeEdit->text(); + argJson["argType"] = argType == "输入参数" ? 1 : 2; + } + + argJsonArray.append(argJson); + } + + QJsonObject contentJson; + contentJson["strategyTemplateName"] = templateName; + contentJson["belongModel"] = iot_service::CStrategyDefine::GetModelIdByName(belongModel); + contentJson["para"] = argJsonArray; + + QJsonObject sendJson; + sendJson["type"] = (m_isAdding ? "strategyTemplateAdd" : "strategyTemplateUpdate"); + sendJson["content"] = contentJson; + + if( sendMsgToDomain(sendJson) ) + { + QMessageBox::information(this, tr("提示"), m_isAdding ? tr("策略模板保存成功!") : tr("策略模板更新成功!")); + + if( m_isAdding ) + { + emit templateNumChanged(); + reloadDataByDb(); + m_templateNameListWidget->setCurrentRow(m_templateNameListWidget->count()-1); + onTemplateNameListItemClicked(m_templateNameListWidget->currentItem()); + } + + m_isAdding = false; + } + else + { + QMessageBox::information(this, tr("提示"), m_isAdding ? tr("策略模板保存失败!") : tr("策略模板更新失败!")); + } +} + +void CTemplateManagerWidget::onAddArgButtonClicked() +{ + m_retrieverDialog->exec(); +} + +void CTemplateManagerWidget::onDeleteArgButtonClicked() +{ + bool needDelete = false; + + // 支持多行删除 + do + { + needDelete = false; + + for( int i=0; irowCount(); i++ ) + { + QCheckBox* box = qobject_cast(m_argTableWidget->cellWidget(i, 0)); + if( box->checkState() == Qt::Checked ) + { + m_argTableWidget->removeRow(i); + needDelete = true; + break; + } + } + } + while( needDelete ); +} + +void CTemplateManagerWidget::onRetriveDialogItemTagTriggered(const QString& tagName, const QString& tagDesc, bool isMulti) +{ + m_retrieverDialog->accept(); + + QStringList parts = tagName.split("."); + QString newTagName = tagName; + if (parts.size() >= 3) + { + newTagName = parts.mid(2).join("."); + } + + addArgTableOneRow(); + updateArgTableRowData(m_argTableWidget->rowCount()-1, {newTagName, tagDesc, "策略内容", "int", "0", "kw", "2"}); +} + +void CTemplateManagerWidget::onTemplateNameEditChange(const QString& text) +{ + if( text == iot_service::CStrategyDefine::RealTimeControlTemplateName ) + { + m_addArgButton->show(); + m_deleteArgButton->show(); + } + else + { + m_addArgButton->hide(); + m_deleteArgButton->hide(); + } +} diff --git a/product/src/gui/plugin/StrategyControlWidget/CTemplateManagerWidget.h b/product/src/gui/plugin/StrategyControlWidget/CTemplateManagerWidget.h new file mode 100644 index 00000000..bebd3d8c --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/CTemplateManagerWidget.h @@ -0,0 +1,62 @@ +#ifndef CTEMPLATEMANAGERWIDGET_H +#define CTEMPLATEMANAGERWIDGET_H + +#include +#include +#include +#include +#include +#include + +#include + +#include "CStrategySqlApi.h" +#include "net_msg_bus_api/CMbCommunicator.h" +#include "GraphTool/Retriever/CRetriever.h" + +class CTemplateManagerWidget : public QWidget +{ + Q_OBJECT + +signals: + void templateNumChanged(); // 模板数量发送变化时emit + +public: + CTemplateManagerWidget(QWidget *parent = NULL); + +private: + void initUI(); + + bool reloadDataByDb(); + + void addArgTableOneRow(); + void updateArgTableRowData(int row, const QList& rowValue); + + bool sendMsgToDomain(const QJsonObject& sendJson); + + QListWidget* m_templateNameListWidget; + QTableWidget* m_argTableWidget; + QLineEdit* m_templateNameEdit; + QComboBox* m_modelComboBox; + + QPushButton* m_addArgButton; + QPushButton* m_deleteArgButton; + + CRetriever* m_retrieverDialog; + + boost::scoped_ptr m_dbApi; + boost::scoped_ptr m_mbCommPtr; + bool m_isAdding; + +private slots: + void onTemplateNameListItemClicked(QListWidgetItem* item); + void onTemplateNameEditChange(const QString& text); + void onAddTemplateButtonClicked(); + void onDeleteTemplateButtonClicked(); + void onSaveTemplateButtonClicked(); + void onAddArgButtonClicked(); + void onDeleteArgButtonClicked(); + void onRetriveDialogItemTagTriggered(const QString &tagName, const QString &tagDesc, bool isMulti); +}; + +#endif // CTEMPLATEMANAGERWIDGET_H diff --git a/product/src/gui/plugin/StrategyControlWidget/StrategyControlWidget.pro b/product/src/gui/plugin/StrategyControlWidget/StrategyControlWidget.pro new file mode 100644 index 00000000..9a39510e --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/StrategyControlWidget.pro @@ -0,0 +1,56 @@ +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += plugin + +TARGET = StrategyControlWidget + +TEMPLATE = lib + +HEADERS += \ + CStrategyControlWidget.h \ + CStrategyControlPluginWidget.h \ + template/CPeakValleyTemplateWidget.h \ + CMbApi.h \ + CDispatchCalendarWidget.h \ + custom_widget/CCalendarWidget.h \ + CTemplateManagerWidget.h \ + template/CHcRemoteTemplateWidget.h \ + ../../../application/strategy_server/CStrategySqlApi.h \ + ../../../application/strategy_server/CStrategyDefine.h \ + template/CRealTimeControlTemplateWidget.h + +SOURCES += \ + CStrategyControlWidget.cpp \ + main.cpp \ + CStrategyControlPluginWidget.cpp \ + template/CPeakValleyTemplateWidget.cpp \ + CMbApi.cpp \ + CDispatchCalendarWidget.cpp \ + custom_widget/CCalendarWidget.cpp \ + CTemplateManagerWidget.cpp \ + template/CHcRemoteTemplateWidget.cpp \ + ../../../application/strategy_server/CStrategySqlApi.cpp \ + ../../../application/strategy_server/CStrategyDefine.cpp \ + template/CRealTimeControlTemplateWidget.cpp + +LIBS += -ldb_base_api \ + -ldb_api_ex \ + -llog4cplus \ + -lpub_logger_api \ + -lpub_utility_api \ + -lnet_msg_bus_api \ + -lRetriever \ + -lpub_widget + +INCLUDEPATH += ../../../application/strategy_server + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/StrategyControlWidget/custom_widget/CCalendarWidget.cpp b/product/src/gui/plugin/StrategyControlWidget/custom_widget/CCalendarWidget.cpp new file mode 100644 index 00000000..4115864c --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/custom_widget/CCalendarWidget.cpp @@ -0,0 +1,69 @@ +#include "CCalendarWidget.h" + +#include +#include + +CCalendarWidget::CCalendarWidget(QWidget* parent) + : QCalendarWidget(parent) +{ +} + +void CCalendarWidget::setStrategyDispatch(const QMap& strategyDispatchMap) +{ + m_strategyDispatchMap = strategyDispatchMap; +} + +void CCalendarWidget::paintCell(QPainter* painter, const QRect& rect, const QDate& date) const +{ + QStringList strategyList = m_strategyDispatchMap[date]; + + QString text = QString("%1日\n%2").arg(date.day()).arg(strategyList.join("\n")); + + if (date == selectedDate()) + { + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + + painter->setPen(Qt::NoPen); + painter->setBrush(QColor(118, 178, 224)); + painter->drawRect(rect); + + painter->setPen(QColor(255, 255, 255)); + painter->drawText(rect, Qt::AlignCenter, text); + + painter->restore(); + } + else if (date == QDate::currentDate()) + { + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + + painter->setPen(QPen(Qt::white)); + painter->drawRect(rect); + painter->drawText(rect, Qt::AlignCenter, text); + + painter->restore(); + } + else if( date.month() != monthShown() ) + { + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + + painter->setPen(Qt::gray); + painter->drawRect(rect); + painter->drawText(rect, Qt::AlignCenter, text); + + painter->restore(); + } + else + { + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + + painter->setPen(QPen(Qt::white)); + painter->drawRect(rect); + + painter->drawText(rect, Qt::AlignCenter, text); + painter->restore(); + } +} diff --git a/product/src/gui/plugin/StrategyControlWidget/custom_widget/CCalendarWidget.h b/product/src/gui/plugin/StrategyControlWidget/custom_widget/CCalendarWidget.h new file mode 100644 index 00000000..dc8fe568 --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/custom_widget/CCalendarWidget.h @@ -0,0 +1,23 @@ +#ifndef CCALENDARWIDGET_H +#define CCALENDARWIDGET_H + +#include +#include +#include + +class CCalendarWidget : public QCalendarWidget +{ + Q_OBJECT + +public: + CCalendarWidget(QWidget* parent = NULL); + void setStrategyDispatch(const QMap& strategyDispatchMap); + +protected: + void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const; + +private: + QMap m_strategyDispatchMap; +}; + +#endif // CCALENDARWIDGET_H diff --git a/product/src/gui/plugin/StrategyControlWidget/main.cpp b/product/src/gui/plugin/StrategyControlWidget/main.cpp new file mode 100644 index 00000000..1d62df2e --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/main.cpp @@ -0,0 +1,13 @@ +#include + +#include "CStrategyControlWidget.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + CStrategyControlWidget w; + w.show(); + + return a.exec(); +} diff --git a/product/src/gui/plugin/StrategyControlWidget/template/CHcRemoteTemplateWidget.cpp b/product/src/gui/plugin/StrategyControlWidget/template/CHcRemoteTemplateWidget.cpp new file mode 100644 index 00000000..ac1c5b5f --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/template/CHcRemoteTemplateWidget.cpp @@ -0,0 +1,244 @@ +#include "CHcRemoteTemplateWidget.h" + +#include +#include +#include +#include +#include +#include +#include + +CHcRemoteTemplateWidget::CHcRemoteTemplateWidget(const QString& templateName, QWidget* parent) + : QWidget(parent), + m_templateName(templateName), + m_dbApi(new CStrategySqlApi()) +{ + initUI(); + reloadDataByDB(); +} + +void CHcRemoteTemplateWidget::initUI() +{ + QVBoxLayout* mainLayout = new QVBoxLayout(this); + + // + QHBoxLayout* topLayout = new QHBoxLayout(); + + m_strategyNameComboBox = new QComboBox(); + connect(m_strategyNameComboBox, &QComboBox::currentTextChanged, this, &CHcRemoteTemplateWidget::onStrategyNameComboCurrentTextChanged); + + topLayout->addWidget(m_strategyNameComboBox); + topLayout->addStretch(); + topLayout->addWidget(new QPushButton(tr("刷新"))); + + m_timeScetionTable = new QTableWidget(0, 9); + m_timeScetionTable->setHorizontalHeaderLabels(QStringList() << tr("") << tr("开始时间") << tr("") << tr("结束时间") << tr("") + << tr("储能类型") << tr("") << tr("储能功率") << tr("")); + m_timeScetionTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + m_timeScetionTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); + m_timeScetionTable->setColumnWidth(0, 20); + + m_paraTableWidget = new QTableWidget(0, 7); + m_paraTableWidget->setHorizontalHeaderLabels(QStringList() << tr("参数标签") << tr("参数名称") << tr("数据类型") << tr("值类型") << tr("默认值") << tr("值单位") << tr("参数类型") ); + m_paraTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + + // + mainLayout->addLayout(topLayout); + mainLayout->addWidget(m_timeScetionTable); + mainLayout->addSpacing(20); + mainLayout->addWidget(m_paraTableWidget); +} + +void CHcRemoteTemplateWidget::onStrategyNameComboCurrentTextChanged(const QString &text) +{ + while( m_timeScetionTable->rowCount() != 0 ) + { + m_timeScetionTable->removeRow(0); + } + + while( m_paraTableWidget->rowCount() != 0 ) + { + m_paraTableWidget->removeRow(0); + } + + int strategyId = -1; + if( m_dbApi->getStrategyIdByName(text, strategyId) ) + { + QList> timeSectionValueList = m_dbApi->getStrategyTimeSectionById(strategyId, QDate::currentDate()); + + for( int i=0; i& valueList = timeSectionValueList[i]; + + updateTimeSectionTableOneRow(i, valueList); + } + + QList> paraValueList = m_dbApi->getStrategyParaById(strategyId); + + for( int i=0; igetTemplateIdByName(m_templateName, templateId) ) + { + m_allTemplatePara = m_dbApi->getTemplateParaById(templateId); + } + + m_strategyNameComboBox->clear(); + m_strategyNameComboBox->addItems(m_dbApi->getStrategyNameByTemplateName(m_templateName)); + + if( m_strategyNameComboBox->count() > 0 ) + { + m_strategyNameComboBox->setCurrentIndex(0); + } +} + +void CHcRemoteTemplateWidget::addTimeSectionTableOneRow() +{ + int newRow = m_timeScetionTable->rowCount(); + + QComboBox* controlComboBox = new QComboBox(); + controlComboBox->addItems(QStringList{"充电", "放电"}); + + m_timeScetionTable->insertRow(newRow); + + m_timeScetionTable->setCellWidget(newRow, 0, new QCheckBox()); + + m_timeScetionTable->setCellWidget(newRow, 1, new QTimeEdit()); + + m_timeScetionTable->setItem(newRow, 2, new QTableWidgetItem(tr("到"))); + m_timeScetionTable->item(newRow, 2)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); + + m_timeScetionTable->setCellWidget(newRow, 3, new QTimeEdit()); + + m_timeScetionTable->setItem(newRow, 4, new QTableWidgetItem(tr("执行"))); + m_timeScetionTable->item(newRow, 4)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); + + m_timeScetionTable->setCellWidget(newRow, 5, controlComboBox); + + m_timeScetionTable->setItem(newRow, 6, new QTableWidgetItem(tr("储能执行功率"))); + m_timeScetionTable->item(newRow, 6)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); + + m_timeScetionTable->setCellWidget(newRow, 7, new QLineEdit()); + + m_timeScetionTable->setItem(newRow, 8, new QTableWidgetItem(tr("kw"))); + m_timeScetionTable->item(newRow, 8)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); +} + +void CHcRemoteTemplateWidget::updateTimeSectionTableOneRow(int row, const QList &rowList) +{ + if( (row < m_timeScetionTable->rowCount()) && (rowList.size() >=4) ) + { + QTimeEdit* beginTimeEdit = qobject_cast(m_timeScetionTable->cellWidget(row, 1)); + if( beginTimeEdit != NULL ) + { + beginTimeEdit->setTime(QTime::fromString(rowList[0].toString(), "hh:mm")); + } + + QTimeEdit* endTimeEdit = qobject_cast(m_timeScetionTable->cellWidget(row, 3)); + if( endTimeEdit != NULL ) + { + endTimeEdit->setTime(QTime::fromString(rowList[1].toString(), "hh:mm")); + } + + QComboBox* controlCombobox = qobject_cast(m_timeScetionTable->cellWidget(row, 5)); + if( controlCombobox != NULL ) + { + controlCombobox->setCurrentIndex(rowList[2].toInt()-1); + } + + QLineEdit* powerEdit = qobject_cast(m_timeScetionTable->cellWidget(row, 7)); + if( powerEdit != NULL ) + { + powerEdit->setText(rowList[3].toString()); + } + } +} + +void CHcRemoteTemplateWidget::addParaTableOneRow() +{ + int newRow = m_paraTableWidget->rowCount(); + + m_paraTableWidget->insertRow(newRow); + + for( int i=0; icolumnCount(); i++ ) + { + QTableWidgetItem* item = new QTableWidgetItem(); + item->setFlags(item->flags() & ~Qt::ItemIsEditable); + + m_paraTableWidget->setItem(newRow, i, item); + } +} + +void CHcRemoteTemplateWidget::updateParaTableOneRow(int row, const QString ¶TagName) +{ + if( (0 <= row) && (row < m_paraTableWidget->rowCount()) ) + { + QList valueList; + for( const QList& list : m_allTemplatePara ) + { + if( list.indexOf(paraTagName) != -1 ) + { + valueList = list; + break; + } + } + + if( valueList.isEmpty() ) + { + return; + } + + QTableWidgetItem* paraTagNameItem = m_paraTableWidget->item(row, 0); + if( paraTagNameItem != NULL ) + { + paraTagNameItem->setText(valueList[0].toString()); + } + + QTableWidgetItem* paraNameItem = m_paraTableWidget->item(row, 1); + if( paraNameItem != NULL ) + { + paraNameItem->setText(valueList[1].toString()); + } + + QTableWidgetItem* dataTypeItem = m_paraTableWidget->item(row, 2); + if( dataTypeItem != NULL ) + { + dataTypeItem->setText(valueList[2].toString()); + } + + QTableWidgetItem* valueTypeItem = m_paraTableWidget->item(row, 3); + if( valueTypeItem != NULL ) + { + valueTypeItem->setText(valueList[3].toString()); + } + + QTableWidgetItem* valueItem = m_paraTableWidget->item(row, 4); + if( valueItem != NULL ) + { + valueItem->setText(valueList[4].toString()); + } + + QTableWidgetItem* valueUnitItem = m_paraTableWidget->item(row, 5); + if( valueUnitItem != NULL ) + { + valueUnitItem->setText(valueList[5].toString()); + } + + QTableWidgetItem* paraTypeItem = m_paraTableWidget->item(row, 6); + if( paraTypeItem != NULL ) + { + int paraType = valueList[6].toInt(); + paraTypeItem->setText(paraType == 1 ? "输入参数" : "输出参数"); + } + } +} diff --git a/product/src/gui/plugin/StrategyControlWidget/template/CHcRemoteTemplateWidget.h b/product/src/gui/plugin/StrategyControlWidget/template/CHcRemoteTemplateWidget.h new file mode 100644 index 00000000..e45a65be --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/template/CHcRemoteTemplateWidget.h @@ -0,0 +1,38 @@ +#ifndef CHCREMOTETEMPLATEWIDGET_H +#define CHCREMOTETEMPLATEWIDGET_H + +#include +#include + +#include "CStrategySqlApi.h" + +class CHcRemoteTemplateWidget : public QWidget +{ + Q_OBJECT + +public: + CHcRemoteTemplateWidget(const QString& templateName, QWidget* parent = NULL); + + void initUI(); + +public slots: + void onStrategyNameComboCurrentTextChanged(const QString& text); + void reloadDataByDB(); + +private: + void addTimeSectionTableOneRow(); + void updateTimeSectionTableOneRow(int row, const QList& rowList); + + void addParaTableOneRow(); + void updateParaTableOneRow(int row, const QString& paraTagName); + + QComboBox* m_strategyNameComboBox; + QTableWidget* m_timeScetionTable; + QTableWidget* m_paraTableWidget; + + QString m_templateName; + QList> m_allTemplatePara; + boost::scoped_ptr m_dbApi; +}; + +#endif // CHCREMOTETEMPLATEWIDGET_H diff --git a/product/src/gui/plugin/StrategyControlWidget/template/CPeakValleyTemplateWidget.cpp b/product/src/gui/plugin/StrategyControlWidget/template/CPeakValleyTemplateWidget.cpp new file mode 100644 index 00000000..9a4f7c1e --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/template/CPeakValleyTemplateWidget.cpp @@ -0,0 +1,551 @@ +#include "CPeakValleyTemplateWidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common/MessageChannel.h" + +CPeakValleyTemplateWidget::CPeakValleyTemplateWidget(const QString& templateName, QWidget* parent) + : QWidget(parent), + m_templateName(templateName), + m_dbApi(new CStrategySqlApi()), + m_mbCommPtr(new iot_net::CMbCommunicator()), + m_isAdding(false) +{ + initUI(); + reloadDataFromDB(); +} + +CPeakValleyTemplateWidget::~CPeakValleyTemplateWidget() +{ + +} + +void CPeakValleyTemplateWidget::initUI() +{ + QVBoxLayout* mainLayout = new QVBoxLayout(this); + + // + QHBoxLayout* topLayout = new QHBoxLayout(); + + m_strategyNameComboBox = new QComboBox(); + m_strategyNameComboBox->setFixedWidth(200); + connect(m_strategyNameComboBox, &QComboBox::currentTextChanged, this, &CPeakValleyTemplateWidget::onStrategyNameComboCurrentTextChanged); + + QPushButton* addStrategyButton = new QPushButton("新增"); + connect(addStrategyButton, &QPushButton::clicked, this, &CPeakValleyTemplateWidget::onAddStrategyButtonClicked); + + QPushButton* deleteStrategyButton = new QPushButton("删除"); + connect(deleteStrategyButton, &QPushButton::clicked, this, &CPeakValleyTemplateWidget::onDeleteStrategyButtonClicked); + + QPushButton* saveStrategyButton = new QPushButton("保存"); + connect(saveStrategyButton, &QPushButton::clicked, this, &CPeakValleyTemplateWidget::onSaveStrategyButtonClicked); + + QPushButton* refreshStrategyButton = new QPushButton("刷新"); + + topLayout->addWidget(m_strategyNameComboBox); + topLayout->addWidget(addStrategyButton); + topLayout->addWidget(deleteStrategyButton); + topLayout->addStretch(); + topLayout->addWidget(saveStrategyButton); + topLayout->addWidget(refreshStrategyButton); + + // + QVBoxLayout* bottomLayout = new QVBoxLayout(); + + m_timeScetionTable = new QTableWidget(0, 9); + m_timeScetionTable->setHorizontalHeaderLabels(QStringList() << tr("") << tr("开始时间") << tr("") << tr("结束时间") << tr("") + << tr("储能类型") << tr("") << tr("储能功率") << tr("")); + m_timeScetionTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + + m_timeScetionTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed); + m_timeScetionTable->setColumnWidth(0, 20); + + QHBoxLayout* timeSectionButtonLayout = new QHBoxLayout(); + + QPushButton* timeScetionAddButton = new QPushButton(tr("新增")); + connect(timeScetionAddButton, &QPushButton::clicked, this, &CPeakValleyTemplateWidget::onTimeSectionAddButtonClicked); + + QPushButton* timeSectionDeleteButton = new QPushButton(tr("删除")); + connect(timeSectionDeleteButton, &QPushButton::clicked, this, &CPeakValleyTemplateWidget::onTimeSectionDeleteButtonClicked); + + timeSectionButtonLayout->addStretch(); + timeSectionButtonLayout->addWidget(timeScetionAddButton); + timeSectionButtonLayout->addWidget(timeSectionDeleteButton); + + m_paraTableWidget = new QTableWidget(0, 7); + m_paraTableWidget->setHorizontalHeaderLabels(QStringList() << tr("参数标签") << tr("参数名称") << tr("数据类型") << tr("值类型") << tr("默认值") << tr("值单位") << tr("参数类型") ); + + m_paraTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + + bottomLayout->addWidget(m_timeScetionTable); + bottomLayout->addLayout(timeSectionButtonLayout); + bottomLayout->addSpacing(50); + bottomLayout->addWidget(m_paraTableWidget); + + // + mainLayout->addLayout(topLayout); + mainLayout->addSpacing(20); + mainLayout->addLayout(bottomLayout); +} + +void CPeakValleyTemplateWidget::reloadDataFromDB() +{ + int templateId = -1; + if( m_dbApi->getTemplateIdByName(m_templateName, templateId) ) + { + m_allTemplatePara = m_dbApi->getTemplateParaById(templateId); + } + + m_strategyNameComboBox->clear(); + m_strategyNameComboBox->addItems(m_dbApi->getStrategyNameByTemplateName(m_templateName)); + + if( m_strategyNameComboBox->count() > 0 ) + { + m_strategyNameComboBox->setCurrentIndex(0); + } +} + +void CPeakValleyTemplateWidget::addTimeSectionTableOneRow() +{ + int newRow = m_timeScetionTable->rowCount(); + + QComboBox* controlComboBox = new QComboBox(); + controlComboBox->addItems(QStringList{"充电", "放电"}); + + m_timeScetionTable->insertRow(newRow); + + m_timeScetionTable->setCellWidget(newRow, 0, new QCheckBox()); + + m_timeScetionTable->setCellWidget(newRow, 1, new QTimeEdit()); + + m_timeScetionTable->setItem(newRow, 2, new QTableWidgetItem(tr("到"))); + m_timeScetionTable->item(newRow, 2)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); + + m_timeScetionTable->setCellWidget(newRow, 3, new QTimeEdit()); + + m_timeScetionTable->setItem(newRow, 4, new QTableWidgetItem(tr("执行"))); + m_timeScetionTable->item(newRow, 4)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); + + m_timeScetionTable->setCellWidget(newRow, 5, controlComboBox); + + m_timeScetionTable->setItem(newRow, 6, new QTableWidgetItem(tr("储能执行功率"))); + m_timeScetionTable->item(newRow, 6)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); + + m_timeScetionTable->setCellWidget(newRow, 7, new QLineEdit()); + + m_timeScetionTable->setItem(newRow, 8, new QTableWidgetItem(tr("kw"))); + m_timeScetionTable->item(newRow, 8)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); +} + +void CPeakValleyTemplateWidget::addParaTableOneRow() +{ + int newRow = m_paraTableWidget->rowCount(); + + m_paraTableWidget->insertRow(newRow); + + for( int i=0; icolumnCount(); i++ ) + { + QTableWidgetItem* item = new QTableWidgetItem(); + item->setFlags(item->flags() & ~Qt::ItemIsEditable); + + m_paraTableWidget->setItem(newRow, i, item); + } +} + +void CPeakValleyTemplateWidget::updateTimeSectionTableOneRow(int row, const QList& rowList) +{ + if( (row < m_timeScetionTable->rowCount()) && (rowList.size() >=4) ) + { + QTimeEdit* beginTimeEdit = qobject_cast(m_timeScetionTable->cellWidget(row, 1)); + if( beginTimeEdit != NULL ) + { + beginTimeEdit->setTime(QTime::fromString(rowList[0].toString(), "hh:mm")); + } + + QTimeEdit* endTimeEdit = qobject_cast(m_timeScetionTable->cellWidget(row, 3)); + if( endTimeEdit != NULL ) + { + endTimeEdit->setTime(QTime::fromString(rowList[1].toString(), "hh:mm")); + } + + QComboBox* controlCombobox = qobject_cast(m_timeScetionTable->cellWidget(row, 5)); + if( controlCombobox != NULL ) + { + controlCombobox->setCurrentIndex(rowList[2].toInt()-1); + } + + QLineEdit* powerEdit = qobject_cast(m_timeScetionTable->cellWidget(row, 7)); + if( powerEdit != NULL ) + { + powerEdit->setText(rowList[3].toString()); + } + } +} + +void CPeakValleyTemplateWidget::updateParaTableOneRow(int row, const QString& paraTagName) +{ + if( (0 <= row) && (row < m_paraTableWidget->rowCount()) ) + { + QList valueList; + for( const QList& list : m_allTemplatePara ) + { + if( list.indexOf(paraTagName) != -1 ) + { + valueList = list; + break; + } + } + + if( valueList.isEmpty() ) + { + return; + } + + QTableWidgetItem* paraTagNameItem = m_paraTableWidget->item(row, 0); + if( paraTagNameItem != NULL ) + { + paraTagNameItem->setText(valueList[0].toString()); + } + + QTableWidgetItem* paraNameItem = m_paraTableWidget->item(row, 1); + if( paraNameItem != NULL ) + { + paraNameItem->setText(valueList[1].toString()); + } + + QTableWidgetItem* dataTypeItem = m_paraTableWidget->item(row, 2); + if( dataTypeItem != NULL ) + { + dataTypeItem->setText(valueList[2].toString()); + } + + QTableWidgetItem* valueTypeItem = m_paraTableWidget->item(row, 3); + if( valueTypeItem != NULL ) + { + valueTypeItem->setText(valueList[3].toString()); + } + + QTableWidgetItem* valueItem = m_paraTableWidget->item(row, 4); + if( valueItem != NULL ) + { + valueItem->setText(valueList[4].toString()); + } + + QTableWidgetItem* valueUnitItem = m_paraTableWidget->item(row, 5); + if( valueUnitItem != NULL ) + { + valueUnitItem->setText(valueList[5].toString()); + } + + QTableWidgetItem* paraTypeItem = m_paraTableWidget->item(row, 6); + if( paraTypeItem != NULL ) + { + int paraType = valueList[6].toInt(); + paraTypeItem->setText(paraType == 1 ? "输入参数" : "输出参数"); + } + } +} + +void CPeakValleyTemplateWidget::onStrategyNameComboCurrentTextChanged(const QString& text) +{ + if( m_isAdding ) + { + m_strategyNameComboBox->removeItem(m_strategyNameComboBox->count()-1); + m_isAdding = false; + } + + while( m_timeScetionTable->rowCount() != 0 ) + { + m_timeScetionTable->removeRow(0); + } + + while( m_paraTableWidget->rowCount() != 0 ) + { + m_paraTableWidget->removeRow(0); + } + + int strategyId = -1; + if( m_dbApi->getStrategyIdByName(text, strategyId) ) + { + QList> timeSectionValueList = m_dbApi->getStrategyTimeSectionById(strategyId, QDate::currentDate()); + + for( int i=0; i& valueList = timeSectionValueList[i]; + + updateTimeSectionTableOneRow(i, valueList); + } + + QList> paraValueList = m_dbApi->getStrategyParaById(strategyId); + + for( int i=0; irowCount() != 0 ) + { + m_timeScetionTable->removeRow(0); + } + + while( m_paraTableWidget->rowCount() != 0 ) + { + m_paraTableWidget->removeRow(0); + } + + // 每次只允许新增一个策略, 策略名在尾部新增及更新 + if( !m_isAdding ) + { + m_strategyNameComboBox->insertItem(m_strategyNameComboBox->count(), strategyName); + m_strategyNameComboBox->setCurrentIndex(m_strategyNameComboBox->count()-1); + + m_isAdding = true; + } + else + { + m_strategyNameComboBox->setItemText(m_strategyNameComboBox->count()-1, strategyName); + } + + for( int i=0; icurrentText()),QMessageBox::Yes, QMessageBox::Cancel) != QMessageBox::Yes ) + { + return; + } + + if( m_isAdding ) + { + m_isAdding = false; + + while( m_timeScetionTable->rowCount() != 0 ) + { + m_timeScetionTable->removeRow(0); + } + + while( m_paraTableWidget->rowCount() != 0 ) + { + m_paraTableWidget->removeRow(0); + } + + m_strategyNameComboBox->removeItem(m_strategyNameComboBox->count()-1); + } + else + { + QString strategyName = m_strategyNameComboBox->currentText(); + if( !strategyName.isEmpty() ) + { + QJsonObject contentJson; + contentJson["strategyName"] = strategyName; + + QJsonObject sendJson; + sendJson["type"] = "strategyDelete"; + sendJson["content"] = contentJson; + + iot_net::CMbMessage msg; + msg.setSubject(CN_AppId_COMAPP, CH_HMI_TO_OPT_OPTCMD_DOWN); + msg.setData(QJsonDocument(sendJson).toJson(QJsonDocument::Compact).toStdString()); + + if( m_mbCommPtr->sendMsgToDomain(msg) ) + { + QMessageBox::information(this, tr("提示"), tr("策略删除成功!")); + m_strategyNameComboBox->removeItem(m_strategyNameComboBox->count()-1); + } + else + { + QMessageBox::information(this, tr("提示"), tr("策略删除失败!")); + } + } + } +} + +void CPeakValleyTemplateWidget::onSaveStrategyButtonClicked() +{ + QString strategyName = m_strategyNameComboBox->currentText(); + + if( strategyName.isEmpty() ) + { + QMessageBox::information(this, tr("提示"), tr("策略名不允许为空")); + + return; + } + + int templateId = -1; + if( !m_dbApi->getTemplateIdByName(m_templateName, templateId) ) + { + QMessageBox::information(this, tr("提示"), tr("无法获取策略模板信息!")); + + return; + } + + QJsonArray timeSectionArray; + for( int i=0; irowCount(); i++ ) + { + QJsonObject timeSectionJson; + + QTimeEdit* beginTimeEdit = qobject_cast(m_timeScetionTable->cellWidget(i, 1)); + if( beginTimeEdit == NULL ) + { + continue; + } + + QTimeEdit* endTimeEdit = qobject_cast(m_timeScetionTable->cellWidget(i, 3)); + if( endTimeEdit == NULL ) + { + continue; + } + + + QTime beginTime = beginTimeEdit->time(); + QTime endTime = endTimeEdit->time(); + + if( i != 0 ) + { + QTimeEdit* lastEndTimeEdit = qobject_cast(m_timeScetionTable->cellWidget(i-1, 3)); + if( lastEndTimeEdit == NULL ) + { + continue; + } + + QTime lastEndTime = lastEndTimeEdit->time(); + if( lastEndTime > beginTime ) + { + QMessageBox::information(this, tr("提示"), tr("时间段不允许交叉设置")); + return; + } + } + + if( (endTime != QTime(0,0)) && (beginTime >= endTime) ) + { + QMessageBox::information(this, tr("提示"), tr("结束时间必须大于开始时间")); + return; + } + + timeSectionJson["beginTime"] = beginTime.toString("hh:mm"); + timeSectionJson["endTime"] = endTime.toString("hh:mm"); + + QComboBox* controlCombobox = qobject_cast(m_timeScetionTable->cellWidget(i, 5)); + if( controlCombobox != NULL ) + { + timeSectionJson["controlType"] = (controlCombobox->currentText() == "充电" ? 1 : 2); + } + + QLineEdit* powerEdit = qobject_cast(m_timeScetionTable->cellWidget(i, 7)); + if( powerEdit != NULL ) + { + timeSectionJson["power"] = powerEdit->text().toInt(); + } + + timeSectionArray.append(timeSectionJson); + } + + QJsonArray paraArray; + if( m_isAdding ) + { + QList> rowValueList = m_dbApi->getTemplateParaById(templateId); + + for( const auto& valueList : rowValueList ) + { + paraArray.append(valueList[0].toString()); + } + } + else + { + for( int i=0; irowCount(); i++ ) + { + QTableWidgetItem* paraTagItem = m_paraTableWidget->item(i, 0); + if( paraTagItem != NULL ) + { + paraArray.append(paraTagItem->text()); + } + } + } + + QJsonObject contentJson; + contentJson["strategyName"] = strategyName; + contentJson["belongTemplate"] = templateId; + contentJson["timeSection"] = timeSectionArray; + contentJson["para"] = paraArray; + + QJsonObject sendJson; + sendJson["type"] = (m_isAdding ? "strategyAdd" : "strategyUpdate"); + sendJson["content"] = contentJson; + + iot_net::CMbMessage msg; + msg.setSubject(CN_AppId_COMAPP, CH_HMI_TO_OPT_OPTCMD_DOWN); + msg.setData(QJsonDocument(sendJson).toJson(QJsonDocument::Compact).toStdString()); + + if( m_mbCommPtr->sendMsgToDomain(msg) ) + { + QMessageBox::information(this, tr("提示"), m_isAdding ? tr("策略保存成功!") : tr("策略模板更新成功!")); + + m_isAdding = false; + } + else + { + QMessageBox::information(this, tr("提示"), m_isAdding ? tr("策略保存失败!") : tr("策略更新失败!")); + } +} + +void CPeakValleyTemplateWidget::onTimeSectionAddButtonClicked() +{ + addTimeSectionTableOneRow(); +} + +void CPeakValleyTemplateWidget::onTimeSectionDeleteButtonClicked() +{ + bool needDelete = false; + + // 支持多行删除 + do + { + needDelete = false; + + for( int i=0; irowCount(); i++ ) + { + QCheckBox* box = qobject_cast(m_timeScetionTable->cellWidget(i, 0)); + if( box->checkState() == Qt::Checked ) + { + m_timeScetionTable->removeRow(i); + needDelete = true; + break; + } + } + } while( needDelete ); +} diff --git a/product/src/gui/plugin/StrategyControlWidget/template/CPeakValleyTemplateWidget.h b/product/src/gui/plugin/StrategyControlWidget/template/CPeakValleyTemplateWidget.h new file mode 100644 index 00000000..437bc548 --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/template/CPeakValleyTemplateWidget.h @@ -0,0 +1,54 @@ +#ifndef CPEAKVALLEYTEMPLATEWIDGET_H +#define CPEAKVALLEYTEMPLATEWIDGET_H + +#include +#include +#include +#include + +#include "boost/scoped_ptr.hpp" + +#include "net_msg_bus_api/CMbCommunicator.h" + +#include "CStrategySqlApi.h" + +class CPeakValleyTemplateWidget : public QWidget +{ + Q_OBJECT + +public: + CPeakValleyTemplateWidget(const QString& templateName, QWidget* parent = NULL); + ~CPeakValleyTemplateWidget(); + +public slots: + void reloadDataFromDB(); + +private: + void initUI(); + + void addTimeSectionTableOneRow(); + void addParaTableOneRow(); + void updateTimeSectionTableOneRow(int row, const QList& rowList); + void updateParaTableOneRow(int row, const QString& paraTagName); + + QComboBox* m_strategyNameComboBox; + QTableWidget* m_timeScetionTable; + QTableWidget* m_paraTableWidget; + + const QString m_templateName; + boost::scoped_ptr m_dbApi; + boost::scoped_ptr m_mbCommPtr; + + QList> m_allTemplatePara; + bool m_isAdding; // 是否处于新增策略流程中 + +private slots: + void onStrategyNameComboCurrentTextChanged(const QString& text); + void onAddStrategyButtonClicked(); + void onDeleteStrategyButtonClicked(); + void onSaveStrategyButtonClicked(); + void onTimeSectionAddButtonClicked(); + void onTimeSectionDeleteButtonClicked(); +}; + +#endif // CPEAKVALLEYTEMPLATEWIDGET_H diff --git a/product/src/gui/plugin/StrategyControlWidget/template/CRealTimeControlTemplateWidget.cpp b/product/src/gui/plugin/StrategyControlWidget/template/CRealTimeControlTemplateWidget.cpp new file mode 100644 index 00000000..131165d1 --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/template/CRealTimeControlTemplateWidget.cpp @@ -0,0 +1,319 @@ +#include "CRealTimeControlTemplateWidget.h" + +#include +#include +#include + +CRealTimeControlTemplateWidget::CRealTimeControlTemplateWidget(const QString& templateName, QWidget* parent) + : QWidget(parent), + m_templateName(templateName), + m_dbApi(new CStrategySqlApi()) +{ + initUI(); + reloadDataByDB(); +} + +void CRealTimeControlTemplateWidget::onInputAddButtonClicked() +{ +} + +void CRealTimeControlTemplateWidget::onInputDeleteButtonClicked() +{ +} + +void CRealTimeControlTemplateWidget::onOutputAddButtonClicked() +{ +} + +void CRealTimeControlTemplateWidget::onOutputDeleteButtonClicked() +{ + +} + +void CRealTimeControlTemplateWidget::onSaveButtonClicked() +{ + int strategyId = -1; + bool result = m_dbApi->getStrategyIdByName(m_templateName, strategyId); + + result = result && m_dbApi->deleteStrategyInputOutputTagLink(strategyId); + + for( int i=0; irowCount(); i++ ) + { + QString inputParaTagName = m_inputParaTableWidget->item(i, 0)->text(); + + QString outputParaTagName; + QComboBox* comboBox = qobject_cast(m_inputParaTableWidget->cellWidget(i, 7)); + if( comboBox != NULL ) + { + outputParaTagName = comboBox->currentText(); + } + + result = result && m_dbApi->addStrategyInputOutputTagLink(strategyId, inputParaTagName, outputParaTagName); + } + + if( result ) + { + QMessageBox::information(this, "title", "保存成功"); + } + else + { + QMessageBox::warning(this, "title", "保存失败"); + } +} + +void CRealTimeControlTemplateWidget::onStrategyNameComboCurrentTextChanged(const QString& text) +{ + while( m_inputParaTableWidget->rowCount() != 0 ) + { + m_inputParaTableWidget->removeRow(0); + } + + while( m_outputParaTableWidget->rowCount() != 0 ) + { + m_outputParaTableWidget->removeRow(0); + } + + int strategyId = -1; + if( m_dbApi->getStrategyIdByName(text, strategyId) ) + { + QList> paraValueList = m_dbApi->getStrategyParaById(strategyId); + + for( int i=0; irowCount()-1, paraTagName); + } + else + { + addParaTableOneRow(m_outputParaTableWidget); + updateParaTableOneRow(m_outputParaTableWidget, m_outputParaTableWidget->rowCount()-1, paraTagName); + } + } + } +} + +void CRealTimeControlTemplateWidget::initUI() +{ + QVBoxLayout* mainLayout = new QVBoxLayout(this); + + // + QHBoxLayout* topLayout = new QHBoxLayout(); + + m_strategyNameComboBox = new QComboBox(); + connect(m_strategyNameComboBox, &QComboBox::currentTextChanged, this, &CRealTimeControlTemplateWidget::onStrategyNameComboCurrentTextChanged); + + QPushButton* saveButton = new QPushButton(tr("保存")); + connect(saveButton, &QPushButton::clicked, this, &CRealTimeControlTemplateWidget::onSaveButtonClicked); + + topLayout->addWidget(m_strategyNameComboBox); + topLayout->addStretch(); + topLayout->addWidget(saveButton); + + m_inputParaTableWidget = new QTableWidget(0, 8); + m_inputParaTableWidget->setHorizontalHeaderLabels(QStringList() << tr("输入参数标签") << tr("参数名称") << tr("数据类型") << tr("值类型") << tr("默认值") << tr("值单位") << tr("参数类型") << tr("关联参数") ); + m_inputParaTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + + // + QHBoxLayout* inputHLayout = new QHBoxLayout(); + + QPushButton* inputAddButton = new QPushButton(tr("新增")); + connect(inputAddButton, &QPushButton::clicked, this, &CRealTimeControlTemplateWidget::onInputAddButtonClicked); + + QPushButton* inputDeleteButton = new QPushButton(tr("删除")); + connect(inputDeleteButton, &QPushButton::clicked, this, &CRealTimeControlTemplateWidget::onInputDeleteButtonClicked); + + inputHLayout->addStretch(); + inputHLayout->addWidget(inputAddButton); + inputHLayout->addWidget(inputDeleteButton); + + m_outputParaTableWidget = new QTableWidget(0, 7); + m_outputParaTableWidget->setHorizontalHeaderLabels(QStringList() << tr("输出参数标签") << tr("参数名称") << tr("数据类型") << tr("值类型") << tr("默认值") << tr("值单位") << tr("参数类型") ); + m_outputParaTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + + // + QHBoxLayout* outputHLayout = new QHBoxLayout(); + + QPushButton* outputAddButton = new QPushButton(tr("新增")); + connect(outputAddButton, &QPushButton::clicked, this, &CRealTimeControlTemplateWidget::onOutputAddButtonClicked); + + QPushButton* outputDeleteButton = new QPushButton(tr("删除")); + connect(outputDeleteButton, &QPushButton::clicked, this, &CRealTimeControlTemplateWidget::onOutputDeleteButtonClicked); + + outputHLayout->addStretch(); + outputHLayout->addWidget(outputAddButton); + outputHLayout->addWidget(outputDeleteButton); + + // + mainLayout->addLayout(topLayout); + mainLayout->addWidget(m_inputParaTableWidget); +// mainLayout->addLayout(inputHLayout); + mainLayout->addSpacing(40); + mainLayout->addWidget(m_outputParaTableWidget); +// mainLayout->addLayout(outputHLayout); +} + +void CRealTimeControlTemplateWidget::addParaTableOneRow(QTableWidget* tableWidget) +{ + if( tableWidget != NULL ) + { + int newRow = tableWidget->rowCount(); + + tableWidget->insertRow(newRow); + + for( int i=0; icolumnCount(); i++ ) + { + if( (tableWidget == m_inputParaTableWidget) && (i == tableWidget->columnCount()-1) ) + { + tableWidget->setCellWidget(newRow, i, new QComboBox()); + } + else + { + QTableWidgetItem* item = new QTableWidgetItem(); + + tableWidget->setItem(newRow, i, item); + } + } + } +} + +bool CRealTimeControlTemplateWidget::isInputPara(const QString& paraTagName) +{ + bool ret = false; + + QList valueList; + for( const QList& list : m_allTemplatePara ) + { + if( list.indexOf(paraTagName) != -1 ) + { + valueList = list; + break; + } + } + + if( !valueList.isEmpty() && (valueList[6].toInt() == 1) ) + { + ret = true; + } + + return ret; +} + +QStringList CRealTimeControlTemplateWidget::getOutputParaTag() +{ + QStringList ret; + + for( const QList& list : m_allTemplatePara ) + { + if( list[6].toInt() == 2 ) + { + ret.append(list[0].toString()); + } + } + + return ret; +} + +void CRealTimeControlTemplateWidget::updateParaTableOneRow(QTableWidget *paraTableWidget, int row, const QString& paraTagName) +{ + if( paraTableWidget == NULL ) + { + return; + } + + if( (0 <= row) && (row < paraTableWidget->rowCount()) ) + { + QList valueList; + for( const QList& list : m_allTemplatePara ) + { + if( list.indexOf(paraTagName) != -1 ) + { + valueList = list; + break; + } + } + + if( valueList.isEmpty() ) + { + return; + } + + QTableWidgetItem* paraTagNameItem = paraTableWidget->item(row, 0); + if( paraTagNameItem != NULL ) + { + paraTagNameItem->setText(valueList[0].toString()); + } + + QTableWidgetItem* paraNameItem = paraTableWidget->item(row, 1); + if( paraNameItem != NULL ) + { + paraNameItem->setText(valueList[1].toString()); + } + + QTableWidgetItem* dataTypeItem = paraTableWidget->item(row, 2); + if( dataTypeItem != NULL ) + { + dataTypeItem->setText(valueList[2].toString()); + } + + QTableWidgetItem* valueTypeItem = paraTableWidget->item(row, 3); + if( valueTypeItem != NULL ) + { + valueTypeItem->setText(valueList[3].toString()); + } + + QTableWidgetItem* valueItem = paraTableWidget->item(row, 4); + if( valueItem != NULL ) + { + valueItem->setText(valueList[4].toString()); + } + + QTableWidgetItem* valueUnitItem = paraTableWidget->item(row, 5); + if( valueUnitItem != NULL ) + { + valueUnitItem->setText(valueList[5].toString()); + } + + QTableWidgetItem* paraTypeItem = paraTableWidget->item(row, 6); + if( paraTypeItem != NULL ) + { + int paraType = valueList[6].toInt(); + paraTypeItem->setText(paraType == 1 ? "输入参数" : "输出参数"); + } + + if( paraTableWidget == m_inputParaTableWidget ) + { + QComboBox* comboBox = qobject_cast(paraTableWidget->cellWidget(row, 7)); + if( comboBox != NULL ) + { + comboBox->addItems(getOutputParaTag()); + + QString outputParaTagName; + if( m_dbApi->getStrategyOutputParaTagName(valueList[0].toString(), outputParaTagName) ) + { + comboBox->setCurrentText(outputParaTagName); + } + } + } + } +} + +void CRealTimeControlTemplateWidget::reloadDataByDB() +{ + int templateId = -1; + if( m_dbApi->getTemplateIdByName(m_templateName, templateId) ) + { + m_allTemplatePara = m_dbApi->getTemplateParaById(templateId); + } + + m_strategyNameComboBox->clear(); + m_strategyNameComboBox->addItems(m_dbApi->getStrategyNameByTemplateName(m_templateName)); + + if( m_strategyNameComboBox->count() > 0 ) + { + m_strategyNameComboBox->setCurrentIndex(0); + } +} diff --git a/product/src/gui/plugin/StrategyControlWidget/template/CRealTimeControlTemplateWidget.h b/product/src/gui/plugin/StrategyControlWidget/template/CRealTimeControlTemplateWidget.h new file mode 100644 index 00000000..ede30e51 --- /dev/null +++ b/product/src/gui/plugin/StrategyControlWidget/template/CRealTimeControlTemplateWidget.h @@ -0,0 +1,47 @@ +#ifndef CREALTIMECONTROLTEMPLATEWIDGET_H +#define CREALTIMECONTROLTEMPLATEWIDGET_H + +#include +#include +#include +#include + +#include "CStrategySqlApi.h" + +class CRealTimeControlTemplateWidget : public QWidget +{ + Q_OBJECT + +public: + CRealTimeControlTemplateWidget(const QString& templateName, QWidget* parent = NULL); + +public slots: + void reloadDataByDB(); + +private slots: + void onInputAddButtonClicked(); + void onInputDeleteButtonClicked(); + void onOutputAddButtonClicked(); + void onOutputDeleteButtonClicked(); + void onSaveButtonClicked(); + + void onStrategyNameComboCurrentTextChanged(const QString& text); + +private: + void initUI(); + + void addParaTableOneRow(QTableWidget* tableWidget); + bool isInputPara(const QString& paraTagName); + QStringList getOutputParaTag(); + void updateParaTableOneRow(QTableWidget* paraTableWidget, int row, const QString& paraTagName); + + QComboBox* m_strategyNameComboBox; + QTableWidget* m_inputParaTableWidget; + QTableWidget* m_outputParaTableWidget; + + QString m_templateName; + QList> m_allTemplatePara; + boost::scoped_ptr m_dbApi; +}; + +#endif // CREALTIMECONTROLTEMPLATEWIDGET_H diff --git a/product/src/gui/plugin/SysParamWidget/CMsgDeal.cpp b/product/src/gui/plugin/SysParamWidget/CMsgDeal.cpp new file mode 100644 index 00000000..30d12e92 --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/CMsgDeal.cpp @@ -0,0 +1,382 @@ +#include "CMsgDeal.h" +#include "net_msg_bus_api/CMbCommunicator.h" +#include +#include + +CMsgDeal::CMsgDeal(QObject *parent) + : QObject(parent) +{ + m_sysInfo = NULL; + m_objSendCMb = new CMbCommunicator; + m_objRecvCMb = new CMbCommunicator; + m_filterNetWork = ""; + m_localHost = "localhost"; + m_strPassword = EMS_DEFAULT_PASSWD; + InitMsgBus(); +} + +CMsgDeal::~CMsgDeal() +{ + delete m_objSendCMb; + m_objSendCMb = nullptr; + + m_objRecvCMb->delSub(E_APPID, CH_OPT_TO_HMI_OPTCMD_UP); + delete m_objRecvCMb; + m_objRecvCMb = nullptr; +} + +void CMsgDeal::setNetWorkName(const QString &networkName) +{ + m_filterNetWork = networkName; +} + +void CMsgDeal::setPasswd(const QString &pswd) +{ + m_strPassword = pswd.toStdString(); +} + +void CMsgDeal::InitMsgBus() +{ + if(!createSysInfoInstance(m_sysInfo)) + { + qDebug() << tr("创建系统信息访问库实例失败!"); + } + + m_permMng = getPermMngInstance("base"); + if(m_permMng != NULL) + { + if(m_permMng->PermDllInit() != PERM_NORMAL) + { +// cout << tr("权限接口初始化失败!").toStdString() << endl; + } + } + + if(!m_objRecvCMb->addSub(E_APPID, CH_OPT_TO_HMI_OPTCMD_UP)) + { +// cout << tr("总线订阅失败!").toStdString() << endl; + return; + } + + SNodeInfo sNodeInfo; + m_sysInfo->getLocalNodeInfo(sNodeInfo); + m_nDomainID = sNodeInfo.nDomainId; + m_localHost = QString::fromStdString(sNodeInfo.strName); +} + +void CMsgDeal::clearMsgBus() +{ + iot_net::CMbMessage msg; + while(true) + { + if(!m_objRecvCMb->recvMsg(msg, 0)) + { + break; + } + } +} + +QString CMsgDeal::NTPQuery(const QString& hostName) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Query_NTP_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated, hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Query_NTP_Message_Ack,hostName); +} + +QString CMsgDeal::TimeQuery(const QString& hostName) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Query_Time_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated, hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Query_Time_Message_Ack,hostName); +} + +QString CMsgDeal::IPQuery(const QString& hostName) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Query_IP_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated,hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Query_IP_Message_Ack,hostName); +} + +QString CMsgDeal::RevNTPSet(const QString& hostName,const bool& sel, const QString& ntpIP) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Set_NTP_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + sReqHead.strPassword = m_strPassword; + + m_strNTPIP = ntpIP.toStdString(); + m_bNTPOn = sel; + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated,hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Set_NTP_Message_Ack,hostName); +} + +QString CMsgDeal::RevTimeSet(const QString& hostName,const QDateTime& dateTime) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Set_Time_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + + m_nSetTime = dateTime.toSecsSinceEpoch(); + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated,hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Set_Time_Message_Ack,hostName); +} + +QString CMsgDeal::RevIPSet(const QString& hostName,const QString& netWorkName, const QString& ip, + const QString& gatway, const QString& mask) +{ + //构造Json,赋值 + SReqHead sReqHead; + sReqHead.nMsgType = enum_Set_IP_Message; + sReqHead.nAppID = E_APPID; + sReqHead.strHostName = m_localHost.toStdString(); + sReqHead.strPassword = m_strPassword; + + m_strNetWorkName = netWorkName.toStdString(); + m_strIp = ip.toStdString(); + m_strGatway = gatway.toStdString(); + m_strMask = mask.toStdString(); + + //构造消息 + iot_net::CMbMessage msgCreated = CreateMsg(sReqHead); + + //发送消息 + clearMsgBus(); + if(!m_objSendCMb->sendMsgToHost(msgCreated,hostName.toStdString().c_str())) + { + return tr("发送消息失败"); + } + + return RevMessage(enum_Set_IP_Message_Ack,hostName); +} + +QString CMsgDeal::RevMessage(int nMsgType, const QString &hostName) +{ + Q_UNUSED(nMsgType); + Q_UNUSED(hostName); + + iot_net::CMbMessage msg; + while(m_objRecvCMb->recvMsg(msg, 3000)) + { + if(msg.getMsgType() != MT_SYS_PARAMS_TO_HMI_UP) + { + continue; + } + + //字符串反序列化Json数据 + boost::property_tree::ptree pt; + std::string msgStr((char*)msg.getDataPtr(), (int)msg.getDataSize()); + try { + std::istringstream iss; + iss.str(msgStr.c_str()); + boost::property_tree::json_parser::read_json(iss, pt); + } + catch (boost::property_tree::ptree_error &pt_error) + { + Q_UNUSED(pt_error); + return tr("消息解析错误"); + } + //解析Json数据 + int msgType = pt.get("msgType"); + std::string ErroStr = pt.get("ErroStr"); + if(!ErroStr.empty()) + { + return QString::fromStdString(ErroStr); + } + + switch(msgType) { + case enum_Query_NTP_Message_Ack: { + QString strNTPIP = QString::fromStdString(pt.get("NTPIP")); + bool bNTPOn = pt.get("NTPOn"); + emit SendNTPQuery(strNTPIP,bNTPOn); + return ""; + } break; + case enum_Query_Time_Message_Ack: { + int64 nDateTime = pt.get("Time"); +// cout << "nDateTime: " << nDateTime << endl; + emit SendTimeQuery(nDateTime); + return ""; + } break; + case enum_Query_IP_Message_Ack: { + boost::property_tree::ptree ch_parser = pt.get_child("NetworkList"); + QString strNetWorkName, strIP, strGatway, strMask; + for(boost::property_tree::ptree::value_type &v : ch_parser) + { + boost::property_tree::ptree p = v.second; + QString temp = QString::fromStdString(p.get("NetworkName")); + if(!m_filterNetWork.isEmpty()) + { + if(temp.compare(m_filterNetWork) != 0) + { + continue; + } + } + strNetWorkName = temp; + strIP = QString::fromStdString(p.get("IP")); + strGatway = QString::fromStdString(p.get("Gatway")); + strMask = QString::fromStdString(p.get("Mask")); + break; + } + + emit SendIPQuery(strNetWorkName, strIP, strGatway, strMask); + return ""; + } break; + case enum_Query_Led_Message_Ack: { + int nLed = std::atoi(pt.get("LedValue").c_str()); + emit SendLedQuery(nLed); + return ""; + } break; + case enum_Set_NTP_Message_Ack: { + return ""; + } break; + case enum_Set_Time_Message_Ack: { + return ""; + } break; + case enum_Set_IP_Message_Ack: { + return ""; + } break; + case enum_Set_Led_Message_Ack: { + return ""; + } break; + default: + return tr("未知的命令"); + break; + } + } + + return tr("未接收到消息"); +} + +iot_net::CMbMessage CMsgDeal::CreateMsg(const SReqHead& sReqHead) +{ + m_jsonMap.clear(); + + //m_jsonMap初始化 + m_jsonMap["msgType"] = to_string(sReqHead.nMsgType); + m_jsonMap["strSrcTag"] = sReqHead.strSrcTag; + m_jsonMap["nSrcDomainID"] = to_string(sReqHead.nSrcDomainID); + m_jsonMap["nDstDomainID"] = to_string(sReqHead.nDstDomainID); + m_jsonMap["nAppID"] = to_string(sReqHead.nAppID); + m_jsonMap["strHostName"] = sReqHead.strHostName; + m_jsonMap["strInstName"] = sReqHead.strInstName; + m_jsonMap["strCommName"] = sReqHead.strCommName; + m_jsonMap["nUserID"] = to_string(sReqHead.nUserID); + m_jsonMap["nUserGroupID"] = to_string(sReqHead.nUserGroupID); + m_jsonMap["nOptTime"] = to_string(sReqHead.nOptTime); + m_jsonMap["strKeyIdTag"] = sReqHead.strKeyIdTag; + m_jsonMap["ErroStr"] = sReqHead.ErroStr; + m_jsonMap["Password"] = sReqHead.strPassword; + + switch(sReqHead.nMsgType) { + case enum_Set_NTP_Message: { + m_jsonMap["NTPIP"] = m_strNTPIP; + m_jsonMap["NTPOn"] = std::to_string(m_bNTPOn); + } + case enum_Set_Time_Message: { + m_jsonMap["Time"] = to_string(m_nSetTime); + } break; + case enum_Set_Led_Message: { + m_jsonMap["LedValue"] = to_string(m_nLedValue); + } break; +// case enum_Set_IP_Message: { +// } break; + default: break; + } + + //构建Json数据 + boost::property_tree::ptree pt; + QMap::iterator iter; + for(iter = m_jsonMap.begin(); iter != m_jsonMap.end(); iter++) { + pt.put(iter.key(), iter.value()); + } + + if(sReqHead.nMsgType == enum_Set_IP_Message) + { + boost::property_tree::ptree children; + boost::property_tree::ptree child; + pt.put("NetworkCount", to_string(4)); + child.put("NetworkName", m_strNetWorkName); + child.put("IP", m_strIp); + child.put("Gatway", m_strGatway); + child.put("Mask", m_strMask); + children.push_back(std::make_pair("", child)); + pt.add_child("NetworkList", children); + } + + //将Json数据序列化为字符串 + std::ostringstream jsonStrem; + boost::property_tree::write_json(jsonStrem, pt,false); + std::string jsonString = jsonStrem.str(); + + //构造消息 + iot_net::CMbMessage msg; + msg.setMsgType(MT_HMI_TO_SYS_PARAMS_DOWN); + msg.setSubject(E_APPID, CH_HMI_TO_OPT_OPTCMD_DOWN); + msg.setData(jsonString); + + return msg; +} diff --git a/product/src/gui/plugin/SysParamWidget/CMsgDeal.h b/product/src/gui/plugin/SysParamWidget/CMsgDeal.h new file mode 100644 index 00000000..a4c65f9b --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/CMsgDeal.h @@ -0,0 +1,103 @@ +#ifndef CMSGDEAL_H +#define CMSGDEAL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PreDefine.h" + +#include "public/pub_sysinfo_api/SysInfoApi.h" +#include "perm_mng_api/PermMngApi.h" +#include "net_msg_bus_api/CMbCommunicator.h" +#include "common/MessageChannel.h" + +/** + * 只有这个功能用platform的Json构建和解析, + * CMsgDeal用boost构建和解析Json + */ +#include "service/operate_server_api/JsonMessageStruct.h" +#include "service/operate_server_api/JsonOptCommand.h" + +using namespace std; +using namespace iot_public; +using namespace iot_service; +using namespace iot_net; + +static const int E_APPID = 1; + +class CMsgDeal : public QObject +{ + Q_OBJECT +public: + explicit CMsgDeal(QObject *parent = nullptr); + ~CMsgDeal(); + + void setNetWorkName(const QString& networkName); + void setPasswd(const QString& pswd); + +signals: + void SendNTPQuery(const QString& ntpIP,bool ntpOn); + void SendTimeQuery(const int64& nDateTime); + void SendIPQuery(const QString& netWorkName, const QString& ip, + const QString& gatway, const QString& mask); + void SendLedQuery(const int& ledValue); + +public slots: + QString RevNTPSet(const QString& hostName,const bool& sel, const QString& ntpIP); + QString RevTimeSet(const QString& hostName,const QDateTime& dateTime); + QString RevIPSet(const QString& hostName,const QString& netWorkName, const QString& ip, + const QString& gatway, const QString& mask); + + QString NTPQuery(const QString& hostName); //查询初始NTP + QString TimeQuery(const QString& hostName); //查询初始NTP + QString IPQuery(const QString& hostName); //查询初始NTP + +private slots: + QString RevMessage(int nMsgType,const QString& hostName); + +private: + void InitMsgBus(); + bool AddSub(int appID, int channel); + bool DelSub(int appID, int channel); + void clearMsgBus(); + iot_net::CMbMessage CreateMsg(const SReqHead& sReqHead); + +private: + iot_public::CSysInfoInterfacePtr m_sysInfo; + iot_service::CPermMngApiPtr m_permMng; + + iot_net::CMbCommunicator* m_objSendCMb;//发送 + iot_net::CMbCommunicator* m_objRecvCMb;//接收 + + std::string m_curRtu; + std::string m_strHostName; + std::string m_strInstName; + int m_nOptTime; + + QMap m_jsonMap; + int m_nDomainID; + std::string m_strPassword; + std::string m_strNTPIP; //设置NTPIP + bool m_bNTPOn; //设置NTPIP 是否启用 + int64 m_nSetTime; //设置时间 + std::string m_strNetWorkName; //网卡 + std::string m_strIp; //IP地址 + std::string m_strGatway; //网关 + std::string m_strMask; //子网掩码 + int64 m_nLedValue; //设置亮度 + + QString m_filterNetWork; + QString m_localHost; +}; + +#endif // CMSGDEAL_H diff --git a/product/src/gui/plugin/SysParamWidget/CMsgHeadParse.cpp b/product/src/gui/plugin/SysParamWidget/CMsgHeadParse.cpp new file mode 100644 index 00000000..f856c9c1 --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/CMsgHeadParse.cpp @@ -0,0 +1,43 @@ +#include "CMsgHeadParse.h" + +CMsgHeadParse::CMsgHeadParse() +{ + +} + +bool CMsgHeadParse::GenerateHead(const SReqHead &stHead, boost::property_tree::ptree &pt_root) +{ + pt_root.put("msgType", stHead.nMsgType); + pt_root.put("strSrcTag", stHead.strSrcTag ); + pt_root.put("nSrcDomainID",stHead.nSrcDomainID ); + pt_root.put("nDstDomainID",stHead.nDstDomainID ); + pt_root.put("nAppID" ,stHead.nAppID ); + pt_root.put("strHostName" ,stHead.strHostName ); + pt_root.put("strInstName" ,stHead.strInstName ); + pt_root.put("strCommName" ,stHead.strCommName ); + pt_root.put("nUserID" ,stHead.nUserID ); + pt_root.put("nUserGroupID",stHead.nUserGroupID ); + pt_root.put("nOptTime" ,stHead.nOptTime ); + pt_root.put("strKeyIdTag", stHead.strKeyIdTag); + pt_root.put("ErroStr", stHead.ErroStr); + + return true; +} + +bool CMsgHeadParse::ParseHead(const boost::property_tree::ptree& parser, SReqHead &stHead) +{ + stHead.nMsgType = parser.get("msgType"); + stHead.strSrcTag = parser.get("strSrcTag","hmi"); + stHead.nSrcDomainID = parser.get("nSrcDomainID"); + stHead.nDstDomainID = parser.get("nDstDomainID"); + stHead.nAppID = parser.get("nAppID"); + stHead.strHostName = parser.get("strHostName",""); + stHead.strInstName = parser.get("strInstName",""); + stHead.strCommName = parser.get("strCommName",""); + stHead.nUserID = parser.get("nUserID",-1); + stHead.nUserGroupID = parser.get("nUserGroupID",-1); + stHead.nOptTime = parser.get("nOptTime"); + stHead.strKeyIdTag = parser.get("strKeyIdTag", ""); + stHead.ErroStr = parser.get("ErroStr", ""); + return true; +} diff --git a/product/src/gui/plugin/SysParamWidget/CMsgHeadParse.h b/product/src/gui/plugin/SysParamWidget/CMsgHeadParse.h new file mode 100644 index 00000000..b23411e2 --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/CMsgHeadParse.h @@ -0,0 +1,20 @@ +#ifndef CMSGHEADPARSE_H +#define CMSGHEADPARSE_H + +#include +#include +#include + +#include "PreDefine.h" + +class CMsgHeadParse +{ +public: + CMsgHeadParse(); + + bool static GenerateHead(const SReqHead& stHead,boost::property_tree::ptree &pt_root ); + bool static ParseHead(const boost::property_tree::ptree& parser, SReqHead& stHead); + +}; + +#endif // CMSGHEADPARSE_H diff --git a/product/src/gui/plugin/SysParamWidget/CRealDataCollect.cpp b/product/src/gui/plugin/SysParamWidget/CRealDataCollect.cpp new file mode 100644 index 00000000..7a08d503 --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/CRealDataCollect.cpp @@ -0,0 +1,248 @@ +#include "CRealDataCollect.h" + +#include + +#include +using namespace std; + +CRealDataCollect* CRealDataCollect::m_pInstance = NULL; + +CRealDataCollect::CRealDataCollect() + : m_pMbComm(NULL), + m_pTimer(NULL), + m_nTimeCount(0) +{ +// cout << "CRealDataCollect::CRealDataCollect" << endl; + initMsg(); + if(!addSub()) + { + return; + } + +// cout << "CRealDataCollect::CRealDataCollect addSub" << endl; + + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(recvMessage())); + m_pTimer->start(100); +} + +CRealDataCollect *CRealDataCollect::instance() +{ + if(m_pInstance == NULL) + { + m_pInstance = new CRealDataCollect(); + } + return m_pInstance; +} + +void CRealDataCollect::release() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = NULL; + + delSub(); + closeMsg(); + m_pInstance = NULL; + delete this; +} + +void CRealDataCollect::initMsg() +{ + if(m_pMbComm == NULL) + { + m_pMbComm = new iot_net::CMbCommunicator("CSysParamWidget"); + } +} + +void CRealDataCollect::closeMsg() +{ + if(m_pMbComm != NULL) + { + delete m_pMbComm; + } + m_pMbComm = NULL; +} + +void CRealDataCollect::clearMsg() +{ + if(m_pMbComm) + { + iot_net::CMbMessage objMsg; + while(m_pMbComm->recvMsg(objMsg, 0)) + {} + } +} + +bool CRealDataCollect::addSub() +{ + if(m_pMbComm) + { + return m_pMbComm->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else + { + return false; + } +} + +bool CRealDataCollect::delSub() +{ + if(m_pMbComm) + { + return m_pMbComm->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + } + else + { + return false; + } +} + +void CRealDataCollect::recvMessage() +{ + m_nTimeCount = (m_nTimeCount + 1) % 36000; + + if(m_nTimeCount % 10 == 0) + { +// cout << "CRealDataCollect::recvMessage processChangeData" << endl; + processChangeData(); + } + + try + { + iot_net::CMbMessage objMsg; + for(int i = 0; i < 6; i++) + { + if(m_pMbComm->recvMsg(objMsg, 0)) + { + if(objMsg.isValid()) + { + if(objMsg.getMsgType() != iot_idl::MT_DP_CHANGE_DATA) + { + continue; + } + if(objMsg.getChannelID() != CH_SCADA_TO_HMI_DATA_CHANGE) + { + continue; + } + parserMsg(objMsg); + } + } + } + } + catch(...) + { + + } +} + +void CRealDataCollect::processChangeData() +{ + if(!m_aiMap.isEmpty()) + { + emit signal_updateAi(m_aiMap); + m_aiMap.clear(); + } + + if(!m_diMap.isEmpty()) + { + emit signal_updateDi(m_diMap); + m_diMap.clear(); + } + + if(!m_piMap.isEmpty()) + { + emit signal_updatePi(m_piMap); + m_piMap.clear(); + } + + if(!m_miMap.isEmpty()) + { + emit signal_updateMi(m_miMap); + m_miMap.clear(); + } +} + +int CRealDataCollect::parserMsg(const iot_net::CMbMessage &msg) +{ + iot_idl::SRealTimeDataPkg changeDataPackage; + try + { + changeDataPackage.ParseFromArray(msg.getDataPtr(),(int)msg.getDataSize()); + int aiSize = changeDataPackage.stairtd_size(); + if(aiSize > 0) + { + iot_idl::SAiRealTimeData aiStru; + QString tagName; + float value; + uint status; + for(int i = 0; i < aiSize;++i) + { + aiStru = changeDataPackage.stairtd(i); + tagName = QString::fromStdString(aiStru.strtagname()); + value = aiStru.fvalue(); + status = aiStru.ustatus(); + m_aiMap[tagName] = qMakePair(value, status); + } + } + + int diSize = changeDataPackage.stdirtd_size(); + if(diSize > 0) + { + iot_idl::SDiRealTimeData diStu; + QString tagName; + int value; + uint status; + for(int i = 0; i < diSize; ++i) + { + diStu = changeDataPackage.stdirtd(i); + tagName = QString::fromStdString(diStu.strtagname()); + value = diStu.nvalue(); + status = diStu.ustatus(); + m_diMap[tagName] = qMakePair(value, status); + } + } + + int piSize = changeDataPackage.stpirtd_size(); + if(piSize > 0) + { + iot_idl::SPiRealTimeData piStu; + QString tagName; + double value; + uint status; + for(int i = 0 ; i < piSize; ++i) + { + piStu = changeDataPackage.stpirtd(i); + tagName = QString::fromStdString(piStu.strtagname()); + value = piStu.dvalue(); + status = piStu.ustatus(); + m_piMap[tagName] = qMakePair(value, status); + } + } + + int miSize = changeDataPackage.stmirtd_size(); + if(miSize > 0) + { + iot_idl::SMiRealTimeData miStu; + QString tagName; + int value; + uint status; + for(int i = 0 ; i < miSize ; ++i) + { + miStu = changeDataPackage.stmirtd(i); + tagName = QString::fromStdString(miStu.strtagname()); + value = miStu.nvalue(); + status = miStu.ustatus(); + m_miMap[tagName] = qMakePair(value, status); + } + } + } + catch(...) + { + return 0; + } + return 1; +} diff --git a/product/src/gui/plugin/SysParamWidget/CRealDataCollect.h b/product/src/gui/plugin/SysParamWidget/CRealDataCollect.h new file mode 100644 index 00000000..4b72a5c7 --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/CRealDataCollect.h @@ -0,0 +1,52 @@ +#ifndef CRealDataCollect_H +#define CRealDataCollect_H + +#include +#include +#include "net_msg_bus_api/CMbCommunicator.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" + +class QTimer; +class CRealDataCollect : public QObject +{ + Q_OBJECT +public: + static CRealDataCollect * instance(); + + void release(); + +private: + CRealDataCollect(); + + void initMsg(); + void closeMsg(); + void clearMsg(); + bool addSub(); + bool delSub(); + + int parserMsg(const iot_net::CMbMessage &); + +private slots: + void recvMessage(); + void processChangeData(); + +signals: + void signal_updateAi(QMap> aiMap); + void signal_updateDi(QMap> diMap); + void signal_updatePi(QMap> piMap); + void signal_updateMi(QMap> miMap); + +private: + iot_net::CMbCommunicator *m_pMbComm; + QTimer * m_pTimer; + int m_nTimeCount; + QMap> m_aiMap; + QMap> m_diMap; + QMap> m_piMap; + QMap> m_miMap; + + static CRealDataCollect * m_pInstance; +}; + +#endif // CRealDataCollect_H diff --git a/product/src/gui/plugin/SysParamWidget/CSysParamPluginWidget.cpp b/product/src/gui/plugin/SysParamWidget/CSysParamPluginWidget.cpp new file mode 100644 index 00000000..499b814a --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/CSysParamPluginWidget.cpp @@ -0,0 +1,25 @@ +#include "CSysParamPluginWidget.h" + +CSysParamPluginWidget::CSysParamPluginWidget(QObject *parent) + : QObject(parent) +{ + +} + +CSysParamPluginWidget::~CSysParamPluginWidget() +{ + +} + +bool CSysParamPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CSysParamWidget *pWidget = new CSysParamWidget(parent, editMode); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CSysParamPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/SysParamWidget/CSysParamPluginWidget.h b/product/src/gui/plugin/SysParamWidget/CSysParamPluginWidget.h new file mode 100644 index 00000000..e9b4d4a0 --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/CSysParamPluginWidget.h @@ -0,0 +1,22 @@ +#ifndef CSYSPARAMPLUGINWIDGET_H +#define CSYSPARAMPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape +#include "CSysParamWidget.h" + +class CSysParamPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) + Q_INTERFACES(CPluginWidgetInterface) + +public: + CSysParamPluginWidget(QObject *parent = 0); + ~CSysParamPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif // CSYSPARAMPLUGINWIDGET_H diff --git a/product/src/gui/plugin/SysParamWidget/CSysParamWidget.cpp b/product/src/gui/plugin/SysParamWidget/CSysParamWidget.cpp new file mode 100644 index 00000000..2966c20f --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/CSysParamWidget.cpp @@ -0,0 +1,353 @@ +#include "CSysParamWidget.h" +#include "ui_CSysParamWidget.h" + +#include +#include +CSysParamWidget::CSysParamWidget(QWidget *parent, bool isEditMode) : + QWidget(parent), + ui(new Ui::CSysParamWidget), + m_isEditMode(isEditMode) +{ + ui->setupUi(this); + + m_sPassword = EMS_DEFAULT_PASSWD; + + m_ipHostName = "localhost"; + m_ntpHostNames.push_back("localhost"); + m_timeHostNames.push_back("localhost"); + + //ui->lineEdit_NTPIP->setValidator(new QRegExpValidator(QRegExp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"))); + ui->lineEdit_IP->setValidator(new QRegExpValidator(QRegExp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"))); + ui->lineEdit_Gatway->setValidator(new QRegExpValidator(QRegExp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"))); +// ui->lineEdit_Mask->setValidator(new QRegExpValidator(QRegExp("(254|252|248|240|224|192|128|0)\\.0\\.0\\.0|255\\.(254|252|248|240|224|192|128|0)\\.0\\.0|255\\.255\\.(254|252|248|240|224|192|128|0)\\.0|255\\.255\\.255\\.(254|252|248|240|224|192|128|0)"))); + ui->lineEdit_Mask->setValidator(new QRegExpValidator(QRegExp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"))); + + InitStyle(); + m_pCMsgDeal = new CMsgDeal; + + connect(m_pCMsgDeal, &CMsgDeal::SendNTPQuery, this, &CSysParamWidget::RevNTPQuery); + connect(m_pCMsgDeal, &CMsgDeal::SendTimeQuery, this, &CSysParamWidget::RevTimeQuery); + connect(m_pCMsgDeal, &CMsgDeal::SendIPQuery, this, &CSysParamWidget::RevIPQuery); + connect(ui->rbtn_ntp_yes, &QRadioButton::clicked, this, &CSysParamWidget::SelYes_Clicked); + connect(ui->rbtn_ntp_no, &QRadioButton::clicked, this, &CSysParamWidget::SelNo_Clicked); + connect(ui->btn_timeQuery, &QPushButton::clicked, this, &CSysParamWidget::TimeQuery_Clicked); + connect(ui->btn_timeSet, &QPushButton::clicked, this, &CSysParamWidget::TimeSet_Clicked); + connect(ui->btn_ipQuery, &QPushButton::clicked, this, &CSysParamWidget::IPQuery_Clicked); + connect(ui->btn_ipSet, &QPushButton::clicked, this, &CSysParamWidget::IPSet_Clicked); + ui->rbtn_ntp_no->setChecked(true); +} + +CSysParamWidget::~CSysParamWidget() +{ + if(m_pCMsgDeal) + { + delete m_pCMsgDeal; + m_pCMsgDeal = nullptr; + } + + delete ui; +} + +void CSysParamWidget::InitSet(const QString& password) +{ + m_sPassword = password; + m_pCMsgDeal->setPasswd(password); +} + +void CSysParamWidget::setNTPSetHosts(const QString &hostNames) +{ + m_ntpHostNames = hostNames.split(","); +} + +void CSysParamWidget::setTimeSetHosts(const QString &hostNames) +{ + m_timeHostNames = hostNames.split(","); +} + +void CSysParamWidget::setIpSetHost(const QString &hostName) +{ + m_ipHostName = hostName; +} + +void CSysParamWidget::setNetWorkName(const QString &networkName) +{ + m_pCMsgDeal->setNetWorkName(networkName); +} + +void CSysParamWidget::initViewData() +{ + if (!ntpQuery()) + { + return; + } + + if (!timeQuery()) + { + return; + } + + if (!ipQuery()) + { + return; + } +} + +bool CSysParamWidget::ntpSet() +{ + QString NTPIP = ui->lineEdit_NTPIP->text(); + if (ui->rbtn_ntp_yes->isChecked() && NTPIP.isEmpty()) + { + showMsg(QString("NTP服务器IP不允许为空")); + return false; + } + /* + QRegExp rx("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"); + if(!rx.exactMatch(NTPIP)) + { + showMsg(QString("NTP服务器:%1不符合规范,请检查").arg(NTPIP)); + return; + } + */ + + QStringList::iterator iter = m_ntpHostNames.begin(); + bool bSelect = ui->rbtn_ntp_yes->isChecked(); + for (; iter != m_ntpHostNames.end(); ++iter) + { + QString ret = m_pCMsgDeal->RevNTPSet(*iter, bSelect, NTPIP); + if (!ret.isEmpty()) + { + showMsg(QString(tr("NTP设置失败:%1,主机名:%2")).arg(ret).arg(*iter)); + return false; + } + } + + //ui->rbtn_ntp_yes->setChecked(bSelect); + //ui->rbtn_ntp_no->setChecked(!bSelect); + + showMsg(QString(tr("NTP设置成功"))); + + return true; +} + +bool CSysParamWidget::timeSet() +{ + //if(m_bTimeSet) + { + QDate date = ui->dateEdit_timeSet->date(); + QTime time = ui->timeEdit_timeSet->time(); + QDateTime dateTime(date, time); + + QStringList::iterator iter = m_timeHostNames.begin(); + for (; iter != m_timeHostNames.end(); ++iter) + { + QString ret = m_pCMsgDeal->RevTimeSet(*iter, dateTime); + if (!ret.isEmpty()) + { + showMsg(QString(tr("时间设置失败:%1,主机名:%2")).arg(ret).arg(*iter)); + return false; + } + } + + showMsg(QString(tr("时间设置成功"))); + } + //else + //{ + //showMsg(QString(tr("设置时间失败,请先关闭NTP"))); + //} + return false; +} + +bool CSysParamWidget::ntpQuery() +{ + QString ret; + ret = m_pCMsgDeal->NTPQuery(m_ntpHostNames.at(0)); + if (!ret.isEmpty()) + { + showMsg(QString("NTP信息查询失败:%1,主机名:%2").arg(ret).arg(m_ntpHostNames.at(0))); + return false; + } + return true; +} + +bool CSysParamWidget::timeQuery() +{ + QString ret = m_pCMsgDeal->TimeQuery(m_timeHostNames.at(0)); + if (!ret.isEmpty()) + { + showMsg(QString("时间信息查询失败:%1,主机名:%2").arg(ret).arg(m_timeHostNames.at(0))); + return false; + } + + return true; +} + +bool CSysParamWidget::ipQuery() +{ + QString ret = m_pCMsgDeal->IPQuery(m_ipHostName); + if (!ret.isEmpty()) + { + showMsg(QString("网络信息查询失败:%1,主机名:%2").arg(ret).arg(m_ipHostName)); + return false; + } + + return true; +} + +void CSysParamWidget::InitStyle() +{ + QString styleSheet; + std::string stylepath = iot_public::CFileStyle::getPathOfStyleFile("public.qss"); + QFile file(QString::fromStdString(stylepath)); + file.open(QFile::ReadOnly); + if (file.isOpen()) + { + styleSheet.append(file.readAll()); + file.close(); + } + stylepath = iot_public::CFileStyle::getPathOfStyleFile("SysParamWidget.qss"); + QFile file1(QString::fromStdString(stylepath)); + file1.open(QFile::ReadOnly); + if (file1.isOpen()) + { + styleSheet.append(file1.readAll()); + file1.close(); + } + setStyleSheet(styleSheet); +} + +void CSysParamWidget::showMsg(const QString &msg) +{ +// if(ui->m_showMsgLabel->text().isEmpty()) +// QTimer::singleShot(3000,this,&CSysParamWidget::clearMsg); + +// ui->m_showMsgLabel->setText(msg); + + QMessageBox::information(this, "", msg); +} + +void CSysParamWidget::clearMsg() +{ +// ui->m_showMsgLabel->setText(""); +} + +void CSysParamWidget::RevNTPQuery(const QString& ntpIP,bool ntpOn) +{ +// cout << "CSysParamWidget::RevNTPQuery ntpIP: " << ntpIP.toStdString() << endl; + ui->rbtn_ntp_yes->setChecked(ntpOn); + ui->rbtn_ntp_no->setChecked(!ntpOn); + ui->lineEdit_NTPIP->setText(ntpIP); +} + +void CSysParamWidget::RevTimeQuery(const int64& nDateTime) +{ +// cout << "CSysParamWidget::RevTimeQuery nDateTime: " << nDateTime << endl; + QDateTime dateTime; + dateTime.setTime_t(nDateTime); + ui->dateEdit_timeSet->setDate(dateTime.date()); + ui->timeEdit_timeSet->setTime(dateTime.time()); + + cout << "CSysParamWidget::RevTimeQuery nDateTime end" << endl; +} + +void CSysParamWidget::RevIPQuery(const QString& netWorkName, const QString& ip, + const QString& gatway, const QString& mask) +{ +// cout << "CSysParamWidget::RevIPQuery netWorkName: " << netWorkName.toStdString() << endl; +// cout << "CSysParamWidget::RevIPQuery ip: " << ip.toStdString() << endl; +// cout << "CSysParamWidget::RevIPQuery gatway: " << gatway.toStdString() << endl; +// cout << "CSysParamWidget::RevIPQuery mask: " << mask.toStdString() << endl; + + ui->lineEdit_NetWorkName->setText(netWorkName); + ui->lineEdit_IP->setText(ip); + ui->lineEdit_Gatway->setText(gatway); + ui->lineEdit_Mask->setText(mask); +} + +void CSysParamWidget::SelYes_Clicked(const bool& checked) +{ + ui->widget_time->setEnabled(!checked); + ui->lineEdit_NTPIP->setEnabled(checked); +} + +void CSysParamWidget::SelNo_Clicked(const bool& checked) +{ + ui->widget_time->setEnabled(checked); + ui->lineEdit_NTPIP->setEnabled(!checked); +} + +void CSysParamWidget::TimeSet_Clicked() +{ + if (!ntpSet()) + { + return; + } + + if (ui->widget_time->isEnabled()) + { + timeSet(); + } +} + +void CSysParamWidget::IPSet_Clicked() +{ + QString strNetWorkName = ui->lineEdit_NetWorkName->text(); //网卡 + QString strIp = ui->lineEdit_IP->text(); //IP地址 + QString strGatway = ui->lineEdit_Gatway->text(); //网关 + QString strMask = ui->lineEdit_Mask->text(); //子网掩码 + if(strIp.isEmpty()) + { + showMsg(QString("IP地址不允许为空")); + return; + } + QRegExp rx("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"); + if(!rx.exactMatch(strIp)) + { + showMsg(QString("IP地址:%1不符合规范,请检查").arg(strIp)); + return; + } + if(strGatway.isEmpty()) + { + showMsg(QString("网关不允许为空")); + return; + } + if(!rx.exactMatch(strGatway)) + { + showMsg(QString("网关:%1不符合规范,请检查").arg(strGatway)); + return; + } + QRegExp rx1("(254|252|248|240|224|192|128|0)\\.0\\.0\\.0|255\\.(254|252|248|240|224|192|128|0)\\.0\\.0|255\\.255\\.(254|252|248|240|224|192|128|0)\\.0|255\\.255\\.255\\.(254|252|248|240|224|192|128|0)"); + if(strMask.isEmpty()) + { + showMsg(QString("子网掩码不允许为空")); + return; + } + if(!rx1.exactMatch(strMask)) + { + showMsg(QString("子网掩码:%1不符合规范,请检查").arg(strMask)); + return; + } + + QString ret = m_pCMsgDeal->RevIPSet(m_ipHostName,strNetWorkName, strIp, strGatway, strMask); + if(!ret.isEmpty()) + { + showMsg(QString(tr("IP设置失败:%1,主机名:%2")).arg(ret).arg(m_ipHostName)); + return; + } + + showMsg(QString(tr("IP设置成功"))); +} + +void CSysParamWidget::TimeQuery_Clicked() +{ + if (!ntpQuery()) + { + return; + } + + timeQuery(); +} + +void CSysParamWidget::IPQuery_Clicked() +{ + ipQuery(); +} diff --git a/product/src/gui/plugin/SysParamWidget/CSysParamWidget.h b/product/src/gui/plugin/SysParamWidget/CSysParamWidget.h new file mode 100644 index 00000000..06edaa82 --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/CSysParamWidget.h @@ -0,0 +1,79 @@ +#ifndef CSYSPARAMWIDGET_H +#define CSYSPARAMWIDGET_H + +#include +#include +#include +#include +#include + +#include "CMsgDeal.h" +#include "public/pub_utility_api/FileStyle.h" +#include "net/net_msg_bus_api/MsgBusApi.h" + +namespace Ui { +class CSysParamWidget; +} + +class CSysParamWidget : public QWidget +{ + Q_OBJECT + +public: + explicit CSysParamWidget(QWidget *parent = 0, bool isEditMode = true); + ~CSysParamWidget(); + +public slots: + /** + * @brief InitSet 设置初始化 + * @param password root密码传参,部分Linux设置需要root密码 + * @param manualTag 人工设置的测点 + */ + void InitSet(const QString& password); + + void setNTPSetHosts(const QString& hostNames); + void setTimeSetHosts(const QString& hostNames); + + void setIpSetHost(const QString& hostName); + void setNetWorkName(const QString& networkName); + + void initViewData(); +private slots: + void SelYes_Clicked(const bool& checked); //NTP设置选择是 + void SelNo_Clicked(const bool& checked); //NTP设置选择否 + + void TimeSet_Clicked(); //时间设置 + void TimeQuery_Clicked();//Time查询 + void IPQuery_Clicked();//IP查询 + void IPSet_Clicked(); //IP设置 + + void RevNTPQuery(const QString& ntpIP,bool ntpOn); //初始化查询NTP + void RevTimeQuery(const int64& nDateTime); //初始化查询时间 + void RevIPQuery(const QString& netWorkName, const QString& ip, + const QString& gatway, const QString& mask); //初始化查询IP +private: + bool ntpSet(); + bool timeSet(); + bool ntpQuery(); + bool timeQuery(); + bool ipQuery(); +private: + void InitStyle(); + void showMsg(const QString& msg); + void clearMsg(); +private: + Ui::CSysParamWidget *ui; + bool m_isEditMode; + + CMsgDeal* m_pCMsgDeal; + + QString m_sPassword; + + QString m_sManulSetTag; + + QStringList m_ntpHostNames; + QStringList m_timeHostNames; + QString m_ipHostName; +}; + +#endif // CSYSPARAMWIDGET_H diff --git a/product/src/gui/plugin/SysParamWidget/CSysParamWidget.ui b/product/src/gui/plugin/SysParamWidget/CSysParamWidget.ui new file mode 100644 index 00000000..b292af19 --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/CSysParamWidget.ui @@ -0,0 +1,616 @@ + + + CSysParamWidget + + + + 0 + 0 + 1003 + 614 + + + + CSysParamWidget + + + + + + + 20 + + + 20 + + + 20 + + + 20 + + + 20 + + + + + + 20 + + + 20 + + + 20 + + + 20 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + IP设置 + + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 查询 + + + + + + + 设置 + + + + + + + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + 网卡 + + + + + + + 子网掩码 + + + + + + + IP地址 + + + + + + + false + + + + 300 + 0 + + + + + + + + + + + + + + + 300 + 0 + + + + + + + + + + + + + + + 300 + 0 + + + + + + + + + + + + + + + 300 + 0 + + + + + + + + + + + + + + 网关 + + + + + + + + + + + + + + 20 + + + 20 + + + 20 + + + 20 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 查询 + + + + + + + 设置 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 日期 + + + + + + + + 0 + 0 + 0 + 2023 + 8 + 1 + + + + yyyy-MM-dd + + + + 2023 + 8 + 1 + + + + + + + + 时间 + + + + + + + hh:mm:ss + + + + + + + + + + + + + + + + 时间设置 + + + + + + + Qt::Horizontal + + + + 273 + 20 + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + + + + NTP设置 + + + + + + + Qt::Horizontal + + + + 128 + 28 + + + + + + + + + + + + + + + + + 是否开启NTP + + + + + + + + + + + + + + + + + + + true + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + NTP服务器 + + + + + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + btn_timeSet + clicked() + CSysParamWidget + NTPSet_Clicked() + + + 812 + 59 + + + 303 + 197 + + + + + rbtn_ntp_yes + toggled(bool) + CSysParamWidget + SelYes_Clicked(bool) + + + 159 + 115 + + + 152 + 82 + + + + + rbtn_ntp_no + toggled(bool) + CSysParamWidget + SelNo_Clicked(bool) + + + 203 + 115 + + + 245 + 81 + + + + + + TimeSet_Clicked() + IPSet_Clicked() + LedSet_Clicked() + NTPSet_Clicked() + SelYes_Clicked(bool) + SelNo_Clicked(bool) + Manual_Clicked() + ManualEnable_Clicked(bool) + ManualDisable_Clicked(bool) + + diff --git a/product/src/gui/plugin/SysParamWidget/PreDefine.h b/product/src/gui/plugin/SysParamWidget/PreDefine.h new file mode 100644 index 00000000..1198ca58 --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/PreDefine.h @@ -0,0 +1,144 @@ +#ifndef PREDEFINE_H +#define PREDEFINE_H + +#include +#include +#include +#include "common/DataType.h" +#include "service/operate_server_api/JsonOptCommand.h" + +static const std::string APP_PROCESSNAME = "SysParamWidget"; + +static const std::string CONFING_IS_CREATE_ALARM = "isGenAlarmToOpt"; +static const std::string CONFING_UI_TIMER_TO_SEND_SECONDS = "UiTimerToSendSeconds"; + +#define MT_SYS_PARAMS_TO_HMI_UP 10001 +#define MT_HMI_TO_SYS_PARAMS_DOWN 10002 + +#define MT_OPT_COMMON_DOWN 68 + +enum SysParams_MsgType +{ + enum_Set_IP_Message = 1, //设置IP地址 + enum_Set_IP_Message_Ack = 2, //设置IP 服务端应答结果 + enum_Set_Time_Message = 3, //设置时间 + enum_Set_Time_Message_Ack = 4, //设置时间 应答 + enum_Set_Led_Message = 5, //设置亮度 + enum_Set_Led_Message_Ack = 6,//设置亮度 应答 + enum_Reboot_Message = 7, //重启 + enum_Reboot_Message_Ack = 8,//重启 应答 + enum_Set_NTP_Message = 9, //设置NTP + enum_Set_NTP_Message_Ack = 10,//设置NTP 应答 + enum_Set_Process_Message = 11, //杀死进程 + enum_Set_Process_Message_Ack = 12,//杀死进程 应答 + enum_Query_IP_Message = 51, //查询IP地址 + enum_Query_IP_Message_Ack = 52, //查询IP 服务端应答结果 + enum_Query_Time_Message = 53, //查询时间 + enum_Query_Time_Message_Ack = 54, //查询时间 应答 + enum_Query_Led_Message = 55, //查询亮度 + enum_Query_Led_Message_Ack = 56,//查询亮度 应答 + enum_Query_Online_Message = 57, //查询是否在线 + enum_Query_Online_Message_Ack = 58,//是否在线 应答 + enum_Query_NTP_Message = 59, //查询NTP + enum_Query_NTP_Message_Ack = 60,//查询NTP 应答 +}; + +struct SReqHead +{ + int nMsgType; //!<消息类型 + std::string strSrcTag; //!< 源标签(即发送端进程名) + int nSrcDomainID; //!< 消息发送源域名 + int nDstDomainID; //!< 消息目标域名 + int nAppID; //!< 所属应用ID + std::string strHostName; //!< 发送端主机名 key1 + std::string strInstName; //!< 发送端实例名 key2 + std::string strCommName; //!< 发送端通讯器名 + int nUserID; //!< 发送端用户ID + int nUserGroupID; //!< 发送端用户组ID + int64 nOptTime; //!< 消息发送时间 key3 + std::string strKeyIdTag; + std::string strPassword;//linux权限的密码 + std::string ErroStr; + SReqHead() + { + nMsgType = 0; + strSrcTag = ""; + nSrcDomainID = 0; + nDstDomainID = 0; + nAppID = -1; + strHostName = ""; + strInstName = ""; + strCommName = ""; + nUserID = -1; + nUserGroupID = -1; + nOptTime = 0; + strKeyIdTag = ""; + strPassword= "kbdct@0755"; + } +}; + +//时间设置 +struct STimeSetRequest +{ + SReqHead stHead; + int64 nTime; +}; + +struct SOneIpObj +{ + std::string strNetWorkName; + std::string strIp; + std::string strGatway; + std::string strMask; +}; + +//IP设置 +struct SIpSetRequest +{ + SReqHead stHead; + int NetworkCount; + std::vector NetList; +}; + +//亮度调节 +struct SLedSetRequest +{ + SReqHead stHead; + int64 nLedValue; +}; + +//重启 +struct SRebootSetRequest +{ + SReqHead stHead; + int64 nTime; +}; + +//进程设置 +struct SProcessSetRequest +{ + SReqHead stHead; + std::string strProcessName; +}; + +//人工置数 +struct STOptTagInfo +{ + QString keyIdTag; + int optType; + qint64 optTime; + int locationId; + int subSystem; + double setValue; + int nIsSet; + QString stateText; + QString hostName; + QString userName; + QString userGroup; + + QString tagName; + QString devName; + QString table; +}; + +#endif // PREDEFINE_H diff --git a/product/src/gui/plugin/SysParamWidget/SysParamWidget.pro b/product/src/gui/plugin/SysParamWidget/SysParamWidget.pro new file mode 100644 index 00000000..f8467101 --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/SysParamWidget.pro @@ -0,0 +1,53 @@ +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += plugin + +TARGET = SysParamWidget +TEMPLATE = lib + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.cpp \ + CMsgDeal.cpp \ + CSysParamPluginWidget.cpp \ + main.cpp \ + CSysParamWidget.cpp \ + CRealDataCollect.cpp + +HEADERS += \ + ../../../../../platform/src/include/service/operate_server_api/JsonMessageStruct.h \ + ../../../../../platform/src/include/service/operate_server_api/JsonOptCommand.h \ + CMsgDeal.h \ + CSysParamPluginWidget.h \ + CSysParamWidget.h \ + PreDefine.h \ + CRealDataCollect.h + +FORMS += \ + CSysParamWidget.ui + +LIBS += -lprotobuf \ + -ldb_base_api \ + -ldb_api_ex \ + -lnet_msg_bus_api \ + -lpub_sysinfo_api \ + -lperm_mng_api \ + -llog4cplus \ + -lpub_logger_api \ + -ldp_chg_data_api \ + -lpub_utility_api + + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} diff --git a/product/src/gui/plugin/SysParamWidget/main.cpp b/product/src/gui/plugin/SysParamWidget/main.cpp new file mode 100644 index 00000000..a0ff9e0d --- /dev/null +++ b/product/src/gui/plugin/SysParamWidget/main.cpp @@ -0,0 +1,11 @@ +#include "CSysParamWidget.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + CSysParamWidget w; + w.show(); + return a.exec(); +} diff --git a/product/src/gui/plugin/TrendCurves/CCurveLegendView.cpp b/product/src/gui/plugin/TrendCurves/CCurveLegendView.cpp index 5eb3e195..26799592 100644 --- a/product/src/gui/plugin/TrendCurves/CCurveLegendView.cpp +++ b/product/src/gui/plugin/TrendCurves/CCurveLegendView.cpp @@ -2,6 +2,8 @@ #include "CCurveLegendModel.h" #include #include +#include +#include CCurveLegendView::CCurveLegendView(QWidget *parent) : CTableView(parent) @@ -9,6 +11,43 @@ CCurveLegendView::CCurveLegendView(QWidget *parent) } +void CCurveLegendView::adjustHeaderWidth() +{ + QHeaderView *header = horizontalHeader(); + int sectionCount = header->count(); + if (sectionCount == 0 || !model()) { + return; + } + + QFontMetrics fontMetrics(header->font()); + const int maxWidthThreshold = 200; + const int baseHeight = 30; + int maxHeightMultiplier = 1; + + for (int section = 0; section < sectionCount; ++section) { + QString headerText = model()->headerData(section, Qt::Horizontal).toString(); + if (headerText.isEmpty()) { + continue; + } + + int textWidth = fontMetrics.width(headerText) + 20; // 额外空间 + int heightMultiplier = 1; + + // 调整宽度和计算换行高度 + if (textWidth > maxWidthThreshold) { + header->resizeSection(section, maxWidthThreshold); + heightMultiplier = qCeil(static_cast(textWidth) / maxWidthThreshold); + } else { + header->resizeSection(section, textWidth); + } + + maxHeightMultiplier = qMax(maxHeightMultiplier, heightMultiplier); + } + + header->setFixedHeight(maxHeightMultiplier * baseHeight); +} + + void CCurveLegendView::contextMenuEvent(QContextMenuEvent *event) { CCurveLegendModel * pModel = dynamic_cast(model()); @@ -27,3 +66,9 @@ void CCurveLegendView::contextMenuEvent(QContextMenuEvent *event) return; } +void CCurveLegendView::showEvent(QShowEvent *event) +{ + QTableView::showEvent(event); + adjustHeaderWidth(); +} + diff --git a/product/src/gui/plugin/TrendCurves/CCurveLegendView.h b/product/src/gui/plugin/TrendCurves/CCurveLegendView.h index 455229da..fbda0eec 100644 --- a/product/src/gui/plugin/TrendCurves/CCurveLegendView.h +++ b/product/src/gui/plugin/TrendCurves/CCurveLegendView.h @@ -9,8 +9,11 @@ class CCurveLegendView : public CTableView public: CCurveLegendView(QWidget *parent = Q_NULLPTR); + void adjustHeaderWidth(); + protected: void contextMenuEvent(QContextMenuEvent *event); + void showEvent(QShowEvent *event) override ; }; #endif // CCURVELEGENDVIEW_H diff --git a/product/src/gui/plugin/TrendCurves/CHisDataManage.cpp b/product/src/gui/plugin/TrendCurves/CHisDataManage.cpp index 2bca4f53..705a3e0f 100644 --- a/product/src/gui/plugin/TrendCurves/CHisDataManage.cpp +++ b/product/src/gui/plugin/TrendCurves/CHisDataManage.cpp @@ -1,7 +1,6 @@ #include "CHisDataManage.h" #include "db_his_query_api/DbHisQueryApi.h" #include "sample_server_api/SampleDefine.h" -#include "CTrendInfoManage.h" #include "pub_logger_api/logger.h" using namespace iot_dbms; @@ -10,9 +9,7 @@ int CHisDataManage::m_nProcessNumber = 0; CHisDataManage::CHisDataManage(QObject *parent) : QObject(parent), m_TsdbExcuting(false), - m_bHasPendingCommandCurve(false), - m_bHasPendingCommandEvent(false), - m_bHasPendingCommandCompute(false), + m_bHasPending(false), m_tsdbConnPtr((CTsdbConn*)nullptr) { initTsdbApi(); @@ -28,26 +25,15 @@ CHisDataManage::~CHisDataManage() releaseTsdbApi(); } - foreach (TsdbCommand cmd, m_listCommandCurve) - { - cmd.pVecMpKey->clear(); - delete cmd.pVecMpKey; + foreach (QList cmdList, m_listCommand) { + foreach (TsdbCommand cmd, cmdList) + { + cmd.pVecMpKey->clear(); + delete cmd.pVecMpKey; + } + cmdList.clear(); } - m_listCommandCurve.clear(); - - foreach (TsdbCommand cmd, m_listCommandEvent) - { - cmd.pVecMpKey->clear(); - delete cmd.pVecMpKey; - } - m_listCommandEvent.clear(); - - foreach (TsdbCommand cmd, m_listCommandCompute) - { - cmd.pVecMpKey->clear(); - delete cmd.pVecMpKey; - } - m_listCommandCompute.clear(); + m_listCommand.clear(); } bool CHisDataManage::isTsdbExuting() @@ -56,41 +42,47 @@ bool CHisDataManage::isTsdbExuting() return m_TsdbExcuting; } -void CHisDataManage::postTsdbCommandQueue(E_His_Type type, std::vector *vecMpKey, double lower, double upper, int nGroupBySec, std::vector vecCM) +void CHisDataManage::postTsdbCommandQueue(const QList &cmd) { QMutexLocker locker(&m_mutex); - TsdbCommand cmd; - cmd.type = type; - cmd.pVecMpKey = vecMpKey; - cmd.lower = lower; - cmd.upper = upper; - cmd.nGroupBySec = nGroupBySec; - cmd.vecMethod = vecCM; - switch(type) + m_bHasPending = true; + m_listCommand.push_back(cmd); +} + +void CHisDataManage::queryHistoryRecord(const QList &cmdList) +{ { - case E_ORIGINAL: - case E_POLYMERIC: + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = true; + } + + emit sigHisSearch(true); + foreach (TsdbCommand cmd, cmdList) { + if(E_ORIGINAL == cmd.type) + { + queryHistoryOriginalData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.dataType); + } + else if(E_POLYMERIC == cmd.type) + { + queryHistoryPolymericData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.nGroupBySec, cmd.vecMethod.front(), cmd.dataType); + } + else if(E_EVENTPOINT == cmd.type) + { + queryHistoryEvents(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.vecMethod.front(), cmd.nGroupBySec); + } + else if(E_COMPUTER == cmd.type) + { + queryHistoryComputeData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.vecMethod, cmd.dataType); + } + } + emit sigHisSearch(false); + { - m_bHasPendingCommandCurve = true; - m_listCommandCurve.push_back(cmd); - break; - } - case E_EVENTPOINT: - { - m_bHasPendingCommandEvent = true; - m_listCommandEvent.push_back(cmd); - break; - } - case E_COMPUTER: - { - m_bHasPendingCommandCompute = true; - m_listCommandCompute.push_back(cmd); - break; - } - default: - break; + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = false; } + checkTsdbCommandQueue(); } void CHisDataManage::release() @@ -134,65 +126,41 @@ bool CHisDataManage::getValidTsdbConnPtr(iot_dbms::CTsdbConnPtr &ptr) void CHisDataManage::checkTsdbCommandQueue() { - checkTsdbCommandQueue(m_bHasPendingCommandCurve, m_listCommandCurve); - checkTsdbCommandQueue(m_bHasPendingCommandEvent, m_listCommandEvent); - checkTsdbCommandQueue(m_bHasPendingCommandCompute, m_listCommandCompute); -} - -void CHisDataManage::checkTsdbCommandQueue(bool &bHasPend, QList &listCommand) -{ - if(bHasPend) + if(m_bHasPending) { - bHasPend = false; - TsdbCommand cmd; + m_bHasPending = false; + QList cmdList; { QMutexLocker locker(&m_mutex); - if(!listCommand.isEmpty()) + if(!m_listCommand.isEmpty()) { - cmd = listCommand.takeLast(); + cmdList = m_listCommand.takeLast(); } } - if(E_ORIGINAL == cmd.type) - { - queryHistoryOriginalData(cmd.pVecMpKey, cmd.lower, cmd.upper); - } - else if(E_POLYMERIC == cmd.type) - { - queryHistoryPolymericData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.nGroupBySec, cmd.vecMethod.front()); - } - else if(E_EVENTPOINT == cmd.type) - { - queryHistoryEvents(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.vecMethod.front(), cmd.nGroupBySec); - } - else if(E_COMPUTER == cmd.type) - { - queryHistoryComputeData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.vecMethod); - } + queryHistoryRecord(cmdList); } else { - foreach (TsdbCommand cmd, listCommand) + foreach (QList cmdList, m_listCommand) { - std::vector::iterator it = cmd.pVecMpKey->begin(); - while(it != cmd.pVecMpKey->end()) - { - free( (char*)it->m_pszTagName ); - ++it; + foreach (TsdbCommand cmd, cmdList) { + std::vector::iterator it = cmd.pVecMpKey->begin(); + while(it != cmd.pVecMpKey->end()) + { + free( (char*)it->m_pszTagName ); + ++it; + } + cmd.pVecMpKey->clear(); + delete cmd.pVecMpKey; } - cmd.pVecMpKey->clear(); - delete cmd.pVecMpKey; + cmdList.clear(); } - listCommand.clear(); + m_listCommand.clear(); } } void CHisDataManage::queryHistoryOriginalData(std::vector *vecMpKey, double lower, double upper, E_Data_Type type) { - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = true; - } - double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; std::vector *> *vecResult = new std::vector *>(); @@ -203,13 +171,11 @@ void CHisDataManage::queryHistoryOriginalData(std::vector *vecMpK { vecResult->push_back(new std::vector()); } - emit sigHisSearch(true); if(!getHisSamplePoint(*tsdbConnPtr, 10000, *vecMpKey, lower - nIntervalSecs, upper + nIntervalSecs, NULL, NULL, CM_NULL, 0, FM_NULL_METHOD, *vecResult)) { LOGINFO("TrendCurve CHisDataManage::queryHistoryOriginalData: 查询超时!"); } - emit sigHisSearch(false); } else { @@ -217,21 +183,10 @@ void CHisDataManage::queryHistoryOriginalData(std::vector *vecMpK } emit sigupdateHisOriginalData(vecMpKey, vecResult, type); - - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = false; - } - checkTsdbCommandQueue(); } -void CHisDataManage::queryHistoryPolymericData(std::vector *vecMpKey, double lower, double upper, int nGroupBySec, const EnComputeMethod &enCm) +void CHisDataManage::queryHistoryPolymericData(std::vector *vecMpKey, double lower, double upper, int nGroupBySec, const EnComputeMethod &enCm, E_Data_Type type) { - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = true; - } - double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; std::vector *> *vecResult = new std::vector *>(); @@ -242,35 +197,22 @@ void CHisDataManage::queryHistoryPolymericData(std::vector *vecMp { vecResult->push_back(new std::vector()); } - emit sigHisSearch(true); if(!getHisSamplePoint(*tsdbConnPtr, 10000, *vecMpKey, lower - nIntervalSecs, upper + nIntervalSecs, NULL, NULL, enCm, nGroupBySec * 1000, FM_NULL_METHOD, *vecResult)) { LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 查询超时!"); } - emit sigHisSearch(false); } else { LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 未获取到有效的TSDB连接!"); } - emit sigHistoryPolymericData(vecMpKey, vecResult, nGroupBySec); - - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = false; - } - checkTsdbCommandQueue(); + emit sigHistoryPolymericData(vecMpKey, vecResult, nGroupBySec, type); } -void CHisDataManage::queryHistoryComputeData(std::vector *vecMpKey, double lower, double upper, const std::vector &vecCM) +void CHisDataManage::queryHistoryComputeData(std::vector *vecMpKey, double lower, double upper, const std::vector &vecCM, E_Data_Type type) { - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = true; - } - std::vector *> *> > cmResult; iot_dbms::CTsdbConnPtr tsdbConnPtr; @@ -283,7 +225,6 @@ void CHisDataManage::queryHistoryComputeData(std::vector *vecMpKe { vecResult->push_back(new std::vector()); } - emit sigHisSearch(true); if(!getHisValue(*tsdbConnPtr, 10000, *vecMpKey, lower, upper, NULL, NULL, NULL, NULL, NULL, vecCM[nCmIndex], 0, FM_NULL_METHOD, *vecResult)) { @@ -293,7 +234,6 @@ void CHisDataManage::queryHistoryComputeData(std::vector *vecMpKe tmp.first = vecCM[nCmIndex]; tmp.second = vecResult; cmResult.push_back(tmp); - emit sigHisSearch(false); } } else @@ -301,22 +241,11 @@ void CHisDataManage::queryHistoryComputeData(std::vector *vecMpKe LOGINFO("TrendCurve CHisDataManage::queryHistoryComputeData: 未获取到有效的TSDB连接!"); } - emit sigHistoryComputeData(vecMpKey, cmResult); - - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = false; - } - checkTsdbCommandQueue(); + emit sigHistoryComputeData(vecMpKey, cmResult, type); } void CHisDataManage::queryHistoryEvents(std::vector *vecMpKey, double lower, double upper, const EnComputeMethod &enCM, int nGroupBySec) { - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = true; - } - std::vector *> *vecResult = new std::vector *>(); iot_dbms::CTsdbConnPtr tsdbConnPtr; @@ -326,22 +255,14 @@ void CHisDataManage::queryHistoryEvents(std::vector *vecMpKey, do { vecResult->push_back(new std::vector()); } - emit sigHisSearch(true); if(!getHisEventPoint(*tsdbConnPtr, 10000, *vecMpKey, lower, upper, enCM, nGroupBySec * 1000, *vecResult)) { LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 查询超时!Lower: %f, Upper: %f, GroupByMs: %d", lower, upper, nGroupBySec); } - emit sigHisSearch(false); } else { LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 未获取到有效的TSDB连接!"); } emit sigHistoryEvent(vecMpKey, vecResult); - - { - QMutexLocker locker(&m_mutex); - m_TsdbExcuting = false; - } - checkTsdbCommandQueue(); } diff --git a/product/src/gui/plugin/TrendCurves/CHisDataManage.h b/product/src/gui/plugin/TrendCurves/CHisDataManage.h index 780cbdbc..dce041ac 100644 --- a/product/src/gui/plugin/TrendCurves/CHisDataManage.h +++ b/product/src/gui/plugin/TrendCurves/CHisDataManage.h @@ -10,8 +10,8 @@ enum E_Data_Type { - E_REALTIME, - E_HISTORY + E_HISTORY, + E_PRECURVE, }; enum E_His_Type @@ -41,6 +41,7 @@ struct TsdbCommand vecMethod = std::vector{iot_dbms::CM_NULL}; } E_His_Type type; + E_Data_Type dataType; std::vector * pVecMpKey; double lower; double upper; @@ -64,10 +65,12 @@ signals: void sigHistoryPolymericData(std::vector *vecMpKey, std::vector *> *vecResult, - int nGroupBySec); + int nGroupBySec, + E_Data_Type type = E_HISTORY); void sigHistoryComputeData(std::vector *vecMpKey, - std::vector *> *> > cmResult); + std::vector *> *> > cmResult, + E_Data_Type type = E_HISTORY); void sigHistoryEvent(std::vector *vecMpKey, std::vector *> *vecResult); @@ -77,11 +80,11 @@ signals: public slots: void release(); - void postTsdbCommandQueue(E_His_Type type, std::vector *vecMpKey, - double lower, double upper, - int nGroupBySec = -1, - std::vector vecCM = std::vector{iot_dbms::CM_NULL}); + void postTsdbCommandQueue(const QList &cmd); + void queryHistoryRecord(const QList &cmdList); + +private: void queryHistoryOriginalData(std::vector *vecMpKey, double lower, double upper, E_Data_Type type = E_HISTORY); @@ -89,11 +92,13 @@ public slots: void queryHistoryPolymericData(std::vector *vecMpKey, double lower, double upper, int nGroupBySec, - const iot_dbms::EnComputeMethod &enCm); + const iot_dbms::EnComputeMethod &enCm, + E_Data_Type type = E_HISTORY); void queryHistoryComputeData(std::vector *vecMpKey, double lower, double upper, - const std::vector &vecCM); + const std::vector &vecCM, + E_Data_Type type = E_HISTORY); void queryHistoryEvents(std::vector *vecMpKey, double lower, double upper, @@ -103,18 +108,12 @@ public slots: protected: bool getValidTsdbConnPtr(iot_dbms::CTsdbConnPtr &ptr); void checkTsdbCommandQueue(); - void checkTsdbCommandQueue(bool &bHasPend, QList &listCommand); private: bool m_TsdbExcuting; - bool m_bHasPendingCommandCurve; - bool m_bHasPendingCommandEvent; - bool m_bHasPendingCommandCompute; + bool m_bHasPending; iot_dbms::CTsdbConnPtr m_tsdbConnPtr; - - QList m_listCommandCurve; - QList m_listCommandEvent; - QList m_listCommandCompute; + QList> m_listCommand; QMutex m_mutex; static int m_nProcessNumber; }; diff --git a/product/src/gui/plugin/TrendCurves/CPlotWidget.cpp b/product/src/gui/plugin/TrendCurves/CPlotWidget.cpp index 437724b9..cefb68e5 100644 --- a/product/src/gui/plugin/TrendCurves/CPlotWidget.cpp +++ b/product/src/gui/plugin/TrendCurves/CPlotWidget.cpp @@ -9,8 +9,8 @@ #include "./widgets/CEditCollectWidget.h" #include "./widgets/CSWitchButton.h" #include "./widgets/CToolTip.h" -#include "CMyCheckBox.h" -#include "CMyListWidget.h" +#include "./widgets/CMyCheckBox.h" +#include "./widgets/CMyListWidget.h" #include "model_excel/xlsx/xlsxdocument.h" using namespace iot_dbms; @@ -21,6 +21,7 @@ CPlotWidget::CPlotWidget(QWidget *parent) : m_type(E_Trend_Invalid), m_showType(E_Show_Curve), m_bHisAdaption(false), + m_bShowPreCurve(false), m_TrendTypeButton(Q_NULLPTR), m_pLengedModel(Q_NULLPTR), m_pTableDataModel(Q_NULLPTR), @@ -39,7 +40,9 @@ CPlotWidget::CPlotWidget(QWidget *parent) : m_isSetSliderValue(false), m_isTooltip(true), m_isAdaptShow(true), - m_isAlarmShow(true) + m_isAlarmShow(true), + m_isPreCurveShow(true), + m_bEnableNan(true) { ui->setupUi(this); setContentsMargins(1, 1, 1, 1); @@ -51,6 +54,7 @@ CPlotWidget::CPlotWidget(QWidget *parent) : qRegisterMetaType< std::vector *> >("std::vector *>"); qRegisterMetaType< std::vector *> *> > >( "std::vector *> *> >"); + qRegisterMetaType< QList >("QList"); } CPlotWidget::~CPlotWidget() @@ -161,6 +165,7 @@ void CPlotWidget::initialize() ui->interval->addItem(tr("一小时"), 60*60); ui->interval->addItem(tr("八小时"), 8*60*60); ui->interval->addItem(tr("一天"), 24*60*60); + ui->interval->addItem(tr("全部"), 0); connect(ui->interval, &QComboBox::currentTextChanged, this, &CPlotWidget::slotIntervalChanged); connect(ui->customSearch, &QPushButton::clicked, this, &CPlotWidget::slotCustomSearch); connect(ui->startData, &QDateTimeEdit::dateTimeChanged, this, &CPlotWidget::slotStartDateChanged); @@ -208,10 +213,13 @@ void CPlotWidget::initialize() ui->m_dataView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); ui->m_dataView->setSelectionBehavior(QAbstractItemView::SelectRows); // ui->m_dataView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); -// ui->m_dataView->horizontalHeader()->setMinimumSectionSize(200); - ui->m_dataView->horizontalHeader()->setDefaultSectionSize(200); +// ui->m_dataView->horizontalHeader()->setDefaultSectionSize(200); + ui->m_dataView->setHorizontalHeader(new CustomHeaderView(Qt::Horizontal,ui->m_dataView)); + ui->m_dataView->horizontalHeader()->setMinimumSectionSize(200); connect(ui->m_dataView, SIGNAL(clicked(QModelIndex)), this, SLOT(tableSelectionChanged(QModelIndex))); + + connect(ui->m_dataView->horizontalHeader(),&QHeaderView::sectionCountChanged,ui->m_dataView,&CTableView::adjustHeaderWidth); //< initTableView m_pLengedModel = new CCurveLegendModel(ui->lengedView); ui->lengedView->setModel(m_pLengedModel); @@ -225,6 +233,9 @@ void CPlotWidget::initialize() ui->lengedView->setSelectionMode(QAbstractItemView::SingleSelection); ui->lengedView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ui->lengedView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + ui->lengedView->setHorizontalHeader(new CustomHeaderView(Qt::Horizontal,ui->lengedView)); + connect(ui->lengedView->horizontalHeader(),&QHeaderView::sectionCountChanged,ui->lengedView,&CCurveLegendView::adjustHeaderWidth); + connect(m_pLengedModel, &CCurveLegendModel::graphVisibleChanged, this, &CPlotWidget::graphVisibleChanged); connect(m_pLengedModel, &CCurveLegendModel::graphPropertyChanged, this, &CPlotWidget::graphPropertyChanged); @@ -237,10 +248,11 @@ void CPlotWidget::initialize() ui->clear->setEnabled(false); ui->collectCurve->setVisible(false); ui->switchBtn->setToggle(false); - ui->switchBtn->setText(tr("曲线")); - ui->switchBtn->setCheckedText(tr("表格")); + ui->switchBtn->setText(tr("表格")); + ui->switchBtn->setCheckedText(tr("曲线")); ui->m_dataView->setVisible(false); connect(ui->adapt, &QCheckBox::toggled, this, &CPlotWidget::updateAdaptState); + connect(ui->preCurve, &QCheckBox::toggled, this, &CPlotWidget::updatePreCurveState); connect(ui->collectCurve, &QPushButton::clicked, this, &CPlotWidget::addCollect); connect(ui->plotPrint, &QPushButton::clicked, this, &CPlotWidget::slotPrint); connect(ui->plotExport, &QPushButton::clicked, this, &CPlotWidget::slotExport); @@ -264,13 +276,10 @@ void CPlotWidget::initialize() m_pHisDataManage->moveToThread(m_pHisDataThread); connect(m_pHisDataThread, &QThread::finished, m_pHisDataThread, &QObject::deleteLater); connect(this, &CPlotWidget::releaseHisDataThread, m_pHisDataManage, &CHisDataManage::release, Qt::BlockingQueuedConnection); - connect(this, &CPlotWidget::sigQueryHistoryOriginalData, m_pHisDataManage, &CHisDataManage::queryHistoryOriginalData, Qt::QueuedConnection); - connect(this, &CPlotWidget::sigQueryHistoryPolymericData, m_pHisDataManage, &CHisDataManage::queryHistoryPolymericData, Qt::QueuedConnection); - connect(this, &CPlotWidget::sigQueryHistoryComputeData, m_pHisDataManage, &CHisDataManage::queryHistoryComputeData, Qt::QueuedConnection); + connect(this, &CPlotWidget::sigQueryHistoryRecord, m_pHisDataManage, &CHisDataManage::queryHistoryRecord, Qt::QueuedConnection); connect(m_pHisDataManage, &CHisDataManage::sigupdateHisOriginalData, this, &CPlotWidget::updateHisOriginalData, Qt::QueuedConnection); connect(m_pHisDataManage, &CHisDataManage::sigHistoryPolymericData, this, &CPlotWidget::updateHisPolymericData, Qt::QueuedConnection); connect(m_pHisDataManage, &CHisDataManage::sigHistoryComputeData, this, &CPlotWidget::updateHisComputeData, Qt::QueuedConnection); - connect(this, &CPlotWidget::sigQueryHistoryEvent, m_pHisDataManage, &CHisDataManage::queryHistoryEvents, Qt::QueuedConnection); connect(m_pHisDataManage, &CHisDataManage::sigHistoryEvent, this, &CPlotWidget::updatePhaseTracer, Qt::QueuedConnection); connect(m_pHisDataManage, &CHisDataManage::sigHisSearch, this, &CPlotWidget::slotEnableSearch, Qt::QueuedConnection); m_pHisDataThread->start(); @@ -366,7 +375,6 @@ void CPlotWidget::updateLengedColumnWidth() ui->lengedView->setColumnWidth(CCurveLegendModel::MIN, nLengedWidth / 12.); ui->lengedView->setColumnWidth(CCurveLegendModel::MINTIME, nLengedWidth / 12. * 1.5); ui->lengedView->setColumnWidth(CCurveLegendModel::AVE, nLengedWidth / 12.); - //单位目前未查询处理为空,屏蔽显示 ui->lengedView->setColumnWidth(CCurveLegendModel::UNIT, nLengedWidth / 12. * 1.5); // ui->lengedView->setColumnWidth(CCurveLegendModel::FACTOR, nLengedWidth / 12.); // ui->lengedView->setColumnWidth(CCurveLegendModel::OFFSET, nLengedWidth / 12.); @@ -513,6 +521,12 @@ void CPlotWidget::insertTag(const QString &tag, const bool &resetTitle) { setTitle(tr("趋势图")); } + + //如果是动态加载设备的话,需要在此尝试加载一下本设备数据,如果已经加载会跳过 + QStringList devList; + devList << tag.left(tag.lastIndexOf(".")); + CTrendInfoManage::instance()->loadTagInfoByDevTag(devList); + Curve curve; curve.tag = tag; QList list = m_pTrendGraph->curveColors(); @@ -553,14 +567,14 @@ void CPlotWidget::removeTag(const QString &tag, const bool &resetTitle) } m_isSetSliderValue = false; setAllLengedShow(); - int nIndex = m_pTrendGraph->removeCurve(tag); - if(nIndex != -1) + QList removeList = m_pTrendGraph->removeCurve(tag); + for(int nIndex = 0; nIndex < removeList.length(); ++nIndex) { if(m_showType == E_Show_Table) { m_pTableDataModel->removeCurveData(ui->plot->graph(nIndex)->desc()); } - ui->plot->removeGraph(nIndex); + ui->plot->removeGraph(removeList[nIndex]); } m_pLengedModel->setTrendGraph(m_pTrendGraph); @@ -586,6 +600,7 @@ void CPlotWidget::removeTag(const QString &tag, const bool &resetTitle) groupQueryHistoryEvent(); } } + m_isSetSliderValue = true; rescaleYAxisRange(); ui->plot->replot(); } @@ -656,19 +671,26 @@ void CPlotWidget::setClearVisible(bool visible) void CPlotWidget::setAdaptVisible(bool visible) { - m_isAdaptShow = false; + m_isAdaptShow = visible; ui->adapt->setVisible(visible); } void CPlotWidget::setAlarmPointVisible(bool visible) { - m_isAlarmShow = false; + m_isAlarmShow = visible; ui->checkBox_alarmPoint->setVisible(visible); ui->comboBox_alarmStatus->setVisible(visible); } +void CPlotWidget::setPreCurveVisible(bool visible) +{ + m_isPreCurveShow = visible; + + ui->preCurve->setVisible(visible); +} + void CPlotWidget::insertCurve(Curve curve) { m_isSetSliderValue = true; @@ -716,6 +738,7 @@ void CPlotWidget::insertCurve(Curve curve) QCPGraph * graph = ui->plot->addGraph(); graph->setName(curve.tag); graph->setDesc(curve.desc); + graph->setType(curve.curveType); QPen pen; pen.setWidth(1); pen.setColor(curve.color); @@ -733,19 +756,34 @@ void CPlotWidget::insertCurve(Curve curve) graph->setLineStyle(QCPGraph::lsStepLeft); } - //< 查询最新十分钟数据 -// double upper = QDateTime::currentMSecsSinceEpoch(); -// double lower = upper - (10 * 60 * 1000); -// SMeasPointKey key; -// std::string tmp = curve.tag.toStdString(); -// char * tag = (char*)malloc(tmp.size() + 1); -// memset(tag, 0, tmp.size() + 1); -// memcpy(tag, tmp.c_str(), tmp.size()); -// key.m_pszTagName = tag; -// key.m_enType = getMeasType(curve.type); -// std::vector * vecMpKey = new std::vector(); -// vecMpKey->push_back(key); -// emit sigQueryHistoryOriginalData(vecMpKey, lower, upper, E_REALTIME); + if(m_bShowPreCurve) + { + Curve preCurve; + preCurve.visible = curve.visible; + preCurve.tag = curve.tag; + preCurve.desc = tr("昨日曲线-") + curve.desc; + preCurve.type = curve.type; + preCurve.unit = curve.unit; + preCurve.color = curve.color.darker(200); + preCurve.curveType = enPrevCurve; + m_pTrendGraph->addCurve(preCurve); + QCPGraph * graph = ui->plot->addGraph(); + graph->setName(preCurve.tag); + graph->setDesc(preCurve.desc); + graph->setType(preCurve.curveType); + QPen pen; + pen.setWidth(1); + pen.setColor(preCurve.color.darker(200)); + graph->setPen(pen); + updateCurveSelectionColor(graph); + connect(graph, SIGNAL(selectionChanged(bool)), this, SLOT(graphSelectionChanged(bool)), Qt::QueuedConnection); + //< 方波 + QString type = CTrendInfoManage::instance()->getTagType(preCurve.tag); + if(type == "digital" || type == "mix") + { + graph->setLineStyle(QCPGraph::lsStepLeft); + } + } updateCurves(); @@ -892,6 +930,21 @@ void CPlotWidget::setPlotTickPen(const QColor &color) ui->plot->yAxis2->setSubTickPen(color); } +void CPlotWidget::clearCustomInterval() +{ + ui->interval->clear(); +} + +void CPlotWidget::addCustomInterval(const QString &desc, const int &sec) +{ + if(desc.isEmpty() || sec <=0) + { + return; + } + + ui->interval->addItem(desc,sec); +} + void CPlotWidget::realTimeElapsed() { //< 刷新X轴 @@ -904,7 +957,7 @@ void CPlotWidget::realTimeElapsed() for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) { QCPGraph * graph = ui->plot->graph(nIndex); - m_pTrendGraph->updateRTCurveStatisticsInfo(graph->name()); + m_pTrendGraph->updateRTCurveStatisticsInfo(graph->name(), graph->type()); QVector * pCPGraphData = graph->data()->data(); if(pCPGraphData->isEmpty()) @@ -975,7 +1028,12 @@ void CPlotWidget::updateRealTimeTableData() { continue; } - const QVector< QPair > > &values = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()).values; + if(ui->plot->graph(nIndex)->type() == enPrevCurve) + { + continue; + } + const QVector< QPair > > &values = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name(), + ui->plot->graph(nIndex)->type()).values; QVector vecGraphData; double preValue = DBL_MAX; QVector< QPair > >::const_iterator iter = values.constBegin(); @@ -996,9 +1054,6 @@ void CPlotWidget::updateRealTimeTableData() headerList.append(ui->plot->graph(nIndex)->desc()); } resetCurveData(curveData, headerList, false); - - - graphVisibleChanged(true); } void CPlotWidget::plotAxisRangeChanged(const QCPRange &newRange, const QCPRange &oldRange) @@ -1161,10 +1216,7 @@ void CPlotWidget::plotAxisRangeChanged(const QCPRange &newRange, const QCPRange void CPlotWidget::updateTrendShowMode(int nIndex, bool updateXAxisRange) { m_type = (E_Trend_Type)nIndex; - m_isSetSliderValue = true; - updateGraphTitle(nIndex); - if(Q_NULLPTR != m_pTimer && m_pTimer->isActive()) { m_pTimer->stop(); @@ -1183,57 +1235,25 @@ void CPlotWidget::updateTrendShowMode(int nIndex, bool updateXAxisRange) ui->plot->axisRect()->setRangeZoom(Qt::Horizontal); //< 水平缩放 ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); ui->plot->xAxis->setScaleType(QCPAxis::stLinear); - + updateGraphTitle(nIndex); + updateAxisFormat(updateXAxisRange); + //< clear view int count = ui->plot->graphCount(); for(int n(0); nplot->graph(n); graph->data()->clear(); } - ui->plot->clearItems(); m_listTracer.clear(); + m_pTableDataModel->clear(); + afterModeSwitch(); - updateAxisFormat(updateXAxisRange); - - if (m_type == E_Trend_RealTime || m_type == E_Trend_Invalid) + if (m_type == E_Trend_His_Custom) { - ui->dataWidget->setVisible(false); - ui->customWidget->setVisible(false); - ui->adapt->setVisible(false); - ui->checkBox_alarmPoint->setVisible(false); - ui->comboBox_alarmStatus->setVisible(false); - } - else if (m_type == E_Trend_His_Custom) - { - ui->customWidget->setVisible(true); - ui->dataWidget->setVisible(false); slotCustomSearch(); } - else - { - ui->dataWidget->setVisible(true); - ui->customWidget->setVisible(false); - if(m_isAdaptShow) - { - ui->adapt->setVisible(true); - } - if(m_isAlarmShow) - { - ui->checkBox_alarmPoint->setVisible(true); - ui->comboBox_alarmStatus->setVisible(true); - } - ui->date->setDateTime(QDateTime::currentDateTime()); - } - if(m_showType == E_Show_Table) - { - ui->adapt->setVisible(false); - ui->checkBox_alarmPoint->setVisible(false); - ui->comboBox_alarmStatus->setVisible(false); - m_pTableDataModel->clear(); - } - - // if(m_type == E_Trend_RealTime) + else if (m_type == E_Trend_RealTime) { if(E_Show_Table == m_showType) { @@ -1241,19 +1261,22 @@ void CPlotWidget::updateTrendShowMode(int nIndex, bool updateXAxisRange) } updateCurves(); } + else + { + ui->date->setDateTime(QDateTime::currentDateTime()); + } } -void CPlotWidget::updateComputeValue(double lower, double upper, std::vector vecMethod) +TsdbCommand CPlotWidget::getHisCurveCmd(double lower, double upper, int nGroupBy, E_Data_Type type) { - if(!ui->plot->graphCount()) - { - return; - } - std::vector * vecMpKey = new std::vector(); for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) { - const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()); + if(ui->plot->graph(nIndex)->type() != type) + { + continue; + } + const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name(), ui->plot->graph(nIndex)->type()); SMeasPointKey key; std::string tmp = curve.tag.toStdString(); char * tag = (char*)malloc(tmp.size() + 1); @@ -1264,14 +1287,53 @@ void CPlotWidget::updateComputeValue(double lower, double upper, std::vectorpush_back(key); } - if(!m_pHisDataManage->isTsdbExuting()) + TsdbCommand cmd; + if(E_Trend_His_Hour == m_type || E_Trend_His_Minute == m_type || nGroupBy <= 0) { - emit sigQueryHistoryComputeData(vecMpKey, lower, upper, vecMethod); + cmd.type = E_ORIGINAL; } else { - m_pHisDataManage->postTsdbCommandQueue(E_COMPUTER, vecMpKey, lower, upper, -1, vecMethod); + cmd.type = E_POLYMERIC; } + cmd.dataType = type; + cmd.pVecMpKey = vecMpKey; + cmd.lower = lower; + cmd.upper = upper; + cmd.nGroupBySec = nGroupBy; + cmd.vecMethod = std::vector{iot_dbms::CM_FIRST}; + return cmd; +} + +TsdbCommand CPlotWidget::getComputeCmd(double lower, double upper, std::vector vecMethod, E_Data_Type type) +{ + std::vector * vecMpKey = new std::vector(); + for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) + { + if(ui->plot->graph(nIndex)->type() != type) + { + continue; + } + const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name(), ui->plot->graph(nIndex)->type()); + SMeasPointKey key; + std::string tmp = curve.tag.toStdString(); + char * tag = (char*)malloc(tmp.size() + 1); + memset(tag, 0, tmp.size() + 1); + memcpy(tag, tmp.c_str(), tmp.size()); + key.m_pszTagName = tag; + key.m_enType = getMeasType(curve.type); + vecMpKey->push_back(key); + } + + TsdbCommand cmd; + cmd.type = E_COMPUTER; + cmd.dataType = type; + cmd.pVecMpKey = vecMpKey; + cmd.lower = lower; + cmd.upper = upper; + cmd.nGroupBySec = -1; + cmd.vecMethod = vecMethod; + return cmd; } void CPlotWidget::updateGraphTitle(int nIndex) @@ -1322,7 +1384,7 @@ void CPlotWidget::updateCurves() } else { - updateHistoryCurveRecord(ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper); + updateHistoryCurveRecord(); } } @@ -1339,7 +1401,7 @@ void CPlotWidget::updateRealTimeCurveRecord() //< 清空数据 QSharedPointer container(new QCPGraphDataContainer()); - const QVector< QPair > > &values = m_pTrendGraph->curve(graph->name()).values; + const QVector< QPair > > &values = m_pTrendGraph->curve(graph->name(), graph->type()).values; QVector< QPair > >::const_iterator it = values.constBegin(); double preValue = DBL_MAX; while (it != values.constEnd()) @@ -1369,7 +1431,7 @@ void CPlotWidget::updateRealTimeCurveRecord() ui->plot->replot(); } -void CPlotWidget::updateHistoryCurveRecord(double lower, double upper) +void CPlotWidget::updateHistoryCurveRecord() { if(!ui->plot->graphCount()) { @@ -1381,46 +1443,32 @@ void CPlotWidget::updateHistoryCurveRecord(double lower, double upper) return; } - std::vector * vecMpKey = new std::vector(); - for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) - { - const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()); - SMeasPointKey key; - std::string tmp = curve.tag.toStdString(); - char * tag = (char*)malloc(tmp.size() + 1); - memset(tag, 0, tmp.size() + 1); - memcpy(tag, tmp.c_str(), tmp.size()); - key.m_pszTagName = tag; - key.m_enType = getMeasType(curve.type); - vecMpKey->push_back(key); + QPair range = getFatureDataTime(m_type, ui->date->dateTime()); + std::vector vecMethod{iot_dbms::CM_MAX, iot_dbms::CM_MIN}; + + QList cmdList; + TsdbCommand curve = getHisCurveCmd(ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, currentGroupByMinute() * 60, E_HISTORY); + TsdbCommand computer = getComputeCmd(range.first, range.second, vecMethod, E_HISTORY); + cmdList.push_back(curve); + cmdList.push_back(computer); + + if(m_bShowPreCurve){ + QPair preCurveRange = getOffsetRange(ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, -1); + QPair preComputeRange = getOffsetRange(range.first, range.second, -1); + TsdbCommand preCurve = getHisCurveCmd(preCurveRange.first, preCurveRange.second, currentGroupByMinute() * 60, E_PRECURVE); + TsdbCommand perComputer = getComputeCmd(preComputeRange.first, preComputeRange.second, vecMethod, E_PRECURVE); + cmdList.push_back(preCurve); + cmdList.push_back(perComputer); } if(!m_pHisDataManage->isTsdbExuting()) { - if(E_Trend_His_Hour == m_type || E_Trend_His_Minute == m_type) - { - emit sigQueryHistoryOriginalData(vecMpKey, lower, upper); - } - else - { - emit sigQueryHistoryPolymericData(vecMpKey, lower, upper, currentGroupByMinute() * 60, iot_dbms::CM_FIRST); - } + emit sigQueryHistoryRecord(cmdList); } else { - if(E_Trend_His_Hour == m_type || E_Trend_His_Minute == m_type) - { - m_pHisDataManage->postTsdbCommandQueue(E_ORIGINAL, vecMpKey, lower, upper); - } - else - { - m_pHisDataManage->postTsdbCommandQueue(E_POLYMERIC, vecMpKey, lower, upper, currentGroupByMinute() * 60, std::vector{iot_dbms::CM_FIRST}); - } + m_pHisDataManage->postTsdbCommandQueue(cmdList); } - - QPair range = getFatureDataTime(m_type, ui->date->dateTime()); - std::vector vecMethod{iot_dbms::CM_MAX, iot_dbms::CM_MIN}; - updateComputeValue(range.first, range.second, vecMethod); } void CPlotWidget::updateHisOriginalData(std::vector *vecMpKey, std::vector *> *vecResult, E_Data_Type type) @@ -1434,37 +1482,21 @@ void CPlotWidget::updateHisOriginalData(std::vector *vecMpKey, st if(m_showType == E_Show_Table) { isAddVirtualPoint = false; - if(m_type == E_Trend_His_Custom) - { - lower = ui->startData->dateTime().toMSecsSinceEpoch(); - upper = ui->endData->dateTime().toMSecsSinceEpoch(); - } } - updateHisData(vecMpKey, vecResult, vecRange, vecContainer, lower, upper, isAddVirtualPoint); + if(m_type == E_Trend_His_Custom) + { + lower = ui->startData->dateTime().toMSecsSinceEpoch(); + upper = ui->endData->dateTime().toMSecsSinceEpoch(); + } + updateHisData(vecMpKey, vecResult, vecRange, vecContainer, lower, upper, type, isAddVirtualPoint); - if(E_REALTIME == type) + if(m_showType == E_Show_Curve) { - for(size_t nIndex(0); nIndex < vecContainer.size(); ++nIndex) - { - QCPGraphDataContainer::iterator it = vecContainer.at(nIndex)->begin(); - while(it != vecContainer.at(nIndex)->end()) - { - m_pTrendGraph->pushCurveRTDataValue(vecMpKey->at(nIndex).m_pszTagName, it->key, it->value, it->status); - ++it; - } - } - updateCurves(); + updateHistoryGraph(vecMpKey, vecContainer, vecRange, type); } - else if(E_HISTORY == type) + else if(m_showType == E_Show_Table) { - if(m_showType == E_Show_Curve) - { - updateHistoryGraph(vecMpKey, vecContainer, vecRange); - } - else if(m_showType == E_Show_Table) - { - updateHistoryData(vecMpKey, vecContainer, vecRange); - } + updateHistoryData(vecMpKey, vecContainer, vecRange, type); } m_pLengedModel->update(); @@ -1490,7 +1522,7 @@ void CPlotWidget::updateHisOriginalData(std::vector *vecMpKey, st delete vecMpKey; } -void CPlotWidget::updateHisPolymericData(std::vector *vecMpKey, std::vector *> *vecResult, int nGroupBySec) +void CPlotWidget::updateHisPolymericData(std::vector *vecMpKey, std::vector *> *vecResult, int nGroupBySec, E_Data_Type type) { std::vector< QSharedPointer > vecRange; std::vector< QSharedPointer > vecContainer; @@ -1499,25 +1531,33 @@ void CPlotWidget::updateHisPolymericData(std::vector *vecMpKey, s { if(m_showType == E_Show_Curve) { - updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->plot->xAxis->range().lower, - ui->plot->xAxis->range().upper, true, nGroupBySec); + if(m_type == E_Trend_His_Custom) + { + updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->startData->dateTime().toMSecsSinceEpoch(), + ui->endData->dateTime().toMSecsSinceEpoch(), type, true, nGroupBySec); + } + else + { + updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->plot->xAxis->range().lower, + ui->plot->xAxis->range().upper, type, true, nGroupBySec); + } - updateHistoryGraph(vecMpKey, vecContainer, vecRange); + updateHistoryGraph(vecMpKey, vecContainer, vecRange, type); } else if(m_showType == E_Show_Table) { if(m_type == E_Trend_His_Custom) { updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->startData->dateTime().toMSecsSinceEpoch(), - ui->endData->dateTime().toMSecsSinceEpoch(), false, nGroupBySec); + ui->endData->dateTime().toMSecsSinceEpoch(), type, false, nGroupBySec); } else { updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->plot->xAxis->range().lower, - ui->plot->xAxis->range().upper, false, nGroupBySec); + ui->plot->xAxis->range().upper, type, false, nGroupBySec); } - updateHistoryData(vecMpKey, vecContainer, vecRange); + updateHistoryData(vecMpKey, vecContainer, vecRange, type); } } m_pLengedModel->update(); @@ -1543,7 +1583,7 @@ void CPlotWidget::updateHisPolymericData(std::vector *vecMpKey, s delete vecMpKey; } -void CPlotWidget::updateHisComputeData(std::vector *vecMpKey, std::vector *> *> > cmResult) +void CPlotWidget::updateHisComputeData(std::vector *vecMpKey, std::vector *> *> > cmResult, E_Data_Type type) { typename std::vector *> *> >::const_iterator resultIter = cmResult.begin(); while(resultIter != cmResult.end()) @@ -1553,22 +1593,17 @@ void CPlotWidget::updateHisComputeData(std::vector *vecMpKey, std while(it != resultIter->second->end()) { int nIndex = it - resultIter->second->begin(); - if(nIndex > ui->plot->graphCount()-1) + int nGraphIndex = m_pTrendGraph->index(vecMpKey->at(nIndex).m_pszTagName, type); + if(nGraphIndex == -1) { - ++it; - continue; - } - QCPGraph * graph = ui->plot->graph(nIndex); - if(graph->name() != QString(vecMpKey->at(nIndex).m_pszTagName)) - { - ++it; continue; } + QCPGraph * graph = ui->plot->graph(nGraphIndex); std::vector * vecPoint = *it; if(vecPoint->empty()) { ++it; - setCurveStatisData(graph->name(), method, true); + setCurveStatisData(graph->name(), graph->type(), method, true); continue; } @@ -1588,10 +1623,10 @@ void CPlotWidget::updateHisComputeData(std::vector *vecMpKey, std if(std::isnan(value)) { ++pt; - setCurveStatisData(graph->name(), method, true); + setCurveStatisData(graph->name(), graph->type(), method, true); continue; } - setCurveStatisData(graph->name(), method, false, value, pt->m_nTime); + setCurveStatisData(graph->name(), graph->type(), method, false, value, pt->m_nTime); ++pt; } ++it; @@ -1620,7 +1655,7 @@ void CPlotWidget::updateHisComputeData(std::vector *vecMpKey, std delete vecMpKey; } -void CPlotWidget::updateHistoryGraph(std::vector *vecMpKey, std::vector > &vecContainer, std::vector > &vecRange) +void CPlotWidget::updateHistoryGraph(std::vector *vecMpKey, std::vector > &vecContainer, std::vector > &vecRange, E_Data_Type type) { double lower = ui->plot->xAxis->range().lower; double upper = ui->plot->xAxis->range().upper; @@ -1638,18 +1673,13 @@ void CPlotWidget::updateHistoryGraph(std::vector *vecMpKey, std:: for(int nIndex(0); nIndex < (int)vecContainer.size(); ++nIndex) { - if(nIndex > ui->plot->graphCount()-1) + int nGraphIndex = m_pTrendGraph->index(vecMpKey->at(nIndex).m_pszTagName, type); + if(nGraphIndex == -1) { continue; } - QCPGraph * graph = ui->plot->graph(nIndex); - { - if(graph->name() != QString(vecMpKey->at(nIndex).m_pszTagName)) - { - continue; - } - } - updateCurveHisData(lower, upper, graph, nIndex, vecContainer.at(nIndex), vecRange.at(nIndex)); + QCPGraph * graph = ui->plot->graph(nGraphIndex); + updateCurveHisData(lower, upper, graph, nGraphIndex, vecContainer.at(nIndex), vecRange.at(nIndex), type); graph->data()->clear(); graph->setData(vecContainer.at(nIndex)); } @@ -1659,7 +1689,7 @@ void CPlotWidget::updateHistoryGraph(std::vector *vecMpKey, std:: ui->plot->replot(); } -void CPlotWidget::updateHistoryData(std::vector *vecMpKey, std::vector > &vecContainer, std::vector > &vecRange) +void CPlotWidget::updateHistoryData(std::vector *vecMpKey, std::vector > &vecContainer, std::vector > &vecRange, E_Data_Type type) { double lower,upper; if(m_type == E_Trend_His_Custom) @@ -1677,22 +1707,13 @@ void CPlotWidget::updateHistoryData(std::vector *vecMpKey, std::v QStringList headerList; for(int nIndex(0); nIndex < (int)vecContainer.size(); ++nIndex) { - if(nIndex > ui->plot->graphCount()-1) + int nGraphIndex = m_pTrendGraph->index(vecMpKey->at(nIndex).m_pszTagName, type); + if(nGraphIndex == -1) { continue; } - QCPGraph * graph = ui->plot->graph(nIndex); - { - if(graph->name() == "curve.tag") - { - continue; - } - if(graph->name() != QString(vecMpKey->at(nIndex).m_pszTagName)) - { - continue; - } - } - updateCurveHisData(lower, upper, graph, nIndex, vecContainer.at(nIndex), vecRange.at(nIndex)); + QCPGraph * graph = ui->plot->graph(nGraphIndex); + updateCurveHisData(lower, upper, graph, nGraphIndex, vecContainer.at(nIndex), vecRange.at(nIndex), type); QVector vecGraphData; QCPGraphDataContainer::const_iterator iter = vecContainer.at(nIndex)->constBegin(); @@ -1712,14 +1733,14 @@ void CPlotWidget::updateHistoryData(std::vector *vecMpKey, std::v enableSearch(true); } -void CPlotWidget::updateCurveHisData(double lower, double upper, QCPGraph *graph, int index, QSharedPointer container, QSharedPointer range) +void CPlotWidget::updateCurveHisData(double lower, double upper, QCPGraph *graph, int index, QSharedPointer container, QSharedPointer range, E_Data_Type type) { int count = 0; //< accuml size double offset = 0.; double factor = 1.; double accuml = 0.; - const Curve &curve = m_pTrendGraph->curve(graph->name()); + const Curve &curve = m_pTrendGraph->curve(graph->name(), type); if(m_bHisAdaption && m_type != E_Trend_RealTime) { double maxVal = range->max; @@ -1792,7 +1813,7 @@ void CPlotWidget::updateCurveHisData(double lower, double upper, QCPGraph *graph average = accuml / count; } } - m_pTrendGraph->setCurveHisDataValue(graph->name(), max, min, maxTime, minTime, average, accuml, *range); + m_pTrendGraph->setCurveHisDataValue(graph->name(), type, max, min, maxTime, minTime, average, accuml, *range); } void CPlotWidget::updatePhaseTracer(std::vector *vecMpKey, std::vector *> *vecResult) @@ -1819,7 +1840,6 @@ void CPlotWidget::updatePhaseTracer(std::vector *vecMpK } } QPointF prePt(-1000., -1000.); - //< 1min 显示所有事件 bool bMinRange = ui->plot->xAxis->range().size() > 60; QMultiMap< double, QStringList >::iterator rIter = map.begin(); @@ -2181,6 +2201,63 @@ void CPlotWidget::updateAdaptState(bool isAdapt) updateYAxisTicker(); } +void CPlotWidget::updatePreCurveState(bool isPreCurve) +{ + m_bShowPreCurve = isPreCurve; + if(m_bShowPreCurve) + { + const QList curves = m_pTrendGraph->curves(); + for(int n = 0; n < curves.length(); ++n) + { + if(curves[n].tag == "curve.tag") + { + continue; + } + Curve preCurve; + preCurve.tag = curves[n].tag; + preCurve.desc = tr("昨日曲线-") + curves[n].desc; + preCurve.type = curves[n].type; + preCurve.unit = curves[n].unit; + preCurve.color = curves[n].color.darker(200); + preCurve.curveType = enPrevCurve; + m_pTrendGraph->addCurve(preCurve); + QCPGraph * graph = ui->plot->addGraph(); + graph->setName(preCurve.tag); + graph->setDesc(preCurve.desc); + graph->setType(preCurve.curveType); + QPen pen; + pen.setWidth(1); + pen.setColor(preCurve.color.darker(200)); + graph->setPen(pen); + updateCurveSelectionColor(graph); + connect(graph, SIGNAL(selectionChanged(bool)), this, SLOT(graphSelectionChanged(bool)), Qt::QueuedConnection); + //< 方波 + QString type = CTrendInfoManage::instance()->getTagType(preCurve.tag); + if(type == "digital" || type == "mix") + { + graph->setLineStyle(QCPGraph::lsStepLeft); + } + } + updateCurves(); + } + else + { + const QList curves = m_pTrendGraph->curves(); + for(int n = curves.length() - 1; n >= 0; --n) + { + if(curves[n].curveType != enPrevCurve) + { + continue; + } + m_pTrendGraph->removeCurve(n); + ui->plot->removeGraph(n); + } + rescaleYAxisRange(); + ui->plot->replot(); + } + m_pLengedModel->setTrendGraph(m_pTrendGraph); +} + void CPlotWidget::slotCollectGraph(const QString &text) { emit collectGraph(text, *m_pTrendGraph); @@ -2261,33 +2338,6 @@ void CPlotWidget::slotExport() xlsx.write(hexTo26(col)+QString::number(row+2), m_pTableDataModel->data(index), format); } } - //m_pTrendGraph - int curRow = xlsx.dimension().lastRow(); - xlsx.write(hexTo26(0)+QString::number(curRow+1) , "最大值" ,format); - xlsx.write(hexTo26(0)+QString::number(curRow+2) , "最大值时间" ,format); - xlsx.write(hexTo26(0)+QString::number(curRow+3) , "最小值" ,format); - xlsx.write(hexTo26(0)+QString::number(curRow+4) , "最小值时间" ,format); - xlsx.write(hexTo26(0)+QString::number(curRow+5) , "平均值" ,format); - for(int col = 1,r = 0; col <= m_pTableDataModel->rowCount(); col++,r++) - { - xlsx.write(hexTo26(col)+QString::number(curRow+1) , - m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::MAX) , - Qt::DisplayRole) ,format); - xlsx.write(hexTo26(col)+QString::number(curRow+2) , - m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::MAXTIME) , - Qt::DisplayRole) ,format); - - xlsx.write(hexTo26(col)+QString::number(curRow+3) , - m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::MIN) , - Qt::DisplayRole) ,format); - - xlsx.write(hexTo26(col)+QString::number(curRow+4) , - m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::MINTIME) , - Qt::DisplayRole) ,format); - xlsx.write(hexTo26(col)+QString::number(curRow+5) , - m_pLengedModel->data(m_pLengedModel->index(r,CCurveLegendModel::ColumnField::AVE) , - Qt::DisplayRole) ,format); - } if(xlsx.saveAs(strFileName)) { @@ -2397,12 +2447,14 @@ void CPlotWidget::nextPage() void CPlotWidget::graphVisibleChanged(const bool &check) { + Q_UNUSED(check); + //< 脚本调用setTagVisible导致无法自适应 // m_isSetSliderValue = check; for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) { QCPGraph * graph = ui->plot->graph(nIndex); - const Curve &curve = m_pTrendGraph->curve(graph->name()); + const Curve &curve = m_pTrendGraph->curve(graph->name(), graph->type()); graph->setVisible(curve.visible); if(!curve.visible || curve.tag == "curve.tag") { @@ -2427,7 +2479,7 @@ void CPlotWidget::graphPropertyChanged() for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) { QCPGraph * graph = ui->plot->graph(nIndex); - const Curve &curve = m_pTrendGraph->curve(graph->name()); + const Curve &curve = m_pTrendGraph->curve(graph->name(), graph->type()); graph->setPen(curve.color); updateCurveSelectionColor(graph); } @@ -2441,7 +2493,7 @@ void CPlotWidget::deleteCurrentGraph() if(m_pTrendGraph->curves().size() > 0 && index >= 0) { QCPGraph * graph = ui->plot->graph(index); - const Curve &curve = m_pTrendGraph->curve(graph->name()); + const Curve &curve = m_pTrendGraph->curve(graph->name(), graph->type()); QString tag = curve.tag; if(tag != "curve.tag") { @@ -2488,7 +2540,7 @@ void CPlotWidget::updateLengedValue(const double &dateTime) { QCPGraph * graph = ui->plot->graph(nIndex); double graphValue = graph->value(dateTime); - const Curve &curve = m_pTrendGraph->curve(graph->name()); + const Curve &curve = m_pTrendGraph->curve(graph->name(), graph->type()); double value = graphValue; if(m_bHisAdaption && m_type != E_Trend_RealTime) @@ -2508,7 +2560,7 @@ void CPlotWidget::graphSelectionChanged(bool select) QCPGraph * graph = dynamic_cast(sender()); if(Q_NULLPTR != graph && select) { - ui->lengedView->selectRow(m_pTrendGraph->index(graph->name())); + ui->lengedView->selectRow(m_pTrendGraph->index(graph->name(), graph->type())); } ui->plot->replot(QCustomPlot::rpQueuedRefresh); } @@ -2572,7 +2624,7 @@ void CPlotWidget::updateYAxisTicker() if(m_bHisAdaption && m_type != E_Trend_RealTime) { QSharedPointer ticker(new QCPAxisTickerText); - const Curve &curve = m_pTrendGraph->curve(graphs.first()->name()); + const Curve &curve = m_pTrendGraph->curve(graphs.first()->name(), graphs.first()->type()); if(!curve.visible) { return; @@ -2677,9 +2729,6 @@ EnMeasPiontType CPlotWidget::getMeasType(const QString &type) void CPlotWidget::setLegendCurveTransformColumnVisible(const bool &visible) { Q_UNUSED(visible) - //单位未赋值,隐藏 - //ui->lengedView->setColumnHidden(CCurveLegendModel::UNIT, true); - ui->lengedView->setColumnHidden(CCurveLegendModel::FACTOR, true); ui->lengedView->setColumnHidden(CCurveLegendModel::OFFSET, true); } @@ -2862,18 +2911,18 @@ void CPlotWidget::setSliderRange(double lower, double upper, bool setValue) } } -void CPlotWidget::setCurveStatisData(const QString &tag, EnComputeMethod method, bool reset, const double &value, const double &time) +void CPlotWidget::setCurveStatisData(const QString &tag, const int &curType, EnComputeMethod method, bool reset, const double &value, const double &time) { switch (method) { case CM_MAX: { if(reset) { - m_pTrendGraph->resetCurveStatisMax(tag); + m_pTrendGraph->resetCurveStatisMax(tag, curType); } else { - m_pTrendGraph->setCurveStatisMax(tag, value, time); + m_pTrendGraph->setCurveStatisMax(tag, curType, value, time); } break; } @@ -2881,11 +2930,11 @@ void CPlotWidget::setCurveStatisData(const QString &tag, EnComputeMethod method, { if(reset) { - m_pTrendGraph->resetCurveStatisMin(tag); + m_pTrendGraph->resetCurveStatisMin(tag, curType); } else { - m_pTrendGraph->setCurveStatisMin(tag, value, time); + m_pTrendGraph->setCurveStatisMin(tag, curType, value, time); } break; } @@ -2948,10 +2997,14 @@ bool CPlotWidget::isMutation(const double &preValue, const double &curValue) template void CPlotWidget::updateHisData(std::vector *vecMpKey, std::vector*> *vecResult, std::vector > &vecRange, std::vector< QSharedPointer > &vecContainer, - double lower, double upper, + double lower, double upper, E_Data_Type type, bool isAddVirtualPoint, int nGroupBySec) { int nMaxIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000 + nGroupBySec * 1000; + QPair offsetRange = qMakePair(lower, upper); + if(type == E_PRECURVE){ + offsetRange = getOffsetRange(lower, upper, -1); + } typename std::vector *>::const_iterator it = vecResult->begin(); while(it != vecResult->end()) { @@ -2970,16 +3023,16 @@ void CPlotWidget::updateHisData(std::vector *vecMpKey, std::vecto //< Graph Bound _Tp left; - left.m_nTime = lower; - typename std::vector<_Tp>::const_iterator varHisLeft = std::upper_bound((*vecPoint).begin(), (*vecPoint).end(), left, compareVarPoint<_Tp>); + left.m_nTime = offsetRange.first; + typename std::vector<_Tp>::iterator varHisLeft = std::upper_bound((*vecPoint).begin(), (*vecPoint).end(), left, compareVarPoint<_Tp>); if(varHisLeft != (*vecPoint).begin() && varHisLeft != (*vecPoint).end()) { --varHisLeft; } _Tp right; - right.m_nTime = upper; - typename std::vector<_Tp>::const_iterator varHisRight = std::lower_bound((*vecPoint).begin(), (*vecPoint).end(), right, compareVarPoint<_Tp>); + right.m_nTime = offsetRange.second; + typename std::vector<_Tp>::iterator varHisRight = std::lower_bound((*vecPoint).begin(), (*vecPoint).end(), right, compareVarPoint<_Tp>); if(varHisRight == (*vecPoint).end()) { varHisRight = (*vecPoint).end() - 1; @@ -3014,9 +3067,17 @@ void CPlotWidget::updateHisData(std::vector *vecMpKey, std::vecto int lastStatus = 0; //< Handle Data - typename std::vector<_Tp>::const_iterator pt = varHisLeft; + typename std::vector<_Tp>::iterator pt = varHisLeft; + double offsetTime = 0; + if(pt != varHisRight) + { + if(type == E_PRECURVE){ + offsetTime = getOffsetTime(pt->m_nTime); + } + } while(pt != varHisRight) { + pt->m_nTime += offsetTime; double value = qSqrt(-1.); if (typeid(boost::int32_t) == pt->m_varValue.type()) { @@ -3044,7 +3105,7 @@ void CPlotWidget::updateHisData(std::vector *vecMpKey, std::vecto qint64 timeStamp = pt->m_nTime; int status = CTrendInfoManage::instance()->getInvalidStatus(pointType, pt->m_nStatus); - if(lastTimeStamp > 0 && lastTimeStamp + nMaxIntervalSecs < timeStamp) + if(lastTimeStamp > 0 && lastTimeStamp + nMaxIntervalSecs < timeStamp && m_bEnableNan) { container->add(QCPGraphData(lastTimeStamp+nGroupBySec*1000, qSqrt(-1.), lastStatus)); } @@ -3155,29 +3216,31 @@ void CPlotWidget::groupQueryHistoryEvent() int ByMinute = currentGroupByMinute(); int g_groupByDuration = ByMinute * 60; - if(!m_pHisDataManage->isTsdbExuting()) + QList cmdList; + TsdbCommand cmd; + cmd.type = E_EVENTPOINT; + cmd.dataType = E_HISTORY; + cmd.pVecMpKey = vecMpKey; + cmd.lower = ui->plot->xAxis->range().lower; + cmd.upper = ui->plot->xAxis->range().upper; + cmd.nGroupBySec = g_groupByDuration; + if(g_groupByDuration == 0) { - if(g_groupByDuration == 0) - { - emit sigQueryHistoryEvent(vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, iot_dbms::CM_NULL, g_groupByDuration); - } - else - { - emit sigQueryHistoryEvent(vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, iot_dbms::CM_SAMPLE, g_groupByDuration); - } + cmd.vecMethod = std::vector{iot_dbms::CM_NULL}; } else { - if(g_groupByDuration == 0) - { - m_pHisDataManage->postTsdbCommandQueue(E_EVENTPOINT, vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, g_groupByDuration, - std::vector{iot_dbms::CM_NULL}); - } - else - { - m_pHisDataManage->postTsdbCommandQueue(E_EVENTPOINT, vecMpKey, ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, g_groupByDuration, - std::vector{iot_dbms::CM_SAMPLE}); - } + cmd.vecMethod = std::vector{iot_dbms::CM_SAMPLE}; + } + cmdList.push_back(cmd); + + if(!m_pHisDataManage->isTsdbExuting()) + { + emit sigQueryHistoryRecord(cmdList); + } + else + { + m_pHisDataManage->postTsdbCommandQueue(cmdList); } ui->plot->replot(); @@ -3241,6 +3304,7 @@ void CPlotWidget::addHorizontalLine() m_horizontalGraph->setData(xLineVector,yLineVector,statusVector); m_horizontalGraph->setName("curve.tag"); + m_horizontalGraph->setType(enRealCurve); m_horizontalGraph->removeFromLegend(); horizontalCurve.tag = "curve.tag"; horizontalCurve.visible = false; @@ -3327,16 +3391,187 @@ void CPlotWidget::enableSearch(bool enable) { if(enable) { + ui->preCurve->setEnabled(true); ui->customSearch->setEnabled(true); ui->customSearch->setText(tr("查询")); } else { + ui->preCurve->setEnabled(false); ui->customSearch->setEnabled(false); ui->customSearch->setText(tr("查询中")); } } +void CPlotWidget::afterModeSwitch() +{ + bool isTool = true; + switch (m_type) { + case E_Trend_Invalid: + case E_Trend_RealTime:{ + isTool = false; + ui->dataWidget->setVisible(false); + ui->customWidget->setVisible(false); + ui->customSearch->setVisible(false); + ui->preCurve->setChecked(false); + break; + } + case E_Trend_His_Minute: + case E_Trend_His_Hour: + case E_Trend_His_Day: + case E_Trend_His_Week: + case E_Trend_His_Month: + case E_Trend_His_Quarter: + case E_Trend_His_Year:{ + isTool = true; + ui->dataWidget->setVisible(true); + ui->customWidget->setVisible(false); + ui->customSearch->setVisible(false); + break; + } + case E_Trend_His_Custom:{ + isTool = true; + ui->dataWidget->setVisible(false); + ui->customWidget->setVisible(true); + ui->customSearch->setVisible(false); + break; + } + default: + break; + } + + if(m_showType == E_Show_Table){ + isTool = false; + ui->customSearch->setVisible(true); + ui->preCurve->setChecked(false); + } + + ui->checkBox_alarmPoint->setVisible(isTool); + ui->comboBox_alarmStatus->setVisible(isTool); + ui->adapt->setVisible(isTool); + ui->preCurve->setVisible(isTool); + if(!m_isAlarmShow){ + ui->checkBox_alarmPoint->setVisible(false); + ui->comboBox_alarmStatus->setVisible(false); + } + if(!m_isAdaptShow){ + ui->adapt->setVisible(false); + } + if(!m_isPreCurveShow){ + ui->preCurve->setVisible(false); + } + + bool isTable = m_showType == E_Show_Table ? true : false; + ui->plot->setVisible(!isTable); + ui->widget->setVisible(!isTable); + ui->m_dataView->setVisible(isTable); + ui->plotExport->setVisible(isTable); + ui->plotPrint->setVisible(!isTable); +} + +QPair CPlotWidget::getOffsetRange(const double &lower, const double &upper, int direction) +{ + QPair result; + QDateTime lowDate = QDateTime::fromMSecsSinceEpoch(lower); + QDateTime upDate = QDateTime::fromMSecsSinceEpoch(upper); + switch (m_type) { + case E_Trend_Invalid: + case E_Trend_RealTime:{ + break; + } + case E_Trend_His_Minute:{ + result.first = lower + 600000 * direction; + result.second = upper + 600000 * direction; + break; + } + case E_Trend_His_Hour:{ + result.first = lower + 3600000 * direction; + result.second = upper + 3600000 * direction; + break; + } + case E_Trend_His_Day:{ + result.first = lower + 86400000 * direction; + result.second = upper + 86400000 * direction; + break; + } + case E_Trend_His_Week:{ + result.first = lower + 604800000 * direction; + result.second = upper + 604800000 * direction; + break; + } + case E_Trend_His_Month:{ + result.first = lowDate.addMonths(1 * direction).toMSecsSinceEpoch(); + result.second = upDate.addMonths(1 * direction).toMSecsSinceEpoch(); + break; + } + case E_Trend_His_Quarter:{ + result.first = lowDate.addMonths(3 * direction).toMSecsSinceEpoch(); + result.second = upDate.addMonths(3 * direction).toMSecsSinceEpoch(); + break; + } + case E_Trend_His_Year:{ + result.first = lowDate.addYears(1 * direction).toMSecsSinceEpoch(); + result.second = upDate.addYears(1 * direction).toMSecsSinceEpoch(); + break; + } + case E_Trend_His_Custom:{ + result.first = lower + (upper - lower) * direction; + result.second = upper + (upper - lower) * direction; + break; + } + default: + break; + } + return result; +} + +double CPlotWidget::getOffsetTime(const double &time) +{ + double result = 0; + QDateTime origin = QDateTime::fromMSecsSinceEpoch(time); + switch (m_type) { + case E_Trend_Invalid: + case E_Trend_RealTime:{ + break; + } + case E_Trend_His_Minute:{ + result = 600000; + break; + } + case E_Trend_His_Hour:{ + result = 3600000; + break; + } + case E_Trend_His_Day:{ + result = 86400000; + break; + } + case E_Trend_His_Week:{ + result = 604800000; + break; + } + case E_Trend_His_Month:{ + result = origin.addMonths(1).toMSecsSinceEpoch() - time; + break; + } + case E_Trend_His_Quarter:{ + result = origin.addMonths(3).toMSecsSinceEpoch() - time; + break; + } + case E_Trend_His_Year:{ + result = origin.addYears(1).toMSecsSinceEpoch() - time; + break; + } + case E_Trend_His_Custom:{ + result = ui->endData->dateTime().toMSecsSinceEpoch() - ui->startData->dateTime().toMSecsSinceEpoch(); + break; + } + default: + break; + } + return result; +} + void CPlotWidget::alarmTextChanged(const QString &text) { Q_UNUSED(text) @@ -3420,67 +3655,51 @@ void CPlotWidget::alarmPointCheckStateChanged() void CPlotWidget::showTypeChanged(bool checked) { m_pTableDataModel->clear(); - if(checked) - { - m_showType = E_Show_Table; - - } - else - { - m_showType = E_Show_Curve; - } - ui->plot->setVisible(!checked); - ui->widget->setVisible(!checked); - ui->m_dataView->setVisible(checked); - ui->plotExport->setVisible(checked); - ui->plotPrint->setVisible(!checked); - ui->customSearch->setVisible(checked); + checked ? m_showType = E_Show_Table : m_showType = E_Show_Curve; if(m_type == E_Trend_RealTime) { - ui->adapt->setVisible(false); - ui->checkBox_alarmPoint->setVisible(false); - ui->comboBox_alarmStatus->setVisible(false); - /*if(E_Show_Table == m_showType) + if(E_Show_Table == m_showType) { updateRealTimeTableData(); - }*/ - } - else - { - if(m_isAdaptShow) - { - ui->adapt->setVisible(!checked); - } - if(m_isAlarmShow) - { - ui->checkBox_alarmPoint->setVisible(!checked); - ui->comboBox_alarmStatus->setVisible(!checked); } } - - - updateRealTimeTableData(); + afterModeSwitch(); updateCurves(); - - + graphVisibleChanged(true); } void CPlotWidget::slotStartDateChanged(const QDateTime &dateTime) { - if(ui->endData->dateTime() > dateTime) + int sec = ui->interval->currentData().toInt(); + + QDateTime endTime = ui->endData->dateTime(); + + if( endTime > dateTime ) { ui->plot->xAxis->setRangeLower(dateTime.toMSecsSinceEpoch()); + + if( (sec == 0) && (endTime.toSecsSinceEpoch() - dateTime.toSecsSinceEpoch() > THREE_DAY) ) + { + sec = THREE_DAY; + ui->startData->setDateTime(endTime.addSecs(-sec)); + } } else { - int sec = ui->interval->currentData().toInt(); - if(sec < 600) + if( sec == 0 ) + { + sec = THREE_DAY; + } + else if( sec < 600 ) { sec = 600; } - ui->startData->setDateTime(ui->endData->dateTime().addSecs(-sec)); + else + {} + + ui->startData->setDateTime(endTime.addSecs(-sec)); } if(E_Show_Curve == m_showType) @@ -3491,18 +3710,33 @@ void CPlotWidget::slotStartDateChanged(const QDateTime &dateTime) void CPlotWidget::slotEndDateChanged(const QDateTime &dateTime) { - if(ui->startData->dateTime() < dateTime) + int sec = ui->interval->currentData().toInt(); + + QDateTime startTime = ui->startData->dateTime(); + if(startTime < dateTime) { ui->plot->xAxis->setRangeUpper(dateTime.toMSecsSinceEpoch()); + + if( (sec == 0) && (dateTime.toSecsSinceEpoch() - startTime.toSecsSinceEpoch() > THREE_DAY) ) + { + sec = THREE_DAY; + ui->endData->setDateTime(startTime.addSecs(sec)); + } } else { - int sec = ui->interval->currentData().toInt(); - if(sec < 600) + if( sec == 0 ) + { + sec = THREE_DAY; + } + else if(sec < 600) { sec = 600; } - ui->endData->setDateTime(ui->startData->dateTime().addSecs(sec)); + else + {} + + ui->endData->setDateTime(startTime.addSecs(sec)); } if(E_Show_Curve == m_showType) @@ -3548,30 +3782,27 @@ void CPlotWidget::slotCustomSearch(bool isForce) enableSearch(false); std::vector vecMethod{iot_dbms::CM_MAX, iot_dbms::CM_MIN}; - updateComputeValue(lower, upper, vecMethod); - std::vector * vecMpKey = new std::vector(); - for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) - { - const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name()); - SMeasPointKey key; - std::string tmp = curve.tag.toStdString(); - char * tag = (char*)malloc(tmp.size() + 1); - memset(tag, 0, tmp.size() + 1); - memcpy(tag, tmp.c_str(), tmp.size()); - key.m_pszTagName = tag; - key.m_enType = getMeasType(curve.type); - vecMpKey->push_back(key); + double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; + QList cmdList; + TsdbCommand curve = getHisCurveCmd(lower + nIntervalSecs, upper - nIntervalSecs, sec, E_HISTORY); + TsdbCommand computer = getComputeCmd(lower, upper, vecMethod, E_HISTORY); + cmdList.push_back(curve); + cmdList.push_back(computer); + if(m_bShowPreCurve){ + QPair preRange = getOffsetRange(lower, upper, -1); + TsdbCommand preCurve = getHisCurveCmd(preRange.first + nIntervalSecs, preRange.second - nIntervalSecs, sec, E_PRECURVE); + TsdbCommand perComputer = getComputeCmd(preRange.first, preRange.second, vecMethod, E_PRECURVE); + cmdList.push_back(preCurve); + cmdList.push_back(perComputer); } - double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; -// if(!m_pHisDataManage->isTsdbExuting()) -// { -// emit sigQueryHistoryPolymericData(vecMpKey, lower + nIntervalSecs, upper - nIntervalSecs, sec, iot_dbms::CM_FIRST); -// } -// else + if(!m_pHisDataManage->isTsdbExuting()) { - //< 添加多条曲线时,可能存在顺序混乱,导致显示列缺失,因此都使用post的方式查询 - m_pHisDataManage->postTsdbCommandQueue(E_POLYMERIC, vecMpKey, lower + nIntervalSecs, upper - nIntervalSecs, sec, std::vector{iot_dbms::CM_FIRST}); + emit sigQueryHistoryRecord(cmdList); + } + else + { + m_pHisDataManage->postTsdbCommandQueue(cmdList); } } @@ -3579,3 +3810,8 @@ void CPlotWidget::slotEnableSearch(bool enable) { enableSearch(!enable); } + +void CPlotWidget::setEnableAddNanFlag(bool bEnable) +{ + m_bEnableNan = bEnable; +} diff --git a/product/src/gui/plugin/TrendCurves/CPlotWidget.h b/product/src/gui/plugin/TrendCurves/CPlotWidget.h index 5c21b2e0..cb4dfd17 100644 --- a/product/src/gui/plugin/TrendCurves/CPlotWidget.h +++ b/product/src/gui/plugin/TrendCurves/CPlotWidget.h @@ -85,10 +85,14 @@ public: void setClearVisible(bool visible); + void setEnableAddNanFlag(bool bEnable); + void setAdaptVisible(bool visible); void setAlarmPointVisible(bool visible); + void setPreCurveVisible(bool visible); + void insertCurve(Curve curve); void clear(bool clearTitle = false); @@ -115,6 +119,10 @@ public: QColor plotTickPen(); void setPlotTickPen(const QColor &color); + //用于重新设置自定义界面中的周期间隔 + void clearCustomInterval(); + void addCustomInterval(const QString &desc,const int &sec); + signals: void clearCurve(); void queryHisEvent(const QString &tag, const int &type, const qint64 &time); @@ -122,22 +130,7 @@ signals: void updateTagCheckState(const QString &tag, const bool &outOfRange); void releaseHisDataThread(); void releaseHisEventThread(); - - void sigQueryHistoryOriginalData(std::vector *vecMpKey, - double lower, double upper, - E_Data_Type type = E_HISTORY); - - void sigQueryHistoryPolymericData(std::vector *vecMpKey, - double lower, double upper, int nGroupByMinute, iot_dbms::EnComputeMethod method); - - void sigQueryHistoryComputeData(std::vector *vecMpKey, - double lower, double upper, - std::vector method); - - void sigQueryHistoryEvent(std::vector *vecMpKey, - double lower, double upper, - iot_dbms::EnComputeMethod enCM, - int nGroupByMinute); + void sigQueryHistoryRecord(const QList &cmdList); void sigAddCollect(int x, int y); void sigHideCollect(); @@ -165,13 +158,14 @@ private slots: void updateTrendShowMode(int nIndex, bool updateXAxisRange = true); - void updateComputeValue(double lower, double upper, std::vector vecMethod); + TsdbCommand getHisCurveCmd(double lower, double upper, int nGroupBy, E_Data_Type type); + TsdbCommand getComputeCmd(double lower, double upper, std::vector vecMethod, E_Data_Type type); void updateCurves(); void updateRealTimeCurveRecord(); - void updateHistoryCurveRecord(double lower, double upper); + void updateHistoryCurveRecord(); void updateHisOriginalData(std::vector *vecMpKey, std::vector *> *vecResult, @@ -179,23 +173,28 @@ private slots: void updateHisPolymericData(std::vector *vecMpKey, std::vector *> *vecResult, - int nGroupBySec); + int nGroupBySec, + E_Data_Type type = E_HISTORY); void updateHisComputeData(std::vector *vecMpKey, - std::vector *> *> > cmResult); + std::vector *> *> > cmResult, + E_Data_Type type = E_HISTORY); void updateHistoryGraph(std::vector *vecMpKey, std::vector< QSharedPointer > &vecContainer, - std::vector< QSharedPointer > &vecRange); + std::vector< QSharedPointer > &vecRange, + E_Data_Type type); void updateHistoryData(std::vector *vecMpKey, std::vector< QSharedPointer > &vecContainer, - std::vector< QSharedPointer > &vecRange); + std::vector< QSharedPointer > &vecRange, + E_Data_Type type); void updateCurveHisData(double lower, double upper, QCPGraph * graph, int index, QSharedPointer container, - QSharedPointer range); + QSharedPointer range, + E_Data_Type type); void updatePhaseTracer(std::vector *vecMpKey, std::vector *> *vecResult); @@ -204,6 +203,7 @@ private slots: void updateAxisFormat(bool updateXAxisRange); QPair getFatureDataTime(E_Trend_Type type, QDateTime curTime = QDateTime()); void updateAdaptState(bool isAdapt); + void updatePreCurveState(bool isPreCurve); void addCollect(); void slotPrint(); void slotExport(); @@ -263,6 +263,7 @@ private: std::vector< QSharedPointer > &vecRange, std::vector< QSharedPointer > &vecContainer, double lower, double upper, + E_Data_Type type, bool isAddVirtualPoint = false, int nGroupBySec = 0); @@ -272,7 +273,7 @@ private: template bool checkStatus(const iot_dbms::SVarHisSamplePoint &var, const int &nInvalid); - void setCurveStatisData(const QString &tag, iot_dbms::EnComputeMethod method, bool reset, const double &value = 0, const double &time = 0); + void setCurveStatisData(const QString &tag, const int &curType, iot_dbms::EnComputeMethod method, bool reset, const double &value = 0, const double &time = 0); bool isMutation(const double &preValue, const double &curValue); @@ -289,11 +290,15 @@ private: void resetCurveData(const QMap>& dataMap, const QStringList& headerList, bool ascs = true); void enableSearch(bool enable); + void afterModeSwitch(); + QPair getOffsetRange(const double &lower, const double &upper, int direction); + double getOffsetTime(const double &time); private: Ui::CPlotWidget *ui; E_Trend_Type m_type; E_Show_Type m_showType; bool m_bHisAdaption; + bool m_bShowPreCurve; QButtonGroup * m_TrendTypeButton; CCurveLegendModel * m_pLengedModel; CTableDataModel * m_pTableDataModel; @@ -331,6 +336,10 @@ private: bool m_isTooltip; bool m_isAdaptShow; bool m_isAlarmShow; + bool m_isPreCurveShow; + bool m_bEnableNan;//caodingfa:定时存盘周期可变时,原有逻辑会导致每个间隔插入一个Nan值,导致无效,为不影响原逻辑,增加一个开关 + + const int THREE_DAY = 3*24*60*60; // 查询全部数据时, 最多查询3天, 避免数据过多导致界面卡顿 }; #endif // CPLOTWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves/CPlotWidget.ui b/product/src/gui/plugin/TrendCurves/CPlotWidget.ui index 82ecce4d..c9217a8a 100644 --- a/product/src/gui/plugin/TrendCurves/CPlotWidget.ui +++ b/product/src/gui/plugin/TrendCurves/CPlotWidget.ui @@ -83,26 +83,28 @@ 0 - - - - - 0 - 0 - - - - - 42 - 24 - - - - 对比 - - - true - + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + @@ -124,30 +126,59 @@ - + + + + + 0 + 0 + + + + + 50 + 24 + + + + 对比 + + + true + + + + - 130 + 208 0 - + 收藏 - + 导出 + + + + 打印 + + + @@ -164,13 +195,6 @@ - - - - 打印 - - - @@ -249,28 +273,23 @@
- - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - + + + + + 0 + 0 + + + + + 0 + 24 + + + + 昨日曲线 +
diff --git a/product/src/gui/plugin/TrendCurves/CTableDataModel.cpp b/product/src/gui/plugin/TrendCurves/CTableDataModel.cpp index 7b3295c8..beefe8b6 100644 --- a/product/src/gui/plugin/TrendCurves/CTableDataModel.cpp +++ b/product/src/gui/plugin/TrendCurves/CTableDataModel.cpp @@ -20,7 +20,7 @@ void CTableDataModel::clear() { beginResetModel(); m_curveDataMap.clear(); - m_header.clear(); + //m_header.clear(); m_timeList.clear(); m_bAscs = true; endResetModel(); @@ -227,3 +227,31 @@ QVariant CTableDataModel::data(const QModelIndex &index, int role) const return QVariant(); } + +CustomHeaderView::CustomHeaderView(Qt::Orientation orientation ,QWidget *parent) +:QHeaderView(orientation,parent) +{ +} +CustomHeaderView::~CustomHeaderView() +{ +} + +void CustomHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const +{ + + //就简单几句 + //拿到text数据,在写数据的时候,设置textwordwrap,居中。 + QString textstr = model()->headerData(visualIndex(logicalIndex),Qt::Horizontal).toString(); + painter->save(); + //painter->drawText(rect,Qt::TextWordWrap | Qt::AlignCenter, textstr); + // 从当前样式中获取边框颜色 + QStyleOptionHeader opt; + initStyleOption(&opt); + opt.rect = rect; + opt.section = logicalIndex; + + // 使用样式绘制边框 + style()->drawControl(QStyle::CE_HeaderSection, &opt, painter, this); + painter->drawText(rect,Qt::TextWordWrap | Qt::AlignCenter, textstr); + painter->restore(); +} diff --git a/product/src/gui/plugin/TrendCurves/CTableDataModel.h b/product/src/gui/plugin/TrendCurves/CTableDataModel.h index 4949b9ed..7b56d70b 100644 --- a/product/src/gui/plugin/TrendCurves/CTableDataModel.h +++ b/product/src/gui/plugin/TrendCurves/CTableDataModel.h @@ -37,5 +37,15 @@ private: QList m_timeList; bool m_bAscs; }; +class CustomHeaderView : public QHeaderView +{ + Q_OBJECT +public: + CustomHeaderView(Qt::Orientation orientation = Qt::Horizontal,QWidget *parent = nullptr); //这里为了省事,给默认值为水平表头,因为我正好使用水平的表头 + ~CustomHeaderView(); + +protected: + virtual void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const; +}; #endif // CTABLEDATAMODEL_H diff --git a/product/src/gui/plugin/TrendCurves/CTableView.cpp b/product/src/gui/plugin/TrendCurves/CTableView.cpp index c7c43ee5..83bf25dc 100644 --- a/product/src/gui/plugin/TrendCurves/CTableView.cpp +++ b/product/src/gui/plugin/TrendCurves/CTableView.cpp @@ -30,3 +30,35 @@ void CTableView::setTableRowHeight(const int &nHeight) verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); } + +void CTableView::showEvent(QShowEvent *event){ + QTableView::showEvent(event); + adjustHeaderWidth(); +} + + +// 自动调整表头宽度以适应文本 +void CTableView::adjustHeaderWidth() { + QHeaderView *header = horizontalHeader(); + int sections = header->count(); + int maxWidth = 0; + QFontMetrics fm(header->font()); + int maxWidthThreshold = 200; // 设置换行的阈值 + + for (int i = 0; i < sections; ++i) { + QString text = model()->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); + int width = fm.width(text) + 10; // 加上一些额外空间 + maxWidth = qMax(maxWidth, width); + } + + for (int i = 0; i < sections; ++i) { + QString text = model()->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); + int width = fm.width(text) + 10; // 加上一些额外空间 + // 如果宽度超过阈值,则换行 + if (width > maxWidthThreshold) { + header->resizeSection(i, maxWidthThreshold); + } else { + header->resizeSection(i, maxWidth); + } + } +} diff --git a/product/src/gui/plugin/TrendCurves/CTableView.h b/product/src/gui/plugin/TrendCurves/CTableView.h index 2758f072..b200ded1 100644 --- a/product/src/gui/plugin/TrendCurves/CTableView.h +++ b/product/src/gui/plugin/TrendCurves/CTableView.h @@ -17,6 +17,9 @@ public: int tableRowHeight(); void setTableRowHeight(const int &nHeight); + void adjustHeaderWidth(); +protected: + void showEvent(QShowEvent *event) override ; private: int m_nTableColWidth; diff --git a/product/src/gui/plugin/TrendCurves/CTrendEditDialog.cpp b/product/src/gui/plugin/TrendCurves/CTrendEditDialog.cpp index c15a1f74..c67af848 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendEditDialog.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendEditDialog.cpp @@ -4,6 +4,7 @@ #include "CTrendEditModel.h" #include "GraphTool/Retriever/CRetriever.h" #include "pub_utility_api/FileUtil.h" +#include "CTableDataModel.h" using namespace iot_dbms; @@ -16,6 +17,10 @@ CTrendEditDialog::CTrendEditDialog(QWidget *parent) : ui->setupUi(this); ui->m_retrieverWidget->setWindowFlags(Qt::Widget); ui->m_retrieverWidget->setMultVisible(false); + ui->m_retrieverWidget->setCloseBtnVisible(false); + ui->m_retrieverWidget->installEventFilter(this); + ui->frame->setFixedWidth(320); + setMinimumWidth(1200); //setWindowModality(Qt::WindowModal); initialize(); connect(ui->addCurve, SIGNAL(clicked()), this, SLOT(slot_addCureve())); @@ -53,6 +58,8 @@ void CTrendEditDialog::initTrendView() ui->trendView->setAlternatingRowColors(true); ui->trendView->horizontalHeader()->setStretchLastSection(true); + ui->trendView->setHorizontalHeader(new CustomHeaderView(Qt::Horizontal,ui->trendView)); + connect(ui->trendView->horizontalHeader(),&QHeaderView::sectionCountChanged,ui->trendView,&CTrendEditView::adjustHeaderWidth); connect(ui->m_retrieverWidget, &CRetriever::itemTagTriggered, ui->trendView, &CTrendEditView::appendTagName); } @@ -68,6 +75,16 @@ void CTrendEditDialog::resizeEvent(QResizeEvent *event) updateTrendViewColumnWidth(); } +bool CTrendEditDialog::eventFilter(QObject *o, QEvent *e) +{ + if( e->type() == QEvent::MouseMove ) + { + return true; + } + + return QDialog::eventFilter(o, e); +} + void CTrendEditDialog::updateTrendViewColumnWidth() { diff --git a/product/src/gui/plugin/TrendCurves/CTrendEditDialog.h b/product/src/gui/plugin/TrendCurves/CTrendEditDialog.h index d6e6001a..b0d056f1 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendEditDialog.h +++ b/product/src/gui/plugin/TrendCurves/CTrendEditDialog.h @@ -28,6 +28,7 @@ public: protected: void showEvent(QShowEvent *event); void resizeEvent(QResizeEvent *event); + bool eventFilter(QObject *o, QEvent *e); protected slots: void slot_updateTrend(); diff --git a/product/src/gui/plugin/TrendCurves/CTrendEditView.cpp b/product/src/gui/plugin/TrendCurves/CTrendEditView.cpp index 41e6c5f3..8d2d6e12 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendEditView.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendEditView.cpp @@ -50,6 +50,42 @@ void CTrendEditView::appendTagName(const QString &strTagName, const QString &str } } +void CTrendEditView::adjustHeaderWidth() +{ + QHeaderView *header = horizontalHeader(); + int sectionCount = header->count(); + if (sectionCount == 0 || !model()) { + return; + } + + QFontMetrics fontMetrics(header->font()); + const int maxWidthThreshold = 200; + const int baseHeight = 30; + int maxHeightMultiplier = 1; + + for (int section = 0; section < sectionCount; ++section) { + QString headerText = model()->headerData(section, Qt::Horizontal).toString(); + if (headerText.isEmpty()) { + continue; + } + + int textWidth = fontMetrics.width(headerText) + 20; // 额外空间 + int heightMultiplier = 1; + + // 调整宽度和计算换行高度 + if (textWidth > maxWidthThreshold) { + header->resizeSection(section, maxWidthThreshold); + heightMultiplier = qCeil(static_cast(textWidth) / maxWidthThreshold); + } else { + header->resizeSection(section, textWidth); + } + + maxHeightMultiplier = qMax(maxHeightMultiplier, heightMultiplier); + } + + header->setFixedHeight(maxHeightMultiplier * baseHeight); +} + void CTrendEditView::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasText()) @@ -96,3 +132,9 @@ void CTrendEditView::dropEvent(QDropEvent *event) } event->accept(); } + +void CTrendEditView::showEvent(QShowEvent *event) +{ + QTableView::showEvent(event); + adjustHeaderWidth(); +} diff --git a/product/src/gui/plugin/TrendCurves/CTrendEditView.h b/product/src/gui/plugin/TrendCurves/CTrendEditView.h index e4d1b92c..0e0b8480 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendEditView.h +++ b/product/src/gui/plugin/TrendCurves/CTrendEditView.h @@ -12,10 +12,12 @@ public: public slots: void appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti); + void adjustHeaderWidth(); protected: void dragEnterEvent(QDragEnterEvent *event); void dragMoveEvent(QDragMoveEvent *event); void dropEvent(QDropEvent *event); + void showEvent(QShowEvent *event) override ; }; #endif // CTRENDEDITVIEW_H diff --git a/product/src/gui/plugin/TrendCurves/CTrendFavTreeWidget.cpp b/product/src/gui/plugin/TrendCurves/CTrendFavTreeWidget.cpp index 90fc64be..46574f7d 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendFavTreeWidget.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendFavTreeWidget.cpp @@ -159,12 +159,26 @@ void CTrendFavTreeWidget::slotEditTrendEdit() void CTrendFavTreeWidget::slotRemoveTrendEdit() { - QList selectItem = selectedItems(); - foreach (QTreeWidgetItem *item, selectItem) { - int index = indexOfTopLevelItem(item); - takeTopLevelItem(index); + int ret=QMessageBox::question(this, tr("提示"), tr("确定删除所选项吗?"), QMessageBox::Yes,QMessageBox::No); + if(QMessageBox::Yes==ret) + { + QList selectItem = selectedItems(); + foreach (QTreeWidgetItem *item, selectItem) { + if( m_trendGraphMap.contains(item) ) + { + CTrendGraph* graph = m_trendGraphMap[item]; + if( graph != NULL ) + { + graph->clear(); + emit showTrendGraph(graph, "趋势图"); + } + } + + int index = indexOfTopLevelItem(item); + takeTopLevelItem(index); + } + savaTrendGraph(); } - savaTrendGraph(); } void CTrendFavTreeWidget::slotItemChanged(QTreeWidgetItem *item, int column) @@ -181,6 +195,8 @@ void CTrendFavTreeWidget::slotItemChanged(QTreeWidgetItem *item, int column) return; } } + + emit updateTitle(content); } void CTrendFavTreeWidget::slotImport() @@ -213,7 +229,7 @@ void CTrendFavTreeWidget::slotExport() QString CTrendFavTreeWidget::getNewValidTitle() { - QString title = QString("自定义趋势_"); + QString title = QString(tr("自定义趋势_")); QStringList listItemText; for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) { @@ -348,6 +364,10 @@ void CTrendFavTreeWidget::savaTrendGraph(const QString &filePath, const QList CTrendGraph::curveColors() const return list; } -const Curve &CTrendGraph::curve(const QString &tag) const +const Curve &CTrendGraph::curve(const QString &tag, const int &curType) const { for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) { - if(m_listCurve.at(nIndex).tag == tag) + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) { return m_listCurve.at(nIndex); } } Q_ASSERT_X(false, "CTrendGraph::curve", "curve is not exists"); + + static Curve invalid; + return invalid; } -int CTrendGraph::index(const QString &tag) const +int CTrendGraph::index(const QString &tag, const int &curType) const { + //< TODO 性能 for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) { - if(m_listCurve.at(nIndex).tag == tag) + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) { return nIndex; } @@ -69,17 +73,28 @@ void CTrendGraph::addCurve(const Curve &curve) m_listCurve.append(curve); } -int CTrendGraph::removeCurve(const QString &tag) +QList CTrendGraph::removeCurve(const QString &tag) { + QList removeList; for(int nIndex(m_listCurve.size() - 1); nIndex >= 0; nIndex--) { if(m_listCurve.at(nIndex).tag == tag) { m_listCurve.removeAt(nIndex); - return nIndex; + removeList.append(nIndex); } } - return -1; + return removeList; +} + +bool CTrendGraph::removeCurve(const int &nIndex) +{ + if(nIndex < 0 || nIndex >= m_listCurve.size()) + { + return false; + } + m_listCurve.removeAt(nIndex); + return true; } void CTrendGraph::setCurveVisible(const int &nIndex, const bool &visible) @@ -112,11 +127,11 @@ void CTrendGraph::setCurveGraphOffset(const int &nIndex, const double &offset) m_listCurve[nIndex].graphOffset = offset; } -void CTrendGraph::setCurveHisDataValue(const QString &tag, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range) +void CTrendGraph::setCurveHisDataValue(const QString &tag, const int &curType, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range) { for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) { - if(m_listCurve.at(nIndex).tag == tag) + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) { m_listCurve[nIndex].hisMax = max; m_listCurve[nIndex].hisMin = min; @@ -132,7 +147,7 @@ void CTrendGraph::setCurveHisDataValue(const QString &tag, const double &max, co void CTrendGraph::pushCurveRTDataValue(const QString &tag, const double &key, const double &value, const int &status) { //< 保留20min实时数据 - int nIndex = m_listCurve.indexOf(tag); + int nIndex = m_listCurve.indexOf(tag); //< 实时数据索引一定在前面 if (-1 == nIndex || qIsNaN(value)) { return; @@ -148,11 +163,11 @@ void CTrendGraph::pushCurveRTDataValue(const QString &tag, const double &key, co } } -void CTrendGraph::setCurveStatisMax(const QString &tag, const double &max, const double &maxTime) +void CTrendGraph::setCurveStatisMax(const QString &tag, const int &curType, const double &max, const double &maxTime) { for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) { - if(m_listCurve.at(nIndex).tag == tag) + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) { m_listCurve[nIndex].sHisMax = max; m_listCurve[nIndex].sHisMaxTime = maxTime; @@ -160,11 +175,11 @@ void CTrendGraph::setCurveStatisMax(const QString &tag, const double &max, const } } -void CTrendGraph::setCurveStatisMin(const QString &tag, const double &min, const double &minTime) +void CTrendGraph::setCurveStatisMin(const QString &tag, const int &curType, const double &min, const double &minTime) { for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) { - if(m_listCurve.at(nIndex).tag == tag) + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) { m_listCurve[nIndex].sHisMin = min; m_listCurve[nIndex].sHisMinTime = minTime; @@ -172,11 +187,11 @@ void CTrendGraph::setCurveStatisMin(const QString &tag, const double &min, const } } -void CTrendGraph::resetCurveStatisMax(const QString &tag) +void CTrendGraph::resetCurveStatisMax(const QString &tag, const int &curType) { for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) { - if(m_listCurve.at(nIndex).tag == tag) + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) { m_listCurve[nIndex].sHisMax = -DBL_MAX; m_listCurve[nIndex].sHisMaxTime = -DBL_MAX; @@ -184,11 +199,11 @@ void CTrendGraph::resetCurveStatisMax(const QString &tag) } } -void CTrendGraph::resetCurveStatisMin(const QString &tag) +void CTrendGraph::resetCurveStatisMin(const QString &tag, const int &curType) { for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) { - if(m_listCurve.at(nIndex).tag == tag) + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) { m_listCurve[nIndex].sHisMin = DBL_MAX; m_listCurve[nIndex].sHisMinTime = DBL_MAX; @@ -196,11 +211,11 @@ void CTrendGraph::resetCurveStatisMin(const QString &tag) } } -void CTrendGraph::updateRTCurveStatisticsInfo(const QString &strTagName) +void CTrendGraph::updateRTCurveStatisticsInfo(const QString &strTagName, const int &curType) { for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) { - if(m_listCurve.at(nIndex).tag == strTagName) + if(m_listCurve.at(nIndex).tag == strTagName && m_listCurve.at(nIndex).curveType == curType) { updateRTCurveStatisticsInfo(m_listCurve[nIndex]); return; diff --git a/product/src/gui/plugin/TrendCurves/CTrendGraph.h b/product/src/gui/plugin/TrendCurves/CTrendGraph.h index 5520b05f..1563aa0f 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendGraph.h +++ b/product/src/gui/plugin/TrendCurves/CTrendGraph.h @@ -28,9 +28,15 @@ struct Range double max; }; +enum Type +{ + enRealCurve = 0, //< 实际测点曲线 + enPrevCurve //< 昨日曲线 +}; + struct Curve { - Curve(const QString &strTagName = QString()) + Curve(const QString &strTagName = QString(), Type type = enRealCurve) : visible(true), rtMax(-DBL_MAX), rtMin(DBL_MAX), @@ -56,11 +62,12 @@ struct Curve desc(QString()), type(QString()), unit(QString()), - color(QColor()){} + color(QColor()), + curveType(type){} inline bool operator==(const Curve &curve) const { - return tag == curve.tag; + return ((tag == curve.tag) && (curveType == curve.curveType)); } inline bool operator==(const QString &strTagName) const @@ -97,6 +104,7 @@ struct Curve QString type; QString unit; QColor color; + Type curveType; QVector< QPair > > values; }; @@ -113,13 +121,14 @@ public: const QList curveColors() const; - const Curve &curve(const QString &tag) const; - int index(const QString &tag) const; + const Curve &curve(const QString &tag, const int &curType) const; + int index(const QString &tag, const int &curType = enRealCurve) const; void clear(); void addCurve(const Curve &curve); - int removeCurve(const QString &tag); + QList removeCurve(const QString &tag); + bool removeCurve(const int &nIndex); void setCurveVisible(const int &nIndex, const bool &visible); @@ -127,20 +136,20 @@ public: void setCurveFactor(const int &nIndex, const double &factor); void setCurveOffset(const int &nIndex, const double &offset); - void setCurveHisDataValue(const QString &tag, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range); + void setCurveHisDataValue(const QString &tag, const int &curType, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range); void pushCurveRTDataValue(const QString &tag, const double &key, const double &value, const int &status); - void setCurveStatisMax(const QString &tag, const double &max, const double &maxTime); - void setCurveStatisMin(const QString &tag, const double &min, const double &minTime); + void setCurveStatisMax(const QString &tag, const int &curType, const double &max, const double &maxTime); + void setCurveStatisMin(const QString &tag, const int &curType, const double &min, const double &minTime); - void resetCurveStatisMax(const QString &tag); - void resetCurveStatisMin(const QString &tag); + void resetCurveStatisMax(const QString &tag, const int &curType); + void resetCurveStatisMin(const QString &tag, const int &curType); void setCurveGraphFactor(const int &nIndex, const double &factor); void setCurveGraphOffset(const int &nIndex, const double &offset); //< 更新实时曲线统计信息 - void updateRTCurveStatisticsInfo(const QString &strTagName); + void updateRTCurveStatisticsInfo(const QString &strTagName, const int &curType); void updateRTCurveStatisticsInfo(Curve &curve); private: diff --git a/product/src/gui/plugin/TrendCurves/CTrendInfoManage.cpp b/product/src/gui/plugin/TrendCurves/CTrendInfoManage.cpp index d9f60c30..617a24b4 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendInfoManage.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendInfoManage.cpp @@ -5,6 +5,7 @@ #include "pub_utility_api/FileUtil.h" #include "perm_mng_api/PermMngApi.h" #include "pub_logger_api/logger.h" +#include using namespace iot_dbms; using namespace iot_public; @@ -23,6 +24,8 @@ CTrendInfoManage *CTrendInfoManage::instance() CTrendInfoManage::CTrendInfoManage() { + m_bLoadTagInfoWhenInit = false; //默认加载所有信息 + loadCfg(); //加载配置文件,会重新覆盖掉默认参数值 //< 实时库 m_rtdbAccess = new iot_dbms::CRdbAccess(); @@ -40,7 +43,13 @@ CTrendInfoManage::CTrendInfoManage() loadRTLocation(); loadDevGroupInfo(pReadDb); loadDeviceInfo(pReadDb); - loadTagInfo(pReadDb); + + //通过setEnableDynamicLoadTag函数加载了,默认不加载测点,防止测点太多打开趋势页面太慢 + //loadAllTagInfo(pReadDb); + if(m_bLoadTagInfoWhenInit) + { + loadAllTagInfo(pReadDb); + } loadStateDefine(); loadAlarmStatusDefine(); loadAlarmStatus(); @@ -61,7 +70,6 @@ void CTrendInfoManage::destory() m_locationInfo.clear(); m_devGroupInfo.clear(); - m_devLocation.clear(); m_deviceInfo.clear(); m_listTagName.clear(); m_listTagInfo.clear(); @@ -255,6 +263,50 @@ QMap CTrendInfoManage::getAlarmOtherStatus() return m_alarmOtherStatus; } +bool CTrendInfoManage::loadTagInfoByDevGroup(const QString &strDevGrpTag) +{ + auto iter = m_deviceInfo.find(strDevGrpTag); + if(iter == m_deviceInfo.end()) + { + return false; + } + + return loadTagInfoByDevTag(iter.value().keys()); +} + +bool CTrendInfoManage::loadTagInfoByDevTag(const QStringList &listDevTag) +{ + QStringList queryDevTag; + foreach (QString strCur, listDevTag) + { + if(m_listTagName.contains(strCur)) //已经加载过了就不再加载了 + { + continue; + } + queryDevTag.push_back(strCur); + } + + if(queryDevTag.isEmpty()) + { + return false; + } + + CDbApi * pReadDb = new CDbApi(DB_CONN_MODEL_READ); + if(!pReadDb->open()) + { + delete pReadDb; + pReadDb = Q_NULLPTR; + return false; + } + + bool bRet = loadTagInfo(pReadDb,listDevTag); + + delete pReadDb; + pReadDb = Q_NULLPTR; + + return bRet; +} + void CTrendInfoManage::loadRTLocation() { iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); @@ -377,18 +429,21 @@ void CTrendInfoManage::loadDeviceInfo(CDbApi *pReadDb) pReadDb->execute(sqlSequenceQuery, query); while(query.next()) { - const QString &tag_name = query.value(0).toString(); - const QString &description = query.value(1).toString(); - const QString &group_tag_name = query.value(2).toString(); - const int location_id = query.value(0).toInt(); + //const QString &tag_name = query.value(0).toString(); + //const QString &description = query.value(1).toString(); + //const QString &group_tag_name = query.value(2).toString(); - m_deviceInfo[group_tag_name].insert(tag_name, description); - m_devLocation[location_id].insert(tag_name, description); + m_deviceInfo[query.value(2).toString()].insert(query.value(0).toString(), query.value(1).toString()); } } -void CTrendInfoManage::loadTagInfo(CDbApi *pReadDb) +bool CTrendInfoManage::loadTagInfo(CDbApi *pReadDb, const QStringList &listDevice) { + if(listDevice.isEmpty()) + { + return false; + } + QSqlQuery query; QStringList listType; listType.append(QStringLiteral("analog")); @@ -396,19 +451,8 @@ void CTrendInfoManage::loadTagInfo(CDbApi *pReadDb) listType.append(QStringLiteral("accuml")); // listType.append(QString("mix")); - QString strDeviceFilter; - if(!m_deviceInfo.isEmpty()) - { - QStringList listDevice; - QMap >::const_iterator iter = m_deviceInfo.constBegin(); - while (iter != m_deviceInfo.constEnd()) - { - listDevice.append(iter.value().keys()); - ++iter; - } - strDeviceFilter = "'" % listDevice.join("', '") % "'"; - strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); - } + QString strDeviceFilter = "'" % listDevice.join("', '") % "'"; + strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); query.setForwardOnly(true); for(int nIndex(0); nIndex < listType.size(); nIndex++) @@ -425,6 +469,7 @@ FROM %2 as t1 left join dev_info as t2 on t1.device = t2.tag_name").arg(strUnitF { sqlSequenceQuery.append(QString(" WHERE %1 ORDER BY SEQ_NO asc;").arg(strDeviceFilter)); } + pReadDb->execute(sqlSequenceQuery, query); while(query.next()) { @@ -436,18 +481,25 @@ FROM %2 as t1 left join dev_info as t2 on t1.device = t2.tag_name").arg(strUnitF //const QString devDesc = query.value(5).toString(); const QString strDescription = m_locationInfo[location] % QChar('.') % m_devGroupInfo[location][query.value(0).toString()] % QChar('.') % query.value(5).toString() % QChar('.') % query.value(2).toString(); m_listTagName[device] << tagName; - - //QString strUnitDesc = m_listTagUnit.value(query.value(5).toInt(), QString()); - // m_listTagInfo[tagName] = QStringList() << strDescription << strCurType << m_listTagUnit.value(query.value(5).toInt(), QString()); - QString strUnitDesc =""; - if(QStringLiteral("analog") == strCurType || QStringLiteral("accuml") == strCurType) - { - strUnitDesc = m_listTagUnit.value(query.value(6).toInt(), QString()); - } - m_listTagInfo[tagName] = QStringList() << strDescription << strCurType << strUnitDesc; + m_listTagInfo[tagName] = QStringList() << strDescription << strCurType << m_listTagUnit.value(query.value(6).toInt(), QString()); } } + + return true; +} + +void CTrendInfoManage::loadAllTagInfo(iot_dbms::CDbApi *pReadDb) +{ + QStringList listDevice; + QMap >::const_iterator iter = m_deviceInfo.constBegin(); + while (iter != m_deviceInfo.constEnd()) + { + listDevice.append(iter.value().keys()); + ++iter; + } + + loadTagInfo(pReadDb,listDevice); } void CTrendInfoManage::loadUnit(CDbApi *pReadDb) @@ -608,3 +660,47 @@ void CTrendInfoManage::initInvalidStatus() m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SINHIBIT_REF")); //< 屏蔽禁止刷新 m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SOURCE_ABNORMAL"));//< 数据来源不正常 } + +void CTrendInfoManage::loadCfg() +{ + QDomDocument document; + QString strFileName = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trend.xml"); + QFile file(strFileName); + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement root = document.documentElement(); + if(root.isNull()) + { + return; + } + + QDomNodeList paramNodeList = root.elementsByTagName("param"); + for(int graphIndex(0); graphIndex < paramNodeList.size(); graphIndex++) + { + QDomNode paramNode = paramNodeList.at(graphIndex); + if(paramNode.isNull()) + { + continue; + } + + QDomElement paramElement = paramNode.toElement(); + if(!paramElement.isNull()) + { + QString name = paramElement.attribute("name", QString()); + QString value = paramElement.attribute("value", QString()); + if(name == "loadTagInfoWhenInit") + { + m_bLoadTagInfoWhenInit = (value == "1"); + } + } + } +} diff --git a/product/src/gui/plugin/TrendCurves/CTrendInfoManage.h b/product/src/gui/plugin/TrendCurves/CTrendInfoManage.h index df7d03e3..23b07248 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendInfoManage.h +++ b/product/src/gui/plugin/TrendCurves/CTrendInfoManage.h @@ -7,7 +7,19 @@ #include #include "dbms/rdb_api/CRdbAccess.h" #include "dbms/db_api_ex/CDbApi.h" + +//< 屏蔽xml_parser编译告警 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-copy" +#endif + #include "boost/property_tree/xml_parser.hpp" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "boost/typeof/typeof.hpp" #include "boost/filesystem.hpp" @@ -62,13 +74,20 @@ public: QMap getAlarmOtherStatus(); + //加载指定设备组下测点的信息,为空代表加载所有设备组的测点 + bool loadTagInfoByDevGroup(const QString &strDevGrpTag); + //加载指定设备下的测点信息,为空代表加载所有设备 + bool loadTagInfoByDevTag(const QStringList &listDevTag); + private: CTrendInfoManage(); void loadRTLocation(); void loadDevGroupInfo(iot_dbms::CDbApi *pReadDb); //新增设备组 void loadDeviceInfo(iot_dbms::CDbApi *pReadDb); //新增设备组时修改 - void loadTagInfo(iot_dbms::CDbApi *pReadDb); + //strDevGrpTag为空加载所有设备组,如果不为空加载指定的设备组 + bool loadTagInfo(iot_dbms::CDbApi *pReadDb,const QStringList &listDevice = QStringList()); + void loadAllTagInfo(iot_dbms::CDbApi *pReadDb); void loadUnit(iot_dbms::CDbApi *pReadDb); void loadStateDefine(); void loadAlarmStatusDefine(); @@ -76,12 +95,13 @@ private: void loadAlarmOtherStatus(); void initInvalidStatus(); + void loadCfg(); + private: iot_dbms::CRdbAccess * m_rtdbAccess; QMap m_locationInfo; //< LocationID-LocationDesc QMap > m_devGroupInfo; //< LocationID- 新增设备组 QMap > > m_devGroupInfoMap; - QMap > m_devLocation; //< LocationID- 新增设备组 QMap > m_deviceInfo; //< DevGroupName- 新增设备组时修改 QMap m_listTagName; //< DeviceName-list QHash m_listTagInfo; //< TagName-TagInfo @@ -93,7 +113,7 @@ private: QList m_locationOrderList; //< location_id: 按location_no排序 int m_nInvalidAnalog; int m_nInvalidDigital; - + bool m_bLoadTagInfoWhenInit; //第一次是否加载所有的测点数据,默认加载 static CTrendInfoManage * m_pInstance; }; diff --git a/product/src/gui/plugin/TrendCurves/CTrendPluginWidget.h b/product/src/gui/plugin/TrendCurves/CTrendPluginWidget.h index 55a26a86..06c92ce7 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendPluginWidget.h +++ b/product/src/gui/plugin/TrendCurves/CTrendPluginWidget.h @@ -7,7 +7,7 @@ class CTrendPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/TrendCurves/CTrendTreeModel.cpp b/product/src/gui/plugin/TrendCurves/CTrendTreeModel.cpp index 929c1cc3..52989220 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendTreeModel.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendTreeModel.cpp @@ -65,13 +65,12 @@ void CTrendTreeModel::initTrendTagInfo() ++iter_device; continue; } -// QTreeWidgetItem * devItem = new QTreeWidgetItem(devGroupItem, QStringList() << iter_device.value(), DEV_TYPE); -// devItem->setData(0, ItemTagRole, iter_device.key()); + QTreeWidgetItem * devItem = new QTreeWidgetItem(devGroupItem, QStringList() << iter_device.value(), DEV_TYPE); + devItem->setData(0, ItemTagRole, iter_device.key()); QStringList::const_iterator iter_tag = listTagName.constBegin(); while (iter_tag != listTagName.constEnd()) { -// QTreeWidgetItem * tagItem = new QTreeWidgetItem(devItem, QStringList() << CTrendInfoManage::instance()->getTagDescription(*iter_tag).section(".", -1), TAG_TYPE); - QTreeWidgetItem * tagItem = new QTreeWidgetItem(devGroupItem, QStringList() << CTrendInfoManage::instance()->getTagDescription(*iter_tag).section(".", -1), TAG_TYPE); + QTreeWidgetItem * tagItem = new QTreeWidgetItem(devItem, QStringList() << CTrendInfoManage::instance()->getTagDescription(*iter_tag).section(".", -1), TAG_TYPE); tagItem->setData(0, ItemTagRole, *iter_tag); tagItem->setToolTip(0, *iter_tag); ++iter_tag; @@ -86,10 +85,10 @@ void CTrendTreeModel::initTrendTagInfo() { return; } - for(int n=0; nchildCount(); n++) - { - m_pView->expand(index(n,0)); - } +// for(int n=0; nchildCount(); n++) +// { +// m_pView->expand(index(n,0)); +// } } void CTrendTreeModel::clearTrendTagInfo() @@ -210,7 +209,6 @@ QVariant CTrendTreeModel::data(const QModelIndex &index, int role) const bool CTrendTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) { - if(!index.isValid()) { return false; @@ -221,7 +219,11 @@ bool CTrendTreeModel::setData(const QModelIndex &index, const QVariant &value, i { if(Qt::CheckStateRole == role) { - emit itemCheckStateChanged(item->data(0, ItemTagRole).toString(), value.toInt()); + //只有状态发生变化才更新,否则在单个设备测点数量过多的时候,清空动作会时间很长 + if(item->checkState(0) != value.toInt()) + { + emit itemCheckStateChanged(item->data(0, ItemTagRole).toString(), value.toInt()); + } } item->setData(index.column(), role, value); } @@ -254,8 +256,7 @@ void CTrendTreeModel::setChildrenCheckState(const QModelIndex &index, const Qt:: { return; } -// if(DEV_TYPE == item->type()) - if(DEV_GROUP_TYPE == item->type()) + if(DEV_TYPE == item->type()) { for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) { @@ -279,6 +280,22 @@ void CTrendTreeModel::updateNodeVisualState(const QString &content, QItemSelecti } } +void CTrendTreeModel::loadTagInfoByDevGroup(const QString &strDevGrpTag) +{ + if(CTrendInfoManage::instance()->loadTagInfoByDevGroup(strDevGrpTag)) + { + initTrendTagInfo(); + } +} + +void CTrendTreeModel::loadTagInfoByDevTag(const QStringList &listDevTag) +{ + if(CTrendInfoManage::instance()->loadTagInfoByDevTag(listDevTag)) + { + initTrendTagInfo(); + } +} + bool CTrendTreeModel::traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection) { if(!index.isValid()) @@ -378,16 +395,16 @@ void CTrendTreeModel::updateTagCheckState(const QString &tag, const bool &checke QTreeWidgetItem * deviceGroupItem = locationItem->child(nDeviceGroupRow); for(int nDeviceRow(0); nDeviceRow < deviceGroupItem->childCount(); nDeviceRow++) { -// QTreeWidgetItem * deviceItem = deviceGroupItem->child(nDeviceRow); -// for(int nTagRow(0); nTagRow < deviceItem->childCount(); nTagRow++) -// { - QTreeWidgetItem * tagItem = deviceGroupItem->child(nDeviceRow); + QTreeWidgetItem * deviceItem = deviceGroupItem->child(nDeviceRow); + for(int nTagRow(0); nTagRow < deviceItem->childCount(); nTagRow++) + { + QTreeWidgetItem * tagItem = deviceItem->child(nTagRow); if(tag == tagItem->data(0, ItemTagRole).toString()) { tagItem->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked); return; } -// } + } } } } diff --git a/product/src/gui/plugin/TrendCurves/CTrendTreeModel.h b/product/src/gui/plugin/TrendCurves/CTrendTreeModel.h index 30c59a77..36748ab0 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendTreeModel.h +++ b/product/src/gui/plugin/TrendCurves/CTrendTreeModel.h @@ -45,6 +45,12 @@ public: void updateNodeVisualState(const QString &content, QItemSelection &selection); + //加载指定设备组下测点的信息,为空代表加载所有设备组的测点 + void loadTagInfoByDevGroup(const QString &strDevGrpTag); + + //加载指定设备下的测点信息,为空代表加载所有设备 + void loadTagInfoByDevTag(const QStringList &listDevTag); + signals: void itemCheckStateChanged(const QString &strTagName, const int &checkedState); diff --git a/product/src/gui/plugin/TrendCurves/CTrendTreeView.cpp b/product/src/gui/plugin/TrendCurves/CTrendTreeView.cpp index d28d2142..c4c9fc7d 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendTreeView.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendTreeView.cpp @@ -18,8 +18,7 @@ void CTrendTreeView::contextMenuEvent(QContextMenuEvent *event) QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); if(Q_NULLPTR != pItem) { -// if(DEV_TYPE == pItem->type()) - if(DEV_GROUP_TYPE == pItem->type()) + if(DEV_TYPE == pItem->type()) { QMenu menu; menu.addAction(tr("全选"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Checked); }); @@ -54,6 +53,12 @@ void CTrendTreeView::mouseDoubleClickEvent(QMouseEvent *event) pModel->setData(index, state, Qt::CheckStateRole); update(); } + else if(DEV_GROUP_TYPE == pItem->type()) + { + int row=pModel->parent(index).row(); + pModel->loadTagInfoByDevGroup(pItem->data(0,ItemTagRole).toString()); + expand(pModel->index(row,0)); + } } } return QTreeView::mouseDoubleClickEvent(event); diff --git a/product/src/gui/plugin/TrendCurves/CTrendWindow.cpp b/product/src/gui/plugin/TrendCurves/CTrendWindow.cpp index 5ac3bae5..32f5ff54 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendWindow.cpp +++ b/product/src/gui/plugin/TrendCurves/CTrendWindow.cpp @@ -218,6 +218,14 @@ void CTrendWindow::setAlarmPointVisible(bool visible) } } +void CTrendWindow::setPreCurveVisible(bool visible) +{ + if(m_plotWidget) + { + m_plotWidget->setPreCurveVisible(visible); + } +} + void CTrendWindow::initWindow() { m_pTagWidget = new QTabWidget(this); @@ -246,6 +254,8 @@ void CTrendWindow::initWindow() m_pTagWidget->addTab(pFavoritesTreeWidget, tr("收藏夹")); m_pTagWidget->setContentsMargins(1,1,1,1); m_pTagWidget->setCurrentIndex(1); + m_pTagWidget->setMinimumWidth(290); + m_plotWidget = new CPlotWidget(this); m_plotWidget->initialize(); m_pSplitter = new QSplitter(this); @@ -264,6 +274,7 @@ void CTrendWindow::initWindow() connect(m_plotWidget, &CPlotWidget::updateTagCheckState, m_pTrendTreeModel, &CTrendTreeModel::updateTagCheckState, Qt::QueuedConnection); connect(m_pTrendTreeModel, &CTrendTreeModel::itemCheckStateChanged, this, &CTrendWindow::itemCheckStateChanged); connect(pFavoritesTreeWidget, &CTrendFavTreeWidget::showTrendGraph, this, &CTrendWindow::showTrendGraph); + connect(pFavoritesTreeWidget, &CTrendFavTreeWidget::updateTitle, this, &CTrendWindow::setTitle); if(!m_isEditMode) { @@ -480,6 +491,13 @@ void CTrendWindow::updateTrendName(const QString &title) void CTrendWindow::showTrendGraph(CTrendGraph *graph, const QString &name) { + QStringList devList; + foreach (Curve cur, graph->curves()) { + devList << cur.tag.left(cur.tag.lastIndexOf(".")); + } + + m_pTrendTreeModel->loadTagInfoByDevTag(devList); + m_plotWidget->clear(); if(!name.isEmpty()) { @@ -541,3 +559,27 @@ bool CTrendWindow::eventFilter(QObject *watched, QEvent *event) return QWidget::eventFilter(watched, event); } +void CTrendWindow::setEnableAddNanFlag(bool bEnable) +{ + if(m_plotWidget) + { + m_plotWidget->setEnableAddNanFlag(bEnable); + } +} + +void CTrendWindow::clearCustomInterval() +{ + if(m_plotWidget) + { + m_plotWidget->clearCustomInterval(); + } +} + +void CTrendWindow::addCustomInterval(const QString &desc, const int &sec) +{ + if(m_plotWidget) + { + m_plotWidget->addCustomInterval(desc,sec); + } +} + diff --git a/product/src/gui/plugin/TrendCurves/CTrendWindow.h b/product/src/gui/plugin/TrendCurves/CTrendWindow.h index 078ea172..0769381a 100644 --- a/product/src/gui/plugin/TrendCurves/CTrendWindow.h +++ b/product/src/gui/plugin/TrendCurves/CTrendWindow.h @@ -48,6 +48,12 @@ public slots: void setDevTreeVisible(bool visible); void setAdaptVisible(bool visible); void setAlarmPointVisible(bool visible); + void setPreCurveVisible(bool visible); + void setEnableAddNanFlag(bool bEnable); //caodingfa:定时存盘周期可变时,原有逻辑会导致每个间隔插入一个Nan值,导致无效,为不影响原逻辑,增加一个开关 + + //用于重新设置自定义界面中的周期间隔 + void clearCustomInterval(); + void addCustomInterval(const QString &desc,const int &sec); void login(); void logout(); diff --git a/product/src/gui/plugin/TrendCurves/TrendCurves.pro b/product/src/gui/plugin/TrendCurves/TrendCurves.pro index 64b6db69..e6c2902c 100644 --- a/product/src/gui/plugin/TrendCurves/TrendCurves.pro +++ b/product/src/gui/plugin/TrendCurves/TrendCurves.pro @@ -7,6 +7,7 @@ QT += core gui widgets sql xml printsupport + TARGET = TrendCurves TEMPLATE = lib @@ -14,6 +15,7 @@ CONFIG += plugin INCLUDEPATH += $$PWD + SOURCES += \ $$PWD/plot/qcustomplot.cpp \ $$PWD/widgets/CTabButton.cpp \ @@ -23,6 +25,8 @@ SOURCES += \ $$PWD/widgets/QxtSpanSlider.cpp \ $$PWD/widgets/CSWitchButton.cpp \ $$PWD/widgets/CSliderRangeWidget.cpp \ + $$PWD/widgets/CMyCheckBox.cpp \ + $$PWD/widgets/CMyListWidget.cpp \ CTrendWindow.cpp \ CTrendGraph.cpp \ CPlotWidget.cpp \ @@ -39,11 +43,8 @@ SOURCES += \ CTrendTreeView.cpp \ CHisDataManage.cpp \ CCurveLegendView.cpp \ - CMyCheckBox.cpp \ - CMyListWidget.cpp \ CTableDataModel.cpp \ CTableView.cpp -# main.cpp HEADERS += \ $$PWD/plot/qcustomplot.h \ @@ -55,6 +56,8 @@ HEADERS += \ $$PWD/widgets/QxtSpanSlider_p.h \ $$PWD/widgets/CSWitchButton.h \ $$PWD/widgets/CSliderRangeWidget.h \ + $$PWD/widgets/CMyCheckBox.h \ + $$PWD/widgets/CMyListWidget.h \ CTrendWindow.h \ CTrendGraph.h \ CPlotWidget.h \ @@ -71,8 +74,6 @@ HEADERS += \ CTrendTreeView.h \ CHisDataManage.h \ CCurveLegendView.h \ - CMyCheckBox.h \ - CMyListWidget.h \ CTableDataModel.h \ CTableView.h @@ -83,7 +84,7 @@ FORMS += \ LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -lmodel_excel LIBS += -lpub_utility_api -lpub_sysinfo_api LIBS += -ldb_base_api -ldb_api_ex -lrdb_api -lrdb_net_api -ltsdb_api -ldb_his_query_api -LIBS += -lnet_msg_bus_api -lperm_mng_api -ldp_chg_data_api -lRetriever +LIBS += -lnet_msg_bus_api -lperm_mng_api -ldp_chg_data_api -lRetriever -lpub_widget include($$PWD/../../../idl_files/idl_files.pri) diff --git a/product/src/gui/plugin/TrendCurves/main.cpp b/product/src/gui/plugin/TrendCurves/main.cpp index ee72bb87..4e651cea 100644 --- a/product/src/gui/plugin/TrendCurves/main.cpp +++ b/product/src/gui/plugin/TrendCurves/main.cpp @@ -18,7 +18,7 @@ int main(int argc, char *argv[]) return -1; } - if(perm->SysLogin("1", "1", 1, 12*60*60, "hmi") != 0) + if(perm->SysLogin("admin", "admin", 1, 12*60*60, "hmi") != 0) { return -1; } diff --git a/product/src/gui/plugin/TrendCurves/plot/qcustomplot.cpp b/product/src/gui/plugin/TrendCurves/plot/qcustomplot.cpp index c35c5fd9..bfd47151 100644 --- a/product/src/gui/plugin/TrendCurves/plot/qcustomplot.cpp +++ b/product/src/gui/plugin/TrendCurves/plot/qcustomplot.cpp @@ -6062,16 +6062,23 @@ QString QCPAxisTickerDateTime::getTickLabel(double tick, const QLocale &locale, QVector QCPAxisTickerDateTime::createTickVector(double tickStep, const QCPRange &range) { QVector result = QCPAxisTicker::createTickVector(tickStep, range); + if (!result.isEmpty()) { if (mDateStrategy == dsUniformTimeInDay) { QDateTime uniformDateTime = keyToDateTime(mTickOrigin); // the time of this datetime will be set for all other ticks, if possible QDateTime tickDateTime; + int nOffsetToUTC = 0 - uniformDateTime.offsetFromUtc(); for (int i=0; i QCPAxisTickerDateTime::createTickVector(double tickStep, const Q tickDateTime.setDate(QDate(tickDateTime.date().year(), tickDateTime.date().month(), thisUniformDay)); result[i] = dateTimeToKey(tickDateTime); } + } else if(tickStep >= 43200000) + { + QDateTime curTime = QDateTime::currentDateTime(); + int nOffset = curTime.offsetFromUtc() * 1000; + for(int i = 1; i < result.size() - 1;++i) + { + result[i] = result[i] - nOffset; + } } + } return result; } @@ -10732,6 +10748,11 @@ void QCPAbstractPlottable::setDesc(const QString &desc) mDesc = desc; } +void QCPAbstractPlottable::setType(const int &type) +{ + mType = type; +} + /*! Sets whether fills of this plottable are drawn antialiased or not. diff --git a/product/src/gui/plugin/TrendCurves/plot/qcustomplot.h b/product/src/gui/plugin/TrendCurves/plot/qcustomplot.h index 6208f928..e630f91f 100644 --- a/product/src/gui/plugin/TrendCurves/plot/qcustomplot.h +++ b/product/src/gui/plugin/TrendCurves/plot/qcustomplot.h @@ -3310,6 +3310,7 @@ public: // getters: QString name() const { return mName; } QString desc() const { return mDesc; } + int type() const { return mType; } bool antialiasedFill() const { return mAntialiasedFill; } bool antialiasedScatters() const { return mAntialiasedScatters; } QPen pen() const { return mPen; } @@ -3324,6 +3325,7 @@ public: // setters: void setName(const QString &name); void setDesc(const QString &desc); + void setType(const int &type); void setAntialiasedFill(bool enabled); void setAntialiasedScatters(bool enabled); void setPen(const QPen &pen); @@ -3362,6 +3364,7 @@ protected: // property members: QString mName; QString mDesc; + int mType; bool mAntialiasedFill, mAntialiasedScatters; QPen mPen; QBrush mBrush; diff --git a/product/src/gui/plugin/TrendCurves/widgets/CMyCheckBox.cpp b/product/src/gui/plugin/TrendCurves/widgets/CMyCheckBox.cpp new file mode 100644 index 00000000..2b37e36c --- /dev/null +++ b/product/src/gui/plugin/TrendCurves/widgets/CMyCheckBox.cpp @@ -0,0 +1,21 @@ +#include "CMyCheckBox.h" +#include + +CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) + :QCheckBox(text,parent) +{ + +} + +CMyCheckBox::CMyCheckBox(QWidget *parent) + :QCheckBox(parent) +{ + +} + +void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) +{ + Q_UNUSED(e) + setChecked(!isChecked()); + emit clicked(isChecked()); +} diff --git a/product/src/gui/plugin/TrendCurves/widgets/CMyCheckBox.h b/product/src/gui/plugin/TrendCurves/widgets/CMyCheckBox.h new file mode 100644 index 00000000..1dad82e3 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves/widgets/CMyCheckBox.h @@ -0,0 +1,16 @@ +#ifndef MYCHECKBOX_H +#define MYCHECKBOX_H + +#include + +class CMyCheckBox : public QCheckBox +{ +public: + CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); + CMyCheckBox(QWidget *parent = Q_NULLPTR); + +protected: + void mouseReleaseEvent(QMouseEvent *e); +}; + +#endif // MYCHECKBOX_H diff --git a/product/src/gui/plugin/TrendCurves/widgets/CMyListWidget.cpp b/product/src/gui/plugin/TrendCurves/widgets/CMyListWidget.cpp new file mode 100644 index 00000000..fa73a493 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves/widgets/CMyListWidget.cpp @@ -0,0 +1,12 @@ +#include "CMyListWidget.h" + +CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) +{ + +} + +void CMyListWidget::showEvent(QShowEvent *event) +{ + this->updateGeometries(); + QListWidget::showEvent(event); +} diff --git a/product/src/gui/plugin/TrendCurves/widgets/CMyListWidget.h b/product/src/gui/plugin/TrendCurves/widgets/CMyListWidget.h new file mode 100644 index 00000000..728f308d --- /dev/null +++ b/product/src/gui/plugin/TrendCurves/widgets/CMyListWidget.h @@ -0,0 +1,15 @@ +#ifndef CMYLISTWIDGET_H +#define CMYLISTWIDGET_H + +#include + +class CMyListWidget : public QListWidget +{ +public: + explicit CMyListWidget(QWidget *parent = 0); + +protected: + void showEvent(QShowEvent *event); +}; + +#endif // CMYLISTWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves/widgets/CSWitchButton.cpp b/product/src/gui/plugin/TrendCurves/widgets/CSWitchButton.cpp index 66afc5a5..af418f62 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CSWitchButton.cpp +++ b/product/src/gui/plugin/TrendCurves/widgets/CSWitchButton.cpp @@ -34,15 +34,18 @@ void CSWitchButton::paintEvent(QPaintEvent *event) QColor background; QColor handleColor; QString text; + QString unSelectText; if (isEnabled()) { // 可用状态 if (m_bChecked) { // 打开状态 background = m_checkedColor; handleColor = m_handleColor; text = m_strText; + unSelectText=m_strCheckText; } else { //关闭状态 background = m_background; handleColor = m_handleColor; text = m_strCheckText; + unSelectText=m_strText; } } else { // 不可用状态 background = m_disabledColor; @@ -59,6 +62,7 @@ void CSWitchButton::paintEvent(QPaintEvent *event) painter.drawRoundedRect(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), width()/2, height()), m_radius, m_radius); painter.setPen(m_textColor); painter.drawText(QRectF(width()/2 - m_nX + (m_nHeight / 2), height()/5, width()/2, height()), text); + painter.drawText(QRectF(m_nX, height()/5, width()/2, height()), unSelectText); } // 鼠标按下事件 diff --git a/product/src/gui/plugin/TrendCurves/widgets/CToolTip.cpp b/product/src/gui/plugin/TrendCurves/widgets/CToolTip.cpp index ac07bd68..3c455114 100644 --- a/product/src/gui/plugin/TrendCurves/widgets/CToolTip.cpp +++ b/product/src/gui/plugin/TrendCurves/widgets/CToolTip.cpp @@ -74,7 +74,7 @@ void CToolTip::on_pushButton_clicked() QString alarmTime,alarmContent; QStringList header; header<setHorizontalHeaderLabels(header); + model->setHorizontalHeaderLabels(header); QHeaderView *rowHeader = alarmTable->verticalHeader(); rowHeader->setHidden(true); for(int i = 0;i < rowCount;i++) @@ -91,7 +91,7 @@ void CToolTip::on_pushButton_clicked() alarmTable->setModel(model); alarmTable->resizeColumnsToContents(); alarmTable->setObjectName("m_tipAlarmTable"); - alarmTable->resize(470,300); + alarmTable->resize(800,400); alarmTable->setWindowFlags(alarmTable->windowFlags()&~(Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint)); alarmTable->horizontalHeader()->setStretchLastSection(true); alarmTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); diff --git a/product/src/gui/plugin/TrendCurves_pad/CCurveLegendModel.cpp b/product/src/gui/plugin/TrendCurves_pad/CCurveLegendModel.cpp new file mode 100644 index 00000000..9cff9756 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CCurveLegendModel.cpp @@ -0,0 +1,579 @@ +#include "CCurveLegendModel.h" +#include "CTrendGraph.h" +#include +#include +#include +#include +#include +#include + +ColorWidget::ColorWidget(QWidget *parent) + : QWidget(parent) +{ + setStyleSheet(""); +} + +ColorWidget::~ColorWidget() +{ +} + +void ColorWidget::setColor(const QColor &color) +{ + this->m_color = color; + emit colorChanged(); +} + +QColor ColorWidget::color() const +{ + return m_color; +} + +void ColorWidget::updateCurrentColor() +{ + QColorDialog dlg(this); + dlg.setOption(QColorDialog::DontUseNativeDialog); + dlg.setWindowFlag(Qt::FramelessWindowHint); + dlg.setCurrentColor(m_color); + dlg.exec(); + if(dlg.selectedColor().isValid()) + { + setColor(dlg.selectedColor()); + } +} + +void ColorWidget::paintEvent(QPaintEvent *event) +{ + QPainter p(this); + p.setPen(Qt::white); + p.setBrush(m_color); + p.drawRect(rect().adjusted(3, 6, -3, -6)); + QWidget::paintEvent(event); +} + +void ColorWidget::mousePressEvent(QMouseEvent *event) +{ + QWidget::mousePressEvent(event); + updateCurrentColor(); +} + + +CCurveLegnedDelegate::CCurveLegnedDelegate(QObject *parent) + : QStyledItemDelegate(parent) +{ + +} + +void CCurveLegnedDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItem viewOption(option); + initStyleOption(&viewOption, index); + if (option.state.testFlag(QStyle::State_HasFocus)) + { + viewOption.state = viewOption.state ^ QStyle::State_HasFocus; + } + QStyledItemDelegate::paint(painter, viewOption, index); + + if(!index.isValid() || !const_cast(index.model())) + { + return; + } + CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); + if(!model) + { + return; + } + + if(CCurveLegendModel::COLOR == index.column()) + { + painter->save(); + painter->fillRect(option.rect.adjusted(3, 6, -3, -6), QBrush(Qt::white)); + painter->fillRect(option.rect.adjusted(3, 6, -3, -6), QBrush(model->data(index).value())); + painter->restore(); + } +} + +QWidget *CCurveLegnedDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option) + if(!index.isValid() || !const_cast(index.model())) + { + return Q_NULLPTR; + } + CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); + if(!model) + { + return Q_NULLPTR; + } + + if(CCurveLegendModel::COLOR == index.column()) + { + ColorWidget * colorWidget = new ColorWidget(parent); + connect(colorWidget, &ColorWidget::colorChanged, this, &CCurveLegnedDelegate::slotColorChangde); + return colorWidget; + } + if(CCurveLegendModel::FACTOR == index.column() || CCurveLegendModel::OFFSET == index.column()) + { + QDoubleSpinBox * spinBox = new QDoubleSpinBox(parent); + return spinBox; + } + + return Q_NULLPTR; +} + +void CCurveLegnedDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + if(!index.isValid() || Q_NULLPTR == editor) + { + return; + } + + CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); + if(!model) + { + return; + } + + if(CCurveLegendModel::COLOR == index.column()) + { + ColorWidget * colorWidget = dynamic_cast(editor); + if(colorWidget) + { + colorWidget->setColor(model->data(index).value()); + } + return; + } + if(CCurveLegendModel::FACTOR == index.column() || CCurveLegendModel::OFFSET == index.column()) + { + QDoubleSpinBox * spinBox = dynamic_cast(editor); + if(spinBox) + { + spinBox->setValue(model->data(index).toDouble()); + spinBox->setSingleStep(1.); + spinBox->setMaximum(10000); + spinBox->setMinimum(-10000); + } + return; + } + return; +} + +void CCurveLegnedDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + if(!index.isValid() || !const_cast(index.model())) + { + return; + } + if(!model) + { + return; + } + + if(dynamic_cast(editor)) + { + model->setData(index, dynamic_cast(editor)->value()); + return; + } + else if(dynamic_cast(editor)) + { + model->setData(index, dynamic_cast(editor)->color()); + return; + } + +} + +bool CCurveLegnedDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ +// if(index.column() == 0 && event->type() == QEvent::MouseButtonPress) +// { +// QMouseEvent *mouseEvent = static_cast(event); +// if(mouseEvent->button() == Qt::LeftButton && option.rect.contains(mouseEvent->pos())) +// { +// if(const_cast(index.model())) +// { +// CCurveLegendModel * model = dynamic_cast(const_cast(index.model())); +// if(!model) +// { +// return QStyledItemDelegate::editorEvent(event, model, option, index); +// } +// } +// } +// } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +void CCurveLegnedDelegate::slotColorChangde() +{ + QWidget * pWidget = dynamic_cast(sender()); + if(pWidget) + { + emit commitData(pWidget); + emit closeEditor(pWidget); + } +} + +CCurveLegendModel::CCurveLegendModel(QObject *parent) + : QAbstractTableModel(parent), m_lengedMode(), + m_graph(Q_NULLPTR) +{ + m_header << tr("设备组-测点") << tr("颜色") << tr("值") << tr("最大值") << tr("最大值时间") << tr("最小值") << tr("最小值时间") << tr("平均值") + << tr("单位") << tr("Y轴缩放系数") << tr("Y轴偏移系数"); +} + +void CCurveLegendModel::setMode(const CCurveLegendModel::LengedMode &mode) +{ + m_lengedMode = mode; + update(); +} + +CCurveLegendModel::LengedMode CCurveLegendModel::getMode() +{ + return m_lengedMode; +} + +void CCurveLegendModel::setTrendGraph(CTrendGraph *graph) +{ + if(nullptr == graph) + { + return; + } + + beginResetModel(); + m_graph = graph; + endResetModel(); +} + +void CCurveLegendModel::setTrendCurrentValues(QList list) +{ + m_currentValue.swap(list); + update(); +} + +void CCurveLegendModel::update() +{ + QModelIndex topLeft = createIndex(0, VALUE); + QModelIndex bottomRight = createIndex(rowCount() - 1, columnCount() - 1); + emit dataChanged(topLeft, bottomRight); +} + +void CCurveLegendModel::clear() +{ + beginResetModel(); + m_graph = Q_NULLPTR; + m_currentValue.clear(); + endResetModel(); +} + +QVariant CCurveLegendModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + return m_header.at(section); + } + } + return QVariant(); +} + +int CCurveLegendModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid() || Q_NULLPTR == m_graph) + return 0; + + return m_graph->curves().count(); +} + +int CCurveLegendModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid() || Q_NULLPTR == m_graph) + return 0; + + return m_header.count(); +} + +QVariant CCurveLegendModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid() || Q_NULLPTR == m_graph) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == NAME) + { + return QVariant(Qt::AlignLeft | Qt::AlignVCenter); + } + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + + if(Qt::CheckStateRole == role && NAME == index.column()) + { + if(m_graph->curves().at(index.row()).visible) + { + return Qt::Checked; + } + else + { + return Qt::Unchecked; + } + } + + if(Qt::DisplayRole != role) + { + return QVariant(); + } + + Curve curve = m_graph->curves().at(index.row()); + switch (index.column()) + { + case NAME: + { + return curve.desc; + } + break; + case COLOR: + { + return curve.color; + } + break; + case VALUE: + { + if(qIsNaN(m_currentValue.value(index.row()))) + { + return QString("-"); + } + else + { + return QString::number(m_currentValue.value(index.row()), 'f', 2); + } + } + break; + case MAX: + { + if(LENGED_RT_MODE == m_lengedMode) + { + if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.rtMax) < _EPSILON_) + { + return QString("--"); + } + return QString::number(curve.rtMax, 'f', 2); + } + else + { + if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.sHisMax) < _EPSILON_) + { + return QString("--"); + } + return QString::number(curve.sHisMax, 'f', 2); + } + } + break; + case MAXTIME: + { + if(LENGED_RT_MODE == m_lengedMode) + { + if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.rtMaxTime) < _EPSILON_) + { + return QString("--"); + } + return QDateTime::fromMSecsSinceEpoch(curve.rtMaxTime).toString("hh:mm:ss"); + } + else + { + if("digital" == curve.type || "mix" == curve.type || qAbs((-DBL_MAX) - curve.sHisMaxTime) < _EPSILON_) + { + return QString("--"); + } + return QDateTime::fromMSecsSinceEpoch(curve.sHisMaxTime).toString("yyyy-MM-dd hh:mm:ss"); + } + } + break; + case MIN: + { + if(LENGED_RT_MODE == m_lengedMode) + { + if("digital" == curve.type || "mix" == curve.type || qAbs(DBL_MAX - curve.rtMin) < _EPSILON_) + { + return QString("--"); + } + return QString::number(curve.rtMin, 'f', 2); + } + else + { + if("digital" == curve.type || "mix" == curve.type || qAbs(DBL_MAX - curve.sHisMin) < _EPSILON_) + { + return QString("--"); + } + return QString::number(curve.sHisMin, 'f', 2); + } + } + break; + case MINTIME: + { + if(LENGED_RT_MODE == m_lengedMode) + { + if("digital" == curve.type || "mix" == curve.type || qAbs((DBL_MAX) - curve.rtMinTime) < _EPSILON_) + { + return QString("--"); + } + return QDateTime::fromMSecsSinceEpoch(curve.rtMinTime).toString("hh:mm:ss"); + } + else + { + if("digital" == curve.type || "mix" == curve.type || qAbs((DBL_MAX) - curve.sHisMinTime) < _EPSILON_) + { + return QString("--"); + } + return QDateTime::fromMSecsSinceEpoch(curve.sHisMinTime).toString("yyyy-MM-dd hh:mm:ss"); + } + } + break; + case AVE: + { + + if(LENGED_RT_MODE == m_lengedMode) + { + if("analog" != curve.type || qAbs((-DBL_MAX) - curve.rtAverage) < _EPSILON_ || qIsNaN(curve.rtAverage)) + { + return QString("--"); + } + return QString::number(curve.rtAverage, 'f', 2); + } + else + { + if("analog" != curve.type || qAbs((-DBL_MAX) - curve.hisAverage) < _EPSILON_ || qIsNaN(curve.hisAverage)) + { + return QString("--"); + } + return QString::number(curve.hisAverage, 'f', 2); + } + } + break; + case UNIT: + { + if(curve.unit.isEmpty()) + { + return QString("--"); + } + return curve.unit; + } + break; + case FACTOR: + { + return curve.factor; + } + break; + case OFFSET: + { + return curve.offset; + } + break; + default: + break; + } + + return QVariant(); +} + +bool CCurveLegendModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(!index.isValid()) + { + return false; + } + if(Qt::CheckStateRole == role && NAME == index.column()) + { + m_graph->setCurveVisible(index.row(), value.toBool()); + emit graphVisibleChanged(value.toBool()); + return true; + } + if(Qt::EditRole != role) + { + return false; + } + + if(COLOR == index.column()) + { + m_graph->setCurveColor(index.row(), value.value()); + } + if(FACTOR == index.column()) + { + m_graph->setCurveFactor(index.row(), value.toDouble()); + } + else if(OFFSET == index.column()) + { + m_graph->setCurveOffset(index.row(), value.toDouble()); + } + emit graphPropertyChanged(); + + QModelIndex topLeft = createIndex(0, 0); + QModelIndex bottomright = createIndex(rowCount() - 1, columnCount() - 1); + emit dataChanged(topLeft, bottomright); + + return true; +} + +Qt::ItemFlags CCurveLegendModel::flags(const QModelIndex &index) const +{ + if(!index.isValid()) + { + return Qt::NoItemFlags; + } + + Qt::ItemFlags itemFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + if(COLOR == index.column() || FACTOR == index.column() || OFFSET == index.column()) + { + itemFlags |= Qt::ItemIsEditable; + } + else if(NAME == index.column()) + { + itemFlags |= Qt::ItemIsUserCheckable; + } + + return itemFlags; +} + +void CCurveLegendModel::setChildrenCheckState(const Qt::CheckState &state) +{ + for(int nChildIndex(0); nChildIndex < rowCount(); nChildIndex++) + { + m_graph->setCurveVisible(nChildIndex, state); + } + emit graphVisibleChanged(state == Qt::Checked ? true : false); +} + +void CCurveLegendModel::deleteSelectGraph() +{ + emit deleteCurrentGraph(); +} + +void CCurveLegendModel::jumpToMaxTime(const QModelIndex &index) +{ + if(!index.isValid()) + { + return; + } + + Curve curve = m_graph->curves().at(index.row()); + if(qAbs((-DBL_MAX) - curve.sHisMaxTime) < _EPSILON_) + { + return; + } + emit sigJumpToMaxTime(curve.sHisMaxTime); +} + +void CCurveLegendModel::jumpToMinTime(const QModelIndex &index) +{ + if(!index.isValid()) + { + return; + } + + Curve curve = m_graph->curves().at(index.row()); + if(qAbs((DBL_MAX) - curve.sHisMinTime) < _EPSILON_) + { + return; + } + emit sigJumpToMinTime(curve.sHisMinTime); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CCurveLegendModel.h b/product/src/gui/plugin/TrendCurves_pad/CCurveLegendModel.h new file mode 100644 index 00000000..98dce1b9 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CCurveLegendModel.h @@ -0,0 +1,124 @@ +#ifndef CCURVELEGENDMODEL_H +#define CCURVELEGENDMODEL_H + +#include +#include +#include + + +class CTrendGraph; + +class ColorWidget : public QWidget +{ + Q_OBJECT +public: + explicit ColorWidget(QWidget *parent=Q_NULLPTR); + ~ColorWidget(); + + void setColor(const QColor &color); + QColor color() const; + + void updateCurrentColor(); + +signals: + void colorChanged(); + +protected: + void paintEvent(QPaintEvent * event); + void mousePressEvent(QMouseEvent *event); + +private: + QColor m_color; +}; + +class CCurveLegnedDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CCurveLegnedDelegate(QObject *parent = nullptr); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; + + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + +protected: + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); + +private slots: + void slotColorChangde(); +}; + +class CCurveLegendModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + enum LengedMode + { + LENGED_RT_MODE = 0, + LENGED_HIS_MODE + }; + + enum ColumnField + { + NAME = 0, + COLOR, + VALUE, + MAX, + MAXTIME, + MIN, + MINTIME, + AVE, + UNIT, + FACTOR, + OFFSET + }; + + + explicit CCurveLegendModel(QObject *parent = nullptr); + + void setMode(const LengedMode &mode); + LengedMode getMode(); + + void setTrendGraph(CTrendGraph * graph); + + void setTrendCurrentValues(QList list); + + void update(); + + void clear(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + Qt::ItemFlags flags(const QModelIndex &index) const; + + void setChildrenCheckState(const Qt::CheckState &state); + void deleteSelectGraph(); + void jumpToMaxTime(const QModelIndex &index); + void jumpToMinTime(const QModelIndex &index); + +signals: + void graphVisibleChanged(const bool &check); + void graphPropertyChanged(); + void deleteCurrentGraph(); + void sigJumpToMaxTime(const double &time); + void sigJumpToMinTime(const double &time); + +private: + LengedMode m_lengedMode; + QStringList m_header; + CTrendGraph * m_graph; + QList m_currentValue; +}; + +#endif // CCURVELEGENDMODEL_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CCurveLegendView.cpp b/product/src/gui/plugin/TrendCurves_pad/CCurveLegendView.cpp new file mode 100644 index 00000000..bbee2ec7 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CCurveLegendView.cpp @@ -0,0 +1,72 @@ +#include "CCurveLegendView.h" +#include "CCurveLegendModel.h" +#include +#include +#include +#include +#include +#include "pub_utility_api/FileStyle.h" + + +CCurveLegendView::CCurveLegendView(QWidget *parent) + : CTableView(parent) +{ + +} + +void CCurveLegendView::contextMenuEvent(QContextMenuEvent *event) +{ + CCurveLegendModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QMenu menu(this); + menu.addAction(tr("全不选"), [=](){ pModel->setChildrenCheckState(Qt::Unchecked); }); + menu.addAction(tr("删除"),[=](){ pModel->deleteSelectGraph(); }); + if(pModel->getMode() != CCurveLegendModel::LENGED_RT_MODE) + { + menu.addAction(tr("查看最大值"),[=](){ pModel->jumpToMaxTime(currentIndex()); }); + menu.addAction(tr("查看最小值"),[=](){ pModel->jumpToMinTime(currentIndex()); }); + } + menu.exec(event->globalPos()); + } + return; +} + +void CCurveLegendView::mouseDoubleClickEvent(QMouseEvent *event) +{ + + qDebug() << "CCurveLegendView::mousePressEvent"; + CCurveLegendModel *pLegendModel = dynamic_cast(model()); + if(Q_NULLPTR != pLegendModel) + { + QModelIndex index = indexAt(event->pos()); + if(!index.isValid() || !pLegendModel->headerData(index.column() , Qt::Horizontal , Qt::DisplayRole).toString().contains("设备组-测点")) + { + return; + } + QMessageBox msg; + msg.setWindowTitle("事件内容"); + msg.setText(index.data(Qt::DisplayRole).toString()); + msg.addButton("确认",QMessageBox::AcceptRole); + + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + qssfile1.close(); + } + + if(!qss.isEmpty()) + { + msg.setStyleSheet(qss); + } + msg.exec(); + } +} + + + + diff --git a/product/src/gui/plugin/TrendCurves_pad/CCurveLegendView.h b/product/src/gui/plugin/TrendCurves_pad/CCurveLegendView.h new file mode 100644 index 00000000..4a64fb50 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CCurveLegendView.h @@ -0,0 +1,17 @@ +#ifndef CCURVELEGENDVIEW_H +#define CCURVELEGENDVIEW_H + +#include "CTableView.h" + +class CCurveLegendView : public CTableView +{ + Q_OBJECT +public: + CCurveLegendView(QWidget *parent = Q_NULLPTR); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); +}; + +#endif // CCURVELEGENDVIEW_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CHisDataManage.cpp b/product/src/gui/plugin/TrendCurves_pad/CHisDataManage.cpp new file mode 100644 index 00000000..f163d45a --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CHisDataManage.cpp @@ -0,0 +1,281 @@ +#include "CHisDataManage.h" +#include "db_his_query_api/DbHisQueryApi.h" +#include "sample_server_api/SampleDefine.h" +#include "pub_logger_api/logger.h" +using namespace iot_dbms; + +int CHisDataManage::m_nProcessNumber = 0; + +CHisDataManage::CHisDataManage(QObject *parent) + : QObject(parent), + m_TsdbExcuting(false), + m_bHasPending(false), + m_tsdbConnPtr((CTsdbConn*)nullptr) +{ + initTsdbApi(); + m_nProcessNumber++; +} + +CHisDataManage::~CHisDataManage() +{ + QMutexLocker locker(&m_mutex); + m_tsdbConnPtr = boost::shared_ptr(Q_NULLPTR); + if(--m_nProcessNumber == 0) + { + releaseTsdbApi(); + } + + foreach (QList cmdList, m_listCommand) { + foreach (TsdbCommand cmd, cmdList) + { + cmd.pVecMpKey->clear(); + delete cmd.pVecMpKey; + } + cmdList.clear(); + } + m_listCommand.clear(); +} + +bool CHisDataManage::isTsdbExuting() +{ + QMutexLocker locker(&m_mutex); + return m_TsdbExcuting; +} + +void CHisDataManage::postTsdbCommandQueue(const QList &cmd) +{ + QMutexLocker locker(&m_mutex); + + m_bHasPending = true; + m_listCommand.push_back(cmd); +} + +void CHisDataManage::queryHistoryRecord(const QList &cmdList) +{ + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = true; + } + + emit sigHisSearch(true); + foreach (TsdbCommand cmd, cmdList) { + if(E_ORIGINAL == cmd.type) + { + queryHistoryOriginalData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.dataType); + } + else if(E_POLYMERIC == cmd.type) + { + queryHistoryPolymericData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.nGroupBySec, cmd.vecMethod.front(), cmd.dataType); + } + else if(E_EVENTPOINT == cmd.type) + { + queryHistoryEvents(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.vecMethod.front(), cmd.nGroupBySec); + } + else if(E_COMPUTER == cmd.type) + { + queryHistoryComputeData(cmd.pVecMpKey, cmd.lower, cmd.upper, cmd.vecMethod, cmd.dataType); + } + } + emit sigHisSearch(false); + + { + QMutexLocker locker(&m_mutex); + m_TsdbExcuting = false; + } + checkTsdbCommandQueue(); +} + +void CHisDataManage::release() +{ + delete this; +} + +bool CHisDataManage::getValidTsdbConnPtr(iot_dbms::CTsdbConnPtr &ptr) +{ + //< 不使用getOneUseableConn()返回的正式库测试 + // ptr.reset(new iot_dbms::CTsdbConn("127.0.0.1", -1, "rqeh6000", "", "")); + // return true; + if(m_tsdbConnPtr != NULL) + { + if(m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + } + else + { + m_tsdbConnPtr = getOneUseableConn(true); + if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + else + { + m_tsdbConnPtr = getOneUseableConn(false); + if(m_tsdbConnPtr != NULL && m_tsdbConnPtr->pingServer()) + { + ptr = m_tsdbConnPtr; + return true; + } + } + } + return false; +} + +void CHisDataManage::checkTsdbCommandQueue() +{ + if(m_bHasPending) + { + m_bHasPending = false; + QList cmdList; + { + QMutexLocker locker(&m_mutex); + if(!m_listCommand.isEmpty()) + { + cmdList = m_listCommand.takeLast(); + } + } + queryHistoryRecord(cmdList); + } + else + { + foreach (QList cmdList, m_listCommand) + { + foreach (TsdbCommand cmd, cmdList) { + std::vector::iterator it = cmd.pVecMpKey->begin(); + while(it != cmd.pVecMpKey->end()) + { + free( (char*)it->m_pszTagName ); + ++it; + } + cmd.pVecMpKey->clear(); + delete cmd.pVecMpKey; + } + cmdList.clear(); + } + m_listCommand.clear(); + } +} + +void CHisDataManage::queryHistoryOriginalData(std::vector *vecMpKey, double lower, double upper, E_Data_Type type) +{ + double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; + std::vector *> *vecResult = new std::vector *>(); + + iot_dbms::CTsdbConnPtr tsdbConnPtr; + if(getValidTsdbConnPtr(tsdbConnPtr)) + { + for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) + { + vecResult->push_back(new std::vector()); + } + std::vector vecStatusNotHave = getVecStatusNotHave(vecMpKey->size()); + if(!getHisSamplePoint(*tsdbConnPtr, 10000, *vecMpKey, lower - nIntervalSecs, upper + nIntervalSecs, + NULL, &vecStatusNotHave, CM_NULL, 0, FM_NULL_METHOD, *vecResult)) + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryOriginalData: 查询超时!"); + } + } + else + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryOriginalData: 未获取到有效的TSDB连接!"); + } + + emit sigupdateHisOriginalData(vecMpKey, vecResult, type); +} + +void CHisDataManage::queryHistoryPolymericData(std::vector *vecMpKey, double lower, double upper, int nGroupBySec, const EnComputeMethod &enCm, E_Data_Type type) +{ + double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; + std::vector *> *vecResult = new std::vector *>(); + + iot_dbms::CTsdbConnPtr tsdbConnPtr; + if(getValidTsdbConnPtr(tsdbConnPtr)) + { + for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) + { + vecResult->push_back(new std::vector()); + } + std::vector vecStatusNotHave = getVecStatusNotHave(vecMpKey->size()); + if(!getHisSamplePoint(*tsdbConnPtr, 10000, *vecMpKey, lower - nIntervalSecs, upper + nIntervalSecs, + NULL, &vecStatusNotHave, enCm, nGroupBySec * 1000, FM_NULL_METHOD, *vecResult)) + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 查询超时!"); + } + } + else + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 未获取到有效的TSDB连接!"); + } + + emit sigHistoryPolymericData(vecMpKey, vecResult, nGroupBySec, type); +} + +void CHisDataManage::queryHistoryComputeData(std::vector *vecMpKey, double lower, double upper, const std::vector &vecCM, E_Data_Type type) +{ + std::vector *> *> > cmResult; + + iot_dbms::CTsdbConnPtr tsdbConnPtr; + if(getValidTsdbConnPtr(tsdbConnPtr)) + { + for(size_t nCmIndex(0); nCmIndex < vecCM.size(); nCmIndex++) + { + std::vector *> *vecResult = new std::vector *>(); + for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) + { + vecResult->push_back(new std::vector()); + } + std::vector vecStatusNotHave=getVecStatusNotHave(vecMpKey->size()); + if(!getHisValue(*tsdbConnPtr, 10000, *vecMpKey, lower, upper, + NULL, &vecStatusNotHave, NULL, NULL, NULL, vecCM[nCmIndex], 0, FM_NULL_METHOD, *vecResult)) + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryComputeData: 查询超时!"); + } + std::pair *> *> tmp; + tmp.first = vecCM[nCmIndex]; + tmp.second = vecResult; + cmResult.push_back(tmp); + } + } + else + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryComputeData: 未获取到有效的TSDB连接!"); + } + + emit sigHistoryComputeData(vecMpKey, cmResult, type); +} + +void CHisDataManage::queryHistoryEvents(std::vector *vecMpKey, double lower, double upper, const EnComputeMethod &enCM, int nGroupBySec) +{ + std::vector *> *vecResult = new std::vector *>(); + + iot_dbms::CTsdbConnPtr tsdbConnPtr; + if(getValidTsdbConnPtr(tsdbConnPtr)) + { + for(size_t nIndex(0); nIndex < vecMpKey->size(); nIndex++) + { + vecResult->push_back(new std::vector()); + } + if(!getHisEventPoint(*tsdbConnPtr, 10000, *vecMpKey, lower, upper, enCM, nGroupBySec * 1000, *vecResult)) + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 查询超时!Lower: %f, Upper: %f, GroupByMs: %d", lower, upper, nGroupBySec); + } + } + else + { + LOGINFO("TrendCurve CHisDataManage::queryHistoryPolymericData: 未获取到有效的TSDB连接!"); + } + emit sigHistoryEvent(vecMpKey, vecResult); +} + +std::vector CHisDataManage::getVecStatusNotHave(size_t cnt) +{ + std::vector vecNotStatusHave(cnt); + for (size_t nIndex(0); nIndex < cnt; nIndex++) + { + vecNotStatusHave[nIndex] = boost::int32_t(STAUS_NOT_HAVE); + } + return vecNotStatusHave; +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CHisDataManage.h b/product/src/gui/plugin/TrendCurves_pad/CHisDataManage.h new file mode 100644 index 00000000..005ddd75 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CHisDataManage.h @@ -0,0 +1,128 @@ +#ifndef CHISDATAMANAGE_H +#define CHISDATAMANAGE_H + +#include +#include +#include "CTrendGraph.h" +#include "plot/qcustomplot.h" +#include "tsdb_api/TsdbApi.h" +#include "db_his_query_api/DbHisQueryBase.h" + + +#define STAUS_NOT_HAVE 4 + +enum E_Data_Type +{ + E_HISTORY, + E_PRECURVE, +}; + +enum E_His_Type +{ + E_Invalid = -1, + E_ORIGINAL, + E_POLYMERIC, + E_EVENTPOINT, + E_COMPUTER +}; + +struct MeasurementPoint +{ + iot_dbms::EnMeasPiontType type; //< 测点类型 + const QString strTagName; //< 测点TAG名 +}; + +struct TsdbCommand +{ + TsdbCommand() + { + type = E_Invalid; + pVecMpKey = nullptr; + lower = -1.; + upper = -1.; + nGroupBySec = -1; + vecMethod = std::vector{iot_dbms::CM_NULL}; + } + E_His_Type type; + E_Data_Type dataType; + std::vector * pVecMpKey; + double lower; + double upper; + int nGroupBySec; + std::vector vecMethod; +}; + +class CHisDataManage : public QObject +{ + Q_OBJECT +public: + explicit CHisDataManage(QObject *parent = nullptr); + ~CHisDataManage(); + + bool isTsdbExuting(); + +signals: + void sigupdateHisOriginalData(std::vector *vecMpKey, + std::vector *> *vecResult, + E_Data_Type type = E_HISTORY); + + void sigHistoryPolymericData(std::vector *vecMpKey, + std::vector *> *vecResult, + int nGroupBySec, + E_Data_Type type = E_HISTORY); + + void sigHistoryComputeData(std::vector *vecMpKey, + std::vector *> *> > cmResult, + E_Data_Type type = E_HISTORY); + + void sigHistoryEvent(std::vector *vecMpKey, + std::vector *> *vecResult); + + void sigHisSearch(bool enable); + +public slots: + void release(); + + void postTsdbCommandQueue(const QList &cmd); + + void queryHistoryRecord(const QList &cmdList); + +private: + void queryHistoryOriginalData(std::vector *vecMpKey, + double lower, double upper, + E_Data_Type type = E_HISTORY); + + void queryHistoryPolymericData(std::vector *vecMpKey, + double lower, double upper, + int nGroupBySec, + const iot_dbms::EnComputeMethod &enCm, + E_Data_Type type = E_HISTORY); + + void queryHistoryComputeData(std::vector *vecMpKey, + double lower, double upper, + const std::vector &vecCM, + E_Data_Type type = E_HISTORY); + + void queryHistoryEvents(std::vector *vecMpKey, + double lower, double upper, + const iot_dbms::EnComputeMethod &enCM, + int nGroupBySec); + std::vector getVecStatusNotHave(size_t cnt); +protected: + bool getValidTsdbConnPtr(iot_dbms::CTsdbConnPtr &ptr); + void checkTsdbCommandQueue(); + +private: + bool m_TsdbExcuting; + bool m_bHasPending; + iot_dbms::CTsdbConnPtr m_tsdbConnPtr; + QList> m_listCommand; + QMutex m_mutex; + static int m_nProcessNumber; +}; + + +template +inline bool compareVarPoint(const T &a, const T &b) { return a.m_nTime < b.m_nTime; } + +#endif // CHISDATAMANAGE_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CHisEventManage.cpp b/product/src/gui/plugin/TrendCurves_pad/CHisEventManage.cpp new file mode 100644 index 00000000..93ff06af --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CHisEventManage.cpp @@ -0,0 +1,86 @@ +#include "CHisEventManage.h" +#include "service/alarm_server_api/AlarmCommonDef.h" +#include +#include "pub_logger_api/logger.h" + +CHisEventManage::CHisEventManage(QObject *parent) + : QObject(parent) +{ + +} + +CHisEventManage::~CHisEventManage() +{ + +} + +void CHisEventManage::release() +{ + delete this; +} + +void CHisEventManage::queryHisEvent(const qint64 &time, const QMap &timeTag, const QList &alarmStatusList) +{ + QList timeList = timeTag.keys(); + QStringList tagList = timeTag.values(); + if(timeList.isEmpty() || tagList.isEmpty()) + { + emit updateHisEvent(time, QStringList() << tr("未查询到该设备相关事件!")); + return; + } + + CDbApi objReadDb(DB_CONN_HIS_READ); + if(!objReadDb.open()) + { + return; + } + + QString timeFirst = QString::number(timeList.first()); + QString timeEnd = QString::number(timeList.last()); + QString keyTagStr = ""; + foreach (QString tag, tagList) { + QString temp = " key_id_tag like '%" + tag + "%' or"; + keyTagStr += temp; + } + keyTagStr.remove(-2,2); + + QString sqlSequenceQuery = QString("select " + "alm_status," + "time_stamp," + "content " + "from HIS_EVENT " + "where time_stamp >= %1 " + "and time_stamp <= %2 " + "and (%3) " + "order by time_stamp asc").arg(timeFirst).arg(timeEnd).arg(keyTagStr); + LOGINFO("queryHisEvent Query: %s", sqlSequenceQuery.toStdString().c_str()); + + QSqlQuery query; + try + { + objReadDb.execute(sqlSequenceQuery, query); + } + catch(...) + { + qDebug() << "Query Error!"; + } + if(query.isActive()) + { + QStringList contents; + while(query.next()) + { + int status = query.value(0).toInt(); + if(alarmStatusList.contains(status)) + { + contents << QDateTime::fromMSecsSinceEpoch(query.value(1).toDouble()).toString("yyyy-MM-dd hh:mm:ss.zzz\n") + query.value(2).toString(); + } + } + if(contents.isEmpty()) + { + contents << tr("未查询到该设备相关事件!"); + } + + emit updateHisEvent(time, contents); + } + objReadDb.close(); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CHisEventManage.h b/product/src/gui/plugin/TrendCurves_pad/CHisEventManage.h new file mode 100644 index 00000000..c9dabc8a --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CHisEventManage.h @@ -0,0 +1,23 @@ +#ifndef CHISEVENTMANAGE_H +#define CHISEVENTMANAGE_H + +#include "dbms/db_api_ex/CDbApi.h" + +using namespace iot_dbms; +class CHisEventManage : public QObject +{ + Q_OBJECT +public: + CHisEventManage(QObject *parent = Q_NULLPTR); + + ~CHisEventManage(); + + void release(); + + void queryHisEvent(const qint64 &time, const QMap& timeTag, const QList &alarmStatusList); + +signals: + void updateHisEvent(const qint64 &time, QStringList contents); +}; + +#endif // CHISEVENTMANAGE_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CPlotWidget.cpp b/product/src/gui/plugin/TrendCurves_pad/CPlotWidget.cpp new file mode 100644 index 00000000..168efc20 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CPlotWidget.cpp @@ -0,0 +1,3761 @@ +#include "CPlotWidget.h" +#include "ui_CPlotWidget.h" +#include "CCurveLegendModel.h" +#include "CTableDataModel.h" +#include "CHisEventManage.h" +#include "CRealTimeDataCollect.h" +#include "sample_server_api/SampleDefine.h" +#include "pub_logger_api/logger.h" +#include "./widgets/CEditCollectWidget.h" +#include "./widgets/CSWitchButton.h" +#include "./widgets/CToolTip.h" +#include "./widgets/CMyCheckBox.h" +#include "./widgets/CMyListWidget.h" +#include "pub_excel/xlsx/xlsxdocument.h" + +using namespace iot_dbms; + +CPlotWidget::CPlotWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::CPlotWidget), + m_type(E_Trend_Invalid), + m_showType(E_Show_Curve), + m_bHisAdaption(false), + m_bShowPreCurve(false), + m_TrendTypeButton(Q_NULLPTR), + m_pLengedModel(Q_NULLPTR), + m_pTableDataModel(Q_NULLPTR), + m_pTimer(Q_NULLPTR), + m_pTrendGraph(Q_NULLPTR), + m_trendTitle(Q_NULLPTR), + m_pDpcdaForApp(Q_NULLPTR), + m_rtDataCollect(Q_NULLPTR), + m_pHisDataThread(Q_NULLPTR), + m_pHisDataManage(Q_NULLPTR), + m_pHisEventThread(Q_NULLPTR), + m_pHisEventManage(Q_NULLPTR), + m_horizontalGraph(Q_NULLPTR), + m_numWarnFlag(true), + m_isWindowMode(true), + m_isSetSliderValue(false), + m_isTooltip(true), + m_isAdaptShow(true), + m_isAlarmShow(true), + m_isPreCurveShow(true), + m_limitNum(64) +{ + ui->setupUi(this); + setContentsMargins(1, 1, 1, 1); + qRegisterMetaType< E_Point_Type >("E_Point_Type"); + qRegisterMetaType< E_Data_Type >("E_Data_Type"); + qRegisterMetaType< iot_dbms::EnComputeMethod >("iot_dbms::EnComputeMethod"); + qRegisterMetaType< std::vector >("std::vector"); + qRegisterMetaType< std::vector >("std::vector"); + qRegisterMetaType< std::vector *> >("std::vector *>"); + qRegisterMetaType< std::vector *> *> > >( + "std::vector *> *> >"); + qRegisterMetaType< QList >("QList"); +} + +CPlotWidget::~CPlotWidget() +{ + if(m_pTimer) + { + m_pTimer->stop(); + delete m_pTimer; + } + m_pTimer = Q_NULLPTR; + + if(m_pHisEventManage) + { + emit releaseHisEventThread(); + m_pHisEventManage = Q_NULLPTR; + } + + if(m_pHisEventThread) + { + m_pHisEventThread->quit(); + m_pHisEventThread->wait(); + } + m_pHisEventThread = Q_NULLPTR; + + if(m_pHisDataManage) + { + emit releaseHisDataThread(); + m_pHisDataManage = Q_NULLPTR; + } + if(m_pHisDataThread) + { + m_pHisDataThread->quit(); + m_pHisDataThread->wait(); + } + m_pHisDataThread = Q_NULLPTR; + + if(m_pTrendGraph) + { + delete m_pTrendGraph; + } + m_pTrendGraph = Q_NULLPTR; + + if(m_pDpcdaForApp) + { + m_pDpcdaForApp->unsubscribeAll(); + delete m_pDpcdaForApp; + } + m_pDpcdaForApp = Q_NULLPTR; + + if(m_rtDataCollect->isRunning()) + { + m_rtDataCollect->disconnect(this); + m_rtDataCollect->requestInterruption(); + m_rtDataCollect->wait(); + } + m_rtDataCollect = Q_NULLPTR; + delete ui; +} + +/************************************************************************ + * + * 1、初始化界面 + * 2、初始化实时数据采集 + * + ************************************************************************/ +void CPlotWidget::initialize() +{ + m_pTrendGraph = new CTrendGraph(); + m_rtRange = 10 * 60 * 1000; //< second + + //< GroupButton + m_TrendTypeButton = new QButtonGroup(this); + m_TrendTypeButton->addButton(ui->realTime, E_Trend_RealTime); + m_TrendTypeButton->addButton(ui->sec, E_Trend_His_Minute); + m_TrendTypeButton->addButton(ui->day, E_Trend_His_Day); + m_TrendTypeButton->addButton(ui->week, E_Trend_His_Week); + m_TrendTypeButton->addButton(ui->month, E_Trend_His_Month); + m_TrendTypeButton->addButton(ui->quarter, E_Trend_His_Quarter); + m_TrendTypeButton->addButton(ui->year, E_Trend_His_Year); + m_TrendTypeButton->addButton(ui->custom, E_Trend_His_Custom); + connect(m_TrendTypeButton, SIGNAL(buttonClicked(int)), this, SLOT(updateTrendShowMode(int))); + + connect(ui->prePage, &QPushButton::clicked, this, &CPlotWidget::prePage); + connect(ui->nextPage, &QPushButton::clicked, this, &CPlotWidget::nextPage); + connect(ui->date, &QDateTimeEdit::dateTimeChanged, this, &CPlotWidget::slotDateTimeChanged); + ui->date->setCalendarPopup(true); + ui->date->setButtonSymbols(QAbstractSpinBox::NoButtons); + ui->date->setDateTime(QDateTime::currentDateTime()); + + ui->customWidget->setVisible(false); + ui->customSearch->setVisible(false); + ui->startData->setCalendarPopup(true); + ui->endData->setCalendarPopup(true); + ui->startData->setButtonSymbols(QAbstractSpinBox::NoButtons); + ui->endData->setButtonSymbols(QAbstractSpinBox::NoButtons); + ui->startData->setMinimumWidth(150); + ui->endData->setMinimumWidth(150); + QDateTime curDateTime = QDateTime::currentDateTime(); + curDateTime.setTime(QTime(curDateTime.time().hour(), + curDateTime.time().minute(),0,0)); + ui->endData->setDateTime(curDateTime); + QDateTime preDateTime = curDateTime.addSecs(-600); + ui->startData->setDateTime(preDateTime); + ui->interval->setView(new QListView()); + ui->interval->addItem(tr("一秒钟"), 1); + ui->interval->addItem(tr("一分钟"), 1*60); + ui->interval->addItem(tr("十分钟"), 10*60); + ui->interval->addItem(tr("一小时"), 60*60); + ui->interval->addItem(tr("八小时"), 8*60*60); + ui->interval->addItem(tr("一天"), 24*60*60); + connect(ui->interval, &QComboBox::currentTextChanged, this, &CPlotWidget::slotIntervalChanged); + connect(ui->customSearch, &QPushButton::clicked, this, &CPlotWidget::slotCustomSearch); + connect(ui->startData, &QDateTimeEdit::dateTimeChanged, this, &CPlotWidget::slotStartDateChanged); + connect(ui->endData, &QDateTimeEdit::dateTimeChanged, this, &CPlotWidget::slotEndDateChanged); + + //< initPlot + ui->plot->setEnabled(true); + ui->plot->setSymbolPos(QPoint(width() / 2, 0)); + ui->plot->setNoAntialiasingOnDrag(true); + ui->plot->axisRect()->setRangeDrag(Qt::Horizontal); //<水平拖拽 + ui->plot->axisRect()->setRangeZoom(Qt::Horizontal); //<水平缩放 + ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); + QSharedPointer ticker(new QCPAxisTickerDateTime()); + ui->plot->xAxis->setTicker(ticker); + ui->plot->yAxis->setRange(-1, 1); + ui->plot->yAxis->scaleRange(1.02); + ui->plot->yAxis2->setVisible(true); + ui->plot->xAxis->setScaleType(QCPAxis::stLinear); + ui->plot->xAxis->rescale(true); + m_ptrPlotTricker = ui->plot->yAxis->ticker(); + + connect(ui->plot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->plot->yAxis2, SLOT(setRange(QCPRange))); + connect(ui->plot->xAxis, SIGNAL(rangeChanged(const QCPRange &,const QCPRange &)), this, SLOT(plotAxisRangeChanged(const QCPRange &,const QCPRange &))); + connect(ui->plot->xAxis->axisRect(), &QCPAxisRect::rangeDraged, this, &CPlotWidget::updateCurves); + connect(ui->plot->xAxis->axisRect(), &QCPAxisRect::rangeScaled, this, &CPlotWidget::updateCurves); + connect(ui->plot, &QCustomPlot::symbolPosChanged, this, &CPlotWidget::updateLengedValue); + + //< initTitle + m_trendTitle = new QCPItemText(ui->plot); + m_trendTitle->setObjectName("m_trendTitle"); + m_trendTitle->setPositionAlignment(Qt::AlignCenter); + m_trendTitle->position->setType(QCPItemPosition::ptAxisRectRatio); + m_trendTitle->position->setCoords(0.03, 0.01); + m_trendTitle->setColor(QColor(255,255,255)); + m_trendTitle->setFont(QFont("Microsoft YaHei", 10)); + m_trendTitle->setText("实时趋势"); + m_trendTitle->setVisible(false); + + m_pTableDataModel = new CTableDataModel(ui->m_dataView); + ui->m_dataView->setModel(m_pTableDataModel); + ui->m_dataView->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->m_dataView->verticalHeader()->setVisible(false); + ui->m_dataView->setAlternatingRowColors(true); + ui->m_dataView->horizontalHeader()->setObjectName("m_dataView"); + ui->m_dataView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + ui->m_dataView->setSelectionBehavior(QAbstractItemView::SelectRows); +// ui->m_dataView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); +// ui->m_dataView->horizontalHeader()->setMinimumSectionSize(200); +// ui->m_dataView->horizontalHeader()->setDefaultSectionSize(200); + ui->m_dataView->setHorizontalHeader(new CustomHeaderView(Qt::Horizontal,ui->m_dataView)); + + connect(ui->m_dataView, SIGNAL(clicked(QModelIndex)), this, SLOT(tableSelectionChanged(QModelIndex))); + connect(ui->m_dataView->horizontalHeader(),&QHeaderView::sectionCountChanged,ui->m_dataView,&CTableView::adjustHeaderWidth); + //< initTableView + m_pLengedModel = new CCurveLegendModel(ui->lengedView); + ui->lengedView->setModel(m_pLengedModel); + ui->lengedView->setItemDelegate(new CCurveLegnedDelegate(ui->lengedView)); + ui->lengedView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked); + ui->lengedView->verticalHeader()->setVisible(false); + ui->lengedView->setAlternatingRowColors(true); + ui->lengedView->horizontalHeader()->setStretchLastSection(true); + ui->lengedView->horizontalHeader()->setObjectName("m_legendHeader"); + ui->lengedView->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->lengedView->setSelectionMode(QAbstractItemView::SingleSelection); + ui->lengedView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->lengedView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + + connect(m_pLengedModel, &CCurveLegendModel::graphVisibleChanged, this, &CPlotWidget::graphVisibleChanged); + connect(m_pLengedModel, &CCurveLegendModel::graphPropertyChanged, this, &CPlotWidget::graphPropertyChanged); + connect(m_pLengedModel, &CCurveLegendModel::deleteCurrentGraph, this, &CPlotWidget::deleteCurrentGraph); + connect(m_pLengedModel, &CCurveLegendModel::sigJumpToMaxTime, this, &CPlotWidget::jumpToMaxTime); + connect(m_pLengedModel, &CCurveLegendModel::sigJumpToMinTime, this, &CPlotWidget::jumpToMinTime); + connect(ui->lengedView, &QTableView::clicked, this, &CPlotWidget::updateGraphSelection); + + ui->plotExport->setVisible(false); + ui->clear->setEnabled(false); + ui->collectCurve->setVisible(false); + ui->switchBtn->setToggle(false); + ui->switchBtn->setText(tr("表格")); + ui->switchBtn->setCheckedText(tr("曲线")); + ui->m_dataView->setVisible(false); + connect(ui->adapt, &QCheckBox::toggled, this, &CPlotWidget::updateAdaptState); + connect(ui->preCurve, &QCheckBox::toggled, this, &CPlotWidget::updatePreCurveState); + connect(ui->collectCurve, &QPushButton::clicked, this, &CPlotWidget::addCollect); + connect(ui->plotPrint, &QPushButton::clicked, this, &CPlotWidget::slotPrint); + connect(ui->plotExport, &QPushButton::clicked, this, &CPlotWidget::slotExport); + connect(ui->clear, &QPushButton::clicked, this, &CPlotWidget::clear); + connect(ui->switchBtn, &CSWitchButton::toggled, this, &CPlotWidget::showTypeChanged); + if(Q_NULLPTR == m_pTimer) + { + m_pTimer = new QTimer(this); + m_pTimer->setInterval(1000); + connect(m_pTimer, &QTimer::timeout, this, &CPlotWidget::realTimeElapsed); + } + + m_pDpcdaForApp = new iot_service::CDpcdaForApp(); + m_rtDataCollect = new CRealTimeDataCollect(this); + connect(m_rtDataCollect, &CRealTimeDataCollect::finished, m_rtDataCollect, &CRealTimeDataCollect::deleteLater); + connect(m_rtDataCollect, &CRealTimeDataCollect::realTimeTrendDataArrived, this, &CPlotWidget::recvRealTimeTrendData, Qt::QueuedConnection); + m_rtDataCollect->start(); + + m_pHisDataManage = new CHisDataManage(); + m_pHisDataThread = new QThread(this); + m_pHisDataManage->moveToThread(m_pHisDataThread); + connect(m_pHisDataThread, &QThread::finished, m_pHisDataThread, &QObject::deleteLater); + connect(this, &CPlotWidget::releaseHisDataThread, m_pHisDataManage, &CHisDataManage::release, Qt::BlockingQueuedConnection); + connect(this, &CPlotWidget::sigQueryHistoryRecord, m_pHisDataManage, &CHisDataManage::queryHistoryRecord, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigupdateHisOriginalData, this, &CPlotWidget::updateHisOriginalData, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigHistoryPolymericData, this, &CPlotWidget::updateHisPolymericData, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigHistoryComputeData, this, &CPlotWidget::updateHisComputeData, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigHistoryEvent, this, &CPlotWidget::updatePhaseTracer, Qt::QueuedConnection); + connect(m_pHisDataManage, &CHisDataManage::sigHisSearch, this, &CPlotWidget::slotEnableSearch, Qt::QueuedConnection); + m_pHisDataThread->start(); + + m_pHisEventManage = new CHisEventManage(); + m_pHisEventThread = new QThread(this); + m_pHisEventManage->moveToThread(m_pHisEventThread); + connect(m_pHisEventThread, &QThread::finished, m_pHisEventThread, &QObject::deleteLater); + connect(this, &CPlotWidget::releaseHisEventThread, m_pHisEventManage, &CHisEventManage::release, Qt::BlockingQueuedConnection); + connect(m_pHisEventManage, &CHisEventManage::updateHisEvent, this, &CPlotWidget::updateGraphEvent ,Qt::QueuedConnection); + m_pHisEventThread->start(); + + ui->scaleSlider->setMouseTracking(true); + ui->scaleSlider->setHandleMovementMode(QxtSpanSlider::NoCrossing); + ui->scaleSlider->setMinimum(-100000); + ui->scaleSlider->setMaximum(100000); + ui->scaleSlider->setLowerValue(0); + ui->scaleSlider->setUpperValue(0); + connect(ui->scaleSlider, &QxtSpanSlider::lowerValueChanged, this, &CPlotWidget::setYAxisRange); + connect(ui->scaleSlider, &QxtSpanSlider::upperValueChanged, this, &CPlotWidget::setYAxisRange); + connect(ui->scaleSlider, &QxtSpanSlider::sliderPressed, this, &CPlotWidget::sliderPressed); + connect(ui->scaleSlider, &QxtSpanSlider::sliderDoubleClick, this, &CPlotWidget::sliderDoubleClick); + + initAlarmStatusFilter(); + connect(ui->checkBox_alarmPoint, &QCheckBox::clicked, this, &CPlotWidget::alarmPointCheckStateChanged); + + installMousePressEventFilter(); + + QMetaObject::invokeMethod(ui->realTime, "click"); +} + +void CPlotWidget::resizeEvent(QResizeEvent *event) +{ + QSize size = parentWidget()->size(); + int offset = 2; + if(m_isWindowMode) + offset = 15; + if(ui->titleFrame->isVisible()) + { + size.setHeight(size.height() - (ui->titleFrame->height() + ui->toolFrame->height() + ui->pageFrame->height() + ui->lengedView->height() + offset)); + } + else + { + size.setHeight(size.height() - (ui->toolFrame->height() + ui->pageFrame->height() + ui->lengedView->height() + offset)); + } + size.setWidth(ui->lengedView->width() - 20); + ui->plot->resize(size); + ui->plot->replot(); + + updateLengedColumnWidth(); + QWidget::resizeEvent(event); +} + +bool CPlotWidget::eventFilter(QObject *object, QEvent *event) +{ + if (QEvent::MouseButtonPress == event->type()) + { + emit sigHideCollect(); + emit sigHideSliderSet(); + if(object == ui->scaleSlider) + { + m_isTooltip = false; + QToolTip::hideText(); + } + } + else if(QEvent::MouseButtonRelease == event->type()) + { + if(object == ui->scaleSlider) + { + m_isTooltip = true; + } + } + else if(QEvent::MouseMove == event->type()) + { + if(object == ui->scaleSlider && m_isTooltip) + { + QMouseEvent *mouse = dynamic_cast(event); + QToolTip::showText(mouse->globalPos(), tr("双击输入值")); + } + } + + return QWidget::eventFilter(object, event); +} + +void CPlotWidget::updateLengedColumnWidth() +{ + int nLengedWidth = ui->lengedView->width(); + ui->lengedView->setColumnWidth(CCurveLegendModel::NAME, nLengedWidth / 12. * 3); + ui->lengedView->setColumnWidth(CCurveLegendModel::COLOR, nLengedWidth / 12. * 0.5); + ui->lengedView->setColumnWidth(CCurveLegendModel::VALUE, nLengedWidth / 12.); + ui->lengedView->setColumnWidth(CCurveLegendModel::MAX, nLengedWidth / 12.); + ui->lengedView->setColumnWidth(CCurveLegendModel::MAXTIME, nLengedWidth / 12. * 1.5); + ui->lengedView->setColumnWidth(CCurveLegendModel::MIN, nLengedWidth / 12.); + ui->lengedView->setColumnWidth(CCurveLegendModel::MINTIME, nLengedWidth / 12. * 1.5); + ui->lengedView->setColumnWidth(CCurveLegendModel::AVE, nLengedWidth / 12.); + ui->lengedView->setColumnWidth(CCurveLegendModel::UNIT, nLengedWidth / 12. * 1.5); + // ui->lengedView->setColumnWidth(CCurveLegendModel::FACTOR, nLengedWidth / 12.); + // ui->lengedView->setColumnWidth(CCurveLegendModel::OFFSET, nLengedWidth / 12.); +} + +void CPlotWidget::updateCurveSelectionColor(QCPGraph *graph) +{ + if(!graph) + { + return; + } + QPen selectedPen = graph->selectionDecorator()->pen(); + selectedPen.setWidth(1); + QColor color; + QColor graphColor = graph->pen().color(); + int r = graphColor.red() > 225 ? graphColor.red() - 30 : graphColor.red() + 30; + int g = graphColor.green() > 225 ? graphColor.green() - 30 : graphColor.green() + 30; + int b = graphColor.blue() > 225 ? graphColor.blue() - 30 : graphColor.blue() + 30; + color.setRgb(r, g, b); + selectedPen.setColor(color); + graph->selectionDecorator()->setPen(selectedPen); +} + +E_Trend_Type CPlotWidget::getRangeType(const QCPRange &range) +{ + if(range.size() <= 0) + { + return E_Trend_Invalid; + } + + QDateTime upper = QDateTime::fromMSecsSinceEpoch(range.upper); + + if(range.lower >= upper.addSecs(-10).toMSecsSinceEpoch()) + { + return E_Trend_RealTime; + } + else if(range.lower >= upper.addSecs(-600).toMSecsSinceEpoch()) + { + return E_Trend_His_Minute; + } + else if(range.lower >= upper.addSecs(-3600).toMSecsSinceEpoch()) + { + return E_Trend_His_Hour; + } + else if(range.lower >= upper.addDays(-1).toMSecsSinceEpoch()) + { + return E_Trend_His_Day; + } + else if(range.lower >= upper.addDays(-7).toMSecsSinceEpoch()) + { + return E_Trend_His_Week; + } + else if(range.lower >= upper.addMonths(-1).toMSecsSinceEpoch()) + { + return E_Trend_His_Month; + } + else if(range.lower >= upper.addMonths(-3).toMSecsSinceEpoch()) + { + return E_Trend_His_Quarter; + } + else if(range.lower >= upper.addYears(-1).toMSecsSinceEpoch()) + { + return E_Trend_His_Year; + } + + return E_Trend_His_Year; +} + +int CPlotWidget::currentGroupByMinute() +{ + int nGroupByMinute = 0; + switch (m_type) + { + case E_Trend_RealTime: + { + //< Error + } + break; + case E_Trend_His_Minute: + { + //< Error + } + break; + case E_Trend_His_Hour: + { + //< Error + } + break; + case E_Trend_His_Day: + { + nGroupByMinute = 1; + } + break; + case E_Trend_His_Week: + { + nGroupByMinute = 7; + } + break; + case E_Trend_His_Month: + { + nGroupByMinute = 30; + } + break; + case E_Trend_His_Quarter: + { + nGroupByMinute = 90; + } + break; + case E_Trend_His_Year: + { + nGroupByMinute = 365; + } + break; + default: + break; + } + return nGroupByMinute; +} + +/************************************************************************ + * + * 接口 + * + ************************************************************************/ +void CPlotWidget::setTitle(const QString &title) +{ + ui->title->setText(title); +} + +void CPlotWidget::setTitleVisible(bool visible) +{ + ui->titleFrame->setVisible(visible); +} + +void CPlotWidget::setTickCount(const int &count) +{ + QSharedPointer ticker = qSharedPointerDynamicCast(ui->plot->xAxis->ticker()); + ticker->setTickCount(count); +} + +void CPlotWidget::insertTag(const QString &tag, const bool &resetTitle) +{ + if(resetTitle) + { + setTitle(tr("趋势图")); + } + Curve curve; + curve.tag = tag; + QList list = m_pTrendGraph->curveColors(); + int index = 0; + for(int nIndex=0; nIndexindex("curve.tag"); + if(mIndex != -1) + { + ui->lengedView->setRowHidden(mIndex,true); + } + +} + +void CPlotWidget::insertTag(const QStringList &listTag, const bool &resetTitle) +{ + m_pTrendGraph->clear(); + foreach (QString tag, listTag) + { + insertTag(tag, resetTitle); + } +} + +void CPlotWidget::removeTag(const QString &tag, const bool &resetTitle) +{ + if(resetTitle) + { + setTitle(tr("趋势图")); + } + m_isSetSliderValue = false; + setAllLengedShow(); + QList removeList = m_pTrendGraph->removeCurve(tag); + for(int nIndex = 0; nIndex < removeList.length(); ++nIndex) + { + if(m_showType == E_Show_Table) + { + m_pTableDataModel->removeCurveData(ui->plot->graph(nIndex)->desc()); + } + ui->plot->removeGraph(removeList[nIndex]); + } + + m_pLengedModel->setTrendGraph(m_pTrendGraph); + int mIndex = m_pTrendGraph->index("curve.tag"); + if(mIndex != -1) + { + ui->lengedView->setRowHidden(mIndex,true); + } + updateLengedColumnWidth(); + if(!m_pTrendGraph->curves().size()) + { + ui->plot->yAxis->setRange(QCPRange(-1, 1)); + + if(m_isWindowMode) + { + ui->collectCurve->setVisible(false); + } + ui->clear->setEnabled(false); + }else{ + removeCurvesGroupQuery(); + if(m_horizontalGraph) + { + groupQueryHistoryEvent(); + } + } + m_isSetSliderValue = true; + rescaleYAxisRange(); + ui->plot->replot(); +} + +void CPlotWidget::setDisplayTime(const int &trendType, const double &dateTime, const bool &alarm) +{ + QAbstractButton* Button = m_TrendTypeButton->button(trendType); + if(Button) + { + ui->date->blockSignals(true); + QMetaObject::invokeMethod(Button, "click"); + ui->date->blockSignals(false); + + QDateTime nDateTime = QDateTime::fromMSecsSinceEpoch(dateTime); + ui->date->setDateTime(nDateTime); + if(E_Trend_His_Day == trendType) + { + ui->plot->xAxis->blockSignals(true); + ui->plot->xAxis->setRange(dateTime - 600000, dateTime + 600000); + ui->plot->xAxis->blockSignals(false); + } + + ui->plot->setSymbolPos(QPoint(ui->plot->xAxis->coordToPixel(dateTime), 0)); + if(alarm) + { + ui->checkBox_alarmPoint->setChecked(true); + alarmPointCheckStateChanged(); + } + } +} + +void CPlotWidget::setTagVisible(const QString &tag, const bool &visible) +{ + setAllLengedShow(); + int nIndex = m_pTrendGraph->index(tag); + if(nIndex != -1) + { + m_pLengedModel->setData(m_pLengedModel->index(nIndex, 0), visible, Qt::CheckStateRole); + ui->plot->replot(); + } + int mIndex = m_pTrendGraph->index("curve.tag"); + if(mIndex != -1) + { + ui->lengedView->setRowHidden(mIndex,true); + } +} + +void CPlotWidget::setDateButtonVisible(const int &button, const bool &visible) +{ + QAbstractButton* Button = m_TrendTypeButton->button(button); + if(Button) + { + Button->setVisible(visible); + } +} + +void CPlotWidget::setClearVisible(bool visible) +{ + if(visible) + { + ui->clear->show(); + } + else + { + ui->clear->hide(); + } +} + +void CPlotWidget::setAdaptVisible(bool visible) +{ + m_isAdaptShow = visible; + + ui->adapt->setVisible(visible); +} + +void CPlotWidget::setAlarmPointVisible(bool visible) +{ + m_isAlarmShow = visible; + + ui->checkBox_alarmPoint->setVisible(visible); + ui->comboBox_alarmStatus->setVisible(visible); +} + +void CPlotWidget::setPreCurveVisible(bool visible) +{ + m_isPreCurveShow = visible; + + ui->preCurve->setVisible(visible); +} + +void CPlotWidget::insertCurve(Curve curve) +{ + m_isSetSliderValue = true; + if((NULL != m_horizontalGraph && ui->plot->graphCount() >= m_limitNum+1) || + (NULL == m_horizontalGraph && ui->plot->graphCount() >= m_limitNum)) + { + if(m_numWarnFlag) + { + QMessageBox::warning(this, tr("错误"), tr("当前趋势曲线已达最大支持数量[%1]!").arg(m_limitNum), QMessageBox::Ok); + m_numWarnFlag = false; + } + emit updateTagCheckState(curve.tag, false); + return; + } + + m_numWarnFlag = true; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + if(curve.tag == ui->plot->graph(nIndex)->name()) + { + LOGINFO("趋势曲线[%s]已存在", curve.tag.toStdString().c_str()); + return; + } + } + + curve.type = CTrendInfoManage::instance()->getTagType(curve.tag); + curve.unit = CTrendInfoManage::instance()->getTagUnit(curve.tag); + if(curve.type.isEmpty()) + { + LOGINFO("趋势曲线[%s]类型不存在", curve.tag.toStdString().c_str()); + return; + } + + curve.desc = CTrendInfoManage::instance()->getTagDescription(curve.tag); + if(curve.desc.isEmpty()) + { + LOGINFO("趋势曲线[%s]描述不存在", curve.tag.toStdString().c_str()); + return; + } + + m_pDpcdaForApp->subscribe(curve.type.toStdString(), curve.tag.toStdString(), "value"); + + //< 添加曲线 + m_pTrendGraph->addCurve(curve); + QCPGraph * graph = ui->plot->addGraph(); + graph->setName(curve.tag); + graph->setDesc(curve.desc); + graph->setType(curve.curveType); + QPen pen; + pen.setWidth(1); + pen.setColor(curve.color); + graph->setPen(pen); + updateCurveSelectionColor(graph); + + updateGroupQuery(curve.tag); + + connect(graph, SIGNAL(selectionChanged(bool)), this, SLOT(graphSelectionChanged(bool)), Qt::QueuedConnection); + + //< 方波 + QString type = CTrendInfoManage::instance()->getTagType(curve.tag); + if(type == "digital" || type == "mix") + { + graph->setLineStyle(QCPGraph::lsStepLeft); + } + + if(m_bShowPreCurve) + { + Curve preCurve; + preCurve.visible = curve.visible; + preCurve.tag = curve.tag; + preCurve.desc = tr("昨日曲线-") + curve.desc; + preCurve.type = curve.type; + preCurve.unit = curve.unit; + preCurve.color = curve.color.darker(200); + preCurve.curveType = enPrevCurve; + m_pTrendGraph->addCurve(preCurve); + QCPGraph * graph = ui->plot->addGraph(); + graph->setName(preCurve.tag); + graph->setDesc(preCurve.desc); + graph->setType(preCurve.curveType); + QPen pen; + pen.setWidth(1); + pen.setColor(preCurve.color.darker(200)); + graph->setPen(pen); + updateCurveSelectionColor(graph); + connect(graph, SIGNAL(selectionChanged(bool)), this, SLOT(graphSelectionChanged(bool)), Qt::QueuedConnection); + //< 方波 + QString type = CTrendInfoManage::instance()->getTagType(preCurve.tag); + if(type == "digital" || type == "mix") + { + graph->setLineStyle(QCPGraph::lsStepLeft); + } + } + + updateCurves(); + + m_pLengedModel->setTrendGraph(m_pTrendGraph); + updateLengedColumnWidth(); + + ui->clear->setEnabled(true); + + if(m_isWindowMode) + { + ui->collectCurve->setVisible(true); + emit updateTagCheckState(curve.tag, true); + } + setLegendCurveTransformColumnVisible(true); +} + +void CPlotWidget::clear(bool clearTitle) +{ + if(!m_pTrendGraph->curves().size()) + { + ui->clear->setEnabled(false); + } + m_pTrendGraph->clear(); + m_pLengedModel->clear(); + m_pLengedModel->update(); + m_pTableDataModel->clear(); + m_horizontalGraph = NULL; + m_groupTagMap.clear(); + + ui->plot->yAxis->setRange(QCPRange(-1, 1)); + ui->plot->clearItems(clearTitle); + ui->plot->clearGraphs(); + ui->plot->replot(); + ui->checkBox_alarmPoint->setCheckState(Qt::Unchecked); + ui->adapt->setCheckState(Qt::Unchecked); + setTitle(tr("趋势图")); + if(m_isWindowMode) + { + ui->collectCurve->setVisible(false); + } + emit clearCurve(); +} + +void CPlotWidget::setWindowMode(const bool &isWindowMode) +{ + m_isWindowMode = isWindowMode; +} + +void CPlotWidget::setColorList(const QStringList &listColor) +{ + foreach (QString c, listColor) + { + c.replace("\r", ""); + m_listColor.append(QColor(c)); + } +} + +/****************************** 图表颜色 **************************************/ +QColor CPlotWidget::plotBackgroundColor() +{ + return m_plotBackgroundColor; +} + +void CPlotWidget::setPlotBackgroundColor(const QColor &color) +{ + m_plotBackgroundColor = color; + + ui->plot->setBackground(m_plotBackgroundColor); +} + +QPixmap CPlotWidget::plotBackImage() +{ + return m_plotBackImage; +} + +void CPlotWidget::setPlotBackImage(const QPixmap &pm) +{ + m_plotBackImage = pm; + + ui->plot->setBackgroundScaled(false); + ui->plot->setBackground(pm); +} + +QColor CPlotWidget::plotTickColor() +{ + return m_plotTickColor; +} + +void CPlotWidget::setPlotTickColor(const QColor &color) +{ + m_plotTickColor = color; + + ui->plot->xAxis->setTickLabelColor(color); + ui->plot->yAxis->setTickLabelColor(color); + ui->plot->yAxis2->setTickLabelColor(color); +} + +QColor CPlotWidget::plotGridColor() +{ + return m_plotGridColor; +} + +void CPlotWidget::setPlotGridColor(const QColor &color) +{ + m_plotGridColor = color; + + ui->plot->xAxis->grid()->setPen(color); + ui->plot->yAxis->grid()->setPen(color); + + ui->plot->xAxis->grid()->setSubGridPen(color); + ui->plot->yAxis->grid()->setSubGridPen(color); +} + +QColor CPlotWidget::plotZeroLineColor() +{ + return m_plotZeroLineColor; +} + +void CPlotWidget::setPlotZeroLineColor(const QColor &color) +{ + m_plotZeroLineColor = color; + + ui->plot->xAxis->grid()->setZeroLinePen(QPen(color)); + ui->plot->yAxis->grid()->setZeroLinePen(QPen(color)); +} + +QColor CPlotWidget::plotTickPen() +{ + return m_plotTickPen; +} + +void CPlotWidget::setPlotTickPen(const QColor &color) +{ + m_plotTickPen = color; + + ui->plot->xAxis->setBasePen(color); + ui->plot->yAxis->setBasePen(color); + ui->plot->yAxis2->setBasePen(color); + ui->plot->xAxis->setTickPen(color); + ui->plot->yAxis->setTickPen(color); + ui->plot->yAxis2->setTickPen(color); + ui->plot->xAxis->setSubTickPen(color); + ui->plot->yAxis->setSubTickPen(color); + ui->plot->yAxis2->setSubTickPen(color); +} + +void CPlotWidget::setLimitNum(int max) +{ + m_limitNum = max; +} + +void CPlotWidget::realTimeElapsed() +{ + //< 刷新X轴 + const QCPRange &range = ui->plot->xAxis->range(); + double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); + double limit = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 1, 1)); + ui->plot->xAxis->setRange(upper, range.size(), Qt::AlignRight); + + QList listVal; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + m_pTrendGraph->updateRTCurveStatisticsInfo(graph->name(), graph->type()); + QVector * pCPGraphData = graph->data()->data(); + + if(pCPGraphData->isEmpty()) + { + listVal.append(qSqrt(-1.)); + } + else + { + listVal.append((*(pCPGraphData->end() - 2)).value); + + //< set virtual point value + if(limit == pCPGraphData->last().key) + { + pCPGraphData->last().value = (*(pCPGraphData->end() - 2)).value; + } + } + } + + if(E_Show_Table == m_showType) + { + updateRealTimeTableData(); + } + m_pLengedModel->setTrendCurrentValues(listVal); + rescaleYAxisRange(); + ui->plot->replot(); +} + +void CPlotWidget::recvRealTimeTrendData(const QString &tagName, QVariant value, int status, E_Point_Type pointType) +{ +// LOGINFO("Recv RealTime Trend Data-[Tag Name: %s, value: %f] ", tagName.toStdString().c_str(), value.toDouble()); + double key = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); + int validStatus = CTrendInfoManage::instance()->getInvalidStatus(pointType, status); + m_pTrendGraph->pushCurveRTDataValue(tagName, key, value.toDouble(), validStatus); + + if(E_Trend_RealTime != m_type) + { + return; + } + + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + if(graph->name() == tagName) + { + QVector * pCPGraphData = graph->data()->data(); + + if(pCPGraphData->size() > 1 && qAbs(((*(pCPGraphData->end() - 2)).value - value.toDouble())) < _EPSILON_) + { + return; + } + graph->addData(key, value.toDouble(), validStatus); + if( pCPGraphData->first().key < ( key - (20 * 60 * 1000) ) ) + { + graph->data()->removeBefore( key - (20 * 60 * 1000) ); + } + return; + } + } +} + +void CPlotWidget::updateRealTimeTableData() +{ + QMap> curveData; + QStringList headerList; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + if(ui->plot->graph(nIndex)->name() == "curve.tag") + { + continue; + } + if(ui->plot->graph(nIndex)->type() == enPrevCurve) + { + continue; + } + const QVector< QPair > > &values = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name(), + ui->plot->graph(nIndex)->type()).values; + QVector vecGraphData; + double preValue = DBL_MAX; + QVector< QPair > >::const_iterator iter = values.constBegin(); + for(; iter != values.constEnd(); iter++) + { + if(qAbs((iter->second.first)-preValue) < _EPSILON_) + { + continue; + } + QCPGraphData graphData; + graphData.key = iter->first; + graphData.value = iter->second.first; + graphData.status = iter->second.second; + vecGraphData.push_back(graphData); + preValue = iter->second.first; + } + curveData.insert(ui->plot->graph(nIndex)->desc(), vecGraphData); + headerList.append(ui->plot->graph(nIndex)->desc()); + } + resetCurveData(curveData, headerList, false); +} + +void CPlotWidget::plotAxisRangeChanged(const QCPRange &newRange, const QCPRange &oldRange) +{ + Q_UNUSED(oldRange) + if(E_Show_Table == m_showType) + { + return; + } + + QDateTime upper = QDateTime::fromMSecsSinceEpoch(newRange.upper); + double midValue = (newRange.upper + newRange.lower) / 2; + + if(m_type == E_Trend_RealTime) + { + m_rtRange = newRange.size(); + if(m_rtRange > 10 * 60 * 1000) + { + m_rtRange = 10 * 60 * 1000; + } + else if(m_rtRange < 10 * 1000) + { + m_rtRange = 10 * 1000; + } + + double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); + ui->plot->xAxis->setRange(upper, m_rtRange, Qt::AlignRight); + return; + } + else if(m_type == E_Trend_His_Minute || m_type == E_Trend_His_Day || m_type == E_Trend_His_Week || m_type == E_Trend_His_Month || m_type == E_Trend_His_Quarter || m_type == E_Trend_His_Year) + { + QPair dateTime = getFatureDataTime(m_type, ui->date->dateTime()); + double range = newRange.size() > (dateTime.second - dateTime.first)?(dateTime.second - dateTime.first):newRange.size(); + if(newRange.lower < dateTime.first) + { + ui->plot->xAxis->setRange(dateTime.first, range, Qt::AlignLeft); + return; + } + else if(newRange.upper > dateTime.second) + { + ui->plot->xAxis->setRange(dateTime.second, range, Qt::AlignRight); + return; + } + } + else if(m_type == E_Trend_His_Custom) + { + double lower = ui->startData->dateTime().toMSecsSinceEpoch(); + double upper = ui->endData->dateTime().toMSecsSinceEpoch(); + double range = newRange.size() > (upper - lower)?(upper - lower):newRange.size(); + if(newRange.lower < lower) + { + ui->plot->xAxis->setRange(lower, range, Qt::AlignLeft); + return; + } + else if(newRange.upper > upper) + { + ui->plot->xAxis->setRange(upper, range, Qt::AlignRight); + return; + } + } + + QList listToolTip= findChildren(); + foreach (CToolTip * pToolTip, listToolTip) + { + pToolTip->close(); + } + + if(E_Trend_Invalid != m_type && E_Trend_RealTime != m_type) + { + updateYAxisTicker(); + } + + E_Trend_Type rangeType = getRangeType(newRange); + if(m_type == rangeType) + { + return; + } + + if(m_type == E_Trend_His_Minute) + { + if(rangeType == E_Trend_RealTime) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-10).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Hour) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-600).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Day) + { + if(rangeType == E_Trend_His_Minute) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-600).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Week) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-1).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Week) + { + if(rangeType == E_Trend_His_Day) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-1).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Month) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-7).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Month) + { + if(rangeType == E_Trend_His_Week) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addDays(-7).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Quarter) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-1).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Quarter) + { + if(rangeType == E_Trend_His_Month) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-1).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Year) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Year) + { + if(rangeType == E_Trend_His_Quarter) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + else if(m_type == E_Trend_His_Custom) + { + if(rangeType == E_Trend_RealTime) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addSecs(-10).toMSecsSinceEpoch(), Qt::AlignCenter); + } + else if(rangeType == E_Trend_His_Year) + { + ui->plot->xAxis->setRange(midValue, newRange.upper - upper.addMonths(-3).toMSecsSinceEpoch(), Qt::AlignCenter); + } + } + +// if(rangeType != E_Trend_Invalid && rangeType != E_Trend_His_Minute && rangeType != E_Trend_His_Hour) +// { +// m_TrendTypeButton->button((int)rangeType)->setChecked(true); +// } +// updateTrendShowMode(rangeType, false); +} + +void CPlotWidget::updateTrendShowMode(int nIndex, bool updateXAxisRange) +{ + m_type = (E_Trend_Type)nIndex; + m_isSetSliderValue = true; + if(Q_NULLPTR != m_pTimer && m_pTimer->isActive()) + { + m_pTimer->stop(); + } + m_pLengedModel->setMode(CCurveLegendModel::LENGED_HIS_MODE); + if(m_isWindowMode) + { + setLegendCurveTransformColumnVisible(false); + } + //< default setting + ui->prePage->setEnabled(true); + ui->nextPage->setEnabled(true); + ui->date->setEnabled(true); + ui->plot->axisRect()->setScaleRight(false); + ui->plot->axisRect()->setRangeDrag(Qt::Horizontal); //< 水平拖拽 + ui->plot->axisRect()->setRangeZoom(Qt::Horizontal); //< 水平缩放 + ui->plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); + ui->plot->xAxis->setScaleType(QCPAxis::stLinear); + updateGraphTitle(nIndex); + updateAxisFormat(updateXAxisRange); + //< clear view + int count = ui->plot->graphCount(); + for(int n(0); nplot->graph(n); + graph->data()->clear(); + } + ui->plot->clearItems(); + m_listTracer.clear(); + m_pTableDataModel->clear(); + afterModeSwitch(); + + if (m_type == E_Trend_His_Custom) + { + slotCustomSearch(); + } + else if (m_type == E_Trend_RealTime) + { + if(E_Show_Table == m_showType) + { + updateRealTimeTableData(); + } + updateCurves(); + } + else + { + ui->date->setDateTime(QDateTime::currentDateTime()); + } +} + +TsdbCommand CPlotWidget::getHisCurveCmd(double lower, double upper, int nGroupBy, E_Data_Type type) +{ + std::vector * vecMpKey = new std::vector(); + for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) + { + if(ui->plot->graph(nIndex)->type() != type) + { + continue; + } + const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name(), ui->plot->graph(nIndex)->type()); + SMeasPointKey key; + std::string tmp = curve.tag.toStdString(); + char * tag = (char*)malloc(tmp.size() + 1); + memset(tag, 0, tmp.size() + 1); + memcpy(tag, tmp.c_str(), tmp.size()); + key.m_pszTagName = tag; + key.m_enType = getMeasType(curve.type); + vecMpKey->push_back(key); + } + + TsdbCommand cmd; + if(E_Trend_His_Hour == m_type || E_Trend_His_Minute == m_type) + { + cmd.type = E_ORIGINAL; + } + else + { + cmd.type = E_POLYMERIC; + } + cmd.dataType = type; + cmd.pVecMpKey = vecMpKey; + cmd.lower = lower; + cmd.upper = upper; + cmd.nGroupBySec = nGroupBy; + cmd.vecMethod = std::vector{iot_dbms::CM_FIRST}; + return cmd; +} + +TsdbCommand CPlotWidget::getComputeCmd(double lower, double upper, std::vector vecMethod, E_Data_Type type) +{ + std::vector * vecMpKey = new std::vector(); + for(int nIndex(0); nIndex < ui->plot->graphCount(); ++nIndex) + { + if(ui->plot->graph(nIndex)->type() != type) + { + continue; + } + const Curve &curve = m_pTrendGraph->curve(ui->plot->graph(nIndex)->name(), ui->plot->graph(nIndex)->type()); + SMeasPointKey key; + std::string tmp = curve.tag.toStdString(); + char * tag = (char*)malloc(tmp.size() + 1); + memset(tag, 0, tmp.size() + 1); + memcpy(tag, tmp.c_str(), tmp.size()); + key.m_pszTagName = tag; + key.m_enType = getMeasType(curve.type); + vecMpKey->push_back(key); + } + + TsdbCommand cmd; + cmd.type = E_COMPUTER; + cmd.dataType = type; + cmd.pVecMpKey = vecMpKey; + cmd.lower = lower; + cmd.upper = upper; + cmd.nGroupBySec = -1; + cmd.vecMethod = vecMethod; + return cmd; +} + +void CPlotWidget::updateGraphTitle(int nIndex) +{ + m_type = (E_Trend_Type)nIndex; + + if(m_type == E_Trend_RealTime) + { + m_trendTitle->setText(tr("实时趋势")); + } + else if(m_type == E_Trend_His_Minute) + { + m_trendTitle->setText(tr("秒趋势")); + } + else if(m_type == E_Trend_His_Day) + { + m_trendTitle->setText(tr("日趋势")); + } + else if(m_type == E_Trend_His_Week) + { + m_trendTitle->setText(tr("周趋势")); + } + else if(m_type == E_Trend_His_Month) + { + m_trendTitle->setText(tr("月趋势")); + } + else if(m_type == E_Trend_His_Quarter) + { + m_trendTitle->setText(tr("季度趋势")); + } + else if(m_type == E_Trend_His_Year) + { + m_trendTitle->setText(tr("年趋势")); + } + else if(m_type == E_Trend_His_Custom) + { + m_trendTitle->setText(tr("自定义趋势")); + } +} + +void CPlotWidget::updateCurves() +{ + if(E_Trend_RealTime == m_type) + { + updateRealTimeCurveRecord(); + rescaleYAxisRange(); + ui->plot->replot(); + } + else + { + updateHistoryCurveRecord(); + } +} + +void CPlotWidget::updateRealTimeCurveRecord() +{ + if(Q_NULLPTR == m_pTrendGraph) + { + return; + } + double limit = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 1, 1)); + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + //< 清空数据 + QSharedPointer container(new QCPGraphDataContainer()); + + const QVector< QPair > > &values = m_pTrendGraph->curve(graph->name(), graph->type()).values; + QVector< QPair > >::const_iterator it = values.constBegin(); + double preValue = DBL_MAX; + while (it != values.constEnd()) + { + //< LOGINFO("Update RealTime Trend Data-----------------[Time: %f, value: %f] ", it->first, it->second); + if(qAbs((it->second.first)-preValue) < _EPSILON_) + { + ++it; + continue; + } + container->add(QCPGraphData(it->first, it->second.first, it->second.second)); + preValue = it->second.first; + ++it; + } + + //< virtual point + if(container->data()->size() > 0) + { + container->add(QCPGraphData(limit, container->data()->last().value, container->data()->last().status)); + } + else + { + container->add(QCPGraphData(limit, qSqrt(-1.))); + } + graph->setData(container); + } + ui->plot->replot(); +} + +void CPlotWidget::updateHistoryCurveRecord() +{ + if(!ui->plot->graphCount()) + { + return; + } + if(E_Trend_His_Custom == m_type) + { + slotCustomSearch(true); + return; + } + + QPair range = getFatureDataTime(m_type, ui->date->dateTime()); + std::vector vecMethod{iot_dbms::CM_MAX, iot_dbms::CM_MIN}; + + QList cmdList; + TsdbCommand curve = getHisCurveCmd(ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, currentGroupByMinute() * 60, E_HISTORY); + TsdbCommand computer = getComputeCmd(range.first, range.second, vecMethod, E_HISTORY); + cmdList.push_back(curve); + cmdList.push_back(computer); + + if(m_bShowPreCurve){ + QPair preCurveRange = getOffsetRange(ui->plot->xAxis->range().lower, ui->plot->xAxis->range().upper, -1); + QPair preComputeRange = getOffsetRange(range.first, range.second, -1); + TsdbCommand preCurve = getHisCurveCmd(preCurveRange.first, preCurveRange.second, currentGroupByMinute() * 60, E_PRECURVE); + TsdbCommand perComputer = getComputeCmd(preComputeRange.first, preComputeRange.second, vecMethod, E_PRECURVE); + cmdList.push_back(preCurve); + cmdList.push_back(perComputer); + } + + if(!m_pHisDataManage->isTsdbExuting()) + { + emit sigQueryHistoryRecord(cmdList); + } + else + { + m_pHisDataManage->postTsdbCommandQueue(cmdList); + } +} + +void CPlotWidget::updateHisOriginalData(std::vector *vecMpKey, std::vector *> *vecResult, E_Data_Type type) +{ + std::vector< QSharedPointer > vecRange; + std::vector< QSharedPointer > vecContainer; + + bool isAddVirtualPoint = true; + double lower = ui->plot->xAxis->range().lower; + double upper = ui->plot->xAxis->range().upper; + if(m_showType == E_Show_Table) + { + isAddVirtualPoint = false; + } + if(m_type == E_Trend_His_Custom) + { + lower = ui->startData->dateTime().toMSecsSinceEpoch(); + upper = ui->endData->dateTime().toMSecsSinceEpoch(); + } + updateHisData(vecMpKey, vecResult, vecRange, vecContainer, lower, upper, type, isAddVirtualPoint); + + if(m_showType == E_Show_Curve) + { + updateHistoryGraph(vecMpKey, vecContainer, vecRange, type); + } + else if(m_showType == E_Show_Table) + { + updateHistoryData(vecMpKey, vecContainer, vecRange, type); + } + m_pLengedModel->update(); + + //< 释放结果集 + std::vector *>::iterator res = vecResult->begin(); + while(vecResult->end() != res) + { + delete (*res); + ++res; + } + vecResult->clear(); + delete vecResult; + + //< 释放测点信息 + std::vector::iterator key = vecMpKey->begin(); + while(vecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + + } + vecMpKey->clear(); + delete vecMpKey; +} + +void CPlotWidget::updateHisPolymericData(std::vector *vecMpKey, std::vector *> *vecResult, int nGroupBySec, E_Data_Type type) +{ + std::vector< QSharedPointer > vecRange; + std::vector< QSharedPointer > vecContainer; + + if(E_Trend_Invalid != m_type && E_Trend_RealTime != m_type) + { + if(m_showType == E_Show_Curve) + { + if(m_type == E_Trend_His_Custom) + { + updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->startData->dateTime().toMSecsSinceEpoch(), + ui->endData->dateTime().toMSecsSinceEpoch(), type, true, nGroupBySec); + } + else + { + updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->plot->xAxis->range().lower, + ui->plot->xAxis->range().upper, type, true, nGroupBySec); + } + + updateHistoryGraph(vecMpKey, vecContainer, vecRange, type); + } + else if(m_showType == E_Show_Table) + { + if(m_type == E_Trend_His_Custom) + { + updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->startData->dateTime().toMSecsSinceEpoch(), + ui->endData->dateTime().toMSecsSinceEpoch(), type, false, nGroupBySec); + } + else + { + updateHisData(vecMpKey, vecResult, vecRange, vecContainer, ui->plot->xAxis->range().lower, + ui->plot->xAxis->range().upper, type, false, nGroupBySec); + } + + updateHistoryData(vecMpKey, vecContainer, vecRange, type); + } + } + m_pLengedModel->update(); + + //< 释放结果集 + std::vector *>::iterator res = vecResult->begin(); + while(vecResult->end() != res) + { + delete (*res); + ++res; + } + vecResult->clear(); + delete vecResult; + + //< 释放测点信息 + std::vector::iterator key = vecMpKey->begin(); + while(vecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + } + vecMpKey->clear(); + delete vecMpKey; +} + +void CPlotWidget::updateHisComputeData(std::vector *vecMpKey, std::vector *> *> > cmResult, E_Data_Type type) +{ + typename std::vector *> *> >::const_iterator resultIter = cmResult.begin(); + while(resultIter != cmResult.end()) + { + EnComputeMethod method = resultIter->first; + typename std::vector *>::const_iterator it = resultIter->second->begin(); + while(it != resultIter->second->end()) + { + int nIndex = it - resultIter->second->begin(); + int nGraphIndex = m_pTrendGraph->index(vecMpKey->at(nIndex).m_pszTagName, type); + if(nGraphIndex == -1) + { + continue; + } + QCPGraph * graph = ui->plot->graph(nGraphIndex); + std::vector * vecPoint = *it; + if(vecPoint->empty()) + { + ++it; + setCurveStatisData(graph->name(), graph->type(), method, true); + continue; + } + + typename std::vector::const_iterator pt = vecPoint->begin(); + while(pt != vecPoint->end()) + { + double value = qSqrt(-1.); + if (typeid(boost::int32_t) == pt->m_varValue.type()) + { + value = (double)boost::get(pt->m_varValue); + } + else if (typeid(boost::float64_t) == pt->m_varValue.type()) + { + value = (double)boost::get(pt->m_varValue); + } + + if(std::isnan(value)) + { + ++pt; + setCurveStatisData(graph->name(), graph->type(), method, true); + continue; + } + setCurveStatisData(graph->name(), graph->type(), method, false, value, pt->m_nTime); + ++pt; + } + ++it; + } + //< 释放结果集 + std::vector *>::iterator res = resultIter->second->begin(); + while(resultIter->second->end() != res) + { + delete (*res); + ++res; + } + resultIter->second->clear(); + delete resultIter->second; + resultIter++; + } + m_pLengedModel->update(); + + //< 释放测点信息 + std::vector::iterator key = vecMpKey->begin(); + while(vecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + } + vecMpKey->clear(); + delete vecMpKey; +} + +void CPlotWidget::updateHistoryGraph(std::vector *vecMpKey, std::vector > &vecContainer, std::vector > &vecRange, E_Data_Type type) +{ + double lower = ui->plot->xAxis->range().lower; + double upper = ui->plot->xAxis->range().upper; + + if(vecContainer.size() == 0) + { + int count = ui->plot->graphCount(); + for(int n(0); nplot->graph(n); + graph->data()->clear(); + } + ui->plot->replot(); + } + + for(int nIndex(0); nIndex < (int)vecContainer.size(); ++nIndex) + { + int nGraphIndex = m_pTrendGraph->index(vecMpKey->at(nIndex).m_pszTagName, type); + if(nGraphIndex == -1) + { + continue; + } + QCPGraph * graph = ui->plot->graph(nGraphIndex); + updateCurveHisData(lower, upper, graph, nGraphIndex, vecContainer.at(nIndex), vecRange.at(nIndex), type); + graph->data()->clear(); + graph->setData(vecContainer.at(nIndex)); + } + + updateLengedValue(ui->plot->xAxis->pixelToCoord(ui->plot->symbolPos().x())); + rescaleYAxisRange(); + ui->plot->replot(); +} + +void CPlotWidget::updateHistoryData(std::vector *vecMpKey, std::vector > &vecContainer, std::vector > &vecRange, E_Data_Type type) +{ + double lower,upper; + if(m_type == E_Trend_His_Custom) + { + lower = ui->startData->dateTime().toMSecsSinceEpoch(); + upper = ui->endData->dateTime().toMSecsSinceEpoch(); + } + else + { + lower = ui->plot->xAxis->range().lower; + upper = ui->plot->xAxis->range().upper; + } + + QMap> curveData; + QStringList headerList; + for(int nIndex(0); nIndex < (int)vecContainer.size(); ++nIndex) + { + int nGraphIndex = m_pTrendGraph->index(vecMpKey->at(nIndex).m_pszTagName, type); + if(nGraphIndex == -1) + { + continue; + } + QCPGraph * graph = ui->plot->graph(nGraphIndex); + updateCurveHisData(lower, upper, graph, nGraphIndex, vecContainer.at(nIndex), vecRange.at(nIndex), type); + + QVector vecGraphData; + QCPGraphDataContainer::const_iterator iter = vecContainer.at(nIndex)->constBegin(); + while(iter != vecContainer.at(nIndex)->end()) + { + QCPGraphData graphData; + graphData.key = iter->key; + graphData.value = iter->value; + graphData.status = iter->status; + vecGraphData.push_back(graphData); + iter++; + } + curveData.insert(graph->desc(), vecGraphData); + headerList.append(graph->desc()); + } + resetCurveData(curveData, headerList, true); + enableSearch(true); +} + +void CPlotWidget::updateCurveHisData(double lower, double upper, QCPGraph *graph, int index, QSharedPointer container, QSharedPointer range, E_Data_Type type) +{ + int count = 0; //< accuml size + double offset = 0.; + double factor = 1.; + double accuml = 0.; + + const Curve &curve = m_pTrendGraph->curve(graph->name(), type); + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + double maxVal = range->max; + double minVal = range->min; + if(maxVal == minVal) + { + factor = maxVal == 0 ? 0 : 50. / maxVal; + offset = maxVal == 0 ? 50 : 0; + } + else + { + factor = 100. / (maxVal - minVal); + offset = -factor * minVal; + } + m_pTrendGraph->setCurveGraphFactor(index, factor); + m_pTrendGraph->setCurveGraphOffset(index, offset); + } + else + { + factor = curve.factor; + offset = curve.offset; + } + + //< 此设计考虑自定义缩放【已实现,暂未开放】扩展 + double max = -DBL_MAX; + double min = DBL_MAX; + double maxTime = -DBL_MAX; + double minTime = DBL_MAX; + double average = qSqrt(-1.); + QCPGraphDataContainer::iterator iter = container->begin(); + while(iter != container->end()) + { + if(qIsNaN(iter->value)) + { + ++iter; + continue; + } + + //< 统计值 + if(iter->key >= lower && iter->key <= upper) + { + ++count; + if(iter->value > max) + { + max = iter->value; + maxTime = iter->key; + } + if(iter->value < min) + { + min = iter->value; + minTime = iter->key; + } + + accuml += iter->value; + } + + //< 缩放数据 + if(m_bHisAdaption && m_type != E_Trend_RealTime + && m_showType != E_Show_Table) + { + iter->value *= factor; + iter->value += offset; + } + ++iter; + } + if(!container->isEmpty()) + { + if(count) + { + average = accuml / count; + } + } + m_pTrendGraph->setCurveHisDataValue(graph->name(), type, max, min, maxTime, minTime, average, accuml, *range); +} + +void CPlotWidget::updatePhaseTracer(std::vector *vecMpKey, std::vector *> *vecResult) +{ + ui->plot->clearItems(); + m_listTracer.clear(); + QMultiMap< double, QStringList > map; + if(ui->checkBox_alarmPoint->isChecked()) + { + for(size_t tagIndex(0); tagIndex < vecResult->size(); tagIndex++) + { + std::vector *evetVector = vecResult->at(tagIndex); + std::vector::iterator iter = evetVector->begin(); + for(; iter != evetVector->end(); iter++) + { + if(m_alarmStatusList.contains(iter->m_nAlmStatus)) + { + QStringList list; + list.append(vecMpKey->at(tagIndex).m_pszTagName); + list.append(QString::number(iter->m_nAlmType)); + map.insert(iter->m_nTime, list); + } + } + } + } + QPointF prePt(-1000., -1000.); + //< 1min 显示所有事件 + bool bMinRange = ui->plot->xAxis->range().size() > 60; + QMultiMap< double, QStringList >::iterator rIter = map.begin(); + QMultiMap hidePoint; + for(; rIter != map.end(); rIter++) + { + double key = rIter.key(); + if(bMinRange) + { + double curX = ui->plot->xAxis->coordToPixel(key); + double curY = 0; + if( m_horizontalGraph ) + { + curY = ui->plot->yAxis->coordToPixel(m_horizontalGraph->value(key)); + } + QPointF pt = QPointF(curX, curY) - prePt; + if(pt.manhattanLength() < 8) + { + hidePoint.insert(key, rIter.value()[0]); + continue; + } + prePt = QPointF(curX, curY); + } + QStringList value = rIter.value(); + QCPItemTracer *phaseTracer = new QCPItemTracer(ui->plot, key, QString(value[1]).toInt(), QPen(Qt::red), QBrush(Qt::red), m_alarmStatusList); + phaseTracer->setGraphKey(key); + if(m_horizontalGraph!=NULL && m_type != E_Trend_RealTime) + { + phaseTracer->setGraph(m_horizontalGraph); + } + phaseTracer->addHidePoint(key, value[0]); + phaseTracer->setInterpolating(true); + if(m_listTracer.length() > 0) + m_listTracer.last()->setHidePoint(hidePoint); + m_listTracer.append(phaseTracer); + + connect(phaseTracer, &QCPItemTracer::itemTracerHoverd, m_pHisEventManage, &CHisEventManage::queryHisEvent, Qt::BlockingQueuedConnection); + hidePoint.clear(); + hidePoint.insert(key, value[0]); + } + if(m_listTracer.length() > 0 && !hidePoint.isEmpty()) + { + m_listTracer.last()->setHidePoint(hidePoint); + hidePoint.clear(); + } + //< 释放结果集 + std::vector *>::iterator res = vecResult->begin(); + while(res != vecResult->end()) + { + delete (*res); + ++res; + } + delete vecResult; + + //< 释放测点信息 + std::vector::iterator key = vecMpKey->begin(); + while(vecMpKey->end() != key) + { + free( (char*)key->m_pszTagName ); + ++key; + } + vecMpKey->clear(); + delete vecMpKey; + ui->plot->replot(); +} + +void CPlotWidget::updateGraphEvent(const qint64 &time, QStringList contents) +{ + foreach (QCPItemTracer *phaseTracer, m_listTracer) + { + if(phaseTracer->timeStamp() == time) + { + phaseTracer->setInfo(contents); + phaseTracer->showTips(); + } + } +} + +void CPlotWidget::updateAxisFormat(bool updateXAxisRange) +{ +// ui->plot->xAxis->blockSignals(true); + QSharedPointer ticker = qSharedPointerDynamicCast(ui->plot->xAxis->ticker()); + double upper = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()); + switch (m_type) + { + case E_Trend_RealTime: + { + //< 10 min + ui->prePage->setEnabled(false); + ui->nextPage->setEnabled(false); + ui->date->setEnabled(false); + ui->plot->setInteractions(QCP::iRangeZoom | QCP::iSelectPlottables); + ui->plot->axisRect()->setScaleRight(true); + ticker->setDateTimeFormat("hh:mm:ss"); + ui->plot->xAxis->setRange(upper, m_rtRange, Qt::AlignRight); + if(Q_NULLPTR != m_pTimer) + { + m_pTimer->start(); + } + if(m_isWindowMode) + { + ticker->setTickCount(11); + setLegendCurveTransformColumnVisible(true); + } + else + { + ticker->setTickCount(6); + } + + m_pLengedModel->setMode(CCurveLegendModel::LENGED_RT_MODE); + ui->plot->yAxis->setTicker(m_ptrPlotTricker); + ui->plot->yAxis2->setTicker(m_ptrPlotTricker); + } + break; + case E_Trend_His_Minute: + { + if(m_isWindowMode) + { + ticker->setTickCount(12); + } + else + { + ticker->setTickCount(6); + } + ticker->setDateTimeFormat("hh:mm:ss"); + ui->date->setMinimumWidth(170); + ui->date->setDisplayFormat("yyyy-MM-dd hh:mm"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Minute); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Hour: + { + if(m_isWindowMode) + { + ticker->setTickCount(11); + } + else + { + ticker->setTickCount(6); + } + ticker->setDateTimeFormat("hh:mm:ss"); + } + break; + case E_Trend_His_Day: + { + if(m_isWindowMode) + { + ticker->setTickCount(12); + } + else + { + ticker->setTickCount(6); + } + ticker->setDateTimeFormat("hh:mm:ss"); + ui->date->setMinimumWidth(120); + ui->date->setDisplayFormat("yyyy-MM-dd"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Day); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Week: + { + if(m_isWindowMode) + { + ticker->setTickCount(8); + } + else + { + ticker->setTickCount(6); + } + ticker->setDateTimeFormat("MM-dd hh ddd"); + ui->date->setMinimumWidth(120); + ui->date->setDisplayFormat("yyyy-MM-dd"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Week); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Month: + { + if(m_isWindowMode) + { + ticker->setTickCount(11); + } + else + { + ticker->setTickCount(10); + } + ticker->setDateTimeFormat("dd hh"); + ui->date->setMinimumWidth(120); + ui->date->setDisplayFormat("yyyy-MM"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Month); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Quarter: + { + if(m_isWindowMode) + { + ticker->setTickCount(10); + } + else + { + ticker->setTickCount(10); + } + ticker->setDateTimeFormat("MM-dd"); + ui->date->setMinimumWidth(120); + ui->date->setDisplayFormat("yyyy-MM"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Quarter); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Year: + { + if(m_isWindowMode) + { + ticker->setTickCount(13); + } + else + { + ticker->setTickCount(10); + } + ticker->setDateTimeFormat("MM-dd"); + ui->date->setMinimumWidth(120); + ui->date->setDisplayFormat("yyyy"); + if(updateXAxisRange) + { + QPair range = getFatureDataTime(E_Trend_His_Year); + ui->plot->xAxis->setRange(range.first, range.second); + } + } + break; + case E_Trend_His_Custom: + { + ticker->setTickCount(5); + + ticker->setDateTimeFormat("MM-dd hh:mm:ss"); + if(updateXAxisRange) + { + ui->plot->xAxis->setRange(ui->startData->dateTime().toMSecsSinceEpoch(), + ui->endData->dateTime().toMSecsSinceEpoch()); + } + } + break; + default: + break; + } +// ui->plot->xAxis->blockSignals(false); +} + +QPair CPlotWidget::getFatureDataTime(E_Trend_Type type, QDateTime curTime) +{ + QDateTime low; + QDateTime up; + QPair range; + if(!curTime.isValid()) + { + low = QDateTime::currentDateTime(); + up = QDateTime::currentDateTime(); + } + else + { + low = curTime; + up = curTime; + } + + switch (type) { + case E_Trend_His_Day: + { + break; + } + case E_Trend_His_Minute: + { + int minute = up.time().minute(); + up.setTime(QTime(up.time().hour(), (minute/10)*10+9, 59, 999)); + low.setTime(QTime(low.time().hour(), (minute/10)*10)); + range.first = low.toMSecsSinceEpoch(); + range.second = up.toMSecsSinceEpoch(); + return range; + } + case E_Trend_His_Week: + { + up = up.addDays(7-low.date().dayOfWeek()); + low = low.addDays(-low.date().dayOfWeek()+1); + break; + } + case E_Trend_His_Month: + { + up.setDate(QDate(low.date().year(), low.date().month(), low.date().daysInMonth())); + low.setDate(QDate(low.date().year(), low.date().month(), 1)); + break; + } + case E_Trend_His_Quarter: + { + QString month = QString::number(low.date().month()); + if(QString("1,2,3").split(",").indexOf(month) != -1) + { + up.setDate(QDate(low.date().year(), 3, 31)); + low.setDate(QDate(low.date().year(), 1, 1)); + } + else if(QString("4,5,6").split(",").indexOf(month) != -1) + { + up.setDate(QDate(low.date().year(), 6, 30)); + low.setDate(QDate(low.date().year(), 4, 1)); + } + else if(QString("7,8,9").split(",").indexOf(month) != -1) + { + up.setDate(QDate(low.date().year(), 9, 30)); + low.setDate(QDate(low.date().year(), 7, 1)); + } + else if(QString("10,11,12").split(",").indexOf(month) != -1) + { + up.setDate(QDate(low.date().year(), 12, 31)); + low.setDate(QDate(low.date().year(), 10, 1)); + } + break; + } + case E_Trend_His_Year: + { + up.setDate(QDate(low.date().year(), 12, 31)); + low.setDate(QDate(low.date().year(), 1, 1)); + break; + } + default: + break; + } + low.setTime(QTime(0,0,0)); + up.setTime(QTime(23,59,59)); + range.first = low.toMSecsSinceEpoch(); + range.second = up.toMSecsSinceEpoch(); + return range; +} + +void CPlotWidget::updateAdaptState(bool isAdapt) +{ + m_isSetSliderValue = true; + m_bHisAdaption = isAdapt; + if(m_isWindowMode) + { + setLegendCurveTransformColumnVisible(isAdapt); + } + updateCurves(); + + updateYAxisTicker(); +} + +void CPlotWidget::updatePreCurveState(bool isPreCurve) +{ + m_bShowPreCurve = isPreCurve; + if(m_bShowPreCurve) + { + const QList curves = m_pTrendGraph->curves(); + for(int n = 0; n < curves.length(); ++n) + { + if(curves[n].tag == "curve.tag") + { + continue; + } + Curve preCurve; + preCurve.tag = curves[n].tag; + preCurve.desc = tr("昨日曲线-") + curves[n].desc; + preCurve.type = curves[n].type; + preCurve.unit = curves[n].unit; + preCurve.color = curves[n].color.darker(200); + preCurve.curveType = enPrevCurve; + m_pTrendGraph->addCurve(preCurve); + QCPGraph * graph = ui->plot->addGraph(); + graph->setName(preCurve.tag); + graph->setDesc(preCurve.desc); + graph->setType(preCurve.curveType); + QPen pen; + pen.setWidth(1); + pen.setColor(preCurve.color.darker(200)); + graph->setPen(pen); + updateCurveSelectionColor(graph); + connect(graph, SIGNAL(selectionChanged(bool)), this, SLOT(graphSelectionChanged(bool)), Qt::QueuedConnection); + //< 方波 + QString type = CTrendInfoManage::instance()->getTagType(preCurve.tag); + if(type == "digital" || type == "mix") + { + graph->setLineStyle(QCPGraph::lsStepLeft); + } + } + updateCurves(); + } + else + { + const QList curves = m_pTrendGraph->curves(); + for(int n = curves.length() - 1; n >= 0; --n) + { + if(curves[n].curveType != enPrevCurve) + { + continue; + } + m_pTrendGraph->removeCurve(n); + ui->plot->removeGraph(n); + } + rescaleYAxisRange(); + ui->plot->replot(); + } + m_pLengedModel->setTrendGraph(m_pTrendGraph); +} + +void CPlotWidget::slotCollectGraph(const QString &text) +{ + emit collectGraph(text, *m_pTrendGraph); +} + +void CPlotWidget::slotSliderRangeChange(int lower, int upper) +{ + m_isSetSliderValue = false; + if(lower <= upper) + { + ui->scaleSlider->setLowerValue(lower); + ui->scaleSlider->setUpperValue(upper); + } +} + +void CPlotWidget::addCollect() +{ + QPoint pt = ui->collectCurve->mapToGlobal(QPoint()); + int x = pt.x() + ui->collectCurve->width(); + int y = pt.y() + ui->collectCurve->height(); + emit sigAddCollect(x, y); +} + +void CPlotWidget::slotPrint() +{ + QString strFileName = QFileDialog::getSaveFileName(Q_NULLPTR, tr("保存为"), QString("/%1.jpg").arg(ui->title->text()), tr("(*.jpg)"), + Q_NULLPTR, QFileDialog::DontUseNativeDialog); + + if(strFileName.isEmpty()) + { + return; + } + ui->plot->legend->setVisible(true); + m_trendTitle->setVisible(true); + ui->plot->replot(QCustomPlot::rpImmediateRefresh); + bool ret = ui->plot->saveJpg(strFileName, 1600, 800); + ui->plot->legend->setVisible(false); + m_trendTitle->setVisible(false); + ui->plot->replot(QCustomPlot::rpImmediateRefresh); + if(ret) + { + QMessageBox::information(this,tr("提示"),tr("保存成功"),QMessageBox::Ok); + } + else + { + QMessageBox::information(this,tr("提示"),tr("保存失败"),QMessageBox::Ok); + } +} + +void CPlotWidget::slotExport() +{ + QString strFileName = QFileDialog::getSaveFileName(Q_NULLPTR, tr("保存为"), QString("/%1.xlsx").arg(ui->title->text()), tr("(*.xlsx)"), + Q_NULLPTR, QFileDialog::DontUseNativeDialog); + if(strFileName.isEmpty()) + return; + + QXlsx::Document xlsx; + + for(int col = 0; col < m_pTableDataModel->columnCount(); col++) + { + xlsx.write(hexTo26(col)+"1", m_pTableDataModel->headerData(col, Qt::Horizontal, Qt::ToolTipRole)); + xlsx.setColumnWidth(col+1, 35); + } + + QXlsx::Format format; + QColor lastColor, curColor; + for(int row = 0; row < m_pTableDataModel->rowCount(); row++) + { + for(int col = 0; col < m_pTableDataModel->columnCount(); col++) + { + QModelIndex index = m_pTableDataModel->index(row, col); + curColor = QColor(m_pTableDataModel->data(index, Qt::UserRole).toInt() * 4288716964); + if(lastColor != curColor) + { + format.setFontColor(curColor); + lastColor = curColor; + } + xlsx.write(hexTo26(col)+QString::number(row+2), m_pTableDataModel->data(index), format); + } + } + + if(xlsx.saveAs(strFileName)) + { + QMessageBox::information(this,tr("提示"),tr("导出成功!\n导出路径:")+strFileName); + } + else + { + QMessageBox::information(this,tr("提示"),tr("保存失败")); + } +} + +void CPlotWidget::prePage() +{ + m_isSetSliderValue = true; + QDateTime dateTime = ui->date->dateTime(); + switch(m_type) + { + case E_Trend_His_Minute: + { + ui->date->setDateTime(dateTime.addSecs(-600)); + break; + } + case E_Trend_His_Hour: + case E_Trend_His_Day: + { + ui->date->setDateTime(dateTime.addDays(-1)); + break; + } + case E_Trend_His_Week: + { + ui->date->setDateTime(dateTime.addDays(-7)); + break; + } + case E_Trend_His_Month: + { + ui->date->setDateTime(dateTime.addMonths(-1)); + break; + } + case E_Trend_His_Quarter: + { + ui->date->setDateTime(dateTime.addMonths(-3)); + break; + } + case E_Trend_His_Year: + { + ui->date->setDateTime(dateTime.addYears(-1)); + break; + } + default: + return; + } + + QPair range = getFatureDataTime(m_type, ui->date->dateTime()); + ui->plot->xAxis->blockSignals(true); + ui->plot->xAxis->setRange(range.first, range.second); + ui->plot->xAxis->blockSignals(false); + updateCurves(); +} + +void CPlotWidget::nextPage() +{ + m_isSetSliderValue = true; + QDateTime dateTime = ui->date->dateTime(); + switch(m_type) + { + case E_Trend_His_Minute: + { + ui->date->setDateTime(dateTime.addSecs(600)); + break; + } + case E_Trend_His_Hour: + case E_Trend_His_Day: + { + ui->date->setDateTime(dateTime.addDays(1)); + break; + } + case E_Trend_His_Week: + { + ui->date->setDateTime(dateTime.addDays(7)); + break; + } + case E_Trend_His_Month: + { + ui->date->setDateTime(dateTime.addMonths(1)); + break; + } + case E_Trend_His_Quarter: + { + ui->date->setDateTime(dateTime.addMonths(3)); + break; + } + case E_Trend_His_Year: + { + ui->date->setDateTime(dateTime.addYears(1)); + break; + } + default: + return; + } + + QPair range = getFatureDataTime(m_type, ui->date->dateTime()); + ui->plot->xAxis->blockSignals(true); + ui->plot->xAxis->setRange(range.first, range.second); + ui->plot->xAxis->blockSignals(false); + updateCurves(); +} + +void CPlotWidget::graphVisibleChanged(const bool &check) +{ + Q_UNUSED(check); + + //< 脚本调用setTagVisible导致无法自适应 +// m_isSetSliderValue = check; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + const Curve &curve = m_pTrendGraph->curve(graph->name(), graph->type()); + graph->setVisible(curve.visible); + if(!curve.visible || curve.tag == "curve.tag") + { + graph->removeFromLegend(ui->plot->legend); + m_pTableDataModel->setColumnHidden(graph->desc(), true); + } + else + { + graph->addToLegend(ui->plot->legend); + m_pTableDataModel->setColumnHidden(graph->desc(), false); + } + } + ui->plot->clearItems(); + m_listTracer.clear(); + removeCurvesGroupQuery(); + rescaleYAxisRange(); + ui->plot->replot(); +} + +void CPlotWidget::graphPropertyChanged() +{ + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + const Curve &curve = m_pTrendGraph->curve(graph->name(), graph->type()); + graph->setPen(curve.color); + updateCurveSelectionColor(graph); + } + ui->lengedView->setCurrentIndex(ui->lengedView->model()->index(ui->lengedView->currentIndex().row(), 0)); + updateCurves(); +} + +void CPlotWidget::deleteCurrentGraph() +{ + int index = ui->lengedView->currentIndex().row(); + if(m_pTrendGraph->curves().size() > 0 && index >= 0) + { + QCPGraph * graph = ui->plot->graph(index); + const Curve &curve = m_pTrendGraph->curve(graph->name(), graph->type()); + QString tag = curve.tag; + if(tag != "curve.tag") + { + removeTag(tag); + emit updateTagCheckState(tag,false); + } + } +} + +void CPlotWidget::jumpToMaxTime(const double &time) +{ + if(m_type == E_Trend_His_Minute) + { + double range = ui->plot->xAxis->range().size() / 2.0; + ui->plot->xAxis->setRange(time - range, time + range); + updateCurves(); + ui->plot->setSymbolPos(QPoint(ui->plot->xAxis->coordToPixel(time), 0)); + } + else + { + setDisplayTime(E_Trend_His_Minute, time, false); + } +} + +void CPlotWidget::jumpToMinTime(const double &time) +{ + if(m_type == E_Trend_His_Minute) + { + double range = ui->plot->xAxis->range().size() / 2.0; + ui->plot->xAxis->setRange(time - range, time + range); + updateCurves(); + ui->plot->setSymbolPos(QPoint(ui->plot->xAxis->coordToPixel(time), 0)); + } + else + { + setDisplayTime(E_Trend_His_Minute, time, false); + } +} + +void CPlotWidget::updateLengedValue(const double &dateTime) +{ + QList listVal; + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + QCPGraph * graph = ui->plot->graph(nIndex); + double graphValue = graph->value(dateTime); + const Curve &curve = m_pTrendGraph->curve(graph->name(), graph->type()); + double value = graphValue; + + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + value = (graphValue - curve.graphOffset) / curve.graphFactor; + } + listVal.append(value); + } + m_pLengedModel->setTrendCurrentValues(listVal); +} + +void CPlotWidget::graphSelectionChanged(bool select) +{ + ui->lengedView->selectionModel()->clear(); + updateYAxisTicker(); + + QCPGraph * graph = dynamic_cast(sender()); + if(Q_NULLPTR != graph && select) + { + ui->lengedView->selectRow(m_pTrendGraph->index(graph->name(), graph->type())); + } + ui->plot->replot(QCustomPlot::rpQueuedRefresh); +} + +void CPlotWidget::tableSelectionChanged(const QModelIndex &index) +{ + ui->lengedView->selectRow(index.column()-1); +} + +void CPlotWidget::updateGraphSelection() +{ + ui->plot->blockSignals(true); +// ui->plot->clearItems(); + ui->plot->deselectAll(); + ui->plot->blockSignals(false); + int index = ui->lengedView->currentIndex().row(); + QCPGraph * graph = ui->plot->graph(index); + if(graph) + { + if(E_Show_Table == m_showType) + { + int column = m_pTableDataModel->getHeaderIndex(graph->desc()); + if(column < 0) + { + ui->m_dataView->clearSelection(); + } + else + { + ui->m_dataView->selectColumn(column+1); + } + } + else if(E_Show_Curve == m_showType) + { + QCPDataSelection selection(QCPDataRange(0, 1)); + graph->setSelection(selection); + } + } + ui->plot->replot(); +} + +void CPlotWidget::updateYAxisTicker() +{ + QList graphs = ui->plot->selectedGraphs(); + if(graphs.isEmpty()) + { + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + QSharedPointer ticker(new QCPAxisTickerText); + for(int nIndex(0); nIndex <= 100; nIndex+= 20) + { + ticker->addTick(nIndex, " "); + } + ui->plot->yAxis->setTicker(ticker); + ui->plot->yAxis2->setTicker(ticker); + ui->plot->replot(QCustomPlot::rpQueuedRefresh); + return; + } + } + else + { + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + QSharedPointer ticker(new QCPAxisTickerText); + const Curve &curve = m_pTrendGraph->curve(graphs.first()->name(), graphs.first()->type()); + if(!curve.visible) + { + return; + } + QString strUnit = QString(); + if(!curve.unit.isEmpty()) + { + strUnit = QString("\n%1").arg(curve.unit); + } + double min = curve.hisPlotRange.min; + double max = curve.hisPlotRange.max; + double range = max - min; + int lower = ui->scaleSlider->lowerValue(); + int upper = ui->scaleSlider->upperValue(); + if(range != 0 && min == 0) + { + min -= range * abs(upper / (max * 5)); + max += range * abs(lower / (min * 5)); + } + else if(range != 0 && max == 0) + { + max += range * abs(lower / (min * 5)); + min -= range * abs(upper / (max * 5)); + } + if(range == 0) + { + ticker->addTick(50, QString::number(curve.hisPlotRange.max, 'f', 1) + strUnit); + ui->plot->yAxis->setTicker(ticker); + ui->plot->yAxis2->setTicker(ticker); + }else + { + QList ticks = regulate(min, max, 11); + if(!ticks.isEmpty()) + { + double range = curve.hisPlotRange.max - curve.hisPlotRange.min; + for(int nIndex(0); nIndex < ticks.size(); nIndex += 2) + { + ticker->addTick((ticks.at(nIndex) - curve.hisPlotRange.min) / range * 100, QString::number((ticks.at(nIndex)), 'f', 1) + strUnit); + } + ui->plot->yAxis->setTicker(ticker); + ui->plot->yAxis2->setTicker(ticker); + } + } + ui->plot->replot(QCustomPlot::rpQueuedRefresh); + return; + } + } + ui->plot->yAxis->setTicker(m_ptrPlotTricker); + ui->plot->yAxis2->setTicker(m_ptrPlotTricker); + ui->plot->replot(QCustomPlot::rpQueuedRefresh); +} + +void CPlotWidget::installMousePressEventFilter() +{ + ui->plot->installEventFilter(this); + + ui->realTime->installEventFilter(this); + ui->sec->installEventFilter(this); + ui->day->installEventFilter(this); + ui->week->installEventFilter(this); + ui->month->installEventFilter(this); + ui->quarter->installEventFilter(this); + ui->year->installEventFilter(this); + ui->adapt->installEventFilter(this); + ui->checkBox_alarmPoint->installEventFilter(this); + ui->comboBox_alarmStatus->installEventFilter(this); + ui->plotExport->installEventFilter(this); + ui->plotPrint->installEventFilter(this); + ui->prePage->installEventFilter(this); + ui->nextPage->installEventFilter(this); + ui->date->installEventFilter(this); + ui->clear->installEventFilter(this); + ui->scaleSlider->installEventFilter(this); + ui->switchBtn->installEventFilter(this); + ui->m_dataView->viewport()->installEventFilter(this); + ui->m_dataView->horizontalHeader()->viewport()->installEventFilter(this); + ui->lengedView->viewport()->installEventFilter(this); + ui->lengedView->horizontalHeader()->viewport()->installEventFilter(this); +} + +EnMeasPiontType CPlotWidget::getMeasType(const QString &type) +{ + if ("analog" == type) + { + return MPT_AI; //< 模拟量 + } + else if ("digital" == type) + { + return MPT_DI; //< 数字量 + } + else if ("mix" == type) + { + return MPT_MIX; //< 混合量 + } + else if ("accuml" == type) + { + return MPT_ACC; //< 累计(电度)量 + } + return MPT_AI; //< INVALID +} + +void CPlotWidget::setLegendCurveTransformColumnVisible(const bool &visible) +{ + Q_UNUSED(visible) + ui->lengedView->setColumnHidden(CCurveLegendModel::FACTOR, true); + ui->lengedView->setColumnHidden(CCurveLegendModel::OFFSET, true); +} + +QList CPlotWidget::regulate(double min, double max, int tickCount) +{ + QList ticks; + if (tickCount < 1 || max < min) + { + return ticks; + } + + double delta = max - min; + if (delta < 1.0) + { + max += (1.0 - delta) / 2.0; + min -= (1.0 - delta) / 2.0; + } + delta = max - min; + + int exp = (int)(log(delta) / log(10.0)) - 2; + double multiplier = pow(10, exp); + const double solutions[] = { 1, 2, 2.5, 5, 10, 20, 25, 50, 100, 200, 250, 500 }; + + int nIndex = 0; + for (; nIndex < (int)(sizeof(solutions) / sizeof(double)); ++nIndex) + { + double multiCal = multiplier * solutions[nIndex]; + if (((int)(delta / multiCal) + 1) <= tickCount) + { + break; + } + } + + double interval = multiplier * solutions[nIndex]; + + double startPoint = ((int)ceil(min / interval) - 1) * interval; + for (int axisIndex = 0; startPoint + interval*axisIndex <= max; axisIndex++) + { + ticks.append(startPoint + interval*axisIndex); + } + return ticks; +} + +void CPlotWidget::rescaleYAxisRange() +{ + QPair range = regulateYAxisRange(); + if(range.first == DBL_MAX || range.second == -DBL_MAX) + { +// ui->plot->yAxis->setRange(-1, 1); +// ui->plot->yAxis->rescale(true); + } + else + { + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + double factor = (range.second == range.first) ? 0 : 100. / (range.second - range.first); + double offset = -factor * range.first; + range.first = range.first * factor + offset - 1.0; + range.second = range.second * factor + offset + 1.0; + } + setSliderRange(range.first, range.second, m_isSetSliderValue); + ui->plot->yAxis->setRange(ui->scaleSlider->lowerValue(), ui->scaleSlider->upperValue()); + } + + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + updateYAxisTicker(); + } + else + { + ui->plot->replot(); + } + if(m_horizontalGraph) + { + updateHorizontalLine(); + } +} + +QPair CPlotWidget::regulateYAxisRange() +{ + const QList &curveList = m_pTrendGraph->curves(); + QPair range(DBL_MAX,-DBL_MAX); + for(int nIndex=0; nIndex max) + qSwap(min, max); + + double center = (max + min) / 2; + double offset1 = max - center; + double offset2 = center - min; + double offset = offset1 > offset2 ? offset1 : offset2; + int bs = 4; + if(offset < 1) + offset = 1; + + int low = center - bs * offset; + int up = center + bs * offset; + if(low == 0) + low = -2.0; + if(up == 0) + up = 2.0; + + if(low < range.first) + range.first = low; + if(up > range.second) + range.second = up; + } + return range; +} + +void CPlotWidget::setSliderRange(double lower, double upper, bool setValue) +{ + if(lower > upper) + qSwap(lower, upper); + + int range = upper - lower; + int lastUpper = ui->scaleSlider->upperValue(); + int lastLower = ui->scaleSlider->lowerValue(); + + int minimum; + int maximum; + if(lower == 0 && upper == 0) + { + minimum = -10; + maximum = 10; + } + else if(lower >= 0) + { + minimum = lower / 2 - range/5; + maximum = upper * 2 + range/5; + } + else if(upper <= 0) + { + minimum = lower * 2 - range/5; + maximum = upper / 2 + range/5; + } + else if(upper > 0 && lower < 0) + { + minimum = lower * 2 - range/5; + maximum = upper * 2 + range/5; + } + + if(setValue) + { + ui->scaleSlider->setMinimum(minimum); + ui->scaleSlider->setMaximum(maximum); + ui->scaleSlider->setLowerValue(lower - range/5); + ui->scaleSlider->setUpperValue(upper + range/5); + } + else + { + if(lastLower > minimum) + { + ui->scaleSlider->setMinimum(minimum); + } + if(lastUpper < maximum) + { + ui->scaleSlider->setMaximum(maximum); + } + } +} + +void CPlotWidget::setCurveStatisData(const QString &tag, const int &curType, EnComputeMethod method, bool reset, const double &value, const double &time) +{ + switch (method) { + case CM_MAX: + { + if(reset) + { + m_pTrendGraph->resetCurveStatisMax(tag, curType); + } + else + { + m_pTrendGraph->setCurveStatisMax(tag, curType, value, time); + } + break; + } + case CM_MIN: + { + if(reset) + { + m_pTrendGraph->resetCurveStatisMin(tag, curType); + } + else + { + m_pTrendGraph->setCurveStatisMin(tag, curType, value, time); + } + break; + } + default: + break; + } +} + +void CPlotWidget::setYAxisRange() +{ + int lower = ui->scaleSlider->lowerValue(); + int upper = ui->scaleSlider->upperValue(); + QCPRange range(lower, upper); + ui->plot->yAxis->setRange(range); + + if(m_bHisAdaption && m_type != E_Trend_RealTime) + { + updateYAxisTicker(); + } + else + { + ui->plot->replot(); + } + if(m_horizontalGraph) + { + updateHorizontalLine(); + } +} + +void CPlotWidget::sliderPressed() +{ + m_isSetSliderValue = false; +} + +void CPlotWidget::sliderDoubleClick(int x, int y) +{ + emit sigSliderRangeSet(x, y, + ui->scaleSlider->lowerValue(), + ui->scaleSlider->upperValue(), + ui->scaleSlider->minimum(), + ui->scaleSlider->maximum()); +} + +bool CPlotWidget::isMutation(const double &preValue, const double &curValue) +{ + if(preValue == 0) + { + return true; + } + + double coeff = qAbs(0.5 * preValue); + + if(qAbs(curValue-preValue) > coeff) + { + return true; + } + return false; +} + +template +void CPlotWidget::updateHisData(std::vector *vecMpKey, std::vector*> *vecResult, + std::vector > &vecRange, std::vector< QSharedPointer > &vecContainer, + double lower, double upper, E_Data_Type type, + bool isAddVirtualPoint, int nGroupBySec) +{ + int nMaxIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000 + nGroupBySec * 1000; + QPair offsetRange = qMakePair(lower, upper); + if(type == E_PRECURVE){ + offsetRange = getOffsetRange(lower, upper, -1); + } + typename std::vector *>::const_iterator it = vecResult->begin(); + while(it != vecResult->end()) + { + QSharedPointer range(new Range()); + QSharedPointer container(new QCPGraphDataContainer()); + vecRange.push_back(range); + vecContainer.push_back(container); + + //< Valid Check + std::vector<_Tp> * vecPoint = *it; + if(vecPoint->empty()) + { + ++it; + continue; + } + + //< Graph Bound + _Tp left; + left.m_nTime = offsetRange.first; + typename std::vector<_Tp>::iterator varHisLeft = std::upper_bound((*vecPoint).begin(), (*vecPoint).end(), left, compareVarPoint<_Tp>); + if(varHisLeft != (*vecPoint).begin() && varHisLeft != (*vecPoint).end()) + { + --varHisLeft; + } + + _Tp right; + right.m_nTime = offsetRange.second; + typename std::vector<_Tp>::iterator varHisRight = std::lower_bound((*vecPoint).begin(), (*vecPoint).end(), right, compareVarPoint<_Tp>); + if(varHisRight == (*vecPoint).end()) + { + varHisRight = (*vecPoint).end() - 1; + } + ++varHisRight; + + //< Prepare Work(used: record Interval) + E_Point_Type pointType; + switch (vecMpKey->at(it - vecResult->begin()).m_enType) + { + case MPT_AI:{ + pointType = E_ANALOG; + break; + } + case MPT_DI:{ + pointType = E_DIGITAL; + break; + } + case MPT_MIX:{ + pointType = E_MIX; + break; + } + case MPT_ACC:{ + pointType = E_ACCUML; + break; + } + default: + break; + } + qint64 lastTimeStamp = -1; + double lastValue = qSqrt(-1.); + int lastStatus = 0; + + //< Handle Data + typename std::vector<_Tp>::iterator pt = varHisLeft; + double offsetTime = 0; + if(pt != varHisRight) + { + if(type == E_PRECURVE){ + offsetTime = getOffsetTime(pt->m_nTime); + } + } + while(pt != varHisRight) + { + pt->m_nTime += offsetTime; + double value = qSqrt(-1.); + if (typeid(boost::int32_t) == pt->m_varValue.type()) + { + value = (double)boost::get(pt->m_varValue); + } + else if (typeid(boost::float64_t) == pt->m_varValue.type()) + { + value = (double)boost::get(pt->m_varValue); + } + + if(std::isnan(value)) + { + ++pt; + continue; + } + + if(value > range->max) + { + range->max = value; + } + if(value < range->min) + { + range->min = value; + } + + qint64 timeStamp = pt->m_nTime; + int status = CTrendInfoManage::instance()->getInvalidStatus(pointType, pt->m_nStatus); + if(lastTimeStamp > 0 && lastTimeStamp + nMaxIntervalSecs < timeStamp) + { + container->add(QCPGraphData(lastTimeStamp+nGroupBySec*1000, qSqrt(-1.), lastStatus)); + } + else if(lastTimeStamp > 0 && isMutation(lastValue, value) && isAddVirtualPoint) + { + container->add(QCPGraphData(timeStamp, lastValue, lastStatus)); + } + container->add(QCPGraphData(timeStamp, value, status)); + lastTimeStamp = timeStamp; + lastValue = value; + lastStatus = status; + ++pt; + } + ++it; + } +} + +template +bool CPlotWidget::checkStatus(const _Tp &var, const int &nInvalid) +{ + Q_UNUSED(var); + Q_UNUSED(nInvalid); + return true; +} + +template +bool CPlotWidget::checkStatus(const SVarHisSamplePoint &var, const int &nInvalid) +{ + return nInvalid == (var.m_nStatus & nInvalid); +} + +void CPlotWidget::slotDateTimeChanged(const QDateTime &dateTime) +{ + m_isSetSliderValue = true; + QPair range = getFatureDataTime(m_type, dateTime); + ui->plot->xAxis->blockSignals(true); + ui->plot->xAxis->setRange(range.first, range.second); + ui->plot->xAxis->blockSignals(false); + + updateCurves(); +} + +void CPlotWidget::updateGroupQuery(const QString &tag) +{ + if(tag == "curve.tag") + return; + + QMap::iterator iter = m_groupTagMap.begin(); + while(iter != m_groupTagMap.end()) + { + if(iter.value().contains(tag)) + return; + iter++; + } + QString device = tag.section(".", 0, 1); + QString deviceGroup = CTrendInfoManage::instance()->queryDeviceGroup(device); + if(deviceGroup.isEmpty()) + { + ui->plot->replot(QCustomPlot::rpQueuedReplot); + return; + } + QStringList tagList = CTrendInfoManage::instance()->queryTagListDevGroup(deviceGroup); + if(!m_groupTagMap.keys().contains(deviceGroup)) + { + m_groupTagMap.insert(deviceGroup,tagList); + groupQueryHistoryEvent(); + } +} + +void CPlotWidget::removeCurvesGroupQuery() +{ + m_groupTagMap.clear(); + for(int nIndex(0); nIndex < ui->plot->graphCount(); nIndex++) + { + if(ui->plot->graph(nIndex)->visible() == true) + { + updateGroupQuery(ui->plot->graph(nIndex)->name()); + } + } +} + +void CPlotWidget::groupQueryHistoryEvent() +{ + if(m_type == E_Trend_RealTime || m_groupTagMap.isEmpty() || NULL == m_horizontalGraph) + { + ui->plot->clearItems(); + m_listTracer.clear(); + return; + } + + std::vector * vecMpKey = new std::vector(); + QMap::iterator iter = m_groupTagMap.begin(); + while(iter != m_groupTagMap.end()) + { + foreach (QString tagName, iter.value()) { + SMeasPointKey key; + std::string tmp = tagName.toStdString(); + char * tag = (char*)malloc(tmp.size() + 1); + memset(tag, 0, tmp.size() + 1); + memcpy(tag, tmp.c_str(), tmp.size()); + key.m_pszTagName = tag; + key.m_enType = getMeasType(CTrendInfoManage::instance()->getTagType(tagName)); + vecMpKey->push_back(key); + } + iter++; + } + + int ByMinute = currentGroupByMinute(); + int g_groupByDuration = ByMinute * 60; + + QList cmdList; + TsdbCommand cmd; + cmd.type = E_EVENTPOINT; + cmd.dataType = E_HISTORY; + cmd.pVecMpKey = vecMpKey; + cmd.lower = ui->plot->xAxis->range().lower; + cmd.upper = ui->plot->xAxis->range().upper; + cmd.nGroupBySec = g_groupByDuration; + if(g_groupByDuration == 0) + { + cmd.vecMethod = std::vector{iot_dbms::CM_NULL}; + } + else + { + cmd.vecMethod = std::vector{iot_dbms::CM_SAMPLE}; + } + cmdList.push_back(cmd); + + if(!m_pHisDataManage->isTsdbExuting()) + { + emit sigQueryHistoryRecord(cmdList); + } + else + { + m_pHisDataManage->postTsdbCommandQueue(cmdList); + } + + ui->plot->replot(); +} + +void CPlotWidget::initAlarmStatusFilter() +{ + m_pListWidget = new CMyListWidget(this); + m_pLineEdit = new QLineEdit(this); + QMap > m_alarmShowStatus = CTrendInfoManage::instance()->getAlarmShowStatus(); + m_strText = ""; + for(QMap >::const_iterator it = m_alarmShowStatus.constBegin();it != m_alarmShowStatus.constEnd();++it) + { + QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget); + pItem->setData(Qt::UserRole, it.key()); + CMyCheckBox *pCheckBox = new CMyCheckBox(this); + pCheckBox->setText(it.value().first); + m_pListWidget->addItem(pItem); + m_pListWidget->setItemWidget(pItem, pCheckBox); + if(it.value().second) + { + pCheckBox->setCheckState(Qt::Checked); + m_alarmStatusList.append(it.key()); + m_strText += pCheckBox->text(); + m_strText += " "; + } + connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(alarmStatusChanged(int))); + } + ui->comboBox_alarmStatus->setModel(m_pListWidget->model()); + ui->comboBox_alarmStatus->setView(m_pListWidget); + ui->comboBox_alarmStatus->setLineEdit(m_pLineEdit); + if(m_strText == "") + { + m_strText = tr("请选择告警状态"); + } + m_pLineEdit->setText(m_strText); + m_pLineEdit->setReadOnly(true); + connect(m_pLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(alarmTextChanged(const QString &))); +} + +void CPlotWidget::addHorizontalLine() +{ + if(m_horizontalGraph) + { + m_horizontalGraph = NULL; + m_pTrendGraph->removeCurve("curve.tag"); + } + QRect rect = ui->plot->axisRect()->rect(); + double lower = ui->plot->yAxis->pixelToCoord(rect.y() + rect.height() - 6); + double first = ui->plot->xAxis->range().lower; + double final = ui->plot->xAxis->range().upper; + QVector xLineVector,yLineVector; + QVector statusVector; + xLineVector.append(first); + xLineVector.append(final); + yLineVector.append(lower); + yLineVector.append(lower); + statusVector.append(1); + statusVector.append(1); + m_horizontalGraph = ui->plot->addGraph(); + m_horizontalGraph->setData(xLineVector,yLineVector,statusVector); + + m_horizontalGraph->setName("curve.tag"); + m_horizontalGraph->setType(enRealCurve); + m_horizontalGraph->removeFromLegend(); + horizontalCurve.tag = "curve.tag"; + horizontalCurve.visible = false; + m_pTrendGraph->addCurve(horizontalCurve); + m_horizontalGraph->setVisible(false); + + groupQueryHistoryEvent(); + ui->plot->replot(); +} + +void CPlotWidget::updateHorizontalLine() +{ + if(m_type == E_Trend_RealTime) + { + return; + } + QRect rect = ui->plot->axisRect()->rect(); + double lower = ui->plot->yAxis->pixelToCoord(rect.y() + rect.height() - 6); + double first = ui->plot->xAxis->range().lower; + double final = ui->plot->xAxis->range().upper; + QVector xLineVector,yLineVector; + QVector statusVector; + xLineVector.append(first); + xLineVector.append(final); + yLineVector.append(lower); + yLineVector.append(lower); + statusVector.append(1); + statusVector.append(1); + m_horizontalGraph->setData(xLineVector,yLineVector,statusVector); + m_horizontalGraph->setVisible(false); + groupQueryHistoryEvent(); + m_horizontalGraph->removeFromLegend(ui->plot->legend); + ui->plot->replot(); +} + +void CPlotWidget::setAllLengedShow() +{ + int count = ui->lengedView->model()->rowCount(); + for(int nIndex=0; nIndexlengedView->setRowHidden(nIndex, false); + } +} + +QString CPlotWidget::hexTo26(int number) +{ + int p = 26; //进制 + int c = 0; //取余后的数字 + QString temp; + + while (true) { + c = number % p; + number = number / p; + if(number != 0) + { + temp.prepend(QString(QChar(0x41 + c))); + } + else + { + temp.prepend(QString(QChar(0x41 + c))); + break; + } + number--; + } + + return temp; +} + +void CPlotWidget::resetCurveData(const QMap > &dataMap, const QStringList &headerList, bool ascs) +{ + if(E_Show_Table != m_showType) + { + return; + } + int limit = 0; + if(E_Trend_His_Custom == m_type) + { + limit = CUSTOM_MAX_RECORD; + } + m_pTableDataModel->setCurveData(dataMap, headerList, ascs, limit); +} + +void CPlotWidget::enableSearch(bool enable) +{ + if(enable) + { + ui->preCurve->setEnabled(true); + ui->customSearch->setEnabled(true); + ui->customSearch->setText(tr("查询")); + } + else + { + ui->preCurve->setEnabled(false); + ui->customSearch->setEnabled(false); + ui->customSearch->setText(tr("查询中")); + } +} + +void CPlotWidget::afterModeSwitch() +{ + bool isTool = true; + switch (m_type) { + case E_Trend_Invalid: + case E_Trend_RealTime:{ + isTool = false; + ui->dataWidget->setVisible(false); + ui->customWidget->setVisible(false); + ui->customSearch->setVisible(false); + ui->preCurve->setChecked(false); + break; + } + case E_Trend_His_Minute: + case E_Trend_His_Hour: + case E_Trend_His_Day: + case E_Trend_His_Week: + case E_Trend_His_Month: + case E_Trend_His_Quarter: + case E_Trend_His_Year:{ + isTool = true; + ui->dataWidget->setVisible(true); + ui->customWidget->setVisible(false); + ui->customSearch->setVisible(false); + break; + } + case E_Trend_His_Custom:{ + isTool = true; + ui->dataWidget->setVisible(false); + ui->customWidget->setVisible(true); + ui->customSearch->setVisible(false); + break; + } + default: + break; + } + + if(m_showType == E_Show_Table){ + isTool = false; + ui->customSearch->setVisible(true); + ui->preCurve->setChecked(false); + } + + ui->checkBox_alarmPoint->setVisible(isTool); + ui->comboBox_alarmStatus->setVisible(isTool); + ui->adapt->setVisible(isTool); + ui->preCurve->setVisible(isTool); + if(!m_isAlarmShow){ + ui->checkBox_alarmPoint->setVisible(false); + ui->comboBox_alarmStatus->setVisible(false); + } + if(!m_isAdaptShow){ + ui->adapt->setVisible(false); + } + if(!m_isPreCurveShow){ + ui->preCurve->setVisible(false); + } + + bool isTable = m_showType == E_Show_Table ? true : false; + ui->plot->setVisible(!isTable); + ui->widget->setVisible(!isTable); + ui->m_dataView->setVisible(isTable); + ui->plotExport->setVisible(isTable); + ui->plotPrint->setVisible(!isTable); +} + +QPair CPlotWidget::getOffsetRange(const double &lower, const double &upper, int direction) +{ + QPair result; + QDateTime lowDate = QDateTime::fromMSecsSinceEpoch(lower); + QDateTime upDate = QDateTime::fromMSecsSinceEpoch(upper); + switch (m_type) { + case E_Trend_Invalid: + case E_Trend_RealTime:{ + break; + } + case E_Trend_His_Minute:{ + result.first = lower + 600000 * direction; + result.second = upper + 600000 * direction; + break; + } + case E_Trend_His_Hour:{ + result.first = lower + 3600000 * direction; + result.second = upper + 3600000 * direction; + break; + } + case E_Trend_His_Day:{ + result.first = lower + 86400000 * direction; + result.second = upper + 86400000 * direction; + break; + } + case E_Trend_His_Week:{ + result.first = lower + 604800000 * direction; + result.second = upper + 604800000 * direction; + break; + } + case E_Trend_His_Month:{ + result.first = lowDate.addMonths(1 * direction).toMSecsSinceEpoch(); + result.second = upDate.addMonths(1 * direction).toMSecsSinceEpoch(); + break; + } + case E_Trend_His_Quarter:{ + result.first = lowDate.addMonths(3 * direction).toMSecsSinceEpoch(); + result.second = upDate.addMonths(3 * direction).toMSecsSinceEpoch(); + break; + } + case E_Trend_His_Year:{ + result.first = lowDate.addYears(1 * direction).toMSecsSinceEpoch(); + result.second = upDate.addYears(1 * direction).toMSecsSinceEpoch(); + break; + } + case E_Trend_His_Custom:{ + result.first = lower + (upper - lower) * direction; + result.second = upper + (upper - lower) * direction; + break; + } + default: + break; + } + return result; +} + +double CPlotWidget::getOffsetTime(const double &time) +{ + double result = 0; + QDateTime origin = QDateTime::fromMSecsSinceEpoch(time); + switch (m_type) { + case E_Trend_Invalid: + case E_Trend_RealTime:{ + break; + } + case E_Trend_His_Minute:{ + result = 600000; + break; + } + case E_Trend_His_Hour:{ + result = 3600000; + break; + } + case E_Trend_His_Day:{ + result = 86400000; + break; + } + case E_Trend_His_Week:{ + result = 604800000; + break; + } + case E_Trend_His_Month:{ + result = origin.addMonths(1).toMSecsSinceEpoch() - time; + break; + } + case E_Trend_His_Quarter:{ + result = origin.addMonths(3).toMSecsSinceEpoch() - time; + break; + } + case E_Trend_His_Year:{ + result = origin.addYears(1).toMSecsSinceEpoch() - time; + break; + } + case E_Trend_His_Custom:{ + result = ui->endData->dateTime().toMSecsSinceEpoch() - ui->startData->dateTime().toMSecsSinceEpoch(); + break; + } + default: + break; + } + return result; +} + +void CPlotWidget::alarmTextChanged(const QString &text) +{ + Q_UNUSED(text) + m_pLineEdit->setText(m_strText); +} + +void CPlotWidget::alarmStatusChanged(int state) +{ + Q_UNUSED(state) + QString strText(""); + m_alarmStatusList.clear(); + int nCount = m_pListWidget->count(); + for (int i = 0; i < nCount; ++i) + { + QListWidgetItem *pItem = m_pListWidget->item(i); + QWidget *pWidget = m_pListWidget->itemWidget(pItem); + CMyCheckBox *pCheckBox = (CMyCheckBox *)pWidget; + if (pCheckBox->isChecked()) + { + if(pCheckBox->text() == QObject::tr("其他")) + { + QMap m_alarmOtherStatus = CTrendInfoManage::instance()->getAlarmOtherStatus(); + for(QMap::iterator it = m_alarmOtherStatus.begin();it != m_alarmOtherStatus.end();++it) + { + int nData = it.key(); + m_alarmStatusList.append(nData); + } + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + } + else + { + int nData = pItem->data(Qt::UserRole).toInt(); + QString strtext = pCheckBox->text(); + strText.append(strtext).append(" "); + m_alarmStatusList.append(nData); + } + } + } + if (!strText.isEmpty()) + { + m_strText = strText; + m_pLineEdit->setText(strText); + } + else + { + m_pLineEdit->clear(); + m_strText = tr("请选择告警状态"); + m_pLineEdit->setText(tr("请选择告警状态")); + } + groupQueryHistoryEvent(); +} + +void CPlotWidget::alarmPointCheckStateChanged() +{ + setAllLengedShow(); + if(ui->checkBox_alarmPoint->isChecked()) + { + addHorizontalLine(); + m_pLengedModel->setTrendGraph(m_pTrendGraph); + int mIndex = m_pTrendGraph->index("curve.tag"); + if(mIndex != -1) + { + ui->lengedView->setRowHidden(mIndex,true); + } + }else + { + if(m_horizontalGraph) + { + m_pTrendGraph->removeCurve("curve.tag"); + ui->plot->clearItems(); + m_listTracer.clear(); + ui->plot->removeGraph(m_horizontalGraph); + m_horizontalGraph = NULL; + m_pLengedModel->setTrendGraph(m_pTrendGraph); + ui->plot->replot(); + } + } +} + +void CPlotWidget::showTypeChanged(bool checked) +{ + m_pTableDataModel->clear(); + checked ? m_showType = E_Show_Table : m_showType = E_Show_Curve; + + if(m_type == E_Trend_RealTime) + { + if(E_Show_Table == m_showType) + { + updateRealTimeTableData(); + } + } + afterModeSwitch(); + + updateCurves(); + graphVisibleChanged(true); +} + +void CPlotWidget::slotStartDateChanged(const QDateTime &dateTime) +{ + if(ui->endData->dateTime() > dateTime) + { + ui->plot->xAxis->setRangeLower(dateTime.toMSecsSinceEpoch()); + } + else + { + int sec = ui->interval->currentData().toInt(); + if(sec < 600) + { + sec = 600; + } + ui->startData->setDateTime(ui->endData->dateTime().addSecs(-sec)); + } + + if(E_Show_Curve == m_showType) + { + slotCustomSearch(); + } +} + +void CPlotWidget::slotEndDateChanged(const QDateTime &dateTime) +{ + if(ui->startData->dateTime() < dateTime) + { + ui->plot->xAxis->setRangeUpper(dateTime.toMSecsSinceEpoch()); + } + else + { + int sec = ui->interval->currentData().toInt(); + if(sec < 600) + { + sec = 600; + } + ui->endData->setDateTime(ui->startData->dateTime().addSecs(sec)); + } + + if(E_Show_Curve == m_showType) + { + slotCustomSearch(); + } +} + +void CPlotWidget::slotIntervalChanged(const QString &text) +{ + Q_UNUSED(text) + + if(E_Show_Curve == m_showType) + { + slotCustomSearch(); + } +} + +void CPlotWidget::slotCustomSearch(bool isForce) +{ + if(!ui->plot->graphCount()) + { + return; + } + if(!isForce && !ui->customSearch->isEnabled()) + { + return; + } + + double lower = ui->startData->dateTime().toMSecsSinceEpoch(); + double upper = ui->endData->dateTime().toMSecsSinceEpoch(); + if(lower > upper) + { + QMessageBox::information(this,tr("提示"),tr("查询开始时间不能大于结束时间!"),QMessageBox::Ok); + return; + } + int sec = ui->interval->currentData().toInt(); + if((upper - lower) < sec*1000) + { + QMessageBox::information(this,tr("提示"),tr("开始时间和结束时间之差不能小于查询时间间隔!"),QMessageBox::Ok); + return; + } + + enableSearch(false); + std::vector vecMethod{iot_dbms::CM_MAX, iot_dbms::CM_MIN}; + double nIntervalSecs = SAMPLE_CYC_MIN * 60 * 1000; + QList cmdList; + TsdbCommand curve = getHisCurveCmd(lower + nIntervalSecs, upper - nIntervalSecs, sec, E_HISTORY); + TsdbCommand computer = getComputeCmd(lower, upper, vecMethod, E_HISTORY); + cmdList.push_back(curve); + cmdList.push_back(computer); + if(m_bShowPreCurve){ + QPair preRange = getOffsetRange(lower, upper, -1); + TsdbCommand preCurve = getHisCurveCmd(preRange.first + nIntervalSecs, preRange.second - nIntervalSecs, sec, E_PRECURVE); + TsdbCommand perComputer = getComputeCmd(preRange.first, preRange.second, vecMethod, E_PRECURVE); + cmdList.push_back(preCurve); + cmdList.push_back(perComputer); + } + + if(!m_pHisDataManage->isTsdbExuting()) + { + emit sigQueryHistoryRecord(cmdList); + } + else + { + m_pHisDataManage->postTsdbCommandQueue(cmdList); + } +} + +void CPlotWidget::slotEnableSearch(bool enable) +{ + enableSearch(!enable); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CPlotWidget.h b/product/src/gui/plugin/TrendCurves_pad/CPlotWidget.h new file mode 100644 index 00000000..28e70635 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CPlotWidget.h @@ -0,0 +1,340 @@ +#ifndef CPLOTWIDGET_H +#define CPLOTWIDGET_H + +#include +#include "CTrendGraph.h" +#include "CHisDataManage.h" +#include "plot/qcustomplot.h" +#include "CTrendInfoManage.h" +#include "dbms/tsdb_api/TsdbApi.h" +#include "dbms/tsdb_api/CTsdbConn.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "dbms/db_his_query_api/DbHisQueryApi.h" + +#define CUSTOM_MAX_RECORD 10000; + +namespace Ui { +class CPlotWidget; +} + +class QTimer; +class CToolTip; +class QCustomPlot; +class QCPItemText; +class QCPItemTracer; +class QAbstractButton; +class CHisDataManage; +class CHisEventManage; +class CCurveLegendModel; +class CTableDataModel; +class CRealTimeDataCollect; + +enum E_Trend_Type +{ + E_Trend_Invalid = 0, + E_Trend_RealTime = 1, + E_Trend_His_Minute = 2, + E_Trend_His_Hour = 3, + E_Trend_His_Day = 4, + E_Trend_His_Week = 5, + E_Trend_His_Month = 6, + E_Trend_His_Quarter = 7, + E_Trend_His_Year = 8, + E_Trend_His_Custom = 9 +}; + +enum E_Show_Type +{ + E_Show_Curve = 0, + E_Show_Table = 1 +}; + +class CPlotWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QColor plotBackgroundColor READ plotBackgroundColor WRITE setPlotBackgroundColor) + Q_PROPERTY(QColor plotTickColor READ plotTickColor WRITE setPlotTickColor) + Q_PROPERTY(QColor plotGridColor READ plotGridColor WRITE setPlotGridColor) + Q_PROPERTY(QColor plotZeroLineColor READ plotZeroLineColor WRITE setPlotZeroLineColor) + Q_PROPERTY(QColor plotTickPen READ plotTickPen WRITE setPlotTickPen) + Q_PROPERTY(QPixmap plotBackImage READ plotBackImage WRITE setPlotBackImage) + +public: + explicit CPlotWidget(QWidget *parent = 0); + ~CPlotWidget(); + + void initialize(); + + void setTitle(const QString &title); + + void setTitleVisible(bool visible); + + void setTickCount(const int &count); + + void insertTag(const QString &tag, const bool &resetTitle = true); + + void insertTag(const QStringList &listTag, const bool &resetTitle = true); + + void removeTag(const QString &tag, const bool &resetTitle = true); + + void setDisplayTime(const int &trendType, const double &dateTime, const bool &alarm = true); + + void setTagVisible(const QString &tag, const bool &visible); + + void setDateButtonVisible(const int &button, const bool &visible); + + void setClearVisible(bool visible); + + void setAdaptVisible(bool visible); + + void setAlarmPointVisible(bool visible); + + void setPreCurveVisible(bool visible); + + void insertCurve(Curve curve); + + void clear(bool clearTitle = false); + + void setWindowMode(const bool &isWindowMode); + + void setColorList(const QStringList &listColor); + + QColor plotBackgroundColor(); + void setPlotBackgroundColor(const QColor &color); + + QPixmap plotBackImage(); + void setPlotBackImage(const QPixmap &pm); + + QColor plotTickColor(); + void setPlotTickColor(const QColor &color); + + QColor plotGridColor(); + void setPlotGridColor(const QColor &color); + + QColor plotZeroLineColor(); + void setPlotZeroLineColor(const QColor &color); + + QColor plotTickPen(); + void setPlotTickPen(const QColor &color); + + void setLimitNum(int max); + +signals: + void clearCurve(); + void queryHisEvent(const QString &tag, const int &type, const qint64 &time); + void collectGraph(const QString &title, const CTrendGraph &graph); + void updateTagCheckState(const QString &tag, const bool &outOfRange); + void releaseHisDataThread(); + void releaseHisEventThread(); + void sigQueryHistoryRecord(const QList &cmdList); + void sigAddCollect(int x, int y); + void sigHideCollect(); + + void sigSliderRangeSet(int x, int y, int lower, int upper, int minimum, int maximum); + void sigHideSliderSet(); + +protected: + void resizeEvent(QResizeEvent *event); + bool eventFilter(QObject *object, QEvent *event); + void updateLengedColumnWidth(); + void updateCurveSelectionColor(QCPGraph * graph); + +public slots: + void slotCollectGraph(const QString &text); + void slotSliderRangeChange(int lower, int upper); + +private slots: + void realTimeElapsed(); + + void recvRealTimeTrendData(const QString &tagName, QVariant value, int status, E_Point_Type pointType); + + void updateRealTimeTableData(); + + void plotAxisRangeChanged(const QCPRange &newRange, const QCPRange &oldRange); + + void updateTrendShowMode(int nIndex, bool updateXAxisRange = true); + + TsdbCommand getHisCurveCmd(double lower, double upper, int nGroupBy, E_Data_Type type); + TsdbCommand getComputeCmd(double lower, double upper, std::vector vecMethod, E_Data_Type type); + + void updateCurves(); + + void updateRealTimeCurveRecord(); + + void updateHistoryCurveRecord(); + + void updateHisOriginalData(std::vector *vecMpKey, + std::vector *> *vecResult, + E_Data_Type type = E_HISTORY); + + void updateHisPolymericData(std::vector *vecMpKey, + std::vector *> *vecResult, + int nGroupBySec, + E_Data_Type type = E_HISTORY); + + void updateHisComputeData(std::vector *vecMpKey, + std::vector *> *> > cmResult, + E_Data_Type type = E_HISTORY); + + void updateHistoryGraph(std::vector *vecMpKey, + std::vector< QSharedPointer > &vecContainer, + std::vector< QSharedPointer > &vecRange, + E_Data_Type type); + + void updateHistoryData(std::vector *vecMpKey, + std::vector< QSharedPointer > &vecContainer, + std::vector< QSharedPointer > &vecRange, + E_Data_Type type); + + void updateCurveHisData(double lower, double upper, + QCPGraph * graph, int index, + QSharedPointer container, + QSharedPointer range, + E_Data_Type type); + + void updatePhaseTracer(std::vector *vecMpKey, + std::vector *> *vecResult); + void updateGraphEvent(const qint64 &time, QStringList contents); + + void updateAxisFormat(bool updateXAxisRange); + QPair getFatureDataTime(E_Trend_Type type, QDateTime curTime = QDateTime()); + void updateAdaptState(bool isAdapt); + void updatePreCurveState(bool isPreCurve); + void addCollect(); + void slotPrint(); + void slotExport(); + void prePage(); + void nextPage(); + + void graphVisibleChanged(const bool &check); + void graphPropertyChanged(); + void deleteCurrentGraph(); + void jumpToMaxTime(const double &time); + void jumpToMinTime(const double &time); + void updateLengedValue(const double &dateTime); + void graphSelectionChanged(bool select); + void tableSelectionChanged(const QModelIndex &index); + void updateGraphSelection(); + void updateYAxisTicker(); + void setYAxisRange(); + void sliderPressed(); + void sliderDoubleClick(int x, int y); + + void slotDateTimeChanged(const QDateTime &dateTime); + + void alarmTextChanged(const QString &text); + void alarmStatusChanged(int state); + void alarmPointCheckStateChanged(); + + void showTypeChanged(bool checked); + + void slotStartDateChanged(const QDateTime &dateTime); + void slotEndDateChanged(const QDateTime &dateTime); + void slotIntervalChanged(const QString &text); + void slotCustomSearch(bool isForce = false); + void slotEnableSearch(bool enable); + +private: + void installMousePressEventFilter(); + + iot_dbms::EnMeasPiontType getMeasType(const QString &type); + + E_Trend_Type getRangeType(const QCPRange &range); + + void updateGraphTitle(int nIndex); + + int currentGroupByMinute(); + + void setLegendCurveTransformColumnVisible(const bool &visible); + + QList regulate(double min, double max, int tickCount); + + void rescaleYAxisRange(); + QPair regulateYAxisRange(); + void setSliderRange(double lower, double upper, bool setValue = false); + + template + void updateHisData(std::vector *vecMpKey, + std::vector*> *vecResult, + std::vector< QSharedPointer > &vecRange, + std::vector< QSharedPointer > &vecContainer, + double lower, double upper, + E_Data_Type type, + bool isAddVirtualPoint = false, + int nGroupBySec = 0); + + template + bool checkStatus(const _Tp &var, const int &nInvalid); + + template + bool checkStatus(const iot_dbms::SVarHisSamplePoint &var, const int &nInvalid); + + void setCurveStatisData(const QString &tag, const int &curType, iot_dbms::EnComputeMethod method, bool reset, const double &value = 0, const double &time = 0); + + bool isMutation(const double &preValue, const double &curValue); + + void updateGroupQuery(const QString &tag); + void groupQueryHistoryEvent(); + void removeCurvesGroupQuery(); + + void initAlarmStatusFilter(); + void addHorizontalLine(); + void updateHorizontalLine(); + void setAllLengedShow(); + + QString hexTo26(int number); + void resetCurveData(const QMap>& dataMap, const QStringList& headerList, bool ascs = true); + void enableSearch(bool enable); + + void afterModeSwitch(); + QPair getOffsetRange(const double &lower, const double &upper, int direction); + double getOffsetTime(const double &time); +private: + Ui::CPlotWidget *ui; + E_Trend_Type m_type; + E_Show_Type m_showType; + bool m_bHisAdaption; + bool m_bShowPreCurve; + QButtonGroup * m_TrendTypeButton; + CCurveLegendModel * m_pLengedModel; + CTableDataModel * m_pTableDataModel; + QTimer * m_pTimer; + CTrendGraph * m_pTrendGraph; + QCPItemText * m_trendTitle; + double m_rtRange; + iot_service::CDpcdaForApp * m_pDpcdaForApp; + CRealTimeDataCollect * m_rtDataCollect; + QSharedPointer m_ptrPlotTricker; + QThread * m_pHisDataThread; + CHisDataManage * m_pHisDataManage; + QThread * m_pHisEventThread; + CHisEventManage * m_pHisEventManage; + + QPixmap m_plotBackImage; + QColor m_plotBackgroundColor; + QColor m_plotTickColor; + QColor m_plotGridColor; + QColor m_plotZeroLineColor; + QColor m_plotTickPen; + QList m_listTracer; + QList m_listColor; + + QListWidget *m_pListWidget; + QLineEdit *m_pLineEdit; + QList m_alarmStatusList; + QString m_strText; + Curve horizontalCurve; + QCPGraph * m_horizontalGraph; + QMap m_groupTagMap; + bool m_numWarnFlag; + bool m_isWindowMode; + bool m_isSetSliderValue; + bool m_isTooltip; + bool m_isAdaptShow; + bool m_isAlarmShow; + bool m_isPreCurveShow; + + int m_limitNum; +}; + +#endif // CPLOTWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CPlotWidget.ui b/product/src/gui/plugin/TrendCurves_pad/CPlotWidget.ui new file mode 100644 index 00000000..d1d985b8 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CPlotWidget.ui @@ -0,0 +1,787 @@ + + + CPlotWidget + + + + 0 + 0 + 1469 + 558 + + + + Form + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 16777215 + 150 + + + + false + + + false + + + + + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 3 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + 告警描点 + + + + + + + + 0 + 0 + + + + + 50 + 24 + + + + 对比 + + + true + + + + + + + + 130 + 0 + + + + + + + + 收藏 + + + + + + + 导出 + + + + + + + 保存图片 + + + + + + + Qt::Horizontal + + + QSizePolicy::MinimumExpanding + + + + 20 + 20 + + + + + + + + 0 + + + 0 + + + 5 + + + 5 + + + 5 + + + 0 + + + + + + + + + + + + 实时 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 自定义 + + + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + 昨日曲线 + + + + + + + + + + + 0 + 35 + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 359 + 20 + + + + + + + + Qt::Horizontal + + + + 359 + 20 + + + + + + + + + Microsoft YaHei + 20 + 50 + false + + + + + + + 趋势图 + + + + + + + + + + + 0 + 0 + + + + + 20 + 0 + + + + + 20 + 16777215 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 20 + 0 + + + + + 20 + 16777215 + + + + + + + Qt::Vertical + + + + + + + + + + false + + + + 480 + 240 + + + + + + + + + + + + + + 0 + 32 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 2 + + + 0 + + + 2 + + + 6 + + + 0 + + + + + Qt::Horizontal + + + + 50 + 20 + + + + + + + + false + + + 清空 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 58 + 0 + + + + + 58 + 16777215 + + + + border:none; +background:transparent; + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 23 + 59 + 59 + 2037 + 12 + 31 + + + + + 0 + 0 + 0 + 1970 + 1 + 1 + + + + + 2037 + 12 + 31 + + + + yyyy/MM/dd HH:mm + + + + + + + 开始时间 + + + + + + + + + + 结束时间 + + + + + + + + 0 + 0 + + + + + 23 + 59 + 59 + 2037 + 12 + 31 + + + + + 0 + 0 + 0 + 1970 + 1 + 1 + + + + + 2037 + 12 + 31 + + + + yyyy/MM/dd HH:mm + + + + + + + 查询 + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 23 + 59 + 59 + 2037 + 12 + 31 + + + + + 0 + 0 + 0 + 1970 + 1 + 1 + + + + + 2037 + 12 + 31 + + + + yyyy/MM/dd HH:mm + + + + + + + 上一页 + + + + + + + 下一页 + + + + + + + + + + + + + + CSWitchButton + QWidget +
./widgets/CSWitchButton.h
+ 1 +
+ + QCustomPlot + QWidget +
./plot/qcustomplot.h
+ 1 +
+ + CTabButton + QPushButton +
./widgets/CTabButton.h
+
+ + CCurveLegendView + QTableView +
CCurveLegendView.h
+
+ + QxtSpanSlider + QSlider +
./widgets/QxtSpanSlider.h
+
+ + CTableView + QTableView +
CTableView.h
+
+
+ + +
diff --git a/product/src/gui/plugin/TrendCurves_pad/CRealTimeDataCollect.cpp b/product/src/gui/plugin/TrendCurves_pad/CRealTimeDataCollect.cpp new file mode 100644 index 00000000..e19b6bf4 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CRealTimeDataCollect.cpp @@ -0,0 +1,97 @@ +#include "CRealTimeDataCollect.h" +#include "MessageChannel.h" +#include "DataProcMessage.pb.h" +#include "pub_logger_api/logger.h" +#include + +using namespace iot_net; +using namespace iot_public; +using namespace iot_idl; + +CRealTimeDataCollect::CRealTimeDataCollect(QObject *parent) + : QThread(parent) +{ + +} + +CRealTimeDataCollect::~CRealTimeDataCollect() +{ + +} + +void CRealTimeDataCollect::run() +{ + iot_public::CSysInfoInterfacePtr sysInfo; + iot_public::createSysInfoInstance(sysInfo); + + // 初始化通讯器 + CMbCommunicator * pCommunicator = new CMbCommunicator(); + pCommunicator->addSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + while(!isInterruptionRequested()) + { + iot_net::CMbMessage msg; + if (pCommunicator && pCommunicator->recvMsg(msg, 100) && !isInterruptionRequested()) + { + parseTrendDataMessage(msg); + } + } + if (pCommunicator != NULL) + { + pCommunicator->delSub(0, CH_SCADA_TO_HMI_DATA_CHANGE); + delete pCommunicator; + } + pCommunicator = NULL; +} + +void CRealTimeDataCollect::parseTrendDataMessage(const CMbMessage &msg) +{ + int msgType = msg.getMsgType(); + if(MT_DP_CHANGE_DATA == msgType) + { + iot_idl::SRealTimeDataPkg chgDataPkg; + try + { + chgDataPkg.ParseFromArray(msg.getDataPtr(), (int)msg.getDataSize()); + int aiSize = chgDataPkg.stairtd_size(); + for(int i = 0;i < aiSize; i++) + { + const iot_idl::SAiRealTimeData &aiStru = chgDataPkg.stairtd(i); + msgNotify(aiStru.strtagname(), aiStru.fvalue(), aiStru.ustatus(), E_ANALOG); + } + + int diSize = chgDataPkg.stdirtd_size(); + for(int i = 0;i < diSize; i++) + { + const iot_idl::SDiRealTimeData &diStru = chgDataPkg.stdirtd(i); + msgNotify(diStru.strtagname(), diStru.nvalue(), diStru.ustatus(), E_DIGITAL); + } + + int piSize = chgDataPkg.stpirtd_size(); + for(int i = 0;i < piSize; i++) + { + const iot_idl::SPiRealTimeData &piStru = chgDataPkg.stpirtd(i); + msgNotify(piStru.strtagname(), (qint64)piStru.dvalue(), piStru.ustatus(), E_ACCUML); + } + + int miSize = chgDataPkg.stmirtd_size(); + for(int i = 0;i < miSize; i++) + { + const iot_idl::SMiRealTimeData &miStru = chgDataPkg.stmirtd(i); + msgNotify(miStru.strtagname(), miStru.nvalue(), miStru.ustatus(), E_MIX); + } + } + catch (...) + { + LOGERROR("TrendPlugin ParseTrendDataMessage ! MsgType: %d", msgType); + } + } +} + +void CRealTimeDataCollect::msgNotify(const std::string &strTagName, const QVariant &value, const int &status, E_Point_Type pointType) +{ + if((!isInterruptionRequested())) + { + emit realTimeTrendDataArrived(QString::fromStdString(strTagName), value, status, pointType); + } +} + diff --git a/product/src/gui/plugin/TrendCurves_pad/CRealTimeDataCollect.h b/product/src/gui/plugin/TrendCurves_pad/CRealTimeDataCollect.h new file mode 100644 index 00000000..e3894dfb --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CRealTimeDataCollect.h @@ -0,0 +1,46 @@ +#ifndef CREALTIMEDATACOLLECT_H +#define CREALTIMEDATACOLLECT_H + +#include +#include +#include +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "../../include/net/net_msg_bus_api/CMbMessage.h" +#include "../../include/public/pub_sysinfo_api/SysInfoApi.h" +#include "CTrendInfoManage.h" + +struct ChgDataStru +{ + QVariant value; + unsigned int status; +}; + +class CRealTimeDataCollect : public QThread +{ + Q_OBJECT + +public: + CRealTimeDataCollect(QObject *parent = Q_NULLPTR); + ~CRealTimeDataCollect(); + +signals: + void realTimeTrendDataArrived(const QString &tagName, QVariant value, int status, E_Point_Type pointType); + +protected: + /** + * 消息接收线程 + * @brief run + */ + void run(); + +private: + /** + * @brief parseTrendDataMessage 解析实时数据 + * @param msg + */ + void parseTrendDataMessage(const iot_net::CMbMessage &msg); + + void msgNotify(const std::string &strTagName, const QVariant &value, const int &status, E_Point_Type pointType); +}; + +#endif // CREALTIMEDATACOLLECT_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CTableDataModel.cpp b/product/src/gui/plugin/TrendCurves_pad/CTableDataModel.cpp new file mode 100644 index 00000000..48e2d861 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTableDataModel.cpp @@ -0,0 +1,249 @@ +#include "CTableDataModel.h" + +CTableDataModel::CTableDataModel(QObject *parent) + : QAbstractTableModel(parent), + m_pView(static_cast(parent)), + m_bAscs(true) +{ + +} + +CTableDataModel::~CTableDataModel() +{ + m_curveDataMap.clear(); + m_header.clear(); + m_timeList.clear(); + m_pView = nullptr; +} + +void CTableDataModel::clear() +{ + beginResetModel(); + m_curveDataMap.clear(); + //m_header.clear(); + m_timeList.clear(); + m_bAscs = true; + endResetModel(); +} + +void CTableDataModel::setCurveData(const QMap > &curveDataMap, const QStringList &headerList, bool ascs, int limit) +{ + beginResetModel(); + m_curveDataMap = curveDataMap; + m_header = headerList; + m_bAscs = ascs; + + m_timeList.clear(); + bool isLimit = false; + foreach (QString curveName, m_header) + { + QVector curveData = curveDataMap[curveName]; + QVector::const_iterator iter = curveData.constBegin(); + while (iter != curveData.constEnd()) + { + if(limit != 0 && m_timeList.count() >= limit) + { + isLimit = true; + break; + } + if(!m_timeList.contains(iter->key)) + { + m_timeList.append(iter->key); + } + iter++; + } + } + std::sort(m_timeList.begin(), m_timeList.end()); + if(isLimit) + { + QMessageBox::information(m_pView, tr("提示"), tr("只显示前%1条记录!").arg(limit), QMessageBox::Ok); + } + endResetModel(); +} + +void CTableDataModel::removeCurveData(const QString &desc) +{ + bool bRet = m_header.removeOne(desc); + int nRet = m_curveDataMap.remove(desc); + if(bRet || nRet > 0) + { + setCurveData(m_curveDataMap, m_header); + } +} + +bool CTableDataModel::setColumnHidden(const QString &desc, bool hide) +{ + int index = m_header.indexOf(desc); + if(index < 0) + { + return false; + } + m_pView->setColumnHidden(index+1, hide); + return true; +} + +int CTableDataModel::getHeaderIndex(const QString &desc) +{ + int index = m_header.indexOf(desc); + if(index < 0) + { + return -1; + } + if(m_pView->isColumnHidden(index+1)) + { + return -1; + } + return index; +} + +QVariant CTableDataModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + if(0 == section) + { + return tr("时间"); + } + else + { + return QString(m_header.at(section - 1)).section(".", 1); + } + } + } + else if(Qt::ToolTipRole == role) + { + if(Qt::Horizontal == orientation) + { + if(0 == section) + { + return tr("时间"); + } + else + { + return m_header.at(section - 1); + } + } + } + return QVariant(); +} + +int CTableDataModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid() || m_header.isEmpty() || m_timeList.isEmpty()) + return 0; + return m_timeList.count(); +} + +int CTableDataModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid() || m_header.isEmpty()) + return 0; + return m_header.count() + 1; +} + +QVariant CTableDataModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + { + return QVariant(); + } + + if(Qt::TextAlignmentRole == role) + { + if(index.column() == 0) + { + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + return QVariant(Qt::AlignHCenter | Qt::AlignVCenter); + } + + if(Qt::DisplayRole != role && Qt::ForegroundRole != role && Qt::UserRole != role) + { + return QVariant(); + } + + double time = m_timeList.at(index.row()); + if(!m_bAscs) + { + time = m_timeList.at(rowCount() - index.row() - 1); + } + + if(0 < index.column()) + { + QCPGraphData data(time, 0); + + const QVector &vecData = m_curveDataMap[m_header[index.column() - 1]]; + QCPDataContainer::const_reverse_iterator iter = std::find_if(vecData.crbegin(), + vecData.crend(), [=](QCPGraphData const& obj){ return data.sortKey() == obj.sortKey(); }); + if(iter != vecData.crend()) + { + if(Qt::ForegroundRole == role) + { + if(iter->status == 1) + { + return QVariant(QColor(Qt::gray)); + } + } + else if(Qt::UserRole == role) + { + return QVariant(iter->status); + } + else if(Qt::DisplayRole == role) + { + if(qIsNaN(iter->value)) + return "-"; + else + return QString::number(iter->value, 'f', 2); + } + } + } + + if(Qt::DisplayRole != role) + { + return QVariant(); + } + + if(0 == index.column()) + { + return QCPAxisTickerDateTime::keyToDateTime(time).toString("yyyy-MM-dd hh:mm:ss.zzz"); + } + + if(m_bAscs) + { + if((index.row()-1) >= 0 && (index.row()-1) < rowCount()) + { + return createIndex(index.row()-1, index.column()).data(); + } + } + else + { + if((index.row()+1) >= 0 && (index.row()+1) < rowCount()) + { + return createIndex(index.row()+1, index.column()).data(); + } + } + + return QVariant(); +} + + + +CustomHeaderView::CustomHeaderView(Qt::Orientation orientation ,QWidget *parent) +:QHeaderView(orientation,parent) +{ +} +CustomHeaderView::~CustomHeaderView() +{ +} + +void CustomHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const +{ + //就简单几句 + //拿到text数据,在写数据的时候,设置textwordwrap,居中。 + QString textstr = model()->headerData(visualIndex(logicalIndex),Qt::Horizontal).toString(); + painter->save(); + painter->drawText(rect,Qt::TextWordWrap | Qt::AlignCenter, textstr); + painter->restore(); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CTableDataModel.h b/product/src/gui/plugin/TrendCurves_pad/CTableDataModel.h new file mode 100644 index 00000000..22612de0 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTableDataModel.h @@ -0,0 +1,55 @@ +#ifndef CTABLEDATAMODEL_H +#define CTABLEDATAMODEL_H + +#include +#include "plot/qcustomplot.h" +#include +#include + +class CTableDataModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + explicit CTableDataModel(QObject * parent = nullptr); + + ~CTableDataModel(); + + void clear(); + + void setCurveData(const QMap > &curveDataMap, const QStringList &headerList, bool ascs = true, int limit = 0); + + void removeCurveData(const QString &desc); + + bool setColumnHidden(const QString& desc, bool hide); + + int getHeaderIndex(const QString &desc); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: + QTableView * m_pView; + QStringList m_header; + QMap > m_curveDataMap; + QList m_timeList; + bool m_bAscs; +}; + +class CustomHeaderView : public QHeaderView +{ + Q_OBJECT + +public: + CustomHeaderView(Qt::Orientation orientation = Qt::Horizontal,QWidget *parent = nullptr); //这里为了省事,给默认值为水平表头,因为我正好使用水平的表头 + ~CustomHeaderView(); + +protected: + virtual void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const; +}; + +#endif // CTABLEDATAMODEL_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CTableView.cpp b/product/src/gui/plugin/TrendCurves_pad/CTableView.cpp new file mode 100644 index 00000000..440ee230 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTableView.cpp @@ -0,0 +1,65 @@ +#include "CTableView.h" +#include + +CTableView::CTableView(QWidget *parent) + : QTableView(parent) +{ + + +} + +int CTableView::tableColumnWidth() +{ + return m_nTableColWidth; +} + +void CTableView::setTableColumnWidth(const int &nWidth) +{ + m_nTableColWidth = nWidth; + + horizontalHeader()->setDefaultSectionSize(m_nTableColWidth); +} + +int CTableView::tableRowHeight() +{ + return m_nTableRowHeight; +} + +void CTableView::setTableRowHeight(const int &nHeight) +{ + m_nTableRowHeight = nHeight; + + verticalHeader()->setDefaultSectionSize(m_nTableRowHeight); +} +void CTableView::showEvent(QShowEvent *event){ + QTableView::showEvent(event); + adjustHeaderWidth(); +} + + +// 自动调整表头宽度以适应文本 +void CTableView::adjustHeaderWidth() { + QHeaderView *header = horizontalHeader(); + int sections = header->count(); + int maxWidth = 0; + QFontMetrics fm(header->font()); + int maxWidthThreshold = 200; // 设置换行的阈值 + + for (int i = 0; i < sections; ++i) { + QString text = model()->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); + int width = fm.width(text) + 10; // 加上一些额外空间 + maxWidth = qMax(maxWidth, width); + } + + for (int i = 0; i < sections; ++i) { + QString text = model()->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); + int width = fm.width(text) + 10; // 加上一些额外空间 + // 如果宽度超过阈值,则换行 + if (width > maxWidthThreshold) { + header->resizeSection(i, maxWidthThreshold); + } else { + header->resizeSection(i, maxWidth); + } + } +} + diff --git a/product/src/gui/plugin/TrendCurves_pad/CTableView.h b/product/src/gui/plugin/TrendCurves_pad/CTableView.h new file mode 100644 index 00000000..9af04653 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTableView.h @@ -0,0 +1,30 @@ +#ifndef CTABLEVIEW_H +#define CTABLEVIEW_H + +#include + +class CTableView : public QTableView +{ + Q_OBJECT + Q_PROPERTY(int tableColumnWidth READ tableColumnWidth WRITE setTableColumnWidth) + Q_PROPERTY(int tableRowHeight READ tableRowHeight WRITE setTableRowHeight) + +public: + CTableView(QWidget *parent = Q_NULLPTR); + + int tableColumnWidth(); + void setTableColumnWidth(const int &nWidth); + + int tableRowHeight(); + void setTableRowHeight(const int &nHeight); + void adjustHeaderWidth(); + +protected: + void showEvent(QShowEvent *event) override ; + +private: + int m_nTableColWidth; + int m_nTableRowHeight; +}; + +#endif // CTABLEVIEW_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendEditDialog.cpp b/product/src/gui/plugin/TrendCurves_pad/CTrendEditDialog.cpp new file mode 100644 index 00000000..c15a1f74 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendEditDialog.cpp @@ -0,0 +1,149 @@ +#include +#include "CTrendEditDialog.h" +#include "ui_CTrendEditDialog.h" +#include "CTrendEditModel.h" +#include "GraphTool/Retriever/CRetriever.h" +#include "pub_utility_api/FileUtil.h" + +using namespace iot_dbms; + +CTrendEditDialog::CTrendEditDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CTrendEditDialog), + m_graph(nullptr), + m_pRretriever(nullptr) +{ + ui->setupUi(this); + ui->m_retrieverWidget->setWindowFlags(Qt::Widget); + ui->m_retrieverWidget->setMultVisible(false); + //setWindowModality(Qt::WindowModal); + initialize(); + connect(ui->addCurve, SIGNAL(clicked()), this, SLOT(slot_addCureve())); + connect(ui->removeCurve, SIGNAL(clicked()), this, SLOT(slot_removeCureve())); + connect(ui->clearCurve, SIGNAL(clicked()), this, SLOT(slot_clearCureve())); + connect(ui->ok, SIGNAL(clicked()), this, SLOT(slot_updateTrend())); + connect(ui->cancle, SIGNAL(clicked()), this, SLOT(close())); +} + +CTrendEditDialog::~CTrendEditDialog() +{ + if(m_pRretriever != NULL) + { + delete m_pRretriever; + } + m_pRretriever = NULL; + delete ui; +} + +void CTrendEditDialog::initialize() +{ + + initTrendView(); + + m_pRretriever = new CRetriever(this); +} + +void CTrendEditDialog::initTrendView() +{ + m_model = new CTrendEditModel(this); + ui->trendView->setModel(m_model); + ui->trendView->horizontalHeader()->setStretchLastSection(true); + CTrendDelegate * delegate = new CTrendDelegate(this); + ui->trendView->setItemDelegate(delegate); + ui->trendView->setAlternatingRowColors(true); + ui->trendView->horizontalHeader()->setStretchLastSection(true); + + connect(ui->m_retrieverWidget, &CRetriever::itemTagTriggered, ui->trendView, &CTrendEditView::appendTagName); +} + +void CTrendEditDialog::showEvent(QShowEvent *event) +{ + QDialog::showEvent(event); + updateTrendViewColumnWidth(); +} + +void CTrendEditDialog::resizeEvent(QResizeEvent *event) +{ + QDialog::resizeEvent(event); + updateTrendViewColumnWidth(); +} + + +void CTrendEditDialog::updateTrendViewColumnWidth() +{ + int nTrendViewWidth = ui->trendView->width(); + ui->trendView->setColumnWidth(0, nTrendViewWidth / 3 * 2); +} + + +void CTrendEditDialog::setTrendGraph(CTrendGraph *graph) +{ + if( Q_NULLPTR == graph ) + { + return; + } + m_graph = graph; + m_model->setTrendCurves(m_graph->curves()); +} + +CTrendGraph *CTrendEditDialog::trendGraph() const +{ + return m_graph; +} + +void CTrendEditDialog::slot_updateTrend() +{ + if(m_model->rowCount() == 0) + { + QMessageBox::warning(this, tr("警告"), tr("测点数量不允许为空!")); + return; + } + + for(int nIndex(0); nIndex < m_model->rowCount(); ++nIndex) + { + if(m_model->curves().at(nIndex).tag == "") + { + QMessageBox::warning(this, tr("警告"), tr("测点名称不允许存在空值!")); + return; + } + } + if(nullptr == m_graph) + { + m_graph = new CTrendGraph(); + } + m_graph->setCurves(m_model->curves()); + accept(); +} + +void CTrendEditDialog::slot_addCureve() +{ + m_model->addTrendCurve(); +} + +void CTrendEditDialog::slot_removeCureve() +{ + if(!ui->trendView->currentIndex().isValid()) + { + QMessageBox::information(this, tr("提示"), tr("当前未选中行!")); + return; + } + QItemSelectionModel *itemSelection = ui->trendView->selectionModel(); + QModelIndexList indexList = itemSelection->selectedRows(); + m_model->removeTrendCurve(indexList); +} + +void CTrendEditDialog::slot_clearCureve() +{ + m_model->clearTrendCurves(); +} + +void CTrendEditDialog::slot_showRetriever() +{ + if(nullptr == m_pRretriever) + { + m_pRretriever = new CRetriever(this); + } + m_pRretriever->show(); +} + + diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendEditDialog.h b/product/src/gui/plugin/TrendCurves_pad/CTrendEditDialog.h new file mode 100644 index 00000000..d6e6001a --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendEditDialog.h @@ -0,0 +1,49 @@ +#ifndef CTRENDEDITDIALOG_H +#define CTRENDEDITDIALOG_H + +#include +#include "CTrendGraph.h" + +namespace Ui { +class CTrendEditDialog; +} + +class CRetriever; +class CTrendEditModel; + +class CTrendEditDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CTrendEditDialog(QWidget *parent = 0); + ~CTrendEditDialog(); + + void initialize(); + void initTrendView(); + + void setTrendGraph(CTrendGraph * data); + CTrendGraph * trendGraph() const; + +protected: + void showEvent(QShowEvent *event); + void resizeEvent(QResizeEvent *event); + +protected slots: + void slot_updateTrend(); + void slot_addCureve(); + void slot_removeCureve(); + void slot_clearCureve(); + void slot_showRetriever(); + +private: + void updateTrendViewColumnWidth(); + +private: + Ui::CTrendEditDialog *ui; + CTrendGraph * m_graph; + CTrendEditModel * m_model; + CRetriever * m_pRretriever; +}; + +#endif // CTRENDEDITDIALOG_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendEditDialog.ui b/product/src/gui/plugin/TrendCurves_pad/CTrendEditDialog.ui new file mode 100644 index 00000000..16901664 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendEditDialog.ui @@ -0,0 +1,193 @@ + + + CTrendEditDialog + + + + 0 + 0 + 1047 + 566 + + + + 趋势编辑 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 取消 + + + + + + + 确定 + + + + + + + Qt::Horizontal + + + + 500 + 20 + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + QFrame::NoFrame + + + QFrame::Sunken + + + 1 + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 3 + + + + + 2 + + + 0 + + + + + 添加 + + + + + + + 删除 + + + + + + + 清空 + + + + + + + Qt::Horizontal + + + + 408 + 20 + + + + + + + + + + + + + + + + + + + + + + CTrendEditView + QTableView +
CTrendEditView.h
+
+ + CRetriever + QWidget +
GraphTool/Retriever/CRetriever.h
+ 1 +
+
+ + + + onAddCureve() + +
diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendEditModel.cpp b/product/src/gui/plugin/TrendCurves_pad/CTrendEditModel.cpp new file mode 100644 index 00000000..08fcc893 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendEditModel.cpp @@ -0,0 +1,267 @@ +#include +#include +#include +#include "CTrendGraph.h" +#include "CTrendEditModel.h" + +CTrendDelegate::CTrendDelegate(QWidget *parent) + : QStyledItemDelegate(parent), + m_parent(parent) +{ + +} + +QWidget *CTrendDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(option) + if(!index.isValid() || !const_cast(index.model())) + { + return parent; + } + if( 2 == index.column() ) + { + QSpinBox * spin = new QSpinBox(parent); + spin->setMinimum(1); + spin->setMaximum(10); + spin->setSingleStep(1); + return spin; + } + return Q_NULLPTR; +} + +void CTrendDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyledItemDelegate::paint(painter, option, index); + if (!index.isValid()) + { + return; + } + if (!const_cast(index.model())) + { + return; + } + CTrendEditModel * model = dynamic_cast(const_cast(index.model())); + if (!model) + { + return; + } + if (1 == index.column()) + { + painter->save(); + painter->fillRect(option.rect.adjusted(2,1,-2,-1), model->color(index)); + painter->restore(); + } +} + +void CTrendDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + QStyledItemDelegate::setEditorData(editor, index); +} + +void CTrendDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + QStyledItemDelegate::setModelData(editor, model, index); +} + +void CTrendDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + Q_UNUSED(index) + editor->setGeometry(option.rect.adjusted(3,3,-3,-3)); +} + +bool CTrendDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + if(1 == index.column()) + { + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton) + { + if(const_cast(index.model())) + { + CTrendEditModel * dataModel = dynamic_cast(model); + if(dataModel) + { + QColor color = dataModel->color(index); + color = QColorDialog::getColor(color, m_parent, tr("颜色选择"), QColorDialog::DontUseNativeDialog); + if(color.isValid()) + { + dataModel->setData(index, color); + } + } + } + } + } + return QStyledItemDelegate::editorEvent(event, model, option, index); +} + +CTrendEditModel::CTrendEditModel(QObject *parent) + :QAbstractTableModel(parent) +{ + m_header << tr("测点名称") << tr("颜色"); +} + +CTrendEditModel::~CTrendEditModel() +{ + m_listCurve.clear(); +} + +void CTrendEditModel::addTrendCurve() +{ + beginResetModel(); + Curve curve; + curve.tag = QString(""); + curve.desc = QString(""); + curve.color = QColor(qrand() % 255, qrand() % 255, qrand() % 255); + m_listCurve.append(curve); + endResetModel(); +} + +void CTrendEditModel::removeTrendCurve(const QModelIndexList & indexList) +{ + beginResetModel(); + int cof = 0; + foreach (QModelIndex index, indexList) { + m_listCurve.removeAt(index.row() - cof); + cof++; + } + endResetModel(); +} + +void CTrendEditModel::clearTrendCurves() +{ + beginResetModel(); + m_listCurve.clear(); + endResetModel(); +} + +void CTrendEditModel::setTrendCurves(QList curves) +{ + beginResetModel(); + m_listCurve = curves; + endResetModel(); +} + +QList CTrendEditModel::curves() +{ + return m_listCurve; +} + +QColor CTrendEditModel::color(const QModelIndex &index) const +{ + if(index.isValid() && 1 == index.column() ) + { + return m_listCurve.at(index.row()).color; + } + return QColor(); +} + +QVariant CTrendEditModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(Qt::DisplayRole == role) + { + if(Qt::Horizontal == orientation) + { + return m_header.at(section); + } + } + return QVariant(); + +} + +QVariant CTrendEditModel::data(const QModelIndex &index, int role) const +{ + if(Qt::DisplayRole != role || !index.isValid()) + { + return QVariant(); + } + Curve curve = m_listCurve.at(index.row()); + switch (index.column()) + { + case 0: + { + return QString("%1").arg(curve.tag); + } + case 1: + { + return curve.color; + } + default: + break; + } + return QVariant(); +} + +bool CTrendEditModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_UNUSED(role) + if(!index.isValid()) + { + return false; + } + switch (index.column()) + { + case 0: + { + QStringList list = value.toString().split("."); + m_listCurve[index.row()].tag = list.at(3) + QString(".") + list.at(4) + QString(".") + list.at(5); + m_listCurve[index.row()].type = list.at(2); + break; + } + case 1: + { + m_listCurve[index.row()].color = value.value(); + break; + } + default: + break; + } + emit dataChanged(index, index); + return true; +} + +int CTrendEditModel::columnCount(const QModelIndex &index) const +{ + if (index.isValid()) + return 0; + return m_header.size(); +} + +int CTrendEditModel::rowCount(const QModelIndex &index) const +{ + if (index.isValid()) + return 0; + return m_listCurve.count(); +} + +Qt::ItemFlags CTrendEditModel::flags(const QModelIndex &index) const +{ + if(!index.isValid()) + { + return Qt::NoItemFlags; + } + return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; +} + +QString CTrendEditModel::checkAppendData(const QString &tag) +{ + QStringList list = tag.split("."); + if(list.length() != 7) + { + return tr("点标签非法"); + } + QString tagName = list.at(3) + QString(".") + list.at(4) + QString(".") + list.at(5); + QString type = list.at(2); + if(type != "analog" && type != "accuml") + { + return tr("只能添加模拟量和累积量!"); + } + + foreach (Curve curve, m_listCurve) { + if(curve.tag == tagName) + { + return tr("该测点已存在!"); + } + } + return ""; +} + diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendEditModel.h b/product/src/gui/plugin/TrendCurves_pad/CTrendEditModel.h new file mode 100644 index 00000000..17089c63 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendEditModel.h @@ -0,0 +1,99 @@ +#ifndef CTRENDEDITMODEL_H +#define CTRENDEDITMODEL_H + +/***************************************** +/ * + * 趋势曲线设置视图模型 + * + * ***************************************/ + +#include +#include +#include +#include +#include +#include +#include "CTrendGraph.h" + +//Delegate Label +class CColorLabel : public QLabel +{ + Q_OBJECT +public: + CColorLabel(QWidget * parent = Q_NULLPTR) : QLabel(parent){} + + void setColor(const QColor &color) { m_color = color; } + QColor color() const { return m_color; } + +protected: + virtual void mousePressEvent(QMouseEvent *event) + { + QLabel::mousePressEvent(event); + QColor color = QColorDialog::getColor(m_color, this, tr("颜色选择"), QColorDialog::DontUseNativeDialog); + if(color.isValid()) + { + m_color = color; + } + } + + virtual void paintEvent(QPaintEvent * event) + { + QPainter p(this); + p.fillRect(rect(), QBrush(m_color)); + QLabel::paintEvent(event); + } + +private: + QColor m_color; +}; + +class CTrendDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + CTrendDelegate(QWidget *parent = 0); + + virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; + virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + virtual void setEditorData(QWidget *editor, const QModelIndex &index) const; + virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; + +protected: + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); + +private: + QWidget * m_parent; +}; + +class CTrendEditModel : public QAbstractTableModel +{ + Q_OBJECT +public: + CTrendEditModel(QObject *parent = Q_NULLPTR); + ~CTrendEditModel(); + + void addTrendCurve(); + void removeTrendCurve(const QModelIndexList &indexList); + void clearTrendCurves(); + + void setTrendCurves(QList curves); + QList curves(); + + QColor color(const QModelIndex &index) const; + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + virtual int columnCount(const QModelIndex &index = QModelIndex()) const; + virtual int rowCount(const QModelIndex &index = QModelIndex()) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + QString checkAppendData(const QString& tag); + +private: + QStringList m_header; + QList m_listCurve; +}; + +#endif // CTRENDEDITMODEL_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendEditView.cpp b/product/src/gui/plugin/TrendCurves_pad/CTrendEditView.cpp new file mode 100644 index 00000000..41e6c5f3 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendEditView.cpp @@ -0,0 +1,98 @@ +#include "CTrendEditView.h" +#include +#include +#include +#include +#include +#include +#include "CTrendEditModel.h" + +CTrendEditView::CTrendEditView(QWidget *parent) + : CTableView(parent) +{ + setAcceptDrops(true); + setDropIndicatorShown(true); + setDragEnabled(true); + setDragDropMode(QAbstractItemView::DragDrop); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setSelectionBehavior(QAbstractItemView::SelectRows); +} + +void CTrendEditView::appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti) +{ + Q_UNUSED(strTagDesc); + if(dynamic_cast(model())) + { + CTrendEditModel * curveDataModel = dynamic_cast(model()); + + QString ret = curveDataModel->checkAppendData(strTagName); + if(ret != "") + { + QMessageBox::warning(this, tr("提示"), ret); + return; + } + + if(!isMulti) + { + if(currentIndex() == QModelIndex()) + { + QMessageBox::warning(this, tr("提示"), tr("请选中一行!")); + return; + } + + curveDataModel->setData(currentIndex().sibling(currentIndex().row(), 0), strTagName); + } + else + { + curveDataModel->addTrendCurve(); + curveDataModel->setData(model()->sibling(model()->rowCount()-1, 0, currentIndex()), strTagName); + } + } +} + +void CTrendEditView::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasText()) + { + event->acceptProposedAction(); + event->setDropAction(Qt::CopyAction); + } + else + { + event->setAccepted(false); + } +} + +void CTrendEditView::dragMoveEvent(QDragMoveEvent *event) +{ + if (event->mimeData()->hasText()) + { + event->acceptProposedAction(); + event->setDropAction(Qt::CopyAction); + } + else + { + event->setAccepted(false); + } +} + +void CTrendEditView::dropEvent(QDropEvent *event) +{ + const QMimeData *mimeData = event->mimeData(); + if (mimeData->hasText()) + { + QString content = mimeData->text(); + if(dynamic_cast(model())) + { + CTrendEditModel * curveDataModel = dynamic_cast(model()); + QPoint pt = mapFromGlobal(QCursor::pos()); + pt.setY(pt.y() - horizontalHeader()->height()); + QModelIndex index = indexAt(pt); + if(!curveDataModel->setData(index.sibling(index.row(), 0), content)) + { + QMessageBox::warning(this, tr("警告"), tr("该测点已存在!")); + } + } + } + event->accept(); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendEditView.h b/product/src/gui/plugin/TrendCurves_pad/CTrendEditView.h new file mode 100644 index 00000000..e4d1b92c --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendEditView.h @@ -0,0 +1,21 @@ +#ifndef CTRENDEDITVIEW_H +#define CTRENDEDITVIEW_H + +#include "CTableView.h" + +class CTrendEditView : public CTableView +{ + Q_OBJECT +public: + CTrendEditView(QWidget *parent = Q_NULLPTR); + +public slots: + void appendTagName(const QString &strTagName, const QString &strTagDesc, bool isMulti); + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); +}; + +#endif // CTRENDEDITVIEW_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendFavTreeWidget.cpp b/product/src/gui/plugin/TrendCurves_pad/CTrendFavTreeWidget.cpp new file mode 100644 index 00000000..9fc5a77a --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendFavTreeWidget.cpp @@ -0,0 +1,377 @@ +#include "CTrendFavTreeWidget.h" +#include "CTrendEditDialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "perm_mng_api/PermMngApi.h" +#include "pub_utility_api/FileUtil.h" + +//< 趋势编辑 权限定义 +#define FUNC_NOM_TREND_EDIT ("FUNC_NOM_TREND_EDIT") + +CTrendFavTreeWidget::CTrendFavTreeWidget(QWidget *parent) + : QTreeWidget(parent) +{ + setColumnCount(1); + setHeaderLabel(tr("收藏夹")); + setSelectionMode(QAbstractItemView::ExtendedSelection); + setEditTriggers(EditKeyPressed); + connect(this, &CTrendFavTreeWidget::doubleClicked, this, &CTrendFavTreeWidget::slotShowTrendGraph); + connect(this, &CTrendFavTreeWidget::itemChanged, this, &CTrendFavTreeWidget::slotItemChanged); + setObjectName("CTrendFavTreeWidget"); + loadTrendGraph(); + setEditTriggers(NoEditTriggers); +} + +CTrendFavTreeWidget::~CTrendFavTreeWidget() +{ + savaTrendGraph(); + qDeleteAll(m_trendGraphMap); + m_trendGraphMap.clear(); +} + +void CTrendFavTreeWidget::collectGraph(const QString &title, const CTrendGraph &graph) +{ + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + if(topLevelItem(nIndex)->text(0) == title ) + { + QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); + return; + } + } + + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << title, Item_GRAPH_Type); + item->setFlags(item->flags() | Qt::ItemIsEditable); + addTopLevelItem(item); + CTrendGraph * tmp = new CTrendGraph(); + tmp->setCurves(graph.curves()); + tmp->removeCurve("curve.tag"); + m_trendGraphMap.insert(item, tmp); + savaTrendGraph(); +} + + +void CTrendFavTreeWidget::contextMenuEvent(QContextMenuEvent *event) +{ + //< 权限处理--暂不处理 +// bool bIsEditable = false; +// iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); +// if(permMngPtr == NULL) +// { +// return; +// } + +// permMngPtr->PermDllInit(); +// std::string tmp = FUNC_NOM_TREND_EDIT; +// if (PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &tmp)) +// { +// bIsEditable = true; +// } + + QMenu menu(this); + QTreeWidgetItem * item = itemAt(event->pos()); + + if(!item) + { + QAction * newAction = new QAction(tr("添加趋势"), &menu); + menu.addAction(newAction); + connect(newAction, SIGNAL(triggered()), this, SLOT(slotNewTrendEdit())); + + QAction * importAction = new QAction(tr("导入"), &menu); + menu.addAction(importAction); + connect(importAction, SIGNAL(triggered()), this, SLOT(slotImport())); + } + else + { + if(Item_GRAPH_Type == item->type()) + { + QAction * showAction = new QAction(tr("显示"), &menu); + menu.addAction(showAction); + connect(showAction, SIGNAL(triggered()), this, SLOT(slotShowTrendGraph())); + +// QAction * editAction = new QAction(tr("编辑"), &menu); +// menu.addAction(editAction); +// connect(editAction, SIGNAL(triggered()), this, SLOT(slotEditTrendEdit())); + + QAction * renameAction = new QAction(tr("重命名"), &menu); + menu.addAction(renameAction); + connect(renameAction, &QAction::triggered, this, [&]() { + m_strEditItemContent = item->text(0); + editItem(item);}); + + QAction * deleteAction = new QAction(tr("删除"), &menu); + menu.addAction(deleteAction); + connect(deleteAction, SIGNAL(triggered()), this, SLOT(slotRemoveTrendEdit())); + + QAction * exportAction = new QAction(tr("导出"), &menu); + menu.addAction(exportAction); + connect(exportAction, SIGNAL(triggered()), this, SLOT(slotExport())); + } + } + + menu.exec(event->globalPos()); +} + +void CTrendFavTreeWidget::slotNewTrendEdit() +{ + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << getNewValidTitle(), Item_GRAPH_Type); + item->setFlags(item->flags() | Qt::ItemIsEditable); + addTopLevelItem(item); + editItem(item); +} + +void CTrendFavTreeWidget::slotShowTrendGraph() +{ + if(!m_trendGraphMap.contains(currentItem())) + { + CTrendGraph * graph = new CTrendGraph; + m_trendGraphMap.insert(currentItem(), graph); + } + emit showTrendGraph(m_trendGraphMap.value(currentItem()), currentItem()->text(0)); +} + +void CTrendFavTreeWidget::slotEditTrendEdit() +{ + CTrendEditDialog *dlg = new CTrendEditDialog(this); + + if(m_trendGraphMap.contains(currentItem())) + { + dlg->setTrendGraph(m_trendGraphMap.value(currentItem())); + } + if(QDialog::Accepted == dlg->exec()) + { + CTrendGraph * graph = dlg->trendGraph(); + + m_trendGraphMap.insert(currentItem(), graph); + savaTrendGraph(); + } + + delete dlg; + dlg = NULL; +} + +void CTrendFavTreeWidget::slotRemoveTrendEdit() +{ + + int ret=QMessageBox::question(this, tr("提示"), tr("确定删除所选项吗?"), QMessageBox::Yes,QMessageBox::No); + if(QMessageBox::Yes==ret) + { + QList selectItem = selectedItems(); + foreach (QTreeWidgetItem *item, selectItem) { + int index = indexOfTopLevelItem(item); + takeTopLevelItem(index); + } + savaTrendGraph(); + } + +} + +void CTrendFavTreeWidget::slotItemChanged(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column) + QString content = item->text(0); + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + QTreeWidgetItem *temp = topLevelItem(nIndex); + if( temp != item && temp->text(0) == content ) + { + QMessageBox::warning(this, tr("错误"), tr("当前趋势名称已存在!"), QMessageBox::Ok); + item->setText(0, m_strEditItemContent); + return; + } + } + emit updateTitle(content); +} + +void CTrendFavTreeWidget::slotImport() +{ + QString filePath = QFileDialog::getOpenFileName(this, tr("选择趋势收藏文件"), QString(), "*.xml"); + if(filePath.isEmpty()) + { + return; + } + loadTrendGraph(filePath); + savaTrendGraph(); +} + +void CTrendFavTreeWidget::slotExport() +{ + QString filePath = QFileDialog::getSaveFileName(this, tr("保存趋势收藏文件"), QString("trendFav.xml"), "*.xml"); + if(filePath.isEmpty()) + { + return; + } + + QList selectItem = selectedItems(); + if(selectItem.isEmpty()) + { + return; + } + + savaTrendGraph(filePath, selectItem); +} + +QString CTrendFavTreeWidget::getNewValidTitle() +{ + QString title = QString("自定义趋势_"); + QStringList listItemText; + for(int nIndex(0); nIndex < topLevelItemCount(); nIndex++) + { + listItemText << topLevelItem(nIndex)->text(0); + } + int serial = 0; + while(listItemText.contains(title + QString::number(serial))) + { + serial++; + } + return title + QString::number(serial); +} + +void CTrendFavTreeWidget::loadTrendGraph(const QString &filePath) +{ + QDomDocument document; + QString strFileName; + if(filePath.isEmpty()) + { + strFileName = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trendgraph.xml"); + } + else + { + strFileName = filePath; + } + QFile file(strFileName); + if (!file.open(QIODevice::ReadOnly)) + { + return; + } + if (!document.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QDomElement root = document.documentElement(); + if(!root.isNull()) + { + QDomNodeList graphNodeList = root.elementsByTagName("graph"); + for(int graphIndex(0); graphIndex < graphNodeList.size(); graphIndex++) + { + QDomNode graphNode = graphNodeList.at(graphIndex); + if(!graphNode.isNull()) + { + QDomElement graphElement = graphNode.toElement(); + if(!graphElement.isNull()) + { + QString name = graphElement.attribute("name", QString()); + QTreeWidgetItem * graphItem = new QTreeWidgetItem(QStringList() << name, Item_GRAPH_Type); + graphItem->setFlags(graphItem->flags() | Qt::ItemIsEditable); + + QList curves; + QDomNodeList curveNodeList = graphElement.elementsByTagName("curve"); + for(int nCurveIndex(0); nCurveIndex < curveNodeList.size(); nCurveIndex++) + { + QDomNode curveNode = curveNodeList.at(nCurveIndex); + QDomElement curveElement = curveNode.toElement(); + if(!curveElement.isNull()) + { + QDomNodeList itemList = curveElement.elementsByTagName("item"); + for(int itemIndex(0); itemIndex < itemList.size(); itemIndex++) + { + QDomNode itemNode = itemList.at(itemIndex); + + if(!itemNode.isNull()) + { + while(!itemNode.isNull()) + { + QDomElement item = itemNode.toElement(); + if(!item.isNull()) + { + Curve curve; + curve.tag = item.attribute("tag"); + curve.color = QColor(item.attribute("color").toUInt() & 0x00ffffff); + curves.append(curve); + } + itemNode = curveNode.nextSibling(); + } + } + } + } + } + CTrendGraph * graph = new CTrendGraph(); + graph->setCurves(curves); + m_trendGraphMap.insert(graphItem, graph); + addTopLevelItem(graphItem); + } + } + } + } +} + +void CTrendFavTreeWidget::savaTrendGraph(const QString &filePath, const QList &itemList) +{ + QFile file; + if(!filePath.isEmpty()) + { + file.setFileName(filePath); + } + else + { + QString strTrendDir = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + QString("../../data/model"); + QDir dir; + if(!dir.exists(strTrendDir)) + { + dir.mkdir(strTrendDir); + } + QString strTrendFile = QString::fromStdString(iot_public::CFileUtil::getCurModuleDir()) + QString("../../data/model/trendgraph.xml"); + file.setFileName(strTrendFile); + } + + if(file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + QDomDocument document; + + QString strHeader("version='1.0' encoding='utf-8'"); + document.appendChild(document.createProcessingInstruction("xml", strHeader)); + QDomElement root = document.createElement("Profile"); + int nCount = itemList.isEmpty()? topLevelItemCount():itemList.length(); + for(int nIndex(0); nIndex < nCount; nIndex++) + { + QTreeWidgetItem * item = itemList.isEmpty()? topLevelItem(nIndex):itemList.at(nIndex); + QDomElement graphNode = document.createElement("graph"); + graphNode.setAttribute("name", item->text(0)); + + QDomElement curveNode = document.createElement("curve"); + if(m_trendGraphMap.contains(item)) + { + const QList listCurve = m_trendGraphMap.value(item)->curves(); + for(int nCurveIndex(0); nCurveIndex < listCurve.size(); nCurveIndex++) + { + Curve curve = listCurve.at(nCurveIndex); + if(curve.curveType != enRealCurve) + { + continue; + } + QDomElement item = document.createElement("item"); + item.setAttribute("tag", curve.tag); + item.setAttribute("color", curve.color.rgb()); + curveNode.appendChild(item); + } + } + graphNode.appendChild(curveNode); + root.appendChild(graphNode); + } + document.appendChild(root); + + QTextStream content(&file); + document.save(content, 4); + } + file.close(); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendFavTreeWidget.h b/product/src/gui/plugin/TrendCurves_pad/CTrendFavTreeWidget.h new file mode 100644 index 00000000..76314344 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendFavTreeWidget.h @@ -0,0 +1,50 @@ +#ifndef CTRENDFAVTREEWIDGET_H +#define CTRENDFAVTREEWIDGET_H + +#include + +enum E_Tree_ItemType +{ + Item_GRAPH_Type = QTreeWidgetItem::UserType + 1, + Item_TAG_Type, +}; + +class CTrendGraph; + +class CTrendFavTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + explicit CTrendFavTreeWidget(QWidget *parent = nullptr); + ~CTrendFavTreeWidget(); + +signals: + void showTrendGraph(CTrendGraph * graph, QString name); + void updateTitle(QString name); + +public slots: + void collectGraph(const QString &title, const CTrendGraph &graph); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + +protected slots: + void slotNewTrendEdit(); + void slotShowTrendGraph(); + void slotEditTrendEdit(); + void slotRemoveTrendEdit(); + void slotItemChanged(QTreeWidgetItem *item, int column); + void slotImport(); + void slotExport(); + +private: + QString getNewValidTitle(); + void loadTrendGraph(const QString& filePath = QString()); + void savaTrendGraph(const QString& filePath = QString(), const QList& itemList = QList()); + +private: + QMap m_trendGraphMap; + QString m_strEditItemContent; +}; + +#endif // CTRENDFAVTREEWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendGraph.cpp b/product/src/gui/plugin/TrendCurves_pad/CTrendGraph.cpp new file mode 100644 index 00000000..950566c1 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendGraph.cpp @@ -0,0 +1,257 @@ +#include "CTrendGraph.h" +#include +#include "plot/qcustomplot.h" + +const double _EPSILON_ = 1e-5; + +CTrendGraph::CTrendGraph() +{ + +} + +CTrendGraph::~CTrendGraph() +{ + clear(); +} + +const QList CTrendGraph::curves() const +{ + return m_listCurve; +} + +void CTrendGraph::setCurves(QList listCurve) +{ + m_listCurve.swap(listCurve); +} + +const QList CTrendGraph::curveColors() const +{ + QList list; + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + list.append(m_listCurve[nIndex].color); + } + return list; +} + +const Curve &CTrendGraph::curve(const QString &tag, const int &curType) const +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + return m_listCurve.at(nIndex); + } + } + + Q_ASSERT_X(false, "CTrendGraph::curve", "curve is not exists"); + + static Curve invalid; + return invalid; +} + +int CTrendGraph::index(const QString &tag, const int &curType) const +{ + //< TODO 性能 + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + return nIndex; + } + } + return -1; +} + +void CTrendGraph::clear() +{ + m_listCurve.clear(); +} + +void CTrendGraph::addCurve(const Curve &curve) +{ + m_listCurve.append(curve); +} + +QList CTrendGraph::removeCurve(const QString &tag) +{ + QList removeList; + for(int nIndex(m_listCurve.size() - 1); nIndex >= 0; nIndex--) + { + if(m_listCurve.at(nIndex).tag == tag) + { + m_listCurve.removeAt(nIndex); + removeList.append(nIndex); + } + } + return removeList; +} + +bool CTrendGraph::removeCurve(const int &nIndex) +{ + if(nIndex < 0 || nIndex >= m_listCurve.size()) + { + return false; + } + m_listCurve.removeAt(nIndex); + return true; +} + +void CTrendGraph::setCurveVisible(const int &nIndex, const bool &visible) +{ + m_listCurve[nIndex].visible = visible; +} + +void CTrendGraph::setCurveColor(const int &nIndex, const QColor &color) +{ + m_listCurve[nIndex].color = color; +} + +void CTrendGraph::setCurveFactor(const int &nIndex, const double &factor) +{ + m_listCurve[nIndex].factor = factor; +} + +void CTrendGraph::setCurveOffset(const int &nIndex, const double &offset) +{ + m_listCurve[nIndex].offset = offset; +} + +void CTrendGraph::setCurveGraphFactor(const int &nIndex, const double &factor) +{ + m_listCurve[nIndex].graphFactor = factor; +} + +void CTrendGraph::setCurveGraphOffset(const int &nIndex, const double &offset) +{ + m_listCurve[nIndex].graphOffset = offset; +} + +void CTrendGraph::setCurveHisDataValue(const QString &tag, const int &curType, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + m_listCurve[nIndex].hisMax = max; + m_listCurve[nIndex].hisMin = min; + m_listCurve[nIndex].hisAverage = average; + m_listCurve[nIndex].hisAccuml = accuml; + m_listCurve[nIndex].hisPlotRange = range; + m_listCurve[nIndex].hisMaxTime = maxTime; + m_listCurve[nIndex].hisMinTime = minTime; + } + } +} + +void CTrendGraph::pushCurveRTDataValue(const QString &tag, const double &key, const double &value, const int &status) +{ + //< 保留20min实时数据 + int nIndex = m_listCurve.indexOf(tag); //< 实时数据索引一定在前面 + if (-1 == nIndex || qIsNaN(value)) + { + return; + } + + Curve &curve = m_listCurve[nIndex]; + curve.values.append(qMakePair>( + key, qMakePair(value, status))); + QVector< QPair > > &values = curve.values; + if (values.first().first < (key - (20 * 60 * 1000))) + { + values.removeFirst(); + } +} + +void CTrendGraph::setCurveStatisMax(const QString &tag, const int &curType, const double &max, const double &maxTime) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + m_listCurve[nIndex].sHisMax = max; + m_listCurve[nIndex].sHisMaxTime = maxTime; + } + } +} + +void CTrendGraph::setCurveStatisMin(const QString &tag, const int &curType, const double &min, const double &minTime) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + m_listCurve[nIndex].sHisMin = min; + m_listCurve[nIndex].sHisMinTime = minTime; + } + } +} + +void CTrendGraph::resetCurveStatisMax(const QString &tag, const int &curType) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + m_listCurve[nIndex].sHisMax = -DBL_MAX; + m_listCurve[nIndex].sHisMaxTime = -DBL_MAX; + } + } +} + +void CTrendGraph::resetCurveStatisMin(const QString &tag, const int &curType) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == tag && m_listCurve.at(nIndex).curveType == curType) + { + m_listCurve[nIndex].sHisMin = DBL_MAX; + m_listCurve[nIndex].sHisMinTime = DBL_MAX; + } + } +} + +void CTrendGraph::updateRTCurveStatisticsInfo(const QString &strTagName, const int &curType) +{ + for(int nIndex(0); nIndex < m_listCurve.size(); nIndex++) + { + if(m_listCurve.at(nIndex).tag == strTagName && m_listCurve.at(nIndex).curveType == curType) + { + updateRTCurveStatisticsInfo(m_listCurve[nIndex]); + return; + } + } +} + +void CTrendGraph::updateRTCurveStatisticsInfo(Curve &curve) +{ + //< 计算10min内实时数据最大值、最小值、累计值、平均值 + qreal rtMax = -DBL_MAX; + qreal rtMin = DBL_MAX; + qreal rtMaxTime = -DBL_MAX; + qreal rtMinTime = DBL_MAX; + qreal rtAccuml = 0; + int nIndex = curve.values.size(); + double validKey = QCPAxisTickerDateTime::dateTimeToKey(QDateTime::currentDateTime()) - (10 * 60 * 1000); + while (--nIndex >= 0 && curve.values.at(nIndex).first >= validKey) + { + if (curve.values.at(nIndex).second.first <= rtMin) + { + rtMin = curve.values.at(nIndex).second.first; + rtMinTime = curve.values.at(nIndex).first; + } + if(curve.values.at(nIndex).second.first >= rtMax) + { + rtMax = curve.values.at(nIndex).second.first; + rtMaxTime = curve.values.at(nIndex).first; + } + rtAccuml += curve.values.at(nIndex).second.first; + } + + curve.rtMin = rtMin; + curve.rtMax = rtMax; + curve.rtMinTime = rtMinTime; + curve.rtMaxTime = rtMaxTime; + curve.rtAccuml = rtAccuml; + curve.rtAverage = rtAccuml / (curve.values.size() - (nIndex + 1)); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendGraph.h b/product/src/gui/plugin/TrendCurves_pad/CTrendGraph.h new file mode 100644 index 00000000..1563aa0f --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendGraph.h @@ -0,0 +1,161 @@ +#ifndef CTRENDGRAPH_H +#define CTRENDGRAPH_H + +#include +#include +#include +#include +#include +#include + +/******************************趋势图形************************** + * 此类包含趋势静态配置属性 + **************************************************************/ +extern const double _EPSILON_; + +struct Range +{ + Range() + : min(DBL_MAX), + max(-DBL_MAX) + {} + + Range(double _min, double _max) + : min(_min), + max(_max) + {} + double min; + double max; +}; + +enum Type +{ + enRealCurve = 0, //< 实际测点曲线 + enPrevCurve //< 昨日曲线 +}; + +struct Curve +{ + Curve(const QString &strTagName = QString(), Type type = enRealCurve) + : visible(true), + rtMax(-DBL_MAX), + rtMin(DBL_MAX), + rtAverage(-DBL_MAX), + rtAccuml(0), + hisMax(-DBL_MAX), + hisMin(DBL_MAX), + hisAverage(-DBL_MAX), + hisAccuml(0), + graphFactor(1.), + graphOffset(0.), + factor(1.), + offset(0.), + rtMaxTime(-DBL_MAX), + rtMinTime(DBL_MAX), + hisMaxTime(-DBL_MAX), + hisMinTime(DBL_MAX), + sHisMax(-DBL_MAX), + sHisMin(DBL_MAX), + sHisMaxTime(-DBL_MAX), + sHisMinTime(DBL_MAX), + tag(strTagName), + desc(QString()), + type(QString()), + unit(QString()), + color(QColor()), + curveType(type){} + + inline bool operator==(const Curve &curve) const + { + return ((tag == curve.tag) && (curveType == curve.curveType)); + } + + inline bool operator==(const QString &strTagName) const + { + return tag == strTagName; + } + + bool visible; + double rtMax; + double rtMin; + double rtAverage; + double rtAccuml; + double hisMax; + double hisMin; + double hisAverage; + double hisAccuml; + double graphFactor; + double graphOffset; + double factor; + double offset; + double rtMaxTime; + double rtMinTime; + double hisMaxTime; + double hisMinTime; + double sHisMax; //< 实际的最大值(influx统计),仅用于显示 + double sHisMin; //< 实际的最小值(influx统计),仅用于显示 + double sHisMaxTime; //< 实际的最大值时间(influx统计),仅用于显示 + double sHisMinTime; //< 实际的最小值时间(influx统计),仅用于显示 + + Range hisPlotRange; //< hisPlotRange > Range(hisMin, hisMax) [趋势对比计算刻度] + + QString tag; + QString desc; + QString type; + QString unit; + QColor color; + Type curveType; + + QVector< QPair > > values; +}; + +class CTrendGraph +{ +public: + CTrendGraph(); + + ~CTrendGraph(); + + const QList curves() const; + void setCurves(QList listCurve); + + const QList curveColors() const; + + const Curve &curve(const QString &tag, const int &curType) const; + int index(const QString &tag, const int &curType = enRealCurve) const; + + void clear(); + + void addCurve(const Curve &curve); + QList removeCurve(const QString &tag); + bool removeCurve(const int &nIndex); + + void setCurveVisible(const int &nIndex, const bool &visible); + + void setCurveColor(const int &nIndex, const QColor &color); + void setCurveFactor(const int &nIndex, const double &factor); + void setCurveOffset(const int &nIndex, const double &offset); + + void setCurveHisDataValue(const QString &tag, const int &curType, const double &max, const double &min, const double &maxTime, const double &minTime, const double &average, const double &accuml, const Range &range); + void pushCurveRTDataValue(const QString &tag, const double &key, const double &value, const int &status); + + void setCurveStatisMax(const QString &tag, const int &curType, const double &max, const double &maxTime); + void setCurveStatisMin(const QString &tag, const int &curType, const double &min, const double &minTime); + + void resetCurveStatisMax(const QString &tag, const int &curType); + void resetCurveStatisMin(const QString &tag, const int &curType); + + void setCurveGraphFactor(const int &nIndex, const double &factor); + void setCurveGraphOffset(const int &nIndex, const double &offset); + + //< 更新实时曲线统计信息 + void updateRTCurveStatisticsInfo(const QString &strTagName, const int &curType); + void updateRTCurveStatisticsInfo(Curve &curve); + +private: + QList m_listCurve; +}; + +#endif // CTRENDGRAPH_H + + diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendInfoManage.cpp b/product/src/gui/plugin/TrendCurves_pad/CTrendInfoManage.cpp new file mode 100644 index 00000000..6243edd0 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendInfoManage.cpp @@ -0,0 +1,604 @@ +#include "CTrendInfoManage.h" +#include "service/perm_mng_api/PermMngApi.h" +#include "pub_sysinfo_api/SysInfoApi.h" +#include "pub_utility_api/CharUtil.h" +#include "pub_utility_api/FileUtil.h" +#include "perm_mng_api/PermMngApi.h" +#include "pub_logger_api/logger.h" + +using namespace iot_dbms; +using namespace iot_public; +using namespace std; + +CTrendInfoManage *CTrendInfoManage::m_pInstance = NULL; + +CTrendInfoManage *CTrendInfoManage::instance() +{ + if(NULL == m_pInstance) + { + m_pInstance = new CTrendInfoManage(); + } + return m_pInstance; +} + +CTrendInfoManage::CTrendInfoManage() +{ + //< 实时库 + m_rtdbAccess = new iot_dbms::CRdbAccess(); + + m_listTagInfo.reserve(30097); // 保证三万点测试的素数 + + CDbApi * pReadDb = new CDbApi(DB_CONN_MODEL_READ); + if(!pReadDb->open()) + { + delete pReadDb; + pReadDb = Q_NULLPTR; + return; + } + + loadUnit(pReadDb); + loadRTLocation(); + loadDevGroupInfo(pReadDb); + loadDeviceInfo(pReadDb); + loadTagInfo(pReadDb); + loadStateDefine(); + loadAlarmStatusDefine(); + loadAlarmStatus(); + loadAlarmOtherStatus(); + initInvalidStatus(); + + delete pReadDb; + pReadDb = Q_NULLPTR; +} + +void CTrendInfoManage::destory() +{ + if(m_rtdbAccess != NULL) + { + delete m_rtdbAccess; + } + m_rtdbAccess = NULL; + + m_locationInfo.clear(); + m_devGroupInfo.clear(); + m_deviceInfo.clear(); + m_listTagName.clear(); + m_listTagInfo.clear(); + m_listTagUnit.clear(); + m_menuState.clear(); + m_alarmShowStatus.clear(); + m_alarmOtherStatus.clear(); + m_alarmStatusDefineMap.clear(); + m_locationOrderList.clear(); + m_pInstance = NULL; + delete this; +} + +QMap CTrendInfoManage::locationInfo() +{ + return m_locationInfo; +} + +QString CTrendInfoManage::getLocationDesc(const int &locId) +{ + return m_locationInfo.value(locId); +} + +QList CTrendInfoManage::locationOrderList() +{ + return m_locationOrderList; +} + +QMap CTrendInfoManage::devGroupInfo(const int &location) +{ + return m_devGroupInfo.value(location, QMap()); +} + +QList > CTrendInfoManage::devGroupInfoList(const int &location) +{ + return m_devGroupInfoMap.value(location, QList >()); +} + +QMap CTrendInfoManage::deviceInfo(const QString &devGroupName) +{ + return m_deviceInfo.value(devGroupName, QMap()); +} + +QStringList CTrendInfoManage::queryTagListDevGroup(const QString &devGroup) +{ + QStringList tagList = QStringList(); + QMap devMap = m_deviceInfo.value(devGroup); + if(devMap.isEmpty()) + { + return tagList; + } + QStringList deviceList = devMap.keys(); + foreach (QString device, deviceList) { + tagList.append(m_listTagName.value(device, QStringList())); + } + return tagList; +} + +QStringList CTrendInfoManage::queryTagList(const QString &device) +{ + QStringList result = m_listTagName.value(device, QStringList()); + for(int nIndex = 0; nIndex < result.length(); ++nIndex) + { + if(getTagType(result.at(nIndex)) == "digital") + { + result.removeAt(nIndex); + nIndex--; + } + } + return result; +} + +QString CTrendInfoManage::queryDeviceGroup(const QString &device) +{ + QMap >::const_iterator iter = m_deviceInfo.begin(); + for(; iter != m_deviceInfo.end(); ++iter) + { + QStringList deviceList = iter.value().keys(); + if(deviceList.indexOf(device) != -1) + { + return iter.key(); + } + } + return QString(); +} + +QString CTrendInfoManage::getTagDescription(const QString &tag) +{ + QStringList values = m_listTagInfo.value(tag, QStringList()); + if(values.isEmpty()) + { + return QString(); + } + return values.at(0); +} + +QString CTrendInfoManage::getTagType(const QString &tag) +{ + QStringList values = m_listTagInfo.value(tag, QStringList()); + if(values.isEmpty()) + { + return QString(); + } + return values.at(1); +} + +QString CTrendInfoManage::getTagUnit(const QString &tag) +{ + QStringList values = m_listTagInfo.value(tag, QStringList()); + if(values.isEmpty()) + { + return QString(); + } + return values.at(2); +} + +bool CTrendInfoManage::checkTrendEditPerm() +{ + iot_public::SNodeInfo stNodeInfo; + iot_public::CSysInfoInterfacePtr spSysInfo; + if (!iot_public::createSysInfoInstance(spSysInfo)) + { + LOGERROR("创建系统信息访问库实例失败!"); + return false; + } + spSysInfo->getLocalNodeInfo(stNodeInfo); + + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr != NULL) + { + if(0 == permMngPtr->PermDllInit()) + { + LOGERROR("权限接口初始化失败!"); + return false; + } + std::string strTendEdit = FUNC_NOM_TREND_EDIT; + if(PERM_PERMIT == permMngPtr->PermCheck(PERM_NOM_FUNC_DEF, &strTendEdit)) + { + return true; + } + } + return false; +} + +int CTrendInfoManage::getStateActualValue(const QString &state) +{ + if(state.isEmpty()) + { + return 0; + } + return m_menuState.value(state); +} + +int CTrendInfoManage::getInvalidStatus(E_Point_Type pointType, int status) +{ + switch (pointType) + { + case E_ANALOG:{ + if(0 != (status & m_nInvalidAnalog)) + { + return 1; + } + break; + } + case E_DIGITAL:{ + if(0 != (status & m_nInvalidDigital)) + { + return 1; + } + break; + } + case E_MIX:{ + break; + } + case E_ACCUML:{ + break; + } + default: + break; + } + return 0; +} + +QMap > CTrendInfoManage::getAlarmShowStatus() +{ + return m_alarmShowStatus; +} + +QMap CTrendInfoManage::getAlarmOtherStatus() +{ + return m_alarmOtherStatus; +} + +void CTrendInfoManage::loadRTLocation() +{ + iot_service::CPermMngApiPtr permMngPtr = iot_service::getPermMngInstance("base"); + if(permMngPtr == NULL || (PERM_NORMAL != permMngPtr->PermDllInit())) + { + LOGERROR("权限接口初始化失败!"); + return; + } + int level; + std::vector vecLocationId; + std::vector vecPermPic; + if (PERM_NORMAL != permMngPtr->GetUsergInfo(level, vecLocationId, vecPermPic)) + { + LOGERROR("权限接口获取获取当前登录用户组的等级、所属车站ID失败!"); + return; + } + + std::string strApplicationName = "base"; + std::string strTableName = "sys_model_location_info"; + QPair id_value; + id_value.first = "location_id"; + id_value.second = "description"; + if(m_rtdbAccess->open(strApplicationName.c_str(), strTableName.c_str())) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.push_back(id_value.first); + columns.push_back(id_value.second); + + std::string sOrderColumn = "location_no"; + + if(m_rtdbAccess->select(result, columns, sOrderColumn)) + { + m_locationInfo.clear(); + m_locationOrderList.clear(); + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + + std::vector ::const_iterator it = vecLocationId.cbegin(); + while (it != vecLocationId.cend()) + { + if(key.toInt() == *it) + { + m_locationInfo[key.toInt()] = value.toStdString().c_str(); + m_locationOrderList << key.toInt(); + } + ++it; + } + } + } + } + m_rtdbAccess->close(); +} + +void CTrendInfoManage::loadDevGroupInfo(CDbApi *pReadDb) +{ + QSqlQuery query; + + QString strLoctionFilter; + if(!m_locationInfo.keys().isEmpty()) + { + QStringList listLocation; + foreach (int nLocationID, m_locationInfo.keys()) + { + listLocation.append(QString::number(nLocationID)); + } + strLoctionFilter = QString("(%1 in (%2))").arg("location_id").arg(listLocation.join(",")); + }else + { + return ; + } + QString sqlSequenceQuery = QStringLiteral("select tag_name, description, location_id from dev_group where sub_system > 3 "); + if(!strLoctionFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" and %1 order by dev_group_no asc;").arg(strLoctionFilter)); + }else + { + sqlSequenceQuery.append(QStringLiteral(" order by dev_group_no asc;")); + } + query.setForwardOnly(true); + pReadDb->execute(sqlSequenceQuery, query); + + while(query.next()) + { + const QString &tag_name = query.value(0).toString(); + const QString &description = query.value(1).toString(); + const int location_id = query.value(2).toInt(); + + m_devGroupInfoMap[location_id].append(QPair(tag_name,description)); + m_devGroupInfo[location_id].insert(tag_name, description); + } +} + +void CTrendInfoManage::loadDeviceInfo(CDbApi *pReadDb) +{ + QSqlQuery query; + + QString strLoctionFilter; + QList > listDevGroup = m_devGroupInfo.values(); + if(!listDevGroup.isEmpty()) + { + QStringList listLocation; + for(int i=0; iexecute(sqlSequenceQuery, query); + while(query.next()) + { + //const QString &tag_name = query.value(0).toString(); + //const QString &description = query.value(1).toString(); + //const QString &group_tag_name = query.value(2).toString(); + + m_deviceInfo[query.value(2).toString()].insert(query.value(0).toString(), query.value(1).toString()); + } +} + +void CTrendInfoManage::loadTagInfo(CDbApi *pReadDb) +{ + QSqlQuery query; + QStringList listType; + listType.append(QStringLiteral("analog")); + listType.append(QStringLiteral("digital")); + listType.append(QStringLiteral("accuml")); + // listType.append(QString("mix")); + + QString strDeviceFilter; + if(!m_deviceInfo.isEmpty()) + { + QStringList listDevice; + QMap >::const_iterator iter = m_deviceInfo.constBegin(); + while (iter != m_deviceInfo.constEnd()) + { + listDevice.append(iter.value().keys()); + ++iter; + } + strDeviceFilter = "'" % listDevice.join("', '") % "'"; + strDeviceFilter = QString("(%1 in (%2))").arg("device").arg(strDeviceFilter); + } + + query.setForwardOnly(true); + for(int nIndex(0); nIndex < listType.size(); nIndex++) + { + const QString strCurType = listType.at(nIndex); + QString strUnitField; + if(QStringLiteral("analog") == strCurType || QStringLiteral("accuml") == strCurType) + { + strUnitField = QStringLiteral(", t1.unit_id "); + } + QString sqlSequenceQuery = QString("SELECT t2.group_tag_name, t1.tag_name, t1.description, t1.device, t1.location_id, t2.DESCRIPTION %1 \ +FROM %2 as t1 left join dev_info as t2 on t1.device = t2.tag_name").arg(strUnitField).arg(strCurType); + if(!strDeviceFilter.isEmpty()) + { + sqlSequenceQuery.append(QString(" WHERE %1 ORDER BY SEQ_NO asc;").arg(strDeviceFilter)); + } + pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + //const QString group = query.value(0).toString(); + const QString &tagName = query.value(1).toString(); + //const QString tagDesc = query.value(2).toString(); + const QString &device = query.value(3).toString(); + const int location = query.value(4).toInt(); + //const QString devDesc = query.value(5).toString(); + const QString strDescription = m_locationInfo[location] % QChar('.') % m_devGroupInfo[location][query.value(0).toString()] % QChar('.') % query.value(5).toString() % QChar('.') % query.value(2).toString(); + m_listTagName[device] << tagName; + + QString strUnitDesc = QString(); + if(query.value(6).isValid()) + { + strUnitDesc = m_listTagUnit.value(query.value(6).toInt(), QString()); + } + m_listTagInfo[tagName] = QStringList() << strDescription << strCurType << strUnitDesc; + } + } +} + +void CTrendInfoManage::loadUnit(CDbApi *pReadDb) +{ + QSqlQuery query; + QString sqlSequenceQuery = QStringLiteral("select unit_id, unit_name from dict_unit_info"); + query.setForwardOnly(true); + pReadDb->execute(sqlSequenceQuery, query); + while(query.next()) + { + m_listTagUnit[query.value(0).toInt()] = query.value(1).toString(); + } +} + +void CTrendInfoManage::loadStateDefine() +{ + if(m_rtdbAccess->open("base", "dict_menu_info")) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + + CRdbQueryResult result; + std::vector columns; + columns.emplace_back("menu_macro_name"); + columns.emplace_back("actual_value"); + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + CVarType name; + CVarType value; + result.getColumnValue(nIndex, 0, name); + result.getColumnValue(nIndex, 1, value); + m_menuState.insert(name.toStdString().c_str(), value.toInt()); + } + } + } + m_rtdbAccess->close(); +} + +void CTrendInfoManage::loadAlarmStatusDefine() +{ + if(m_rtdbAccess->open("base", "alarm_status_define")) + { + iot_dbms::CTableLockGuard locker(*m_rtdbAccess); + iot_dbms::CRdbQueryResult result; + std::vector columns; + columns.emplace_back("status_value"); + columns.emplace_back("display_name"); + + if(m_rtdbAccess->select(result, columns)) + { + for(int nIndex(0); nIndex < result.getRecordCount(); nIndex++) + { + iot_dbms::CVarType key; + iot_dbms::CVarType value; + result.getColumnValue(nIndex, 0, key); + result.getColumnValue(nIndex, 1, value); + m_alarmStatusDefineMap[key.toInt()] = QString::fromStdString(value.toStdString()); + } + } + } + m_rtdbAccess->close(); +} + +void CTrendInfoManage::loadAlarmStatus() +{ + const std::string strConfFullPath = iot_public::CFileUtil::getPathOfCfgFile("alarmStatus.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + string strCheck = pParamIter->second.get(".check"); + QPair value; + if(StringToInt(strKey) != 9999) + { + value.first = m_alarmStatusDefineMap[StringToInt(strKey)]; + }else + { + value.first = QObject::tr("其他"); + } + value.second = StringToInt(strCheck); + m_alarmShowStatus[StringToInt(strKey)] = value; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CTrendInfoManage::loadAlarmOtherStatus() +{ + const std::string strConfFullPath = iot_public::CFileUtil::getPathOfCfgFile("alarmOther.xml"); + boost::property_tree::ptree pt; + namespace xml = boost::property_tree::xml_parser; + try + { + xml::read_xml(strConfFullPath, pt, xml::no_comments); + BOOST_AUTO(module, pt.get_child("root")); + for (BOOST_AUTO(pModuleIter, module.begin()); pModuleIter != module.end(); ++pModuleIter) + { + boost::property_tree::ptree ptParam = pModuleIter->second; + for (BOOST_AUTO(pParamIter, ptParam.begin()); pParamIter != ptParam.end(); ++pParamIter) + { + if (pParamIter->first == "param") + { + string strKey = pParamIter->second.get(".key"); + m_alarmOtherStatus[StringToInt(strKey)] = m_alarmStatusDefineMap[StringToInt(strKey)]; + } + } + } + } + catch (std::exception &ex) + { + LOGERROR("解析配置文件[%s]失败.Msg=[%s]", strConfFullPath.c_str(), ex.what()); + } +} + +void CTrendInfoManage::initInvalidStatus() +{ + int temp = 0x01; + m_nInvalidAnalog = 0; + m_nInvalidDigital = 0; + + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_INVALID")); //< 无效 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_GK_OFF")); //< 工况退出 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_NOT_CHANGE")); //< 不刷新 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_BAD_DATA")); //< 坏数据 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_TB")); //< 突变 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_GET_CAL")); //< 计算值 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_NOT_REAL")); //< 非实测值 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_NOT_INIT")); //< 未初始化 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_SET_DATA")); //< 人工置数 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_PINHIBIT_REF")); //< 点禁止刷新 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_DINHIBIT_REF")); //< 挂牌禁止刷新 + m_nInvalidAnalog |= (temp << getStateActualValue("MENU_STATE_AI_SINHIBIT_REF")); //< 屏蔽禁止刷新 + + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_GK_OFF")); //< 工况退出 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_INVALID")); //< 无效 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_NOT_REAL")); //< 非实测值 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_GET_CAL")); //< 计算值 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_PART_ABNORMAL")); //< 分量不正常 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SET_DATA")); //< 人工置数 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_PINHIBIT_REF")); //< 点禁止刷新 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_DINHIBIT_REF")); //< 挂牌禁止刷新 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SINHIBIT_REF")); //< 屏蔽禁止刷新 + m_nInvalidDigital |= (temp << getStateActualValue("MENU_STATE_DI_SOURCE_ABNORMAL"));//< 数据来源不正常 +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendInfoManage.h b/product/src/gui/plugin/TrendCurves_pad/CTrendInfoManage.h new file mode 100644 index 00000000..982b84c3 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendInfoManage.h @@ -0,0 +1,99 @@ +#ifndef CTRENDINFOMANAGE_H +#define CTRENDINFOMANAGE_H + +#include +#include +#include +#include +#include "dbms/rdb_api/CRdbAccess.h" +#include "dbms/db_api_ex/CDbApi.h" +#include "boost/property_tree/xml_parser.hpp" +#include "boost/typeof/typeof.hpp" +#include "boost/filesystem.hpp" + +#define FUNC_NOM_TREND_EDIT "FUNC_NOM_TREND_EDIT" + +enum E_Point_Type +{ + E_ANALOG, //< 模拟量 + E_DIGITAL, //< 数字量 + E_MIX, //< 混合量 + E_ACCUML, //< 累计量 +}; + +class CTrendInfoManage +{ +public: + static CTrendInfoManage * instance(); + + void destory(); + + QMap locationInfo(); + + QString getLocationDesc(const int &locId); + + QList locationOrderList(); + + QMap devGroupInfo(const int& location); //新增设备组 + + QList > devGroupInfoList(const int& location); + + QMap deviceInfo(const QString &devGroupName); //新增设备组时修改 + + QStringList queryTagListDevGroup(const QString &devGroup); + + QStringList queryTagList(const QString &device); + + QString queryDeviceGroup(const QString &device); + + QString getTagDescription(const QString &tag); + + QString getTagType(const QString &tag); + + QString getTagUnit(const QString &tag); + + bool checkTrendEditPerm(); + + int getStateActualValue(const QString &state); + + int getInvalidStatus(E_Point_Type pointType, int status); + + QMap > getAlarmShowStatus(); + + QMap getAlarmOtherStatus(); + +private: + CTrendInfoManage(); + + void loadRTLocation(); + void loadDevGroupInfo(iot_dbms::CDbApi *pReadDb); //新增设备组 + void loadDeviceInfo(iot_dbms::CDbApi *pReadDb); //新增设备组时修改 + void loadTagInfo(iot_dbms::CDbApi *pReadDb); + void loadUnit(iot_dbms::CDbApi *pReadDb); + void loadStateDefine(); + void loadAlarmStatusDefine(); + void loadAlarmStatus(); + void loadAlarmOtherStatus(); + void initInvalidStatus(); + +private: + iot_dbms::CRdbAccess * m_rtdbAccess; + QMap m_locationInfo; //< LocationID-LocationDesc + QMap > m_devGroupInfo; //< LocationID- 新增设备组 + QMap > > m_devGroupInfoMap; + QMap > m_deviceInfo; //< DevGroupName- 新增设备组时修改 + QMap m_listTagName; //< DeviceName-list + QHash m_listTagInfo; //< TagName-TagInfo + QMap m_listTagUnit; + QMap m_menuState; + QMap > m_alarmShowStatus; + QMap m_alarmOtherStatus; + QMap m_alarmStatusDefineMap; + QList m_locationOrderList; //< location_id: 按location_no排序 + int m_nInvalidAnalog; + int m_nInvalidDigital; + + static CTrendInfoManage * m_pInstance; +}; + +#endif // CTRENDINFOMANAGE_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendPluginWidget.cpp b/product/src/gui/plugin/TrendCurves_pad/CTrendPluginWidget.cpp new file mode 100644 index 00000000..e8b1fdd8 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendPluginWidget.cpp @@ -0,0 +1,27 @@ +#include +#include "CTrendPluginWidget.h" +#include "CTrendWindow.h" + +CTrendPluginWidget::CTrendPluginWidget(QObject *parent): QObject(parent) +{ + +} + +CTrendPluginWidget::~CTrendPluginWidget() +{ + +} + +bool CTrendPluginWidget::createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec) +{ + CTrendWindow *pWidget = new CTrendWindow(editMode, ptrVec, parent); + pWidget->initialize(E_Trend_Window); + *widget = (QWidget *)pWidget; + *pTrendWindow = (IPluginWidget *)pWidget; + return true; +} + +void CTrendPluginWidget::release() +{ + +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendPluginWidget.h b/product/src/gui/plugin/TrendCurves_pad/CTrendPluginWidget.h new file mode 100644 index 00000000..06c92ce7 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendPluginWidget.h @@ -0,0 +1,22 @@ +#ifndef CTRENDPLUGINWIDGET_H +#define CTRENDPLUGINWIDGET_H + +#include +#include "GraphShape/CPluginWidget.h" //< ISCS6000_HOME/platform/src/include/gui/GraphShape + +class CTrendPluginWidget : public QObject, public CPluginWidgetInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) + Q_INTERFACES(CPluginWidgetInterface) + +public: + CTrendPluginWidget(QObject *parent = 0); + ~CTrendPluginWidget(); + + bool createWidget(QWidget *parent, bool editMode, QWidget **widget, IPluginWidget **pTrendWindow, QVector ptrVec); + void release(); +}; + +#endif //CTRENDPLUGINWIDGET_H + diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendTreeItem.cpp b/product/src/gui/plugin/TrendCurves_pad/CTrendTreeItem.cpp new file mode 100644 index 00000000..0285a476 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendTreeItem.cpp @@ -0,0 +1,114 @@ +#include +#include "CTrendTreeItem.h" + +CTrendTreeItem::CTrendTreeItem(int type) + : m_parentItem(Q_NULLPTR), + m_data(QString()), + m_tag(QString()), + m_type(type), + m_checkState(Qt::Unchecked) +{ + +} + +CTrendTreeItem::CTrendTreeItem(CTrendTreeItem *parent, const QString &data, const int &type) + : m_parentItem(parent), + m_data(data), + m_tag(QString()), + m_type(type), + m_checkState(Qt::Unchecked) +{ + if(m_parentItem) + { + m_parentItem->m_childItems.append(this); + } +} + +CTrendTreeItem::~CTrendTreeItem() +{ + qDeleteAll(m_childItems); + m_childItems.clear(); +} + +int CTrendTreeItem::type() const +{ + return m_type; +} + +int CTrendTreeItem::indexOfChild(const CTrendTreeItem *item) const +{ + for(int nIndex(0); nIndex < m_childItems.size(); ++nIndex) + { + if(item == m_childItems[nIndex]) + { + return nIndex; + } + } + return -1; +} + +CTrendTreeItem *CTrendTreeItem::child(int row) const +{ + return m_childItems.value(row); +} + +CTrendTreeItem *CTrendTreeItem::parent() const +{ + return m_parentItem; +} + +int CTrendTreeItem::row() const +{ + if (m_parentItem) + { + return m_parentItem->m_childItems.indexOf(const_cast(this)); + } + + return 0; +} + +int CTrendTreeItem::childCount() const +{ + return m_childItems.count(); +} + +int CTrendTreeItem::columnCount() const +{ + return 1; +} + +QVariant CTrendTreeItem::data(Qt::ItemDataRole role) const +{ + if(Qt::DisplayRole == role) + { + return m_data; + } + else if(Qt::UserRole == role) + { + return m_tag; + } + else if(Qt::CheckStateRole == role) + { + return m_checkState; + } +} + +bool CTrendTreeItem::setData(const QVariant &value, Qt::ItemDataRole role) +{ + if(Qt::DisplayRole == role) + { + m_data = value.toString(); + return true; + } + else if(Qt::UserRole == role) + { + m_tag = value.toString(); + return true; + } + else if(Qt::CheckStateRole == role) + { + m_checkState = (Qt::CheckState)value.toInt(); + return true; + } + return false; +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendTreeItem.h b/product/src/gui/plugin/TrendCurves_pad/CTrendTreeItem.h new file mode 100644 index 00000000..2adc9aaa --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendTreeItem.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CTRENDTREEITEM_H +#define CTRENDTREEITEM_H + +#include +#include + +enum NodeType +{ + ROOT_TYPE = 10000, + LOCATION_TYPE, + DEV_TYPE, + TAG_TYPE +}; + +class CTrendTreeItem +{ +public: + CTrendTreeItem(int type); + CTrendTreeItem(CTrendTreeItem *parent, const QString &data, const int &type); + ~CTrendTreeItem(); + + int type() const; + + int indexOfChild(const CTrendTreeItem * item) const; + + CTrendTreeItem *child(int row) const; + CTrendTreeItem *parent() const; + + int row() const; + + int childCount() const; + int columnCount() const; + + QVariant data(Qt::ItemDataRole role = Qt::DisplayRole) const; + bool setData(const QVariant &value, Qt::ItemDataRole role); + +private: + CTrendTreeItem *m_parentItem; + QString m_data; + QString m_tag; + int m_type; + Qt::CheckState m_checkState; + + QList m_childItems; + +}; + +#endif // CTRENDTREEITEM_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendTreeModel.cpp b/product/src/gui/plugin/TrendCurves_pad/CTrendTreeModel.cpp new file mode 100644 index 00000000..d59a4c8a --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendTreeModel.cpp @@ -0,0 +1,510 @@ +#include "CTrendTreeModel.h" +#include "CTrendInfoManage.h" +#include +#include "pub_logger_api/logger.h" +const int ItemTagRole = Qt::UserRole + 1; + +CTrendTreeModel::CTrendTreeModel(QObject *parent, QTreeView *view) + : QAbstractItemModel(parent), + m_pView(view), + m_rootItem(Q_NULLPTR) +{ + QTimer::singleShot(300, this, [=](){initTrendTagInfo();}); +} + +CTrendTreeModel::~CTrendTreeModel() +{ + if(Q_NULLPTR != m_rootItem) + { + delete m_rootItem; + } + m_rootItem = Q_NULLPTR; +} + + +void CTrendTreeModel::initTrendTagInfo() +{ + beginResetModel(); + + if(Q_NULLPTR != m_rootItem) + { + delete m_rootItem; + } + m_rootItem = new QTreeWidgetItem(ROOT_TYPE); + + //< load location + QList locList = CTrendInfoManage::instance()->locationOrderList(); + foreach (const int &locId, locList) { + bool isItemShow = isFilterShow(LOCATION_TYPE,QString::number(locId)); + if(!isItemShow) + { + continue; + } + + QString desc = CTrendInfoManage::instance()->getLocationDesc(locId); + QList > devGroupInfoList = CTrendInfoManage::instance()->devGroupInfoList(locId); + if(devGroupInfoList.isEmpty()) + { + continue; + } + QString locationStr = desc; + QTreeWidgetItem * locationItem = new QTreeWidgetItem(m_rootItem, QStringList() << locationStr, LOCATION_TYPE); + locationItem->setToolTip(0, locationStr); + locationItem->setData(0, ItemTagRole, locId); + QList >::const_iterator iter_devGroup = devGroupInfoList.constBegin(); + while (iter_devGroup != devGroupInfoList.constEnd()) + { + //< load device + QMap devInfo = CTrendInfoManage::instance()->deviceInfo((*iter_devGroup).first); + if(devInfo.isEmpty()) + { + ++iter_devGroup; + continue; + } + QString devGroupStr = (*iter_devGroup).second; + + isItemShow = isFilterShow(DEV_GROUP_TYPE,(*iter_devGroup).first); + if(!isItemShow) + { + continue; + } + QTreeWidgetItem * devGroupItem = new QTreeWidgetItem(locationItem,QStringList() << devGroupStr, DEV_GROUP_TYPE); + devGroupItem->setData(0, ItemTagRole, (*iter_devGroup).first); + devGroupItem->setToolTip(0, devGroupStr); + QMap::const_iterator iter_device = devInfo.constBegin(); + while (iter_device != devInfo.constEnd()) + { + //< load tag + QStringList listTagName = CTrendInfoManage::instance()->queryTagList(iter_device.key()); + if(listTagName.isEmpty()) + { + ++iter_device; + continue; + } + + isItemShow = isFilterShow(DEV_TYPE,iter_device.key()); + if(!isItemShow) + { + continue; + } + + QString devStr = iter_device.value(); + QTreeWidgetItem * devItem = new QTreeWidgetItem(devGroupItem,QStringList() << devStr, DEV_TYPE); + devItem->setToolTip(0, iter_device.value()); + devItem->setData(0, ItemTagRole, iter_device.key()); + QStringList::const_iterator iter_tag = listTagName.constBegin(); + while (iter_tag != listTagName.constEnd()) + { + isItemShow = isFilterShow(TAG_TYPE, *iter_tag); + if(!isItemShow) + { + continue; + } + + QString tagStr = CTrendInfoManage::instance()->getTagDescription(*iter_tag).section(".", -1); + QTreeWidgetItem * tagItem = new QTreeWidgetItem(devItem,QStringList() << tagStr, TAG_TYPE); + tagItem->setData(0, ItemTagRole, *iter_tag); + QString toolStr = QString("%1(%2)").arg(tagStr).arg(*iter_tag); + tagItem->setToolTip(0, toolStr); + ++iter_tag; + } + ++iter_device; + } + ++iter_devGroup; + } + } + endResetModel(); + if(m_pView == Q_NULLPTR) + { + return; + } + for(int n=0; nchildCount(); n++) + { + m_pView->expand(index(n,0)); + } +} + +void CTrendTreeModel::clearTrendTagInfo() +{ + CTrendInfoManage::instance()->destory(); + beginResetModel(); + if(Q_NULLPTR != m_rootItem) + { + delete m_rootItem; + } + m_rootItem = Q_NULLPTR; + endResetModel(); +} + +QVariant CTrendTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_UNUSED(section) + Q_UNUSED(orientation) + Q_UNUSED(role) + return QVariant(); +} + +QModelIndex CTrendTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if(!hasIndex(row, column, parent) || Q_NULLPTR == m_rootItem) + { + return QModelIndex(); + } + + QTreeWidgetItem * parentItem; + if(!parent.isValid()) + { + parentItem = m_rootItem; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + if(parentItem) + { + QTreeWidgetItem *childItem = parentItem->child(row); + if(childItem) + { + return createIndex(row,0,childItem); + } + } + + return QModelIndex(); +} + +QModelIndex CTrendTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + QTreeWidgetItem *childItem = static_cast(index.internalPointer()); + if (!childItem) + { + return QModelIndex(); + } + + QTreeWidgetItem *parentItem = childItem->parent(); + + if (parentItem == m_rootItem) + { + return QModelIndex(); + } + + int row = parentItem->parent()->indexOfChild(parentItem); + return createIndex(row, 0, parentItem); +} + +int CTrendTreeModel::rowCount(const QModelIndex &parent) const +{ + if(!parent.isValid()) + { + if (NULL != m_rootItem) + { + return m_rootItem->childCount(); + } + else + { + return 0; + } + } + else + { + QTreeWidgetItem * parentItem = static_cast(parent.internalPointer()); + return parentItem->childCount(); + } +} + +int CTrendTreeModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return 1; +} + +QVariant CTrendTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item) + { + if(TAG_TYPE == item->type() && Qt::CheckStateRole == role && 0 == index.column()) + { + return item->checkState(index.column()); + } + return item->data(index.column(), role); + } + return QVariant(); +} + +bool CTrendTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + + if(!index.isValid()) + { + return false; + } + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item) + { + if(Qt::CheckStateRole == role) + { + emit itemCheckStateChanged(item->data(0, ItemTagRole).toString(), value.toInt()); + } + item->setData(index.column(), role, value); + } + + return true; +} + +Qt::ItemFlags CTrendTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return Qt::NoItemFlags; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(item && TAG_TYPE == item->type()) + { + return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; + } + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +void CTrendTreeModel::setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return; + } + if(DEV_TYPE == item->type()) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + if(m_pView->isRowHidden(nChildIndex, index)) + { + continue; + } + setData(index.child(nChildIndex, 0), state, Qt::CheckStateRole); + } + m_pView->update(); + } +} + +void CTrendTreeModel::updateNodeVisualState(const QString &content, QItemSelection &selection) +{ + for(int nRow(0); nRow < m_rootItem->childCount(); nRow++) + { + QModelIndex topLevelIndex = createIndex(nRow, 0, m_rootItem->child(nRow)); + bool hit = traverNode(content, topLevelIndex, selection); + m_pView->setRowHidden(topLevelIndex.row(), topLevelIndex.parent(), !hit); + } +} + +void CTrendTreeModel::setFilterWhiteList(int itemType, const QStringList &tags) +{ + m_whiteList[itemType] = tags; +} + +void CTrendTreeModel::setFilterBlackList(int itemType, const QStringList &tags) +{ + m_blackList[itemType] = tags; +} + +QStringList CTrendTreeModel::getFilterWhiteList(int itemType) +{ + std::map::iterator iter = m_whiteList.find(itemType); + if(iter != m_whiteList.end()) + { + return iter->second; + } + + return QStringList(); +} + +QStringList CTrendTreeModel::getFilterBlackList(int itemType) +{ + std::map::iterator iter = m_blackList.find(itemType); + if(iter != m_blackList.end()) + { + return iter->second; + } + + return QStringList(); +} + +bool CTrendTreeModel::isFilterShow(int itemType, const QString &tag) +{ + QStringList wlist = getFilterWhiteList(itemType); + QStringList blist = getFilterBlackList(itemType); + + if(!wlist.isEmpty()) + { + foreach (const QString &str, wlist) { + if (str.compare(tag) == 0) + return true; + } + + return false; + } + + if(!blist.isEmpty()) + { + foreach (const QString &str, blist) { + if (str.compare(tag) == 0) + return false; + } + + return true; + } + + return true; +} + +bool CTrendTreeModel::traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection) +{ + if(!index.isValid()) + { + return false; + } + + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return false; + } + + bool isContains = false; + if(content.isEmpty()) + { + isContains = true; + } + else + { + isContains = item->text(index.column()).contains(content); + if(isContains) + { + selection.append(QItemSelectionRange(index)); + } + } + + if(TAG_TYPE == item->type()) + { + m_pView->setRowHidden(index.row(), index.parent(), !isContains); + return isContains; + } + + bool hasHit = false; + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + if(isContains) + { + break; + } + if(traverNode(content, index.child(nChildIndex, 0), selection)) + { + hasHit = true; + } + } + + if(DEV_TYPE == item->type()) + { + if(isContains) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + m_pView->setRowHidden(nChildIndex, index, false); + } + } + m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); + } + + if(DEV_GROUP_TYPE == item->type()) + { + if(isContains) + { + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + m_pView->setRowHidden(nChildIndex, index, false); + for(int n(0); n < item->child(nChildIndex)->childCount(); n++) + { + m_pView->setRowHidden(n, createIndex(n, 0, item->child(nChildIndex)), false); + } + } + } + m_pView->setRowHidden(index.row(), index.parent(), !hasHit & !isContains); + } + + return hasHit | isContains; +} + +void CTrendTreeModel::clearCheckState() +{ + if(!m_rootItem) + { + return; + } + blockSignals(true); + for(int nRow(0); nRow < m_rootItem->childCount(); nRow++) + { + QModelIndex topLevelIndex = createIndex(nRow, 0, m_rootItem->child(nRow)); + updateChildCheckState(topLevelIndex, Qt::Unchecked); + } + blockSignals(false); + m_pView->update(); +} + +void CTrendTreeModel::updateTagCheckState(const QString &tag, const bool &checked) +{ + for(int nLocationRow(0); nLocationRow < m_rootItem->childCount(); nLocationRow++) + { + QTreeWidgetItem * locationItem = m_rootItem->child(nLocationRow); + for(int nDeviceGroupRow(0); nDeviceGroupRow < locationItem->childCount(); nDeviceGroupRow++) + { + QTreeWidgetItem * deviceGroupItem = locationItem->child(nDeviceGroupRow); + for(int nDeviceRow(0); nDeviceRow < deviceGroupItem->childCount(); nDeviceRow++) + { + QTreeWidgetItem * deviceItem = deviceGroupItem->child(nDeviceRow); + for(int nTagRow(0); nTagRow < deviceItem->childCount(); nTagRow++) + { + QTreeWidgetItem * tagItem = deviceItem->child(nTagRow); + if(tag == tagItem->data(0, ItemTagRole).toString()) + { + tagItem->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked); + return; + } + } + } + } + } +} + +void CTrendTreeModel::updateChildCheckState(const QModelIndex &index, const Qt::CheckState &state) +{ + if(!index.isValid()) + { + return; + } + QTreeWidgetItem * item = static_cast(index.internalPointer()); + if(!item) + { + return; + } + if(TAG_TYPE == item->type()) + { + item->setCheckState(0, state); + } + for(int nChildIndex(0); nChildIndex < item->childCount(); nChildIndex++) + { + updateChildCheckState(index.child(nChildIndex, 0), state); + } +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendTreeModel.h b/product/src/gui/plugin/TrendCurves_pad/CTrendTreeModel.h new file mode 100644 index 00000000..c5c5a67e --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendTreeModel.h @@ -0,0 +1,80 @@ +#ifndef CTRENDTREEMODEL_H +#define CTRENDTREEMODEL_H + +#include +#include +#include +#include + +enum NodeType +{ + ROOT_TYPE = 10000, + LOCATION_TYPE, + DEV_GROUP_TYPE, + DEV_TYPE, + TAG_TYPE +}; + +extern const int ItemTagRole; + +class CTrendTreeModel : public QAbstractItemModel +{ + Q_OBJECT +public: + CTrendTreeModel(QObject *parent = Q_NULLPTR, QTreeView *view = Q_NULLPTR); + + ~CTrendTreeModel(); + + void initTrendTagInfo(); + + void clearTrendTagInfo(); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + + QModelIndex parent(const QModelIndex &index) const override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + void setChildrenCheckState(const QModelIndex &index, const Qt::CheckState &state); + + void updateNodeVisualState(const QString &content, QItemSelection &selection); + + void setFilterWhiteList(int itemType,const QStringList &tags); + + void setFilterBlackList(int itemType,const QStringList &tags); + + QStringList getFilterWhiteList(int itemType); + + QStringList getFilterBlackList(int itemType); + + bool isFilterShow(int itemType,const QString& tag); + +signals: + void itemCheckStateChanged(const QString &strTagName, const int &checkedState); + +public slots: + void clearCheckState(); + void updateTagCheckState(const QString &tag, const bool &checked); + +protected: + bool traverNode(const QString &content, const QModelIndex &index, QItemSelection &selection); + + void updateChildCheckState(const QModelIndex &index, const Qt::CheckState &state); + +private: + QTreeView * m_pView; + QStringList m_header; + QTreeWidgetItem * m_rootItem; + std::map m_whiteList; + std::map m_blackList; +}; + +#endif // CTRENDTREEMODEL_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendTreeView.cpp b/product/src/gui/plugin/TrendCurves_pad/CTrendTreeView.cpp new file mode 100644 index 00000000..7cb8d5ad --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendTreeView.cpp @@ -0,0 +1,59 @@ +#include "CTrendTreeView.h" +#include "CTrendTreeModel.h" +#include +#include +#include + +CTrendTreeView::CTrendTreeView(QWidget *parent) + : QTreeView(parent) +{ + +} + +void CTrendTreeView::contextMenuEvent(QContextMenuEvent *event) +{ + CTrendTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QTreeWidgetItem * pItem = static_cast(indexAt(event->pos()).internalPointer()); + if(Q_NULLPTR != pItem) + { + if(DEV_TYPE == pItem->type()) + { + QMenu menu(this); + menu.addAction(tr("全选"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Checked); }); + menu.addAction(tr("清空"), [=](){ pModel->setChildrenCheckState(indexAt(event->pos()), Qt::Unchecked); }); + menu.exec(event->globalPos()); + } + } + } + return; +} + +void CTrendTreeView::mouseDoubleClickEvent(QMouseEvent *event) +{ + CTrendTreeModel * pModel = dynamic_cast(model()); + if(Q_NULLPTR != pModel) + { + QModelIndex index = indexAt(event->pos()); + QTreeWidgetItem * pItem = static_cast(index.internalPointer()); + if(Q_NULLPTR != pItem) + { + if(TAG_TYPE == pItem->type()) + { + Qt::CheckState state = pItem->data(0, Qt::CheckStateRole).value(); + if (Qt::Checked == state) + { + state = Qt::Unchecked; + } + else + { + state = Qt::Checked; + } + pModel->setData(index, state, Qt::CheckStateRole); + update(); + } + } + } + return QTreeView::mouseDoubleClickEvent(event); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendTreeView.h b/product/src/gui/plugin/TrendCurves_pad/CTrendTreeView.h new file mode 100644 index 00000000..2fb82d37 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendTreeView.h @@ -0,0 +1,17 @@ +#ifndef CTRENDTREEVIEW_H +#define CTRENDTREEVIEW_H + +#include + +class CTrendTreeView : public QTreeView +{ + Q_OBJECT +public: + CTrendTreeView(QWidget *parent = Q_NULLPTR); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); +}; + +#endif // CTRENDTREEVIEW_H diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendWindow.cpp b/product/src/gui/plugin/TrendCurves_pad/CTrendWindow.cpp new file mode 100644 index 00000000..2fa1075a --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendWindow.cpp @@ -0,0 +1,579 @@ +#include "CTrendWindow.h" +#include +#include +#include +#include +#include +#include "CPlotWidget.h" +#include +#include +#include "CTrendTreeView.h" +#include "CTrendTreeModel.h" +#include "CTrendInfoManage.h" +#include "CTrendFavTreeWidget.h" +#include "pub_utility_api/FileUtil.h" +#include "./widgets/CEditCollectWidget.h" +#include "./widgets/CSliderRangeWidget.h" +#include "pub_utility_api/FileStyle.h" + +CTrendWindow::CTrendWindow(bool editMode, QVector ptrVec, QWidget *parent) + : QWidget(parent), + m_isEditMode(editMode), + m_pTagWidget(Q_NULLPTR), + m_plotWidget(Q_NULLPTR), + m_pTagTreeView(Q_NULLPTR), + m_pTrendTreeModel(Q_NULLPTR), + m_pSearchButton(Q_NULLPTR), + m_pSearchTextEdit(Q_NULLPTR), + m_pSplitter(Q_NULLPTR), + m_pCollectWidget(Q_NULLPTR), + m_pSliderRangeWidget(Q_NULLPTR) +{ + Q_UNUSED(ptrVec) + + QString qss = QString(); + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("public.qss") ; + QFile qssfile1(QString::fromStdString(strFullPath)); + qssfile1.open(QFile::ReadOnly); + if (qssfile1.isOpen()) + { + qss += QLatin1String(qssfile1.readAll()); + //setStyleSheet(qss); + qssfile1.close(); + } + + strFullPath = iot_public::CFileStyle::getPathOfStyleFile("trendCurves.qss") ; + QFile qssfile2(QString::fromStdString(strFullPath)); + qssfile2.open(QFile::ReadOnly); + if (qssfile2.isOpen()) + { + qss += QLatin1String(qssfile2.readAll()); + //setStyleSheet(qss); + qssfile2.close(); + } + if(!qss.isEmpty()) + { + setStyleSheet(qss); + } +} + +CTrendWindow::~CTrendWindow() +{ + CTrendInfoManage::instance()->destory(); +} + +void CTrendWindow::initialize(const int &mode) +{ + clearChildren(); + + if(m_isEditMode) + { + initWindow(); + return; + } + + if(E_Trend_Window == (E_Trend_Mode)mode) + { + initWindow(); + } + else if(E_Trend_Widget == (E_Trend_Mode)mode) + { + initWidget(); + } + + if(m_plotWidget) + { + QString strColorConfig; + std::string strFullPath = iot_public::CFileStyle::getPathOfStyleFile("curveColor.cfg") ; + QFile colorFile(QString::fromStdString(strFullPath)); + if (colorFile.open(QIODevice::ReadOnly)) + { + QTextStream colorStream(&colorFile); + strColorConfig= colorStream.readAll(); + } + QStringList listColor = strColorConfig.split("\n"); + m_plotWidget->setColorList(listColor); + + m_pCollectWidget = new CEditCollectWidget(this); + connect(m_pCollectWidget, &CEditCollectWidget::acceptedInput, this, &CTrendWindow::slotCollectGraph); + connect(this, &CTrendWindow::sigCollectGraph, m_plotWidget, &CPlotWidget::slotCollectGraph); + connect(m_plotWidget, &CPlotWidget::sigAddCollect, this, &CTrendWindow::slotAddCollect); + connect(m_plotWidget, &CPlotWidget::sigHideCollect, this, &CTrendWindow::slotHideCollect); + + m_pSliderRangeWidget = new CSliderRangeWidget(this); + connect(m_pSliderRangeWidget, &CSliderRangeWidget::acceptedInput, this, &CTrendWindow::slotSliderChange); + connect(this, &CTrendWindow::sigSliderRangeChange, m_plotWidget, &CPlotWidget::slotSliderRangeChange); + connect(m_plotWidget, &CPlotWidget::sigSliderRangeSet, this, &CTrendWindow::slotSliderRangeSet); + connect(m_plotWidget, &CPlotWidget::sigHideSliderSet, this, &CTrendWindow::slotHideSliderSet); + + } +} + +void CTrendWindow::setTitle(const QString &title) +{ + if(m_plotWidget) + { + m_plotWidget->setTitle(title); + } +} + +void CTrendWindow::setTitleVisible(bool visible) +{ + if(m_plotWidget) + { + m_plotWidget->setTitleVisible(visible); + } +} + +void CTrendWindow::setTickCount(const int &count) +{ + if(m_plotWidget) + { + m_plotWidget->setTickCount(count); + } +} + +void CTrendWindow::insertTag(const QString &tag, const bool &resetTitle) +{ + if(m_plotWidget) + { + m_plotWidget->insertTag(tag,resetTitle); + } +} + +void CTrendWindow::insertTag(const QStringList &listTag, const bool &resetTitle) +{ + if(m_plotWidget) + { + m_plotWidget->insertTag(listTag,resetTitle); + } +} + +void CTrendWindow::removeTag(const QString &tag, const bool &resetTitle) +{ + if(m_plotWidget) + { + m_plotWidget->removeTag(tag,resetTitle); + } +} + +void CTrendWindow::setDisplayTime(const int &trendType, const double &dateTime) +{ + if(m_plotWidget) + { + m_plotWidget->setDisplayTime(trendType, dateTime); + } +} + +void CTrendWindow::setTagVisible(const QString &tag, const bool &visible) +{ + if(m_plotWidget) + { + m_plotWidget->setTagVisible(tag, visible); + } +} + +void CTrendWindow::clearTag() +{ + if(m_plotWidget) + { + m_plotWidget->clear(); + } +} + +void CTrendWindow::setDateButtonVisible(const int &button, const bool &visible) +{ + if(m_plotWidget) + { + m_plotWidget->setDateButtonVisible(button, visible); + } +} + +void CTrendWindow::setClearVisible(bool visible) +{ + if(m_plotWidget) + { + m_plotWidget->setClearVisible(visible); + } +} + +void CTrendWindow::setDevTreeVisible(bool visible) +{ + m_pTagWidget->setVisible(visible); +} + +void CTrendWindow::setAdaptVisible(bool visible) +{ + if(m_plotWidget) + { + m_plotWidget->setAdaptVisible(visible); + } +} + +void CTrendWindow::setAlarmPointVisible(bool visible) +{ + if(m_plotWidget) + { + m_plotWidget->setAlarmPointVisible(visible); + } +} + +void CTrendWindow::setPreCurveVisible(bool visible) +{ + if(m_plotWidget) + { + m_plotWidget->setPreCurveVisible(visible); + } +} + +void CTrendWindow::initWindow() +{ + m_pTagWidget = new QTabWidget(this); + m_pTagWidget->setTabPosition(QTabWidget::North); + m_pTagTreeView = new CTrendTreeView(this); + m_pTrendTreeModel = new CTrendTreeModel(this, m_pTagTreeView); + m_pTagTreeView->setModel(m_pTrendTreeModel); + m_pTagTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_pTagTreeView->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + + QHBoxLayout * pHBoxLayout = new QHBoxLayout(m_pTagTreeView->header()); + m_pSearchTextEdit = new QLineEdit(m_pTagTreeView->header()); + m_pSearchTextEdit->setObjectName("searchTextEdit"); + m_pSearchButton = new QPushButton(m_pTagTreeView->header()); + m_pSearchButton->setObjectName("searchButton"); + connect(m_pSearchTextEdit, &QLineEdit::returnPressed, this, &CTrendWindow::FindTagName); + connect(m_pSearchButton, &QPushButton::clicked, this, &CTrendWindow::FindTagName); + pHBoxLayout->addWidget(m_pSearchTextEdit, 1); + pHBoxLayout->addWidget(m_pSearchButton, 0); + pHBoxLayout->setContentsMargins(5,0,5,0); + pHBoxLayout->setSpacing(0); + m_pTagTreeView->header()->setLayout(pHBoxLayout); + m_pTagWidget->addTab(m_pTagTreeView, tr("设备/点")); + CTrendFavTreeWidget * pFavoritesTreeWidget = new CTrendFavTreeWidget(m_pTagWidget); + pFavoritesTreeWidget->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + m_pTagWidget->addTab(pFavoritesTreeWidget, tr("收藏夹")); + m_pTagWidget->setContentsMargins(1,1,1,1); + m_pTagWidget->setCurrentIndex(1); + m_plotWidget = new CPlotWidget(this); + m_plotWidget->initialize(); + m_pSplitter = new QSplitter(this); + m_pSplitter->addWidget(m_pTagWidget); + m_pSplitter->addWidget(m_plotWidget); + m_pSplitter->setStretchFactor(0, 2); + m_pSplitter->setStretchFactor(1, 3); + m_pSplitter->setContentsMargins(6, 6, 6, 6); + m_pSplitter->setHandleWidth(10); + QHBoxLayout * layout = new QHBoxLayout(this); + layout->addWidget(m_pSplitter); + layout->setContentsMargins(0, 0, 0, 0); + setLayout(layout); + connect(m_plotWidget, &CPlotWidget::clearCurve, m_pTrendTreeModel, &CTrendTreeModel::clearCheckState); + connect(m_plotWidget, &CPlotWidget::collectGraph, pFavoritesTreeWidget, &CTrendFavTreeWidget::collectGraph); + connect(m_plotWidget, &CPlotWidget::updateTagCheckState, m_pTrendTreeModel, &CTrendTreeModel::updateTagCheckState, Qt::QueuedConnection); + connect(m_pTrendTreeModel, &CTrendTreeModel::itemCheckStateChanged, this, &CTrendWindow::itemCheckStateChanged); + connect(pFavoritesTreeWidget, &CTrendFavTreeWidget::showTrendGraph, this, &CTrendWindow::showTrendGraph); + connect(pFavoritesTreeWidget, &CTrendFavTreeWidget::updateTitle, this, &CTrendWindow::setTitle); + + if(!m_isEditMode) + { + m_pTagWidget->installEventFilter(this); + m_pTagWidget->tabBar()->installEventFilter(this); + m_pTagTreeView->viewport()->installEventFilter(this); + m_pTagTreeView->header()->viewport()->installEventFilter(this); + m_pSearchTextEdit->installEventFilter(this); + m_pSearchButton->installEventFilter(this); + pFavoritesTreeWidget->viewport()->installEventFilter(this); + pFavoritesTreeWidget->header()->viewport()->installEventFilter(this); + } +} + +void CTrendWindow::initWidget() +{ + m_plotWidget = new CPlotWidget(this); + m_plotWidget->initialize(); + m_plotWidget->setTickCount(5); + m_plotWidget->setWindowMode(false); + QHBoxLayout * layout = new QHBoxLayout(this); + layout->addWidget(m_plotWidget); + layout->setMargin(3); + setLayout(layout); +} + +void CTrendWindow::clearChildren() +{ + if(m_pSearchButton) + { + delete m_pSearchButton; + } + m_pSearchButton = Q_NULLPTR; + + if(m_pSearchTextEdit) + { + delete m_pSearchTextEdit; + } + m_pSearchTextEdit = Q_NULLPTR; + + if(m_pTagTreeView) + { + delete m_pTagTreeView; + } + m_pTagTreeView = Q_NULLPTR; + + if(m_pTagWidget) + { + delete m_pTagWidget; + } + m_pTagWidget = Q_NULLPTR; + + if(m_pCollectWidget) + { + m_pCollectWidget->close(); + delete m_pCollectWidget; + } + m_pCollectWidget = Q_NULLPTR; + + if(m_pSliderRangeWidget) + { + m_pSliderRangeWidget->close(); + delete m_pSliderRangeWidget; + } + m_pSliderRangeWidget = Q_NULLPTR; + + if(m_plotWidget) + { + delete m_plotWidget; + } + m_plotWidget = Q_NULLPTR; + + if(m_pTrendTreeModel) + { + delete m_pTrendTreeModel; + } + m_pTrendTreeModel = Q_NULLPTR; + + if(m_pSplitter) + { + delete m_pSplitter; + } + m_pSplitter = Q_NULLPTR; + + if(layout()) + { + delete layout(); + } +} + +void CTrendWindow::login() +{ + if(m_pTrendTreeModel) + { + m_pTrendTreeModel->initTrendTagInfo(); + } +} + +void CTrendWindow::logout() +{ + if(m_pTrendTreeModel) + { + m_pTrendTreeModel->clearTrendTagInfo(); + } + + if(m_plotWidget) + { + m_plotWidget->clear(true); + } +} + +void CTrendWindow::setDevTreeWidth(int width) +{ + m_pTagWidget->setMinimumWidth(width); +} + +void CTrendWindow::setFilterWhiteList(int itemType, const QString &tags) +{ + QStringList ls = tags.split(","); + m_pTrendTreeModel->setFilterWhiteList(itemType,ls); +} + +void CTrendWindow::setFilterBlackList(int itemType, const QString &tags) +{ + QStringList ls = tags.split(","); + m_pTrendTreeModel->setFilterBlackList(itemType,ls); +} + +void CTrendWindow::setTableType(int index) +{ + m_pTagWidget->setCurrentIndex(index); +} + +void CTrendWindow::slotCollectGraph() +{ + if(!m_pCollectWidget) + { + return; + } + if(!m_pCollectWidget->text().isEmpty()) + { + emit sigCollectGraph(m_pCollectWidget->text()); + m_pCollectWidget->hide(); + } + else + { + m_pCollectWidget->hide(); + QMessageBox::warning(this, tr("错误"), tr("趋势名称不允许为空!"), + QMessageBox::Ok); + } +} + +void CTrendWindow::slotAddCollect(int x, int y) +{ + m_pCollectWidget->show(); + m_pCollectWidget->clear(); + m_pCollectWidget->setEditFocus(); + QPoint pt; + pt.setX(x - m_pCollectWidget->width()); + pt.setY(y); + m_pCollectWidget->move(pt); +} + +void CTrendWindow::slotHideCollect() +{ + if(!m_pCollectWidget) + { + return; + } + if(!m_pCollectWidget->isHidden()) + { + m_pCollectWidget->hide(); + } +} + +void CTrendWindow::slotSliderChange() +{ + if(!m_pSliderRangeWidget) + { + return; + } + int lower = m_pSliderRangeWidget->lowValue(); + int upper = m_pSliderRangeWidget->upValue(); + if(lower > upper) + { + QMessageBox::warning(this, tr("错误"), tr("最小值不能大于最大值!"), QMessageBox::Ok); + } + else + { + emit sigSliderRangeChange(lower, upper); + m_pSliderRangeWidget->hide(); + } +} + +void CTrendWindow::slotSliderRangeSet(int x, int y, int lower, int upper, int minimum, int maximum) +{ + m_pSliderRangeWidget->setSpinRange(minimum, maximum); + m_pSliderRangeWidget->setLowValue(lower); + m_pSliderRangeWidget->setUpValue(upper); + m_pSliderRangeWidget->show(); + m_pSliderRangeWidget->setEditFocus(); + QPoint pt; + pt.setX(x - m_pSliderRangeWidget->width()); + pt.setY(y); + m_pSliderRangeWidget->move(pt); +} + +void CTrendWindow::slotHideSliderSet() +{ + if(!m_pSliderRangeWidget) + { + return; + } + if(!m_pSliderRangeWidget->isHidden()) + { + m_pSliderRangeWidget->hide(); + } +} + +void CTrendWindow::itemCheckStateChanged(const QString &strTagName, const int &checkedState) +{ + if(Qt::Checked == (Qt::CheckState)checkedState) + { + m_plotWidget->insertTag(strTagName); + } + else if(Qt::Unchecked == (Qt::CheckState)checkedState) + { + m_plotWidget->removeTag(strTagName); + } +} + +void CTrendWindow::updateTrendName(const QString &title) +{ + m_plotWidget->setTitle(title); +} + +void CTrendWindow::showTrendGraph(CTrendGraph *graph, const QString &name) +{ + m_plotWidget->clear(); + if(!name.isEmpty()) + { + updateTrendName(name); + } + foreach (Curve curve, graph->curves()) + { + m_plotWidget->insertCurve(curve); + } +} + +void CTrendWindow::FindTagName() +{ + QString content = m_pSearchTextEdit->text(); + m_pTagTreeView->collapseAll(); + m_pTagTreeView->selectionModel()->clear(); + QItemSelection selection; + m_pTrendTreeModel->updateNodeVisualState(content, selection); + m_pTagTreeView->selectionModel()->select(selection, QItemSelectionModel::Select); + + if(content.isEmpty()) + { + m_pTagTreeView->collapseAll(); + } + else + { + m_pTagTreeView->expandAll(); + } +} + +void CTrendWindow::mousePressEvent(QMouseEvent *event) +{ + if(!m_pCollectWidget->isHidden()) + { + m_pCollectWidget->hide(); + } + if(!m_pSliderRangeWidget->isHidden()) + { + m_pSliderRangeWidget->hide(); + } + return QWidget::mousePressEvent(event); +} + +bool CTrendWindow::eventFilter(QObject *watched, QEvent *event) +{ + if (QEvent::MouseButtonPress == event->type()) + { + if(!m_pCollectWidget->isHidden()) + { + m_pCollectWidget->hide(); + } + if(!m_pSliderRangeWidget->isHidden()) + { + m_pSliderRangeWidget->hide(); + } + return false; + } + + return QWidget::eventFilter(watched, event); +} + + +void CTrendWindow::setLimitTrend(int max) +{ + m_plotWidget->setLimitNum(max); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/CTrendWindow.h b/product/src/gui/plugin/TrendCurves_pad/CTrendWindow.h new file mode 100644 index 00000000..76275e72 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/CTrendWindow.h @@ -0,0 +1,107 @@ +#ifndef CTRENDWINDOW_H +#define CTRENDWINDOW_H + +#include +#include +#include + +class QSplitter; +class QTreeView; +class QLineEdit; +class QTabWidget; +class CPlotWidget; +class CTrendGraph; +class QPushButton; +class CTrendTreeView; +class CTrendTreeModel; +class CEditCollectWidget; +class CSliderRangeWidget; + +enum E_Trend_Mode +{ + E_Trend_Window = 0, + E_Trend_Widget = 1 +}; + +class CTrendWindow : public QWidget +{ + Q_OBJECT +public: + explicit CTrendWindow(bool editMode, QVector ptrVec, QWidget *parent = 0); + ~CTrendWindow(); + +public slots: + void initialize(const int &mode); + + void setTitle(const QString &title); + void setTitleVisible(bool visible); + void setTickCount(const int &count); + + void insertTag(const QString &tag, const bool &resetTitle = true); + void insertTag(const QStringList &listTag, const bool &resetTitle = true); + void removeTag(const QString &tag, const bool &resetTitle = true); + void setDisplayTime(const int &trendType, const double &dateTime); + void setTagVisible(const QString &tag, const bool &visible = false); + void clearTag(); + void setDateButtonVisible(const int &button, const bool &visible = false); + + void setClearVisible(bool visible); + void setDevTreeVisible(bool visible); + void setAdaptVisible(bool visible); + void setAlarmPointVisible(bool visible); + void setPreCurveVisible(bool visible); + + void login(); + void logout(); + + void setDevTreeWidth(int width); + + void setFilterWhiteList(int itemType,const QString &tags); + + void setFilterBlackList(int itemType,const QString &tags); + + void setTableType(int index);//0 为设备-点 1为收藏夹 + + void setLimitTrend(int max); + +signals: + void sigCollectGraph(const QString &text); + void sigSliderRangeChange(int lower, int upper); + +private slots: + void slotCollectGraph(); + void slotAddCollect(int x, int y); + void slotHideCollect(); + + void slotSliderChange(); + void slotSliderRangeSet(int x, int y, int lower, int upper, int minimum, int maximum); + void slotHideSliderSet(); + +protected: + void initWindow(); + void initWidget(); + + void clearChildren(); + + void itemCheckStateChanged(const QString &strTagName, const int &checkedState); + void updateTrendName(const QString &title); + void showTrendGraph(CTrendGraph * graph, const QString &name = QString()); + void FindTagName(); + + void mousePressEvent(QMouseEvent *event); + bool eventFilter(QObject *watched, QEvent *event); + +private: + bool m_isEditMode; + QTabWidget * m_pTagWidget; + CPlotWidget * m_plotWidget; + CTrendTreeView * m_pTagTreeView; + CTrendTreeModel * m_pTrendTreeModel; + QPushButton * m_pSearchButton; + QLineEdit * m_pSearchTextEdit; + QSplitter * m_pSplitter; + CEditCollectWidget * m_pCollectWidget; + CSliderRangeWidget * m_pSliderRangeWidget; +}; + +#endif // CTRENDWINDOW_H diff --git a/product/src/gui/plugin/TrendCurves_pad/TrendCurves_pad.pro b/product/src/gui/plugin/TrendCurves_pad/TrendCurves_pad.pro new file mode 100644 index 00000000..2ecd5f44 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/TrendCurves_pad.pro @@ -0,0 +1,98 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2018-11-09T10:35:55 +# +#------------------------------------------------- + + +QT += core gui widgets sql xml printsupport + + +TARGET = TrendCurves_pad +TEMPLATE = lib + +CONFIG += plugin + +INCLUDEPATH += $$PWD + + +SOURCES += \ + $$PWD/plot/qcustomplot.cpp \ + $$PWD/widgets/CTabButton.cpp \ + $$PWD/widgets/CToolTip.cpp \ + $$PWD/widgets/CEditCollectWidget.cpp \ + $$PWD/widgets/CCalendarWidget.cpp \ + $$PWD/widgets/QxtSpanSlider.cpp \ + $$PWD/widgets/CSWitchButton.cpp \ + $$PWD/widgets/CSliderRangeWidget.cpp \ + $$PWD/widgets/CMyCheckBox.cpp \ + $$PWD/widgets/CMyListWidget.cpp \ + CTrendWindow.cpp \ + CTrendGraph.cpp \ + CPlotWidget.cpp \ + CCurveLegendModel.cpp \ + CTrendTreeModel.cpp \ + CTrendInfoManage.cpp \ + CRealTimeDataCollect.cpp \ + CHisEventManage.cpp \ + CTrendFavTreeWidget.cpp \ + CTrendEditDialog.cpp \ + CTrendEditView.cpp \ + CTrendEditModel.cpp \ + CTrendPluginWidget.cpp \ + CTrendTreeView.cpp \ + CHisDataManage.cpp \ + CCurveLegendView.cpp \ + CTableDataModel.cpp \ + CTableView.cpp + +HEADERS += \ + $$PWD/plot/qcustomplot.h \ + $$PWD/widgets/CTabButton.h \ + $$PWD/widgets/CToolTip.h \ + $$PWD/widgets/CEditCollectWidget.h \ + $$PWD/widgets/CCalendarWidget.h \ + $$PWD/widgets/QxtSpanSlider.h \ + $$PWD/widgets/QxtSpanSlider_p.h \ + $$PWD/widgets/CSWitchButton.h \ + $$PWD/widgets/CSliderRangeWidget.h \ + $$PWD/widgets/CMyCheckBox.h \ + $$PWD/widgets/CMyListWidget.h \ + CTrendWindow.h \ + CTrendGraph.h \ + CPlotWidget.h \ + CCurveLegendModel.h \ + CTrendTreeModel.h \ + CTrendInfoManage.h \ + CRealTimeDataCollect.h \ + CHisEventManage.h \ + CTrendFavTreeWidget.h \ + CTrendEditDialog.h \ + CTrendEditView.h \ + CTrendEditModel.h \ + CTrendPluginWidget.h \ + CTrendTreeView.h \ + CHisDataManage.h \ + CCurveLegendView.h \ + CTableDataModel.h \ + CTableView.h + +FORMS += \ + CPlotWidget.ui \ + CTrendEditDialog.ui + +LIBS += -llog4cplus -lboost_system -lprotobuf -lpub_logger_api -lpub_excel +LIBS += -lpub_utility_api -lpub_sysinfo_api +LIBS += -ldb_base_api -ldb_api_ex -lrdb_api -lrdb_net_api -ltsdb_api -ldb_his_query_api +LIBS += -lnet_msg_bus_api -lperm_mng_api -ldp_chg_data_api -lRetriever -lpub_widget + +include($$PWD/../../../idl_files/idl_files.pri) + +COMMON_PRI=$$PWD/../../../common.pri +exists($$COMMON_PRI) { + include($$COMMON_PRI) +}else { + error("FATAL error: can not find common.pri") +} + + diff --git a/product/src/gui/plugin/TrendCurves_pad/main.cpp b/product/src/gui/plugin/TrendCurves_pad/main.cpp new file mode 100644 index 00000000..4e651cea --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/main.cpp @@ -0,0 +1,46 @@ +#include +#include "CTrendWindow.h" +#include "pub_logger_api/logger.h" +#include "dp_chg_data_api/CDpcdaForApp.h" +#include "net/net_msg_bus_api/MsgBusApi.h" +#include "service/perm_mng_api/PermMngApi.h" + +int main(int argc, char *argv[]) +{ + iot_public::StartLogSystem("", "hmi"); + if (!(iot_net::initMsgBus("HMI", "HMI"))) + { + return -1; + } + iot_service::CPermMngApiPtr perm = iot_service::getPermMngInstance("base"); + if(!perm || PERM_NORMAL != perm->PermDllInit()) + { + return -1; + } + + if(perm->SysLogin("admin", "admin", 1, 12*60*60, "hmi") != 0) + { + return -1; + } + + iot_service::CDpcdaForApp::initGlobalThread(); + + { + LOGINFO("===========================Trend Curve==========================="); + QApplication app(argc, argv); + + QVector ptrVec; + CTrendWindow w(false, ptrVec); + w.initialize(E_Trend_Window); + w.show(); + + app.exec(); + } + + iot_service::CDpcdaForApp::releaseGlobalThread(); + + iot_net::releaseMsgBus(); + iot_public::StopLogSystem(); + + return 0; +} diff --git a/product/src/gui/plugin/TrendCurves_pad/plot/qcustomplot.cpp b/product/src/gui/plugin/TrendCurves_pad/plot/qcustomplot.cpp new file mode 100644 index 00000000..ef197958 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/plot/qcustomplot.cpp @@ -0,0 +1,30468 @@ +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2017 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 04.09.17 ** +** Version: 2.0.0 ** +****************************************************************************/ + +#include "qcustomplot.h" +#include "../widgets/CToolTip.h" + +/* including file 'src/vector2d.cpp', size 7340 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPVector2D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPVector2D + \brief Represents two doubles as a mathematical 2D vector + + This class acts as a replacement for QVector2D with the advantage of double precision instead of + single, and some convenience methods tailored for the QCustomPlot library. +*/ + +/* start documentation of inline functions */ + +/*! \fn void QCPVector2D::setX(double x) + + Sets the x coordinate of this vector to \a x. + + \see setY +*/ + +/*! \fn void QCPVector2D::setY(double y) + + Sets the y coordinate of this vector to \a y. + + \see setX +*/ + +/*! \fn double QCPVector2D::length() const + + Returns the length of this vector. + + \see lengthSquared +*/ + +/*! \fn double QCPVector2D::lengthSquared() const + + Returns the squared length of this vector. In some situations, e.g. when just trying to find the + shortest vector of a group, this is faster than calculating \ref length, because it avoids + calculation of a square root. + + \see length +*/ + +/*! \fn QPoint QCPVector2D::toPoint() const + + Returns a QPoint which has the x and y coordinates of this vector, truncating any floating point + information. + + \see toPointF +*/ + +/*! \fn QPointF QCPVector2D::toPointF() const + + Returns a QPointF which has the x and y coordinates of this vector. + + \see toPoint +*/ + +/*! \fn bool QCPVector2D::isNull() const + + Returns whether this vector is null. A vector is null if \c qIsNull returns true for both x and y + coordinates, i.e. if both are binary equal to 0. +*/ + +/*! \fn QCPVector2D QCPVector2D::perpendicular() const + + Returns a vector perpendicular to this vector, with the same length. +*/ + +/*! \fn double QCPVector2D::dot() const + + Returns the dot/scalar product of this vector with the specified vector \a vec. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates to 0. +*/ +QCPVector2D::QCPVector2D() : + mX(0), + mY(0) +{ +} + +/*! + Creates a QCPVector2D object and initializes the \a x and \a y coordinates with the specified + values. +*/ +QCPVector2D::QCPVector2D(double x, double y) : + mX(x), + mY(y) +{ +} + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of + the specified \a point. +*/ +QCPVector2D::QCPVector2D(const QPoint &point) : + mX(point.x()), + mY(point.y()) +{ +} + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of + the specified \a point. +*/ +QCPVector2D::QCPVector2D(const QPointF &point) : + mX(point.x()), + mY(point.y()) +{ +} + +/*! + Normalizes this vector. After this operation, the length of the vector is equal to 1. + + \see normalized, length, lengthSquared +*/ +void QCPVector2D::normalize() +{ + double len = length(); + mX /= len; + mY /= len; +} + +/*! + Returns a normalized version of this vector. The length of the returned vector is equal to 1. + + \see normalize, length, lengthSquared +*/ +QCPVector2D QCPVector2D::normalized() const +{ + QCPVector2D result(mX, mY); + result.normalize(); + return result; +} + +/*! \overload + + Returns the squared shortest distance of this vector (interpreted as a point) to the finite line + segment given by \a start and \a end. + + \see distanceToStraightLine +*/ +double QCPVector2D::distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const +{ + QCPVector2D v(end-start); + double vLengthSqr = v.lengthSquared(); + if (!qFuzzyIsNull(vLengthSqr)) + { + double mu = v.dot(*this-start)/vLengthSqr; + if (mu < 0) + return (*this-start).lengthSquared(); + else if (mu > 1) + return (*this-end).lengthSquared(); + else + return ((start + mu*v)-*this).lengthSquared(); + } else + return (*this-start).lengthSquared(); +} + +/*! \overload + + Returns the squared shortest distance of this vector (interpreted as a point) to the finite line + segment given by \a line. + + \see distanceToStraightLine +*/ +double QCPVector2D::distanceSquaredToLine(const QLineF &line) const +{ + return distanceSquaredToLine(QCPVector2D(line.p1()), QCPVector2D(line.p2())); +} + +/*! + Returns the shortest distance of this vector (interpreted as a point) to the infinite straight + line given by a \a base point and a \a direction vector. + + \see distanceSquaredToLine +*/ +double QCPVector2D::distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const +{ + return qAbs((*this-base).dot(direction.perpendicular()))/direction.length(); +} + +/*! + Scales this vector by the given \a factor, i.e. the x and y components are multiplied by \a + factor. +*/ +QCPVector2D &QCPVector2D::operator*=(double factor) +{ + mX *= factor; + mY *= factor; + return *this; +} + +/*! + Scales this vector by the given \a divisor, i.e. the x and y components are divided by \a + divisor. +*/ +QCPVector2D &QCPVector2D::operator/=(double divisor) +{ + mX /= divisor; + mY /= divisor; + return *this; +} + +/*! + Adds the given \a vector to this vector component-wise. +*/ +QCPVector2D &QCPVector2D::operator+=(const QCPVector2D &vector) +{ + mX += vector.mX; + mY += vector.mY; + return *this; +} + +/*! + subtracts the given \a vector from this vector component-wise. +*/ +QCPVector2D &QCPVector2D::operator-=(const QCPVector2D &vector) +{ + mX -= vector.mX; + mY -= vector.mY; + return *this; +} +/* end of 'src/vector2d.cpp' */ + + +/* including file 'src/painter.cpp', size 8670 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPainter +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPainter + \brief QPainter subclass used internally + + This QPainter subclass is used to provide some extended functionality e.g. for tweaking position + consistency between antialiased and non-antialiased painting. Further it provides workarounds + for QPainter quirks. + + \warning This class intentionally hides non-virtual functions of QPainter, e.g. setPen, save and + restore. So while it is possible to pass a QCPPainter instance to a function that expects a + QPainter pointer, some of the workarounds and tweaks will be unavailable to the function (because + it will call the base class implementations of the functions actually hidden by QCPPainter). +*/ + +/*! + Creates a new QCPPainter instance and sets default values +*/ +QCPPainter::QCPPainter() : + QPainter(), + mModes(pmDefault), + mIsAntialiasing(false) +{ + // don't setRenderHint(QPainter::NonCosmeticDefautPen) here, because painter isn't active yet and + // a call to begin() will follow +} + +/*! + Creates a new QCPPainter instance on the specified paint \a device and sets default values. Just + like the analogous QPainter constructor, begins painting on \a device immediately. + + Like \ref begin, this method sets QPainter::NonCosmeticDefaultPen in Qt versions before Qt5. +*/ +QCPPainter::QCPPainter(QPaintDevice *device) : + QPainter(device), + mModes(pmDefault), + mIsAntialiasing(false) +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. + if (isActive()) + setRenderHint(QPainter::NonCosmeticDefaultPen); +#endif +} + +/*! + Sets the pen of the painter and applies certain fixes to it, depending on the mode of this + QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QPen &pen) +{ + QPainter::setPen(pen); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Sets the pen (by color) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QColor &color) +{ + QPainter::setPen(color); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Sets the pen (by style) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(Qt::PenStyle penStyle) +{ + QPainter::setPen(penStyle); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Works around a Qt bug introduced with Qt 4.8 which makes drawing QLineF unpredictable when + antialiasing is disabled. Thus when antialiasing is disabled, it rounds the \a line to + integer coordinates and then passes it to the original drawLine. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::drawLine(const QLineF &line) +{ + if (mIsAntialiasing || mModes.testFlag(pmVectorized)) + QPainter::drawLine(line); + else + QPainter::drawLine(line.toLine()); +} + +/*! + Sets whether painting uses antialiasing or not. Use this method instead of using setRenderHint + with QPainter::Antialiasing directly, as it allows QCPPainter to regain pixel exactness between + antialiased and non-antialiased painting (Since Qt < 5.0 uses slightly different coordinate systems for + AA/Non-AA painting). +*/ +void QCPPainter::setAntialiasing(bool enabled) +{ + setRenderHint(QPainter::Antialiasing, enabled); + if (mIsAntialiasing != enabled) + { + mIsAntialiasing = enabled; + if (!mModes.testFlag(pmVectorized)) // antialiasing half-pixel shift only needed for rasterized outputs + { + if (mIsAntialiasing) + translate(0.5, 0.5); + else + translate(-0.5, -0.5); + } + } +} + +/*! + Sets the mode of the painter. This controls whether the painter shall adjust its + fixes/workarounds optimized for certain output devices. +*/ +void QCPPainter::setModes(QCPPainter::PainterModes modes) +{ + mModes = modes; +} + +/*! + Sets the QPainter::NonCosmeticDefaultPen in Qt versions before Qt5 after beginning painting on \a + device. This is necessary to get cosmetic pen consistency across Qt versions, because since Qt5, + all pens are non-cosmetic by default, and in Qt4 this render hint must be set to get that + behaviour. + + The Constructor \ref QCPPainter(QPaintDevice *device) which directly starts painting also sets + the render hint as appropriate. + + \note this function hides the non-virtual base class implementation. +*/ +bool QCPPainter::begin(QPaintDevice *device) +{ + bool result = QPainter::begin(device); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. + if (result) + setRenderHint(QPainter::NonCosmeticDefaultPen); +#endif + return result; +} + +/*! \overload + + Sets the mode of the painter. This controls whether the painter shall adjust its + fixes/workarounds optimized for certain output devices. +*/ +void QCPPainter::setMode(QCPPainter::PainterMode mode, bool enabled) +{ + if (!enabled && mModes.testFlag(mode)) + mModes &= ~mode; + else if (enabled && !mModes.testFlag(mode)) + mModes |= mode; +} + +/*! + Saves the painter (see QPainter::save). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see restore +*/ +void QCPPainter::save() +{ + mAntialiasingStack.push(mIsAntialiasing); + QPainter::save(); +} + +/*! + Restores the painter (see QPainter::restore). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see save +*/ +void QCPPainter::restore() +{ + if (!mAntialiasingStack.isEmpty()) + mIsAntialiasing = mAntialiasingStack.pop(); + else + qDebug() << Q_FUNC_INFO << "Unbalanced save/restore"; + QPainter::restore(); +} + +/*! + Changes the pen width to 1 if it currently is 0. This function is called in the \ref setPen + overrides when the \ref pmNonCosmetic mode is set. +*/ +void QCPPainter::makeNonCosmetic() +{ + if (qFuzzyIsNull(pen().widthF())) + { + QPen p = pen(); + p.setWidth(1); + QPainter::setPen(p); + } +} +/* end of 'src/painter.cpp' */ + + +/* including file 'src/paintbuffer.cpp', size 18502 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPaintBuffer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPaintBuffer + \brief The abstract base class for paint buffers, which define the rendering backend + + This abstract base class defines the basic interface that a paint buffer needs to provide in + order to be usable by QCustomPlot. + + A paint buffer manages both a surface to draw onto, and the matching paint device. The size of + the surface can be changed via \ref setSize. External classes (\ref QCustomPlot and \ref + QCPLayer) request a painter via \ref startPainting and then perform the draw calls. Once the + painting is complete, \ref donePainting is called, so the paint buffer implementation can do + clean up if necessary. Before rendering a frame, each paint buffer is usually filled with a color + using \ref clear (usually the color is \c Qt::transparent), to remove the contents of the + previous frame. + + The simplest paint buffer implementation is \ref QCPPaintBufferPixmap which allows regular + software rendering via the raster engine. Hardware accelerated rendering via pixel buffers and + frame buffer objects is provided by \ref QCPPaintBufferGlPbuffer and \ref QCPPaintBufferGlFbo. + They are used automatically if \ref QCustomPlot::setOpenGl is enabled. +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual QCPPainter *QCPAbstractPaintBuffer::startPainting() = 0 + + Returns a \ref QCPPainter which is ready to draw to this buffer. The ownership and thus the + responsibility to delete the painter after the painting operations are complete is given to the + caller of this method. + + Once you are done using the painter, delete the painter and call \ref donePainting. + + While a painter generated with this method is active, you must not call \ref setSize, \ref + setDevicePixelRatio or \ref clear. + + This method may return 0, if a painter couldn't be activated on the buffer. This usually + indicates a problem with the respective painting backend. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::draw(QCPPainter *painter) const = 0 + + Draws the contents of this buffer with the provided \a painter. This is the method that is used + to finally join all paint buffers and draw them onto the screen. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::clear(const QColor &color) = 0 + + Fills the entire buffer with the provided \a color. To have an empty transparent buffer, use the + named color \c Qt::transparent. + + This method must not be called if there is currently a painter (acquired with \ref startPainting) + active. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::reallocateBuffer() = 0 + + Reallocates the internal buffer with the currently configured size (\ref setSize) and device + pixel ratio, if applicable (\ref setDevicePixelRatio). It is called as soon as any of those + properties are changed on this paint buffer. + + \note Subclasses of \ref QCPAbstractPaintBuffer must call their reimplementation of this method + in their constructor, to perform the first allocation (this can not be done by the base class + because calling pure virtual methods in base class constructors is not possible). +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of inline functions */ + +/*! \fn virtual void QCPAbstractPaintBuffer::donePainting() + + If you have acquired a \ref QCPPainter to paint onto this paint buffer via \ref startPainting, + call this method as soon as you are done with the painting operations and have deleted the + painter. + + paint buffer subclasses may use this method to perform any type of cleanup that is necessary. The + default implementation does nothing. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a paint buffer and initializes it with the provided \a size and \a devicePixelRatio. + + Subclasses must call their \ref reallocateBuffer implementation in their respective constructors. +*/ +QCPAbstractPaintBuffer::QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio) : + mSize(size), + mDevicePixelRatio(devicePixelRatio), + mInvalidated(true) +{ +} + +QCPAbstractPaintBuffer::~QCPAbstractPaintBuffer() +{ +} + +/*! + Sets the paint buffer size. + + The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained + by \ref startPainting are invalidated and must not be used after calling this method. + + If \a size is already the current buffer size, this method does nothing. +*/ +void QCPAbstractPaintBuffer::setSize(const QSize &size) +{ + if (mSize != size) + { + mSize = size; + reallocateBuffer(); + } +} + +/*! + Sets the invalidated flag to \a invalidated. + + This mechanism is used internally in conjunction with isolated replotting of \ref QCPLayer + instances (in \ref QCPLayer::lmBuffered mode). If \ref QCPLayer::replot is called on a buffered + layer, i.e. an isolated repaint of only that layer (and its dedicated paint buffer) is requested, + QCustomPlot will decide depending on the invalidated flags of other paint buffers whether it also + replots them, instead of only the layer on which the replot was called. + + The invalidated flag is set to true when \ref QCPLayer association has changed, i.e. if layers + were added or removed from this buffer, or if they were reordered. It is set to false as soon as + all associated \ref QCPLayer instances are drawn onto the buffer. + + Under normal circumstances, it is not necessary to manually call this method. +*/ +void QCPAbstractPaintBuffer::setInvalidated(bool invalidated) +{ + mInvalidated = invalidated; +} + +/*! + Sets the the device pixel ratio to \a ratio. This is useful to render on high-DPI output devices. + The ratio is automatically set to the device pixel ratio used by the parent QCustomPlot instance. + + The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained + by \ref startPainting are invalidated and must not be used after calling this method. + + \note This method is only available for Qt versions 5.4 and higher. +*/ +void QCPAbstractPaintBuffer::setDevicePixelRatio(double ratio) +{ + if (!qFuzzyCompare(ratio, mDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mDevicePixelRatio = ratio; + reallocateBuffer(); +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mDevicePixelRatio = 1.0; +#endif + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferPixmap +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferPixmap + \brief A paint buffer based on QPixmap, using software raster rendering + + This paint buffer is the default and fall-back paint buffer which uses software rendering and + QPixmap as internal buffer. It is used if \ref QCustomPlot::setOpenGl is false. +*/ + +/*! + Creates a pixmap paint buffer instancen with the specified \a size and \a devicePixelRatio, if + applicable. +*/ +QCPPaintBufferPixmap::QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio) : + QCPAbstractPaintBuffer(size, devicePixelRatio) +{ + QCPPaintBufferPixmap::reallocateBuffer(); +} + +QCPPaintBufferPixmap::~QCPPaintBufferPixmap() +{ +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferPixmap::startPainting() +{ + QCPPainter *result = new QCPPainter(&mBuffer); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::draw(QCPPainter *painter) const +{ + if (painter && painter->isActive()) + painter->drawPixmap(0, 0, mBuffer); + else + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::clear(const QColor &color) +{ + mBuffer.fill(color); +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::reallocateBuffer() +{ + setInvalidated(); + if (!qFuzzyCompare(1.0, mDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mBuffer = QPixmap(mSize*mDevicePixelRatio); + mBuffer.setDevicePixelRatio(mDevicePixelRatio); +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mDevicePixelRatio = 1.0; + mBuffer = QPixmap(mSize); +#endif + } else + { + mBuffer = QPixmap(mSize); + } +} + + +#ifdef QCP_OPENGL_PBUFFER +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferGlPbuffer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferGlPbuffer + \brief A paint buffer based on OpenGL pixel buffers, using hardware accelerated rendering + + This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot + rendering. It is based on OpenGL pixel buffers (pbuffer) and is used in Qt versions before 5.0. + (See \ref QCPPaintBufferGlFbo used in newer Qt versions.) + + The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are + supported by the system. +*/ + +/*! + Creates a \ref QCPPaintBufferGlPbuffer instance with the specified \a size and \a + devicePixelRatio, if applicable. + + The parameter \a multisamples defines how many samples are used per pixel. Higher values thus + result in higher quality antialiasing. If the specified \a multisamples value exceeds the + capability of the graphics hardware, the highest supported multisampling is used. +*/ +QCPPaintBufferGlPbuffer::QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples) : + QCPAbstractPaintBuffer(size, devicePixelRatio), + mGlPBuffer(0), + mMultisamples(qMax(0, multisamples)) +{ + QCPPaintBufferGlPbuffer::reallocateBuffer(); +} + +QCPPaintBufferGlPbuffer::~QCPPaintBufferGlPbuffer() +{ + if (mGlPBuffer) + delete mGlPBuffer; +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferGlPbuffer::startPainting() +{ + if (!mGlPBuffer->isValid()) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return 0; + } + + QCPPainter *result = new QCPPainter(mGlPBuffer); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::draw(QCPPainter *painter) const +{ + if (!painter || !painter->isActive()) + { + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; + return; + } + if (!mGlPBuffer->isValid()) + { + qDebug() << Q_FUNC_INFO << "OpenGL pbuffer isn't valid, reallocateBuffer was not called?"; + return; + } + painter->drawImage(0, 0, mGlPBuffer->toImage()); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::clear(const QColor &color) +{ + if (mGlPBuffer->isValid()) + { + mGlPBuffer->makeCurrent(); + glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mGlPBuffer->doneCurrent(); + } else + qDebug() << Q_FUNC_INFO << "OpenGL pbuffer invalid or context not current"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::reallocateBuffer() +{ + if (mGlPBuffer) + delete mGlPBuffer; + + QGLFormat format; + format.setAlpha(true); + format.setSamples(mMultisamples); + mGlPBuffer = new QGLPixelBuffer(mSize, format); +} +#endif // QCP_OPENGL_PBUFFER + + +#ifdef QCP_OPENGL_FBO +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferGlFbo +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferGlFbo + \brief A paint buffer based on OpenGL frame buffers objects, using hardware accelerated rendering + + This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot + rendering. It is based on OpenGL frame buffer objects (fbo) and is used in Qt versions 5.0 and + higher. (See \ref QCPPaintBufferGlPbuffer used in older Qt versions.) + + The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are + supported by the system. +*/ + +/*! + Creates a \ref QCPPaintBufferGlFbo instance with the specified \a size and \a devicePixelRatio, + if applicable. + + All frame buffer objects shall share one OpenGL context and paint device, which need to be set up + externally and passed via \a glContext and \a glPaintDevice. The set-up is done in \ref + QCustomPlot::setupOpenGl and the context and paint device are managed by the parent QCustomPlot + instance. +*/ +QCPPaintBufferGlFbo::QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice) : + QCPAbstractPaintBuffer(size, devicePixelRatio), + mGlContext(glContext), + mGlPaintDevice(glPaintDevice), + mGlFrameBuffer(0) +{ + QCPPaintBufferGlFbo::reallocateBuffer(); +} + +QCPPaintBufferGlFbo::~QCPPaintBufferGlFbo() +{ + if (mGlFrameBuffer) + delete mGlFrameBuffer; +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferGlFbo::startPainting() +{ + if (mGlPaintDevice.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; + return 0; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return 0; + } + + if (QOpenGLContext::currentContext() != mGlContext.data()) + mGlContext.data()->makeCurrent(mGlContext.data()->surface()); + mGlFrameBuffer->bind(); + QCPPainter *result = new QCPPainter(mGlPaintDevice.data()); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::donePainting() +{ + if (mGlFrameBuffer && mGlFrameBuffer->isBound()) + mGlFrameBuffer->release(); + else + qDebug() << Q_FUNC_INFO << "Either OpenGL frame buffer not valid or was not bound"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::draw(QCPPainter *painter) const +{ + if (!painter || !painter->isActive()) + { + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; + return; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return; + } + painter->drawImage(0, 0, mGlFrameBuffer->toImage()); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::clear(const QColor &color) +{ + if (mGlContext.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; + return; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return; + } + + if (QOpenGLContext::currentContext() != mGlContext.data()) + mGlContext.data()->makeCurrent(mGlContext.data()->surface()); + mGlFrameBuffer->bind(); + glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mGlFrameBuffer->release(); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::reallocateBuffer() +{ + // release and delete possibly existing framebuffer: + if (mGlFrameBuffer) + { + if (mGlFrameBuffer->isBound()) + mGlFrameBuffer->release(); + delete mGlFrameBuffer; + mGlFrameBuffer = 0; + } + + if (mGlContext.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; + return; + } + if (mGlPaintDevice.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; + return; + } + + // create new fbo with appropriate size: + mGlContext.data()->makeCurrent(mGlContext.data()->surface()); + QOpenGLFramebufferObjectFormat frameBufferFormat; + frameBufferFormat.setSamples(mGlContext.data()->format().samples()); + frameBufferFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + mGlFrameBuffer = new QOpenGLFramebufferObject(mSize*mDevicePixelRatio, frameBufferFormat); + if (mGlPaintDevice.data()->size() != mSize*mDevicePixelRatio) + mGlPaintDevice.data()->setSize(mSize*mDevicePixelRatio); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mGlPaintDevice.data()->setDevicePixelRatio(mDevicePixelRatio); +#endif +} +#endif // QCP_OPENGL_FBO +/* end of 'src/paintbuffer.cpp' */ + + +/* including file 'src/layer.cpp', size 37064 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayer + \brief A layer that may contain objects, to control the rendering order + + The Layering system of QCustomPlot is the mechanism to control the rendering order of the + elements inside the plot. + + It is based on the two classes QCPLayer and QCPLayerable. QCustomPlot holds an ordered list of + one or more instances of QCPLayer (see QCustomPlot::addLayer, QCustomPlot::layer, + QCustomPlot::moveLayer, etc.). When replotting, QCustomPlot goes through the list of layers + bottom to top and successively draws the layerables of the layers into the paint buffer(s). + + A QCPLayer contains an ordered list of QCPLayerable instances. QCPLayerable is an abstract base + class from which almost all visible objects derive, like axes, grids, graphs, items, etc. + + \section qcplayer-defaultlayers Default layers + + Initially, QCustomPlot has six layers: "background", "grid", "main", "axes", "legend" and + "overlay" (in that order). On top is the "overlay" layer, which only contains the QCustomPlot's + selection rect (\ref QCustomPlot::selectionRect). The next two layers "axes" and "legend" contain + the default axes and legend, so they will be drawn above plottables. In the middle, there is the + "main" layer. It is initially empty and set as the current layer (see + QCustomPlot::setCurrentLayer). This means, all new plottables, items etc. are created on this + layer by default. Then comes the "grid" layer which contains the QCPGrid instances (which belong + tightly to QCPAxis, see \ref QCPAxis::grid). The Axis rect background shall be drawn behind + everything else, thus the default QCPAxisRect instance is placed on the "background" layer. Of + course, the layer affiliation of the individual objects can be changed as required (\ref + QCPLayerable::setLayer). + + \section qcplayer-ordering Controlling the rendering order via layers + + Controlling the ordering of layerables in the plot is easy: Create a new layer in the position + you want the layerable to be in, e.g. above "main", with \ref QCustomPlot::addLayer. Then set the + current layer with \ref QCustomPlot::setCurrentLayer to that new layer and finally create the + objects normally. They will be placed on the new layer automatically, due to the current layer + setting. Alternatively you could have also ignored the current layer setting and just moved the + objects with \ref QCPLayerable::setLayer to the desired layer after creating them. + + It is also possible to move whole layers. For example, If you want the grid to be shown in front + of all plottables/items on the "main" layer, just move it above "main" with + QCustomPlot::moveLayer. + + The rendering order within one layer is simply by order of creation or insertion. The item + created last (or added last to the layer), is drawn on top of all other objects on that layer. + + When a layer is deleted, the objects on it are not deleted with it, but fall on the layer below + the deleted layer, see QCustomPlot::removeLayer. + + \section qcplayer-buffering Replotting only a specific layer + + If the layer mode (\ref setMode) is set to \ref lmBuffered, you can replot only this specific + layer by calling \ref replot. In certain situations this can provide better replot performance, + compared with a full replot of all layers. Upon creation of a new layer, the layer mode is + initialized to \ref lmLogical. The only layer that is set to \ref lmBuffered in a new \ref + QCustomPlot instance is the "overlay" layer, containing the selection rect. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPLayer::children() const + + Returns a list of all layerables on this layer. The order corresponds to the rendering order: + layerables with higher indices are drawn above layerables with lower indices. +*/ + +/*! \fn int QCPLayer::index() const + + Returns the index this layer has in the QCustomPlot. The index is the integer number by which this layer can be + accessed via \ref QCustomPlot::layer. + + Layers with higher indices will be drawn above layers with lower indices. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPLayer instance. + + Normally you shouldn't directly instantiate layers, use \ref QCustomPlot::addLayer instead. + + \warning It is not checked that \a layerName is actually a unique layer name in \a parentPlot. + This check is only performed by \ref QCustomPlot::addLayer. +*/ +QCPLayer::QCPLayer(QCustomPlot *parentPlot, const QString &layerName) : + QObject(parentPlot), + mParentPlot(parentPlot), + mName(layerName), + mIndex(-1), // will be set to a proper value by the QCustomPlot layer creation function + mVisible(true), + mMode(lmLogical) +{ + // Note: no need to make sure layerName is unique, because layer + // management is done with QCustomPlot functions. +} + +QCPLayer::~QCPLayer() +{ + // If child layerables are still on this layer, detach them, so they don't try to reach back to this + // then invalid layer once they get deleted/moved themselves. This only happens when layers are deleted + // directly, like in the QCustomPlot destructor. (The regular layer removal procedure for the user is to + // call QCustomPlot::removeLayer, which moves all layerables off this layer before deleting it.) + + while (!mChildren.isEmpty()) + mChildren.last()->setLayer(0); // removes itself from mChildren via removeChild() + + if (mParentPlot->currentLayer() == this) + qDebug() << Q_FUNC_INFO << "The parent plot's mCurrentLayer will be a dangling pointer. Should have been set to a valid layer or 0 beforehand."; +} + +/*! + Sets whether this layer is visible or not. If \a visible is set to false, all layerables on this + layer will be invisible. + + This function doesn't change the visibility property of the layerables (\ref + QCPLayerable::setVisible), but the \ref QCPLayerable::realVisibility of each layerable takes the + visibility of the parent layer into account. +*/ +void QCPLayer::setVisible(bool visible) +{ + mVisible = visible; +} + +/*! + Sets the rendering mode of this layer. + + If \a mode is set to \ref lmBuffered for a layer, it will be given a dedicated paint buffer by + the parent QCustomPlot instance. This means it may be replotted individually by calling \ref + QCPLayer::replot, without needing to replot all other layers. + + Layers which are set to \ref lmLogical (the default) are used only to define the rendering order + and can't be replotted individually. + + Note that each layer which is set to \ref lmBuffered requires additional paint buffers for the + layers below, above and for the layer itself. This increases the memory consumption and + (slightly) decreases the repainting speed because multiple paint buffers need to be joined. So + you should carefully choose which layers benefit from having their own paint buffer. A typical + example would be a layer which contains certain layerables (e.g. items) that need to be changed + and thus replotted regularly, while all other layerables on other layers stay static. By default, + only the topmost layer called "overlay" is in mode \ref lmBuffered, and contains the selection + rect. + + \see replot +*/ +void QCPLayer::setMode(QCPLayer::LayerMode mode) +{ + if (mMode != mode) + { + mMode = mode; + if (!mPaintBuffer.isNull()) + mPaintBuffer.data()->setInvalidated(); + } +} + +/*! \internal + + Draws the contents of this layer with the provided \a painter. + + \see replot, drawToPaintBuffer +*/ +void QCPLayer::draw(QCPPainter *painter) +{ + foreach (QCPLayerable *child, mChildren) + { + if (child->realVisibility()) + { + painter->save(); + painter->setClipRect(child->clipRect().translated(0, -1)); + child->applyDefaultAntialiasingHint(painter); + child->draw(painter); + painter->restore(); + } + } +} + +/*! \internal + + Draws the contents of this layer into the paint buffer which is associated with this layer. The + association is established by the parent QCustomPlot, which manages all paint buffers (see \ref + QCustomPlot::setupPaintBuffers). + + \see draw +*/ +void QCPLayer::drawToPaintBuffer() +{ + if (!mPaintBuffer.isNull()) + { + if (QCPPainter *painter = mPaintBuffer.data()->startPainting()) + { + if (painter->isActive()) + draw(painter); + else + qDebug() << Q_FUNC_INFO << "paint buffer returned inactive painter"; + delete painter; + mPaintBuffer.data()->donePainting(); + } else + qDebug() << Q_FUNC_INFO << "paint buffer returned zero painter"; + } else + qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; +} + +/*! + If the layer mode (\ref setMode) is set to \ref lmBuffered, this method allows replotting only + the layerables on this specific layer, without the need to replot all other layers (as a call to + \ref QCustomPlot::replot would do). + + If the layer mode is \ref lmLogical however, this method simply calls \ref QCustomPlot::replot on + the parent QCustomPlot instance. + + QCustomPlot also makes sure to replot all layers instead of only this one, if the layer ordering + has changed since the last full replot and the other paint buffers were thus invalidated. + + \see draw +*/ +void QCPLayer::replot() +{ + if (mMode == lmBuffered && !mParentPlot->hasInvalidatedPaintBuffers()) + { + if (!mPaintBuffer.isNull()) + { + mPaintBuffer.data()->clear(Qt::transparent); + drawToPaintBuffer(); + mPaintBuffer.data()->setInvalidated(false); + mParentPlot->update(); + } else + qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; + } else if (mMode == lmLogical) + mParentPlot->replot(); +} + +/*! \internal + + Adds the \a layerable to the list of this layer. If \a prepend is set to true, the layerable will + be prepended to the list, i.e. be drawn beneath the other layerables already in the list. + + This function does not change the \a mLayer member of \a layerable to this layer. (Use + QCPLayerable::setLayer to change the layer of an object, not this function.) + + \see removeChild +*/ +void QCPLayer::addChild(QCPLayerable *layerable, bool prepend) +{ + if (!mChildren.contains(layerable)) + { + if (prepend) + mChildren.prepend(layerable); + else + mChildren.append(layerable); + if (!mPaintBuffer.isNull()) + mPaintBuffer.data()->setInvalidated(); + } else + qDebug() << Q_FUNC_INFO << "layerable is already child of this layer" << reinterpret_cast(layerable); +} + +/*! \internal + + Removes the \a layerable from the list of this layer. + + This function does not change the \a mLayer member of \a layerable. (Use QCPLayerable::setLayer + to change the layer of an object, not this function.) + + \see addChild +*/ +void QCPLayer::removeChild(QCPLayerable *layerable) +{ + if (mChildren.removeOne(layerable)) + { + if (!mPaintBuffer.isNull()) + mPaintBuffer.data()->setInvalidated(); + } else + qDebug() << Q_FUNC_INFO << "layerable is not child of this layer" << reinterpret_cast(layerable); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayerable +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayerable + \brief Base class for all drawable objects + + This is the abstract base class most visible objects derive from, e.g. plottables, axes, grid + etc. + + Every layerable is on a layer (QCPLayer) which allows controlling the rendering order by stacking + the layers accordingly. + + For details about the layering mechanism, see the QCPLayer documentation. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayerable *QCPLayerable::parentLayerable() const + + Returns the parent layerable of this layerable. The parent layerable is used to provide + visibility hierarchies in conjunction with the method \ref realVisibility. This way, layerables + only get drawn if their parent layerables are visible, too. + + Note that a parent layerable is not necessarily also the QObject parent for memory management. + Further, a layerable doesn't always have a parent layerable, so this function may return 0. + + A parent layerable is set implicitly when placed inside layout elements and doesn't need to be + set manually by the user. +*/ + +/* end documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn virtual void QCPLayerable::applyDefaultAntialiasingHint(QCPPainter *painter) const = 0 + \internal + + This function applies the default antialiasing setting to the specified \a painter, using the + function \ref applyAntialiasingHint. It is the antialiasing state the painter is put in, when + \ref draw is called on the layerable. If the layerable has multiple entities whose antialiasing + setting may be specified individually, this function should set the antialiasing state of the + most prominent entity. In this case however, the \ref draw function usually calls the specialized + versions of this function before drawing each entity, effectively overriding the setting of the + default antialiasing hint. + + First example: QCPGraph has multiple entities that have an antialiasing setting: The graph + line, fills and scatters. Those can be configured via QCPGraph::setAntialiased, + QCPGraph::setAntialiasedFill and QCPGraph::setAntialiasedScatters. Consequently, there isn't only + the QCPGraph::applyDefaultAntialiasingHint function (which corresponds to the graph line's + antialiasing), but specialized ones like QCPGraph::applyFillAntialiasingHint and + QCPGraph::applyScattersAntialiasingHint. So before drawing one of those entities, QCPGraph::draw + calls the respective specialized applyAntialiasingHint function. + + Second example: QCPItemLine consists only of a line so there is only one antialiasing + setting which can be controlled with QCPItemLine::setAntialiased. (This function is inherited by + all layerables. The specialized functions, as seen on QCPGraph, must be added explicitly to the + respective layerable subclass.) Consequently it only has the normal + QCPItemLine::applyDefaultAntialiasingHint. The \ref QCPItemLine::draw function doesn't need to + care about setting any antialiasing states, because the default antialiasing hint is already set + on the painter when the \ref draw function is called, and that's the state it wants to draw the + line with. +*/ + +/*! \fn virtual void QCPLayerable::draw(QCPPainter *painter) const = 0 + \internal + + This function draws the layerable with the specified \a painter. It is only called by + QCustomPlot, if the layerable is visible (\ref setVisible). + + Before this function is called, the painter's antialiasing state is set via \ref + applyDefaultAntialiasingHint, see the documentation there. Further, the clipping rectangle was + set to \ref clipRect. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPLayerable::layerChanged(QCPLayer *newLayer); + + This signal is emitted when the layer of this layerable changes, i.e. this layerable is moved to + a different layer. + + \see setLayer +*/ + +/* end documentation of signals */ + +/*! + Creates a new QCPLayerable instance. + + Since QCPLayerable is an abstract base class, it can't be instantiated directly. Use one of the + derived classes. + + If \a plot is provided, it automatically places itself on the layer named \a targetLayer. If \a + targetLayer is an empty string, it places itself on the current layer of the plot (see \ref + QCustomPlot::setCurrentLayer). + + It is possible to provide 0 as \a plot. In that case, you should assign a parent plot at a later + time with \ref initializeParentPlot. + + The layerable's parent layerable is set to \a parentLayerable, if provided. Direct layerable + parents are mainly used to control visibility in a hierarchy of layerables. This means a + layerable is only drawn, if all its ancestor layerables are also visible. Note that \a + parentLayerable does not become the QObject-parent (for memory management) of this layerable, \a + plot does. It is not uncommon to set the QObject-parent to something else in the constructors of + QCPLayerable subclasses, to guarantee a working destruction hierarchy. +*/ +QCPLayerable::QCPLayerable(QCustomPlot *plot, QString targetLayer, QCPLayerable *parentLayerable) : + QObject(plot), + mVisible(true), + mParentPlot(plot), + mParentLayerable(parentLayerable), + mLayer(0), + mAntialiased(true) +{ + if (mParentPlot) + { + if (targetLayer.isEmpty()) + setLayer(mParentPlot->currentLayer()); + else if (!setLayer(targetLayer)) + qDebug() << Q_FUNC_INFO << "setting QCPlayerable initial layer to" << targetLayer << "failed."; + } +} + +QCPLayerable::~QCPLayerable() +{ + if (mLayer) + { + mLayer->removeChild(this); + mLayer = 0; + } +} + +/*! + Sets the visibility of this layerable object. If an object is not visible, it will not be drawn + on the QCustomPlot surface, and user interaction with it (e.g. click and selection) is not + possible. +*/ +void QCPLayerable::setVisible(bool on) +{ + mVisible = on; +} + +/*! + Sets the \a layer of this layerable object. The object will be placed on top of the other objects + already on \a layer. + + If \a layer is 0, this layerable will not be on any layer and thus not appear in the plot (or + interact/receive events). + + Returns true if the layer of this layerable was successfully changed to \a layer. +*/ +bool QCPLayerable::setLayer(QCPLayer *layer) +{ + return moveToLayer(layer, false); +} + +/*! \overload + Sets the layer of this layerable object by name + + Returns true on success, i.e. if \a layerName is a valid layer name. +*/ +bool QCPLayerable::setLayer(const QString &layerName) +{ + if (!mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (QCPLayer *layer = mParentPlot->layer(layerName)) + { + return setLayer(layer); + } else + { + qDebug() << Q_FUNC_INFO << "there is no layer with name" << layerName; + return false; + } +} + +/*! + Sets whether this object will be drawn antialiased or not. + + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPLayerable::setAntialiased(bool enabled) +{ + mAntialiased = enabled; +} + +/*! + Returns whether this layerable is visible, taking the visibility of the layerable parent and the + visibility of this layerable's layer into account. This is the method that is consulted to decide + whether a layerable shall be drawn or not. + + If this layerable has a direct layerable parent (usually set via hierarchies implemented in + subclasses, like in the case of \ref QCPLayoutElement), this function returns true only if this + layerable has its visibility set to true and the parent layerable's \ref realVisibility returns + true. +*/ +bool QCPLayerable::realVisibility() const +{ + return mVisible && (!mLayer || mLayer->visible()) && (!mParentLayerable || mParentLayerable.data()->realVisibility()); +} + +/*! + This function is used to decide whether a click hits a layerable object or not. + + \a pos is a point in pixel coordinates on the QCustomPlot surface. This function returns the + shortest pixel distance of this point to the object. If the object is either invisible or the + distance couldn't be determined, -1.0 is returned. Further, if \a onlySelectable is true and the + object is not selectable, -1.0 is returned, too. + + If the object is represented not by single lines but by an area like a \ref QCPItemText or the + bars of a \ref QCPBars plottable, a click inside the area should also be considered a hit. In + these cases this function thus returns a constant value greater zero but still below the parent + plot's selection tolerance. (typically the selectionTolerance multiplied by 0.99). + + Providing a constant value for area objects allows selecting line objects even when they are + obscured by such area objects, by clicking close to the lines (i.e. closer than + 0.99*selectionTolerance). + + The actual setting of the selection state is not done by this function. This is handled by the + parent QCustomPlot when the mouseReleaseEvent occurs, and the finally selected object is notified + via the \ref selectEvent/\ref deselectEvent methods. + + \a details is an optional output parameter. Every layerable subclass may place any information + in \a details. This information will be passed to \ref selectEvent when the parent QCustomPlot + decides on the basis of this selectTest call, that the object was successfully selected. The + subsequent call to \ref selectEvent will carry the \a details. This is useful for multi-part + objects (like QCPAxis). This way, a possibly complex calculation to decide which part was clicked + is only done once in \ref selectTest. The result (i.e. the actually clicked part) can then be + placed in \a details. So in the subsequent \ref selectEvent, the decision which part was + selected doesn't have to be done a second time for a single selection operation. + + You may pass 0 as \a details to indicate that you are not interested in those selection details. + + \see selectEvent, deselectEvent, mousePressEvent, wheelEvent, QCustomPlot::setInteractions +*/ +double QCPLayerable::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(pos) + Q_UNUSED(onlySelectable) + Q_UNUSED(details) + return -1.0; +} + +/*! \internal + + Sets the parent plot of this layerable. Use this function once to set the parent plot if you have + passed 0 in the constructor. It can not be used to move a layerable from one QCustomPlot to + another one. + + Note that, unlike when passing a non-null parent plot in the constructor, this function does not + make \a parentPlot the QObject-parent of this layerable. If you want this, call + QObject::setParent(\a parentPlot) in addition to this function. + + Further, you will probably want to set a layer (\ref setLayer) after calling this function, to + make the layerable appear on the QCustomPlot. + + The parent plot change will be propagated to subclasses via a call to \ref parentPlotInitialized + so they can react accordingly (e.g. also initialize the parent plot of child layerables, like + QCPLayout does). +*/ +void QCPLayerable::initializeParentPlot(QCustomPlot *parentPlot) +{ + if (mParentPlot) + { + qDebug() << Q_FUNC_INFO << "called with mParentPlot already initialized"; + return; + } + + if (!parentPlot) + qDebug() << Q_FUNC_INFO << "called with parentPlot zero"; + + mParentPlot = parentPlot; + parentPlotInitialized(mParentPlot); +} + +/*! \internal + + Sets the parent layerable of this layerable to \a parentLayerable. Note that \a parentLayerable does not + become the QObject-parent (for memory management) of this layerable. + + The parent layerable has influence on the return value of the \ref realVisibility method. Only + layerables with a fully visible parent tree will return true for \ref realVisibility, and thus be + drawn. + + \see realVisibility +*/ +void QCPLayerable::setParentLayerable(QCPLayerable *parentLayerable) +{ + mParentLayerable = parentLayerable; +} + +/*! \internal + + Moves this layerable object to \a layer. If \a prepend is true, this object will be prepended to + the new layer's list, i.e. it will be drawn below the objects already on the layer. If it is + false, the object will be appended. + + Returns true on success, i.e. if \a layer is a valid layer. +*/ +bool QCPLayerable::moveToLayer(QCPLayer *layer, bool prepend) +{ + if (layer && !mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (layer && layer->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "layer" << layer->name() << "is not in same QCustomPlot as this layerable"; + return false; + } + + QCPLayer *oldLayer = mLayer; + if (mLayer) + mLayer->removeChild(this); + mLayer = layer; + if (mLayer) + mLayer->addChild(this, prepend); + if (mLayer != oldLayer) + emit layerChanged(mLayer); + return true; +} + +/*! \internal + + Sets the QCPainter::setAntialiasing state on the provided \a painter, depending on the \a + localAntialiased value as well as the overrides \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. Which override enum this function takes into account is + controlled via \a overrideElement. +*/ +void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const +{ + if (mParentPlot && mParentPlot->notAntialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(false); + else if (mParentPlot && mParentPlot->antialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(true); + else + painter->setAntialiasing(localAntialiased); +} + +/*! \internal + + This function is called by \ref initializeParentPlot, to allow subclasses to react on the setting + of a parent plot. This is the case when 0 was passed as parent plot in the constructor, and the + parent plot is set at a later time. + + For example, QCPLayoutElement/QCPLayout hierarchies may be created independently of any + QCustomPlot at first. When they are then added to a layout inside the QCustomPlot, the top level + element of the hierarchy gets its parent plot initialized with \ref initializeParentPlot. To + propagate the parent plot to all the children of the hierarchy, the top level element then uses + this function to pass the parent plot on to its child elements. + + The default implementation does nothing. + + \see initializeParentPlot +*/ +void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot) +{ + Q_UNUSED(parentPlot) +} + +/*! \internal + + Returns the selection category this layerable shall belong to. The selection category is used in + conjunction with \ref QCustomPlot::setInteractions to control which objects are selectable and + which aren't. + + Subclasses that don't fit any of the normal \ref QCP::Interaction values can use \ref + QCP::iSelectOther. This is what the default implementation returns. + + \see QCustomPlot::setInteractions +*/ +QCP::Interaction QCPLayerable::selectionCategory() const +{ + return QCP::iSelectOther; +} + +/*! \internal + + Returns the clipping rectangle of this layerable object. By default, this is the viewport of the + parent QCustomPlot. Specific subclasses may reimplement this function to provide different + clipping rects. + + The returned clipping rect is set on the painter before the draw function of the respective + object is called. +*/ +QRect QCPLayerable::clipRect() const +{ + if (mParentPlot) + return mParentPlot->viewport(); + else + return QRect(); +} + +/*! \internal + + This event is called when the layerable shall be selected, as a consequence of a click by the + user. Subclasses should react to it by setting their selection state appropriately. The default + implementation does nothing. + + \a event is the mouse event that caused the selection. \a additive indicates, whether the user + was holding the multi-select-modifier while performing the selection (see \ref + QCustomPlot::setMultiSelectModifier). if \a additive is true, the selection state must be toggled + (i.e. become selected when unselected and unselected when selected). + + Every selectEvent is preceded by a call to \ref selectTest, which has returned positively (i.e. + returned a value greater than 0 and less than the selection tolerance of the parent QCustomPlot). + The \a details data you output from \ref selectTest is fed back via \a details here. You may + use it to transport any kind of information from the selectTest to the possibly subsequent + selectEvent. Usually \a details is used to transfer which part was clicked, if it is a layerable + that has multiple individually selectable parts (like QCPAxis). This way selectEvent doesn't need + to do the calculation again to find out which part was actually clicked. + + \a selectionStateChanged is an output parameter. If the pointer is non-null, this function must + set the value either to true or false, depending on whether the selection state of this layerable + was actually changed. For layerables that only are selectable as a whole and not in parts, this + is simple: if \a additive is true, \a selectionStateChanged must also be set to true, because the + selection toggles. If \a additive is false, \a selectionStateChanged is only set to true, if the + layerable was previously unselected and now is switched to the selected state. + + \see selectTest, deselectEvent +*/ +void QCPLayerable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(additive) + Q_UNUSED(details) + Q_UNUSED(selectionStateChanged) +} + +/*! \internal + + This event is called when the layerable shall be deselected, either as consequence of a user + interaction or a call to \ref QCustomPlot::deselectAll. Subclasses should react to it by + unsetting their selection appropriately. + + just as in \ref selectEvent, the output parameter \a selectionStateChanged (if non-null), must + return true or false when the selection state of this layerable has changed or not changed, + respectively. + + \see selectTest, selectEvent +*/ +void QCPLayerable::deselectEvent(bool *selectionStateChanged) +{ + Q_UNUSED(selectionStateChanged) +} + +/*! + This event gets called when the user presses a mouse button while the cursor is over the + layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref + selectTest. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a details contains layerable-specific details about the hit, which + were generated in the previous call to \ref selectTest. For example, One-dimensional plottables + like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as + \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c + SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). + + QCustomPlot uses an event propagation system that works the same as Qt's system. If your + layerable doesn't reimplement the \ref mousePressEvent or explicitly calls \c event->ignore() in + its reimplementation, the event will be propagated to the next layerable in the stacking order. + + Once a layerable has accepted the \ref mousePressEvent, it is considered the mouse grabber and + will receive all following calls to \ref mouseMoveEvent or \ref mouseReleaseEvent for this mouse + interaction (a "mouse interaction" in this context ends with the release). + + The default implementation does nothing except explicitly ignoring the event with \c + event->ignore(). + + \see mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->ignore(); +} + +/*! + This event gets called when the user moves the mouse while holding a mouse button, after this + layerable has become the mouse grabber by accepting the preceding \ref mousePressEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a startPos indicates the position where the initial \ref + mousePressEvent occured, that started the mouse interaction. + + The default implementation does nothing. + + \see mousePressEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + event->ignore(); +} + +/*! + This event gets called when the user releases the mouse button, after this layerable has become + the mouse grabber by accepting the preceding \ref mousePressEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a startPos indicates the position where the initial \ref + mousePressEvent occured, that started the mouse interaction. + + The default implementation does nothing. + + \see mousePressEvent, mouseMoveEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + event->ignore(); +} + +/*! + This event gets called when the user presses the mouse button a second time in a double-click, + while the cursor is over the layerable. Whether a cursor is over the layerable is decided by a + preceding call to \ref selectTest. + + The \ref mouseDoubleClickEvent is called instead of the second \ref mousePressEvent. So in the + case of a double-click, the event succession is + pressEvent – releaseEvent – doubleClickEvent – releaseEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a details contains layerable-specific details about the hit, which + were generated in the previous call to \ref selectTest. For example, One-dimensional plottables + like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as + \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c + SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). + + Similarly to \ref mousePressEvent, once a layerable has accepted the \ref mouseDoubleClickEvent, + it is considered the mouse grabber and will receive all following calls to \ref mouseMoveEvent + and \ref mouseReleaseEvent for this mouse interaction (a "mouse interaction" in this context ends + with the release). + + The default implementation does nothing except explicitly ignoring the event with \c + event->ignore(). + + \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, wheelEvent +*/ +void QCPLayerable::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->ignore(); +} + +/*! + This event gets called when the user turns the mouse scroll wheel while the cursor is over the + layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref + selectTest. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). + + The \c event->delta() indicates how far the mouse wheel was turned, which is usually +/- 120 for + single rotation steps. However, if the mouse wheel is turned rapidly, multiple steps may + accumulate to one event, making \c event->delta() larger. On the other hand, if the wheel has + very smooth steps or none at all, the delta may be smaller. + + The default implementation does nothing. + + \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent +*/ +void QCPLayerable::wheelEvent(QWheelEvent *event) +{ + event->ignore(); +} +/* end of 'src/layer.cpp' */ + + +/* including file 'src/axis/range.cpp', size 12221 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPRange +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPRange + \brief Represents the range an axis is encompassing. + + contains a \a lower and \a upper double value and provides convenience input, output and + modification functions. + + \see QCPAxis::setRange +*/ + +/* start of documentation of inline functions */ + +/*! \fn double QCPRange::size() const + + Returns the size of the range, i.e. \a upper-\a lower +*/ + +/*! \fn double QCPRange::center() const + + Returns the center of the range, i.e. (\a upper+\a lower)*0.5 +*/ + +/*! \fn void QCPRange::normalize() + + Makes sure \a lower is numerically smaller than \a upper. If this is not the case, the values are + swapped. +*/ + +/*! \fn bool QCPRange::contains(double value) const + + Returns true when \a value lies within or exactly on the borders of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator+=(const double& value) + + Adds \a value to both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator-=(const double& value) + + Subtracts \a value from both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator*=(const double& value) + + Multiplies both boundaries of the range by \a value. +*/ + +/*! \fn QCPRange &QCPRange::operator/=(const double& value) + + Divides both boundaries of the range by \a value. +*/ + +/* end of documentation of inline functions */ + +/*! + Minimum range size (\a upper - \a lower) the range changing functions will accept. Smaller + intervals would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a minimum magnitude of roughly 1e-308. + + \warning Do not use this constant to indicate "arbitrarily small" values in plotting logic (as + values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to + prevent axis ranges from obtaining underflowing ranges. + + \see validRange, maxRange +*/ +const double QCPRange::minRange = 1e-280; +//const double QCPRange::minRange = QCPAxisTickerDateTime::dateTimeToKey(QDate(1970, 0, 0)); + +/*! + Maximum values (negative and positive) the range will accept in range-changing functions. + Larger absolute values would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a maximum magnitude of roughly 1e308. + + \warning Do not use this constant to indicate "arbitrarily large" values in plotting logic (as + values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to + prevent axis ranges from obtaining overflowing ranges. + + \see validRange, minRange +*/ +const double QCPRange::maxRange = 1e250; +//const double QCPRange::maxRange = QCPAxisTickerDateTime::dateTimeToKey(QDate(2037, 12, 31)); + +/*! + Constructs a range with \a lower and \a upper set to zero. +*/ +QCPRange::QCPRange() : + lower(0), + upper(0) +{ +} + +/*! \overload + + Constructs a range with the specified \a lower and \a upper values. + + The resulting range will be normalized (see \ref normalize), so if \a lower is not numerically + smaller than \a upper, they will be swapped. +*/ +QCPRange::QCPRange(double lower, double upper) : + lower(lower), + upper(upper) +{ + normalize(); +} + +/*! \overload + + Expands this range such that \a otherRange is contained in the new range. It is assumed that both + this range and \a otherRange are normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, it will be replaced by the respective bound + of \a otherRange. + + If \a otherRange is already inside the current range, this function does nothing. + + \see expanded +*/ +void QCPRange::expand(const QCPRange &otherRange) +{ + if (lower > otherRange.lower || qIsNaN(lower)) + lower = otherRange.lower; + if (upper < otherRange.upper || qIsNaN(upper)) + upper = otherRange.upper; +} + +/*! \overload + + Expands this range such that \a includeCoord is contained in the new range. It is assumed that + this range is normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the respective bound will be set to \a + includeCoord. + + If \a includeCoord is already inside the current range, this function does nothing. + + \see expand +*/ +void QCPRange::expand(double includeCoord) +{ + if (lower > includeCoord || qIsNaN(lower)) + lower = includeCoord; + if (upper < includeCoord || qIsNaN(upper)) + upper = includeCoord; +} + + +/*! \overload + + Returns an expanded range that contains this and \a otherRange. It is assumed that both this + range and \a otherRange are normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the returned range's bound will be taken from + \a otherRange. + + \see expand +*/ +QCPRange QCPRange::expanded(const QCPRange &otherRange) const +{ + QCPRange result = *this; + result.expand(otherRange); + return result; +} + +/*! \overload + + Returns an expanded range that includes the specified \a includeCoord. It is assumed that this + range is normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the returned range's bound will be set to \a + includeCoord. + + \see expand +*/ +QCPRange QCPRange::expanded(double includeCoord) const +{ + QCPRange result = *this; + result.expand(includeCoord); + return result; +} + +/*! + Returns this range, possibly modified to not exceed the bounds provided as \a lowerBound and \a + upperBound. If possible, the size of the current range is preserved in the process. + + If the range shall only be bounded at the lower side, you can set \a upperBound to \ref + QCPRange::maxRange. If it shall only be bounded at the upper side, set \a lowerBound to -\ref + QCPRange::maxRange. +*/ +QCPRange QCPRange::bounded(double lowerBound, double upperBound) const +{ + if (lowerBound > upperBound) + qSwap(lowerBound, upperBound); + + QCPRange result(lower, upper); + if (result.lower < lowerBound) + { + result.lower = lowerBound; + result.upper = lowerBound + size(); + if (result.upper > upperBound || qFuzzyCompare(size(), upperBound-lowerBound)) + result.upper = upperBound; + } else if (result.upper > upperBound) + { + result.upper = upperBound; + result.lower = upperBound - size(); + if (result.lower < lowerBound || qFuzzyCompare(size(), upperBound-lowerBound)) + result.lower = lowerBound; + } + + return result; +} + +/*! + Returns a sanitized version of the range. Sanitized means for logarithmic scales, that + the range won't span the positive and negative sign domain, i.e. contain zero. Further + \a lower will always be numerically smaller (or equal) to \a upper. + + If the original range does span positive and negative sign domains or contains zero, + the returned range will try to approximate the original range as good as possible. + If the positive interval of the original range is wider than the negative interval, the + returned range will only contain the positive interval, with lower bound set to \a rangeFac or + \a rangeFac *\a upper, whichever is closer to zero. Same procedure is used if the negative interval + is wider than the positive interval, this time by changing the \a upper bound. +*/ +QCPRange QCPRange::sanitizedForLogScale() const +{ + double rangeFac = 1e-3; + QCPRange sanitizedRange(lower, upper); + sanitizedRange.normalize(); + // can't have range spanning negative and positive values in log plot, so change range to fix it + //if (qFuzzyCompare(sanitizedRange.lower+1, 1) && !qFuzzyCompare(sanitizedRange.upper+1, 1)) + if (sanitizedRange.lower == 0.0 && sanitizedRange.upper != 0.0) + { + // case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } //else if (!qFuzzyCompare(lower+1, 1) && qFuzzyCompare(upper+1, 1)) + else if (sanitizedRange.lower != 0.0 && sanitizedRange.upper == 0.0) + { + // case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else if (sanitizedRange.lower < 0 && sanitizedRange.upper > 0) + { + // find out whether negative or positive interval is wider to decide which sign domain will be chosen + if (-sanitizedRange.lower > sanitizedRange.upper) + { + // negative is wider, do same as in case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else + { + // positive is wider, do same as in case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } + } + // due to normalization, case lower>0 && upper<0 should never occur, because that implies upper -maxRange && + upper < maxRange && + qAbs(lower-upper) >= 1 && + qAbs(lower-upper) < 2 * maxRange); + +// return (lower > -maxRange && +// upper < maxRange && +// qAbs(lower-upper) > minRange && +// qAbs(lower-upper) < maxRange && +// !(lower > 0 && qIsInf(upper/lower)) && +// !(upper < 0 && qIsInf(lower/upper))); +} + +/*! + \overload + Checks, whether the specified range is within valid bounds, which are defined + as QCPRange::maxRange and QCPRange::minRange. + A valid range means: + \li range bounds within -maxRange and maxRange + \li range size above minRange + \li range size below maxRange +*/ +bool QCPRange::validRange(const QCPRange &range) +{ + return validRange(range.lower, range.upper); +// return (range.lower > -maxRange && +// range.upper < maxRange && +// qAbs(range.lower-range.upper) > minRange && +// qAbs(range.lower-range.upper) < maxRange && +// !(range.lower > 0 && qIsInf(range.upper/range.lower)) && +// !(range.upper < 0 && qIsInf(range.lower/range.upper))); +} +/* end of 'src/axis/range.cpp' */ + + +/* including file 'src/selection.cpp', size 21906 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataRange +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataRange + \brief Describes a data range given by begin and end index + + QCPDataRange holds two integers describing the begin (\ref setBegin) and end (\ref setEnd) index + of a contiguous set of data points. The end index points to the data point above the last data point that's part of + the data range, similarly to the nomenclature used in standard iterators. + + Data Ranges are not bound to a certain plottable, thus they can be freely exchanged, created and + modified. If a non-contiguous data set shall be described, the class \ref QCPDataSelection is + used, which holds and manages multiple instances of \ref QCPDataRange. In most situations, \ref + QCPDataSelection is thus used. + + Both \ref QCPDataRange and \ref QCPDataSelection offer convenience methods to work with them, + e.g. \ref bounded, \ref expanded, \ref intersects, \ref intersection, \ref adjusted, \ref + contains. Further, addition and subtraction operators (defined in \ref QCPDataSelection) can be + used to join/subtract data ranges and data selections (or mixtures), to retrieve a corresponding + \ref QCPDataSelection. + + %QCustomPlot's \ref dataselection "data selection mechanism" is based on \ref QCPDataSelection and + QCPDataRange. + + \note Do not confuse \ref QCPDataRange with \ref QCPRange. A \ref QCPRange describes an interval + in floating point plot coordinates, e.g. the current axis range. +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataRange::size() const + + Returns the number of data points described by this data range. This is equal to the end index + minus the begin index. + + \see length +*/ + +/*! \fn int QCPDataRange::length() const + + Returns the number of data points described by this data range. Equivalent to \ref size. +*/ + +/*! \fn void QCPDataRange::setBegin(int begin) + + Sets the begin of this data range. The \a begin index points to the first data point that is part + of the data range. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). + + \see setEnd +*/ + +/*! \fn void QCPDataRange::setEnd(int end) + + Sets the end of this data range. The \a end index points to the data point just above the last + data point that is part of the data range. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). + + \see setBegin +*/ + +/*! \fn bool QCPDataRange::isValid() const + + Returns whether this range is valid. A valid range has a begin index greater or equal to 0, and + an end index greater or equal to the begin index. + + \note Invalid ranges should be avoided and are never the result of any of QCustomPlot's methods + (unless they are themselves fed with invalid ranges). Do not pass invalid ranges to QCustomPlot's + methods. The invalid range is not inherently prevented in QCPDataRange, to allow temporary + invalid begin/end values while manipulating the range. An invalid range is not necessarily empty + (\ref isEmpty), since its \ref length can be negative and thus non-zero. +*/ + +/*! \fn bool QCPDataRange::isEmpty() const + + Returns whether this range is empty, i.e. whether its begin index equals its end index. + + \see size, length +*/ + +/*! \fn QCPDataRange QCPDataRange::adjusted(int changeBegin, int changeEnd) const + + Returns a data range where \a changeBegin and \a changeEnd were added to the begin and end + indices, respectively. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an empty QCPDataRange, with begin and end set to 0. +*/ +QCPDataRange::QCPDataRange() : + mBegin(0), + mEnd(0) +{ +} + +/*! + Creates a QCPDataRange, initialized with the specified \a begin and \a end. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). +*/ +QCPDataRange::QCPDataRange(int begin, int end) : + mBegin(begin), + mEnd(end) +{ +} + +/*! + Returns a data range that matches this data range, except that parts exceeding \a other are + excluded. + + This method is very similar to \ref intersection, with one distinction: If this range and the \a + other range share no intersection, the returned data range will be empty with begin and end set + to the respective boundary side of \a other, at which this range is residing. (\ref intersection + would just return a range with begin and end set to 0.) +*/ +QCPDataRange QCPDataRange::bounded(const QCPDataRange &other) const +{ + QCPDataRange result(intersection(other)); + if (result.isEmpty()) // no intersection, preserve respective bounding side of otherRange as both begin and end of return value + { + if (mEnd <= other.mBegin) + result = QCPDataRange(other.mBegin, other.mBegin); + else + result = QCPDataRange(other.mEnd, other.mEnd); + } + return result; +} + +/*! + Returns a data range that contains both this data range as well as \a other. +*/ +QCPDataRange QCPDataRange::expanded(const QCPDataRange &other) const +{ + return QCPDataRange(qMin(mBegin, other.mBegin), qMax(mEnd, other.mEnd)); +} + +/*! + Returns the data range which is contained in both this data range and \a other. + + This method is very similar to \ref bounded, with one distinction: If this range and the \a other + range share no intersection, the returned data range will be empty with begin and end set to 0. + (\ref bounded would return a range with begin and end set to one of the boundaries of \a other, + depending on which side this range is on.) + + \see QCPDataSelection::intersection +*/ +QCPDataRange QCPDataRange::intersection(const QCPDataRange &other) const +{ + QCPDataRange result(qMax(mBegin, other.mBegin), qMin(mEnd, other.mEnd)); + if (result.isValid()) + return result; + else + return QCPDataRange(); +} + +/*! + Returns whether this data range and \a other share common data points. + + \see intersection, contains +*/ +bool QCPDataRange::intersects(const QCPDataRange &other) const +{ + return !( (mBegin > other.mBegin && mBegin >= other.mEnd) || + (mEnd <= other.mBegin && mEnd < other.mEnd) ); +} + +/*! + Returns whether all data points described by this data range are also in \a other. + + \see intersects +*/ +bool QCPDataRange::contains(const QCPDataRange &other) const +{ + return mBegin <= other.mBegin && mEnd >= other.mEnd; +} + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataSelection +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataSelection + \brief Describes a data set by holding multiple QCPDataRange instances + + QCPDataSelection manages multiple instances of QCPDataRange in order to represent any (possibly + disjoint) set of data selection. + + The data selection can be modified with addition and subtraction operators which take + QCPDataSelection and QCPDataRange instances, as well as methods such as \ref addDataRange and + \ref clear. Read access is provided by \ref dataRange, \ref dataRanges, \ref dataRangeCount, etc. + + The method \ref simplify is used to join directly adjacent or even overlapping QCPDataRange + instances. QCPDataSelection automatically simplifies when using the addition/subtraction + operators. The only case when \ref simplify is left to the user, is when calling \ref + addDataRange, with the parameter \a simplify explicitly set to false. This is useful if many data + ranges will be added to the selection successively and the overhead for simplifying after each + iteration shall be avoided. In this case, you should make sure to call \ref simplify after + completing the operation. + + Use \ref enforceType to bring the data selection into a state complying with the constraints for + selections defined in \ref QCP::SelectionType. + + %QCustomPlot's \ref dataselection "data selection mechanism" is based on QCPDataSelection and + QCPDataRange. + + \section qcpdataselection-iterating Iterating over a data selection + + As an example, the following code snippet calculates the average value of a graph's data + \ref QCPAbstractPlottable::selection "selection": + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpdataselection-iterating-1 + +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataSelection::dataRangeCount() const + + Returns the number of ranges that make up the data selection. The ranges can be accessed by \ref + dataRange via their index. + + \see dataRange, dataPointCount +*/ + +/*! \fn QList QCPDataSelection::dataRanges() const + + Returns all data ranges that make up the data selection. If the data selection is simplified (the + usual state of the selection, see \ref simplify), the ranges are sorted by ascending data point + index. + + \see dataRange +*/ + +/*! \fn bool QCPDataSelection::isEmpty() const + + Returns true if there are no data ranges, and thus no data points, in this QCPDataSelection + instance. + + \see dataRangeCount +*/ + +/* end documentation of inline functions */ + +/*! + Creates an empty QCPDataSelection. +*/ +QCPDataSelection::QCPDataSelection() +{ +} + +/*! + Creates a QCPDataSelection containing the provided \a range. +*/ +QCPDataSelection::QCPDataSelection(const QCPDataRange &range) +{ + mDataRanges.append(range); +} + +/*! + Returns true if this selection is identical (contains the same data ranges with the same begin + and end indices) to \a other. + + Note that both data selections must be in simplified state (the usual state of the selection, see + \ref simplify) for this operator to return correct results. +*/ +bool QCPDataSelection::operator==(const QCPDataSelection &other) const +{ + if (mDataRanges.size() != other.mDataRanges.size()) + return false; + for (int i=0; i= other.end()) + break; // since data ranges are sorted after the simplify() call, no ranges which contain other will come after this + + if (thisEnd > other.begin()) // ranges which don't fulfill this are entirely before other and can be ignored + { + if (thisBegin >= other.begin()) // range leading segment is encompassed + { + if (thisEnd <= other.end()) // range fully encompassed, remove completely + { + mDataRanges.removeAt(i); + continue; + } else // only leading segment is encompassed, trim accordingly + mDataRanges[i].setBegin(other.end()); + } else // leading segment is not encompassed + { + if (thisEnd <= other.end()) // only trailing segment is encompassed, trim accordingly + { + mDataRanges[i].setEnd(other.begin()); + } else // other lies inside this range, so split range + { + mDataRanges[i].setEnd(other.begin()); + mDataRanges.insert(i+1, QCPDataRange(other.end(), thisEnd)); + break; // since data ranges are sorted (and don't overlap) after simplify() call, we're done here + } + } + } + ++i; + } + + return *this; +} + +/*! + Returns the total number of data points contained in all data ranges that make up this data + selection. +*/ +int QCPDataSelection::dataPointCount() const +{ + int result = 0; + for (int i=0; i= 0 && index < mDataRanges.size()) + { + return mDataRanges.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of range:" << index; + return QCPDataRange(); + } +} + +/*! + Returns a \ref QCPDataRange which spans the entire data selection, including possible + intermediate segments which are not part of the original data selection. +*/ +QCPDataRange QCPDataSelection::span() const +{ + if (isEmpty()) + return QCPDataRange(); + else + return QCPDataRange(mDataRanges.first().begin(), mDataRanges.last().end()); +} + +/*! + Adds the given \a dataRange to this data selection. This is equivalent to the += operator but + allows disabling immediate simplification by setting \a simplify to false. This can improve + performance if adding a very large amount of data ranges successively. In this case, make sure to + call \ref simplify manually, after the operation. +*/ +void QCPDataSelection::addDataRange(const QCPDataRange &dataRange, bool simplify) +{ + mDataRanges.append(dataRange); + if (simplify) + this->simplify(); +} + +/*! + Removes all data ranges. The data selection then contains no data points. + + \ref isEmpty +*/ +void QCPDataSelection::clear() +{ + mDataRanges.clear(); +} + +/*! + Sorts all data ranges by range begin index in ascending order, and then joins directly adjacent + or overlapping ranges. This can reduce the number of individual data ranges in the selection, and + prevents possible double-counting when iterating over the data points held by the data ranges. + + This method is automatically called when using the addition/subtraction operators. The only case + when \ref simplify is left to the user, is when calling \ref addDataRange, with the parameter \a + simplify explicitly set to false. +*/ +void QCPDataSelection::simplify() +{ + // remove any empty ranges: + for (int i=mDataRanges.size()-1; i>=0; --i) + { + if (mDataRanges.at(i).isEmpty()) + mDataRanges.removeAt(i); + } + if (mDataRanges.isEmpty()) + return; + + // sort ranges by starting value, ascending: + std::sort(mDataRanges.begin(), mDataRanges.end(), lessThanDataRangeBegin); + + // join overlapping/contiguous ranges: + int i = 1; + while (i < mDataRanges.size()) + { + if (mDataRanges.at(i-1).end() >= mDataRanges.at(i).begin()) // range i overlaps/joins with i-1, so expand range i-1 appropriately and remove range i from list + { + mDataRanges[i-1].setEnd(qMax(mDataRanges.at(i-1).end(), mDataRanges.at(i).end())); + mDataRanges.removeAt(i); + } else + ++i; + } +} + +/*! + Makes sure this data selection conforms to the specified \a type selection type. Before the type + is enforced, \ref simplify is called. + + Depending on \a type, enforcing means adding new data points that were previously not part of the + selection, or removing data points from the selection. If the current selection already conforms + to \a type, the data selection is not changed. + + \see QCP::SelectionType +*/ +void QCPDataSelection::enforceType(QCP::SelectionType type) +{ + simplify(); + switch (type) + { + case QCP::stNone: + { + mDataRanges.clear(); + break; + } + case QCP::stWhole: + { + // whole selection isn't defined by data range, so don't change anything (is handled in plottable methods) + break; + } + case QCP::stSingleData: + { + // reduce all data ranges to the single first data point: + if (!mDataRanges.isEmpty()) + { + if (mDataRanges.size() > 1) + mDataRanges = QList() << mDataRanges.first(); + if (mDataRanges.first().length() > 1) + mDataRanges.first().setEnd(mDataRanges.first().begin()+1); + } + break; + } + case QCP::stDataRange: + { + mDataRanges = QList() << span(); + break; + } + case QCP::stMultipleDataRanges: + { + // this is the selection type that allows all concievable combinations of ranges, so do nothing + break; + } + } +} + +/*! + Returns true if the data selection \a other is contained entirely in this data selection, i.e. + all data point indices that are in \a other are also in this data selection. + + \see QCPDataRange::contains +*/ +bool QCPDataSelection::contains(const QCPDataSelection &other) const +{ + if (other.isEmpty()) return false; + + int otherIndex = 0; + int thisIndex = 0; + while (thisIndex < mDataRanges.size() && otherIndex < other.mDataRanges.size()) + { + if (mDataRanges.at(thisIndex).contains(other.mDataRanges.at(otherIndex))) + ++otherIndex; + else + ++thisIndex; + } + return thisIndex < mDataRanges.size(); // if thisIndex ran all the way to the end to find a containing range for the current otherIndex, other is not contained in this +} + +/*! + Returns a data selection containing the points which are both in this data selection and in the + data range \a other. + + A common use case is to limit an unknown data selection to the valid range of a data container, + using \ref QCPDataContainer::dataRange as \a other. One can then safely iterate over the returned + data selection without exceeding the data container's bounds. +*/ +QCPDataSelection QCPDataSelection::intersection(const QCPDataRange &other) const +{ + QCPDataSelection result; + for (int i=0; iorientation() == Qt::Horizontal) + return QCPRange(axis->pixelToCoord(mRect.left()), axis->pixelToCoord(mRect.left()+mRect.width())); + else + return QCPRange(axis->pixelToCoord(mRect.top()+mRect.height()), axis->pixelToCoord(mRect.top())); + } else + { + qDebug() << Q_FUNC_INFO << "called with axis zero"; + return QCPRange(); + } +} + +/*! + Sets the pen that will be used to draw the selection rect outline. + + \see setBrush +*/ +void QCPSelectionRect::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the brush that will be used to fill the selection rect. By default the selection rect is not + filled, i.e. \a brush is Qt::NoBrush. + + \see setPen +*/ +void QCPSelectionRect::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + If there is currently a selection interaction going on (\ref isActive), the interaction is + canceled. The selection rect will emit the \ref canceled signal. +*/ +void QCPSelectionRect::cancel() +{ + if (mActive) + { + mActive = false; + emit canceled(mRect, 0); + } +} + +/*! \internal + + This method is called by QCustomPlot to indicate that a selection rect interaction was initiated. + The default implementation sets the selection rect to active, initializes the selection rect + geometry and emits the \ref started signal. +*/ +void QCPSelectionRect::startSelection(QMouseEvent *event) +{ + mActive = true; + mRect = QRect(event->pos(), event->pos()); + emit started(event); +} + +/*! \internal + + This method is called by QCustomPlot to indicate that an ongoing selection rect interaction needs + to update its geometry. The default implementation updates the rect and emits the \ref changed + signal. +*/ +void QCPSelectionRect::moveSelection(QMouseEvent *event) +{ + mRect.setBottomRight(event->pos()); + emit changed(mRect, event); + layer()->replot(); +} + +/*! \internal + + This method is called by QCustomPlot to indicate that an ongoing selection rect interaction has + finished by the user releasing the mouse button. The default implementation deactivates the + selection rect and emits the \ref accepted signal. +*/ +void QCPSelectionRect::endSelection(QMouseEvent *event) +{ + mRect.setBottomRight(event->pos()); + mActive = false; + emit accepted(mRect, event); +} + +/*! \internal + + This method is called by QCustomPlot when a key has been pressed by the user while the selection + rect interaction is active. The default implementation allows to \ref cancel the interaction by + hitting the escape key. +*/ +void QCPSelectionRect::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape && mActive) + { + mActive = false; + emit canceled(mRect, event); + } +} + +/* inherits documentation from base class */ +void QCPSelectionRect::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); +} + +/*! \internal + + If the selection rect is active (\ref isActive), draws the selection rect defined by \a mRect. + + \seebaseclassmethod +*/ +void QCPSelectionRect::draw(QCPPainter *painter) +{ + if (mActive) + { + painter->setPen(mPen); + painter->setBrush(mBrush); + painter->drawRect(mRect); + } +} +/* end of 'src/selectionrect.cpp' */ + + +/* including file 'src/layout.cpp', size 79064 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPMarginGroup +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPMarginGroup + \brief A margin group allows synchronization of margin sides if working with multiple layout elements. + + QCPMarginGroup allows you to tie a margin side of two or more layout elements together, such that + they will all have the same size, based on the largest required margin in the group. + + \n + \image html QCPMarginGroup.png "Demonstration of QCPMarginGroup" + \n + + In certain situations it is desirable that margins at specific sides are synchronized across + layout elements. For example, if one QCPAxisRect is below another one in a grid layout, it will + provide a cleaner look to the user if the left and right margins of the two axis rects are of the + same size. The left axis of the top axis rect will then be at the same horizontal position as the + left axis of the lower axis rect, making them appear aligned. The same applies for the right + axes. This is what QCPMarginGroup makes possible. + + To add/remove a specific side of a layout element to/from a margin group, use the \ref + QCPLayoutElement::setMarginGroup method. To completely break apart the margin group, either call + \ref clear, or just delete the margin group. + + \section QCPMarginGroup-example Example + + First create a margin group: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-1 + Then set this group on the layout element sides: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-2 + Here, we've used the first two axis rects of the plot and synchronized their left margins with + each other and their right margins with each other. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPMarginGroup::elements(QCP::MarginSide side) const + + Returns a list of all layout elements that have their margin \a side associated with this margin + group. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPMarginGroup instance in \a parentPlot. +*/ +QCPMarginGroup::QCPMarginGroup(QCustomPlot *parentPlot) : + QObject(parentPlot), + mParentPlot(parentPlot) +{ + mChildren.insert(QCP::msLeft, QList()); + mChildren.insert(QCP::msRight, QList()); + mChildren.insert(QCP::msTop, QList()); + mChildren.insert(QCP::msBottom, QList()); +} + +QCPMarginGroup::~QCPMarginGroup() +{ + clear(); +} + +/*! + Returns whether this margin group is empty. If this function returns true, no layout elements use + this margin group to synchronize margin sides. +*/ +bool QCPMarginGroup::isEmpty() const +{ + QHashIterator > it(mChildren); + while (it.hasNext()) + { + it.next(); + if (!it.value().isEmpty()) + return false; + } + return true; +} + +/*! + Clears this margin group. The synchronization of the margin sides that use this margin group is + lifted and they will use their individual margin sizes again. +*/ +void QCPMarginGroup::clear() +{ + // make all children remove themselves from this margin group: + QHashIterator > it(mChildren); + while (it.hasNext()) + { + it.next(); + const QList elements = it.value(); + for (int i=elements.size()-1; i>=0; --i) + elements.at(i)->setMarginGroup(it.key(), 0); // removes itself from mChildren via removeChild + } +} + +/*! \internal + + Returns the synchronized common margin for \a side. This is the margin value that will be used by + the layout element on the respective side, if it is part of this margin group. + + The common margin is calculated by requesting the automatic margin (\ref + QCPLayoutElement::calculateAutoMargin) of each element associated with \a side in this margin + group, and choosing the largest returned value. (QCPLayoutElement::minimumMargins is taken into + account, too.) +*/ +int QCPMarginGroup::commonMargin(QCP::MarginSide side) const +{ + // query all automatic margins of the layout elements in this margin group side and find maximum: + int result = 0; + const QList elements = mChildren.value(side); + for (int i=0; iautoMargins().testFlag(side)) + continue; + int m = qMax(elements.at(i)->calculateAutoMargin(side), QCP::getMarginValue(elements.at(i)->minimumMargins(), side)); + if (m > result) + result = m; + } + return result; +} + +/*! \internal + + Adds \a element to the internal list of child elements, for the margin \a side. + + This function does not modify the margin group property of \a element. +*/ +void QCPMarginGroup::addChild(QCP::MarginSide side, QCPLayoutElement *element) +{ + if (!mChildren[side].contains(element)) + mChildren[side].append(element); + else + qDebug() << Q_FUNC_INFO << "element is already child of this margin group side" << reinterpret_cast(element); +} + +/*! \internal + + Removes \a element from the internal list of child elements, for the margin \a side. + + This function does not modify the margin group property of \a element. +*/ +void QCPMarginGroup::removeChild(QCP::MarginSide side, QCPLayoutElement *element) +{ + if (!mChildren[side].removeOne(element)) + qDebug() << Q_FUNC_INFO << "element is not child of this margin group side" << reinterpret_cast(element); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutElement +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayoutElement + \brief The abstract base class for all objects that form \ref thelayoutsystem "the layout system". + + This is an abstract base class. As such, it can't be instantiated directly, rather use one of its subclasses. + + A Layout element is a rectangular object which can be placed in layouts. It has an outer rect + (QCPLayoutElement::outerRect) and an inner rect (\ref QCPLayoutElement::rect). The difference + between outer and inner rect is called its margin. The margin can either be set to automatic or + manual (\ref setAutoMargins) on a per-side basis. If a side is set to manual, that margin can be + set explicitly with \ref setMargins and will stay fixed at that value. If it's set to automatic, + the layout element subclass will control the value itself (via \ref calculateAutoMargin). + + Layout elements can be placed in layouts (base class QCPLayout) like QCPLayoutGrid. The top level + layout is reachable via \ref QCustomPlot::plotLayout, and is a \ref QCPLayoutGrid. Since \ref + QCPLayout itself derives from \ref QCPLayoutElement, layouts can be nested. + + Thus in QCustomPlot one can divide layout elements into two categories: The ones that are + invisible by themselves, because they don't draw anything. Their only purpose is to manage the + position and size of other layout elements. This category of layout elements usually use + QCPLayout as base class. Then there is the category of layout elements which actually draw + something. For example, QCPAxisRect, QCPLegend and QCPTextElement are of this category. This does + not necessarily mean that the latter category can't have child layout elements. QCPLegend for + instance, actually derives from QCPLayoutGrid and the individual legend items are child layout + elements in the grid layout. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayout *QCPLayoutElement::layout() const + + Returns the parent layout of this layout element. +*/ + +/*! \fn QRect QCPLayoutElement::rect() const + + Returns the inner rect of this layout element. The inner rect is the outer rect (\ref outerRect, \ref + setOuterRect) shrinked by the margins (\ref setMargins, \ref setAutoMargins). + + In some cases, the area between outer and inner rect is left blank. In other cases the margin + area is used to display peripheral graphics while the main content is in the inner rect. This is + where automatic margin calculation becomes interesting because it allows the layout element to + adapt the margins to the peripheral graphics it wants to draw. For example, \ref QCPAxisRect + draws the axis labels and tick labels in the margin area, thus needs to adjust the margins (if + \ref setAutoMargins is enabled) according to the space required by the labels of the axes. + + \see outerRect +*/ + +/*! \fn QRect QCPLayoutElement::outerRect() const + + Returns the outer rect of this layout element. The outer rect is the inner rect expanded by the + margins (\ref setMargins, \ref setAutoMargins). The outer rect is used (and set via \ref + setOuterRect) by the parent \ref QCPLayout to control the size of this layout element. + + \see rect +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutElement and sets default values. +*/ +QCPLayoutElement::QCPLayoutElement(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), // parenthood is changed as soon as layout element gets inserted into a layout (except for top level layout) + mParentLayout(0), + mMinimumSize(), + mMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX), + mSizeConstraintRect(scrInnerRect), + mRect(0, 0, 0, 0), + mOuterRect(0, 0, 0, 0), + mMargins(0, 0, 0, 0), + mMinimumMargins(0, 0, 0, 0), + mAutoMargins(QCP::msAll) +{ +} + +QCPLayoutElement::~QCPLayoutElement() +{ + setMarginGroup(QCP::msAll, 0); // unregister at margin groups, if there are any + // unregister at layout: + if (qobject_cast(mParentLayout)) // the qobject_cast is just a safeguard in case the layout forgets to call clear() in its dtor and this dtor is called by QObject dtor + mParentLayout->take(this); +} + +/*! + Sets the outer rect of this layout element. If the layout element is inside a layout, the layout + sets the position and size of this layout element using this function. + + Calling this function externally has no effect, since the layout will overwrite any changes to + the outer rect upon the next replot. + + The layout element will adapt its inner \ref rect by applying the margins inward to the outer rect. + + \see rect +*/ +void QCPLayoutElement::setOuterRect(const QRect &rect) +{ + if (mOuterRect != rect) + { + mOuterRect = rect; + mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); + } +} + +/*! + Sets the margins of this layout element. If \ref setAutoMargins is disabled for some or all + sides, this function is used to manually set the margin on those sides. Sides that are still set + to be handled automatically are ignored and may have any value in \a margins. + + The margin is the distance between the outer rect (controlled by the parent layout via \ref + setOuterRect) and the inner \ref rect (which usually contains the main content of this layout + element). + + \see setAutoMargins +*/ +void QCPLayoutElement::setMargins(const QMargins &margins) +{ + if (mMargins != margins) + { + mMargins = margins; + mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); + } +} + +/*! + If \ref setAutoMargins is enabled on some or all margins, this function is used to provide + minimum values for those margins. + + The minimum values are not enforced on margin sides that were set to be under manual control via + \ref setAutoMargins. + + \see setAutoMargins +*/ +void QCPLayoutElement::setMinimumMargins(const QMargins &margins) +{ + if (mMinimumMargins != margins) + { + mMinimumMargins = margins; + } +} + +/*! + Sets on which sides the margin shall be calculated automatically. If a side is calculated + automatically, a minimum margin value may be provided with \ref setMinimumMargins. If a side is + set to be controlled manually, the value may be specified with \ref setMargins. + + Margin sides that are under automatic control may participate in a \ref QCPMarginGroup (see \ref + setMarginGroup), to synchronize (align) it with other layout elements in the plot. + + \see setMinimumMargins, setMargins, QCP::MarginSide +*/ +void QCPLayoutElement::setAutoMargins(QCP::MarginSides sides) +{ + mAutoMargins = sides; +} + +/*! + Sets the minimum size of this layout element. A parent layout tries to respect the \a size here + by changing row/column sizes in the layout accordingly. + + If the parent layout size is not sufficient to satisfy all minimum size constraints of its child + layout elements, the layout may set a size that is actually smaller than \a size. QCustomPlot + propagates the layout's size constraints to the outside by setting its own minimum QWidget size + accordingly, so violations of \a size should be exceptions. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMinimumSize(const QSize &size) +{ + if (mMinimumSize != size) + { + mMinimumSize = size; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! \overload + + Sets the minimum size of this layout element. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMinimumSize(int width, int height) +{ + setMinimumSize(QSize(width, height)); +} + +/*! + Sets the maximum size of this layout element. A parent layout tries to respect the \a size here + by changing row/column sizes in the layout accordingly. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMaximumSize(const QSize &size) +{ + if (mMaximumSize != size) + { + mMaximumSize = size; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! \overload + + Sets the maximum size of this layout element. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMaximumSize(int width, int height) +{ + setMaximumSize(QSize(width, height)); +} + +/*! + Sets to which rect of a layout element the size constraints apply. Size constraints can be set + via \ref setMinimumSize and \ref setMaximumSize. + + The outer rect (\ref outerRect) includes the margins (e.g. in the case of a QCPAxisRect the axis + labels), whereas the inner rect (\ref rect) does not. + + \see setMinimumSize, setMaximumSize +*/ +void QCPLayoutElement::setSizeConstraintRect(SizeConstraintRect constraintRect) +{ + if (mSizeConstraintRect != constraintRect) + { + mSizeConstraintRect = constraintRect; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! + Sets the margin \a group of the specified margin \a sides. + + Margin groups allow synchronizing specified margins across layout elements, see the documentation + of \ref QCPMarginGroup. + + To unset the margin group of \a sides, set \a group to 0. + + Note that margin groups only work for margin sides that are set to automatic (\ref + setAutoMargins). + + \see QCP::MarginSide +*/ +void QCPLayoutElement::setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group) +{ + QVector sideVector; + if (sides.testFlag(QCP::msLeft)) sideVector.append(QCP::msLeft); + if (sides.testFlag(QCP::msRight)) sideVector.append(QCP::msRight); + if (sides.testFlag(QCP::msTop)) sideVector.append(QCP::msTop); + if (sides.testFlag(QCP::msBottom)) sideVector.append(QCP::msBottom); + + for (int i=0; iremoveChild(side, this); + + if (!group) // if setting to 0, remove hash entry. Else set hash entry to new group and register there + { + mMarginGroups.remove(side); + } else // setting to a new group + { + mMarginGroups[side] = group; + group->addChild(side, this); + } + } + } +} + +/*! + Updates the layout element and sub-elements. This function is automatically called before every + replot by the parent layout element. It is called multiple times, once for every \ref + UpdatePhase. The phases are run through in the order of the enum values. For details about what + happens at the different phases, see the documentation of \ref UpdatePhase. + + Layout elements that have child elements should call the \ref update method of their child + elements, and pass the current \a phase unchanged. + + The default implementation executes the automatic margin mechanism in the \ref upMargins phase. + Subclasses should make sure to call the base class implementation. +*/ +void QCPLayoutElement::update(UpdatePhase phase) +{ + if (phase == upMargins) + { + if (mAutoMargins != QCP::msNone) + { + // set the margins of this layout element according to automatic margin calculation, either directly or via a margin group: + QMargins newMargins = mMargins; + QList allMarginSides = QList() << QCP::msLeft << QCP::msRight << QCP::msTop << QCP::msBottom; + foreach (QCP::MarginSide side, allMarginSides) + { + if (mAutoMargins.testFlag(side)) // this side's margin shall be calculated automatically + { + if (mMarginGroups.contains(side)) + QCP::setMarginValue(newMargins, side, mMarginGroups[side]->commonMargin(side)); // this side is part of a margin group, so get the margin value from that group + else + QCP::setMarginValue(newMargins, side, calculateAutoMargin(side)); // this side is not part of a group, so calculate the value directly + // apply minimum margin restrictions: + if (QCP::getMarginValue(newMargins, side) < QCP::getMarginValue(mMinimumMargins, side)) + QCP::setMarginValue(newMargins, side, QCP::getMarginValue(mMinimumMargins, side)); + } + } + setMargins(newMargins); + } + } +} + +/*! + Returns the suggested minimum size this layout element (the \ref outerRect) may be compressed to, + if no manual minimum size is set. + + if a minimum size (\ref setMinimumSize) was not set manually, parent layouts use the returned size + (usually indirectly through \ref QCPLayout::getFinalMinimumOuterSize) to determine the minimum + allowed size of this layout element. + + A manual minimum size is considered set if it is non-zero. + + The default implementation simply returns the sum of the horizontal margins for the width and the + sum of the vertical margins for the height. Reimplementations may use their detailed knowledge + about the layout element's content to provide size hints. +*/ +QSize QCPLayoutElement::minimumOuterSizeHint() const +{ + return QSize(mMargins.left()+mMargins.right(), mMargins.top()+mMargins.bottom()); +} + +/*! + Returns the suggested maximum size this layout element (the \ref outerRect) may be expanded to, + if no manual maximum size is set. + + if a maximum size (\ref setMaximumSize) was not set manually, parent layouts use the returned + size (usually indirectly through \ref QCPLayout::getFinalMaximumOuterSize) to determine the + maximum allowed size of this layout element. + + A manual maximum size is considered set if it is smaller than Qt's \c QWIDGETSIZE_MAX. + + The default implementation simply returns \c QWIDGETSIZE_MAX for both width and height, implying + no suggested maximum size. Reimplementations may use their detailed knowledge about the layout + element's content to provide size hints. +*/ +QSize QCPLayoutElement::maximumOuterSizeHint() const +{ + return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); +} + +/*! + Returns a list of all child elements in this layout element. If \a recursive is true, all + sub-child elements are included in the list, too. + + \warning There may be entries with value 0 in the returned list. (For example, QCPLayoutGrid may have + empty cells which yield 0 at the respective index.) +*/ +QList QCPLayoutElement::elements(bool recursive) const +{ + Q_UNUSED(recursive) + return QList(); +} + +/*! + Layout elements are sensitive to events inside their outer rect. If \a pos is within the outer + rect, this method returns a value corresponding to 0.99 times the parent plot's selection + tolerance. However, layout elements are not selectable by default. So if \a onlySelectable is + true, -1.0 is returned. + + See \ref QCPLayerable::selectTest for a general explanation of this virtual method. + + QCPLayoutElement subclasses may reimplement this method to provide more specific selection test + behaviour. +*/ +double QCPLayoutElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + + if (onlySelectable) + return -1; + + if (QRectF(mOuterRect).contains(pos)) + { + if (mParentPlot) + return mParentPlot->selectionTolerance()*0.99; + else + { + qDebug() << Q_FUNC_INFO << "parent plot not defined"; + return -1; + } + } else + return -1; +} + +/*! \internal + + propagates the parent plot initialization to all child elements, by calling \ref + QCPLayerable::initializeParentPlot on them. +*/ +void QCPLayoutElement::parentPlotInitialized(QCustomPlot *parentPlot) +{ + foreach (QCPLayoutElement* el, elements(false)) + { + if (!el->parentPlot()) + el->initializeParentPlot(parentPlot); + } +} + +/*! \internal + + Returns the margin size for this \a side. It is used if automatic margins is enabled for this \a + side (see \ref setAutoMargins). If a minimum margin was set with \ref setMinimumMargins, the + returned value will not be smaller than the specified minimum margin. + + The default implementation just returns the respective manual margin (\ref setMargins) or the + minimum margin, whichever is larger. +*/ +int QCPLayoutElement::calculateAutoMargin(QCP::MarginSide side) +{ + return qMax(QCP::getMarginValue(mMargins, side), QCP::getMarginValue(mMinimumMargins, side)); +} + +/*! \internal + + This virtual method is called when this layout element was moved to a different QCPLayout, or + when this layout element has changed its logical position (e.g. row and/or column) within the + same QCPLayout. Subclasses may use this to react accordingly. + + Since this method is called after the completion of the move, you can access the new parent + layout via \ref layout(). + + The default implementation does nothing. +*/ +void QCPLayoutElement::layoutChanged() +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayout +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayout + \brief The abstract base class for layouts + + This is an abstract base class for layout elements whose main purpose is to define the position + and size of other child layout elements. In most cases, layouts don't draw anything themselves + (but there are exceptions to this, e.g. QCPLegend). + + QCPLayout derives from QCPLayoutElement, and thus can itself be nested in other layouts. + + QCPLayout introduces a common interface for accessing and manipulating the child elements. Those + functions are most notably \ref elementCount, \ref elementAt, \ref takeAt, \ref take, \ref + simplify, \ref removeAt, \ref remove and \ref clear. Individual subclasses may add more functions + to this interface which are more specialized to the form of the layout. For example, \ref + QCPLayoutGrid adds functions that take row and column indices to access cells of the layout grid + more conveniently. + + Since this is an abstract base class, you can't instantiate it directly. Rather use one of its + subclasses like QCPLayoutGrid or QCPLayoutInset. + + For a general introduction to the layout system, see the dedicated documentation page \ref + thelayoutsystem "The Layout System". +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual int QCPLayout::elementCount() const = 0 + + Returns the number of elements/cells in the layout. + + \see elements, elementAt +*/ + +/*! \fn virtual QCPLayoutElement* QCPLayout::elementAt(int index) const = 0 + + Returns the element in the cell with the given \a index. If \a index is invalid, returns 0. + + Note that even if \a index is valid, the respective cell may be empty in some layouts (e.g. + QCPLayoutGrid), so this function may return 0 in those cases. You may use this function to check + whether a cell is empty or not. + + \see elements, elementCount, takeAt +*/ + +/*! \fn virtual QCPLayoutElement* QCPLayout::takeAt(int index) = 0 + + Removes the element with the given \a index from the layout and returns it. + + If the \a index is invalid or the cell with that index is empty, returns 0. + + Note that some layouts don't remove the respective cell right away but leave an empty cell after + successful removal of the layout element. To collapse empty cells, use \ref simplify. + + \see elementAt, take +*/ + +/*! \fn virtual bool QCPLayout::take(QCPLayoutElement* element) = 0 + + Removes the specified \a element from the layout and returns true on success. + + If the \a element isn't in this layout, returns false. + + Note that some layouts don't remove the respective cell right away but leave an empty cell after + successful removal of the layout element. To collapse empty cells, use \ref simplify. + + \see takeAt +*/ + +/* end documentation of pure virtual functions */ + +/*! + Creates an instance of QCPLayout and sets default values. Note that since QCPLayout + is an abstract base class, it can't be instantiated directly. +*/ +QCPLayout::QCPLayout() +{ +} + +/*! + If \a phase is \ref upLayout, calls \ref updateLayout, which subclasses may reimplement to + reposition and resize their cells. + + Finally, the call is propagated down to all child \ref QCPLayoutElement "QCPLayoutElements". + + For details about this method and the update phases, see the documentation of \ref + QCPLayoutElement::update. +*/ +void QCPLayout::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + // set child element rects according to layout: + if (phase == upLayout) + updateLayout(); + + // propagate update call to child elements: + const int elCount = elementCount(); + for (int i=0; iupdate(phase); + } +} + +/* inherits documentation from base class */ +QList QCPLayout::elements(bool recursive) const +{ + const int c = elementCount(); + QList result; +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + result.reserve(c); +#endif + for (int i=0; ielements(recursive); + } + } + return result; +} + +/*! + Simplifies the layout by collapsing empty cells. The exact behavior depends on subclasses, the + default implementation does nothing. + + Not all layouts need simplification. For example, QCPLayoutInset doesn't use explicit + simplification while QCPLayoutGrid does. +*/ +void QCPLayout::simplify() +{ +} + +/*! + Removes and deletes the element at the provided \a index. Returns true on success. If \a index is + invalid or points to an empty cell, returns false. + + This function internally uses \ref takeAt to remove the element from the layout and then deletes + the returned element. Note that some layouts don't remove the respective cell right away but leave an + empty cell after successful removal of the layout element. To collapse empty cells, use \ref + simplify. + + \see remove, takeAt +*/ +bool QCPLayout::removeAt(int index) +{ + if (QCPLayoutElement *el = takeAt(index)) + { + delete el; + return true; + } else + return false; +} + +/*! + Removes and deletes the provided \a element. Returns true on success. If \a element is not in the + layout, returns false. + + This function internally uses \ref takeAt to remove the element from the layout and then deletes + the element. Note that some layouts don't remove the respective cell right away but leave an + empty cell after successful removal of the layout element. To collapse empty cells, use \ref + simplify. + + \see removeAt, take +*/ +bool QCPLayout::remove(QCPLayoutElement *element) +{ + if (take(element)) + { + delete element; + return true; + } else + return false; +} + +/*! + Removes and deletes all layout elements in this layout. Finally calls \ref simplify to make sure + all empty cells are collapsed. + + \see remove, removeAt +*/ +void QCPLayout::clear() +{ + for (int i=elementCount()-1; i>=0; --i) + { + if (elementAt(i)) + removeAt(i); + } + simplify(); +} + +/*! + Subclasses call this method to report changed (minimum/maximum) size constraints. + + If the parent of this layout is again a QCPLayout, forwards the call to the parent's \ref + sizeConstraintsChanged. If the parent is a QWidget (i.e. is the \ref QCustomPlot::plotLayout of + QCustomPlot), calls QWidget::updateGeometry, so if the QCustomPlot widget is inside a Qt QLayout, + it may update itself and resize cells accordingly. +*/ +void QCPLayout::sizeConstraintsChanged() const +{ + if (QWidget *w = qobject_cast(parent())) + w->updateGeometry(); + else if (QCPLayout *l = qobject_cast(parent())) + l->sizeConstraintsChanged(); +} + +/*! \internal + + Subclasses reimplement this method to update the position and sizes of the child elements/cells + via calling their \ref QCPLayoutElement::setOuterRect. The default implementation does nothing. + + The geometry used as a reference is the inner \ref rect of this layout. Child elements should stay + within that rect. + + \ref getSectionSizes may help with the reimplementation of this function. + + \see update +*/ +void QCPLayout::updateLayout() +{ +} + + +/*! \internal + + Associates \a el with this layout. This is done by setting the \ref QCPLayoutElement::layout, the + \ref QCPLayerable::parentLayerable and the QObject parent to this layout. + + Further, if \a el didn't previously have a parent plot, calls \ref + QCPLayerable::initializeParentPlot on \a el to set the paret plot. + + This method is used by subclass specific methods that add elements to the layout. Note that this + method only changes properties in \a el. The removal from the old layout and the insertion into + the new layout must be done additionally. +*/ +void QCPLayout::adoptElement(QCPLayoutElement *el) +{ + if (el) + { + el->mParentLayout = this; + el->setParentLayerable(this); + el->setParent(this); + if (!el->parentPlot()) + el->initializeParentPlot(mParentPlot); + el->layoutChanged(); + } else + qDebug() << Q_FUNC_INFO << "Null element passed"; +} + +/*! \internal + + Disassociates \a el from this layout. This is done by setting the \ref QCPLayoutElement::layout + and the \ref QCPLayerable::parentLayerable to zero. The QObject parent is set to the parent + QCustomPlot. + + This method is used by subclass specific methods that remove elements from the layout (e.g. \ref + take or \ref takeAt). Note that this method only changes properties in \a el. The removal from + the old layout must be done additionally. +*/ +void QCPLayout::releaseElement(QCPLayoutElement *el) +{ + if (el) + { + el->mParentLayout = 0; + el->setParentLayerable(0); + el->setParent(mParentPlot); + // Note: Don't initializeParentPlot(0) here, because layout element will stay in same parent plot + } else + qDebug() << Q_FUNC_INFO << "Null element passed"; +} + +/*! \internal + + This is a helper function for the implementation of \ref updateLayout in subclasses. + + It calculates the sizes of one-dimensional sections with provided constraints on maximum section + sizes, minimum section sizes, relative stretch factors and the final total size of all sections. + + The QVector entries refer to the sections. Thus all QVectors must have the same size. + + \a maxSizes gives the maximum allowed size of each section. If there shall be no maximum size + imposed, set all vector values to Qt's QWIDGETSIZE_MAX. + + \a minSizes gives the minimum allowed size of each section. If there shall be no minimum size + imposed, set all vector values to zero. If the \a minSizes entries add up to a value greater than + \a totalSize, sections will be scaled smaller than the proposed minimum sizes. (In other words, + not exceeding the allowed total size is taken to be more important than not going below minimum + section sizes.) + + \a stretchFactors give the relative proportions of the sections to each other. If all sections + shall be scaled equally, set all values equal. If the first section shall be double the size of + each individual other section, set the first number of \a stretchFactors to double the value of + the other individual values (e.g. {2, 1, 1, 1}). + + \a totalSize is the value that the final section sizes will add up to. Due to rounding, the + actual sum may differ slightly. If you want the section sizes to sum up to exactly that value, + you could distribute the remaining difference on the sections. + + The return value is a QVector containing the section sizes. +*/ +QVector QCPLayout::getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const +{ + if (maxSizes.size() != minSizes.size() || minSizes.size() != stretchFactors.size()) + { + qDebug() << Q_FUNC_INFO << "Passed vector sizes aren't equal:" << maxSizes << minSizes << stretchFactors; + return QVector(); + } + if (stretchFactors.isEmpty()) + return QVector(); + int sectionCount = stretchFactors.size(); + QVector sectionSizes(sectionCount); + // if provided total size is forced smaller than total minimum size, ignore minimum sizes (squeeze sections): + int minSizeSum = 0; + for (int i=0; i minimumLockedSections; + QList unfinishedSections; + for (int i=0; i result(sectionCount); + for (int i=0; iminimumOuterSizeHint(); + QSize minOuter = el->minimumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset minimum of 0) + if (minOuter.width() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + minOuter.rwidth() += el->margins().left() + el->margins().right(); + if (minOuter.height() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + minOuter.rheight() += el->margins().top() + el->margins().bottom(); + + return QSize(minOuter.width() > 0 ? minOuter.width() : minOuterHint.width(), + minOuter.height() > 0 ? minOuter.height() : minOuterHint.height());; +} + +/*! \internal + + This is a helper function for the implementation of subclasses. + + It returns the maximum size that should finally be used for the outer rect of the passed layout + element \a el. + + It takes into account whether a manual maximum size is set (\ref + QCPLayoutElement::setMaximumSize), which size constraint is set (\ref + QCPLayoutElement::setSizeConstraintRect), as well as the maximum size hint, if no manual maximum + size was set (\ref QCPLayoutElement::maximumOuterSizeHint). +*/ +QSize QCPLayout::getFinalMaximumOuterSize(const QCPLayoutElement *el) +{ + QSize maxOuterHint = el->maximumOuterSizeHint(); + QSize maxOuter = el->maximumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset maximum of QWIDGETSIZE_MAX) + if (maxOuter.width() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + maxOuter.rwidth() += el->margins().left() + el->margins().right(); + if (maxOuter.height() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + maxOuter.rheight() += el->margins().top() + el->margins().bottom(); + + return QSize(maxOuter.width() < QWIDGETSIZE_MAX ? maxOuter.width() : maxOuterHint.width(), + maxOuter.height() < QWIDGETSIZE_MAX ? maxOuter.height() : maxOuterHint.height()); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutGrid +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayoutGrid + \brief A layout that arranges child elements in a grid + + Elements are laid out in a grid with configurable stretch factors (\ref setColumnStretchFactor, + \ref setRowStretchFactor) and spacing (\ref setColumnSpacing, \ref setRowSpacing). + + Elements can be added to cells via \ref addElement. The grid is expanded if the specified row or + column doesn't exist yet. Whether a cell contains a valid layout element can be checked with \ref + hasElement, that element can be retrieved with \ref element. If rows and columns that only have + empty cells shall be removed, call \ref simplify. Removal of elements is either done by just + adding the element to a different layout or by using the QCPLayout interface \ref take or \ref + remove. + + If you use \ref addElement(QCPLayoutElement*) without explicit parameters for \a row and \a + column, the grid layout will choose the position according to the current \ref setFillOrder and + the wrapping (\ref setWrap). + + Row and column insertion can be performed with \ref insertRow and \ref insertColumn. +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPLayoutGrid::rowCount() const + + Returns the number of rows in the layout. + + \see columnCount +*/ + +/*! \fn int QCPLayoutGrid::columnCount() const + + Returns the number of columns in the layout. + + \see rowCount +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutGrid and sets default values. +*/ +QCPLayoutGrid::QCPLayoutGrid() : + mColumnSpacing(5), + mRowSpacing(5), + mWrap(0), + mFillOrder(foRowsFirst) +{ +} + +QCPLayoutGrid::~QCPLayoutGrid() +{ + // clear all child layout elements. This is important because only the specific layouts know how + // to handle removing elements (clear calls virtual removeAt method to do that). + clear(); +} + +/*! + Returns the element in the cell in \a row and \a column. + + Returns 0 if either the row/column is invalid or if the cell is empty. In those cases, a qDebug + message is printed. To check whether a cell exists and isn't empty, use \ref hasElement. + + \see addElement, hasElement +*/ +QCPLayoutElement *QCPLayoutGrid::element(int row, int column) const +{ + if (row >= 0 && row < mElements.size()) + { + if (column >= 0 && column < mElements.first().size()) + { + if (QCPLayoutElement *result = mElements.at(row).at(column)) + return result; + else + qDebug() << Q_FUNC_INFO << "Requested cell is empty. Row:" << row << "Column:" << column; + } else + qDebug() << Q_FUNC_INFO << "Invalid column. Row:" << row << "Column:" << column; + } else + qDebug() << Q_FUNC_INFO << "Invalid row. Row:" << row << "Column:" << column; + return 0; +} + + +/*! \overload + + Adds the \a element to cell with \a row and \a column. If \a element is already in a layout, it + is first removed from there. If \a row or \a column don't exist yet, the layout is expanded + accordingly. + + Returns true if the element was added successfully, i.e. if the cell at \a row and \a column + didn't already have an element. + + Use the overload of this method without explicit row/column index to place the element according + to the configured fill order and wrapping settings. + + \see element, hasElement, take, remove +*/ +bool QCPLayoutGrid::addElement(int row, int column, QCPLayoutElement *element) +{ + if (!hasElement(row, column)) + { + if (element && element->layout()) // remove from old layout first + element->layout()->take(element); + expandTo(row+1, column+1); + mElements[row][column] = element; + if (element) + adoptElement(element); + return true; + } else + qDebug() << Q_FUNC_INFO << "There is already an element in the specified row/column:" << row << column; + return false; +} + +/*! \overload + + Adds the \a element to the next empty cell according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap). If \a element is already in a layout, it is first + removed from there. If necessary, the layout is expanded to hold the new element. + + Returns true if the element was added successfully. + + \see setFillOrder, setWrap, element, hasElement, take, remove +*/ +bool QCPLayoutGrid::addElement(QCPLayoutElement *element) +{ + int rowIndex = 0; + int colIndex = 0; + if (mFillOrder == foColumnsFirst) + { + while (hasElement(rowIndex, colIndex)) + { + ++colIndex; + if (colIndex >= mWrap && mWrap > 0) + { + colIndex = 0; + ++rowIndex; + } + } + } else + { + while (hasElement(rowIndex, colIndex)) + { + ++rowIndex; + if (rowIndex >= mWrap && mWrap > 0) + { + rowIndex = 0; + ++colIndex; + } + } + } + return addElement(rowIndex, colIndex, element); +} + +/*! + Returns whether the cell at \a row and \a column exists and contains a valid element, i.e. isn't + empty. + + \see element +*/ +bool QCPLayoutGrid::hasElement(int row, int column) +{ + if (row >= 0 && row < rowCount() && column >= 0 && column < columnCount()) + return mElements.at(row).at(column); + else + return false; +} + +/*! + Sets the stretch \a factor of \a column. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref + QCPLayoutElement::setSizeConstraintRect.) + + The default stretch factor of newly created rows/columns is 1. + + \see setColumnStretchFactors, setRowStretchFactor +*/ +void QCPLayoutGrid::setColumnStretchFactor(int column, double factor) +{ + if (column >= 0 && column < columnCount()) + { + if (factor > 0) + mColumnStretchFactors[column] = factor; + else + qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; + } else + qDebug() << Q_FUNC_INFO << "Invalid column:" << column; +} + +/*! + Sets the stretch \a factors of all columns. \a factors must have the size \ref columnCount. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref + QCPLayoutElement::setSizeConstraintRect.) + + The default stretch factor of newly created rows/columns is 1. + + \see setColumnStretchFactor, setRowStretchFactors +*/ +void QCPLayoutGrid::setColumnStretchFactors(const QList &factors) +{ + if (factors.size() == mColumnStretchFactors.size()) + { + mColumnStretchFactors = factors; + for (int i=0; i= 0 && row < rowCount()) + { + if (factor > 0) + mRowStretchFactors[row] = factor; + else + qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; + } else + qDebug() << Q_FUNC_INFO << "Invalid row:" << row; +} + +/*! + Sets the stretch \a factors of all rows. \a factors must have the size \ref rowCount. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref + QCPLayoutElement::setSizeConstraintRect.) + + The default stretch factor of newly created rows/columns is 1. + + \see setRowStretchFactor, setColumnStretchFactors +*/ +void QCPLayoutGrid::setRowStretchFactors(const QList &factors) +{ + if (factors.size() == mRowStretchFactors.size()) + { + mRowStretchFactors = factors; + for (int i=0; i tempElements; + if (rearrange) + { + tempElements.reserve(elCount); + for (int i=0; i()); + mRowStretchFactors.append(1); + } + // go through rows and expand columns as necessary: + int newColCount = qMax(columnCount(), newColumnCount); + for (int i=0; i rowCount()) + newIndex = rowCount(); + + mRowStretchFactors.insert(newIndex, 1); + QList newRow; + for (int col=0; col columnCount()) + newIndex = columnCount(); + + mColumnStretchFactors.insert(newIndex, 1); + for (int row=0; row= 0 && row < rowCount()) + { + if (column >= 0 && column < columnCount()) + { + switch (mFillOrder) + { + case foRowsFirst: return column*rowCount() + row; + case foColumnsFirst: return row*columnCount() + column; + } + } else + qDebug() << Q_FUNC_INFO << "row index out of bounds:" << row; + } else + qDebug() << Q_FUNC_INFO << "column index out of bounds:" << column; + return 0; +} + +/*! + Converts the linear index to row and column indices and writes the result to \a row and \a + column. + + The way the cells are indexed depends on \ref setFillOrder. If it is \ref foRowsFirst, the + indices increase left to right and then top to bottom. If it is \ref foColumnsFirst, the indices + increase top to bottom and then left to right. + + If there are no cells (i.e. column or row count is zero), sets \a row and \a column to -1. + + For the retrieved \a row and \a column to be valid, the passed \a index must be valid itself, + i.e. greater or equal to zero and smaller than the current \ref elementCount. + + \see rowColToIndex +*/ +void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const +{ + row = -1; + column = -1; + const int nCols = columnCount(); + const int nRows = rowCount(); + if (nCols == 0 || nRows == 0) + return; + if (index < 0 || index >= elementCount()) + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return; + } + + switch (mFillOrder) + { + case foRowsFirst: + { + column = index / nRows; + row = index % nRows; + break; + } + case foColumnsFirst: + { + row = index / nCols; + column = index % nCols; + break; + } + } +} + +/* inherits documentation from base class */ +void QCPLayoutGrid::updateLayout() +{ + QVector minColWidths, minRowHeights, maxColWidths, maxRowHeights; + getMinimumRowColSizes(&minColWidths, &minRowHeights); + getMaximumRowColSizes(&maxColWidths, &maxRowHeights); + + int totalRowSpacing = (rowCount()-1) * mRowSpacing; + int totalColSpacing = (columnCount()-1) * mColumnSpacing; + QVector colWidths = getSectionSizes(maxColWidths, minColWidths, mColumnStretchFactors.toVector(), mRect.width()-totalColSpacing); + QVector rowHeights = getSectionSizes(maxRowHeights, minRowHeights, mRowStretchFactors.toVector(), mRect.height()-totalRowSpacing); + + // go through cells and set rects accordingly: + int yOffset = mRect.top(); + for (int row=0; row 0) + yOffset += rowHeights.at(row-1)+mRowSpacing; + int xOffset = mRect.left(); + for (int col=0; col 0) + xOffset += colWidths.at(col-1)+mColumnSpacing; + if (mElements.at(row).at(col)) + mElements.at(row).at(col)->setOuterRect(QRect(xOffset, yOffset, colWidths.at(col), rowHeights.at(row))); + } + } +} + +/*! + \seebaseclassmethod + + Note that the association of the linear \a index to the row/column based cells depends on the + current setting of \ref setFillOrder. + + \see rowColToIndex +*/ +QCPLayoutElement *QCPLayoutGrid::elementAt(int index) const +{ + if (index >= 0 && index < elementCount()) + { + int row, col; + indexToRowCol(index, row, col); + return mElements.at(row).at(col); + } else + return 0; +} + +/*! + \seebaseclassmethod + + Note that the association of the linear \a index to the row/column based cells depends on the + current setting of \ref setFillOrder. + + \see rowColToIndex +*/ +QCPLayoutElement *QCPLayoutGrid::takeAt(int index) +{ + if (QCPLayoutElement *el = elementAt(index)) + { + releaseElement(el); + int row, col; + indexToRowCol(index, row, col); + mElements[row][col] = 0; + return el; + } else + { + qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; + return 0; + } +} + +/* inherits documentation from base class */ +bool QCPLayoutGrid::take(QCPLayoutElement *element) +{ + if (element) + { + for (int i=0; i QCPLayoutGrid::elements(bool recursive) const +{ + QList result; + const int elCount = elementCount(); +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + result.reserve(elCount); +#endif + for (int i=0; ielements(recursive); + } + } + return result; +} + +/*! + Simplifies the layout by collapsing rows and columns which only contain empty cells. +*/ +void QCPLayoutGrid::simplify() +{ + // remove rows with only empty cells: + for (int row=rowCount()-1; row>=0; --row) + { + bool hasElements = false; + for (int col=0; col=0; --col) + { + bool hasElements = false; + for (int row=0; row minColWidths, minRowHeights; + getMinimumRowColSizes(&minColWidths, &minRowHeights); + QSize result(0, 0); + for (int i=0; i maxColWidths, maxRowHeights; + getMaximumRowColSizes(&maxColWidths, &maxRowHeights); + + QSize result(0, 0); + for (int i=0; i QWIDGETSIZE_MAX) + result.setHeight(QWIDGETSIZE_MAX); + if (result.width() > QWIDGETSIZE_MAX) + result.setWidth(QWIDGETSIZE_MAX); + return result; +} + +/*! \internal + + Places the minimum column widths and row heights into \a minColWidths and \a minRowHeights + respectively. + + The minimum height of a row is the largest minimum height of any element's outer rect in that + row. The minimum width of a column is the largest minimum width of any element's outer rect in + that column. + + This is a helper function for \ref updateLayout. + + \see getMaximumRowColSizes +*/ +void QCPLayoutGrid::getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const +{ + *minColWidths = QVector(columnCount(), 0); + *minRowHeights = QVector(rowCount(), 0); + for (int row=0; rowat(col) < minSize.width()) + (*minColWidths)[col] = minSize.width(); + if (minRowHeights->at(row) < minSize.height()) + (*minRowHeights)[row] = minSize.height(); + } + } + } +} + +/*! \internal + + Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights + respectively. + + The maximum height of a row is the smallest maximum height of any element's outer rect in that + row. The maximum width of a column is the smallest maximum width of any element's outer rect in + that column. + + This is a helper function for \ref updateLayout. + + \see getMinimumRowColSizes +*/ +void QCPLayoutGrid::getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const +{ + *maxColWidths = QVector(columnCount(), QWIDGETSIZE_MAX); + *maxRowHeights = QVector(rowCount(), QWIDGETSIZE_MAX); + for (int row=0; rowat(col) > maxSize.width()) + (*maxColWidths)[col] = maxSize.width(); + if (maxRowHeights->at(row) > maxSize.height()) + (*maxRowHeights)[row] = maxSize.height(); + } + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutInset +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPLayoutInset + \brief A layout that places child elements aligned to the border or arbitrarily positioned + + Elements are placed either aligned to the border or at arbitrary position in the area of the + layout. Which placement applies is controlled with the \ref InsetPlacement (\ref + setInsetPlacement). + + Elements are added via \ref addElement(QCPLayoutElement *element, Qt::Alignment alignment) or + addElement(QCPLayoutElement *element, const QRectF &rect). If the first method is used, the inset + placement will default to \ref ipBorderAligned and the element will be aligned according to the + \a alignment parameter. The second method defaults to \ref ipFree and allows placing elements at + arbitrary position and size, defined by \a rect. + + The alignment or rect can be set via \ref setInsetAlignment or \ref setInsetRect, respectively. + + This is the layout that every QCPAxisRect has as \ref QCPAxisRect::insetLayout. +*/ + +/* start documentation of inline functions */ + +/*! \fn virtual void QCPLayoutInset::simplify() + + The QCPInsetLayout does not need simplification since it can never have empty cells due to its + linear index structure. This method does nothing. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutInset and sets default values. +*/ +QCPLayoutInset::QCPLayoutInset() +{ +} + +QCPLayoutInset::~QCPLayoutInset() +{ + // clear all child layout elements. This is important because only the specific layouts know how + // to handle removing elements (clear calls virtual removeAt method to do that). + clear(); +} + +/*! + Returns the placement type of the element with the specified \a index. +*/ +QCPLayoutInset::InsetPlacement QCPLayoutInset::insetPlacement(int index) const +{ + if (elementAt(index)) + return mInsetPlacement.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return ipFree; + } +} + +/*! + Returns the alignment of the element with the specified \a index. The alignment only has a + meaning, if the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned. +*/ +Qt::Alignment QCPLayoutInset::insetAlignment(int index) const +{ + if (elementAt(index)) + return mInsetAlignment.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return 0; + } +} + +/*! + Returns the rect of the element with the specified \a index. The rect only has a + meaning, if the inset placement (\ref setInsetPlacement) is \ref ipFree. +*/ +QRectF QCPLayoutInset::insetRect(int index) const +{ + if (elementAt(index)) + return mInsetRect.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return QRectF(); + } +} + +/*! + Sets the inset placement type of the element with the specified \a index to \a placement. + + \see InsetPlacement +*/ +void QCPLayoutInset::setInsetPlacement(int index, QCPLayoutInset::InsetPlacement placement) +{ + if (elementAt(index)) + mInsetPlacement[index] = placement; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/*! + If the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned, this function + is used to set the alignment of the element with the specified \a index to \a alignment. + + \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, + Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other + alignment flags will be ignored. +*/ +void QCPLayoutInset::setInsetAlignment(int index, Qt::Alignment alignment) +{ + if (elementAt(index)) + mInsetAlignment[index] = alignment; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/*! + If the inset placement (\ref setInsetPlacement) is \ref ipFree, this function is used to set the + position and size of the element with the specified \a index to \a rect. + + \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) + will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right + corner of the layout, with 35% width and height of the parent layout. + + Note that the minimum and maximum sizes of the embedded element (\ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize) are enforced. +*/ +void QCPLayoutInset::setInsetRect(int index, const QRectF &rect) +{ + if (elementAt(index)) + mInsetRect[index] = rect; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/* inherits documentation from base class */ +void QCPLayoutInset::updateLayout() +{ + for (int i=0; i finalMaxSize.width()) + insetRect.setWidth(finalMaxSize.width()); + if (insetRect.size().height() > finalMaxSize.height()) + insetRect.setHeight(finalMaxSize.height()); + } else if (mInsetPlacement.at(i) == ipBorderAligned) + { + insetRect.setSize(finalMinSize); + Qt::Alignment al = mInsetAlignment.at(i); + if (al.testFlag(Qt::AlignLeft)) insetRect.moveLeft(rect().x()); + else if (al.testFlag(Qt::AlignRight)) insetRect.moveRight(rect().x()+rect().width()); + else insetRect.moveLeft(rect().x()+rect().width()*0.5-finalMinSize.width()*0.5); // default to Qt::AlignHCenter + if (al.testFlag(Qt::AlignTop)) insetRect.moveTop(rect().y()); + else if (al.testFlag(Qt::AlignBottom)) insetRect.moveBottom(rect().y()+rect().height()); + else insetRect.moveTop(rect().y()+rect().height()*0.5-finalMinSize.height()*0.5); // default to Qt::AlignVCenter + } + mElements.at(i)->setOuterRect(insetRect); + } +} + +/* inherits documentation from base class */ +int QCPLayoutInset::elementCount() const +{ + return mElements.size(); +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutInset::elementAt(int index) const +{ + if (index >= 0 && index < mElements.size()) + return mElements.at(index); + else + return 0; +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutInset::takeAt(int index) +{ + if (QCPLayoutElement *el = elementAt(index)) + { + releaseElement(el); + mElements.removeAt(index); + mInsetPlacement.removeAt(index); + mInsetAlignment.removeAt(index); + mInsetRect.removeAt(index); + return el; + } else + { + qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; + return 0; + } +} + +/* inherits documentation from base class */ +bool QCPLayoutInset::take(QCPLayoutElement *element) +{ + if (element) + { + for (int i=0; irealVisibility() && mElements.at(i)->selectTest(pos, onlySelectable) >= 0) + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/*! + Adds the specified \a element to the layout as an inset aligned at the border (\ref + setInsetAlignment is initialized with \ref ipBorderAligned). The alignment is set to \a + alignment. + + \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, + Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other + alignment flags will be ignored. + + \see addElement(QCPLayoutElement *element, const QRectF &rect) +*/ +void QCPLayoutInset::addElement(QCPLayoutElement *element, Qt::Alignment alignment) +{ + if (element) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + mElements.append(element); + mInsetPlacement.append(ipBorderAligned); + mInsetAlignment.append(alignment); + mInsetRect.append(QRectF(0.6, 0.6, 0.4, 0.4)); + adoptElement(element); + } else + qDebug() << Q_FUNC_INFO << "Can't add null element"; +} + +/*! + Adds the specified \a element to the layout as an inset with free positioning/sizing (\ref + setInsetAlignment is initialized with \ref ipFree). The position and size is set to \a + rect. + + \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) + will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right + corner of the layout, with 35% width and height of the parent layout. + + \see addElement(QCPLayoutElement *element, Qt::Alignment alignment) +*/ +void QCPLayoutInset::addElement(QCPLayoutElement *element, const QRectF &rect) +{ + if (element) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + mElements.append(element); + mInsetPlacement.append(ipFree); + mInsetAlignment.append(Qt::AlignRight|Qt::AlignTop); + mInsetRect.append(rect); + adoptElement(element); + } else + qDebug() << Q_FUNC_INFO << "Can't add null element"; +} +/* end of 'src/layout.cpp' */ + + +/* including file 'src/lineending.cpp', size 11536 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLineEnding +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLineEnding + \brief Handles the different ending decorations for line-like items + + \image html QCPLineEnding.png "The various ending styles currently supported" + + For every ending a line-like item has, an instance of this class exists. For example, QCPItemLine + has two endings which can be set with QCPItemLine::setHead and QCPItemLine::setTail. + + The styles themselves are defined via the enum QCPLineEnding::EndingStyle. Most decorations can + be modified regarding width and length, see \ref setWidth and \ref setLength. The direction of + the ending decoration (e.g. direction an arrow is pointing) is controlled by the line-like item. + For example, when both endings of a QCPItemLine are set to be arrows, they will point to opposite + directions, e.g. "outward". This can be changed by \ref setInverted, which would make the + respective arrow point inward. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify a + QCPLineEnding::EndingStyle where actually a QCPLineEnding is expected, e.g. + \snippet documentation/doc-code-snippets/mainwindow.cpp qcplineending-sethead +*/ + +/*! + Creates a QCPLineEnding instance with default values (style \ref esNone). +*/ +QCPLineEnding::QCPLineEnding() : + mStyle(esNone), + mWidth(8), + mLength(10), + mInverted(false) +{ +} + +/*! + Creates a QCPLineEnding instance with the specified values. +*/ +QCPLineEnding::QCPLineEnding(QCPLineEnding::EndingStyle style, double width, double length, bool inverted) : + mStyle(style), + mWidth(width), + mLength(length), + mInverted(inverted) +{ +} + +/*! + Sets the style of the ending decoration. +*/ +void QCPLineEnding::setStyle(QCPLineEnding::EndingStyle style) +{ + mStyle = style; +} + +/*! + Sets the width of the ending decoration, if the style supports it. On arrows, for example, the + width defines the size perpendicular to the arrow's pointing direction. + + \see setLength +*/ +void QCPLineEnding::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the length of the ending decoration, if the style supports it. On arrows, for example, the + length defines the size in pointing direction. + + \see setWidth +*/ +void QCPLineEnding::setLength(double length) +{ + mLength = length; +} + +/*! + Sets whether the ending decoration shall be inverted. For example, an arrow decoration will point + inward when \a inverted is set to true. + + Note that also the \a width direction is inverted. For symmetrical ending styles like arrows or + discs, this doesn't make a difference. However, asymmetric styles like \ref esHalfBar are + affected by it, which can be used to control to which side the half bar points to. +*/ +void QCPLineEnding::setInverted(bool inverted) +{ + mInverted = inverted; +} + +/*! \internal + + Returns the maximum pixel radius the ending decoration might cover, starting from the position + the decoration is drawn at (typically a line ending/\ref QCPItemPosition of an item). + + This is relevant for clipping. Only omit painting of the decoration when the position where the + decoration is supposed to be drawn is farther away from the clipping rect than the returned + distance. +*/ +double QCPLineEnding::boundingDistance() const +{ + switch (mStyle) + { + case esNone: + return 0; + + case esFlatArrow: + case esSpikeArrow: + case esLineArrow: + case esSkewedBar: + return qSqrt(mWidth*mWidth+mLength*mLength); // items that have width and length + + case esDisc: + case esSquare: + case esDiamond: + case esBar: + case esHalfBar: + return mWidth*1.42; // items that only have a width -> width*sqrt(2) + + } + return 0; +} + +/*! + Starting from the origin of this line ending (which is style specific), returns the length + covered by the line ending symbol, in backward direction. + + For example, the \ref esSpikeArrow has a shorter real length than a \ref esFlatArrow, even if + both have the same \ref setLength value, because the spike arrow has an inward curved back, which + reduces the length along its center axis (the drawing origin for arrows is at the tip). + + This function is used for precise, style specific placement of line endings, for example in + QCPAxes. +*/ +double QCPLineEnding::realLength() const +{ + switch (mStyle) + { + case esNone: + case esLineArrow: + case esSkewedBar: + case esBar: + case esHalfBar: + return 0; + + case esFlatArrow: + return mLength; + + case esDisc: + case esSquare: + case esDiamond: + return mWidth*0.5; + + case esSpikeArrow: + return mLength*0.8; + } + return 0; +} + +/*! \internal + + Draws the line ending with the specified \a painter at the position \a pos. The direction of the + line ending is controlled with \a dir. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const +{ + if (mStyle == esNone) + return; + + QCPVector2D lengthVec = dir.normalized() * mLength*(mInverted ? -1 : 1); + if (lengthVec.isNull()) + lengthVec = QCPVector2D(1, 0); + QCPVector2D widthVec = dir.normalized().perpendicular() * mWidth*0.5*(mInverted ? -1 : 1); + + QPen penBackup = painter->pen(); + QBrush brushBackup = painter->brush(); + QPen miterPen = penBackup; + miterPen.setJoinStyle(Qt::MiterJoin); // to make arrow heads spikey + QBrush brush(painter->pen().color(), Qt::SolidPattern); + switch (mStyle) + { + case esNone: break; + case esFlatArrow: + { + QPointF points[3] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 3); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esSpikeArrow: + { + QPointF points[4] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec*0.8).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esLineArrow: + { + QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(), + pos.toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->drawPolyline(points, 3); + painter->setPen(penBackup); + break; + } + case esDisc: + { + painter->setBrush(brush); + painter->drawEllipse(pos.toPointF(), mWidth*0.5, mWidth*0.5); + painter->setBrush(brushBackup); + break; + } + case esSquare: + { + QCPVector2D widthVecPerp = widthVec.perpendicular(); + QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(), + (pos-widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esDiamond: + { + QCPVector2D widthVecPerp = widthVec.perpendicular(); + QPointF points[4] = {(pos-widthVecPerp).toPointF(), + (pos-widthVec).toPointF(), + (pos+widthVecPerp).toPointF(), + (pos+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esBar: + { + painter->drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF()); + break; + } + case esHalfBar: + { + painter->drawLine((pos+widthVec).toPointF(), pos.toPointF()); + break; + } + case esSkewedBar: + { + if (qFuzzyIsNull(painter->pen().widthF()) && !painter->modes().testFlag(QCPPainter::pmNonCosmetic)) + { + // if drawing with cosmetic pen (perfectly thin stroke, happens only in vector exports), draw bar exactly on tip of line + painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)).toPointF(), + (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)).toPointF()); + } else + { + // if drawing with thick (non-cosmetic) pen, shift bar a little in line direction to prevent line from sticking through bar slightly + painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF(), + (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF()); + } + break; + } + } +} + +/*! \internal + \overload + + Draws the line ending. The direction is controlled with the \a angle parameter in radians. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const +{ + draw(painter, pos, QCPVector2D(qCos(angle), qSin(angle))); +} +/* end of 'src/lineending.cpp' */ + + +/* including file 'src/axis/axisticker.cpp', size 18664 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTicker +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTicker + \brief The base class tick generator used by QCPAxis to create tick positions and tick labels + + Each QCPAxis has an internal QCPAxisTicker (or a subclass) in order to generate tick positions + and tick labels for the current axis range. The ticker of an axis can be set via \ref + QCPAxis::setTicker. Since that method takes a QSharedPointer, multiple + axes can share the same ticker instance. + + This base class generates normal tick coordinates and numeric labels for linear axes. It picks a + reasonable tick step (the separation between ticks) which results in readable tick labels. The + number of ticks that should be approximately generated can be set via \ref setTickCount. + Depending on the current tick step strategy (\ref setTickStepStrategy), the algorithm either + sacrifices readability to better match the specified tick count (\ref + QCPAxisTicker::tssMeetTickCount) or relaxes the tick count in favor of better tick steps (\ref + QCPAxisTicker::tssReadability), which is the default. + + The following more specialized axis ticker subclasses are available, see details in the + respective class documentation: + +
+ + + + + + + +
QCPAxisTickerFixed\image html axisticker-fixed.png
QCPAxisTickerLog\image html axisticker-log.png
QCPAxisTickerPi\image html axisticker-pi.png
QCPAxisTickerText\image html axisticker-text.png
QCPAxisTickerDateTime\image html axisticker-datetime.png
QCPAxisTickerTime\image html axisticker-time.png + \image html axisticker-time2.png
+
+ + \section axisticker-subclassing Creating own axis tickers + + Creating own axis tickers can be achieved very easily by sublassing QCPAxisTicker and + reimplementing some or all of the available virtual methods. + + In the simplest case you might wish to just generate different tick steps than the other tickers, + so you only reimplement the method \ref getTickStep. If you additionally want control over the + string that will be shown as tick label, reimplement \ref getTickLabel. + + If you wish to have complete control, you can generate the tick vectors and tick label vectors + yourself by reimplementing \ref createTickVector and \ref createLabelVector. The default + implementations use the previously mentioned virtual methods \ref getTickStep and \ref + getTickLabel, but your reimplementations don't necessarily need to do so. For example in the case + of unequal tick steps, the method \ref getTickStep loses its usefulness and can be ignored. + + The sub tick count between major ticks can be controlled with \ref getSubTickCount. Full sub tick + placement control is obtained by reimplementing \ref createSubTickVector. + + See the documentation of all these virtual methods in QCPAxisTicker for detailed information + about the parameters and expected return values. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTicker::QCPAxisTicker() : + mTickStepStrategy(tssReadability), + mTickCount(5), + mTickOrigin(0) +{ +} + +QCPAxisTicker::~QCPAxisTicker() +{ + +} + +/*! + Sets which strategy the axis ticker follows when choosing the size of the tick step. For the + available strategies, see \ref TickStepStrategy. +*/ +void QCPAxisTicker::setTickStepStrategy(QCPAxisTicker::TickStepStrategy strategy) +{ + mTickStepStrategy = strategy; +} + +/*! + Sets how many ticks this ticker shall aim to generate across the axis range. Note that \a count + is not guaranteed to be matched exactly, as generating readable tick intervals may conflict with + the requested number of ticks. + + Whether the readability has priority over meeting the requested \a count can be specified with + \ref setTickStepStrategy. +*/ +void QCPAxisTicker::setTickCount(int count) +{ + if (count > 0) + mTickCount = count; + else + qDebug() << Q_FUNC_INFO << "tick count must be greater than zero:" << count; +} + +/*! + Sets the mathematical coordinate (or "offset") of the zeroth tick. This tick coordinate is just a + concept and doesn't need to be inside the currently visible axis range. + + By default \a origin is zero, which for example yields ticks {-5, 0, 5, 10, 15,...} when the tick + step is five. If \a origin is now set to 1 instead, the correspondingly generated ticks would be + {-4, 1, 6, 11, 16,...}. +*/ +void QCPAxisTicker::setTickOrigin(double origin) +{ + mTickOrigin = origin; +} + +/*! + This is the method called by QCPAxis in order to actually generate tick coordinates (\a ticks), + tick label strings (\a tickLabels) and sub tick coordinates (\a subTicks). + + The ticks are generated for the specified \a range. The generated labels typically follow the + specified \a locale, \a formatChar and number \a precision, however this might be different (or + even irrelevant) for certain QCPAxisTicker subclasses. + + The output parameter \a ticks is filled with the generated tick positions in axis coordinates. + The output parameters \a subTicks and \a tickLabels are optional (set them to 0 if not needed) + and are respectively filled with sub tick coordinates, and tick label strings belonging to \a + ticks by index. +*/ +void QCPAxisTicker::generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels) +{ + // generate (major) ticks: + double tickStep = getTickStep(range); + ticks = createTickVector(tickStep, range); + trimTicks(range, ticks, true); // trim ticks to visible range plus one outer tick on each side (incase a subclass createTickVector creates more) + + // generate sub ticks between major ticks: + if (subTicks) + { + if (ticks.size() > 0) + { + *subTicks = createSubTickVector(getSubTickCount(tickStep), ticks); + trimTicks(range, *subTicks, false); + } else + *subTicks = QVector(); + } + + // finally trim also outliers (no further clipping happens in axis drawing): + trimTicks(range, ticks, false); + // generate labels for visible ticks if requested: + if (tickLabels) + *tickLabels = createLabelVector(ticks, locale, formatChar, precision); +} + +/*! \internal + + Takes the entire currently visible axis range and returns a sensible tick step in + order to provide readable tick labels as well as a reasonable number of tick counts (see \ref + setTickCount, \ref setTickStepStrategy). + + If a QCPAxisTicker subclass only wants a different tick step behaviour than the default + implementation, it should reimplement this method. See \ref cleanMantissa for a possible helper + function. +*/ +double QCPAxisTicker::getTickStep(const QCPRange &range) +{ + double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + return cleanMantissa(exactStep); +} + +/*! \internal + + Takes the \a tickStep, i.e. the distance between two consecutive ticks, and returns + an appropriate number of sub ticks for that specific tick step. + + Note that a returned sub tick count of e.g. 4 will split each tick interval into 5 sections. +*/ +int QCPAxisTicker::getSubTickCount(double tickStep) +{ + int result = 1; // default to 1, if no proper value can be found + + // separate integer and fractional part of mantissa: + double epsilon = 0.01; + double intPartf; + int intPart; + double fracPart = modf(getMantissa(tickStep), &intPartf); + intPart = intPartf; + + // handle cases with (almost) integer mantissa: + if (fracPart < epsilon || 1.0-fracPart < epsilon) + { + if (1.0-fracPart < epsilon) + ++intPart; + switch (intPart) + { + case 1: result = 4; break; // 1.0 -> 0.2 substep + case 2: result = 3; break; // 2.0 -> 0.5 substep + case 3: result = 2; break; // 3.0 -> 1.0 substep + case 4: result = 3; break; // 4.0 -> 1.0 substep + case 5: result = 4; break; // 5.0 -> 1.0 substep + case 6: result = 2; break; // 6.0 -> 2.0 substep + case 7: result = 6; break; // 7.0 -> 1.0 substep + case 8: result = 3; break; // 8.0 -> 2.0 substep + case 9: result = 2; break; // 9.0 -> 3.0 substep + } + } else + { + // handle cases with significantly fractional mantissa: + if (qAbs(fracPart-0.5) < epsilon) // *.5 mantissa + { + switch (intPart) + { + case 1: result = 2; break; // 1.5 -> 0.5 substep + case 2: result = 4; break; // 2.5 -> 0.5 substep + case 3: result = 4; break; // 3.5 -> 0.7 substep + case 4: result = 2; break; // 4.5 -> 1.5 substep + case 5: result = 4; break; // 5.5 -> 1.1 substep (won't occur with default getTickStep from here on) + case 6: result = 4; break; // 6.5 -> 1.3 substep + case 7: result = 2; break; // 7.5 -> 2.5 substep + case 8: result = 4; break; // 8.5 -> 1.7 substep + case 9: result = 4; break; // 9.5 -> 1.9 substep + } + } + // if mantissa fraction isn't 0.0 or 0.5, don't bother finding good sub tick marks, leave default + } + + return result; +} + +/*! \internal + + This method returns the tick label string as it should be printed under the \a tick coordinate. + If a textual number is returned, it should respect the provided \a locale, \a formatChar and \a + precision. + + If the returned value contains exponentials of the form "2e5" and beautifully typeset powers is + enabled in the QCPAxis number format (\ref QCPAxis::setNumberFormat), the exponential part will + be formatted accordingly using multiplication symbol and superscript during rendering of the + label automatically. +*/ +QString QCPAxisTicker::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + return locale.toString(tick, formatChar.toLatin1(), precision); +} + +/*! \internal + + Returns a vector containing all coordinates of sub ticks that should be drawn. It generates \a + subTickCount sub ticks between each tick pair given in \a ticks. + + If a QCPAxisTicker subclass needs maximal control over the generated sub ticks, it should + reimplement this method. Depending on the purpose of the subclass it doesn't necessarily need to + base its result on \a subTickCount or \a ticks. +*/ +QVector QCPAxisTicker::createSubTickVector(int subTickCount, const QVector &ticks) +{ + QVector result; + if (subTickCount <= 0 || ticks.size() < 2) + return result; + + result.reserve((ticks.size()-1)*subTickCount); + for (int i=1; i QCPAxisTicker::createTickVector(double tickStep, const QCPRange &range) +{ + QVector result; + // Generate tick positions according to tickStep: + qint64 firstStep = floor((range.lower-mTickOrigin)/tickStep); // do not use qFloor here, or we'll lose 64 bit precision + qint64 lastStep = ceil((range.upper-mTickOrigin)/tickStep); // do not use qCeil here, or we'll lose 64 bit precision + int tickcount = lastStep-firstStep+1; + if (tickcount < 0) tickcount = 0; + result.resize(tickcount); + for (int i=0; i QCPAxisTicker::createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision) +{ + QVector result; + result.reserve(ticks.size()); + for (int i=0; i &ticks, bool keepOneOutlier) const +{ + bool lowFound = false; + bool highFound = false; + int lowIndex = 0; + int highIndex = -1; + + for (int i=0; i < ticks.size(); ++i) + { + if (ticks.at(i) >= range.lower) + { + lowFound = true; + lowIndex = i; + break; + } + } + for (int i=ticks.size()-1; i >= 0; --i) + { + if (ticks.at(i) <= range.upper) + { + highFound = true; + highIndex = i; + break; + } + } + + if (highFound && lowFound) + { + int trimFront = qMax(0, lowIndex-(keepOneOutlier ? 1 : 0)); + int trimBack = qMax(0, ticks.size()-(keepOneOutlier ? 2 : 1)-highIndex); + if (trimFront > 0 || trimBack > 0) + ticks = ticks.mid(trimFront, ticks.size()-trimFront-trimBack); + } else // all ticks are either all below or all above the range + ticks.clear(); +} + +/*! \internal + + Returns the coordinate contained in \a candidates which is closest to the provided \a target. + + This method assumes \a candidates is not empty and sorted in ascending order. +*/ +double QCPAxisTicker::pickClosest(double target, const QVector &candidates) const +{ + if (candidates.size() == 1) + return candidates.first(); + QVector::const_iterator it = std::lower_bound(candidates.constBegin(), candidates.constEnd(), target); + if (it == candidates.constEnd()) + return *(it-1); + else if (it == candidates.constBegin()) + return *it; + else + return target-*(it-1) < *it-target ? *(it-1) : *it; +} + +/*! \internal + + Returns the decimal mantissa of \a input. Optionally, if \a magnitude is not set to zero, it also + returns the magnitude of \a input as a power of 10. + + For example, an input of 142.6 will return a mantissa of 1.426 and a magnitude of 100. +*/ +double QCPAxisTicker::getMantissa(double input, double *magnitude) const +{ + const double mag = qPow(10.0, qFloor(qLn(input)/qLn(10.0))); + if (magnitude) *magnitude = mag; + return input/mag; +} + +/*! \internal + + Returns a number that is close to \a input but has a clean, easier human readable mantissa. How + strongly the mantissa is altered, and thus how strong the result deviates from the original \a + input, depends on the current tick step strategy (see \ref setTickStepStrategy). +*/ +double QCPAxisTicker::cleanMantissa(double input) const +{ + double magnitude; + const double mantissa = getMantissa(input, &magnitude); + switch (mTickStepStrategy) + { + case tssReadability: + { + return pickClosest(mantissa, QVector() << 1.0 << 2.0 << 2.5 << 5.0 << 10.0)*magnitude; + } + case tssMeetTickCount: + { + // this gives effectively a mantissa of 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 8.0, 10.0 + if (mantissa <= 5.0) + return (int)(mantissa*2)/2.0*magnitude; // round digit after decimal point to 0.5 + else + return (int)(mantissa/2.0)*2.0*magnitude; // round to first digit in multiples of 2 + } + } + return input; +} +/* end of 'src/axis/axisticker.cpp' */ + + +/* including file 'src/axis/axistickerdatetime.cpp', size 14443 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerDateTime +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerDateTime + \brief Specialized axis ticker for calendar dates and times as axis ticks + + \image html axisticker-datetime.png + + This QCPAxisTicker subclass generates ticks that correspond to real calendar dates and times. The + plot axis coordinate is interpreted as Unix Time, so seconds since Epoch (January 1, 1970, 00:00 + UTC). This is also used for example by QDateTime in the toTime_t()/setTime_t() methods + with a precision of one second. Since Qt 4.7, millisecond accuracy can be obtained from QDateTime + by using QDateTime::fromMSecsSinceEpoch()/1000.0. The static methods \ref dateTimeToKey + and \ref keyToDateTime conveniently perform this conversion achieving a precision of one + millisecond on all Qt versions. + + The format of the date/time display in the tick labels is controlled with \ref setDateTimeFormat. + If a different time spec (time zone) shall be used, see \ref setDateTimeSpec. + + This ticker produces unequal tick spacing in order to provide intuitive date and time-of-day + ticks. For example, if the axis range spans a few years such that there is one tick per year, + ticks will be positioned on 1. January of every year. This is intuitive but, due to leap years, + will result in slightly unequal tick intervals (visually unnoticeable). The same can be seen in + the image above: even though the number of days varies month by month, this ticker generates + ticks on the same day of each month. + + If you would like to change the date/time that is used as a (mathematical) starting date for the + ticks, use the \ref setTickOrigin(const QDateTime &origin) method overload, which takes a + QDateTime. If you pass 15. July, 9:45 to this method, the yearly ticks will end up on 15. July at + 9:45 of every year. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerdatetime-creation + + \note If you rather wish to display relative times in terms of days, hours, minutes, seconds and + milliseconds, and are not interested in the intricacies of real calendar dates with months and + (leap) years, have a look at QCPAxisTickerTime instead. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerDateTime::QCPAxisTickerDateTime() : + mDateTimeFormat(QLatin1String("hh:mm:ss\ndd.MM.yy")), + mDateTimeSpec(Qt::LocalTime), + mDateStrategy(dsNone) +{ + setTickCount(4); +} + +/*! + Sets the format in which dates and times are displayed as tick labels. For details about the \a + format string, see the documentation of QDateTime::toString(). + + Newlines can be inserted with "\n". + + \see setDateTimeSpec +*/ +void QCPAxisTickerDateTime::setDateTimeFormat(const QString &format) +{ + mDateTimeFormat = format; +} + +/*! + Sets the time spec that is used for creating the tick labels from corresponding dates/times. + + The default value of QDateTime objects (and also QCPAxisTickerDateTime) is + Qt::LocalTime. However, if the date time values passed to QCustomPlot (e.g. in the form + of axis ranges or keys of a plottable) are given in the UTC spec, set \a spec to Qt::UTC + to get the correct axis labels. + + \see setDateTimeFormat +*/ +void QCPAxisTickerDateTime::setDateTimeSpec(Qt::TimeSpec spec) +{ + mDateTimeSpec = spec; +} + +/*! + Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) in seconds since Epoch (1. Jan 1970, + 00:00 UTC). For the date time ticker it might be more intuitive to use the overload which + directly takes a QDateTime, see \ref setTickOrigin(const QDateTime &origin). + + This is useful to define the month/day/time recurring at greater tick interval steps. For + example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick + per year, the ticks will end up on 15. July at 9:45 of every year. +*/ +void QCPAxisTickerDateTime::setTickOrigin(double origin) +{ + QCPAxisTicker::setTickOrigin(origin); +} + +/*! + Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) as a QDateTime \a origin. + + This is useful to define the month/day/time recurring at greater tick interval steps. For + example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick + per year, the ticks will end up on 15. July at 9:45 of every year. +*/ +void QCPAxisTickerDateTime::setTickOrigin(const QDateTime &origin) +{ + setTickOrigin(dateTimeToKey(origin)); +} + +/*! \internal + + Returns a sensible tick step with intervals appropriate for a date-time-display, such as weekly, + monthly, bi-monthly, etc. + + Note that this tick step isn't used exactly when generating the tick vector in \ref + createTickVector, but only as a guiding value requiring some correction for each individual tick + interval. Otherwise this would lead to unintuitive date displays, e.g. jumping between first day + in the month to the last day in the previous month from tick to tick, due to the non-uniform + length of months. The same problem arises with leap years. + + \seebaseclassmethod +*/ +double QCPAxisTickerDateTime::getTickStep(const QCPRange &range) +{ + double result = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + + mDateStrategy = dsNone; + if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds + { + result = cleanMantissa(result); + } else if (result < 86400*30437.5*12) // below a year + { +// result = pickClosest(result, QVector() +// << 1 << 2.5 << 5 << 10 << 15 << 30 << 60 << 2.5*60 << 5*60 << 10*60 << 15*60 << 30*60 << 60*60 // second, minute, hour range +// << 3600*2 << 3600*3 << 3600*6 << 3600*12 << 3600*24 // hour to day range +// << 86400*2 << 86400*5 << 86400*7 << 86400*14 << 86400*30.4375 << 86400*30.4375*2 << 86400*30.4375*3 << 86400*30.4375*6 << 86400*30.4375*12); // day, week, month range (avg. days per month includes leap years) + result = pickClosest(result, QVector() + << 1000 << 1000*2.5 << 1000*5 << 1000*10 << 1000*15 << 1000*30 << 1000*60 << 1000*2.5*60 << 1000*5*60 << 1000*10*60 << 1000*15*60 << 1000*30*60 << 1000*60*60 // second, minute, hour range + << 1000*3600*2 << 1000*3600*3 << 1000*3600*6 << 1000*3600*12 << 1000*3600*24 // hour to day range + << 1000*86400*2 << 1000*86400*5 << 1000*86400*7 << 1000*86400*14 << 1000*86400*30.4375 << 1000*86400*30.4375*2 << 1000*86400*30.4375*3 << 1000*86400*30.4375*6 << 1000*86400*30.4375*12); // day, week, month range (avg. days per month includes leap years) + if (result > 86400*30437.5-1) // month tick intervals or larger + mDateStrategy = dsUniformDayInMonth; + else if (result > 3600*24*1000-1) // day tick intervals or larger + mDateStrategy = dsUniformTimeInDay; + } else // more than a year, go back to normal clean mantissa algorithm but in units of years + { + const double secondsPerYear = 86400*30437.5*12; // average including leap years + result = cleanMantissa(result/secondsPerYear)*secondsPerYear; + mDateStrategy = dsUniformDayInMonth; + } + return result; +} + +/*! \internal + + Returns a sensible sub tick count with intervals appropriate for a date-time-display, such as weekly, + monthly, bi-monthly, etc. + + \seebaseclassmethod +*/ +int QCPAxisTickerDateTime::getSubTickCount(double tickStep) +{ + int result = QCPAxisTicker::getSubTickCount(tickStep); + switch (qRound64(tickStep)) // hand chosen subticks for specific minute/hour/day/week/month range (as specified in getTickStep) + { + case 5*1000*60: result = 4; break; + case 10*1000*60: result = 1; break; + case 15*1000*60: result = 2; break; + case 30*1000*60: result = 1; break; + case 60*1000*60: result = 3; break; + case 3600*1000*2: result = 3; break; + case 3600*1000*3: result = 2; break; + case 3600*1000*6: result = 1; break; + case 3600*1000*12: result = 3; break; + case 3600*1000*24: result = 3; break; + case 86400*1000*2: result = 1; break; + case 86400*1000*5: result = 4; break; + case 86400*1000*7: result = 6; break; + case 86400*1000*14: result = 1; break; + case (qint64)(86400*1000*30.4375+0.5): result = 3; break; + case (qint64)(86400*1000*30.4375*2+0.5): result = 1; break; + case (qint64)(86400*1000*30.4375*3+0.5): result = 2; break; + case (qint64)(86400*1000*30.4375*6+0.5): result = 5; break; + case (qint64)(86400*1000*30.4375*12+0.5): result = 3; break; + } + return result; +} + +/*! \internal + + Generates a date/time tick label for tick coordinate \a tick, based on the currently set format + (\ref setDateTimeFormat) and time spec (\ref setDateTimeSpec). + + \seebaseclassmethod +*/ +QString QCPAxisTickerDateTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + Q_UNUSED(precision) + Q_UNUSED(formatChar) + return locale.toString(keyToDateTime(tick).toTimeSpec(mDateTimeSpec), mDateTimeFormat); +} + +/*! \internal + + Uses the passed \a tickStep as a guiding value and applies corrections in order to obtain + non-uniform tick intervals but intuitive tick labels, e.g. falling on the same day of each month. + + \seebaseclassmethod +*/ +QVector QCPAxisTickerDateTime::createTickVector(double tickStep, const QCPRange &range) +{ + QVector result = QCPAxisTicker::createTickVector(tickStep, range); + if (!result.isEmpty()) + { + if (mDateStrategy == dsUniformTimeInDay) + { + QDateTime uniformDateTime = keyToDateTime(mTickOrigin); // the time of this datetime will be set for all other ticks, if possible + QDateTime tickDateTime; + for (int i=0; i 15) // with leap years involved, date month may jump backwards or forwards, and needs to be corrected before setting day + tickDateTime = tickDateTime.addMonths(-1); + tickDateTime.setDate(QDate(tickDateTime.date().year(), tickDateTime.date().month(), thisUniformDay)); + result[i] = dateTimeToKey(tickDateTime); + } + } + } + return result; +} + +/*! + A convenience method which turns \a key (in seconds since Epoch 1. Jan 1970, 00:00 UTC) into a + QDateTime object. This can be used to turn axis coordinates to actual QDateTimes. + + The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it + works around the lack of a QDateTime::fromMSecsSinceEpoch in Qt 4.6) + + \see dateTimeToKey +*/ +QDateTime QCPAxisTickerDateTime::keyToDateTime(double key) +{ + return QDateTime::fromMSecsSinceEpoch(key); +} + +/*! \overload + + A convenience method which turns a QDateTime object into a double value that corresponds to + seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by + QCPAxisTickerDateTime. + + The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it + works around the lack of a QDateTime::toMSecsSinceEpoch in Qt 4.6) + + \see keyToDateTime +*/ +double QCPAxisTickerDateTime::dateTimeToKey(const QDateTime dateTime) +{ + return dateTime.toMSecsSinceEpoch(); +} + +/*! \overload + + A convenience method which turns a QDate object into a double value that corresponds to + seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by + QCPAxisTickerDateTime. + + \see keyToDateTime +*/ +double QCPAxisTickerDateTime::dateTimeToKey(const QDate date) +{ + return QDateTime(date).toMSecsSinceEpoch(); +} +/* end of 'src/axis/axistickerdatetime.cpp' */ + + +/* including file 'src/axis/axistickertime.cpp', size 11747 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerTime +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerTime + \brief Specialized axis ticker for time spans in units of milliseconds to days + + \image html axisticker-time.png + + This QCPAxisTicker subclass generates ticks that corresponds to time intervals. + + The format of the time display in the tick labels is controlled with \ref setTimeFormat and \ref + setFieldWidth. The time coordinate is in the unit of seconds with respect to the time coordinate + zero. Unlike with QCPAxisTickerDateTime, the ticks don't correspond to a specific calendar date + and time. + + The time can be displayed in milliseconds, seconds, minutes, hours and days. Depending on the + largest available unit in the format specified with \ref setTimeFormat, any time spans above will + be carried in that largest unit. So for example if the format string is "%m:%s" and a tick at + coordinate value 7815 (being 2 hours, 10 minutes and 15 seconds) is created, the resulting tick + label will show "130:15" (130 minutes, 15 seconds). If the format string is "%h:%m:%s", the hour + unit will be used and the label will thus be "02:10:15". Negative times with respect to the axis + zero will carry a leading minus sign. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation + + Here is an example of a time axis providing time information in days, hours and minutes. Due to + the axis range spanning a few days and the wanted tick count (\ref setTickCount), the ticker + decided to use tick steps of 12 hours: + + \image html axisticker-time2.png + + The format string for this example is + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation-2 + + \note If you rather wish to display calendar dates and times, have a look at QCPAxisTickerDateTime + instead. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerTime::QCPAxisTickerTime() : + mTimeFormat(QLatin1String("%h:%m:%s")), + mSmallestUnit(tuSeconds), + mBiggestUnit(tuHours) +{ + setTickCount(4); + mFieldWidth[tuMilliseconds] = 3; + mFieldWidth[tuSeconds] = 2; + mFieldWidth[tuMinutes] = 2; + mFieldWidth[tuHours] = 2; + mFieldWidth[tuDays] = 1; + + mFormatPattern[tuMilliseconds] = QLatin1String("%z"); + mFormatPattern[tuSeconds] = QLatin1String("%s"); + mFormatPattern[tuMinutes] = QLatin1String("%m"); + mFormatPattern[tuHours] = QLatin1String("%h"); + mFormatPattern[tuDays] = QLatin1String("%d"); +} + +/*! + Sets the format that will be used to display time in the tick labels. + + The available patterns are: + - %%z for milliseconds + - %%s for seconds + - %%m for minutes + - %%h for hours + - %%d for days + + The field width (zero padding) can be controlled for each unit with \ref setFieldWidth. + + The largest unit that appears in \a format will carry all the remaining time of a certain tick + coordinate, even if it overflows the natural limit of the unit. For example, if %%m is the + largest unit it might become larger than 59 in order to consume larger time values. If on the + other hand %%h is available, the minutes will wrap around to zero after 59 and the time will + carry to the hour digit. +*/ +void QCPAxisTickerTime::setTimeFormat(const QString &format) +{ + mTimeFormat = format; + + // determine smallest and biggest unit in format, to optimize unit replacement and allow biggest + // unit to consume remaining time of a tick value and grow beyond its modulo (e.g. min > 59) + mSmallestUnit = tuMilliseconds; + mBiggestUnit = tuMilliseconds; + bool hasSmallest = false; + for (int i = tuMilliseconds; i <= tuDays; ++i) + { + TimeUnit unit = static_cast(i); + if (mTimeFormat.contains(mFormatPattern.value(unit))) + { + if (!hasSmallest) + { + mSmallestUnit = unit; + hasSmallest = true; + } + mBiggestUnit = unit; + } + } +} + +/*! + Sets the field widh of the specified \a unit to be \a width digits, when displayed in the tick + label. If the number for the specific unit is shorter than \a width, it will be padded with an + according number of zeros to the left in order to reach the field width. + + \see setTimeFormat +*/ +void QCPAxisTickerTime::setFieldWidth(QCPAxisTickerTime::TimeUnit unit, int width) +{ + mFieldWidth[unit] = qMax(width, 1); +} + +/*! \internal + + Returns the tick step appropriate for time displays, depending on the provided \a range and the + smallest available time unit in the current format (\ref setTimeFormat). For example if the unit + of seconds isn't available in the format, this method will not generate steps (like 2.5 minutes) + that require sub-minute precision to be displayed correctly. + + \seebaseclassmethod +*/ +double QCPAxisTickerTime::getTickStep(const QCPRange &range) +{ + double result = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + + if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds + { + if (mSmallestUnit == tuMilliseconds) + result = qMax(cleanMantissa(result), 0.001); // smallest tick step is 1 millisecond + else // have no milliseconds available in format, so stick with 1 second tickstep + result = 1.0; + } else if (result < 3600*24) // below a day + { + // the filling of availableSteps seems a bit contorted but it fills in a sorted fashion and thus saves a post-fill sorting run + QVector availableSteps; + // seconds range: + if (mSmallestUnit <= tuSeconds) + availableSteps << 1; + if (mSmallestUnit == tuMilliseconds) + availableSteps << 2.5; // only allow half second steps if milliseconds are there to display it + else if (mSmallestUnit == tuSeconds) + availableSteps << 2; + if (mSmallestUnit <= tuSeconds) + availableSteps << 5 << 10 << 15 << 30; + // minutes range: + if (mSmallestUnit <= tuMinutes) + availableSteps << 1*60; + if (mSmallestUnit <= tuSeconds) + availableSteps << 2.5*60; // only allow half minute steps if seconds are there to display it + else if (mSmallestUnit == tuMinutes) + availableSteps << 2*60; + if (mSmallestUnit <= tuMinutes) + availableSteps << 5*60 << 10*60 << 15*60 << 30*60; + // hours range: + if (mSmallestUnit <= tuHours) + availableSteps << 1*3600 << 2*3600 << 3*3600 << 6*3600 << 12*3600 << 24*3600; + // pick available step that is most appropriate to approximate ideal step: + result = pickClosest(result, availableSteps); + } else // more than a day, go back to normal clean mantissa algorithm but in units of days + { + const double secondsPerDay = 3600*24; + result = cleanMantissa(result/secondsPerDay)*secondsPerDay; + } + return result; +} + +/*! \internal + + Returns the sub tick count appropriate for the provided \a tickStep and time displays. + + \seebaseclassmethod +*/ +int QCPAxisTickerTime::getSubTickCount(double tickStep) +{ + int result = QCPAxisTicker::getSubTickCount(tickStep); + switch (qRound(tickStep)) // hand chosen subticks for specific minute/hour/day range (as specified in getTickStep) + { + case 5*60: result = 4; break; + case 10*60: result = 1; break; + case 15*60: result = 2; break; + case 30*60: result = 1; break; + case 60*60: result = 3; break; + case 3600*2: result = 3; break; + case 3600*3: result = 2; break; + case 3600*6: result = 1; break; + case 3600*12: result = 3; break; + case 3600*24: result = 3; break; + } + return result; +} + +/*! \internal + + Returns the tick label corresponding to the provided \a tick and the configured format and field + widths (\ref setTimeFormat, \ref setFieldWidth). + + \seebaseclassmethod +*/ +QString QCPAxisTickerTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + Q_UNUSED(precision) + Q_UNUSED(formatChar) + Q_UNUSED(locale) + bool negative = tick < 0; + if (negative) tick *= -1; + double values[tuDays+1]; // contains the msec/sec/min/... value with its respective modulo (e.g. minute 0..59) + double restValues[tuDays+1]; // contains the msec/sec/min/... value as if it's the largest available unit and thus consumes the remaining time + + restValues[tuMilliseconds] = tick*1000; + values[tuMilliseconds] = modf(restValues[tuMilliseconds]/1000, &restValues[tuSeconds])*1000; + values[tuSeconds] = modf(restValues[tuSeconds]/60, &restValues[tuMinutes])*60; + values[tuMinutes] = modf(restValues[tuMinutes]/60, &restValues[tuHours])*60; + values[tuHours] = modf(restValues[tuHours]/24, &restValues[tuDays])*24; + // no need to set values[tuDays] because days are always a rest value (there is no higher unit so it consumes all remaining time) + + QString result = mTimeFormat; + for (int i = mSmallestUnit; i <= mBiggestUnit; ++i) + { + TimeUnit iUnit = static_cast(i); + replaceUnit(result, iUnit, qRound(iUnit == mBiggestUnit ? restValues[iUnit] : values[iUnit])); + } + if (negative) + result.prepend(QLatin1Char('-')); + return result; +} + +/*! \internal + + Replaces all occurrences of the format pattern belonging to \a unit in \a text with the specified + \a value, using the field width as specified with \ref setFieldWidth for the \a unit. +*/ +void QCPAxisTickerTime::replaceUnit(QString &text, QCPAxisTickerTime::TimeUnit unit, int value) const +{ + QString valueStr = QString::number(value); + while (valueStr.size() < mFieldWidth.value(unit)) + valueStr.prepend(QLatin1Char('0')); + + text.replace(mFormatPattern.value(unit), valueStr); +} +/* end of 'src/axis/axistickertime.cpp' */ + + +/* including file 'src/axis/axistickerfixed.cpp', size 5583 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerFixed +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerFixed + \brief Specialized axis ticker with a fixed tick step + + \image html axisticker-fixed.png + + This QCPAxisTicker subclass generates ticks with a fixed tick step set with \ref setTickStep. It + is also possible to allow integer multiples and integer powers of the specified tick step with + \ref setScaleStrategy. + + A typical application of this ticker is to make an axis only display integers, by setting the + tick step of the ticker to 1.0 and the scale strategy to \ref ssMultiples. + + Another case is when a certain number has a special meaning and axis ticks should only appear at + multiples of that value. In this case you might also want to consider \ref QCPAxisTickerPi + because despite the name it is not limited to only pi symbols/values. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerfixed-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerFixed::QCPAxisTickerFixed() : + mTickStep(1.0), + mScaleStrategy(ssNone) +{ +} + +/*! + Sets the fixed tick interval to \a step. + + The axis ticker will only use this tick step when generating axis ticks. This might cause a very + high tick density and overlapping labels if the axis range is zoomed out. Using \ref + setScaleStrategy it is possible to relax the fixed step and also allow multiples or powers of \a + step. This will enable the ticker to reduce the number of ticks to a reasonable amount (see \ref + setTickCount). +*/ +void QCPAxisTickerFixed::setTickStep(double step) +{ + if (step > 0) + mTickStep = step; + else + qDebug() << Q_FUNC_INFO << "tick step must be greater than zero:" << step; +} + +/*! + Sets whether the specified tick step (\ref setTickStep) is absolutely fixed or whether + modifications may be applied to it before calculating the finally used tick step, such as + permitting multiples or powers. See \ref ScaleStrategy for details. + + The default strategy is \ref ssNone, which means the tick step is absolutely fixed. +*/ +void QCPAxisTickerFixed::setScaleStrategy(QCPAxisTickerFixed::ScaleStrategy strategy) +{ + mScaleStrategy = strategy; +} + +/*! \internal + + Determines the actually used tick step from the specified tick step and scale strategy (\ref + setTickStep, \ref setScaleStrategy). + + This method either returns the specified tick step exactly, or, if the scale strategy is not \ref + ssNone, a modification of it to allow varying the number of ticks in the current axis range. + + \seebaseclassmethod +*/ +double QCPAxisTickerFixed::getTickStep(const QCPRange &range) +{ + switch (mScaleStrategy) + { + case ssNone: + { + return mTickStep; + } + case ssMultiples: + { + double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + if (exactStep < mTickStep) + return mTickStep; + else + return (qint64)(cleanMantissa(exactStep/mTickStep)+0.5)*mTickStep; + } + case ssPowers: + { + double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + return qPow(mTickStep, (int)(qLn(exactStep)/qLn(mTickStep)+0.5)); + } + } + return mTickStep; +} +/* end of 'src/axis/axistickerfixed.cpp' */ + + +/* including file 'src/axis/axistickertext.cpp', size 8653 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerText +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerText + \brief Specialized axis ticker which allows arbitrary labels at specified coordinates + + \image html axisticker-text.png + + This QCPAxisTicker subclass generates ticks which can be directly specified by the user as + coordinates and associated strings. They can be passed as a whole with \ref setTicks or one at a + time with \ref addTick. Alternatively you can directly access the internal storage via \ref ticks + and modify the tick/label data there. + + This is useful for cases where the axis represents categories rather than numerical values. + + If you are updating the ticks of this ticker regularly and in a dynamic fasion (e.g. dependent on + the axis range), it is a sign that you should probably create an own ticker by subclassing + QCPAxisTicker, instead of using this one. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertext-creation +*/ + +/* start of documentation of inline functions */ + +/*! \fn QMap &QCPAxisTickerText::ticks() + + Returns a non-const reference to the internal map which stores the tick coordinates and their + labels. + + You can access the map directly in order to add, remove or manipulate ticks, as an alternative to + using the methods provided by QCPAxisTickerText, such as \ref setTicks and \ref addTick. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerText::QCPAxisTickerText() : + mSubTickCount(0) +{ +} + +/*! \overload + + Sets the ticks that shall appear on the axis. The map key of \a ticks corresponds to the axis + coordinate, and the map value is the string that will appear as tick label. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTicks, addTick, clear +*/ +void QCPAxisTickerText::setTicks(const QMap &ticks) +{ + mTicks = ticks; +} + +/*! \overload + + Sets the ticks that shall appear on the axis. The entries of \a positions correspond to the axis + coordinates, and the entries of \a labels are the respective strings that will appear as tick + labels. + + \see addTicks, addTick, clear +*/ +void QCPAxisTickerText::setTicks(const QVector &positions, const QVector labels) +{ + clear(); + addTicks(positions, labels); +} + +/*! + Sets the number of sub ticks that shall appear between ticks. For QCPAxisTickerText, there is no + automatic sub tick count calculation. So if sub ticks are needed, they must be configured with this + method. +*/ +void QCPAxisTickerText::setSubTickCount(int subTicks) +{ + if (subTicks >= 0) + mSubTickCount = subTicks; + else + qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; +} + +/*! + Clears all ticks. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see setTicks, addTicks, addTick +*/ +void QCPAxisTickerText::clear() +{ + mTicks.clear(); +} + +/*! + Adds a single tick to the axis at the given axis coordinate \a position, with the provided tick \a + label. + + \see addTicks, setTicks, clear +*/ +void QCPAxisTickerText::addTick(double position, QString label) +{ + mTicks.insert(position, label); +} + +/*! \overload + + Adds the provided \a ticks to the ones already existing. The map key of \a ticks corresponds to + the axis coordinate, and the map value is the string that will appear as tick label. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTick, setTicks, clear +*/ +void QCPAxisTickerText::addTicks(const QMap &ticks) +{ + mTicks.unite(ticks); +} + +/*! \overload + + Adds the provided ticks to the ones already existing. The entries of \a positions correspond to + the axis coordinates, and the entries of \a labels are the respective strings that will appear as + tick labels. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTick, setTicks, clear +*/ +void QCPAxisTickerText::addTicks(const QVector &positions, const QVector &labels) +{ + if (positions.size() != labels.size()) + qDebug() << Q_FUNC_INFO << "passed unequal length vectors for positions and labels:" << positions.size() << labels.size(); + int n = qMin(positions.size(), labels.size()); + for (int i=0; i QCPAxisTickerText::createTickVector(double tickStep, const QCPRange &range) +{ + Q_UNUSED(tickStep) + QVector result; + if (mTicks.isEmpty()) + return result; + + QMap::const_iterator start = mTicks.lowerBound(range.lower); + QMap::const_iterator end = mTicks.upperBound(range.upper); + // this method should try to give one tick outside of range so proper subticks can be generated: + if (start != mTicks.constBegin()) --start; + if (end != mTicks.constEnd()) ++end; + for (QMap::const_iterator it = start; it != end; ++it) + result.append(it.key()); + + return result; +} +/* end of 'src/axis/axistickertext.cpp' */ + + +/* including file 'src/axis/axistickerpi.cpp', size 11170 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerPi +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerPi + \brief Specialized axis ticker to display ticks in units of an arbitrary constant, for example pi + + \image html axisticker-pi.png + + This QCPAxisTicker subclass generates ticks that are expressed with respect to a given symbolic + constant with a numerical value specified with \ref setPiValue and an appearance in the tick + labels specified with \ref setPiSymbol. + + Ticks may be generated at fractions of the symbolic constant. How these fractions appear in the + tick label can be configured with \ref setFractionStyle. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerpi-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerPi::QCPAxisTickerPi() : + mPiSymbol(QLatin1String(" ")+QChar(0x03C0)), + mPiValue(M_PI), + mPeriodicity(0), + mFractionStyle(fsUnicodeFractions), + mPiTickStep(0) +{ + setTickCount(4); +} + +/*! + Sets how the symbol part (which is always a suffix to the number) shall appear in the axis tick + label. + + If a space shall appear between the number and the symbol, make sure the space is contained in \a + symbol. +*/ +void QCPAxisTickerPi::setPiSymbol(QString symbol) +{ + mPiSymbol = symbol; +} + +/*! + Sets the numerical value that the symbolic constant has. + + This will be used to place the appropriate fractions of the symbol at the respective axis + coordinates. +*/ +void QCPAxisTickerPi::setPiValue(double pi) +{ + mPiValue = pi; +} + +/*! + Sets whether the axis labels shall appear periodicly and if so, at which multiplicity of the + symbolic constant. + + To disable periodicity, set \a multiplesOfPi to zero. + + For example, an axis that identifies 0 with 2pi would set \a multiplesOfPi to two. +*/ +void QCPAxisTickerPi::setPeriodicity(int multiplesOfPi) +{ + mPeriodicity = qAbs(multiplesOfPi); +} + +/*! + Sets how the numerical/fractional part preceding the symbolic constant is displayed in tick + labels. See \ref FractionStyle for the various options. +*/ +void QCPAxisTickerPi::setFractionStyle(QCPAxisTickerPi::FractionStyle style) +{ + mFractionStyle = style; +} + +/*! \internal + + Returns the tick step, using the constant's value (\ref setPiValue) as base unit. In consequence + the numerical/fractional part preceding the symbolic constant is made to have a readable + mantissa. + + \seebaseclassmethod +*/ +double QCPAxisTickerPi::getTickStep(const QCPRange &range) +{ + mPiTickStep = range.size()/mPiValue/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + mPiTickStep = cleanMantissa(mPiTickStep); + return mPiTickStep*mPiValue; +} + +/*! \internal + + Returns the sub tick count, using the constant's value (\ref setPiValue) as base unit. In + consequence the sub ticks divide the numerical/fractional part preceding the symbolic constant + reasonably, and not the total tick coordinate. + + \seebaseclassmethod +*/ +int QCPAxisTickerPi::getSubTickCount(double tickStep) +{ + return QCPAxisTicker::getSubTickCount(tickStep/mPiValue); +} + +/*! \internal + + Returns the tick label as a fractional/numerical part and a symbolic string as suffix. The + formatting of the fraction is done according to the specified \ref setFractionStyle. The appended + symbol is specified with \ref setPiSymbol. + + \seebaseclassmethod +*/ +QString QCPAxisTickerPi::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + double tickInPis = tick/mPiValue; + if (mPeriodicity > 0) + tickInPis = fmod(tickInPis, mPeriodicity); + + if (mFractionStyle != fsFloatingPoint && mPiTickStep > 0.09 && mPiTickStep < 50) + { + // simply construct fraction from decimal like 1.234 -> 1234/1000 and then simplify fraction, smaller digits are irrelevant due to mPiTickStep conditional above + int denominator = 1000; + int numerator = qRound(tickInPis*denominator); + simplifyFraction(numerator, denominator); + if (qAbs(numerator) == 1 && denominator == 1) + return (numerator < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); + else if (numerator == 0) + return QLatin1String("0"); + else + return fractionToString(numerator, denominator) + mPiSymbol; + } else + { + if (qFuzzyIsNull(tickInPis)) + return QLatin1String("0"); + else if (qFuzzyCompare(qAbs(tickInPis), 1.0)) + return (tickInPis < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); + else + return QCPAxisTicker::getTickLabel(tickInPis, locale, formatChar, precision) + mPiSymbol; + } +} + +/*! \internal + + Takes the fraction given by \a numerator and \a denominator and modifies the values to make sure + the fraction is in irreducible form, i.e. numerator and denominator don't share any common + factors which could be cancelled. +*/ +void QCPAxisTickerPi::simplifyFraction(int &numerator, int &denominator) const +{ + if (numerator == 0 || denominator == 0) + return; + + int num = numerator; + int denom = denominator; + while (denom != 0) // euclidean gcd algorithm + { + int oldDenom = denom; + denom = num % denom; + num = oldDenom; + } + // num is now gcd of numerator and denominator + numerator /= num; + denominator /= num; +} + +/*! \internal + + Takes the fraction given by \a numerator and \a denominator and returns a string representation. + The result depends on the configured fraction style (\ref setFractionStyle). + + This method is used to format the numerical/fractional part when generating tick labels. It + simplifies the passed fraction to an irreducible form using \ref simplifyFraction and factors out + any integer parts of the fraction (e.g. "10/4" becomes "2 1/2"). +*/ +QString QCPAxisTickerPi::fractionToString(int numerator, int denominator) const +{ + if (denominator == 0) + { + qDebug() << Q_FUNC_INFO << "called with zero denominator"; + return QString(); + } + if (mFractionStyle == fsFloatingPoint) // should never be the case when calling this function + { + qDebug() << Q_FUNC_INFO << "shouldn't be called with fraction style fsDecimal"; + return QString::number(numerator/(double)denominator); // failsafe + } + int sign = numerator*denominator < 0 ? -1 : 1; + numerator = qAbs(numerator); + denominator = qAbs(denominator); + + if (denominator == 1) + { + return QString::number(sign*numerator); + } else + { + int integerPart = numerator/denominator; + int remainder = numerator%denominator; + if (remainder == 0) + { + return QString::number(sign*integerPart); + } else + { + if (mFractionStyle == fsAsciiFractions) + { + return QString(QLatin1String("%1%2%3/%4")) + .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) + .arg(integerPart > 0 ? QString::number(integerPart)+QLatin1String(" ") : QLatin1String("")) + .arg(remainder) + .arg(denominator); + } else if (mFractionStyle == fsUnicodeFractions) + { + return QString(QLatin1String("%1%2%3")) + .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) + .arg(integerPart > 0 ? QString::number(integerPart) : QLatin1String("")) + .arg(unicodeFraction(remainder, denominator)); + } + } + } + return QString(); +} + +/*! \internal + + Returns the unicode string representation of the fraction given by \a numerator and \a + denominator. This is the representation used in \ref fractionToString when the fraction style + (\ref setFractionStyle) is \ref fsUnicodeFractions. + + This method doesn't use the single-character common fractions but builds each fraction from a + superscript unicode number, the unicode fraction character, and a subscript unicode number. +*/ +QString QCPAxisTickerPi::unicodeFraction(int numerator, int denominator) const +{ + return unicodeSuperscript(numerator)+QChar(0x2044)+unicodeSubscript(denominator); +} + +/*! \internal + + Returns the unicode string representing \a number as superscript. This is used to build + unicode fractions in \ref unicodeFraction. +*/ +QString QCPAxisTickerPi::unicodeSuperscript(int number) const +{ + if (number == 0) + return QString(QChar(0x2070)); + + QString result; + while (number > 0) + { + const int digit = number%10; + switch (digit) + { + case 1: { result.prepend(QChar(0x00B9)); break; } + case 2: { result.prepend(QChar(0x00B2)); break; } + case 3: { result.prepend(QChar(0x00B3)); break; } + default: { result.prepend(QChar(0x2070+digit)); break; } + } + number /= 10; + } + return result; +} + +/*! \internal + + Returns the unicode string representing \a number as subscript. This is used to build unicode + fractions in \ref unicodeFraction. +*/ +QString QCPAxisTickerPi::unicodeSubscript(int number) const +{ + if (number == 0) + return QString(QChar(0x2080)); + + QString result; + while (number > 0) + { + result.prepend(QChar(0x2080+number%10)); + number /= 10; + } + return result; +} +/* end of 'src/axis/axistickerpi.cpp' */ + + +/* including file 'src/axis/axistickerlog.cpp', size 7106 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerLog +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerLog + \brief Specialized axis ticker suited for logarithmic axes + + \image html axisticker-log.png + + This QCPAxisTicker subclass generates ticks with unequal tick intervals suited for logarithmic + axis scales. The ticks are placed at powers of the specified log base (\ref setLogBase). + + Especially in the case of a log base equal to 10 (the default), it might be desirable to have + tick labels in the form of powers of ten without mantissa display. To achieve this, set the + number precision (\ref QCPAxis::setNumberPrecision) to zero and the number format (\ref + QCPAxis::setNumberFormat) to scientific (exponential) display with beautifully typeset decimal + powers, so a format string of "eb". This will result in the following axis tick labels: + + \image html axisticker-log-powers.png + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerlog-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerLog::QCPAxisTickerLog() : + mLogBase(10.0), + mSubTickCount(8), // generates 10 intervals + mLogBaseLnInv(1.0/qLn(mLogBase)) +{ +} + +/*! + Sets the logarithm base used for tick coordinate generation. The ticks will be placed at integer + powers of \a base. +*/ +void QCPAxisTickerLog::setLogBase(double base) +{ + if (base > 0) + { + mLogBase = base; + mLogBaseLnInv = 1.0/qLn(mLogBase); + } else + qDebug() << Q_FUNC_INFO << "log base has to be greater than zero:" << base; +} + +/*! + Sets the number of sub ticks in a tick interval. Within each interval, the sub ticks are spaced + linearly to provide a better visual guide, so the sub tick density increases toward the higher + tick. + + Note that \a subTicks is the number of sub ticks (not sub intervals) in one tick interval. So in + the case of logarithm base 10 an intuitive sub tick spacing would be achieved with eight sub + ticks (the default). This means e.g. between the ticks 10 and 100 there will be eight ticks, + namely at 20, 30, 40, 50, 60, 70, 80 and 90. +*/ +void QCPAxisTickerLog::setSubTickCount(int subTicks) +{ + if (subTicks >= 0) + mSubTickCount = subTicks; + else + qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; +} + +/*! \internal + + Since logarithmic tick steps are necessarily different for each tick interval, this method does + nothing in the case of QCPAxisTickerLog + + \seebaseclassmethod +*/ +double QCPAxisTickerLog::getTickStep(const QCPRange &range) +{ + // Logarithmic axis ticker has unequal tick spacing, so doesn't need this method + Q_UNUSED(range) + return 1.0; +} + +/*! \internal + + Returns the sub tick count specified in \ref setSubTickCount. For QCPAxisTickerLog, there is no + automatic sub tick count calculation necessary. + + \seebaseclassmethod +*/ +int QCPAxisTickerLog::getSubTickCount(double tickStep) +{ + Q_UNUSED(tickStep) + return mSubTickCount; +} + +/*! \internal + + Creates ticks with a spacing given by the logarithm base and an increasing integer power in the + provided \a range. The step in which the power increases tick by tick is chosen in order to keep + the total number of ticks as close as possible to the tick count (\ref setTickCount). The + parameter \a tickStep is ignored for QCPAxisTickerLog + + \seebaseclassmethod +*/ +QVector QCPAxisTickerLog::createTickVector(double tickStep, const QCPRange &range) +{ + Q_UNUSED(tickStep) + QVector result; + if (range.lower > 0 && range.upper > 0) // positive range + { + double exactPowerStep = qLn(range.upper/range.lower)*mLogBaseLnInv/(double)(mTickCount+1e-10); + double newLogBase = qPow(mLogBase, qMax((int)cleanMantissa(exactPowerStep), 1)); + double currentTick = qPow(newLogBase, qFloor(qLn(range.lower)/qLn(newLogBase))); + result.append(currentTick); + while (currentTick < range.upper && currentTick > 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentTick *= newLogBase; + result.append(currentTick); + } + } else if (range.lower < 0 && range.upper < 0) // negative range + { + double exactPowerStep = qLn(range.lower/range.upper)*mLogBaseLnInv/(double)(mTickCount+1e-10); + double newLogBase = qPow(mLogBase, qMax((int)cleanMantissa(exactPowerStep), 1)); + double currentTick = -qPow(newLogBase, qCeil(qLn(-range.lower)/qLn(newLogBase))); + result.append(currentTick); + while (currentTick < range.upper && currentTick < 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentTick /= newLogBase; + result.append(currentTick); + } + } else // invalid range for logarithmic scale, because lower and upper have different sign + { + qDebug() << Q_FUNC_INFO << "Invalid range for logarithmic plot: " << range.lower << ".." << range.upper; + } + + return result; +} +/* end of 'src/axis/axistickerlog.cpp' */ + + +/* including file 'src/axis/axis.cpp', size 99397 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGrid +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGrid + \brief Responsible for drawing the grid of a QCPAxis. + + This class is tightly bound to QCPAxis. Every axis owns a grid instance and uses it to draw the + grid lines, sub grid lines and zero-line. You can interact with the grid of an axis via \ref + QCPAxis::grid. Normally, you don't need to create an instance of QCPGrid yourself. + + The axis and grid drawing was split into two classes to allow them to be placed on different + layers (both QCPAxis and QCPGrid inherit from QCPLayerable). Thus it is possible to have the grid + in the background and the axes in the foreground, and any plottables/items in between. This + described situation is the default setup, see the QCPLayer documentation. +*/ + +/*! + Creates a QCPGrid instance and sets default values. + + You shouldn't instantiate grids on their own, since every QCPAxis brings its own QCPGrid. +*/ +QCPGrid::QCPGrid(QCPAxis *parentAxis) : + QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis), + mParentAxis(parentAxis) +{ + // warning: this is called in QCPAxis constructor, so parentAxis members should not be accessed/called + setParent(parentAxis); + setPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); + setSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); + setZeroLinePen(QPen(QColor(200,200,200), 0, Qt::SolidLine)); + setSubGridVisible(false); + setAntialiased(false); + setAntialiasedSubGrid(false); + setAntialiasedZeroLine(false); +} + +/*! + Sets whether grid lines at sub tick marks are drawn. + + \see setSubGridPen +*/ +void QCPGrid::setSubGridVisible(bool visible) +{ + mSubGridVisible = visible; +} + +/*! + Sets whether sub grid lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedSubGrid(bool enabled) +{ + mAntialiasedSubGrid = enabled; +} + +/*! + Sets whether zero lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedZeroLine(bool enabled) +{ + mAntialiasedZeroLine = enabled; +} + +/*! + Sets the pen with which (major) grid lines are drawn. +*/ +void QCPGrid::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen with which sub grid lines are drawn. +*/ +void QCPGrid::setSubGridPen(const QPen &pen) +{ + mSubGridPen = pen; +} + +/*! + Sets the pen with which zero lines are drawn. + + Zero lines are lines at value coordinate 0 which may be drawn with a different pen than other grid + lines. To disable zero lines and just draw normal grid lines at zero, set \a pen to Qt::NoPen. +*/ +void QCPGrid::setZeroLinePen(const QPen &pen) +{ + mZeroLinePen = pen; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing the major grid lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeGrid); +} + +/*! \internal + + Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning + over the complete axis rect. Also draws the zero line, if appropriate (\ref setZeroLinePen). +*/ +void QCPGrid::draw(QCPPainter *painter) +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + if (mParentAxis->subTicks() && mSubGridVisible) + drawSubGridLines(painter); + drawGridLines(painter); +} + +/*! \internal + + Draws the main grid lines and possibly a zero line with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawGridLines(QCPPainter *painter) const +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + const int tickCount = mParentAxis->mTickVector.size(); + double t; // helper variable, result of coordinate-to-pixel transforms + if (mParentAxis->orientation() == Qt::Horizontal) + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->range().size()*1E-6; // for comparing double to zero + for (int i=0; imTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + } + } else + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->mRange.size()*1E-6; // for comparing double to zero + for (int i=0; imTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + } + } +} + +/*! \internal + + Draws the sub grid lines with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawSubGridLines(QCPPainter *painter) const +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + applyAntialiasingHint(painter, mAntialiasedSubGrid, QCP::aeSubGrid); + double t; // helper variable, result of coordinate-to-pixel transforms + painter->setPen(mSubGridPen); + if (mParentAxis->orientation() == Qt::Horizontal) + { + for (int i=0; imSubTickVector.size(); ++i) + { + t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + } + } else + { + for (int i=0; imSubTickVector.size(); ++i) + { + t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxis +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxis + \brief Manages a single axis inside a QCustomPlot. + + Usually doesn't need to be instantiated externally. Access %QCustomPlot's default four axes via + QCustomPlot::xAxis (bottom), QCustomPlot::yAxis (left), QCustomPlot::xAxis2 (top) and + QCustomPlot::yAxis2 (right). + + Axes are always part of an axis rect, see QCPAxisRect. + \image html AxisNamesOverview.png +
Naming convention of axis parts
+ \n + + \image html AxisRectSpacingOverview.png +
Overview of the spacings and paddings that define the geometry of an axis. The dashed gray line + on the left represents the QCustomPlot widget border.
+ + Each axis holds an instance of QCPAxisTicker which is used to generate the tick coordinates and + tick labels. You can access the currently installed \ref ticker or set a new one (possibly one of + the specialized subclasses, or your own subclass) via \ref setTicker. For details, see the + documentation of QCPAxisTicker. +*/ + +/* start of documentation of inline functions */ + +/*! \fn Qt::Orientation QCPAxis::orientation() const + + Returns the orientation of this axis. The axis orientation (horizontal or vertical) is deduced + from the axis type (left, top, right or bottom). + + \see orientation(AxisType type), pixelOrientation +*/ + +/*! \fn QCPGrid *QCPAxis::grid() const + + Returns the \ref QCPGrid instance belonging to this axis. Access it to set details about the way the + grid is displayed. +*/ + +/*! \fn static Qt::Orientation QCPAxis::orientation(AxisType type) + + Returns the orientation of the specified axis type + + \see orientation(), pixelOrientation +*/ + +/*! \fn int QCPAxis::pixelOrientation() const + + Returns which direction points towards higher coordinate values/keys, in pixel space. + + This method returns either 1 or -1. If it returns 1, then going in the positive direction along + the orientation of the axis in pixels corresponds to going from lower to higher axis coordinates. + On the other hand, if this method returns -1, going to smaller pixel values corresponds to going + from lower to higher axis coordinates. + + For example, this is useful to easily shift axis coordinates by a certain amount given in pixels, + without having to care about reversed or vertically aligned axes: + + \code + double newKey = keyAxis->pixelToCoord(keyAxis->coordToPixel(oldKey)+10*keyAxis->pixelOrientation()); + \endcode + + \a newKey will then contain a key that is ten pixels towards higher keys, starting from \a oldKey. +*/ + +/*! \fn QSharedPointer QCPAxis::ticker() const + + Returns a modifiable shared pointer to the currently installed axis ticker. The axis ticker is + responsible for generating the tick positions and tick labels of this axis. You can access the + \ref QCPAxisTicker with this method and modify basic properties such as the approximate tick count + (\ref QCPAxisTicker::setTickCount). + + You can gain more control over the axis ticks by setting a different \ref QCPAxisTicker subclass, see + the documentation there. A new axis ticker can be set with \ref setTicker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see setTicker +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange) + + This signal is emitted when the range of this axis has changed. You can connect it to the \ref + setRange slot of another axis to communicate the new range to the other axis, in order for it to + be synchronized. + + You may also manipulate/correct the range with \ref setRange in a slot connected to this signal. + This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper + range shouldn't go beyond certain values (see \ref QCPRange::bounded). For example, the following + slot would limit the x axis to ranges between 0 and 10: + \code + customPlot->xAxis->setRange(newRange.bounded(0, 10)) + \endcode +*/ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange, const QCPRange &oldRange) + \overload + + Additionally to the new range, this signal also provides the previous range held by the axis as + \a oldRange. +*/ + +/*! \fn void QCPAxis::scaleTypeChanged(QCPAxis::ScaleType scaleType); + + This signal is emitted when the scale type changes, by calls to \ref setScaleType +*/ + +/*! \fn void QCPAxis::selectionChanged(QCPAxis::SelectableParts selection) + + This signal is emitted when the selection state of this axis has changed, either by user interaction + or by a direct call to \ref setSelectedParts. +*/ + +/*! \fn void QCPAxis::selectableChanged(const QCPAxis::SelectableParts &parts); + + This signal is emitted when the selectability changes, by calls to \ref setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs an Axis instance of Type \a type for the axis rect \a parent. + + Usually it isn't necessary to instantiate axes directly, because you can let QCustomPlot create + them for you with \ref QCPAxisRect::addAxis. If you want to use own QCPAxis-subclasses however, + create them manually and then inject them also via \ref QCPAxisRect::addAxis. +*/ +QCPAxis::QCPAxis(QCPAxisRect *parent, AxisType type) : + QCPLayerable(parent->parentPlot(), QString(), parent), + // axis base: + mAxisType(type), + mAxisRect(parent), + mPadding(5), + mOrientation(orientation(type)), + mSelectableParts(spAxis | spTickLabels | spAxisLabel), + mSelectedParts(spNone), + mBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedBasePen(QPen(Qt::blue, 2)), + // axis label: + mLabel(), + mLabelFont(mParentPlot->font()), + mSelectedLabelFont(QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)), + mLabelColor(Qt::black), + mSelectedLabelColor(Qt::blue), + // tick labels: + mTickLabels(true), + mTickLabelFont(mParentPlot->font()), + mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)), + mTickLabelColor(Qt::black), + mSelectedTickLabelColor(Qt::blue), + mNumberPrecision(6), + mNumberFormatChar('g'), + mNumberBeautifulPowers(true), + // ticks and subticks: + mTicks(true), + mSubTicks(true), + mTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedTickPen(QPen(Qt::blue, 2)), + mSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedSubTickPen(QPen(Qt::blue, 2)), + // scale and range: + mRange(0, 5), + mRangeReversed(false), + mScaleType(stLinear), + // internal members: + mGrid(new QCPGrid(this)), + mAxisPainter(new QCPAxisPainterPrivate(parent->parentPlot())), + mTicker(new QCPAxisTicker), + mCachedMarginValid(false), + mCachedMargin(0) +{ + setParent(parent); + mGrid->setVisible(false); + setAntialiased(false); + setLayer(mParentPlot->currentLayer()); // it's actually on that layer already, but we want it in front of the grid, so we place it on there again + + if (type == atTop) + { + setTickLabelPadding(3); + setLabelPadding(6); + } else if (type == atRight) + { + setTickLabelPadding(7); + setLabelPadding(12); + } else if (type == atBottom) + { + setTickLabelPadding(3); + setLabelPadding(3); + } else if (type == atLeft) + { + setTickLabelPadding(5); + setLabelPadding(10); + } +} + +QCPAxis::~QCPAxis() +{ + delete mAxisPainter; + delete mGrid; // delete grid here instead of via parent ~QObject for better defined deletion order +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLabelPadding() const +{ + return mAxisPainter->tickLabelPadding; +} + +/* No documentation as it is a property getter */ +double QCPAxis::tickLabelRotation() const +{ + return mAxisPainter->tickLabelRotation; +} + +/* No documentation as it is a property getter */ +QCPAxis::LabelSide QCPAxis::tickLabelSide() const +{ + return mAxisPainter->tickLabelSide; +} + +/* No documentation as it is a property getter */ +QString QCPAxis::numberFormat() const +{ + QString result; + result.append(mNumberFormatChar); + if (mNumberBeautifulPowers) + { + result.append(QLatin1Char('b')); + if (mAxisPainter->numberMultiplyCross) + result.append(QLatin1Char('c')); + } + return result; +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLengthIn() const +{ + return mAxisPainter->tickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLengthOut() const +{ + return mAxisPainter->tickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPAxis::subTickLengthIn() const +{ + return mAxisPainter->subTickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPAxis::subTickLengthOut() const +{ + return mAxisPainter->subTickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPAxis::labelPadding() const +{ + return mAxisPainter->labelPadding; +} + +/* No documentation as it is a property getter */ +int QCPAxis::offset() const +{ + return mAxisPainter->offset; +} + +/* No documentation as it is a property getter */ +QCPLineEnding QCPAxis::lowerEnding() const +{ + return mAxisPainter->lowerEnding; +} + +/* No documentation as it is a property getter */ +QCPLineEnding QCPAxis::upperEnding() const +{ + return mAxisPainter->upperEnding; +} + +/*! + Sets whether the axis uses a linear scale or a logarithmic scale. + + Note that this method controls the coordinate transformation. You will likely also want to use a + logarithmic tick spacing and labeling, which can be achieved by setting an instance of \ref + QCPAxisTickerLog via \ref setTicker. See the documentation of \ref QCPAxisTickerLog about the + details of logarithmic axis tick creation. + + \ref setNumberPrecision +*/ +void QCPAxis::setScaleType(QCPAxis::ScaleType type) +{ + if (mScaleType != type) + { + mScaleType = type; + if (mScaleType == stLogarithmic) + setRange(mRange.sanitizedForLogScale()); + mCachedMarginValid = false; + emit scaleTypeChanged(mScaleType); + } +} + +/*! + Sets the range of the axis. + + This slot may be connected with the \ref rangeChanged signal of another axis so this axis + is always synchronized with the other axis range, when it changes. + + To invert the direction of an axis, use \ref setRangeReversed. +*/ +void QCPAxis::setRange(const QCPRange &range) +{ + if (range.lower == mRange.lower && range.upper == mRange.upper) + return; + + if (!QCPRange::validRange(range)) return; + QCPRange oldRange = mRange; + if (mScaleType == stLogarithmic) + { + mRange = range.sanitizedForLogScale(); + } else + { + mRange = range.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains iSelectAxes.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPAxis::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font. + + The entire selection mechanism for axes is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you + wish to change the selection state manually. + + This function can change the selection state of a part, independent of the \ref setSelectableParts setting. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, + setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor +*/ +void QCPAxis::setSelectedParts(const SelectableParts &selected) +{ + if (mSelectedParts != selected) + { + mSelectedParts = selected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + \overload + + Sets the lower and upper bound of the axis range. + + To invert the direction of an axis, use \ref setRangeReversed. + + There is also a slot to set a range, see \ref setRange(const QCPRange &range). +*/ +void QCPAxis::setRange(double lower, double upper) +{ + if (lower == mRange.lower && upper == mRange.upper) + return; + + if (!QCPRange::validRange(lower, upper)) return; + QCPRange oldRange = mRange; + mRange.lower = lower; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + \overload + + Sets the range of the axis. + + The \a position coordinate indicates together with the \a alignment parameter, where the new + range will be positioned. \a size defines the size of the new axis range. \a alignment may be + Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, + or center of the range to be aligned with \a position. Any other values of \a alignment will + default to Qt::AlignCenter. +*/ +void QCPAxis::setRange(double position, double size, Qt::AlignmentFlag alignment) +{ + if (alignment == Qt::AlignLeft) + setRange(position, position+size); + else if (alignment == Qt::AlignRight) + setRange(position-size, position); + else // alignment == Qt::AlignCenter + setRange(position-size/2.0, position+size/2.0); +} + +/*! + Sets the lower bound of the axis range. The upper bound is not changed. + \see setRange +*/ +void QCPAxis::setRangeLower(double lower) +{ + if (mRange.lower == lower) + return; + + QCPRange oldRange = mRange; + mRange.lower = lower; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets the upper bound of the axis range. The lower bound is not changed. + \see setRange +*/ +void QCPAxis::setRangeUpper(double upper) +{ + if (mRange.upper == upper) + return; + + QCPRange oldRange = mRange; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the axis range (direction) is displayed reversed. Normally, the values on horizontal + axes increase left to right, on vertical axes bottom to top. When \a reversed is set to true, the + direction of increasing values is inverted. + + Note that the range and data interface stays the same for reversed axes, e.g. the \a lower part + of the \ref setRange interface will still reference the mathematically smaller number than the \a + upper part. +*/ +void QCPAxis::setRangeReversed(bool reversed) +{ + mRangeReversed = reversed; +} + +/*! + The axis ticker is responsible for generating the tick positions and tick labels. See the + documentation of QCPAxisTicker for details on how to work with axis tickers. + + You can change the tick positioning/labeling behaviour of this axis by setting a different + QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis + ticker, access it via \ref ticker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see ticker +*/ +void QCPAxis::setTicker(QSharedPointer ticker) +{ + if (ticker) + mTicker = ticker; + else + qDebug() << Q_FUNC_INFO << "can not set 0 as axis ticker"; + // no need to invalidate margin cache here because produced tick labels are checked for changes in setupTickVector +} + +/*! + Sets whether tick marks are displayed. + + Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve + that, see \ref setTickLabels. + + \see setSubTicks +*/ +void QCPAxis::setTicks(bool show) +{ + if (mTicks != show) + { + mTicks = show; + mCachedMarginValid = false; + } +} + +/*! + Sets whether tick labels are displayed. Tick labels are the numbers drawn next to tick marks. +*/ +void QCPAxis::setTickLabels(bool show) +{ + if (mTickLabels != show) + { + mTickLabels = show; + mCachedMarginValid = false; + if (!mTickLabels) + mTickVectorLabels.clear(); + } +} + +/*! + Sets the distance between the axis base line (including any outward ticks) and the tick labels. + \see setLabelPadding, setPadding +*/ +void QCPAxis::setTickLabelPadding(int padding) +{ + if (mAxisPainter->tickLabelPadding != padding) + { + mAxisPainter->tickLabelPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the font of the tick labels. + + \see setTickLabels, setTickLabelColor +*/ +void QCPAxis::setTickLabelFont(const QFont &font) +{ + if (font != mTickLabelFont) + { + mTickLabelFont = font; + mCachedMarginValid = false; + } +} + +/*! + Sets the color of the tick labels. + + \see setTickLabels, setTickLabelFont +*/ +void QCPAxis::setTickLabelColor(const QColor &color) +{ + mTickLabelColor = color; +} + +/*! + Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, + the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values + from -90 to 90 degrees. + + If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For + other angles, the label is drawn with an offset such that it seems to point toward or away from + the tick mark. +*/ +void QCPAxis::setTickLabelRotation(double degrees) +{ + if (!qFuzzyIsNull(degrees-mAxisPainter->tickLabelRotation)) + { + mAxisPainter->tickLabelRotation = qBound(-90.0, degrees, 90.0); + mCachedMarginValid = false; + } +} + +/*! + Sets whether the tick labels (numbers) shall appear inside or outside the axis rect. + + The usual and default setting is \ref lsOutside. Very compact plots sometimes require tick labels + to be inside the axis rect, to save space. If \a side is set to \ref lsInside, the tick labels + appear on the inside are additionally clipped to the axis rect. +*/ +void QCPAxis::setTickLabelSide(LabelSide side) +{ + mAxisPainter->tickLabelSide = side; + mCachedMarginValid = false; +} + +/*! + Sets the number format for the numbers in tick labels. This \a formatCode is an extended version + of the format code used e.g. by QString::number() and QLocale::toString(). For reference about + that, see the "Argument Formats" section in the detailed description of the QString class. + + \a formatCode is a string of one, two or three characters. The first character is identical to + the normal format code used by Qt. In short, this means: 'e'/'E' scientific format, 'f' fixed + format, 'g'/'G' scientific or fixed, whichever is shorter. + + The second and third characters are optional and specific to QCustomPlot:\n + If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. + "5.5e9", which is ugly in a plot. So when the second char of \a formatCode is set to 'b' (for + "beautiful"), those exponential numbers are formatted in a more natural way, i.e. "5.5 + [multiplication sign] 10 [superscript] 9". By default, the multiplication sign is a centered dot. + If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can + be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the + cross and 183 (0xB7) for the dot. + + Examples for \a formatCode: + \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, + normal scientific format is used + \li \c gb If number is small, fixed format is used, if number is large, scientific format is used with + beautifully typeset decimal powers and a dot as multiplication sign + \li \c ebc All numbers are in scientific format with beautifully typeset decimal power and a cross as + multiplication sign + \li \c fb illegal format code, since fixed format doesn't support (or need) beautifully typeset decimal + powers. Format code will be reduced to 'f'. + \li \c hello illegal format code, since first char is not 'e', 'E', 'f', 'g' or 'G'. Current format + code will not be changed. +*/ +void QCPAxis::setNumberFormat(const QString &formatCode) +{ + if (formatCode.isEmpty()) + { + qDebug() << Q_FUNC_INFO << "Passed formatCode is empty"; + return; + } + mCachedMarginValid = false; + + // interpret first char as number format char: + QString allowedFormatChars(QLatin1String("eEfgG")); + if (allowedFormatChars.contains(formatCode.at(0))) + { + mNumberFormatChar = QLatin1Char(formatCode.at(0).toLatin1()); + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; + return; + } + if (formatCode.length() < 2) + { + mNumberBeautifulPowers = false; + mAxisPainter->numberMultiplyCross = false; + return; + } + + // interpret second char as indicator for beautiful decimal powers: + if (formatCode.at(1) == QLatin1Char('b') && (mNumberFormatChar == QLatin1Char('e') || mNumberFormatChar == QLatin1Char('g'))) + { + mNumberBeautifulPowers = true; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; + return; + } + if (formatCode.length() < 3) + { + mAxisPainter->numberMultiplyCross = false; + return; + } + + // interpret third char as indicator for dot or cross multiplication symbol: + if (formatCode.at(2) == QLatin1Char('c')) + { + mAxisPainter->numberMultiplyCross = true; + } else if (formatCode.at(2) == QLatin1Char('d')) + { + mAxisPainter->numberMultiplyCross = false; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (third char neither 'c' nor 'd'):" << formatCode; + return; + } +} + +/*! + Sets the precision of the tick label numbers. See QLocale::toString(double i, char f, int prec) + for details. The effect of precisions are most notably for number Formats starting with 'e', see + \ref setNumberFormat +*/ +void QCPAxis::setNumberPrecision(int precision) +{ + if (mNumberPrecision != precision) + { + mNumberPrecision = precision; + mCachedMarginValid = false; + } +} + +/*! + Sets the length of the ticks in pixels. \a inside is the length the ticks will reach inside the + plot and \a outside is the length they will reach outside the plot. If \a outside is greater than + zero, the tick labels and axis label will increase their distance to the axis accordingly, so + they won't collide with the ticks. + + \see setSubTickLength, setTickLengthIn, setTickLengthOut +*/ +void QCPAxis::setTickLength(int inside, int outside) +{ + setTickLengthIn(inside); + setTickLengthOut(outside); +} + +/*! + Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach + inside the plot. + + \see setTickLengthOut, setTickLength, setSubTickLength +*/ +void QCPAxis::setTickLengthIn(int inside) +{ + if (mAxisPainter->tickLengthIn != inside) + { + mAxisPainter->tickLengthIn = inside; + } +} + +/*! + Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach + outside the plot. If \a outside is greater than zero, the tick labels and axis label will + increase their distance to the axis accordingly, so they won't collide with the ticks. + + \see setTickLengthIn, setTickLength, setSubTickLength +*/ +void QCPAxis::setTickLengthOut(int outside) +{ + if (mAxisPainter->tickLengthOut != outside) + { + mAxisPainter->tickLengthOut = outside; + mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets whether sub tick marks are displayed. + + Sub ticks are only potentially visible if (major) ticks are also visible (see \ref setTicks) + + \see setTicks +*/ +void QCPAxis::setSubTicks(bool show) +{ + if (mSubTicks != show) + { + mSubTicks = show; + mCachedMarginValid = false; + } +} + +/*! + Sets the length of the subticks in pixels. \a inside is the length the subticks will reach inside + the plot and \a outside is the length they will reach outside the plot. If \a outside is greater + than zero, the tick labels and axis label will increase their distance to the axis accordingly, + so they won't collide with the ticks. + + \see setTickLength, setSubTickLengthIn, setSubTickLengthOut +*/ +void QCPAxis::setSubTickLength(int inside, int outside) +{ + setSubTickLengthIn(inside); + setSubTickLengthOut(outside); +} + +/*! + Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside + the plot. + + \see setSubTickLengthOut, setSubTickLength, setTickLength +*/ +void QCPAxis::setSubTickLengthIn(int inside) +{ + if (mAxisPainter->subTickLengthIn != inside) + { + mAxisPainter->subTickLengthIn = inside; + } +} + +/*! + Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach + outside the plot. If \a outside is greater than zero, the tick labels will increase their + distance to the axis accordingly, so they won't collide with the ticks. + + \see setSubTickLengthIn, setSubTickLength, setTickLength +*/ +void QCPAxis::setSubTickLengthOut(int outside) +{ + if (mAxisPainter->subTickLengthOut != outside) + { + mAxisPainter->subTickLengthOut = outside; + mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets the pen, the axis base line is drawn with. + + \see setTickPen, setSubTickPen +*/ +void QCPAxis::setBasePen(const QPen &pen) +{ + mBasePen = pen; +} + +/*! + Sets the pen, tick marks will be drawn with. + + \see setTickLength, setBasePen +*/ +void QCPAxis::setTickPen(const QPen &pen) +{ + mTickPen = pen; +} + +/*! + Sets the pen, subtick marks will be drawn with. + + \see setSubTickCount, setSubTickLength, setBasePen +*/ +void QCPAxis::setSubTickPen(const QPen &pen) +{ + mSubTickPen = pen; +} + +/*! + Sets the font of the axis label. + + \see setLabelColor +*/ +void QCPAxis::setLabelFont(const QFont &font) +{ + if (mLabelFont != font) + { + mLabelFont = font; + mCachedMarginValid = false; + } +} + +/*! + Sets the color of the axis label. + + \see setLabelFont +*/ +void QCPAxis::setLabelColor(const QColor &color) +{ + mLabelColor = color; +} + +/*! + Sets the text of the axis label that will be shown below/above or next to the axis, depending on + its orientation. To disable axis labels, pass an empty string as \a str. +*/ +void QCPAxis::setLabel(const QString &str) +{ + if (mLabel != str) + { + mLabel = str; + mCachedMarginValid = false; + } +} + +/*! + Sets the distance between the tick labels and the axis label. + + \see setTickLabelPadding, setPadding +*/ +void QCPAxis::setLabelPadding(int padding) +{ + if (mAxisPainter->labelPadding != padding) + { + mAxisPainter->labelPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the padding of the axis. + + When \ref QCPAxisRect::setAutoMargins is enabled, the padding is the additional outer most space, + that is left blank. + + The axis padding has no meaning if \ref QCPAxisRect::setAutoMargins is disabled. + + \see setLabelPadding, setTickLabelPadding +*/ +void QCPAxis::setPadding(int padding) +{ + if (mPadding != padding) + { + mPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the offset the axis has to its axis rect side. + + If an axis rect side has multiple axes and automatic margin calculation is enabled for that side, + only the offset of the inner most axis has meaning (even if it is set to be invisible). The + offset of the other, outer axes is controlled automatically, to place them at appropriate + positions. +*/ +void QCPAxis::setOffset(int offset) +{ + mAxisPainter->offset = offset; +} + +/*! + Sets the font that is used for tick labels when they are selected. + + \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelFont(const QFont &font) +{ + if (font != mSelectedTickLabelFont) + { + mSelectedTickLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts + } +} + +/*! + Sets the font that is used for the axis label when it is selected. + + \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelFont(const QFont &font) +{ + mSelectedLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts +} + +/*! + Sets the color that is used for tick labels when they are selected. + + \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelColor(const QColor &color) +{ + if (color != mSelectedTickLabelColor) + { + mSelectedTickLabelColor = color; + } +} + +/*! + Sets the color that is used for the axis label when it is selected. + + \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelColor(const QColor &color) +{ + mSelectedLabelColor = color; +} + +/*! + Sets the pen that is used to draw the axis base line when selected. + + \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedBasePen(const QPen &pen) +{ + mSelectedBasePen = pen; +} + +/*! + Sets the pen that is used to draw the (major) ticks when selected. + + \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickPen(const QPen &pen) +{ + mSelectedTickPen = pen; +} + +/*! + Sets the pen that is used to draw the subticks when selected. + + \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedSubTickPen(const QPen &pen) +{ + mSelectedSubTickPen = pen; +} + +/*! + Sets the style for the lower axis ending. See the documentation of QCPLineEnding for available + styles. + + For horizontal axes, this method refers to the left ending, for vertical axes the bottom ending. + Note that this meaning does not change when the axis range is reversed with \ref + setRangeReversed. + + \see setUpperEnding +*/ +void QCPAxis::setLowerEnding(const QCPLineEnding &ending) +{ + mAxisPainter->lowerEnding = ending; +} + +/*! + Sets the style for the upper axis ending. See the documentation of QCPLineEnding for available + styles. + + For horizontal axes, this method refers to the right ending, for vertical axes the top ending. + Note that this meaning does not change when the axis range is reversed with \ref + setRangeReversed. + + \see setLowerEnding +*/ +void QCPAxis::setUpperEnding(const QCPLineEnding &ending) +{ + mAxisPainter->upperEnding = ending; +} + +/*! + If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper + bounds of the range. The range is simply moved by \a diff. + + If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This + corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). +*/ +void QCPAxis::moveRange(double diff) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + mRange.lower += diff; + mRange.upper += diff; + } else // mScaleType == stLogarithmic + { + mRange.lower *= diff; + mRange.upper *= diff; + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis by \a factor around the center of the current axis range. For + example, if \a factor is 2.0, then the axis range will double its size, and the point at the axis + range center won't have changed its position in the QCustomPlot widget (i.e. coordinates around + the center will have moved symmetrically closer). + + If you wish to scale around a different coordinate than the current axis range center, use the + overload \ref scaleRange(double factor, double center). +*/ +void QCPAxis::scaleRange(double factor) +{ + scaleRange(factor, range().center()); +} + +/*! \overload + + Scales the range of this axis by \a factor around the coordinate \a center. For example, if \a + factor is 2.0, \a center is 1.0, then the axis range will double its size, and the point at + coordinate 1.0 won't have changed its position in the QCustomPlot widget (i.e. coordinates + around 1.0 will have moved symmetrically closer to 1.0). + + \see scaleRange(double factor) +*/ +void QCPAxis::scaleRange(double factor, double center) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + QCPRange newRange; + newRange.lower = (mRange.lower-center)*factor + center; + newRange.upper = (mRange.upper-center)*factor + center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLinScale(); + } else // mScaleType == stLogarithmic + { + if ((mRange.upper < 0 && center < 0) || (mRange.upper > 0 && center > 0)) // make sure center has same sign as range + { + QCPRange newRange; + newRange.lower = qPow(mRange.lower/center, factor)*center; + newRange.upper = qPow(mRange.upper/center, factor)*center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLogScale(); + } else + qDebug() << Q_FUNC_INFO << "Center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center; + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis to have a certain scale \a ratio to \a otherAxis. The scaling will + be done around the center of the current axis range. + + For example, if \a ratio is 1, this axis is the \a yAxis and \a otherAxis is \a xAxis, graphs + plotted with those axes will appear in a 1:1 aspect ratio, independent of the aspect ratio the + axis rect has. + + This is an operation that changes the range of this axis once, it doesn't fix the scale ratio + indefinitely. Note that calling this function in the constructor of the QCustomPlot's parent + won't have the desired effect, since the widget dimensions aren't defined yet, and a resizeEvent + will follow. +*/ +void QCPAxis::setScaleRatio(const QCPAxis *otherAxis, double ratio) +{ + int otherPixelSize, ownPixelSize; + + if (otherAxis->orientation() == Qt::Horizontal) + otherPixelSize = otherAxis->axisRect()->width(); + else + otherPixelSize = otherAxis->axisRect()->height(); + + if (orientation() == Qt::Horizontal) + ownPixelSize = axisRect()->width(); + else + ownPixelSize = axisRect()->height(); + + double newRangeSize = ratio*otherAxis->range().size()*ownPixelSize/(double)otherPixelSize; + setRange(range().center(), newRangeSize, Qt::AlignCenter); +} + +/*! + Changes the axis range such that all plottables associated with this axis are fully visible in + that dimension. + + \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes +*/ +void QCPAxis::rescale(bool onlyVisiblePlottables) +{ + QList p = plottables(); + QCPRange newRange; + bool haveRange = false; + for (int i=0; irealVisibility() && onlyVisiblePlottables) + continue; + QCPRange plottableRange; + bool currentFoundRange; + QCP::SignDomain signDomain = QCP::sdBoth; + if (mScaleType == stLogarithmic) + signDomain = (mRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); + if (p.at(i)->keyAxis() == this) + plottableRange = p.at(i)->getKeyRange(currentFoundRange, signDomain); + else + plottableRange = p.at(i)->getValueRange(currentFoundRange, signDomain); + if (currentFoundRange) + { + if (!haveRange) + newRange = plottableRange; + else + newRange.expand(plottableRange); + haveRange = true; + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mScaleType == stLinear) + { + newRange.lower = center-mRange.size()/2.0; + newRange.upper = center+mRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mRange.upper/mRange.lower); + newRange.upper = center*qSqrt(mRange.upper/mRange.lower); + } + } + setRange(newRange); + } +} + +/*! + Transforms \a value, in pixel coordinates of the QCustomPlot widget, to axis coordinates. +*/ +double QCPAxis::pixelToCoord(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.lower; + else + return -(value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (value-mAxisRect->left())/(double)mAxisRect->width())*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (mAxisRect->left()-value)/(double)mAxisRect->width())*mRange.upper; + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.lower; + else + return -(mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (mAxisRect->bottom()-value)/(double)mAxisRect->height())*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (value-mAxisRect->bottom())/(double)mAxisRect->height())*mRange.upper; + } + } +} + +/*! + Transforms \a value, in coordinates of the axis, to pixel coordinates of the QCustomPlot widget. +*/ +double QCPAxis::coordToPixel(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mRange.lower)/mRange.size()*mAxisRect->width()+mAxisRect->left(); + else + return (mRange.upper-value)/mRange.size()*mAxisRect->width()+mAxisRect->left(); + } else // mScaleType == stLogarithmic + { + if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->right()+200 : mAxisRect->left()-200; + else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->left()-200 : mAxisRect->right()+200; + else + { + if (!mRangeReversed) + return qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); + else + return qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); + } + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return mAxisRect->bottom()-(value-mRange.lower)/mRange.size()*mAxisRect->height(); + else + return mAxisRect->bottom()-(mRange.upper-value)/mRange.size()*mAxisRect->height(); + } else // mScaleType == stLogarithmic + { + if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->top()-200 : mAxisRect->bottom()+200; + else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->bottom()+200 : mAxisRect->top()-200; + else + { + if (!mRangeReversed) + return mAxisRect->bottom()-qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); + else + return mAxisRect->bottom()-qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); + } + } + } +} + +/*! + Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function + is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this + function does not change the current selection state of the axis. + + If the axis is not visible (\ref setVisible), this function always returns \ref spNone. + + \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions +*/ +QCPAxis::SelectablePart QCPAxis::getPartAt(const QPointF &pos) const +{ + if (!mVisible) + return spNone; + + if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) + return spAxis; + else if (mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint())) + return spTickLabels; + else if (mAxisPainter->labelSelectionBox().contains(pos.toPoint())) + return spAxisLabel; + else + return spNone; +} + +/* inherits documentation from base class */ +double QCPAxis::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + SelectablePart part = getPartAt(pos); + if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) + return -1; + + if (details) + details->setValue(part); + return mParentPlot->selectionTolerance()*0.99; +} + +/*! + Returns a list of all the plottables that have this axis as key or value axis. + + If you are only interested in plottables of type QCPGraph, see \ref graphs. + + \see graphs, items +*/ +QList QCPAxis::plottables() const +{ + QList result; + if (!mParentPlot) return result; + + for (int i=0; imPlottables.size(); ++i) + { + if (mParentPlot->mPlottables.at(i)->keyAxis() == this ||mParentPlot->mPlottables.at(i)->valueAxis() == this) + result.append(mParentPlot->mPlottables.at(i)); + } + return result; +} + +/*! + Returns a list of all the graphs that have this axis as key or value axis. + + \see plottables, items +*/ +QList QCPAxis::graphs() const +{ + QList result; + if (!mParentPlot) return result; + + for (int i=0; imGraphs.size(); ++i) + { + if (mParentPlot->mGraphs.at(i)->keyAxis() == this || mParentPlot->mGraphs.at(i)->valueAxis() == this) + result.append(mParentPlot->mGraphs.at(i)); + } + return result; +} + +/*! + Returns a list of all the items that are associated with this axis. An item is considered + associated with an axis if at least one of its positions uses the axis as key or value axis. + + \see plottables, graphs +*/ +QList QCPAxis::items() const +{ + QList result; + if (!mParentPlot) return result; + + for (int itemId=0; itemIdmItems.size(); ++itemId) + { + QList positions = mParentPlot->mItems.at(itemId)->positions(); + for (int posId=0; posIdkeyAxis() == this || positions.at(posId)->valueAxis() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + break; + } + } + } + return result; +} + +/*! + Transforms a margin side to the logically corresponding axis type. (QCP::msLeft to + QCPAxis::atLeft, QCP::msRight to QCPAxis::atRight, etc.) +*/ +QCPAxis::AxisType QCPAxis::marginSideToAxisType(QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return atLeft; + case QCP::msRight: return atRight; + case QCP::msTop: return atTop; + case QCP::msBottom: return atBottom; + default: break; + } + qDebug() << Q_FUNC_INFO << "Invalid margin side passed:" << (int)side; + return atLeft; +} + +/*! + Returns the axis type that describes the opposite axis of an axis with the specified \a type. +*/ +QCPAxis::AxisType QCPAxis::opposite(QCPAxis::AxisType type) +{ + switch (type) + { + case atLeft: return atRight; break; + case atRight: return atLeft; break; + case atBottom: return atTop; break; + case atTop: return atBottom; break; + default: qDebug() << Q_FUNC_INFO << "invalid axis type"; return atLeft; break; + } +} + +/* inherits documentation from base class */ +void QCPAxis::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + SelectablePart part = details.value(); + if (mSelectableParts.testFlag(part)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^part : part); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAxis::deselectEvent(bool *selectionStateChanged) +{ + SelectableParts selBefore = mSelectedParts; + setSelectedParts(mSelectedParts & ~mSelectableParts); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + For the axis to accept this event and perform the single axis drag, the parent \ref QCPAxisRect + must be configured accordingly, i.e. it must allow range dragging in the orientation of this axis + (\ref QCPAxisRect::setRangeDrag) and this axis must be a draggable axis (\ref + QCPAxisRect::setRangeDragAxes) + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. +*/ +void QCPAxis::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + if (!mParentPlot->interactions().testFlag(QCP::iRangeDrag) || + !mAxisRect->rangeDrag().testFlag(orientation()) || + !mAxisRect->rangeDragAxes(orientation()).contains(this)) + { + event->ignore(); + return; + } + + if (event->buttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mParentPlot->noAntialiasingOnDrag()) + { + mAADragBackup = mParentPlot->antialiasedElements(); + mNotAADragBackup = mParentPlot->notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + mDragStartRange = mRange; + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. + + \see QCPAxis::mousePressEvent +*/ +void QCPAxis::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (mDragging) + { + const double startPixel = orientation() == Qt::Horizontal ? startPos.x() : startPos.y(); + const double currentPixel = orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y(); + if (mScaleType == QCPAxis::stLinear) + { + const double diff = pixelToCoord(startPixel) - pixelToCoord(currentPixel); + setRange(mDragStartRange.lower+diff, mDragStartRange.upper+diff); + } else if (mScaleType == QCPAxis::stLogarithmic) + { + const double diff = pixelToCoord(startPixel) / pixelToCoord(currentPixel); + setRange(mDragStartRange.lower*diff, mDragStartRange.upper*diff); + } + + if (mParentPlot->noAntialiasingOnDrag()) + mParentPlot->setNotAntialiasedElements(QCP::aeAll); + mParentPlot->replot(QCustomPlot::rpQueuedReplot); + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. + + \see QCPAxis::mousePressEvent +*/ +void QCPAxis::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(event) + Q_UNUSED(startPos) + mDragging = false; + if (mParentPlot->noAntialiasingOnDrag()) + { + mParentPlot->setAntialiasedElements(mAADragBackup); + mParentPlot->setNotAntialiasedElements(mNotAADragBackup); + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user zoom individual axes + exclusively, by performing the wheel event on top of the axis. + + For the axis to accept this event and perform the single axis zoom, the parent \ref QCPAxisRect + must be configured accordingly, i.e. it must allow range zooming in the orientation of this axis + (\ref QCPAxisRect::setRangeZoom) and this axis must be a zoomable axis (\ref + QCPAxisRect::setRangeZoomAxes) + + \seebaseclassmethod + + \note The zooming of possibly multiple axes at once by performing the wheel event anywhere in the + axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::wheelEvent. +*/ +void QCPAxis::wheelEvent(QWheelEvent *event) +{ + // Mouse range zooming interaction: + if (!mParentPlot->interactions().testFlag(QCP::iRangeZoom) || + !mAxisRect->rangeZoom().testFlag(orientation()) || + !mAxisRect->rangeZoomAxes(orientation()).contains(this)) + { + event->ignore(); + return; + } + + const double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually + const double factor = qPow(mAxisRect->rangeZoomFactor(orientation()), wheelSteps); + scaleRange(factor, pixelToCoord(orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y())); + mParentPlot->replot(); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing axis lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased +*/ +void QCPAxis::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeAxes); +} + +/*! \internal + + Draws the axis with the specified \a painter, using the internal QCPAxisPainterPrivate instance. + + \seebaseclassmethod +*/ +void QCPAxis::draw(QCPPainter *painter) +{ + QVector subTickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickLabels; // the final vector passed to QCPAxisPainter + tickPositions.reserve(mTickVector.size()); + tickLabels.reserve(mTickVector.size()); + subTickPositions.reserve(mSubTickVector.size()); + + if (mTicks) + { + for (int i=0; itype = mAxisType; + mAxisPainter->basePen = getBasePen(); + mAxisPainter->labelFont = getLabelFont(); + mAxisPainter->labelColor = getLabelColor(); + mAxisPainter->label = mLabel; + mAxisPainter->substituteExponent = mNumberBeautifulPowers; + mAxisPainter->tickPen = getTickPen(); + mAxisPainter->subTickPen = getSubTickPen(); + mAxisPainter->tickLabelFont = getTickLabelFont(); + mAxisPainter->tickLabelColor = getTickLabelColor(); + mAxisPainter->axisRect = mAxisRect->rect(); + mAxisPainter->viewportRect = mParentPlot->viewport(); + mAxisPainter->abbreviateDecimalPowers = mScaleType == stLogarithmic; + mAxisPainter->reversedEndings = mRangeReversed; + mAxisPainter->tickPositions = tickPositions; + mAxisPainter->tickLabels = tickLabels; + mAxisPainter->subTickPositions = subTickPositions; + mAxisPainter->draw(painter); +} + +/*! \internal + + Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling + QCPAxisTicker::generate on the currently installed ticker. + + If a change in the label text/count is detected, the cached axis margin is invalidated to make + sure the next margin calculation recalculates the label sizes and returns an up-to-date value. +*/ +void QCPAxis::setupTickVectors() +{ + if (!mParentPlot) return; + if ((!mTicks && !mTickLabels && !mGrid->visible()) || mRange.size() <= 0) return; + + QVector oldLabels = mTickVectorLabels; + mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : 0, mTickLabels ? &mTickVectorLabels : 0); + mCachedMarginValid &= mTickVectorLabels == oldLabels; // if labels have changed, margin might have changed, too +} + +/*! \internal + + Returns the pen that is used to draw the axis base line. Depending on the selection state, this + is either mSelectedBasePen or mBasePen. +*/ +QPen QCPAxis::getBasePen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedBasePen : mBasePen; +} + +/*! \internal + + Returns the pen that is used to draw the (major) ticks. Depending on the selection state, this + is either mSelectedTickPen or mTickPen. +*/ +QPen QCPAxis::getTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedTickPen : mTickPen; +} + +/*! \internal + + Returns the pen that is used to draw the subticks. Depending on the selection state, this + is either mSelectedSubTickPen or mSubTickPen. +*/ +QPen QCPAxis::getSubTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedSubTickPen : mSubTickPen; +} + +/*! \internal + + Returns the font that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelFont or mTickLabelFont. +*/ +QFont QCPAxis::getTickLabelFont() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelFont : mTickLabelFont; +} + +/*! \internal + + Returns the font that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelFont or mLabelFont. +*/ +QFont QCPAxis::getLabelFont() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelFont : mLabelFont; +} + +/*! \internal + + Returns the color that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelColor or mTickLabelColor. +*/ +QColor QCPAxis::getTickLabelColor() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelColor : mTickLabelColor; +} + +/*! \internal + + Returns the color that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelColor or mLabelColor. +*/ +QColor QCPAxis::getLabelColor() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelColor : mLabelColor; +} + +/*! \internal + + Returns the appropriate outward margin for this axis. It is needed if \ref + QCPAxisRect::setAutoMargins is set to true on the parent axis rect. An axis with axis type \ref + atLeft will return an appropriate left margin, \ref atBottom will return an appropriate bottom + margin and so forth. For the calculation, this function goes through similar steps as \ref draw, + so changing one function likely requires the modification of the other one as well. + + The margin consists of the outward tick length, tick label padding, tick label size, label + padding, label size, and padding. + + The margin is cached internally, so repeated calls while leaving the axis range, fonts, etc. + unchanged are very fast. +*/ +int QCPAxis::calculateMargin() +{ + if (!mVisible) // if not visible, directly return 0, don't cache 0 because we can't react to setVisible in QCPAxis + return 0; + + if (mCachedMarginValid) + return mCachedMargin; + + // run through similar steps as QCPAxis::draw, and calculate margin needed to fit axis and its labels + int margin = 0; + + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickLabels; // the final vector passed to QCPAxisPainter + tickPositions.reserve(mTickVector.size()); + tickLabels.reserve(mTickVector.size()); + + if (mTicks) + { + for (int i=0; itype = mAxisType; + mAxisPainter->labelFont = getLabelFont(); + mAxisPainter->label = mLabel; + mAxisPainter->tickLabelFont = mTickLabelFont; + mAxisPainter->axisRect = mAxisRect->rect(); + mAxisPainter->viewportRect = mParentPlot->viewport(); + mAxisPainter->tickPositions = tickPositions; + mAxisPainter->tickLabels = tickLabels; + margin += mAxisPainter->size(); + margin += mPadding; + + mCachedMargin = margin; + mCachedMarginValid = true; + return margin; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAxis::selectionCategory() const +{ + return QCP::iSelectAxes; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisPainterPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxisPainterPrivate + + \internal + \brief (Private) + + This is a private class and not part of the public QCustomPlot interface. + + It is used by QCPAxis to do the low-level drawing of axis backbone, tick marks, tick labels and + axis label. It also buffers the labels to reduce replot times. The parameters are configured by + directly accessing the public member variables. +*/ + +/*! + Constructs a QCPAxisPainterPrivate instance. Make sure to not create a new instance on every + redraw, to utilize the caching mechanisms. +*/ +QCPAxisPainterPrivate::QCPAxisPainterPrivate(QCustomPlot *parentPlot) : + type(QCPAxis::atLeft), + basePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + lowerEnding(QCPLineEnding::esNone), + upperEnding(QCPLineEnding::esNone), + labelPadding(0), + tickLabelPadding(0), + tickLabelRotation(0), + tickLabelSide(QCPAxis::lsOutside), + substituteExponent(true), + numberMultiplyCross(false), + tickLengthIn(5), + tickLengthOut(0), + subTickLengthIn(2), + subTickLengthOut(0), + tickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + subTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + offset(0), + abbreviateDecimalPowers(false), + reversedEndings(false), + mParentPlot(parentPlot), + mLabelCache(16) // cache at most 16 (tick) labels +{ +} + +QCPAxisPainterPrivate::~QCPAxisPainterPrivate() +{ +} + +/*! \internal + + Draws the axis with the specified \a painter. + + The selection boxes (mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox) are set + here, too. +*/ +void QCPAxisPainterPrivate::draw(QCPPainter *painter) +{ + QByteArray newHash = generateLabelParameterHash(); + if (newHash != mLabelParameterHash) + { + mLabelCache.clear(); + mLabelParameterHash = newHash; + } + + QPoint origin; + switch (type) + { + case QCPAxis::atLeft: origin = axisRect.bottomLeft() +QPoint(-offset, 0); break; + case QCPAxis::atRight: origin = axisRect.bottomRight()+QPoint(+offset, 0); break; + case QCPAxis::atTop: origin = axisRect.topLeft() +QPoint(0, -offset); break; + case QCPAxis::atBottom: origin = axisRect.bottomLeft() +QPoint(0, +offset); break; + } + + double xCor = 0, yCor = 0; // paint system correction, for pixel exact matches (affects baselines and ticks of top/right axes) + switch (type) + { + case QCPAxis::atTop: yCor = -1; break; + case QCPAxis::atRight: xCor = 1; break; + default: break; + } + int margin = 0; + // draw baseline: + QLineF baseLine; + painter->setPen(basePen); + if (QCPAxis::orientation(type) == Qt::Horizontal) + baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(axisRect.width()+xCor, yCor)); + else + baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(xCor, -axisRect.height()+yCor)); + if (reversedEndings) + baseLine = QLineF(baseLine.p2(), baseLine.p1()); // won't make a difference for line itself, but for line endings later + painter->drawLine(baseLine); + + // draw ticks: + if (!tickPositions.isEmpty()) + { + painter->setPen(tickPen); + int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; // direction of ticks ("inward" is right for left axis and left for right axis) + if (QCPAxis::orientation(type) == Qt::Horizontal) + { + for (int i=0; idrawLine(QLineF(tickPositions.at(i)+xCor, origin.y()-tickLengthOut*tickDir+yCor, tickPositions.at(i)+xCor, origin.y()+tickLengthIn*tickDir+yCor)); + } else + { + for (int i=0; idrawLine(QLineF(origin.x()-tickLengthOut*tickDir+xCor, tickPositions.at(i)+yCor, origin.x()+tickLengthIn*tickDir+xCor, tickPositions.at(i)+yCor)); + } + } + + // draw subticks: + if (!subTickPositions.isEmpty()) + { + painter->setPen(subTickPen); + // direction of ticks ("inward" is right for left axis and left for right axis) + int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; + if (QCPAxis::orientation(type) == Qt::Horizontal) + { + for (int i=0; idrawLine(QLineF(subTickPositions.at(i)+xCor, origin.y()-subTickLengthOut*tickDir+yCor, subTickPositions.at(i)+xCor, origin.y()+subTickLengthIn*tickDir+yCor)); + } else + { + for (int i=0; idrawLine(QLineF(origin.x()-subTickLengthOut*tickDir+xCor, subTickPositions.at(i)+yCor, origin.x()+subTickLengthIn*tickDir+xCor, subTickPositions.at(i)+yCor)); + } + } + margin += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // draw axis base endings: + bool antialiasingBackup = painter->antialiasing(); + painter->setAntialiasing(true); // always want endings to be antialiased, even if base and ticks themselves aren't + painter->setBrush(QBrush(basePen.color())); + QCPVector2D baseLineVector(baseLine.dx(), baseLine.dy()); + if (lowerEnding.style() != QCPLineEnding::esNone) + lowerEnding.draw(painter, QCPVector2D(baseLine.p1())-baseLineVector.normalized()*lowerEnding.realLength()*(lowerEnding.inverted()?-1:1), -baseLineVector); + if (upperEnding.style() != QCPLineEnding::esNone) + upperEnding.draw(painter, QCPVector2D(baseLine.p2())+baseLineVector.normalized()*upperEnding.realLength()*(upperEnding.inverted()?-1:1), baseLineVector); + painter->setAntialiasing(antialiasingBackup); + + // tick labels: + QRect oldClipRect; + if (tickLabelSide == QCPAxis::lsInside) // if using inside labels, clip them to the axis rect + { + oldClipRect = painter->clipRegion().boundingRect(); + painter->setClipRect(axisRect); + } + QSize tickLabelsSize(0, 0); // size of largest tick label, for offset calculation of axis label + if (!tickLabels.isEmpty()) + { + if (tickLabelSide == QCPAxis::lsOutside) + margin += tickLabelPadding; + painter->setFont(tickLabelFont); + painter->setPen(QPen(tickLabelColor)); + const int maxLabelIndex = qMin(tickPositions.size(), tickLabels.size()); + int distanceToAxis = margin; + if (tickLabelSide == QCPAxis::lsInside) + distanceToAxis = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); + for (int i=0; isetClipRect(oldClipRect); + + // axis label: + QRect labelBounds; + if (!label.isEmpty()) + { + margin += labelPadding; + painter->setFont(labelFont); + painter->setPen(QPen(labelColor)); + labelBounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip, label); + if (type == QCPAxis::atLeft) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()-margin-labelBounds.height()), origin.y()); + painter->rotate(-90); + painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + painter->setTransform(oldTransform); + } + else if (type == QCPAxis::atRight) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()+margin+labelBounds.height()), origin.y()-axisRect.height()); + painter->rotate(90); + painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + painter->setTransform(oldTransform); + } + else if (type == QCPAxis::atTop) + painter->drawText(origin.x(), origin.y()-margin-labelBounds.height(), axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + else if (type == QCPAxis::atBottom) + painter->drawText(origin.x(), origin.y()+margin, axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + } + + // set selection boxes: + int selectionTolerance = 0; + if (mParentPlot) + selectionTolerance = mParentPlot->selectionTolerance(); + else + qDebug() << Q_FUNC_INFO << "mParentPlot is null"; + int selAxisOutSize = qMax(qMax(tickLengthOut, subTickLengthOut), selectionTolerance); + int selAxisInSize = selectionTolerance; + int selTickLabelSize; + int selTickLabelOffset; + if (tickLabelSide == QCPAxis::lsOutside) + { + selTickLabelSize = (QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + selTickLabelOffset = qMax(tickLengthOut, subTickLengthOut)+tickLabelPadding; + } else + { + selTickLabelSize = -(QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + selTickLabelOffset = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); + } + int selLabelSize = labelBounds.height(); + int selLabelOffset = qMax(tickLengthOut, subTickLengthOut)+(!tickLabels.isEmpty() && tickLabelSide == QCPAxis::lsOutside ? tickLabelPadding+selTickLabelSize : 0)+labelPadding; + if (type == QCPAxis::atLeft) + { + mAxisSelectionBox.setCoords(origin.x()-selAxisOutSize, axisRect.top(), origin.x()+selAxisInSize, axisRect.bottom()); + mTickLabelsSelectionBox.setCoords(origin.x()-selTickLabelOffset-selTickLabelSize, axisRect.top(), origin.x()-selTickLabelOffset, axisRect.bottom()); + mLabelSelectionBox.setCoords(origin.x()-selLabelOffset-selLabelSize, axisRect.top(), origin.x()-selLabelOffset, axisRect.bottom()); + } else if (type == QCPAxis::atRight) + { + mAxisSelectionBox.setCoords(origin.x()-selAxisInSize, axisRect.top(), origin.x()+selAxisOutSize, axisRect.bottom()); + mTickLabelsSelectionBox.setCoords(origin.x()+selTickLabelOffset+selTickLabelSize, axisRect.top(), origin.x()+selTickLabelOffset, axisRect.bottom()); + mLabelSelectionBox.setCoords(origin.x()+selLabelOffset+selLabelSize, axisRect.top(), origin.x()+selLabelOffset, axisRect.bottom()); + } else if (type == QCPAxis::atTop) + { + mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisOutSize, axisRect.right(), origin.y()+selAxisInSize); + mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()-selTickLabelOffset-selTickLabelSize, axisRect.right(), origin.y()-selTickLabelOffset); + mLabelSelectionBox.setCoords(axisRect.left(), origin.y()-selLabelOffset-selLabelSize, axisRect.right(), origin.y()-selLabelOffset); + } else if (type == QCPAxis::atBottom) + { + mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisInSize, axisRect.right(), origin.y()+selAxisOutSize); + mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()+selTickLabelOffset+selTickLabelSize, axisRect.right(), origin.y()+selTickLabelOffset); + mLabelSelectionBox.setCoords(axisRect.left(), origin.y()+selLabelOffset+selLabelSize, axisRect.right(), origin.y()+selLabelOffset); + } + mAxisSelectionBox = mAxisSelectionBox.normalized(); + mTickLabelsSelectionBox = mTickLabelsSelectionBox.normalized(); + mLabelSelectionBox = mLabelSelectionBox.normalized(); + // draw hitboxes for debug purposes: + //painter->setBrush(Qt::NoBrush); + //painter->drawRects(QVector() << mAxisSelectionBox << mTickLabelsSelectionBox << mLabelSelectionBox); +} + +/*! \internal + + Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone + direction) needed to fit the axis. +*/ +int QCPAxisPainterPrivate::size() const +{ + int result = 0; + + // get length of tick marks pointing outwards: + if (!tickPositions.isEmpty()) + result += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // calculate size of tick labels: + if (tickLabelSide == QCPAxis::lsOutside) + { + QSize tickLabelsSize(0, 0); + if (!tickLabels.isEmpty()) + { + for (int i=0; ibufferDevicePixelRatio())); + result.append(QByteArray::number(tickLabelRotation)); + result.append(QByteArray::number((int)tickLabelSide)); + result.append(QByteArray::number((int)substituteExponent)); + result.append(QByteArray::number((int)numberMultiplyCross)); + result.append(tickLabelColor.name().toLatin1()+QByteArray::number(tickLabelColor.alpha(), 16)); + result.append(tickLabelFont.toString().toLatin1()); + return result; +} + +/*! \internal + + Draws a single tick label with the provided \a painter, utilizing the internal label cache to + significantly speed up drawing of labels that were drawn in previous calls. The tick label is + always bound to an axis, the distance to the axis is controllable via \a distanceToAxis in + pixels. The pixel position in the axis direction is passed in the \a position parameter. Hence + for the bottom axis, \a position would indicate the horizontal pixel position (not coordinate), + at which the label should be drawn. + + In order to later draw the axis label in a place that doesn't overlap with the tick labels, the + largest tick label size is needed. This is acquired by passing a \a tickLabelsSize to the \ref + drawTickLabel calls during the process of drawing all tick labels of one axis. In every call, \a + tickLabelsSize is expanded, if the drawn label exceeds the value \a tickLabelsSize currently + holds. + + The label is drawn with the font and pen that are currently set on the \a painter. To draw + superscripted powers, the font is temporarily made smaller by a fixed factor (see \ref + getTickLabelData). +*/ +void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize) +{ + // warning: if you change anything here, also adapt getMaxTickLabelSize() accordingly! + if (text.isEmpty()) return; + QSize finalSize; + QPointF labelAnchor; + switch (type) + { + case QCPAxis::atLeft: labelAnchor = QPointF(axisRect.left()-distanceToAxis-offset, position); break; + case QCPAxis::atRight: labelAnchor = QPointF(axisRect.right()+distanceToAxis+offset, position); break; + case QCPAxis::atTop: labelAnchor = QPointF(position, axisRect.top()-distanceToAxis-offset); break; + case QCPAxis::atBottom: labelAnchor = QPointF(position, axisRect.bottom()+distanceToAxis+offset); break; + } + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && !painter->modes().testFlag(QCPPainter::pmNoCaching)) // label caching enabled + { + CachedLabel *cachedLabel = mLabelCache.take(text); // attempt to get label from cache + if (!cachedLabel) // no cached label existed, create it + { + cachedLabel = new CachedLabel; + TickLabelData labelData = getTickLabelData(painter->font(), text); + cachedLabel->offset = getTickLabelDrawOffset(labelData)+labelData.rotatedTotalBounds.topLeft(); + if (!qFuzzyCompare(1.0, mParentPlot->bufferDevicePixelRatio())) + { + cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()*mParentPlot->bufferDevicePixelRatio()); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED +# ifdef QCP_DEVICEPIXELRATIO_FLOAT + cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatioF()); +# else + cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio()); +# endif +#endif + } else + cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); + cachedLabel->pixmap.fill(Qt::transparent); + QCPPainter cachePainter(&cachedLabel->pixmap); + cachePainter.setPen(painter->pen()); + drawTickLabel(&cachePainter, -labelData.rotatedTotalBounds.topLeft().x(), -labelData.rotatedTotalBounds.topLeft().y(), labelData); + } + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = labelAnchor.x()+cachedLabel->offset.x()+cachedLabel->pixmap.width()/mParentPlot->bufferDevicePixelRatio() > viewportRect.right() || labelAnchor.x()+cachedLabel->offset.x() < viewportRect.left(); + else + labelClippedByBorder = labelAnchor.y()+cachedLabel->offset.y()+cachedLabel->pixmap.height()/mParentPlot->bufferDevicePixelRatio() > viewportRect.bottom() || labelAnchor.y()+cachedLabel->offset.y() < viewportRect.top(); + } + if (!labelClippedByBorder) + { + painter->drawPixmap(labelAnchor+cachedLabel->offset, cachedLabel->pixmap); + finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); + } + mLabelCache.insert(text, cachedLabel); // return label to cache or insert for the first time if newly created + } else // label caching disabled, draw text directly on surface: + { + TickLabelData labelData = getTickLabelData(painter->font(), text); + QPointF finalPosition = labelAnchor + getTickLabelDrawOffset(labelData); + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = finalPosition.x()+(labelData.rotatedTotalBounds.width()+labelData.rotatedTotalBounds.left()) > viewportRect.right() || finalPosition.x()+labelData.rotatedTotalBounds.left() < viewportRect.left(); + else + labelClippedByBorder = finalPosition.y()+(labelData.rotatedTotalBounds.height()+labelData.rotatedTotalBounds.top()) > viewportRect.bottom() || finalPosition.y()+labelData.rotatedTotalBounds.top() < viewportRect.top(); + } + if (!labelClippedByBorder) + { + drawTickLabel(painter, finalPosition.x(), finalPosition.y(), labelData); + finalSize = labelData.rotatedTotalBounds.size(); + } + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a + y. This function is used by \ref placeTickLabel to create new tick labels for the cache, or to + directly draw the labels on the QCustomPlot surface when label caching is disabled, i.e. when + QCP::phCacheLabels plotting hint is not set. +*/ +void QCPAxisPainterPrivate::drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const +{ + // backup painter settings that we're about to change: + QTransform oldTransform = painter->transform(); + QFont oldFont = painter->font(); + + // transform painter to position/rotation: + painter->translate(x, y); + if (!qFuzzyIsNull(tickLabelRotation)) + painter->rotate(tickLabelRotation); + + // draw text: + if (!labelData.expPart.isEmpty()) // indicator that beautiful powers must be used + { + painter->setFont(labelData.baseFont); + painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.basePart); + if (!labelData.suffixPart.isEmpty()) + painter->drawText(labelData.baseBounds.width()+1+labelData.expBounds.width(), 0, 0, 0, Qt::TextDontClip, labelData.suffixPart); + painter->setFont(labelData.expFont); + painter->drawText(labelData.baseBounds.width()+1, 0, labelData.expBounds.width(), labelData.expBounds.height(), Qt::TextDontClip, labelData.expPart); + } else + { + painter->setFont(labelData.baseFont); + painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart); + } + + // reset painter settings to what it was before: + painter->setTransform(oldTransform); + painter->setFont(oldFont); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Transforms the passed \a text and \a font to a tickLabelData structure that can then be further + processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and + exponent if necessary (member substituteExponent) and calculates appropriate bounding boxes. +*/ +QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(const QFont &font, const QString &text) const +{ + TickLabelData result; + + // determine whether beautiful decimal powers should be used + bool useBeautifulPowers = false; + int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart + int eLast = -1; // last index of exponent part, rest of text after this will be suffixPart + if (substituteExponent) + { + ePos = text.indexOf(QLatin1Char('e')); + if (ePos > 0 && text.at(ePos-1).isDigit()) + { + eLast = ePos; + while (eLast+1 < text.size() && (text.at(eLast+1) == QLatin1Char('+') || text.at(eLast+1) == QLatin1Char('-') || text.at(eLast+1).isDigit())) + ++eLast; + if (eLast > ePos) // only if also to right of 'e' is a digit/+/- interpret it as beautifiable power + useBeautifulPowers = true; + } + } + + // calculate text bounding rects and do string preparation for beautiful decimal powers: + result.baseFont = font; + if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line + result.baseFont.setPointSizeF(result.baseFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding + if (useBeautifulPowers) + { + // split text into parts of number/symbol that will be drawn normally and part that will be drawn as exponent: + result.basePart = text.left(ePos); + result.suffixPart = text.mid(eLast+1); // also drawn normally but after exponent + // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base: + if (abbreviateDecimalPowers && result.basePart == QLatin1String("1")) + result.basePart = QLatin1String("10"); + else + result.basePart += (numberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) + QLatin1String("10"); + result.expPart = text.mid(ePos+1, eLast-ePos); + // clip "+" and leading zeros off expPart: + while (result.expPart.length() > 2 && result.expPart.at(1) == QLatin1Char('0')) // length > 2 so we leave one zero when numberFormatChar is 'e' + result.expPart.remove(1, 1); + if (!result.expPart.isEmpty() && result.expPart.at(0) == QLatin1Char('+')) + result.expPart.remove(0, 1); + // prepare smaller font for exponent: + result.expFont = font; + if (result.expFont.pointSize() > 0) + result.expFont.setPointSize(result.expFont.pointSize()*0.75); + else + result.expFont.setPixelSize(result.expFont.pixelSize()*0.75); + // calculate bounding rects of base part(s), exponent part and total one: + result.baseBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.basePart); + result.expBounds = QFontMetrics(result.expFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.expPart); + if (!result.suffixPart.isEmpty()) + result.suffixBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.suffixPart); + result.totalBounds = result.baseBounds.adjusted(0, 0, result.expBounds.width()+result.suffixBounds.width()+2, 0); // +2 consists of the 1 pixel spacing between base and exponent (see drawTickLabel) and an extra pixel to include AA + } else // useBeautifulPowers == false + { + result.basePart = text; + result.totalBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.basePart); + } + result.totalBounds.moveTopLeft(QPoint(0, 0)); // want bounding box aligned top left at origin, independent of how it was created, to make further processing simpler + + // calculate possibly different bounding rect after rotation: + result.rotatedTotalBounds = result.totalBounds; + if (!qFuzzyIsNull(tickLabelRotation)) + { + QTransform transform; + transform.rotate(tickLabelRotation); + result.rotatedTotalBounds = transform.mapRect(result.rotatedTotalBounds); + } + + return result; +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Calculates the offset at which the top left corner of the specified tick label shall be drawn. + The offset is relative to a point right next to the tick the label belongs to. + + This function is thus responsible for e.g. centering tick labels under ticks and positioning them + appropriately when they are rotated. +*/ +QPointF QCPAxisPainterPrivate::getTickLabelDrawOffset(const TickLabelData &labelData) const +{ + /* + calculate label offset from base point at tick (non-trivial, for best visual appearance): short + explanation for bottom axis: The anchor, i.e. the point in the label that is placed + horizontally under the corresponding tick is always on the label side that is closer to the + axis (e.g. the left side of the text when we're rotating clockwise). On that side, the height + is halved and the resulting point is defined the anchor. This way, a 90 degree rotated text + will be centered under the tick (i.e. displaced horizontally by half its height). At the same + time, a 45 degree rotated text will "point toward" its tick, as is typical for rotated tick + labels. + */ + bool doRotation = !qFuzzyIsNull(tickLabelRotation); + bool flip = qFuzzyCompare(qAbs(tickLabelRotation), 90.0); // perfect +/-90 degree flip. Indicates vertical label centering on vertical axes. + double radians = tickLabelRotation/180.0*M_PI; + int x=0, y=0; + if ((type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsInside)) // Anchor at right side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = -qCos(radians)*labelData.totalBounds.width(); + y = flip ? -labelData.totalBounds.width()/2.0 : -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height()/2.0; + } else + { + x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height(); + y = flip ? +labelData.totalBounds.width()/2.0 : +qSin(-radians)*labelData.totalBounds.width()-qCos(-radians)*labelData.totalBounds.height()/2.0; + } + } else + { + x = -labelData.totalBounds.width(); + y = -labelData.totalBounds.height()/2.0; + } + } else if ((type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsInside)) // Anchor at left side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = +qSin(radians)*labelData.totalBounds.height(); + y = flip ? -labelData.totalBounds.width()/2.0 : -qCos(radians)*labelData.totalBounds.height()/2.0; + } else + { + x = 0; + y = flip ? +labelData.totalBounds.width()/2.0 : -qCos(-radians)*labelData.totalBounds.height()/2.0; + } + } else + { + x = 0; + y = -labelData.totalBounds.height()/2.0; + } + } else if ((type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsInside)) // Anchor at bottom side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = -qCos(radians)*labelData.totalBounds.width()+qSin(radians)*labelData.totalBounds.height()/2.0; + y = -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height(); + } else + { + x = -qSin(-radians)*labelData.totalBounds.height()/2.0; + y = -qCos(-radians)*labelData.totalBounds.height(); + } + } else + { + x = -labelData.totalBounds.width()/2.0; + y = -labelData.totalBounds.height(); + } + } else if ((type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsInside)) // Anchor at top side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = +qSin(radians)*labelData.totalBounds.height()/2.0; + y = 0; + } else + { + x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height()/2.0; + y = +qSin(-radians)*labelData.totalBounds.width(); + } + } else + { + x = -labelData.totalBounds.width()/2.0; + y = 0; + } + } + + return QPointF(x, y); +} + +/*! \internal + + Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label + to be drawn, depending on number format etc. Since only the largest tick label is wanted for the + margin calculation, the passed \a tickLabelsSize is only expanded, if it's currently set to a + smaller width/height. +*/ +void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const +{ + // note: this function must return the same tick label sizes as the placeTickLabel function. + QSize finalSize; + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && mLabelCache.contains(text)) // label caching enabled and have cached label + { + const CachedLabel *cachedLabel = mLabelCache.object(text); + finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); + } else // label caching disabled or no label with this text cached: + { + TickLabelData labelData = getTickLabelData(font, text); + finalSize = labelData.rotatedTotalBounds.size(); + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} +/* end of 'src/axis/axis.cpp' */ + + +/* including file 'src/scatterstyle.cpp', size 17450 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPScatterStyle +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPScatterStyle + \brief Represents the visual appearance of scatter points + + This class holds information about shape, color and size of scatter points. In plottables like + QCPGraph it is used to store how scatter points shall be drawn. For example, \ref + QCPGraph::setScatterStyle takes a QCPScatterStyle instance. + + A scatter style consists of a shape (\ref setShape), a line color (\ref setPen) and possibly a + fill (\ref setBrush), if the shape provides a fillable area. Further, the size of the shape can + be controlled with \ref setSize. + + \section QCPScatterStyle-defining Specifying a scatter style + + You can set all these configurations either by calling the respective functions on an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-1 + + Or you can use one of the various constructors that take different parameter combinations, making + it easy to specify a scatter style in a single call, like so: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-2 + + \section QCPScatterStyle-undefinedpen Leaving the color/pen up to the plottable + + There are two constructors which leave the pen undefined: \ref QCPScatterStyle() and \ref + QCPScatterStyle(ScatterShape shape, double size). If those constructors are used, a call to \ref + isPenDefined will return false. It leads to scatter points that inherit the pen from the + plottable that uses the scatter style. Thus, if such a scatter style is passed to QCPGraph, the line + color of the graph (\ref QCPGraph::setPen) will be used by the scatter points. This makes + it very convenient to set up typical scatter settings: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-shortcreation + + Notice that it wasn't even necessary to explicitly call a QCPScatterStyle constructor. This works + because QCPScatterStyle provides a constructor that can transform a \ref ScatterShape directly + into a QCPScatterStyle instance (that's the \ref QCPScatterStyle(ScatterShape shape, double size) + constructor with a default for \a size). In those cases, C++ allows directly supplying a \ref + ScatterShape, where actually a QCPScatterStyle is expected. + + \section QCPScatterStyle-custompath-and-pixmap Custom shapes and pixmaps + + QCPScatterStyle supports drawing custom shapes and arbitrary pixmaps as scatter points. + + For custom shapes, you can provide a QPainterPath with the desired shape to the \ref + setCustomPath function or call the constructor that takes a painter path. The scatter shape will + automatically be set to \ref ssCustom. + + For pixmaps, you call \ref setPixmap with the desired QPixmap. Alternatively you can use the + constructor that takes a QPixmap. The scatter shape will automatically be set to \ref ssPixmap. + Note that \ref setSize does not influence the appearance of the pixmap. +*/ + +/* start documentation of inline functions */ + +/*! \fn bool QCPScatterStyle::isNone() const + + Returns whether the scatter shape is \ref ssNone. + + \see setShape +*/ + +/*! \fn bool QCPScatterStyle::isPenDefined() const + + Returns whether a pen has been defined for this scatter style. + + The pen is undefined if a constructor is called that does not carry \a pen as parameter. Those + are \ref QCPScatterStyle() and \ref QCPScatterStyle(ScatterShape shape, double size). If the pen + is undefined, the pen of the respective plottable will be used for drawing scatters. + + If a pen was defined for this scatter style instance, and you now wish to undefine the pen, call + \ref undefinePen. + + \see setPen +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPScatterStyle instance with size set to 6. No shape, pen or brush is defined. + + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited + from the plottable that uses this scatter style. +*/ +QCPScatterStyle::QCPScatterStyle() : + mSize(6), + mShape(ssNone), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape and size to \a size. No pen or + brush is defined. + + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited + from the plottable that uses this scatter style. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, double size) : + mSize(size), + mShape(shape), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, + and size to \a size. No brush is defined, i.e. the scatter point will not be filled. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, double size) : + mSize(size), + mShape(shape), + mPen(QPen(color)), + mBrush(Qt::NoBrush), + mPenDefined(true) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, + the brush color to \a fill (with a solid pattern), and size to \a size. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) : + mSize(size), + mShape(shape), + mPen(QPen(color)), + mBrush(QBrush(fill)), + mPenDefined(true) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen set to \a pen, the + brush to \a brush, and size to \a size. + + \warning In some cases it might be tempting to directly use a pen style like Qt::NoPen as \a pen + and a color like Qt::blue as \a brush. Notice however, that the corresponding call\n + QCPScatterStyle(QCPScatterShape::ssCircle, Qt::NoPen, Qt::blue, 5)\n + doesn't necessarily lead C++ to use this constructor in some cases, but might mistake + Qt::NoPen for a QColor and use the + \ref QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) + constructor instead (which will lead to an unexpected look of the scatter points). To prevent + this, be more explicit with the parameter types. For example, use QBrush(Qt::blue) + instead of just Qt::blue, to clearly point out to the compiler that this constructor is + wanted. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size) : + mSize(size), + mShape(shape), + mPen(pen), + mBrush(brush), + mPenDefined(pen.style() != Qt::NoPen) +{ +} + +/*! + Creates a new QCPScatterStyle instance which will show the specified \a pixmap. The scatter shape + is set to \ref ssPixmap. +*/ +QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap) : + mSize(5), + mShape(ssPixmap), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPixmap(pixmap), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with a custom shape that is defined via \a customPath. The + scatter shape is set to \ref ssCustom. + + The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly + different meaning than for built-in scatter points: The custom path will be drawn scaled by a + factor of \a size/6.0. Since the default \a size is 6, the custom path will appear in its + original size by default. To for example double the size of the path, set \a size to 12. +*/ +QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush, double size) : + mSize(size), + mShape(ssCustom), + mPen(pen), + mBrush(brush), + mCustomPath(customPath), + mPenDefined(pen.style() != Qt::NoPen) +{ +} + +/*! + Copies the specified \a properties from the \a other scatter style to this scatter style. +*/ +void QCPScatterStyle::setFromOther(const QCPScatterStyle &other, ScatterProperties properties) +{ + if (properties.testFlag(spPen)) + { + setPen(other.pen()); + if (!other.isPenDefined()) + undefinePen(); + } + if (properties.testFlag(spBrush)) + setBrush(other.brush()); + if (properties.testFlag(spSize)) + setSize(other.size()); + if (properties.testFlag(spShape)) + { + setShape(other.shape()); + if (other.shape() == ssPixmap) + setPixmap(other.pixmap()); + else if (other.shape() == ssCustom) + setCustomPath(other.customPath()); + } +} + +/*! + Sets the size (pixel diameter) of the drawn scatter points to \a size. + + \see setShape +*/ +void QCPScatterStyle::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the shape to \a shape. + + Note that the calls \ref setPixmap and \ref setCustomPath automatically set the shape to \ref + ssPixmap and \ref ssCustom, respectively. + + \see setSize +*/ +void QCPScatterStyle::setShape(QCPScatterStyle::ScatterShape shape) +{ + mShape = shape; +} + +/*! + Sets the pen that will be used to draw scatter points to \a pen. + + If the pen was previously undefined (see \ref isPenDefined), the pen is considered defined after + a call to this function, even if \a pen is Qt::NoPen. If you have defined a pen + previously by calling this function and now wish to undefine the pen, call \ref undefinePen. + + \see setBrush +*/ +void QCPScatterStyle::setPen(const QPen &pen) +{ + mPenDefined = true; + mPen = pen; +} + +/*! + Sets the brush that will be used to fill scatter points to \a brush. Note that not all scatter + shapes have fillable areas. For example, \ref ssPlus does not while \ref ssCircle does. + + \see setPen +*/ +void QCPScatterStyle::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the pixmap that will be drawn as scatter point to \a pixmap. + + Note that \ref setSize does not influence the appearance of the pixmap. + + The scatter shape is automatically set to \ref ssPixmap. +*/ +void QCPScatterStyle::setPixmap(const QPixmap &pixmap) +{ + setShape(ssPixmap); + mPixmap = pixmap; +} + +/*! + Sets the custom shape that will be drawn as scatter point to \a customPath. + + The scatter shape is automatically set to \ref ssCustom. +*/ +void QCPScatterStyle::setCustomPath(const QPainterPath &customPath) +{ + setShape(ssCustom); + mCustomPath = customPath; +} + +/*! + Sets this scatter style to have an undefined pen (see \ref isPenDefined for what an undefined pen + implies). + + A call to \ref setPen will define a pen. +*/ +void QCPScatterStyle::undefinePen() +{ + mPenDefined = false; +} + +/*! + Applies the pen and the brush of this scatter style to \a painter. If this scatter style has an + undefined pen (\ref isPenDefined), sets the pen of \a painter to \a defaultPen instead. + + This function is used by plottables (or any class that wants to draw scatters) just before a + number of scatters with this style shall be drawn with the \a painter. + + \see drawShape +*/ +void QCPScatterStyle::applyTo(QCPPainter *painter, const QPen &defaultPen) const +{ + painter->setPen(mPenDefined ? mPen : defaultPen); + painter->setBrush(mBrush); +} + +/*! + Draws the scatter shape with \a painter at position \a pos. + + This function does not modify the pen or the brush on the painter, as \ref applyTo is meant to be + called before scatter points are drawn with \ref drawShape. + + \see applyTo +*/ +void QCPScatterStyle::drawShape(QCPPainter *painter, const QPointF &pos) const +{ + drawShape(painter, pos.x(), pos.y()); +} + +/*! \overload + Draws the scatter shape with \a painter at position \a x and \a y. +*/ +void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const +{ + double w = mSize/2.0; + switch (mShape) + { + case ssNone: break; + case ssDot: + { + painter->drawLine(QPointF(x, y), QPointF(x+0.0001, y)); + break; + } + case ssCross: + { + painter->drawLine(QLineF(x-w, y-w, x+w, y+w)); + painter->drawLine(QLineF(x-w, y+w, x+w, y-w)); + break; + } + case ssPlus: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssCircle: + { + painter->drawEllipse(QPointF(x , y), w, w); + break; + } + case ssDisc: + { + QBrush b = painter->brush(); + painter->setBrush(painter->pen().color()); + painter->drawEllipse(QPointF(x , y), w, w); + painter->setBrush(b); + break; + } + case ssSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + break; + } + case ssDiamond: + { + QPointF lineArray[4] = {QPointF(x-w, y), + QPointF( x, y-w), + QPointF(x+w, y), + QPointF( x, y+w)}; + painter->drawPolygon(lineArray, 4); + break; + } + case ssStar: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707)); + painter->drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707)); + break; + } + case ssTriangle: + { + QPointF lineArray[3] = {QPointF(x-w, y+0.755*w), + QPointF(x+w, y+0.755*w), + QPointF( x, y-0.977*w)}; + painter->drawPolygon(lineArray, 3); + break; + } + case ssTriangleInverted: + { + QPointF lineArray[3] = {QPointF(x-w, y-0.755*w), + QPointF(x+w, y-0.755*w), + QPointF( x, y+0.977*w)}; + painter->drawPolygon(lineArray, 3); + break; + } + case ssCrossSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + painter->drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95)); + painter->drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w)); + break; + } + case ssPlusSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + painter->drawLine(QLineF(x-w, y, x+w*0.95, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssCrossCircle: + { + painter->drawEllipse(QPointF(x, y), w, w); + painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.670, y+w*0.670)); + painter->drawLine(QLineF(x-w*0.707, y+w*0.670, x+w*0.670, y-w*0.707)); + break; + } + case ssPlusCircle: + { + painter->drawEllipse(QPointF(x, y), w, w); + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssPeace: + { + painter->drawEllipse(QPointF(x, y), w, w); + painter->drawLine(QLineF(x, y-w, x, y+w)); + painter->drawLine(QLineF(x, y, x-w*0.707, y+w*0.707)); + painter->drawLine(QLineF(x, y, x+w*0.707, y+w*0.707)); + break; + } + case ssPixmap: + { + const double widthHalf = mPixmap.width()*0.5; + const double heightHalf = mPixmap.height()*0.5; +#if QT_VERSION < QT_VERSION_CHECK(4, 8, 0) + const QRectF clipRect = painter->clipRegion().boundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); +#else + const QRectF clipRect = painter->clipBoundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); +#endif + if (clipRect.contains(x, y)) + painter->drawPixmap(x-widthHalf, y-heightHalf, mPixmap); + break; + } + case ssCustom: + { + QTransform oldTransform = painter->transform(); + painter->translate(x, y); + painter->scale(mSize/6.0, mSize/6.0); + painter->drawPath(mCustomPath); + painter->setTransform(oldTransform); + break; + } + } +} +/* end of 'src/scatterstyle.cpp' */ + +//amalgamation: add datacontainer.cpp + +/* including file 'src/plottable.cpp', size 38845 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPSelectionDecorator +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPSelectionDecorator + \brief Controls how a plottable's data selection is drawn + + Each \ref QCPAbstractPlottable instance has one \ref QCPSelectionDecorator (accessible via \ref + QCPAbstractPlottable::selectionDecorator) and uses it when drawing selected segments of its data. + + The selection decorator controls both pen (\ref setPen) and brush (\ref setBrush), as well as the + scatter style (\ref setScatterStyle) if the plottable draws scatters. Since a \ref + QCPScatterStyle is itself composed of different properties such as color shape and size, the + decorator allows specifying exactly which of those properties shall be used for the selected data + point, via \ref setUsedScatterProperties. + + A \ref QCPSelectionDecorator subclass instance can be passed to a plottable via \ref + QCPAbstractPlottable::setSelectionDecorator, allowing greater customizability of the appearance + of selected segments. + + Use \ref copyFrom to easily transfer the settings of one decorator to another one. This is + especially useful since plottables take ownership of the passed selection decorator, and thus the + same decorator instance can not be passed to multiple plottables. + + Selection decorators can also themselves perform drawing operations by reimplementing \ref + drawDecoration, which is called by the plottable's draw method. The base class \ref + QCPSelectionDecorator does not make use of this however. For example, \ref + QCPSelectionDecoratorBracket draws brackets around selected data segments. +*/ + +/*! + Creates a new QCPSelectionDecorator instance with default values +*/ +QCPSelectionDecorator::QCPSelectionDecorator() : + mPen(QColor(80, 80, 255), 2.5), + mBrush(Qt::NoBrush), + mScatterStyle(), + mUsedScatterProperties(QCPScatterStyle::spNone), + mPlottable(0) +{ +} + +QCPSelectionDecorator::~QCPSelectionDecorator() +{ +} + +/*! + Sets the pen that will be used by the parent plottable to draw selected data segments. +*/ +void QCPSelectionDecorator::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the brush that will be used by the parent plottable to draw selected data segments. +*/ +void QCPSelectionDecorator::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the scatter style that will be used by the parent plottable to draw scatters in selected + data segments. + + \a usedProperties specifies which parts of the passed \a scatterStyle will be used by the + plottable. The used properties can also be changed via \ref setUsedScatterProperties. +*/ +void QCPSelectionDecorator::setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties) +{ + mScatterStyle = scatterStyle; + setUsedScatterProperties(usedProperties); +} + +/*! + Use this method to define which properties of the scatter style (set via \ref setScatterStyle) + will be used for selected data segments. All properties of the scatter style that are not + specified in \a properties will remain as specified in the plottable's original scatter style. + + \see QCPScatterStyle::ScatterProperty +*/ +void QCPSelectionDecorator::setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties) +{ + mUsedScatterProperties = properties; +} + +/*! + Sets the pen of \a painter to the pen of this selection decorator. + + \see applyBrush, getFinalScatterStyle +*/ +void QCPSelectionDecorator::applyPen(QCPPainter *painter) const +{ + painter->setPen(mPen); +} + +/*! + Sets the brush of \a painter to the brush of this selection decorator. + + \see applyPen, getFinalScatterStyle +*/ +void QCPSelectionDecorator::applyBrush(QCPPainter *painter) const +{ + painter->setBrush(mBrush); +} + +/*! + Returns the scatter style that the parent plottable shall use for selected scatter points. The + plottable's original (unselected) scatter style must be passed as \a unselectedStyle. Depending + on the setting of \ref setUsedScatterProperties, the returned scatter style is a mixture of this + selecion decorator's scatter style (\ref setScatterStyle), and \a unselectedStyle. + + \see applyPen, applyBrush, setScatterStyle +*/ +QCPScatterStyle QCPSelectionDecorator::getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const +{ + QCPScatterStyle result(unselectedStyle); + result.setFromOther(mScatterStyle, mUsedScatterProperties); + + // if style shall inherit pen from plottable (has no own pen defined), give it the selected + // plottable pen explicitly, so it doesn't use the unselected plottable pen when used in the + // plottable: + if (!result.isPenDefined()) + result.setPen(mPen); + + return result; +} + +/*! + Copies all properties (e.g. color, fill, scatter style) of the \a other selection decorator to + this selection decorator. +*/ +void QCPSelectionDecorator::copyFrom(const QCPSelectionDecorator *other) +{ + setPen(other->pen()); + setBrush(other->brush()); + setScatterStyle(other->scatterStyle(), other->usedScatterProperties()); +} + +/*! + This method is called by all plottables' draw methods to allow custom selection decorations to be + drawn. Use the passed \a painter to perform the drawing operations. \a selection carries the data + selection for which the decoration shall be drawn. + + The default base class implementation of \ref QCPSelectionDecorator has no special decoration, so + this method does nothing. +*/ +void QCPSelectionDecorator::drawDecoration(QCPPainter *painter, QCPDataSelection selection) +{ + Q_UNUSED(painter) + Q_UNUSED(selection) +} + +/*! \internal + + This method is called as soon as a selection decorator is associated with a plottable, by a call + to \ref QCPAbstractPlottable::setSelectionDecorator. This way the selection decorator can obtain a pointer to the plottable that uses it (e.g. to access + data points via the \ref QCPAbstractPlottable::interface1D interface). + + If the selection decorator was already added to a different plottable before, this method aborts + the registration and returns false. +*/ +bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottable) +{ + if (!mPlottable) + { + mPlottable = plottable; + return true; + } else + { + qDebug() << Q_FUNC_INFO << "This selection decorator is already registered with plottable:" << reinterpret_cast(mPlottable); + return false; + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPlottable +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPlottable + \brief The abstract base class for all data representing objects in a plot. + + It defines a very basic interface like name, pen, brush, visibility etc. Since this class is + abstract, it can't be instantiated. Use one of the subclasses or create a subclass yourself to + create new ways of displaying data (see "Creating own plottables" below). Plottables that display + one-dimensional data (i.e. data points have a single key dimension and one or multiple values at + each key) are based off of the template subclass \ref QCPAbstractPlottable1D, see details + there. + + All further specifics are in the subclasses, for example: + \li A normal graph with possibly a line and/or scatter points \ref QCPGraph + (typically created with \ref QCustomPlot::addGraph) + \li A parametric curve: \ref QCPCurve + \li A bar chart: \ref QCPBars + \li A statistical box plot: \ref QCPStatisticalBox + \li A color encoded two-dimensional map: \ref QCPColorMap + \li An OHLC/Candlestick chart: \ref QCPFinancial + + \section plottables-subclassing Creating own plottables + + Subclassing directly from QCPAbstractPlottable is only recommended if you wish to display + two-dimensional data like \ref QCPColorMap, i.e. two logical key dimensions and one (or more) + data dimensions. If you want to display data with only one logical key dimension, you should + rather derive from \ref QCPAbstractPlottable1D. + + If subclassing QCPAbstractPlottable directly, these are the pure virtual functions you must + implement: + \li \ref selectTest + \li \ref draw + \li \ref drawLegendIcon + \li \ref getKeyRange + \li \ref getValueRange + + See the documentation of those functions for what they need to do. + + For drawing your plot, you can use the \ref coordsToPixels functions to translate a point in plot + coordinates to pixel coordinates. This function is quite convenient, because it takes the + orientation of the key and value axes into account for you (x and y are swapped when the key axis + is vertical and the value axis horizontal). If you are worried about performance (i.e. you need + to translate many points in a loop like QCPGraph), you can directly use \ref + QCPAxis::coordToPixel. However, you must then take care about the orientation of the axis + yourself. + + Here are some important members you inherit from QCPAbstractPlottable: + + + + + + + + + + + + + + + + + + + + + + + + + + +
QCustomPlot *\b mParentPlotA pointer to the parent QCustomPlot instance. The parent plot is inferred from the axes that are passed in the constructor.
QString \b mNameThe name of the plottable.
QPen \b mPenThe generic pen of the plottable. You should use this pen for the most prominent data representing lines in the plottable + (e.g QCPGraph uses this pen for its graph lines and scatters)
QBrush \b mBrushThe generic brush of the plottable. You should use this brush for the most prominent fillable structures in the plottable + (e.g. QCPGraph uses this brush to control filling under the graph)
QPointer<\ref QCPAxis> \b mKeyAxis, \b mValueAxisThe key and value axes this plottable is attached to. Call their QCPAxis::coordToPixel functions to translate coordinates + to pixels in either the key or value dimension. Make sure to check whether the pointer is null before using it. If one of + the axes is null, don't draw the plottable.
\ref QCPSelectionDecorator \b mSelectionDecoratorThe currently set selection decorator which specifies how selected data of the plottable shall be drawn and decorated. + When drawing your data, you must consult this decorator for the appropriate pen/brush before drawing unselected/selected data segments. + Finally, you should call its \ref QCPSelectionDecorator::drawDecoration method at the end of your \ref draw implementation.
\ref QCP::SelectionType \b mSelectableIn which composition, if at all, this plottable's data may be selected. Enforcing this setting on the data selection is done + by QCPAbstractPlottable automatically.
\ref QCPDataSelection \b mSelectionHolds the current selection state of the plottable's data, i.e. the selected data ranges (\ref QCPDataRange).
+*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPSelectionDecorator *QCPAbstractPlottable::selectionDecorator() const + + Provides access to the selection decorator of this plottable. The selection decorator controls + how selected data ranges are drawn (e.g. their pen color and fill), see \ref + QCPSelectionDecorator for details. + + If you wish to use an own \ref QCPSelectionDecorator subclass, pass an instance of it to \ref + setSelectionDecorator. +*/ + +/*! \fn bool QCPAbstractPlottable::selected() const + + Returns true if there are any data points of the plottable currently selected. Use \ref selection + to retrieve the current \ref QCPDataSelection. +*/ + +/*! \fn QCPDataSelection QCPAbstractPlottable::selection() const + + Returns a \ref QCPDataSelection encompassing all the data points that are currently selected on + this plottable. + + \see selected, setSelection, setSelectable +*/ + +/*! \fn virtual QCPPlottableInterface1D *QCPAbstractPlottable::interface1D() + + If this plottable is a one-dimensional plottable, i.e. it implements the \ref + QCPPlottableInterface1D, returns the \a this pointer with that type. Otherwise (e.g. in the case + of a \ref QCPColorMap) returns zero. + + You can use this method to gain read access to data coordinates while holding a pointer to the + abstract base class only. +*/ + +/* end of documentation of inline functions */ +/* start of documentation of pure virtual functions */ + +/*! \fn void QCPAbstractPlottable::drawLegendIcon(QCPPainter *painter, const QRect &rect) const = 0 + \internal + + called by QCPLegend::draw (via QCPPlottableLegendItem::draw) to create a graphical representation + of this plottable inside \a rect, next to the plottable name. + + The passed \a painter has its cliprect set to \a rect, so painting outside of \a rect won't + appear outside the legend icon border. +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const = 0 + + Returns the coordinate range that all data in this plottable span in the key axis dimension. For + logarithmic plots, one can set \a inSignDomain to either \ref QCP::sdNegative or \ref + QCP::sdPositive in order to restrict the returned range to that sign domain. E.g. when only + negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and all positive points + will be ignored for range calculation. For no restriction, just set \a inSignDomain to \ref + QCP::sdBoth (default). \a foundRange is an output parameter that indicates whether a range could + be found or not. If this is false, you shouldn't use the returned range (e.g. no points in data). + + Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by + this function may have size zero (e.g. when there is only one data point). In this case \a + foundRange would return true, but the returned range is not a valid range in terms of \ref + QCPRange::validRange. + + \see rescaleAxes, getValueRange +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const = 0 + + Returns the coordinate range that the data points in the specified key range (\a inKeyRange) span + in the value axis dimension. For logarithmic plots, one can set \a inSignDomain to either \ref + QCP::sdNegative or \ref QCP::sdPositive in order to restrict the returned range to that sign + domain. E.g. when only negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and + all positive points will be ignored for range calculation. For no restriction, just set \a + inSignDomain to \ref QCP::sdBoth (default). \a foundRange is an output parameter that indicates + whether a range could be found or not. If this is false, you shouldn't use the returned range + (e.g. no points in data). + + If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), + all data points are considered, without any restriction on the keys. + + Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by + this function may have size zero (e.g. when there is only one data point). In this case \a + foundRange would return true, but the returned range is not a valid range in terms of \ref + QCPRange::validRange. + + \see rescaleAxes, getKeyRange +*/ + +/* end of documentation of pure virtual functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAbstractPlottable::selectionChanged(bool selected) + + This signal is emitted when the selection state of this plottable has changed, either by user + interaction or by a direct call to \ref setSelection. The parameter \a selected indicates whether + there are any points selected or not. + + \see selectionChanged(const QCPDataSelection &selection) +*/ + +/*! \fn void QCPAbstractPlottable::selectionChanged(const QCPDataSelection &selection) + + This signal is emitted when the selection state of this plottable has changed, either by user + interaction or by a direct call to \ref setSelection. The parameter \a selection holds the + currently selected data ranges. + + \see selectionChanged(bool selected) +*/ + +/*! \fn void QCPAbstractPlottable::selectableChanged(QCP::SelectionType selectable); + + This signal is emitted when the selectability of this plottable has changed. + + \see setSelectable +*/ + +/* end of documentation of signals */ + +/*! + Constructs an abstract plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as + its value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance + and have perpendicular orientations. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + Since QCPAbstractPlottable is an abstract class that defines the basic interface to plottables, + it can't be directly instantiated. + + You probably want one of the subclasses like \ref QCPGraph or \ref QCPCurve instead. +*/ +QCPAbstractPlottable::QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPLayerable(keyAxis->parentPlot(), QString(), keyAxis->axisRect()), + mName(), + mDesc(), + mAntialiasedFill(true), + mAntialiasedScatters(true), + mPen(Qt::black), + mBrush(Qt::NoBrush), + mKeyAxis(keyAxis), + mValueAxis(valueAxis), + mSelectable(QCP::stWhole), + mSelectionDecorator(0) +{ + if (keyAxis->parentPlot() != valueAxis->parentPlot()) + qDebug() << Q_FUNC_INFO << "Parent plot of keyAxis is not the same as that of valueAxis."; + if (keyAxis->orientation() == valueAxis->orientation()) + qDebug() << Q_FUNC_INFO << "keyAxis and valueAxis must be orthogonal to each other."; + + mParentPlot->registerPlottable(this); + setSelectionDecorator(new QCPSelectionDecorator); +} + +QCPAbstractPlottable::~QCPAbstractPlottable() +{ + if (mSelectionDecorator) + { + delete mSelectionDecorator; + mSelectionDecorator = 0; + } +} + +/*! + The name is the textual representation of this plottable as it is displayed in the legend + (\ref QCPLegend). It may contain any UTF-8 characters, including newlines. +*/ +void QCPAbstractPlottable::setName(const QString &name) +{ + mName = name; +} + +void QCPAbstractPlottable::setDesc(const QString &desc) +{ + mDesc = desc; +} + +void QCPAbstractPlottable::setType(const int &type) +{ + mType = type; +} + +/*! + Sets whether fills of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedFill(bool enabled) +{ + mAntialiasedFill = enabled; +} + +/*! + Sets whether the scatter symbols of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedScatters(bool enabled) +{ + mAntialiasedScatters = enabled; +} + +/*! + The pen is used to draw basic lines that make up the plottable representation in the + plot. + + For example, the \ref QCPGraph subclass draws its graph lines with this pen. + + \see setBrush +*/ +void QCPAbstractPlottable::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + The brush is used to draw basic fills of the plottable representation in the + plot. The Fill can be a color, gradient or texture, see the usage of QBrush. + + For example, the \ref QCPGraph subclass draws the fill under the graph with this brush, when + it's not set to Qt::NoBrush. + + \see setPen +*/ +void QCPAbstractPlottable::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + The key axis of a plottable can be set to any axis of a QCustomPlot, as long as it is orthogonal + to the plottable's value axis. This function performs no checks to make sure this is the case. + The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and the + y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setValueAxis +*/ +void QCPAbstractPlottable::setKeyAxis(QCPAxis *axis) +{ + mKeyAxis = axis; +} + +/*! + The value axis of a plottable can be set to any axis of a QCustomPlot, as long as it is + orthogonal to the plottable's key axis. This function performs no checks to make sure this is the + case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and + the y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setKeyAxis +*/ +void QCPAbstractPlottable::setValueAxis(QCPAxis *axis) +{ + mValueAxis = axis; +} + + +/*! + Sets which data ranges of this plottable are selected. Selected data ranges are drawn differently + (e.g. color) in the plot. This can be controlled via the selection decorator (see \ref + selectionDecorator). + + The entire selection mechanism for plottables is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when + you wish to change the selection state programmatically. + + Using \ref setSelectable you can further specify for each plottable whether and to which + granularity it is selectable. If \a selection is not compatible with the current \ref + QCP::SelectionType set via \ref setSelectable, the resulting selection will be adjusted + accordingly (see \ref QCPDataSelection::enforceType). + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPAbstractPlottable::setSelection(QCPDataSelection selection) +{ + selection.enforceType(mSelectable); + if (mSelection != selection) + { + mSelection = selection; + emit selectionChanged(selected()); + emit selectionChanged(mSelection); + } +} + +/*! + Use this method to set an own QCPSelectionDecorator (subclass) instance. This allows you to + customize the visual representation of selected data ranges further than by using the default + QCPSelectionDecorator. + + The plottable takes ownership of the \a decorator. + + The currently set decorator can be accessed via \ref selectionDecorator. +*/ +void QCPAbstractPlottable::setSelectionDecorator(QCPSelectionDecorator *decorator) +{ + if (decorator) + { + if (decorator->registerWithPlottable(this)) + { + if (mSelectionDecorator) // delete old decorator if necessary + delete mSelectionDecorator; + mSelectionDecorator = decorator; + } + } else if (mSelectionDecorator) // just clear decorator + { + delete mSelectionDecorator; + mSelectionDecorator = 0; + } +} + +/*! + Sets whether and to which granularity this plottable can be selected. + + A selection can happen by clicking on the QCustomPlot surface (When \ref + QCustomPlot::setInteractions contains \ref QCP::iSelectPlottables), by dragging a selection rect + (When \ref QCustomPlot::setSelectionRectMode is \ref QCP::srmSelect), or programmatically by + calling \ref setSelection. + + \see setSelection, QCP::SelectionType +*/ +void QCPAbstractPlottable::setSelectable(QCP::SelectionType selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + QCPDataSelection oldSelection = mSelection; + mSelection.enforceType(mSelectable); + emit selectableChanged(mSelectable); + if (mSelection != oldSelection) + { + emit selectionChanged(selected()); + emit selectionChanged(mSelection); + } + } +} + + +/*! + Convenience function for transforming a key/value pair to pixels on the QCustomPlot surface, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a key and \a value are transformed to the coodinates in pixels and are written to \a x and \a y. + + \see pixelsToCoords, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::coordsToPixels(double key, double value, double &x, double &y) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + x = keyAxis->coordToPixel(key); + y = valueAxis->coordToPixel(value); + } else + { + y = keyAxis->coordToPixel(key); + x = valueAxis->coordToPixel(value); + } +} + +/*! \overload + + Transforms the given \a key and \a value to pixel coordinates and returns them in a QPointF. +*/ +const QPointF QCPAbstractPlottable::coordsToPixels(double key, double value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyAxis->coordToPixel(key), valueAxis->coordToPixel(value)); + else + return QPointF(valueAxis->coordToPixel(value), keyAxis->coordToPixel(key)); +} + +/*! + Convenience function for transforming a x/y pixel pair on the QCustomPlot surface to plot coordinates, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a x and \a y are transformed to the plot coodinates and are written to \a key and \a value. + + \see coordsToPixels, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::pixelsToCoords(double x, double y, double &key, double &value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + key = keyAxis->pixelToCoord(x); + value = valueAxis->pixelToCoord(y); + } else + { + key = keyAxis->pixelToCoord(y); + value = valueAxis->pixelToCoord(x); + } +} + +/*! \overload + + Returns the pixel input \a pixelPos as plot coordinates \a key and \a value. +*/ +void QCPAbstractPlottable::pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const +{ + pixelsToCoords(pixelPos.x(), pixelPos.y(), key, value); +} + +/*! + Rescales the key and value axes associated with this plottable to contain all displayed data, so + the whole plottable is visible. If the scaling of an axis is logarithmic, rescaleAxes will make + sure not to rescale to an illegal range i.e. a range containing different signs and/or zero. + Instead it will stay in the current sign domain and ignore all parts of the plottable that lie + outside of that domain. + + \a onlyEnlarge makes sure the ranges are only expanded, never reduced. So it's possible to show + multiple plottables in their entirety by multiple calls to rescaleAxes where the first call has + \a onlyEnlarge set to false (the default), and all subsequent set to true. + + \see rescaleKeyAxis, rescaleValueAxis, QCustomPlot::rescaleAxes, QCPAxis::rescale +*/ +void QCPAbstractPlottable::rescaleAxes(bool onlyEnlarge) const +{ + rescaleKeyAxis(onlyEnlarge); + rescaleValueAxis(onlyEnlarge); +} + +/*! + Rescales the key axis of the plottable so the whole plottable is visible. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleKeyAxis(bool onlyEnlarge) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + + QCP::SignDomain signDomain = QCP::sdBoth; + if (keyAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (keyAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); + + bool foundRange; + QCPRange newRange = getKeyRange(foundRange, signDomain); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(keyAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (keyAxis->scaleType() == QCPAxis::stLinear) + { + newRange.lower = center-keyAxis->range().size()/2.0; + newRange.upper = center+keyAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(keyAxis->range().upper/keyAxis->range().lower); + newRange.upper = center*qSqrt(keyAxis->range().upper/keyAxis->range().lower); + } + } + keyAxis->setRange(newRange); + } +} + +/*! + Rescales the value axis of the plottable so the whole plottable is visible. If \a inKeyRange is + set to true, only the data points which are in the currently visible key axis range are + considered. + + Returns true if the axis was actually scaled. This might not be the case if this plottable has an + invalid range, e.g. because it has no data points. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleValueAxis(bool onlyEnlarge, bool inKeyRange) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCP::SignDomain signDomain = QCP::sdBoth; + if (valueAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (valueAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); + + bool foundRange; + QCPRange newRange = getValueRange(foundRange, signDomain, inKeyRange ? keyAxis->range() : QCPRange()); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(valueAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + newRange.lower = center-valueAxis->range().size()/2.0; + newRange.upper = center+valueAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(valueAxis->range().upper/valueAxis->range().lower); + newRange.upper = center*qSqrt(valueAxis->range().upper/valueAxis->range().lower); + } + } + valueAxis->setRange(newRange); + } +} + +/*! \overload + + Adds this plottable to the specified \a legend. + + Creates a QCPPlottableLegendItem which is inserted into the legend. Returns true on success, i.e. + when the legend exists and a legend item associated with this plottable isn't already in the + legend. + + If the plottable needs a more specialized representation in the legend, you can create a + corresponding subclass of \ref QCPPlottableLegendItem and add it to the legend manually instead + of calling this method. + + \see removeFromLegend, QCPLegend::addItem +*/ +bool QCPAbstractPlottable::addToLegend(QCPLegend *legend) +{ + if (!legend) + { + qDebug() << Q_FUNC_INFO << "passed legend is null"; + return false; + } + if (legend->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "passed legend isn't in the same QCustomPlot as this plottable"; + return false; + } + + if (!legend->hasItemWithPlottable(this)) + { + legend->addItem(new QCPPlottableLegendItem(legend, this)); + return true; + } else + return false; +} + +/*! \overload + + Adds this plottable to the legend of the parent QCustomPlot (\ref QCustomPlot::legend). + + \see removeFromLegend +*/ +bool QCPAbstractPlottable::addToLegend() +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + else + return addToLegend(mParentPlot->legend); +} + +/*! \overload + + Removes the plottable from the specifed \a legend. This means the \ref QCPPlottableLegendItem + that is associated with this plottable is removed. + + Returns true on success, i.e. if the legend exists and a legend item associated with this + plottable was found and removed. + + \see addToLegend, QCPLegend::removeItem +*/ +bool QCPAbstractPlottable::removeFromLegend(QCPLegend *legend) const +{ + if (!legend) + { + qDebug() << Q_FUNC_INFO << "passed legend is null"; + return false; + } + + if (QCPPlottableLegendItem *lip = legend->itemWithPlottable(this)) + return legend->removeItem(lip); + else + return false; +} + +/*! \overload + + Removes the plottable from the legend of the parent QCustomPlot. + + \see addToLegend +*/ +bool QCPAbstractPlottable::removeFromLegend() const +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + else + return removeFromLegend(mParentPlot->legend); +} + +/* inherits documentation from base class */ +QRect QCPAbstractPlottable::clipRect() const +{ + if (mKeyAxis && mValueAxis) + return mKeyAxis.data()->axisRect()->rect() & mValueAxis.data()->axisRect()->rect(); + else + return QRect(); +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractPlottable::selectionCategory() const +{ + return QCP::iSelectPlottables; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased, applyFillAntialiasingHint, applyScattersAntialiasingHint +*/ +void QCPAbstractPlottable::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aePlottables); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable fills. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyDefaultAntialiasingHint, applyScattersAntialiasingHint +*/ +void QCPAbstractPlottable::applyFillAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedFill, QCP::aeFills); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable scatter points. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyFillAntialiasingHint, applyDefaultAntialiasingHint +*/ +void QCPAbstractPlottable::applyScattersAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedScatters, QCP::aeScatters); +} + +/* inherits documentation from base class */ +void QCPAbstractPlottable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + + if (mSelectable != QCP::stNone) + { + QCPDataSelection newSelection = details.value(); + QCPDataSelection selectionBefore = mSelection; + if (additive) + { + if (mSelectable == QCP::stWhole) // in whole selection mode, we toggle to no selection even if currently unselected point was hit + { + if (selected()) + setSelection(QCPDataSelection()); + else + setSelection(newSelection); + } else // in all other selection modes we toggle selections of homogeneously selected/unselected segments + { + if (mSelection.contains(newSelection)) // if entire newSelection is already selected, toggle selection + setSelection(mSelection-newSelection); + else + setSelection(mSelection+newSelection); + } + } else + setSelection(newSelection); + if (selectionStateChanged) + *selectionStateChanged = mSelection != selectionBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractPlottable::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable != QCP::stNone) + { + QCPDataSelection selectionBefore = mSelection; + setSelection(QCPDataSelection()); + if (selectionStateChanged) + *selectionStateChanged = mSelection != selectionBefore; + } +} +/* end of 'src/plottable.cpp' */ + + +/* including file 'src/item.cpp', size 49269 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemAnchor +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemAnchor + \brief An anchor of an item to which positions can be attached to. + + An item (QCPAbstractItem) may have one or more anchors. Unlike QCPItemPosition, an anchor doesn't + control anything on its item, but provides a way to tie other items via their positions to the + anchor. + + For example, a QCPItemRect is defined by its positions \a topLeft and \a bottomRight. + Additionally it has various anchors like \a top, \a topRight or \a bottomLeft etc. So you can + attach the \a start (which is a QCPItemPosition) of a QCPItemLine to one of the anchors by + calling QCPItemPosition::setParentAnchor on \a start, passing the wanted anchor of the + QCPItemRect. This way the start of the line will now always follow the respective anchor location + on the rect item. + + Note that QCPItemPosition derives from QCPItemAnchor, so every position can also serve as an + anchor to other positions. + + To learn how to provide anchors in your own item subclasses, see the subclassing section of the + QCPAbstractItem documentation. +*/ + +/* start documentation of inline functions */ + +/*! \fn virtual QCPItemPosition *QCPItemAnchor::toQCPItemPosition() + + Returns 0 if this instance is merely a QCPItemAnchor, and a valid pointer of type QCPItemPosition* if + it actually is a QCPItemPosition (which is a subclass of QCPItemAnchor). + + This safe downcast functionality could also be achieved with a dynamic_cast. However, QCustomPlot avoids + dynamic_cast to work with projects that don't have RTTI support enabled (e.g. -fno-rtti flag with + gcc compiler). +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPItemAnchor. You shouldn't create QCPItemAnchor instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createAnchor instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemAnchor::QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId) : + mName(name), + mParentPlot(parentPlot), + mParentItem(parentItem), + mAnchorId(anchorId) +{ +} + +QCPItemAnchor::~QCPItemAnchor() +{ + // unregister as parent at children: + foreach (QCPItemPosition *child, mChildrenX.toList()) + { + if (child->parentAnchorX() == this) + child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX + } + foreach (QCPItemPosition *child, mChildrenY.toList()) + { + if (child->parentAnchorY() == this) + child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY + } +} + +/*! + Returns the final absolute pixel position of the QCPItemAnchor on the QCustomPlot surface. + + The pixel information is internally retrieved via QCPAbstractItem::anchorPixelPosition of the + parent item, QCPItemAnchor is just an intermediary. +*/ +QPointF QCPItemAnchor::pixelPosition() const +{ + if (mParentItem) + { + if (mAnchorId > -1) + { + return mParentItem->anchorPixelPosition(mAnchorId); + } else + { + qDebug() << Q_FUNC_INFO << "no valid anchor id set:" << mAnchorId; + return QPointF(); + } + } else + { + qDebug() << Q_FUNC_INFO << "no parent item set"; + return QPointF(); + } +} + +/*! \internal + + Adds \a pos to the childX list of this anchor, which keeps track of which children use this + anchor as parent anchor for the respective coordinate. This is necessary to notify the children + prior to destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChildX(QCPItemPosition *pos) +{ + if (!mChildrenX.contains(pos)) + mChildrenX.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the childX list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChildX(QCPItemPosition *pos) +{ + if (!mChildrenX.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + +/*! \internal + + Adds \a pos to the childY list of this anchor, which keeps track of which children use this + anchor as parent anchor for the respective coordinate. This is necessary to notify the children + prior to destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChildY(QCPItemPosition *pos) +{ + if (!mChildrenY.contains(pos)) + mChildrenY.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the childY list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChildY(QCPItemPosition *pos) +{ + if (!mChildrenY.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemPosition +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemPosition + \brief Manages the position of an item. + + Every item has at least one public QCPItemPosition member pointer which provides ways to position the + item on the QCustomPlot surface. Some items have multiple positions, for example QCPItemRect has two: + \a topLeft and \a bottomRight. + + QCPItemPosition has a type (\ref PositionType) that can be set with \ref setType. This type + defines how coordinates passed to \ref setCoords are to be interpreted, e.g. as absolute pixel + coordinates, as plot coordinates of certain axes, etc. For more advanced plots it is also + possible to assign different types per X/Y coordinate of the position (see \ref setTypeX, \ref + setTypeY). This way an item could be positioned at a fixed pixel distance from the top in the Y + direction, while following a plot coordinate in the X direction. + + A QCPItemPosition may have a parent QCPItemAnchor, see \ref setParentAnchor. This way you can tie + multiple items together. If the QCPItemPosition has a parent, its coordinates (\ref setCoords) + are considered to be absolute pixels in the reference frame of the parent anchor, where (0, 0) + means directly ontop of the parent anchor. For example, You could attach the \a start position of + a QCPItemLine to the \a bottom anchor of a QCPItemText to make the starting point of the line + always be centered under the text label, no matter where the text is moved to. For more advanced + plots, it is possible to assign different parent anchors per X/Y coordinate of the position, see + \ref setParentAnchorX, \ref setParentAnchorY. This way an item could follow another item in the X + direction but stay at a fixed position in the Y direction. Or even follow item A in X, and item B + in Y. + + Note that every QCPItemPosition inherits from QCPItemAnchor and thus can itself be used as parent + anchor for other positions. + + To set the apparent pixel position on the QCustomPlot surface directly, use \ref setPixelPosition. This + works no matter what type this QCPItemPosition is or what parent-child situation it is in, as \ref + setPixelPosition transforms the coordinates appropriately, to make the position appear at the specified + pixel values. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPItemPosition::PositionType *QCPItemPosition::type() const + + Returns the current position type. + + If different types were set for X and Y (\ref setTypeX, \ref setTypeY), this method returns the + type of the X coordinate. In that case rather use \a typeX() and \a typeY(). + + \see setType +*/ + +/*! \fn QCPItemAnchor *QCPItemPosition::parentAnchor() const + + Returns the current parent anchor. + + If different parent anchors were set for X and Y (\ref setParentAnchorX, \ref setParentAnchorY), + this method returns the parent anchor of the Y coordinate. In that case rather use \a + parentAnchorX() and \a parentAnchorY(). + + \see setParentAnchor +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPItemPosition. You shouldn't create QCPItemPosition instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createPosition instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemPosition::QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name) : + QCPItemAnchor(parentPlot, parentItem, name), + mPositionTypeX(ptAbsolute), + mPositionTypeY(ptAbsolute), + mKey(0), + mValue(0), + mParentAnchorX(0), + mParentAnchorY(0) +{ +} + +QCPItemPosition::~QCPItemPosition() +{ + // unregister as parent at children: + // Note: this is done in ~QCPItemAnchor again, but it's important QCPItemPosition does it itself, because only then + // the setParentAnchor(0) call the correct QCPItemPosition::pixelPosition function instead of QCPItemAnchor::pixelPosition + foreach (QCPItemPosition *child, mChildrenX.toList()) + { + if (child->parentAnchorX() == this) + child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX + } + foreach (QCPItemPosition *child, mChildrenY.toList()) + { + if (child->parentAnchorY() == this) + child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY + } + // unregister as child in parent: + if (mParentAnchorX) + mParentAnchorX->removeChildX(this); + if (mParentAnchorY) + mParentAnchorY->removeChildY(this); +} + +/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ +QCPAxisRect *QCPItemPosition::axisRect() const +{ + return mAxisRect.data(); +} + +/*! + Sets the type of the position. The type defines how the coordinates passed to \ref setCoords + should be handled and how the QCPItemPosition should behave in the plot. + + The possible values for \a type can be separated in two main categories: + + \li The position is regarded as a point in plot coordinates. This corresponds to \ref ptPlotCoords + and requires two axes that define the plot coordinate system. They can be specified with \ref setAxes. + By default, the QCustomPlot's x- and yAxis are used. + + \li The position is fixed on the QCustomPlot surface, i.e. independent of axis ranges. This + corresponds to all other types, i.e. \ref ptAbsolute, \ref ptViewportRatio and \ref + ptAxisRectRatio. They differ only in the way the absolute position is described, see the + documentation of \ref PositionType for details. For \ref ptAxisRectRatio, note that you can specify + the axis rect with \ref setAxisRect. By default this is set to the main axis rect. + + Note that the position type \ref ptPlotCoords is only available (and sensible) when the position + has no parent anchor (\ref setParentAnchor). + + If the type is changed, the apparent pixel position on the plot is preserved. This means + the coordinates as retrieved with coords() and set with \ref setCoords may change in the process. + + This method sets the type for both X and Y directions. It is also possible to set different types + for X and Y, see \ref setTypeX, \ref setTypeY. +*/ +void QCPItemPosition::setType(QCPItemPosition::PositionType type) +{ + setTypeX(type); + setTypeY(type); +} + +/*! + This method sets the position type of the X coordinate to \a type. + + For a detailed description of what a position type is, see the documentation of \ref setType. + + \see setType, setTypeY +*/ +void QCPItemPosition::setTypeX(QCPItemPosition::PositionType type) +{ + if (mPositionTypeX != type) + { + // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect + // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. + bool retainPixelPosition = true; + if ((mPositionTypeX == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) + retainPixelPosition = false; + if ((mPositionTypeX == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) + retainPixelPosition = false; + + QPointF pixel; + if (retainPixelPosition) + pixel = pixelPosition(); + + mPositionTypeX = type; + + if (retainPixelPosition) + setPixelPosition(pixel); + } +} + +/*! + This method sets the position type of the Y coordinate to \a type. + + For a detailed description of what a position type is, see the documentation of \ref setType. + + \see setType, setTypeX +*/ +void QCPItemPosition::setTypeY(QCPItemPosition::PositionType type) +{ + if (mPositionTypeY != type) + { + // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect + // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. + bool retainPixelPosition = true; + if ((mPositionTypeY == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) + retainPixelPosition = false; + if ((mPositionTypeY == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) + retainPixelPosition = false; + + QPointF pixel; + if (retainPixelPosition) + pixel = pixelPosition(); + + mPositionTypeY = type; + + if (retainPixelPosition) + setPixelPosition(pixel); + } +} + +/*! + Sets the parent of this QCPItemPosition to \a parentAnchor. This means the position will now + follow any position changes of the anchor. The local coordinate system of positions with a parent + anchor always is absolute pixels, with (0, 0) being exactly on top of the parent anchor. (Hence + the type shouldn't be set to \ref ptPlotCoords for positions with parent anchors.) + + if \a keepPixelPosition is true, the current pixel position of the QCPItemPosition is preserved + during reparenting. If it's set to false, the coordinates are set to (0, 0), i.e. the position + will be exactly on top of the parent anchor. + + To remove this QCPItemPosition from any parent anchor, set \a parentAnchor to 0. + + If the QCPItemPosition previously had no parent and the type is \ref ptPlotCoords, the type is + set to \ref ptAbsolute, to keep the position in a valid state. + + This method sets the parent anchor for both X and Y directions. It is also possible to set + different parents for X and Y, see \ref setParentAnchorX, \ref setParentAnchorY. +*/ +bool QCPItemPosition::setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + bool successX = setParentAnchorX(parentAnchor, keepPixelPosition); + bool successY = setParentAnchorY(parentAnchor, keepPixelPosition); + return successX && successY; +} + +/*! + This method sets the parent anchor of the X coordinate to \a parentAnchor. + + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. + + \see setParentAnchor, setParentAnchorY +*/ +bool QCPItemPosition::setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->parentAnchorX(); + } else + { + // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the + // same, to prevent a position being child of an anchor which itself depends on the position, + // because they're both on the same item: + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchorX && mPositionTypeX == ptPlotCoords) + setTypeX(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPosition(); + // unregister at current parent anchor: + if (mParentAnchorX) + mParentAnchorX->removeChildX(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChildX(this); + mParentAnchorX = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPosition(pixelP); + else + setCoords(0, coords().y()); + return true; +} + +/*! + This method sets the parent anchor of the Y coordinate to \a parentAnchor. + + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. + + \see setParentAnchor, setParentAnchorX +*/ +bool QCPItemPosition::setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->parentAnchorY(); + } else + { + // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the + // same, to prevent a position being child of an anchor which itself depends on the position, + // because they're both on the same item: + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchorY && mPositionTypeY == ptPlotCoords) + setTypeY(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPosition(); + // unregister at current parent anchor: + if (mParentAnchorY) + mParentAnchorY->removeChildY(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChildY(this); + mParentAnchorY = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPosition(pixelP); + else + setCoords(coords().x(), 0); + return true; +} + +/*! + Sets the coordinates of this QCPItemPosition. What the coordinates mean, is defined by the type + (\ref setType, \ref setTypeX, \ref setTypeY). + + For example, if the type is \ref ptAbsolute, \a key and \a value mean the x and y pixel position + on the QCustomPlot surface. In that case the origin (0, 0) is in the top left corner of the + QCustomPlot viewport. If the type is \ref ptPlotCoords, \a key and \a value mean a point in the + plot coordinate system defined by the axes set by \ref setAxes. By default those are the + QCustomPlot's xAxis and yAxis. See the documentation of \ref setType for other available + coordinate types and their meaning. + + If different types were configured for X and Y (\ref setTypeX, \ref setTypeY), \a key and \a + value must also be provided in the different coordinate systems. Here, the X type refers to \a + key, and the Y type refers to \a value. + + \see setPixelPosition +*/ +void QCPItemPosition::setCoords(double key, double value) +{ + mKey = key; + mValue = value; +} + +/*! \overload + + Sets the coordinates as a QPointF \a pos where pos.x has the meaning of \a key and pos.y the + meaning of \a value of the \ref setCoords(double key, double value) method. +*/ +void QCPItemPosition::setCoords(const QPointF &pos) +{ + setCoords(pos.x(), pos.y()); +} + +/*! + Returns the final absolute pixel position of the QCPItemPosition on the QCustomPlot surface. It + includes all effects of type (\ref setType) and possible parent anchors (\ref setParentAnchor). + + \see setPixelPosition +*/ +QPointF QCPItemPosition::pixelPosition() const +{ + QPointF result; + + // determine X: + switch (mPositionTypeX) + { + case ptAbsolute: + { + result.rx() = mKey; + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + break; + } + case ptViewportRatio: + { + result.rx() = mKey*mParentPlot->viewport().width(); + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + else + result.rx() += mParentPlot->viewport().left(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + result.rx() = mKey*mAxisRect.data()->width(); + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + else + result.rx() += mAxisRect.data()->left(); + } else + qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) + result.rx() = mKeyAxis.data()->coordToPixel(mKey); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) + result.rx() = mValueAxis.data()->coordToPixel(mValue); + else + qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; + break; + } + } + + // determine Y: + switch (mPositionTypeY) + { + case ptAbsolute: + { + result.ry() = mValue; + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + break; + } + case ptViewportRatio: + { + result.ry() = mValue*mParentPlot->viewport().height(); + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + else + result.ry() += mParentPlot->viewport().top(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + result.ry() = mValue*mAxisRect.data()->height(); + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + else + result.ry() += mAxisRect.data()->top(); + } else + qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) + result.ry() = mKeyAxis.data()->coordToPixel(mKey); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) + result.ry() = mValueAxis.data()->coordToPixel(mValue); + else + qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; + break; + } + } + + return result; +} + +/*! + When \ref setType is \ref ptPlotCoords, this function may be used to specify the axes the + coordinates set with \ref setCoords relate to. By default they are set to the initial xAxis and + yAxis of the QCustomPlot. +*/ +void QCPItemPosition::setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + mKeyAxis = keyAxis; + mValueAxis = valueAxis; +} + +/*! + When \ref setType is \ref ptAxisRectRatio, this function may be used to specify the axis rect the + coordinates set with \ref setCoords relate to. By default this is set to the main axis rect of + the QCustomPlot. +*/ +void QCPItemPosition::setAxisRect(QCPAxisRect *axisRect) +{ + mAxisRect = axisRect; +} + +/*! + Sets the apparent pixel position. This works no matter what type (\ref setType) this + QCPItemPosition is or what parent-child situation it is in, as coordinates are transformed + appropriately, to make the position finally appear at the specified pixel values. + + Only if the type is \ref ptAbsolute and no parent anchor is set, this function's effect is + identical to that of \ref setCoords. + + \see pixelPosition, setCoords +*/ +void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) +{ + double x = pixelPosition.x(); + double y = pixelPosition.y(); + + switch (mPositionTypeX) + { + case ptAbsolute: + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + break; + } + case ptViewportRatio: + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + else + x -= mParentPlot->viewport().left(); + x /= (double)mParentPlot->viewport().width(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + else + x -= mAxisRect.data()->left(); + x /= (double)mAxisRect.data()->width(); + } else + qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) + x = mKeyAxis.data()->pixelToCoord(x); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) + y = mValueAxis.data()->pixelToCoord(x); + else + qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; + break; + } + } + + switch (mPositionTypeY) + { + case ptAbsolute: + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + break; + } + case ptViewportRatio: + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + else + y -= mParentPlot->viewport().top(); + y /= (double)mParentPlot->viewport().height(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + else + y -= mAxisRect.data()->top(); + y /= (double)mAxisRect.data()->height(); + } else + qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) + x = mKeyAxis.data()->pixelToCoord(y); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) + y = mValueAxis.data()->pixelToCoord(y); + else + qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; + break; + } + } + + setCoords(x, y); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractItem + \brief The abstract base class for all items in a plot. + + In QCustomPlot, items are supplemental graphical elements that are neither plottables + (QCPAbstractPlottable) nor axes (QCPAxis). While plottables are always tied to two axes and thus + plot coordinates, items can also be placed in absolute coordinates independent of any axes. Each + specific item has at least one QCPItemPosition member which controls the positioning. Some items + are defined by more than one coordinate and thus have two or more QCPItemPosition members (For + example, QCPItemRect has \a topLeft and \a bottomRight). + + This abstract base class defines a very basic interface like visibility and clipping. Since this + class is abstract, it can't be instantiated. Use one of the subclasses or create a subclass + yourself to create new items. + + The built-in items are: + + + + + + + + + + +
QCPItemLineA line defined by a start and an end point. May have different ending styles on each side (e.g. arrows).
QCPItemStraightLineA straight line defined by a start and a direction point. Unlike QCPItemLine, the straight line is infinitely long and has no endings.
QCPItemCurveA curve defined by start, end and two intermediate control points. May have different ending styles on each side (e.g. arrows).
QCPItemRectA rectangle
QCPItemEllipseAn ellipse
QCPItemPixmapAn arbitrary pixmap
QCPItemTextA text label
QCPItemBracketA bracket which may be used to reference/highlight certain parts in the plot.
QCPItemTracerAn item that can be attached to a QCPGraph and sticks to its data points, given a key coordinate.
+ + \section items-clipping Clipping + + Items are by default clipped to the main axis rect (they are only visible inside the axis rect). + To make an item visible outside that axis rect, disable clipping via \ref setClipToAxisRect + "setClipToAxisRect(false)". + + On the other hand if you want the item to be clipped to a different axis rect, specify it via + \ref setClipAxisRect. This clipAxisRect property of an item is only used for clipping behaviour, and + in principle is independent of the coordinate axes the item might be tied to via its position + members (\ref QCPItemPosition::setAxes). However, it is common that the axis rect for clipping + also contains the axes used for the item positions. + + \section items-using Using items + + First you instantiate the item you want to use and add it to the plot: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-1 + by default, the positions of the item are bound to the x- and y-Axis of the plot. So we can just + set the plot coordinates where the line should start/end: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-2 + If we don't want the line to be positioned in plot coordinates but a different coordinate system, + e.g. absolute pixel positions on the QCustomPlot surface, we need to change the position type like this: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-3 + Then we can set the coordinates, this time in pixels: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-4 + and make the line visible on the entire QCustomPlot, by disabling clipping to the axis rect: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-5 + + For more advanced plots, it is even possible to set different types and parent anchors per X/Y + coordinate of an item position, using for example \ref QCPItemPosition::setTypeX or \ref + QCPItemPosition::setParentAnchorX. For details, see the documentation of \ref QCPItemPosition. + + \section items-subclassing Creating own items + + To create an own item, you implement a subclass of QCPAbstractItem. These are the pure + virtual functions, you must implement: + \li \ref selectTest + \li \ref draw + + See the documentation of those functions for what they need to do. + + \subsection items-positioning Allowing the item to be positioned + + As mentioned, item positions are represented by QCPItemPosition members. Let's assume the new item shall + have only one point as its position (as opposed to two like a rect or multiple like a polygon). You then add + a public member of type QCPItemPosition like so: + + \code QCPItemPosition * const myPosition;\endcode + + the const makes sure the pointer itself can't be modified from the user of your new item (the QCPItemPosition + instance it points to, can be modified, of course). + The initialization of this pointer is made easy with the \ref createPosition function. Just assign + the return value of this function to each QCPItemPosition in the constructor of your item. \ref createPosition + takes a string which is the name of the position, typically this is identical to the variable name. + For example, the constructor of QCPItemExample could look like this: + + \code + QCPItemExample::QCPItemExample(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + myPosition(createPosition("myPosition")) + { + // other constructor code + } + \endcode + + \subsection items-drawing The draw function + + To give your item a visual representation, reimplement the \ref draw function and use the passed + QCPPainter to draw the item. You can retrieve the item position in pixel coordinates from the + position member(s) via \ref QCPItemPosition::pixelPosition. + + To optimize performance you should calculate a bounding rect first (don't forget to take the pen + width into account), check whether it intersects the \ref clipRect, and only draw the item at all + if this is the case. + + \subsection items-selection The selectTest function + + Your implementation of the \ref selectTest function may use the helpers \ref + QCPVector2D::distanceSquaredToLine and \ref rectDistance. With these, the implementation of the + selection test becomes significantly simpler for most items. See the documentation of \ref + selectTest for what the function parameters mean and what the function should return. + + \subsection anchors Providing anchors + + Providing anchors (QCPItemAnchor) starts off like adding a position. First you create a public + member, e.g. + + \code QCPItemAnchor * const bottom;\endcode + + and create it in the constructor with the \ref createAnchor function, assigning it a name and an + anchor id (an integer enumerating all anchors on the item, you may create an own enum for this). + Since anchors can be placed anywhere, relative to the item's position(s), your item needs to + provide the position of every anchor with the reimplementation of the \ref anchorPixelPosition(int + anchorId) function. + + In essence the QCPItemAnchor is merely an intermediary that itself asks your item for the pixel + position when anything attached to the anchor needs to know the coordinates. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QList QCPAbstractItem::positions() const + + Returns all positions of the item in a list. + + \see anchors, position +*/ + +/*! \fn QList QCPAbstractItem::anchors() const + + Returns all anchors of the item in a list. Note that since a position (QCPItemPosition) is always + also an anchor, the list will also contain the positions of this item. + + \see positions, anchor +*/ + +/* end of documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn void QCPAbstractItem::draw(QCPPainter *painter) = 0 + \internal + + Draws this item with the provided \a painter. + + The cliprect of the provided painter is set to the rect returned by \ref clipRect before this + function is called. The clipRect depends on the clipping settings defined by \ref + setClipToAxisRect and \ref setClipAxisRect. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPAbstractItem::selectionChanged(bool selected) + This signal is emitted when the selection state of this item has changed, either by user interaction + or by a direct call to \ref setSelected. +*/ + +/* end documentation of signals */ + +/*! + Base class constructor which initializes base class members. +*/ +QCPAbstractItem::QCPAbstractItem(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), + mClipToAxisRect(false), + mSelectable(true), + mSelected(false) +{ + parentPlot->registerItem(this); + + QList rects = parentPlot->axisRects(); + if (rects.size() > 0) + { + setClipToAxisRect(true); + setClipAxisRect(rects.first()); + } +} + +QCPAbstractItem::~QCPAbstractItem() +{ + // don't delete mPositions because every position is also an anchor and thus in mAnchors + qDeleteAll(mAnchors); +} + +/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ +QCPAxisRect *QCPAbstractItem::clipAxisRect() const +{ + return mClipAxisRect.data(); +} + +/*! + Sets whether the item shall be clipped to an axis rect or whether it shall be visible on the + entire QCustomPlot. The axis rect can be set with \ref setClipAxisRect. + + \see setClipAxisRect +*/ +void QCPAbstractItem::setClipToAxisRect(bool clip) +{ + mClipToAxisRect = clip; + if (mClipToAxisRect) + setParentLayerable(mClipAxisRect.data()); +} + +/*! + Sets the clip axis rect. It defines the rect that will be used to clip the item when \ref + setClipToAxisRect is set to true. + + \see setClipToAxisRect +*/ +void QCPAbstractItem::setClipAxisRect(QCPAxisRect *rect) +{ + mClipAxisRect = rect; + if (mClipToAxisRect) + setParentLayerable(mClipAxisRect.data()); +} + +/*! + Sets whether the user can (de-)select this item by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains QCustomPlot::iSelectItems.) + + However, even when \a selectable was set to false, it is possible to set the selection manually, + by calling \ref setSelected. + + \see QCustomPlot::setInteractions, setSelected +*/ +void QCPAbstractItem::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this item is selected or not. When selected, it might use a different visual + appearance (e.g. pen and brush), this depends on the specific item though. + + The entire selection mechanism for items is handled automatically when \ref + QCustomPlot::setInteractions contains QCustomPlot::iSelectItems. You only need to call this + function when you wish to change the selection state manually. + + This function can change the selection state even when \ref setSelectable was set to false. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPAbstractItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/*! + Returns the QCPItemPosition with the specified \a name. If this item doesn't have a position by + that name, returns 0. + + This function provides an alternative way to access item positions. Normally, you access + positions direcly by their member pointers (which typically have the same variable name as \a + name). + + \see positions, anchor +*/ +QCPItemPosition *QCPAbstractItem::position(const QString &name) const +{ + for (int i=0; iname() == name) + return mPositions.at(i); + } + qDebug() << Q_FUNC_INFO << "position with name not found:" << name; + return 0; +} + +/*! + Returns the QCPItemAnchor with the specified \a name. If this item doesn't have an anchor by + that name, returns 0. + + This function provides an alternative way to access item anchors. Normally, you access + anchors direcly by their member pointers (which typically have the same variable name as \a + name). + + \see anchors, position +*/ +QCPItemAnchor *QCPAbstractItem::anchor(const QString &name) const +{ + for (int i=0; iname() == name) + return mAnchors.at(i); + } + qDebug() << Q_FUNC_INFO << "anchor with name not found:" << name; + return 0; +} + +/*! + Returns whether this item has an anchor with the specified \a name. + + Note that you can check for positions with this function, too. This is because every position is + also an anchor (QCPItemPosition inherits from QCPItemAnchor). + + \see anchor, position +*/ +bool QCPAbstractItem::hasAnchor(const QString &name) const +{ + for (int i=0; iname() == name) + return true; + } + return false; +} + +/*! \internal + + Returns the rect the visual representation of this item is clipped to. This depends on the + current setting of \ref setClipToAxisRect as well as the axis rect set with \ref setClipAxisRect. + + If the item is not clipped to an axis rect, QCustomPlot's viewport rect is returned. + + \see draw +*/ +QRect QCPAbstractItem::clipRect() const +{ + if (mClipToAxisRect && mClipAxisRect) + return mClipAxisRect.data()->rect(); + else + return mParentPlot->viewport(); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing item lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPAbstractItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeItems); +} + +/*! \internal + + A convenience function which returns the selectTest value for a specified \a rect and a specified + click position \a pos. \a filledRect defines whether a click inside the rect should also be + considered a hit or whether only the rect border is sensitive to hits. + + This function may be used to help with the implementation of the \ref selectTest function for + specific items. + + For example, if your item consists of four rects, call this function four times, once for each + rect, in your \ref selectTest reimplementation. Finally, return the minimum (non -1) of all four + returned values. +*/ +double QCPAbstractItem::rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const +{ + double result = -1; + + // distance to border: + QList lines; + lines << QLineF(rect.topLeft(), rect.topRight()) << QLineF(rect.bottomLeft(), rect.bottomRight()) + << QLineF(rect.topLeft(), rect.bottomLeft()) << QLineF(rect.topRight(), rect.bottomRight()); + double minDistSqr = std::numeric_limits::max(); + for (int i=0; i mParentPlot->selectionTolerance()*0.99) + { + if (rect.contains(pos)) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/*! \internal + + Returns the pixel position of the anchor with Id \a anchorId. This function must be reimplemented in + item subclasses if they want to provide anchors (QCPItemAnchor). + + For example, if the item has two anchors with id 0 and 1, this function takes one of these anchor + ids and returns the respective pixel points of the specified anchor. + + \see createAnchor +*/ +QPointF QCPAbstractItem::anchorPixelPosition(int anchorId) const +{ + qDebug() << Q_FUNC_INFO << "called on item which shouldn't have any anchors (this method not reimplemented). anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Creates a QCPItemPosition, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the position + member (This is needed to provide the name-based \ref position access to positions). + + Don't delete positions created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each position member. Don't create QCPItemPositions with \b new yourself, because they + won't be registered with the item properly. + + \see createAnchor +*/ +QCPItemPosition *QCPAbstractItem::createPosition(const QString &name) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemPosition *newPosition = new QCPItemPosition(mParentPlot, this, name); + mPositions.append(newPosition); + mAnchors.append(newPosition); // every position is also an anchor + newPosition->setAxes(mParentPlot->xAxis, mParentPlot->yAxis); + newPosition->setType(QCPItemPosition::ptPlotCoords); + if (mParentPlot->axisRect()) + newPosition->setAxisRect(mParentPlot->axisRect()); + newPosition->setCoords(0, 0); + return newPosition; +} + +/*! \internal + + Creates a QCPItemAnchor, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the anchor + member (This is needed to provide the name based \ref anchor access to anchors). + + The \a anchorId must be a number identifying the created anchor. It is recommended to create an + enum (e.g. "AnchorIndex") for this on each item that uses anchors. This id is used by the anchor + to identify itself when it calls QCPAbstractItem::anchorPixelPosition. That function then returns + the correct pixel coordinates for the passed anchor id. + + Don't delete anchors created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each anchor member. Don't create QCPItemAnchors with \b new yourself, because then they + won't be registered with the item properly. + + \see createPosition +*/ +QCPItemAnchor *QCPAbstractItem::createAnchor(const QString &name, int anchorId) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemAnchor *newAnchor = new QCPItemAnchor(mParentPlot, this, name, anchorId); + mAnchors.append(newAnchor); + return newAnchor; +} + +/* inherits documentation from base class */ +void QCPAbstractItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractItem::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractItem::selectionCategory() const +{ + return QCP::iSelectItems; +} +/* end of 'src/item.cpp' */ + + +/* including file 'src/core.cpp', size 125037 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCustomPlot +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCustomPlot + + \brief The central class of the library. This is the QWidget which displays the plot and + interacts with the user. + + For tutorials on how to use QCustomPlot, see the website\n + http://www.qcustomplot.com/ +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPSelectionRect *QCustomPlot::selectionRect() const + + Allows access to the currently used QCPSelectionRect instance (or subclass thereof), that is used + to handle and draw selection rect interactions (see \ref setSelectionRectMode). + + \see setSelectionRect +*/ + +/*! \fn QCPLayoutGrid *QCustomPlot::plotLayout() const + + Returns the top level layout of this QCustomPlot instance. It is a \ref QCPLayoutGrid, initially containing just + one cell with the main QCPAxisRect inside. +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCustomPlot::mouseDoubleClick(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse double click event. +*/ + +/*! \fn void QCustomPlot::mousePress(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse press event. + + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref + QCPAxisRect::setRangeDragAxes. +*/ + +/*! \fn void QCustomPlot::mouseMove(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse move event. + + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref + QCPAxisRect::setRangeDragAxes. + + \warning It is discouraged to change the drag-axes with \ref QCPAxisRect::setRangeDragAxes here, + because the dragging starting point was saved the moment the mouse was pressed. Thus it only has + a meaning for the range drag axes that were set at that moment. If you want to change the drag + axes, consider doing this in the \ref mousePress signal instead. +*/ + +/*! \fn void QCustomPlot::mouseRelease(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse release event. + + It is emitted before QCustomPlot handles any other mechanisms like object selection. So a + slot connected to this signal can still influence the behaviour e.g. with \ref setInteractions or + \ref QCPAbstractPlottable::setSelectable. +*/ + +/*! \fn void QCustomPlot::mouseWheel(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse wheel event. + + It is emitted before QCustomPlot handles any other mechanisms like range zooming. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeZoom, \ref + QCPAxisRect::setRangeZoomAxes or \ref QCPAxisRect::setRangeZoomFactor. +*/ + +/*! \fn void QCustomPlot::plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) + + This signal is emitted when a plottable is clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. The parameter \a dataIndex indicates the data point that was closest to the click + position. + + \see plottableDoubleClick +*/ + +/*! \fn void QCustomPlot::plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) + + This signal is emitted when a plottable is double clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. The parameter \a dataIndex indicates the data point that was closest to the click + position. + + \see plottableClick +*/ + +/*! \fn void QCustomPlot::itemClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemDoubleClick +*/ + +/*! \fn void QCustomPlot::itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is double clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemClick +*/ + +/*! \fn void QCustomPlot::axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisDoubleClick +*/ + +/*! \fn void QCustomPlot::axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is double clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisClick +*/ + +/*! \fn void QCustomPlot::legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is 0. This happens for a click inside the legend padding or the space between + two items. + + \see legendDoubleClick +*/ + +/*! \fn void QCustomPlot::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is double clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is 0. This happens for a click inside the legend padding or the space between + two items. + + \see legendClick +*/ + +/*! \fn void QCustomPlot::selectionChangedByUser() + + This signal is emitted after the user has changed the selection in the QCustomPlot, e.g. by + clicking. It is not emitted when the selection state of an object has changed programmatically by + a direct call to setSelected()/setSelection() on an object or by calling \ref + deselectAll. + + In addition to this signal, selectable objects also provide individual signals, for example \ref + QCPAxis::selectionChanged or \ref QCPAbstractPlottable::selectionChanged. Note that those signals + are emitted even if the selection state is changed programmatically. + + See the documentation of \ref setInteractions for details about the selection mechanism. + + \see selectedPlottables, selectedGraphs, selectedItems, selectedAxes, selectedLegends +*/ + +/*! \fn void QCustomPlot::beforeReplot() + + This signal is emitted immediately before a replot takes place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously, it won't cause an infinite recursion. + + \see replot, afterReplot +*/ + +/*! \fn void QCustomPlot::afterReplot() + + This signal is emitted immediately after a replot has taken place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously, it won't cause an infinite recursion. + + \see replot, beforeReplot +*/ + +/* end of documentation of signals */ +/* start of documentation of public members */ + +/*! \var QCPAxis *QCustomPlot::xAxis + + A pointer to the primary x Axis (bottom) of the main axis rect of the plot. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::yAxis + + A pointer to the primary y Axis (left) of the main axis rect of the plot. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::xAxis2 + + A pointer to the secondary x Axis (top) of the main axis rect of the plot. Secondary axes are + invisible by default. Use QCPAxis::setVisible to change this (or use \ref + QCPAxisRect::setupFullAxesBox). + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::yAxis2 + + A pointer to the secondary y Axis (right) of the main axis rect of the plot. Secondary axes are + invisible by default. Use QCPAxis::setVisible to change this (or use \ref + QCPAxisRect::setupFullAxesBox). + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPLegend *QCustomPlot::legend + + A pointer to the default legend of the main axis rect. The legend is invisible by default. Use + QCPLegend::setVisible to change this. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple legends to the plot, use the layout system interface to + access the new legend. For example, legends can be placed inside an axis rect's \ref + QCPAxisRect::insetLayout "inset layout", and must then also be accessed via the inset layout. If + the default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointer becomes 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/* end of documentation of public members */ + +/*! + Constructs a QCustomPlot and sets reasonable default values. +*/ +QCustomPlot::QCustomPlot(QWidget *parent) : + QWidget(parent), + xAxis(0), + yAxis(0), + xAxis2(0), + yAxis2(0), + legend(0), + mBufferDevicePixelRatio(1.0), // will be adapted to primary screen below + mPlotLayout(0), + mAutoAddPlottableToLegend(true), + mAntialiasedElements(QCP::aeNone), + mNotAntialiasedElements(QCP::aeNone), + mInteractions(0), + mSelectionTolerance(8), + mNoAntialiasingOnDrag(false), + mBackgroundBrush(Qt::white, Qt::SolidPattern), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mCurrentLayer(0), + mPlottingHints(QCP::phCacheLabels|QCP::phImmediateRefresh), + mMultiSelectModifier(Qt::ControlModifier), + mSelectionRectMode(QCP::srmNone), + mSelectionRect(0), + mOpenGl(false), + mSymbolPressed(false), + mMouseHasMoved(false), + mMouseEventLayerable(0), + mMouseSignalLayerable(0), + mReplotting(false), + mReplotQueued(false), + mOpenGlMultisamples(16), + mOpenGlAntialiasedElementsBackup(QCP::aeNone), + mOpenGlCacheLabelsBackup(true) +{ + setAttribute(Qt::WA_NoMousePropagation); + setAttribute(Qt::WA_OpaquePaintEvent); + setFocusPolicy(Qt::ClickFocus); + setMouseTracking(true); + QLocale currentLocale = locale(); + currentLocale.setNumberOptions(QLocale::OmitGroupSeparator); + setLocale(currentLocale); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED +# ifdef QCP_DEVICEPIXELRATIO_FLOAT + setBufferDevicePixelRatio(QWidget::devicePixelRatioF()); +# else + setBufferDevicePixelRatio(QWidget::devicePixelRatio()); +# endif +#endif + + mOpenGlAntialiasedElementsBackup = mAntialiasedElements; + mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); + // create initial layers: + mLayers.append(new QCPLayer(this, QLatin1String("background"))); + mLayers.append(new QCPLayer(this, QLatin1String("grid"))); + mLayers.append(new QCPLayer(this, QLatin1String("main"))); + mLayers.append(new QCPLayer(this, QLatin1String("axes"))); + mLayers.append(new QCPLayer(this, QLatin1String("legend"))); + mLayers.append(new QCPLayer(this, QLatin1String("overlay"))); + updateLayerIndices(); + setCurrentLayer(QLatin1String("main")); + layer(QLatin1String("overlay"))->setMode(QCPLayer::lmBuffered); + + // create initial layout, axis rect and legend: + mPlotLayout = new QCPLayoutGrid; + mPlotLayout->initializeParentPlot(this); + mPlotLayout->setParent(this); // important because if parent is QWidget, QCPLayout::sizeConstraintsChanged will call QWidget::updateGeometry + mPlotLayout->setLayer(QLatin1String("main")); + QCPAxisRect *defaultAxisRect = new QCPAxisRect(this, true); + mPlotLayout->addElement(0, 0, defaultAxisRect); + xAxis = defaultAxisRect->axis(QCPAxis::atBottom); + yAxis = defaultAxisRect->axis(QCPAxis::atLeft); + xAxis2 = defaultAxisRect->axis(QCPAxis::atTop); + yAxis2 = defaultAxisRect->axis(QCPAxis::atRight); + legend = new QCPLegend; + legend->setVisible(false); + defaultAxisRect->insetLayout()->addElement(legend, Qt::AlignRight|Qt::AlignTop); + defaultAxisRect->insetLayout()->setMargins(QMargins(12, 12, 12, 12)); + + defaultAxisRect->setLayer(QLatin1String("background")); + xAxis->setLayer(QLatin1String("axes")); + yAxis->setLayer(QLatin1String("axes")); + xAxis2->setLayer(QLatin1String("axes")); + yAxis2->setLayer(QLatin1String("axes")); + xAxis->grid()->setLayer(QLatin1String("grid")); + yAxis->grid()->setLayer(QLatin1String("grid")); + xAxis2->grid()->setLayer(QLatin1String("grid")); + yAxis2->grid()->setLayer(QLatin1String("grid")); + legend->setLayer(QLatin1String("legend")); + + // create selection rect instance: + mSelectionRect = new QCPSelectionRect(this); + mSelectionRect->setLayer(QLatin1String("overlay")); + + setViewport(rect()); // needs to be called after mPlotLayout has been created + + replot(rpQueuedReplot); +} + +QCustomPlot::~QCustomPlot() +{ + clearPlottables(); + clearItems(true); + + if (mPlotLayout) + { + delete mPlotLayout; + mPlotLayout = 0; + } + + mCurrentLayer = 0; + qDeleteAll(mLayers); // don't use removeLayer, because it would prevent the last layer to be removed + mLayers.clear(); +} + +void QCustomPlot::setSymbolPos(const QPoint pos) +{ + mSymbolPos = QPoint(pos.x(), 0); +} + +/*! + Sets which elements are forcibly drawn antialiased as an \a or combination of QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a antialiasedElements contains \ref QCP::aePlottables, all plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a antialiasedElements is already set in \ref setNotAntialiasedElements, it is + removed from there. + + \see setNotAntialiasedElements +*/ +void QCustomPlot::setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements) +{ + mAntialiasedElements = antialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets whether the specified \a antialiasedElement is forcibly drawn antialiased. + + See \ref setAntialiasedElements for details. + + \see setNotAntialiasedElement +*/ +void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled) +{ + if (!enabled && mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements &= ~antialiasedElement; + else if (enabled && !mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements |= antialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets which elements are forcibly drawn not antialiased as an \a or combination of + QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a notAntialiasedElements contains \ref QCP::aePlottables, no plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a notAntialiasedElements is already set in \ref setAntialiasedElements, it is + removed from there. + + \see setAntialiasedElements +*/ +void QCustomPlot::setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements) +{ + mNotAntialiasedElements = notAntialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + Sets whether the specified \a notAntialiasedElement is forcibly drawn not antialiased. + + See \ref setNotAntialiasedElements for details. + + \see setAntialiasedElement +*/ +void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled) +{ + if (!enabled && mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements &= ~notAntialiasedElement; + else if (enabled && !mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements |= notAntialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + If set to true, adding a plottable (e.g. a graph) to the QCustomPlot automatically also adds the + plottable to the legend (QCustomPlot::legend). + + \see addGraph, QCPLegend::addItem +*/ +void QCustomPlot::setAutoAddPlottableToLegend(bool on) +{ + mAutoAddPlottableToLegend = on; +} + +/*! + Sets the possible interactions of this QCustomPlot as an or-combination of \ref QCP::Interaction + enums. There are the following types of interactions: + + Axis range manipulation is controlled via \ref QCP::iRangeDrag and \ref QCP::iRangeZoom. When the + respective interaction is enabled, the user may drag axes ranges and zoom with the mouse wheel. + For details how to control which axes the user may drag/zoom and in what orientations, see \ref + QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeDragAxes, + \ref QCPAxisRect::setRangeZoomAxes. + + Plottable data selection is controlled by \ref QCP::iSelectPlottables. If \ref + QCP::iSelectPlottables is set, the user may select plottables (graphs, curves, bars,...) and + their data by clicking on them or in their vicinity (\ref setSelectionTolerance). Whether the + user can actually select a plottable and its data can further be restricted with the \ref + QCPAbstractPlottable::setSelectable method on the specific plottable. For details, see the + special page about the \ref dataselection "data selection mechanism". To retrieve a list of all + currently selected plottables, call \ref selectedPlottables. If you're only interested in + QCPGraphs, you may use the convenience function \ref selectedGraphs. + + Item selection is controlled by \ref QCP::iSelectItems. If \ref QCP::iSelectItems is set, the user + may select items (QCPItemLine, QCPItemText,...) by clicking on them or in their vicinity. To find + out whether a specific item is selected, call QCPAbstractItem::selected(). To retrieve a list of + all currently selected items, call \ref selectedItems. + + Axis selection is controlled with \ref QCP::iSelectAxes. If \ref QCP::iSelectAxes is set, the user + may select parts of the axes by clicking on them. What parts exactly (e.g. Axis base line, tick + labels, axis label) are selectable can be controlled via \ref QCPAxis::setSelectableParts for + each axis. To retrieve a list of all axes that currently contain selected parts, call \ref + selectedAxes. Which parts of an axis are selected, can be retrieved with QCPAxis::selectedParts(). + + Legend selection is controlled with \ref QCP::iSelectLegend. If this is set, the user may + select the legend itself or individual items by clicking on them. What parts exactly are + selectable can be controlled via \ref QCPLegend::setSelectableParts. To find out whether the + legend or any of its child items are selected, check the value of QCPLegend::selectedParts. To + find out which child items are selected, call \ref QCPLegend::selectedItems. + + All other selectable elements The selection of all other selectable objects (e.g. + QCPTextElement, or your own layerable subclasses) is controlled with \ref QCP::iSelectOther. If set, the + user may select those objects by clicking on them. To find out which are currently selected, you + need to check their selected state explicitly. + + If the selection state has changed by user interaction, the \ref selectionChangedByUser signal is + emitted. Each selectable object additionally emits an individual selectionChanged signal whenever + their selection state has changed, i.e. not only by user interaction. + + To allow multiple objects to be selected by holding the selection modifier (\ref + setMultiSelectModifier), set the flag \ref QCP::iMultiSelect. + + \note In addition to the selection mechanism presented here, QCustomPlot always emits + corresponding signals, when an object is clicked or double clicked. see \ref plottableClick and + \ref plottableDoubleClick for example. + + \see setInteraction, setSelectionTolerance +*/ +void QCustomPlot::setInteractions(const QCP::Interactions &interactions) +{ + mInteractions = interactions; +} + +/*! + Sets the single \a interaction of this QCustomPlot to \a enabled. + + For details about the interaction system, see \ref setInteractions. + + \see setInteractions +*/ +void QCustomPlot::setInteraction(const QCP::Interaction &interaction, bool enabled) +{ + if (!enabled && mInteractions.testFlag(interaction)) + mInteractions &= ~interaction; + else if (enabled && !mInteractions.testFlag(interaction)) + mInteractions |= interaction; +} + +/*! + Sets the tolerance that is used to decide whether a click selects an object (e.g. a plottable) or + not. + + If the user clicks in the vicinity of the line of e.g. a QCPGraph, it's only regarded as a + potential selection when the minimum distance between the click position and the graph line is + smaller than \a pixels. Objects that are defined by an area (e.g. QCPBars) only react to clicks + directly inside the area and ignore this selection tolerance. In other words, it only has meaning + for parts of objects that are too thin to exactly hit with a click and thus need such a + tolerance. + + \see setInteractions, QCPLayerable::selectTest +*/ +void QCustomPlot::setSelectionTolerance(int pixels) +{ + mSelectionTolerance = pixels; +} + +/*! + Sets whether antialiasing is disabled for this QCustomPlot while the user is dragging axes + ranges. If many objects, especially plottables, are drawn antialiased, this greatly improves + performance during dragging. Thus it creates a more responsive user experience. As soon as the + user stops dragging, the last replot is done with normal antialiasing, to restore high image + quality. + + \see setAntialiasedElements, setNotAntialiasedElements +*/ +void QCustomPlot::setNoAntialiasingOnDrag(bool enabled) +{ + mNoAntialiasingOnDrag = enabled; +} + +/*! + Sets the plotting hints for this QCustomPlot instance as an \a or combination of QCP::PlottingHint. + + \see setPlottingHint +*/ +void QCustomPlot::setPlottingHints(const QCP::PlottingHints &hints) +{ + mPlottingHints = hints; +} + +/*! + Sets the specified plotting \a hint to \a enabled. + + \see setPlottingHints +*/ +void QCustomPlot::setPlottingHint(QCP::PlottingHint hint, bool enabled) +{ + QCP::PlottingHints newHints = mPlottingHints; + if (!enabled) + newHints &= ~hint; + else + newHints |= hint; + + if (newHints != mPlottingHints) + setPlottingHints(newHints); +} + +/*! + Sets the keyboard modifier that will be recognized as multi-select-modifier. + + If \ref QCP::iMultiSelect is specified in \ref setInteractions, the user may select multiple + objects (or data points) by clicking on them one after the other while holding down \a modifier. + + By default the multi-select-modifier is set to Qt::ControlModifier. + + \see setInteractions +*/ +void QCustomPlot::setMultiSelectModifier(Qt::KeyboardModifier modifier) +{ + mMultiSelectModifier = modifier; +} + +/*! + Sets how QCustomPlot processes mouse click-and-drag interactions by the user. + + If \a mode is \ref QCP::srmNone, the mouse drag is forwarded to the underlying objects. For + example, QCPAxisRect may process a mouse drag by dragging axis ranges, see \ref + QCPAxisRect::setRangeDrag. If \a mode is not \ref QCP::srmNone, the current selection rect (\ref + selectionRect) becomes activated and allows e.g. rect zooming and data point selection. + + If you wish to provide your user both with axis range dragging and data selection/range zooming, + use this method to switch between the modes just before the interaction is processed, e.g. in + reaction to the \ref mousePress or \ref mouseMove signals. For example you could check whether + the user is holding a certain keyboard modifier, and then decide which \a mode shall be set. + + If a selection rect interaction is currently active, and \a mode is set to \ref QCP::srmNone, the + interaction is canceled (\ref QCPSelectionRect::cancel). Switching between any of the other modes + will keep the selection rect active. Upon completion of the interaction, the behaviour is as + defined by the currently set \a mode, not the mode that was set when the interaction started. + + \see setInteractions, setSelectionRect, QCPSelectionRect +*/ +void QCustomPlot::setSelectionRectMode(QCP::SelectionRectMode mode) +{ + if (mSelectionRect) + { + if (mode == QCP::srmNone) + mSelectionRect->cancel(); // when switching to none, we immediately want to abort a potentially active selection rect + + // disconnect old connections: + if (mSelectionRectMode == QCP::srmSelect) + disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mSelectionRectMode == QCP::srmZoom) + disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + + // establish new ones: + if (mode == QCP::srmSelect) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mode == QCP::srmZoom) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + } + + mSelectionRectMode = mode; +} + +/*! + Sets the \ref QCPSelectionRect instance that QCustomPlot will use if \a mode is not \ref + QCP::srmNone and the user performs a click-and-drag interaction. QCustomPlot takes ownership of + the passed \a selectionRect. It can be accessed later via \ref selectionRect. + + This method is useful if you wish to replace the default QCPSelectionRect instance with an + instance of a QCPSelectionRect subclass, to introduce custom behaviour of the selection rect. + + \see setSelectionRectMode +*/ +void QCustomPlot::setSelectionRect(QCPSelectionRect *selectionRect) +{ + if (mSelectionRect) + delete mSelectionRect; + + mSelectionRect = selectionRect; + + if (mSelectionRect) + { + // establish connections with new selection rect: + if (mSelectionRectMode == QCP::srmSelect) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mSelectionRectMode == QCP::srmZoom) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + } +} + +/*! + \warning This is still an experimental feature and its performance depends on the system that it + runs on. Having multiple QCustomPlot widgets in one application with enabled OpenGL rendering + might cause context conflicts on some systems. + + This method allows to enable OpenGL plot rendering, for increased plotting performance of + graphically demanding plots (thick lines, translucent fills, etc.). + + If \a enabled is set to true, QCustomPlot will try to initialize OpenGL and, if successful, + continue plotting with hardware acceleration. The parameter \a multisampling controls how many + samples will be used per pixel, it essentially controls the antialiasing quality. If \a + multisampling is set too high for the current graphics hardware, the maximum allowed value will + be used. + + You can test whether switching to OpenGL rendering was successful by checking whether the + according getter \a QCustomPlot::openGl() returns true. If the OpenGL initialization fails, + rendering continues with the regular software rasterizer, and an according qDebug output is + generated. + + If switching to OpenGL was successful, this method disables label caching (\ref setPlottingHint + "setPlottingHint(QCP::phCacheLabels, false)") and turns on QCustomPlot's antialiasing override + for all elements (\ref setAntialiasedElements "setAntialiasedElements(QCP::aeAll)"), leading to a + higher quality output. The antialiasing override allows for pixel-grid aligned drawing in the + OpenGL paint device. As stated before, in OpenGL rendering the actual antialiasing of the plot is + controlled with \a multisampling. If \a enabled is set to false, the antialiasing/label caching + settings are restored to what they were before OpenGL was enabled, if they weren't altered in the + meantime. + + \note OpenGL support is only enabled if QCustomPlot is compiled with the macro \c QCUSTOMPLOT_USE_OPENGL + defined. This define must be set before including the QCustomPlot header both during compilation + of the QCustomPlot library as well as when compiling your application. It is best to just include + the line DEFINES += QCUSTOMPLOT_USE_OPENGL in the respective qmake project files. + \note If you are using a Qt version before 5.0, you must also add the module "opengl" to your \c + QT variable in the qmake project files. For Qt versions 5.0 and higher, QCustomPlot switches to a + newer OpenGL interface which is already in the "gui" module. +*/ +void QCustomPlot::setOpenGl(bool enabled, int multisampling) +{ + mOpenGlMultisamples = qMax(0, multisampling); +#ifdef QCUSTOMPLOT_USE_OPENGL + mOpenGl = enabled; + if (mOpenGl) + { + if (setupOpenGl()) + { + // backup antialiasing override and labelcaching setting so we can restore upon disabling OpenGL + mOpenGlAntialiasedElementsBackup = mAntialiasedElements; + mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); + // set antialiasing override to antialias all (aligns gl pixel grid properly), and disable label caching (would use software rasterizer for pixmap caches): + setAntialiasedElements(QCP::aeAll); + setPlottingHint(QCP::phCacheLabels, false); + } else + { + qDebug() << Q_FUNC_INFO << "Failed to enable OpenGL, continuing plotting without hardware acceleration."; + mOpenGl = false; + } + } else + { + // restore antialiasing override and labelcaching to what it was before enabling OpenGL, if nobody changed it in the meantime: + if (mAntialiasedElements == QCP::aeAll) + setAntialiasedElements(mOpenGlAntialiasedElementsBackup); + if (!mPlottingHints.testFlag(QCP::phCacheLabels)) + setPlottingHint(QCP::phCacheLabels, mOpenGlCacheLabelsBackup); + freeOpenGl(); + } + // recreate all paint buffers: + mPaintBuffers.clear(); + setupPaintBuffers(); +#else + Q_UNUSED(enabled) + qDebug() << Q_FUNC_INFO << "QCustomPlot can't use OpenGL because QCUSTOMPLOT_USE_OPENGL was not defined during compilation (add 'DEFINES += QCUSTOMPLOT_USE_OPENGL' to your qmake .pro file)"; +#endif +} + +/*! + Sets the viewport of this QCustomPlot. Usually users of QCustomPlot don't need to change the + viewport manually. + + The viewport is the area in which the plot is drawn. All mechanisms, e.g. margin caluclation take + the viewport to be the outer border of the plot. The viewport normally is the rect() of the + QCustomPlot widget, i.e. a rect with top left (0, 0) and size of the QCustomPlot widget. + + Don't confuse the viewport with the axis rect (QCustomPlot::axisRect). An axis rect is typically + an area enclosed by four axes, where the graphs/plottables are drawn in. The viewport is larger + and contains also the axes themselves, their tick numbers, their labels, or even additional axis + rects, color scales and other layout elements. + + This function is used to allow arbitrary size exports with \ref toPixmap, \ref savePng, \ref + savePdf, etc. by temporarily changing the viewport size. +*/ +void QCustomPlot::setViewport(const QRect &rect) +{ + mViewport = rect; + if (mPlotLayout) + mPlotLayout->setOuterRect(mViewport); +} + +/*! + Sets the device pixel ratio used by the paint buffers of this QCustomPlot instance. + + Normally, this doesn't need to be set manually, because it is initialized with the regular \a + QWidget::devicePixelRatio which is configured by Qt to fit the display device (e.g. 1 for normal + displays, 2 for High-DPI displays). + + Device pixel ratios are supported by Qt only for Qt versions since 5.4. If this method is called + when QCustomPlot is being used with older Qt versions, outputs an according qDebug message and + leaves the internal buffer device pixel ratio at 1.0. +*/ +void QCustomPlot::setBufferDevicePixelRatio(double ratio) +{ + if (!qFuzzyCompare(ratio, mBufferDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mBufferDevicePixelRatio = ratio; + for (int i=0; isetDevicePixelRatio(mBufferDevicePixelRatio); + // Note: axis label cache has devicePixelRatio as part of cache hash, so no need to manually clear cache here +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mBufferDevicePixelRatio = 1.0; +#endif + } +} + +/*! + Sets \a pm as the viewport background pixmap (see \ref setViewport). The pixmap is always drawn + below all other objects in the plot. + + For cases where the provided pixmap doesn't have the same size as the viewport, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (whether and how the aspect ratio is + preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + If a background brush was set with \ref setBackground(const QBrush &brush), the viewport will + first be filled with that brush, before drawing the background pixmap. This can be useful for + background pixmaps with translucent areas. + + \see setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! + Sets the background brush of the viewport (see \ref setViewport). + + Before drawing everything else, the background is filled with \a brush. If a background pixmap + was set with \ref setBackground(const QPixmap &pm), this brush will be used to fill the viewport + before the background pixmap is drawn. This can be useful for background pixmaps with translucent + areas. + + Set \a brush to Qt::NoBrush or Qt::Transparent to leave background transparent. This can be + useful for exporting to image formats which support transparency, e.g. \ref savePng. + + \see setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the viewport, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the viewport background pixmap shall be scaled to fit the viewport. If \a scaled is + set to true, control whether and how the aspect ratio of the original pixmap is preserved with + \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the viewport dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCustomPlot::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the viewport background pixmap is enabled (\ref setBackgroundScaled), use this + function to define whether and how the aspect ratio of the original pixmap is preserved. + + \see setBackground, setBackgroundScaled +*/ +void QCustomPlot::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +/*! + Returns the plottable with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last added + plottable, see QCustomPlot::plottable() + + \see plottableCount +*/ +QCPAbstractPlottable *QCustomPlot::plottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + { + return mPlottables.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last plottable that was added to the plot. If there are no plottables in the plot, + returns 0. + + \see plottableCount +*/ +QCPAbstractPlottable *QCustomPlot::plottable() +{ + if (!mPlottables.isEmpty()) + { + return mPlottables.last(); + } else + return 0; +} + +/*! + Removes the specified plottable from the plot and deletes it. If necessary, the corresponding + legend item is also removed from the default legend (QCustomPlot::legend). + + Returns true on success. + + \see clearPlottables +*/ +bool QCustomPlot::removePlottable(QCPAbstractPlottable *plottable) +{ + if (!mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable not in list:" << reinterpret_cast(plottable); + return false; + } + + // remove plottable from legend: + plottable->removeFromLegend(); + // special handling for QCPGraphs to maintain the simple graph interface: + if (QCPGraph *graph = qobject_cast(plottable)) + mGraphs.removeOne(graph); + // remove plottable: + delete plottable; + mPlottables.removeOne(plottable); + return true; +} + +/*! \overload + + Removes and deletes the plottable by its \a index. +*/ +bool QCustomPlot::removePlottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + return removePlottable(mPlottables[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all plottables from the plot and deletes them. Corresponding legend items are also + removed from the default legend (QCustomPlot::legend). + + Returns the number of plottables removed. + + \see removePlottable +*/ +int QCustomPlot::clearPlottables() +{ + int c = mPlottables.size(); + for (int i=c-1; i >= 0; --i) + removePlottable(mPlottables[i]); + return c; +} + +/*! + Returns the number of currently existing plottables in the plot + + \see plottable +*/ +int QCustomPlot::plottableCount() const +{ + return mPlottables.size(); +} + +/*! + Returns a list of the selected plottables. If no plottables are currently selected, the list is empty. + + There is a convenience function if you're only interested in selected graphs, see \ref selectedGraphs. + + \see setInteractions, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection +*/ +QList QCustomPlot::selectedPlottables() const +{ + QList result; + foreach (QCPAbstractPlottable *plottable, mPlottables) + { + if (plottable->selected()) + result.append(plottable); + } + return result; +} + +/*! + Returns the plottable at the pixel position \a pos. Plottables that only consist of single lines + (like graphs) have a tolerance band around them, see \ref setSelectionTolerance. If multiple + plottables come into consideration, the one closest to \a pos is returned. + + If \a onlySelectable is true, only plottables that are selectable + (QCPAbstractPlottable::setSelectable) are considered. + + If there is no plottable at \a pos, the return value is 0. + + \see itemAt, layoutElementAt +*/ +QCPAbstractPlottable *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable) const +{ + QCPAbstractPlottable *resultPlottable = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + foreach (QCPAbstractPlottable *plottable, mPlottables) + { + if (onlySelectable && !plottable->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPabstractPlottable::selectable + continue; + if ((plottable->keyAxis()->axisRect()->rect() & plottable->valueAxis()->axisRect()->rect()).contains(pos.toPoint())) // only consider clicks inside the rect that is spanned by the plottable's key/value axes + { + double currentDistance = plottable->selectTest(pos, false); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultPlottable = plottable; + resultDistance = currentDistance; + } + } + } + + return resultPlottable; +} + +/*! + Returns whether this QCustomPlot instance contains the \a plottable. +*/ +bool QCustomPlot::hasPlottable(QCPAbstractPlottable *plottable) const +{ + return mPlottables.contains(plottable); +} + +/*! + Returns the graph with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last created + graph, see QCustomPlot::graph() + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph(int index) const +{ + if (index >= 0 && index < mGraphs.size()) + { + return mGraphs.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last graph, that was created with \ref addGraph. If there are no graphs in the plot, + returns 0. + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph() const +{ + if (!mGraphs.isEmpty()) + { + return mGraphs.last(); + } else + return 0; +} + +/*! + Creates a new graph inside the plot. If \a keyAxis and \a valueAxis are left unspecified (0), the + bottom (xAxis) is used as key and the left (yAxis) is used as value axis. If specified, \a + keyAxis and \a valueAxis must reside in this QCustomPlot. + + \a keyAxis will be used as key axis (typically "x") and \a valueAxis as value axis (typically + "y") for the graph. + + Returns a pointer to the newly created graph, or 0 if adding the graph failed. + + \see graph, graphCount, removeGraph, clearGraphs +*/ +QCPGraph *QCustomPlot::addGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + if (!keyAxis) keyAxis = xAxis; + if (!valueAxis) valueAxis = yAxis; + if (!keyAxis || !valueAxis) + { + qDebug() << Q_FUNC_INFO << "can't use default QCustomPlot xAxis or yAxis, because at least one is invalid (has been deleted)"; + return 0; + } + if (keyAxis->parentPlot() != this || valueAxis->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "passed keyAxis or valueAxis doesn't have this QCustomPlot as parent"; + return 0; + } + + QCPGraph *newGraph = new QCPGraph(keyAxis, valueAxis); + newGraph->setName(QLatin1String("Graph ")+QString::number(mGraphs.size())); + return newGraph; +} + +/*! + Removes the specified \a graph from the plot and deletes it. If necessary, the corresponding + legend item is also removed from the default legend (QCustomPlot::legend). If any other graphs in + the plot have a channel fill set towards the removed graph, the channel fill property of those + graphs is reset to zero (no channel fill). + + Returns true on success. + + \see clearGraphs +*/ +bool QCustomPlot::removeGraph(QCPGraph *graph) +{ + return removePlottable(graph); +} + +/*! \overload + + Removes and deletes the graph by its \a index. +*/ +bool QCustomPlot::removeGraph(int index) +{ + if (index >= 0 && index < mGraphs.size()) + return removeGraph(mGraphs[index]); + else + return false; +} + +/*! + Removes all graphs from the plot and deletes them. Corresponding legend items are also removed + from the default legend (QCustomPlot::legend). + + Returns the number of graphs removed. + + \see removeGraph +*/ +int QCustomPlot::clearGraphs() +{ + int c = mGraphs.size(); + for (int i=c-1; i >= 0; --i) + removeGraph(mGraphs[i]); + return c; +} + +/*! + Returns the number of currently existing graphs in the plot + + \see graph, addGraph +*/ +int QCustomPlot::graphCount() const +{ + return mGraphs.size(); +} + +/*! + Returns a list of the selected graphs. If no graphs are currently selected, the list is empty. + + If you are not only interested in selected graphs but other plottables like QCPCurve, QCPBars, + etc., use \ref selectedPlottables. + + \see setInteractions, selectedPlottables, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection +*/ +QList QCustomPlot::selectedGraphs() const +{ + QList result; + foreach (QCPGraph *graph, mGraphs) + { + if (graph->selected()) + result.append(graph); + } + return result; +} + +/*! + Returns the item with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last added + item, see QCustomPlot::item() + + \see itemCount +*/ +QCPAbstractItem *QCustomPlot::item(int index) const +{ + if (index >= 0 && index < mItems.size()) + { + return mItems.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last item that was added to this plot. If there are no items in the plot, + returns 0. + + \see itemCount +*/ +QCPAbstractItem *QCustomPlot::item() const +{ + if (!mItems.isEmpty()) + { + return mItems.last(); + } else + return 0; +} + +/*! + Removes the specified item from the plot and deletes it. + + Returns true on success. + + \see clearItems +*/ +bool QCustomPlot::removeItem(QCPAbstractItem *item) +{ + if (mItems.contains(item)) + { + delete item; + mItems.removeOne(item); + return true; + } else + { + qDebug() << Q_FUNC_INFO << "item not in list:" << reinterpret_cast(item); + return false; + } +} + +/*! \overload + + Removes and deletes the item by its \a index. +*/ +bool QCustomPlot::removeItem(int index) +{ + if (index >= 0 && index < mItems.size()) + return removeItem(mItems[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all items from the plot and deletes them. + + Returns the number of items removed. + + \see removeItem +*/ +int QCustomPlot::clearItems(bool clearTitle) +{ + int c = mItems.size(); + for (int i=c-1; i >= 0; --i) + { + if(mItems[i]->objectName() == "m_trendTitle") + { + if(!clearTitle) + { + continue; + } + } + removeItem(mItems[i]); + } + return c; +} + +/*! + Returns the number of currently existing items in the plot + + \see item +*/ +int QCustomPlot::itemCount() const +{ + return mItems.size(); +} + +/*! + Returns a list of the selected items. If no items are currently selected, the list is empty. + + \see setInteractions, QCPAbstractItem::setSelectable, QCPAbstractItem::setSelected +*/ +QList QCustomPlot::selectedItems() const +{ + QList result; + foreach (QCPAbstractItem *item, mItems) + { + if (item->selected()) + result.append(item); + } + return result; +} + +/*! + Returns the item at the pixel position \a pos. Items that only consist of single lines (e.g. \ref + QCPItemLine or \ref QCPItemCurve) have a tolerance band around them, see \ref + setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is + returned. + + If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are + considered. + + If there is no item at \a pos, the return value is 0. + + \see plottableAt, layoutElementAt +*/ +QCPAbstractItem *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const +{ + QCPAbstractItem *resultItem = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + foreach (QCPAbstractItem *item, mItems) + { + if (onlySelectable && !item->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractItem::selectable + continue; + if (!item->clipToAxisRect() || item->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it + { + double currentDistance = item->selectTest(pos, false); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultItem = item; + resultDistance = currentDistance; + } + } + } + + return resultItem; +} + +/*! + Returns whether this QCustomPlot contains the \a item. + + \see item +*/ +bool QCustomPlot::hasItem(QCPAbstractItem *item) const +{ + return mItems.contains(item); +} + +/*! + Returns the layer with the specified \a name. If there is no layer with the specified name, 0 is + returned. + + Layer names are case-sensitive. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(const QString &name) const +{ + foreach (QCPLayer *layer, mLayers) + { + if (layer->name() == name) + return layer; + } + return 0; +} + +/*! \overload + + Returns the layer by \a index. If the index is invalid, 0 is returned. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(int index) const +{ + if (index >= 0 && index < mLayers.size()) + { + return mLayers.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! + Returns the layer that is set as current layer (see \ref setCurrentLayer). +*/ +QCPLayer *QCustomPlot::currentLayer() const +{ + return mCurrentLayer; +} + +/*! + Sets the layer with the specified \a name to be the current layer. All layerables (\ref + QCPLayerable), e.g. plottables and items, are created on the current layer. + + Returns true on success, i.e. if there is a layer with the specified \a name in the QCustomPlot. + + Layer names are case-sensitive. + + \see addLayer, moveLayer, removeLayer, QCPLayerable::setLayer +*/ +bool QCustomPlot::setCurrentLayer(const QString &name) +{ + if (QCPLayer *newCurrentLayer = layer(name)) + { + return setCurrentLayer(newCurrentLayer); + } else + { + qDebug() << Q_FUNC_INFO << "layer with name doesn't exist:" << name; + return false; + } +} + +/*! \overload + + Sets the provided \a layer to be the current layer. + + Returns true on success, i.e. when \a layer is a valid layer in the QCustomPlot. + + \see addLayer, moveLayer, removeLayer +*/ +bool QCustomPlot::setCurrentLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + + mCurrentLayer = layer; + return true; +} + +/*! + Returns the number of currently existing layers in the plot + + \see layer, addLayer +*/ +int QCustomPlot::layerCount() const +{ + return mLayers.size(); +} + +/*! + Adds a new layer to this QCustomPlot instance. The new layer will have the name \a name, which + must be unique. Depending on \a insertMode, it is positioned either below or above \a otherLayer. + + Returns true on success, i.e. if there is no other layer named \a name and \a otherLayer is a + valid layer inside this QCustomPlot. + + If \a otherLayer is 0, the highest layer in the QCustomPlot will be used. + + For an explanation of what layers are in QCustomPlot, see the documentation of \ref QCPLayer. + + \see layer, moveLayer, removeLayer +*/ +bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!otherLayer) + otherLayer = mLayers.last(); + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + if (layer(name)) + { + qDebug() << Q_FUNC_INFO << "A layer exists already with the name" << name; + return false; + } + + QCPLayer *newLayer = new QCPLayer(this, name); + mLayers.insert(otherLayer->index() + (insertMode==limAbove ? 1:0), newLayer); + updateLayerIndices(); + setupPaintBuffers(); // associates new layer with the appropriate paint buffer + return true; +} + +/*! + Removes the specified \a layer and returns true on success. + + All layerables (e.g. plottables and items) on the removed layer will be moved to the layer below + \a layer. If \a layer is the bottom layer, the layerables are moved to the layer above. In both + cases, the total rendering order of all layerables in the QCustomPlot is preserved. + + If \a layer is the current layer (\ref setCurrentLayer), the layer below (or above, if bottom + layer) becomes the new current layer. + + It is not possible to remove the last layer of the plot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::removeLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (mLayers.size() < 2) + { + qDebug() << Q_FUNC_INFO << "can't remove last layer"; + return false; + } + + // append all children of this layer to layer below (if this is lowest layer, prepend to layer above) + int removedIndex = layer->index(); + bool isFirstLayer = removedIndex==0; + QCPLayer *targetLayer = isFirstLayer ? mLayers.at(removedIndex+1) : mLayers.at(removedIndex-1); + QList children = layer->children(); + if (isFirstLayer) // prepend in reverse order (so order relative to each other stays the same) + { + for (int i=children.size()-1; i>=0; --i) + children.at(i)->moveToLayer(targetLayer, true); + } else // append normally + { + for (int i=0; imoveToLayer(targetLayer, false); + } + // if removed layer is current layer, change current layer to layer below/above: + if (layer == mCurrentLayer) + setCurrentLayer(targetLayer); + // invalidate the paint buffer that was responsible for this layer: + if (!layer->mPaintBuffer.isNull()) + layer->mPaintBuffer.data()->setInvalidated(); + // remove layer: + delete layer; + mLayers.removeOne(layer); + updateLayerIndices(); + return true; +} + +/*! + Moves the specified \a layer either above or below \a otherLayer. Whether it's placed above or + below is controlled with \a insertMode. + + Returns true on success, i.e. when both \a layer and \a otherLayer are valid layers in the + QCustomPlot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::moveLayer(QCPLayer *layer, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + + if (layer->index() > otherLayer->index()) + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 1:0)); + else if (layer->index() < otherLayer->index()) + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 0:-1)); + + // invalidate the paint buffers that are responsible for the layers: + if (!layer->mPaintBuffer.isNull()) + layer->mPaintBuffer.data()->setInvalidated(); + if (!otherLayer->mPaintBuffer.isNull()) + otherLayer->mPaintBuffer.data()->setInvalidated(); + + updateLayerIndices(); + return true; +} + +/*! + Returns the number of axis rects in the plot. + + All axis rects can be accessed via QCustomPlot::axisRect(). + + Initially, only one axis rect exists in the plot. + + \see axisRect, axisRects +*/ +int QCustomPlot::axisRectCount() const +{ + return axisRects().size(); +} + +/*! + Returns the axis rect with \a index. + + Initially, only one axis rect (with index 0) exists in the plot. If multiple axis rects were + added, all of them may be accessed with this function in a linear fashion (even when they are + nested in a layout hierarchy or inside other axis rects via QCPAxisRect::insetLayout). + + \see axisRectCount, axisRects +*/ +QCPAxisRect *QCustomPlot::axisRect(int index) const +{ + const QList rectList = axisRects(); + if (index >= 0 && index < rectList.size()) + { + return rectList.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "invalid axis rect index" << index; + return 0; + } +} + +/*! + Returns all axis rects in the plot. + + \see axisRectCount, axisRect +*/ +QList QCustomPlot::axisRects() const +{ + QList result; + QStack elementStack; + if (mPlotLayout) + elementStack.push(mPlotLayout); + + while (!elementStack.isEmpty()) + { + foreach (QCPLayoutElement *element, elementStack.pop()->elements(false)) + { + if (element) + { + elementStack.push(element); + if (QCPAxisRect *ar = qobject_cast(element)) + result.append(ar); + } + } + } + + return result; +} + +/*! + Returns the layout element at pixel position \a pos. If there is no element at that position, + returns 0. + + Only visible elements are used. If \ref QCPLayoutElement::setVisible on the element itself or on + any of its parent elements is set to false, it will not be considered. + + \see itemAt, plottableAt +*/ +QCPLayoutElement *QCustomPlot::layoutElementAt(const QPointF &pos) const +{ + QCPLayoutElement *currentElement = mPlotLayout; + bool searchSubElements = true; + while (searchSubElements && currentElement) + { + searchSubElements = false; + foreach (QCPLayoutElement *subElement, currentElement->elements(false)) + { + if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) + { + currentElement = subElement; + searchSubElements = true; + break; + } + } + } + return currentElement; +} + +/*! + Returns the layout element of type \ref QCPAxisRect at pixel position \a pos. This method ignores + other layout elements even if they are visually in front of the axis rect (e.g. a \ref + QCPLegend). If there is no axis rect at that position, returns 0. + + Only visible axis rects are used. If \ref QCPLayoutElement::setVisible on the axis rect itself or + on any of its parent elements is set to false, it will not be considered. + + \see layoutElementAt +*/ +QCPAxisRect *QCustomPlot::axisRectAt(const QPointF &pos) const +{ + QCPAxisRect *result = 0; + QCPLayoutElement *currentElement = mPlotLayout; + bool searchSubElements = true; + while (searchSubElements && currentElement) + { + searchSubElements = false; + foreach (QCPLayoutElement *subElement, currentElement->elements(false)) + { + if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) + { + currentElement = subElement; + searchSubElements = true; + if (QCPAxisRect *ar = qobject_cast(currentElement)) + result = ar; + break; + } + } + } + return result; +} + +/*! + Returns the axes that currently have selected parts, i.e. whose selection state is not \ref + QCPAxis::spNone. + + \see selectedPlottables, selectedLegends, setInteractions, QCPAxis::setSelectedParts, + QCPAxis::setSelectableParts +*/ +QList QCustomPlot::selectedAxes() const +{ + QList result, allAxes; + foreach (QCPAxisRect *rect, axisRects()) + allAxes << rect->axes(); + + foreach (QCPAxis *axis, allAxes) + { + if (axis->selectedParts() != QCPAxis::spNone) + result.append(axis); + } + + return result; +} + +/*! + Returns the legends that currently have selected parts, i.e. whose selection state is not \ref + QCPLegend::spNone. + + \see selectedPlottables, selectedAxes, setInteractions, QCPLegend::setSelectedParts, + QCPLegend::setSelectableParts, QCPLegend::selectedItems +*/ +QList QCustomPlot::selectedLegends() const +{ + QList result; + + QStack elementStack; + if (mPlotLayout) + elementStack.push(mPlotLayout); + + while (!elementStack.isEmpty()) + { + foreach (QCPLayoutElement *subElement, elementStack.pop()->elements(false)) + { + if (subElement) + { + elementStack.push(subElement); + if (QCPLegend *leg = qobject_cast(subElement)) + { + if (leg->selectedParts() != QCPLegend::spNone) + result.append(leg); + } + } + } + } + + return result; +} + +/*! + Deselects all layerables (plottables, items, axes, legends,...) of the QCustomPlot. + + Since calling this function is not a user interaction, this does not emit the \ref + selectionChangedByUser signal. The individual selectionChanged signals are emitted though, if the + objects were previously selected. + + \see setInteractions, selectedPlottables, selectedItems, selectedAxes, selectedLegends +*/ +void QCustomPlot::deselectAll() +{ + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + layerable->deselectEvent(0); + } +} + +/*! + Causes a complete replot into the internal paint buffer(s). Finally, the widget surface is + refreshed with the new buffer contents. This is the method that must be called to make changes to + the plot, e.g. on the axis ranges or data points of graphs, visible. + + The parameter \a refreshPriority can be used to fine-tune the timing of the replot. For example + if your application calls \ref replot very quickly in succession (e.g. multiple independent + functions change some aspects of the plot and each wants to make sure the change gets replotted), + it is advisable to set \a refreshPriority to \ref QCustomPlot::rpQueuedReplot. This way, the + actual replotting is deferred to the next event loop iteration. Multiple successive calls of \ref + replot with this priority will only cause a single replot, avoiding redundant replots and + improving performance. + + Under a few circumstances, QCustomPlot causes a replot by itself. Those are resize events of the + QCustomPlot widget and user interactions (object selection and range dragging/zooming). + + Before the replot happens, the signal \ref beforeReplot is emitted. After the replot, \ref + afterReplot is emitted. It is safe to mutually connect the replot slot with any of those two + signals on two QCustomPlots to make them replot synchronously, it won't cause an infinite + recursion. + + If a layer is in mode \ref QCPLayer::lmBuffered (\ref QCPLayer::setMode), it is also possible to + replot only that specific layer via \ref QCPLayer::replot. See the documentation there for + details. +*/ +void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) +{ + if (refreshPriority == QCustomPlot::rpQueuedReplot) + { + if (!mReplotQueued) + { + mReplotQueued = true; + QTimer::singleShot(0, this, SLOT(replot())); + } + return; + } + + if (mReplotting) // incase signals loop back to replot slot + return; + mReplotting = true; + mReplotQueued = false; + emit beforeReplot(); + + updateLayout(); + // draw all layered objects (grid, axes, plottables, items, legend,...) into their buffers: + setupPaintBuffers(); + foreach (QCPLayer *layer, mLayers) + layer->drawToPaintBuffer(); + for (int i=0; isetInvalidated(false); + + if ((refreshPriority == rpRefreshHint && mPlottingHints.testFlag(QCP::phImmediateRefresh)) || refreshPriority==rpImmediateRefresh) + repaint(); + else + update(); + + emit afterReplot(); + mReplotting = false; +} + +/*! + Rescales the axes such that all plottables (like graphs) in the plot are fully visible. + + if \a onlyVisiblePlottables is set to true, only the plottables that have their visibility set to true + (QCPLayerable::setVisible), will be used to rescale the axes. + + \see QCPAbstractPlottable::rescaleAxes, QCPAxis::rescale +*/ +void QCustomPlot::rescaleAxes(bool onlyVisiblePlottables) +{ + QList allAxes; + foreach (QCPAxisRect *rect, axisRects()) + allAxes << rect->axes(); + + foreach (QCPAxis *axis, allAxes) + axis->rescale(onlyVisiblePlottables); +} + +/*! + Saves a PDF with the vectorized plot to the file \a fileName. The axis ratio as well as the scale + of texts and lines will be derived from the specified \a width and \a height. This means, the + output will look like the normal on-screen output of a QCustomPlot widget with the corresponding + pixel width and height. If either \a width or \a height is zero, the exported image will have the + same dimensions as the QCustomPlot widget currently has. + + Setting \a exportPen to \ref QCP::epNoCosmetic allows to disable the use of cosmetic pens when + drawing to the PDF file. Cosmetic pens are pens with numerical width 0, which are always drawn as + a one pixel wide line, no matter what zoom factor is set in the PDF-Viewer. For more information + about cosmetic pens, see the QPainter and QPen documentation. + + The objects of the plot will appear in the current selection state. If you don't want any + selected objects to be painted in their selected look, deselect everything with \ref deselectAll + before calling this function. + + Returns true on success. + + \warning + \li If you plan on editing the exported PDF file with a vector graphics editor like Inkscape, it + is advised to set \a exportPen to \ref QCP::epNoCosmetic to avoid losing those cosmetic lines + (which might be quite many, because cosmetic pens are the default for e.g. axes and tick marks). + \li If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \a pdfCreator and \a pdfTitle may be used to set the according metadata fields in the resulting + PDF file. + + \note On Android systems, this method does nothing and issues an according qDebug warning + message. This is also the case if for other reasons the define flag \c QT_NO_PRINTER is set. + + \see savePng, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePdf(const QString &fileName, int width, int height, QCP::ExportPen exportPen, const QString &pdfCreator, const QString &pdfTitle) +{ + bool success = false; +#ifdef QT_NO_PRINTER + Q_UNUSED(fileName) + Q_UNUSED(exportPen) + Q_UNUSED(width) + Q_UNUSED(height) + Q_UNUSED(pdfCreator) + Q_UNUSED(pdfTitle) + qDebug() << Q_FUNC_INFO << "Qt was built without printer support (QT_NO_PRINTER). PDF not created."; +#else + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + QPrinter printer(QPrinter::ScreenResolution); + printer.setOutputFileName(fileName); + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setColorMode(QPrinter::Color); + printer.printEngine()->setProperty(QPrintEngine::PPK_Creator, pdfCreator); + printer.printEngine()->setProperty(QPrintEngine::PPK_DocumentName, pdfTitle); + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) + printer.setFullPage(true); + printer.setPaperSize(viewport().size(), QPrinter::DevicePixel); +#else + QPageLayout pageLayout; + pageLayout.setMode(QPageLayout::FullPageMode); + pageLayout.setOrientation(QPageLayout::Portrait); + pageLayout.setMargins(QMarginsF(0, 0, 0, 0)); + pageLayout.setPageSize(QPageSize(viewport().size(), QPageSize::Point, QString(), QPageSize::ExactMatch)); + printer.setPageLayout(pageLayout); +#endif + QCPPainter printpainter; + if (printpainter.begin(&printer)) + { + printpainter.setMode(QCPPainter::pmVectorized); + printpainter.setMode(QCPPainter::pmNoCaching); + printpainter.setMode(QCPPainter::pmNonCosmetic, exportPen==QCP::epNoCosmetic); + printpainter.setWindow(mViewport); + if (mBackgroundBrush.style() != Qt::NoBrush && + mBackgroundBrush.color() != Qt::white && + mBackgroundBrush.color() != Qt::transparent && + mBackgroundBrush.color().alpha() > 0) // draw pdf background color if not white/transparent + printpainter.fillRect(viewport(), mBackgroundBrush); + draw(&printpainter); + printpainter.end(); + success = true; + } + setViewport(oldViewport); +#endif // QT_NO_PRINTER + return success; +} + +/*! + Saves a PNG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + image compression can be controlled with the \a quality parameter which must be between 0 and 100 + or -1 to use the default setting. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the PNG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + If you want the PNG to have a transparent background, call \ref setBackground(const QBrush &brush) + with no brush (Qt::NoBrush) or a transparent color (Qt::transparent), before saving. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePng(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "PNG", quality, resolution, resolutionUnit); +} + +/*! + Saves a JPEG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + image compression can be controlled with the \a quality parameter which must be between 0 and 100 + or -1 to use the default setting. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the JPEG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, savePng, saveBmp, saveRastered +*/ +bool QCustomPlot::saveJpg(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "JPG", quality, resolution, resolutionUnit); +} + +/*! + Saves a BMP image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the BMP format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, savePng, saveJpg, saveRastered +*/ +bool QCustomPlot::saveBmp(const QString &fileName, int width, int height, double scale, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "BMP", -1, resolution, resolutionUnit); +} + +/*! \internal + + Returns a minimum size hint that corresponds to the minimum size of the top level layout + (\ref plotLayout). To prevent QCustomPlot from being collapsed to size/width zero, set a minimum + size (setMinimumSize) either on the whole QCustomPlot or on any layout elements inside the plot. + This is especially important, when placed in a QLayout where other components try to take in as + much space as possible (e.g. QMdiArea). +*/ +QSize QCustomPlot::minimumSizeHint() const +{ + return mPlotLayout->minimumOuterSizeHint(); +} + +/*! \internal + + Returns a size hint that is the same as \ref minimumSizeHint. + +*/ +QSize QCustomPlot::sizeHint() const +{ + return mPlotLayout->minimumOuterSizeHint(); +} + +/*! \internal + + Event handler for when the QCustomPlot widget needs repainting. This does not cause a \ref replot, but + draws the internal buffer on the widget surface. +*/ +void QCustomPlot::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + QCPPainter painter(this); + if (!painter.isActive()) + { + return; + } + painter.setRenderHint(QPainter::HighQualityAntialiasing); // to make Antialiasing look good if using the OpenGL graphicssystem + if (mBackgroundBrush.style() != Qt::NoBrush) + painter.fillRect(mViewport, mBackgroundBrush); + drawBackground(&painter); + for (int bufferIndex = 0; bufferIndex < mPaintBuffers.size(); ++bufferIndex) + mPaintBuffers.at(bufferIndex)->draw(&painter); + + if(!axisRect()->isScaleRight()) + { + //< 横坐标有效值 + int x = mSymbolPos.x() >= yAxis->axisRect()->left() ? mSymbolPos.x() : yAxis->axisRect()->left(); + x = x <= yAxis->axisRect()->right() ? x : yAxis->axisRect()->right(); + //< 纵坐标 + int y = yAxis->axisRect()->top(); + + painter.save(); + painter.setPen(QColor(182, 194, 205)); + painter.setBrush(QColor(182, 194, 205)); + painter.setAntialiasing(true); + QPolygon polygon; + polygon.append(QPoint(x, y)); + polygon.append(QPoint(x + 3, y - 5)); + polygon.append(QPoint(x + 3, 0)); + polygon.append(QPoint(x - 3, 0)); + polygon.append(QPoint(x - 3, y - 5)); + painter.drawPolygon(polygon); + painter.drawLine(QPoint(x, y), QPoint(x, yAxis->axisRect()->bottom())); + painter.restore(); + } +} + +/*! \internal + + Event handler for a resize of the QCustomPlot widget. The viewport (which becomes the outer rect + of mPlotLayout) is resized appropriately. Finally a \ref replot is performed. +*/ +void QCustomPlot::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + // resize and repaint the buffer: + setViewport(rect()); + replot(rpQueuedRefresh); // queued refresh is important here, to prevent painting issues in some contexts (e.g. MDI subwindow) +} + +/*! \internal + + Event handler for when a double click occurs. Emits the \ref mouseDoubleClick signal, then + determines the layerable under the cursor and forwards the event to it. Finally, emits the + specialized signals when certain objecs are clicked (e.g. \ref plottableDoubleClick, \ref + axisDoubleClick, etc.). + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) +{ + emit mouseDoubleClick(event); + mMouseHasMoved = false; + mMousePressPos = event->pos(); + + // determine layerable under the cursor (this event is called instead of the second press event in a double-click): + QList details; + QList candidates = layerableListAt(mMousePressPos, false, &details); + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list + candidates.at(i)->mouseDoubleClickEvent(event, details.at(i)); + if (event->isAccepted()) + { + mMouseEventLayerable = candidates.at(i); + mMouseEventLayerableDetails = details.at(i); + break; + } + } + + // emit specialized object double click signals: + if (!candidates.isEmpty()) + { + if (QCPAbstractPlottable *ap = qobject_cast(candidates.first())) + { + int dataIndex = 0; + if (!details.first().value().isEmpty()) + dataIndex = details.first().value().dataRange().begin(); + emit plottableDoubleClick(ap, dataIndex, event); + } else if (QCPAxis *ax = qobject_cast(candidates.first())) + emit axisDoubleClick(ax, details.first().value(), event); + else if (QCPAbstractItem *ai = qobject_cast(candidates.first())) + emit itemDoubleClick(ai, event); + else if (QCPLegend *lg = qobject_cast(candidates.first())) + emit legendDoubleClick(lg, 0, event); + else if (QCPAbstractLegendItem *li = qobject_cast(candidates.first())) + emit legendDoubleClick(li->parentLegend(), li, event); + } + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for when a mouse button is pressed. Emits the mousePress signal. + + If the current \ref setSelectionRectMode is not \ref QCP::srmNone, passes the event to the + selection rect. Otherwise determines the layerable under the cursor and forwards the event to it. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCustomPlot::mousePressEvent(QMouseEvent *event) +{ + if(cursor().shape() == Qt::SizeHorCursor && event->button() == Qt::LeftButton) + { + mSymbolPos = event->pos(); + mSymbolPressed = true; + return; + } + + emit mousePress(event); + // save some state to tell in releaseEvent whether it was a click: + + + mMouseHasMoved = false; + mMousePressPos = event->pos(); + + if (mSelectionRect && mSelectionRectMode != QCP::srmNone) + { + if (mSelectionRectMode != QCP::srmZoom || qobject_cast(axisRectAt(mMousePressPos))) // in zoom mode only activate selection rect if on an axis rect + mSelectionRect->startSelection(event); + } else + { + // no selection rect interaction, prepare for click signal emission and forward event to layerable under the cursor: + QList details; + QList candidates = layerableListAt(mMousePressPos, false, &details); + if (!candidates.isEmpty()) + { + mMouseSignalLayerable = candidates.first(); // candidate for signal emission is always topmost hit layerable (signal emitted in release event) + mMouseSignalLayerableDetails = details.first(); + } + // forward event to topmost candidate which accepts the event: + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events call ignore() on the event, in that case propagate to next candidate in list + candidates.at(i)->mousePressEvent(event, details.at(i)); + if (event->isAccepted()) + { + mMouseEventLayerable = candidates.at(i); + mMouseEventLayerableDetails = details.at(i); + break; + } + } + } + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. + update(); +} + +/*! \internal + + Event handler for when the cursor is moved. Emits the \ref mouseMove signal. + + If the selection rect (\ref setSelectionRect) is currently active, the event is forwarded to it + in order to update the rect geometry. + + Otherwise, if a layout element has mouse capture focus (a mousePressEvent happened on top of the + layout element before), the mouseMoveEvent is forwarded to that element. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseMoveEvent(QMouseEvent *event) +{ + //< time tip + if(!axisRect()->isScaleRight() && !mSymbolPressed && qAbs(mSymbolPos.x() - event->pos().x()) < 5) + { + if(event->pos().y() > yAxis->axisRect()->top()) + { + if(Qt::SizeHorCursor != cursor().shape()) + { + setCursor(QCursor(Qt::SizeHorCursor)); + } + } + static QString preTipsContent = QString(); + QString strTime = QDateTime::fromMSecsSinceEpoch(xAxis->pixelToCoord(mSymbolPos.x())).toString("yyyy-MM-dd hh:mm:ss zzz"); + if(preTipsContent == strTime && findChild("ToolTip")) + { + return; + } + preTipsContent = strTime; + QFontMetrics metrics(QToolTip::font()); + int pixelsWide = metrics.width(strTime); + int pixelsHigh = metrics.height(); + QPoint position = mapToGlobal(QPoint(event->pos().x() - (pixelsWide / 2), -(pixelsHigh / 2))); + CToolTip::popup(position, strTime, this); + return; + } + + if(mSymbolPressed && event->pos().x() >= yAxis->mAxisRect->left() &&event->pos().x() <= yAxis->mAxisRect->right()) + { + setCursor(QCursor(Qt::SizeHorCursor)); + mSymbolPos = event->pos(); + emit symbolPosChanged(xAxis->pixelToCoord(mSymbolPos.x())); + update(); + return; + } + setCursor(QCursor(Qt::ArrowCursor)); + + + emit mouseMove(event); + if (!mMouseHasMoved && (mMousePressPos-event->pos()).manhattanLength() > 3) + mMouseHasMoved = true; // moved too far from mouse press position, don't handle as click on mouse release + + if (mSelectionRect && mSelectionRect->isActive()) + mSelectionRect->moveSelection(event); + else if (mMouseEventLayerable) // call event of affected layerable: + mMouseEventLayerable->mouseMoveEvent(event, mMousePressPos); + + //< Extra By ZH + QList details; + QList candidates = layerableListAt(event->pos(), false, &details); + for (int i = 0; i < candidates.size(); ++i) + { + if(dynamic_cast(candidates.at(i))) + { + event->accept(); + candidates.at(i)->mouseMoveEvent(event, mMousePressPos); + } + } + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for when a mouse button is released. Emits the \ref mouseRelease signal. + + If the mouse was moved less than a certain threshold in any direction since the \ref + mousePressEvent, it is considered a click which causes the selection mechanism (if activated via + \ref setInteractions) to possibly change selection states accordingly. Further, specialized mouse + click signals are emitted (e.g. \ref plottableClick, \ref axisClick, etc.) + + If a layerable is the mouse capturer (a \ref mousePressEvent happened on top of the layerable + before), the \ref mouseReleaseEvent is forwarded to that element. + + \see mousePressEvent, mouseMoveEvent +*/ +void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) +{ + emit mouseRelease(event); + + mSymbolPressed = false; + if (!mMouseHasMoved) // mouse hasn't moved (much) between press and release, so handle as click + { + if (mSelectionRect && mSelectionRect->isActive()) // a simple click shouldn't successfully finish a selection rect, so cancel it here + mSelectionRect->cancel(); + if (event->button() == Qt::LeftButton) + processPointSelection(event); + + // emit specialized click signals of QCustomPlot instance: + if (QCPAbstractPlottable *ap = qobject_cast(mMouseSignalLayerable)) + { + int dataIndex = 0; + if (!mMouseSignalLayerableDetails.value().isEmpty()) + dataIndex = mMouseSignalLayerableDetails.value().dataRange().begin(); + emit plottableClick(ap, dataIndex, event); + } else if (QCPAxis *ax = qobject_cast(mMouseSignalLayerable)) + emit axisClick(ax, mMouseSignalLayerableDetails.value(), event); + else if (QCPAbstractItem *ai = qobject_cast(mMouseSignalLayerable)) + emit itemClick(ai, event); + else if (QCPLegend *lg = qobject_cast(mMouseSignalLayerable)) + emit legendClick(lg, 0, event); + else if (QCPAbstractLegendItem *li = qobject_cast(mMouseSignalLayerable)) + emit legendClick(li->parentLegend(), li, event); + mMouseSignalLayerable = 0; + } + + if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the selection rect is canceled there + { + // finish selection rect, the appropriate action will be taken via signal-slot connection: + mSelectionRect->endSelection(event); + } else + { + // call event of affected layerable: + if (mMouseEventLayerable) + { + mMouseEventLayerable->mouseReleaseEvent(event, mMousePressPos); + mMouseEventLayerable = 0; + } + } + + if (noAntialiasingOnDrag()) + replot(rpQueuedReplot); + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for mouse wheel events. First, the \ref mouseWheel signal is emitted. Then + determines the affected layerable and forwards the event to it. +*/ +void QCustomPlot::wheelEvent(QWheelEvent *event) +{ + QRect rt = axisRect()->mRect; + if(event->pos().x() < rt.left() || event->pos().x() > rt.right() || event->pos().y() < rt.top() || event->pos().y() > rt.bottom()) + { + return; + } + + emit mouseWheel(event); + // forward event to layerable under cursor: + QList candidates = layerableListAt(event->pos(), false); + + + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list + candidates.at(i)->wheelEvent(event); + if (event->isAccepted()) + break; + } + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +bool QCustomPlot::eventFilter(QObject *object, QEvent *event) +{ + QLabel * pLabel = dynamic_cast(object); + if (pLabel) + { + if(event->type() == QEvent::Wheel) + { + QWheelEvent * pWheelEvent = dynamic_cast(event); + QWheelEvent e(mapFromGlobal(pWheelEvent->globalPos()), + pWheelEvent->globalPos(), + pWheelEvent->pixelDelta(), + pWheelEvent->angleDelta(), + pWheelEvent->delta(), + pWheelEvent->orientation(), + pWheelEvent->buttons(), + pWheelEvent->modifiers()); + + wheelEvent(&e); + return true; + } + else if(event->type() == QEvent::MouseMove) + { + QMouseEvent *pMouseEvent = dynamic_cast(event); + QPoint pt = mapFromGlobal(pMouseEvent->globalPos()); + QMouseEvent e(pMouseEvent->type(), + pt, pt, + pMouseEvent->screenPos(), + pMouseEvent->button(), + pMouseEvent->buttons(), + pMouseEvent->modifiers(), + pMouseEvent->source()); + mouseMoveEvent(&e); + return true; + } + } + return QWidget::eventFilter(object, event); +} + +/*! \internal + + This function draws the entire plot, including background pixmap, with the specified \a painter. + It does not make use of the paint buffers like \ref replot, so this is the function typically + used by saving/exporting methods such as \ref savePdf or \ref toPainter. + + Note that it does not fill the background with the background brush (as the user may specify with + \ref setBackground(const QBrush &brush)), this is up to the respective functions calling this + method. +*/ +void QCustomPlot::draw(QCPPainter *painter) +{ + updateLayout(); + + // draw viewport background pixmap: + drawBackground(painter); + + // draw all layered objects (grid, axes, plottables, items, legend,...): + foreach (QCPLayer *layer, mLayers) + layer->draw(painter); + + /* Debug code to draw all layout element rects + foreach (QCPLayoutElement* el, findChildren()) + { + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(QColor(0, 0, 0, 100), 0, Qt::DashLine)); + painter->drawRect(el->rect()); + painter->setPen(QPen(QColor(255, 0, 0, 100), 0, Qt::DashLine)); + painter->drawRect(el->outerRect()); + } + */ +} + +/*! \internal + + Performs the layout update steps defined by \ref QCPLayoutElement::UpdatePhase, by calling \ref + QCPLayoutElement::update on the main plot layout. + + Here, the layout elements calculate their positions and margins, and prepare for the following + draw call. +*/ +void QCustomPlot::updateLayout() +{ + // run through layout phases: + mPlotLayout->update(QCPLayoutElement::upPreparation); + mPlotLayout->update(QCPLayoutElement::upMargins); + mPlotLayout->update(QCPLayoutElement::upLayout); +} + +/*! \internal + + Draws the viewport background pixmap of the plot. + + If a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the viewport with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was + set. + + Note that this function does not draw a fill with the background brush + (\ref setBackground(const QBrush &brush)) beneath the pixmap. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::drawBackground(QCPPainter *painter) +{ + // Note: background color is handled in individual replot/save functions + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mViewport.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mViewport.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mViewport.topLeft(), mScaledBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mViewport.topLeft(), mBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height())); + } + } +} + +/*! \internal + + Goes through the layers and makes sure this QCustomPlot instance holds the correct number of + paint buffers and that they have the correct configuration (size, pixel ratio, etc.). + Allocations, reallocations and deletions of paint buffers are performed as necessary. It also + associates the paint buffers with the layers, so they draw themselves into the right buffer when + \ref QCPLayer::drawToPaintBuffer is called. This means it associates adjacent \ref + QCPLayer::lmLogical layers to a mutual paint buffer and creates dedicated paint buffers for + layers in \ref QCPLayer::lmBuffered mode. + + This method uses \ref createPaintBuffer to create new paint buffers. + + After this method, the paint buffers are empty (filled with \c Qt::transparent) and invalidated + (so an attempt to replot only a single buffered layer causes a full replot). + + This method is called in every \ref replot call, prior to actually drawing the layers (into their + associated paint buffer). If the paint buffers don't need changing/reallocating, this method + basically leaves them alone and thus finishes very fast. +*/ +void QCustomPlot::setupPaintBuffers() +{ + int bufferIndex = 0; + if (mPaintBuffers.isEmpty()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + + for (int layerIndex = 0; layerIndex < mLayers.size(); ++layerIndex) + { + QCPLayer *layer = mLayers.at(layerIndex); + if (layer->mode() == QCPLayer::lmLogical) + { + layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); + } else if (layer->mode() == QCPLayer::lmBuffered) + { + ++bufferIndex; + if (bufferIndex >= mPaintBuffers.size()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); + if (layerIndex < mLayers.size()-1 && mLayers.at(layerIndex+1)->mode() == QCPLayer::lmLogical) // not last layer, and next one is logical, so prepare another buffer for next layerables + { + ++bufferIndex; + if (bufferIndex >= mPaintBuffers.size()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + } + } + } + // remove unneeded buffers: + while (mPaintBuffers.size()-1 > bufferIndex) + mPaintBuffers.removeLast(); + // resize buffers to viewport size and clear contents: + for (int i=0; isetSize(viewport().size()); // won't do anything if already correct size + mPaintBuffers.at(i)->clear(Qt::transparent); + mPaintBuffers.at(i)->setInvalidated(); + } +} + +/*! \internal + + This method is used by \ref setupPaintBuffers when it needs to create new paint buffers. + + Depending on the current setting of \ref setOpenGl, and the current Qt version, different + backends (subclasses of \ref QCPAbstractPaintBuffer) are created, initialized with the proper + size and device pixel ratio, and returned. +*/ +QCPAbstractPaintBuffer *QCustomPlot::createPaintBuffer() +{ + if (mOpenGl) + { +#if defined(QCP_OPENGL_FBO) + return new QCPPaintBufferGlFbo(viewport().size(), mBufferDevicePixelRatio, mGlContext, mGlPaintDevice); +#elif defined(QCP_OPENGL_PBUFFER) + return new QCPPaintBufferGlPbuffer(viewport().size(), mBufferDevicePixelRatio, mOpenGlMultisamples); +#else + qDebug() << Q_FUNC_INFO << "OpenGL enabled even though no support for it compiled in, this shouldn't have happened. Falling back to pixmap paint buffer."; + return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); +#endif + } else + return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); +} + +/*! + This method returns whether any of the paint buffers held by this QCustomPlot instance are + invalidated. + + If any buffer is invalidated, a partial replot (\ref QCPLayer::replot) is not allowed and always + causes a full replot (\ref QCustomPlot::replot) of all layers. This is the case when for example + the layer order has changed, new layers were added, layers were removed, or layer modes were + changed (\ref QCPLayer::setMode). + + \see QCPAbstractPaintBuffer::setInvalidated +*/ +bool QCustomPlot::hasInvalidatedPaintBuffers() +{ + for (int i=0; iinvalidated()) + return true; + } + return false; +} + +/*! \internal + + When \ref setOpenGl is set to true, this method is used to initialize OpenGL (create a context, + surface, paint device). + + Returns true on success. + + If this method is successful, all paint buffers should be deleted and then reallocated by calling + \ref setupPaintBuffers, so the OpenGL-based paint buffer subclasses (\ref + QCPPaintBufferGlPbuffer, \ref QCPPaintBufferGlFbo) are used for subsequent replots. + + \see freeOpenGl +*/ +bool QCustomPlot::setupOpenGl() +{ +#ifdef QCP_OPENGL_FBO + freeOpenGl(); + QSurfaceFormat proposedSurfaceFormat; + proposedSurfaceFormat.setSamples(mOpenGlMultisamples); +#ifdef QCP_OPENGL_OFFSCREENSURFACE + QOffscreenSurface *surface = new QOffscreenSurface; +#else + QWindow *surface = new QWindow; + surface->setSurfaceType(QSurface::OpenGLSurface); +#endif + surface->setFormat(proposedSurfaceFormat); + surface->create(); + mGlSurface = QSharedPointer(surface); + mGlContext = QSharedPointer(new QOpenGLContext); + mGlContext->setFormat(mGlSurface->format()); + if (!mGlContext->create()) + { + qDebug() << Q_FUNC_INFO << "Failed to create OpenGL context"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + if (!mGlContext->makeCurrent(mGlSurface.data())) // context needs to be current to create paint device + { + qDebug() << Q_FUNC_INFO << "Failed to make opengl context current"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) + { + qDebug() << Q_FUNC_INFO << "OpenGL of this system doesn't support frame buffer objects"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + mGlPaintDevice = QSharedPointer(new QOpenGLPaintDevice); + return true; +#elif defined(QCP_OPENGL_PBUFFER) + return QGLFormat::hasOpenGL(); +#else + return false; +#endif +} + +/*! \internal + + When \ref setOpenGl is set to false, this method is used to deinitialize OpenGL (releases the + context and frees resources). + + After OpenGL is disabled, all paint buffers should be deleted and then reallocated by calling + \ref setupPaintBuffers, so the standard software rendering paint buffer subclass (\ref + QCPPaintBufferPixmap) is used for subsequent replots. + + \see setupOpenGl +*/ +void QCustomPlot::freeOpenGl() +{ +#ifdef QCP_OPENGL_FBO + mGlPaintDevice.clear(); + mGlContext.clear(); + mGlSurface.clear(); +#endif +} + +/*! \internal + + This method is used by \ref QCPAxisRect::removeAxis to report removed axes to the QCustomPlot + so it may clear its QCustomPlot::xAxis, yAxis, xAxis2 and yAxis2 members accordingly. +*/ +void QCustomPlot::axisRemoved(QCPAxis *axis) +{ + if (xAxis == axis) + xAxis = 0; + if (xAxis2 == axis) + xAxis2 = 0; + if (yAxis == axis) + yAxis = 0; + if (yAxis2 == axis) + yAxis2 = 0; + + // Note: No need to take care of range drag axes and range zoom axes, because they are stored in smart pointers +} + +/*! \internal + + This method is used by the QCPLegend destructor to report legend removal to the QCustomPlot so + it may clear its QCustomPlot::legend member accordingly. +*/ +void QCustomPlot::legendRemoved(QCPLegend *legend) +{ + if (this->legend == legend) + this->legend = 0; +} + +/*! \internal + + This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref + setSelectionRectMode is set to \ref QCP::srmSelect. + + First, it determines which axis rect was the origin of the selection rect judging by the starting + point of the selection. Then it goes through the plottables (\ref QCPAbstractPlottable1D to be + precise) associated with that axis rect and finds the data points that are in \a rect. It does + this by querying their \ref QCPAbstractPlottable1D::selectTestRect method. + + Then, the actual selection is done by calling the plottables' \ref + QCPAbstractPlottable::selectEvent, placing the found selected data points in the \a details + parameter as QVariant(\ref QCPDataSelection). All plottables that weren't touched by \a + rect receive a \ref QCPAbstractPlottable::deselectEvent. + + \see processRectZoom +*/ +void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) +{ + bool selectionStateChanged = false; + + if (mInteractions.testFlag(QCP::iSelectPlottables)) + { + QMap > potentialSelections; // map key is number of selected data points, so we have selections sorted by size + QRectF rectF(rect.normalized()); + if (QCPAxisRect *affectedAxisRect = axisRectAt(rectF.topLeft())) + { + // determine plottables that were hit by the rect and thus are candidates for selection: + foreach (QCPAbstractPlottable *plottable, affectedAxisRect->plottables()) + { + if (QCPPlottableInterface1D *plottableInterface = plottable->interface1D()) + { + QCPDataSelection dataSel = plottableInterface->selectTestRect(rectF, true); + if (!dataSel.isEmpty()) + potentialSelections.insertMulti(dataSel.dataPointCount(), QPair(plottable, dataSel)); + } + } + + if (!mInteractions.testFlag(QCP::iMultiSelect)) + { + // only leave plottable with most selected points in map, since we will only select a single plottable: + if (!potentialSelections.isEmpty()) + { + QMap >::iterator it = potentialSelections.begin(); + while (it != potentialSelections.end()-1) // erase all except last element + it = potentialSelections.erase(it); + } + } + + bool additive = event->modifiers().testFlag(mMultiSelectModifier); + // deselect all other layerables if not additive selection: + if (!additive) + { + // emit deselection except to those plottables who will be selected afterwards: + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + { + if ((potentialSelections.isEmpty() || potentialSelections.constBegin()->first != layerable) && mInteractions.testFlag(layerable->selectionCategory())) + { + bool selChanged = false; + layerable->deselectEvent(&selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + + // go through selections in reverse (largest selection first) and emit select events: + QMap >::const_iterator it = potentialSelections.constEnd(); + while (it != potentialSelections.constBegin()) + { + --it; + if (mInteractions.testFlag(it.value().first->selectionCategory())) + { + bool selChanged = false; + it.value().first->selectEvent(event, additive, QVariant::fromValue(it.value().second), &selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + + if (selectionStateChanged) + { + emit selectionChangedByUser(); + replot(rpQueuedReplot); + } else if (mSelectionRect) + mSelectionRect->layer()->replot(); +} + +/*! \internal + + This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref + setSelectionRectMode is set to \ref QCP::srmZoom. + + It determines which axis rect was the origin of the selection rect judging by the starting point + of the selection, and then zooms the axes defined via \ref QCPAxisRect::setRangeZoomAxes to the + provided \a rect (see \ref QCPAxisRect::zoom). + + \see processRectSelection +*/ +void QCustomPlot::processRectZoom(QRect rect, QMouseEvent *event) +{ + Q_UNUSED(event) + if (QCPAxisRect *axisRect = axisRectAt(rect.topLeft())) + { + QList affectedAxes = QList() << axisRect->rangeZoomAxes(Qt::Horizontal) << axisRect->rangeZoomAxes(Qt::Vertical); + affectedAxes.removeAll(static_cast(0)); + axisRect->zoom(QRectF(rect), affectedAxes); + } + replot(rpQueuedReplot); // always replot to make selection rect disappear +} + +/*! \internal + + This method is called when a simple left mouse click was detected on the QCustomPlot surface. + + It first determines the layerable that was hit by the click, and then calls its \ref + QCPLayerable::selectEvent. All other layerables receive a QCPLayerable::deselectEvent (unless the + multi-select modifier was pressed, see \ref setMultiSelectModifier). + + In this method the hit layerable is determined a second time using \ref layerableAt (after the + one in \ref mousePressEvent), because we want \a onlySelectable set to true this time. This + implies that the mouse event grabber (mMouseEventLayerable) may be a different one from the + clicked layerable determined here. For example, if a non-selectable layerable is in front of a + selectable layerable at the click position, the front layerable will receive mouse events but the + selectable one in the back will receive the \ref QCPLayerable::selectEvent. + + \see processRectSelection, QCPLayerable::selectTest +*/ +void QCustomPlot::processPointSelection(QMouseEvent *event) +{ + QVariant details; + QCPLayerable *clickedLayerable = layerableAt(event->pos(), true, &details); + bool selectionStateChanged = false; + bool additive = mInteractions.testFlag(QCP::iMultiSelect) && event->modifiers().testFlag(mMultiSelectModifier); + // deselect all other layerables if not additive selection: + if (!additive) + { + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + { + if (layerable != clickedLayerable && mInteractions.testFlag(layerable->selectionCategory())) + { + bool selChanged = false; + layerable->deselectEvent(&selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + if (clickedLayerable && mInteractions.testFlag(clickedLayerable->selectionCategory())) + { + // a layerable was actually clicked, call its selectEvent: + bool selChanged = false; + clickedLayerable->selectEvent(event, additive, details, &selChanged); + selectionStateChanged |= selChanged; + } + if (selectionStateChanged) + { + emit selectionChangedByUser(); + replot(rpQueuedReplot); + } +} + +/*! \internal + + Registers the specified plottable with this QCustomPlot and, if \ref setAutoAddPlottableToLegend + is enabled, adds it to the legend (QCustomPlot::legend). QCustomPlot takes ownership of the + plottable. + + Returns true on success, i.e. when \a plottable isn't already in this plot and the parent plot of + \a plottable is this QCustomPlot. + + This method is called automatically in the QCPAbstractPlottable base class constructor. +*/ +bool QCustomPlot::registerPlottable(QCPAbstractPlottable *plottable) +{ + if (mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable already added to this QCustomPlot:" << reinterpret_cast(plottable); + return false; + } + if (plottable->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "plottable not created with this QCustomPlot as parent:" << reinterpret_cast(plottable); + return false; + } + + mPlottables.append(plottable); + // possibly add plottable to legend: + if (mAutoAddPlottableToLegend) + plottable->addToLegend(); + if (!plottable->layer()) // usually the layer is already set in the constructor of the plottable (via QCPLayerable constructor) + plottable->setLayer(currentLayer()); + return true; +} + +/*! \internal + + In order to maintain the simplified graph interface of QCustomPlot, this method is called by the + QCPGraph constructor to register itself with this QCustomPlot's internal graph list. Returns true + on success, i.e. if \a graph is valid and wasn't already registered with this QCustomPlot. + + This graph specific registration happens in addition to the call to \ref registerPlottable by the + QCPAbstractPlottable base class. +*/ +bool QCustomPlot::registerGraph(QCPGraph *graph) +{ + if (!graph) + { + qDebug() << Q_FUNC_INFO << "passed graph is zero"; + return false; + } + if (mGraphs.contains(graph)) + { + qDebug() << Q_FUNC_INFO << "graph already registered with this QCustomPlot"; + return false; + } + + mGraphs.append(graph); + return true; +} + + +/*! \internal + + Registers the specified item with this QCustomPlot. QCustomPlot takes ownership of the item. + + Returns true on success, i.e. when \a item wasn't already in the plot and the parent plot of \a + item is this QCustomPlot. + + This method is called automatically in the QCPAbstractItem base class constructor. +*/ +bool QCustomPlot::registerItem(QCPAbstractItem *item) +{ + if (mItems.contains(item)) + { + qDebug() << Q_FUNC_INFO << "item already added to this QCustomPlot:" << reinterpret_cast(item); + return false; + } + if (item->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "item not created with this QCustomPlot as parent:" << reinterpret_cast(item); + return false; + } + + mItems.append(item); + if (!item->layer()) // usually the layer is already set in the constructor of the item (via QCPLayerable constructor) + item->setLayer(currentLayer()); + return true; +} + +/*! \internal + + Assigns all layers their index (QCPLayer::mIndex) in the mLayers list. This method is thus called + after every operation that changes the layer indices, like layer removal, layer creation, layer + moving. +*/ +void QCustomPlot::updateLayerIndices() const +{ + for (int i=0; imIndex = i; +} + +/*! \internal + + Returns the top-most layerable at pixel position \a pos. If \a onlySelectable is set to true, + only those layerables that are selectable will be considered. (Layerable subclasses communicate + their selectability via the QCPLayerable::selectTest method, by returning -1.) + + \a selectionDetails is an output parameter that contains selection specifics of the affected + layerable. This is useful if the respective layerable shall be given a subsequent + QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains + information about which part of the layerable was hit, in multi-part layerables (e.g. + QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref + QCPDataSelection instance with the single data point which is closest to \a pos. + + \see layerableListAt, layoutElementAt, axisRectAt +*/ +QCPLayerable *QCustomPlot::layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails) const +{ + QList details; + QList candidates = layerableListAt(pos, onlySelectable, selectionDetails ? &details : 0); + if (selectionDetails && !details.isEmpty()) + *selectionDetails = details.first(); + if (!candidates.isEmpty()) + return candidates.first(); + else + return 0; +} + +/*! \internal + + Returns the layerables at pixel position \a pos. If \a onlySelectable is set to true, only those + layerables that are selectable will be considered. (Layerable subclasses communicate their + selectability via the QCPLayerable::selectTest method, by returning -1.) + + The returned list is sorted by the layerable/drawing order. If you only need to know the top-most + layerable, rather use \ref layerableAt. + + \a selectionDetails is an output parameter that contains selection specifics of the affected + layerable. This is useful if the respective layerable shall be given a subsequent + QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains + information about which part of the layerable was hit, in multi-part layerables (e.g. + QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref + QCPDataSelection instance with the single data point which is closest to \a pos. + + \see layerableAt, layoutElementAt, axisRectAt +*/ +QList QCustomPlot::layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails) const +{ + QList result; + for (int layerIndex=mLayers.size()-1; layerIndex>=0; --layerIndex) + { + const QList layerables = mLayers.at(layerIndex)->children(); + for (int i=layerables.size()-1; i>=0; --i) + { + if (!layerables.at(i)->realVisibility()) + continue; + QVariant details; + double dist = layerables.at(i)->selectTest(pos, onlySelectable, selectionDetails ? &details : 0); + if (dist >= 0 && dist < selectionTolerance()) + { + result.append(layerables.at(i)); + if (selectionDetails) + selectionDetails->append(details); + } + } + } + return result; +} + +/*! + Saves the plot to a rastered image file \a fileName in the image format \a format. The plot is + sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and scale 2.0 lead + to a full resolution file with width 200.) If the \a format supports compression, \a quality may + be between 0 and 100 to control it. + + Returns true on success. If this function fails, most likely the given \a format isn't supported + by the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The \a resolution will be written to the image file header (if the file format supports this) and + has no direct consequence for the quality or the pixel size. However, if opening the image with a + tool which respects the metadata, it will be able to scale the image to match either a given size + in real units of length (inch, centimeters, etc.), or the target display DPI. You can specify in + which units \a resolution is given, by setting \a resolutionUnit. The \a resolution is converted + to the format's expected resolution unit internally. + + \see saveBmp, saveJpg, savePng, savePdf +*/ +bool QCustomPlot::saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + QImage buffer = toPixmap(width, height, scale).toImage(); + + int dotsPerMeter = 0; + switch (resolutionUnit) + { + case QCP::ruDotsPerMeter: dotsPerMeter = resolution; break; + case QCP::ruDotsPerCentimeter: dotsPerMeter = resolution*100; break; + case QCP::ruDotsPerInch: dotsPerMeter = resolution/0.0254; break; + } + buffer.setDotsPerMeterX(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools + buffer.setDotsPerMeterY(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools + if (!buffer.isNull()) + return buffer.save(fileName, format, quality); + else + return false; +} + +/*! + Renders the plot to a pixmap and returns it. + + The plot is sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and + scale 2.0 lead to a full resolution pixmap with width 200.) + + \see toPainter, saveRastered, saveBmp, savePng, saveJpg, savePdf +*/ +QPixmap QCustomPlot::toPixmap(int width, int height, double scale) +{ + // this method is somewhat similar to toPainter. Change something here, and a change in toPainter might be necessary, too. + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + int scaledWidth = qRound(scale*newWidth); + int scaledHeight = qRound(scale*newHeight); + + QPixmap result(scaledWidth, scaledHeight); + result.fill(mBackgroundBrush.style() == Qt::SolidPattern ? mBackgroundBrush.color() : Qt::transparent); // if using non-solid pattern, make transparent now and draw brush pattern later + QCPPainter painter; + painter.begin(&result); + if (painter.isActive()) + { + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); + painter.setMode(QCPPainter::pmNoCaching); + if (!qFuzzyCompare(scale, 1.0)) + { + if (scale > 1.0) // for scale < 1 we always want cosmetic pens where possible, because else lines might disappear for very small scales + painter.setMode(QCPPainter::pmNonCosmetic); + painter.scale(scale, scale); + } + if (mBackgroundBrush.style() != Qt::SolidPattern && mBackgroundBrush.style() != Qt::NoBrush) // solid fills were done a few lines above with QPixmap::fill + painter.fillRect(mViewport, mBackgroundBrush); + draw(&painter); + setViewport(oldViewport); + painter.end(); + } else // might happen if pixmap has width or height zero + { + qDebug() << Q_FUNC_INFO << "Couldn't activate painter on pixmap"; + return QPixmap(); + } + return result; +} + +/*! + Renders the plot using the passed \a painter. + + The plot is sized to \a width and \a height in pixels. If the \a painter's scale is not 1.0, the resulting plot will + appear scaled accordingly. + + \note If you are restricted to using a QPainter (instead of QCPPainter), create a temporary QPicture and open a QCPPainter + on it. Then call \ref toPainter with this QCPPainter. After ending the paint operation on the picture, draw it with + the QPainter. This will reproduce the painter actions the QCPPainter took, with a QPainter. + + \see toPixmap +*/ +void QCustomPlot::toPainter(QCPPainter *painter, int width, int height) +{ + // this method is somewhat similar to toPixmap. Change something here, and a change in toPixmap might be necessary, too. + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + if (painter->isActive()) + { + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); + painter->setMode(QCPPainter::pmNoCaching); + if (mBackgroundBrush.style() != Qt::NoBrush) // unlike in toPixmap, we can't do QPixmap::fill for Qt::SolidPattern brush style, so we also draw solid fills with fillRect here + painter->fillRect(mViewport, mBackgroundBrush); + draw(painter); + setViewport(oldViewport); + } else + qDebug() << Q_FUNC_INFO << "Passed painter is not active"; +} +/* end of 'src/core.cpp' */ + +//amalgamation: add plottable1d.cpp + +/* including file 'src/colorgradient.cpp', size 24646 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorGradient +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorGradient + \brief Defines a color gradient for use with e.g. \ref QCPColorMap + + This class describes a color gradient which can be used to encode data with color. For example, + QCPColorMap and QCPColorScale have \ref QCPColorMap::setGradient "setGradient" methods which + take an instance of this class. Colors are set with \ref setColorStopAt(double position, const QColor &color) + with a \a position from 0 to 1. In between these defined color positions, the + color will be interpolated linearly either in RGB or HSV space, see \ref setColorInterpolation. + + Alternatively, load one of the preset color gradients shown in the image below, with \ref + loadPreset, or by directly specifying the preset in the constructor. + + Apart from red, green and blue components, the gradient also interpolates the alpha values of the + configured color stops. This allows to display some portions of the data range as transparent in + the plot. + + \image html QCPColorGradient.png + + The \ref QCPColorGradient(GradientPreset preset) constructor allows directly converting a \ref + GradientPreset to a QCPColorGradient. This means that you can directly pass \ref GradientPreset + to all the \a setGradient methods, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorgradient-setgradient + + The total number of levels used in the gradient can be set with \ref setLevelCount. Whether the + color gradient shall be applied periodically (wrapping around) to data values that lie outside + the data range specified on the plottable instance can be controlled with \ref setPeriodic. +*/ + +/*! + Constructs a new, empty QCPColorGradient with no predefined color stops. You can add own color + stops with \ref setColorStopAt. + + The color level count is initialized to 350. +*/ +QCPColorGradient::QCPColorGradient() : + mLevelCount(350), + mColorInterpolation(ciRGB), + mPeriodic(false), + mColorBufferInvalidated(true) +{ + mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); +} + +/*! + Constructs a new QCPColorGradient initialized with the colors and color interpolation according + to \a preset. + + The color level count is initialized to 350. +*/ +QCPColorGradient::QCPColorGradient(GradientPreset preset) : + mLevelCount(350), + mColorInterpolation(ciRGB), + mPeriodic(false), + mColorBufferInvalidated(true) +{ + mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); + loadPreset(preset); +} + +/* undocumented operator */ +bool QCPColorGradient::operator==(const QCPColorGradient &other) const +{ + return ((other.mLevelCount == this->mLevelCount) && + (other.mColorInterpolation == this->mColorInterpolation) && + (other.mPeriodic == this->mPeriodic) && + (other.mColorStops == this->mColorStops)); +} + +/*! + Sets the number of discretization levels of the color gradient to \a n. The default is 350 which + is typically enough to create a smooth appearance. The minimum number of levels is 2. + + \image html QCPColorGradient-levelcount.png +*/ +void QCPColorGradient::setLevelCount(int n) +{ + if (n < 2) + { + qDebug() << Q_FUNC_INFO << "n must be greater or equal 2 but was" << n; + n = 2; + } + if (n != mLevelCount) + { + mLevelCount = n; + mColorBufferInvalidated = true; + } +} + +/*! + Sets at which positions from 0 to 1 which color shall occur. The positions are the keys, the + colors are the values of the passed QMap \a colorStops. In between these color stops, the color + is interpolated according to \ref setColorInterpolation. + + A more convenient way to create a custom gradient may be to clear all color stops with \ref + clearColorStops (or creating a new, empty QCPColorGradient) and then adding them one by one with + \ref setColorStopAt. + + \see clearColorStops +*/ +void QCPColorGradient::setColorStops(const QMap &colorStops) +{ + mColorStops = colorStops; + mColorBufferInvalidated = true; +} + +/*! + Sets the \a color the gradient will have at the specified \a position (from 0 to 1). In between + these color stops, the color is interpolated according to \ref setColorInterpolation. + + \see setColorStops, clearColorStops +*/ +void QCPColorGradient::setColorStopAt(double position, const QColor &color) +{ + mColorStops.insert(position, color); + mColorBufferInvalidated = true; +} + +/*! + Sets whether the colors in between the configured color stops (see \ref setColorStopAt) shall be + interpolated linearly in RGB or in HSV color space. + + For example, a sweep in RGB space from red to green will have a muddy brown intermediate color, + whereas in HSV space the intermediate color is yellow. +*/ +void QCPColorGradient::setColorInterpolation(QCPColorGradient::ColorInterpolation interpolation) +{ + if (interpolation != mColorInterpolation) + { + mColorInterpolation = interpolation; + mColorBufferInvalidated = true; + } +} + +/*! + Sets whether data points that are outside the configured data range (e.g. \ref + QCPColorMap::setDataRange) are colored by periodically repeating the color gradient or whether + they all have the same color, corresponding to the respective gradient boundary color. + + \image html QCPColorGradient-periodic.png + + As shown in the image above, gradients that have the same start and end color are especially + suitable for a periodic gradient mapping, since they produce smooth color transitions throughout + the color map. A preset that has this property is \ref gpHues. + + In practice, using periodic color gradients makes sense when the data corresponds to a periodic + dimension, such as an angle or a phase. If this is not the case, the color encoding might become + ambiguous, because multiple different data values are shown as the same color. +*/ +void QCPColorGradient::setPeriodic(bool enabled) +{ + mPeriodic = enabled; +} + +/*! \overload + + This method is used to quickly convert a \a data array to colors. The colors will be output in + the array \a scanLine. Both \a data and \a scanLine must have the length \a n when passed to this + function. The data range that shall be used for mapping the data value to the gradient is passed + in \a range. \a logarithmic indicates whether the data values shall be mapped to colors + logarithmically. + + if \a data actually contains 2D-data linearized via [row*columnCount + column], you can + set \a dataIndexFactor to columnCount to convert a column instead of a row of the data + array, in \a scanLine. \a scanLine will remain a regular (1D) array. This works because \a data + is addressed data[i*dataIndexFactor]. + + Use the overloaded method to additionally provide alpha map data. + + The QRgb values that are placed in \a scanLine have their r, g and b components premultiplied + with alpha (see QImage::Format_ARGB32_Premultiplied). +*/ +void QCPColorGradient::colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) +{ + // If you change something here, make sure to also adapt color() and the other colorize() overload + if (!data) + { + qDebug() << Q_FUNC_INFO << "null pointer given as data"; + return; + } + if (!scanLine) + { + qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; + return; + } + if (mColorBufferInvalidated) + updateColorBuffer(); + + if (!logarithmic) + { + const double posToIndexFactor = (mLevelCount-1)/range.size(); + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + scanLine[i] = mColorBuffer.at(index); + } + } + } else // logarithmic == true + { + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + scanLine[i] = mColorBuffer.at(index); + } + } + } +} + +/*! \overload + + Additionally to the other overload of \ref colorize, this method takes the array \a alpha, which + has the same size and structure as \a data and encodes the alpha information per data point. + + The QRgb values that are placed in \a scanLine have their r, g and b components premultiplied + with alpha (see QImage::Format_ARGB32_Premultiplied). +*/ +void QCPColorGradient::colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) +{ + // If you change something here, make sure to also adapt color() and the other colorize() overload + if (!data) + { + qDebug() << Q_FUNC_INFO << "null pointer given as data"; + return; + } + if (!alpha) + { + qDebug() << Q_FUNC_INFO << "null pointer given as alpha"; + return; + } + if (!scanLine) + { + qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; + return; + } + if (mColorBufferInvalidated) + updateColorBuffer(); + + if (!logarithmic) + { + const double posToIndexFactor = (mLevelCount-1)/range.size(); + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + if (alpha[dataIndexFactor*i] == 255) + { + scanLine[i] = mColorBuffer.at(index); + } else + { + const QRgb rgb = mColorBuffer.at(index); + const float alphaF = alpha[dataIndexFactor*i]/255.0f; + scanLine[i] = qRgba(qRed(rgb)*alphaF, qGreen(rgb)*alphaF, qBlue(rgb)*alphaF, qAlpha(rgb)*alphaF); + } + } + } + } else // logarithmic == true + { + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + if (alpha[dataIndexFactor*i] == 255) + { + scanLine[i] = mColorBuffer.at(index); + } else + { + const QRgb rgb = mColorBuffer.at(index); + const float alphaF = alpha[dataIndexFactor*i]/255.0f; + scanLine[i] = qRgba(qRed(rgb)*alphaF, qGreen(rgb)*alphaF, qBlue(rgb)*alphaF, qAlpha(rgb)*alphaF); + } + } + } + } +} + +/*! \internal + + This method is used to colorize a single data value given in \a position, to colors. The data + range that shall be used for mapping the data value to the gradient is passed in \a range. \a + logarithmic indicates whether the data value shall be mapped to a color logarithmically. + + If an entire array of data values shall be converted, rather use \ref colorize, for better + performance. + + The returned QRgb has its r, g and b components premultiplied with alpha (see + QImage::Format_ARGB32_Premultiplied). +*/ +QRgb QCPColorGradient::color(double position, const QCPRange &range, bool logarithmic) +{ + // If you change something here, make sure to also adapt ::colorize() + if (mColorBufferInvalidated) + updateColorBuffer(); + int index = 0; + if (!logarithmic) + index = (position-range.lower)*(mLevelCount-1)/range.size(); + else + index = qLn(position/range.lower)/qLn(range.upper/range.lower)*(mLevelCount-1); + if (mPeriodic) + { + index = index % mLevelCount; + if (index < 0) + index += mLevelCount; + } else + { + if (index < 0) + index = 0; + else if (index >= mLevelCount) + index = mLevelCount-1; + } + return mColorBuffer.at(index); +} + +/*! + Clears the current color stops and loads the specified \a preset. A preset consists of predefined + color stops and the corresponding color interpolation method. + + The available presets are: + \image html QCPColorGradient.png +*/ +void QCPColorGradient::loadPreset(GradientPreset preset) +{ + clearColorStops(); + switch (preset) + { + case gpGrayscale: + setColorInterpolation(ciRGB); + setColorStopAt(0, Qt::black); + setColorStopAt(1, Qt::white); + break; + case gpHot: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(50, 0, 0)); + setColorStopAt(0.2, QColor(180, 10, 0)); + setColorStopAt(0.4, QColor(245, 50, 0)); + setColorStopAt(0.6, QColor(255, 150, 10)); + setColorStopAt(0.8, QColor(255, 255, 50)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpCold: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 50)); + setColorStopAt(0.2, QColor(0, 10, 180)); + setColorStopAt(0.4, QColor(0, 50, 245)); + setColorStopAt(0.6, QColor(10, 150, 255)); + setColorStopAt(0.8, QColor(50, 255, 255)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpNight: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(10, 20, 30)); + setColorStopAt(1, QColor(250, 255, 250)); + break; + case gpCandy: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(0, 0, 255)); + setColorStopAt(1, QColor(255, 250, 250)); + break; + case gpGeography: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(70, 170, 210)); + setColorStopAt(0.20, QColor(90, 160, 180)); + setColorStopAt(0.25, QColor(45, 130, 175)); + setColorStopAt(0.30, QColor(100, 140, 125)); + setColorStopAt(0.5, QColor(100, 140, 100)); + setColorStopAt(0.6, QColor(130, 145, 120)); + setColorStopAt(0.7, QColor(140, 130, 120)); + setColorStopAt(0.9, QColor(180, 190, 190)); + setColorStopAt(1, QColor(210, 210, 230)); + break; + case gpIon: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(50, 10, 10)); + setColorStopAt(0.45, QColor(0, 0, 255)); + setColorStopAt(0.8, QColor(0, 255, 255)); + setColorStopAt(1, QColor(0, 255, 0)); + break; + case gpThermal: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 50)); + setColorStopAt(0.15, QColor(20, 0, 120)); + setColorStopAt(0.33, QColor(200, 30, 140)); + setColorStopAt(0.6, QColor(255, 100, 0)); + setColorStopAt(0.85, QColor(255, 255, 40)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpPolar: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(50, 255, 255)); + setColorStopAt(0.18, QColor(10, 70, 255)); + setColorStopAt(0.28, QColor(10, 10, 190)); + setColorStopAt(0.5, QColor(0, 0, 0)); + setColorStopAt(0.72, QColor(190, 10, 10)); + setColorStopAt(0.82, QColor(255, 70, 10)); + setColorStopAt(1, QColor(255, 255, 50)); + break; + case gpSpectrum: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(50, 0, 50)); + setColorStopAt(0.15, QColor(0, 0, 255)); + setColorStopAt(0.35, QColor(0, 255, 255)); + setColorStopAt(0.6, QColor(255, 255, 0)); + setColorStopAt(0.75, QColor(255, 30, 0)); + setColorStopAt(1, QColor(50, 0, 0)); + break; + case gpJet: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 100)); + setColorStopAt(0.15, QColor(0, 50, 255)); + setColorStopAt(0.35, QColor(0, 255, 255)); + setColorStopAt(0.65, QColor(255, 255, 0)); + setColorStopAt(0.85, QColor(255, 30, 0)); + setColorStopAt(1, QColor(100, 0, 0)); + break; + case gpHues: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(255, 0, 0)); + setColorStopAt(1.0/3.0, QColor(0, 0, 255)); + setColorStopAt(2.0/3.0, QColor(0, 255, 0)); + setColorStopAt(1, QColor(255, 0, 0)); + break; + } +} + +/*! + Clears all color stops. + + \see setColorStops, setColorStopAt +*/ +void QCPColorGradient::clearColorStops() +{ + mColorStops.clear(); + mColorBufferInvalidated = true; +} + +/*! + Returns an inverted gradient. The inverted gradient has all properties as this \ref + QCPColorGradient, but the order of the color stops is inverted. + + \see setColorStops, setColorStopAt +*/ +QCPColorGradient QCPColorGradient::inverted() const +{ + QCPColorGradient result(*this); + result.clearColorStops(); + for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) + result.setColorStopAt(1.0-it.key(), it.value()); + return result; +} + +/*! \internal + + Returns true if the color gradient uses transparency, i.e. if any of the configured color stops + has an alpha value below 255. +*/ +bool QCPColorGradient::stopsUseAlpha() const +{ + for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) + { + if (it.value().alpha() < 255) + return true; + } + return false; +} + +/*! \internal + + Updates the internal color buffer which will be used by \ref colorize and \ref color, to quickly + convert positions to colors. This is where the interpolation between color stops is calculated. +*/ +void QCPColorGradient::updateColorBuffer() +{ + if (mColorBuffer.size() != mLevelCount) + mColorBuffer.resize(mLevelCount); + if (mColorStops.size() > 1) + { + double indexToPosFactor = 1.0/(double)(mLevelCount-1); + const bool useAlpha = stopsUseAlpha(); + for (int i=0; i::const_iterator it = mColorStops.lowerBound(position); + if (it == mColorStops.constEnd()) // position is on or after last stop, use color of last stop + { + mColorBuffer[i] = (it-1).value().rgba(); + } else if (it == mColorStops.constBegin()) // position is on or before first stop, use color of first stop + { + mColorBuffer[i] = it.value().rgba(); + } else // position is in between stops (or on an intermediate stop), interpolate color + { + QMap::const_iterator high = it; + QMap::const_iterator low = it-1; + double t = (position-low.key())/(high.key()-low.key()); // interpolation factor 0..1 + switch (mColorInterpolation) + { + case ciRGB: + { + if (useAlpha) + { + const int alpha = (1-t)*low.value().alpha() + t*high.value().alpha(); + const float alphaPremultiplier = alpha/255.0f; // since we use QImage::Format_ARGB32_Premultiplied + mColorBuffer[i] = qRgba(((1-t)*low.value().red() + t*high.value().red())*alphaPremultiplier, + ((1-t)*low.value().green() + t*high.value().green())*alphaPremultiplier, + ((1-t)*low.value().blue() + t*high.value().blue())*alphaPremultiplier, + alpha); + } else + { + mColorBuffer[i] = qRgb(((1-t)*low.value().red() + t*high.value().red()), + ((1-t)*low.value().green() + t*high.value().green()), + ((1-t)*low.value().blue() + t*high.value().blue())); + } + break; + } + case ciHSV: + { + QColor lowHsv = low.value().toHsv(); + QColor highHsv = high.value().toHsv(); + double hue = 0; + double hueDiff = highHsv.hueF()-lowHsv.hueF(); + if (hueDiff > 0.5) + hue = lowHsv.hueF() - t*(1.0-hueDiff); + else if (hueDiff < -0.5) + hue = lowHsv.hueF() + t*(1.0+hueDiff); + else + hue = lowHsv.hueF() + t*hueDiff; + if (hue < 0) hue += 1.0; + else if (hue >= 1.0) hue -= 1.0; + if (useAlpha) + { + const QRgb rgb = QColor::fromHsvF(hue, + (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), + (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); + const float alpha = (1-t)*lowHsv.alphaF() + t*highHsv.alphaF(); + mColorBuffer[i] = qRgba(qRed(rgb)*alpha, qGreen(rgb)*alpha, qBlue(rgb)*alpha, 255*alpha); + } + else + { + mColorBuffer[i] = QColor::fromHsvF(hue, + (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), + (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); + } + break; + } + } + } + } + } else if (mColorStops.size() == 1) + { + const QRgb rgb = mColorStops.constBegin().value().rgb(); + const float alpha = mColorStops.constBegin().value().alphaF(); + mColorBuffer.fill(qRgba(qRed(rgb)*alpha, qGreen(rgb)*alpha, qBlue(rgb)*alpha, 255*alpha)); + } else // mColorStops is empty, fill color buffer with black + { + mColorBuffer.fill(qRgb(0, 0, 0)); + } + mColorBufferInvalidated = false; +} +/* end of 'src/colorgradient.cpp' */ + + +/* including file 'src/selectiondecorator-bracket.cpp', size 12313 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPSelectionDecoratorBracket +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPSelectionDecoratorBracket + \brief A selection decorator which draws brackets around each selected data segment + + Additionally to the regular highlighting of selected segments via color, fill and scatter style, + this \ref QCPSelectionDecorator subclass draws markers at the begin and end of each selected data + segment of the plottable. + + The shape of the markers can be controlled with \ref setBracketStyle, \ref setBracketWidth and + \ref setBracketHeight. The color/fill can be controlled with \ref setBracketPen and \ref + setBracketBrush. + + To introduce custom bracket styles, it is only necessary to sublcass \ref + QCPSelectionDecoratorBracket and reimplement \ref drawBracket. The rest will be managed by the + base class. +*/ + +/*! + Creates a new QCPSelectionDecoratorBracket instance with default values. +*/ +QCPSelectionDecoratorBracket::QCPSelectionDecoratorBracket() : + mBracketPen(QPen(Qt::black)), + mBracketBrush(Qt::NoBrush), + mBracketWidth(5), + mBracketHeight(50), + mBracketStyle(bsSquareBracket), + mTangentToData(false), + mTangentAverage(2) +{ + +} + +QCPSelectionDecoratorBracket::~QCPSelectionDecoratorBracket() +{ +} + +/*! + Sets the pen that will be used to draw the brackets at the beginning and end of each selected + data segment. +*/ +void QCPSelectionDecoratorBracket::setBracketPen(const QPen &pen) +{ + mBracketPen = pen; +} + +/*! + Sets the brush that will be used to draw the brackets at the beginning and end of each selected + data segment. +*/ +void QCPSelectionDecoratorBracket::setBracketBrush(const QBrush &brush) +{ + mBracketBrush = brush; +} + +/*! + Sets the width of the drawn bracket. The width dimension is always parallel to the key axis of + the data, or the tangent direction of the current data slope, if \ref setTangentToData is + enabled. +*/ +void QCPSelectionDecoratorBracket::setBracketWidth(int width) +{ + mBracketWidth = width; +} + +/*! + Sets the height of the drawn bracket. The height dimension is always perpendicular to the key axis + of the data, or the tangent direction of the current data slope, if \ref setTangentToData is + enabled. +*/ +void QCPSelectionDecoratorBracket::setBracketHeight(int height) +{ + mBracketHeight = height; +} + +/*! + Sets the shape that the bracket/marker will have. + + \see setBracketWidth, setBracketHeight +*/ +void QCPSelectionDecoratorBracket::setBracketStyle(QCPSelectionDecoratorBracket::BracketStyle style) +{ + mBracketStyle = style; +} + +/*! + Sets whether the brackets will be rotated such that they align with the slope of the data at the + position that they appear in. + + For noisy data, it might be more visually appealing to average the slope over multiple data + points. This can be configured via \ref setTangentAverage. +*/ +void QCPSelectionDecoratorBracket::setTangentToData(bool enabled) +{ + mTangentToData = enabled; +} + +/*! + Controls over how many data points the slope shall be averaged, when brackets shall be aligned + with the data (if \ref setTangentToData is true). + + From the position of the bracket, \a pointCount points towards the selected data range will be + taken into account. The smallest value of \a pointCount is 1, which is effectively equivalent to + disabling \ref setTangentToData. +*/ +void QCPSelectionDecoratorBracket::setTangentAverage(int pointCount) +{ + mTangentAverage = pointCount; + if (mTangentAverage < 1) + mTangentAverage = 1; +} + +/*! + Draws the bracket shape with \a painter. The parameter \a direction is either -1 or 1 and + indicates whether the bracket shall point to the left or the right (i.e. is a closing or opening + bracket, respectively). + + The passed \a painter already contains all transformations that are necessary to position and + rotate the bracket appropriately. Painting operations can be performed as if drawing upright + brackets on flat data with horizontal key axis, with (0, 0) being the center of the bracket. + + If you wish to sublcass \ref QCPSelectionDecoratorBracket in order to provide custom bracket + shapes (see \ref QCPSelectionDecoratorBracket::bsUserStyle), this is the method you should + reimplement. +*/ +void QCPSelectionDecoratorBracket::drawBracket(QCPPainter *painter, int direction) const +{ + switch (mBracketStyle) + { + case bsSquareBracket: + { + painter->drawLine(QLineF(mBracketWidth*direction, -mBracketHeight*0.5, 0, -mBracketHeight*0.5)); + painter->drawLine(QLineF(mBracketWidth*direction, mBracketHeight*0.5, 0, mBracketHeight*0.5)); + painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); + break; + } + case bsHalfEllipse: + { + painter->drawArc(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight, -90*16, -180*16*direction); + break; + } + case bsEllipse: + { + painter->drawEllipse(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight); + break; + } + case bsPlus: + { + painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); + painter->drawLine(QLineF(-mBracketWidth*0.5, 0, mBracketWidth*0.5, 0)); + break; + } + default: + { + qDebug() << Q_FUNC_INFO << "unknown/custom bracket style can't be handeld by default implementation:" << static_cast(mBracketStyle); + break; + } + } +} + +/*! + Draws the bracket decoration on the data points at the begin and end of each selected data + segment given in \a seletion. + + It uses the method \ref drawBracket to actually draw the shapes. + + \seebaseclassmethod +*/ +void QCPSelectionDecoratorBracket::drawDecoration(QCPPainter *painter, QCPDataSelection selection) +{ + if (!mPlottable || selection.isEmpty()) return; + + if (QCPPlottableInterface1D *interface1d = mPlottable->interface1D()) + { + foreach (const QCPDataRange &dataRange, selection.dataRanges()) + { + // determine position and (if tangent mode is enabled) angle of brackets: + int openBracketDir = (mPlottable->keyAxis() && !mPlottable->keyAxis()->rangeReversed()) ? 1 : -1; + int closeBracketDir = -openBracketDir; + QPointF openBracketPos = getPixelCoordinates(interface1d, dataRange.begin()); + QPointF closeBracketPos = getPixelCoordinates(interface1d, dataRange.end()-1); + double openBracketAngle = 0; + double closeBracketAngle = 0; + if (mTangentToData) + { + openBracketAngle = getTangentAngle(interface1d, dataRange.begin(), openBracketDir); + closeBracketAngle = getTangentAngle(interface1d, dataRange.end()-1, closeBracketDir); + } + // draw opening bracket: + QTransform oldTransform = painter->transform(); + painter->setPen(mBracketPen); + painter->setBrush(mBracketBrush); + painter->translate(openBracketPos); + painter->rotate(openBracketAngle/M_PI*180.0); + drawBracket(painter, openBracketDir); + painter->setTransform(oldTransform); + // draw closing bracket: + painter->setPen(mBracketPen); + painter->setBrush(mBracketBrush); + painter->translate(closeBracketPos); + painter->rotate(closeBracketAngle/M_PI*180.0); + drawBracket(painter, closeBracketDir); + painter->setTransform(oldTransform); + } + } +} + +/*! \internal + + If \ref setTangentToData is enabled, brackets need to be rotated according to the data slope. + This method returns the angle in radians by which a bracket at the given \a dataIndex must be + rotated. + + The parameter \a direction must be set to either -1 or 1, representing whether it is an opening + or closing bracket. Since for slope calculation multiple data points are required, this defines + the direction in which the algorithm walks, starting at \a dataIndex, to average those data + points. (see \ref setTangentToData and \ref setTangentAverage) + + \a interface1d is the interface to the plottable's data which is used to query data coordinates. +*/ +double QCPSelectionDecoratorBracket::getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const +{ + if (!interface1d || dataIndex < 0 || dataIndex >= interface1d->dataCount()) + return 0; + direction = direction < 0 ? -1 : 1; // enforce direction is either -1 or 1 + + // how many steps we can actually go from index in the given direction without exceeding data bounds: + int averageCount; + if (direction < 0) + averageCount = qMin(mTangentAverage, dataIndex); + else + averageCount = qMin(mTangentAverage, interface1d->dataCount()-1-dataIndex); + qDebug() << averageCount; + // calculate point average of averageCount points: + QVector points(averageCount); + QPointF pointsAverage; + int currentIndex = dataIndex; + for (int i=0; ikeyAxis(); + QCPAxis *valueAxis = mPlottable->valueAxis(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(0, 0); } + + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex)), valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex))); + else + return QPointF(valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex)), keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex))); +} +/* end of 'src/selectiondecorator-bracket.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-axisrect.cpp', size 47584 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisRect +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxisRect + \brief Holds multiple axes and arranges them in a rectangular shape. + + This class represents an axis rect, a rectangular area that is bounded on all sides with an + arbitrary number of axes. + + Initially QCustomPlot has one axis rect, accessible via QCustomPlot::axisRect(). However, the + layout system allows to have multiple axis rects, e.g. arranged in a grid layout + (QCustomPlot::plotLayout). + + By default, QCPAxisRect comes with four axes, at bottom, top, left and right. They can be + accessed via \ref axis by providing the respective axis type (\ref QCPAxis::AxisType) and index. + If you need all axes in the axis rect, use \ref axes. The top and right axes are set to be + invisible initially (QCPAxis::setVisible). To add more axes to a side, use \ref addAxis or \ref + addAxes. To remove an axis, use \ref removeAxis. + + The axis rect layerable itself only draws a background pixmap or color, if specified (\ref + setBackground). It is placed on the "background" layer initially (see \ref QCPLayer for an + explanation of the QCustomPlot layer system). The axes that are held by the axis rect can be + placed on other layers, independently of the axis rect. + + Every axis rect has a child layout of type \ref QCPLayoutInset. It is accessible via \ref + insetLayout and can be used to have other layout elements (or even other layouts with multiple + elements) hovering inside the axis rect. + + If an axis rect is clicked and dragged, it processes this by moving certain axis ranges. The + behaviour can be controlled with \ref setRangeDrag and \ref setRangeDragAxes. If the mouse wheel + is scrolled while the cursor is on the axis rect, certain axes are scaled. This is controllable + via \ref setRangeZoom, \ref setRangeZoomAxes and \ref setRangeZoomFactor. These interactions are + only enabled if \ref QCustomPlot::setInteractions contains \ref QCP::iRangeDrag and \ref + QCP::iRangeZoom. + + \image html AxisRectSpacingOverview.png +
Overview of the spacings and paddings that define the geometry of an axis. The dashed + line on the far left indicates the viewport/widget border.
+*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayoutInset *QCPAxisRect::insetLayout() const + + Returns the inset layout of this axis rect. It can be used to place other layout elements (or + even layouts with multiple other elements) inside/on top of an axis rect. + + \see QCPLayoutInset +*/ + +/*! \fn int QCPAxisRect::left() const + + Returns the pixel position of the left border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::right() const + + Returns the pixel position of the right border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::top() const + + Returns the pixel position of the top border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::bottom() const + + Returns the pixel position of the bottom border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::width() const + + Returns the pixel width of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::height() const + + Returns the pixel height of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QSize QCPAxisRect::size() const + + Returns the pixel size of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::topLeft() const + + Returns the top left corner of this axis rect in pixels. Margins are not taken into account here, + so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::topRight() const + + Returns the top right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::bottomLeft() const + + Returns the bottom left corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::bottomRight() const + + Returns the bottom right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::center() const + + Returns the center of this axis rect in pixels. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a QCPAxisRect instance and sets default values. An axis is added for each of the four + sides, the top and right axes are set invisible initially. +*/ +QCPAxisRect::QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes) : + QCPLayoutElement(parentPlot), + mBackgroundBrush(Qt::NoBrush), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mInsetLayout(new QCPLayoutInset), + mRangeDrag(Qt::Horizontal|Qt::Vertical), + mRangeZoom(Qt::Horizontal|Qt::Vertical), + mRangeZoomFactorHorz(0.85), + mRangeZoomFactorVert(0.85), + mDragging(false), + mIsScaleRight(false) +{ + mInsetLayout->initializeParentPlot(mParentPlot); + mInsetLayout->setParentLayerable(this); + mInsetLayout->setParent(this); + + setMinimumSize(50, 50); + setMinimumMargins(QMargins(15, 15, 15, 15)); + mAxes.insert(QCPAxis::atLeft, QList()); + mAxes.insert(QCPAxis::atRight, QList()); + mAxes.insert(QCPAxis::atTop, QList()); + mAxes.insert(QCPAxis::atBottom, QList()); + + if (setupDefaultAxes) + { + QCPAxis *xAxis = addAxis(QCPAxis::atBottom); + QCPAxis *yAxis = addAxis(QCPAxis::atLeft); + QCPAxis *xAxis2 = addAxis(QCPAxis::atTop); + QCPAxis *yAxis2 = addAxis(QCPAxis::atRight); + setRangeDragAxes(xAxis, yAxis); + setRangeZoomAxes(xAxis, yAxis); + xAxis2->setVisible(false); + yAxis2->setVisible(false); + xAxis->grid()->setVisible(true); + yAxis->grid()->setVisible(true); + xAxis2->grid()->setVisible(false); + yAxis2->grid()->setVisible(false); + xAxis2->grid()->setZeroLinePen(Qt::NoPen); + yAxis2->grid()->setZeroLinePen(Qt::NoPen); + xAxis2->grid()->setVisible(false); + yAxis2->grid()->setVisible(false); + } +} + +QCPAxisRect::~QCPAxisRect() +{ + delete mInsetLayout; + mInsetLayout = 0; + + QList axesList = axes(); + for (int i=0; i ax(mAxes.value(type)); + if (index >= 0 && index < ax.size()) + { + return ax.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "Axis index out of bounds:" << index; + return 0; + } +} + +/*! + Returns all axes on the axis rect sides specified with \a types. + + \a types may be a single \ref QCPAxis::AxisType or an or-combination, to get the axes of + multiple sides. + + \see axis +*/ +QList QCPAxisRect::axes(QCPAxis::AxisTypes types) const +{ + QList result; + if (types.testFlag(QCPAxis::atLeft)) + result << mAxes.value(QCPAxis::atLeft); + if (types.testFlag(QCPAxis::atRight)) + result << mAxes.value(QCPAxis::atRight); + if (types.testFlag(QCPAxis::atTop)) + result << mAxes.value(QCPAxis::atTop); + if (types.testFlag(QCPAxis::atBottom)) + result << mAxes.value(QCPAxis::atBottom); + return result; +} + +/*! \overload + + Returns all axes of this axis rect. +*/ +QList QCPAxisRect::axes() const +{ + QList result; + QHashIterator > it(mAxes); + while (it.hasNext()) + { + it.next(); + result << it.value(); + } + return result; +} + +/*! + Adds a new axis to the axis rect side specified with \a type, and returns it. If \a axis is 0, a + new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to + remove an axis, use \ref removeAxis instead of deleting it manually. + + You may inject QCPAxis instances (or subclasses of QCPAxis) by setting \a axis to an axis that was + previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership + of the axis, so you may not delete it afterwards. Further, the \a axis must have been created + with this axis rect as parent and with the same axis type as specified in \a type. If this is not + the case, a debug output is generated, the axis is not added, and the method returns 0. + + This method can not be used to move \a axis between axis rects. The same \a axis instance must + not be added multiple times to the same or different axis rects. + + If an axis rect side already contains one or more axes, the lower and upper endings of the new + axis (\ref QCPAxis::setLowerEnding, \ref QCPAxis::setUpperEnding) are set to \ref + QCPLineEnding::esHalfBar. + + \see addAxes, setupFullAxesBox +*/ +QCPAxis *QCPAxisRect::addAxis(QCPAxis::AxisType type, QCPAxis *axis) +{ + QCPAxis *newAxis = axis; + if (!newAxis) + { + newAxis = new QCPAxis(this, type); + } else // user provided existing axis instance, do some sanity checks + { + if (newAxis->axisType() != type) + { + qDebug() << Q_FUNC_INFO << "passed axis has different axis type than specified in type parameter"; + return 0; + } + if (newAxis->axisRect() != this) + { + qDebug() << Q_FUNC_INFO << "passed axis doesn't have this axis rect as parent axis rect"; + return 0; + } + if (axes().contains(newAxis)) + { + qDebug() << Q_FUNC_INFO << "passed axis is already owned by this axis rect"; + return 0; + } + } + if (mAxes[type].size() > 0) // multiple axes on one side, add half-bar axis ending to additional axes with offset + { + bool invert = (type == QCPAxis::atRight) || (type == QCPAxis::atBottom); + newAxis->setLowerEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, !invert)); + newAxis->setUpperEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, invert)); + } + mAxes[type].append(newAxis); + + // reset convenience axis pointers on parent QCustomPlot if they are unset: + if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) + { + switch (type) + { + case QCPAxis::atBottom: { if (!mParentPlot->xAxis) mParentPlot->xAxis = newAxis; break; } + case QCPAxis::atLeft: { if (!mParentPlot->yAxis) mParentPlot->yAxis = newAxis; break; } + case QCPAxis::atTop: { if (!mParentPlot->xAxis2) mParentPlot->xAxis2 = newAxis; break; } + case QCPAxis::atRight: { if (!mParentPlot->yAxis2) mParentPlot->yAxis2 = newAxis; break; } + } + } + + return newAxis; +} + +/*! + Adds a new axis with \ref addAxis to each axis rect side specified in \a types. This may be an + or-combination of QCPAxis::AxisType, so axes can be added to multiple sides at once. + + Returns a list of the added axes. + + \see addAxis, setupFullAxesBox +*/ +QList QCPAxisRect::addAxes(QCPAxis::AxisTypes types) +{ + QList result; + if (types.testFlag(QCPAxis::atLeft)) + result << addAxis(QCPAxis::atLeft); + if (types.testFlag(QCPAxis::atRight)) + result << addAxis(QCPAxis::atRight); + if (types.testFlag(QCPAxis::atTop)) + result << addAxis(QCPAxis::atTop); + if (types.testFlag(QCPAxis::atBottom)) + result << addAxis(QCPAxis::atBottom); + return result; +} + +/*! + Removes the specified \a axis from the axis rect and deletes it. + + Returns true on success, i.e. if \a axis was a valid axis in this axis rect. + + \see addAxis +*/ +bool QCPAxisRect::removeAxis(QCPAxis *axis) +{ + // don't access axis->axisType() to provide safety when axis is an invalid pointer, rather go through all axis containers: + QHashIterator > it(mAxes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(axis)) + { + if (it.value().first() == axis && it.value().size() > 1) // if removing first axis, transfer axis offset to the new first axis (which at this point is the second axis, if it exists) + it.value()[1]->setOffset(axis->offset()); + mAxes[it.key()].removeOne(axis); + if (qobject_cast(parentPlot())) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the axis rect is not in any layout and thus QObject-child of QCustomPlot) + parentPlot()->axisRemoved(axis); + delete axis; + return true; + } + } + qDebug() << Q_FUNC_INFO << "Axis isn't in axis rect:" << reinterpret_cast(axis); + return false; +} + +/*! + Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. + + All axes of this axis rect will have their range zoomed accordingly. If you only wish to zoom + specific axes, use the overloaded version of this method. + + \see QCustomPlot::setSelectionRectMode +*/ +void QCPAxisRect::zoom(const QRectF &pixelRect) +{ + zoom(pixelRect, axes()); +} + +/*! \overload + + Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. + + Only the axes passed in \a affectedAxes will have their ranges zoomed accordingly. + + \see QCustomPlot::setSelectionRectMode +*/ +void QCPAxisRect::zoom(const QRectF &pixelRect, const QList &affectedAxes) +{ + foreach (QCPAxis *axis, affectedAxes) + { + if (!axis) + { + qDebug() << Q_FUNC_INFO << "a passed axis was zero"; + continue; + } + QCPRange pixelRange; + if (axis->orientation() == Qt::Horizontal) + pixelRange = QCPRange(pixelRect.left(), pixelRect.right()); + else + pixelRange = QCPRange(pixelRect.top(), pixelRect.bottom()); + axis->setRange(axis->pixelToCoord(pixelRange.lower), axis->pixelToCoord(pixelRange.upper)); + } +} + +/*! + Convenience function to create an axis on each side that doesn't have any axes yet and set their + visibility to true. Further, the top/right axes are assigned the following properties of the + bottom/left axes: + + \li range (\ref QCPAxis::setRange) + \li range reversed (\ref QCPAxis::setRangeReversed) + \li scale type (\ref QCPAxis::setScaleType) + \li tick visibility (\ref QCPAxis::setTicks) + \li number format (\ref QCPAxis::setNumberFormat) + \li number precision (\ref QCPAxis::setNumberPrecision) + \li tick count of ticker (\ref QCPAxisTicker::setTickCount) + \li tick origin of ticker (\ref QCPAxisTicker::setTickOrigin) + + Tick label visibility (\ref QCPAxis::setTickLabels) of the right and top axes are set to false. + + If \a connectRanges is true, the \ref QCPAxis::rangeChanged "rangeChanged" signals of the bottom + and left axes are connected to the \ref QCPAxis::setRange slots of the top and right axes. +*/ +void QCPAxisRect::setupFullAxesBox(bool connectRanges) +{ + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + if (axisCount(QCPAxis::atBottom) == 0) + xAxis = addAxis(QCPAxis::atBottom); + else + xAxis = axis(QCPAxis::atBottom); + + if (axisCount(QCPAxis::atLeft) == 0) + yAxis = addAxis(QCPAxis::atLeft); + else + yAxis = axis(QCPAxis::atLeft); + + if (axisCount(QCPAxis::atTop) == 0) + xAxis2 = addAxis(QCPAxis::atTop); + else + xAxis2 = axis(QCPAxis::atTop); + + if (axisCount(QCPAxis::atRight) == 0) + yAxis2 = addAxis(QCPAxis::atRight); + else + yAxis2 = axis(QCPAxis::atRight); + + xAxis->setVisible(true); + yAxis->setVisible(true); + xAxis2->setVisible(true); + yAxis2->setVisible(true); + xAxis2->setTickLabels(false); + yAxis2->setTickLabels(false); + + xAxis2->setRange(xAxis->range()); + xAxis2->setRangeReversed(xAxis->rangeReversed()); + xAxis2->setScaleType(xAxis->scaleType()); + xAxis2->setTicks(xAxis->ticks()); + xAxis2->setNumberFormat(xAxis->numberFormat()); + xAxis2->setNumberPrecision(xAxis->numberPrecision()); + xAxis2->ticker()->setTickCount(xAxis->ticker()->tickCount()); + xAxis2->ticker()->setTickOrigin(xAxis->ticker()->tickOrigin()); + + yAxis2->setRange(yAxis->range()); + yAxis2->setRangeReversed(yAxis->rangeReversed()); + yAxis2->setScaleType(yAxis->scaleType()); + yAxis2->setTicks(yAxis->ticks()); + yAxis2->setNumberFormat(yAxis->numberFormat()); + yAxis2->setNumberPrecision(yAxis->numberPrecision()); + yAxis2->ticker()->setTickCount(yAxis->ticker()->tickCount()); + yAxis2->ticker()->setTickOrigin(yAxis->ticker()->tickOrigin()); + + if (connectRanges) + { + connect(xAxis, SIGNAL(rangeChanged(QCPRange)), xAxis2, SLOT(setRange(QCPRange))); + connect(yAxis, SIGNAL(rangeChanged(QCPRange)), yAxis2, SLOT(setRange(QCPRange))); + } +} + +/*! + Returns a list of all the plottables that are associated with this axis rect. + + A plottable is considered associated with an axis rect if its key or value axis (or both) is in + this axis rect. + + \see graphs, items +*/ +QList QCPAxisRect::plottables() const +{ + // Note: don't append all QCPAxis::plottables() into a list, because we might get duplicate entries + QList result; + for (int i=0; imPlottables.size(); ++i) + { + if (mParentPlot->mPlottables.at(i)->keyAxis()->axisRect() == this || mParentPlot->mPlottables.at(i)->valueAxis()->axisRect() == this) + result.append(mParentPlot->mPlottables.at(i)); + } + return result; +} + +/*! + Returns a list of all the graphs that are associated with this axis rect. + + A graph is considered associated with an axis rect if its key or value axis (or both) is in + this axis rect. + + \see plottables, items +*/ +QList QCPAxisRect::graphs() const +{ + // Note: don't append all QCPAxis::graphs() into a list, because we might get duplicate entries + QList result; + for (int i=0; imGraphs.size(); ++i) + { + if (mParentPlot->mGraphs.at(i)->keyAxis()->axisRect() == this || mParentPlot->mGraphs.at(i)->valueAxis()->axisRect() == this) + result.append(mParentPlot->mGraphs.at(i)); + } + return result; +} + +/*! + Returns a list of all the items that are associated with this axis rect. + + An item is considered associated with an axis rect if any of its positions has key or value axis + set to an axis that is in this axis rect, or if any of its positions has \ref + QCPItemPosition::setAxisRect set to the axis rect, or if the clip axis rect (\ref + QCPAbstractItem::setClipAxisRect) is set to this axis rect. + + \see plottables, graphs +*/ +QList QCPAxisRect::items() const +{ + // Note: don't just append all QCPAxis::items() into a list, because we might get duplicate entries + // and miss those items that have this axis rect as clipAxisRect. + QList result; + for (int itemId=0; itemIdmItems.size(); ++itemId) + { + if (mParentPlot->mItems.at(itemId)->clipAxisRect() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + continue; + } + QList positions = mParentPlot->mItems.at(itemId)->positions(); + for (int posId=0; posIdaxisRect() == this || + positions.at(posId)->keyAxis()->axisRect() == this || + positions.at(posId)->valueAxis()->axisRect() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + break; + } + } + } + return result; +} + +/*! + This method is called automatically upon replot and doesn't need to be called by users of + QCPAxisRect. + + Calls the base class implementation to update the margins (see \ref QCPLayoutElement::update), + and finally passes the \ref rect to the inset layout (\ref insetLayout) and calls its + QCPInsetLayout::update function. + + \seebaseclassmethod +*/ +void QCPAxisRect::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + switch (phase) + { + case upPreparation: + { + QList allAxes = axes(); + for (int i=0; isetupTickVectors(); + break; + } + case upLayout: + { + mInsetLayout->setOuterRect(rect()); + break; + } + default: break; + } + + // pass update call on to inset layout (doesn't happen automatically, because QCPAxisRect doesn't derive from QCPLayout): + mInsetLayout->update(phase); +} + +/* inherits documentation from base class */ +QList QCPAxisRect::elements(bool recursive) const +{ + QList result; + if (mInsetLayout) + { + result << mInsetLayout; + if (recursive) + result << mInsetLayout->elements(recursive); + } + return result; +} + +/* inherits documentation from base class */ +void QCPAxisRect::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + painter->setAntialiasing(false); +} + +/* inherits documentation from base class */ +void QCPAxisRect::draw(QCPPainter *painter) +{ + drawBackground(painter); +} + +/*! + Sets \a pm as the axis background pixmap. The axis background pixmap will be drawn inside the + axis rect. Since axis rects place themselves on the "background" layer by default, the axis rect + backgrounds are usually drawn below everything else. + + For cases where the provided pixmap doesn't have the same size as the axis rect, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (i.e. whether and how the aspect ratio + is preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + Below the pixmap, the axis rect may be optionally filled with a brush, if specified with \ref + setBackground(const QBrush &brush). + + \see setBackgroundScaled, setBackgroundScaledMode, setBackground(const QBrush &brush) +*/ +void QCPAxisRect::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! \overload + + Sets \a brush as the background brush. The axis rect background will be filled with this brush. + Since axis rects place themselves on the "background" layer by default, the axis rect backgrounds + are usually drawn below everything else. + + The brush will be drawn before (under) any background pixmap, which may be specified with \ref + setBackground(const QPixmap &pm). + + To disable drawing of a background brush, set \a brush to Qt::NoBrush. + + \see setBackground(const QPixmap &pm) +*/ +void QCPAxisRect::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the axis rect, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPAxisRect::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the axis background pixmap shall be scaled to fit the axis rect or not. If \a scaled + is set to true, you may control whether and how the aspect ratio of the original pixmap is + preserved with \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the axis rect dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCPAxisRect::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the axis background pixmap is enabled (\ref setBackgroundScaled), use this function to + define whether and how the aspect ratio of the original pixmap passed to \ref setBackground is preserved. + \see setBackground, setBackgroundScaled +*/ +void QCPAxisRect::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +/*! + Returns the range drag axis of the \a orientation provided. If multiple axes were set, returns + the first one (use \ref rangeDragAxes to retrieve a list with all set axes). + + \see setRangeDragAxes +*/ +QCPAxis *QCPAxisRect::rangeDragAxis(Qt::Orientation orientation) +{ + if (orientation == Qt::Horizontal) + return mRangeDragHorzAxis.isEmpty() ? 0 : mRangeDragHorzAxis.first().data(); + else + return mRangeDragVertAxis.isEmpty() ? 0 : mRangeDragVertAxis.first().data(); +} + +/*! + Returns the range zoom axis of the \a orientation provided. If multiple axes were set, returns + the first one (use \ref rangeZoomAxes to retrieve a list with all set axes). + + \see setRangeZoomAxes +*/ +QCPAxis *QCPAxisRect::rangeZoomAxis(Qt::Orientation orientation) +{ + if (orientation == Qt::Horizontal) + return mRangeZoomHorzAxis.isEmpty() ? 0 : mRangeZoomHorzAxis.first().data(); + else + return mRangeZoomVertAxis.isEmpty() ? 0 : mRangeZoomVertAxis.first().data(); +} + +/*! + Returns all range drag axes of the \a orientation provided. + + \see rangeZoomAxis, setRangeZoomAxes +*/ +QList QCPAxisRect::rangeDragAxes(Qt::Orientation orientation) +{ + QList result; + if (orientation == Qt::Horizontal) + { + for (int i=0; i QCPAxisRect::rangeZoomAxes(Qt::Orientation orientation) +{ + QList result; + if (orientation == Qt::Horizontal) + { + for (int i=0; iQt::Horizontal | + Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions + contains \ref QCP::iRangeDrag to enable the range dragging interaction. + + \see setRangeZoom, setRangeDragAxes, QCustomPlot::setNoAntialiasingOnDrag +*/ +void QCPAxisRect::setRangeDrag(Qt::Orientations orientations) +{ + mRangeDrag = orientations; +} + +/*! + Sets which axis orientation may be zoomed by the user with the mouse wheel. What orientation + corresponds to which specific axis can be set with \ref setRangeZoomAxes(QCPAxis *horizontal, + QCPAxis *vertical). By default, the horizontal axis is the bottom axis (xAxis) and the vertical + axis is the left axis (yAxis). + + To disable range zooming entirely, pass 0 as \a orientations or remove \ref QCP::iRangeZoom from \ref + QCustomPlot::setInteractions. To enable range zooming for both directions, pass Qt::Horizontal | + Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions + contains \ref QCP::iRangeZoom to enable the range zooming interaction. + + \see setRangeZoomFactor, setRangeZoomAxes, setRangeDrag +*/ +void QCPAxisRect::setRangeZoom(Qt::Orientations orientations) +{ + mRangeZoom = orientations; +} + +/*! \overload + + Sets the axes whose range will be dragged when \ref setRangeDrag enables mouse range dragging on + the QCustomPlot widget. Pass 0 if no axis shall be dragged in the respective orientation. + + Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall + react to dragging interactions. + + \see setRangeZoomAxes +*/ +void QCPAxisRect::setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + QList horz, vert; + if (horizontal) + horz.append(horizontal); + if (vertical) + vert.append(vertical); + setRangeDragAxes(horz, vert); +} + +/*! \overload + + This method allows to set up multiple axes to react to horizontal and vertical dragging. The drag + orientation that the respective axis will react to is deduced from its orientation (\ref + QCPAxis::orientation). + + In the unusual case that you wish to e.g. drag a vertically oriented axis with a horizontal drag + motion, use the overload taking two separate lists for horizontal and vertical dragging. +*/ +void QCPAxisRect::setRangeDragAxes(QList axes) +{ + QList horz, vert; + foreach (QCPAxis *ax, axes) + { + if (ax->orientation() == Qt::Horizontal) + horz.append(ax); + else + vert.append(ax); + } + setRangeDragAxes(horz, vert); +} + +/*! \overload + + This method allows to set multiple axes up to react to horizontal and vertical dragging, and + define specifically which axis reacts to which drag orientation (irrespective of the axis + orientation). +*/ +void QCPAxisRect::setRangeDragAxes(QList horizontal, QList vertical) +{ + mRangeDragHorzAxis.clear(); + foreach (QCPAxis *ax, horizontal) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeDragHorzAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); + } + mRangeDragVertAxis.clear(); + foreach (QCPAxis *ax, vertical) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeDragVertAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); + } +} + +/*! + Sets the axes whose range will be zoomed when \ref setRangeZoom enables mouse wheel zooming on + the QCustomPlot widget. Pass 0 if no axis shall be zoomed in the respective orientation. + + The two axes can be zoomed with different strengths, when different factors are passed to \ref + setRangeZoomFactor(double horizontalFactor, double verticalFactor). + + Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall + react to zooming interactions. + + \see setRangeDragAxes +*/ +void QCPAxisRect::setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + QList horz, vert; + if (horizontal) + horz.append(horizontal); + if (vertical) + vert.append(vertical); + setRangeZoomAxes(horz, vert); +} + +/*! \overload + + This method allows to set up multiple axes to react to horizontal and vertical range zooming. The + zoom orientation that the respective axis will react to is deduced from its orientation (\ref + QCPAxis::orientation). + + In the unusual case that you wish to e.g. zoom a vertically oriented axis with a horizontal zoom + interaction, use the overload taking two separate lists for horizontal and vertical zooming. +*/ +void QCPAxisRect::setRangeZoomAxes(QList axes) +{ + QList horz, vert; + foreach (QCPAxis *ax, axes) + { + if (ax->orientation() == Qt::Horizontal) + horz.append(ax); + else + vert.append(ax); + } + setRangeZoomAxes(horz, vert); +} + +/*! \overload + + This method allows to set multiple axes up to react to horizontal and vertical zooming, and + define specifically which axis reacts to which zoom orientation (irrespective of the axis + orientation). +*/ +void QCPAxisRect::setRangeZoomAxes(QList horizontal, QList vertical) +{ + mRangeZoomHorzAxis.clear(); + foreach (QCPAxis *ax, horizontal) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeZoomHorzAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); + } + mRangeZoomVertAxis.clear(); + foreach (QCPAxis *ax, vertical) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeZoomVertAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); + } +} + +/*! + Sets how strong one rotation step of the mouse wheel zooms, when range zoom was activated with + \ref setRangeZoom. The two parameters \a horizontalFactor and \a verticalFactor provide a way to + let the horizontal axis zoom at different rates than the vertical axis. Which axis is horizontal + and which is vertical, can be set with \ref setRangeZoomAxes. + + When the zoom factor is greater than one, scrolling the mouse wheel backwards (towards the user) + will zoom in (make the currently visible range smaller). For zoom factors smaller than one, the + same scrolling direction will zoom out. +*/ +void QCPAxisRect::setRangeZoomFactor(double horizontalFactor, double verticalFactor) +{ + mRangeZoomFactorHorz = horizontalFactor; + mRangeZoomFactorVert = verticalFactor; +} + +/*! \overload + + Sets both the horizontal and vertical zoom \a factor. +*/ +void QCPAxisRect::setRangeZoomFactor(double factor) +{ + mRangeZoomFactorHorz = factor; + mRangeZoomFactorVert = factor; +} + +/*! \internal + + Draws the background of this axis rect. It may consist of a background fill (a QBrush) and a + pixmap. + + If a brush was given via \ref setBackground(const QBrush &brush), this function first draws an + according filling inside the axis rect with the provided \a painter. + + Then, if a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the axis rect with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was + set. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPAxisRect::drawBackground(QCPPainter *painter) +{ + // draw background fill: + if (mBackgroundBrush != Qt::NoBrush) + painter->fillRect(mRect, mBackgroundBrush); + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mRect.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mRect.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mScaledBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height())); + } + } +} + +/*! \internal + + This function makes sure multiple axes on the side specified with \a type don't collide, but are + distributed according to their respective space requirement (QCPAxis::calculateMargin). + + It does this by setting an appropriate offset (\ref QCPAxis::setOffset) on all axes except the + one with index zero. + + This function is called by \ref calculateAutoMargin. +*/ +void QCPAxisRect::updateAxesOffset(QCPAxis::AxisType type) +{ + const QList axesList = mAxes.value(type); + if (axesList.isEmpty()) + return; + + bool isFirstVisible = !axesList.first()->visible(); // if the first axis is visible, the second axis (which is where the loop starts) isn't the first visible axis, so initialize with false + for (int i=1; ioffset() + axesList.at(i-1)->calculateMargin(); + if (axesList.at(i)->visible()) // only add inner tick length to offset if this axis is visible and it's not the first visible one (might happen if true first axis is invisible) + { + if (!isFirstVisible) + offset += axesList.at(i)->tickLengthIn(); + isFirstVisible = false; + } + axesList.at(i)->setOffset(offset); + } +} + +/* inherits documentation from base class */ +int QCPAxisRect::calculateAutoMargin(QCP::MarginSide side) +{ + if (!mAutoMargins.testFlag(side)) + qDebug() << Q_FUNC_INFO << "Called with side that isn't specified as auto margin"; + + updateAxesOffset(QCPAxis::marginSideToAxisType(side)); + + // note: only need to look at the last (outer most) axis to determine the total margin, due to updateAxisOffset call + const QList axesList = mAxes.value(QCPAxis::marginSideToAxisType(side)); + if (axesList.size() > 0) + return axesList.last()->offset() + axesList.last()->calculateMargin(); + else + return 0; +} + +/*! \internal + + Reacts to a change in layout to potentially set the convenience axis pointers \ref + QCustomPlot::xAxis, \ref QCustomPlot::yAxis, etc. of the parent QCustomPlot to the respective + axes of this axis rect. This is only done if the respective convenience pointer is currently zero + and if there is no QCPAxisRect at position (0, 0) of the plot layout. + + This automation makes it simpler to replace the main axis rect with a newly created one, without + the need to manually reset the convenience pointers. +*/ +void QCPAxisRect::layoutChanged() +{ + if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) + { + if (axisCount(QCPAxis::atBottom) > 0 && !mParentPlot->xAxis) + mParentPlot->xAxis = axis(QCPAxis::atBottom); + if (axisCount(QCPAxis::atLeft) > 0 && !mParentPlot->yAxis) + mParentPlot->yAxis = axis(QCPAxis::atLeft); + if (axisCount(QCPAxis::atTop) > 0 && !mParentPlot->xAxis2) + mParentPlot->xAxis2 = axis(QCPAxis::atTop); + if (axisCount(QCPAxis::atRight) > 0 && !mParentPlot->yAxis2) + mParentPlot->yAxis2 = axis(QCPAxis::atRight); + } +} + +/*! \internal + + Event handler for when a mouse button is pressed on the axis rect. If the left mouse button is + pressed, the range dragging interaction is initialized (the actual range manipulation happens in + the \ref mouseMoveEvent). + + The mDragging flag is set to true and some anchor points are set that are needed to determine the + distance the mouse was dragged in the mouse move/release events later. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + if (event->buttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mParentPlot->noAntialiasingOnDrag()) + { + mAADragBackup = mParentPlot->antialiasedElements(); + mNotAADragBackup = mParentPlot->notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + mDragStartHorzRange.clear(); + for (int i=0; irange()); + mDragStartVertRange.clear(); + for (int i=0; irange()); + } + } +} + +/*! \internal + + Event handler for when the mouse is moved on the axis rect. If range dragging was activated in a + preceding \ref mousePressEvent, the range is moved accordingly. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + // Mouse range dragging interaction: + if (mDragging && mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + + if (mRangeDrag.testFlag(Qt::Horizontal)) + { + for (int i=0; i= mDragStartHorzRange.size()) + break; + + //< Drag + if (ax->mScaleType == QCPAxis::stLinear) + { + double diff = ax->pixelToCoord(startPos.x()) - ax->pixelToCoord(event->pos().x()); + ax->setRange(mDragStartHorzRange.at(i).lower+diff, mDragStartHorzRange.at(i).upper+diff); + + if(diff != 0) + { + mIsDragMove = true; + } + } + //< Scale + else if (ax->mScaleType == QCPAxis::stLogarithmic) + { + double diff = ax->pixelToCoord(startPos.x()) / ax->pixelToCoord(event->pos().x()); + ax->setRange(mDragStartHorzRange.at(i).lower*diff, mDragStartHorzRange.at(i).upper*diff); + if(diff != 0) + { + mIsDragMove = true; + } + } + } + } + + if (mRangeDrag.testFlag(Qt::Vertical)) + { + for (int i=0; i= mDragStartVertRange.size()) + break; + if (ax->mScaleType == QCPAxis::stLinear) + { + double diff = ax->pixelToCoord(startPos.y()) - ax->pixelToCoord(event->pos().y()); + ax->setRange(mDragStartVertRange.at(i).lower+diff, mDragStartVertRange.at(i).upper+diff); + } else if (ax->mScaleType == QCPAxis::stLogarithmic) + { + double diff = ax->pixelToCoord(startPos.y()) / ax->pixelToCoord(event->pos().y()); + ax->setRange(mDragStartVertRange.at(i).lower*diff, mDragStartVertRange.at(i).upper*diff); + } + } + } + + if (mRangeDrag != 0) // if either vertical or horizontal drag was enabled, do a replot + { + if (mParentPlot->noAntialiasingOnDrag()) + mParentPlot->setNotAntialiasedElements(QCP::aeAll); + mParentPlot->replot(QCustomPlot::rpQueuedReplot); + } + + } +} + +/* inherits documentation from base class */ +void QCPAxisRect::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(event) + Q_UNUSED(startPos) + + //< Note: update His Date + + if(mIsDragMove) + { + emit rangeDraged(); + mIsDragMove = false; + } + + mDragging = false; + if (mParentPlot->noAntialiasingOnDrag()) + { + mParentPlot->setAntialiasedElements(mAADragBackup); + mParentPlot->setNotAntialiasedElements(mNotAADragBackup); + } +} + +/*! \internal + + Event handler for mouse wheel events. If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the + ranges of the axes defined as rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of + the scaling operation is the current cursor position inside the axis rect. The scaling factor is + dependent on the mouse wheel delta (which direction the wheel was rotated) to provide a natural + zooming feel. The Strength of the zoom can be controlled via \ref setRangeZoomFactor. + + Note, that event->delta() is usually +/-120 for single rotation steps. However, if the mouse + wheel is turned rapidly, many steps may bunch up to one event, so the event->delta() may then be + multiples of 120. This is taken into account here, by calculating \a wheelSteps and using it as + exponent of the range zoom factor. This takes care of the wheel direction automatically, by + inverting the factor, when the wheel step is negative (f^-1 = 1/f). +*/ +void QCPAxisRect::wheelEvent(QWheelEvent *event) +{ + // Mouse range zooming interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeZoom)) + { + if (mRangeZoom != 0) + { + double factor; + double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually + if (mRangeZoom.testFlag(Qt::Horizontal)) + { + factor = qPow(mRangeZoomFactorHorz, wheelSteps); + for (int i=0; iscaleRange(factor,mRangeZoomHorzAxis.at(i)->range().upper); + } + else + { + mRangeZoomHorzAxis.at(i)->scaleRange(factor, mRangeZoomHorzAxis.at(i)->pixelToCoord(event->pos().x())); + } + emit rangeScaled(); + } + } + } + if (mRangeZoom.testFlag(Qt::Vertical)) + { + factor = qPow(mRangeZoomFactorVert, wheelSteps); + for (int i=0; iscaleRange(factor, mRangeZoomVertAxis.at(i)->pixelToCoord(event->pos().y())); + } + } + mParentPlot->replot(); + } + } +} +/* end of 'src/layoutelements/layoutelement-axisrect.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-legend.cpp', size 31097 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractLegendItem + \brief The abstract base class for all entries in a QCPLegend. + + It defines a very basic interface for entries in a QCPLegend. For representing plottables in the + legend, the subclass \ref QCPPlottableLegendItem is more suitable. + + Only derive directly from this class when you need absolute freedom (e.g. a custom legend entry + that's not even associated with a plottable). + + You must implement the following pure virtual functions: + \li \ref draw (from QCPLayerable) + + You inherit the following members you may use: + + + + + + + + +
QCPLegend *\b mParentLegendA pointer to the parent QCPLegend.
QFont \b mFontThe generic font of the item. You should use this font for all or at least the most prominent text of the item.
+*/ + +/* start of documentation of signals */ + +/*! \fn void QCPAbstractLegendItem::selectionChanged(bool selected) + + This signal is emitted when the selection state of this legend item has changed, either by user + interaction or by a direct call to \ref setSelected. +*/ + +/* end of documentation of signals */ + +/*! + Constructs a QCPAbstractLegendItem and associates it with the QCPLegend \a parent. This does not + cause the item to be added to \a parent, so \ref QCPLegend::addItem must be called separately. +*/ +QCPAbstractLegendItem::QCPAbstractLegendItem(QCPLegend *parent) : + QCPLayoutElement(parent->parentPlot()), + mParentLegend(parent), + mFont(parent->font()), + mTextColor(parent->textColor()), + mSelectedFont(parent->selectedFont()), + mSelectedTextColor(parent->selectedTextColor()), + mSelectable(true), + mSelected(false) +{ + setLayer(QLatin1String("legend")); + setMargins(QMargins(0, 0, 0, 0)); +} + +/*! + Sets the default font of this specific legend item to \a font. + + \see setTextColor, QCPLegend::setFont +*/ +void QCPAbstractLegendItem::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the default text color of this specific legend item to \a color. + + \see setFont, QCPLegend::setTextColor +*/ +void QCPAbstractLegendItem::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + When this legend item is selected, \a font is used to draw generic text, instead of the normal + font set with \ref setFont. + + \see setFont, QCPLegend::setSelectedFont +*/ +void QCPAbstractLegendItem::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + When this legend item is selected, \a color is used to draw generic text, instead of the normal + color set with \ref setTextColor. + + \see setTextColor, QCPLegend::setSelectedTextColor +*/ +void QCPAbstractLegendItem::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether this specific legend item is selectable. + + \see setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this specific legend item is selected. + + It is possible to set the selection state of this item by calling this function directly, even if + setSelectable is set to false. + + \see setSelectableParts, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/* inherits documentation from base class */ +double QCPAbstractLegendItem::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (!mParentPlot) return -1; + if (onlySelectable && (!mSelectable || !mParentLegend->selectableParts().testFlag(QCPLegend::spItems))) + return -1; + + if (mRect.contains(pos.toPoint())) + return mParentPlot->selectionTolerance()*0.99; + else + return -1; +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegendItems); +} + +/* inherits documentation from base class */ +QRect QCPAbstractLegendItem::clipRect() const +{ + return mOuterRect; +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPlottableLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPlottableLegendItem + \brief A legend item representing a plottable with an icon and the plottable name. + + This is the standard legend item for plottables. It displays an icon of the plottable next to the + plottable name. The icon is drawn by the respective plottable itself (\ref + QCPAbstractPlottable::drawLegendIcon), and tries to give an intuitive symbol for the plottable. + For example, the QCPGraph draws a centered horizontal line and/or a single scatter point in the + middle. + + Legend items of this type are always associated with one plottable (retrievable via the + plottable() function and settable with the constructor). You may change the font of the plottable + name with \ref setFont. Icon padding and border pen is taken from the parent QCPLegend, see \ref + QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding. + + The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend + creates/removes legend items of this type. + + Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of + QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout + interface, QCPLegend has specialized functions for handling legend items conveniently, see the + documentation of \ref QCPLegend. +*/ + +/*! + Creates a new legend item associated with \a plottable. + + Once it's created, it can be added to the legend via \ref QCPLegend::addItem. + + A more convenient way of adding/removing a plottable to/from the legend is via the functions \ref + QCPAbstractPlottable::addToLegend and \ref QCPAbstractPlottable::removeFromLegend. +*/ +QCPPlottableLegendItem::QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable) : + QCPAbstractLegendItem(parent), + mPlottable(plottable) +{ + setAntialiased(false); +} + +/*! \internal + + Returns the pen that shall be used to draw the icon border, taking into account the selection + state of this item. +*/ +QPen QCPPlottableLegendItem::getIconBorderPen() const +{ + return mSelected ? mParentLegend->selectedIconBorderPen() : mParentLegend->iconBorderPen(); +} + +/*! \internal + + Returns the text color that shall be used to draw text, taking into account the selection state + of this item. +*/ +QColor QCPPlottableLegendItem::getTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} + +/*! \internal + + Returns the font that shall be used to draw text, taking into account the selection state of this + item. +*/ +QFont QCPPlottableLegendItem::getFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Draws the item with \a painter. The size and position of the drawn legend item is defined by the + parent layout (typically a \ref QCPLegend) and the \ref minimumOuterSizeHint and \ref + maximumOuterSizeHint of this legend item. +*/ +void QCPPlottableLegendItem::draw(QCPPainter *painter) +{ + if (!mPlottable) return; + painter->setFont(getFont()); + painter->setPen(QPen(getTextColor())); + QSizeF iconSize = mParentLegend->iconSize(); + QRectF textRect = painter->fontMetrics().boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->desc()); + QRectF iconRect(mRect.topLeft(), iconSize); + int textHeight = qMax(textRect.height(), iconSize.height()); // if text has smaller height than icon, center text vertically in icon height, else align tops + painter->drawText(mRect.x()+iconSize.width()+mParentLegend->iconTextPadding(), mRect.y(), textRect.width(), textHeight, Qt::TextDontClip, mPlottable->desc()); + // draw icon: + painter->save(); + painter->setClipRect(iconRect, Qt::IntersectClip); + mPlottable->drawLegendIcon(painter, iconRect); + painter->restore(); + // draw icon border: + if (getIconBorderPen().style() != Qt::NoPen) + { + painter->setPen(getIconBorderPen()); + painter->setBrush(Qt::NoBrush); + int halfPen = qCeil(painter->pen().widthF()*0.5)+1; + painter->setClipRect(mOuterRect.adjusted(-halfPen, -halfPen, halfPen, halfPen)); // extend default clip rect so thicker pens (especially during selection) are not clipped + painter->drawRect(iconRect); + } +} + +/*! \internal + + Calculates and returns the size of this item. This includes the icon, the text and the padding in + between. + + \seebaseclassmethod +*/ +QSize QCPPlottableLegendItem::minimumOuterSizeHint() const +{ + if (!mPlottable) return QSize(); + QSize result(0, 0); + QRect textRect; + QFontMetrics fontMetrics(getFont()); + QSize iconSize = mParentLegend->iconSize(); + textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->desc()); + result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width()); + result.setHeight(qMax(textRect.height(), iconSize.height())); + result.rwidth() += mMargins.left()+mMargins.right(); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLegend +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLegend + \brief Manages a legend inside a QCustomPlot. + + A legend is a small box somewhere in the plot which lists plottables with their name and icon. + + A legend is populated with legend items by calling \ref QCPAbstractPlottable::addToLegend on the + plottable, for which a legend item shall be created. In the case of the main legend (\ref + QCustomPlot::legend), simply adding plottables to the plot while \ref + QCustomPlot::setAutoAddPlottableToLegend is set to true (the default) creates corresponding + legend items. The legend item associated with a certain plottable can be removed with \ref + QCPAbstractPlottable::removeFromLegend. However, QCPLegend also offers an interface to add and + manipulate legend items directly: \ref item, \ref itemWithPlottable, \ref itemCount, \ref + addItem, \ref removeItem, etc. + + Since \ref QCPLegend derives from \ref QCPLayoutGrid, it can be placed in any position a \ref + QCPLayoutElement may be positioned. The legend items are themselves \ref QCPLayoutElement + "QCPLayoutElements" which are placed in the grid layout of the legend. \ref QCPLegend only adds + an interface specialized for handling child elements of type \ref QCPAbstractLegendItem, as + mentioned above. In principle, any other layout elements may also be added to a legend via the + normal \ref QCPLayoutGrid interface. See the special page about \link thelayoutsystem The Layout + System\endlink for examples on how to add other elements to the legend and move it outside the axis + rect. + + Use the methods \ref setFillOrder and \ref setWrap inherited from \ref QCPLayoutGrid to control + in which order (column first or row first) the legend is filled up when calling \ref addItem, and + at which column or row wrapping occurs. + + By default, every QCustomPlot has one legend (\ref QCustomPlot::legend) which is placed in the + inset layout of the main axis rect (\ref QCPAxisRect::insetLayout). To move the legend to another + position inside the axis rect, use the methods of the \ref QCPLayoutInset. To move the legend + outside of the axis rect, place it anywhere else with the \ref QCPLayout/\ref QCPLayoutElement + interface. +*/ + +/* start of documentation of signals */ + +/*! \fn void QCPLegend::selectionChanged(QCPLegend::SelectableParts selection); + + This signal is emitted when the selection state of this legend has changed. + + \see setSelectedParts, setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs a new QCPLegend instance with default values. + + Note that by default, QCustomPlot already contains a legend ready to be used as \ref + QCustomPlot::legend +*/ +QCPLegend::QCPLegend() +{ + setFillOrder(QCPLayoutGrid::foRowsFirst); + setWrap(0); + + setRowSpacing(3); + setColumnSpacing(8); + setMargins(QMargins(7, 5, 7, 4)); + setAntialiased(false); + setIconSize(32, 18); + + setIconTextPadding(7); + + setSelectableParts(spLegendBox | spItems); + setSelectedParts(spNone); + + setBorderPen(QPen(Qt::black, 0)); + setSelectedBorderPen(QPen(Qt::blue, 2)); + setIconBorderPen(Qt::NoPen); + setSelectedIconBorderPen(QPen(Qt::blue, 2)); + setBrush(Qt::white); + setSelectedBrush(Qt::white); + setTextColor(Qt::black); + setSelectedTextColor(Qt::blue); +} + +QCPLegend::~QCPLegend() +{ + clearItems(); + if (qobject_cast(mParentPlot)) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the legend is not in any layout and thus QObject-child of QCustomPlot) + mParentPlot->legendRemoved(this); +} + +/* no doc for getter, see setSelectedParts */ +QCPLegend::SelectableParts QCPLegend::selectedParts() const +{ + // check whether any legend elements selected, if yes, add spItems to return value + bool hasSelectedItems = false; + for (int i=0; iselected()) + { + hasSelectedItems = true; + break; + } + } + if (hasSelectedItems) + return mSelectedParts | spItems; + else + return mSelectedParts & ~spItems; +} + +/*! + Sets the pen, the border of the entire legend is drawn with. +*/ +void QCPLegend::setBorderPen(const QPen &pen) +{ + mBorderPen = pen; +} + +/*! + Sets the brush of the legend background. +*/ +void QCPLegend::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the default font of legend text. Legend items that draw text (e.g. the name of a graph) will + use this font by default. However, a different font can be specified on a per-item-basis by + accessing the specific legend item. + + This function will also set \a font on all already existing legend items. + + \see QCPAbstractLegendItem::setFont +*/ +void QCPLegend::setFont(const QFont &font) +{ + mFont = font; + for (int i=0; isetFont(mFont); + } +} + +/*! + Sets the default color of legend text. Legend items that draw text (e.g. the name of a graph) + will use this color by default. However, a different colors can be specified on a per-item-basis + by accessing the specific legend item. + + This function will also set \a color on all already existing legend items. + + \see QCPAbstractLegendItem::setTextColor +*/ +void QCPLegend::setTextColor(const QColor &color) +{ + mTextColor = color; + for (int i=0; isetTextColor(color); + } +} + +/*! + Sets the size of legend icons. Legend items that draw an icon (e.g. a visual + representation of the graph) will use this size by default. +*/ +void QCPLegend::setIconSize(const QSize &size) +{ + mIconSize = size; +} + +/*! \overload +*/ +void QCPLegend::setIconSize(int width, int height) +{ + mIconSize.setWidth(width); + mIconSize.setHeight(height); +} + +/*! + Sets the horizontal space in pixels between the legend icon and the text next to it. + Legend items that draw an icon (e.g. a visual representation of the graph) and text (e.g. the + name of the graph) will use this space by default. +*/ +void QCPLegend::setIconTextPadding(int padding) +{ + mIconTextPadding = padding; +} + +/*! + Sets the pen used to draw a border around each legend icon. Legend items that draw an + icon (e.g. a visual representation of the graph) will use this pen by default. + + If no border is wanted, set this to \a Qt::NoPen. +*/ +void QCPLegend::setIconBorderPen(const QPen &pen) +{ + mIconBorderPen = pen; +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains \ref QCP::iSelectLegend.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPLegend::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective legend parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font and brush. If some legend items are selected and \a selected + doesn't contain \ref spItems, those items become deselected. + + The entire selection mechanism is handled automatically when \ref QCustomPlot::setInteractions + contains iSelectLegend. You only need to call this function when you wish to change the selection + state manually. + + This function can change the selection state of a part even when \ref setSelectableParts was set to a + value that actually excludes the part. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + Note that it doesn't make sense to set the selected state \ref spItems here when it wasn't set + before, because there's no way to specify which exact items to newly select. Do this by calling + \ref QCPAbstractLegendItem::setSelected directly on the legend item you wish to select. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush, + setSelectedFont +*/ +void QCPLegend::setSelectedParts(const SelectableParts &selected) +{ + SelectableParts newSelected = selected; + mSelectedParts = this->selectedParts(); // update mSelectedParts in case item selection changed + + if (mSelectedParts != newSelected) + { + if (!mSelectedParts.testFlag(spItems) && newSelected.testFlag(spItems)) // attempt to set spItems flag (can't do that) + { + qDebug() << Q_FUNC_INFO << "spItems flag can not be set, it can only be unset with this function"; + newSelected &= ~spItems; + } + if (mSelectedParts.testFlag(spItems) && !newSelected.testFlag(spItems)) // spItems flag was unset, so clear item selection + { + for (int i=0; isetSelected(false); + } + } + mSelectedParts = newSelected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + When the legend box is selected, this pen is used to draw the border instead of the normal pen + set via \ref setBorderPen. + + \see setSelectedParts, setSelectableParts, setSelectedBrush +*/ +void QCPLegend::setSelectedBorderPen(const QPen &pen) +{ + mSelectedBorderPen = pen; +} + +/*! + Sets the pen legend items will use to draw their icon borders, when they are selected. + + \see setSelectedParts, setSelectableParts, setSelectedFont +*/ +void QCPLegend::setSelectedIconBorderPen(const QPen &pen) +{ + mSelectedIconBorderPen = pen; +} + +/*! + When the legend box is selected, this brush is used to draw the legend background instead of the normal brush + set via \ref setBrush. + + \see setSelectedParts, setSelectableParts, setSelectedBorderPen +*/ +void QCPLegend::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the default font that is used by legend items when they are selected. + + This function will also set \a font on all already existing legend items. + + \see setFont, QCPAbstractLegendItem::setSelectedFont +*/ +void QCPLegend::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; + for (int i=0; isetSelectedFont(font); + } +} + +/*! + Sets the default text color that is used by legend items when they are selected. + + This function will also set \a color on all already existing legend items. + + \see setTextColor, QCPAbstractLegendItem::setSelectedTextColor +*/ +void QCPLegend::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; + for (int i=0; isetSelectedTextColor(color); + } +} + +/*! + Returns the item with index \a i. + + Note that the linear index depends on the current fill order (\ref setFillOrder). + + \see itemCount, addItem, itemWithPlottable +*/ +QCPAbstractLegendItem *QCPLegend::item(int index) const +{ + return qobject_cast(elementAt(index)); +} + +/*! + Returns the QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns 0. + + \see hasItemWithPlottable +*/ +QCPPlottableLegendItem *QCPLegend::itemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + for (int i=0; i(item(i))) + { + if (pli->plottable() == plottable) + return pli; + } + } + return 0; +} + +/*! + Returns the number of items currently in the legend. + + Note that if empty cells are in the legend (e.g. by calling methods of the \ref QCPLayoutGrid + base class which allows creating empty cells), they are included in the returned count. + + \see item +*/ +int QCPLegend::itemCount() const +{ + return elementCount(); +} + +/*! + Returns whether the legend contains \a item. + + \see hasItemWithPlottable +*/ +bool QCPLegend::hasItem(QCPAbstractLegendItem *item) const +{ + for (int i=0; iitem(i)) + return true; + } + return false; +} + +/*! + Returns whether the legend contains a QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns false. + + \see itemWithPlottable +*/ +bool QCPLegend::hasItemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + return itemWithPlottable(plottable); +} + +/*! + Adds \a item to the legend, if it's not present already. The element is arranged according to the + current fill order (\ref setFillOrder) and wrapping (\ref setWrap). + + Returns true on sucess, i.e. if the item wasn't in the list already and has been successfuly added. + + The legend takes ownership of the item. + + \see removeItem, item, hasItem +*/ +bool QCPLegend::addItem(QCPAbstractLegendItem *item) +{ + return addElement(item); +} + +/*! \overload + + Removes the item with the specified \a index from the legend and deletes it. + + After successful removal, the legend is reordered according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item + was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. + + Returns true, if successful. Unlike \ref QCPLayoutGrid::removeAt, this method only removes + elements derived from \ref QCPAbstractLegendItem. + + \see itemCount, clearItems +*/ +bool QCPLegend::removeItem(int index) +{ + if (QCPAbstractLegendItem *ali = item(index)) + { + bool success = remove(ali); + if (success) + setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering + return success; + } else + return false; +} + +/*! \overload + + Removes \a item from the legend and deletes it. + + After successful removal, the legend is reordered according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item + was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. + + Returns true, if successful. + + \see clearItems +*/ +bool QCPLegend::removeItem(QCPAbstractLegendItem *item) +{ + bool success = remove(item); + if (success) + setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering + return success; +} + +/*! + Removes all items from the legend. +*/ +void QCPLegend::clearItems() +{ + for (int i=itemCount()-1; i>=0; --i) + removeItem(i); +} + +/*! + Returns the legend items that are currently selected. If no items are selected, + the list is empty. + + \see QCPAbstractLegendItem::setSelected, setSelectable +*/ +QList QCPLegend::selectedItems() const +{ + QList result; + for (int i=0; iselected()) + result.append(ali); + } + } + return result; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing main legend elements. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased +*/ +void QCPLegend::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegend); +} + +/*! \internal + + Returns the pen used to paint the border of the legend, taking into account the selection state + of the legend box. +*/ +QPen QCPLegend::getBorderPen() const +{ + return mSelectedParts.testFlag(spLegendBox) ? mSelectedBorderPen : mBorderPen; +} + +/*! \internal + + Returns the brush used to paint the background of the legend, taking into account the selection + state of the legend box. +*/ +QBrush QCPLegend::getBrush() const +{ + return mSelectedParts.testFlag(spLegendBox) ? mSelectedBrush : mBrush; +} + +/*! \internal + + Draws the legend box with the provided \a painter. The individual legend items are layerables + themselves, thus are drawn independently. +*/ +void QCPLegend::draw(QCPPainter *painter) +{ + // draw background rect: + painter->setBrush(getBrush()); + painter->setPen(getBorderPen()); + painter->drawRect(mOuterRect); +} + +/* inherits documentation from base class */ +double QCPLegend::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + if (onlySelectable && !mSelectableParts.testFlag(spLegendBox)) + return -1; + + if (mOuterRect.contains(pos.toPoint())) + { + if (details) details->setValue(spLegendBox); + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/* inherits documentation from base class */ +void QCPLegend::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + mSelectedParts = selectedParts(); // in case item selection has changed + if (details.value() == spLegendBox && mSelectableParts.testFlag(spLegendBox)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^spLegendBox : mSelectedParts|spLegendBox); // no need to unset spItems in !additive case, because they will be deselected by QCustomPlot (they're normal QCPLayerables with own deselectEvent) + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPLegend::deselectEvent(bool *selectionStateChanged) +{ + mSelectedParts = selectedParts(); // in case item selection has changed + if (mSelectableParts.testFlag(spLegendBox)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(selectedParts() & ~spLegendBox); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPLegend::selectionCategory() const +{ + return QCP::iSelectLegend; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractLegendItem::selectionCategory() const +{ + return QCP::iSelectLegend; +} + +/* inherits documentation from base class */ +void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot) +{ + if (parentPlot && !parentPlot->legend) + parentPlot->legend = this; +} +/* end of 'src/layoutelements/layoutelement-legend.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-textelement.cpp', size 12761 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPTextElement +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPTextElement + \brief A layout element displaying a text + + The text may be specified with \ref setText, the formatting can be controlled with \ref setFont, + \ref setTextColor, and \ref setTextFlags. + + A text element can be added as follows: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcptextelement-creation +*/ + +/* start documentation of signals */ + +/*! \fn void QCPTextElement::selectionChanged(bool selected) + + This signal is emitted when the selection state has changed to \a selected, either by user + interaction or by a direct call to \ref setSelected. + + \see setSelected, setSelectable +*/ + +/*! \fn void QCPTextElement::clicked(QMouseEvent *event) + + This signal is emitted when the text element is clicked. + + \see doubleClicked, selectTest +*/ + +/*! \fn void QCPTextElement::doubleClicked(QMouseEvent *event) + + This signal is emitted when the text element is double clicked. + + \see clicked, selectTest +*/ + +/* end documentation of signals */ + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. The initial text is empty (\ref + setText). +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mText(), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mSelectedFont = parentPlot->font(); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mSelectedFont = parentPlot->font(); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with \a pointSize. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(QLatin1String("sans serif"), pointSize)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), pointSize)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mFont.setPointSizeF(pointSize); + mSelectedFont = parentPlot->font(); + mSelectedFont.setPointSizeF(pointSize); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with \a pointSize and the specified \a fontFamily. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(fontFamily, pointSize)), + mTextColor(Qt::black), + mSelectedFont(QFont(fontFamily, pointSize)), + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with the specified \a font. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(font), + mTextColor(Qt::black), + mSelectedFont(font), + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! + Sets the text that will be displayed to \a text. Multiple lines can be created by insertion of "\n". + + \see setFont, setTextColor, setTextFlags +*/ +void QCPTextElement::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets options for text alignment and wrapping behaviour. \a flags is a bitwise OR-combination of + \c Qt::AlignmentFlag and \c Qt::TextFlag enums. + + Possible enums are: + - Qt::AlignLeft + - Qt::AlignRight + - Qt::AlignHCenter + - Qt::AlignJustify + - Qt::AlignTop + - Qt::AlignBottom + - Qt::AlignVCenter + - Qt::AlignCenter + - Qt::TextDontClip + - Qt::TextSingleLine + - Qt::TextExpandTabs + - Qt::TextShowMnemonic + - Qt::TextWordWrap + - Qt::TextIncludeTrailingSpaces +*/ +void QCPTextElement::setTextFlags(int flags) +{ + mTextFlags = flags; +} + +/*! + Sets the \a font of the text. + + \see setTextColor, setSelectedFont +*/ +void QCPTextElement::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the \a color of the text. + + \see setFont, setSelectedTextColor +*/ +void QCPTextElement::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + Sets the \a font of the text that will be used if the text element is selected (\ref setSelected). + + \see setFont +*/ +void QCPTextElement::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the \a color of the text that will be used if the text element is selected (\ref setSelected). + + \see setTextColor +*/ +void QCPTextElement::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether the user may select this text element. + + Note that even when \a selectable is set to false, the selection state may be changed + programmatically via \ref setSelected. +*/ +void QCPTextElement::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets the selection state of this text element to \a selected. If the selection has changed, \ref + selectionChanged is emitted. + + Note that this function can change the selection state independently of the current \ref + setSelectable state. +*/ +void QCPTextElement::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/* inherits documentation from base class */ +void QCPTextElement::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); +} + +/* inherits documentation from base class */ +void QCPTextElement::draw(QCPPainter *painter) +{ + painter->setFont(mainFont()); + painter->setPen(QPen(mainTextColor())); + painter->drawText(mRect, Qt::AlignCenter, mText, &mTextBoundingRect); +} + +/* inherits documentation from base class */ +QSize QCPTextElement::minimumOuterSizeHint() const +{ + QFontMetrics metrics(mFont); + QSize result(metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size()); + result.rwidth() += mMargins.left()+mMargins.right(); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + +/* inherits documentation from base class */ +QSize QCPTextElement::maximumOuterSizeHint() const +{ + QFontMetrics metrics(mFont); + QSize result(metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size()); + result.setWidth(QWIDGETSIZE_MAX); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + +/* inherits documentation from base class */ +void QCPTextElement::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPTextElement::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/*! + Returns 0.99*selectionTolerance (see \ref QCustomPlot::setSelectionTolerance) when \a pos is + within the bounding box of the text element's text. Note that this bounding box is updated in the + draw call. + + If \a pos is outside the text's bounding box or if \a onlySelectable is true and this text + element is not selectable (\ref setSelectable), returns -1. + + \seebaseclassmethod +*/ +double QCPTextElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + if (mTextBoundingRect.contains(pos.toPoint())) + return mParentPlot->selectionTolerance()*0.99; + else + return -1; +} + +/*! + Accepts the mouse event in order to emit the according click signal in the \ref + mouseReleaseEvent. + + \seebaseclassmethod +*/ +void QCPTextElement::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->accept(); +} + +/*! + Emits the \ref clicked signal if the cursor hasn't moved by more than a few pixels since the \ref + mousePressEvent. + + \seebaseclassmethod +*/ +void QCPTextElement::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + if ((QPointF(event->pos())-startPos).manhattanLength() <= 3) + emit clicked(event); +} + +/*! + Emits the \ref doubleClicked signal. + + \seebaseclassmethod +*/ +void QCPTextElement::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + emit doubleClicked(event); +} + +/*! \internal + + Returns the main font to be used. This is mSelectedFont if \ref setSelected is set to + true, else mFont is returned. +*/ +QFont QCPTextElement::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the main color to be used. This is mSelectedTextColor if \ref setSelected is set to + true, else mTextColor is returned. +*/ +QColor QCPTextElement::mainTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} +/* end of 'src/layoutelements/layoutelement-textelement.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-colorscale.cpp', size 25770 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorScale +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorScale + \brief A color scale for use with color coding data such as QCPColorMap + + This layout element can be placed on the plot to correlate a color gradient with data values. It + is usually used in combination with one or multiple \ref QCPColorMap "QCPColorMaps". + + \image html QCPColorScale.png + + The color scale can be either horizontal or vertical, as shown in the image above. The + orientation and the side where the numbers appear is controlled with \ref setType. + + Use \ref QCPColorMap::setColorScale to connect a color map with a color scale. Once they are + connected, they share their gradient, data range and data scale type (\ref setGradient, \ref + setDataRange, \ref setDataScaleType). Multiple color maps may be associated with a single color + scale, to make them all synchronize these properties. + + To have finer control over the number display and axis behaviour, you can directly access the + \ref axis. See the documentation of QCPAxis for details about configuring axes. For example, if + you want to change the number of automatically generated ticks, call + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-tickcount + + Placing a color scale next to the main axis rect works like with any other layout element: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-creation + In this case we have placed it to the right of the default axis rect, so it wasn't necessary to + call \ref setType, since \ref QCPAxis::atRight is already the default. The text next to the color + scale can be set with \ref setLabel. + + For optimum appearance (like in the image above), it may be desirable to line up the axis rect and + the borders of the color scale. Use a \ref QCPMarginGroup to achieve this: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-margingroup + + Color scales are initialized with a non-zero minimum top and bottom margin (\ref + setMinimumMargins), because vertical color scales are most common and the minimum top/bottom + margin makes sure it keeps some distance to the top/bottom widget border. So if you change to a + horizontal color scale by setting \ref setType to \ref QCPAxis::atBottom or \ref QCPAxis::atTop, you + might want to also change the minimum margins accordingly, e.g. setMinimumMargins(QMargins(6, 0, 6, 0)). +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPAxis *QCPColorScale::axis() const + + Returns the internal \ref QCPAxis instance of this color scale. You can access it to alter the + appearance and behaviour of the axis. \ref QCPColorScale duplicates some properties in its + interface for convenience. Those are \ref setDataRange (\ref QCPAxis::setRange), \ref + setDataScaleType (\ref QCPAxis::setScaleType), and the method \ref setLabel (\ref + QCPAxis::setLabel). As they each are connected, it does not matter whether you use the method on + the QCPColorScale or on its QCPAxis. + + If the type of the color scale is changed with \ref setType, the axis returned by this method + will change, too, to either the left, right, bottom or top axis, depending on which type was set. +*/ + +/* end documentation of signals */ +/* start documentation of signals */ + +/*! \fn void QCPColorScale::dataRangeChanged(const QCPRange &newRange); + + This signal is emitted when the data range changes. + + \see setDataRange +*/ + +/*! \fn void QCPColorScale::dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + + This signal is emitted when the data scale type changes. + + \see setDataScaleType +*/ + +/*! \fn void QCPColorScale::gradientChanged(const QCPColorGradient &newGradient); + + This signal is emitted when the gradient changes. + + \see setGradient +*/ + +/* end documentation of signals */ + +/*! + Constructs a new QCPColorScale. +*/ +QCPColorScale::QCPColorScale(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mType(QCPAxis::atTop), // set to atTop such that setType(QCPAxis::atRight) below doesn't skip work because it thinks it's already atRight + mDataScaleType(QCPAxis::stLinear), + mBarWidth(20), + mAxisRect(new QCPColorScaleAxisRectPrivate(this)) +{ + setMinimumMargins(QMargins(0, 6, 0, 6)); // for default right color scale types, keep some room at bottom and top (important if no margin group is used) + setType(QCPAxis::atRight); + setDataRange(QCPRange(0, 6)); +} + +QCPColorScale::~QCPColorScale() +{ + delete mAxisRect; +} + +/* undocumented getter */ +QString QCPColorScale::label() const +{ + if (!mColorAxis) + { + qDebug() << Q_FUNC_INFO << "internal color axis undefined"; + return QString(); + } + + return mColorAxis.data()->label(); +} + +/* undocumented getter */ +bool QCPColorScale::rangeDrag() const +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return false; + } + + return mAxisRect.data()->rangeDrag().testFlag(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); +} + +/* undocumented getter */ +bool QCPColorScale::rangeZoom() const +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return false; + } + + return mAxisRect.data()->rangeZoom().testFlag(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); +} + +/*! + Sets at which side of the color scale the axis is placed, and thus also its orientation. + + Note that after setting \a type to a different value, the axis returned by \ref axis() will + be a different one. The new axis will adopt the following properties from the previous axis: The + range, scale type, label and ticker (the latter will be shared and not copied). +*/ +void QCPColorScale::setType(QCPAxis::AxisType type) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + if (mType != type) + { + mType = type; + QCPRange rangeTransfer(0, 6); + QString labelTransfer; + QSharedPointer tickerTransfer; + // transfer/revert some settings on old axis if it exists: + bool doTransfer = (bool)mColorAxis; + if (doTransfer) + { + rangeTransfer = mColorAxis.data()->range(); + labelTransfer = mColorAxis.data()->label(); + tickerTransfer = mColorAxis.data()->ticker(); + mColorAxis.data()->setLabel(QString()); + disconnect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + disconnect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } + QList allAxisTypes = QList() << QCPAxis::atLeft << QCPAxis::atRight << QCPAxis::atBottom << QCPAxis::atTop; + foreach (QCPAxis::AxisType atype, allAxisTypes) + { + mAxisRect.data()->axis(atype)->setTicks(atype == mType); + mAxisRect.data()->axis(atype)->setTickLabels(atype== mType); + } + // set new mColorAxis pointer: + mColorAxis = mAxisRect.data()->axis(mType); + // transfer settings to new axis: + if (doTransfer) + { + mColorAxis.data()->setRange(rangeTransfer); // range transfer necessary if axis changes from vertical to horizontal or vice versa (axes with same orientation are synchronized via signals) + mColorAxis.data()->setLabel(labelTransfer); + mColorAxis.data()->setTicker(tickerTransfer); + } + connect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + connect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + mAxisRect.data()->setRangeDragAxes(QList() << mColorAxis.data()); + } +} + +/*! + Sets the range spanned by the color gradient and that is shown by the axis in the color scale. + + It is equivalent to calling QCPColorMap::setDataRange on any of the connected color maps. It is + also equivalent to directly accessing the \ref axis and setting its range with \ref + QCPAxis::setRange. + + \see setDataScaleType, setGradient, rescaleDataRange +*/ +void QCPColorScale::setDataRange(const QCPRange &dataRange) +{ + if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) + { + mDataRange = dataRange; + if (mColorAxis) + mColorAxis.data()->setRange(mDataRange); + emit dataRangeChanged(mDataRange); + } +} + +/*! + Sets the scale type of the color scale, i.e. whether values are linearly associated with colors + or logarithmically. + + It is equivalent to calling QCPColorMap::setDataScaleType on any of the connected color maps. It is + also equivalent to directly accessing the \ref axis and setting its scale type with \ref + QCPAxis::setScaleType. + + \see setDataRange, setGradient +*/ +void QCPColorScale::setDataScaleType(QCPAxis::ScaleType scaleType) +{ + if (mDataScaleType != scaleType) + { + mDataScaleType = scaleType; + if (mColorAxis) + mColorAxis.data()->setScaleType(mDataScaleType); + if (mDataScaleType == QCPAxis::stLogarithmic) + setDataRange(mDataRange.sanitizedForLogScale()); + emit dataScaleTypeChanged(mDataScaleType); + } +} + +/*! + Sets the color gradient that will be used to represent data values. + + It is equivalent to calling QCPColorMap::setGradient on any of the connected color maps. + + \see setDataRange, setDataScaleType +*/ +void QCPColorScale::setGradient(const QCPColorGradient &gradient) +{ + if (mGradient != gradient) + { + mGradient = gradient; + if (mAxisRect) + mAxisRect.data()->mGradientImageInvalidated = true; + emit gradientChanged(mGradient); + } +} + +/*! + Sets the axis label of the color scale. This is equivalent to calling \ref QCPAxis::setLabel on + the internal \ref axis. +*/ +void QCPColorScale::setLabel(const QString &str) +{ + if (!mColorAxis) + { + qDebug() << Q_FUNC_INFO << "internal color axis undefined"; + return; + } + + mColorAxis.data()->setLabel(str); +} + +/*! + Sets the width (or height, for horizontal color scales) the bar where the gradient is displayed + will have. +*/ +void QCPColorScale::setBarWidth(int width) +{ + mBarWidth = width; +} + +/*! + Sets whether the user can drag the data range (\ref setDataRange). + + Note that \ref QCP::iRangeDrag must be in the QCustomPlot's interactions (\ref + QCustomPlot::setInteractions) to allow range dragging. +*/ +void QCPColorScale::setRangeDrag(bool enabled) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + if (enabled) + mAxisRect.data()->setRangeDrag(QCPAxis::orientation(mType)); + else + mAxisRect.data()->setRangeDrag(0); +} + +/*! + Sets whether the user can zoom the data range (\ref setDataRange) by scrolling the mouse wheel. + + Note that \ref QCP::iRangeZoom must be in the QCustomPlot's interactions (\ref + QCustomPlot::setInteractions) to allow range dragging. +*/ +void QCPColorScale::setRangeZoom(bool enabled) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + if (enabled) + mAxisRect.data()->setRangeZoom(QCPAxis::orientation(mType)); + else + mAxisRect.data()->setRangeZoom(0); +} + +/*! + Returns a list of all the color maps associated with this color scale. +*/ +QList QCPColorScale::colorMaps() const +{ + QList result; + for (int i=0; iplottableCount(); ++i) + { + if (QCPColorMap *cm = qobject_cast(mParentPlot->plottable(i))) + if (cm->colorScale() == this) + result.append(cm); + } + return result; +} + +/*! + Changes the data range such that all color maps associated with this color scale are fully mapped + to the gradient in the data dimension. + + \see setDataRange +*/ +void QCPColorScale::rescaleDataRange(bool onlyVisibleMaps) +{ + QList maps = colorMaps(); + QCPRange newRange; + bool haveRange = false; + QCP::SignDomain sign = QCP::sdBoth; + if (mDataScaleType == QCPAxis::stLogarithmic) + sign = (mDataRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); + for (int i=0; irealVisibility() && onlyVisibleMaps) + continue; + QCPRange mapRange; + if (maps.at(i)->colorScale() == this) + { + bool currentFoundRange = true; + mapRange = maps.at(i)->data()->dataBounds(); + if (sign == QCP::sdPositive) + { + if (mapRange.lower <= 0 && mapRange.upper > 0) + mapRange.lower = mapRange.upper*1e-3; + else if (mapRange.lower <= 0 && mapRange.upper <= 0) + currentFoundRange = false; + } else if (sign == QCP::sdNegative) + { + if (mapRange.upper >= 0 && mapRange.lower < 0) + mapRange.upper = mapRange.lower*1e-3; + else if (mapRange.upper >= 0 && mapRange.lower >= 0) + currentFoundRange = false; + } + if (currentFoundRange) + { + if (!haveRange) + newRange = mapRange; + else + newRange.expand(mapRange); + haveRange = true; + } + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this dimension), shift current range to at least center the data + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mDataScaleType == QCPAxis::stLinear) + { + newRange.lower = center-mDataRange.size()/2.0; + newRange.upper = center+mDataRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mDataRange.upper/mDataRange.lower); + newRange.upper = center*qSqrt(mDataRange.upper/mDataRange.lower); + } + } + setDataRange(newRange); + } +} + +/* inherits documentation from base class */ +void QCPColorScale::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + mAxisRect.data()->update(phase); + + switch (phase) + { + case upMargins: + { + if (mType == QCPAxis::atBottom || mType == QCPAxis::atTop) + { + setMaximumSize(QWIDGETSIZE_MAX, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()); + setMinimumSize(0, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()); + } else + { + setMaximumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), QWIDGETSIZE_MAX); + setMinimumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), 0); + } + break; + } + case upLayout: + { + mAxisRect.data()->setOuterRect(rect()); + break; + } + default: break; + } +} + +/* inherits documentation from base class */ +void QCPColorScale::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + painter->setAntialiasing(false); +} + +/* inherits documentation from base class */ +void QCPColorScale::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mousePressEvent(event, details); +} + +/* inherits documentation from base class */ +void QCPColorScale::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mouseMoveEvent(event, startPos); +} + +/* inherits documentation from base class */ +void QCPColorScale::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mouseReleaseEvent(event, startPos); +} + +/* inherits documentation from base class */ +void QCPColorScale::wheelEvent(QWheelEvent *event) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->wheelEvent(event); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorScaleAxisRectPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorScaleAxisRectPrivate + + \internal + \brief An axis rect subclass for use in a QCPColorScale + + This is a private class and not part of the public QCustomPlot interface. + + It provides the axis rect functionality for the QCPColorScale class. +*/ + + +/*! + Creates a new instance, as a child of \a parentColorScale. +*/ +QCPColorScaleAxisRectPrivate::QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale) : + QCPAxisRect(parentColorScale->parentPlot(), true), + mParentColorScale(parentColorScale), + mGradientImageInvalidated(true) +{ + setParentLayerable(parentColorScale); + setMinimumMargins(QMargins(0, 0, 0, 0)); + QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + axis(type)->setVisible(true); + axis(type)->grid()->setVisible(false); + axis(type)->setPadding(0); + connect(axis(type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectionChanged(QCPAxis::SelectableParts))); + connect(axis(type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectableChanged(QCPAxis::SelectableParts))); + } + + connect(axis(QCPAxis::atLeft), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atRight), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atRight), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atLeft), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atTop), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atTop), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atBottom), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atLeft), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atRight), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atRight), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atLeft), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atBottom), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atTop), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atTop), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atBottom), SLOT(setScaleType(QCPAxis::ScaleType))); + + // make layer transfers of color scale transfer to axis rect and axes + // the axes must be set after axis rect, such that they appear above color gradient drawn by axis rect: + connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), this, SLOT(setLayer(QCPLayer*))); + foreach (QCPAxis::AxisType type, allAxisTypes) + connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), axis(type), SLOT(setLayer(QCPLayer*))); +} + +/*! \internal + + Updates the color gradient image if necessary, by calling \ref updateGradientImage, then draws + it. Then the axes are drawn by calling the \ref QCPAxisRect::draw base class implementation. + + \seebaseclassmethod +*/ +void QCPColorScaleAxisRectPrivate::draw(QCPPainter *painter) +{ + if (mGradientImageInvalidated) + updateGradientImage(); + + bool mirrorHorz = false; + bool mirrorVert = false; + if (mParentColorScale->mColorAxis) + { + mirrorHorz = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atBottom || mParentColorScale->type() == QCPAxis::atTop); + mirrorVert = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atLeft || mParentColorScale->type() == QCPAxis::atRight); + } + + painter->drawImage(rect().adjusted(0, -1, 0, -1), mGradientImage.mirrored(mirrorHorz, mirrorVert)); + QCPAxisRect::draw(painter); +} + +/*! \internal + + Uses the current gradient of the parent \ref QCPColorScale (specified in the constructor) to + generate a gradient image. This gradient image will be used in the \ref draw method. +*/ +void QCPColorScaleAxisRectPrivate::updateGradientImage() +{ + if (rect().isEmpty()) + return; + + const QImage::Format format = QImage::Format_ARGB32_Premultiplied; + int n = mParentColorScale->mGradient.levelCount(); + int w, h; + QVector data(n); + for (int i=0; imType == QCPAxis::atBottom || mParentColorScale->mType == QCPAxis::atTop) + { + w = n; + h = rect().height(); + mGradientImage = QImage(w, h, format); + QVector pixels; + for (int y=0; y(mGradientImage.scanLine(y))); + mParentColorScale->mGradient.colorize(data.constData(), QCPRange(0, n-1), pixels.first(), n); + for (int y=1; y(mGradientImage.scanLine(y)); + const QRgb lineColor = mParentColorScale->mGradient.color(data[h-1-y], QCPRange(0, n-1)); + for (int x=0; x allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + if (QCPAxis *senderAxis = qobject_cast(sender())) + if (senderAxis->axisType() == type) + continue; + + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) + { + if (selectedParts.testFlag(QCPAxis::spAxis)) + axis(type)->setSelectedParts(axis(type)->selectedParts() | QCPAxis::spAxis); + else + axis(type)->setSelectedParts(axis(type)->selectedParts() & ~QCPAxis::spAxis); + } + } +} + +/*! \internal + + This slot is connected to the selectableChanged signals of the four axes in the constructor. It + synchronizes the selectability of the axes. +*/ +void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectableParts selectableParts) +{ + // synchronize axis base selectability: + QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + if (QCPAxis *senderAxis = qobject_cast(sender())) + if (senderAxis->axisType() == type) + continue; + + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) + { + if (selectableParts.testFlag(QCPAxis::spAxis)) + axis(type)->setSelectableParts(axis(type)->selectableParts() | QCPAxis::spAxis); + else + axis(type)->setSelectableParts(axis(type)->selectableParts() & ~QCPAxis::spAxis); + } + } +} +/* end of 'src/layoutelements/layoutelement-colorscale.cpp' */ + + +/* including file 'src/plottables/plottable-graph.cpp', size 73960 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGraphData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGraphData + \brief Holds the data of one single data point for QCPGraph. + + The stored data is: + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + \li \a value: coordinate on the value axis of this data point (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPGraphDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPGraphData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPGraphDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPGraphData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPGraphData QCPGraphData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPGraphData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPGraphData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPGraphData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPGraphData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and value set to zero. +*/ +QCPGraphData::QCPGraphData() : + key(0), + value(0) +{ +} + +/*! + Constructs a data point with the specified \a key and \a value. +*/ +QCPGraphData::QCPGraphData(double key, double value, int status) : + key(key), + value(value), + status(status) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGraph +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGraph + \brief A plottable representing a graph in a plot. + + \image html QCPGraph.png + + Usually you create new graphs by calling QCustomPlot::addGraph. The resulting instance can be + accessed via QCustomPlot::graph. + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the data via the \ref data method, which returns a pointer to the internal + \ref QCPGraphDataContainer. + + Graphs are used to display single-valued data. Single-valued means that there should only be one + data point per unique key coordinate. In other words, the graph can't have \a loops. If you do + want to plot non-single-valued curves, rather use the QCPCurve plottable. + + Gaps in the graph line can be created by adding data points with NaN as value + (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be + separated. + + \section qcpgraph-appearance Changing the appearance + + The appearance of the graph is mainly determined by the line style, scatter style, brush and pen + of the graph (\ref setLineStyle, \ref setScatterStyle, \ref setBrush, \ref setPen). + + \subsection filling Filling under or between graphs + + QCPGraph knows two types of fills: Normal graph fills towards the zero-value-line parallel to + the key axis of the graph, and fills between two graphs, called channel fills. To enable a fill, + just set a brush with \ref setBrush which is neither Qt::NoBrush nor fully transparent. + + By default, a normal fill towards the zero-value-line will be drawn. To set up a channel fill + between this graph and another one, call \ref setChannelFillGraph with the other graph as + parameter. + + \see QCustomPlot::addGraph, QCustomPlot::graph +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPGraph::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPGraphDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a graph which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPGraph is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPGraph, so do not delete it manually + but use QCustomPlot::removePlottable() instead. + + To directly create a graph inside a plot, you can also use the simpler QCustomPlot::addGraph function. +*/ +QCPGraph::QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis) +{ + // special handling for QCPGraphs to maintain the simple graph interface: + mParentPlot->registerGraph(this); + + setPen(QPen(Qt::blue, 0)); + setBrush(Qt::NoBrush); + + setLineStyle(lsLine); + setScatterSkip(0); + setChannelFillGraph(0); + setAdaptiveSampling(true); +} + +QCPGraph::~QCPGraph() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPGraphs may share the same data container safely. + Modifying the data in the container will then affect all graphs that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the graph's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-2 + + \see addData +*/ +void QCPGraph::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPGraph::setData(const QVector &keys, const QVector &values, const QVector &status, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, values, status, alreadySorted); +} + +/*! + Sets how the single data points are connected in the plot. For scatter-only plots, set \a ls to + \ref lsNone and \ref setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPGraph::setLineStyle(LineStyle ls) +{ + mLineStyle = ls; +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points + are drawn (e.g. for line-only-plots with appropriate line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPGraph::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +/*! + If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of + scatter points are skipped/not drawn after every drawn scatter point. + + This can be used to make the data appear sparser while for example still having a smooth line, + and to improve performance for very high density plots. + + If \a skip is set to 0 (default), all scatter points are drawn. + + \see setScatterStyle +*/ +void QCPGraph::setScatterSkip(int skip) +{ + mScatterSkip = qMax(0, skip); +} + +/*! + Sets the target graph for filling the area between this graph and \a targetGraph with the current + brush (\ref setBrush). + + When \a targetGraph is set to 0, a normal graph fill to the zero-value-line will be shown. To + disable any filling, set the brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPGraph::setChannelFillGraph(QCPGraph *targetGraph) +{ + // prevent setting channel target to this graph itself: + if (targetGraph == this) + { + qDebug() << Q_FUNC_INFO << "targetGraph is this graph itself"; + mChannelFillGraph = 0; + return; + } + // prevent setting channel target to a graph not in the plot: + if (targetGraph && targetGraph->mParentPlot != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "targetGraph not in same plot"; + mChannelFillGraph = 0; + return; + } + + mChannelFillGraph = targetGraph; +} + +/*! + Sets whether adaptive sampling shall be used when plotting this graph. QCustomPlot's adaptive + sampling technique can drastically improve the replot performance for graphs with a larger number + of points (e.g. above 10,000), without notably changing the appearance of the graph. + + By default, adaptive sampling is enabled. Even if enabled, QCustomPlot decides whether adaptive + sampling shall actually be used on a per-graph basis. So leaving adaptive sampling enabled has no + disadvantage in almost all cases. + + \image html adaptive-sampling-line.png "A line plot of 500,000 points without and with adaptive sampling" + + As can be seen, line plots experience no visual degradation from adaptive sampling. Outliers are + reproduced reliably, as well as the overall shape of the data set. The replot time reduces + dramatically though. This allows QCustomPlot to display large amounts of data in realtime. + + \image html adaptive-sampling-scatter.png "A scatter plot of 100,000 points without and with adaptive sampling" + + Care must be taken when using high-density scatter plots in combination with adaptive sampling. + The adaptive sampling algorithm treats scatter plots more carefully than line plots which still + gives a significant reduction of replot times, but not quite as much as for line plots. This is + because scatter plots inherently need more data points to be preserved in order to still resemble + the original, non-adaptive-sampling plot. As shown above, the results still aren't quite + identical, as banding occurs for the outer data points. This is in fact intentional, such that + the boundaries of the data cloud stay visible to the viewer. How strong the banding appears, + depends on the point density, i.e. the number of points in the plot. + + For some situations with scatter plots it might thus be desirable to manually turn adaptive + sampling off. For example, when saving the plot to disk. This can be achieved by setting \a + enabled to false before issuing a command like \ref QCustomPlot::savePng, and setting \a enabled + back to true afterwards. +*/ +void QCPGraph::setAdaptiveSampling(bool enabled) +{ + mAdaptiveSampling = enabled; +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPGraph::addData(const QVector &keys, const QVector &values, const QVector &status, bool alreadySorted) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + int n = qMin(keys.size(), values.size()); + if (keys.size() != status.size()) + qDebug() << Q_FUNC_INFO << "keys and status have different sizes:" << keys.size() << status.size(); + n = qMin(n, status.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->value = values[i]; + it->status = status[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPGraph::addData(double key, double value, int status) +{ + mDataContainer->add(QCPGraphData(key, value, status)); +} + +double QCPGraph::value(const double &key) +{ + QCPDataContainer::const_iterator lower = mDataContainer->findBegin(key, true); + if(lower == mDataContainer->constEnd()) + { + return qSqrt(-1.); + } + + if(lsStepLeft == mLineStyle) + { + return lower->value; + } + + QCPDataContainer::const_iterator upper = mDataContainer->findEnd(key, false); + if(upper == mDataContainer->constEnd() || upper == mDataContainer->constBegin()) + { + return qSqrt(-1.); + } + + if(upper->key == lower->key) + { + return lower->value; + } + + double rate = (upper->value - lower->value) / (upper->key - lower->key); + return rate * (key - lower->key) + lower->value; +} + +/* inherits documentation from base class */ +double QCPGraph::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPGraphDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + return mDataContainer->keyRange(foundRange, inSignDomain); +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPGraph::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; + if (mLineStyle == lsNone && mScatterStyle.isNone()) return; + + QVector lines, scatters; // line and (if necessary) scatter pixel coordinates will be stored here while iterating over segments + QVector status; + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + // get line pixel points appropriate to line style: + QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getLines takes care) + getLines(&lines, lineDataRange, &status); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPGraphDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); + } +#endif + + // draw fill of graph: + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyBrush(painter); + else + painter->setBrush(mBrush); + painter->setPen(Qt::NoPen); + drawFill(painter, &lines); + + // draw line: + if (mLineStyle != lsNone) + { + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else + painter->setPen(mPen); + painter->setBrush(Qt::NoBrush); + if (mLineStyle == lsImpulse) + drawImpulsePlot(painter, lines); + else + drawLinePlot(painter, lines, status); // also step plots can be drawn as a line plot + } + + // draw scatters: + QCPScatterStyle finalScatterStyle = mScatterStyle; + if (isSelectedSegment && mSelectionDecorator) + finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); + if (!finalScatterStyle.isNone()) + { + getScatters(&scatters, allSegments.at(i)); + drawScatterPlot(painter, scatters, finalScatterStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPGraph::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +/*! \internal + + This method retrieves an optimized set of data points via \ref getOptimizedLineData, an branches + out to the line style specific functions such as \ref dataToLines, \ref dataToStepLeftLines, etc. + according to the line style of the graph. + + \a lines will be filled with points in pixel coordinates, that can be drawn with the according + draw functions like \ref drawLinePlot and \ref drawImpulsePlot. The points returned in \a lines + aren't necessarily the original data points. For example, step line styles require additional + points to form the steps when drawn. If the line style of the graph is \ref lsNone, the \a + lines vector will be empty. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. In this function, the specified range may exceed the total data bounds without harm: + a correspondingly trimmed data range will be used. This takes the burden off the user of this + function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref + getDataSegments. + + \see getScatters +*/ +void QCPGraph::getLines(QVector *lines, const QCPDataRange &dataRange, QVector *status) const +{ + if (!lines || !status) return; + QCPGraphDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, dataRange); + if (begin == end) + { + lines->clear(); + status->clear(); + return; + } + + QVector lineData; + if (mLineStyle != lsNone) + getOptimizedLineData(&lineData, begin, end); + + if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in lineData (significantly simplifies following processing) + std::reverse(lineData.begin(), lineData.end()); + + switch (mLineStyle) + { + case lsNone: lines->clear();status->clear(); break; + case lsLine: dataToLines(lineData, *lines, *status); break; + case lsStepLeft: dataToStepLeftLines(lineData, *lines, *status); break; + case lsStepRight: dataToStepRightLines(lineData, *lines, *status); break; + case lsStepCenter: dataToStepCenterLines(lineData, *lines, *status); break; + case lsImpulse: dataToImpulseLines(lineData, *lines, *status); break; + } +} + +/*! \internal + + This method retrieves an optimized set of data points via \ref getOptimizedScatterData and then + converts them to pixel coordinates. The resulting points are returned in \a scatters, and can be + passed to \ref drawScatterPlot. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. In this function, the specified range may exceed the total data bounds without harm: + a correspondingly trimmed data range will be used. This takes the burden off the user of this + function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref + getDataSegments. +*/ +void QCPGraph::getScatters(QVector *scatters, const QCPDataRange &dataRange) const +{ + if (!scatters) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; scatters->clear(); return; } + + QCPGraphDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, dataRange); + if (begin == end) + { + scatters->clear(); + return; + } + + QVector data; + getOptimizedScatterData(&data, begin, end); + + if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in data (significantly simplifies following processing) + std::reverse(data.begin(), data.end()); + + scatters->resize(data.size()); + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).value)); + (*scatters)[i].setY(keyAxis->coordToPixel(data.at(i).key)); + } + } + } else + { + for (int i=0; icoordToPixel(data.at(i).key)); + (*scatters)[i].setY(valueAxis->coordToPixel(data.at(i).value)); + } + } + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsLine. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +void QCPGraph::dataToLines(const QVector &data, QVector &lines, QVector &status) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + lines.resize(data.size()); + status.resize(data.size()); + + // transform data points to pixels: + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).value)); + lines[i].setY(keyAxis->coordToPixel(data.at(i).key)); + status[i] = data.at(i).status; + } + } else // key axis is horizontal + { + for (int i=0; icoordToPixel(data.at(i).key)); + lines[i].setY(valueAxis->coordToPixel(data.at(i).value)); + status[i] = data.at(i).status; + } + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepLeft. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +void QCPGraph::dataToStepLeftLines(const QVector &data, QVector &lines, QVector &status) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + lines.resize(data.size()*2); + status.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastValue = valueAxis->coordToPixel(data.first().value); + int lastStatus = data.first().status; + for (int i=0; icoordToPixel(data.at(i).key); + lines[i*2+0].setX(lastValue); + lines[i*2+0].setY(key); + status[i*2+0] = lastStatus; + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastStatus = data.at(i).status; + lines[i*2+1].setX(lastValue); + lines[i*2+1].setY(key); + status[i*2+1] = lastStatus; + } + } else // key axis is horizontal + { + double lastValue = valueAxis->coordToPixel(data.first().value); + int lastStatus = data.first().status; + for (int i=0; icoordToPixel(data.at(i).key); + lines[i*2+0].setX(key); + lines[i*2+0].setY(lastValue); + status[i*2+0] = lastStatus; + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastStatus = data.at(i).status; + lines[i*2+1].setX(key); + lines[i*2+1].setY(lastValue); + status[i*2+1] = lastStatus; + } + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepRight. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +void QCPGraph::dataToStepRightLines(const QVector &data, QVector &lines, QVector &status) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + lines.resize(data.size()*2); + status.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastKey = keyAxis->coordToPixel(data.first().key); + for (int i=0; icoordToPixel(data.at(i).value); + const int curStatus = data.at(i).status; + lines[i*2+0].setX(value); + lines[i*2+0].setY(lastKey); + status[i*2+0] = curStatus; + lastKey = keyAxis->coordToPixel(data.at(i).key); + lines[i*2+1].setX(value); + lines[i*2+1].setY(lastKey); + status[i*2+1] = curStatus; + } + } else // key axis is horizontal + { + double lastKey = keyAxis->coordToPixel(data.first().key); + for (int i=0; icoordToPixel(data.at(i).value); + const int curStatus = data.at(i).status; + lines[i*2+0].setX(lastKey); + lines[i*2+0].setY(value); + status[i*2+0] = curStatus; + lastKey = keyAxis->coordToPixel(data.at(i).key); + lines[i*2+1].setX(lastKey); + lines[i*2+1].setY(value); + status[i*2+1] = curStatus; + } + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepCenter. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToImpulseLines, getLines, drawLinePlot +*/ +void QCPGraph::dataToStepCenterLines(const QVector &data, QVector &lines, QVector &status) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + lines.resize(data.size()*2); + status.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastKey = keyAxis->coordToPixel(data.first().key); + double lastValue = valueAxis->coordToPixel(data.first().value); + int lastStatus = data.first().status; + lines[0].setX(lastValue); + lines[0].setY(lastKey); + status[0] = lastStatus; + for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; + lines[i*2-1].setX(lastValue); + lines[i*2-1].setY(key); + status[i*2-1] = lastStatus; + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + lastStatus = data.at(i).status; + lines[i*2+0].setX(lastValue); + lines[i*2+0].setY(key); + status[i*2+0] = lastStatus; + } + lines[data.size()*2-1].setX(lastValue); + lines[data.size()*2-1].setY(lastKey); + status[data.size()*2-1] = lastStatus; + } else // key axis is horizontal + { + double lastKey = keyAxis->coordToPixel(data.first().key); + double lastValue = valueAxis->coordToPixel(data.first().value); + int lastStatus = data.first().status; + lines[0].setX(lastKey); + lines[0].setY(lastValue); + status[0] = lastStatus; + for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; + lines[i*2-1].setX(key); + lines[i*2-1].setY(lastValue); + status[i*2-1] = lastStatus; + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + lastStatus = data.at(i).status; + lines[i*2+0].setX(key); + lines[i*2+0].setY(lastValue); + status[i*2+0] = lastStatus; + } + lines[data.size()*2-1].setX(lastKey); + lines[data.size()*2-1].setY(lastValue); + status[data.size()*2-1] = lastStatus; + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsImpulse. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, getLines, drawImpulsePlot +*/ +void QCPGraph::dataToImpulseLines(const QVector &data, QVector &lines, QVector &status) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + lines.resize(data.size()*2); + status.resize(data.size()*2); + + // transform data points to pixels: + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).key); + const int curStatus = data.at(i).status; + lines[i*2+0].setX(valueAxis->coordToPixel(0)); + lines[i*2+0].setY(key); + status[i*2+0] = curStatus; + lines[i*2+1].setX(valueAxis->coordToPixel(data.at(i).value)); + lines[i*2+1].setY(key); + status[i*2+1] = curStatus; + } + } else // key axis is horizontal + { + for (int i=0; icoordToPixel(data.at(i).key); + const int curStatus = data.at(i).status; + lines[i*2+0].setX(key); + lines[i*2+0].setY(valueAxis->coordToPixel(0)); + status[i*2+0] = curStatus; + lines[i*2+1].setX(key); + lines[i*2+1].setY(valueAxis->coordToPixel(data.at(i).value)); + status[i*2+1] = curStatus; + } + } +} + +/*! \internal + + Draws the fill of the graph using the specified \a painter, with the currently set brush. + + Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref + getFillPolygon or \ref getChannelFillPolygon are used to find the according fill polygons. + + In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas), + this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to + operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN + segments of the two involved graphs, before passing the overlapping pairs to \ref + getChannelFillPolygon. + + Pass the points of this graph's line as \a lines, in pixel coordinates. + + \see drawLinePlot, drawImpulsePlot, drawScatterPlot +*/ +void QCPGraph::drawFill(QCPPainter *painter, QVector *lines) const +{ + if (mLineStyle == lsImpulse) return; // fill doesn't make sense for impulse plot + if (painter->brush().style() == Qt::NoBrush || painter->brush().color().alpha() == 0) return; + + applyFillAntialiasingHint(painter); + QVector segments = getNonNanSegments(lines, keyAxis()->orientation()); + if (!mChannelFillGraph) + { + // draw base fill under graph, fill goes all the way to the zero-value-line: + for (int i=0; idrawPolygon(getFillPolygon(lines, segments.at(i))); + } else + { + // draw fill between this graph and mChannelFillGraph: + QVector otherLines; + QVector status; + mChannelFillGraph->getLines(&otherLines, QCPDataRange(0, mChannelFillGraph->dataCount()), &status); + if (!otherLines.isEmpty()) + { + QVector otherSegments = getNonNanSegments(&otherLines, mChannelFillGraph->keyAxis()->orientation()); + QVector > segmentPairs = getOverlappingSegments(segments, lines, otherSegments, &otherLines); + for (int i=0; idrawPolygon(getChannelFillPolygon(lines, segmentPairs.at(i).first, &otherLines, segmentPairs.at(i).second)); + } + } +} + +/*! \internal + + Draws scatter symbols at every point passed in \a scatters, given in pixel coordinates. The + scatters will be drawn with \a painter and have the appearance as specified in \a style. + + \see drawLinePlot, drawImpulsePlot +*/ +void QCPGraph::drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const +{ + applyScattersAntialiasingHint(painter); + style.applyTo(painter, mPen); + for (int i=0; i &lines, const QVector &status) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + drawPolyline(painter, lines, status); + } +} + +/*! \internal + + Draws impulses from the provided data, i.e. it connects all line pairs in \a lines, given in + pixel coordinates. The \a lines necessary for impulses are generated by \ref dataToImpulseLines + from the regular graph data points. + + \see drawLinePlot, drawScatterPlot +*/ +void QCPGraph::drawImpulsePlot(QCPPainter *painter, const QVector &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + QPen oldPen = painter->pen(); + QPen newPen = painter->pen(); + newPen.setCapStyle(Qt::FlatCap); // so impulse line doesn't reach beyond zero-line + painter->setPen(newPen); + painter->drawLines(lines); + painter->setPen(oldPen); + } +} + +/*! \internal + + Returns via \a lineData the data points that need to be visualized for this graph when plotting + graph lines, taking into consideration the currently visible axis ranges and, if \ref + setAdaptiveSampling is enabled, local point densities. The considered data can be restricted + further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref + getDataSegments). + + This method is used by \ref getLines to retrieve the basic working set of data. + + \see getOptimizedScatterData +*/ +void QCPGraph::getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const +{ + if (!lineData) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (begin == end) return; + + int dataCount = end-begin; + int maxCount = std::numeric_limits::max(); + if (mAdaptiveSampling) + { + double keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); + if (2*keyPixelSpan+2 < (double)std::numeric_limits::max()) + maxCount = 2*keyPixelSpan+2; + } + + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average + { + QCPGraphDataContainer::const_iterator it = begin; + double minValue = it->value; + double maxValue = it->value; + QCPGraphDataContainer::const_iterator currentIntervalFirstPoint = it; + int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction + int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey + double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound)); + double lastIntervalEndKey = currentIntervalStartKey; + double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates + bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) + int intervalDataCount = 1; + ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect + while (it != end) + { + if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this cluster if necessary + { + if (it->value < minValue) + minValue = it->value; + else if (it->value > maxValue) + maxValue = it->value; + ++intervalDataCount; + } else // new pixel interval started + { + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster + { + if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point is further away, so first point of this cluster must be at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); + if (it->key > currentIntervalStartKey+keyEpsilon*2) // new pixel started further away from previous cluster, so make sure the last point of the cluster is at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.8, (it-1)->value)); + } else + lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); + lastIntervalEndKey = (it-1)->key; + minValue = it->value; + maxValue = it->value; + currentIntervalFirstPoint = it; + currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound)); + if (keyEpsilonVariable) + keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); + intervalDataCount = 1; + } + ++it; + } + // handle last interval: + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster + { + if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point wasn't a cluster, so first point of this cluster must be at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); + } else + lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); + + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output + { + lineData->resize(dataCount); + std::copy(begin, end, lineData->begin()); + } +} + +/*! \internal + + Returns via \a scatterData the data points that need to be visualized for this graph when + plotting scatter points, taking into consideration the currently visible axis ranges and, if \ref + setAdaptiveSampling is enabled, local point densities. The considered data can be restricted + further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref + getDataSegments). + + This method is used by \ref getScatters to retrieve the basic working set of data. + + \see getOptimizedLineData +*/ +void QCPGraph::getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const +{ + if (!scatterData) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + const int scatterModulo = mScatterSkip+1; + const bool doScatterSkip = mScatterSkip > 0; + int beginIndex = begin-mDataContainer->constBegin(); + int endIndex = end-mDataContainer->constBegin(); + while (doScatterSkip && begin != end && beginIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter + { + ++beginIndex; + ++begin; + } + if (begin == end) return; + int dataCount = end-begin; + int maxCount = std::numeric_limits::max(); + if (mAdaptiveSampling) + { + int keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); + maxCount = 2*keyPixelSpan+2; + } + + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average + { + double valueMaxRange = valueAxis->range().upper; + double valueMinRange = valueAxis->range().lower; + QCPGraphDataContainer::const_iterator it = begin; + int itIndex = beginIndex; + double minValue = it->value; + double maxValue = it->value; + QCPGraphDataContainer::const_iterator minValueIt = it; + QCPGraphDataContainer::const_iterator maxValueIt = it; + QCPGraphDataContainer::const_iterator currentIntervalStart = it; + int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction + int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey + double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound)); + double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates + bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) + int intervalDataCount = 1; + // advance iterator to second (non-skipped) data point because adaptive sampling works in 1 point retrospect: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + // main loop over data points: + while (it != end) + { + if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this pixel if necessary + { + if (it->value < minValue && it->value > valueMinRange && it->value < valueMaxRange) + { + minValue = it->value; + minValueIt = it; + } else if (it->value > maxValue && it->value > valueMinRange && it->value < valueMaxRange) + { + maxValue = it->value; + maxValueIt = it; + } + ++intervalDataCount; + } else // new pixel started + { + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them + { + // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): + double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); + int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average + QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; + int c = 0; + while (intervalIt != it) + { + if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) + scatterData->append(*intervalIt); + ++c; + if (!doScatterSkip) + ++intervalIt; + else + intervalIt += scatterModulo; // since we know indices of "currentIntervalStart", "intervalIt" and "it" are multiples of scatterModulo, we can't accidentally jump over "it" here + } + } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) + scatterData->append(*currentIntervalStart); + minValue = it->value; + maxValue = it->value; + currentIntervalStart = it; + currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound)); + if (keyEpsilonVariable) + keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); + intervalDataCount = 1; + } + // advance to next data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + // handle last interval: + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them + { + // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): + double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); + int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average + QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; + int intervalItIndex = intervalIt-mDataContainer->constBegin(); + int c = 0; + while (intervalIt != it) + { + if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) + scatterData->append(*intervalIt); + ++c; + if (!doScatterSkip) + ++intervalIt; + else // here we can't guarantee that adding scatterModulo doesn't exceed "it" (because "it" is equal to "end" here, and "end" isn't scatterModulo-aligned), so check via index comparison: + { + intervalItIndex += scatterModulo; + if (intervalItIndex < itIndex) + intervalIt += scatterModulo; + else + { + intervalIt = it; + intervalItIndex = itIndex; + } + } + } + } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) + scatterData->append(*currentIntervalStart); + + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output + { + QCPGraphDataContainer::const_iterator it = begin; + int itIndex = beginIndex; + scatterData->reserve(dataCount); + while (it != end) + { + scatterData->append(*it); + // advance to next data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } +} + +/*! + This method outputs the currently visible data range via \a begin and \a end. The returned range + will also never exceed \a rangeRestriction. + + This method takes into account that the drawing of data lines at the axis rect border always + requires the points just outside the visible axis range. So \a begin and \a end may actually + indicate a range that contains one additional data point to the left and right of the visible + axis range. +*/ +void QCPGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const +{ + if (rangeRestriction.isEmpty()) + { + end = mDataContainer->constEnd(); + begin = end; + } else + { + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + // get visible data range: + begin = mDataContainer->findBegin(keyAxis->range().lower); + end = mDataContainer->findEnd(keyAxis->range().upper); + // limit lower/upperEnd to rangeRestriction: + mDataContainer->limitIteratorsToDataRange(begin, end, rangeRestriction); // this also ensures rangeRestriction outside data bounds doesn't break anything + } +} + +/*! \internal + + This method goes through the passed points in \a lineData and returns a list of the segments + which don't contain NaN data points. + + \a keyOrientation defines whether the \a x or \a y member of the passed QPointF is used to check + for NaN. If \a keyOrientation is \c Qt::Horizontal, the \a y member is checked, if it is \c + Qt::Vertical, the \a x member is checked. + + \see getOverlappingSegments, drawFill +*/ +QVector QCPGraph::getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const +{ + QVector result; + const int n = lineData->size(); + + QCPDataRange currentSegment(-1, -1); + int i = 0; + + if (keyOrientation == Qt::Horizontal) + { + while (i < n) + { + while (i < n && qIsNaN(lineData->at(i).y())) // seek next non-NaN data point + ++i; + if (i == n) + break; + currentSegment.setBegin(i++); + while (i < n && !qIsNaN(lineData->at(i).y())) // seek next NaN data point or end of data + ++i; + currentSegment.setEnd(i++); + result.append(currentSegment); + } + } else // keyOrientation == Qt::Vertical + { + while (i < n) + { + while (i < n && qIsNaN(lineData->at(i).x())) // seek next non-NaN data point + ++i; + if (i == n) + break; + currentSegment.setBegin(i++); + while (i < n && !qIsNaN(lineData->at(i).x())) // seek next NaN data point or end of data + ++i; + currentSegment.setEnd(i++); + result.append(currentSegment); + } + } + return result; +} + +/*! \internal + + This method takes two segment lists (e.g. created by \ref getNonNanSegments) \a thisSegments and + \a otherSegments, and their associated point data \a thisData and \a otherData. + + It returns all pairs of segments (the first from \a thisSegments, the second from \a + otherSegments), which overlap in plot coordinates. + + This method is useful in the case of a channel fill between two graphs, when only those non-NaN + segments which actually overlap in their key coordinate shall be considered for drawing a channel + fill polygon. + + It is assumed that the passed segments in \a thisSegments are ordered ascending by index, and + that the segments don't overlap themselves. The same is assumed for the segments in \a + otherSegments. This is fulfilled when the segments are obtained via \ref getNonNanSegments. + + \see getNonNanSegments, segmentsIntersect, drawFill, getChannelFillPolygon +*/ +QVector > QCPGraph::getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const +{ + QVector > result; + if (thisData->isEmpty() || otherData->isEmpty() || thisSegments.isEmpty() || otherSegments.isEmpty()) + return result; + + int thisIndex = 0; + int otherIndex = 0; + const bool verticalKey = mKeyAxis->orientation() == Qt::Vertical; + while (thisIndex < thisSegments.size() && otherIndex < otherSegments.size()) + { + if (thisSegments.at(thisIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow + { + ++thisIndex; + continue; + } + if (otherSegments.at(otherIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow + { + ++otherIndex; + continue; + } + double thisLower, thisUpper, otherLower, otherUpper; + if (!verticalKey) + { + thisLower = thisData->at(thisSegments.at(thisIndex).begin()).x(); + thisUpper = thisData->at(thisSegments.at(thisIndex).end()-1).x(); + otherLower = otherData->at(otherSegments.at(otherIndex).begin()).x(); + otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).x(); + } else + { + thisLower = thisData->at(thisSegments.at(thisIndex).begin()).y(); + thisUpper = thisData->at(thisSegments.at(thisIndex).end()-1).y(); + otherLower = otherData->at(otherSegments.at(otherIndex).begin()).y(); + otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).y(); + } + + int bPrecedence; + if (segmentsIntersect(thisLower, thisUpper, otherLower, otherUpper, bPrecedence)) + result.append(QPair(thisSegments.at(thisIndex), otherSegments.at(otherIndex))); + + if (bPrecedence <= 0) // otherSegment doesn't reach as far as thisSegment, so continue with next otherSegment, keeping current thisSegment + ++otherIndex; + else // otherSegment reaches further than thisSegment, so continue with next thisSegment, keeping current otherSegment + ++thisIndex; + } + + return result; +} + +/*! \internal + + Returns whether the segments defined by the coordinates (aLower, aUpper) and (bLower, bUpper) + have overlap. + + The output parameter \a bPrecedence indicates whether the \a b segment reaches farther than the + \a a segment or not. If \a bPrecedence returns 1, segment \a b reaches the farthest to higher + coordinates (i.e. bUpper > aUpper). If it returns -1, segment \a a reaches the farthest. Only if + both segment's upper bounds are identical, 0 is returned as \a bPrecedence. + + It is assumed that the lower bounds always have smaller or equal values than the upper bounds. + + \see getOverlappingSegments +*/ +bool QCPGraph::segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const +{ + bPrecedence = 0; + if (aLower > bUpper) + { + bPrecedence = -1; + return false; + } else if (bLower > aUpper) + { + bPrecedence = 1; + return false; + } else + { + if (aUpper > bUpper) + bPrecedence = -1; + else if (aUpper < bUpper) + bPrecedence = 1; + + return true; + } +} + +/*! \internal + + Returns the point which closes the fill polygon on the zero-value-line parallel to the key axis. + The logarithmic axis scale case is a bit special, since the zero-value-line in pixel coordinates + is in positive or negative infinity. So this case is handled separately by just closing the fill + polygon on the axis which lies in the direction towards the zero value. + + \a matchingDataPoint will provide the key (in pixels) of the returned point. Depending on whether + the key axis of this graph is horizontal or vertical, \a matchingDataPoint will provide the x or + y value of the returned point, respectively. +*/ +QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + QPointF result; + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + if (keyAxis->orientation() == Qt::Horizontal) + { + result.setX(matchingDataPoint.x()); + result.setY(valueAxis->coordToPixel(0)); + } else // keyAxis->orientation() == Qt::Vertical + { + result.setX(valueAxis->coordToPixel(0)); + result.setY(matchingDataPoint.y()); + } + } else // valueAxis->mScaleType == QCPAxis::stLogarithmic + { + // In logarithmic scaling we can't just draw to value 0 so we just fill all the way + // to the axis which is in the direction towards 0 + if (keyAxis->orientation() == Qt::Vertical) + { + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + result.setX(keyAxis->axisRect()->right()); + else + result.setX(keyAxis->axisRect()->left()); + result.setY(matchingDataPoint.y()); + } else if (keyAxis->axisType() == QCPAxis::atTop || keyAxis->axisType() == QCPAxis::atBottom) + { + result.setX(matchingDataPoint.x()); + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + result.setY(keyAxis->axisRect()->top()); + else + result.setY(keyAxis->axisRect()->bottom()); + } + } + return result; +} + +/*! \internal + + Returns the polygon needed for drawing normal fills between this graph and the key axis. + + Pass the graph's data points (in pixel coordinates) as \a lineData, and specify the \a segment + which shall be used for the fill. The collection of \a lineData points described by \a segment + must not contain NaN data points (see \ref getNonNanSegments). + + The returned fill polygon will be closed at the key axis (the zero-value line) for linear value + axes. For logarithmic value axes the polygon will reach just beyond the corresponding axis rect + side (see \ref getFillBasePoint). + + For increased performance (due to implicit sharing), keep the returned QPolygonF const. + + \see drawFill, getNonNanSegments +*/ +const QPolygonF QCPGraph::getFillPolygon(const QVector *lineData, QCPDataRange segment) const +{ + if (segment.size() < 2) + return QPolygonF(); + QPolygonF result(segment.size()+2); + + result[0] = getFillBasePoint(lineData->at(segment.begin())); + std::copy(lineData->constBegin()+segment.begin(), lineData->constBegin()+segment.end(), result.begin()+1); + result[result.size()-1] = getFillBasePoint(lineData->at(segment.end()-1)); + + return result; +} + +/*! \internal + + Returns the polygon needed for drawing (partial) channel fills between this graph and the graph + specified by \ref setChannelFillGraph. + + The data points of this graph are passed as pixel coordinates via \a thisData, the data of the + other graph as \a otherData. The returned polygon will be calculated for the specified data + segments \a thisSegment and \a otherSegment, pertaining to the respective \a thisData and \a + otherData, respectively. + + The passed \a thisSegment and \a otherSegment should correspond to the segment pairs returned by + \ref getOverlappingSegments, to make sure only segments that actually have key coordinate overlap + need to be processed here. + + For increased performance due to implicit sharing, keep the returned QPolygonF const. + + \see drawFill, getOverlappingSegments, getNonNanSegments +*/ +const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *thisData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const +{ + if (!mChannelFillGraph) + return QPolygonF(); + + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPolygonF(); } + if (!mChannelFillGraph.data()->mKeyAxis) { qDebug() << Q_FUNC_INFO << "channel fill target key axis invalid"; return QPolygonF(); } + + if (mChannelFillGraph.data()->mKeyAxis.data()->orientation() != keyAxis->orientation()) + return QPolygonF(); // don't have same axis orientation, can't fill that (Note: if keyAxis fits, valueAxis will fit too, because it's always orthogonal to keyAxis) + + if (thisData->isEmpty()) return QPolygonF(); + QVector thisSegmentData(thisSegment.size()); + QVector otherSegmentData(otherSegment.size()); + std::copy(thisData->constBegin()+thisSegment.begin(), thisData->constBegin()+thisSegment.end(), thisSegmentData.begin()); + std::copy(otherData->constBegin()+otherSegment.begin(), otherData->constBegin()+otherSegment.end(), otherSegmentData.begin()); + // pointers to be able to swap them, depending which data range needs cropping: + QVector *staticData = &thisSegmentData; + QVector *croppedData = &otherSegmentData; + + // crop both vectors to ranges in which the keys overlap (which coord is key, depends on axisType): + if (keyAxis->orientation() == Qt::Horizontal) + { + // x is key + // crop lower bound: + if (staticData->first().x() < croppedData->first().x()) // other one must be cropped + qSwap(staticData, croppedData); + const int lowBound = findIndexBelowX(croppedData, staticData->first().x()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (!qFuzzyCompare(croppedData->at(1).x(), croppedData->at(0).x())) + slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x()); + else + slope = 0; + (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x())); + (*croppedData)[0].setX(staticData->first().x()); + + // crop upper bound: + if (staticData->last().x() > croppedData->last().x()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexAboveX(croppedData, staticData->last().x()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + const int li = croppedData->size()-1; // last index + if (!qFuzzyCompare(croppedData->at(li).x(), croppedData->at(li-1).x())) + slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x()); + else + slope = 0; + (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x())); + (*croppedData)[li].setX(staticData->last().x()); + } else // mKeyAxis->orientation() == Qt::Vertical + { + // y is key + // crop lower bound: + if (staticData->first().y() < croppedData->first().y()) // other one must be cropped + qSwap(staticData, croppedData); + int lowBound = findIndexBelowY(croppedData, staticData->first().y()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (!qFuzzyCompare(croppedData->at(1).y(), croppedData->at(0).y())) // avoid division by zero in step plots + slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y()); + else + slope = 0; + (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y())); + (*croppedData)[0].setY(staticData->first().y()); + + // crop upper bound: + if (staticData->last().y() > croppedData->last().y()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexAboveY(croppedData, staticData->last().y()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + int li = croppedData->size()-1; // last index + if (!qFuzzyCompare(croppedData->at(li).y(), croppedData->at(li-1).y())) // avoid division by zero in step plots + slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y()); + else + slope = 0; + (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y())); + (*croppedData)[li].setY(staticData->last().y()); + } + + // return joined: + for (int i=otherSegmentData.size()-1; i>=0; --i) // insert reversed, otherwise the polygon will be twisted + thisSegmentData << otherSegmentData.at(i); + return QPolygonF(thisSegmentData); +} + +/*! \internal + + Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in + \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key + axis is horizontal. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveX(const QVector *data, double x) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).x() < x) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/*! \internal + + Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in + \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key + axis is horizontal. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexBelowX(const QVector *data, double x) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).x() > x) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} + +/*! \internal + + Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in + \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key + axis is vertical. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveY(const QVector *data, double y) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).y() < y) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/*! \internal + + Calculates the minimum distance in pixels the graph's representation has from the given \a + pixelPoint. This is used to determine whether the graph was clicked or not, e.g. in \ref + selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that if + the graph has a line representation, the returned distance may be smaller than the distance to + the \a closestData point, since the distance to the graph line is also taken into account. + + If either the graph has no data or if the line style is \ref lsNone and the scatter style's shape + is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the graph), returns -1.0. +*/ +double QCPGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (mDataContainer->isEmpty()) + return -1.0; + if (mLineStyle == lsNone && mScatterStyle.isNone()) + return -1.0; + + // calculate minimum distances to graph data points and find closestData iterator: + double minDistSqr = std::numeric_limits::max(); + // determine which key range comes into question, taking selection tolerance around pos into account: + double posKeyMin, posKeyMax, dummy; + pixelsToCoords(pixelPoint-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); + pixelsToCoords(pixelPoint+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); + if (posKeyMin > posKeyMax) + qSwap(posKeyMin, posKeyMax); + // iterate over found data points and then choose the one with the shortest distance to pos: + QCPGraphDataContainer::const_iterator begin = mDataContainer->findBegin(posKeyMin, true); + QCPGraphDataContainer::const_iterator end = mDataContainer->findEnd(posKeyMax, true); + for (QCPGraphDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestData = it; + } + } + + // calculate distance to graph line if there is one (if so, will probably be smaller than distance to closest data point): + if (mLineStyle != lsNone) + { + // line displayed, calculate distance to line segments: + QVector lineData; + QVector status; + getLines(&lineData, QCPDataRange(0, dataCount()), &status); + QCPVector2D p(pixelPoint); + const int step = mLineStyle==lsImpulse ? 2 : 1; // impulse plot differs from other line styles in that the lineData points are only pairwise connected + for (int i=0; i *data, double y) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).y() > y) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} +/* end of 'src/plottables/plottable-graph.cpp' */ + + +/* including file 'src/plottables/plottable-curve.cpp', size 63527 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPCurveData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPCurveData + \brief Holds the data of one single data point for QCPCurve. + + The stored data is: + \li \a t: the free ordering parameter of this curve point, like in the mathematical vector (x(t), y(t)). (This is the \a sortKey) + \li \a key: coordinate on the key axis of this curve point (this is the \a mainKey) + \li \a value: coordinate on the value axis of this curve point (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPCurveDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPCurveData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPCurveDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPCurveData::sortKey() const + + Returns the \a t member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPCurveData QCPCurveData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey (assigned to the data point's \a t member). + All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPCurveData::sortKeyIsMainKey() + + Since the member \a key is the data point key coordinate and the member \a t is the data ordering + parameter, this method returns false. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPCurveData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPCurveData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPCurveData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a curve data point with t, key and value set to zero. +*/ +QCPCurveData::QCPCurveData() : + t(0), + key(0), + value(0) +{ +} + +/*! + Constructs a curve data point with the specified \a t, \a key and \a value. +*/ +QCPCurveData::QCPCurveData(double t, double key, double value) : + t(t), + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPCurve +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPCurve + \brief A plottable representing a parametric curve in a plot. + + \image html QCPCurve.png + + Unlike QCPGraph, plottables of this type may have multiple points with the same key coordinate, + so their visual representation can have \a loops. This is realized by introducing a third + coordinate \a t, which defines the order of the points described by the other two coordinates \a + x and \a y. + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the curve's data via the \ref data method, which returns a pointer to the + internal \ref QCPCurveDataContainer. + + Gaps in the curve can be created by adding data points with NaN as key and value + (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be + separated. + + \section qcpcurve-appearance Changing the appearance + + The appearance of the curve is determined by the pen and the brush (\ref setPen, \ref setBrush). + + \section qcpcurve-usage Usage + + Like all data representing objects in QCustomPlot, the QCPCurve is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-2 +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPCurve::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPCurveDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a curve which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPCurve is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPCurve, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis) +{ + // modify inherited properties from abstract plottable: + setPen(QPen(Qt::blue, 0)); + setBrush(Qt::NoBrush); + + setScatterStyle(QCPScatterStyle()); + setLineStyle(lsLine); + setScatterSkip(0); +} + +QCPCurve::~QCPCurve() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPCurves may share the same data container safely. + Modifying the data in the container will then affect all curves that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the curve's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-2 + + \see addData +*/ +void QCPCurve::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a t, \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a t in ascending order, you can + set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPCurve::setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(t, keys, values, alreadySorted); +} + + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + The t parameter of each data point will be set to the integer index of the respective key/value + pair. + + \see addData +*/ +void QCPCurve::setData(const QVector &keys, const QVector &values) +{ + mDataContainer->clear(); + addData(keys, values); +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref + QCPScatterStyle::ssNone, no scatter points are drawn (e.g. for line-only plots with appropriate + line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPCurve::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +/*! + If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of + scatter points are skipped/not drawn after every drawn scatter point. + + This can be used to make the data appear sparser while for example still having a smooth line, + and to improve performance for very high density plots. + + If \a skip is set to 0 (default), all scatter points are drawn. + + \see setScatterStyle +*/ +void QCPCurve::setScatterSkip(int skip) +{ + mScatterSkip = qMax(0, skip); +} + +/*! + Sets how the single data points are connected in the plot or how they are represented visually + apart from the scatter symbol. For scatter-only plots, set \a style to \ref lsNone and \ref + setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPCurve::setLineStyle(QCPCurve::LineStyle style) +{ + mLineStyle = style; +} + +/*! \overload + + Adds the provided points in \a t, \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (t.size() != keys.size() || t.size() != values.size()) + qDebug() << Q_FUNC_INFO << "ts, keys and values have different sizes:" << t.size() << keys.size() << values.size(); + const int n = qMin(qMin(t.size(), keys.size()), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->t = t[i]; + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + The t parameter of each data point will be set to the integer index of the respective key/value + pair. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(const QVector &keys, const QVector &values) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + double tStart; + if (!mDataContainer->isEmpty()) + tStart = (mDataContainer->constEnd()-1)->t + 1.0; + else + tStart = 0; + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->t = tStart + i; + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, true); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + Adds the provided data point as \a t, \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(double t, double key, double value) +{ + mDataContainer->add(QCPCurveData(t, key, value)); +} + +/*! \overload + + Adds the provided data point as \a key and \a value to the current data. + + The t parameter is generated automatically by increments of 1 for each point, starting at the + highest t of previously existing data or 0, if the curve data is empty. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(double key, double value) +{ + if (!mDataContainer->isEmpty()) + mDataContainer->add(QCPCurveData((mDataContainer->constEnd()-1)->t + 1.0, key, value)); + else + mDataContainer->add(QCPCurveData(0.0, key, value)); +} + +/* inherits documentation from base class */ +double QCPCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPCurveDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + return mDataContainer->keyRange(foundRange, inSignDomain); +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPCurve::draw(QCPPainter *painter) +{ + if (mDataContainer->isEmpty()) return; + + // allocate line vector: + QVector lines, scatters; + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + + // fill with curve data: + QPen finalCurvePen = mPen; // determine the final pen already here, because the line optimization depends on its stroke width + if (isSelectedSegment && mSelectionDecorator) + finalCurvePen = mSelectionDecorator->pen(); + + QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getCurveLines takes care) + getCurveLines(&lines, lineDataRange, finalCurvePen.widthF()); + + // check data validity if flag set: + #ifdef QCUSTOMPLOT_CHECK_DATA + for (QCPCurveDataContainer::const_iterator it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->t) || + QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); + } + #endif + + // draw curve fill: + applyFillAntialiasingHint(painter); + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyBrush(painter); + else + painter->setBrush(mBrush); + painter->setPen(Qt::NoPen); + if (painter->brush().style() != Qt::NoBrush && painter->brush().color().alpha() != 0) + painter->drawPolygon(QPolygonF(lines)); + + // draw curve line: + if (mLineStyle != lsNone) + { + painter->setPen(finalCurvePen); + painter->setBrush(Qt::NoBrush); + drawCurveLine(painter, lines); + } + + // draw scatters: + QCPScatterStyle finalScatterStyle = mScatterStyle; + if (isSelectedSegment && mSelectionDecorator) + finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); + if (!finalScatterStyle.isNone()) + { + getScatters(&scatters, allSegments.at(i), finalScatterStyle.size()); + drawScatterPlot(painter, scatters, finalScatterStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPCurve::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +/*! \internal + + Draws lines between the points in \a lines, given in pixel coordinates. + + \see drawScatterPlot, getCurveLines +*/ +void QCPCurve::drawCurveLine(QCPPainter *painter, const QVector &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + drawPolyline(painter, lines); + } +} + +/*! \internal + + Draws scatter symbols at every point passed in \a points, given in pixel coordinates. The + scatters will be drawn with \a painter and have the appearance as specified in \a style. + + \see drawCurveLine, getCurveLines +*/ +void QCPCurve::drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const +{ + // draw scatter point symbols: + applyScattersAntialiasingHint(painter); + style.applyTo(painter, mPen); + for (int i=0; i *lines, const QCPDataRange &dataRange, double penWidth) const +{ + if (!lines) return; + lines->clear(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + // add margins to rect to compensate for stroke width + const double strokeMargin = qMax(qreal(1.0), qreal(penWidth*0.75)); // stroke radius + 50% safety + const double keyMin = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().lower)-strokeMargin*keyAxis->pixelOrientation()); + const double keyMax = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().upper)+strokeMargin*keyAxis->pixelOrientation()); + const double valueMin = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().lower)-strokeMargin*valueAxis->pixelOrientation()); + const double valueMax = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().upper)+strokeMargin*valueAxis->pixelOrientation()); + QCPCurveDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + mDataContainer->limitIteratorsToDataRange(itBegin, itEnd, dataRange); + if (itBegin == itEnd) + return; + QCPCurveDataContainer::const_iterator it = itBegin; + QCPCurveDataContainer::const_iterator prevIt = itEnd-1; + int prevRegion = getRegion(prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin); + QVector trailingPoints; // points that must be applied after all other points (are generated only when handling first point to get virtual segment between last and first point right) + while (it != itEnd) + { + const int currentRegion = getRegion(it->key, it->value, keyMin, valueMax, keyMax, valueMin); + if (currentRegion != prevRegion) // changed region, possibly need to add some optimized edge points or original points if entering R + { + if (currentRegion != 5) // segment doesn't end in R, so it's a candidate for removal + { + QPointF crossA, crossB; + if (prevRegion == 5) // we're coming from R, so add this point optimized + { + lines->append(getOptimizedPoint(currentRegion, it->key, it->value, prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin)); + // in the situations 5->1/7/9/3 the segment may leave R and directly cross through two outer regions. In these cases we need to add an additional corner point + *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + } else if (mayTraverse(prevRegion, currentRegion) && + getTraverse(prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin, crossA, crossB)) + { + // add the two cross points optimized if segment crosses R and if segment isn't virtual zeroth segment between last and first curve point: + QVector beforeTraverseCornerPoints, afterTraverseCornerPoints; + getTraverseCornerPoints(prevRegion, currentRegion, keyMin, valueMax, keyMax, valueMin, beforeTraverseCornerPoints, afterTraverseCornerPoints); + if (it != itBegin) + { + *lines << beforeTraverseCornerPoints; + lines->append(crossA); + lines->append(crossB); + *lines << afterTraverseCornerPoints; + } else + { + lines->append(crossB); + *lines << afterTraverseCornerPoints; + trailingPoints << beforeTraverseCornerPoints << crossA ; + } + } else // doesn't cross R, line is just moving around in outside regions, so only need to add optimized point(s) at the boundary corner(s) + { + *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + } + } else // segment does end in R, so we add previous point optimized and this point at original position + { + if (it == itBegin) // it is first point in curve and prevIt is last one. So save optimized point for adding it to the lineData in the end + trailingPoints << getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + else + lines->append(getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin)); + lines->append(coordsToPixels(it->key, it->value)); + } + } else // region didn't change + { + if (currentRegion == 5) // still in R, keep adding original points + { + lines->append(coordsToPixels(it->key, it->value)); + } else // still outside R, no need to add anything + { + // see how this is not doing anything? That's the main optimization... + } + } + prevIt = it; + prevRegion = currentRegion; + ++it; + } + *lines << trailingPoints; +} + +/*! \internal + + Called by \ref draw to generate points in pixel coordinates which represent the scatters of the + curve. If a scatter skip is configured (\ref setScatterSkip), the returned points are accordingly + sparser. + + Scatters that aren't visible in the current axis rect are optimized away. + + \a scatters will be filled with points in pixel coordinates, that can be drawn with \ref + drawScatterPlot. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. + + \a scatterWidth specifies the scatter width that will be used to later draw the scatters at pixel + coordinates generated by this function. This is needed here to calculate an accordingly wider + margin around the axis rect when performing the data point reduction. + + \see draw, drawScatterPlot +*/ +void QCPCurve::getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const +{ + if (!scatters) return; + scatters->clear(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); + mDataContainer->limitIteratorsToDataRange(begin, end, dataRange); + if (begin == end) + return; + const int scatterModulo = mScatterSkip+1; + const bool doScatterSkip = mScatterSkip > 0; + int endIndex = end-mDataContainer->constBegin(); + + QCPRange keyRange = keyAxis->range(); + QCPRange valueRange = valueAxis->range(); + // extend range to include width of scatter symbols: + keyRange.lower = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.lower)-scatterWidth*keyAxis->pixelOrientation()); + keyRange.upper = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.upper)+scatterWidth*keyAxis->pixelOrientation()); + valueRange.lower = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.lower)-scatterWidth*valueAxis->pixelOrientation()); + valueRange.upper = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.upper)+scatterWidth*valueAxis->pixelOrientation()); + + QCPCurveDataContainer::const_iterator it = begin; + int itIndex = begin-mDataContainer->constBegin(); + while (doScatterSkip && it != end && itIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter + { + ++itIndex; + ++it; + } + if (keyAxis->orientation() == Qt::Vertical) + { + while (it != end) + { + if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) + scatters->append(QPointF(valueAxis->coordToPixel(it->value), keyAxis->coordToPixel(it->key))); + + // advance iterator to next (non-skipped) data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } else + { + while (it != end) + { + if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) + scatters->append(QPointF(keyAxis->coordToPixel(it->key), valueAxis->coordToPixel(it->value))); + + // advance iterator to next (non-skipped) data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + It returns the region of the given point (\a key, \a value) with respect to a rectangle defined + by \a keyMin, \a keyMax, \a valueMin, and \a valueMax. + + The regions are enumerated from top to bottom (\a valueMin to \a valueMax) and left to right (\a + keyMin to \a keyMax): + + + + + +
147
258
369
+ + With the rectangle being region 5, and the outer regions extending infinitely outwards. In the + curve optimization algorithm, region 5 is considered to be the visible portion of the plot. +*/ +int QCPCurve::getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + if (key < keyMin) // region 123 + { + if (value > valueMax) + return 1; + else if (value < valueMin) + return 3; + else + return 2; + } else if (key > keyMax) // region 789 + { + if (value > valueMax) + return 7; + else if (value < valueMin) + return 9; + else + return 8; + } else // region 456 + { + if (value > valueMax) + return 4; + else if (value < valueMin) + return 6; + else + return 5; + } +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method is used in case the current segment passes from inside the visible rect (region 5, + see \ref getRegion) to any of the outer regions (\a otherRegion). The current segment is given by + the line connecting (\a key, \a value) with (\a otherKey, \a otherValue). + + It returns the intersection point of the segment with the border of region 5. + + For this function it doesn't matter whether (\a key, \a value) is the point inside region 5 or + whether it's (\a otherKey, \a otherValue), i.e. whether the segment is coming from region 5 or + leaving it. It is important though that \a otherRegion correctly identifies the other region not + equal to 5. +*/ +QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double otherValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + // The intersection point interpolation here is done in pixel coordinates, so we don't need to + // differentiate between different axis scale types. Note that the nomenclature + // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be + // different in pixel coordinates (horz/vert key axes, reversed ranges) + + const double keyMinPx = mKeyAxis->coordToPixel(keyMin); + const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); + const double valueMinPx = mValueAxis->coordToPixel(valueMin); + const double valueMaxPx = mValueAxis->coordToPixel(valueMax); + const double otherValuePx = mValueAxis->coordToPixel(otherValue); + const double valuePx = mValueAxis->coordToPixel(value); + const double otherKeyPx = mKeyAxis->coordToPixel(otherKey); + const double keyPx = mKeyAxis->coordToPixel(key); + double intersectKeyPx = keyMinPx; // initial key just a fail-safe + double intersectValuePx = valueMinPx; // initial value just a fail-safe + switch (otherRegion) + { + case 1: // top and left edge + { + intersectValuePx = valueMaxPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMinPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + case 2: // left edge + { + intersectKeyPx = keyMinPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + break; + } + case 3: // bottom and left edge + { + intersectValuePx = valueMinPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMinPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + case 4: // top edge + { + intersectValuePx = valueMaxPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + break; + } + case 5: + { + break; // case 5 shouldn't happen for this function but we add it anyway to prevent potential discontinuity in branch table + } + case 6: // bottom edge + { + intersectValuePx = valueMinPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + break; + } + case 7: // top and right edge + { + intersectValuePx = valueMaxPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMaxPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + case 8: // right edge + { + intersectKeyPx = keyMaxPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + break; + } + case 9: // bottom and right edge + { + intersectValuePx = valueMinPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMaxPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + } + if (mKeyAxis->orientation() == Qt::Horizontal) + return QPointF(intersectKeyPx, intersectValuePx); + else + return QPointF(intersectValuePx, intersectKeyPx); +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + In situations where a single segment skips over multiple regions it might become necessary to add + extra points at the corners of region 5 (see \ref getRegion) such that the optimized segment + doesn't unintentionally cut through the visible area of the axis rect and create plot artifacts. + This method provides these points that must be added, assuming the original segment doesn't + start, end, or traverse region 5. (Corner points where region 5 is traversed are calculated by + \ref getTraverseCornerPoints.) + + For example, consider a segment which directly goes from region 4 to 2 but originally is far out + to the top left such that it doesn't cross region 5. Naively optimizing these points by + projecting them on the top and left borders of region 5 will create a segment that surely crosses + 5, creating a visual artifact in the plot. This method prevents this by providing extra points at + the top left corner, making the optimized curve correctly pass from region 4 to 1 to 2 without + traversing 5. +*/ +QVector QCPCurve::getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + QVector result; + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 2: { result << coordsToPixels(keyMin, valueMax); break; } + case 4: { result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); break; } + case 7: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); break; } + case 6: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 9: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } + else + { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } + break; + } + } + break; + } + case 2: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + case 4: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 7: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 3: + { + switch (currentRegion) + { + case 2: { result << coordsToPixels(keyMin, valueMin); break; } + case 6: { result << coordsToPixels(keyMin, valueMin); break; } + case 1: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); break; } + case 9: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); break; } + case 4: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 7: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } + else + { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } + break; + } + } + break; + } + case 4: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 2: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 3: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } + case 9: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 5: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 6: + { + switch (currentRegion) + { + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 2: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 1: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 7: + { + switch (currentRegion) + { + case 4: { result << coordsToPixels(keyMax, valueMax); break; } + case 8: { result << coordsToPixels(keyMax, valueMax); break; } + case 1: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); break; } + case 2: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 3: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } + else + { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } + break; + } + } + break; + } + case 8: + { + switch (currentRegion) + { + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 4: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 1: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 9: + { + switch (currentRegion) + { + case 6: { result << coordsToPixels(keyMax, valueMin); break; } + case 8: { result << coordsToPixels(keyMax, valueMin); break; } + case 3: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); break; } + case 7: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); break; } + case 2: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 4: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 1: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } + else + { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } + break; + } + } + break; + } + } + return result; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method returns whether a segment going from \a prevRegion to \a currentRegion (see \ref + getRegion) may traverse the visible region 5. This function assumes that neither \a prevRegion + nor \a currentRegion is 5 itself. + + If this method returns false, the segment for sure doesn't pass region 5. If it returns true, the + segment may or may not pass region 5 and a more fine-grained calculation must be used (\ref + getTraverse). +*/ +bool QCPCurve::mayTraverse(int prevRegion, int currentRegion) const +{ + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 4: + case 7: + case 2: + case 3: return false; + default: return true; + } + } + case 2: + { + switch (currentRegion) + { + case 1: + case 3: return false; + default: return true; + } + } + case 3: + { + switch (currentRegion) + { + case 1: + case 2: + case 6: + case 9: return false; + default: return true; + } + } + case 4: + { + switch (currentRegion) + { + case 1: + case 7: return false; + default: return true; + } + } + case 5: return false; // should never occur + case 6: + { + switch (currentRegion) + { + case 3: + case 9: return false; + default: return true; + } + } + case 7: + { + switch (currentRegion) + { + case 1: + case 4: + case 8: + case 9: return false; + default: return true; + } + } + case 8: + { + switch (currentRegion) + { + case 7: + case 9: return false; + default: return true; + } + } + case 9: + { + switch (currentRegion) + { + case 3: + case 6: + case 8: + case 7: return false; + default: return true; + } + } + default: return true; + } +} + + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method assumes that the \ref mayTraverse test has returned true, so there is a chance the + segment defined by (\a prevKey, \a prevValue) and (\a key, \a value) goes through the visible + region 5. + + The return value of this method indicates whether the segment actually traverses region 5 or not. + + If the segment traverses 5, the output parameters \a crossA and \a crossB indicate the entry and + exit points of region 5. They will become the optimized points for that segment. +*/ +bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const +{ + // The intersection point interpolation here is done in pixel coordinates, so we don't need to + // differentiate between different axis scale types. Note that the nomenclature + // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be + // different in pixel coordinates (horz/vert key axes, reversed ranges) + + QList intersections; + const double valueMinPx = mValueAxis->coordToPixel(valueMin); + const double valueMaxPx = mValueAxis->coordToPixel(valueMax); + const double keyMinPx = mKeyAxis->coordToPixel(keyMin); + const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); + const double keyPx = mKeyAxis->coordToPixel(key); + const double valuePx = mValueAxis->coordToPixel(value); + const double prevKeyPx = mKeyAxis->coordToPixel(prevKey); + const double prevValuePx = mValueAxis->coordToPixel(prevValue); + if (qFuzzyIsNull(key-prevKey)) // line is parallel to value axis + { + // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMinPx) : QPointF(valueMinPx, keyPx)); // direction will be taken care of at end of method + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMaxPx) : QPointF(valueMaxPx, keyPx)); + } else if (qFuzzyIsNull(value-prevValue)) // line is parallel to key axis + { + // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, valuePx) : QPointF(valuePx, keyMinPx)); // direction will be taken care of at end of method + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, valuePx) : QPointF(valuePx, keyMaxPx)); + } else // line is skewed + { + double gamma; + double keyPerValuePx = (keyPx-prevKeyPx)/(valuePx-prevValuePx); + // check top of rect: + gamma = prevKeyPx + (valueMaxPx-prevValuePx)*keyPerValuePx; + if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMaxPx) : QPointF(valueMaxPx, gamma)); + // check bottom of rect: + gamma = prevKeyPx + (valueMinPx-prevValuePx)*keyPerValuePx; + if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMinPx) : QPointF(valueMinPx, gamma)); + const double valuePerKeyPx = 1.0/keyPerValuePx; + // check left of rect: + gamma = prevValuePx + (keyMinPx-prevKeyPx)*valuePerKeyPx; + if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, gamma) : QPointF(gamma, keyMinPx)); + // check right of rect: + gamma = prevValuePx + (keyMaxPx-prevKeyPx)*valuePerKeyPx; + if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, gamma) : QPointF(gamma, keyMaxPx)); + } + + // handle cases where found points isn't exactly 2: + if (intersections.size() > 2) + { + // line probably goes through corner of rect, and we got duplicate points there. single out the point pair with greatest distance in between: + double distSqrMax = 0; + QPointF pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = intersections.at(i); + pv2 = intersections.at(k); + distSqrMax = distSqr; + } + } + } + intersections = QList() << pv1 << pv2; + } else if (intersections.size() != 2) + { + // one or even zero points found (shouldn't happen unless line perfectly tangent to corner), no need to draw segment + return false; + } + + // possibly re-sort points so optimized point segment has same direction as original segment: + double xDelta = keyPx-prevKeyPx; + double yDelta = valuePx-prevValuePx; + if (mKeyAxis->orientation() != Qt::Horizontal) + qSwap(xDelta, yDelta); + if (xDelta*(intersections.at(1).x()-intersections.at(0).x()) + yDelta*(intersections.at(1).y()-intersections.at(0).y()) < 0) // scalar product of both segments < 0 -> opposite direction + intersections.move(0, 1); + crossA = intersections.at(0); + crossB = intersections.at(1); + return true; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method assumes that the \ref getTraverse test has returned true, so the segment definitely + traverses the visible region 5 when going from \a prevRegion to \a currentRegion. + + In certain situations it is not sufficient to merely generate the entry and exit points of the + segment into/out of region 5, as \ref getTraverse provides. It may happen that a single segment, in + addition to traversing region 5, skips another region outside of region 5, which makes it + necessary to add an optimized corner point there (very similar to the job \ref + getOptimizedCornerPoints does for segments that are completely in outside regions and don't + traverse 5). + + As an example, consider a segment going from region 1 to region 6, traversing the lower left + corner of region 5. In this configuration, the segment additionally crosses the border between + region 1 and 2 before entering region 5. This makes it necessary to add an additional point in + the top left corner, before adding the optimized traverse points. So in this case, the output + parameter \a beforeTraverse will contain the top left corner point, and \a afterTraverse will be + empty. + + In some cases, such as when going from region 1 to 9, it may even be necessary to add additional + corner points before and after the traverse. Then both \a beforeTraverse and \a afterTraverse + return the respective corner points. +*/ +void QCPCurve::getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const +{ + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 6: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } + case 9: { beforeTraverse << coordsToPixels(keyMin, valueMax); afterTraverse << coordsToPixels(keyMax, valueMin); break; } + case 8: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } + } + break; + } + case 2: + { + switch (currentRegion) + { + case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } + case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 3: + { + switch (currentRegion) + { + case 4: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } + case 7: { beforeTraverse << coordsToPixels(keyMin, valueMin); afterTraverse << coordsToPixels(keyMax, valueMax); break; } + case 8: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 4: + { + switch (currentRegion) + { + case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } + case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 5: { break; } // shouldn't happen because this method only handles full traverses + case 6: + { + switch (currentRegion) + { + case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 7: + { + switch (currentRegion) + { + case 2: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } + case 3: { beforeTraverse << coordsToPixels(keyMax, valueMax); afterTraverse << coordsToPixels(keyMin, valueMin); break; } + case 6: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 8: + { + switch (currentRegion) + { + case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 9: + { + switch (currentRegion) + { + case 2: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } + case 1: { beforeTraverse << coordsToPixels(keyMax, valueMin); afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 4: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + } +} + +/*! \internal + + Calculates the (minimum) distance (in pixels) the curve's representation has from the given \a + pixelPoint in pixels. This is used to determine whether the curve was clicked or not, e.g. in + \ref selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that + if the curve has a line representation, the returned distance may be smaller than the distance to + the \a closestData point, since the distance to the curve line is also taken into account. + + If either the curve has no data or if the line style is \ref lsNone and the scatter style's shape + is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the curve), returns + -1.0. +*/ +double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (mDataContainer->isEmpty()) + return -1.0; + if (mLineStyle == lsNone && mScatterStyle.isNone()) + return -1.0; + + if (mDataContainer->size() == 1) + { + QPointF dataPoint = coordsToPixels(mDataContainer->constBegin()->key, mDataContainer->constBegin()->value); + closestData = mDataContainer->constBegin(); + return QCPVector2D(dataPoint-pixelPoint).length(); + } + + // calculate minimum distances to curve data points and find closestData iterator: + double minDistSqr = std::numeric_limits::max(); + // iterate over found data points and then choose the one with the shortest distance to pos: + QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); + for (QCPCurveDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestData = it; + } + } + + // calculate distance to line if there is one (if so, will probably be smaller than distance to closest data point): + if (mLineStyle != lsNone) + { + QVector lines; + getCurveLines(&lines, QCPDataRange(0, dataCount()), mParentPlot->selectionTolerance()*1.2); // optimized lines outside axis rect shouldn't respond to clicks at the edge, so use 1.2*tolerance as pen width + for (int i=0; i QCPBarsGroup::bars() const + + Returns all bars currently in this group. + + \see bars(int index) +*/ + +/*! \fn int QCPBarsGroup::size() const + + Returns the number of QCPBars plottables that are part of this group. + +*/ + +/*! \fn bool QCPBarsGroup::isEmpty() const + + Returns whether this bars group is empty. + + \see size +*/ + +/*! \fn bool QCPBarsGroup::contains(QCPBars *bars) + + Returns whether the specified \a bars plottable is part of this group. + +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a new bars group for the specified QCustomPlot instance. +*/ +QCPBarsGroup::QCPBarsGroup(QCustomPlot *parentPlot) : + QObject(parentPlot), + mParentPlot(parentPlot), + mSpacingType(stAbsolute), + mSpacing(4) +{ +} + +QCPBarsGroup::~QCPBarsGroup() +{ + clear(); +} + +/*! + Sets how the spacing between adjacent bars is interpreted. See \ref SpacingType. + + The actual spacing can then be specified with \ref setSpacing. + + \see setSpacing +*/ +void QCPBarsGroup::setSpacingType(SpacingType spacingType) +{ + mSpacingType = spacingType; +} + +/*! + Sets the spacing between adjacent bars. What the number passed as \a spacing actually means, is + defined by the current \ref SpacingType, which can be set with \ref setSpacingType. + + \see setSpacingType +*/ +void QCPBarsGroup::setSpacing(double spacing) +{ + mSpacing = spacing; +} + +/*! + Returns the QCPBars instance with the specified \a index in this group. If no such QCPBars + exists, returns 0. + + \see bars(), size +*/ +QCPBars *QCPBarsGroup::bars(int index) const +{ + if (index >= 0 && index < mBars.size()) + { + return mBars.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! + Removes all QCPBars plottables from this group. + + \see isEmpty +*/ +void QCPBarsGroup::clear() +{ + foreach (QCPBars *bars, mBars) // since foreach takes a copy, removing bars in the loop is okay + bars->setBarsGroup(0); // removes itself via removeBars +} + +/*! + Adds the specified \a bars plottable to this group. Alternatively, you can also use \ref + QCPBars::setBarsGroup on the \a bars instance. + + \see insert, remove +*/ +void QCPBarsGroup::append(QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + if (!mBars.contains(bars)) + bars->setBarsGroup(this); + else + qDebug() << Q_FUNC_INFO << "bars plottable is already in this bars group:" << reinterpret_cast(bars); +} + +/*! + Inserts the specified \a bars plottable into this group at the specified index position \a i. + This gives you full control over the ordering of the bars. + + \a bars may already be part of this group. In that case, \a bars is just moved to the new index + position. + + \see append, remove +*/ +void QCPBarsGroup::insert(int i, QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + // first append to bars list normally: + if (!mBars.contains(bars)) + bars->setBarsGroup(this); + // then move to according position: + mBars.move(mBars.indexOf(bars), qBound(0, i, mBars.size()-1)); +} + +/*! + Removes the specified \a bars plottable from this group. + + \see contains, clear +*/ +void QCPBarsGroup::remove(QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + if (mBars.contains(bars)) + bars->setBarsGroup(0); + else + qDebug() << Q_FUNC_INFO << "bars plottable is not in this bars group:" << reinterpret_cast(bars); +} + +/*! \internal + + Adds the specified \a bars to the internal mBars list of bars. This method does not change the + barsGroup property on \a bars. + + \see unregisterBars +*/ +void QCPBarsGroup::registerBars(QCPBars *bars) +{ + if (!mBars.contains(bars)) + mBars.append(bars); +} + +/*! \internal + + Removes the specified \a bars from the internal mBars list of bars. This method does not change + the barsGroup property on \a bars. + + \see registerBars +*/ +void QCPBarsGroup::unregisterBars(QCPBars *bars) +{ + mBars.removeOne(bars); +} + +/*! \internal + + Returns the pixel offset in the key dimension the specified \a bars plottable should have at the + given key coordinate \a keyCoord. The offset is relative to the pixel position of the key + coordinate \a keyCoord. +*/ +double QCPBarsGroup::keyPixelOffset(const QCPBars *bars, double keyCoord) +{ + // find list of all base bars in case some mBars are stacked: + QList baseBars; + foreach (const QCPBars *b, mBars) + { + while (b->barBelow()) + b = b->barBelow(); + if (!baseBars.contains(b)) + baseBars.append(b); + } + // find base bar this "bars" is stacked on: + const QCPBars *thisBase = bars; + while (thisBase->barBelow()) + thisBase = thisBase->barBelow(); + + // determine key pixel offset of this base bars considering all other base bars in this barsgroup: + double result = 0; + int index = baseBars.indexOf(thisBase); + if (index >= 0) + { + if (baseBars.size() % 2 == 1 && index == (baseBars.size()-1)/2) // is center bar (int division on purpose) + { + return result; + } else + { + double lowerPixelWidth, upperPixelWidth; + int startIndex; + int dir = (index <= (baseBars.size()-1)/2) ? -1 : 1; // if bar is to lower keys of center, dir is negative + if (baseBars.size() % 2 == 0) // even number of bars + { + startIndex = baseBars.size()/2 + (dir < 0 ? -1 : 0); + result += getPixelSpacing(baseBars.at(startIndex), keyCoord)*0.5; // half of middle spacing + } else // uneven number of bars + { + startIndex = (baseBars.size()-1)/2+dir; + baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; // half of center bar + result += getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord); // center bar spacing + } + for (int i = startIndex; i != index; i += dir) // add widths and spacings of bars in between center and our bars + { + baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth); + result += getPixelSpacing(baseBars.at(i), keyCoord); + } + // finally half of our bars width: + baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; + // correct sign of result depending on orientation and direction of key axis: + result *= dir*thisBase->keyAxis()->pixelOrientation(); + } + } + return result; +} + +/*! \internal + + Returns the spacing in pixels which is between this \a bars and the following one, both at the + key coordinate \a keyCoord. + + \note Typically the returned value doesn't depend on \a bars or \a keyCoord. \a bars is only + needed to get access to the key axis transformation and axis rect for the modes \ref + stAxisRectRatio and \ref stPlotCoords. The \a keyCoord is only relevant for spacings given in + \ref stPlotCoords on a logarithmic axis. +*/ +double QCPBarsGroup::getPixelSpacing(const QCPBars *bars, double keyCoord) +{ + switch (mSpacingType) + { + case stAbsolute: + { + return mSpacing; + } + case stAxisRectRatio: + { + if (bars->keyAxis()->orientation() == Qt::Horizontal) + return bars->keyAxis()->axisRect()->width()*mSpacing; + else + return bars->keyAxis()->axisRect()->height()*mSpacing; + } + case stPlotCoords: + { + double keyPixel = bars->keyAxis()->coordToPixel(keyCoord); + return qAbs(bars->keyAxis()->coordToPixel(keyCoord+mSpacing)-keyPixel); + } + } + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBarsData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBarsData + \brief Holds the data of one single data point (one bar) for QCPBars. + + The stored data is: + \li \a key: coordinate on the key axis of this bar (this is the \a mainKey and the \a sortKey) + \li \a value: height coordinate on the value axis of this bar (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPBarsDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPBarsData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPBarsDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPBarsData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPBarsData QCPBarsData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPBarsData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPBarsData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPBarsData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPBarsData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a bar data point with key and value set to zero. +*/ +QCPBarsData::QCPBarsData() : + key(0), + value(0) +{ +} + +/*! + Constructs a bar data point with the specified \a key and \a value. +*/ +QCPBarsData::QCPBarsData(double key, double value) : + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBars +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBars + \brief A plottable representing a bar chart in a plot. + + \image html QCPBars.png + + To plot data, assign it with the \ref setData or \ref addData functions. + + \section qcpbars-appearance Changing the appearance + + The appearance of the bars is determined by the pen and the brush (\ref setPen, \ref setBrush). + The width of the individual bars can be controlled with \ref setWidthType and \ref setWidth. + + Bar charts are stackable. This means, two QCPBars plottables can be placed on top of each other + (see \ref QCPBars::moveAbove). So when two bars are at the same key position, they will appear + stacked. + + If you would like to group multiple QCPBars plottables together so they appear side by side as + shown below, use QCPBarsGroup. + + \image html QCPBarsGroup.png + + \section qcpbars-usage Usage + + Like all data representing objects in QCustomPlot, the QCPBars is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-2 +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPBars::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPBarsDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/*! \fn QCPBars *QCPBars::barBelow() const + Returns the bars plottable that is directly below this bars plottable. + If there is no such plottable, returns 0. + + \see barAbove, moveBelow, moveAbove +*/ + +/*! \fn QCPBars *QCPBars::barAbove() const + Returns the bars plottable that is directly above this bars plottable. + If there is no such plottable, returns 0. + + \see barBelow, moveBelow, moveAbove +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a bar chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPBars is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPBars, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPBars::QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mWidth(0.75), + mWidthType(wtPlotCoords), + mBarsGroup(0), + mBaseValue(0), + mStackingGap(0) +{ + // modify inherited properties from abstract plottable: + mPen.setColor(Qt::blue); + mPen.setStyle(Qt::SolidLine); + mBrush.setColor(QColor(40, 50, 255, 30)); + mBrush.setStyle(Qt::SolidPattern); + mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); +} + +QCPBars::~QCPBars() +{ + setBarsGroup(0); + if (mBarBelow || mBarAbove) + connectBars(mBarBelow.data(), mBarAbove.data()); // take this bar out of any stacking +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPBars may share the same data container safely. + Modifying the data in the container will then affect all bars that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the bar's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-2 + + \see addData +*/ +void QCPBars::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPBars::setData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, values, alreadySorted); +} + +/*! + Sets the width of the bars. + + How the number passed as \a width is interpreted (e.g. screen pixels, plot coordinates,...), + depends on the currently set width type, see \ref setWidthType and \ref WidthType. +*/ +void QCPBars::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets how the width of the bars is defined. See the documentation of \ref WidthType for an + explanation of the possible values for \a widthType. + + The default value is \ref wtPlotCoords. + + \see setWidth +*/ +void QCPBars::setWidthType(QCPBars::WidthType widthType) +{ + mWidthType = widthType; +} + +/*! + Sets to which QCPBarsGroup this QCPBars instance belongs to. Alternatively, you can also use \ref + QCPBarsGroup::append. + + To remove this QCPBars from any group, set \a barsGroup to 0. +*/ +void QCPBars::setBarsGroup(QCPBarsGroup *barsGroup) +{ + // deregister at old group: + if (mBarsGroup) + mBarsGroup->unregisterBars(this); + mBarsGroup = barsGroup; + // register at new group: + if (mBarsGroup) + mBarsGroup->registerBars(this); +} + +/*! + Sets the base value of this bars plottable. + + The base value defines where on the value coordinate the bars start. How far the bars extend from + the base value is given by their individual value data. For example, if the base value is set to + 1, a bar with data value 2 will have its lowest point at value coordinate 1 and highest point at + 3. + + For stacked bars, only the base value of the bottom-most QCPBars has meaning. + + The default base value is 0. +*/ +void QCPBars::setBaseValue(double baseValue) +{ + mBaseValue = baseValue; +} + +/*! + If this bars plottable is stacked on top of another bars plottable (\ref moveAbove), this method + allows specifying a distance in \a pixels, by which the drawn bar rectangles will be separated by + the bars below it. +*/ +void QCPBars::setStackingGap(double pixels) +{ + mStackingGap = pixels; +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPBars::addData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + Adds the provided data point as \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPBars::addData(double key, double value) +{ + mDataContainer->add(QCPBarsData(key, value)); +} + +/*! + Moves this bars plottable below \a bars. In other words, the bars of this plottable will appear + below the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object below itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to 0. + + \see moveBelow, barAbove, barBelow +*/ +void QCPBars::moveBelow(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar below it: + if (bars) + { + if (bars->mBarBelow) + connectBars(bars->mBarBelow.data(), this); + connectBars(this, bars); + } +} + +/*! + Moves this bars plottable above \a bars. In other words, the bars of this plottable will appear + above the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object above itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to 0. + + \see moveBelow, barBelow, barAbove +*/ +void QCPBars::moveAbove(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar above it: + if (bars) + { + if (bars->mBarAbove) + connectBars(this, bars->mBarAbove.data()); + connectBars(bars, this); + } +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPBars::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(getBarRect(it->key, it->value))) + result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +double QCPBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (getBarRect(it->key, it->value).contains(pos)) + { + if (details) + { + int pointIndex = it-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return mParentPlot->selectionTolerance()*0.99; + } + } + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + /* Note: If this QCPBars uses absolute pixels as width (or is in a QCPBarsGroup with spacing in + absolute pixels), using this method to adapt the key axis range to fit the bars into the + currently visible axis range will not work perfectly. Because in the moment the axis range is + changed to the new range, the fixed pixel widths/spacings will represent different coordinate + spans than before, which in turn would require a different key range to perfectly fit, and so on. + The only solution would be to iteratively approach the perfect fitting axis range, but the + mismatch isn't large enough in most applications, to warrant this here. If a user does need a + better fit, he should call the corresponding axis rescale multiple times in a row. + */ + QCPRange range; + range = mDataContainer->keyRange(foundRange, inSignDomain); + + // determine exact range of bars by including bar width and barsgroup offset: + if (foundRange && mKeyAxis) + { + double lowerPixelWidth, upperPixelWidth, keyPixel; + // lower range bound: + getPixelWidth(range.lower, lowerPixelWidth, upperPixelWidth); + keyPixel = mKeyAxis.data()->coordToPixel(range.lower) + lowerPixelWidth; + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, range.lower); + const double lowerCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); + if (!qIsNaN(lowerCorrected) && qIsFinite(lowerCorrected) && range.lower > lowerCorrected) + range.lower = lowerCorrected; + // upper range bound: + getPixelWidth(range.upper, lowerPixelWidth, upperPixelWidth); + keyPixel = mKeyAxis.data()->coordToPixel(range.upper) + upperPixelWidth; + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, range.upper); + const double upperCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); + if (!qIsNaN(upperCorrected) && qIsFinite(upperCorrected) && range.upper < upperCorrected) + range.upper = upperCorrected; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + // Note: can't simply use mDataContainer->valueRange here because we need to + // take into account bar base value and possible stacking of multiple bars + QCPRange range; + range.lower = mBaseValue; + range.upper = mBaseValue; + bool haveLower = true; // set to true, because baseValue should always be visible in bar charts + bool haveUpper = true; // set to true, because baseValue should always be visible in bar charts + QCPBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + if (inKeyRange != QCPRange()) + { + itBegin = mDataContainer->findBegin(inKeyRange.lower); + itEnd = mDataContainer->findEnd(inKeyRange.upper); + } + for (QCPBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + const double current = it->value + getStackedBaseValue(it->key, it->value >= 0); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } + + foundRange = true; // return true because bar charts always have the 0-line visible + return range; +} + +/* inherits documentation from base class */ +QPointF QCPBars::dataPixelPosition(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + const QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; + const double valuePixel = valueAxis->coordToPixel(getStackedBaseValue(it->key, it->value >= 0) + it->value); + const double keyPixel = keyAxis->coordToPixel(it->key) + (mBarsGroup ? mBarsGroup->keyPixelOffset(this, it->key) : 0); + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyPixel, valuePixel); + else + return QPointF(valuePixel, keyPixel); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QPointF(); + } +} + +/* inherits documentation from base class */ +void QCPBars::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mDataContainer->isEmpty()) return; + + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPBarsDataContainer::const_iterator begin = visibleBegin; + QCPBarsDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + for (QCPBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + if (QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); +#endif + // draw bar: + if (isSelectedSegment && mSelectionDecorator) + { + mSelectionDecorator->applyBrush(painter); + mSelectionDecorator->applyPen(painter); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + } + applyDefaultAntialiasingHint(painter); + painter->drawPolygon(getBarRect(it->key, it->value)); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setBrush(mBrush); + painter->setPen(mPen); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! \internal + + called by \ref draw to determine which data (key) range is visible at the current key axis range + setting, so only that needs to be processed. It also takes into account the bar width. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a end returns an iterator one higher than the highest visible data point. Same as before, \a end + may also lie just outside of the visible range. + + if the plottable contains no data, both \a begin and \a end point to constEnd. +*/ +void QCPBars::getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + if (mDataContainer->isEmpty()) + { + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + + // get visible data range as QMap iterators + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower); + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper); + double lowerPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().lower); + double upperPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().upper); + bool isVisible = false; + // walk left from begin to find lower bar that actually is completely outside visible pixel range: + QCPBarsDataContainer::const_iterator it = begin; + while (it != mDataContainer->constBegin()) + { + --it; + const QRectF barRect = getBarRect(it->key, it->value); + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.right() >= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.left() <= lowerPixelBound)); + else // keyaxis is vertical + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.top() <= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.bottom() >= lowerPixelBound)); + if (isVisible) + begin = it; + else + break; + } + // walk right from ubound to find upper bar that actually is completely outside visible pixel range: + it = end; + while (it != mDataContainer->constEnd()) + { + const QRectF barRect = getBarRect(it->key, it->value); + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.left() <= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.right() >= upperPixelBound)); + else // keyaxis is vertical + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.bottom() >= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.top() <= upperPixelBound)); + if (isVisible) + end = it+1; + else + break; + ++it; + } +} + +/*! \internal + + Returns the rect in pixel coordinates of a single bar with the specified \a key and \a value. The + rect is shifted according to the bar stacking (see \ref moveAbove) and base value (see \ref + setBaseValue), and to have non-overlapping border lines with the bars stacked below. +*/ +QRectF QCPBars::getBarRect(double key, double value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QRectF(); } + + double lowerPixelWidth, upperPixelWidth; + getPixelWidth(key, lowerPixelWidth, upperPixelWidth); + double base = getStackedBaseValue(key, value >= 0); + double basePixel = valueAxis->coordToPixel(base); + double valuePixel = valueAxis->coordToPixel(base+value); + double keyPixel = keyAxis->coordToPixel(key); + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, key); + double bottomOffset = (mBarBelow && mPen != Qt::NoPen ? 1 : 0)*(mPen.isCosmetic() ? 1 : mPen.widthF()); + bottomOffset += mBarBelow ? mStackingGap : 0; + bottomOffset *= (value<0 ? -1 : 1)*valueAxis->pixelOrientation(); + if (qAbs(valuePixel-basePixel) <= qAbs(bottomOffset)) + bottomOffset = valuePixel-basePixel; + if (keyAxis->orientation() == Qt::Horizontal) + { + return QRectF(QPointF(keyPixel+lowerPixelWidth, valuePixel), QPointF(keyPixel+upperPixelWidth, basePixel+bottomOffset)).normalized(); + } else + { + return QRectF(QPointF(basePixel+bottomOffset, keyPixel+lowerPixelWidth), QPointF(valuePixel, keyPixel+upperPixelWidth)).normalized(); + } +} + +/*! \internal + + This function is used to determine the width of the bar at coordinate \a key, according to the + specified width (\ref setWidth) and width type (\ref setWidthType). + + The output parameters \a lower and \a upper return the number of pixels the bar extends to lower + and higher keys, relative to the \a key coordinate (so with a non-reversed horizontal axis, \a + lower is negative and \a upper positive). +*/ +void QCPBars::getPixelWidth(double key, double &lower, double &upper) const +{ + lower = 0; + upper = 0; + switch (mWidthType) + { + case wtAbsolute: + { + upper = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + lower = -upper; + break; + } + case wtAxisRectRatio: + { + if (mKeyAxis && mKeyAxis.data()->axisRect()) + { + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + upper = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + else + upper = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + lower = -upper; + } else + qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; + break; + } + case wtPlotCoords: + { + if (mKeyAxis) + { + double keyPixel = mKeyAxis.data()->coordToPixel(key); + upper = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; + lower = mKeyAxis.data()->coordToPixel(key-mWidth*0.5)-keyPixel; + // no need to qSwap(lower, higher) when range reversed, because higher/lower are gained by + // coordinate transform which includes range direction + } else + qDebug() << Q_FUNC_INFO << "No key axis defined"; + break; + } + } +} + +/*! \internal + + This function is called to find at which value to start drawing the base of a bar at \a key, when + it is stacked on top of another QCPBars (e.g. with \ref moveAbove). + + positive and negative bars are separated per stack (positive are stacked above baseValue upwards, + negative are stacked below baseValue downwards). This can be indicated with \a positive. So if the + bar for which we need the base value is negative, set \a positive to false. +*/ +double QCPBars::getStackedBaseValue(double key, bool positive) const +{ + if (mBarBelow) + { + double max = 0; // don't initialize with mBaseValue here because only base value of bottom-most bar has meaning in a bar stack + // find bars of mBarBelow that are approximately at key and find largest one: + double epsilon = qAbs(key)*(sizeof(key)==4 ? 1e-6 : 1e-14); // should be safe even when changed to use float at some point + if (key == 0) + epsilon = (sizeof(key)==4 ? 1e-6 : 1e-14); + QCPBarsDataContainer::const_iterator it = mBarBelow.data()->mDataContainer->findBegin(key-epsilon); + QCPBarsDataContainer::const_iterator itEnd = mBarBelow.data()->mDataContainer->findEnd(key+epsilon); + while (it != itEnd) + { + if (it->key > key-epsilon && it->key < key+epsilon) + { + if ((positive && it->value > max) || + (!positive && it->value < max)) + max = it->value; + } + ++it; + } + // recurse down the bar-stack to find the total height: + return max + mBarBelow.data()->getStackedBaseValue(key, positive); + } else + return mBaseValue; +} + +/*! \internal + + Connects \a below and \a above to each other via their mBarAbove/mBarBelow properties. The bar(s) + currently above lower and below upper will become disconnected to lower/upper. + + If lower is zero, upper will be disconnected at the bottom. + If upper is zero, lower will be disconnected at the top. +*/ +void QCPBars::connectBars(QCPBars *lower, QCPBars *upper) +{ + if (!lower && !upper) return; + + if (!lower) // disconnect upper at bottom + { + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) + upper->mBarBelow.data()->mBarAbove = 0; + upper->mBarBelow = 0; + } else if (!upper) // disconnect lower at top + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) + lower->mBarAbove.data()->mBarBelow = 0; + lower->mBarAbove = 0; + } else // connect lower and upper + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) + lower->mBarAbove.data()->mBarBelow = 0; + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) + upper->mBarBelow.data()->mBarAbove = 0; + lower->mBarAbove = upper; + upper->mBarBelow = lower; + } +} +/* end of 'src/plottables/plottable-bars.cpp' */ + + +/* including file 'src/plottables/plottable-statisticalbox.cpp', size 28622 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPStatisticalBoxData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPStatisticalBoxData + \brief Holds the data of one single data point for QCPStatisticalBox. + + The stored data is: + + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + + \li \a minimum: the position of the lower whisker, typically the minimum measurement of the + sample that's not considered an outlier. + + \li \a lowerQuartile: the lower end of the box. The lower and the upper quartiles are the two + statistical quartiles around the median of the sample, they should contain 50% of the sample + data. + + \li \a median: the value of the median mark inside the quartile box. The median separates the + sample data in half (50% of the sample data is below/above the median). (This is the \a mainValue) + + \li \a upperQuartile: the upper end of the box. The lower and the upper quartiles are the two + statistical quartiles around the median of the sample, they should contain 50% of the sample + data. + + \li \a maximum: the position of the upper whisker, typically the maximum measurement of the + sample that's not considered an outlier. + + \li \a outliers: a QVector of outlier values that will be drawn as scatter points at the \a key + coordinate of this data point (see \ref QCPStatisticalBox::setOutlierStyle) + + The container for storing multiple data points is \ref QCPStatisticalBoxDataContainer. It is a + typedef for \ref QCPDataContainer with \ref QCPStatisticalBoxData as the DataType template + parameter. See the documentation there for an explanation regarding the data type's generic + methods. + + \see QCPStatisticalBoxDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPStatisticalBoxData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPStatisticalBoxData QCPStatisticalBoxData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPStatisticalBoxData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPStatisticalBoxData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPStatisticalBoxData::mainValue() const + + Returns the \a median member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPStatisticalBoxData::valueRange() const + + Returns a QCPRange spanning from the \a minimum to the \a maximum member of this statistical box + data point, possibly further expanded by outliers. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and all values set to zero. +*/ +QCPStatisticalBoxData::QCPStatisticalBoxData() : + key(0), + minimum(0), + lowerQuartile(0), + median(0), + upperQuartile(0), + maximum(0) +{ +} + +/*! + Constructs a data point with the specified \a key, \a minimum, \a lowerQuartile, \a median, \a + upperQuartile, \a maximum and optionally a number of \a outliers. +*/ +QCPStatisticalBoxData::QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) : + key(key), + minimum(minimum), + lowerQuartile(lowerQuartile), + median(median), + upperQuartile(upperQuartile), + maximum(maximum), + outliers(outliers) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPStatisticalBox +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPStatisticalBox + \brief A plottable representing a single statistical box in a plot. + + \image html QCPStatisticalBox.png + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the data via the \ref data method, which returns a pointer to the internal + \ref QCPStatisticalBoxDataContainer. + + Additionally each data point can itself have a list of outliers, drawn as scatter points at the + key coordinate of the respective statistical box data point. They can either be set by using the + respective \ref addData(double,double,double,double,double,double,const QVector&) + "addData" method or accessing the individual data points through \ref data, and setting the + QVector outliers of the data points directly. + + \section qcpstatisticalbox-appearance Changing the appearance + + The appearance of each data point box, ranging from the lower to the upper quartile, is + controlled via \ref setPen and \ref setBrush. You may change the width of the boxes with \ref + setWidth in plot coordinates. + + Each data point's visual representation also consists of two whiskers. Whiskers are the lines + which reach from the upper quartile to the maximum, and from the lower quartile to the minimum. + The appearance of the whiskers can be modified with: \ref setWhiskerPen, \ref setWhiskerBarPen, + \ref setWhiskerWidth. The whisker width is the width of the bar perpendicular to the whisker at + the top (for maximum) and bottom (for minimum). If the whisker pen is changed, make sure to set + the \c capStyle to \c Qt::FlatCap. Otherwise the backbone line might exceed the whisker bars by a + few pixels due to the pen cap being not perfectly flat. + + The median indicator line inside the box has its own pen, \ref setMedianPen. + + The outlier data points are drawn as normal scatter points. Their look can be controlled with + \ref setOutlierStyle + + \section qcpstatisticalbox-usage Usage + + Like all data representing objects in QCustomPlot, the QCPStatisticalBox is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-2 +*/ + +/* start documentation of inline functions */ + +/*! \fn QSharedPointer QCPStatisticalBox::data() const + + Returns a shared pointer to the internal data storage of type \ref + QCPStatisticalBoxDataContainer. You may use it to directly manipulate the data, which may be more + convenient and faster than using the regular \ref setData or \ref addData methods. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a statistical box which uses \a keyAxis as its key axis ("x") and \a valueAxis as its + value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and + not have the same orientation. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPStatisticalBox is automatically registered with the QCustomPlot instance inferred + from \a keyAxis. This QCustomPlot instance takes ownership of the QCPStatisticalBox, so do not + delete it manually but use QCustomPlot::removePlottable() instead. +*/ +QCPStatisticalBox::QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mWidth(0.5), + mWhiskerWidth(0.2), + mWhiskerPen(Qt::black, 0, Qt::DashLine, Qt::FlatCap), + mWhiskerBarPen(Qt::black), + mWhiskerAntialiased(false), + mMedianPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap), + mOutlierStyle(QCPScatterStyle::ssCircle, Qt::blue, 6) +{ + setPen(QPen(Qt::black)); + setBrush(Qt::NoBrush); +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPStatisticalBoxes may share the same data container + safely. Modifying the data in the container will then affect all statistical boxes that share the + container. Sharing can be achieved by simply exchanging the data containers wrapped in shared + pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the statistical box data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-2 + + \see addData +*/ +void QCPStatisticalBox::setData(QSharedPointer data) +{ + mDataContainer = data; +} +/*! \overload + + Replaces the current data with the provided points in \a keys, \a minimum, \a lowerQuartile, \a + median, \a upperQuartile and \a maximum. The provided vectors should have equal length. Else, the + number of added points will be the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPStatisticalBox::setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, minimum, lowerQuartile, median, upperQuartile, maximum, alreadySorted); +} + +/*! + Sets the width of the boxes in key coordinates. + + \see setWhiskerWidth +*/ +void QCPStatisticalBox::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the width of the whiskers in key coordinates. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + \see setWidth +*/ +void QCPStatisticalBox::setWhiskerWidth(double width) +{ + mWhiskerWidth = width; +} + +/*! + Sets the pen used for drawing the whisker backbone. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + Make sure to set the \c capStyle of the passed \a pen to \c Qt::FlatCap. Otherwise the backbone + line might exceed the whisker bars by a few pixels due to the pen cap being not perfectly flat. + + \see setWhiskerBarPen +*/ +void QCPStatisticalBox::setWhiskerPen(const QPen &pen) +{ + mWhiskerPen = pen; +} + +/*! + Sets the pen used for drawing the whisker bars. Those are the lines parallel to the key axis at + each end of the whisker backbone. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + \see setWhiskerPen +*/ +void QCPStatisticalBox::setWhiskerBarPen(const QPen &pen) +{ + mWhiskerBarPen = pen; +} + +/*! + Sets whether the statistical boxes whiskers are drawn with antialiasing or not. + + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPStatisticalBox::setWhiskerAntialiased(bool enabled) +{ + mWhiskerAntialiased = enabled; +} + +/*! + Sets the pen used for drawing the median indicator line inside the statistical boxes. +*/ +void QCPStatisticalBox::setMedianPen(const QPen &pen) +{ + mMedianPen = pen; +} + +/*! + Sets the appearance of the outlier data points. + + Outliers can be specified with the method + \ref addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) +*/ +void QCPStatisticalBox::setOutlierStyle(const QCPScatterStyle &style) +{ + mOutlierStyle = style; +} + +/*! \overload + + Adds the provided points in \a keys, \a minimum, \a lowerQuartile, \a median, \a upperQuartile and + \a maximum to the current data. The provided vectors should have equal length. Else, the number + of added points will be the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPStatisticalBox::addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) +{ + if (keys.size() != minimum.size() || minimum.size() != lowerQuartile.size() || lowerQuartile.size() != median.size() || + median.size() != upperQuartile.size() || upperQuartile.size() != maximum.size() || maximum.size() != keys.size()) + qDebug() << Q_FUNC_INFO << "keys, minimum, lowerQuartile, median, upperQuartile, maximum have different sizes:" + << keys.size() << minimum.size() << lowerQuartile.size() << median.size() << upperQuartile.size() << maximum.size(); + const int n = qMin(keys.size(), qMin(minimum.size(), qMin(lowerQuartile.size(), qMin(median.size(), qMin(upperQuartile.size(), maximum.size()))))); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->minimum = minimum[i]; + it->lowerQuartile = lowerQuartile[i]; + it->median = median[i]; + it->upperQuartile = upperQuartile[i]; + it->maximum = maximum[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key, \a minimum, \a lowerQuartile, \a median, \a upperQuartile + and \a maximum to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPStatisticalBox::addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) +{ + mDataContainer->add(QCPStatisticalBoxData(key, minimum, lowerQuartile, median, upperQuartile, maximum, outliers)); +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPStatisticalBox::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(getQuartileBox(it))) + result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +double QCPStatisticalBox::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + QCPStatisticalBoxDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + getVisibleDataBounds(visibleBegin, visibleEnd); + double minDistSqr = std::numeric_limits::max(); + for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (getQuartileBox(it).contains(pos)) // quartile box + { + double currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } else // whiskers + { + const QVector whiskerBackbones(getWhiskerBackboneLines(it)); + for (int i=0; iconstBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return qSqrt(minDistSqr); + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); + // determine exact range by including width of bars/flags: + if (foundRange) + { + if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) + range.lower -= mWidth*0.5; + if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) + range.upper += mWidth*0.5; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::draw(QCPPainter *painter) +{ + if (mDataContainer->isEmpty()) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPStatisticalBoxDataContainer::const_iterator begin = visibleBegin; + QCPStatisticalBoxDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + for (QCPStatisticalBoxDataContainer::const_iterator it=begin; it!=end; ++it) + { + // check data validity if flag set: +# ifdef QCUSTOMPLOT_CHECK_DATA + if (QCP::isInvalidData(it->key, it->minimum) || + QCP::isInvalidData(it->lowerQuartile, it->median) || + QCP::isInvalidData(it->upperQuartile, it->maximum)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range has invalid data." << "Plottable name:" << name(); + for (int i=0; ioutliers.size(); ++i) + if (QCP::isInvalidData(it->outliers.at(i))) + qDebug() << Q_FUNC_INFO << "Data point outlier at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); +# endif + + if (isSelectedSegment && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + QCPScatterStyle finalOutlierStyle = mOutlierStyle; + if (isSelectedSegment && mSelectionDecorator) + finalOutlierStyle = mSelectionDecorator->getFinalScatterStyle(mOutlierStyle); + drawStatisticalBox(painter, it, finalOutlierStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->setBrush(mBrush); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! + Draws the graphical representation of a single statistical box with the data given by the + iterator \a it with the provided \a painter. + + If the statistical box has a set of outlier data points, they are drawn with \a outlierStyle. + + \see getQuartileBox, getWhiskerBackboneLines, getWhiskerBarLines +*/ +void QCPStatisticalBox::drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const +{ + // draw quartile box: + applyDefaultAntialiasingHint(painter); + const QRectF quartileBox = getQuartileBox(it); + painter->drawRect(quartileBox); + // draw median line with cliprect set to quartile box: + painter->save(); + painter->setClipRect(quartileBox, Qt::IntersectClip); + painter->setPen(mMedianPen); + painter->drawLine(QLineF(coordsToPixels(it->key-mWidth*0.5, it->median), coordsToPixels(it->key+mWidth*0.5, it->median))); + painter->restore(); + // draw whisker lines: + applyAntialiasingHint(painter, mWhiskerAntialiased, QCP::aePlottables); + painter->setPen(mWhiskerPen); + painter->drawLines(getWhiskerBackboneLines(it)); + painter->setPen(mWhiskerBarPen); + painter->drawLines(getWhiskerBarLines(it)); + // draw outliers: + applyScattersAntialiasingHint(painter); + outlierStyle.applyTo(painter, mPen); + for (int i=0; ioutliers.size(); ++i) + outlierStyle.drawShape(painter, coordsToPixels(it->key, it->outliers.at(i))); +} + +/*! \internal + + called by \ref draw to determine which data (key) range is visible at the current key axis range + setting, so only that needs to be processed. It also takes into account the bar width. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a end returns an iterator one higher than the highest visible data point. Same as before, \a end + may also lie just outside of the visible range. + + if the plottable contains no data, both \a begin and \a end point to constEnd. +*/ +void QCPStatisticalBox::getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of box to include partially visible data points + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of box to include partially visible data points +} + +/*! \internal + + Returns the box in plot coordinates (keys in x, values in y of the returned rect) that covers the + value range from the lower to the upper quartile, of the data given by \a it. + + \see drawStatisticalBox, getWhiskerBackboneLines, getWhiskerBarLines +*/ +QRectF QCPStatisticalBox::getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QRectF result; + result.setTopLeft(coordsToPixels(it->key-mWidth*0.5, it->upperQuartile)); + result.setBottomRight(coordsToPixels(it->key+mWidth*0.5, it->lowerQuartile)); + return result; +} + +/*! \internal + + Returns the whisker backbones (keys in x, values in y of the returned lines) that cover the value + range from the minimum to the lower quartile, and from the upper quartile to the maximum of the + data given by \a it. + + \see drawStatisticalBox, getQuartileBox, getWhiskerBarLines +*/ +QVector QCPStatisticalBox::getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QVector result(2); + result[0].setPoints(coordsToPixels(it->key, it->lowerQuartile), coordsToPixels(it->key, it->minimum)); // min backbone + result[1].setPoints(coordsToPixels(it->key, it->upperQuartile), coordsToPixels(it->key, it->maximum)); // max backbone + return result; +} + +/*! \internal + + Returns the whisker bars (keys in x, values in y of the returned lines) that are placed at the + end of the whisker backbones, at the minimum and maximum of the data given by \a it. + + \see drawStatisticalBox, getQuartileBox, getWhiskerBackboneLines +*/ +QVector QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QVector result(2); + result[0].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->minimum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->minimum)); // min bar + result[1].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->maximum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->maximum)); // max bar + return result; +} +/* end of 'src/plottables/plottable-statisticalbox.cpp' */ + + +/* including file 'src/plottables/plottable-colormap.cpp', size 47881 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorMapData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorMapData + \brief Holds the two-dimensional data of a QCPColorMap plottable. + + This class is a data storage for \ref QCPColorMap. It holds a two-dimensional array, which \ref + QCPColorMap then displays as a 2D image in the plot, where the array values are represented by a + color, depending on the value. + + The size of the array can be controlled via \ref setSize (or \ref setKeySize, \ref setValueSize). + Which plot coordinates these cells correspond to can be configured with \ref setRange (or \ref + setKeyRange, \ref setValueRange). + + The data cells can be accessed in two ways: They can be directly addressed by an integer index + with \ref setCell. This is the fastest method. Alternatively, they can be addressed by their plot + coordinate with \ref setData. plot coordinate to cell index transformations and vice versa are + provided by the functions \ref coordToCell and \ref cellToCoord. + + A \ref QCPColorMapData also holds an on-demand two-dimensional array of alpha values which (if + allocated) has the same size as the data map. It can be accessed via \ref setAlpha, \ref + fillAlpha and \ref clearAlpha. The memory for the alpha map is only allocated if needed, i.e. on + the first call of \ref setAlpha. \ref clearAlpha restores full opacity and frees the alpha map. + + This class also buffers the minimum and maximum values that are in the data set, to provide + QCPColorMap::rescaleDataRange with the necessary information quickly. Setting a cell to a value + that is greater than the current maximum increases this maximum to the new value. However, + setting the cell that currently holds the maximum value to a smaller value doesn't decrease the + maximum again, because finding the true new maximum would require going through the entire data + array, which might be time consuming. The same holds for the data minimum. This functionality is + given by \ref recalculateDataBounds, such that you can decide when it is sensible to find the + true current minimum and maximum. The method QCPColorMap::rescaleDataRange offers a convenience + parameter \a recalculateDataBounds which may be set to true to automatically call \ref + recalculateDataBounds internally. +*/ + +/* start of documentation of inline functions */ + +/*! \fn bool QCPColorMapData::isEmpty() const + + Returns whether this instance carries no data. This is equivalent to having a size where at least + one of the dimensions is 0 (see \ref setSize). +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a new QCPColorMapData instance. The instance has \a keySize cells in the key direction + and \a valueSize cells in the value direction. These cells will be displayed by the \ref QCPColorMap + at the coordinates \a keyRange and \a valueRange. + + \see setSize, setKeySize, setValueSize, setRange, setKeyRange, setValueRange +*/ +QCPColorMapData::QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange) : + mKeySize(0), + mValueSize(0), + mKeyRange(keyRange), + mValueRange(valueRange), + mIsEmpty(true), + mData(0), + mAlpha(0), + mDataModified(true) +{ + setSize(keySize, valueSize); + fill(0); +} + +QCPColorMapData::~QCPColorMapData() +{ + if (mData) + delete[] mData; + if (mAlpha) + delete[] mAlpha; +} + +/*! + Constructs a new QCPColorMapData instance copying the data and range of \a other. +*/ +QCPColorMapData::QCPColorMapData(const QCPColorMapData &other) : + mKeySize(0), + mValueSize(0), + mIsEmpty(true), + mData(0), + mAlpha(0), + mDataModified(true) +{ + *this = other; +} + +/*! + Overwrites this color map data instance with the data stored in \a other. The alpha map state is + transferred, too. +*/ +QCPColorMapData &QCPColorMapData::operator=(const QCPColorMapData &other) +{ + if (&other != this) + { + const int keySize = other.keySize(); + const int valueSize = other.valueSize(); + if (!other.mAlpha && mAlpha) + clearAlpha(); + setSize(keySize, valueSize); + if (other.mAlpha && !mAlpha) + createAlpha(false); + setRange(other.keyRange(), other.valueRange()); + if (!isEmpty()) + { + memcpy(mData, other.mData, sizeof(mData[0])*keySize*valueSize); + if (mAlpha) + memcpy(mAlpha, other.mAlpha, sizeof(mAlpha[0])*keySize*valueSize); + } + mDataBounds = other.mDataBounds; + mDataModified = true; + } + return *this; +} + +/* undocumented getter */ +double QCPColorMapData::data(double key, double value) +{ + int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; + int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; + if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) + return mData[valueCell*mKeySize + keyCell]; + else + return 0; +} + +/* undocumented getter */ +double QCPColorMapData::cell(int keyIndex, int valueIndex) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + return mData[valueIndex*mKeySize + keyIndex]; + else + return 0; +} + +/*! + Returns the alpha map value of the cell with the indices \a keyIndex and \a valueIndex. + + If this color map data doesn't have an alpha map (because \ref setAlpha was never called after + creation or after a call to \ref clearAlpha), returns 255, which corresponds to full opacity. + + \see setAlpha +*/ +unsigned char QCPColorMapData::alpha(int keyIndex, int valueIndex) +{ + if (mAlpha && keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + return mAlpha[valueIndex*mKeySize + keyIndex]; + else + return 255; +} + +/*! + Resizes the data array to have \a keySize cells in the key dimension and \a valueSize cells in + the value dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting at least one of \a keySize or \a valueSize to zero frees the internal data array and \ref + isEmpty returns true. + + \see setRange, setKeySize, setValueSize +*/ +void QCPColorMapData::setSize(int keySize, int valueSize) +{ + if (keySize != mKeySize || valueSize != mValueSize) + { + mKeySize = keySize; + mValueSize = valueSize; + if (mData) + delete[] mData; + mIsEmpty = mKeySize == 0 || mValueSize == 0; + if (!mIsEmpty) + { +#ifdef __EXCEPTIONS + try { // 2D arrays get memory intensive fast. So if the allocation fails, at least output debug message +#endif + mData = new double[mKeySize*mValueSize]; +#ifdef __EXCEPTIONS + } catch (...) { mData = 0; } +#endif + if (mData) + fill(0); + else + qDebug() << Q_FUNC_INFO << "out of memory for data dimensions "<< mKeySize << "*" << mValueSize; + } else + mData = 0; + + if (mAlpha) // if we had an alpha map, recreate it with new size + createAlpha(); + + mDataModified = true; + } +} + +/*! + Resizes the data array to have \a keySize cells in the key dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting \a keySize to zero frees the internal data array and \ref isEmpty returns true. + + \see setKeyRange, setSize, setValueSize +*/ +void QCPColorMapData::setKeySize(int keySize) +{ + setSize(keySize, mValueSize); +} + +/*! + Resizes the data array to have \a valueSize cells in the value dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting \a valueSize to zero frees the internal data array and \ref isEmpty returns true. + + \see setValueRange, setSize, setKeySize +*/ +void QCPColorMapData::setValueSize(int valueSize) +{ + setSize(mKeySize, valueSize); +} + +/*! + Sets the coordinate ranges the data shall be distributed over. This defines the rectangular area + covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will + be cells centered on the key coordinates 2, 2.5 and 3. + + \see setSize +*/ +void QCPColorMapData::setRange(const QCPRange &keyRange, const QCPRange &valueRange) +{ + setKeyRange(keyRange); + setValueRange(valueRange); +} + +/*! + Sets the coordinate range the data shall be distributed over in the key dimension. Together with + the value range, This defines the rectangular area covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will + be cells centered on the key coordinates 2, 2.5 and 3. + + \see setRange, setValueRange, setSize +*/ +void QCPColorMapData::setKeyRange(const QCPRange &keyRange) +{ + mKeyRange = keyRange; +} + +/*! + Sets the coordinate range the data shall be distributed over in the value dimension. Together with + the key range, This defines the rectangular area covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the value size (\ref setValueSize) is 3 and \a valueRange is set to QCPRange(2, 3) there + will be cells centered on the value coordinates 2, 2.5 and 3. + + \see setRange, setKeyRange, setSize +*/ +void QCPColorMapData::setValueRange(const QCPRange &valueRange) +{ + mValueRange = valueRange; +} + +/*! + Sets the data of the cell, which lies at the plot coordinates given by \a key and \a value, to \a + z. + + \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or + value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes, + you shouldn't use the \ref QCPColorMapData::setData method as it uses a linear transformation to + determine the cell index. Rather directly access the cell index with \ref + QCPColorMapData::setCell. + + \see setCell, setRange +*/ +void QCPColorMapData::setData(double key, double value, double z) +{ + int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; + int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; + if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) + { + mData[valueCell*mKeySize + keyCell] = z; + if (z < mDataBounds.lower) + mDataBounds.lower = z; + if (z > mDataBounds.upper) + mDataBounds.upper = z; + mDataModified = true; + } +} + +/*! + Sets the data of the cell with indices \a keyIndex and \a valueIndex to \a z. The indices + enumerate the cells starting from zero, up to the map's size-1 in the respective dimension (see + \ref setSize). + + In the standard plot configuration (horizontal key axis and vertical value axis, both not + range-reversed), the cell with indices (0, 0) is in the bottom left corner and the cell with + indices (keySize-1, valueSize-1) is in the top right corner of the color map. + + \see setData, setSize +*/ +void QCPColorMapData::setCell(int keyIndex, int valueIndex, double z) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + { + mData[valueIndex*mKeySize + keyIndex] = z; + if (z < mDataBounds.lower) + mDataBounds.lower = z; + if (z > mDataBounds.upper) + mDataBounds.upper = z; + mDataModified = true; + } else + qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; +} + +/*! + Sets the alpha of the color map cell given by \a keyIndex and \a valueIndex to \a alpha. A value + of 0 for \a alpha results in a fully transparent cell, and a value of 255 results in a fully + opaque cell. + + If an alpha map doesn't exist yet for this color map data, it will be created here. If you wish + to restore full opacity and free any allocated memory of the alpha map, call \ref clearAlpha. + + Note that the cell-wise alpha which can be configured here is independent of any alpha configured + in the color map's gradient (\ref QCPColorGradient). If a cell is affected both by the cell-wise + and gradient alpha, the alpha values will be blended accordingly during rendering of the color + map. + + \see fillAlpha, clearAlpha +*/ +void QCPColorMapData::setAlpha(int keyIndex, int valueIndex, unsigned char alpha) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + { + if (mAlpha || createAlpha()) + { + mAlpha[valueIndex*mKeySize + keyIndex] = alpha; + mDataModified = true; + } + } else + qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; +} + +/*! + Goes through the data and updates the buffered minimum and maximum data values. + + Calling this method is only advised if you are about to call \ref QCPColorMap::rescaleDataRange + and can not guarantee that the cells holding the maximum or minimum data haven't been overwritten + with a smaller or larger value respectively, since the buffered maximum/minimum values have been + updated the last time. Why this is the case is explained in the class description (\ref + QCPColorMapData). + + Note that the method \ref QCPColorMap::rescaleDataRange provides a parameter \a + recalculateDataBounds for convenience. Setting this to true will call this method for you, before + doing the rescale. +*/ +void QCPColorMapData::recalculateDataBounds() +{ + if (mKeySize > 0 && mValueSize > 0) + { + double minHeight = mData[0]; + double maxHeight = mData[0]; + const int dataCount = mValueSize*mKeySize; + for (int i=0; i maxHeight) + maxHeight = mData[i]; + if (mData[i] < minHeight) + minHeight = mData[i]; + } + mDataBounds.lower = minHeight; + mDataBounds.upper = maxHeight; + } +} + +/*! + Frees the internal data memory. + + This is equivalent to calling \ref setSize "setSize(0, 0)". +*/ +void QCPColorMapData::clear() +{ + setSize(0, 0); +} + +/*! + Frees the internal alpha map. The color map will have full opacity again. +*/ +void QCPColorMapData::clearAlpha() +{ + if (mAlpha) + { + delete[] mAlpha; + mAlpha = 0; + mDataModified = true; + } +} + +/*! + Sets all cells to the value \a z. +*/ +void QCPColorMapData::fill(double z) +{ + const int dataCount = mValueSize*mKeySize; + for (int i=0; i(data); + return; + } + if (copy) + { + *mMapData = *data; + } else + { + delete mMapData; + mMapData = data; + } + mMapImageInvalidated = true; +} + +/*! + Sets the data range of this color map to \a dataRange. The data range defines which data values + are mapped to the color gradient. + + To make the data range span the full range of the data set, use \ref rescaleDataRange. + + \see QCPColorScale::setDataRange +*/ +void QCPColorMap::setDataRange(const QCPRange &dataRange) +{ + if (!QCPRange::validRange(dataRange)) return; + if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) + { + if (mDataScaleType == QCPAxis::stLogarithmic) + mDataRange = dataRange.sanitizedForLogScale(); + else + mDataRange = dataRange.sanitizedForLinScale(); + mMapImageInvalidated = true; + emit dataRangeChanged(mDataRange); + } +} + +/*! + Sets whether the data is correlated with the color gradient linearly or logarithmically. + + \see QCPColorScale::setDataScaleType +*/ +void QCPColorMap::setDataScaleType(QCPAxis::ScaleType scaleType) +{ + if (mDataScaleType != scaleType) + { + mDataScaleType = scaleType; + mMapImageInvalidated = true; + emit dataScaleTypeChanged(mDataScaleType); + if (mDataScaleType == QCPAxis::stLogarithmic) + setDataRange(mDataRange.sanitizedForLogScale()); + } +} + +/*! + Sets the color gradient that is used to represent the data. For more details on how to create an + own gradient or use one of the preset gradients, see \ref QCPColorGradient. + + The colors defined by the gradient will be used to represent data values in the currently set + data range, see \ref setDataRange. Data points that are outside this data range will either be + colored uniformly with the respective gradient boundary color, or the gradient will repeat, + depending on \ref QCPColorGradient::setPeriodic. + + \see QCPColorScale::setGradient +*/ +void QCPColorMap::setGradient(const QCPColorGradient &gradient) +{ + if (mGradient != gradient) + { + mGradient = gradient; + mMapImageInvalidated = true; + emit gradientChanged(mGradient); + } +} + +/*! + Sets whether the color map image shall use bicubic interpolation when displaying the color map + shrinked or expanded, and not at a 1:1 pixel-to-data scale. + + \image html QCPColorMap-interpolate.png "A 10*10 color map, with interpolation and without interpolation enabled" +*/ +void QCPColorMap::setInterpolate(bool enabled) +{ + mInterpolate = enabled; + mMapImageInvalidated = true; // because oversampling factors might need to change +} + +/*! + Sets whether the outer most data rows and columns are clipped to the specified key and value + range (see \ref QCPColorMapData::setKeyRange, \ref QCPColorMapData::setValueRange). + + if \a enabled is set to false, the data points at the border of the color map are drawn with the + same width and height as all other data points. Since the data points are represented by + rectangles of one color centered on the data coordinate, this means that the shown color map + extends by half a data point over the specified key/value range in each direction. + + \image html QCPColorMap-tightboundary.png "A color map, with tight boundary enabled and disabled" +*/ +void QCPColorMap::setTightBoundary(bool enabled) +{ + mTightBoundary = enabled; +} + +/*! + Associates the color scale \a colorScale with this color map. + + This means that both the color scale and the color map synchronize their gradient, data range and + data scale type (\ref setGradient, \ref setDataRange, \ref setDataScaleType). Multiple color maps + can be associated with one single color scale. This causes the color maps to also synchronize + those properties, via the mutual color scale. + + This function causes the color map to adopt the current color gradient, data range and data scale + type of \a colorScale. After this call, you may change these properties at either the color map + or the color scale, and the setting will be applied to both. + + Pass 0 as \a colorScale to disconnect the color scale from this color map again. +*/ +void QCPColorMap::setColorScale(QCPColorScale *colorScale) +{ + if (mColorScale) // unconnect signals from old color scale + { + disconnect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); + disconnect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); + disconnect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); + disconnect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + disconnect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); + disconnect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } + mColorScale = colorScale; + if (mColorScale) // connect signals to new color scale + { + setGradient(mColorScale.data()->gradient()); + setDataRange(mColorScale.data()->dataRange()); + setDataScaleType(mColorScale.data()->dataScaleType()); + connect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); + connect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); + connect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); + connect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + connect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); + connect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } +} + +/*! + Sets the data range (\ref setDataRange) to span the minimum and maximum values that occur in the + current data set. This corresponds to the \ref rescaleKeyAxis or \ref rescaleValueAxis methods, + only for the third data dimension of the color map. + + The minimum and maximum values of the data set are buffered in the internal QCPColorMapData + instance (\ref data). As data is updated via its \ref QCPColorMapData::setCell or \ref + QCPColorMapData::setData, the buffered minimum and maximum values are updated, too. For + performance reasons, however, they are only updated in an expanding fashion. So the buffered + maximum can only increase and the buffered minimum can only decrease. In consequence, changes to + the data that actually lower the maximum of the data set (by overwriting the cell holding the + current maximum with a smaller value), aren't recognized and the buffered maximum overestimates + the true maximum of the data set. The same happens for the buffered minimum. To recalculate the + true minimum and maximum by explicitly looking at each cell, the method + QCPColorMapData::recalculateDataBounds can be used. For convenience, setting the parameter \a + recalculateDataBounds calls this method before setting the data range to the buffered minimum and + maximum. + + \see setDataRange +*/ +void QCPColorMap::rescaleDataRange(bool recalculateDataBounds) +{ + if (recalculateDataBounds) + mMapData->recalculateDataBounds(); + setDataRange(mMapData->dataBounds()); +} + +/*! + Takes the current appearance of the color map and updates the legend icon, which is used to + represent this color map in the legend (see \ref QCPLegend). + + The \a transformMode specifies whether the rescaling is done by a faster, low quality image + scaling algorithm (Qt::FastTransformation) or by a slower, higher quality algorithm + (Qt::SmoothTransformation). + + The current color map appearance is scaled down to \a thumbSize. Ideally, this should be equal to + the size of the legend icon (see \ref QCPLegend::setIconSize). If it isn't exactly the configured + legend icon size, the thumb will be rescaled during drawing of the legend item. + + \see setDataRange +*/ +void QCPColorMap::updateLegendIcon(Qt::TransformationMode transformMode, const QSize &thumbSize) +{ + if (mMapImage.isNull() && !data()->isEmpty()) + updateMapImage(); // try to update map image if it's null (happens if no draw has happened yet) + + if (!mMapImage.isNull()) // might still be null, e.g. if data is empty, so check here again + { + bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); + bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); + mLegendIcon = QPixmap::fromImage(mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode); + } +} + +/* inherits documentation from base class */ +double QCPColorMap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mMapData->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (mMapData->keyRange().contains(posKey) && mMapData->valueRange().contains(posValue)) + { + if (details) + details->setValue(QCPDataSelection(QCPDataRange(0, 1))); // temporary solution, to facilitate whole-plottable selection. Replace in future version with segmented 2D selection. + return mParentPlot->selectionTolerance()*0.99; + } + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPColorMap::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + foundRange = true; + QCPRange result = mMapData->keyRange(); + result.normalize(); + if (inSignDomain == QCP::sdPositive) + { + if (result.lower <= 0 && result.upper > 0) + result.lower = result.upper*1e-3; + else if (result.lower <= 0 && result.upper <= 0) + foundRange = false; + } else if (inSignDomain == QCP::sdNegative) + { + if (result.upper >= 0 && result.lower < 0) + result.upper = result.lower*1e-3; + else if (result.upper >= 0 && result.lower >= 0) + foundRange = false; + } + return result; +} + +/* inherits documentation from base class */ +QCPRange QCPColorMap::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + if (inKeyRange != QCPRange()) + { + if (mMapData->keyRange().upper < inKeyRange.lower || mMapData->keyRange().lower > inKeyRange.upper) + { + foundRange = false; + return QCPRange(); + } + } + + foundRange = true; + QCPRange result = mMapData->valueRange(); + result.normalize(); + if (inSignDomain == QCP::sdPositive) + { + if (result.lower <= 0 && result.upper > 0) + result.lower = result.upper*1e-3; + else if (result.lower <= 0 && result.upper <= 0) + foundRange = false; + } else if (inSignDomain == QCP::sdNegative) + { + if (result.upper >= 0 && result.lower < 0) + result.upper = result.lower*1e-3; + else if (result.upper >= 0 && result.lower >= 0) + foundRange = false; + } + return result; +} + +/*! \internal + + Updates the internal map image buffer by going through the internal \ref QCPColorMapData and + turning the data values into color pixels with \ref QCPColorGradient::colorize. + + This method is called by \ref QCPColorMap::draw if either the data has been modified or the map image + has been invalidated for a different reason (e.g. a change of the data range with \ref + setDataRange). + + If the map cell count is low, the image created will be oversampled in order to avoid a + QPainter::drawImage bug which makes inner pixel boundaries jitter when stretch-drawing images + without smooth transform enabled. Accordingly, oversampling isn't performed if \ref + setInterpolate is true. +*/ +void QCPColorMap::updateMapImage() +{ + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) return; + if (mMapData->isEmpty()) return; + + const QImage::Format format = QImage::Format_ARGB32_Premultiplied; + const int keySize = mMapData->keySize(); + const int valueSize = mMapData->valueSize(); + int keyOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)keySize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on + int valueOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)valueSize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on + + // resize mMapImage to correct dimensions including possible oversampling factors, according to key/value axes orientation: + if (keyAxis->orientation() == Qt::Horizontal && (mMapImage.width() != keySize*keyOversamplingFactor || mMapImage.height() != valueSize*valueOversamplingFactor)) + mMapImage = QImage(QSize(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor), format); + else if (keyAxis->orientation() == Qt::Vertical && (mMapImage.width() != valueSize*valueOversamplingFactor || mMapImage.height() != keySize*keyOversamplingFactor)) + mMapImage = QImage(QSize(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor), format); + + if (mMapImage.isNull()) + { + qDebug() << Q_FUNC_INFO << "Couldn't create map image (possibly too large for memory)"; + mMapImage = QImage(QSize(10, 10), format); + mMapImage.fill(Qt::black); + } else + { + QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates. Either the final mMapImage, or if we need oversampling, mUndersampledMapImage + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) + { + // resize undersampled map image to actual key/value cell sizes: + if (keyAxis->orientation() == Qt::Horizontal && (mUndersampledMapImage.width() != keySize || mUndersampledMapImage.height() != valueSize)) + mUndersampledMapImage = QImage(QSize(keySize, valueSize), format); + else if (keyAxis->orientation() == Qt::Vertical && (mUndersampledMapImage.width() != valueSize || mUndersampledMapImage.height() != keySize)) + mUndersampledMapImage = QImage(QSize(valueSize, keySize), format); + localMapImage = &mUndersampledMapImage; // make the colorization run on the undersampled image + } else if (!mUndersampledMapImage.isNull()) + mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has changed) but mUndersampledMapImage still has nonzero size, free it + + const double *rawData = mMapData->mData; + const unsigned char *rawAlpha = mMapData->mAlpha; + if (keyAxis->orientation() == Qt::Horizontal) + { + const int lineCount = valueSize; + const int rowCount = keySize; + for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) + if (rawAlpha) + mGradient.colorize(rawData+line*rowCount, rawAlpha+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); + else + mGradient.colorize(rawData+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); + } + } else // keyAxis->orientation() == Qt::Vertical + { + const int lineCount = keySize; + const int rowCount = valueSize; + for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) + if (rawAlpha) + mGradient.colorize(rawData+line, rawAlpha+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); + else + mGradient.colorize(rawData+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); + } + } + + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) + { + if (keyAxis->orientation() == Qt::Horizontal) + mMapImage = mUndersampledMapImage.scaled(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); + else + mMapImage = mUndersampledMapImage.scaled(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); + } + } + mMapData->mDataModified = false; + mMapImageInvalidated = false; +} + +/* inherits documentation from base class */ +void QCPColorMap::draw(QCPPainter *painter) +{ + if (mMapData->isEmpty()) return; + if (!mKeyAxis || !mValueAxis) return; + applyDefaultAntialiasingHint(painter); + + if (mMapData->mDataModified || mMapImageInvalidated) + updateMapImage(); + + // use buffer if painting vectorized (PDF): + const bool useBuffer = painter->modes().testFlag(QCPPainter::pmVectorized); + QCPPainter *localPainter = painter; // will be redirected to paint on mapBuffer if painting vectorized + QRectF mapBufferTarget; // the rect in absolute widget coordinates where the visible map portion/buffer will end up in + QPixmap mapBuffer; + if (useBuffer) + { + const double mapBufferPixelRatio = 3; // factor by which DPI is increased in embedded bitmaps + mapBufferTarget = painter->clipRegion().boundingRect(); + mapBuffer = QPixmap((mapBufferTarget.size()*mapBufferPixelRatio).toSize()); + mapBuffer.fill(Qt::transparent); + localPainter = new QCPPainter(&mapBuffer); + localPainter->scale(mapBufferPixelRatio, mapBufferPixelRatio); + localPainter->translate(-mapBufferTarget.topLeft()); + } + + QRectF imageRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), + coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); + // extend imageRect to contain outer halves/quarters of bordering/cornering pixels (cells are centered on map range boundary): + double halfCellWidth = 0; // in pixels + double halfCellHeight = 0; // in pixels + if (keyAxis()->orientation() == Qt::Horizontal) + { + if (mMapData->keySize() > 1) + halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->keySize()-1); + if (mMapData->valueSize() > 1) + halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->valueSize()-1); + } else // keyAxis orientation is Qt::Vertical + { + if (mMapData->keySize() > 1) + halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->keySize()-1); + if (mMapData->valueSize() > 1) + halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->valueSize()-1); + } + imageRect.adjust(-halfCellWidth, -halfCellHeight, halfCellWidth, halfCellHeight); + const bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); + const bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); + const bool smoothBackup = localPainter->renderHints().testFlag(QPainter::SmoothPixmapTransform); + localPainter->setRenderHint(QPainter::SmoothPixmapTransform, mInterpolate); + QRegion clipBackup; + if (mTightBoundary) + { + clipBackup = localPainter->clipRegion(); + QRectF tightClipRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), + coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); + localPainter->setClipRect(tightClipRect, Qt::IntersectClip); + } + localPainter->drawImage(imageRect, mMapImage.mirrored(mirrorX, mirrorY)); + if (mTightBoundary) + localPainter->setClipRegion(clipBackup); + localPainter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup); + + if (useBuffer) // localPainter painted to mapBuffer, so now draw buffer with original painter + { + delete localPainter; + painter->drawPixmap(mapBufferTarget.toRect(), mapBuffer); + } +} + +/* inherits documentation from base class */ +void QCPColorMap::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + applyDefaultAntialiasingHint(painter); + // draw map thumbnail: + if (!mLegendIcon.isNull()) + { + QPixmap scaledIcon = mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::FastTransformation); + QRectF iconRect = QRectF(0, 0, scaledIcon.width(), scaledIcon.height()); + iconRect.moveCenter(rect.center()); + painter->drawPixmap(iconRect.topLeft(), scaledIcon); + } + /* + // draw frame: + painter->setBrush(Qt::NoBrush); + painter->setPen(Qt::black); + painter->drawRect(rect.adjusted(1, 1, 0, 0)); + */ +} +/* end of 'src/plottables/plottable-colormap.cpp' */ + + +/* including file 'src/plottables/plottable-financial.cpp', size 42610 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPFinancialData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPFinancialData + \brief Holds the data of one single data point for QCPFinancial. + + The stored data is: + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + \li \a open: The opening value at the data point (this is the \a mainValue) + \li \a high: The high/maximum value at the data point + \li \a low: The low/minimum value at the data point + \li \a close: The closing value at the data point + + The container for storing multiple data points is \ref QCPFinancialDataContainer. It is a typedef + for \ref QCPDataContainer with \ref QCPFinancialData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPFinancialDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPFinancialData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPFinancialData QCPFinancialData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPFinancialData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPFinancialData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPFinancialData::mainValue() const + + Returns the \a open member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPFinancialData::valueRange() const + + Returns a QCPRange spanning from the \a low to the \a high value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and all values set to zero. +*/ +QCPFinancialData::QCPFinancialData() : + key(0), + open(0), + high(0), + low(0), + close(0) +{ +} + +/*! + Constructs a data point with the specified \a key and OHLC values. +*/ +QCPFinancialData::QCPFinancialData(double key, double open, double high, double low, double close) : + key(key), + open(open), + high(high), + low(low), + close(close) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPFinancial +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPFinancial + \brief A plottable representing a financial stock chart + + \image html QCPFinancial.png + + This plottable represents time series data binned to certain intervals, mainly used for stock + charts. The two common representations OHLC (Open-High-Low-Close) bars and Candlesticks can be + set via \ref setChartStyle. + + The data is passed via \ref setData as a set of open/high/low/close values at certain keys + (typically times). This means the data must be already binned appropriately. If data is only + available as a series of values (e.g. \a price against \a time), you can use the static + convenience function \ref timeSeriesToOhlc to generate binned OHLC-data which can then be passed + to \ref setData. + + The width of the OHLC bars/candlesticks can be controlled with \ref setWidth and \ref + setWidthType. A typical choice is to set the width type to \ref wtPlotCoords (the default) and + the width to (or slightly less than) one time bin interval width. + + \section qcpfinancial-appearance Changing the appearance + + Charts can be either single- or two-colored (\ref setTwoColored). If set to be single-colored, + lines are drawn with the plottable's pen (\ref setPen) and fills with the brush (\ref setBrush). + + If set to two-colored, positive changes of the value during an interval (\a close >= \a open) are + represented with a different pen and brush than negative changes (\a close < \a open). These can + be configured with \ref setPenPositive, \ref setPenNegative, \ref setBrushPositive, and \ref + setBrushNegative. In two-colored mode, the normal plottable pen/brush is ignored. Upon selection + however, the normal selected pen/brush (provided by the \ref selectionDecorator) is used, + irrespective of whether the chart is single- or two-colored. + + \section qcpfinancial-usage Usage + + Like all data representing objects in QCustomPlot, the QCPFinancial is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot + instance takes ownership of the plottable, so do not delete it manually but use + QCustomPlot::removePlottable() instead. The newly created plottable can be modified, e.g.: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-2 + Here we have used the static helper method \ref timeSeriesToOhlc, to turn a time-price data + series into a 24-hour binned open-high-low-close data series as QCPFinancial uses. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPFinancialDataContainer *QCPFinancial::data() const + + Returns a pointer to the internal data storage of type \ref QCPFinancialDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods, in certain situations. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a financial chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPFinancial is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPFinancial, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPFinancial::QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mChartStyle(csCandlestick), + mWidth(0.5), + mWidthType(wtPlotCoords), + mTwoColored(true), + mBrushPositive(QBrush(QColor(50, 160, 0))), + mBrushNegative(QBrush(QColor(180, 0, 15))), + mPenPositive(QPen(QColor(40, 150, 0))), + mPenNegative(QPen(QColor(170, 5, 5))) +{ + mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); +} + +QCPFinancial::~QCPFinancial() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPFinancials may share the same data container safely. + Modifying the data in the container will then affect all financials that share the container. + Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the financial's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-2 + + \see addData, timeSeriesToOhlc +*/ +void QCPFinancial::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys, \a open, \a high, \a low and \a + close. The provided vectors should have equal length. Else, the number of added points will be + the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData, timeSeriesToOhlc +*/ +void QCPFinancial::setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, open, high, low, close, alreadySorted); +} + +/*! + Sets which representation style shall be used to display the OHLC data. +*/ +void QCPFinancial::setChartStyle(QCPFinancial::ChartStyle style) +{ + mChartStyle = style; +} + +/*! + Sets the width of the individual bars/candlesticks to \a width in plot key coordinates. + + A typical choice is to set it to (or slightly less than) one bin interval width. +*/ +void QCPFinancial::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets how the width of the financial bars is defined. See the documentation of \ref WidthType for + an explanation of the possible values for \a widthType. + + The default value is \ref wtPlotCoords. + + \see setWidth +*/ +void QCPFinancial::setWidthType(QCPFinancial::WidthType widthType) +{ + mWidthType = widthType; +} + +/*! + Sets whether this chart shall contrast positive from negative trends per data point by using two + separate colors to draw the respective bars/candlesticks. + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenPositive, setPenNegative, setBrushPositive, setBrushNegative +*/ +void QCPFinancial::setTwoColored(bool twoColored) +{ + mTwoColored = twoColored; +} + +/*! + If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills + of data points with a positive trend (i.e. bars/candlesticks with close >= open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setBrushNegative, setPenPositive, setPenNegative +*/ +void QCPFinancial::setBrushPositive(const QBrush &brush) +{ + mBrushPositive = brush; +} + +/*! + If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills + of data points with a negative trend (i.e. bars/candlesticks with close < open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setBrushPositive, setPenNegative, setPenPositive +*/ +void QCPFinancial::setBrushNegative(const QBrush &brush) +{ + mBrushNegative = brush; +} + +/*! + If \ref setTwoColored is set to true, this function controls the pen that is used to draw + outlines of data points with a positive trend (i.e. bars/candlesticks with close >= open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenNegative, setBrushPositive, setBrushNegative +*/ +void QCPFinancial::setPenPositive(const QPen &pen) +{ + mPenPositive = pen; +} + +/*! + If \ref setTwoColored is set to true, this function controls the pen that is used to draw + outlines of data points with a negative trend (i.e. bars/candlesticks with close < open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenPositive, setBrushNegative, setBrushPositive +*/ +void QCPFinancial::setPenNegative(const QPen &pen) +{ + mPenNegative = pen; +} + +/*! \overload + + Adds the provided points in \a keys, \a open, \a high, \a low and \a close to the current data. + The provided vectors should have equal length. Else, the number of added points will be the size + of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. + + \see timeSeriesToOhlc +*/ +void QCPFinancial::addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) +{ + if (keys.size() != open.size() || open.size() != high.size() || high.size() != low.size() || low.size() != close.size() || close.size() != keys.size()) + qDebug() << Q_FUNC_INFO << "keys, open, high, low, close have different sizes:" << keys.size() << open.size() << high.size() << low.size() << close.size(); + const int n = qMin(keys.size(), qMin(open.size(), qMin(high.size(), qMin(low.size(), close.size())))); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->open = open[i]; + it->high = high[i]; + it->low = low[i]; + it->close = close[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key, \a open, \a high, \a low and \a close to the current + data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. + + \see timeSeriesToOhlc +*/ +void QCPFinancial::addData(double key, double open, double high, double low, double close) +{ + mDataContainer->add(QCPFinancialData(key, open, high, low, close)); +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPFinancial::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPFinancialDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(selectionHitBox(it))) + result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +double QCPFinancial::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + QCPFinancialDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + getVisibleDataBounds(visibleBegin, visibleEnd); + // perform select test according to configured style: + double result = -1; + switch (mChartStyle) + { + case QCPFinancial::csOhlc: + result = ohlcSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; + case QCPFinancial::csCandlestick: + result = candlestickSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; + } + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } + + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPFinancial::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); + // determine exact range by including width of bars/flags: + if (foundRange) + { + if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) + range.lower -= mWidth*0.5; + if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) + range.upper += mWidth*0.5; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPFinancial::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/*! + A convenience function that converts time series data (\a value against \a time) to OHLC binned + data points. The return value can then be passed on to \ref QCPFinancialDataContainer::set(const + QCPFinancialDataContainer&). + + The size of the bins can be controlled with \a timeBinSize in the same units as \a time is given. + For example, if the unit of \a time is seconds and single OHLC/Candlesticks should span an hour + each, set \a timeBinSize to 3600. + + \a timeBinOffset allows to control precisely at what \a time coordinate a bin should start. The + value passed as \a timeBinOffset doesn't need to be in the range encompassed by the \a time keys. + It merely defines the mathematical offset/phase of the bins that will be used to process the + data. +*/ +QCPFinancialDataContainer QCPFinancial::timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset) +{ + QCPFinancialDataContainer data; + int count = qMin(time.size(), value.size()); + if (count == 0) + return QCPFinancialDataContainer(); + + QCPFinancialData currentBinData(0, value.first(), value.first(), value.first(), value.first()); + int currentBinIndex = qFloor((time.first()-timeBinOffset)/timeBinSize+0.5); + for (int i=0; i currentBinData.high) currentBinData.high = value.at(i); + if (i == count-1) // last data point is in current bin, finalize bin: + { + currentBinData.close = value.at(i); + currentBinData.key = timeBinOffset+(index)*timeBinSize; + data.add(currentBinData); + } + } else // data point not anymore in current bin, set close of old and open of new bin, and add old to map: + { + // finalize current bin: + currentBinData.close = value.at(i-1); + currentBinData.key = timeBinOffset+(index-1)*timeBinSize; + data.add(currentBinData); + // start next bin: + currentBinIndex = index; + currentBinData.open = value.at(i); + currentBinData.high = value.at(i); + currentBinData.low = value.at(i); + } + } + + return data; +} + +/* inherits documentation from base class */ +void QCPFinancial::draw(QCPPainter *painter) +{ + // get visible data range: + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPFinancialDataContainer::const_iterator begin = visibleBegin; + QCPFinancialDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + // draw data segment according to configured style: + switch (mChartStyle) + { + case QCPFinancial::csOhlc: + drawOhlcPlot(painter, begin, end, isSelectedSegment); break; + case QCPFinancial::csCandlestick: + drawCandlestickPlot(painter, begin, end, isSelectedSegment); break; + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPFinancial::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + painter->setAntialiasing(false); // legend icon especially of csCandlestick looks better without antialiasing + if (mChartStyle == csOhlc) + { + if (mTwoColored) + { + // draw upper left half icon with positive color: + painter->setBrush(mBrushPositive); + painter->setPen(mPenPositive); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + // draw bottom right half icon with negative color: + painter->setBrush(mBrushNegative); + painter->setPen(mPenNegative); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + } + } else if (mChartStyle == csCandlestick) + { + if (mTwoColored) + { + // draw upper left half icon with positive color: + painter->setBrush(mBrushPositive); + painter->setPen(mPenPositive); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + // draw bottom right half icon with negative color: + painter->setBrush(mBrushNegative); + painter->setPen(mPenNegative); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + } + } +} + +/*! \internal + + Draws the data from \a begin to \a end-1 as OHLC bars with the provided \a painter. + + This method is a helper function for \ref draw. It is used when the chart style is \ref csOhlc. +*/ +void QCPFinancial::drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else if (mTwoColored) + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + else + painter->setPen(mPen); + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw backbone: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(it->low))); + // draw open: + double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides + painter->drawLine(QPointF(keyPixel-pixelWidth, openPixel), QPointF(keyPixel, openPixel)); + // draw close: + painter->drawLine(QPointF(keyPixel, closePixel), QPointF(keyPixel+pixelWidth, closePixel)); + } + } else + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else if (mTwoColored) + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + else + painter->setPen(mPen); + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw backbone: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(it->low), keyPixel)); + // draw open: + double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides + painter->drawLine(QPointF(openPixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel)); + // draw close: + painter->drawLine(QPointF(closePixel, keyPixel), QPointF(closePixel, keyPixel+pixelWidth)); + } + } +} + +/*! \internal + + Draws the data from \a begin to \a end-1 as Candlesticks with the provided \a painter. + + This method is a helper function for \ref draw. It is used when the chart style is \ref csCandlestick. +*/ +void QCPFinancial::drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else if (mTwoColored) + { + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw high: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); + // draw low: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->low)), QPointF(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); + // draw open-close box: + double pixelWidth = getPixelWidth(it->key, keyPixel); + painter->drawRect(QRectF(QPointF(keyPixel-pixelWidth, closePixel), QPointF(keyPixel+pixelWidth, openPixel))); + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else if (mTwoColored) + { + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw high: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); + // draw low: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->low), keyPixel), QPointF(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); + // draw open-close box: + double pixelWidth = getPixelWidth(it->key, keyPixel); + painter->drawRect(QRectF(QPointF(closePixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel+pixelWidth))); + } + } +} + +/*! \internal + + This function is used to determine the width of the bar at coordinate \a key, according to the + specified width (\ref setWidth) and width type (\ref setWidthType). Provide the pixel position of + \a key in \a keyPixel (because usually this was already calculated via \ref QCPAxis::coordToPixel + when this function is called). + + It returns the number of pixels the bar extends to higher keys, relative to the \a key + coordinate. So with a non-reversed horizontal axis, the return value is positive. With a reversed + horizontal axis, the return value is negative. This is important so the open/close flags on the + \ref csOhlc bar are drawn to the correct side. +*/ +double QCPFinancial::getPixelWidth(double key, double keyPixel) const +{ + double result = 0; + switch (mWidthType) + { + case wtAbsolute: + { + if (mKeyAxis) + result = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + break; + } + case wtAxisRectRatio: + { + if (mKeyAxis && mKeyAxis.data()->axisRect()) + { + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + result = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + else + result = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + } else + qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; + break; + } + case wtPlotCoords: + { + if (mKeyAxis) + result = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; + else + qDebug() << Q_FUNC_INFO << "No key axis defined"; + break; + } + } + return result; +} + +/*! \internal + + This method is a helper function for \ref selectTest. It is used to test for selection when the + chart style is \ref csOhlc. It only tests against the data points between \a begin and \a end. + + Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical + representation of the plottable, and \a closestDataPoint will point to the respective data point. +*/ +double QCPFinancial::ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const +{ + closestDataPoint = mDataContainer->constEnd(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + double minDistSqr = std::numeric_limits::max(); + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double keyPixel = keyAxis->coordToPixel(it->key); + // calculate distance to backbone: + double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low))); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double keyPixel = keyAxis->coordToPixel(it->key); + // calculate distance to backbone: + double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel)); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + This method is a helper function for \ref selectTest. It is used to test for selection when the + chart style is \ref csCandlestick. It only tests against the data points between \a begin and \a + end. + + Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical + representation of the plottable, and \a closestDataPoint will point to the respective data point. +*/ +double QCPFinancial::candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const +{ + closestDataPoint = mDataContainer->constEnd(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + double minDistSqr = std::numeric_limits::max(); + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double currentDistSqr; + // determine whether pos is in open-close-box: + QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); + QCPRange boxValueRange(it->close, it->open); + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box + { + currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + } else + { + // calculate distance to high/low lines: + double keyPixel = keyAxis->coordToPixel(it->key); + double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); + double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); + currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); + } + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double currentDistSqr; + // determine whether pos is in open-close-box: + QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); + QCPRange boxValueRange(it->close, it->open); + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box + { + currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + } else + { + // calculate distance to high/low lines: + double keyPixel = keyAxis->coordToPixel(it->key); + double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); + double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); + currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); + } + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + called by the drawing methods to determine which data (key) range is visible at the current key + axis range setting, so only that needs to be processed. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + begin may still be just outside the visible range. + + \a end returns the iterator just above the highest data point that needs to be taken into + account. Same as before, \a end may also lie just outside of the visible range + + if the plottable contains no data, both \a begin and \a end point to \c constEnd. +*/ +void QCPFinancial::getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of ohlc/candlestick to include partially visible data points + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of ohlc/candlestick to include partially visible data points +} + +/*! \internal + + Returns the hit box in pixel coordinates that will be used for data selection with the selection + rect (\ref selectTestRect), of the data point given by \a it. +*/ +QRectF QCPFinancial::selectionHitBox(QCPFinancialDataContainer::const_iterator it) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QRectF(); } + + double keyPixel = keyAxis->coordToPixel(it->key); + double highPixel = valueAxis->coordToPixel(it->high); + double lowPixel = valueAxis->coordToPixel(it->low); + double keyWidthPixels = keyPixel-keyAxis->coordToPixel(it->key-mWidth*0.5); + if (keyAxis->orientation() == Qt::Horizontal) + return QRectF(keyPixel-keyWidthPixels, highPixel, keyWidthPixels*2, lowPixel-highPixel).normalized(); + else + return QRectF(highPixel, keyPixel-keyWidthPixels, lowPixel-highPixel, keyWidthPixels*2).normalized(); +} +/* end of 'src/plottables/plottable-financial.cpp' */ + + +/* including file 'src/plottables/plottable-errorbar.cpp', size 37355 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPErrorBarsData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPErrorBarsData + \brief Holds the data of one single error bar for QCPErrorBars. + + The stored data is: + \li \a errorMinus: how much the error bar extends towards negative coordinates from the data + point position + \li \a errorPlus: how much the error bar extends towards positive coordinates from the data point + position + + The container for storing the error bar information is \ref QCPErrorBarsDataContainer. It is a + typedef for QVector<\ref QCPErrorBarsData>. + + \see QCPErrorBarsDataContainer +*/ + +/*! + Constructs an error bar with errors set to zero. +*/ +QCPErrorBarsData::QCPErrorBarsData() : + errorMinus(0), + errorPlus(0) +{ +} + +/*! + Constructs an error bar with equal \a error in both negative and positive direction. +*/ +QCPErrorBarsData::QCPErrorBarsData(double error) : + errorMinus(error), + errorPlus(error) +{ +} + +/*! + Constructs an error bar with negative and positive errors set to \a errorMinus and \a errorPlus, + respectively. +*/ +QCPErrorBarsData::QCPErrorBarsData(double errorMinus, double errorPlus) : + errorMinus(errorMinus), + errorPlus(errorPlus) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPErrorBars +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPErrorBars + \brief A plottable that adds a set of error bars to other plottables. + + \image html QCPErrorBars.png + + The \ref QCPErrorBars plottable can be attached to other one-dimensional plottables (e.g. \ref + QCPGraph, \ref QCPCurve, \ref QCPBars, etc.) and equips them with error bars. + + Use \ref setDataPlottable to define for which plottable the \ref QCPErrorBars shall display the + error bars. The orientation of the error bars can be controlled with \ref setErrorType. + + By using \ref setData, you can supply the actual error data, either as symmetric error or + plus/minus asymmetric errors. \ref QCPErrorBars only stores the error data. The absolute + key/value position of each error bar will be adopted from the configured data plottable. The + error data of the \ref QCPErrorBars are associated one-to-one via their index to the data points + of the data plottable. You can directly access and manipulate the error bar data via \ref data. + + Set either of the plus/minus errors to NaN (qQNaN() or + std::numeric_limits::quiet_NaN()) to not show the respective error bar on the data point at + that index. + + \section qcperrorbars-appearance Changing the appearance + + The appearance of the error bars is defined by the pen (\ref setPen), and the width of the + whiskers (\ref setWhiskerWidth). Further, the error bar backbones may leave a gap around the data + point center to prevent that error bars are drawn too close to or even through scatter points. + This gap size can be controlled via \ref setSymbolGap. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPErrorBars::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPErrorBarsDataContainer. You + may use it to directly manipulate the error values, which may be more convenient and faster than + using the regular \ref setData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs an error bars plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + It is also important that the \a keyAxis and \a valueAxis are the same for the error bars + plottable and the data plottable that the error bars shall be drawn on (\ref setDataPlottable). + + The created \ref QCPErrorBars is automatically registered with the QCustomPlot instance inferred + from \a keyAxis. This QCustomPlot instance takes ownership of the \ref QCPErrorBars, so do not + delete it manually but use \ref QCustomPlot::removePlottable() instead. +*/ +QCPErrorBars::QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mDataContainer(new QVector), + mErrorType(etValueError), + mWhiskerWidth(9), + mSymbolGap(10) +{ + setPen(QPen(Qt::black, 0)); + setBrush(Qt::NoBrush); +} + +QCPErrorBars::~QCPErrorBars() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple \ref QCPErrorBars instances may share the same data + container safely. Modifying the data in the container will then affect all \ref QCPErrorBars + instances that share the container. Sharing can be achieved by simply exchanging the data + containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, assign the + data containers directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-2 + (This uses different notation compared with other plottables, because the \ref QCPErrorBars + uses a \c QVector as its data container, instead of a \ref QCPDataContainer.) + + \see addData +*/ +void QCPErrorBars::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Sets symmetrical error values as specified in \a error. The errors will be associated one-to-one + by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see addData +*/ +void QCPErrorBars::setData(const QVector &error) +{ + mDataContainer->clear(); + addData(error); +} + +/*! \overload + + Sets asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be + associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see addData +*/ +void QCPErrorBars::setData(const QVector &errorMinus, const QVector &errorPlus) +{ + mDataContainer->clear(); + addData(errorMinus, errorPlus); +} + +/*! + Sets the data plottable to which the error bars will be applied. The error values specified e.g. + via \ref setData will be associated one-to-one by the data point index to the data points of \a + plottable. This means that the error bars will adopt the key/value coordinates of the data point + with the same index. + + The passed \a plottable must be a one-dimensional plottable, i.e. it must implement the \ref + QCPPlottableInterface1D. Further, it must not be a \ref QCPErrorBars instance itself. If either + of these restrictions is violated, a corresponding qDebug output is generated, and the data + plottable of this \ref QCPErrorBars instance is set to zero. + + For proper display, care must also be taken that the key and value axes of the \a plottable match + those configured for this \ref QCPErrorBars instance. +*/ +void QCPErrorBars::setDataPlottable(QCPAbstractPlottable *plottable) +{ + if (plottable && qobject_cast(plottable)) + { + mDataPlottable = 0; + qDebug() << Q_FUNC_INFO << "can't set another QCPErrorBars instance as data plottable"; + return; + } + if (plottable && !plottable->interface1D()) + { + mDataPlottable = 0; + qDebug() << Q_FUNC_INFO << "passed plottable doesn't implement 1d interface, can't associate with QCPErrorBars"; + return; + } + + mDataPlottable = plottable; +} + +/*! + Sets in which orientation the error bars shall appear on the data points. If your data needs both + error dimensions, create two \ref QCPErrorBars with different \a type. +*/ +void QCPErrorBars::setErrorType(ErrorType type) +{ + mErrorType = type; +} + +/*! + Sets the width of the whiskers (the short bars at the end of the actual error bar backbones) to + \a pixels. +*/ +void QCPErrorBars::setWhiskerWidth(double pixels) +{ + mWhiskerWidth = pixels; +} + +/*! + Sets the gap diameter around the data points that will be left out when drawing the error bar + backbones. This gap prevents that error bars are drawn too close to or even through scatter + points. +*/ +void QCPErrorBars::setSymbolGap(double pixels) +{ + mSymbolGap = pixels; +} + +/*! \overload + + Adds symmetrical error values as specified in \a error. The errors will be associated one-to-one + by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(const QVector &error) +{ + addData(error, error); +} + +/*! \overload + + Adds asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be + associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(const QVector &errorMinus, const QVector &errorPlus) +{ + if (errorMinus.size() != errorPlus.size()) + qDebug() << Q_FUNC_INFO << "minus and plus error vectors have different sizes:" << errorMinus.size() << errorPlus.size(); + const int n = qMin(errorMinus.size(), errorPlus.size()); + mDataContainer->reserve(n); + for (int i=0; iappend(QCPErrorBarsData(errorMinus.at(i), errorPlus.at(i))); +} + +/*! \overload + + Adds a single symmetrical error bar as specified in \a error. The errors will be associated + one-to-one by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(double error) +{ + mDataContainer->append(QCPErrorBarsData(error)); +} + +/*! \overload + + Adds a single asymmetrical error bar as specified in \a errorMinus and \a errorPlus. The errors + will be associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(double errorMinus, double errorPlus) +{ + mDataContainer->append(QCPErrorBarsData(errorMinus, errorPlus)); +} + +/* inherits documentation from base class */ +int QCPErrorBars::dataCount() const +{ + return mDataContainer->size(); +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataMainKey(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataMainKey(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataSortKey(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataSortKey(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataMainValue(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataMainValue(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::dataValueRange(int index) const +{ + if (mDataPlottable) + { + const double value = mDataPlottable->interface1D()->dataMainValue(index); + if (index >= 0 && index < mDataContainer->size() && mErrorType == etValueError) + return QCPRange(value-mDataContainer->at(index).errorMinus, value+mDataContainer->at(index).errorPlus); + else + return QCPRange(value, value); + } else + { + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return QCPRange(); + } +} + +/* inherits documentation from base class */ +QPointF QCPErrorBars::dataPixelPosition(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataPixelPosition(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return QPointF(); +} + +/* inherits documentation from base class */ +bool QCPErrorBars::sortKeyIsMainKey() const +{ + if (mDataPlottable) + { + return mDataPlottable->interface1D()->sortKeyIsMainKey(); + } else + { + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return true; + } +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPErrorBars::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if (!mDataPlottable) + return result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPErrorBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd, QCPDataRange(0, dataCount())); + + QVector backbones, whiskers; + for (QCPErrorBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + backbones.clear(); + whiskers.clear(); + getErrorBarLines(it, backbones, whiskers); + for (int i=0; iconstBegin(), it-mDataContainer->constBegin()+1), false); + break; + } + } + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +int QCPErrorBars::findBegin(double sortKey, bool expandedRange) const +{ + if (mDataPlottable) + { + if (mDataContainer->isEmpty()) + return 0; + int beginIndex = mDataPlottable->interface1D()->findBegin(sortKey, expandedRange); + if (beginIndex >= mDataContainer->size()) + beginIndex = mDataContainer->size()-1; + return beginIndex; + } else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +int QCPErrorBars::findEnd(double sortKey, bool expandedRange) const +{ + if (mDataPlottable) + { + if (mDataContainer->isEmpty()) + return 0; + int endIndex = mDataPlottable->interface1D()->findEnd(sortKey, expandedRange); + if (endIndex > mDataContainer->size()) + endIndex = mDataContainer->size(); + return endIndex; + } else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mDataPlottable) return -1; + + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPErrorBarsDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +void QCPErrorBars::draw(QCPPainter *painter) +{ + if (!mDataPlottable) return; + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; + + // if the sort key isn't the main key, we must check the visibility for each data point/error bar individually + // (getVisibleDataBounds applies range restriction, but otherwise can only return full data range): + bool checkPointVisibility = !mDataPlottable->interface1D()->sortKeyIsMainKey(); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPErrorBarsDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->errorMinus, it->errorPlus)) + qDebug() << Q_FUNC_INFO << "Data point at index" << it-mDataContainer->constBegin() << "invalid." << "Plottable name:" << name(); + } +#endif + + applyDefaultAntialiasingHint(painter); + painter->setBrush(Qt::NoBrush); + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + QVector backbones, whiskers; + for (int i=0; i= unselectedSegments.size(); + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else + painter->setPen(mPen); + if (painter->pen().capStyle() == Qt::SquareCap) + { + QPen capFixPen(painter->pen()); + capFixPen.setCapStyle(Qt::FlatCap); + painter->setPen(capFixPen); + } + backbones.clear(); + whiskers.clear(); + for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + if (!checkPointVisibility || errorBarVisible(it-mDataContainer->constBegin())) + getErrorBarLines(it, backbones, whiskers); + } + painter->drawLines(backbones); + painter->drawLines(whiskers); + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPErrorBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + if (mErrorType == etValueError && mValueAxis && mValueAxis->orientation() == Qt::Vertical) + { + painter->drawLine(QLineF(rect.center().x(), rect.top()+2, rect.center().x(), rect.bottom()-1)); + painter->drawLine(QLineF(rect.center().x()-4, rect.top()+2, rect.center().x()+4, rect.top()+2)); + painter->drawLine(QLineF(rect.center().x()-4, rect.bottom()-1, rect.center().x()+4, rect.bottom()-1)); + } else + { + painter->drawLine(QLineF(rect.left()+2, rect.center().y(), rect.right()-2, rect.center().y())); + painter->drawLine(QLineF(rect.left()+2, rect.center().y()-4, rect.left()+2, rect.center().y()+4)); + painter->drawLine(QLineF(rect.right()-2, rect.center().y()-4, rect.right()-2, rect.center().y()+4)); + } +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + if (!mDataPlottable) + { + foundRange = false; + return QCPRange(); + } + + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + QCPErrorBarsDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (mErrorType == etValueError) + { + // error bar doesn't extend in key dimension (except whisker but we ignore that here), so only use data point center + const double current = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } else // mErrorType == etKeyError + { + const double dataKey = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); + if (qIsNaN(dataKey)) continue; + // plus error: + double current = dataKey + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + // minus error: + current = dataKey - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + } + } + } + + if (haveUpper && !haveLower) + { + range.lower = range.upper; + haveLower = true; + } else if (haveLower && !haveUpper) + { + range.upper = range.lower; + haveUpper = true; + } + + foundRange = haveLower && haveUpper; + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + if (!mDataPlottable) + { + foundRange = false; + return QCPRange(); + } + + QCPRange range; + const bool restrictKeyRange = inKeyRange != QCPRange(); + bool haveLower = false; + bool haveUpper = false; + QCPErrorBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPErrorBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + if (mDataPlottable->interface1D()->sortKeyIsMainKey() && restrictKeyRange) + { + itBegin = mDataContainer->constBegin()+findBegin(inKeyRange.lower); + itEnd = mDataContainer->constBegin()+findEnd(inKeyRange.upper); + } + for (QCPErrorBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange) + { + const double dataKey = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); + if (dataKey < inKeyRange.lower || dataKey > inKeyRange.upper) + continue; + } + if (mErrorType == etValueError) + { + const double dataValue = mDataPlottable->interface1D()->dataMainValue(it-mDataContainer->constBegin()); + if (qIsNaN(dataValue)) continue; + // plus error: + double current = dataValue + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + // minus error: + current = dataValue - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + } + } else // mErrorType == etKeyError + { + // error bar doesn't extend in value dimension (except whisker but we ignore that here), so only use data point center + const double current = mDataPlottable->interface1D()->dataMainValue(it-mDataContainer->constBegin()); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } + } + + if (haveUpper && !haveLower) + { + range.lower = range.upper; + haveLower = true; + } else if (haveLower && !haveUpper) + { + range.upper = range.lower; + haveUpper = true; + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! \internal + + Calculates the lines that make up the error bar belonging to the data point \a it. + + The resulting lines are added to \a backbones and \a whiskers. The vectors are not cleared, so + calling this method with different \a it but the same \a backbones and \a whiskers allows to + accumulate lines for multiple data points. + + This method assumes that \a it is a valid iterator within the bounds of this \ref QCPErrorBars + instance and within the bounds of the associated data plottable. +*/ +void QCPErrorBars::getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const +{ + if (!mDataPlottable) return; + + int index = it-mDataContainer->constBegin(); + QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); + if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y())) + return; + QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis.data() : mKeyAxis.data(); + QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis.data() : mValueAxis.data(); + const double centerErrorAxisPixel = errorAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + const double centerOrthoAxisPixel = orthoAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + const double centerErrorAxisCoord = errorAxis->pixelToCoord(centerErrorAxisPixel); // depending on plottable, this might be different from just mDataPlottable->interface1D()->dataMainKey/Value + const double symbolGap = mSymbolGap*0.5*errorAxis->pixelOrientation(); + // plus error: + double errorStart, errorEnd; + if (!qIsNaN(it->errorPlus)) + { + errorStart = centerErrorAxisPixel+symbolGap; + errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord+it->errorPlus); + if (errorAxis->orientation() == Qt::Vertical) + { + if ((errorStart > errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); + whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); + } else + { + if ((errorStart < errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); + whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); + } + } + // minus error: + if (!qIsNaN(it->errorMinus)) + { + errorStart = centerErrorAxisPixel-symbolGap; + errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord-it->errorMinus); + if (errorAxis->orientation() == Qt::Vertical) + { + if ((errorStart < errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); + whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); + } else + { + if ((errorStart > errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); + whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); + } + } +} + +/*! \internal + + This method outputs the currently visible data range via \a begin and \a end. The returned range + will also never exceed \a rangeRestriction. + + Since error bars with type \ref etKeyError may extend to arbitrarily positive and negative key + coordinates relative to their data point key, this method checks all outer error bars whether + they truly don't reach into the visible portion of the axis rect, by calling \ref + errorBarVisible. On the other hand error bars with type \ref etValueError that are associated + with data plottables whose sort key is equal to the main key (see \ref qcpdatacontainer-datatype + "QCPDataContainer DataType") can be handled very efficiently by finding the visible range of + error bars through binary search (\ref QCPPlottableInterface1D::findBegin and \ref + QCPPlottableInterface1D::findEnd). + + If the plottable's sort key is not equal to the main key, this method returns the full data + range, only restricted by \a rangeRestriction. Drawing optimization then has to be done on a + point-by-point basis in the \ref draw method. +*/ +void QCPErrorBars::getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + end = mDataContainer->constEnd(); + begin = end; + return; + } + if (!mDataPlottable || rangeRestriction.isEmpty()) + { + end = mDataContainer->constEnd(); + begin = end; + return; + } + if (!mDataPlottable->interface1D()->sortKeyIsMainKey()) + { + // if the sort key isn't the main key, it's not possible to find a contiguous range of visible + // data points, so this method then only applies the range restriction and otherwise returns + // the full data range. Visibility checks must be done on a per-datapoin-basis during drawing + QCPDataRange dataRange(0, mDataContainer->size()); + dataRange = dataRange.bounded(rangeRestriction); + begin = mDataContainer->constBegin()+dataRange.begin(); + end = mDataContainer->constBegin()+dataRange.end(); + return; + } + + // get visible data range via interface from data plottable, and then restrict to available error data points: + const int n = qMin(mDataContainer->size(), mDataPlottable->interface1D()->dataCount()); + int beginIndex = mDataPlottable->interface1D()->findBegin(keyAxis->range().lower); + int endIndex = mDataPlottable->interface1D()->findEnd(keyAxis->range().upper); + int i = beginIndex; + while (i > 0 && i < n && i > rangeRestriction.begin()) + { + if (errorBarVisible(i)) + beginIndex = i; + --i; + } + i = endIndex; + while (i >= 0 && i < n && i < rangeRestriction.end()) + { + if (errorBarVisible(i)) + endIndex = i+1; + ++i; + } + QCPDataRange dataRange(beginIndex, endIndex); + dataRange = dataRange.bounded(rangeRestriction.bounded(QCPDataRange(0, mDataContainer->size()))); + begin = mDataContainer->constBegin()+dataRange.begin(); + end = mDataContainer->constBegin()+dataRange.end(); +} + +/*! \internal + + Calculates the minimum distance in pixels the error bars' representation has from the given \a + pixelPoint. This is used to determine whether the error bar was clicked or not, e.g. in \ref + selectTest. The closest data point to \a pixelPoint is returned in \a closestData. +*/ +double QCPErrorBars::pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (!mDataPlottable || mDataContainer->isEmpty()) + return -1.0; + if (!mKeyAxis || !mValueAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + return -1.0; + } + + QCPErrorBarsDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount())); + + // calculate minimum distances to error backbones (whiskers are ignored for speed) and find closestData iterator: + double minDistSqr = std::numeric_limits::max(); + QVector backbones, whiskers; + for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + getErrorBarLines(it, backbones, whiskers); + for (int i=0; i &selectedSegments, QList &unselectedSegments) const +{ + selectedSegments.clear(); + unselectedSegments.clear(); + if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty + { + if (selected()) + selectedSegments << QCPDataRange(0, dataCount()); + else + unselectedSegments << QCPDataRange(0, dataCount()); + } else + { + QCPDataSelection sel(selection()); + sel.simplify(); + selectedSegments = sel.dataRanges(); + unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); + } +} + +/*! \internal + + Returns whether the error bar at the specified \a index is visible within the current key axis + range. + + This method assumes for performance reasons without checking that the key axis, the value axis, + and the data plottable (\ref setDataPlottable) are not zero and that \a index is within valid + bounds of this \ref QCPErrorBars instance and the bounds of the data plottable. +*/ +bool QCPErrorBars::errorBarVisible(int index) const +{ + QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); + const double centerKeyPixel = mKeyAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + if (qIsNaN(centerKeyPixel)) + return false; + + double keyMin, keyMax; + if (mErrorType == etKeyError) + { + const double centerKey = mKeyAxis->pixelToCoord(centerKeyPixel); + const double errorPlus = mDataContainer->at(index).errorPlus; + const double errorMinus = mDataContainer->at(index).errorMinus; + keyMax = centerKey+(qIsNaN(errorPlus) ? 0 : errorPlus); + keyMin = centerKey-(qIsNaN(errorMinus) ? 0 : errorMinus); + } else // mErrorType == etValueError + { + keyMax = mKeyAxis->pixelToCoord(centerKeyPixel+mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); + keyMin = mKeyAxis->pixelToCoord(centerKeyPixel-mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); + } + return ((keyMax > mKeyAxis->range().lower) && (keyMin < mKeyAxis->range().upper)); +} + +/*! \internal + + Returns whether \a line intersects (or is contained in) \a pixelRect. + + \a line is assumed to be either perfectly horizontal or perfectly vertical, as is the case for + error bar lines. +*/ +bool QCPErrorBars::rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const +{ + if (pixelRect.left() > line.x1() && pixelRect.left() > line.x2()) + return false; + else if (pixelRect.right() < line.x1() && pixelRect.right() < line.x2()) + return false; + else if (pixelRect.top() > line.y1() && pixelRect.top() > line.y2()) + return false; + else if (pixelRect.bottom() < line.y1() && pixelRect.bottom() < line.y2()) + return false; + else + return true; +} +/* end of 'src/plottables/plottable-errorbar.cpp' */ + + +/* including file 'src/items/item-straightline.cpp', size 7592 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemStraightLine +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemStraightLine + \brief A straight line that spans infinitely in both directions + + \image html QCPItemStraightLine.png "Straight line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a point1 and \a point2, which define the straight line. +*/ + +/*! + Creates a straight line item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemStraightLine::QCPItemStraightLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + point1(createPosition(QLatin1String("point1"))), + point2(createPosition(QLatin1String("point2"))) +{ + point1->setCoords(0, 0); + point2->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemStraightLine::~QCPItemStraightLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemStraightLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemStraightLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemStraightLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return QCPVector2D(pos).distanceToStraightLine(point1->pixelPosition(), point2->pixelPosition()-point1->pixelPosition()); +} + +/* inherits documentation from base class */ +void QCPItemStraightLine::draw(QCPPainter *painter) +{ + QCPVector2D start(point1->pixelPosition()); + QCPVector2D end(point2->pixelPosition()); + // get visible segment of straight line inside clipRect: + double clipPad = mainPen().widthF(); + QLineF line = getRectClippedStraightLine(start, end-start, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + } +} + +/*! \internal + + Returns the section of the straight line defined by \a base and direction vector \a + vec, that is visible in the specified \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemStraightLine::getRectClippedStraightLine(const QCPVector2D &base, const QCPVector2D &vec, const QRect &rect) const +{ + double bx, by; + double gamma; + QLineF result; + if (vec.x() == 0 && vec.y() == 0) + return result; + if (qFuzzyIsNull(vec.x())) // line is vertical + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + result.setLine(bx+gamma, rect.top(), bx+gamma, rect.bottom()); // no need to check bottom because we know line is vertical + } else if (qFuzzyIsNull(vec.y())) // line is horizontal + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + result.setLine(rect.left(), by+gamma, rect.right(), by+gamma); // no need to check right because we know line is horizontal + } else // line is skewed + { + QList pointVectors; + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + // check right of rect: + bx = rect.right(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QCPVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemStraightLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-straightline.cpp' */ + + +/* including file 'src/items/item-line.cpp', size 8498 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemLine +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemLine + \brief A line from one point to another + + \image html QCPItemLine.png "Line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a start and \a end, which define the end points of the line. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an arrow. +*/ + +/*! + Creates a line item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemLine::QCPItemLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition(QLatin1String("start"))), + end(createPosition(QLatin1String("end"))) +{ + start->setCoords(0, 0); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemLine::~QCPItemLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemLine::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemLine::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return qSqrt(QCPVector2D(pos).distanceSquaredToLine(start->pixelPosition(), end->pixelPosition())); +} + +/* inherits documentation from base class */ +void QCPItemLine::draw(QCPPainter *painter) +{ + QCPVector2D startVec(start->pixelPosition()); + QCPVector2D endVec(end->pixelPosition()); + if (qFuzzyIsNull((startVec-endVec).lengthSquared())) + return; + // get visible segment of straight line inside clipRect: + double clipPad = qMax(mHead.boundingDistance(), mTail.boundingDistance()); + clipPad = qMax(clipPad, (double)mainPen().widthF()); + QLineF line = getRectClippedLine(startVec, endVec, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, startVec, startVec-endVec); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, endVec, endVec-startVec); + } +} + +/*! \internal + + Returns the section of the line defined by \a start and \a end, that is visible in the specified + \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemLine::getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const +{ + bool containsStart = rect.contains(start.x(), start.y()); + bool containsEnd = rect.contains(end.x(), end.y()); + if (containsStart && containsEnd) + return QLineF(start.toPointF(), end.toPointF()); + + QCPVector2D base = start; + QCPVector2D vec = end-start; + double bx, by; + double gamma, mu; + QLineF result; + QList pointVectors; + + if (!qFuzzyIsNull(vec.y())) // line is not horizontal + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + } + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + } + } + if (!qFuzzyIsNull(vec.x())) // line is not vertical + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + } + // check right of rect: + bx = rect.right(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + } + } + + if (containsStart) + pointVectors.append(start); + if (containsEnd) + pointVectors.append(end); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QCPVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-line.cpp' */ + + +/* including file 'src/items/item-curve.cpp', size 7159 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemCurve +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemCurve + \brief A curved line from one point to another + + \image html QCPItemCurve.png "Curve example. Blue dotted circles are anchors, solid blue discs are positions." + + It has four positions, \a start and \a end, which define the end points of the line, and two + control points which define the direction the line exits from the start and the direction from + which it approaches the end: \a startDir and \a endDir. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an + arrow. + + Often it is desirable for the control points to stay at fixed relative positions to the start/end + point. This can be achieved by setting the parent anchor e.g. of \a startDir simply to \a start, + and then specify the desired pixel offset with QCPItemPosition::setCoords on \a startDir. +*/ + +/*! + Creates a curve item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemCurve::QCPItemCurve(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition(QLatin1String("start"))), + startDir(createPosition(QLatin1String("startDir"))), + endDir(createPosition(QLatin1String("endDir"))), + end(createPosition(QLatin1String("end"))) +{ + start->setCoords(0, 0); + startDir->setCoords(0.5, 0); + endDir->setCoords(0, 0.5); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemCurve::~QCPItemCurve() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemCurve::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemCurve::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemCurve::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemCurve::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF startVec(start->pixelPosition()); + QPointF startDirVec(startDir->pixelPosition()); + QPointF endDirVec(endDir->pixelPosition()); + QPointF endVec(end->pixelPosition()); + + QPainterPath cubicPath(startVec); + cubicPath.cubicTo(startDirVec, endDirVec, endVec); + + QPolygonF polygon = cubicPath.toSubpathPolygons().first(); + QCPVector2D p(pos); + double minDistSqr = std::numeric_limits::max(); + for (int i=1; ipixelPosition()); + QCPVector2D startDirVec(startDir->pixelPosition()); + QCPVector2D endDirVec(endDir->pixelPosition()); + QCPVector2D endVec(end->pixelPosition()); + if ((endVec-startVec).length() > 1e10) // too large curves cause crash + return; + + QPainterPath cubicPath(startVec.toPointF()); + cubicPath.cubicTo(startDirVec.toPointF(), endDirVec.toPointF(), endVec.toPointF()); + + // paint visible segment, if existent: + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + QRect cubicRect = cubicPath.controlPointRect().toRect(); + if (cubicRect.isEmpty()) // may happen when start and end exactly on same x or y position + cubicRect.adjust(0, 0, 1, 1); + if (clip.intersects(cubicRect)) + { + painter->setPen(mainPen()); + painter->drawPath(cubicPath); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, startVec, M_PI-cubicPath.angleAtPercent(0)/180.0*M_PI); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, endVec, -cubicPath.angleAtPercent(1)/180.0*M_PI); + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemCurve::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-curve.cpp' */ + + +/* including file 'src/items/item-rect.cpp', size 6479 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemRect +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemRect + \brief A rectangle + + \image html QCPItemRect.png "Rectangle example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle. +*/ + +/*! + Creates a rectangle item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemRect::QCPItemRect(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemRect::~QCPItemRect() +{ +} + +/*! + Sets the pen that will be used to draw the line of the rectangle + + \see setSelectedPen, setBrush +*/ +void QCPItemRect::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the rectangle when selected + + \see setPen, setSelected +*/ +void QCPItemRect::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the rectangle. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemRect::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the rectangle when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemRect::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemRect::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()).normalized(); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectDistance(rect, pos, filledRect); +} + +/* inherits documentation from base class */ +void QCPItemRect::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF rect = QRectF(p1, p2).normalized(); + double clipPad = mainPen().widthF(); + QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) // only draw if bounding rect of rect item is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(rect); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemRect::anchorPixelPosition(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemRect::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemRect::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-rect.cpp' */ + + +/* including file 'src/items/item-text.cpp', size 13338 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemText +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemText + \brief A text label + + \image html QCPItemText.png "Text example. Blue dotted circles are anchors, solid blue discs are positions." + + Its position is defined by the member \a position and the setting of \ref setPositionAlignment. + The latter controls which part of the text rect shall be aligned with \a position. + + The text alignment itself (i.e. left, center, right) can be controlled with \ref + setTextAlignment. + + The text may be rotated around the \a position point with \ref setRotation. +*/ + +/*! + Creates a text item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemText::QCPItemText(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + topLeft(createAnchor(QLatin1String("topLeft"), aiTopLeft)), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottomRight(createAnchor(QLatin1String("bottomRight"), aiBottomRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)), + mText(QLatin1String("text")), + mPositionAlignment(Qt::AlignCenter), + mTextAlignment(Qt::AlignTop|Qt::AlignHCenter), + mRotation(0) +{ + position->setCoords(0, 0); + + setPen(Qt::NoPen); + setSelectedPen(Qt::NoPen); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setColor(Qt::black); + setSelectedColor(Qt::blue); +} + +QCPItemText::~QCPItemText() +{ +} + +/*! + Sets the color of the text. +*/ +void QCPItemText::setColor(const QColor &color) +{ + mColor = color; +} + +/*! + Sets the color of the text that will be used when the item is selected. +*/ +void QCPItemText::setSelectedColor(const QColor &color) +{ + mSelectedColor = color; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text. To disable the + border, set \a pen to Qt::NoPen. + + \see setSelectedPen, setBrush, setPadding +*/ +void QCPItemText::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text, when the item is + selected. To disable the border, set \a pen to Qt::NoPen. + + \see setPen +*/ +void QCPItemText::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used do fill the background of the text. To disable the + background, set \a brush to Qt::NoBrush. + + \see setSelectedBrush, setPen, setPadding +*/ +void QCPItemText::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used do fill the background of the text, when the item is selected. To disable the + background, set \a brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemText::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the font of the text. + + \see setSelectedFont, setColor +*/ +void QCPItemText::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the font of the text that will be used when the item is selected. + + \see setFont +*/ +void QCPItemText::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the text that will be displayed. Multi-line texts are supported by inserting a line break + character, e.g. '\n'. + + \see setFont, setColor, setTextAlignment +*/ +void QCPItemText::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets which point of the text rect shall be aligned with \a position. + + Examples: + \li If \a alignment is Qt::AlignHCenter | Qt::AlignTop, the text will be positioned such + that the top of the text rect will be horizontally centered on \a position. + \li If \a alignment is Qt::AlignLeft | Qt::AlignBottom, \a position will indicate the + bottom left corner of the text rect. + + If you want to control the alignment of (multi-lined) text within the text rect, use \ref + setTextAlignment. +*/ +void QCPItemText::setPositionAlignment(Qt::Alignment alignment) +{ + mPositionAlignment = alignment; +} + +/*! + Controls how (multi-lined) text is aligned inside the text rect (typically Qt::AlignLeft, Qt::AlignCenter or Qt::AlignRight). +*/ +void QCPItemText::setTextAlignment(Qt::Alignment alignment) +{ + mTextAlignment = alignment; +} + +/*! + Sets the angle in degrees by which the text (and the text rectangle, if visible) will be rotated + around \a position. +*/ +void QCPItemText::setRotation(double degrees) +{ + mRotation = degrees; +} + +/*! + Sets the distance between the border of the text rectangle and the text. The appearance (and + visibility) of the text rectangle can be controlled with \ref setPen and \ref setBrush. +*/ +void QCPItemText::setPadding(const QMargins &padding) +{ + mPadding = padding; +} + +/* inherits documentation from base class */ +double QCPItemText::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + // The rect may be rotated, so we transform the actual clicked pos to the rotated + // coordinate system, so we can use the normal rectDistance function for non-rotated rects: + QPointF positionPixels(position->pixelPosition()); + QTransform inputTransform; + inputTransform.translate(positionPixels.x(), positionPixels.y()); + inputTransform.rotate(-mRotation); + inputTransform.translate(-positionPixels.x(), -positionPixels.y()); + QPointF rotatedPos = inputTransform.map(pos); + QFontMetrics fontMetrics(mFont); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(positionPixels, textBoxRect, mPositionAlignment); + textBoxRect.moveTopLeft(textPos.toPoint()); + + return rectDistance(textBoxRect, rotatedPos, true); +} + +/* inherits documentation from base class */ +void QCPItemText::draw(QCPPainter *painter) +{ + QPointF pos(position->pixelPosition()); + QTransform transform = painter->transform(); + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + painter->setFont(mainFont()); + QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textRect.moveTopLeft(textPos.toPoint()+QPoint(mPadding.left(), mPadding.top())); + textBoxRect.moveTopLeft(textPos.toPoint()); + double clipPad = mainPen().widthF(); + QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (transform.mapRect(boundingRect).intersects(painter->transform().mapRect(clipRect()))) + { + painter->setTransform(transform); + if ((mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) || + (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0)) + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(textBoxRect); + } + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(mainColor())); + painter->drawText(textRect, Qt::TextDontClip|mTextAlignment, mText); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemText::anchorPixelPosition(int anchorId) const +{ + // get actual rect points (pretty much copied from draw function): + QPointF pos(position->pixelPosition()); + QTransform transform; + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + QFontMetrics fontMetrics(mainFont()); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRectF textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textBoxRect.moveTopLeft(textPos.toPoint()); + QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect)); + + switch (anchorId) + { + case aiTopLeft: return rectPoly.at(0); + case aiTop: return (rectPoly.at(0)+rectPoly.at(1))*0.5; + case aiTopRight: return rectPoly.at(1); + case aiRight: return (rectPoly.at(1)+rectPoly.at(2))*0.5; + case aiBottomRight: return rectPoly.at(2); + case aiBottom: return (rectPoly.at(2)+rectPoly.at(3))*0.5; + case aiBottomLeft: return rectPoly.at(3); + case aiLeft: return (rectPoly.at(3)+rectPoly.at(0))*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the point that must be given to the QPainter::drawText function (which expects the top + left point of the text rect), according to the position \a pos, the text bounding box \a rect and + the requested \a positionAlignment. + + For example, if \a positionAlignment is Qt::AlignLeft | Qt::AlignBottom the returned point + will be shifted upward by the height of \a rect, starting from \a pos. So if the text is finally + drawn at that point, the lower left corner of the resulting text rect is at \a pos. +*/ +QPointF QCPItemText::getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const +{ + if (positionAlignment == 0 || positionAlignment == (Qt::AlignLeft|Qt::AlignTop)) + return pos; + + QPointF result = pos; // start at top left + if (positionAlignment.testFlag(Qt::AlignHCenter)) + result.rx() -= rect.width()/2.0; + else if (positionAlignment.testFlag(Qt::AlignRight)) + result.rx() -= rect.width(); + if (positionAlignment.testFlag(Qt::AlignVCenter)) + result.ry() -= rect.height()/2.0; + else if (positionAlignment.testFlag(Qt::AlignBottom)) + result.ry() -= rect.height(); + return result; +} + +/*! \internal + + Returns the font that should be used for drawing text. Returns mFont when the item is not selected + and mSelectedFont when it is. +*/ +QFont QCPItemText::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the color that should be used for drawing text. Returns mColor when the item is not + selected and mSelectedColor when it is. +*/ +QColor QCPItemText::mainColor() const +{ + return mSelected ? mSelectedColor : mColor; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemText::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemText::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-text.cpp' */ + + +/* including file 'src/items/item-ellipse.cpp', size 7863 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemEllipse +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemEllipse + \brief An ellipse + + \image html QCPItemEllipse.png "Ellipse example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rect the ellipse will be drawn in. +*/ + +/*! + Creates an ellipse item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemEllipse::QCPItemEllipse(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + topLeftRim(createAnchor(QLatin1String("topLeftRim"), aiTopLeftRim)), + top(createAnchor(QLatin1String("top"), aiTop)), + topRightRim(createAnchor(QLatin1String("topRightRim"), aiTopRightRim)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottomRightRim(createAnchor(QLatin1String("bottomRightRim"), aiBottomRightRim)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeftRim(createAnchor(QLatin1String("bottomLeftRim"), aiBottomLeftRim)), + left(createAnchor(QLatin1String("left"), aiLeft)), + center(createAnchor(QLatin1String("center"), aiCenter)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemEllipse::~QCPItemEllipse() +{ +} + +/*! + Sets the pen that will be used to draw the line of the ellipse + + \see setSelectedPen, setBrush +*/ +void QCPItemEllipse::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the ellipse when selected + + \see setPen, setSelected +*/ +void QCPItemEllipse::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the ellipse. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemEllipse::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the ellipse when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemEllipse::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemEllipse::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + QPointF center((p1+p2)/2.0); + double a = qAbs(p1.x()-p2.x())/2.0; + double b = qAbs(p1.y()-p2.y())/2.0; + double x = pos.x()-center.x(); + double y = pos.y()-center.y(); + + // distance to border: + double c = 1.0/qSqrt(x*x/(a*a)+y*y/(b*b)); + double result = qAbs(c-1)*qSqrt(x*x+y*y); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (x*x/(a*a) + y*y/(b*b) <= 1) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/* inherits documentation from base class */ +void QCPItemEllipse::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF ellipseRect = QRectF(p1, p2).normalized(); + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + if (ellipseRect.intersects(clip)) // only draw if bounding rect of ellipse is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); +#ifdef __EXCEPTIONS + try // drawEllipse sometimes throws exceptions if ellipse is too big + { +#endif + painter->drawEllipse(ellipseRect); +#ifdef __EXCEPTIONS + } catch (...) + { + qDebug() << Q_FUNC_INFO << "Item too large for memory, setting invisible"; + setVisible(false); + } +#endif + } +} + +/* inherits documentation from base class */ +QPointF QCPItemEllipse::anchorPixelPosition(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); + switch (anchorId) + { + case aiTopLeftRim: return rect.center()+(rect.topLeft()-rect.center())*1/qSqrt(2); + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRightRim: return rect.center()+(rect.topRight()-rect.center())*1/qSqrt(2); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottomRightRim: return rect.center()+(rect.bottomRight()-rect.center())*1/qSqrt(2); + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeftRim: return rect.center()+(rect.bottomLeft()-rect.center())*1/qSqrt(2); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + case aiCenter: return (rect.topLeft()+rect.bottomRight())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemEllipse::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemEllipse::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-ellipse.cpp' */ + + +/* including file 'src/items/item-pixmap.cpp', size 10615 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemPixmap +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemPixmap + \brief An arbitrary pixmap + + \image html QCPItemPixmap.png "Pixmap example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle the pixmap will + be drawn in. Depending on the scale setting (\ref setScaled), the pixmap will be either scaled to + fit the rectangle or be drawn aligned to the topLeft position. + + If scaling is enabled and \a topLeft is further to the bottom/right than \a bottomRight (as shown + on the right side of the example image), the pixmap will be flipped in the respective + orientations. +*/ + +/*! + Creates a rectangle item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemPixmap::QCPItemPixmap(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)), + mScaled(false), + mScaledPixmapInvalidated(true), + mAspectRatioMode(Qt::KeepAspectRatio), + mTransformationMode(Qt::SmoothTransformation) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(Qt::NoPen); + setSelectedPen(QPen(Qt::blue)); +} + +QCPItemPixmap::~QCPItemPixmap() +{ +} + +/*! + Sets the pixmap that will be displayed. +*/ +void QCPItemPixmap::setPixmap(const QPixmap &pixmap) +{ + mPixmap = pixmap; + mScaledPixmapInvalidated = true; + if (mPixmap.isNull()) + qDebug() << Q_FUNC_INFO << "pixmap is null"; +} + +/*! + Sets whether the pixmap will be scaled to fit the rectangle defined by the \a topLeft and \a + bottomRight positions. +*/ +void QCPItemPixmap::setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformationMode) +{ + mScaled = scaled; + mAspectRatioMode = aspectRatioMode; + mTransformationMode = transformationMode; + mScaledPixmapInvalidated = true; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap. + + \see setSelectedPen, setBrush +*/ +void QCPItemPixmap::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap when selected + + \see setPen, setSelected +*/ +void QCPItemPixmap::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemPixmap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return rectDistance(getFinalRect(), pos, true); +} + +/* inherits documentation from base class */ +void QCPItemPixmap::draw(QCPPainter *painter) +{ + bool flipHorz = false; + bool flipVert = false; + QRect rect = getFinalRect(&flipHorz, &flipVert); + double clipPad = mainPen().style() == Qt::NoPen ? 0 : mainPen().widthF(); + QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) + { + updateScaledPixmap(rect, flipHorz, flipVert); + painter->drawPixmap(rect.topLeft(), mScaled ? mScaledPixmap : mPixmap); + QPen pen = mainPen(); + if (pen.style() != Qt::NoPen) + { + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + painter->drawRect(rect); + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemPixmap::anchorPixelPosition(int anchorId) const +{ + bool flipHorz; + bool flipVert; + QRect rect = getFinalRect(&flipHorz, &flipVert); + // we actually want denormal rects (negative width/height) here, so restore + // the flipped state: + if (flipHorz) + rect.adjust(rect.width(), 0, -rect.width(), 0); + if (flipVert) + rect.adjust(0, rect.height(), 0, -rect.height()); + + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5;; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Creates the buffered scaled image (\a mScaledPixmap) to fit the specified \a finalRect. The + parameters \a flipHorz and \a flipVert control whether the resulting image shall be flipped + horizontally or vertically. (This is used when \a topLeft is further to the bottom/right than \a + bottomRight.) + + This function only creates the scaled pixmap when the buffered pixmap has a different size than + the expected result, so calling this function repeatedly, e.g. in the \ref draw function, does + not cause expensive rescaling every time. + + If scaling is disabled, sets mScaledPixmap to a null QPixmap. +*/ +void QCPItemPixmap::updateScaledPixmap(QRect finalRect, bool flipHorz, bool flipVert) +{ + if (mPixmap.isNull()) + return; + + if (mScaled) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + double devicePixelRatio = mPixmap.devicePixelRatio(); +#else + double devicePixelRatio = 1.0; +#endif + if (finalRect.isNull()) + finalRect = getFinalRect(&flipHorz, &flipVert); + if (mScaledPixmapInvalidated || finalRect.size() != mScaledPixmap.size()/devicePixelRatio) + { + mScaledPixmap = mPixmap.scaled(finalRect.size()*devicePixelRatio, mAspectRatioMode, mTransformationMode); + if (flipHorz || flipVert) + mScaledPixmap = QPixmap::fromImage(mScaledPixmap.toImage().mirrored(flipHorz, flipVert)); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mScaledPixmap.setDevicePixelRatio(devicePixelRatio); +#endif + } + } else if (!mScaledPixmap.isNull()) + mScaledPixmap = QPixmap(); + mScaledPixmapInvalidated = false; +} + +/*! \internal + + Returns the final (tight) rect the pixmap is drawn in, depending on the current item positions + and scaling settings. + + The output parameters \a flippedHorz and \a flippedVert return whether the pixmap should be drawn + flipped horizontally or vertically in the returned rect. (The returned rect itself is always + normalized, i.e. the top left corner of the rect is actually further to the top/left than the + bottom right corner). This is the case when the item position \a topLeft is further to the + bottom/right than \a bottomRight. + + If scaling is disabled, returns a rect with size of the original pixmap and the top left corner + aligned with the item position \a topLeft. The position \a bottomRight is ignored. +*/ +QRect QCPItemPixmap::getFinalRect(bool *flippedHorz, bool *flippedVert) const +{ + QRect result; + bool flipHorz = false; + bool flipVert = false; + QPoint p1 = topLeft->pixelPosition().toPoint(); + QPoint p2 = bottomRight->pixelPosition().toPoint(); + if (p1 == p2) + return QRect(p1, QSize(0, 0)); + if (mScaled) + { + QSize newSize = QSize(p2.x()-p1.x(), p2.y()-p1.y()); + QPoint topLeft = p1; + if (newSize.width() < 0) + { + flipHorz = true; + newSize.rwidth() *= -1; + topLeft.setX(p2.x()); + } + if (newSize.height() < 0) + { + flipVert = true; + newSize.rheight() *= -1; + topLeft.setY(p2.y()); + } + QSize scaledSize = mPixmap.size(); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + scaledSize /= mPixmap.devicePixelRatio(); + scaledSize.scale(newSize*mPixmap.devicePixelRatio(), mAspectRatioMode); +#else + scaledSize.scale(newSize, mAspectRatioMode); +#endif + result = QRect(topLeft, scaledSize); + } else + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + result = QRect(p1, mPixmap.size()/mPixmap.devicePixelRatio()); +#else + result = QRect(p1, mPixmap.size()); +#endif + } + if (flippedHorz) + *flippedHorz = flipHorz; + if (flippedVert) + *flippedVert = flipVert; + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemPixmap::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-pixmap.cpp' */ + + +/* including file 'src/items/item-tracer.cpp', size 14624 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemTracer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemTracer + \brief Item that sticks to QCPGraph data points + + \image html QCPItemTracer.png "Tracer example. Blue dotted circles are anchors, solid blue discs are positions." + + The tracer can be connected with a QCPGraph via \ref setGraph. Then it will automatically adopt + the coordinate axes of the graph and update its \a position to be on the graph's data. This means + the key stays controllable via \ref setGraphKey, but the value will follow the graph data. If a + QCPGraph is connected, note that setting the coordinates of the tracer item directly via \a + position will have no effect because they will be overriden in the next redraw (this is when the + coordinate update happens). + + If the specified key in \ref setGraphKey is outside the key bounds of the graph, the tracer will + stay at the corresponding end of the graph. + + With \ref setInterpolating you may specify whether the tracer may only stay exactly on data + points or whether it interpolates data points linearly, if given a key that lies between two data + points of the graph. + + The tracer has different visual styles, see \ref setStyle. It is also possible to make the tracer + have no own visual appearance (set the style to \ref tsNone), and just connect other item + positions to the tracer \a position (used as an anchor) via \ref + QCPItemPosition::setParentAnchor. + + \note The tracer position is only automatically updated upon redraws. So when the data of the + graph changes and immediately afterwards (without a redraw) the position coordinates of the + tracer are retrieved, they will not reflect the updated data of the graph. In this case \ref + updatePosition must be called manually, prior to reading the tracer coordinates. +*/ + +/*! + Creates a tracer item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + mSize(6), + mStyle(tsCrosshair), + mGraph(0), + mGraphKey(0), + mInterpolating(false), + mType(-1) +{ + position->setCoords(0, 0); + + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot, qint64 timeStamp, int type, QPen pen, QBrush brush, const QList &alarmStatusList) + : QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + mPen(pen), + mBrush(brush), + mSize(5), + mStyle(tsCircle), + mGraph(0), + mGraphKey(0), + mInterpolating(true), + mType(type), + mTimeStamp(timeStamp), + m_alarmStatusList(alarmStatusList) +{ + position->setCoords(0, 0); + setSelectedBrush(Qt::NoBrush); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemTracer::~QCPItemTracer() +{ +} + +/*! + Sets the pen that will be used to draw the line of the tracer + + \see setSelectedPen, setBrush +*/ +void QCPItemTracer::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the tracer when selected + + \see setPen, setSelected +*/ +void QCPItemTracer::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer + + \see setSelectedBrush, setPen +*/ +void QCPItemTracer::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer, when selected. + + \see setBrush, setSelected +*/ +void QCPItemTracer::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the size of the tracer in pixels, if the style supports setting a size (e.g. \ref tsSquare + does, \ref tsCrosshair does not). +*/ +void QCPItemTracer::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the style/visual appearance of the tracer. + + If you only want to use the tracer \a position as an anchor for other items, set \a style to + \ref tsNone. +*/ +void QCPItemTracer::setStyle(QCPItemTracer::TracerStyle style) +{ + mStyle = style; +} + +/*! + Sets the QCPGraph this tracer sticks to. The tracer \a position will be set to type + QCPItemPosition::ptPlotCoords and the axes will be set to the axes of \a graph. + + To free the tracer from any graph, set \a graph to 0. The tracer \a position can then be placed + freely like any other item position. This is the state the tracer will assume when its graph gets + deleted while still attached to it. + + \see setGraphKey +*/ +void QCPItemTracer::setGraph(QCPGraph *graph) +{ + if (graph) + { + if (graph->parentPlot() == mParentPlot) + { + position->setType(QCPItemPosition::ptPlotCoords); + position->setAxes(graph->keyAxis(), graph->valueAxis()); + mGraph = graph; + updatePosition(); + } else + qDebug() << Q_FUNC_INFO << "graph isn't in same QCustomPlot instance as this item"; + } else + { + mGraph = 0; + } +} + +/*! + Sets the key of the graph's data point the tracer will be positioned at. This is the only free + coordinate of a tracer when attached to a graph. + + Depending on \ref setInterpolating, the tracer will be either positioned on the data point + closest to \a key, or will stay exactly at \a key and interpolate the value linearly. + + \see setGraph, setInterpolating +*/ +void QCPItemTracer::setGraphKey(double key) +{ + mGraphKey = key; +} + +void QCPItemTracer::setHidePoint(const QMultiMap &hidePoint) +{ + m_hidePoint = hidePoint; +} + +void QCPItemTracer::addHidePoint(const qint64 &time, const QString &tag) +{ + m_hidePoint.insert(time, tag); +} + +/*! + Sets whether the value of the graph's data points shall be interpolated, when positioning the + tracer. + + If \a enabled is set to false and a key is given with \ref setGraphKey, the tracer is placed on + the data point of the graph which is closest to the key, but which is not necessarily exactly + there. If \a enabled is true, the tracer will be positioned exactly at the specified key, and + the appropriate value will be interpolated from the graph's data points linearly. + + \see setGraph, setGraphKey +*/ +void QCPItemTracer::setInterpolating(bool enabled) +{ + mInterpolating = enabled; +} + +void QCPItemTracer::setType(const int &type) +{ + mType = type; +} + +void QCPItemTracer::setTimeStamp(const qint64 &timeStamp) +{ + mTimeStamp = timeStamp; +} + +void QCPItemTracer::setInfo(const QStringList infos) +{ + m_infos = infos; +} + +void QCPItemTracer::showTips() +{ + QString tips; + tips += m_infos.join("\n\n"); + CToolTip::popup(mParentPlot->mapToGlobal(position->pixelPosition().toPoint()), tips, this->parentPlot()); +} + +/* inherits documentation from base class */ +double QCPItemTracer::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF center(position->pixelPosition()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return -1; + case tsPlus: + { + if (clipRect().intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(center+QPointF(-w, 0), center+QPointF(w, 0)), + QCPVector2D(pos).distanceSquaredToLine(center+QPointF(0, -w), center+QPointF(0, w)))); + break; + } + case tsCrosshair: + { + return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(clip.left(), center.y()), QCPVector2D(clip.right(), center.y())), + QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(center.x(), clip.top()), QCPVector2D(center.x(), clip.bottom())))); + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + // distance to border: + double centerDist = QCPVector2D(center-pos).length(); + double circleLine = w; + double result = qAbs(centerDist-circleLine); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (centerDist <= circleLine) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; + } + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + QRectF rect = QRectF(center-QPointF(w, w), center+QPointF(w, w)); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectDistance(rect, pos, filledRect); + } + break; + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemTracer::draw(QCPPainter *painter) +{ + updatePosition(); + if (mStyle == tsNone) + return; + + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + QPointF center(position->pixelPosition()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return; + case tsPlus: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + painter->drawLine(QLineF(center+QPointF(-w, 0), center+QPointF(w, 0))); + painter->drawLine(QLineF(center+QPointF(0, -w), center+QPointF(0, w))); + } + break; + } + case tsCrosshair: + { + if (center.y() > clip.top() && center.y() < clip.bottom()) + painter->drawLine(QLineF(clip.left(), center.y(), clip.right(), center.y())); + if (center.x() > clip.left() && center.x() < clip.right()) + painter->drawLine(QLineF(center.x(), clip.top(), center.x(), clip.bottom())); + break; + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawEllipse(center, w, w); + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawRect(QRectF(center-QPointF(w, w), center+QPointF(w, w))); + break; + } + } +} + +void QCPItemTracer::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + QCPAbstractItem::mousePressEvent(event, details); +} + +void QCPItemTracer::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + QCPAbstractItem::mouseMoveEvent(event, startPos); + + if(QPoint(event->pos() - position->pixelPosition().toPoint()).manhattanLength() > 8) + { + hovFlag = 0; + return; + } + else if(QPoint(event->pos() - position->pixelPosition().toPoint()).manhattanLength() < 8) + { + if(hovFlag == 0) + hovFlag = 1; + } + if(hovFlag == 1) + { + emit itemTracerHoverd(mTimeStamp, m_hidePoint, m_alarmStatusList); + hovFlag = 2; + } +} + +/*! + If the tracer is connected with a graph (\ref setGraph), this function updates the tracer's \a + position to reside on the graph data, depending on the configured key (\ref setGraphKey). + + It is called automatically on every redraw and normally doesn't need to be called manually. One + exception is when you want to read the tracer coordinates via \a position and are not sure that + the graph's data (or the tracer key with \ref setGraphKey) hasn't changed since the last redraw. + In that situation, call this function before accessing \a position, to make sure you don't get + out-of-date coordinates. + + If there is no graph set on this tracer, this function does nothing. +*/ +void QCPItemTracer::updatePosition() +{ + if (mGraph) + { + if (mParentPlot->hasPlottable(mGraph)) + { + if (mGraph->data()->size() > 1) + { + QCPGraphDataContainer::const_iterator first = mGraph->data()->constBegin(); + QCPGraphDataContainer::const_iterator last = mGraph->data()->constEnd()-1; + if (mGraphKey <= first->key) + position->setCoords(first->key, first->value); + else if (mGraphKey >= last->key) + position->setCoords(last->key, last->value); + else + { + if(QCPGraph::lsStepLeft == mGraph->lineStyle()) + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->findEnd(mGraphKey, false); + if(it != mGraph->data()->constBegin()) + { + --it; + } + if (mInterpolating) + { + position->setCoords(mGraphKey, it->value); + } + else + { + position->setCoords(it->key, it->value); + } + } + else + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->findBegin(mGraphKey); + if (it != mGraph->data()->constEnd()) // mGraphKey is not exactly on last iterator, but somewhere between iterators + { + QCPGraphDataContainer::const_iterator prevIt = it; + ++it; // won't advance to constEnd because we handled that case (mGraphKey >= last->key) before + if (mInterpolating) + { + // interpolate between iterators around mGraphKey: + double slope = 0; + if (!qFuzzyCompare((double)it->key, (double)prevIt->key)) + slope = (it->value-prevIt->value)/(it->key-prevIt->key); + position->setCoords(mGraphKey, (mGraphKey-prevIt->key)*slope+prevIt->value); + } else + { + // find iterator with key closest to mGraphKey: + if (mGraphKey < (prevIt->key+it->key)*0.5) + position->setCoords(prevIt->key, prevIt->value); + else + position->setCoords(it->key, it->value); + } + } else // mGraphKey is exactly on last iterator (should actually be caught when comparing first/last keys, but this is a failsafe for fp uncertainty) + position->setCoords(it->key, it->value); + } + } + } else if (mGraph->data()->size() == 1) + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->constBegin(); + position->setCoords(it->key, it->value); + } else + qDebug() << Q_FUNC_INFO << "graph has no data"; + } else + qDebug() << Q_FUNC_INFO << "graph not contained in QCustomPlot instance (anymore)"; + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemTracer::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemTracer::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-tracer.cpp' */ + + +/* including file 'src/items/item-bracket.cpp', size 10687 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemBracket +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemBracket + \brief A bracket for referencing/highlighting certain parts in the plot. + + \image html QCPItemBracket.png "Bracket example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a left and \a right, which define the span of the bracket. If \a left is + actually farther to the left than \a right, the bracket is opened to the bottom, as shown in the + example image. + + The bracket supports multiple styles via \ref setStyle. The length, i.e. how far the bracket + stretches away from the embraced span, can be controlled with \ref setLength. + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+ + It provides an anchor \a center, to allow connection of other items, e.g. an arrow (QCPItemLine + or QCPItemCurve) or a text label (QCPItemText), to the bracket. +*/ + +/*! + Creates a bracket item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemBracket::QCPItemBracket(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + left(createPosition(QLatin1String("left"))), + right(createPosition(QLatin1String("right"))), + center(createAnchor(QLatin1String("center"), aiCenter)), + mLength(8), + mStyle(bsCalligraphic) +{ + left->setCoords(0, 0); + right->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemBracket::~QCPItemBracket() +{ +} + +/*! + Sets the pen that will be used to draw the bracket. + + Note that when the style is \ref bsCalligraphic, only the color will be taken from the pen, the + stroke and width are ignored. To change the apparent stroke width of a calligraphic bracket, use + \ref setLength, which has a similar effect. + + \see setSelectedPen +*/ +void QCPItemBracket::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the bracket when selected + + \see setPen, setSelected +*/ +void QCPItemBracket::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the \a length in pixels how far the bracket extends in the direction towards the embraced + span of the bracket (i.e. perpendicular to the left-right-direction) + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+*/ +void QCPItemBracket::setLength(double length) +{ + mLength = length; +} + +/*! + Sets the style of the bracket, i.e. the shape/visual appearance. + + \see setPen +*/ +void QCPItemBracket::setStyle(QCPItemBracket::BracketStyle style) +{ + mStyle = style; +} + +/* inherits documentation from base class */ +double QCPItemBracket::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QCPVector2D p(pos); + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return -1; + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + switch (mStyle) + { + case QCPItemBracket::bsSquare: + case QCPItemBracket::bsRound: + { + double a = p.distanceSquaredToLine(centerVec-widthVec, centerVec+widthVec); + double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec, centerVec-widthVec); + double c = p.distanceSquaredToLine(centerVec+widthVec+lengthVec, centerVec+widthVec); + return qSqrt(qMin(qMin(a, b), c)); + } + case QCPItemBracket::bsCurly: + case QCPItemBracket::bsCalligraphic: + { + double a = p.distanceSquaredToLine(centerVec-widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); + double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec*0.7, centerVec-widthVec*0.75+lengthVec*0.15); + double c = p.distanceSquaredToLine(centerVec+widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); + double d = p.distanceSquaredToLine(centerVec+widthVec+lengthVec*0.7, centerVec+widthVec*0.75+lengthVec*0.15); + return qSqrt(qMin(qMin(a, b), qMin(c, d))); + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemBracket::draw(QCPPainter *painter) +{ + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return; + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + QPolygon boundingPoly; + boundingPoly << leftVec.toPoint() << rightVec.toPoint() + << (rightVec-lengthVec).toPoint() << (leftVec-lengthVec).toPoint(); + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + if (clip.intersects(boundingPoly.boundingRect())) + { + painter->setPen(mainPen()); + switch (mStyle) + { + case bsSquare: + { + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec-widthVec).toPointF()); + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + painter->drawLine((centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + break; + } + case bsRound: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec).toPointF(), (centerVec+widthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-widthVec).toPointF(), (centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCurly: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4*widthVec+lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCalligraphic: + { + painter->setPen(Qt::NoPen); + painter->setBrush(QBrush(mainPen().color())); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+0.8*lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4*widthVec+0.8*lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec-widthVec-lengthVec*0.5).toPointF(), (centerVec-0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+lengthVec*0.2).toPointF()); + path.cubicTo((centerVec+0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+widthVec-lengthVec*0.5).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + + painter->drawPath(path); + break; + } + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemBracket::anchorPixelPosition(int anchorId) const +{ + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return leftVec.toPointF(); + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + switch (anchorId) + { + case aiCenter: + return centerVec.toPointF(); + } + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemBracket::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-bracket.cpp' */ diff --git a/product/src/gui/plugin/TrendCurves_pad/plot/qcustomplot.h b/product/src/gui/plugin/TrendCurves_pad/plot/qcustomplot.h new file mode 100644 index 00000000..e630f91f --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/plot/qcustomplot.h @@ -0,0 +1,6766 @@ +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2017 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 04.09.17 ** +** Version: 2.0.0 ** +****************************************************************************/ + +#ifndef QCUSTOMPLOT_H +#define QCUSTOMPLOT_H + +#include + +// some Qt version/configuration dependent macros to include or exclude certain code paths: +#ifdef QCUSTOMPLOT_USE_OPENGL +# if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# define QCP_OPENGL_PBUFFER +# else +# define QCP_OPENGL_FBO +# endif +# if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) +# define QCP_OPENGL_OFFSCREENSURFACE +# endif +#endif + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) +# define QCP_DEVICEPIXELRATIO_SUPPORTED +# if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) +# define QCP_DEVICEPIXELRATIO_FLOAT +# endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef QCP_OPENGL_FBO +# include +# include +# ifdef QCP_OPENGL_OFFSCREENSURFACE +# include +# else +# include +# endif +#endif +#ifdef QCP_OPENGL_PBUFFER +# include +#endif +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# include +# include +# include +# include +#else +# include +# include +# include +#endif + +class QCPPainter; +class QCustomPlot; +class QCPLayerable; +class QCPLayoutElement; +class QCPLayout; +class QCPAxis; +class QCPAxisRect; +class QCPAxisPainterPrivate; +class QCPAbstractPlottable; +class QCPGraph; +class QCPAbstractItem; +class QCPPlottableInterface1D; +class QCPLegend; +class QCPItemPosition; +class QCPLayer; +class QCPAbstractLegendItem; +class QCPSelectionRect; +class QCPColorMap; +class QCPColorScale; +class QCPBars; + +/* including file 'src/global.h', size 16225 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +// decl definitions for shared library compilation/usage: +#if defined(QCUSTOMPLOT_COMPILE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_EXPORT +#elif defined(QCUSTOMPLOT_USE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_IMPORT +#else +# define QCP_LIB_DECL +#endif + +// define empty macro for Q_DECL_OVERRIDE if it doesn't exist (Qt < 5) +#ifndef Q_DECL_OVERRIDE +# define Q_DECL_OVERRIDE +#endif + +/*! + The QCP Namespace contains general enums, QFlags and functions used throughout the QCustomPlot + library. + + It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject. +*/ +#ifndef Q_MOC_RUN +namespace QCP { +#else +class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS features in namespace + Q_GADGET + Q_ENUMS(ExportPen) + Q_ENUMS(ResolutionUnit) + Q_ENUMS(SignDomain) + Q_ENUMS(MarginSide) + Q_FLAGS(MarginSides) + Q_ENUMS(AntialiasedElement) + Q_FLAGS(AntialiasedElements) + Q_ENUMS(PlottingHint) + Q_FLAGS(PlottingHints) + Q_ENUMS(Interaction) + Q_FLAGS(Interactions) + Q_ENUMS(SelectionRectMode) + Q_ENUMS(SelectionType) +public: +#endif + +/*! + Defines the different units in which the image resolution can be specified in the export + functions. + + \see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered +*/ +enum ResolutionUnit { ruDotsPerMeter ///< Resolution is given in dots per meter (dpm) + ,ruDotsPerCentimeter ///< Resolution is given in dots per centimeter (dpcm) + ,ruDotsPerInch ///< Resolution is given in dots per inch (DPI/PPI) + }; + +/*! + Defines how cosmetic pens (pens with numerical width 0) are handled during export. + + \see QCustomPlot::savePdf +*/ +enum ExportPen { epNoCosmetic ///< Cosmetic pens are converted to pens with pixel width 1 when exporting + ,epAllowCosmetic ///< Cosmetic pens are exported normally (e.g. in PDF exports, cosmetic pens always appear as 1 pixel on screen, independent of viewer zoom level) + }; + +/*! + Represents negative and positive sign domain, e.g. for passing to \ref + QCPAbstractPlottable::getKeyRange and \ref QCPAbstractPlottable::getValueRange. + + This is primarily needed when working with logarithmic axis scales, since only one of the sign + domains can be visible at a time. +*/ +enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero + ,sdBoth ///< Both sign domains, including zero, i.e. all numbers + ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero + }; + +/*! + Defines the sides of a rectangular entity to which margins can be applied. + + \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins +*/ +enum MarginSide { msLeft = 0x01 ///< 0x01 left margin + ,msRight = 0x02 ///< 0x02 right margin + ,msTop = 0x04 ///< 0x04 top margin + ,msBottom = 0x08 ///< 0x08 bottom margin + ,msAll = 0xFF ///< 0xFF all margins + ,msNone = 0x00 ///< 0x00 no margin + }; +Q_DECLARE_FLAGS(MarginSides, MarginSide) + +/*! + Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is + neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective + element how it is drawn. Typically it provides a \a setAntialiased function for this. + + \c AntialiasedElements is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements +*/ +enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks + ,aeGrid = 0x0002 ///< 0x0002 Grid lines + ,aeSubGrid = 0x0004 ///< 0x0004 Sub grid lines + ,aeLegend = 0x0008 ///< 0x0008 Legend box + ,aeLegendItems = 0x0010 ///< 0x0010 Legend items + ,aePlottables = 0x0020 ///< 0x0020 Main lines of plottables + ,aeItems = 0x0040 ///< 0x0040 Main lines of items + ,aeScatters = 0x0080 ///< 0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) + ,aeFills = 0x0100 ///< 0x0100 Borders of fills (e.g. under or between graphs) + ,aeZeroLine = 0x0200 ///< 0x0200 Zero-lines, see \ref QCPGrid::setZeroLinePen + ,aeOther = 0x8000 ///< 0x8000 Other elements that don't fit into any of the existing categories + ,aeAll = 0xFFFF ///< 0xFFFF All elements + ,aeNone = 0x0000 ///< 0x0000 No elements + }; +Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement) + +/*! + Defines plotting hints that control various aspects of the quality and speed of plotting. + + \see QCustomPlot::setPlottingHints +*/ +enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set + ,phFastPolylines = 0x001 ///< 0x001 Graph/Curve lines are drawn with a faster method. This reduces the quality especially of the line segment + ///< joins, thus is most effective for pen sizes larger than 1. It is only used for solid line pens. + ,phImmediateRefresh = 0x002 ///< 0x002 causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpRefreshHint. + ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse). + ,phCacheLabels = 0x004 ///< 0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance. + }; +Q_DECLARE_FLAGS(PlottingHints, PlottingHint) + +/*! + Defines the mouse interactions possible with QCustomPlot. + + \c Interactions is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setInteractions +*/ +enum Interaction { iRangeDrag = 0x001 ///< 0x001 Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes) + ,iRangeZoom = 0x002 ///< 0x002 Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes) + ,iMultiSelect = 0x004 ///< 0x004 The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking + ,iSelectPlottables = 0x008 ///< 0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) + ,iSelectAxes = 0x010 ///< 0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts) + ,iSelectLegend = 0x020 ///< 0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) + ,iSelectItems = 0x040 ///< 0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem) + ,iSelectOther = 0x080 ///< 0x080 All other objects are selectable (e.g. your own derived layerables, other layout elements,...) + }; +Q_DECLARE_FLAGS(Interactions, Interaction) + +/*! + Defines the behaviour of the selection rect. + + \see QCustomPlot::setSelectionRectMode, QCustomPlot::selectionRect, QCPSelectionRect +*/ +enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging + ,srmZoom ///< When dragging the mouse, a selection rect becomes active. Upon releasing, the axes that are currently set as range zoom axes (\ref QCPAxisRect::setRangeZoomAxes) will have their ranges zoomed accordingly. + ,srmSelect ///< When dragging the mouse, a selection rect becomes active. Upon releasing, plottable data points that were within the selection rect are selected, if the plottable's selectability setting permits. (See \ref dataselection "data selection mechanism" for details.) + ,srmCustom ///< When dragging the mouse, a selection rect becomes active. It is the programmer's responsibility to connect according slots to the selection rect's signals (e.g. \ref QCPSelectionRect::accepted) in order to process the user interaction. + }; + +/*! + Defines the different ways a plottable can be selected. These images show the effect of the + different selection types, when the indicated selection rect was dragged: + +
+ + + + + + + + +
\image html selectiontype-none.png stNone\image html selectiontype-whole.png stWhole\image html selectiontype-singledata.png stSingleData\image html selectiontype-datarange.png stDataRange\image html selectiontype-multipledataranges.png stMultipleDataRanges
+
+ + \see QCPAbstractPlottable::setSelectable, QCPDataSelection::enforceType +*/ +enum SelectionType { stNone ///< The plottable is not selectable + ,stWhole ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points selected, the entire plottable is drawn as selected. + ,stSingleData ///< One individual data point can be selected at a time + ,stDataRange ///< Multiple contiguous data points (a data range) can be selected + ,stMultipleDataRanges ///< Any combination of data points/ranges can be selected + }; + +/*! \internal + + Returns whether the specified \a value is considered an invalid data value for plottables (i.e. + is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the + compiler flag \c QCUSTOMPLOT_CHECK_DATA is set. +*/ +inline bool isInvalidData(double value) +{ + return qIsNaN(value) || qIsInf(value); +} + +/*! \internal + \overload + + Checks two arguments instead of one. +*/ +inline bool isInvalidData(double value1, double value2) +{ + return isInvalidData(value1) || isInvalidData(value2); +} + +/*! \internal + + Sets the specified \a side of \a margins to \a value + + \see getMarginValue +*/ +inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value) +{ + switch (side) + { + case QCP::msLeft: margins.setLeft(value); break; + case QCP::msRight: margins.setRight(value); break; + case QCP::msTop: margins.setTop(value); break; + case QCP::msBottom: margins.setBottom(value); break; + case QCP::msAll: margins = QMargins(value, value, value, value); break; + default: break; + } +} + +/*! \internal + + Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or + \ref QCP::msAll, returns 0. + + \see setMarginValue +*/ +inline int getMarginValue(const QMargins &margins, QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return margins.left(); + case QCP::msRight: return margins.right(); + case QCP::msTop: return margins.top(); + case QCP::msBottom: return margins.bottom(); + default: break; + } + return 0; +} + + +extern const QMetaObject staticMetaObject; // in moc-run we create a static meta object for QCP "fake" object. This line is the link to it via QCP::staticMetaObject in normal operation as namespace + +} // end of namespace QCP +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions) +Q_DECLARE_METATYPE(QCP::ExportPen) +Q_DECLARE_METATYPE(QCP::ResolutionUnit) +Q_DECLARE_METATYPE(QCP::SignDomain) +Q_DECLARE_METATYPE(QCP::MarginSide) +Q_DECLARE_METATYPE(QCP::AntialiasedElement) +Q_DECLARE_METATYPE(QCP::PlottingHint) +Q_DECLARE_METATYPE(QCP::Interaction) +Q_DECLARE_METATYPE(QCP::SelectionRectMode) +Q_DECLARE_METATYPE(QCP::SelectionType) + +/* end of 'src/global.h' */ + + +/* including file 'src/vector2d.h', size 4928 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPVector2D +{ +public: + QCPVector2D(); + QCPVector2D(double x, double y); + QCPVector2D(const QPoint &point); + QCPVector2D(const QPointF &point); + + // getters: + double x() const { return mX; } + double y() const { return mY; } + double &rx() { return mX; } + double &ry() { return mY; } + + // setters: + void setX(double x) { mX = x; } + void setY(double y) { mY = y; } + + // non-virtual methods: + double length() const { return qSqrt(mX*mX+mY*mY); } + double lengthSquared() const { return mX*mX+mY*mY; } + QPoint toPoint() const { return QPoint(mX, mY); } + QPointF toPointF() const { return QPointF(mX, mY); } + + bool isNull() const { return qIsNull(mX) && qIsNull(mY); } + void normalize(); + QCPVector2D normalized() const; + QCPVector2D perpendicular() const { return QCPVector2D(-mY, mX); } + double dot(const QCPVector2D &vec) const { return mX*vec.mX+mY*vec.mY; } + double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const; + double distanceSquaredToLine(const QLineF &line) const; + double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const; + + QCPVector2D &operator*=(double factor); + QCPVector2D &operator/=(double divisor); + QCPVector2D &operator+=(const QCPVector2D &vector); + QCPVector2D &operator-=(const QCPVector2D &vector); + +private: + // property members: + double mX, mY; + + friend inline const QCPVector2D operator*(double factor, const QCPVector2D &vec); + friend inline const QCPVector2D operator*(const QCPVector2D &vec, double factor); + friend inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor); + friend inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2); + friend inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2); + friend inline const QCPVector2D operator-(const QCPVector2D &vec); +}; +Q_DECLARE_TYPEINFO(QCPVector2D, Q_MOVABLE_TYPE); + +inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } +inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } +inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) { return QCPVector2D(vec.mX/divisor, vec.mY/divisor); } +inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX+vec2.mX, vec1.mY+vec2.mY); } +inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX-vec2.mX, vec1.mY-vec2.mY); } +inline const QCPVector2D operator-(const QCPVector2D &vec) { return QCPVector2D(-vec.mX, -vec.mY); } + +/*! \relates QCPVector2D + + Prints \a vec in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPVector2D &vec) +{ + d.nospace() << "QCPVector2D(" << vec.x() << ", " << vec.y() << ")"; + return d.space(); +} + +/* end of 'src/vector2d.h' */ + + +/* including file 'src/painter.h', size 4035 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPPainter : public QPainter +{ + Q_GADGET +public: + /*! + Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds, + depending on whether they are wanted on the respective output device. + */ + enum PainterMode { pmDefault = 0x00 ///< 0x00 Default mode for painting on screen devices + ,pmVectorized = 0x01 ///< 0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes. + ,pmNoCaching = 0x02 ///< 0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels + ,pmNonCosmetic = 0x04 ///< 0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width 1 pixel in the vector image/pdf viewer, independent of zoom.) + }; + Q_ENUMS(PainterMode) + Q_FLAGS(PainterModes) + Q_DECLARE_FLAGS(PainterModes, PainterMode) + + QCPPainter(); + explicit QCPPainter(QPaintDevice *device); + + // getters: + bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); } + PainterModes modes() const { return mModes; } + + // setters: + void setAntialiasing(bool enabled); + void setMode(PainterMode mode, bool enabled=true); + void setModes(PainterModes modes); + + // methods hiding non-virtual base class functions (QPainter bug workarounds): + bool begin(QPaintDevice *device); + void setPen(const QPen &pen); + void setPen(const QColor &color); + void setPen(Qt::PenStyle penStyle); + void drawLine(const QLineF &line); + void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));} + void save(); + void restore(); + + // non-virtual methods: + void makeNonCosmetic(); + +protected: + // property members: + PainterModes mModes; + bool mIsAntialiasing; + + // non-property members: + QStack mAntialiasingStack; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes) +Q_DECLARE_METATYPE(QCPPainter::PainterMode) + +/* end of 'src/painter.h' */ + + +/* including file 'src/paintbuffer.h', size 4958 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAbstractPaintBuffer +{ +public: + explicit QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio); + virtual ~QCPAbstractPaintBuffer(); + + // getters: + QSize size() const { return mSize; } + bool invalidated() const { return mInvalidated; } + double devicePixelRatio() const { return mDevicePixelRatio; } + + // setters: + void setSize(const QSize &size); + void setInvalidated(bool invalidated=true); + void setDevicePixelRatio(double ratio); + + // introduced virtual methods: + virtual QCPPainter *startPainting() = 0; + virtual void donePainting() {} + virtual void draw(QCPPainter *painter) const = 0; + virtual void clear(const QColor &color) = 0; + +protected: + // property members: + QSize mSize; + double mDevicePixelRatio; + + // non-property members: + bool mInvalidated; + + // introduced virtual methods: + virtual void reallocateBuffer() = 0; +}; + + +class QCP_LIB_DECL QCPPaintBufferPixmap : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio); + virtual ~QCPPaintBufferPixmap(); + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QPixmap mBuffer; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; + + +#ifdef QCP_OPENGL_PBUFFER +class QCP_LIB_DECL QCPPaintBufferGlPbuffer : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples); + virtual ~QCPPaintBufferGlPbuffer(); + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QGLPixelBuffer *mGlPBuffer; + int mMultisamples; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; +#endif // QCP_OPENGL_PBUFFER + + +#ifdef QCP_OPENGL_FBO +class QCP_LIB_DECL QCPPaintBufferGlFbo : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice); + virtual ~QCPPaintBufferGlFbo(); + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void donePainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QWeakPointer mGlContext; + QWeakPointer mGlPaintDevice; + QOpenGLFramebufferObject *mGlFrameBuffer; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; +#endif // QCP_OPENGL_FBO + +/* end of 'src/paintbuffer.h' */ + + +/* including file 'src/layer.h', size 6885 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPLayer : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QString name READ name) + Q_PROPERTY(int index READ index) + Q_PROPERTY(QList children READ children) + Q_PROPERTY(bool visible READ visible WRITE setVisible) + Q_PROPERTY(LayerMode mode READ mode WRITE setMode) + /// \endcond +public: + + /*! + Defines the different rendering modes of a layer. Depending on the mode, certain layers can be + replotted individually, without the need to replot (possibly complex) layerables on other + layers. + + \see setMode + */ + enum LayerMode { lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers. + ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot). + }; + Q_ENUMS(LayerMode) + + QCPLayer(QCustomPlot* parentPlot, const QString &layerName); + virtual ~QCPLayer(); + + // getters: + QCustomPlot *parentPlot() const { return mParentPlot; } + QString name() const { return mName; } + int index() const { return mIndex; } + QList children() const { return mChildren; } + bool visible() const { return mVisible; } + LayerMode mode() const { return mMode; } + + // setters: + void setVisible(bool visible); + void setMode(LayerMode mode); + + // non-virtual methods: + void replot(); + +protected: + // property members: + QCustomPlot *mParentPlot; + QString mName; + int mIndex; + QList mChildren; + bool mVisible; + LayerMode mMode; + + // non-property members: + QWeakPointer mPaintBuffer; + + // non-virtual methods: + void draw(QCPPainter *painter); + void drawToPaintBuffer(); + void addChild(QCPLayerable *layerable, bool prepend); + void removeChild(QCPLayerable *layerable); + +private: + Q_DISABLE_COPY(QCPLayer) + + friend class QCustomPlot; + friend class QCPLayerable; +}; +Q_DECLARE_METATYPE(QCPLayer::LayerMode) + +class QCP_LIB_DECL QCPLayerable : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool visible READ visible WRITE setVisible) + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QCPLayerable* parentLayerable READ parentLayerable) + Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged) + Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased) + /// \endcond +public: + QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0); + virtual ~QCPLayerable(); + + // getters: + bool visible() const { return mVisible; } + QCustomPlot *parentPlot() const { return mParentPlot; } + QCPLayerable *parentLayerable() const { return mParentLayerable.data(); } + QCPLayer *layer() const { return mLayer; } + bool antialiased() const { return mAntialiased; } + + // setters: + void setVisible(bool on); + Q_SLOT bool setLayer(QCPLayer *layer); + bool setLayer(const QString &layerName); + void setAntialiased(bool enabled); + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-property methods: + bool realVisibility() const; + +signals: + void layerChanged(QCPLayer *newLayer); + +protected: + // property members: + bool mVisible; + QCustomPlot *mParentPlot; + QPointer mParentLayerable; + QCPLayer *mLayer; + bool mAntialiased; + + // introduced virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot); + virtual QCP::Interaction selectionCategory() const; + virtual QRect clipRect() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0; + virtual void draw(QCPPainter *painter) = 0; + // selection events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + // low-level mouse events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details); + virtual void wheelEvent(QWheelEvent *event); + + // non-property methods: + void initializeParentPlot(QCustomPlot *parentPlot); + void setParentLayerable(QCPLayerable* parentLayerable); + bool moveToLayer(QCPLayer *layer, bool prepend); + void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const; + +private: + Q_DISABLE_COPY(QCPLayerable) + + friend class QCustomPlot; + friend class QCPLayer; + friend class QCPAxisRect; +}; + +/* end of 'src/layer.h' */ + + +/* including file 'src/axis/range.h', size 5280 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPRange +{ +public: + double lower, upper; + + QCPRange(); + QCPRange(double lower, double upper); + + bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; } + bool operator!=(const QCPRange& other) const { return !(*this == other); } + + QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; } + QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; } + QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; } + QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; } + friend inline const QCPRange operator+(const QCPRange&, double); + friend inline const QCPRange operator+(double, const QCPRange&); + friend inline const QCPRange operator-(const QCPRange& range, double value); + friend inline const QCPRange operator*(const QCPRange& range, double value); + friend inline const QCPRange operator*(double value, const QCPRange& range); + friend inline const QCPRange operator/(const QCPRange& range, double value); + + double size() const { return upper-lower; } + double center() const { return (upper+lower)*0.5; } + void normalize() { if (lower > upper) qSwap(lower, upper); } + void expand(const QCPRange &otherRange); + void expand(double includeCoord); + QCPRange expanded(const QCPRange &otherRange) const; + QCPRange expanded(double includeCoord) const; + QCPRange bounded(double lowerBound, double upperBound) const; + QCPRange sanitizedForLogScale() const; + QCPRange sanitizedForLinScale() const; + bool contains(double value) const { return value >= lower && value <= upper; } + + static bool validRange(double lower, double upper); + static bool validRange(const QCPRange &range); + static const double minRange; + static const double maxRange; + +}; +Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); + +/*! \relates QCPRange + + Prints \a range in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPRange &range) +{ + d.nospace() << "QCPRange(" << range.lower << ", " << range.upper << ")"; + return d.space(); +} + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(const QCPRange& range, double value) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(double value, const QCPRange& range) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Subtracts \a value from both boundaries of the range. +*/ +inline const QCPRange operator-(const QCPRange& range, double value) +{ + QCPRange result(range); + result -= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(const QCPRange& range, double value) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(double value, const QCPRange& range) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Divides both boundaries of the range by \a value. +*/ +inline const QCPRange operator/(const QCPRange& range, double value) +{ + QCPRange result(range); + result /= value; + return result; +} + +/* end of 'src/axis/range.h' */ + + +/* including file 'src/selection.h', size 8579 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPDataRange +{ +public: + QCPDataRange(); + QCPDataRange(int begin, int end); + + bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; } + bool operator!=(const QCPDataRange& other) const { return !(*this == other); } + + // getters: + int begin() const { return mBegin; } + int end() const { return mEnd; } + int size() const { return mEnd-mBegin; } + int length() const { return size(); } + + // setters: + void setBegin(int begin) { mBegin = begin; } + void setEnd(int end) { mEnd = end; } + + // non-property methods: + bool isValid() const { return (mEnd >= mBegin) && (mBegin >= 0); } + bool isEmpty() const { return length() == 0; } + QCPDataRange bounded(const QCPDataRange &other) const; + QCPDataRange expanded(const QCPDataRange &other) const; + QCPDataRange intersection(const QCPDataRange &other) const; + QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); } + bool intersects(const QCPDataRange &other) const; + bool contains(const QCPDataRange &other) const; + +private: + // property members: + int mBegin, mEnd; + +}; +Q_DECLARE_TYPEINFO(QCPDataRange, Q_MOVABLE_TYPE); + + +class QCP_LIB_DECL QCPDataSelection +{ +public: + explicit QCPDataSelection(); + explicit QCPDataSelection(const QCPDataRange &range); + + bool operator==(const QCPDataSelection& other) const; + bool operator!=(const QCPDataSelection& other) const { return !(*this == other); } + QCPDataSelection &operator+=(const QCPDataSelection& other); + QCPDataSelection &operator+=(const QCPDataRange& other); + QCPDataSelection &operator-=(const QCPDataSelection& other); + QCPDataSelection &operator-=(const QCPDataRange& other); + friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b); + + // getters: + int dataRangeCount() const { return mDataRanges.size(); } + int dataPointCount() const; + QCPDataRange dataRange(int index=0) const; + QList dataRanges() const { return mDataRanges; } + QCPDataRange span() const; + + // non-property methods: + void addDataRange(const QCPDataRange &dataRange, bool simplify=true); + void clear(); + bool isEmpty() const { return mDataRanges.isEmpty(); } + void simplify(); + void enforceType(QCP::SelectionType type); + bool contains(const QCPDataSelection &other) const; + QCPDataSelection intersection(const QCPDataRange &other) const; + QCPDataSelection intersection(const QCPDataSelection &other) const; + QCPDataSelection inverse(const QCPDataRange &outerRange) const; + +private: + // property members: + QList mDataRanges; + + inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); } +}; +Q_DECLARE_METATYPE(QCPDataSelection) + + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! \relates QCPDataRange + + Prints \a dataRange in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPDataRange &dataRange) +{ + d.nospace() << "[" << dataRange.begin() << ".." << dataRange.end()-1 << "]"; + return d.space(); +} + +/*! \relates QCPDataSelection + + Prints \a selection in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPDataSelection &selection) +{ + d.nospace() << "QCPDataSelection("; + for (int i=0; i elements(QCP::MarginSide side) const { return mChildren.value(side); } + bool isEmpty() const; + void clear(); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + QHash > mChildren; + + // introduced virtual methods: + virtual int commonMargin(QCP::MarginSide side) const; + + // non-virtual methods: + void addChild(QCP::MarginSide side, QCPLayoutElement *element); + void removeChild(QCP::MarginSide side, QCPLayoutElement *element); + +private: + Q_DISABLE_COPY(QCPMarginGroup) + + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLayout* layout READ layout) + Q_PROPERTY(QRect rect READ rect) + Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect) + Q_PROPERTY(QMargins margins READ margins WRITE setMargins) + Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins) + Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize) + Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize) + Q_PROPERTY(SizeConstraintRect sizeConstraintRect READ sizeConstraintRect WRITE setSizeConstraintRect) + /// \endcond +public: + /*! + Defines the phases of the update process, that happens just before a replot. At each phase, + \ref update is called with the according UpdatePhase value. + */ + enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout + ,upMargins ///< Phase in which the margins are calculated and set + ,upLayout ///< Final phase in which the layout system places the rects of the elements + }; + Q_ENUMS(UpdatePhase) + + /*! + Defines to which rect of a layout element the size constraints that can be set via \ref + setMinimumSize and \ref setMaximumSize apply. The outer rect (\ref outerRect) includes the + margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect) + does not. + + \see setSizeConstraintRect + */ + enum SizeConstraintRect { scrInnerRect ///< Minimum/Maximum size constraints apply to inner rect + , scrOuterRect ///< Minimum/Maximum size constraints apply to outer rect, thus include layout element margins + }; + Q_ENUMS(SizeConstraintRect) + + explicit QCPLayoutElement(QCustomPlot *parentPlot=0); + virtual ~QCPLayoutElement(); + + // getters: + QCPLayout *layout() const { return mParentLayout; } + QRect rect() const { return mRect; } + QRect outerRect() const { return mOuterRect; } + QMargins margins() const { return mMargins; } + QMargins minimumMargins() const { return mMinimumMargins; } + QCP::MarginSides autoMargins() const { return mAutoMargins; } + QSize minimumSize() const { return mMinimumSize; } + QSize maximumSize() const { return mMaximumSize; } + SizeConstraintRect sizeConstraintRect() const { return mSizeConstraintRect; } + QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, (QCPMarginGroup*)0); } + QHash marginGroups() const { return mMarginGroups; } + + // setters: + void setOuterRect(const QRect &rect); + void setMargins(const QMargins &margins); + void setMinimumMargins(const QMargins &margins); + void setAutoMargins(QCP::MarginSides sides); + void setMinimumSize(const QSize &size); + void setMinimumSize(int width, int height); + void setMaximumSize(const QSize &size); + void setMaximumSize(int width, int height); + void setSizeConstraintRect(SizeConstraintRect constraintRect); + void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group); + + // introduced virtual methods: + virtual void update(UpdatePhase phase); + virtual QSize minimumOuterSizeHint() const; + virtual QSize maximumOuterSizeHint() const; + virtual QList elements(bool recursive) const; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + +protected: + // property members: + QCPLayout *mParentLayout; + QSize mMinimumSize, mMaximumSize; + SizeConstraintRect mSizeConstraintRect; + QRect mRect, mOuterRect; + QMargins mMargins, mMinimumMargins; + QCP::MarginSides mAutoMargins; + QHash mMarginGroups; + + // introduced virtual methods: + virtual int calculateAutoMargin(QCP::MarginSide side); + virtual void layoutChanged(); + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) } + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE { Q_UNUSED(painter) } + virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPLayoutElement) + + friend class QCustomPlot; + friend class QCPLayout; + friend class QCPMarginGroup; +}; +Q_DECLARE_METATYPE(QCPLayoutElement::UpdatePhase) + + +class QCP_LIB_DECL QCPLayout : public QCPLayoutElement +{ + Q_OBJECT +public: + explicit QCPLayout(); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual int elementCount() const = 0; + virtual QCPLayoutElement* elementAt(int index) const = 0; + virtual QCPLayoutElement* takeAt(int index) = 0; + virtual bool take(QCPLayoutElement* element) = 0; + virtual void simplify(); + + // non-virtual methods: + bool removeAt(int index); + bool remove(QCPLayoutElement* element); + void clear(); + +protected: + // introduced virtual methods: + virtual void updateLayout(); + + // non-virtual methods: + void sizeConstraintsChanged() const; + void adoptElement(QCPLayoutElement *el); + void releaseElement(QCPLayoutElement *el); + QVector getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const; + static QSize getFinalMinimumOuterSize(const QCPLayoutElement *el); + static QSize getFinalMaximumOuterSize(const QCPLayoutElement *el); + +private: + Q_DISABLE_COPY(QCPLayout) + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(int rowCount READ rowCount) + Q_PROPERTY(int columnCount READ columnCount) + Q_PROPERTY(QList columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors) + Q_PROPERTY(QList rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors) + Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing) + Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing) + Q_PROPERTY(FillOrder fillOrder READ fillOrder WRITE setFillOrder) + Q_PROPERTY(int wrap READ wrap WRITE setWrap) + /// \endcond +public: + + /*! + Defines in which direction the grid is filled when using \ref addElement(QCPLayoutElement*). + The column/row at which wrapping into the next row/column occurs can be specified with \ref + setWrap. + + \see setFillOrder + */ + enum FillOrder { foRowsFirst ///< Rows are filled first, and a new element is wrapped to the next column if the row count would exceed \ref setWrap. + ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap. + }; + Q_ENUMS(FillOrder) + + explicit QCPLayoutGrid(); + virtual ~QCPLayoutGrid(); + + // getters: + int rowCount() const { return mElements.size(); } + int columnCount() const { return mElements.size() > 0 ? mElements.first().size() : 0; } + QList columnStretchFactors() const { return mColumnStretchFactors; } + QList rowStretchFactors() const { return mRowStretchFactors; } + int columnSpacing() const { return mColumnSpacing; } + int rowSpacing() const { return mRowSpacing; } + int wrap() const { return mWrap; } + FillOrder fillOrder() const { return mFillOrder; } + + // setters: + void setColumnStretchFactor(int column, double factor); + void setColumnStretchFactors(const QList &factors); + void setRowStretchFactor(int row, double factor); + void setRowStretchFactors(const QList &factors); + void setColumnSpacing(int pixels); + void setRowSpacing(int pixels); + void setWrap(int count); + void setFillOrder(FillOrder order, bool rearrange=true); + + // reimplemented virtual methods: + virtual void updateLayout() Q_DECL_OVERRIDE; + virtual int elementCount() const Q_DECL_OVERRIDE { return rowCount()*columnCount(); } + virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; + virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + virtual void simplify() Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; + + // non-virtual methods: + QCPLayoutElement *element(int row, int column) const; + bool addElement(int row, int column, QCPLayoutElement *element); + bool addElement(QCPLayoutElement *element); + bool hasElement(int row, int column); + void expandTo(int newRowCount, int newColumnCount); + void insertRow(int newIndex); + void insertColumn(int newIndex); + int rowColToIndex(int row, int column) const; + void indexToRowCol(int index, int &row, int &column) const; + +protected: + // property members: + QList > mElements; + QList mColumnStretchFactors; + QList mRowStretchFactors; + int mColumnSpacing, mRowSpacing; + int mWrap; + FillOrder mFillOrder; + + // non-virtual methods: + void getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const; + void getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const; + +private: + Q_DISABLE_COPY(QCPLayoutGrid) +}; +Q_DECLARE_METATYPE(QCPLayoutGrid::FillOrder) + + +class QCP_LIB_DECL QCPLayoutInset : public QCPLayout +{ + Q_OBJECT +public: + /*! + Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset. + */ + enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect + ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment + }; + Q_ENUMS(InsetPlacement) + + explicit QCPLayoutInset(); + virtual ~QCPLayoutInset(); + + // getters: + InsetPlacement insetPlacement(int index) const; + Qt::Alignment insetAlignment(int index) const; + QRectF insetRect(int index) const; + + // setters: + void setInsetPlacement(int index, InsetPlacement placement); + void setInsetAlignment(int index, Qt::Alignment alignment); + void setInsetRect(int index, const QRectF &rect); + + // reimplemented virtual methods: + virtual void updateLayout() Q_DECL_OVERRIDE; + virtual int elementCount() const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; + virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; + virtual void simplify() Q_DECL_OVERRIDE {} + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void addElement(QCPLayoutElement *element, Qt::Alignment alignment); + void addElement(QCPLayoutElement *element, const QRectF &rect); + +protected: + // property members: + QList mElements; + QList mInsetPlacement; + QList mInsetAlignment; + QList mInsetRect; + +private: + Q_DISABLE_COPY(QCPLayoutInset) +}; +Q_DECLARE_METATYPE(QCPLayoutInset::InsetPlacement) + +/* end of 'src/layout.h' */ + + +/* including file 'src/lineending.h', size 4426 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPLineEnding +{ + Q_GADGET +public: + /*! + Defines the type of ending decoration for line-like items, e.g. an arrow. + + \image html QCPLineEnding.png + + The width and length of these decorations can be controlled with the functions \ref setWidth + and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only + support a width, the length property is ignored. + + \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding + */ + enum EndingStyle { esNone ///< No ending decoration + ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle) + ,esSpikeArrow ///< A filled arrow head with an indented back + ,esLineArrow ///< A non-filled arrow head with open back + ,esDisc ///< A filled circle + ,esSquare ///< A filled square + ,esDiamond ///< A filled diamond (45 degrees rotated square) + ,esBar ///< A bar perpendicular to the line + ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted) + ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength) + }; + Q_ENUMS(EndingStyle) + + QCPLineEnding(); + QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); + + // getters: + EndingStyle style() const { return mStyle; } + double width() const { return mWidth; } + double length() const { return mLength; } + bool inverted() const { return mInverted; } + + // setters: + void setStyle(EndingStyle style); + void setWidth(double width); + void setLength(double length); + void setInverted(bool inverted); + + // non-property methods: + double boundingDistance() const; + double realLength() const; + void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const; + void draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const; + +protected: + // property members: + EndingStyle mStyle; + double mWidth, mLength; + bool mInverted; +}; +Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE); +Q_DECLARE_METATYPE(QCPLineEnding::EndingStyle) + +/* end of 'src/lineending.h' */ + + +/* including file 'src/axis/axisticker.h', size 4177 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines the strategies that the axis ticker may follow when choosing the size of the tick step. + + \see setTickStepStrategy + */ + enum TickStepStrategy + { + tssReadability ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount) + ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count + }; + Q_ENUMS(TickStepStrategy) + + QCPAxisTicker(); + virtual ~QCPAxisTicker(); + + // getters: + TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; } + int tickCount() const { return mTickCount; } + double tickOrigin() const { return mTickOrigin; } + + // setters: + void setTickStepStrategy(TickStepStrategy strategy); + void setTickCount(int count); + void setTickOrigin(double origin); + + // introduced virtual methods: + virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels); + +protected: + // property members: + TickStepStrategy mTickStepStrategy; + int mTickCount; + double mTickOrigin; + + // introduced virtual methods: + virtual double getTickStep(const QCPRange &range); + virtual int getSubTickCount(double tickStep); + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision); + virtual QVector createTickVector(double tickStep, const QCPRange &range); + virtual QVector createSubTickVector(int subTickCount, const QVector &ticks); + virtual QVector createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision); + + // non-virtual methods: + void trimTicks(const QCPRange &range, QVector &ticks, bool keepOneOutlier) const; + double pickClosest(double target, const QVector &candidates) const; + double getMantissa(double input, double *magnitude=0) const; + double cleanMantissa(double input) const; +}; +Q_DECLARE_METATYPE(QCPAxisTicker::TickStepStrategy) +Q_DECLARE_METATYPE(QSharedPointer) + +/* end of 'src/axis/axisticker.h' */ + + +/* including file 'src/axis/axistickerdatetime.h', size 3289 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker +{ +public: + QCPAxisTickerDateTime(); + + // getters: + QString dateTimeFormat() const { return mDateTimeFormat; } + Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; } + + // setters: + void setDateTimeFormat(const QString &format); + void setDateTimeSpec(Qt::TimeSpec spec); + void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen) + void setTickOrigin(const QDateTime &origin); + + // static methods: + static QDateTime keyToDateTime(double key); + static double dateTimeToKey(const QDateTime dateTime); + static double dateTimeToKey(const QDate date); + +protected: + // property members: + QString mDateTimeFormat; + Qt::TimeSpec mDateTimeSpec; + + // non-property members: + enum DateStrategy {dsNone, dsUniformTimeInDay, dsUniformDayInMonth} mDateStrategy; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; +}; + +/* end of 'src/axis/axistickerdatetime.h' */ + + +/* including file 'src/axis/axistickertime.h', size 3542 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines the logical units in which fractions of time spans can be expressed. + + \see setFieldWidth, setTimeFormat + */ + enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat) + ,tuSeconds ///< Seconds (%%s in \ref setTimeFormat) + ,tuMinutes ///< Minutes (%%m in \ref setTimeFormat) + ,tuHours ///< Hours (%%h in \ref setTimeFormat) + ,tuDays ///< Days (%%d in \ref setTimeFormat) + }; + Q_ENUMS(TimeUnit) + + QCPAxisTickerTime(); + + // getters: + QString timeFormat() const { return mTimeFormat; } + int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); } + + // setters: + void setTimeFormat(const QString &format); + void setFieldWidth(TimeUnit unit, int width); + +protected: + // property members: + QString mTimeFormat; + QHash mFieldWidth; + + // non-property members: + TimeUnit mSmallestUnit, mBiggestUnit; + QHash mFormatPattern; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + + // non-virtual methods: + void replaceUnit(QString &text, TimeUnit unit, int value) const; +}; +Q_DECLARE_METATYPE(QCPAxisTickerTime::TimeUnit) + +/* end of 'src/axis/axistickertime.h' */ + + +/* including file 'src/axis/axistickerfixed.h', size 3308 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerFixed : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines how the axis ticker may modify the specified tick step (\ref setTickStep) in order to + control the number of ticks in the axis range. + + \see setScaleStrategy + */ + enum ScaleStrategy { ssNone ///< Modifications are not allowed, the specified tick step is absolutely fixed. This might cause a high tick density and overlapping labels if the axis range is zoomed out. + ,ssMultiples ///< An integer multiple of the specified tick step is allowed. The used factor follows the base class properties of \ref setTickStepStrategy and \ref setTickCount. + ,ssPowers ///< An integer power of the specified tick step is allowed. + }; + Q_ENUMS(ScaleStrategy) + + QCPAxisTickerFixed(); + + // getters: + double tickStep() const { return mTickStep; } + ScaleStrategy scaleStrategy() const { return mScaleStrategy; } + + // setters: + void setTickStep(double step); + void setScaleStrategy(ScaleStrategy strategy); + +protected: + // property members: + double mTickStep; + ScaleStrategy mScaleStrategy; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; +}; +Q_DECLARE_METATYPE(QCPAxisTickerFixed::ScaleStrategy) + +/* end of 'src/axis/axistickerfixed.h' */ + + +/* including file 'src/axis/axistickertext.h', size 3085 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerText : public QCPAxisTicker +{ +public: + QCPAxisTickerText(); + + // getters: + QMap &ticks() { return mTicks; } + int subTickCount() const { return mSubTickCount; } + + // setters: + void setTicks(const QMap &ticks); + void setTicks(const QVector &positions, const QVector labels); + void setSubTickCount(int subTicks); + + // non-virtual methods: + void clear(); + void addTick(double position, QString label); + void addTicks(const QMap &ticks); + void addTicks(const QVector &positions, const QVector &labels); + +protected: + // property members: + QMap mTicks; + int mSubTickCount; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; + +}; + +/* end of 'src/axis/axistickertext.h' */ + + +/* including file 'src/axis/axistickerpi.h', size 3911 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerPi : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines how fractions should be displayed in tick labels. + + \see setFractionStyle + */ + enum FractionStyle { fsFloatingPoint ///< Fractions are displayed as regular decimal floating point numbers, e.g. "0.25" or "0.125". + ,fsAsciiFractions ///< Fractions are written as rationals using ASCII characters only, e.g. "1/4" or "1/8" + ,fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and the fraction symbol. + }; + Q_ENUMS(FractionStyle) + + QCPAxisTickerPi(); + + // getters: + QString piSymbol() const { return mPiSymbol; } + double piValue() const { return mPiValue; } + bool periodicity() const { return mPeriodicity; } + FractionStyle fractionStyle() const { return mFractionStyle; } + + // setters: + void setPiSymbol(QString symbol); + void setPiValue(double pi); + void setPeriodicity(int multiplesOfPi); + void setFractionStyle(FractionStyle style); + +protected: + // property members: + QString mPiSymbol; + double mPiValue; + int mPeriodicity; + FractionStyle mFractionStyle; + + // non-property members: + double mPiTickStep; // size of one tick step in units of mPiValue + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + + // non-virtual methods: + void simplifyFraction(int &numerator, int &denominator) const; + QString fractionToString(int numerator, int denominator) const; + QString unicodeFraction(int numerator, int denominator) const; + QString unicodeSuperscript(int number) const; + QString unicodeSubscript(int number) const; +}; +Q_DECLARE_METATYPE(QCPAxisTickerPi::FractionStyle) + +/* end of 'src/axis/axistickerpi.h' */ + + +/* including file 'src/axis/axistickerlog.h', size 2663 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerLog : public QCPAxisTicker +{ +public: + QCPAxisTickerLog(); + + // getters: + double logBase() const { return mLogBase; } + int subTickCount() const { return mSubTickCount; } + + // setters: + void setLogBase(double base); + void setSubTickCount(int subTicks); + +protected: + // property members: + double mLogBase; + int mSubTickCount; + + // non-property members: + double mLogBaseLnInv; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; +}; + +/* end of 'src/axis/axistickerlog.h' */ + + +/* including file 'src/axis/axis.h', size 20634 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPGrid :public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible) + Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid) + Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen) + Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen) + /// \endcond +public: + explicit QCPGrid(QCPAxis *parentAxis); + + // getters: + bool subGridVisible() const { return mSubGridVisible; } + bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } + bool antialiasedZeroLine() const { return mAntialiasedZeroLine; } + QPen pen() const { return mPen; } + QPen subGridPen() const { return mSubGridPen; } + QPen zeroLinePen() const { return mZeroLinePen; } + + // setters: + void setSubGridVisible(bool visible); + void setAntialiasedSubGrid(bool enabled); + void setAntialiasedZeroLine(bool enabled); + void setPen(const QPen &pen); + void setSubGridPen(const QPen &pen); + void setZeroLinePen(const QPen &pen); + +protected: + // property members: + bool mSubGridVisible; + bool mAntialiasedSubGrid, mAntialiasedZeroLine; + QPen mPen, mSubGridPen, mZeroLinePen; + + // non-property members: + QCPAxis *mParentAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + void drawGridLines(QCPPainter *painter) const; + void drawSubGridLines(QCPPainter *painter) const; + + friend class QCPAxis; +}; + + +class QCP_LIB_DECL QCPAxis : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(AxisType axisType READ axisType) + Q_PROPERTY(QCPAxisRect* axisRect READ axisRect) + Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged) + Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged) + Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed) + Q_PROPERTY(QSharedPointer ticker READ ticker WRITE setTicker) + Q_PROPERTY(bool ticks READ ticks WRITE setTicks) + Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels) + Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding) + Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont) + Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor) + Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation) + Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide) + Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat) + Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision) + Q_PROPERTY(QVector tickVector READ tickVector) + Q_PROPERTY(QVector tickVectorLabels READ tickVectorLabels) + Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn) + Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut) + Q_PROPERTY(bool subTicks READ subTicks WRITE setSubTicks) + Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn) + Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut) + Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen) + Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen) + Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen) + Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont) + Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding) + Q_PROPERTY(int padding READ padding WRITE setPadding) + Q_PROPERTY(int offset READ offset WRITE setOffset) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged) + Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont) + Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont) + Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor) + Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor) + Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen) + Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen) + Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen) + Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding) + Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding) + Q_PROPERTY(QCPGrid* grid READ grid) + /// \endcond +public: + /*! + Defines at which side of the axis rect the axis will appear. This also affects how the tick + marks are drawn, on which side the labels are placed etc. + */ + enum AxisType { atLeft = 0x01 ///< 0x01 Axis is vertical and on the left side of the axis rect + ,atRight = 0x02 ///< 0x02 Axis is vertical and on the right side of the axis rect + ,atTop = 0x04 ///< 0x04 Axis is horizontal and on the top side of the axis rect + ,atBottom = 0x08 ///< 0x08 Axis is horizontal and on the bottom side of the axis rect + }; + Q_ENUMS(AxisType) + Q_FLAGS(AxisTypes) + Q_DECLARE_FLAGS(AxisTypes, AxisType) + /*! + Defines on which side of the axis the tick labels (numbers) shall appear. + + \see setTickLabelSide + */ + enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect + ,lsOutside ///< Tick labels will be displayed outside the axis rect + }; + Q_ENUMS(LabelSide) + /*! + Defines the scale of an axis. + \see setScaleType + */ + enum ScaleType { stLinear ///< Linear scaling + ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance). + }; + Q_ENUMS(ScaleType) + /*! + Defines the selectable parts of an axis. + \see setSelectableParts, setSelectedParts + */ + enum SelectablePart { spNone = 0 ///< None of the selectable parts + ,spAxis = 0x001 ///< The axis backbone and tick marks + ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) + ,spAxisLabel = 0x004 ///< The axis label + }; + Q_ENUMS(SelectablePart) + Q_FLAGS(SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPAxis(QCPAxisRect *parent, AxisType type); + virtual ~QCPAxis(); + + // getters: + AxisType axisType() const { return mAxisType; } + QCPAxisRect *axisRect() const { return mAxisRect; } + ScaleType scaleType() const { return mScaleType; } + const QCPRange range() const { return mRange; } + bool rangeReversed() const { return mRangeReversed; } + QSharedPointer ticker() const { return mTicker; } + bool ticks() const { return mTicks; } + bool tickLabels() const { return mTickLabels; } + int tickLabelPadding() const; + QFont tickLabelFont() const { return mTickLabelFont; } + QColor tickLabelColor() const { return mTickLabelColor; } + double tickLabelRotation() const; + LabelSide tickLabelSide() const; + QString numberFormat() const; + int numberPrecision() const { return mNumberPrecision; } + QVector tickVector() const { return mTickVector; } + QVector tickVectorLabels() const { return mTickVectorLabels; } + int tickLengthIn() const; + int tickLengthOut() const; + bool subTicks() const { return mSubTicks; } + int subTickLengthIn() const; + int subTickLengthOut() const; + QPen basePen() const { return mBasePen; } + QPen tickPen() const { return mTickPen; } + QPen subTickPen() const { return mSubTickPen; } + QFont labelFont() const { return mLabelFont; } + QColor labelColor() const { return mLabelColor; } + QString label() const { return mLabel; } + int labelPadding() const; + int padding() const { return mPadding; } + int offset() const; + SelectableParts selectedParts() const { return mSelectedParts; } + SelectableParts selectableParts() const { return mSelectableParts; } + QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } + QFont selectedLabelFont() const { return mSelectedLabelFont; } + QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } + QColor selectedLabelColor() const { return mSelectedLabelColor; } + QPen selectedBasePen() const { return mSelectedBasePen; } + QPen selectedTickPen() const { return mSelectedTickPen; } + QPen selectedSubTickPen() const { return mSelectedSubTickPen; } + QCPLineEnding lowerEnding() const; + QCPLineEnding upperEnding() const; + QCPGrid *grid() const { return mGrid; } + + // setters: + Q_SLOT void setScaleType(QCPAxis::ScaleType type); + Q_SLOT void setRange(const QCPRange &range); + void setRange(double lower, double upper); + void setRange(double position, double size, Qt::AlignmentFlag alignment); + void setRangeLower(double lower); + void setRangeUpper(double upper); + void setRangeReversed(bool reversed); + void setTicker(QSharedPointer ticker); + void setTicks(bool show); + void setTickLabels(bool show); + void setTickLabelPadding(int padding); + void setTickLabelFont(const QFont &font); + void setTickLabelColor(const QColor &color); + void setTickLabelRotation(double degrees); + void setTickLabelSide(LabelSide side); + void setNumberFormat(const QString &formatCode); + void setNumberPrecision(int precision); + void setTickLength(int inside, int outside=0); + void setTickLengthIn(int inside); + void setTickLengthOut(int outside); + void setSubTicks(bool show); + void setSubTickLength(int inside, int outside=0); + void setSubTickLengthIn(int inside); + void setSubTickLengthOut(int outside); + void setBasePen(const QPen &pen); + void setTickPen(const QPen &pen); + void setSubTickPen(const QPen &pen); + void setLabelFont(const QFont &font); + void setLabelColor(const QColor &color); + void setLabel(const QString &str); + void setLabelPadding(int padding); + void setPadding(int padding); + void setOffset(int offset); + void setSelectedTickLabelFont(const QFont &font); + void setSelectedLabelFont(const QFont &font); + void setSelectedTickLabelColor(const QColor &color); + void setSelectedLabelColor(const QColor &color); + void setSelectedBasePen(const QPen &pen); + void setSelectedTickPen(const QPen &pen); + void setSelectedSubTickPen(const QPen &pen); + Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts); + void setLowerEnding(const QCPLineEnding &ending); + void setUpperEnding(const QCPLineEnding &ending); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-property methods: + Qt::Orientation orientation() const { return mOrientation; } + int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; } + void moveRange(double diff); + void scaleRange(double factor); + void scaleRange(double factor, double center); + void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0); + void rescale(bool onlyVisiblePlottables=false); + double pixelToCoord(double value) const; + double coordToPixel(double value) const; + SelectablePart getPartAt(const QPointF &pos) const; + QList plottables() const; + QList graphs() const; + QList items() const; + + static AxisType marginSideToAxisType(QCP::MarginSide side); + static Qt::Orientation orientation(AxisType type) { return type==atBottom||type==atTop ? Qt::Horizontal : Qt::Vertical; } + static AxisType opposite(AxisType type); + +signals: + void rangeChanged(const QCPRange &newRange); + void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); + void scaleTypeChanged(QCPAxis::ScaleType scaleType); + void selectionChanged(const QCPAxis::SelectableParts &parts); + void selectableChanged(const QCPAxis::SelectableParts &parts); + +protected: + // property members: + // axis base: + AxisType mAxisType; + QCPAxisRect *mAxisRect; + //int mOffset; // in QCPAxisPainter + int mPadding; + Qt::Orientation mOrientation; + SelectableParts mSelectableParts, mSelectedParts; + QPen mBasePen, mSelectedBasePen; + //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter + // axis label: + //int mLabelPadding; // in QCPAxisPainter + QString mLabel; + QFont mLabelFont, mSelectedLabelFont; + QColor mLabelColor, mSelectedLabelColor; + // tick labels: + //int mTickLabelPadding; // in QCPAxisPainter + bool mTickLabels; + //double mTickLabelRotation; // in QCPAxisPainter + QFont mTickLabelFont, mSelectedTickLabelFont; + QColor mTickLabelColor, mSelectedTickLabelColor; + int mNumberPrecision; + QLatin1Char mNumberFormatChar; + bool mNumberBeautifulPowers; + //bool mNumberMultiplyCross; // QCPAxisPainter + // ticks and subticks: + bool mTicks; + bool mSubTicks; + //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter + QPen mTickPen, mSelectedTickPen; + QPen mSubTickPen, mSelectedSubTickPen; + // scale and range: + QCPRange mRange; + bool mRangeReversed; + ScaleType mScaleType; + + // non-property members: + QCPGrid *mGrid; + QCPAxisPainterPrivate *mAxisPainter; + QSharedPointer mTicker; + QVector mTickVector; + QVector mTickVectorLabels; + QVector mSubTickVector; + bool mCachedMarginValid; + int mCachedMargin; + bool mDragging; + QCPRange mDragStartRange; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + + // introduced virtual methods: + virtual int calculateMargin(); + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + // mouse events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); + virtual void wheelEvent(QWheelEvent *event); + + // non-virtual methods: + void setupTickVectors(); + QPen getBasePen() const; + QPen getTickPen() const; + QPen getSubTickPen() const; + QFont getTickLabelFont() const; + QFont getLabelFont() const; + QColor getTickLabelColor() const; + QColor getLabelColor() const; + +private: + Q_DISABLE_COPY(QCPAxis) + + friend class QCustomPlot; + friend class QCPGrid; + friend class QCPAxisRect; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes) +Q_DECLARE_METATYPE(QCPAxis::AxisType) +Q_DECLARE_METATYPE(QCPAxis::LabelSide) +Q_DECLARE_METATYPE(QCPAxis::ScaleType) +Q_DECLARE_METATYPE(QCPAxis::SelectablePart) + + +class QCPAxisPainterPrivate +{ +public: + explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot); + virtual ~QCPAxisPainterPrivate(); + + virtual void draw(QCPPainter *painter); + virtual int size() const; + void clearCache(); + + QRect axisSelectionBox() const { return mAxisSelectionBox; } + QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; } + QRect labelSelectionBox() const { return mLabelSelectionBox; } + + // public property members: + QCPAxis::AxisType type; + QPen basePen; + QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters + int labelPadding; // directly accessed by QCPAxis setters/getters + QFont labelFont; + QColor labelColor; + QString label; + int tickLabelPadding; // directly accessed by QCPAxis setters/getters + double tickLabelRotation; // directly accessed by QCPAxis setters/getters + QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters + bool substituteExponent; + bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters + int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters + QPen tickPen, subTickPen; + QFont tickLabelFont; + QColor tickLabelColor; + QRect axisRect, viewportRect; + double offset; // directly accessed by QCPAxis setters/getters + bool abbreviateDecimalPowers; + bool reversedEndings; + + QVector subTickPositions; + QVector tickPositions; + QVector tickLabels; + +protected: + struct CachedLabel + { + QPointF offset; + QPixmap pixmap; + }; + struct TickLabelData + { + QString basePart, expPart, suffixPart; + QRect baseBounds, expBounds, suffixBounds, totalBounds, rotatedTotalBounds; + QFont baseFont, expFont; + }; + QCustomPlot *mParentPlot; + QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters + QCache mLabelCache; + QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; + + virtual QByteArray generateLabelParameterHash() const; + + virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize); + virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const; + virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const; + virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const; + virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const; +}; + +/* end of 'src/axis/axis.h' */ + + +/* including file 'src/scatterstyle.h', size 7275 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPScatterStyle +{ + Q_GADGET +public: + /*! + Represents the various properties of a scatter style instance. For example, this enum is used + to specify which properties of \ref QCPSelectionDecorator::setScatterStyle will be used when + highlighting selected data points. + + Specific scatter properties can be transferred between \ref QCPScatterStyle instances via \ref + setFromOther. + */ + enum ScatterProperty { spNone = 0x00 ///< 0x00 None + ,spPen = 0x01 ///< 0x01 The pen property, see \ref setPen + ,spBrush = 0x02 ///< 0x02 The brush property, see \ref setBrush + ,spSize = 0x04 ///< 0x04 The size property, see \ref setSize + ,spShape = 0x08 ///< 0x08 The shape property, see \ref setShape + ,spAll = 0xFF ///< 0xFF All properties + }; + Q_ENUMS(ScatterProperty) + Q_FLAGS(ScatterProperties) + Q_DECLARE_FLAGS(ScatterProperties, ScatterProperty) + + /*! + Defines the shape used for scatter points. + + On plottables/items that draw scatters, the sizes of these visualizations (with exception of + \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are + drawn with the pen and brush specified with \ref setPen and \ref setBrush. + */ + enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) + ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius) + ,ssCross ///< \enumimage{ssCross.png} a cross + ,ssPlus ///< \enumimage{ssPlus.png} a plus + ,ssCircle ///< \enumimage{ssCircle.png} a circle + ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) + ,ssSquare ///< \enumimage{ssSquare.png} a square + ,ssDiamond ///< \enumimage{ssDiamond.png} a diamond + ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus + ,ssTriangle ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline + ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner + ,ssCrossSquare ///< \enumimage{ssCrossSquare.png} a square with a cross inside + ,ssPlusSquare ///< \enumimage{ssPlusSquare.png} a square with a plus inside + ,ssCrossCircle ///< \enumimage{ssCrossCircle.png} a circle with a cross inside + ,ssPlusCircle ///< \enumimage{ssPlusCircle.png} a circle with a plus inside + ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines + ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates + ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath) + }; + Q_ENUMS(ScatterShape) + + QCPScatterStyle(); + QCPScatterStyle(ScatterShape shape, double size=6); + QCPScatterStyle(ScatterShape shape, const QColor &color, double size); + QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size); + QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size); + QCPScatterStyle(const QPixmap &pixmap); + QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6); + + // getters: + double size() const { return mSize; } + ScatterShape shape() const { return mShape; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QPixmap pixmap() const { return mPixmap; } + QPainterPath customPath() const { return mCustomPath; } + + // setters: + void setFromOther(const QCPScatterStyle &other, ScatterProperties properties); + void setSize(double size); + void setShape(ScatterShape shape); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setPixmap(const QPixmap &pixmap); + void setCustomPath(const QPainterPath &customPath); + + // non-property methods: + bool isNone() const { return mShape == ssNone; } + bool isPenDefined() const { return mPenDefined; } + void undefinePen(); + void applyTo(QCPPainter *painter, const QPen &defaultPen) const; + void drawShape(QCPPainter *painter, const QPointF &pos) const; + void drawShape(QCPPainter *painter, double x, double y) const; + +protected: + // property members: + double mSize; + ScatterShape mShape; + QPen mPen; + QBrush mBrush; + QPixmap mPixmap; + QPainterPath mCustomPath; + + // non-property members: + bool mPenDefined; +}; +Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE); +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPScatterStyle::ScatterProperties) +Q_DECLARE_METATYPE(QCPScatterStyle::ScatterProperty) +Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape) + +/* end of 'src/scatterstyle.h' */ + + +/* including file 'src/datacontainer.h', size 4596 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +/*! \relates QCPDataContainer + Returns whether the sort key of \a a is less than the sort key of \a b. + + \see QCPDataContainer::sort +*/ +template +inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) { return a.sortKey() < b.sortKey(); } + +template +class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below) +{ +public: + typedef typename QVector::const_iterator const_iterator; + typedef typename QVector::const_reverse_iterator const_reverse_iterator; + typedef typename QVector::iterator iterator; + + QCPDataContainer(); + + // pointer to data + QVector * data() { return &mData; } + + // getters: + int size() const { return mData.size()-mPreallocSize; } + bool isEmpty() const { return size() == 0; } + bool autoSqueeze() const { return mAutoSqueeze; } + + // setters: + void setAutoSqueeze(bool enabled); + + // non-virtual methods: + void set(const QCPDataContainer &data); + void set(const QVector &data, bool alreadySorted=false); + void add(const QCPDataContainer &data); + void add(const QVector &data, bool alreadySorted=false); + void add(const DataType &data); + void removeBefore(double sortKey); + void removeAfter(double sortKey); + void remove(double sortKeyFrom, double sortKeyTo); + void remove(double sortKey); + void clear(); + void sort(); + void squeeze(bool preAllocation=true, bool postAllocation=true); + + const_iterator constBegin() const { return mData.constBegin()+mPreallocSize; } + const_iterator constEnd() const { return mData.constEnd(); } + iterator begin() { return mData.begin()+mPreallocSize; } + iterator end() { return mData.end(); } + const_iterator findBegin(double sortKey, bool expandedRange=true) const; + const_iterator findEnd(double sortKey, bool expandedRange=true) const; + const_iterator at(int index) const { return constBegin()+qBound(0, index, size()); } + QCPRange keyRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth); + QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()); + QCPDataRange dataRange() const { return QCPDataRange(0, size()); } + void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const; + +protected: + // property members: + bool mAutoSqueeze; + + // non-property memebers: + QVector mData; + int mPreallocSize; + int mPreallocIteration; + + // non-virtual methods: + void preallocateGrow(int minimumPreallocSize); + void performAutoSqueeze(); +}; + +// include implementation in header since it is a class template: + +/* including file 'src/datacontainer.cpp', size 31349 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataContainer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataContainer + \brief The generic data container for one-dimensional plottables + + This class template provides a fast container for data storage of one-dimensional data. The data + type is specified as template parameter (called \a DataType in the following) and must provide + some methods as described in the \ref qcpdatacontainer-datatype "next section". + + The data is stored in a sorted fashion, which allows very quick lookups by the sorted key as well + as retrieval of ranges (see \ref findBegin, \ref findEnd, \ref keyRange) using binary search. The + container uses a preallocation and a postallocation scheme, such that appending and prepending + data (with respect to the sort key) is very fast and minimizes reallocations. If data is added + which needs to be inserted between existing keys, the merge usually can be done quickly too, + using the fact that existing data is always sorted. The user can further improve performance by + specifying that added data is already itself sorted by key, if he can guarantee that this is the + case (see for example \ref add(const QVector &data, bool alreadySorted)). + + The data can be accessed with the provided const iterators (\ref constBegin, \ref constEnd). If + it is necessary to alter existing data in-place, the non-const iterators can be used (\ref begin, + \ref end). Changing data members that are not the sort key (for most data types called \a key) is + safe from the container's perspective. + + Great care must be taken however if the sort key is modified through the non-const iterators. For + performance reasons, the iterators don't automatically cause a re-sorting upon their + manipulation. It is thus the responsibility of the user to leave the container in a sorted state + when finished with the data manipulation, before calling any other methods on the container. A + complete re-sort (e.g. after finishing all sort key manipulation) can be done by calling \ref + sort. Failing to do so can not be detected by the container efficiently and will cause both + rendering artifacts and potential data loss. + + Implementing one-dimensional plottables that make use of a \ref QCPDataContainer is usually + done by subclassing from \ref QCPAbstractPlottable1D "QCPAbstractPlottable1D", which + introduces an according \a mDataContainer member and some convenience methods. + + \section qcpdatacontainer-datatype Requirements for the DataType template parameter + + The template parameter DataType is the type of the stored data points. It must be + trivially copyable and have the following public methods, preferably inline: + + \li double sortKey() const\n Returns the member variable of this data point that is the + sort key, defining the ordering in the container. Often this variable is simply called \a key. + + \li static DataType fromSortKey(double sortKey)\n Returns a new instance of the data + type initialized with its sort key set to \a sortKey. + + \li static bool sortKeyIsMainKey()\n Returns true if the sort key is equal to the main + key (see method \c mainKey below). For most plottables this is the case. It is not the case for + example for \ref QCPCurve, which uses \a t as sort key and \a key as main key. This is the reason + why QCPCurve unlike QCPGraph can display parametric curves with loops. + + \li double mainKey() const\n Returns the variable of this data point considered the main + key. This is commonly the variable that is used as the coordinate of this data point on the key + axis of the plottable. This method is used for example when determining the automatic axis + rescaling of key axes (\ref QCPAxis::rescale). + + \li double mainValue() const\n Returns the variable of this data point considered the + main value. This is commonly the variable that is used as the coordinate of this data point on + the value axis of the plottable. + + \li QCPRange valueRange() const\n Returns the range this data point spans in the value + axis coordinate. If the data is single-valued (e.g. QCPGraphData), this is simply a range with + both lower and upper set to the main data point value. However if the data points can represent + multiple values at once (e.g QCPFinancialData with its \a high, \a low, \a open and \a close + values at each \a key) this method should return the range those values span. This method is used + for example when determining the automatic axis rescaling of value axes (\ref + QCPAxis::rescale). +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataContainer::size() const + + Returns the number of data points in the container. +*/ + +/*! \fn bool QCPDataContainer::isEmpty() const + + Returns whether this container holds no data points. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constBegin() const + + Returns a const iterator to the first data point in this container. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constEnd() const + + Returns a const iterator to the element past the last data point in this container. +*/ + +/*! \fn QCPDataContainer::iterator QCPDataContainer::begin() const + + Returns a non-const iterator to the first data point in this container. + + You can manipulate the data points in-place through the non-const iterators, but great care must + be taken when manipulating the sort key of a data point, see \ref sort, or the detailed + description of this class. +*/ + +/*! \fn QCPDataContainer::iterator QCPDataContainer::end() const + + Returns a non-const iterator to the element past the last data point in this container. + + You can manipulate the data points in-place through the non-const iterators, but great care must + be taken when manipulating the sort key of a data point, see \ref sort, or the detailed + description of this class. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::at(int index) const + + Returns a const iterator to the element with the specified \a index. If \a index points beyond + the available elements in this container, returns \ref constEnd, i.e. an iterator past the last + valid element. + + You can use this method to easily obtain iterators from a \ref QCPDataRange, see the \ref + dataselection-accessing "data selection page" for an example. +*/ + +/*! \fn QCPDataRange QCPDataContainer::dataRange() const + + Returns a \ref QCPDataRange encompassing the entire data set of this container. This means the + begin index of the returned range is 0, and the end index is \ref size. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a QCPDataContainer used for plottable classes that represent a series of key-sorted + data +*/ +template +QCPDataContainer::QCPDataContainer() : + mAutoSqueeze(true), + mPreallocSize(0), + mPreallocIteration(0) +{ +} + +/*! + Sets whether the container automatically decides when to release memory from its post- and + preallocation pools when data points are removed. By default this is enabled and for typical + applications shouldn't be changed. + + If auto squeeze is disabled, you can manually decide when to release pre-/postallocation with + \ref squeeze. +*/ +template +void QCPDataContainer::setAutoSqueeze(bool enabled) +{ + if (mAutoSqueeze != enabled) + { + mAutoSqueeze = enabled; + if (mAutoSqueeze) + performAutoSqueeze(); + } +} + +/*! \overload + + Replaces the current data in this container with the provided \a data. + + \see add, remove +*/ +template +void QCPDataContainer::set(const QCPDataContainer &data) +{ + clear(); + add(data); +} + +/*! \overload + + Replaces the current data in this container with the provided \a data + + If you can guarantee that the data points in \a data have ascending order with respect to the + DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. + + \see add, remove +*/ +template +void QCPDataContainer::set(const QVector &data, bool alreadySorted) +{ + mData = data; + mPreallocSize = 0; + mPreallocIteration = 0; + if (!alreadySorted) + sort(); +} + +/*! \overload + + Adds the provided \a data to the current data in this container. + + \see set, remove +*/ +template +void QCPDataContainer::add(const QCPDataContainer &data) +{ + if (data.isEmpty()) + return; + + const int n = data.size(); + const int oldSize = size(); + + if (oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones + { + if (mPreallocSize < n) + preallocateGrow(n); + mPreallocSize -= n; + std::copy(data.constBegin(), data.constEnd(), begin()); + } else // don't need to prepend, so append and merge if necessary + { + mData.resize(mData.size()+n); + std::copy(data.constBegin(), data.constEnd(), end()-n); + if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions + std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); + } +} + +/*! + Adds the provided data points in \a data to the current data. + + If you can guarantee that the data points in \a data have ascending order with respect to the + DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. + + \see set, remove +*/ +template +void QCPDataContainer::add(const QVector &data, bool alreadySorted) +{ + if (data.isEmpty()) + return; + if (isEmpty()) + { + set(data, alreadySorted); + return; + } + + const int n = data.size(); + const int oldSize = size(); + + if (alreadySorted && oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data is sorted and keys are all smaller than or equal to existing ones + { + if (mPreallocSize < n) + preallocateGrow(n); + mPreallocSize -= n; + std::copy(data.constBegin(), data.constEnd(), begin()); + } else // don't need to prepend, so append and then sort and merge if necessary + { + mData.resize(mData.size()+n); + std::copy(data.constBegin(), data.constEnd(), end()-n); + if (!alreadySorted) // sort appended subrange if it wasn't already sorted + std::sort(end()-n, end(), qcpLessThanSortKey); + if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions + std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); + } +} + +/*! \overload + + Adds the provided single data point to the current data. + + \see remove +*/ +template +void QCPDataContainer::add(const DataType &data) +{ + if (isEmpty() || !qcpLessThanSortKey(data, *(constEnd()-1))) // quickly handle appends if new data key is greater or equal to existing ones + { + mData.append(data); + } else if (qcpLessThanSortKey(data, *constBegin())) // quickly handle prepends using preallocated space + { + if (mPreallocSize < 1) + preallocateGrow(1); + --mPreallocSize; + *begin() = data; + } else // handle inserts, maintaining sorted keys + { + QCPDataContainer::iterator insertionPoint = std::lower_bound(begin(), end(), data, qcpLessThanSortKey); + mData.insert(insertionPoint, data); + } +} + +/*! + Removes all data points with (sort-)keys smaller than or equal to \a sortKey. + + \see removeAfter, remove, clear +*/ +template +void QCPDataContainer::removeBefore(double sortKey) +{ + QCPDataContainer::iterator it = begin(); + QCPDataContainer::iterator itEnd = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + mPreallocSize += itEnd-it; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points with (sort-)keys greater than or equal to \a sortKey. + + \see removeBefore, remove, clear +*/ +template +void QCPDataContainer::removeAfter(double sortKey) +{ + QCPDataContainer::iterator it = std::upper_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + QCPDataContainer::iterator itEnd = end(); + mData.erase(it, itEnd); // typically adds it to the postallocated block + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points with (sort-)keys between \a sortKeyFrom and \a sortKeyTo. if \a + sortKeyFrom is greater or equal to \a sortKeyTo, the function does nothing. To remove a single + data point with known (sort-)key, use \ref remove(double sortKey). + + \see removeBefore, removeAfter, clear +*/ +template +void QCPDataContainer::remove(double sortKeyFrom, double sortKeyTo) +{ + if (sortKeyFrom >= sortKeyTo || isEmpty()) + return; + + QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey); + QCPDataContainer::iterator itEnd = std::upper_bound(it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey); + mData.erase(it, itEnd); + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! \overload + + Removes a single data point at \a sortKey. If the position is not known with absolute (binary) + precision, consider using \ref remove(double sortKeyFrom, double sortKeyTo) with a small + fuzziness interval around the suspected position, depeding on the precision with which the + (sort-)key is known. + + \see removeBefore, removeAfter, clear +*/ +template +void QCPDataContainer::remove(double sortKey) +{ + QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (it != end() && it->sortKey() == sortKey) + { + if (it == begin()) + ++mPreallocSize; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) + else + mData.erase(it); + } + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points. + + \see remove, removeAfter, removeBefore +*/ +template +void QCPDataContainer::clear() +{ + mData.clear(); + mPreallocIteration = 0; + mPreallocSize = 0; +} + +/*! + Re-sorts all data points in the container by their sort key. + + When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add, + \ref remove, etc.), the container makes sure to always stay in a sorted state such that a full + resort is never necessary. However, if you choose to directly manipulate the sort key on data + points by accessing and modifying it through the non-const iterators (\ref begin, \ref end), it + is your responsibility to bring the container back into a sorted state before any other methods + are called on it. This can be achieved by calling this method immediately after finishing the + sort key manipulation. +*/ +template +void QCPDataContainer::sort() +{ + std::sort(begin(), end(), qcpLessThanSortKey); +} + +/*! + Frees all unused memory that is currently in the preallocation and postallocation pools. + + Note that QCPDataContainer automatically decides whether squeezing is necessary, if \ref + setAutoSqueeze is left enabled. It should thus not be necessary to use this method for typical + applications. + + The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation + should be freed, respectively. +*/ +template +void QCPDataContainer::squeeze(bool preAllocation, bool postAllocation) +{ + if (preAllocation) + { + if (mPreallocSize > 0) + { + std::copy(begin(), end(), mData.begin()); + mData.resize(size()); + mPreallocSize = 0; + } + mPreallocIteration = 0; + } + if (postAllocation) + mData.squeeze(); +} + +/*! + Returns an iterator to the data point with a (sort-)key that is equal to, just below, or just + above \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be + considered, otherwise the one just above. + + This can be used in conjunction with \ref findEnd to iterate over data points within a given key + range, including or excluding the bounding data points that are just beyond the specified range. + + If \a expandedRange is true but there are no data points below \a sortKey, \ref constBegin is + returned. + + If the container is empty, returns \ref constEnd. + + \see findEnd, QCPPlottableInterface1D::findBegin +*/ +template +typename QCPDataContainer::const_iterator QCPDataContainer::findBegin(double sortKey, bool expandedRange) const +{ + if (isEmpty()) + return constEnd(); + + QCPDataContainer::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know --constEnd is valid because mData isn't empty + --it; + return it; +} + +/*! + Returns an iterator to the element after the data point with a (sort-)key that is equal to, just + above or just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey + will be considered, otherwise the one just below. + + This can be used in conjunction with \ref findBegin to iterate over data points within a given + key range, including the bounding data points that are just below and above the specified range. + + If \a expandedRange is true but there are no data points above \a sortKey, \ref constEnd is + returned. + + If the container is empty, \ref constEnd is returned. + + \see findBegin, QCPPlottableInterface1D::findEnd +*/ +template +typename QCPDataContainer::const_iterator QCPDataContainer::findEnd(double sortKey, bool expandedRange) const +{ + if (isEmpty()) + return constEnd(); + + QCPDataContainer::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (expandedRange && it != constEnd()) + ++it; + return it; +} + +/*! + Returns the range encompassed by the (main-)key coordinate of all data points. The output + parameter \a foundRange indicates whether a sensible range was found. If this is false, you + should not use the returned QCPRange (e.g. the data container is empty or all points have the + same key). + + Use \a signDomain to control which sign of the key coordinates should be considered. This is + relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a + time. + + If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is + the case for most plottables, this method uses this fact and finds the range very quickly. + + \see valueRange +*/ +template +QCPRange QCPDataContainer::keyRange(bool &foundRange, QCP::SignDomain signDomain) +{ + if (isEmpty()) + { + foundRange = false; + return QCPRange(); + } + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + double current; + + QCPDataContainer::const_iterator it = constBegin(); + QCPDataContainer::const_iterator itEnd = constEnd(); + if (signDomain == QCP::sdBoth) // range may be anywhere + { + if (DataType::sortKeyIsMainKey()) // if DataType is sorted by main key (e.g. QCPGraph, but not QCPCurve), use faster algorithm by finding just first and last key with non-NaN value + { + while (it != itEnd) // find first non-nan going up from left + { + if (!qIsNaN(it->mainValue())) + { + range.lower = it->mainKey(); + haveLower = true; + break; + } + ++it; + } + it = itEnd; + while (it != constBegin()) // find first non-nan going down from right + { + --it; + if (!qIsNaN(it->mainValue())) + { + range.upper = it->mainKey(); + haveUpper = true; + break; + } + } + } else // DataType is not sorted by main key, go through all data points and accordingly expand range + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } + } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if ((current < range.lower || !haveLower) && current < 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current < 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if ((current < range.lower || !haveLower) && current > 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current > 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! + Returns the range encompassed by the value coordinates of the data points in the specified key + range (\a inKeyRange), using the full \a DataType::valueRange reported by the data points. The + output parameter \a foundRange indicates whether a sensible range was found. If this is false, + you should not use the returned QCPRange (e.g. the data container is empty or all points have the + same value). + + If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), + all data points are considered, without any restriction on the keys. + + Use \a signDomain to control which sign of the value coordinates should be considered. This is + relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a + time. + + \see keyRange +*/ +template +QCPRange QCPDataContainer::valueRange(bool &foundRange, QCP::SignDomain signDomain, const QCPRange &inKeyRange) +{ + if (isEmpty()) + { + foundRange = false; + return QCPRange(); + } + QCPRange range; + const bool restrictKeyRange = inKeyRange != QCPRange(); + bool haveLower = false; + bool haveUpper = false; + QCPRange current; + QCPDataContainer::const_iterator itBegin = constBegin(); + QCPDataContainer::const_iterator itEnd = constEnd(); + if (DataType::sortKeyIsMainKey() && restrictKeyRange) + { + itBegin = findBegin(inKeyRange.lower); + itEnd = findEnd(inKeyRange.upper); + } + if (signDomain == QCP::sdBoth) // range may be anywhere + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && current.lower < 0 && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && current.upper < 0 && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && current.lower > 0 && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && current.upper > 0 && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! + Makes sure \a begin and \a end mark a data range that is both within the bounds of this data + container's data, as well as within the specified \a dataRange. The initial range described by + the passed iterators \a begin and \a end is never expanded, only contracted if necessary. + + This function doesn't require for \a dataRange to be within the bounds of this data container's + valid range. +*/ +template +void QCPDataContainer::limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const +{ + QCPDataRange iteratorRange(begin-constBegin(), end-constBegin()); + iteratorRange = iteratorRange.bounded(dataRange.bounded(this->dataRange())); + begin = constBegin()+iteratorRange.begin(); + end = constBegin()+iteratorRange.end(); +} + +/*! \internal + + Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on + the preallocation history, the container will grow by more than requested, to speed up future + consecutive size increases. + + if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this + method does nothing. +*/ +template +void QCPDataContainer::preallocateGrow(int minimumPreallocSize) +{ + if (minimumPreallocSize <= mPreallocSize) + return; + + int newPreallocSize = minimumPreallocSize; + newPreallocSize += (1u< +void QCPDataContainer::performAutoSqueeze() +{ + const int totalAlloc = mData.capacity(); + const int postAllocSize = totalAlloc-mData.size(); + const int usedSize = size(); + bool shrinkPostAllocation = false; + bool shrinkPreAllocation = false; + if (totalAlloc > 650000) // if allocation is larger, shrink earlier with respect to total used size + { + shrinkPostAllocation = postAllocSize > usedSize*1.5; // QVector grow strategy is 2^n for static data. Watch out not to oscillate! + shrinkPreAllocation = mPreallocSize*10 > usedSize; + } else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below 1k points don't even bother + { + shrinkPostAllocation = postAllocSize > usedSize*5; + shrinkPreAllocation = mPreallocSize > usedSize*1.5; // preallocation can grow into postallocation, so can be smaller + } + + if (shrinkPreAllocation || shrinkPostAllocation) + squeeze(shrinkPreAllocation, shrinkPostAllocation); +} +/* end of 'src/datacontainer.cpp' */ + + +/* end of 'src/datacontainer.h' */ + + +/* including file 'src/plottable.h', size 8312 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPSelectionDecorator +{ + Q_GADGET +public: + QCPSelectionDecorator(); + virtual ~QCPSelectionDecorator(); + + // getters: + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; } + + // setters: + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen); + void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties); + + // non-virtual methods: + void applyPen(QCPPainter *painter) const; + void applyBrush(QCPPainter *painter) const; + QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const; + + // introduced virtual methods: + virtual void copyFrom(const QCPSelectionDecorator *other); + virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection); + +protected: + // property members: + QPen mPen; + QBrush mBrush; + QCPScatterStyle mScatterStyle; + QCPScatterStyle::ScatterProperties mUsedScatterProperties; + // non-property members: + QCPAbstractPlottable *mPlottable; + + // introduced virtual methods: + virtual bool registerWithPlottable(QCPAbstractPlottable *plottable); + +private: + Q_DISABLE_COPY(QCPSelectionDecorator) + friend class QCPAbstractPlottable; +}; +Q_DECLARE_METATYPE(QCPSelectionDecorator*) + + +class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill) + Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis) + Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis) + Q_PROPERTY(QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(QCPDataSelection selection READ selection WRITE setSelection NOTIFY selectionChanged) + Q_PROPERTY(QCPSelectionDecorator* selectionDecorator READ selectionDecorator WRITE setSelectionDecorator) + /// \endcond +public: + QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPAbstractPlottable(); + + // getters: + QString name() const { return mName; } + QString desc() const { return mDesc; } + int type() const { return mType; } + bool antialiasedFill() const { return mAntialiasedFill; } + bool antialiasedScatters() const { return mAntialiasedScatters; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + QCP::SelectionType selectable() const { return mSelectable; } + bool selected() const { return !mSelection.isEmpty(); } + QCPDataSelection selection() const { return mSelection; } + QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; } + + // setters: + void setName(const QString &name); + void setDesc(const QString &desc); + void setType(const int &type); + void setAntialiasedFill(bool enabled); + void setAntialiasedScatters(bool enabled); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setKeyAxis(QCPAxis *axis); + void setValueAxis(QCPAxis *axis); + Q_SLOT void setSelectable(QCP::SelectionType selectable); + Q_SLOT void setSelection(QCPDataSelection selection); + void setSelectionDecorator(QCPSelectionDecorator *decorator); + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; + virtual QCPPlottableInterface1D *interface1D() { return 0; } + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0; + + // non-property methods: + void coordsToPixels(double key, double value, double &x, double &y) const; + const QPointF coordsToPixels(double key, double value) const; + void pixelsToCoords(double x, double y, double &key, double &value) const; + void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; + void rescaleAxes(bool onlyEnlarge=false) const; + void rescaleKeyAxis(bool onlyEnlarge=false) const; + void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const; + bool addToLegend(QCPLegend *legend); + bool addToLegend(); + bool removeFromLegend(QCPLegend *legend) const; + bool removeFromLegend() const; + +signals: + void selectionChanged(bool selected); + void selectionChanged(const QCPDataSelection &selection); + void selectableChanged(QCP::SelectionType selectable); + +protected: + // property members: + QString mName; + QString mDesc; + int mType; + bool mAntialiasedFill, mAntialiasedScatters; + QPen mPen; + QBrush mBrush; + QPointer mKeyAxis, mValueAxis; + QCP::SelectionType mSelectable; + QCPDataSelection mSelection; + QCPSelectionDecorator *mSelectionDecorator; + + // reimplemented virtual methods: + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0; + + // non-virtual methods: + void applyFillAntialiasingHint(QCPPainter *painter) const; + void applyScattersAntialiasingHint(QCPPainter *painter) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable) + + friend class QCustomPlot; + friend class QCPAxis; + friend class QCPPlottableLegendItem; +}; + + +/* end of 'src/plottable.h' */ + + +/* including file 'src/item.h', size 9384 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemAnchor +{ + Q_GADGET +public: + QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1); + virtual ~QCPItemAnchor(); + + // getters: + QString name() const { return mName; } + virtual QPointF pixelPosition() const; + +protected: + // property members: + QString mName; + + // non-property members: + QCustomPlot *mParentPlot; + QCPAbstractItem *mParentItem; + int mAnchorId; + QSet mChildrenX, mChildrenY; + + // introduced virtual methods: + virtual QCPItemPosition *toQCPItemPosition() { return 0; } + + // non-virtual methods: + void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + +private: + Q_DISABLE_COPY(QCPItemAnchor) + + friend class QCPItemPosition; +}; + + + +class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor +{ + Q_GADGET +public: + /*! + Defines the ways an item position can be specified. Thus it defines what the numbers passed to + \ref setCoords actually mean. + + \see setType + */ + enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. + ,ptViewportRatio ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the viewport/widget, etc. + ,ptAxisRectRatio ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1. + ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). + }; + Q_ENUMS(PositionType) + + QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name); + virtual ~QCPItemPosition(); + + // getters: + PositionType type() const { return typeX(); } + PositionType typeX() const { return mPositionTypeX; } + PositionType typeY() const { return mPositionTypeY; } + QCPItemAnchor *parentAnchor() const { return parentAnchorX(); } + QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; } + QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; } + double key() const { return mKey; } + double value() const { return mValue; } + QPointF coords() const { return QPointF(mKey, mValue); } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + QCPAxisRect *axisRect() const; + virtual QPointF pixelPosition() const Q_DECL_OVERRIDE; + + // setters: + void setType(PositionType type); + void setTypeX(PositionType type); + void setTypeY(PositionType type); + bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + void setCoords(double key, double value); + void setCoords(const QPointF &coords); + void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); + void setAxisRect(QCPAxisRect *axisRect); + void setPixelPosition(const QPointF &pixelPosition); + +protected: + // property members: + PositionType mPositionTypeX, mPositionTypeY; + QPointer mKeyAxis, mValueAxis; + QPointer mAxisRect; + double mKey, mValue; + QCPItemAnchor *mParentAnchorX, *mParentAnchorY; + + // reimplemented virtual methods: + virtual QCPItemPosition *toQCPItemPosition() Q_DECL_OVERRIDE { return this; } + +private: + Q_DISABLE_COPY(QCPItemPosition) + +}; +Q_DECLARE_METATYPE(QCPItemPosition::PositionType) + + +class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect) + Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + explicit QCPAbstractItem(QCustomPlot *parentPlot); + virtual ~QCPAbstractItem(); + + // getters: + bool clipToAxisRect() const { return mClipToAxisRect; } + QCPAxisRect *clipAxisRect() const; + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setClipToAxisRect(bool clip); + void setClipAxisRect(QCPAxisRect *rect); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE = 0; + + // non-virtual methods: + QList positions() const { return mPositions; } + QList anchors() const { return mAnchors; } + QCPItemPosition *position(const QString &name) const; + QCPItemAnchor *anchor(const QString &name) const; + bool hasAnchor(const QString &name) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + bool mClipToAxisRect; + QPointer mClipAxisRect; + QList mPositions; + QList mAnchors; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual QPointF anchorPixelPosition(int anchorId) const; + + // non-virtual methods: + double rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const; + QCPItemPosition *createPosition(const QString &name); + QCPItemAnchor *createAnchor(const QString &name, int anchorId); + +private: + Q_DISABLE_COPY(QCPAbstractItem) + + friend class QCustomPlot; + friend class QCPItemAnchor; +}; + +/* end of 'src/item.h' */ + + +/* including file 'src/core.h', size 14886 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCustomPlot : public QWidget +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QRect viewport READ viewport WRITE setViewport) + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout) + Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend) + Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance) + Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag) + Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier) + Q_PROPERTY(bool openGl READ openGl WRITE setOpenGl) + /// \endcond +public: + /*! + Defines how a layer should be inserted relative to an other layer. + + \see addLayer, moveLayer + */ + enum LayerInsertMode { limBelow ///< Layer is inserted below other layer + ,limAbove ///< Layer is inserted above other layer + }; + Q_ENUMS(LayerInsertMode) + + /*! + Defines with what timing the QCustomPlot surface is refreshed after a replot. + + \see replot + */ + enum RefreshPriority { rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling QWidget::repaint() after the replot + ,rpQueuedRefresh ///< Replots immediately, but queues the widget repaint, by calling QWidget::update() after the replot. This way multiple redundant widget repaints can be avoided. + ,rpRefreshHint ///< Whether to use immediate or queued refresh depends on whether the plotting hint \ref QCP::phImmediateRefresh is set, see \ref setPlottingHints. + ,rpQueuedReplot ///< Queues the entire replot for the next event loop iteration. This way multiple redundant replots can be avoided. The actual replot is then done with \ref rpRefreshHint priority. + }; + Q_ENUMS(RefreshPriority) + + explicit QCustomPlot(QWidget *parent = 0); + virtual ~QCustomPlot(); + + // getters: + QRect viewport() const { return mViewport; } + double bufferDevicePixelRatio() const { return mBufferDevicePixelRatio; } + QPixmap background() const { return mBackgroundPixmap; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + QCPLayoutGrid *plotLayout() const { return mPlotLayout; } + QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; } + QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; } + bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; } + const QCP::Interactions interactions() const { return mInteractions; } + int selectionTolerance() const { return mSelectionTolerance; } + bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; } + QCP::PlottingHints plottingHints() const { return mPlottingHints; } + Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; } + QCP::SelectionRectMode selectionRectMode() const { return mSelectionRectMode; } + QCPSelectionRect *selectionRect() const { return mSelectionRect; } + bool openGl() const { return mOpenGl; } + QPoint symbolPos() { return mSymbolPos; } + + // setters: + void setSymbolPos(const QPoint pos); + void setViewport(const QRect &rect); + void setBufferDevicePixelRatio(double ratio); + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements); + void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true); + void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements); + void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true); + void setAutoAddPlottableToLegend(bool on); + void setInteractions(const QCP::Interactions &interactions); + void setInteraction(const QCP::Interaction &interaction, bool enabled=true); + void setSelectionTolerance(int pixels); + void setNoAntialiasingOnDrag(bool enabled); + void setPlottingHints(const QCP::PlottingHints &hints); + void setPlottingHint(QCP::PlottingHint hint, bool enabled=true); + void setMultiSelectModifier(Qt::KeyboardModifier modifier); + void setSelectionRectMode(QCP::SelectionRectMode mode); + void setSelectionRect(QCPSelectionRect *selectionRect); + void setOpenGl(bool enabled, int multisampling=16); + + // non-property methods: + // plottable interface: + QCPAbstractPlottable *plottable(int index); + QCPAbstractPlottable *plottable(); + bool removePlottable(QCPAbstractPlottable *plottable); + bool removePlottable(int index); + int clearPlottables(); + int plottableCount() const; + QList selectedPlottables() const; + QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasPlottable(QCPAbstractPlottable *plottable) const; + + // specialized interface for QCPGraph: + QCPGraph *graph(int index) const; + QCPGraph *graph() const; + QCPGraph *addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0); + bool removeGraph(QCPGraph *graph); + bool removeGraph(int index); + int clearGraphs(); + int graphCount() const; + QList selectedGraphs() const; + + // item interface: + QCPAbstractItem *item(int index) const; + QCPAbstractItem *item() const; + bool removeItem(QCPAbstractItem *item); + bool removeItem(int index); + int clearItems(bool clearTitle = false); + int itemCount() const; + QList selectedItems() const; + QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasItem(QCPAbstractItem *item) const; + + // layer interface: + QCPLayer *layer(const QString &name) const; + QCPLayer *layer(int index) const; + QCPLayer *currentLayer() const; + bool setCurrentLayer(const QString &name); + bool setCurrentLayer(QCPLayer *layer); + int layerCount() const; + bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove); + bool removeLayer(QCPLayer *layer); + bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); + + // axis rect/layout interface: + int axisRectCount() const; + QCPAxisRect* axisRect(int index=0) const; + QList axisRects() const; + QCPLayoutElement* layoutElementAt(const QPointF &pos) const; + QCPAxisRect* axisRectAt(const QPointF &pos) const; + Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false); + + QList selectedAxes() const; + QList selectedLegends() const; + Q_SLOT void deselectAll(); + + bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString()); + bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + QPixmap toPixmap(int width=0, int height=0, double scale=1.0); + void toPainter(QCPPainter *painter, int width=0, int height=0); + Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint); + + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + QCPLegend *legend; + +signals: + void mouseDoubleClick(QMouseEvent *event); + void mousePress(QMouseEvent *event); + void mouseMove(QMouseEvent *event); + void mouseRelease(QMouseEvent *event); + void mouseWheel(QWheelEvent *event); + + //< 鼠标按下 更新CCurveLegendModel值 + void symbolPosChanged(const double &value); + + void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); + void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); + void itemClick(QCPAbstractItem *item, QMouseEvent *event); + void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event); + void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + + void selectionChangedByUser(); + void beforeReplot(); + void afterReplot(); + +protected: + // property members: + QRect mViewport; + double mBufferDevicePixelRatio; + QCPLayoutGrid *mPlotLayout; + bool mAutoAddPlottableToLegend; + QList mPlottables; + QList mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph + QList mItems; + QList mLayers; + QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements; + QCP::Interactions mInteractions; + int mSelectionTolerance; + bool mNoAntialiasingOnDrag; + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayer *mCurrentLayer; + QCP::PlottingHints mPlottingHints; + Qt::KeyboardModifier mMultiSelectModifier; + QCP::SelectionRectMode mSelectionRectMode; + QCPSelectionRect *mSelectionRect; + bool mOpenGl; + + // non-property members: + QList > mPaintBuffers; + bool mSymbolPressed; + QPoint mSymbolPos; + QPoint mMousePressPos; + bool mMouseHasMoved; + QPointer mMouseEventLayerable; + QPointer mMouseSignalLayerable; + QVariant mMouseEventLayerableDetails; + QVariant mMouseSignalLayerableDetails; + bool mReplotting; + bool mReplotQueued; + int mOpenGlMultisamples; + QCP::AntialiasedElements mOpenGlAntialiasedElementsBackup; + bool mOpenGlCacheLabelsBackup; +#ifdef QCP_OPENGL_FBO + QSharedPointer mGlContext; + QSharedPointer mGlSurface; + QSharedPointer mGlPaintDevice; +#endif + + // reimplemented virtual methods: + virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; + virtual QSize sizeHint() const Q_DECL_OVERRIDE; + virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + virtual void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + bool eventFilter(QObject *object, QEvent *event); + + // introduced virtual methods: + virtual void draw(QCPPainter *painter); + virtual void updateLayout(); + virtual void axisRemoved(QCPAxis *axis); + virtual void legendRemoved(QCPLegend *legend); + Q_SLOT virtual void processRectSelection(QRect rect, QMouseEvent *event); + Q_SLOT virtual void processRectZoom(QRect rect, QMouseEvent *event); + Q_SLOT virtual void processPointSelection(QMouseEvent *event); + + // non-virtual methods: + bool registerPlottable(QCPAbstractPlottable *plottable); + bool registerGraph(QCPGraph *graph); + bool registerItem(QCPAbstractItem* item); + void updateLayerIndices() const; + QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const; + QList layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails=0) const; + void drawBackground(QCPPainter *painter); + void setupPaintBuffers(); + QCPAbstractPaintBuffer *createPaintBuffer(); + bool hasInvalidatedPaintBuffers(); + bool setupOpenGl(); + void freeOpenGl(); + + friend class QCPLegend; + friend class QCPAxis; + friend class QCPLayer; + friend class QCPAxisRect; + friend class QCPAbstractPlottable; + friend class QCPGraph; + friend class QCPAbstractItem; +}; +Q_DECLARE_METATYPE(QCustomPlot::LayerInsertMode) +Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority) + +/* end of 'src/core.h' */ + + +/* including file 'src/plottable1d.h', size 4544 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCPPlottableInterface1D +{ +public: + virtual ~QCPPlottableInterface1D() {} + // introduced pure virtual methods: + virtual int dataCount() const = 0; + virtual double dataMainKey(int index) const = 0; + virtual double dataSortKey(int index) const = 0; + virtual double dataMainValue(int index) const = 0; + virtual QCPRange dataValueRange(int index) const = 0; + virtual QPointF dataPixelPosition(int index) const = 0; + virtual bool sortKeyIsMainKey() const = 0; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; + virtual int findBegin(double sortKey, bool expandedRange=true) const = 0; + virtual int findEnd(double sortKey, bool expandedRange=true) const = 0; +}; + +template +class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D // no QCP_LIB_DECL, template class ends up in header (cpp included below) +{ + // No Q_OBJECT macro due to template class + +public: + QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPAbstractPlottable1D(); + + // virtual methods of 1d plottable interface: + virtual int dataCount() const Q_DECL_OVERRIDE; + virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; + virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; + virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; + virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } + +protected: + // property members: + QSharedPointer > mDataContainer; + + // helpers for subclasses: + void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; + void drawPolyline(QCPPainter *painter, const QVector &lineData, const QVector &status=QVector()) const; + void drawPolyline(QCPPainter *painter, const QPointF *points, const int *status, int pointCount) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable1D) + +}; + +// include implementation in header since it is a class template: + +/* including file 'src/plottable1d.cpp', size 22240 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPlottableInterface1D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPlottableInterface1D + \brief Defines an abstract interface for one-dimensional plottables + + This class contains only pure virtual methods which define a common interface to the data + of one-dimensional plottables. + + For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred + base class for one-dimensional plottables). So if you use that template class as base class of + your one-dimensional plottable, you won't have to care about implementing the 1d interface + yourself. + + If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d + interface (e.g. like \ref QCPErrorBars does), you should inherit from both \ref + QCPAbstractPlottable and \ref QCPPlottableInterface1D and accordingly reimplement the pure + virtual methods of the 1d interface, matching your data container. Also, reimplement \ref + QCPAbstractPlottable::interface1D to return the \c this pointer. + + If you have a \ref QCPAbstractPlottable pointer, you can check whether it implements this + interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return + value. If it indeed implements this interface, you may use it to access the plottable's data + without needing to know the exact type of the plottable or its data point type. +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual int QCPPlottableInterface1D::dataCount() const = 0; + + Returns the number of data points of the plottable. +*/ + +/*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; + + Returns a data selection containing all the data points of this plottable which are contained (or + hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref + dataselection "data selection mechanism"). + + If \a onlySelectable is true, an empty QCPDataSelection is returned if this plottable is not + selectable (i.e. if \ref QCPAbstractPlottable::setSelectable is \ref QCP::stNone). + + \note \a rect must be a normalized rect (positive or zero width and height). This is especially + important when using the rect of \ref QCPSelectionRect::accepted, which is not necessarily + normalized. Use QRect::normalized() when passing a rect which might not be normalized. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataMainKey(int index) const = 0 + + Returns the main key of the data point at the given \a index. + + What the main key is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataSortKey(int index) const = 0 + + Returns the sort key of the data point at the given \a index. + + What the sort key is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataMainValue(int index) const = 0 + + Returns the main value of the data point at the given \a index. + + What the main value is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual QCPRange QCPPlottableInterface1D::dataValueRange(int index) const = 0 + + Returns the value range of the data point at the given \a index. + + What the value range is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual QPointF QCPPlottableInterface1D::dataPixelPosition(int index) const = 0 + + Returns the pixel position on the widget surface at which the data point at the given \a index + appears. + + Usually this corresponds to the point of \ref dataMainKey/\ref dataMainValue, in pixel + coordinates. However, depending on the plottable, this might be a different apparent position + than just a coord-to-pixel transform of those values. For example, \ref QCPBars apparent data + values can be shifted depending on their stacking, bar grouping or configured base value. +*/ + +/*! \fn virtual bool QCPPlottableInterface1D::sortKeyIsMainKey() const = 0 + + Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey). + + What the sort and main keys are, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0 + + Returns the index of the data point with a (sort-)key that is equal to, just below, or just above + \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be considered, + otherwise the one just above. + + This can be used in conjunction with \ref findEnd to iterate over data points within a given key + range, including or excluding the bounding data points that are just beyond the specified range. + + If \a expandedRange is true but there are no data points below \a sortKey, 0 is returned. + + If the container is empty, returns 0 (in that case, \ref findEnd will also return 0, so a loop + using these methods will not iterate over the index 0). + + \see findEnd, QCPDataContainer::findBegin +*/ + +/*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0 + + Returns the index one after the data point with a (sort-)key that is equal to, just above, or + just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be + considered, otherwise the one just below. + + This can be used in conjunction with \ref findBegin to iterate over data points within a given + key range, including the bounding data points that are just below and above the specified range. + + If \a expandedRange is true but there are no data points above \a sortKey, the index just above the + highest data point is returned. + + If the container is empty, returns 0. + + \see findBegin, QCPDataContainer::findEnd +*/ + +/* end documentation of pure virtual functions */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPlottable1D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPlottable1D + \brief A template base class for plottables with one-dimensional data + + This template class derives from \ref QCPAbstractPlottable and from the abstract interface \ref + QCPPlottableInterface1D. It serves as a base class for all one-dimensional data (i.e. data with + one key dimension), such as \ref QCPGraph and QCPCurve. + + The template parameter \a DataType is the type of the data points of this plottable (e.g. \ref + QCPGraphData or \ref QCPCurveData). The main purpose of this base class is to provide the member + \a mDataContainer (a shared pointer to a \ref QCPDataContainer "QCPDataContainer") and + implement the according virtual methods of the \ref QCPPlottableInterface1D, such that most + subclassed plottables don't need to worry about this anymore. + + Further, it provides a convenience method for retrieving selected/unselected data segments via + \ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to + draw selected segments with a different pen/brush than unselected segments (also see \ref + QCPSelectionDecorator). + + This class implements basic functionality of \ref QCPAbstractPlottable::selectTest and \ref + QCPPlottableInterface1D::selectTestRect, assuming point-like data points, based on the 1D data + interface. In spite of that, most plottable subclasses will want to reimplement those methods + again, to provide a more accurate hit test based on their specific data visualization geometry. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPPlottableInterface1D *QCPAbstractPlottable1D::interface1D() + + Returns a \ref QCPPlottableInterface1D pointer to this plottable, providing access to its 1D + interface. + + \seebaseclassmethod +*/ + +/* end documentation of inline functions */ + +/*! + Forwards \a keyAxis and \a valueAxis to the \ref QCPAbstractPlottable::QCPAbstractPlottable + "QCPAbstractPlottable" constructor and allocates the \a mDataContainer. +*/ +template +QCPAbstractPlottable1D::QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mDataContainer(new QCPDataContainer) +{ +} + +template +QCPAbstractPlottable1D::~QCPAbstractPlottable1D() +{ +} + +/*! + \copydoc QCPPlottableInterface1D::dataCount +*/ +template +int QCPAbstractPlottable1D::dataCount() const +{ + return mDataContainer->size(); +} + +/*! + \copydoc QCPPlottableInterface1D::dataMainKey +*/ +template +double QCPAbstractPlottable1D::dataMainKey(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->mainKey(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataSortKey +*/ +template +double QCPAbstractPlottable1D::dataSortKey(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->sortKey(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataMainValue +*/ +template +double QCPAbstractPlottable1D::dataMainValue(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->mainValue(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataValueRange +*/ +template +QCPRange QCPAbstractPlottable1D::dataValueRange(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->valueRange(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QCPRange(0, 0); + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataPixelPosition +*/ +template +QPointF QCPAbstractPlottable1D::dataPixelPosition(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + const typename QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; + return coordsToPixels(it->mainKey(), it->mainValue()); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QPointF(); + } +} + +/*! + \copydoc QCPPlottableInterface1D::sortKeyIsMainKey +*/ +template +bool QCPAbstractPlottable1D::sortKeyIsMainKey() const +{ + return DataType::sortKeyIsMainKey(); +} + +/*! + Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is + point-like. Most subclasses will want to reimplement this method again, to provide a more + accurate hit test based on the true data visualization geometry. + + \seebaseclassmethod +*/ +template +QCPDataSelection QCPAbstractPlottable1D::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + // convert rect given in pixels to ranges given in plot coordinates: + double key1, value1, key2, value2; + pixelsToCoords(rect.topLeft(), key1, value1); + pixelsToCoords(rect.bottomRight(), key2, value2); + QCPRange keyRange(key1, key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2 + QCPRange valueRange(value1, value2); + typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); + typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); + if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: + { + begin = mDataContainer->findBegin(keyRange.lower, false); + end = mDataContainer->findEnd(keyRange.upper, false); + } + if (begin == end) + return result; + + int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect + for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) + { + if (currentSegmentBegin == -1) + { + if (valueRange.contains(it->mainValue()) && keyRange.contains(it->mainKey())) // start segment + currentSegmentBegin = it-mDataContainer->constBegin(); + } else if (!valueRange.contains(it->mainValue()) || !keyRange.contains(it->mainKey())) // segment just ended + { + result.addDataRange(QCPDataRange(currentSegmentBegin, it-mDataContainer->constBegin()), false); + currentSegmentBegin = -1; + } + } + // process potential last segment: + if (currentSegmentBegin != -1) + result.addDataRange(QCPDataRange(currentSegmentBegin, end-mDataContainer->constBegin()), false); + + result.simplify(); + return result; +} + +/*! + \copydoc QCPPlottableInterface1D::findBegin +*/ +template +int QCPAbstractPlottable1D::findBegin(double sortKey, bool expandedRange) const +{ + return mDataContainer->findBegin(sortKey, expandedRange)-mDataContainer->constBegin(); +} + +/*! + \copydoc QCPPlottableInterface1D::findEnd +*/ +template +int QCPAbstractPlottable1D::findEnd(double sortKey, bool expandedRange) const +{ + return mDataContainer->findEnd(sortKey, expandedRange)-mDataContainer->constBegin(); +} + +/*! + Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is + point-like. Most subclasses will want to reimplement this method again, to provide a more + accurate hit test based on the true data visualization geometry. + + \seebaseclassmethod +*/ +template +double QCPAbstractPlottable1D::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + QCPDataSelection selectionResult; + double minDistSqr = std::numeric_limits::max(); + int minDistIndex = mDataContainer->size(); + + typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); + typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); + if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: + { + // determine which key range comes into question, taking selection tolerance around pos into account: + double posKeyMin, posKeyMax, dummy; + pixelsToCoords(pos-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); + pixelsToCoords(pos+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); + if (posKeyMin > posKeyMax) + qSwap(posKeyMin, posKeyMax); + begin = mDataContainer->findBegin(posKeyMin, true); + end = mDataContainer->findEnd(posKeyMax, true); + } + if (begin == end) + return -1; + QCPRange keyRange(mKeyAxis->range()); + QCPRange valueRange(mValueAxis->range()); + for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double mainKey = it->mainKey(); + const double mainValue = it->mainValue(); + if (keyRange.contains(mainKey) && valueRange.contains(mainValue)) // make sure data point is inside visible range, for speedup in cases where sort key isn't main key and we iterate over all points + { + const double currentDistSqr = QCPVector2D(coordsToPixels(mainKey, mainValue)-pos).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + minDistIndex = it-mDataContainer->constBegin(); + } + } + } + if (minDistIndex != mDataContainer->size()) + selectionResult.addDataRange(QCPDataRange(minDistIndex, minDistIndex+1), false); + + selectionResult.simplify(); + if (details) + details->setValue(selectionResult); + return qSqrt(minDistSqr); +} + +/*! + Splits all data into selected and unselected segments and outputs them via \a selectedSegments + and \a unselectedSegments, respectively. + + This is useful when subclasses implement their \ref draw method and need to draw selected + segments with a different pen/brush than unselected segments (also see \ref + QCPSelectionDecorator). + + \see setSelection +*/ +template +void QCPAbstractPlottable1D::getDataSegments(QList &selectedSegments, QList &unselectedSegments) const +{ + selectedSegments.clear(); + unselectedSegments.clear(); + if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty + { + if (selected()) + selectedSegments << QCPDataRange(0, dataCount()); + else + unselectedSegments << QCPDataRange(0, dataCount()); + } else + { + QCPDataSelection sel(selection()); + sel.simplify(); + selectedSegments = sel.dataRanges(); + unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); + } +} + +/*! + A helper method which draws a line with the passed \a painter, according to the pixel data in \a + lineData. NaN points create gaps in the line, as expected from QCustomPlot's plottables (this is + the main difference to QPainter's regular drawPolyline, which handles NaNs by lagging or + crashing). + + Further it uses a faster line drawing technique based on \ref QCPPainter::drawLine rather than \c + QPainter::drawPolyline if the configured \ref QCustomPlot::setPlottingHints() and \a painter + style allows. +*/ +template +void QCPAbstractPlottable1D::drawPolyline(QCPPainter *painter, const QVector &lineData, const QVector &status) const +{ + // if drawing solid line and not in PDF, use much faster line drawing instead of polyline: + if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) && + painter->pen().style() == Qt::SolidLine && + !painter->modes().testFlag(QCPPainter::pmVectorized) && + !painter->modes().testFlag(QCPPainter::pmNoCaching)) + { + int i = 0; + bool lastIsNan = false; + const int lineDataSize = lineData.size(); + while (i < lineDataSize && (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN + ++i; + ++i; // because drawing works in 1 point retrospect + while (i < lineDataSize) + { + if (!qIsNaN(lineData.at(i).y()) && !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line + { + if (!lastIsNan) + painter->drawLine(lineData.at(i-1), lineData.at(i)); + else + lastIsNan = false; + } else + lastIsNan = true; + ++i; + } + } else + { + int segmentStart = 0; + int i = 0; + const int lineDataSize = lineData.size(); + while (i < lineDataSize) + { + if (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()) || qIsInf(lineData.at(i).y())) // NaNs create a gap in the line. Also filter Infs which make drawPolyline block + { + if(status.size() == lineDataSize) + { + drawPolyline(painter, lineData.constData()+segmentStart, status.constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point + } + else + { + painter->drawPolyline(lineData.constData()+segmentStart, i-segmentStart); + } + segmentStart = i+1; + } + ++i; + } + // draw last segment: + if(status.size() == lineDataSize) + { + drawPolyline(painter, lineData.constData()+segmentStart, status.constData()+segmentStart, lineDataSize-segmentStart); + } + else + { + painter->drawPolyline(lineData.constData()+segmentStart, lineDataSize-segmentStart); + } + } +} + +template +void QCPAbstractPlottable1D::drawPolyline(QCPPainter *painter, const QPointF *points, const int *status, int pointCount) const +{ + painter->save(); + QColor color = painter->pen().color(); + int preStatus = 0; + int curStatus = 0; + int segmentStart = 0; + for(int i(0); idrawPolyline(points+segmentStart, i-segmentStart+1); + if(curStatus == 1) + painter->setPen(Qt::gray); + else + painter->setPen(color); + segmentStart = i; + preStatus = curStatus; + } + } + painter->drawPolyline(points+segmentStart, pointCount-segmentStart); + painter->restore(); +} +/* end of 'src/plottable1d.cpp' */ + + +/* end of 'src/plottable1d.h' */ + + +/* including file 'src/colorgradient.h', size 6243 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPColorGradient +{ + Q_GADGET +public: + /*! + Defines the color spaces in which color interpolation between gradient stops can be performed. + + \see setColorInterpolation + */ + enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated + ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance) + }; + Q_ENUMS(ColorInterpolation) + + /*! + Defines the available presets that can be loaded with \ref loadPreset. See the documentation + there for an image of the presets. + */ + enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation) + ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation) + ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation) + ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation) + ,gpCandy ///< Blue over pink to white + ,gpGeography ///< Colors suitable to represent different elevations on geographical maps + ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates) + ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white + ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values + ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates) + ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates) + ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic) + }; + Q_ENUMS(GradientPreset) + + QCPColorGradient(); + QCPColorGradient(GradientPreset preset); + bool operator==(const QCPColorGradient &other) const; + bool operator!=(const QCPColorGradient &other) const { return !(*this == other); } + + // getters: + int levelCount() const { return mLevelCount; } + QMap colorStops() const { return mColorStops; } + ColorInterpolation colorInterpolation() const { return mColorInterpolation; } + bool periodic() const { return mPeriodic; } + + // setters: + void setLevelCount(int n); + void setColorStops(const QMap &colorStops); + void setColorStopAt(double position, const QColor &color); + void setColorInterpolation(ColorInterpolation interpolation); + void setPeriodic(bool enabled); + + // non-property methods: + void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); + void colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); + QRgb color(double position, const QCPRange &range, bool logarithmic=false); + void loadPreset(GradientPreset preset); + void clearColorStops(); + QCPColorGradient inverted() const; + +protected: + // property members: + int mLevelCount; + QMap mColorStops; + ColorInterpolation mColorInterpolation; + bool mPeriodic; + + // non-property members: + QVector mColorBuffer; // have colors premultiplied with alpha (for usage with QImage::Format_ARGB32_Premultiplied) + bool mColorBufferInvalidated; + + // non-virtual methods: + bool stopsUseAlpha() const; + void updateColorBuffer(); +}; +Q_DECLARE_METATYPE(QCPColorGradient::ColorInterpolation) +Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset) + +/* end of 'src/colorgradient.h' */ + + +/* including file 'src/selectiondecorator-bracket.h', size 4442 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator +{ + Q_GADGET +public: + + /*! + Defines which shape is drawn at the boundaries of selected data ranges. + + Some of the bracket styles further allow specifying a height and/or width, see \ref + setBracketHeight and \ref setBracketWidth. + */ + enum BracketStyle { bsSquareBracket ///< A square bracket is drawn. + ,bsHalfEllipse ///< A half ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. + ,bsEllipse ///< An ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. + ,bsPlus ///< A plus is drawn. + ,bsUserStyle ///< Start custom bracket styles at this index when subclassing and reimplementing \ref drawBracket. + }; + Q_ENUMS(BracketStyle) + + QCPSelectionDecoratorBracket(); + virtual ~QCPSelectionDecoratorBracket(); + + // getters: + QPen bracketPen() const { return mBracketPen; } + QBrush bracketBrush() const { return mBracketBrush; } + int bracketWidth() const { return mBracketWidth; } + int bracketHeight() const { return mBracketHeight; } + BracketStyle bracketStyle() const { return mBracketStyle; } + bool tangentToData() const { return mTangentToData; } + int tangentAverage() const { return mTangentAverage; } + + // setters: + void setBracketPen(const QPen &pen); + void setBracketBrush(const QBrush &brush); + void setBracketWidth(int width); + void setBracketHeight(int height); + void setBracketStyle(BracketStyle style); + void setTangentToData(bool enabled); + void setTangentAverage(int pointCount); + + // introduced virtual methods: + virtual void drawBracket(QCPPainter *painter, int direction) const; + + // virtual methods: + virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection) Q_DECL_OVERRIDE; + +protected: + // property members: + QPen mBracketPen; + QBrush mBracketBrush; + int mBracketWidth; + int mBracketHeight; + BracketStyle mBracketStyle; + bool mTangentToData; + int mTangentAverage; + + // non-virtual methods: + double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const; + QPointF getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const; + +}; +Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle) + +/* end of 'src/selectiondecorator-bracket.h' */ + + +/* including file 'src/layoutelements/layoutelement-axisrect.h', size 7507 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true); + virtual ~QCPAxisRect(); + + // getters: + QPixmap background() const { return mBackgroundPixmap; } + QBrush backgroundBrush() const { return mBackgroundBrush; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + Qt::Orientations rangeDrag() const { return mRangeDrag; } + Qt::Orientations rangeZoom() const { return mRangeZoom; } + QCPAxis *rangeDragAxis(Qt::Orientation orientation); + QCPAxis *rangeZoomAxis(Qt::Orientation orientation); + QList rangeDragAxes(Qt::Orientation orientation); + QList rangeZoomAxes(Qt::Orientation orientation); + double rangeZoomFactor(Qt::Orientation orientation); + + // setters: + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setRangeDrag(Qt::Orientations orientations); + void setRangeZoom(Qt::Orientations orientations); + void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeDragAxes(QList axes); + void setRangeDragAxes(QList horizontal, QList vertical); + void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeZoomAxes(QList axes); + void setRangeZoomAxes(QList horizontal, QList vertical); + void setRangeZoomFactor(double horizontalFactor, double verticalFactor); + void setRangeZoomFactor(double factor); + + // non-property methods: + int axisCount(QCPAxis::AxisType type) const; + QCPAxis *axis(QCPAxis::AxisType type, int index=0) const; + QList axes(QCPAxis::AxisTypes types) const; + QList axes() const; + QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=0); + QList addAxes(QCPAxis::AxisTypes types); + bool removeAxis(QCPAxis *axis); + QCPLayoutInset *insetLayout() const { return mInsetLayout; } + + void zoom(const QRectF &pixelRect); + void zoom(const QRectF &pixelRect, const QList &affectedAxes); + void setupFullAxesBox(bool connectRanges=false); + QList plottables() const; + QList graphs() const; + QList items() const; + + // read-only interface imitating a QRect: + int left() const { return mRect.left(); } + int right() const { return mRect.right(); } + int top() const { return mRect.top(); } + int bottom() const { return mRect.bottom(); } + int width() const { return mRect.width(); } + int height() const { return mRect.height(); } + QSize size() const { return mRect.size(); } + QPoint topLeft() const { return mRect.topLeft(); } + QPoint topRight() const { return mRect.topRight(); } + QPoint bottomLeft() const { return mRect.bottomLeft(); } + QPoint bottomRight() const { return mRect.bottomRight(); } + QPoint center() const { return mRect.center(); } + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + + void setScaleRight(const bool &scaleRight = true) { mIsScaleRight = scaleRight; } + bool isScaleRight() { return mIsScaleRight; } + +signals: + void rangeDraged(); + void rangeScaled(); + +protected: + // property members: + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayoutInset *mInsetLayout; + Qt::Orientations mRangeDrag, mRangeZoom; + QList > mRangeDragHorzAxis, mRangeDragVertAxis; + QList > mRangeZoomHorzAxis, mRangeZoomVertAxis; + double mRangeZoomFactorHorz, mRangeZoomFactorVert; + + // non-property members: + QList mDragStartHorzRange, mDragStartVertRange; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + bool mDragging; + QHash > mAxes; + + //< ZH + bool mIsScaleRight; + bool mIsDragMove; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual int calculateAutoMargin(QCP::MarginSide side) Q_DECL_OVERRIDE; + virtual void layoutChanged() Q_DECL_OVERRIDE; + // events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + // non-property methods: + void drawBackground(QCPPainter *painter); + void updateAxesOffset(QCPAxis::AxisType type); + +private: + Q_DISABLE_COPY(QCPAxisRect) + + friend class QCustomPlot; +}; + + +/* end of 'src/layoutelements/layoutelement-axisrect.h' */ + + +/* including file 'src/layoutelements/layoutelement-legend.h', size 10397 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLegend* parentLegend READ parentLegend) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged) + /// \endcond +public: + explicit QCPAbstractLegendItem(QCPLegend *parent); + + // getters: + QCPLegend *parentLegend() const { return mParentLegend; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + QCPLegend *mParentLegend; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPAbstractLegendItem) + + friend class QCPLegend; +}; + + +class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem +{ + Q_OBJECT +public: + QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable); + + // getters: + QCPAbstractPlottable *plottable() { return mPlottable; } + +protected: + // property members: + QCPAbstractPlottable *mPlottable; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen getIconBorderPen() const; + QColor getTextColor() const; + QFont getFont() const; +}; + + +class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) + Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding) + Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged) + Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen) + Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + /// \endcond +public: + /*! + Defines the selectable parts of a legend + + \see setSelectedParts, setSelectableParts + */ + enum SelectablePart { spNone = 0x000 ///< 0x000 None + ,spLegendBox = 0x001 ///< 0x001 The legend box (frame) + ,spItems = 0x002 ///< 0x002 Legend items individually (see \ref selectedItems) + }; + Q_ENUMS(SelectablePart) + Q_FLAGS(SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPLegend(); + virtual ~QCPLegend(); + + // getters: + QPen borderPen() const { return mBorderPen; } + QBrush brush() const { return mBrush; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QSize iconSize() const { return mIconSize; } + int iconTextPadding() const { return mIconTextPadding; } + QPen iconBorderPen() const { return mIconBorderPen; } + SelectableParts selectableParts() const { return mSelectableParts; } + SelectableParts selectedParts() const; + QPen selectedBorderPen() const { return mSelectedBorderPen; } + QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + + // setters: + void setBorderPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setIconSize(const QSize &size); + void setIconSize(int width, int height); + void setIconTextPadding(int padding); + void setIconBorderPen(const QPen &pen); + Q_SLOT void setSelectableParts(const SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const SelectableParts &selectedParts); + void setSelectedBorderPen(const QPen &pen); + void setSelectedIconBorderPen(const QPen &pen); + void setSelectedBrush(const QBrush &brush); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QCPAbstractLegendItem *item(int index) const; + QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; + int itemCount() const; + bool hasItem(QCPAbstractLegendItem *item) const; + bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const; + bool addItem(QCPAbstractLegendItem *item); + bool removeItem(int index); + bool removeItem(QCPAbstractLegendItem *item); + void clearItems(); + QList selectedItems() const; + +signals: + void selectionChanged(QCPLegend::SelectableParts parts); + void selectableChanged(QCPLegend::SelectableParts parts); + +protected: + // property members: + QPen mBorderPen, mIconBorderPen; + QBrush mBrush; + QFont mFont; + QColor mTextColor; + QSize mIconSize; + int mIconTextPadding; + SelectableParts mSelectedParts, mSelectableParts; + QPen mSelectedBorderPen, mSelectedIconBorderPen; + QBrush mSelectedBrush; + QFont mSelectedFont; + QColor mSelectedTextColor; + + // reimplemented virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen getBorderPen() const; + QBrush getBrush() const; + +private: + Q_DISABLE_COPY(QCPLegend) + + friend class QCustomPlot; + friend class QCPAbstractLegendItem; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts) +Q_DECLARE_METATYPE(QCPLegend::SelectablePart) + +/* end of 'src/layoutelements/layoutelement-legend.h' */ + + +/* including file 'src/layoutelements/layoutelement-textelement.h', size 5353 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + explicit QCPTextElement(QCustomPlot *parentPlot); + QCPTextElement(QCustomPlot *parentPlot, const QString &text); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font); + + // getters: + QString text() const { return mText; } + int textFlags() const { return mTextFlags; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setText(const QString &text); + void setTextFlags(int flags); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + void clicked(QMouseEvent *event); + void doubleClicked(QMouseEvent *event); + +protected: + // property members: + QString mText; + int mTextFlags; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + QRect mTextBoundingRect; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // non-virtual methods: + QFont mainFont() const; + QColor mainTextColor() const; + +private: + Q_DISABLE_COPY(QCPTextElement) +}; + + + +/* end of 'src/layoutelements/layoutelement-textelement.h' */ + + +/* including file 'src/layoutelements/layoutelement-colorscale.h', size 5923 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + + +class QCPColorScaleAxisRectPrivate : public QCPAxisRect +{ + Q_OBJECT +public: + explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale); +protected: + QCPColorScale *mParentColorScale; + QImage mGradientImage; + bool mGradientImageInvalidated; + // re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale + using QCPAxisRect::calculateAutoMargin; + using QCPAxisRect::mousePressEvent; + using QCPAxisRect::mouseMoveEvent; + using QCPAxisRect::mouseReleaseEvent; + using QCPAxisRect::wheelEvent; + using QCPAxisRect::update; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + void updateGradientImage(); + Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts); + Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts); + friend class QCPColorScale; +}; + + +class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType) + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth) + Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPColorScale(QCustomPlot *parentPlot); + virtual ~QCPColorScale(); + + // getters: + QCPAxis *axis() const { return mColorAxis.data(); } + QCPAxis::AxisType type() const { return mType; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + QCPColorGradient gradient() const { return mGradient; } + QString label() const; + int barWidth () const { return mBarWidth; } + bool rangeDrag() const; + bool rangeZoom() const; + + // setters: + void setType(QCPAxis::AxisType type); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setLabel(const QString &str); + void setBarWidth(int width); + void setRangeDrag(bool enabled); + void setRangeZoom(bool enabled); + + // non-property methods: + QList colorMaps() const; + void rescaleDataRange(bool onlyVisibleMaps); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + +signals: + void dataRangeChanged(const QCPRange &newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(const QCPColorGradient &newGradient); + +protected: + // property members: + QCPAxis::AxisType mType; + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorGradient mGradient; + int mBarWidth; + + // non-property members: + QPointer mAxisRect; + QPointer mColorAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + // events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPColorScale) + + friend class QCPColorScaleAxisRectPrivate; +}; + + +/* end of 'src/layoutelements/layoutelement-colorscale.h' */ + + +/* including file 'src/plottables/plottable-graph.h', size 9294 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPGraphData +{ +public: + QCPGraphData(); + QCPGraphData(double key, double value, int status=0); + + inline double sortKey() const { return key; } + inline static QCPGraphData fromSortKey(double sortKey) { return QCPGraphData(sortKey, 0, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + inline int mainStatus() const { return status; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } + + double key, value; + int status; +}; +Q_DECLARE_TYPEINFO(QCPGraphData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPGraphDataContainer + + Container for storing \ref QCPGraphData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPGraph holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPGraphData, QCPGraph::setData +*/ +typedef QCPDataContainer QCPGraphDataContainer; + +class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) + Q_PROPERTY(QCPGraph* channelFillGraph READ channelFillGraph WRITE setChannelFillGraph) + Q_PROPERTY(bool adaptiveSampling READ adaptiveSampling WRITE setAdaptiveSampling) + /// \endcond +public: + /*! + Defines how the graph's line is represented visually in the plot. The line is drawn with the + current pen of the graph (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented + ///< with symbols according to the scatter style, see \ref setScatterStyle) + ,lsLine ///< data points are connected by a straight line + ,lsStepLeft ///< line is drawn as steps where the step height is the value of the left data point + ,lsStepRight ///< line is drawn as steps where the step height is the value of the right data point + ,lsStepCenter ///< line is drawn as steps where the step is in between two data points + ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line + }; + Q_ENUMS(LineStyle) + + explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPGraph(); + + // getters: + QSharedPointer data() const { return mDataContainer; } + LineStyle lineStyle() const { return mLineStyle; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + int scatterSkip() const { return mScatterSkip; } + QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); } + bool adaptiveSampling() const { return mAdaptiveSampling; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &values, const QVector &status, bool alreadySorted=false); + void setLineStyle(LineStyle ls); + void setScatterStyle(const QCPScatterStyle &style); + void setScatterSkip(int skip); + void setChannelFillGraph(QCPGraph *targetGraph); + void setAdaptiveSampling(bool enabled); + + // non-property methods: + void addData(const QVector &keys, const QVector &values, const QVector &status, bool alreadySorted=false); + void addData(double key, double value, int status=0); + + /** + * @brief value 根据key值,查找value + */ + double value(const double &key); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + LineStyle mLineStyle; + QCPScatterStyle mScatterStyle; + int mScatterSkip; + QPointer mChannelFillGraph; + bool mAdaptiveSampling; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawFill(QCPPainter *painter, QVector *lines) const; + virtual void drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const; + virtual void drawLinePlot(QCPPainter *painter, const QVector &lines, const QVector &status) const; + virtual void drawImpulsePlot(QCPPainter *painter, const QVector &lines) const; + + virtual void getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const; + virtual void getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const; + + // non-virtual methods: + void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; + void getLines(QVector *lines, const QCPDataRange &dataRange, QVector *status) const; + void getScatters(QVector *scatters, const QCPDataRange &dataRange) const; + void dataToLines(const QVector &data, QVector &lines, QVector &status) const; + void dataToStepLeftLines(const QVector &data, QVector &lines, QVector &status) const; + void dataToStepRightLines(const QVector &data, QVector &lines, QVector &status) const; + void dataToStepCenterLines(const QVector &data, QVector &lines, QVector &status) const; + void dataToImpulseLines(const QVector &data, QVector &lines, QVector &status) const; + QVector getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const; + QVector > getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const; + bool segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const; + QPointF getFillBasePoint(QPointF matchingDataPoint) const; + const QPolygonF getFillPolygon(const QVector *lineData, QCPDataRange segment) const; + const QPolygonF getChannelFillPolygon(const QVector *lineData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const; + int findIndexBelowX(const QVector *data, double x) const; + int findIndexAboveX(const QVector *data, double x) const; + int findIndexBelowY(const QVector *data, double y) const; + int findIndexAboveY(const QVector *data, double y) const; + double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPGraph::LineStyle) + +/* end of 'src/plottables/plottable-graph.h' */ + + +/* including file 'src/plottables/plottable-curve.h', size 7409 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPCurveData +{ +public: + QCPCurveData(); + QCPCurveData(double t, double key, double value); + + inline double sortKey() const { return t; } + inline static QCPCurveData fromSortKey(double sortKey) { return QCPCurveData(sortKey, 0, 0); } + inline static bool sortKeyIsMainKey() { return false; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } + + double t, key, value; +}; +Q_DECLARE_TYPEINFO(QCPCurveData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPCurveDataContainer + + Container for storing \ref QCPCurveData points. The data is stored sorted by \a t, so the \a + sortKey() (returning \a t) is different from \a mainKey() (returning \a key). + + This template instantiation is the container in which QCPCurve holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPCurveData, QCPCurve::setData +*/ +typedef QCPDataContainer QCPCurveDataContainer; + +class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + /// \endcond +public: + /*! + Defines how the curve's line is represented visually in the plot. The line is drawn with the + current pen of the curve (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< No line is drawn between data points (e.g. only scatters) + ,lsLine ///< Data points are connected with a straight line + }; + Q_ENUMS(LineStyle) + + explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPCurve(); + + // getters: + QSharedPointer data() const { return mDataContainer; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + int scatterSkip() const { return mScatterSkip; } + LineStyle lineStyle() const { return mLineStyle; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); + void setData(const QVector &keys, const QVector &values); + void setScatterStyle(const QCPScatterStyle &style); + void setScatterSkip(int skip); + void setLineStyle(LineStyle style); + + // non-property methods: + void addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(const QVector &keys, const QVector &values); + void addData(double t, double key, double value); + void addData(double key, double value); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + QCPScatterStyle mScatterStyle; + int mScatterSkip; + LineStyle mLineStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawCurveLine(QCPPainter *painter, const QVector &lines) const; + virtual void drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const; + + // non-virtual methods: + void getCurveLines(QVector *lines, const QCPDataRange &dataRange, double penWidth) const; + void getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const; + int getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + QVector getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + bool mayTraverse(int prevRegion, int currentRegion) const; + bool getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const; + void getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const; + double pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPCurve::LineStyle) + +/* end of 'src/plottables/plottable-curve.h' */ + + +/* including file 'src/plottables/plottable-bars.h', size 8924 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPBarsGroup : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(SpacingType spacingType READ spacingType WRITE setSpacingType) + Q_PROPERTY(double spacing READ spacing WRITE setSpacing) + /// \endcond +public: + /*! + Defines the ways the spacing between bars in the group can be specified. Thus it defines what + the number passed to \ref setSpacing actually means. + + \see setSpacingType, setSpacing + */ + enum SpacingType { stAbsolute ///< Bar spacing is in absolute pixels + ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size + ,stPlotCoords ///< Bar spacing is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(SpacingType) + + QCPBarsGroup(QCustomPlot *parentPlot); + virtual ~QCPBarsGroup(); + + // getters: + SpacingType spacingType() const { return mSpacingType; } + double spacing() const { return mSpacing; } + + // setters: + void setSpacingType(SpacingType spacingType); + void setSpacing(double spacing); + + // non-virtual methods: + QList bars() const { return mBars; } + QCPBars* bars(int index) const; + int size() const { return mBars.size(); } + bool isEmpty() const { return mBars.isEmpty(); } + void clear(); + bool contains(QCPBars *bars) const { return mBars.contains(bars); } + void append(QCPBars *bars); + void insert(int i, QCPBars *bars); + void remove(QCPBars *bars); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + SpacingType mSpacingType; + double mSpacing; + QList mBars; + + // non-virtual methods: + void registerBars(QCPBars *bars); + void unregisterBars(QCPBars *bars); + + // virtual methods: + double keyPixelOffset(const QCPBars *bars, double keyCoord); + double getPixelSpacing(const QCPBars *bars, double keyCoord); + +private: + Q_DISABLE_COPY(QCPBarsGroup) + + friend class QCPBars; +}; +Q_DECLARE_METATYPE(QCPBarsGroup::SpacingType) + + +class QCP_LIB_DECL QCPBarsData +{ +public: + QCPBarsData(); + QCPBarsData(double key, double value); + + inline double sortKey() const { return key; } + inline static QCPBarsData fromSortKey(double sortKey) { return QCPBarsData(sortKey, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } // note that bar base value isn't held in each QCPBarsData and thus can't/shouldn't be returned here + + double key, value; +}; +Q_DECLARE_TYPEINFO(QCPBarsData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPBarsDataContainer + + Container for storing \ref QCPBarsData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPBars holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPBarsData, QCPBars::setData +*/ +typedef QCPDataContainer QCPBarsDataContainer; + +class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) + Q_PROPERTY(QCPBarsGroup* barsGroup READ barsGroup WRITE setBarsGroup) + Q_PROPERTY(double baseValue READ baseValue WRITE setBaseValue) + Q_PROPERTY(double stackingGap READ stackingGap WRITE setStackingGap) + Q_PROPERTY(QCPBars* barBelow READ barBelow) + Q_PROPERTY(QCPBars* barAbove READ barAbove) + /// \endcond +public: + /*! + Defines the ways the width of the bar can be specified. Thus it defines what the number passed + to \ref setWidth actually means. + + \see setWidthType, setWidth + */ + enum WidthType { wtAbsolute ///< Bar width is in absolute pixels + ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size + ,wtPlotCoords ///< Bar width is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(WidthType) + + explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPBars(); + + // getters: + double width() const { return mWidth; } + WidthType widthType() const { return mWidthType; } + QCPBarsGroup *barsGroup() const { return mBarsGroup; } + double baseValue() const { return mBaseValue; } + double stackingGap() const { return mStackingGap; } + QCPBars *barBelow() const { return mBarBelow.data(); } + QCPBars *barAbove() const { return mBarAbove.data(); } + QSharedPointer data() const { return mDataContainer; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void setWidth(double width); + void setWidthType(WidthType widthType); + void setBarsGroup(QCPBarsGroup *barsGroup); + void setBaseValue(double baseValue); + void setStackingGap(double pixels); + + // non-property methods: + void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(double key, double value); + void moveBelow(QCPBars *bars); + void moveAbove(QCPBars *bars); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + +protected: + // property members: + double mWidth; + WidthType mWidthType; + QCPBarsGroup *mBarsGroup; + double mBaseValue; + double mStackingGap; + QPointer mBarBelow, mBarAbove; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const; + QRectF getBarRect(double key, double value) const; + void getPixelWidth(double key, double &lower, double &upper) const; + double getStackedBaseValue(double key, bool positive) const; + static void connectBars(QCPBars* lower, QCPBars* upper); + + friend class QCustomPlot; + friend class QCPLegend; + friend class QCPBarsGroup; +}; +Q_DECLARE_METATYPE(QCPBars::WidthType) + +/* end of 'src/plottables/plottable-bars.h' */ + + +/* including file 'src/plottables/plottable-statisticalbox.h', size 7516 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPStatisticalBoxData +{ +public: + QCPStatisticalBoxData(); + QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector& outliers=QVector()); + + inline double sortKey() const { return key; } + inline static QCPStatisticalBoxData fromSortKey(double sortKey) { return QCPStatisticalBoxData(sortKey, 0, 0, 0, 0, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return median; } + + inline QCPRange valueRange() const + { + QCPRange result(minimum, maximum); + for (QVector::const_iterator it = outliers.constBegin(); it != outliers.constEnd(); ++it) + result.expand(*it); + return result; + } + + double key, minimum, lowerQuartile, median, upperQuartile, maximum; + QVector outliers; +}; +Q_DECLARE_TYPEINFO(QCPStatisticalBoxData, Q_MOVABLE_TYPE); + + +/*! \typedef QCPStatisticalBoxDataContainer + + Container for storing \ref QCPStatisticalBoxData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPStatisticalBox holds its data. For + details about the generic container, see the documentation of the class template \ref + QCPDataContainer. + + \see QCPStatisticalBoxData, QCPStatisticalBox::setData +*/ +typedef QCPDataContainer QCPStatisticalBoxDataContainer; + +class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) + Q_PROPERTY(QPen whiskerPen READ whiskerPen WRITE setWhiskerPen) + Q_PROPERTY(QPen whiskerBarPen READ whiskerBarPen WRITE setWhiskerBarPen) + Q_PROPERTY(bool whiskerAntialiased READ whiskerAntialiased WRITE setWhiskerAntialiased) + Q_PROPERTY(QPen medianPen READ medianPen WRITE setMedianPen) + Q_PROPERTY(QCPScatterStyle outlierStyle READ outlierStyle WRITE setOutlierStyle) + /// \endcond +public: + explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis); + + // getters: + QSharedPointer data() const { return mDataContainer; } + double width() const { return mWidth; } + double whiskerWidth() const { return mWhiskerWidth; } + QPen whiskerPen() const { return mWhiskerPen; } + QPen whiskerBarPen() const { return mWhiskerBarPen; } + bool whiskerAntialiased() const { return mWhiskerAntialiased; } + QPen medianPen() const { return mMedianPen; } + QCPScatterStyle outlierStyle() const { return mOutlierStyle; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); + void setWidth(double width); + void setWhiskerWidth(double width); + void setWhiskerPen(const QPen &pen); + void setWhiskerBarPen(const QPen &pen); + void setWhiskerAntialiased(bool enabled); + void setMedianPen(const QPen &pen); + void setOutlierStyle(const QCPScatterStyle &style); + + // non-property methods: + void addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); + void addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers=QVector()); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + double mWidth; + double mWhiskerWidth; + QPen mWhiskerPen, mWhiskerBarPen; + bool mWhiskerAntialiased; + QPen mMedianPen; + QCPScatterStyle mOutlierStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const; + + // non-virtual methods: + void getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const; + QRectF getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const; + QVector getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const; + QVector getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-statisticalbox.h' */ + + +/* including file 'src/plottables/plottable-colormap.h', size 7070 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPColorMapData +{ +public: + QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange); + ~QCPColorMapData(); + QCPColorMapData(const QCPColorMapData &other); + QCPColorMapData &operator=(const QCPColorMapData &other); + + // getters: + int keySize() const { return mKeySize; } + int valueSize() const { return mValueSize; } + QCPRange keyRange() const { return mKeyRange; } + QCPRange valueRange() const { return mValueRange; } + QCPRange dataBounds() const { return mDataBounds; } + double data(double key, double value); + double cell(int keyIndex, int valueIndex); + unsigned char alpha(int keyIndex, int valueIndex); + + // setters: + void setSize(int keySize, int valueSize); + void setKeySize(int keySize); + void setValueSize(int valueSize); + void setRange(const QCPRange &keyRange, const QCPRange &valueRange); + void setKeyRange(const QCPRange &keyRange); + void setValueRange(const QCPRange &valueRange); + void setData(double key, double value, double z); + void setCell(int keyIndex, int valueIndex, double z); + void setAlpha(int keyIndex, int valueIndex, unsigned char alpha); + + // non-property methods: + void recalculateDataBounds(); + void clear(); + void clearAlpha(); + void fill(double z); + void fillAlpha(unsigned char alpha); + bool isEmpty() const { return mIsEmpty; } + void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const; + void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const; + +protected: + // property members: + int mKeySize, mValueSize; + QCPRange mKeyRange, mValueRange; + bool mIsEmpty; + + // non-property members: + double *mData; + unsigned char *mAlpha; + QCPRange mDataBounds; + bool mDataModified; + + bool createAlpha(bool initializeOpaque=true); + + friend class QCPColorMap; +}; + + +class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate) + Q_PROPERTY(bool tightBoundary READ tightBoundary WRITE setTightBoundary) + Q_PROPERTY(QCPColorScale* colorScale READ colorScale WRITE setColorScale) + /// \endcond +public: + explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPColorMap(); + + // getters: + QCPColorMapData *data() const { return mMapData; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + bool interpolate() const { return mInterpolate; } + bool tightBoundary() const { return mTightBoundary; } + QCPColorGradient gradient() const { return mGradient; } + QCPColorScale *colorScale() const { return mColorScale.data(); } + + // setters: + void setData(QCPColorMapData *data, bool copy=false); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setInterpolate(bool enabled); + void setTightBoundary(bool enabled); + void setColorScale(QCPColorScale *colorScale); + + // non-property methods: + void rescaleDataRange(bool recalculateDataBounds=false); + Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18)); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +signals: + void dataRangeChanged(const QCPRange &newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(const QCPColorGradient &newGradient); + +protected: + // property members: + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorMapData *mMapData; + QCPColorGradient mGradient; + bool mInterpolate; + bool mTightBoundary; + QPointer mColorScale; + + // non-property members: + QImage mMapImage, mUndersampledMapImage; + QPixmap mLegendIcon; + bool mMapImageInvalidated; + + // introduced virtual methods: + virtual void updateMapImage(); + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-colormap.h' */ + + +/* including file 'src/plottables/plottable-financial.h', size 8622 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPFinancialData +{ +public: + QCPFinancialData(); + QCPFinancialData(double key, double open, double high, double low, double close); + + inline double sortKey() const { return key; } + inline static QCPFinancialData fromSortKey(double sortKey) { return QCPFinancialData(sortKey, 0, 0, 0, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return open; } + + inline QCPRange valueRange() const { return QCPRange(low, high); } // open and close must lie between low and high, so we don't need to check them + + double key, open, high, low, close; +}; +Q_DECLARE_TYPEINFO(QCPFinancialData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPFinancialDataContainer + + Container for storing \ref QCPFinancialData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPFinancial holds its data. For details + about the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPFinancialData, QCPFinancial::setData +*/ +typedef QCPDataContainer QCPFinancialDataContainer; + +class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle) + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) + Q_PROPERTY(bool twoColored READ twoColored WRITE setTwoColored) + Q_PROPERTY(QBrush brushPositive READ brushPositive WRITE setBrushPositive) + Q_PROPERTY(QBrush brushNegative READ brushNegative WRITE setBrushNegative) + Q_PROPERTY(QPen penPositive READ penPositive WRITE setPenPositive) + Q_PROPERTY(QPen penNegative READ penNegative WRITE setPenNegative) + /// \endcond +public: + /*! + Defines the ways the width of the financial bar can be specified. Thus it defines what the + number passed to \ref setWidth actually means. + + \see setWidthType, setWidth + */ + enum WidthType { wtAbsolute ///< width is in absolute pixels + ,wtAxisRectRatio ///< width is given by a fraction of the axis rect size + ,wtPlotCoords ///< width is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(WidthType) + + /*! + Defines the possible representations of OHLC data in the plot. + + \see setChartStyle + */ + enum ChartStyle { csOhlc ///< Open-High-Low-Close bar representation + ,csCandlestick ///< Candlestick representation + }; + Q_ENUMS(ChartStyle) + + explicit QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPFinancial(); + + // getters: + QSharedPointer data() const { return mDataContainer; } + ChartStyle chartStyle() const { return mChartStyle; } + double width() const { return mWidth; } + WidthType widthType() const { return mWidthType; } + bool twoColored() const { return mTwoColored; } + QBrush brushPositive() const { return mBrushPositive; } + QBrush brushNegative() const { return mBrushNegative; } + QPen penPositive() const { return mPenPositive; } + QPen penNegative() const { return mPenNegative; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); + void setChartStyle(ChartStyle style); + void setWidth(double width); + void setWidthType(WidthType widthType); + void setTwoColored(bool twoColored); + void setBrushPositive(const QBrush &brush); + void setBrushNegative(const QBrush &brush); + void setPenPositive(const QPen &pen); + void setPenNegative(const QPen &pen); + + // non-property methods: + void addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); + void addData(double key, double open, double high, double low, double close); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + + // static methods: + static QCPFinancialDataContainer timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset = 0); + +protected: + // property members: + ChartStyle mChartStyle; + double mWidth; + WidthType mWidthType; + bool mTwoColored; + QBrush mBrushPositive, mBrushNegative; + QPen mPenPositive, mPenNegative; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); + void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); + double getPixelWidth(double key, double keyPixel) const; + double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; + double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; + void getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const; + QRectF selectionHitBox(QCPFinancialDataContainer::const_iterator it) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPFinancial::ChartStyle) + +/* end of 'src/plottables/plottable-financial.h' */ + + +/* including file 'src/plottables/plottable-errorbar.h', size 7727 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPErrorBarsData +{ +public: + QCPErrorBarsData(); + explicit QCPErrorBarsData(double error); + QCPErrorBarsData(double errorMinus, double errorPlus); + + double errorMinus, errorPlus; +}; +Q_DECLARE_TYPEINFO(QCPErrorBarsData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPErrorBarsDataContainer + + Container for storing \ref QCPErrorBarsData points. It is a typedef for QVector<\ref + QCPErrorBarsData>. + + This is the container in which \ref QCPErrorBars holds its data. Unlike most other data + containers for plottables, it is not based on \ref QCPDataContainer. This is because the error + bars plottable is special in that it doesn't store its own key and value coordinate per error + bar. It adopts the key and value from the plottable to which the error bars shall be applied + (\ref QCPErrorBars::setDataPlottable). So the stored \ref QCPErrorBarsData doesn't need a + sortable key, but merely an index (as \c QVector provides), which maps one-to-one to the indices + of the other plottable's data. + + \see QCPErrorBarsData, QCPErrorBars::setData +*/ +typedef QVector QCPErrorBarsDataContainer; + +class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottableInterface1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QSharedPointer data READ data WRITE setData) + Q_PROPERTY(QCPAbstractPlottable* dataPlottable READ dataPlottable WRITE setDataPlottable) + Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType) + Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) + Q_PROPERTY(double symbolGap READ symbolGap WRITE setSymbolGap) + /// \endcond +public: + + /*! + Defines in which orientation the error bars shall appear. If your data needs both error + dimensions, create two \ref QCPErrorBars with different \ref ErrorType. + + \see setErrorType + */ + enum ErrorType { etKeyError ///< The errors are for the key dimension (bars appear parallel to the key axis) + ,etValueError ///< The errors are for the value dimension (bars appear parallel to the value axis) + }; + Q_ENUMS(ErrorType) + + explicit QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPErrorBars(); + // getters: + QSharedPointer data() const { return mDataContainer; } + QCPAbstractPlottable *dataPlottable() const { return mDataPlottable.data(); } + ErrorType errorType() const { return mErrorType; } + double whiskerWidth() const { return mWhiskerWidth; } + double symbolGap() const { return mSymbolGap; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &error); + void setData(const QVector &errorMinus, const QVector &errorPlus); + void setDataPlottable(QCPAbstractPlottable* plottable); + void setErrorType(ErrorType type); + void setWhiskerWidth(double pixels); + void setSymbolGap(double pixels); + + // non-property methods: + void addData(const QVector &error); + void addData(const QVector &errorMinus, const QVector &errorPlus); + void addData(double error); + void addData(double errorMinus, double errorPlus); + + // virtual methods of 1d plottable interface: + virtual int dataCount() const Q_DECL_OVERRIDE; + virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; + virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; + virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; + virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } + +protected: + // property members: + QSharedPointer mDataContainer; + QPointer mDataPlottable; + ErrorType mErrorType; + double mWhiskerWidth; + double mSymbolGap; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const; + void getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; + double pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const; + // helpers: + void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; + bool errorBarVisible(int index) const; + bool rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-errorbar.h' */ + + +/* including file 'src/items/item-straightline.h', size 3117 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + explicit QCPItemStraightLine(QCustomPlot *parentPlot); + virtual ~QCPItemStraightLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const point1; + QCPItemPosition * const point2; + +protected: + // property members: + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QLineF getRectClippedStraightLine(const QCPVector2D &point1, const QCPVector2D &vec, const QRect &rect) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-straightline.h' */ + + +/* including file 'src/items/item-line.h', size 3407 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + explicit QCPItemLine(QCustomPlot *parentPlot); + virtual ~QCPItemLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const start; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-line.h' */ + + +/* including file 'src/items/item-curve.h', size 3379 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + explicit QCPItemCurve(QCustomPlot *parentPlot); + virtual ~QCPItemCurve(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const start; + QCPItemPosition * const startDir; + QCPItemPosition * const endDir; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; +}; + +/* end of 'src/items/item-curve.h' */ + + +/* including file 'src/items/item-rect.h', size 3688 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + explicit QCPItemRect(QCustomPlot *parentPlot); + virtual ~QCPItemRect(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-rect.h' */ + + +/* including file 'src/items/item-text.h', size 5554 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemText : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(Qt::Alignment positionAlignment READ positionAlignment WRITE setPositionAlignment) + Q_PROPERTY(Qt::Alignment textAlignment READ textAlignment WRITE setTextAlignment) + Q_PROPERTY(double rotation READ rotation WRITE setRotation) + Q_PROPERTY(QMargins padding READ padding WRITE setPadding) + /// \endcond +public: + explicit QCPItemText(QCustomPlot *parentPlot); + virtual ~QCPItemText(); + + // getters: + QColor color() const { return mColor; } + QColor selectedColor() const { return mSelectedColor; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont font() const { return mFont; } + QFont selectedFont() const { return mSelectedFont; } + QString text() const { return mText; } + Qt::Alignment positionAlignment() const { return mPositionAlignment; } + Qt::Alignment textAlignment() const { return mTextAlignment; } + double rotation() const { return mRotation; } + QMargins padding() const { return mPadding; } + + // setters; + void setColor(const QColor &color); + void setSelectedColor(const QColor &color); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setFont(const QFont &font); + void setSelectedFont(const QFont &font); + void setText(const QString &text); + void setPositionAlignment(Qt::Alignment alignment); + void setTextAlignment(Qt::Alignment alignment); + void setRotation(double degrees); + void setPadding(const QMargins &padding); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const position; + QCPItemAnchor * const topLeft; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRight; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QColor mColor, mSelectedColor; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + QFont mFont, mSelectedFont; + QString mText; + Qt::Alignment mPositionAlignment; + Qt::Alignment mTextAlignment; + double mRotation; + QMargins mPadding; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const; + QFont mainFont() const; + QColor mainColor() const; + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-text.h' */ + + +/* including file 'src/items/item-ellipse.h', size 3868 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + explicit QCPItemEllipse(QCustomPlot *parentPlot); + virtual ~QCPItemEllipse(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const topLeftRim; + QCPItemAnchor * const top; + QCPItemAnchor * const topRightRim; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRightRim; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeftRim; + QCPItemAnchor * const left; + QCPItemAnchor * const center; + +protected: + enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-ellipse.h' */ + + +/* including file 'src/items/item-pixmap.h', size 4373 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) + Q_PROPERTY(bool scaled READ scaled WRITE setScaled) + Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode) + Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + explicit QCPItemPixmap(QCustomPlot *parentPlot); + virtual ~QCPItemPixmap(); + + // getters: + QPixmap pixmap() const { return mPixmap; } + bool scaled() const { return mScaled; } + Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; } + Qt::TransformationMode transformationMode() const { return mTransformationMode; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPixmap(const QPixmap &pixmap); + void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPixmap mPixmap; + QPixmap mScaledPixmap; + bool mScaled; + bool mScaledPixmapInvalidated; + Qt::AspectRatioMode mAspectRatioMode; + Qt::TransformationMode mTransformationMode; + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false); + QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-pixmap.h' */ + + +/* including file 'src/items/item-tracer.h', size 4762 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(double size READ size WRITE setSize) + Q_PROPERTY(TracerStyle style READ style WRITE setStyle) + Q_PROPERTY(QCPGraph* graph READ graph WRITE setGraph) + Q_PROPERTY(double graphKey READ graphKey WRITE setGraphKey) + Q_PROPERTY(bool interpolating READ interpolating WRITE setInterpolating) + /// \endcond +public: + /*! + The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize. + + \see setStyle + */ + enum TracerStyle { tsNone ///< The tracer is not visible + ,tsPlus ///< A plus shaped crosshair with limited size + ,tsCrosshair ///< A plus shaped crosshair which spans the complete axis rect + ,tsCircle ///< A circle + ,tsSquare ///< A square + }; + Q_ENUMS(TracerStyle) + + explicit QCPItemTracer(QCustomPlot *parentPlot); + QCPItemTracer(QCustomPlot *parentPlot, qint64 timeStamp, int type, QPen pen, QBrush brush, const QList &alarmStatusList); + virtual ~QCPItemTracer(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + double size() const { return mSize; } + TracerStyle style() const { return mStyle; } + QCPGraph *graph() const { return mGraph; } + double graphKey() const { return mGraphKey; } + bool interpolating() const { return mInterpolating; } + int type() const { return mType; } + qint64 timeStamp() const { return mTimeStamp; } + QMap hidePoint() const { return m_hidePoint; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setSize(double size); + void setStyle(TracerStyle style); + void setGraph(QCPGraph *graph); + void setGraphKey(double key); + void setHidePoint(const QMultiMap &hidePoint); + void addHidePoint(const qint64 &time, const QString &tag); + void setInterpolating(bool enabled); + + void setType(const int &type); + void setTimeStamp(const qint64 &timeStamp); + void setInfo(const QStringList infos); + + void showTips(); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void updatePosition(); + + QCPItemPosition * const position; + +signals: + void itemTracerHoverd(const qint64 &time, const QMap& timeTag, const QList &alarmStatusList); + +protected: + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + double mSize; + TracerStyle mStyle; + QCPGraph *mGraph; + QMultiMap m_hidePoint; + double mGraphKey; + bool mInterpolating; + int mType; + qint64 mTimeStamp; + QStringList m_infos; + QList m_alarmStatusList; + int hovFlag; + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + + + virtual void mousePressEvent (QMouseEvent *event, const QVariant &details); + + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; +Q_DECLARE_METATYPE(QCPItemTracer::TracerStyle) + +/* end of 'src/items/item-tracer.h' */ + + +/* including file 'src/items/item-bracket.h', size 3969 */ +/* commit 9868e55d3b412f2f89766bb482fcf299e93a0988 2017-09-04 01:56:22 +0200 */ + +class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(double length READ length WRITE setLength) + Q_PROPERTY(BracketStyle style READ style WRITE setStyle) + /// \endcond +public: + /*! + Defines the various visual shapes of the bracket item. The appearance can be further modified + by \ref setLength and \ref setPen. + + \see setStyle + */ + enum BracketStyle { bsSquare ///< A brace with angled edges + ,bsRound ///< A brace with round edges + ,bsCurly ///< A curly brace + ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression + }; + Q_ENUMS(BracketStyle) + + explicit QCPItemBracket(QCustomPlot *parentPlot); + virtual ~QCPItemBracket(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + double length() const { return mLength; } + BracketStyle style() const { return mStyle; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setLength(double length); + void setStyle(BracketStyle style); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const left; + QCPItemPosition * const right; + QCPItemAnchor * const center; + +protected: + // property members: + enum AnchorIndex {aiCenter}; + QPen mPen, mSelectedPen; + double mLength; + BracketStyle mStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; +}; +Q_DECLARE_METATYPE(QCPItemBracket::BracketStyle) + +/* end of 'src/items/item-bracket.h' */ + + +#endif // QCUSTOMPLOT_H + diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CCalendarWidget.cpp b/product/src/gui/plugin/TrendCurves_pad/widgets/CCalendarWidget.cpp new file mode 100644 index 00000000..84f59f65 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CCalendarWidget.cpp @@ -0,0 +1,41 @@ +#include "CCalendarWidget.h" +#include + +CCalendarWidget::CCalendarWidget(QWidget *parent) + : QCalendarWidget(parent) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + setAttribute(Qt::WA_DeleteOnClose); + setHorizontalHeaderFormat(NoHorizontalHeader); + setVerticalHeaderFormat(NoVerticalHeader); + + setMinimumDate(QDate(1970, 0, 0)); + setMaximumDate(QDate(2037, 12, 31)); + + installEventFilter(this); + +} + +CCalendarWidget::~CCalendarWidget() +{ +} + +QSize CCalendarWidget::sizeHint() const +{ + return QSize(260, 180); +} + + +bool CCalendarWidget::eventFilter(QObject *object, QEvent *event) +{ + if (object == this) + { + if (QEvent::WindowDeactivate == event->type()) + { + this->close(); + event->accept(); + return true; + } + } + return QWidget::eventFilter(object, event); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CCalendarWidget.h b/product/src/gui/plugin/TrendCurves_pad/widgets/CCalendarWidget.h new file mode 100644 index 00000000..aa30d8a2 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CCalendarWidget.h @@ -0,0 +1,19 @@ +#ifndef CCALENDARWIDGET_H +#define CCALENDARWIDGET_H + +#include + +class CCalendarWidget : public QCalendarWidget +{ + Q_OBJECT +public: + CCalendarWidget(QWidget *parent = Q_NULLPTR); + ~CCalendarWidget(); + +protected: + QSize sizeHint() const; + + bool eventFilter(QObject *object, QEvent *event); +}; + +#endif // CCALENDARWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CEditCollectWidget.cpp b/product/src/gui/plugin/TrendCurves_pad/widgets/CEditCollectWidget.cpp new file mode 100644 index 00000000..e6c02728 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CEditCollectWidget.cpp @@ -0,0 +1,76 @@ +#include "CEditCollectWidget.h" +#include +#include +#include +#include +#include +#include + +CEditCollectWidget::CEditCollectWidget(QWidget *parent) : + QDialog(parent) +{ +// installEventFilter(this); +// setAttribute(Qt::WA_DeleteOnClose); + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + + QHBoxLayout * pTopLayout = new QHBoxLayout(); + QLabel * label = new QLabel(tr("趋势名称:"), this); + m_pNameEdit = new QLineEdit(this); + m_pNameEdit->setMinimumHeight(25); + pTopLayout->addWidget(label, 0); + pTopLayout->addWidget(m_pNameEdit, 10); + pTopLayout->setMargin(0); + QHBoxLayout * pBottomLayout = new QHBoxLayout(); + QPushButton * ok = new QPushButton(tr("确定"), this); + QPushButton * cancle = new QPushButton(tr("取消"), this); + pBottomLayout->addStretch(10); + pBottomLayout->addWidget(ok, 1); + pBottomLayout->addWidget(cancle, 1); + pBottomLayout->setMargin(0); + QVBoxLayout * layout = new QVBoxLayout(this); + layout->addLayout(pTopLayout, 1); + layout->addLayout(pBottomLayout, 1); + setLayout(layout); + layout->setMargin(0); + setContentsMargins(5,0,5,0); + setMaximumHeight(75); + + connect(ok, &QPushButton::clicked, this, [=]() { + emit acceptedInput(); + }); + connect(cancle, &QPushButton::clicked, this, [=]() { hide(); }); +} + +CEditCollectWidget::~CEditCollectWidget() +{ + +} + +void CEditCollectWidget::clear() +{ + m_pNameEdit->clear(); +} + +QString CEditCollectWidget::text() +{ + return m_pNameEdit->text(); +} + +void CEditCollectWidget::setEditFocus() +{ + m_pNameEdit->setFocus(); +} + +//bool CEditCollectWidget::eventFilter(QObject *object, QEvent *event) +//{ +// if (object == this) +// { +// if (QEvent::WindowDeactivate == event->type()) +// { +// this->hide(); +// event->accept(); +// return true; +// } +// } +// return QDialog::eventFilter(object, event); +//} diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CEditCollectWidget.h b/product/src/gui/plugin/TrendCurves_pad/widgets/CEditCollectWidget.h new file mode 100644 index 00000000..35b5f0c1 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CEditCollectWidget.h @@ -0,0 +1,30 @@ +#ifndef CEDITCOLLECTWIDGET_H +#define CEDITCOLLECTWIDGET_H + +#include + +class QLineEdit; +class CEditCollectWidget : public QDialog +{ + Q_OBJECT +public: + explicit CEditCollectWidget(QWidget *parent = 0); + ~CEditCollectWidget(); + + void clear(); + + QString text(); + + void setEditFocus(); + +signals: + void acceptedInput(); + +//protected: +// bool eventFilter(QObject *object, QEvent *event); + +private: + QLineEdit * m_pNameEdit; +}; + +#endif // CEDITCOLLECTWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CMyCheckBox.cpp b/product/src/gui/plugin/TrendCurves_pad/widgets/CMyCheckBox.cpp new file mode 100644 index 00000000..2b37e36c --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CMyCheckBox.cpp @@ -0,0 +1,21 @@ +#include "CMyCheckBox.h" +#include + +CMyCheckBox::CMyCheckBox(QString text, QWidget *parent) + :QCheckBox(text,parent) +{ + +} + +CMyCheckBox::CMyCheckBox(QWidget *parent) + :QCheckBox(parent) +{ + +} + +void CMyCheckBox::mouseReleaseEvent(QMouseEvent *e) +{ + Q_UNUSED(e) + setChecked(!isChecked()); + emit clicked(isChecked()); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CMyCheckBox.h b/product/src/gui/plugin/TrendCurves_pad/widgets/CMyCheckBox.h new file mode 100644 index 00000000..1dad82e3 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CMyCheckBox.h @@ -0,0 +1,16 @@ +#ifndef MYCHECKBOX_H +#define MYCHECKBOX_H + +#include + +class CMyCheckBox : public QCheckBox +{ +public: + CMyCheckBox(QString text,QWidget *parent = Q_NULLPTR); + CMyCheckBox(QWidget *parent = Q_NULLPTR); + +protected: + void mouseReleaseEvent(QMouseEvent *e); +}; + +#endif // MYCHECKBOX_H diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CMyListWidget.cpp b/product/src/gui/plugin/TrendCurves_pad/widgets/CMyListWidget.cpp new file mode 100644 index 00000000..fa73a493 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CMyListWidget.cpp @@ -0,0 +1,12 @@ +#include "CMyListWidget.h" + +CMyListWidget::CMyListWidget(QWidget *parent):QListWidget(parent) +{ + +} + +void CMyListWidget::showEvent(QShowEvent *event) +{ + this->updateGeometries(); + QListWidget::showEvent(event); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CMyListWidget.h b/product/src/gui/plugin/TrendCurves_pad/widgets/CMyListWidget.h new file mode 100644 index 00000000..728f308d --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CMyListWidget.h @@ -0,0 +1,15 @@ +#ifndef CMYLISTWIDGET_H +#define CMYLISTWIDGET_H + +#include + +class CMyListWidget : public QListWidget +{ +public: + explicit CMyListWidget(QWidget *parent = 0); + +protected: + void showEvent(QShowEvent *event); +}; + +#endif // CMYLISTWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CSWitchButton.cpp b/product/src/gui/plugin/TrendCurves_pad/widgets/CSWitchButton.cpp new file mode 100644 index 00000000..af418f62 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CSWitchButton.cpp @@ -0,0 +1,225 @@ +#include +#include +#include +#include "CSWitchButton.h" + +CSWitchButton::CSWitchButton(QWidget *parent) + : QWidget(parent), + m_bChecked(false), + m_background(Qt::green), + m_checkedColor(Qt::red), + m_disabledColor(Qt::darkGray), + m_handleColor(Qt::white), + m_textColor(Qt::blue), + m_radius(5.0), + m_borderColor(Qt::gray), + m_nHeight(12), + m_nMargin(0) +{ + setCursor(Qt::PointingHandCursor); + + connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); +} + +// 绘制开关 +void CSWitchButton::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + + QPainter painter(this); + painter.setPen(m_borderColor); + painter.setRenderHint(QPainter::Antialiasing); + + QPainterPath path; + QColor background; + QColor handleColor; + QString text; + QString unSelectText; + if (isEnabled()) { // 可用状态 + if (m_bChecked) { // 打开状态 + background = m_checkedColor; + handleColor = m_handleColor; + text = m_strText; + unSelectText=m_strCheckText; + } else { //关闭状态 + background = m_background; + handleColor = m_handleColor; + text = m_strCheckText; + unSelectText=m_strText; + } + } else { // 不可用状态 + background = m_disabledColor; + handleColor = m_disabledColor; + } + // 绘制边界 + painter.setBrush(background); + + path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width(), height()), m_radius, m_radius); + painter.drawPath(path.simplified()); + + // 绘制滑块 + painter.setBrush(handleColor); + painter.drawRoundedRect(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), width()/2, height()), m_radius, m_radius); + painter.setPen(m_textColor); + painter.drawText(QRectF(width()/2 - m_nX + (m_nHeight / 2), height()/5, width()/2, height()), text); + painter.drawText(QRectF(m_nX, height()/5, width()/2, height()), unSelectText); +} + +// 鼠标按下事件 +void CSWitchButton::mousePressEvent(QMouseEvent *event) +{ + if (isEnabled()) { + if (event->buttons() & Qt::LeftButton) { + event->accept(); + } else { + event->ignore(); + } + } +} + +// 鼠标释放事件 - 切换开关状态、发射toggled()信号 +void CSWitchButton::mouseReleaseEvent(QMouseEvent *event) +{ + if (isEnabled()) { + if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) { + event->accept(); + m_timer.start(10); + m_bChecked = !m_bChecked; + emit toggled(m_bChecked); + } else { + event->ignore(); + } + } +} + +// 大小改变事件 +void CSWitchButton::resizeEvent(QResizeEvent *event) +{ + m_nX = m_nHeight / 2; + m_nY = m_nHeight / 2; + QWidget::resizeEvent(event); +} + +// 默认大小 +QSize CSWitchButton::sizeHint() const +{ + return minimumSizeHint(); +} + +// 最小大小 +QSize CSWitchButton::minimumSizeHint() const +{ + return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin); +} + +// 切换状态 - 滑动 +void CSWitchButton::onTimeout() +{ + if (m_bChecked) { + m_nX += 3; + if (m_nX >= width()/2 + m_nHeight / 2) + { + m_nX = width()/2 + m_nHeight / 2; + m_timer.stop(); + } + } else { + m_nX -= 3; + if (m_nX <= m_nHeight / 2) + { + m_nX = m_nHeight / 2; + m_timer.stop(); + } + } + update(); +} + +bool CSWitchButton::isToggled() +{ + return m_bChecked; +} + +void CSWitchButton::setToggle(bool checked) +{ + m_bChecked = checked; +} + +void CSWitchButton::setText(QString text) +{ + m_strText = text; +} + +void CSWitchButton::setCheckedText(QString text) +{ + m_strCheckText = text; +} + +QColor CSWitchButton::backgroundColor() +{ + return m_background; +} + +void CSWitchButton::setBackgroundColor(QColor color) +{ + m_background = color; +} + +QColor CSWitchButton::checkedColor() +{ + return m_checkedColor; +} + +void CSWitchButton::setCheckedColor(QColor color) +{ + m_checkedColor = color; +} + +QColor CSWitchButton::disableColor() +{ + return m_disabledColor; +} + +void CSWitchButton::setDisableColor(QColor color) +{ + m_disabledColor = color; +} + +QColor CSWitchButton::handleColor() +{ + return m_handleColor; +} + +void CSWitchButton::setHandleColor(QColor color) +{ + m_handleColor = color; +} + +QColor CSWitchButton::textColor() +{ + return m_textColor; +} + +void CSWitchButton::setTextColor(QColor color) +{ + m_textColor = color; +} + +qreal CSWitchButton::radius() +{ + return m_radius; +} + +void CSWitchButton::setRadius(qreal radius) +{ + m_radius = radius; +} + +QColor CSWitchButton::borderColor() +{ + return m_borderColor; +} + +void CSWitchButton::setBorderColor(QColor color) +{ + m_borderColor = color; +} + diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CSWitchButton.h b/product/src/gui/plugin/TrendCurves_pad/widgets/CSWitchButton.h new file mode 100644 index 00000000..80f188f2 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CSWitchButton.h @@ -0,0 +1,92 @@ +#ifndef SWITCHBUTTON_H +#define SWITCHBUTTON_H + +#include +#include + +class CSWitchButton : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) + Q_PROPERTY(QColor checkedColor READ checkedColor WRITE setCheckedColor) + Q_PROPERTY(QColor disableColor READ disableColor WRITE setDisableColor) + Q_PROPERTY(QColor handleColor READ handleColor WRITE setHandleColor) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(qreal radius READ radius WRITE setRadius) + Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) + +public: + explicit CSWitchButton(QWidget *parent = 0); + + bool isToggled(); + + void setToggle(bool checked); + + void setText(QString text); + + void setCheckedText(QString text); + + QColor backgroundColor(); + void setBackgroundColor(QColor color); + + QColor checkedColor(); + void setCheckedColor(QColor color); + + QColor disableColor(); + void setDisableColor(QColor color); + + QColor handleColor(); + void setHandleColor(QColor color); + + QColor textColor(); + void setTextColor(QColor color); + + qreal radius(); + void setRadius(qreal radius); + + QColor borderColor(); + void setBorderColor(QColor color); + +protected: + // 绘制开关 + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + // 鼠标按下事件 + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + + // 鼠标释放事件 - 切换开关状态、发射toggled()信号 + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + + // 大小改变事件 + void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + + // 缺省大小 + QSize sizeHint() const Q_DECL_OVERRIDE; + QSize minimumSizeHint() const Q_DECL_OVERRIDE; + +signals: + void toggled(bool checked); + +private slots: + // 状态切换时,用于产生滑动效果 + void onTimeout(); + +private: + bool m_bChecked; + QColor m_background; + QColor m_checkedColor; + QColor m_disabledColor; + QColor m_handleColor; + QColor m_textColor; + qreal m_radius; + QColor m_borderColor; + QString m_strText; + QString m_strCheckText; + qreal m_nX{}; + qreal m_nY{}; + qint16 m_nHeight; + qint16 m_nMargin; + QTimer m_timer; +}; + +#endif // SWITCHBUTTON_H diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CSliderRangeWidget.cpp b/product/src/gui/plugin/TrendCurves_pad/widgets/CSliderRangeWidget.cpp new file mode 100644 index 00000000..cc2ca2e0 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CSliderRangeWidget.cpp @@ -0,0 +1,72 @@ +#include "CSliderRangeWidget.h" +#include +#include +#include +#include +#include + +CSliderRangeWidget::CSliderRangeWidget(QWidget *parent) : + QDialog(parent) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + + QGridLayout * pTopLayout = new QGridLayout(); + QLabel * label1 = new QLabel(tr("最小值:"), this); + m_lowSpin = new QSpinBox(this); + QLabel * label2 = new QLabel(tr("最大值:"), this); + m_upSpin = new QSpinBox(this); + QPushButton * ok = new QPushButton(tr("确定"), this); + QPushButton * cancle = new QPushButton(tr("取消"), this); + pTopLayout->addWidget(label1, 0, 0, 1, 1); + pTopLayout->addWidget(m_lowSpin, 0, 1, 1, 1); + pTopLayout->addWidget(label2, 1, 0, 1, 1); + pTopLayout->addWidget(m_upSpin, 1, 1, 1, 1); + pTopLayout->addWidget(ok, 2, 0, 1, 1); + pTopLayout->addWidget(cancle, 2, 1, 1, 1); + pTopLayout->setMargin(0); + setLayout(pTopLayout); + setContentsMargins(5,3,5,3); + + connect(ok, &QPushButton::clicked, this, [=]() { + emit acceptedInput(); + }); + connect(cancle, &QPushButton::clicked, this, [=]() { hide(); }); +} + +CSliderRangeWidget::~CSliderRangeWidget() +{ + +} + +void CSliderRangeWidget::setLowValue(int value) +{ + m_lowSpin->setValue(value); +} + +void CSliderRangeWidget::setUpValue(int value) +{ + m_upSpin->setValue(value); +} + +void CSliderRangeWidget::setSpinRange(int lower, int upper) +{ + m_lowSpin->setMinimum(lower); + m_lowSpin->setMaximum(upper); + m_upSpin->setMinimum(lower); + m_upSpin->setMaximum(upper); +} + +int CSliderRangeWidget::lowValue() +{ + return m_lowSpin->value(); +} + +int CSliderRangeWidget::upValue() +{ + return m_upSpin->value(); +} + +void CSliderRangeWidget::setEditFocus() +{ + m_lowSpin->setFocus(); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CSliderRangeWidget.h b/product/src/gui/plugin/TrendCurves_pad/widgets/CSliderRangeWidget.h new file mode 100644 index 00000000..e851dea1 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CSliderRangeWidget.h @@ -0,0 +1,34 @@ +#ifndef CSLIDERRANGEWIDGET_H +#define CSLIDERRANGEWIDGET_H + +#include + +class QSpinBox; +class CSliderRangeWidget : public QDialog +{ + Q_OBJECT +public: + explicit CSliderRangeWidget(QWidget *parent = 0); + ~CSliderRangeWidget(); + + void setLowValue(int value); + + void setUpValue(int value); + + void setSpinRange(int lower, int upper); + + int lowValue(); + + int upValue(); + + void setEditFocus(); + +signals: + void acceptedInput(); + +private: + QSpinBox * m_lowSpin; + QSpinBox * m_upSpin; +}; + +#endif // CSLIDERRANGEWIDGET_H diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CTabButton.cpp b/product/src/gui/plugin/TrendCurves_pad/widgets/CTabButton.cpp new file mode 100644 index 00000000..f6e1e452 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CTabButton.cpp @@ -0,0 +1,428 @@ +#include "CTabButton.h" +#include +#include "CCalendarWidget.h" + +CTabButton::CTabButton(QWidget *parent) + : QPushButton(parent), + m_isShowCalendarEnable(false) +{ + paddingLeft = 5; + paddingRight = 5; + paddingTop = 5; + paddingBottom = 5; + textAlign = TextAlign_Center; + + showLine = true; + lineSpace = 0; + lineWidth = 6; + linePosition = LinePosition_Bottom; + lineColor = QColor(24, 144, 255); + + normalBgColor = QColor(0, 38, 75); + hoverBgColor = QColor(2, 49, 93); + checkBgColor = QColor(2, 49, 93); + normalTextColor = QColor(182, 194, 205); + hoverTextColor = QColor(255, 255, 255); + checkTextColor = QColor(20, 130, 231); + + normalBgBrush = Qt::NoBrush; + hoverBgBrush = Qt::NoBrush; + checkBgBrush = Qt::NoBrush; + + font = QFont("Microsoft YaHei"); + font.setPointSize(12); + hover = false; + setCheckable(true); +} + +void CTabButton::setShowCalendarEnable(const bool &enable) +{ + m_isShowCalendarEnable = enable; +} + + +int CTabButton::getPaddingLeft() const +{ + return this->paddingLeft; +} + +int CTabButton::getPaddingRight() const +{ + return this->paddingRight; +} + +int CTabButton::getPaddingTop() const +{ + return this->paddingTop; +} + +int CTabButton::getPaddingBottom() const +{ + return this->paddingBottom; +} + +CTabButton::TextAlign CTabButton::getTextAlign() const +{ + return this->textAlign; +} + +QColor CTabButton::getNormalBgColor() const +{ + return this->normalBgColor; +} + +QColor CTabButton::getHoverBgColor() const +{ + return this->hoverBgColor; +} + +QColor CTabButton::getCheckBgColor() const +{ + return this->checkBgColor; +} + +QColor CTabButton::getNormalTextColor() const +{ + return this->normalTextColor; +} + +QColor CTabButton::getHoverTextColor() const +{ + return this->hoverTextColor; +} + +QColor CTabButton::getCheckTextColor() const +{ + return this->checkTextColor; +} + +QFont CTabButton::getFont() const +{ + return this->font; +} + + +void CTabButton::setPaddingLeft(int paddingLeft) +{ + if (this->paddingLeft != paddingLeft) { + this->paddingLeft = paddingLeft; + update(); + } +} + +void CTabButton::setPaddingRight(int paddingRight) +{ + if (this->paddingRight != paddingRight) { + this->paddingRight = paddingRight; + update(); + } +} + +void CTabButton::setPaddingTop(int paddingTop) +{ + if (this->paddingTop != paddingTop) { + this->paddingTop = paddingTop; + update(); + } +} + +void CTabButton::setPaddingBottom(int paddingBottom) +{ + if (this->paddingBottom != paddingBottom) { + this->paddingBottom = paddingBottom; + update(); + } +} + +void CTabButton::setPadding(int padding) +{ + setPadding(padding, padding, padding, padding); +} + +void CTabButton::setPadding(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom) +{ + this->paddingLeft = paddingLeft; + this->paddingRight = paddingRight; + this->paddingTop = paddingTop; + this->paddingBottom = paddingBottom; + update(); +} + +void CTabButton::setTextAlign(const CTabButton::TextAlign &textAlign) +{ + if (this->textAlign != textAlign) { + this->textAlign = textAlign; + update(); + } +} + +void CTabButton::setShowLine(bool showLine) +{ + if (this->showLine != showLine) { + this->showLine = showLine; + update(); + } +} + +void CTabButton::setLineSpace(int lineSpace) +{ + if (this->lineSpace != lineSpace) { + this->lineSpace = lineSpace; + update(); + } +} + +void CTabButton::setLineWidth(int lineWidth) +{ + if (this->lineWidth != lineWidth) { + this->lineWidth = lineWidth; + update(); + } +} + +void CTabButton::setLinePosition(const CTabButton::LinePosition &linePosition) +{ + if (this->linePosition != linePosition) { + this->linePosition = linePosition; + update(); + } +} + +void CTabButton::setLineColor(const QColor &lineColor) +{ + if (this->lineColor != lineColor) { + this->lineColor = lineColor; + update(); + } +} + +void CTabButton::setNormalBgColor(const QColor &normalBgColor) +{ + if (this->normalBgColor != normalBgColor) { + this->normalBgColor = normalBgColor; + update(); + } +} + +void CTabButton::setHoverBgColor(const QColor &hoverBgColor) +{ + if (this->hoverBgColor != hoverBgColor) { + this->hoverBgColor = hoverBgColor; + update(); + } +} + +void CTabButton::setCheckBgColor(const QColor &checkBgColor) +{ + if (this->checkBgColor != checkBgColor) { + this->checkBgColor = checkBgColor; + update(); + } +} + +void CTabButton::setNormalTextColor(const QColor &normalTextColor) +{ + if (this->normalTextColor != normalTextColor) { + this->normalTextColor = normalTextColor; + update(); + } +} + +void CTabButton::setHoverTextColor(const QColor &hoverTextColor) +{ + if (this->hoverTextColor != hoverTextColor) { + this->hoverTextColor = hoverTextColor; + update(); + } +} + +void CTabButton::setCheckTextColor(const QColor &checkTextColor) +{ + if (this->checkTextColor != checkTextColor) { + this->checkTextColor = checkTextColor; + update(); + } +} + +void CTabButton::setNormalBgBrush(const QBrush &normalBgBrush) +{ + if (this->normalBgBrush != normalBgBrush) { + this->normalBgBrush = normalBgBrush; + update(); + } +} + +void CTabButton::setHoverBgBrush(const QBrush &hoverBgBrush) +{ + if (this->hoverBgBrush != hoverBgBrush) { + this->hoverBgBrush = hoverBgBrush; + update(); + } +} + +void CTabButton::setCheckBgBrush(const QBrush &checkBgBrush) +{ + if (this->checkBgBrush != checkBgBrush) { + this->checkBgBrush = checkBgBrush; + update(); + } +} + +void CTabButton::setFont(const QFont &font) +{ + this->font = font; +} + + +void CTabButton::enterEvent(QEvent *) +{ + hover = true; + update(); +} + +void CTabButton::leaveEvent(QEvent *) +{ + hover = false; + update(); +} + +void CTabButton::paintEvent(QPaintEvent *e) +{ + QPushButton::paintEvent(e); +// //绘制准备工作,启用反锯齿 +// QPainter painter(this); +// painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + +// //绘制背景 +// drawBg(&painter); +// //绘制文字 +// drawText(&painter); +// //绘制边框线条 +// drawLine(&painter); +} + +void CTabButton::drawBg(QPainter *painter) +{ + painter->save(); + painter->setPen(Qt::NoPen); + + int width = this->width(); + int height = this->height(); + + QRect bgRect; + if (linePosition == LinePosition_Left) { + bgRect = QRect(lineSpace, 0, width - lineSpace, height); + } else if (linePosition == LinePosition_Right) { + bgRect = QRect(0, 0, width - lineSpace, height); + } else if (linePosition == LinePosition_Top) { + bgRect = QRect(0, lineSpace, width, height - lineSpace); + } else if (linePosition == LinePosition_Bottom) { + bgRect = QRect(0, 0, width, height - lineSpace); + } + + //如果画刷存在则取画刷 + QBrush bgBrush; + if (isChecked()) { + bgBrush = checkBgBrush; + } else if (hover) { + bgBrush = hoverBgBrush; + } else { + bgBrush = normalBgBrush; + } + + if (bgBrush != Qt::NoBrush) { + painter->setBrush(bgBrush); + } else { + //根据当前状态选择对应颜色 + QColor bgColor; + if (isChecked()) { + bgColor = checkBgColor; + } else if (hover) { + bgColor = hoverBgColor; + } else { + bgColor = normalBgColor; + } + + painter->setBrush(bgColor); + } + + painter->drawRect(bgRect); + + painter->restore(); +} + +void CTabButton::drawText(QPainter *painter) +{ + painter->save(); + painter->setBrush(Qt::NoBrush); + + //根据当前状态选择对应颜色 + QColor textColor; + if (isChecked()) { + textColor = checkTextColor; + } else if (hover) { + textColor = hoverTextColor; + } else { + textColor = normalTextColor; + } + + QRect textRect = QRect(paddingLeft, paddingTop, width() - paddingLeft - paddingRight, height() - paddingTop - paddingBottom); + painter->setPen(textColor); + painter->setFont(font); + painter->drawText(textRect, textAlign | Qt::AlignVCenter, text()); + + painter->restore(); +} + + +void CTabButton::drawLine(QPainter *painter) +{ + if (!showLine) { + return; + } + + if (!isChecked()) { + return; + } + + painter->save(); + + QPen pen; + pen.setWidth(lineWidth); + pen.setColor(lineColor); + painter->setPen(pen); + + //根据线条位置设置线条坐标 + QPoint pointStart, pointEnd; + if (linePosition == LinePosition_Left) { + pointStart = QPoint(0, 0); + pointEnd = QPoint(0, height()); + } else if (linePosition == LinePosition_Right) { + pointStart = QPoint(width(), 0); + pointEnd = QPoint(width(), height()); + } else if (linePosition == LinePosition_Top) { + pointStart = QPoint(0, 0); + pointEnd = QPoint(width(), 0); + } else if (linePosition == LinePosition_Bottom) { + pointStart = QPoint(0, height()); + pointEnd = QPoint(width(), height()); + } + + painter->drawLine(pointStart, pointEnd); + + painter->restore(); +} + +void CTabButton::contextMenuEvent(QContextMenuEvent *event) +{ + Q_UNUSED(event) + if(!m_isShowCalendarEnable) + { + return; + } + CCalendarWidget * calendar = new CCalendarWidget(this); + calendar->setSelectedDate(QDate::currentDate()); + connect(calendar, &CCalendarWidget::clicked, this, &CTabButton::dataChanged); + calendar->show(); + calendar->move(parentWidget()->mapToGlobal(QPoint(width(), height() + 2))); +} diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CTabButton.h b/product/src/gui/plugin/TrendCurves_pad/widgets/CTabButton.h new file mode 100644 index 00000000..f43a01ea --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CTabButton.h @@ -0,0 +1,136 @@ +#ifndef CTABBUTTON_H +#define CTABBUTTON_H + +#include +#include + +class CTabButton : public QPushButton +{ + Q_OBJECT + +public: + enum TextAlign { + TextAlign_Left = 0x0001, //左侧对齐 + TextAlign_Right = 0x0002, //右侧对齐 + TextAlign_Top = 0x0020, //顶部对齐 + TextAlign_Bottom = 0x0040, //底部对齐 + TextAlign_Center = 0x0004 //居中对齐 + }; + + enum LinePosition { + LinePosition_Left = 0, //左侧 + LinePosition_Right = 1, //右侧 + LinePosition_Top = 2, //顶部 + LinePosition_Bottom = 3 //底部 + }; + + explicit CTabButton(QWidget *parent = Q_NULLPTR); + + void setShowCalendarEnable(const bool &enable); + + int getPaddingLeft() const; + int getPaddingRight() const; + int getPaddingTop() const; + int getPaddingBottom() const; + TextAlign getTextAlign() const; + + QColor getNormalBgColor() const; + QColor getHoverBgColor() const; + QColor getCheckBgColor() const; + QColor getNormalTextColor() const; + QColor getHoverTextColor() const; + QColor getCheckTextColor() const; + + QFont getFont() const; + +public slots: + //设置文字间隔 + void setPaddingLeft(int paddingLeft); + void setPaddingRight(int paddingRight); + void setPaddingTop(int paddingTop); + void setPaddingBottom(int paddingBottom); + void setPadding(int padding); + void setPadding(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom); + + //设置文字对齐 + void setTextAlign(const TextAlign &textAlign); + + //设置显示线条 + void setShowLine(bool showLine); + //设置线条间隔 + void setLineSpace(int lineSpace); + //设置线条宽度 + void setLineWidth(int lineWidth); + //设置线条位置 + void setLinePosition(const LinePosition &linePosition); + //设置线条颜色 + void setLineColor(const QColor &lineColor); + + //设置正常背景颜色 + void setNormalBgColor(const QColor &normalBgColor); + //设置悬停背景颜色 + void setHoverBgColor(const QColor &hoverBgColor); + //设置选中背景颜色 + void setCheckBgColor(const QColor &checkBgColor); + + //设置正常文字颜色 + void setNormalTextColor(const QColor &normalTextColor); + //设置悬停文字颜色 + void setHoverTextColor(const QColor &hoverTextColor); + //设置选中文字颜色 + void setCheckTextColor(const QColor &checkTextColor); + + //设置正常背景画刷 + void setNormalBgBrush(const QBrush &normalBgBrush); + //设置悬停背景画刷 + void setHoverBgBrush(const QBrush &hoverBgBrush); + //设置选中背景画刷 + void setCheckBgBrush(const QBrush &checkBgBrush); + + void setFont(const QFont &font); + +signals: + void dataChanged(const QDate &date); + +protected: + void enterEvent(QEvent *); + void leaveEvent(QEvent *); + void paintEvent(QPaintEvent *e); + void drawBg(QPainter *painter); + void drawText(QPainter *painter); + void drawLine(QPainter *painter); + + void contextMenuEvent(QContextMenuEvent *event); + +private: + int paddingLeft; //文字左侧间隔 + int paddingRight; //文字右侧间隔 + int paddingTop; //文字顶部间隔 + int paddingBottom; //文字底部间隔 + TextAlign textAlign; //文字对齐 + + bool showLine; //显示线条 + int lineSpace; //线条间隔 + int lineWidth; //线条宽度 + LinePosition linePosition; //线条位置 + QColor lineColor; //线条颜色 + + QColor normalBgColor; //正常背景颜色 + QColor hoverBgColor; //悬停背景颜色 + QColor checkBgColor; //选中背景颜色 + QColor normalTextColor; //正常文字颜色 + QColor hoverTextColor; //悬停文字颜色 + QColor checkTextColor; //选中文字颜色 + + QBrush normalBgBrush; //正常背景画刷 + QBrush hoverBgBrush; //悬停背景画刷 + QBrush checkBgBrush; //选中背景画刷 + + QFont font; + + bool hover; //悬停标志位 + + bool m_isShowCalendarEnable; +}; + +#endif // CTABBUTTON_H diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CToolTip.cpp b/product/src/gui/plugin/TrendCurves_pad/widgets/CToolTip.cpp new file mode 100644 index 00000000..ac07bd68 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CToolTip.cpp @@ -0,0 +1,139 @@ +#include "CToolTip.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CHisEventManage.h" + +CToolTip::CToolTip(QWidget *parent) + : QDialog(parent), + m_parent(parent) +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); + setAttribute(Qt::WA_DeleteOnClose); + setObjectName("ToolTip"); + label_ = new QLabel(this); + label_->setMouseTracking(true); + label_->installEventFilter(parent); + button_ = new QPushButton(tr("全部"),this); + button_->setObjectName("m_tipButton"); + QVBoxLayout *mVLayout = new QVBoxLayout(this); + QHBoxLayout *mHLayout = new QHBoxLayout(this); + mHLayout->addWidget(label_); + label_->setMargin(3); + mVLayout->addLayout(mHLayout); + mVLayout->addWidget(button_); + mHLayout->setMargin(0); + installEventFilter(this); + label_->setObjectName("m_tipLabel"); + connect(button_,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked())); +} + +CToolTip::~CToolTip() +{ + m_parent = nullptr; +} + +QString CToolTip::text() +{ + return label_->text(); +} + +void CToolTip::setText(const QString &text) +{ + label_->setText(text); +} + +bool CToolTip::eventFilter(QObject *object, QEvent *event) +{ + if (object == this) + { + if (QEvent::WindowDeactivate == event->type()) + { + this->close(); + event->accept(); + return true; + } + } + return QWidget::eventFilter(object, event); +} + +void CToolTip::on_pushButton_clicked() +{ + int rowCount = alarmList.size(); + alarmTable = new QTableView(m_parent); + model = new QStandardItemModel(); + model->setRowCount(rowCount); + alarmTable->setWindowTitle(tr("告警列表")); + QString alarmTime,alarmContent; + QStringList header; + header<setHorizontalHeaderLabels(header); + QHeaderView *rowHeader = alarmTable->verticalHeader(); + rowHeader->setHidden(true); + for(int i = 0;i < rowCount;i++) + { + QString tmp; + QStringList tmpList; + tmp = alarmList.at(i); + tmpList = tmp.split("\n"); + alarmTime = tmpList[0]; + alarmContent = tmpList[1]; + model->setItem(i,0,new QStandardItem(alarmTime)); + model->setItem(i,1,new QStandardItem(alarmContent)); + } + alarmTable->setModel(model); + alarmTable->resizeColumnsToContents(); + alarmTable->setObjectName("m_tipAlarmTable"); + alarmTable->resize(470,300); + alarmTable->setWindowFlags(alarmTable->windowFlags()&~(Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint)); + alarmTable->horizontalHeader()->setStretchLastSection(true); + alarmTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + alarmTable->setWindowFlag(Qt::WindowStaysOnTopHint); + alarmTable->setWindowFlag(Qt::Dialog); + alarmTable->setWindowModality(Qt::ApplicationModal); + alarmTable->setAttribute(Qt::WA_DeleteOnClose); + alarmTable->setSelectionBehavior(QAbstractItemView::SelectRows); + alarmTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + alarmTable->show(); +} + +void CToolTip::popup(QPoint pos, const QString &text, QWidget *parent) +{ + CToolTip * tip = new CToolTip(parent); + QString showTipText; + if(!tip->alarmList.isEmpty()) + { + tip->alarmList.clear(); + } + tip->alarmList = text.split("\n\n"); + if(tip->alarmList.size()>5) + { + for(int i = 0;i<5;i++) + { + showTipText += tip->alarmList.at(i); + showTipText += "\n\n"; + } + } + else { + showTipText = text; + tip->button_->setVisible(false); + } + tip->setText(showTipText); + tip->show(); + int screenWidth = QApplication::desktop()->screenGeometry().width(); + if((tip->width() + pos.x()) < screenWidth) + { + tip->move(pos.x(),pos.y()-tip->height()); + } + else + { + tip->move(pos.x() - tip->width(), pos.y()-tip->height()); + } +} diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/CToolTip.h b/product/src/gui/plugin/TrendCurves_pad/widgets/CToolTip.h new file mode 100644 index 00000000..e4e691a9 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/CToolTip.h @@ -0,0 +1,39 @@ +#ifndef CTOOLTIP_H +#define CTOOLTIP_H + +#include + +class QLabel; +class QTableView; +class QStandardItemModel; + +class CToolTip : public QDialog +{ + Q_OBJECT +public: + CToolTip(QWidget *parent = nullptr); + ~CToolTip(); + + QString text(); + void setText(const QString &text); + static void popup(QPoint pos, const QString &text, QWidget *parent = nullptr); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +signals: + void alarmListMsg(const QStringList &alarmTable); + +protected slots: + void on_pushButton_clicked(); + +private: + QLabel *label_; + QPushButton *button_; + QStringList alarmList; + QStandardItemModel *model; + QTableView *alarmTable; + QWidget *m_parent; +}; + +#endif // CTOOLTIP_H diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/QxtSpanSlider.cpp b/product/src/gui/plugin/TrendCurves_pad/widgets/QxtSpanSlider.cpp new file mode 100644 index 00000000..6a3cfe30 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/QxtSpanSlider.cpp @@ -0,0 +1,746 @@ +#include "QxtSpanSlider.h" +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** +*****************************************************************************/ + +#include "QxtSpanSlider_p.h" +#include +#include +#include +#include +#include +#include + +QxtSpanSliderPrivate::QxtSpanSliderPrivate() : + lower(0), + upper(0), + lowerPos(0), + upperPos(0), + offset(0), + position(0), + lastPressed(QxtSpanSlider::NoHandle), + mainControl(QxtSpanSlider::LowerHandle), + lowerPressed(QStyle::SC_None), + upperPressed(QStyle::SC_None), + movement(QxtSpanSlider::FreeMovement), + firstMovement(false), + blockTracking(false) +{ +} + +void QxtSpanSliderPrivate::initStyleOption(QStyleOptionSlider* option, QxtSpanSlider::SpanHandle handle) const +{ + const QxtSpanSlider* p = q_ptr; + p->initStyleOption(option); + option->sliderPosition = (handle == QxtSpanSlider::LowerHandle ? lowerPos : upperPos); + option->sliderValue = (handle == QxtSpanSlider::LowerHandle ? lower : upper); +} + +int QxtSpanSliderPrivate::pixelPosToRangeValue(int pos) const +{ + QStyleOptionSlider opt; + initStyleOption(&opt); + + int sliderMin = 0; + int sliderMax = 0; + int sliderLength = 0; + const QSlider* p = q_ptr; + const QRect gr = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, p); + const QRect sr = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, p); + if (p->orientation() == Qt::Horizontal) + { + sliderLength = sr.width(); + sliderMin = gr.x(); + sliderMax = gr.right() - sliderLength + 1; + } + else + { + sliderLength = sr.height(); + sliderMin = gr.y(); + sliderMax = gr.bottom() - sliderLength + 1; + } + return QStyle::sliderValueFromPosition(p->minimum(), p->maximum(), pos - sliderMin, + sliderMax - sliderMin, opt.upsideDown); +} + +void QxtSpanSliderPrivate::handleMousePress(const QPoint& pos, QStyle::SubControl& control, int value, QxtSpanSlider::SpanHandle handle) +{ + QStyleOptionSlider opt; + initStyleOption(&opt, handle); + QxtSpanSlider* p = q_ptr; + const QStyle::SubControl oldControl = control; + control = p->style()->hitTestComplexControl(QStyle::CC_Slider, &opt, pos, p); + const QRect sr = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, p); + if (control == QStyle::SC_SliderHandle) + { + position = value; + offset = pick(pos - sr.topLeft()); + lastPressed = handle; + p->setSliderDown(true); + emit p->sliderPressed(handle); + } + if (control != oldControl) + p->update(sr); +} + +void QxtSpanSliderPrivate::setupPainter(QPainter* painter, Qt::Orientation orientation, qreal x1, qreal y1, qreal x2, qreal y2) const +{ + QColor highlight = q_ptr->palette().color(QPalette::Highlight); + QLinearGradient gradient(x1, y1, x2, y2); + gradient.setColorAt(0, highlight.dark(120)); + gradient.setColorAt(1, highlight.light(108)); + painter->setBrush(gradient); + + if (orientation == Qt::Horizontal) + painter->setPen(QPen(highlight.dark(130), 0)); + else + painter->setPen(QPen(highlight.dark(150), 0)); +} + +void QxtSpanSliderPrivate::drawSpan(QStylePainter* painter, const QRect& rect) const +{ + QStyleOptionSlider opt; + initStyleOption(&opt); + const QSlider* p = q_ptr; + + // area + QRect groove = p->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, p); + if (opt.orientation == Qt::Horizontal) + groove.adjust(0, 0, -1, 0); + else + groove.adjust(0, 0, 0, -1); + + // pen & brush + painter->setPen(QPen(p->palette().color(QPalette::Dark).light(110), 0)); + if (opt.orientation == Qt::Horizontal) + setupPainter(painter, opt.orientation, groove.center().x(), groove.top(), groove.center().x(), groove.bottom()); + else + setupPainter(painter, opt.orientation, groove.left(), groove.center().y(), groove.right(), groove.center().y()); + + // draw groove + painter->drawRect(rect.intersected(groove)); +} + +void QxtSpanSliderPrivate::drawHandle(QStylePainter* painter, QxtSpanSlider::SpanHandle handle) const +{ + QStyleOptionSlider opt; + initStyleOption(&opt, handle); + opt.subControls = QStyle::SC_SliderHandle; + QStyle::SubControl pressed = (handle == QxtSpanSlider::LowerHandle ? lowerPressed : upperPressed); + if (pressed == QStyle::SC_SliderHandle) + { + opt.activeSubControls = pressed; + opt.state |= QStyle::State_Sunken; + } + painter->drawComplexControl(QStyle::CC_Slider, opt); +} + +void QxtSpanSliderPrivate::triggerAction(QAbstractSlider::SliderAction action, bool main) +{ + int value = 0; + bool no = false; + bool up = false; + const int min = q_ptr->minimum(); + const int max = q_ptr->maximum(); + const QxtSpanSlider::SpanHandle altControl = (mainControl == QxtSpanSlider::LowerHandle ? QxtSpanSlider::UpperHandle : QxtSpanSlider::LowerHandle); + + blockTracking = true; + + switch (action) + { + case QAbstractSlider::SliderSingleStepAdd: + if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) + { + value = qBound(min, upper + q_ptr->singleStep(), max); + up = true; + break; + } + value = qBound(min, lower + q_ptr->singleStep(), max); + break; + case QAbstractSlider::SliderSingleStepSub: + if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) + { + value = qBound(min, upper - q_ptr->singleStep(), max); + up = true; + break; + } + value = qBound(min, lower - q_ptr->singleStep(), max); + break; + case QAbstractSlider::SliderToMinimum: + value = min; + if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) + up = true; + break; + case QAbstractSlider::SliderToMaximum: + value = max; + if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) + up = true; + break; + case QAbstractSlider::SliderMove: + if ((main && mainControl == QxtSpanSlider::UpperHandle) || (!main && altControl == QxtSpanSlider::UpperHandle)) + up = true; + case QAbstractSlider::SliderNoAction: + no = true; + break; + default: + qWarning("QxtSpanSliderPrivate::triggerAction: Unknown action"); + break; + } + + if (!no && !up) + { + if (movement == QxtSpanSlider::NoCrossing) + value = qMin(value, upper); + else if (movement == QxtSpanSlider::NoOverlapping) + value = qMin(value, upper - 1); + + if (movement == QxtSpanSlider::FreeMovement && value > upper) + { + swapControls(); + q_ptr->setUpperPosition(value); + } + else + { + q_ptr->setLowerPosition(value); + } + } + else if (!no) + { + if (movement == QxtSpanSlider::NoCrossing) + value = qMax(value, lower); + else if (movement == QxtSpanSlider::NoOverlapping) + value = qMax(value, lower + 1); + + if (movement == QxtSpanSlider::FreeMovement && value < lower) + { + swapControls(); + q_ptr->setLowerPosition(value); + } + else + { + q_ptr->setUpperPosition(value); + } + } + + blockTracking = false; + q_ptr->setLowerValue(lowerPos); + q_ptr->setUpperValue(upperPos); +} + +void QxtSpanSliderPrivate::swapControls() +{ + qSwap(lower, upper); + qSwap(lowerPressed, upperPressed); + lastPressed = (lastPressed == QxtSpanSlider::LowerHandle ? QxtSpanSlider::UpperHandle : QxtSpanSlider::LowerHandle); + mainControl = (mainControl == QxtSpanSlider::LowerHandle ? QxtSpanSlider::UpperHandle : QxtSpanSlider::LowerHandle); +} + +void QxtSpanSliderPrivate::updateRange(int min, int max) +{ + Q_UNUSED(min); + Q_UNUSED(max); + // setSpan() takes care of keeping span in range + q_ptr->setSpan(lower, upper); +} + +void QxtSpanSliderPrivate::movePressedHandle() +{ + switch (lastPressed) + { + case QxtSpanSlider::LowerHandle: + if (lowerPos != lower) + { + bool main = (mainControl == QxtSpanSlider::LowerHandle); + triggerAction(QAbstractSlider::SliderMove, main); + } + break; + case QxtSpanSlider::UpperHandle: + if (upperPos != upper) + { + bool main = (mainControl == QxtSpanSlider::UpperHandle); + triggerAction(QAbstractSlider::SliderMove, main); + } + break; + default: + break; + } +} + +/*! + \class QxtSpanSlider + \inmodule QxtWidgets + \brief The QxtSpanSlider widget is a QSlider with two handles. + QxtSpanSlider is a slider with two handles. QxtSpanSlider is + handy for letting user to choose an span between min/max. + The span color is calculated based on QPalette::Highlight. + The keys are bound according to the following table: + \table + \header \o Orientation \o Key \o Handle + \row \o Qt::Horizontal \o Qt::Key_Left \o lower + \row \o Qt::Horizontal \o Qt::Key_Right \o lower + \row \o Qt::Horizontal \o Qt::Key_Up \o upper + \row \o Qt::Horizontal \o Qt::Key_Down \o upper + \row \o Qt::Vertical \o Qt::Key_Up \o lower + \row \o Qt::Vertical \o Qt::Key_Down \o lower + \row \o Qt::Vertical \o Qt::Key_Left \o upper + \row \o Qt::Vertical \o Qt::Key_Right \o upper + \endtable + Keys are bound by the time the slider is created. A key is bound + to same handle for the lifetime of the slider. So even if the handle + representation might change from lower to upper, the same key binding + remains. + \image qxtspanslider.png "QxtSpanSlider in Plastique style." + \bold {Note:} QxtSpanSlider inherits QSlider for implementation specific + reasons. Adjusting any single handle specific properties like + \list + \o QAbstractSlider::sliderPosition + \o QAbstractSlider::value + \endlist + has no effect. However, all slider specific properties like + \list + \o QAbstractSlider::invertedAppearance + \o QAbstractSlider::invertedControls + \o QAbstractSlider::minimum + \o QAbstractSlider::maximum + \o QAbstractSlider::orientation + \o QAbstractSlider::pageStep + \o QAbstractSlider::singleStep + \o QSlider::tickInterval + \o QSlider::tickPosition + \endlist + are taken into consideration. + */ + +/*! + \enum QxtSpanSlider::HandleMovementMode + This enum describes the available handle movement modes. + \value FreeMovement The handles can be moved freely. + \value NoCrossing The handles cannot cross, but they can still overlap each other. The lower and upper values can be the same. + \value NoOverlapping The handles cannot overlap each other. The lower and upper values cannot be the same. + */ + +/*! + \enum QxtSpanSlider::SpanHandle + This enum describes the available span handles. + \omitvalue NoHandle \omit Internal only (for now). \endomit + \value LowerHandle The lower boundary handle. + \value UpperHandle The upper boundary handle. + */ + +/*! + \fn QxtSpanSlider::lowerValueChanged(int lower) + This signal is emitted whenever the \a lower value has changed. + */ + +/*! + \fn QxtSpanSlider::upperValueChanged(int upper) + This signal is emitted whenever the \a upper value has changed. + */ + +/*! + \fn QxtSpanSlider::spanChanged(int lower, int upper) + This signal is emitted whenever both the \a lower and the \a upper + values have changed ie. the span has changed. + */ + +/*! + \fn QxtSpanSlider::lowerPositionChanged(int lower) + This signal is emitted whenever the \a lower position has changed. + */ + +/*! + \fn QxtSpanSlider::upperPositionChanged(int upper) + This signal is emitted whenever the \a upper position has changed. + */ + +/*! + \fn QxtSpanSlider::sliderPressed(SpanHandle handle) + This signal is emitted whenever the \a handle has been pressed. + */ + +/*! + Constructs a new QxtSpanSlider with \a parent. + */ +QxtSpanSlider::QxtSpanSlider(QWidget* parent) : QSlider(parent), d_ptr(new QxtSpanSliderPrivate()) +{ + d_ptr->q_ptr = this; + connect(this, SIGNAL(rangeChanged(int, int)), d_ptr, SLOT(updateRange(int, int))); + connect(this, SIGNAL(sliderReleased()), d_ptr, SLOT(movePressedHandle())); +} + +/*! + Constructs a new QxtSpanSlider with \a orientation and \a parent. + */ +QxtSpanSlider::QxtSpanSlider(Qt::Orientation orientation, QWidget* parent) : QSlider(orientation, parent), d_ptr(new QxtSpanSliderPrivate()) +{ + d_ptr->q_ptr = this; + connect(this, SIGNAL(rangeChanged(int, int)), d_ptr, SLOT(updateRange(int, int))); + connect(this, SIGNAL(sliderReleased()), d_ptr, SLOT(movePressedHandle())); +} + +/*! + Destructs the span slider. + */ +QxtSpanSlider::~QxtSpanSlider() +{ + if(d_ptr) + { + delete d_ptr; + } + d_ptr = NULL; +} + +/*! + \property QxtSpanSlider::handleMovementMode + \brief the handle movement mode + */ +QxtSpanSlider::HandleMovementMode QxtSpanSlider::handleMovementMode() const +{ + return d_ptr->movement; +} + +void QxtSpanSlider::setHandleMovementMode(QxtSpanSlider::HandleMovementMode mode) +{ + d_ptr->movement = mode; +} + +/*! + \property QxtSpanSlider::lowerValue + \brief the lower value of the span + */ +int QxtSpanSlider::lowerValue() const +{ + return qMin(d_ptr->lower, d_ptr->upper); +} + +void QxtSpanSlider::setLowerValue(int lower) +{ + setSpan(lower, d_ptr->upper); +} + +/*! + \property QxtSpanSlider::upperValue + \brief the upper value of the span + */ +int QxtSpanSlider::upperValue() const +{ + return qMax(d_ptr->lower, d_ptr->upper); +} + +void QxtSpanSlider::setUpperValue(int upper) +{ + setSpan(d_ptr->lower, upper); +} + +/*! + Sets the span from \a lower to \a upper. + */ +void QxtSpanSlider::setSpan(int lower, int upper) +{ + const int low = qBound(minimum(), lower, maximum()); + const int upp = qBound(minimum(), upper, maximum()); + if (low != d_ptr->lower || upp != d_ptr->upper) + { + if (low != d_ptr->lower) + { + d_ptr->lower = low; + d_ptr->lowerPos = low; + emit lowerValueChanged(low); + } + if (upp != d_ptr->upper) + { + d_ptr->upper = upp; + d_ptr->upperPos = upp; + emit upperValueChanged(upp); + } + emit spanChanged(d_ptr->lower, d_ptr->upper); + update(); + } +} + +/*! + \property QxtSpanSlider::lowerPosition + \brief the lower position of the span + */ +int QxtSpanSlider::lowerPosition() const +{ + return d_ptr->lowerPos; +} + +void QxtSpanSlider::setLowerPosition(int lower) +{ + if (d_ptr->lowerPos != lower) + { + d_ptr->lowerPos = lower; + if (!hasTracking()) + update(); + if (isSliderDown()) + emit lowerPositionChanged(lower); + if (hasTracking() && !d_ptr->blockTracking) + { + bool main = (d_ptr->mainControl == QxtSpanSlider::LowerHandle); + d_ptr->triggerAction(SliderMove, main); + } + } +} + +/*! + \property QxtSpanSlider::upperPosition + \brief the upper position of the span + */ +int QxtSpanSlider::upperPosition() const +{ + return d_ptr->upperPos; +} + +void QxtSpanSlider::setUpperPosition(int upper) +{ + if (d_ptr->upperPos != upper) + { + d_ptr->upperPos = upper; + if (!hasTracking()) + update(); + if (isSliderDown()) + emit upperPositionChanged(upper); + if (hasTracking() && !d_ptr->blockTracking) + { + bool main = (d_ptr->mainControl == QxtSpanSlider::UpperHandle); + d_ptr->triggerAction(SliderMove, main); + } + } +} + +/*! + \reimp + */ +void QxtSpanSlider::keyPressEvent(QKeyEvent* event) +{ + QSlider::keyPressEvent(event); + + bool main = true; + SliderAction action = SliderNoAction; + switch (event->key()) + { + case Qt::Key_Left: + main = (orientation() == Qt::Horizontal); + action = !invertedAppearance() ? SliderSingleStepSub : SliderSingleStepAdd; + break; + case Qt::Key_Right: + main = (orientation() == Qt::Horizontal); + action = !invertedAppearance() ? SliderSingleStepAdd : SliderSingleStepSub; + break; + case Qt::Key_Up: + main = (orientation() == Qt::Vertical); + action = invertedControls() ? SliderSingleStepSub : SliderSingleStepAdd; + break; + case Qt::Key_Down: + main = (orientation() == Qt::Vertical); + action = invertedControls() ? SliderSingleStepAdd : SliderSingleStepSub; + break; + case Qt::Key_Home: + main = (d_ptr->mainControl == QxtSpanSlider::LowerHandle); + action = SliderToMinimum; + break; + case Qt::Key_End: + main = (d_ptr->mainControl == QxtSpanSlider::UpperHandle); + action = SliderToMaximum; + break; + default: + event->ignore(); + break; + } + + if (action) + d_ptr->triggerAction(action, main); +} + +/*! + \reimp + */ +void QxtSpanSlider::mousePressEvent(QMouseEvent* event) +{ + if (minimum() == maximum() || (event->buttons() ^ event->button())) + { + event->ignore(); + return; + } + + d_ptr->handleMousePress(event->pos(), d_ptr->upperPressed, d_ptr->upper, QxtSpanSlider::UpperHandle); + if (d_ptr->upperPressed != QStyle::SC_SliderHandle) + d_ptr->handleMousePress(event->pos(), d_ptr->lowerPressed, d_ptr->lower, QxtSpanSlider::LowerHandle); + + d_ptr->firstMovement = true; + event->accept(); +} + +void QxtSpanSlider::mouseDoubleClickEvent(QMouseEvent *event) +{ + QSlider::mouseDoubleClickEvent(event); + emit sliderDoubleClick(event->globalX(), event->globalY()); +} + +/*! + \reimp + */ +void QxtSpanSlider::mouseMoveEvent(QMouseEvent* event) +{ + if (d_ptr->lowerPressed != QStyle::SC_SliderHandle && d_ptr->upperPressed != QStyle::SC_SliderHandle) + { + event->ignore(); + return; + } + + QStyleOptionSlider opt; + d_ptr->initStyleOption(&opt); + const int m = style()->pixelMetric(QStyle::PM_MaximumDragDistance, &opt, this); + int newPosition = d_ptr->pixelPosToRangeValue(d_ptr->pick(event->pos()) - d_ptr->offset); + if (m >= 0) + { + const QRect r = rect().adjusted(-m, -m, m, m); + if (!r.contains(event->pos())) + { + newPosition = d_ptr->position; + } + } + + // pick the preferred handle on the first movement + if (d_ptr->firstMovement) + { + if (d_ptr->lower == d_ptr->upper) + { + if (newPosition < lowerValue()) + { + d_ptr->swapControls(); + d_ptr->firstMovement = false; + } + } + else + { + d_ptr->firstMovement = false; + } + } + + if (d_ptr->lowerPressed == QStyle::SC_SliderHandle) + { + if (d_ptr->movement == NoCrossing) + newPosition = qMin(newPosition, upperValue()); + else if (d_ptr->movement == NoOverlapping) + newPosition = qMin(newPosition, upperValue() - 1); + + if (d_ptr->movement == FreeMovement && newPosition > d_ptr->upper) + { + d_ptr->swapControls(); + setUpperPosition(newPosition); + } + else + { + setLowerPosition(newPosition); + } + } + else if (d_ptr->upperPressed == QStyle::SC_SliderHandle) + { + if (d_ptr->movement == NoCrossing) + newPosition = qMax(newPosition, lowerValue()); + else if (d_ptr->movement == NoOverlapping) + newPosition = qMax(newPosition, lowerValue() + 1); + + if (d_ptr->movement == FreeMovement && newPosition < d_ptr->lower) + { + d_ptr->swapControls(); + setLowerPosition(newPosition); + } + else + { + setUpperPosition(newPosition); + } + } + event->accept(); +} + +/*! + \reimp + */ +void QxtSpanSlider::mouseReleaseEvent(QMouseEvent* event) +{ + QSlider::mouseReleaseEvent(event); + setSliderDown(false); + d_ptr->lowerPressed = QStyle::SC_None; + d_ptr->upperPressed = QStyle::SC_None; + update(); +} + +/*! + \reimp + */ +void QxtSpanSlider::paintEvent(QPaintEvent* event) +{ + Q_UNUSED(event); + QStylePainter painter(this); + + // groove & ticks + QStyleOptionSlider opt; + d_ptr->initStyleOption(&opt); + opt.sliderValue = 0; + opt.sliderPosition = 0; + opt.subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderTickmarks; + painter.drawComplexControl(QStyle::CC_Slider, opt); + + // handle rects + opt.sliderPosition = d_ptr->lowerPos; + const QRect lr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + const int lrv = d_ptr->pick(lr.center()); + opt.sliderPosition = d_ptr->upperPos; + const QRect ur = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); + const int urv = d_ptr->pick(ur.center()); + + // span + const int minv = qMin(lrv, urv); + const int maxv = qMax(lrv, urv); + const QPoint c = QRect(lr.center(), ur.center()).center(); + QRect spanRect; + if (orientation() == Qt::Horizontal) + spanRect = QRect(QPoint(minv, c.y() - 2), QPoint(maxv, c.y() + 1)); + else + spanRect = QRect(QPoint(c.x() - 2, minv), QPoint(c.x() + 1, maxv)); + d_ptr->drawSpan(&painter, spanRect); + + // handles + switch (d_ptr->lastPressed) + { + case QxtSpanSlider::LowerHandle: + d_ptr->drawHandle(&painter, QxtSpanSlider::UpperHandle); + d_ptr->drawHandle(&painter, QxtSpanSlider::LowerHandle); + break; + case QxtSpanSlider::UpperHandle: + default: + d_ptr->drawHandle(&painter, QxtSpanSlider::LowerHandle); + d_ptr->drawHandle(&painter, QxtSpanSlider::UpperHandle); + break; + } +} diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/QxtSpanSlider.h b/product/src/gui/plugin/TrendCurves_pad/widgets/QxtSpanSlider.h new file mode 100644 index 00000000..fd9ad794 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/QxtSpanSlider.h @@ -0,0 +1,111 @@ +#ifndef QXTSPANSLIDER_H +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** +*****************************************************************************/ + +#define QXTSPANSLIDER_H + +#include +//#include "qxtnamespace.h" +//#include "qxtglobal.h" + +class QxtSpanSliderPrivate; + +class QxtSpanSlider : public QSlider { + Q_OBJECT + + //QXT_DECLARE_PRIVATE(QxtSpanSlider) + Q_PROPERTY(int lowerValue READ lowerValue WRITE setLowerValue) + Q_PROPERTY(int upperValue READ upperValue WRITE setUpperValue) + Q_PROPERTY(int lowerPosition READ lowerPosition WRITE setLowerPosition) + Q_PROPERTY(int upperPosition READ upperPosition WRITE setUpperPosition) + Q_PROPERTY(HandleMovementMode handleMovementMode READ handleMovementMode WRITE setHandleMovementMode) + Q_ENUMS(HandleMovementMode) + +public: + explicit QxtSpanSlider(QWidget* parent = 0); + explicit QxtSpanSlider(Qt::Orientation orientation, QWidget* parent = 0); + virtual ~QxtSpanSlider(); + + enum HandleMovementMode + { + FreeMovement, + NoCrossing, + NoOverlapping + }; + + enum SpanHandle + { + NoHandle, + LowerHandle, + UpperHandle + }; + + HandleMovementMode handleMovementMode() const; + void setHandleMovementMode(HandleMovementMode mode); + + int lowerValue() const; + int upperValue() const; + + int lowerPosition() const; + int upperPosition() const; + +public Q_SLOTS: + void setLowerValue(int lower); + void setUpperValue(int upper); + void setSpan(int lower, int upper); + + void setLowerPosition(int lower); + void setUpperPosition(int upper); + +Q_SIGNALS: + void spanChanged(int lower, int upper); + void lowerValueChanged(int lower); + void upperValueChanged(int upper); + + void lowerPositionChanged(int lower); + void upperPositionChanged(int upper); + + void sliderPressed(SpanHandle handle); + void sliderDoubleClick(int x, int y); + +protected: + virtual void keyPressEvent(QKeyEvent* event); + virtual void mousePressEvent(QMouseEvent* event); + virtual void mouseDoubleClickEvent(QMouseEvent* event); + virtual void mouseMoveEvent(QMouseEvent* event); + virtual void mouseReleaseEvent(QMouseEvent* event); + virtual void paintEvent(QPaintEvent* event); + +private: + QxtSpanSliderPrivate* d_ptr; + friend class QxtSpanSliderPrivate; +}; + +#endif // QXTSPANSLIDER_H \ No newline at end of file diff --git a/product/src/gui/plugin/TrendCurves_pad/widgets/QxtSpanSlider_p.h b/product/src/gui/plugin/TrendCurves_pad/widgets/QxtSpanSlider_p.h new file mode 100644 index 00000000..0c58fe07 --- /dev/null +++ b/product/src/gui/plugin/TrendCurves_pad/widgets/QxtSpanSlider_p.h @@ -0,0 +1,84 @@ +#ifndef QXTSPANSLIDER_P_H +/**************************************************************************** +** Copyright (c) 2006 - 2011, the LibQxt project. +** See the Qxt AUTHORS file for a list of authors and copyright holders. +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** * Neither the name of the LibQxt project nor the +** names of its contributors may be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** +*****************************************************************************/ + +#define QXTSPANSLIDER_P_H + +#include +#include +#include "QxtSpanSlider.h" + +QT_FORWARD_DECLARE_CLASS(QStylePainter) +QT_FORWARD_DECLARE_CLASS(QStyleOptionSlider) + +class QxtSpanSliderPrivate : public QObject { + Q_OBJECT +public: + QxtSpanSliderPrivate(); + void initStyleOption(QStyleOptionSlider* option, QxtSpanSlider::SpanHandle handle = QxtSpanSlider::UpperHandle) const; + int pick(const QPoint& pt) const + { + return q_ptr->orientation() == Qt::Horizontal ? pt.x() : pt.y(); + } + int pixelPosToRangeValue(int pos) const; + void handleMousePress(const QPoint& pos, QStyle::SubControl& control, int value, QxtSpanSlider::SpanHandle handle); + void drawHandle(QStylePainter* painter, QxtSpanSlider::SpanHandle handle) const; + void setupPainter(QPainter* painter, Qt::Orientation orientation, qreal x1, qreal y1, qreal x2, qreal y2) const; + void drawSpan(QStylePainter* painter, const QRect& rect) const; + void triggerAction(QAbstractSlider::SliderAction action, bool main); + void swapControls(); + + int lower; + int upper; + int lowerPos; + int upperPos; + int offset; + int position; + QxtSpanSlider::SpanHandle lastPressed; + QxtSpanSlider::SpanHandle mainControl; + QStyle::SubControl lowerPressed; + QStyle::SubControl upperPressed; + QxtSpanSlider::HandleMovementMode movement; + bool firstMovement; + bool blockTracking; + + +public Q_SLOTS: + void updateRange(int min, int max); + void movePressedHandle(); + +private: + QxtSpanSlider* q_ptr; + friend class QxtSpanSlider; + + +}; + +#endif // QXTSPANSLIDER_P_H diff --git a/product/src/gui/plugin/UserManageWidget/UserManagePluginWidget.h b/product/src/gui/plugin/UserManageWidget/UserManagePluginWidget.h index 00da12ac..7a718bfa 100644 --- a/product/src/gui/plugin/UserManageWidget/UserManagePluginWidget.h +++ b/product/src/gui/plugin/UserManageWidget/UserManagePluginWidget.h @@ -7,7 +7,7 @@ class UserManagePluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/UserManageWidget/UserManageWidget.cpp b/product/src/gui/plugin/UserManageWidget/UserManageWidget.cpp index da391ec2..bcf5a694 100644 --- a/product/src/gui/plugin/UserManageWidget/UserManageWidget.cpp +++ b/product/src/gui/plugin/UserManageWidget/UserManageWidget.cpp @@ -13,6 +13,10 @@ #include #include "pub_logger_api/logger.h" #include "pub_utility_api/FileStyle.h" +#include +#include "public/pub_utility_api/FileUtil.h" +#include +#include #define CLK_FUNC "CLK_FUNC" #define CLK_USER "CLK_USER" @@ -98,6 +102,7 @@ void UserManageWidget::initialize(int model) else if(E_Window_User == model) { m_stack->setCurrentIndex(1); + resetUserWidgetBar(); } else if(E_Window_Role == model) { @@ -174,3 +179,60 @@ void UserManageWidget::checkPerm() LOGINFO("当前登录用户ID[%d],用户组ID[%d],具有浏览权限!",nUserId,nUserGrpId); } } + +void UserManageWidget::resetUserWidgetBar() +{ + //设置QToolBar按钮风格 + QWidget* w = m_stack->currentWidget(); + if(w== nullptr) + return; + QList listToolBar = w->findChildren(); + + for(auto toolbar : listToolBar) + toolbar->setToolButtonStyle(Qt::ToolButtonTextOnly); + + //设置下方QTabWidget的设置窗口 + //读取配置文件 + std::string tabBarCfgPathstr = iot_public::CFileUtil::getPathOfCfgFile("userManagerWidgetTabBar.xml"); + QString tabBarCfgPath = QString::fromStdString(tabBarCfgPathstr); + if(tabBarCfgPath.isEmpty()) + return; + + QDomDocument doc; + QFile file(tabBarCfgPath); + if (!file.open(QIODevice::ReadOnly)) + return; + if (!doc.setContent(&file)) + { + file.close(); + return; + } + file.close(); + + QStringList tabBarNameList; + QDomNodeList domNodeList = doc.elementsByTagName("TabBar"); + for(int i=0 ; i < domNodeList.size(); i++) + { + QDomElement e = domNodeList.at(i).toElement(); + if(!e.isNull() && e.attribute("visiable") == "true") + { + tabBarNameList.append(e.attribute("desc")); + } + } + QList listTabBar = w->findChildren(); + for(auto tabBar :listTabBar) + { + for(int i=0 ; i< tabBar->count() ; i++) + { + if(tabBarNameList.indexOf(tabBar->tabText(i)) <0) + { + tabBar->setTabEnabled(i,false); + tabBar->removeTab(i); + i--; + } + } + } + + //设置 + +} diff --git a/product/src/gui/plugin/UserManageWidget/UserManageWidget.h b/product/src/gui/plugin/UserManageWidget/UserManageWidget.h index afb91ab7..fee293b0 100644 --- a/product/src/gui/plugin/UserManageWidget/UserManageWidget.h +++ b/product/src/gui/plugin/UserManageWidget/UserManageWidget.h @@ -49,6 +49,9 @@ private: void checkPerm(); + //将工具栏设置和系统一致的风格 + void resetUserWidgetBar(); + private: Ui::UserManageWidget *ui; diff --git a/product/src/gui/plugin/UserManageWidget/UserManageWidget.pro b/product/src/gui/plugin/UserManageWidget/UserManageWidget.pro index 594bc0f5..3720051e 100644 --- a/product/src/gui/plugin/UserManageWidget/UserManageWidget.pro +++ b/product/src/gui/plugin/UserManageWidget/UserManageWidget.pro @@ -4,7 +4,7 @@ # #------------------------------------------------- -QT += core gui widgets charts sql +QT += core gui widgets charts sql xml greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -21,7 +21,7 @@ exists($$PWD/../../../common.pri) { } INCLUDEPATH += $$PWD/../../../../../platform/src/include/tools/model_common \ - $$PWD/../../../../../platform/src/include/tools/model_excel/xlsx \ + $$PWD/../../../../../platform/src/include/public/pub_excel/xlsx \ $$PWD/../../../../../platform/src/include/tools/model_table \ $$PWD/../../../../../platform/src/include/tools/model_user \ $$PWD/../../../../../platform/src/include/tools/model_table/CustomWidget \ @@ -61,7 +61,8 @@ LIBS += -lpub_logger_api LIBS += -llog4cplus LIBS += -lmodel_table LIBS += -lmodel_common -LIBS += -lmodel_excel +LIBS += -lpub_excel LIBS += -lmodel_user + diff --git a/product/src/gui/plugin/UserManageWidget/main.cpp b/product/src/gui/plugin/UserManageWidget/main.cpp index 0279a18a..daa30b97 100644 --- a/product/src/gui/plugin/UserManageWidget/main.cpp +++ b/product/src/gui/plugin/UserManageWidget/main.cpp @@ -9,7 +9,7 @@ int main(int argc, char *argv[]) QApplication a(argc, argv); std::string name="admin"; - std::string password ="kbdct"; + std::string password ="admin"; iot_public::StartLogSystem("HMI", "hmi"); iot_net::initMsgBus("HMI", "HMI"); int group =1; diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzePlugin.h b/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzePlugin.h index 94f522c2..610e4ce3 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzePlugin.h +++ b/product/src/gui/plugin/WaveAnalyzeWidget/CWaveAnalyzePlugin.h @@ -7,7 +7,7 @@ class CWaveAnalyzePlugin : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CComtradeFile.cpp b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CComtradeFile.cpp index c3456100..f5e3a406 100644 --- a/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CComtradeFile.cpp +++ b/product/src/gui/plugin/WaveAnalyzeWidget/WaveAnalyze/CComtradeFile.cpp @@ -3797,7 +3797,7 @@ void CComtradeFile::LoadDisplayOption() int i,nIndex; QString szCnt,szSub; //显示属性 - nIndex = CSectionOperate::GetSection(sectlist,tr("Display Attribute"),tr("SHENZHEN KANGBIDA CONTROL TECHNOLOGY CO.LTD"));//显示属性 + nIndex = CSectionOperate::GetSection(sectlist,tr("Display Attribute"),tr("SHENZHEN BYD CO.LTD"));//显示属性 if(nIndex<0) return; CInfSection& sect1 = sectlist[nIndex]; @@ -3807,7 +3807,7 @@ void CComtradeFile::LoadDisplayOption() m_DispAttr.m_dTagsHeight = sect1.GetAttribute(tr("State Channel Height"), "20").toDouble();//状态通道高度 //模拟通道显示属性 - nIndex = CSectionOperate::GetSection(sectlist, tr("Analogous Channel Display"),tr("SHENZHEN KANGBIDA CONTROL TECHNOLOGY CO.LTD"));//模拟通道显示 + nIndex = CSectionOperate::GetSection(sectlist, tr("Analogous Channel Display"),tr("SHENZHEN BYD CO.LTD"));//模拟通道显示 if(nIndex<0) return; CInfSection sect2 = sectlist[nIndex];; int nAnalogueNum = sect2.GetAttribute(tr("Analogous Channel Count"), "0").toInt();//模拟通道个数 @@ -3835,7 +3835,7 @@ void CComtradeFile::LoadDisplayOption() } //状态通道显示属性 - nIndex = CSectionOperate::GetSection(sectlist, tr("State Channel Display"), tr("SHENZHEN KANGBIDA CONTROL TECHNOLOGY CO.LTD"));//状态通道显示 + nIndex = CSectionOperate::GetSection(sectlist, tr("State Channel Display"), tr("SHENZHEN BYD CO.LTD"));//状态通道显示 if(nIndex<0) return; CInfSection sect3 = sectlist[nIndex]; int nDigitalNum = sect3.GetAttribute(tr("State Channel Count"), "0").toInt();//状态通道个数 diff --git a/product/src/gui/plugin/WebBrowserWidget/CBrowserPluginWidget.h b/product/src/gui/plugin/WebBrowserWidget/CBrowserPluginWidget.h index 1d519d88..a1485778 100644 --- a/product/src/gui/plugin/WebBrowserWidget/CBrowserPluginWidget.h +++ b/product/src/gui/plugin/WebBrowserWidget/CBrowserPluginWidget.h @@ -7,7 +7,7 @@ class CBrowserPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/WebBrowserWidget/main.cpp b/product/src/gui/plugin/WebBrowserWidget/main.cpp index 8b6cc07e..db45bf9e 100644 --- a/product/src/gui/plugin/WebBrowserWidget/main.cpp +++ b/product/src/gui/plugin/WebBrowserWidget/main.cpp @@ -17,7 +17,7 @@ int main(int argc, char *argv[]) { return -1; } - if(perm->SysLogin("Test", "kbdct", 1, 12*60*60, "hmi") != 0) + if(perm->SysLogin("admin", "admin", 1, 12*60*60, "hmi") != 0) { return -1; } diff --git a/product/src/gui/plugin/WorkTicket/CWorkTicketPluginWidget.h b/product/src/gui/plugin/WorkTicket/CWorkTicketPluginWidget.h index 5b1379a8..843e3e95 100644 --- a/product/src/gui/plugin/WorkTicket/CWorkTicketPluginWidget.h +++ b/product/src/gui/plugin/WorkTicket/CWorkTicketPluginWidget.h @@ -7,7 +7,7 @@ class CWorkTicketPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/WorkTicket/WorkTicketWidget.cpp b/product/src/gui/plugin/WorkTicket/WorkTicketWidget.cpp index 7580ccb9..19051217 100644 --- a/product/src/gui/plugin/WorkTicket/WorkTicketWidget.cpp +++ b/product/src/gui/plugin/WorkTicket/WorkTicketWidget.cpp @@ -76,10 +76,10 @@ void WorkTicketWidget::initLayout() void WorkTicketWidget::initTableModel() { -// QSettings settings("KbdSoft.ZHJK","ISCS6000.tools"); +// QSettings settings("IOT","ISCS6000.tools"); // KbdTableDataMgr::getInstance()->initDBLink(DataBaseInterface::DirectLink, // settings.value("login/user","root").toString(), -// settings.value("login/psw","kbdct@0755").toString(), +// settings.value("login/psw","ems@byd23").toString(), // settings.value("login/ip","192.168.190.128").toString(), // settings.value("login/port","3306").toInt(), // settings.value("login/dbname","ISCS6000").toString(), diff --git a/product/src/gui/plugin/iDongOpsWidget/CIDongOpsPluginWidget.h b/product/src/gui/plugin/iDongOpsWidget/CIDongOpsPluginWidget.h index a26aca16..9442baeb 100644 --- a/product/src/gui/plugin/iDongOpsWidget/CIDongOpsPluginWidget.h +++ b/product/src/gui/plugin/iDongOpsWidget/CIDongOpsPluginWidget.h @@ -7,7 +7,7 @@ class CIDongOpsPluginWidget : public QObject, public CPluginWidgetInterface { Q_OBJECT - Q_PLUGIN_METADATA(IID "kbd.PluginWidgetInterface/1.0") + Q_PLUGIN_METADATA(IID HMI_WidgetPlugin_IID) Q_INTERFACES(CPluginWidgetInterface) public: diff --git a/product/src/gui/plugin/plugin.pro b/product/src/gui/plugin/plugin.pro index aa529a4e..6748d1de 100644 --- a/product/src/gui/plugin/plugin.pro +++ b/product/src/gui/plugin/plugin.pro @@ -18,42 +18,53 @@ SUBDIRS+= \ ConstCurves \ AlarmStatisWidget \ DevHisDataWidget \ - BriefReportWidget \ + #BriefReportWidget \ ShiftWidget \ DevRealDataWidget \ - RobotCtrlWidget \ + #RobotCtrlWidget \ IpcPlusWidget \ - LoadStatWidget \ + #LoadStatWidget \ FaultRecordWidget \ IpcWallWidget \ - BIWidget \ + #BIWidget \ UserManageWidget \ AlarmManageWidget \ HtmlBrowserWidget \ HmiRollWidget \ - ScheduleWidget \ + #ScheduleWidget \ AlarmAnalyzeWidget \ FbdEditorWidget \ AlarmShieldWidget \ - iDongOpsWidget \ + #iDongOpsWidget \ RelaySettingWidget \ AssetWidget \ ButtonGroupWidget \ PointRealDataWidget \ - InverseTimeLimit \ + #InverseTimeLimit \ BreadcrumbNavWidget \ HangPanelWidget \ SimOptWidget \ FaultRecallRecordWidget \ PointLockWidget \ - MediaWidget \ + #MediaWidget \ LimitOptWidget \ DevSpePointWidget \ DocumentManageWidget \ - WaveAnalyzeWidget \ + #WaveAnalyzeWidget \ ChanStatusWidget \ SerialDevStatusWidget \ WebBrowserWidget \ - BusbarTemperatureWidget + ChanParaWidget \ + CNTPTimeWidget \ + SecondReportWidget \ + SysParamWidget \ + TrendCurves_pad \ + AlarmWidget_pad \ + EventWidget_pad \ + ChanRealStatusWidget\ + SecondNavigationWidget\ + SecondButtonGroupWidget\ + BatchOperation\ + StrategyControlWidget SequenceManageWidget.depends = SequenceWidget diff --git a/product/src/gui/product_en.ts b/product/src/gui/product_en.ts new file mode 100644 index 00000000..b4900154 --- /dev/null +++ b/product/src/gui/product_en.ts @@ -0,0 +1,18766 @@ + + + + + AddBtnForm + + Form + Form + + + + AddObjAlarmDialog + + + Dialog + Dialog + + + + 设备 + Device + + + + 自定义告警名称 + Name + + + + 类型 + Type + + + + 告警等级定义 + Level + + + + 告警点计算函数 + Calc function + + + + 告警规则 + Alarm role + + + + 越上限值 + Limit up1 + + + + 越下限值 + Limit low1 + + + + 数字量文本: + Digital text: + + + + 添加 + Add + + + + 取消 + Cancel + + + + 新增告警点 + Custom alarm + + + + 值 + Value + + + + + 模拟量 + Analog + + + 选择参数 + Select Parameters + + + + + 数字量 + Digital + + + + 枚举量 + Mix + + + + + + + + + + + + + 提示 + Tip + + + + 自定义告警名称不能为空! + Name is required! + + + + 无告警点计算函数,请先配置计算点函数! + No calculation function,please configure the calculation point function first! + + + + 参数:%1的参数标签不能为空! + Param:The parameter label of %1 cannot be empty! + + + + 越下限值必须小于越上限值! + The lower limit must be less than the upper limit! + + + + 无数字量文本,请先配置数字量文本! + No digital text,please configure digital text first! + + + + + + 添加失败!正在回滚事务~ + Add failed!transaction is being rolled back + + + + + 添加成功 + Add success + + + + 计次告警描述 + Counting alarm description + + + + 计时告警描述 + Timing alarm description + + + + AlarmCalcParaTableModel + + + 参数名称 + Parameter name + + + + 参数标签 + Parameter tag + + + + 操作 + Operating + + + + AlarmDevTreeModel + + + 位置/设备组 + Location/DeviceGroup + + + + AlarmManageForm + + + Form + Form + + + + AlarmManageWidget + + + AlarmManageWidget + AlarmManageWidget + + + + 请输入搜索内容 + Please output search content + + + + + 查询 + Search + + + + 新增告警点 + Custom alarm + + + 屏蔽一览表 + Shield list + + + + 保存 + Save + + + + 描述设置 + Describe settings + + + 计算公式 + Calculation Formula + + + 计算函数 + Calculation Function + + + + 测点描述 + Point desc + + + 屏蔽设置 + Shield settings + + + 是否告警屏蔽 + Alarm shield + + + 屏蔽时段类型 + Time type + + + 屏蔽事由 + Reasons + + + 开始时间 + Start time + + + 结束时间 + End time + + + 一 + MON + + + 二 + TUE + + + 三 + WED + + + 四 + THU + + + 五 + FRI + + + 六 + SAT + + + 七 + SUN + + + 日期 + Date + + + 至 + To + + + + + 告警动作 + Alarm action + + + + 是否自定义告警 + Custom alarm + + + + 告警优先级 + Priority + + + + 模拟量 + Analog + + + + 数字量 + Digital + + + + 多选 + MultiSelection + + + + 越限等级 + Limit number + + + + 告警推图文件 + Pic name + + + + + 选择 + Select + + + ... + ... + + + + 告警声音文件 + Sound name + + + + 越限设置 + Limit settings + + + 越线等级 + Limit level + + + + 越上限值 + Upper limit + + + + 越下限值 + Lower limit + + + + 越上上限值 + Upper 2 limit + + + + 越下下限值 + Lower 2 limit + + + + 越限告警 + Limit alarm + + + + + 是 + Yes + + + + + 否 + No + + + 一次性 + One time + + + 每周 + Week + + + 每月 + Month + + + + 0 + 0 + + + + 1 + 1 + + + + 2 + 2 + + + + + + + + + + + + + + + + + + + + + 提示 + Tip + + + + + 保存失败!正在回滚事务~ + Save failed!transaction is being rolled back + + + + + 保存成功! + Save success! + + + + + 确认删除? + Confirm on delete? + + + + + 删除失败!正在回滚事务~ + Failure to delete!Rollback transaction~ + + + 选择参数 + Select Parameters + + + 枚举量 + Mix + + + 值 + Value + + + + 当前登录用户无修改权限! + The current user have no perm to modify! + + + + 越下下限值必须小于越下限值 + The lower 2 limit must be less than the lower limit + + + + + 越下限值必须小于越上限值 + The lower limit must be less than the upper limit + + + + 越上限值必须小于越上上限值 + The upper limit must be less than the upper 2 limit + + + + 当前登录用户无新增告警点权限! + The current user have no perm to add custom alarm! + + + + + 全选 + Check All + + + + + 全不选 + Unchecked All + + + + + 删除 + Delete + + + + + 点描述不能为空! + Description can not be empty! + + + 操作名称不能为空! + Operation name can not be empty! + + + 开始时间要小于结束时间! + Start time must be less than end time! + + + 请选中需要屏蔽的礼拜! + Please select the time to be blocked! + + + 开始日不能大于结束日! + The start date can not be greater than the end date! + + + 未知的屏蔽时间类型 + Unknown shield time type + + + 越下下限不能大于越下限 + The lower 2 limit can not be greater than the lower limit + + + 越下限不能大于越上限 + The lower limit can not be greater than the upper limit + + + 越上限不能大于越上上限 + The upper limit can not be greater than the upper 2 limit + + + + 请选择要添加自定义告警的设备组! + Please select the device group to add custom alarms! + + + + 此设备组下无可用设备,请重新选择设备组! + There is no available device under this device group,please reselect the device group! + + + + Open Pic + Open Picture + + + + Pic Files (*.glx) + GLX Picture Files (*.glx) + + + + Open Voice + Open Audio + + + + Pic Files (*.wav) + Wave Audio Files (*.wav) + + + + AlarmMng + + + 未知车站 + Unknown loction + + + + 未知设备组 + Unknonwn device group + + + + 未知设备 + Unknown device + + + + 未知 + Unknown + + + 其他 + Other + + + + AlarmPointTableModel + + + 告警点名称 + Name + + + 所属厂站 + Location + + + 是否屏蔽 + Shield + + + 屏蔽时段 + Shield time + + + + 告警等级 + Alarm level + + + + 告警动作 + Alarm action + + + + 所属位置 + Location + + + + 所属设备组 + Device Group + + + + 所属设备 + Device + + + 是 + Yes + + + 否 + No + + + / + / + + + 每周( + Week( + + + 每月( + Month( + + + + 未知 + Unknown + + + + AlarmShieldDelegate + + 删除 + Delete + + + 启用 + Enable + + + 取消 + Cancel + + + 提示 + Tip + + + 删除失败! + Failed to deleted! + + + 删除成功! + Successfully deleted! + + + + AlarmShieldDialog + + Dialog + Dialog + + + 启用 + Enabled + + + 取消 + Cancel + + + 删除 + Delete + + + 屏蔽状态 + Enable status + + + 名称 + Name + + + 查询 + Search + + + 屏蔽一览表 + Shield list + + + 全部 + All + + + 已启用 + Enabled + + + 未启用 + Unenabled + + + 提示 + Tip + + + 启用失败,正在回滚 + Enable failed,rolling back + + + 取消失败,正在回滚 + Cancel failed,rolling back + + + 删除失败,正在回滚! + Delete failed,rolling back! + + + 删除成功! + Successfully deleted! + + + + AlarmShieldTableModel + + 名称 + Name + + + 屏蔽类型 + Shield Type + + + 屏蔽属性 + Shield attribute + + + 屏蔽模式 + Shield mode + + + 是否启用 + Enable + + + 时段类型 + Time type + + + 屏蔽时段 + Shield time + + + 操作用户 + User + + + 操作主机 + Hostname + + + 操作 + Operating + + + 全站屏蔽 + Shield location + + + 设备屏蔽 + Shield device + + + 测点屏蔽 + Shield point + + + 电压屏蔽 + Shield voltage + + + 设备组屏蔽 + Shield dev group + + + 责任区屏蔽 + Shield region + + + 未知 + Unknown + + + 已启用 + Enabled + + + 未启用 + Unenabled + + + 一次性屏蔽 + Once time + + + 每周 + Week + + + 每月 + Month + + + 每周( + Week( + + + 每月( + Month( + + + + BriefReportWidget + + 运行简报 + BriefReport + + + 位置 + Location + + + 日 + Day + + + 周 + Week + + + 月 + Month + + + 季 + Quarter + + + 年 + Year + + + 查询 + Search + + + 导出 + Export + + + 关键告警 + Key Alarms + + + 操作记录 + Operate Events + + + 巡检记录 + Inspection Events + + + 检修记录 + Overhaul Events + + + 保存 + Save + + + 时间 + Time + + + Tab 1 + Tab 1 + + + Tab 2 + Tab 2 + + + Tab 3 + Tab 3 + + + Tab 4 + Tab 4 + + + + BrowserDialog + + 下载模板 + Download Template + + + + CAccidentReviewDialog + + + + + + 事故追忆 + Accident Memory + + + + + + + 确认 + Confirm + + + + + + + 取消 + Cancel + + + + + + + + + + + 提示 + Prompt + + + + + + + 请选择一张画面! + Please select a graph! + + + + + + + 请选择其他画面! + Please select other graph! + + + + CActionSequModel + + + 标记 + Marker + + + + 开关名称 + Switch Name + + + + 目标状态 + Target State + + + + 执行状态 + Execution Status + + + + 实际状态 + Actual Status + + + + 延时 + Delay + + + + 未执行 + non-execution + + + + 正在执行 + executing + + + + 已触发 + triggered + + + + 执行失败 + execution failure + + + + 执行成功 + execution success + + + + 执行终止 + execution termination + + + + 执行暂停 + execution pause + + + + 执行跳过 + execution skip + + + + CAddBtnForm + + 添加图片 + Add Image + + + 添加边框 + Add Border + + + 添加渐变 + Add Gradient + + + 添加颜色 + Add Color + + + 添加字体 + Add Font + + + 添加副控制 + Add SubControl + + + 添加状态 + Add State + + + 背景图片 + Background Image + + + 边框图片 + Border Image + + + 图片 + Image + + + 颜色 + Color + + + 背景颜色 + Background Color + + + 间隔背景颜色 + Alternate Background Color + + + 边框颜色 + Border Color + + + 上边框颜色 + Top Border Color + + + 右边框颜色 + Right Border Color + + + 下边框颜色 + Bottom Border Color + + + 左边框颜色 + Left Border Color + + + 网格颜色 + Gridline Color + + + 选中颜色 + Selection Color + + + 选中背景颜色 + Selection Background Color + + + add-line + Add Line + + + add-page + Add Page + + + branch + Branch + + + chunk + Chunk + + + close-button + Close Button + + + corner + Corner + + + down-arrow + Down Arrow + + + down-button + Down Button + + + drop-down + Drop Down + + + float-button + Float Button + + + groove + Groove + + + indicator + Indicator + + + handle + Handle + + + icon + Icon + + + item + Item + + + left-arrow + Left Arrow + + + left-corner + Left Corner + + + menu-arrow + Menu Arrow + + + menu-button + Menu Button + + + menu-indicator + Menu Indicator + + + right-arrow + Right Arrow + + + pane + Pane + + + right-corner + Right Corner + + + scroller + Scroller + + + section + Section + + + separator + Separator + + + sub-line + Sub Line + + + sub-page + Sub Page + + + tab + Tab + + + tab-bar + Tab Bar + + + tear + Tear + + + tearoff + Tear Off + + + text + Text + + + title + Title + + + up-arrow + Up Arrow + + + up-button + Up Button + + + active + Active + + + adjoins-item + Adjoins Item + + + alternate + Alternate + + + bottom + Bottom + + + checked + Checked + + + closable + Closable + + + closed + Closed + + + default + Default + + + disabled + Disabled + + + editable + Editable + + + edit-focus + Edit Focus + + + enabled + Enabled + + + exclusive + Exclusive + + + first + First + + + flat + Flat + + + floatable + Floatable + + + focus + Focus + + + has-children + Has Children + + + has-siblings + Has Siblings + + + horizontal + Horizontal + + + hover + Hover + + + indeterminate + Indeterminate + + + last + Last + + + left + Left + + + maximized + Maximized + + + middle + Middle + + + minimized + Minimized + + + movable + Movable + + + no-frame + No Frame + + + non-exclusive + Non-Exclusive + + + off + Off + + + on + On + + + only-one + Only One + + + open + Open + + + next-selected + Next Selected + + + pressed + Pressed + + + previous-selected + Previous Selected + + + read-only + Read Only + + + right + Right + + + selected + Selected + + + top + Top + + + unchecked + Unchecked + + + vertical + Vertical + + + window + Window + + + 无边框 + No Border + + + 点状边框 + Dotted Border + + + 虚线边框 + Dashed Border + + + 实线边框 + Solid Border + + + 双线边框 + Double Border + + + 边框圆角 + Border Radius + + + 左上边框圆角 + TopLeft Border Radius + + + 右上边框圆角 + TopRight Border Radius + + + 左下边框圆角 + BottomLeft Border Radius + + + 右下边框圆角 + BottomRight Border Radius + + + 选择文件 + Select File + + + 选择渐变 + Select Gradient + + + 选择颜色 + Select Color + + + + CAddShieldDialog + + + 新增告警屏蔽 + New Alarm Shield + + + + 对象类型 + Type + + + + 显示勾选项 + Show Checked Only + + + + 关键字过滤 + Filter by keyword + + + + 对象名称 + Name + + + + 屏蔽类型 + Shield Type + + + + 名称 + Name + + + + + 时段类型 + Type + + + + + + 结束时间 + End Time + + + + + + 开始时间 + Start Time + + + + 一 + Mon + + + + 二 + Tue + + + + 三 + Wed + + + + 四 + Thur + + + + 五 + Fri + + + + 六 + Sat + + + + 七 + Sun + + + + 至 + to + + + + 日期 + Date + + + + 屏蔽描述 + Shield Description + + + + 新增 + New + + + + 取消 + Cancel + + + + 保存 + Save + + + 修改告警屏蔽 + Modify Alarm Shield + + + + 编辑告警屏蔽 + Modify Alarm Shield + + + + 位置 + Location + + + + 设备组 + Device Group + + + + 设备 + Device + + + 测点 + Point + + + + 一次性 + Once + + + + 每周 + Week + + + + 每月 + Month + + + + 请先取消屏蔽! + Please disable first! + + + + 请至少勾选一项! + Please check at least one item! + + + + 当前用户无标签设置功能权限! + The current user have no perm to operate! + + + + 对象名称不能为空! + Name cannot be empty! + + + + 屏蔽类型为空! + Shield type cannot be empty! + + + + 时段类型为空! + Time type cannot be empty! + + + + 开始时间不能大于结束时间! + Start time cannot be more than end time! + + + + 周一到周七至少需要选择一天! + At least check one day from monday to sunday! + + + + 获取当前登录用户失败! + Failed to get current user! + + + + 保存失败! + Failed to save! + + + + 提示 + Prompt + + + + CAiAlarmDelegate + + 当前无告警! + No alarm at present! + + + + CAiAlarmTreeModel + + + + 时间 + Time + + + + + 优先级 + Priority + + + + + 位置 + Location + + + + + 责任区 + Region + + + + + 告警类型 + Alarm Type + + + + + 告警状态 + Alarm State + + + + + 确认状态 + Confirm State + + + + + 告警内容 + Alarm Content + + + + + 复归状态 + Resume State + + + + CAlarmBaseData + + + + 其他 + Other + + + + CAlarmColorWidget + + + + Form + Form + + + + + 动作颜色 + ActionColor + + + + + 恢复颜色 + ResumeColor + + + + + 确认颜色 + ConfirmColor + + + + + 闪烁颜色 + FlickerColor + + + + CAlarmCompare + + + Form + Form + + + + 告警等级 + Alarm level + + + + 统计类型 + StatisType + + + + 日 + Day + + + + 月 + Month + + + + 时间段 + Time + + + + 告警内容关键字 + Alarm Content Keywords + + + 关键字 + Keyword + + + + 查询 + Search + + + + 11 + 11 + + + + 22 + 22 + + + + 33 + 33 + + + + + + + + + + + + + 警告 + Warning + + + + 未选择告警等级 + No alarm level checked + + + + 开始时间需小于等于结束时间 + The start time must be equal or less than the end time + + + + 当前类型最多七天 + Current statis type up to seven days + + + + 当前类型最多六个月 + Current statis type up to six months + + + + 请选择位置 + Please select a location + + + + + 位置最少选择2个 + At least two location + + + + 位置最多选择%1个 + Location cannot more than %1 + + + + 请选择设备组 + Please select a device group + + + + 设备组最多选择%1个 + Device group cannot more than %1 + + + + 提示 + Prompt + + + + 告警条数过多,仅显示前 %1 条 + Too many alarm,show only %1 + + + + + yyyy-MM-dd + yyyy-MM-dd + + + + - + + + + + CAlarmDelegate + + 当前无告警! + No alarm at present! + + + + CAlarmDeviceTreeModel + + + + 系统信息 + System Information + + + + CAlarmDeviceTreeView + + + 禁止告警 + Inhibit Alarm + + + + 全选 + Check All + + + + 清空 + Clear + + + + 选择 + Select + + + + 清除 + Clear + + + + CAlarmFilterDialog + + + + 过滤 + Filter + + + + + 优先级 + Priority + + + + + + + + + + + 全选 + Check All + + + + + 位置 + Location + + + + + 责任区 + Region + + + + + 告警状态 + Alarm State + + + + + 复归 + Resume + + + + + 已复归 + Resumed + + + + + 未复归 + Unresumed + + + + + 设备类型 + Device Type + + + + + 时间 + Time + + + + + 开始时间 + Start Time + + + + + 结束时间 + End Time + + + + + 告警内容关键字 + Alarm Content Keywords + + + 区域 + Location + + + + + 状态 + State + + + + + 已确认 + Confirmed + + + + + 未确认 + Unconfirmed + + + + + 确定 + Confirm + + + + + 取消 + Cancel + + + + + + + yyyy/MM/dd hh:mm + yyyy/MM/dd hh:mm + + + + 提示 + Hint + + + + 结束时间大于开始时间! + End time should be later than the start time! + + + + CAlarmForm + + + + Form + Form + + + + + 导出 + Export + + + + + 过滤 + Filter + + + 禁止告警列表 + Alarm Inhibition List + + + + + 时间: + Time: + + + + + 告警状态: + Alarm State: + + + + + 禁止列表 + Prohibited List + + + + + 优先级: + Priority: + + + + + + + + + 确认 + Confirm + + + + + 关闭 + Close + + + + 全勾选 + Select All + + + + + + + + + 删除 + Delete + + + + + + + 0 + 0 + + + + + 过滤告警数量: + Number of Filtered Alarms: + + + + + 当前显示数量: + Current Display Count: + + + + + 位置: + Location: + + + + + 智能告警 + Intelligent Alarm + + + + + 设置 + Settings + + + + + + + + + 请选择时间 + Please Select Time + + + + + + + + + + + + + + + + + 请选择优先级 + Select Priority + + + + + + + + + + + + + + + + + 请选择位置 + Select Location + + + + + + + + + + + + + + + + + 请选择告警状态 + Select Alarm State + + + + 确定删除所有事件? + Are you sure you want to delete all events? + + + + 删除完成! + Deletion completed! + + + + + Save File + Save File + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 提示 + Prompt + + + + + 导出成功 + Export succeeded + + + + 请选择一条告警! + Please select an alarm! + + + + + + + + 全选 + Check All + + + + + + + + + 全不选 + All Unchecked + + + + + + + 视频 + Video + + + + + + + 事故追忆 + Accident Memory + + + + + + + 禁止告警 + Inhibit Alarm + + + + + + + + + 禁止告警失败! + Failure to inhibit alarm! + + + + + + + 警告 + Warning + + + 当前测点告警已禁止,无需重复禁止! + The current Measuring point alarm is forbidden, there is no need to repeat the prohibition! + + + 工单管理 + Work Management + + + + + 合并 + Merge + + + + + 分离 + Separate + + + + + + + + + + + + + 当前未选中任何项! + No item is currently selected! + + + + + + + + + 当前用户不具备该告警删除操作权限! + The current user does not have the right to delete the alarm operation! + + + + + + + + + + + + + + + + + + + + + 是否跳过该项? + Do you want to skip this item? + + + + + + + + + + + + + + + + + + + + + 跳过 + Skip + + + + + + + + + + + + + + + + + + + + + 全部跳过 + Skip All + + + + + + + + + + + + + + + + + + + + + 取消 + Cancel + + + + + + + 包含未确认告警! + Contains unconfirmed alarm! + + + + + 当前未选中任何智能告警和未聚类的原始告警! + No intelligent alarms and unclustered original alarms is currently selected! + + + + + 包含未确认原始告警告警! + Contains unconfirmed original warning warning! + + + + + + + 当前用户不具备该告警确认操作权限! + The current user does not have the warning to confirm the operation permission! + + + + + 包含智能告警,无法合并! + Contains intelligent alarm, cannot merge! + + + + + 包含已经聚类的原始告警,无法合并! + Contains original warnings that have been clustered, cannot be merged! + + + + + 当前用户无此条原始告警合并权限! + The current user does not have this original warning merge permission! + + + + + 包含不同域的原始告警,无法合并! + Original alerts containing different domains cannot be merged! + + + + + 包含智能告警,无法分离! + Contains intelligent warning, cannot separate! + + + + + 无原始告警,无法分离! + No original warning, no separation! + + + + + + + 包含未聚类的原始告警,无法分离! + Contains unclustered original warnings, cannot be separated! + + + + + 无此条智能告警的编辑权限! + No edit permission of this intelligent alarm! + + + + + 包含不同智能告警下的原始告警,无法分离! + Contains different intelligent alarms under the original alarm, can not be separated! + + + + + + + 请选中含有趋势的告警(模拟量和累积量)! + Please select the alarm with trend(Ai and Pi)! + + + + + + + + + 请选中具有视频的告警! + Please select the alarm with video! + + + + + + 确定 + OK + + + + + 按设备组关键字搜索 + Search by device group keyword + + + + + 禁止告警失败,请检查实时库连接! + Failed to inhibit alarm, please check the real-time database connection! + + + + + 请选择至少一条告警! + Please select at least one alarm! + + + + + 无禁止告警权限! + Have no permission to inhibit alarm! + + + + + 初始化权限失败! + Failed to initialize permissions! + + + + + + + + + 故障录播暂不实现 + Fault not achieved + + + + CAlarmInhibitDialog + + + + 禁止告警列表 + Prohibit List + + + + + 关闭 + Close + + + + + + + 取消禁止告警 + Cancel + + + + + 时间 + Time + + + + + 优先级 + Priority + + + + + 位置 + Location + + + + + 责任区 + Region + + + + + 告警类型 + Alarm Type + + + + + 确认状态 + Confirm State + + + + + 告警内容 + Alarm Content + + + + + 未确认 + Unconfirmed + + + + + 已确认 + Confirmed + + + + + 警告 + Warning + + + + + 请选择取消禁止告警所在的行! + Please select the row where the alarm is cancelled! + + + + CAlarmItemModel + + + + 时间 + Time + + + + + 优先级 + Priority + + + + + 位置 + Location + + + + + 责任区 + Region + + + + + 告警类型 + Alarm Type + + + + + 告警状态 + Alarm State + + + + + 确认状态 + Confirm State + + + + 告警内容 + Alarm Content + + + + + 复归状态 + Resume state + + + + 告警内容 + Alarm Content + + + + + 未复归 + Resumed + + + + + 已复归 + Unresumed + + + 未知优先级: + Unknown Priority: + + + 未知位置: + Unknown Location: + + + 未知责任区: + Unknown Region: + + + 未知告警类型: + Unknown Alarm Type: + + + 未知告警状态: + Unknown Alarm State: + + + + + 未确认 + Unconfirmed + + + + + 已确认 + Confirmed + + + 其他 + Other + + + + + - + - + + + + CAlarmModel + + + 时间 + Time + + + + 优先级 + Priority + + + + 所属位置 + Location + + + + 告警内容 + Alarm Content + + + + + 操作 + Operation + + + + 趋势 + Trend + + + + 录波 + Wave Recording + + + + CAlarmMsgManage + + 其他 + Other + + + + CAlarmPlugin + + + + 提示 + Tip + + + + + 此次一共确认 + A total of + + + + + 条告警 + alarms were confirmed this time + + + + + + + + + 当前用户不具备该告警确认操作权限! + The current user does not have the warning to confirm the operation permission! + + + + + + + + + + + 是否跳过该项? + Do you want to skip this item? + + + + + + + + + + + 跳过 + Skip + + + + + + + + + + + 全部跳过 + Skip All + + + + + + + + + + + 取消 + Cancel + + + + + 包含未确认告警! + Contains unconfirmed alarm! + + + + CAlarmReport + + + Dialog + Dialog + + + + 导出 + Export + + + + 选择导出目录 + Select the export directory + + + + CAlarmSetDlg + + + + 设置 + Config + + + + + 动作选择 + Action + + + + + 声音告警 + Sound alarm + + + + + 语音告警 + Voice alarm + + + + + 告警方式 + Alarm method + + + + + 方式 + Style + + + + + 次数 + Number of alarms + + + + + 优先级颜色选择 + Priority color selection + + + + + <html><head/><body><p>选中告警时,告警的文字颜色</p></body></html> + <html><head/><body><p>The color of alarm text when alarm selected</p></body></html> + + + + + 选中文字颜色 + Text Selected Color + + + + + + + + + 颜色 + Color + + + + + <html><head/><body><p>选中告警时,告警的背景颜色</p></body></html> + <html><head/><body><p>The color of alarm backgournd when alarm selected</p></body></html> + + + + + 选中背景颜色 + Back Selected Color + + + + + <html><head/><body><p>无告警时,告警小窗中&quot;当前无告警&quot;文字颜色</p></body></html> + <html><head/><body><p>The text color of &quot;No alarm at present&quot; when no alarm</p></body></html> + + + + + 无告警文字颜色 + Text No Alarm + + + 选中颜色 + Selected color + + + 文字颜色 + Text color + + + 无告警颜色 + No alarm color + + + + + 语音引擎 + Speech engine + + + + + 引擎 + Engine + + + + + 语言 + Language + + + + + 语音名称 + Voice name + + + + + 确定 + OK + + + + + 取消 + Cancel + + + -1:重复 0:不报 x:重复x次 + -1:repeat x:repeat x times + + + + + 不报 + No Alarm + + + + + 重复 + Repeat + + + + + 重复x次 + Repeat x times + + + + CAlarmSetMng + + + + 当前无告警! + No alarm at present! + + + + + 未知告警等级 + Unknown Alarm Level + + + + CAlarmShield + + 屏蔽设备树 + Device Tree + + + + 新增 + New + + + + 批量启用 + Enable + + + + 批量取消 + Disable + + + + 批量删除 + Delete + + + + 屏蔽状态 + Shield Status + + + + 名称 + Name + + + + 查询 + Search + + + + + + + + + + 提示 + Prompt + + + + 请勾选一条未启用的屏蔽信息! + Please check a disable shield info! + + + + 屏蔽失败! + Enable failure! + + + + 请勾选一条已启用的屏蔽信息! + Please check a enable shield info! + + + + 解除失败! + Disable failure! + + + + 请先取消屏蔽! + Please disable first! + + + + 请勾选一条屏蔽信息! + Please check a shield info! + + + + 删除失败! + Delete failure! + + + + 全部 + All + + + + 未启用 + Disable + + + + 已启用 + Enable + + + + 已过期 + Expired + + + + CAlarmShield + CAlarmShield + + + + CAlarmShiledDialog + + + + 禁止告警 + Inhibit Alarm + + + + + 未找到插件 + No Plugin + + + + + 装载异常 + Load abnormal + + + + CAlarmStatWidget + + Form + Form + + + 按设备类型统计 + Statistics by device type + + + 按时间统计 + Time-based Statistics + + + PushButton + PushButton + + + 图表 + Chart + + + 列表 + List + + + 时间段 + Time Period + + + ~ + ~ + + + 设备类型: + Device Type: + + + yyyy-MM-dd + yyyy-MM-dd + + + 告警级别: + Alarm Level: + + + 查询 + Query + + + 位置: + Position: + + + 提示 + Tip + + + 警告 + Warning + + + 没有查询到任何站点信息 + No site information was found in the query. + + + 开始时间需小于等于结束时间 + The start time must be less than or equal to the end time. + + + 最多查询31天的数据 + You can query data for a maximum of 31 days. + + + + CAlarmStatisTableModel + + 统计日期 + Statistical Date + + + 区域名称 + Location + + + 设备类型 + Device Type + + + %1总数 + Number of %1 + + + + CAlarmStatisWidget + + 区域: + Location: + + + 统计方式: + Statistical Style: + + + 设备类型: + Device Type: + + + 开始时间: + Start Time: + + + 结束时间: + End Time: + + + 查询 + Search + + + 打印 + Print + + + 清除 + Clear + + + 日统计 + Day + + + 月统计 + Month + + + 年统计 + Year + + + 提示 + Prompt + + + 结束时间不能小于开始时间! + The end time cannot be less than start time! + + + 保存 + Save + + + 导出成功! +导出路径: + Exported successfully! +Exported path: + + + 保存失败 + Failed to save + + + + CAlarmStatistics + + + CAlarmStatistics + 告警统计 + + + + 位置 + Location + + + + 告警等级 + Alarm Level + + + + 时间段 + Time + + + 关键字 + Keyword + + + + 告警内容关键字 + Alarm Content Keywords + + + + 查询 + Search + + + + 普通告警 + Alarm + + + + 智能告警 + Intelligent Alarm + + + + 告警比对 + Alarm Compare + + + + 分析报告 + Analysis Report + + + + 22 + 22 + + + + 33 + 33 + + + + + 警告 + Warning + + + + 未选择告警等级 + No alarm selected + + + + 开始时间需小于等于结束时间 + The start time must equal or less than the end time + + + + + yyyy-MM-dd + yyyy-MM-dd + + + + - + - + + + + CAlarmTaskMngDlg + + + + 工单管理 + Work management + + + + + 作业组状态: + Work status: + + + + + 未创建 + No created + + + + + 创建作业组 + Create job group + + + + + 查看作业组 + View job group + + + + + 查看资产 + View assets + + + + + + + + + + + 提醒 + Remind + + + + + 艾动接口初始化失败 + Idong interface failed to initialize + + + + + + + 未关联作业组,请先关联作业组 + Assignment group not associated,please associate first + + + + + 创建作业组成功 + Successfully created job group + + + + + 创建作业组失败 + Faild to create job group + + + + + 获取作业组信息失败 + Failed to obtain job group information + + + + CAlarmWidget + + + + + + + + + + + + + + 确认 + Confirm + + + + + 当前用户不具备该告警所在位置的操作权限! + The current user does not have the operation authority of the location of the alarm! + + + + + 当前用户不具备该告警所在责任区的操作权限! + The current user does not have the operation authority of the responsible area of the alarm! + + + + CAnaAxisShow + + Hide This Channel + 隐藏此通道 + + + Restore to Default Group + 恢复至默认分组 + + + Wave Amplitude Zoom In + 波形幅度放大 + + + Wave Amplitude Zoom Out + 波形幅度缩小 + + + + CAnimationConfigDialog + + 动画配置 + Animation Configuration + + + 取消 + Cancel + + + 确定 + Confirm + + + 旋转动画 + Rotation Animation + + + 动画过渡间隔: + Animation Excessive Interval: + + + ms + ms + + + 关联测点: + Point: + + + ° + ° + + + 最小值 + Minimum + + + 旋转偏移角度 + Rotation offset + + + 最大值 + Maximum + + + 测点值 + Measuring Point Value + + + None + None + + + 动画值配置: + Animation Value Configuration: + + + 位移动画 + Translation Animation + + + 水平偏移像素 + Horizontal Offset Pixel + + + 垂直偏移像素 + Vertical Offset Pixel + + + px + px + + + 缩放动画 + Scale Animation + + + 水平缩放比例 + Horizontal Scaling + + + 垂直缩放比例 + Vertical Scaling + + + % + % + + + + CAssetDataMng + + + 需要导入的资产信息为空 + Asset info is empty + + + + 数据库打开失败,导入资产信息失败 + Failure to open database,failure to import asset info + + + + + 满足条件的导入条数为0 + No matched number + + + + 执行插入语句失败,导入资产信息失败 + Failure to insert sql,failure to import asset info + + + + + 一共%1条,成功导入%2条 + Total %1,%2 import successful + + + + 需要导入的维护记录为空 + Maintenance records is empty + + + + 数据库打开失败,导入维护记录失败 + Failure to open database,failure to import maintenance records + + + + 执行插入语句失败,导入维护记录失败 + Failure to insert sql,failure to import maintenance records + + + + CAssetTableModel + + + 设备名称 + Device Name + + + + 备注 + Remark + + + + 设备ID + DeviceId + + + + 型号 + Type + + + + 参数 + Parameter + + + + 安装日期 + Installation Date + + + + 状态 + Status + + + + 厂家联系方式 + Manufacturer Contact + + + + 维护周期 + Maintenance Period + + + + 一个月 + One Month + + + + 三个月 + Three Months + + + + 半年 + Six Months + + + + 一年 + One Year + + + + CAssetView + + + 全选 + Check All + + + + 全不选 + Unchecked All + + + + CAssetWidget + + + 添加 + Add + + + + 删除 + Delete + + + + 导入 + Import + + + + 导出 + Export + + + + 关键字 + Keywords + + + + 查询 + Search + + + + 未知设备组 + Unknonwn device group + + + + Save File + Save File + + + + 当前未选中任何项! + No item is currently selected! + + + + CAssetWidget + CAssetWidget + + + + 位置/设备组 + Location/DeviceGroup + + + + 设备组 + DeviceGroup + + + + 设备管理 + DeviceManage + + + + 添加资产信息 + Add asset info + + + + 同时会删除维护记录 + Delete maintenance records at the same time + + + + 对设备名称、型号、参数和内容生效 + Effective for device name、type、parameter and content + + + + 未知位置 + Unknonwn location + + + + + 提示 + Prompt + + + + 所属设备组 + Device Group + + + + Open File + Open File + + + + 请先选中位置或设备组 + Please select location and device group first + + + + 设备组为空 + Device group is empty + + + + 添加成功! + Successful add! + + + + 删除失败! + Failure to delete! + + + + 删除成功! + Successful delete! + + + + + 资产信息 + Asset info + + + + + 维护记录 + Maintenance records + + + + CBIWidget + + 用户不具有指定权限 + The user does not have the specified permissions + + + 无用户登录信息 + No user login information + + + 输入名称不存在 + The input name does not exist + + + 输入名称不唯一 + The input name is not unique + + + 不允许在该节点登录 + Logon on this node is not allowed + + + 用户口令错误 + Password error + + + 用户已失效 + User deactivated + + + 用户已锁定 + User locked + + + 用户不属于所选用户组 + The user does not belong to the selected user group + + + 未知错误,系统可能未正常启动 + Unknown error, system may not start properly + + + 未知错误 + Unknown error + + + 内存出错 + Memory error + + + + CBatchOperation + + + Dialog + Dialog + + + + 测点类型 + Type of measurement point + + + + 批量操作 + batch operation + + + + 执行 + Execute + + + + 全部 + All + + + + 模拟量 + Analog + + + + 数字量 + Digital + + + + 混合量 + Mix + + + + + + + 获取登录信息失败! + Failure to get login info! + + + + + 获取登录账户失败! + Failure to get login user! + + + + + 无标签操作权限! + Have no perm to operate! + + + + 测点“%1”,%2 + Test point “%1”, %2 + + + + 控制进行中 + Control in progress + + + + 下发取消命令失败 + Failure to send cancel command + + + + 提示 + prompt + + + + + 成功 + success + + + + 失败 + failure + + + + 失败:%1 + failure:%1 + + + + 批量编辑 + batch edit + + + + + 警告 + Warning + + + + + 暂不能批量操作! + Batch operation is temporarily unavailable! + + + + CBatchOperationModel + + + 测点信息 + Measurement point information + + + + 当前值 + Current Value + + + + 控制操作 + control operation + + + + 执行结果 + Executing results + + + + CBindCheckModel + + 检查结果 + Result + + + 对象名称 + Object Name + + + 点描述 + Description + + + 点标签 + Library + + + 正常 + Normal + + + 无对象名称 + No name + + + 对象名称重复 + Repeat name + + + 联库错误 + Library error + + + 未联库 + No library + + + + CBindCheckWidget + + 检查 + Check + + + 正常项 + Normal + + + 异常项 + abNormal + + + 未联库 + No library + + + + CBoxTreeWidget + + 搜索... + Search... + + + + CBrowserWidget + + 下载模板 + Download Template + + + + CButtonGroupWidget + + + 配置错误! + Configuration Error! + + + + CChanRealStatusWidget + + + 通讯状态 + Communication status + + + + 正常 + Normal + + + + 异常 + Abnormal + + + + 未找到组号%1! + Not found group %1! + + + + CChartShape + + 饼图 + Pie Chart + + + 棒图 + Bar Chart + + + 折线图 + Line Chart + + + 实时图 + Real-time Chart + + + + CColorConfigWidget + + 颜色选择 + Select Color + + + + CColorLabel + + + + 颜色选择 + Select Color + + + + CCombBoxDelegate + + 星期日 + Sunday + + + 星期一 + Monday + + + 星期二 + Tuesday + + + 星期三 + Wednesday + + + 星期四 + Thursday + + + 星期五 + Friday + + + 星期六 + Saturday + + + 否 + No + + + 是 + Yes + + + + CComtradeFile + + The Filename is Error! + 文件名错误! + + + The Path is Error! + 路径错误! + + + The Header File's Format is Error + 头部文件格式错误 + + + Config Files Open Failed + 配置文件打开失败 + + + Config File, Line + 配置文件,行 + + + Channel Count Error + 通道数量错误 + + + Channel Count Over Limited + 通道数量超过限制 + + + Wave Channel Data Lost! + 波形通道数据丢失! + + + on-off Channel Data Lost! + 开关通道数据丢失! + + + Format Error! + 格式错误! + + + Data File Open Failed + 数据文件打开失败 + + + Info File Open Failed + 信息文件打开失败 + + + Display Attribute + 显示属性 + + + SHENZHEN KANGBIDA CONTROL TECHNOLOGY CO.LTD + 深圳市远信储能技术有限公司 + + + Value Type + 值类型 + + + Sampling Width + 采样宽度 + + + Grid Height + 网格高度 + + + State Channel Height + 状态通道高度 + + + Analogous Channel Display + 模拟通道显示 + + + Analogous Channel Count + 模拟通道数量 + + + Analogous Channel + 模拟通道 + + + State Channel Display + 状态通道显示 + + + State Channel Count + 状态通道数量 + + + Status Channel + 状态通道 + + + + CConditionModel + + + 参数 + Parameter + + + + 条件 + Condition + + + + 且 + And + + + + 小于 %1 + less than %1 + + + + 小于等于 %1 + less than or equal to %1 + + + + 等于 %1 + equals %1 + + + + 大于等于 %1 + greater than or equal to %1 + + + + 大于 %1 + greater than %1 + + + + 不等于 %1 + not equal to %1 + + + + CConfigDialog + + 基础配置 + 配置 + Configuration + + + 背景: + Background: + + + * + * + + + 首页: + Homepage: + + + 像素 + Pixels + + + 页面配置 + Page Configuration + + + 分辨率: + Resolution: + + + 失电颜色: + Power Loss Color: + + + 单屏显示 + Single Screen Display + + + 多屏配置 + Multi-Screen Configuration + + + 脚本配置 + ScriptConfig + + + 屏幕个数: + Screen Number: + + + 确定 + Confirm + + + 取消 + Cancel + + + + CConfirmDialog + + 提交 + Submit + + + 日志信息: + Log Information: + + + 确认 + Confirm + + + 取消 + Cancel + + + 无修改 + No Changes + + + 添加 + Add + + + 冲突 + Conflict + + + 删除 + Delete + + + 忽略 + Ignore + + + 修改 + Modify + + + 替换 + Replace + + + 未纳入版本控制的目录,被外部引用的目录所创建 + Directory not under version control, created by an external reference + + + 未纳入版本控制 + Not under version control + + + 遗失 + Lost + + + 重名 + Duplicate Name + + + 自定义非法状态 + Custom Illegal State + + + 改变 + Changed + + + 未锁定 + Unlocked + + + 锁定 + Locked + + + 没有历史 + No History + + + 包含历史 + Contains History + + + 正常 + Normal + + + 以切换 + Switched + + + 被外部引用创建的文件 + Files created by external references + + + 没有被锁定标记 + Not marked as locked + + + 存在锁定标记 + Marked as locked + + + 树冲突 + Tree conflict + + + 名称 + Name + + + 状态 + Status + + + + CConstCurves + + + 查询 + Search + + + + 名称 + Name + + + + 值 + Value + + + + CConstCurves + CConstCurves + + + + + + 提示 + Prompt + + + + %1 定值读取失败: %2 + %1 failure to read const: %2 + + + + %1 定值读取超时 + %1 timeout + + + + %1 下发定值读取命令失败 + %1 failure to send read command + + + + CCurveChartView + + + 位置: + Location: + + + + 设备类型: + DeviceType: + + + + CCurveLegendModel + + + + 颜色 + Color + + + + + 值 + Value + + + + + 最大值 + Maximum + + + + + 最大值时间 + Maximum Time + + + + + 最小值 + Minimum + + + + + 最小值时间 + Minimum Time + + + + + 平均值 + Average Value + + + + + 单位 + Unit + + + + + Y轴缩放系数 + Yaxis Scaling Factor + + + + + Y轴偏移系数 + Yaxis Offset Factor + + + 名称 + Name + + + + + 设备组-测点 + DeviceGroup-Point + + + 设备-测点 + Device - Measurement Point + + + + CCurveLegendView + + + + 全不选 + Unchecked All + + + + + 删除 + Delete + + + + + 查看最大值 + Show Maximum + + + + + 查看最小值 + Show Minimun + + + + CDataBindModel + + 标签名称 + Label Name + + + + CDataBindView + + 提示 + Prompt + + + 当前测点已经存在! + The current measuring point already exists! + + + 警告 + Warning + + + 当前未选中任何行! + No rows are currently selected! + + + 删除 + Delete + + + 清空 + Clear + + + 新建 + New + + + + CDataOptWidget + + + + 专业 + Subsystem + + + + 设备组/点 + Device group/point + + + + 位置 + Location + + + + 刷新 + Refresh + + + + 全部 + All + + + + + + 未知 + Unknown + + + + CDataOptWidget + CDataOptWidget + + + + 位置: + Location: + + + + 标签类型: + Type: + + + 设备组 + Device Group + + + + 设备 + Device + + + 标签名 + Point Name + + + + 标签类型 + Type + + + + 操作时间 + Operate Time + + + + 设置值 + Value + + + + 状态文本 + State Text + + + + 主机 + Hostname + + + + 操作员 + Operator + + + + 用户组 + UserGroup + + + + 点标签 + Point Tag + + + + 表名 + Table Name + + + + 总数 + Total + + + + 取消设置 + Cancel + + + 无取消人工置数权限! + Have no perm to cancel manual setting! + + + + 获取当前登录用户失败! + Failed to retrieve the current logged-in user! + + + + 无操作权限! + No operation permission! + + + + 初始化权限失败! + Failure to initialize perm! + + + + 提示 + Prompt + + + + 请至少选择一项人工置数信息! + Please select a record first! + + + + 获取标签操作信息有误,%1 + Failure to read tag operate record,%1 + + + + 获取标签信息有误,%1 + Failure to read tag info,%1 + + + + 下发取消命令失败 + Failure to send cancel command + + + + CDataOptWork + + + 读取标签信息表失败 + Failure to read tag info + + + 读取标签信息表失败,或者请检查标签信息表中是否存在残留数据! + Failed to read the tag information table, or please check if there is any residual data in the tag information table! + + + + CDesignerScene + + 提示 + Prompt + + + 组合图元不可镜像! + Composite primitive cannot be mirrored! + + + 精灵图元不可镜像! + Sprite elements cannot be mirrored! + + + 控件图元不可镜像! + Wiget primitive cannot be mirrored! + + + 图表图元不可镜像! + Chart primitive cannot be mirrored! + + + + CDesignerView + + 视图 + View + + + 动画配置 + Animation Configuration + + + 添加到精灵图元 + Add to Sprite + + + 文字编辑 + Text Edit + + + 文本编辑 + Text Editor + + + 数据源配置 + Data Source Configuration + + + 检索器 + Retriever + + + 显示网格 + Show Grid + + + 网格间距 + Grid Spacing + + + 网格颜色 + Grid Color + + + 编辑图元 + Edit Primitive + + + 文本替换 + Text Replace + + + + CDesignerWnd + + 清空联库 + Clear Library + + + 设计窗口 + Design Window + + + 窗口 + Window + + + 图形已被修改! +保存所作的改动? + The graphics have been modified! +Save the changes? + + + 保存 + Save + + + 不保存 + Discard + + + 取消 + Cancel + + + 新建 + New + + + 提醒 + Warn + + + 请选择新建类型? + Select new type? + + + 新建图形 + New Graphics + + + 新建图元 + New primitive + + + 打开 + Open + + + 打开文件 + Open File + + + pic (*.glx *.ilx *.elx) + pic (*.glx *.ilx *.elx) + + + 提示 + Warn + + + 找不到文件: + File Not Found: + + + 保存文件 + Save File + + + 另存文件 + Save As File + + + 图元名称首字母不能为数字! + 图元名称的首字母不能是数字! + + + 图元名称只支持中文、字母、数字和下划线 + 图元名称仅支持中文、字母、数字和下划线 + + + 非法的命名 + Illegal naming + + + 精灵图元 + Sprite + + + 未设置所属专业.位置 + No Subsystem.Station + + + 无效的位置信息 + Invalid Station + + + 操作dev_topo_info失败 + Operate dev_topo_info failed + + + 操作dev_topo_ver失败 + Operate dev_topo_ver failed + + + 上传拓扑成功! + Successful upload topology! + + + F5 + F5 + + + 错误 + Error + + + 图表图元不允许嵌套! + Chart primitive are not allowed to be nested! + + + 当前选中的图元包含非基础图元! + The currently selected primitive contains non-base primitive! + + + 当前未选中图元! + No primitive are currently selected! + + + 取消组合的图元不允许超过一个! + No more than one uncombined primitive is allowed! + + + 当前选中的图元不是组合图元! + The currently selected primitive is not a composite primitive! + + + 执行上传拓扑? + Perform upload topology? + + + 确认 + Confirm + + + error + error + + + 未设置所属应用.专业.车站名 + No App.Subsystem.Station + + + 警告 + Warning + + + 操作数据库失败 + Failed to operate database + + + 关闭 + Close + + + Ctrl+N + Ctrl+N + + + Ctrl+O + Ctrl+O + + + Ctrl+S + Ctrl+S + + + F11 + F11 + + + 调试 + Debug + + + 重新联库 + Connect Library Again + + + Ctrl+F + Ctrl+F + + + 检索器 + Retriever + + + F2 + F2 + + + 图层管理 + Layer Management + + + Delete + Delete + + + Ctrl+C + Ctrl+C + + + 全选 + Check All + + + Ctrl+A + Ctrl+A + + + Ctrl+X + Ctrl+X + + + Ctrl+V + Ctrl+V + + + Ctrl+k + Ctrl+k + + + Ctrl+b + Ctrl+b + + + 添加图元 + Add primitive + + + 移除图元 + Remove primitive + + + 编辑图元 + Edit primitive + + + 增加图库 + Add Gallery + + + 删除图库 + Delete Gallery + + + 位置: + Location: + + + 栅格 + Grid + + + 捕捉 + Catch + + + 正交 + Quadrature + + + 属性编辑 + Property Edit + + + 联库信息 + Library Information + + + 模型检查 + Library Check + + + 图层 + Layer Management + + + + + + + + + - + - + + + 属性 + Attribute + + + 图层显示 + Layer Display + + + 状态 + State + + + 图层数量已达到最大值,不允许继续添加图层! + The number of layers has reached its maximum value. It is not allowed to continue adding layers! + + + 图层%1 + Layer%1 + + + 状态%1 + State%1 + + + %1 - %2[*] + %1 - %2[*] + + + 当前图元名称已存在,不允许重复添加! + The current primitive name already exists. Repeat addition is not allowed! + + + 请输入新建图库的名称 + Please enter the name of the new gallery + + + 图库名称不能为空! + Gallery name cannot be empty! + + + 图库名称首字母不能为数字! + Gallery name initials can not be a number! + + + 图库名称首字母不能为空格! + Gallery name initials can not be space! + + + 图库名称只支持中文、字母、数字和下划线 + The name of the graphic library only supports Chinese characters, letters, numbers, and underscores. + + + 该图库名称已存在! + The name of the gallery already exists! + + + 图元状态数量已达到最大值,不允许继续添加图元状态! + The maximum number of primitive states has been reached,continue to adding primitive state is not allowed! + + + 精灵图元编辑模式下不允许添加图层! + Sprite element editing mode does not allow adding layers! + + + 图层数量至少为1,不允许继续删除图层! + The number of layers should be at least 1,continue to delete layer is not allowed! + + + 图元状态数量至少为1,不允许继续删除图元状态! + The number of primitive state should be at least 1,continue to delete primitive state is not allowed! + + + 精灵图元编辑模式下不允许删除图层! + Deleting layers is not allowed in sprite element editing mode! + + + 非图表图元暂不支持关联统计量! + Correlation statistics are not supported for non-chart primitive! + + + 另存为 + Save as + + + 运行 + Run + + + 浏览 + Browse + + + 图形设计 + Graphic Design + + + 新建编辑图形 + New graphics + + + 工具箱 + ToolBox + + + 属性编辑器 + Property Editor + + + 设置 + Config + + + 页面配置 + Config + + + 全局变量 + Global Parameter + + + 着色策略 + Strategy + + + 文件同步 + FileSync + + + web发布 + Web Publish + + + 上传拓扑 + UploadTopo + + + 脚本编辑器 + Script Editor + + + 剪切 + Cut + + + 拷贝 + Copy + + + 复制 + Copy + + + 粘贴 + Paste + + + 撤消 + Undo + + + 恢复 + Redo + + + 删除 + Delete + + + 组合 + Group + + + 取消组合 + Ungroup + + + 上移一层 + Level Up + + + 下移一层 + Level Down + + + 置顶 + To Top + + + 置底 + To Bottom + + + 左对齐 + Left Align + + + 右对齐 + Right Align + + + 上对齐 + Top Align + + + 下对齐 + Bottom Align + + + 水平居中对齐 + Horizontal Center Align + + + 垂直居中对齐 + Vertical Center Align + + + 水平等距 + Horizontal Equidistant + + + 垂直等距 + Vertical Equidistant + + + 水平镜像 + Horizontal Mirror + + + 垂直镜像 + Vertical Mirror + + + 等大 + EqualLarge + + + 等小 + EqualSmall + + + 位置工具 + Align Tool + + + 文件(&F) + File(&F) + + + 窗口(&W) + Window(&W) + + + 系统(&S) + System(&S) + + + 工具(&T) + Tool(&T) + + + 编辑(&E) + Edit(&E) + + + 页面 + Page + + + + CDevHisDataWidget + + + 区域: + Location: + + + + 开始时间: + Start Time: + + + + 设备类型: + Device Type: + + + + 结束时间: + End Time: + + + + 设备名称: + Device Name: + + + + 查询 + Search + + + + Excel + Excel + + + + Pdf + Pdf + + + Excel格式导出 + Export to Excel Format + + + Pdf格式导出 + Export to PDF Format + + + + 打印 + Print + + + + 清除 + Clear + + + + + 保存 + Save + + + + + + + 提示 + Prompt + + + + + 导出成功! +导出路径: + Exported successfully! +Exported path: + + + + + 保存失败 + Failed to save + + + + CDevHisDataWidget + CDevHisDataWidget + + + + + yyyy-MM-dd HH:mm + yyyy-MM-dd HH:mm + + + + CDevHisTableModel + + + 日期/时间 + Date/Time + + + + 设备名称 + Device Name + + + + 所属区域 + Location + + + + CDevRealDataWidget + + + 位置 + Location + + + + 点类型 + Point Type + + + 设备 + Device + + + + 设备组 + DevGroup + + + + 专业 + Subsystem + + + 过滤 + Filter + + + 按测点过滤 + Filter by measuring point + + + + 禁止告警 + Inhibit Alarm + + + + 全部 + All + + + + 模拟量 + Analog + + + + 数字量 + Digital + + + + 累积量 + Accuml + + + + 混合量 + Mix + + + + 测点关键字查询 + Measurement Point Keyword Search + + + + 查询 + Query + + + + 所有 + All + + + + CDevRealDataWidget + 实时数据控件 + + + + 关键字查询 + Keyword Search + + + + 禁止控制 + Prohibit Control + + + + 恢复控制 + Resume Control + + + + 禁止刷新 + Prohibit Refresh + + + + 恢复刷新 + Resume Refresh + + + + 恢复告警 + Resume Alarm + + + + 人工置数 + Manual Setting + + + + 取消置数 + Cancel Setting + + + + + 查询设备组信息失败! + Failed to retrieve device group information! + + + + + + + 请至少选择一项! + Please select at least one item! + + + + 行“%1”,%2 + Row "%1", %2 + + + + “%1”等,共(%2)项 + "%1" and others, a total of (%2) items + + + + + + “%1”,%2 + "%1", %2 + + + + 下发取消命令失败 + Failure to send cancel command + + + + 提示 + Prompt + + + + + 获取登录信息失败! + Failure to get login info! + + + + 获取登录账户失败! + Failure to get login user! + + + + 无标签操作权限! + Have no perm to operate! + + + + CDevSpePointWidget + + + + + 测点标签为空! + Measurement point label is empty! + + + + + + 数据库连接打开失败! + Failed to open the database connection! + + + + + + 测点标签不合法! + + 测点标签不合法! + Measurement point label is not valid! + + + + + + 重复添加! + + 重复添加! + Duplicate addition! + + + + + 查询设备描述失败! + + 查询设备描述失败! + Failed to query device description! + + + + + 传入参数个数不一致! + Number of input parameters is inconsistent! + + + + CDevTreeModel + + + 位置/设备组/设备 + Location/DevGroup/Device + + + + CDevTreeView + + + 全选 + Check All + + + + 清空 + Clear + + + + CDeviceNavWidget + + Form + Form + + + + CDgtNameShow + + Hide This Channel + Hide This Channel + + + Restore to Default Group + Restore to Default Group + + + + CDisposalPlanDialog + + + + Dialog + Dialog + + + + + 告警时间: + Alarm Time: + + + + + 告警内容: + Alarm Content: + + + + + 处置预案: + Disposal Plan: + + + + + 处置预案 + Disposal Plan + + + + CDocumentManageWidget + + + 文档管理 + Document Management + + + + 添加 + Add + + + + 修改 + Modify + + + + + 删除 + Delete + + + + 下载 + Download + + + + 上传 + Upload + + + + 查询 + Search + + + + 输入文档名称查询 + Enter Document Name to Search + + + + 打开 + Open + + + + CDrillDownChart + + + 位置 + Location + + + + 总共: + Total: + + + + CDropListWidget + + 删除选中项 + Delete the selected item + + + + CDutyDefineDialog + + Dialog + Dialog + + + 保存 + Save + + + 添加一行 + Add a row + + + 删除最后一行 + Delete the last row + + + + CDutySetting + + 导出 + Export + + + 保存 + Save + + + CDutySetting + CDutySetting + + + 用户组 + UserGroup + + + 上一周 + Last week + + + 本周 + This week + + + 下一周 + Next week + + + 引用上周 + Refer to last week + + + 班次管理 + Shift management + + + 选择导出目录 + Select the export directory + + + + CEditCollectWidget + + + + 趋势名称: + Trend Name: + + + + + 确定 + Confirm + + + + + 取消 + Cancel + + + + CEventDataCollect + + + + 其他 + Other + + + + 系统信息 + System Information + + + + CEventDeviceTreeModel + + + + 系统信息 + System Information + + + + .系统 + .system + + + + CEventDeviceTreeView + + + 全选 + Check All + + + + 清空 + Clear + + + + 选择 + Select + + + + 清除 + Clear + + + + CEventFilterDialog + + + + 过滤 + Filter + + + + + 优先级 + Priority + + + + + + + + + + + 全选 + Check All + + + + + 位置 + Location + + + + + 责任区 + Responsibility Area + + + + + 事件状态 + Event State + + + + + 设备类型 + Device Type + + + + + 事件内容关键字 + Event content keywords + + + + + 时间 + Time + + + + + 开始时间 + Start Time + + + + + 结束时间 + End Time + + + + + 确定 + Confirm + + + + + 取消 + Cancel + + + + + + + yyyy/MM/dd hh:mm + yyyy/MM/dd hh:mm + + + 区域 + Location + + + + + 复归 + Resume + + + + + 已复归 + Resumed + + + + + 未复归 + unResumed + + + + + + + + + 提示 + Prompt + + + + + 历史事件过滤必须选择时间! + Select time before filter! + + + + + 开始时间不能大于结束时间! + The start time cannot more than the end time! + + + + + 时间间隔不得超过90天! + The time interval cannot more than 90 days! + + + + CEventForm + + + + 事件 + Event + + + + + 位置: + Location: + + + + + 时间: + Time: + + + + 刷新 + Refresh + + + + + 过滤 + Filter + + + + 全勾选 + Select All + + + + 全不选 + Deselect All + + + + + 清空 + Clear + + + + + 导出 + Export + + + + + 优先级: + Priority: + + + + + 关闭 + Close + + + + + 事件状态: + Event State: + + + 事件总数: + Number of Event: + + + + + + + 按设备组关键字搜索 + Search by device group keyword + + + + + + + + + 请选择时间 + Select time + + + + + + + + + + + + + + + 请选择优先级 + Select priority + + + + + + + + + + + + + + + 请选择位置 + Select location + + + + + + + 请选择告警状态 + Select Alarm State + + + + + + + + + + + 请选择事件状态 + Select event state + + + + + + + 事故追忆 + Accident Memory + + + + + 实时事件 + RealTime Event + + + + + 历史事件 + Historical Event + + + 实时事件总数: + RealTime Event: + + + + + 正在查询历史事件... + Querying historical events... + + + + + 错误 + Error + + + + + 当前用户不具备事件浏览权限 + The current user does not have the right to browse the events + + + + + 导出成功 + Export succeeded + + + 历史事件数量: + History Event: + + + + + + + + + 提示 + Prompt + + + %1 历史事件数量超出%2条,未予显示! + The number of %1 historical events exceeds %2,not displayed! + + + + + + + 实时事件总数: + Total number of realtime event: + + + + + + + 0 + 0 + + + + + 历史事件总数: + Total number of historical event: + + + + + 历史事件数量: + Number of historical event: + + + + + 历史事件数量超出10000条,超出部分不显示 + The number of historical events beyond 10000,the excess part does not show + + + + + + + 历史事件数量超出%1条,未予显示! + The number of historical events beyond %1,not shown! + + + + + Save File + Save File + + + + CEventHistoryModel + + + + 时间 + Time + + + + + 优先级 + Priority + + + + + 位置 + Location + + + + + 责任区 + Responsibility Area + + + + + 事件类型 + Event Type + + + + + 事件状态 + Event State + + + + + 确认人 + Confirmor + + + + + 确认时间 + Confirm time + + + + 事件内容 + Event Content + + + + + 复归状态 + Resume Status + + + + 事件内容 + Event Content + + + + + 未复归 + unResumed + + + + + 已复归 + Resumed + + + + CEventItemModel + + + + 时间 + Time + + + + + 优先级 + Priority + + + + + 位置 + Location + + + + + 责任区 + Responsibility Area + + + + + 事件类型 + Event Type + + + + + 事件状态 + Event State + + + + + 事件内容 + Event Content + + + + + 复归状态 + Resume Status + + + + + 未复归 + unResumed + + + + + 已复归 + Resumed + + + + CExplorerWnd + + 打开文件 + Open File + + + 提示 + Prompt + + + 加密狗运行异常! + Dongle running abnormal! + + + 加密狗检测正常! + Dongle detection normal! + + + 确认退出系统? + Exit system? + + + 确认 + Confirm + + + 取消 + Cancel + + + 编辑图形 + Edit graphics + + + Ctrl+d + Ctrl+d + + + 加密狗状态 + Dongle state + + + Ctrl+R + Ctrl+R + + + Ctrl+E + Ctrl+E + + + 退出 + Exit + + + 导航图 + Navigation Chart + + + %1 - %2 + %1 - %2 + + + 导出图形 + Export graphics + + + 图形文件(*.png) + Graphics file(*.png) + + + + CFaultRecallRecordWidget + + + + 位置 + Location + + + + 名称 + Name + + + + 刷新 + Refresh + + + + 清空 + Clear + + + + 删除 + Delete + + + + 全部 + All + + + + CFaultRecallRecordWidget + CFaultRecallRecordWidget + + + + + 开始时间 + Start time + + + + + 结束时间 + End time + + + + 画面 + Graph + + + + 播放 + Play + + + + + + + 提示 + Prompt + + + + 请选择一项记录! + Please select a record! + + + + 确定开始播放“%1”? + Confirm to start playing “%1”? + + + + 请选择删除项! + Please select a record! + + + + 确定删除记录“%1”? + Confirm to delete “%1”? + + + + + + 打开数据库失败。 + Failure to open database. + + + + 删除“%1”失败! + Failure to delete “%1”! + + + + 确定清空所有记录? + Confirm to clear all records? + + + + 清空失败! + Failure to clear! + + + + CFileFolderTree + + + 名称: + Name: + + + + + + + + + + + + + + + 提示 + Hint + + + + 非法的命名 + Illegal Naming + + + + + + 当前登录用户无运维管理功能权限 + The current logged-in user does not have operational management permissions + + + + 添加目录 + Add Directory + + + + + 目录已存在 + The directory already exists + + + + 添加目录失败 + Failed to add the directory + + + + 请选择要修改的目录 + Please select the directory to modify + + + + 修改目录名称 + Modify directory name + + + + 修改目录名称失败 + Failed to modify the directory name + + + + 请选择要删除的目录 + Please select the directory to delete + + + + 确认删除? + Confirm on delete? + + + + 删除目录失败 + Failed to delete the directory + + + + + 添加 + Add + + + + 修改 + Modify + + + + 删除 + Delete + + + + CFileSyncDialog + + 文件同步 + FileSync + + + 提交 + Submit + + + 删除 + Delete + + + 添加 + Add + + + 提示 + Hint + + + 无需添加 + No need to add + + + 确认添加 + Confirm to add + + + 添加失败: + Add failed: + + + 无需删除 + No need to delete + + + 确认删除 + Confirm + + + 删除失败: + Deletion failed: + + + 选择文件 + Select File + + + 名称 + Name + + + 修改日期 + Modification Date + + + 状态 + Status + + + (异常) + (Abnormal) + + + 无需提交 + No Need to Submit + + + 提交失败: + Submission Failed: + + + + CFileTableWidget + + + + + + + + + + + + + + + + + + 提示 + Hint + + + + + 当前登录用户无运维管理功能权限 + The current logged-in user does not have operational management permissions + + + + 请选择上传目录 + Please select the upload directory + + + + 上传文档 + Upload document + + + + + 文档已存在: %1,是否替换? + The document already exists: %1, do you want to replace it? + + + + %1 上传失败 + %1 Upload failed + + + + 上传成功 + Upload successful + + + + + + 请选择文档 + Please select a document + + + + 请选择下载路径 + Please select a download path + + + + %1 下载失败 + %1 Download failed + + + + 下载成功 + Download successful + + + + 确认删除? + Confirm on delete? + + + + 删除 %1 失败 + Failed to delete %1 + + + + 文档不存在 + The document does not exist + + + + 打开文档失败 + Failed to open the document + + + + 序号 + Serial Number + + + + 文档名称 + Document Name + + + + 文档修改时间 + Document Modification Time + + + + 文档路径 + Document Path + + + 请选择一个录波文件 + Please select an oscillogram file + + + 请选择导出路径 + Please select an export path + + + 文件已存在: %1,是否替换? + File already exists: %1, do you want to replace it? + + + %1 导出失败 + %1 Export failed + + + 导出成功 + Export succeeded + + + 设备名 + Device Name + + + 创建时间 + Creation Time + + + 文件名 + File Name + + + + CFindReplace + + 已替换:%1个 + Replaced: %1 + + + + CFlowLine + + 潮流颜色 + Flow color + + + 潮流长度 + Flow lenth + + + + CGTableWidget + + 导出xlsx文件为 + Export xlsx file to + + + + CGlobalConfigDialog + + 全局变量 + Global Parameter + + + + + + + + + - + - + + + 确定 + Confirm + + + 取消 + Cancel + + + 描述 + Description + + + 名称 + Name + + + 类型 + Type + + + 值 + Value + + + 提示 + Prompt + + + 保存失败! + Failed to save! + + + 数值型 + Number + + + 布尔型 + Bool + + + 字符串 + String + + + + CGraphApp + + 提示 + Prompt + + + 系统未启动! + System not started! + + + 加密狗检测异常! + WatchDog running abnormal! + + + 加密狗运行异常! + WatchDog running abnormal! + + + + CGraphDataAcess + + 用户不具有指定权限 + The user does not have the specified permissions + + + 无用户登录信息 + No user login information + + + 输入名称不存在 + The input name does not exist + + + 输入名称不唯一 + The input name is not unique + + + 不允许在该节点登录 + Logon on this node is not allowed + + + 用户口令错误 + Password error + + + 密码错误 + Password error + + + 用户已失效 + User deactivated + + + 用户已锁定 + User locked + + + 用户不属于所选用户组 + The user does not belong to the selected user group + + + 未知错误,系统可能未正常启动 + Unknown error, the system may not have started properly + + + 未知错误 + Unknown error + + + 内存出错 + Memory error + + + + CGraphFileTree + + 搜索... + Search... + + + 刷新 + 刷新 + + + + CGraphView + + 标题 + Title + + + 图幅 + Sheet + + + 背景色 + Background Color + + + 背景图片 + Background Image + + + 是否缩放 + Whether to Zoom + + + 是否拓扑 + Whether Topology + + + 自适应显示 + Adaptive display + + + 窗口标识 + Window Identifier + + + 发布类型 + Publish Type + + + 图层显示 + Layer Display + + + 窗口关闭按钮 + Window Close Button + + + 专业.位置 + Subsystem.Station + + + 模态 + Modal + + + 平面显示 + Graphic Display + + + 是否带电:%1 + Charged:%1 + + + 设备名:%1 +所属站:%2 +值:%3 +状态:%4 +%5 + Device Name:%1 Location:%2 Value:%3 State:%4 %5 + + + 设备名:%1 +所属站:%2 +值:%3 +状态:%4 + Device Name:%1 Location:%2 Value:%3 State:%4 + + + + CGridShape + + 网格线颜色 + Gridline color + + + 网格填充颜色 + Grid color + + + 交替填充颜色 + Alternate color + + + + CGroupManageDialog + + + 轮询组配置 + Polling Group + + + + + 新增 + Add + + + + + 删除 + Delete + + + + 保存 + Save + + + + 轮询组 + Group + + + + 提示 + Prompt + + + + 轮询组不能为空! + Polling group cannot be empty! + + + + 轮询组不能重复! + Polling group cannot repeat! + + + + 轮询组不能有特殊符号! + Polling group invalid! + + + + CHangPanelWidget + + + 位置 + Location + + + + 设备名称 + Device Name + + + + 专业 + Subsystem + + + + 操作主机 + Hostname + + + + 操作人 + Operator + + + + 刷新 + Refresh + + + + + + 未知 + Unknown + + + + CHangPanelWidget + CHangPanelWidget + + + + 位置: + Location: + + + + 专业: + Subsystem: + + + + 设备组 + Device Group + + + + 挂牌类型 + Type + + + + 挂牌时间 + Time + + + + 操作人组 + Operator Group + + + + 备注信息 + Remark + + + + 标签名 + Tag Name + + + + 总数 + Total + + + + 取消挂牌 + Cancel + + + + 无取消挂牌操作权限! + Have no perm to operate! + + + + 初始化权限失败! + Failure to initialize perm! + + + + 提示 + Prompt + + + + 请选择一项挂牌信息! + Please select a record! + + + + + 获取标签挂牌信息有误,%1 + Failure to read token info,%1 + + + + 下发取消挂牌命令失败 + Failure to send cancel command + + + + CHangPanelWork + + + 读取标签信息表失败 + Failure to read tag info + + + + CHisEventManage + + + + + + 未查询到该设备相关事件! + No event related to this device was found! + + + + CHistoryActionModel + + + + 动作 + Action + + + 车站 + Location + + + + + 描述 + Description + + + + + 执行结果 + Executing results + + + + + 位置 + Location + + + + CHistoryLinkFilterDialog + + + 过滤 + Filter + + + + 位置 + Location + + + + 用户 + User + + + + 结果 + Result + + + + 类型 + Type + + + + 时间 + Time + + + + 起始时间: + Start Time: + + + + 结束时间: + End Time: + + + + 执行成功 + execution success + + + + 执行失败 + execution failure + + + + 执行终止 + execution termination + + + + 执行跳过 + execution skip + + + + 标准联动 + Standard Linkage + + + + 自定义联动 + Custom Linkage + + + + CHistoryLinkModel + + + 名称 + Name + + + 车站 + Location + + + + 时间 + Time + + + + 用户 + User + + + + 类型 + Type + + + + 执行结果 + Executing results + + + + 位置 + Location + + + + CHistorySequenceFilterDialog + + + 过滤 + Filter + + + + 位置 + 车站 + Location + + + + 用户 + User + + + + 结果 + Result + + + + 类型 + Type + + + + 标准顺控 + Standard sequence + + + + 自定义顺控 + Custom sequence control + + + + 时间 + Time + + + + 起始时间: + Start Time: + + + + 结束时间: + End Time: + + + + 执行成功 + execution success + + + + 执行失败 + execution failure + + + + 执行终止 + execution termination + + + + 执行跳过 + execution skip + + + + CHistorySequenceModel + + + 名称 + Name + + + 车站 + Location + + + + 时间 + Time + + + + 用户 + User + + + + 类型 + Type + + + + 执行结果 + Executing results + + + + 位置 + Location + + + + 标准顺控 + Standard sequence control + + + + 自定义顺控 + Custom sequence + + + + CHmiConfig + + 屏幕首页面 + Home Screen + + + 屏幕号 + Screen Number + + + 提示 + Prompt + + + 保存失败! + Failed to save! + + + 描述 + Description + + + 名称 + Name + + + 类型 + Type + + + 值 + Value + + + 数值型 + Number + + + 布尔型 + Bool + + + 字符串 + String + + + + CIconActDialog + + + + 图元动作 + Graphic Element Action + + + + 添加 + Add + + + + + + + + + + + 删除 + Delete + + + + - + - + + + + 确认 + Confirm + + + + 取消 + Cancel + + + + 选择文件 + Select File + + + + + 提示 + Hint + + + + + 保存失败! + Save Failed! + + + + 左键单击 + Left-click + + + + 左键双击 + Double-click with the left mouse button + + + + 禁止 + Prohibit + + + + 允许 + Allow + + + + CInputDialog + + + 批量操作 + Batch Operation + + + + 设置值: + Setting value: + + + + 设置值 + Setting value + + + + 确定 + confirm + + + + 取消 + cancel + + + + CLayerDlg + + 图层工具 + Layer Tool + + + + CLimitOptWidget + + + 确认 + Confirm + + + + 关闭 + Close + + + + + 未知 + Unknown + + + + 否 + No + + + + 是 + Yes + + + + CLimitOptWidget + CLimitOptWidget + + + + + + + + + + 提示 + Prompt + + + + %1[%2-%3], 无标签操作权限! + %1[%2-%3], not perm! + + + + 设置成功 + Setting successful + + + + 设备属性 + Name + + + + 是否越限 + Limit + + + 越限级别数量 + Limit Number + + + + 越限级别 + Exceedance Level + + + + 越上限 + Upper Limit + + + + 越下限 + Lower Limit + + + + 越上上限 + Upper Limit 2 + + + + 越下下限 + Lower Limit 2 + + + + 越三级上限 + Upper Limit 3 + + + + 越三级下限 + Lower Limit 3 + + + + 越上限应大于越下限! + The upper limit must more than the lower limit! + + + + 越上上限应大于越下下限! + The upper limit 2 must more than the lower limit 2! + + + + 越下下限应小于越下限! + The lower limit 2 must less than the lower limit! + + + + 越上上限应大于越上限! + The upper limit 2 must more than the upper limit! + + + + 无越限 + No Exceedance + + + + 一级越限 + First-Level Exceedance + + + + 二级越限 + Second-Level Exceedance + + + + CLimitOptWork + + + 系统初始化失败! + Failure to initialize system! + + + + 更改是否越限失败! + Failure to set isLimit! + + + + 更改越限信息失败! + Failure to change limit info! + + + + 越限设置 + Set limit + + + + 取消越限设置 + Cancel limit + + + + 操作员: + Operator: + + + + 操作主机: + Hostname: + + + + CLineEditWithBt + + + + 选择文件 + Select File + + + + CLineEditWithBtn + + + 选择文件 + Select file + + + + CLineStatusShow + + Line B + Line B + + + Dot No. + Dot No. + + + Absolute Timestamp + Absolute Timestamp + + + Relative Time Difference + Relative Time Difference + + + Line C + Line C + + + Dot Difference + Dot Difference + + + Time Difference + Time Difference + + + + CLinkCtrlTableModel + + + 联动名称 + Linkage Name + + + + 联动类型 + Linkage Type + + + + 联动状态 + Linkage State + + + + 执行方式 + Executive Mode + + + + 触发时间 + Trigger Time + + + 车站火灾 + Location fire + + + 区间阻塞 + Interval blocking + + + 日常运营 + Daily operations + + + 自定义1 + Custom 1 + + + 自定义2 + Custom 2 + + + + 未执行 + non execution + + + + 正在执行 + executing + + + + 已触发 + triggered + + + + 执行失败 + execution failure + + + + 执行成功 + execution success + + + + 执行终止 + execution termination + + + + 执行暂停 + execution pause + + + + 执行跳过 + execution skip + + + + 过期配置 + Expired Configuration + + + + 全自动 + Automatic + + + + 半自动 + Simi-automatic + + + + 手动 + Manual + + + + 请点击“所有联动”按钮刷新配置 + Please click the "All Linkages" button to refresh the configuration + + + + CLinkCtrlTreeModel + + + 内容 + Content + + + + 选择 + Select + + + + 执行方式 + Executive Mode + + + + 延迟时间 + Delay Time + + + + 失败处理 + Failure handling + + + + 执行状态 + Executive state + + + + 串行 + Serial + + + + 并行 + Parallel + + + + 秒 + second + + + + 自动跳过 + Automatic skip + + + + 人工干预 + Manual intervention + + + + 终止联动 + 自动终止 + Linkage termination + + + + 执行下个功能 + 自动重试 + Next Function + + + + 未执行 + non execution + + + + 正在执行 + executing + + + + 已触发 + triggered + + + + 执行失败 + execution failure + + + + 执行成功 + execution success + + + + 执行终止 + execution termination + + + + 执行暂停 + execution pause + + + + 执行跳过 + execution skip + + + + CLinkCtrlWidget + + + 联动 + Linkage + + + 联动分类 + Classification of Linkage + + + + 待执行联动 + Pending linkage + + + + 所有联动 + All linkage + + + + 联动类型 + Linkage Type + + + 车站火灾 + Location fire + + + 区间阻塞 + Interval blocking + + + 日常运营 + Daily operations + + + 自定义1 + Custom 1 + + + 自定义2 + Custom 2 + + + + 联动列表 + LinkageList + + + + 搜索 + Search + + + + 动作列表 + ActionList + + + + + 终止 + Terminate + + + + 执行 + Execute + + + + 单步 + Step + + + + + + + + + + 暂停 + Pause + + + + 导出 + Export + + + + 打印 + Print + + + + + + + 当前用户不具备联动操作权限! + The current user does not have linkage operation authority! + + + + + + + 错误 + Error + + + + + + + 当前未选中联动 + Not linkage selected currently + + + + + + 继续 + continue + + + + + 联动名称: + Linkage Name: + + + + 错误代码: + Error code: + + + + 错误描述: + Error description: + + + + 联动操作请求失败 + Linkage operation request failed + + + + 执行失败,请求人工干预! + Execution failed, manual intervention request! + + + + 功能名称: + Function name: + + + + 动作名称: + Action name: + + + + 人工干预请求 + Manual intervention request + + + + 重试 + Retry + + + + 跳过 + Skip + + + + Save File + Save File + + + + + 联动报告 + Linkage Report + + + + 历史列表 + HistoryList + + + + 执行详情 + Execute Detail + + + + 过滤 + Filter + + + + (*.pdf *) + (*.pdf *) + + + + CLinkLine + + 置换端 + Displacement end + + + + CLoadDefTblWidget + + 位置 + Location + + + 添加记录 + Translate the following string into English: "添加记录" + + + 删除记录 + Translate the following string into English: "删除记录" + + + 撤销更改 + Translate the following string into English: "撤销更改" + + + 保存 + Save + + + Excel导出 + Translate the following string into English: "Excel导出" + + + Excel导入 + Translate the following string into English: "Excel导入" + + + + CLocationSequModel + + + 标记 + Marker + + + + 场站 + Station + + + + 顺控名称 + Sequence name + + + + 执行状态 + Execution status + + + + 未执行 + Not executed + + + + 正在执行 + Executing + + + + 已触发 + triggered + + + + 执行失败 + execution failure + + + + 执行成功 + execution success + + + + 执行终止 + execution termination + + + + 执行暂停 + execution pause + + + + 执行跳过 + execution skip + + + + CLoginDlg + + 登录 + Login + + + 用户 + User + + + 用户组 + UserGroup + + + 密码 + Password + + + 取消 + Cancel + + + 警告 + Warning + + + 登录失败 + Login Failed + + + + CMainWidget + + + 告警统计 + Alarm Statistic + + + + 告警对比 + Alarm Compare + + + + CMainWindow + + + CMainWindow + CMainWindow + + + + 设备/点 + Device/Point + + + + 清除测点 + Clear Measurement Points + + + + 收藏夹 + Favorite + + + + CMediaAVWidget + + Form + Form + + + current time + current time + + + duration + duration + + + 多媒体 + Multimedia + + + + CMediaWidget + + CRobotLinkCtrlWidget + CRobotLinkCtrlWidget + + + 多媒体 + Multimedia + + + + CMsgDeal + + + + + + + + + + + + + + + + + 发送消息失败 + Failed to send message + + + + + + 创建系统信息访问库实例失败! + Failed to create an instance of the system information access library! + + + + 权限接口初始化失败! + Failed to initialize the permission interface! + + + + 总线订阅失败! + Failed to subscribe to the bus! + + + + + + 消息解析错误 + Error parsing message + + + + + + 未知的命令 + Unknown command + + + + + + 未接收到消息 + No message received + + + + CMyCalendar + + + + + + + Form + Form + + + + + + + + 至 + To + + + + + + + + 取消 + Cancel + + + 确认 + Confirm + + + + CNTPTimeWidget + + + CNTPTimeWidget + CNTPTimeWidget + + + + IP设置 + IP Settings + + + + + + + + 设置 + Settings + + + + 网卡 + Network Card + + + + IP地址 + IP Address + + + + 子网掩码 + Subnet Mask + + + + 网关 + Gateway + + + + 控制投退 + control throwback + + + + 是否启用 + whether to enable + + + + 启用 + Enable + + + + 禁用 + Disable + + + + 亮度调节 + Brightness adjustment + + + + 亮度设置 + Brightness setting + + + + 时间设置 + Time Settings + + + + 时间 + Time + + + + 日期 + Date + + + + hh:mm:ss + hh:mm:ss + + + + yyyy-MM-dd + yyyy-MM-dd + + + + NTP设置 + NTP Settings + + + + 是否开启NTP + Enable NTP + + + + 否 + No + + + + 是 + Yes + + + + NTP服务器 + NTP Server + + + + NTP设置失败:%1,主机名:%2 + NTP setting failed: %1, hostname: %2 + + + + NTP设置成功 + NTP setting succeeded + + + + 时间设置失败:%1,主机名:%2 + Time setting failed: %1, hostname: %2 + + + + 时间设置成功 + Time setting succeeded + + + + 设置时间失败,请先关闭NTP + Failed to set the time, please turn off NTP first + + + + IP设置失败:%1,主机名:%2 + IP setting failed: %1, hostname: %2 + + + + IP设置成功 + IP setting succeeded + + + + 亮度设置失败:%1,主机名:%2 + Failed to set brightness: %1, hostname: %2 + + + + 亮度设置成功 + Brightness setting successful + + + + CNavigationConfigDialog + + + + + + 打开 + Open + + + + + + + + + 新建项目_ + New Item + + + + CNavigationDialog + + + 导航栏配置工具 + Navigation Bar Configuration Tool + + + + MainWindow + MainWindow + + + + 添加节点 + Add Node + + + + + + + + + + + 添加子节点 + Add ChildNode + + + + ∟ + + + + + 删除节点 + Delete Node + + + + - + - + + + + 清空节点 + Clear Node + + + + × + Close (X) + + + + 上移节点 + Move Node Up + + + + ↑ + Up Arrow + + + + 下移节点 + Move Node Down + + + + ↓ + Down Arrow + + + + + 导入 + Import + + + + + 导出 + Export + + + + 确认 + Confirm + + + + 取消 + Cancel + + + + 属性 + Attribute + + + + + 是否使用 + Enable + + + + + 操作 + Operation + + + + + 图标 + Icon + + + + + 数据 + Data + + + + Web发布 + Web Publishing + + + + Web类型 + Web Type + + + + + 网址 + Website URL + + + + 是 + Yes + + + + + 否 + No + + + + 切换画面 + Switch Screen + + + + 切换导航 + Switch navigation + + + + 调用程序 + call program + + + + 加载网页 + Load Webpage + + + + + 自定义项目 + Custom Item + + + + 新建项目_ + New Project + + + + 最大支持四层结构: %1-%2-%3-%4 + Maximum of four levels of structure supported: %1-%2-%3-%4 + + + + 全部展开 + ExpandAll + + + + 全部收缩 + CollapseAll + + + + + + + + + + + 提示 + Hint + + + + 保存失败! + Save Failed! + + + + 页面 + Page + + + + 一级 + First Level + + + + 二级 + Second Level + + + + 三级 + Third Level + + + + web发布 + Web deployment + + + + web类型 + Web type + + + + 导出成功! +导出路径: + Exported successfully! +Exported path: + + + + 导出失败 + Export Failed + + + + + + 行: %1, [%2] 不符合规范! + Line: %1, [%2] does not comply with the standard! + + + + CNavigationWidget + + + 导入 + Import + + + + 导出 + Export + + + 当前节点名称 + Node Name + + + 画面文件 + Data File + + + 图标文件 + Icon File + + + 上级节点名称 + Second Node + + + 上上级节点名称 + First Node + + + + 是 + Yes + + + + 否 + No + + + + + 提示 + Prompt + + + + 导出成功! +导出路径: + Exported successfully! +Exported path: + + + + 保存失败 + Failure to save + + + + 切换画面 + switch graph + + + + 调用程序 + call program + + + + 一级 + First Level + + + + 二级 + Second Level + + + + 三级 + Third Level + + + + 是否使用 + Enable + + + + 操作 + Operate + + + + 图标 + Icon + + + + 数据 + Data + + + + web发布 + web publish + + + + 属性配置 + Attribute Configuration + + + + 全部展开 + ExpandAll + + + + 全部收缩 + CollapseAll + + + + COperationOrderForm + + 典型票库 + Library + + + 操作开始时间 + Start Time + + + 操作结束时间 + End Time + + + 操作票号: + Operation Banks: + + + + 操作任务 + Operation tasks + + + 备注: + Remark: + + + + 操作人 + Operator + + + + 监护人 + Guardian + + + + 值班负责人 + Principal + + + + 增加 + Add + + + + 删除 + Delete + + + + 上移 + Up + + + + 下移 + Down + + + 保存 + Save + + + 打印 + Print + + + + 预览 + Preview + + + + + + + + + + + + + + + + + + + + + + + + + + + + 提示 + Prompt + + + + 打开历史表失败! + Failed to open history table! + + + + + + + + + + + 保存失败! + Save failed! + + + 操作票号:kbdct_ + Operation Banks:kbdct_ + + + 操作开始时间: + Start Time: + + + 操作结束时间: + End Time: + + + + 备注:<br> + Remark:<br> + + + + 操作人: + Operator: + + + + 监护人: + Guardian: + + + + 值班负责人: + Principal: + + + + 步骤 + Steps + + + + + 备注 + Remark + + + + 行:%1 保存失败! + Row:%1 save failed! + + + + 保存成功! + Save successed! + + + + 典型票名为空! + Typical ticket name is null! + + + + 操作票号为空! + Operation Banks is null! + + + + 操作人为空! + Operator is null! + + + + 监护人为空! + Guardian is null! + + + + 值班负责人为空! + Principal is null! + + + + 行:%1 顺序为空! + Row : %1 number is null! + + + + 行:%1 与行:%2 顺序重复! + Row : %1 and Row : %2 have the same number! + + + 行:%1 操作任务为空! + Row : %1 operation tasks is null! + + + + 典型票名已存在! + Typical ticket name already exist! + + + + 典型票名: '%1' 保存失败! + Typical ticket name: '%1' save failed! + + + 是否保存更改? + Save the change ? + + + + 打印成功! + Print successfully! + + + + 打印失败! + Print failed! + + + + 保存模板 + Save + + + + 开票打印 + Print + + + + 电子签章 + Electronic signature + + + + + yyyy/MM/dd HH:mm:ss + yyyy/MM/dd HH:mm:ss + + + + 结束时间 + End Time + + + + 操作票号 + Operation Banks + + + + 开始时间 + Begin Time + + + + 签章 + Signature + + + + 操作内容 + Operation Content + + + + key_id_tag + key_id_tag + + + + ctrl_value + ctrl_value + + + + 行:%1 操作内容为空! + Row:%1 Operate content is empty! + + + + 已经存在“%1”,是否覆盖? + “%1” is already exist,replace? + + + + 操作票号: + Operation Banks: + + + + 操作开始时间: + Operation begin time: + + + + 操作结束时间: + Operation end time: + + + + 操作任务: + Operation task: + + + + 当前登录用户无运维管理功能权限! + Current user have no perm to operate! + + + + COperationOrderModelForm + + + 提示 + Prompt + + + + 是否保存模板更改? + Save the template change? + + + + COrderManageWidget + + + 典型票管理 + Typical ticket management + + + + 刷新 + Refresh + + + + + 删除 + Delete + + + + 编辑 + Edit + + + 典型票库 + Typical ticket library + + + + 序号 + number + + + + 操作序列简述 + Description of operation sequence + + + 删除 (%1) + Delete(%1) + + + + + 请选中一条记录! + Please select a record! + + + + + + + + 提示 + Prompt + + + + 是否删除 %1 ? + Delete %1 ? + + + + 删除失败! + Delete failed! + + + + 自动开票 + Automatic Ticket + + + + 当前登录用户无运维管理功能权限! + Current user have no perm to operate! + + + + CPenDialog + + Pen + Pen + + + 线宽: + Line Width: + + + 线型: + Line Style: + + + 预览 + Preview + + + NoPen + NoPen + + + SolidLine + SolidLine + + + DashLine + DashLine + + + DotLine + DotLine + + + DashDotLine + DashDotLine + + + DashDotDotLine + DashDotDotLine + + + + CPixmapShape + + 错误 + error + + + 不支持的格式 + Unsupported format + + + + CPlanCurvesConfigure + + 类型配置 + Type Config + + + 年时段配置 + Year Interval Config + + + 周时段配置 + Week Interval Config + + + 日时段模板配置 + Day Interval Temp Config + + + 计划曲线配置 + PlanCurve Config + + + 新建类型 + New Type + + + 保存 + Save + + + 计划类型 + Plan Type + + + 删除 + Delete + + + 新建模板类型 + New Temp Type + + + 日时段模板类型 + Day Interval Temp Type + + + 新建年时段配置 + New Year Interval + + + 新建周时段配置 + New Week Interval + + + 新建日时段配置 + New Day Interval + + + 日模板类型 + Day Temp Type + + + 新建计划曲线 + New PlanCurve + + + 关联标签 + Related Tag + + + 计划曲线名称 + Name + + + 类型ID + Type ID + + + 所属位置 + Location + + + 所属专业 + Subsystem + + + 时段曲线配置 + Interval Curve Config + + + 导入模板 + Import Temp + + + 新建 + New + + + 预览 + Preview + + + 否 + No + + + 是 + Yes + + + 星期日 + Sunday + + + 星期一 + Monday + + + 星期二 + Tuesday + + + 星期三 + Wednesday + + + 星期四 + Thursday + + + 星期五 + Friday + + + 星期六 + Saturday + + + 类型名称 + Name + + + 年时段名称 + Name + + + 是否例外 + isException + + + 开始月 + Start Month + + + 开始日 + Start Day + + + 结束月 + End Month + + + 结束日 + End Day + + + 周时段名称 + Name + + + 星期 + Week + + + 年时段 + Year Interval + + + 周时段 + Week Interval + + + 日时段名称 + Name + + + 开始时间 + Start Time + + + 结束时间 + End Time + + + 值 + Value + + + 提示 + Prompt + + + 保存成功! + Save Successfully! + + + 保存失败! + Save failed! + + + 行: %1 结束时间不能小于开始时间! + Row:%1 End time cannot less than start time! + + + 行: %1 与行:%2 时间段不连续! + Row: %1 is not discontinuous with Row: %2! + + + 周时段配置需覆盖一整周 + Week interval configuration needs to cover the entire week + + + %1 : 开始月不能大于结束月! + %1 : Begin month cannot be bigger than the end month! + + + %1 : 开始日不能大于结束日! + %1 : Begin day cannot be bigger than the end day! + + + 年配置需要覆盖全年! + Year interval configuration need to cover the whole year! + + + 请从1月1日开始配置! + Please start configuration from January 1st! + + + 请配置到12月31日! + Please configure until December 31! + + + 模拟量出口 + Analog output + + + 是否删除曲线'%1'? + Delete curve '%1' ? + + + 删除成功! + Delete successfully! + + + 删除失败! + Delete failed! + + + 计划类型为空,请检查类型配置! + The plan type is empty,please check type config! + + + 周时段配置被使用,无法保存! + Week interval configuration is in use, cannot be saved! + + + 日模板类型为空,请检查类型配置! + The day temp type is empty,please check type config! + + + 未找到年描述 + No year description found + + + 未找到周描述 + No week description found + + + 导入失败 + Import failed + + + 导入成功 + Import successfully + + + + CPlotWidget + + + + Form + Form + + + + + 对比 + Contrast + + + + + 告警描点 + Alarm Plot + + + + + 收藏 + Collect + + + + + 导出 + Export + + + + 打印 + Print + + + 运行趋势分析 + Run Trend Analysis + + + + 保存图片 + Save Image + + + + + 日 + Day + + + + + 实时 + Real + + + + + 周 + Week + + + + + 月 + Month + + + + + 季 + Quarter + + + + + 年 + Year + + + + + 秒 + Second + + + + + 自定义 + Custom + + + + + 昨日曲线 + Yesterday's Curve + + + + + + + + + + + 趋势图 + Trend Graph + + + + + 清空 + Clear + + + + + 开始时间 + Start Time + + + + + 结束时间 + End Time + + + + + + + 查询 + Search + + + + + 上一页 + Preview + + + + + 下一页 + Next + + + + + 一小时 + One Hour + + + + + 八小时 + Eight Hour + + + + + 一天 + One Day + + + + + 曲线 + Curve + + + + + 表格 + Table + + + + + 错误 + Error + + + + 当前趋势曲线已达最大支持数量[64]! + The current trend curve has reached the maximum number of supports [64]! + + + + + 实时趋势 + Realtime + + + + + 秒趋势 + Second + + + + + 日趋势 + Day + + + + + 周趋势 + Week + + + + + 月趋势 + Month + + + + + 季度趋势 + Quarter + + + + + 年趋势 + Year + + + + + 自定义趋势 + Custom + + + + + + + 保存为 + Save as + + + + + + + + + + + + + + + 提示 + Prompt + + + + + 保存成功 + Save successed + + + + + + + 保存失败 + Failure to save + + + + + 导出成功! +导出路径: + Exported successfully! +Exported path: + + + + + + + + + 请选择告警状态 + Select Alarm State + + + + + 查询中 + Searching + + + + + 查询开始时间不能大于结束时间! + The start time cannot more than the end time! + + + + + 开始时间和结束时间之差不能小于查询时间间隔! + The difference between the start time and the end time cannot less than the time interval! + + + 一秒种 + One Second + + + 一分种 + One Minute + + + 十分种 + Ten Minute + + + + + + + + + yyyy/MM/dd HH:mm + yyyy/MM/dd HH:mm + + + + + 一秒钟 + One Second + + + + + 一分钟 + One Minute + + + + + 十分钟 + Ten Minute + + + + + 双击输入值 + Input on double click + + + + 当前趋势曲线已达最大支持数量[%1]! + The current trend curve has reached the maximum supported quantity of [%1]! + + + + + + + 昨日曲线- + Yesterday's Curve - + + + + + (*.jpg) + (*.jpg) + + + + + (*.xlsx) + (*.xlsx) + + + + CPointLockWidget + + + 添加 + Add + + + + 删除 + Delete + + + + 确认 + Confirm + + + + 闭锁配置 + Interlock Configuration + + + + 1-1AH5-断路器 + 1-1AH5 + + + + 控制状态 + Control Status + + + + 启用 + Enable + + + + 取消 + Cancel + + + + + 条件 + Condition + + + + + 无 + None + + + + + 小于 + < + + + + + 小于等于 + <= + + + + + 等于 + == + + + + + 大于等于 + >= + + + + + 大于 + > + + + + + 不等于 + != + + + + 且 + and + + + + 设备列表 + Device List + + + + 状态值 + Status Value + + + + + + + 提示 + Prompt + + + + 请选中需要删除的行 + Please select a row + + + + 请选择测点标签 + Please add a point + + + + + 添加失败 + Failure to add + + + + CPointRealDataWidget + + + 通讯状态 + Communication status + + + + 正常 + Normal + + + + 异常 + Abnormal + + + + + + 未找到组号%1! + Not found group %1! + + + + CPreviewForm + + 新建项目 + New Item + + + + CPrintPreview + + Print Preview + Print Preview + + + Print... + Print... + + + Next + Next + + + Prev + Prev + + + Single/Dual + Single/Dual + + + Zoom In + Zoom In + + + Zoom Out + Zoom Out + + + Close + Close + + + + CProcessBarDialog + + Dialog + Dialog + + + 取消 + Cancel + + + + CProcessDialog + + + Form + Form + + + + 取消 + Cancel + + + + CProcessManage + + + + 最大值 + Maximum + + + + + 最小值 + Minimum + + + + + 平均值 + Average Value + + + + CPropertyDialog + + + Dialog + Dialog + + + + 备注 + Remark + + + + 设备名称 + Device Name + + + + 确认 + Confirm + + + + 添加 + Add + + + + 编辑 + Edit + + + + 安装日期 + Installation Date + + + + 型号 + Type + + + + 参数 + Parameter + + + + 维护周期 + Maintenance Period + + + + yyyy-MM-dd + yyyy-MM-dd + + + + 厂家联系方式 + Manufacturer Contact + + + + 所属设备组 + Device Group + + + + 状态 + State + + + + 取消 + Cancel + + + + 已启用 + Enable + + + + 一个月 + One Month + + + + 三个月 + Three Months + + + + 半年 + Six Months + + + + 一年 + One Year + + + + 提示 + Prompt + + + + 设备名称不能为空! + Device name cannot be empty! + + + + 操作失败,请重新操作! + Failed,please try again! + + + + CRealTableModel + + + 测点 + Measuring Point + + + + 点类型 + Point Type + + + + 设备 + Device + + + + 值 + Value + + + + 状态 + Status + + + + CRecordDialog + + + Dialog + Dialog + + + + 导出 + Export + + + + 删除 + Delete + + + + 添加 + Add + + + + 时间 + Time + + + + 关键字 + Keywords + + + + 查询 + Search + + + + 当前未选中任何项! + No item is currently selected! + + + + Save File + Save File + + + + ~ + ~ + + + + + 对开始时间和结束时间日期生效 + Effective for start time and end time + + + + 对设备名称、记录名称、操作人和维护内容生效 + Effective for device name、record name、operator and maintenance content + + + + %1 维护记录 + %1 maintenance records + + + + + 提示 + Prompt + + + + 删除失败! + Failure to delete! + + + + 删除成功! + Successful delete! + + + + 开始时间不能大于结束时间! + The start time cannot more than end time! + + + + CRecordForm + + + Form + Form + + + + 序号 + Number + + + + 操作人 + Operator + + + + 监护人 + Guardian + + + + 值班负责人 + Principal + + + + 描述 + Description + + + + 备注 + Remark + + + + 刷新 + Refresh + + + + 未执行 + Non execution + + + + 未确认 + Unconfirmed + + + + 检索条件 + Filter + + + + 按值班负责人 + Principal + + + + 按票名包含 + Ticket name + + + + 按操作人 + Operator + + + + 按操作票号 + Operation Banks + + + + 按执行时间 + Execution time + + + + 按完成时间 + Finish time + + + + 按监护人 + Guardian + + + + 操作票号 + Operation Banks + + + + 操作票名 + Ticket name + + + + 开始时间 + Start time + + + + 结束时间 + End time + + + + 执行状态 + Execution status + + + + 详细 + Detail + + + + 已执行 + Executed + + + + 提示 + Prompt + + + + 请选择一项! + Please select one item! + + + + CRecordPropertyDialog + + + Dialog + Dialog + + + + 确认 + Confirm + + + + 添加 + Add + + + + 编辑 + Edit + + + + 维护名称 + Maintenance name + + + + 维护人 + Maintainer + + + + 维护开始时间 + Maintenance start time + + + + + yyyy-MM-dd + yyyy-MM-dd + + + + 维护结束时间 + Maintenance end time + + + + 维护内容 + Maintenance content + + + + 取消 + Cancel + + + + 提示 + Prompt + + + + 记录名称不能为空! + The record name cannot be empty! + + + + 开始时间不能大于结束时间! + The start time cannot more than the end time! + + + + 操作失败,请重新操作! + Failed,please try again! + + + + CRecordTablModel + + + 设备名称 + Device Name + + + + 操作人 + Operator + + + + 记录名称 + Record name + + + + 开始时间 + Start time + + + + 结束时间 + End time + + + + 维护内容 + Maintenance content + + + + CRecordWidget + + + 保存 + Save + + + + 处理问题 + Handling problem + + + + 上班遗留问题 + Last leftover problem + + + + 当班处理问题 + Handling problem on duty + + + + 当班遗留问题 + Leftover problem on duty + + + + 关键信息备注 + Key information notes + + + + CRelaySettingWidget + + + 序号 + Number + + + + 确认 + Confirm + + + + 清空 + Clear + + + + 保护定值管理 + Relay settting management + + + + 切换 + Switch + + + + 当前执行组: + Current group: + + + + 前置设备 + Front equipment + + + + 定值名称 + Name + + + + 定值组号 + Group No + + + + 当前值 + Current Value + + + + 预置值 + Preset Value + + + + 返校值 + Return Value + + + + 范围 + Range + + + + 单位 + Unit + + + + 定值代号 + Code No + + + + isError + isError + + + + 读取 + Read + + + + 修改 + Modify + + + + + + + + + + + + + + + + + + 提示 + Prompt + + + + 未知值:%1 + Unknown Value:%1 + + + + 无保护定值操作权限! + Not relay setting operate perm! + + + + 行:%1,当前值无效,请先读取! + Row:%1,current value is invalid,please read first! + + + + 行:%1,预置值无效,请先读取! + Row:%1,preset value is invalid,please read first! + + + + 行:%1,预置值不在设定范围! + Row:%1,preset value is beyond the range! + + + + 行:%1,返校值无效! + Row:%1,return value is invalid! + + + + 行:%1,预置值与返校值不一致! + Row:%1,preset value is inconsistent with return value! + + + + 请先查询当前执行组! + Please read current group first! + + + + 设置的组号应不为当前执行组! + Setting group no cannot equal to current group no! + + + + 验证 + Verification + + + + 权限验证 + Permissions validation + + + + 请选择切换组! + Please select one group! + + + + 未选择设备! + Not device selected! + + + + 无定值组配置! + Not setting group configuration! + + + + 接收超时! + Receive timeout! + + + + 发送命令失败! + Failure to send command! + + + + CReportFavTreeWidget + + + 收藏夹 + Favorite + + + + 报表管理 + Report Management + + + + 请输入收藏报表名称 + Please enter the favorite report name + + + + + 报表名不能为空! + The report name cannot be empty! + + + + 当前收藏报表名称已存在! + The current favorite report name already exists! + + + + 重命名 + Rename + + + + 删除 + Delete + + + + 当前报表名称已存在! + The current report name already exists! + + + + 选择报表收藏文件 + Select report favorite file + + + + 保存报表收藏文件 + Save report favorite file + + + + 收藏报表_ + Save report_ + + + + CReportStackedWidget + + + 返回 + Return + + + + CReportWidget + + + 导出报表 + Export the report + + + + CRetriever + + 检索器 + Retriever + + + 专业: + Subsystem: + + + 位置: + Location: + + + 设备类型: + Device Type: + + + 设备组: + Device Group: + + + 表名: + Table Name: + + + 统计量模板: + Statistical template: + + + 表检索 + Table + + + 检索方式: + Retriever Mode: + + + 设备检索 + Device + + + 统计量 + Statistical + + + 多点关联 + Multipoint + + + 设备组检索 + Device Group Retrieval + + + 点类型: + Point Type: + + + 值: + Value: + + + 点名: + Point Name: + + + 列名: + Column Name: + + + 数字量 + Digital + + + 模拟量 + Analog + + + 混合量 + Mix + + + 累积量 + Accuml + + + 常量 + Const + + + 通用 + General + + + 其他 + Other + + + 关键字 + Keywords + + + 值 + Value + + + 状态 + State + + + 时间 + Time + + + + CRobotAVWidget + + Form + Form + + + current time + current time + + + duration + duration + + + + CRobotCCDVideoForm + + Form + Form + + + 请输入关键字 + Please input keyword + + + + CRobotCCDVideoItemModel + + 时间 + Time + + + 类型 + Type + + + 设备柜 + Device + + + 照片 + Picture + + + 截图 + Screenshot + + + 录像 + Video + + + + CRobotCtrlWidget + + Form + Form + + + 请选择设备 + Please select a device + + + 执行任务 + Execute Task + + + 空闲中 + Idle + + + 巡检中 + Patrolling + + + 充电中 + Charging + + + 检修中 + Under Maintenance + + + 告警联动: + Alarm Linkage: + + + 机器人状态 + Robot Status + + + 执行任务超时! + Task Execution Timeout! + + + 未找到控制点[%s] + Control Point [%s] Not Found + + + 解析返回结果出错 + Error Parsing Return Result + + + + CRobotDialog + + Dialog + Dialog + + + 机器人联动 + Robot Interlocking + + + + CRobotWidget + + CRobotLinkCtrlWidget + CRobotLinkCtrlWidget + + + + CRollSwitchWidget + + + 播放组 + Group + + + + 画面文件名称 + Graph Name + + + + 画面轮询间隔(s) + Interval + + + + 自动轮询(设定的时间内,未检测到键鼠操作,自动轮询播放画面) + Auto-polling (If no keyboard or mouse operation is detected within the set time, auto-polling will play the screen) + + + 自动轮询 + Autopolling + + + + 开始 + Start + + + + 停止 + Stop + + + + 关闭 + Close + + + 自动轮询时间(s) + Autopolling Delay(s) + + + 自动轮询(设定的时间内,未检测到鼠标移动,自动轮询播放画面) + Autopolling(Auto switching graph when not mouse move in setting time) + + + + 轮询时间(s) + Autopolling time(s) + + + + CRunSequenceFilterDialog + + + 过滤 + Filter + + + + 关键字 + Keywords + + + + 顺控名称: + Sequence name: + + + + 类型 + Type + + + + 标准顺控 + Standard sequence + + + + 自定义顺控 + Custom sequence + + + + 位置 + 车站 + Location + + + + 位置名称: + 车站名称: + Location name: + + + + CRunningSequenceModel + + + 名称 + Name + + + 车站 + Location + + + + 类型 + Type + + + + 执行结果 + Executing results + + + + 位置 + Location + + + + 标准顺控 + Standard sequence + + + + 自定义顺控 + Custom sequence + + + + 未执行 + non-execution + + + + 正在执行 + executing + + + + 已触发 + triggered + + + + 执行失败 + execution failure + + + + 执行成功 + execution success + + + + 执行终止 + execution termination + + + + 执行暂停 + execution pause + + + + 执行跳过 + execution skip + + + + CScreenShot + + 保存图像 + Save Image + + + 图形文件 (*.png) + Graphics file(*.png) + + + + CSecondButtonGroupWidget + + + 配置错误! + Configuration Error! + + + + CSecondNavigationWidget + + + 是 + Yes + + + + 否 + No + + + + 切换画面 + Switch Screen + + + + 调用程序 + call program + + + + 导入 + Import + + + + 导出 + Export + + + + 一级 + First Level + + + + 二级 + Second Level + + + + 三级 + Third Level + + + + 是否使用 + Enable + + + + 操作 + Operation + + + + 图标 + Icon + + + + 数据 + Data + + + + web发布 + + + + + + 提示 + Hint + + + + 导出成功! +导出路径: + Exported successfully! +Exported path: + + + + 保存失败 + Save Failed + + + + 属性配置 + Property Configuration + + + + 全部展开 + ExpandAll + + + + 全部收缩 + CollapseAll + + + + CSecondReportWidget + + + 结束时间晚于开始时间,请调整时间之后再查询! + The end time is later than the start time, please adjust the time and then search again! + + + + 未选择测点,请选择测点之后再查询报表! + No measuring point selected, please select a measuring point and then search for the report! + + + + 暂不支持10000条以上数据的查询,请调整查询时间或时间间隔之后再查询! + Querying more than 10,000 data entries is not supported at the moment. Please adjust the query time or time interval and try again! + + + + 开始时间 + Start Time + + + + 查询时间 + Search time + + + + 当前登录用户无运维管理功能权限! + The current logged-in user does not have permission for operational management functions! + + + + 导出表头失败: +无法打开文件! + Failed to export header: +Unable to open the file! + + + + 导出表头至: + + Export header to: + + + + + + 当前登录用户无运维管理功能权限! + Current user have no perm to operate! + + + + + 报表管理 + Report Management + + + + 导入表头失败: +导入格式错误,仅支持csv文件! + Failed to import header: +Incorrect import format, only CSV files are supported! + + + + 导入表头失败: +无法打开导入的文件! + Failed to import header: +Unable to open the file for import! + + + + 导入表头失败: +表头长度与现有表头长度不一致! + Failed to import header: +The length of the header does not match the existing header length! + + + + 导入表头成功! + Header imported successfully! + + + + 报表数据为空,请先查询报表数据! + The report data is empty, please query the report data first! + + + + 导出报表失败: +无法打开文件! + Failed to export report: +Unable to open the file! + + + + 导出表格成功! + Table exported successfully! + + + + 查询终止! + Query terminated! + + + + 该时间段无数据! + No data available for the specified period! + + + + 生成报表失败! + Failed to generate report! + + + + 时间 + Time + + + + CSecondReportWidgetClass + + + test + Test + + + + 日报表 + Daily Report + + + + 月报表 + Monthly Report + + + + 年报表 + Annual Report + + + + 自定义 + Custom + + + + 是否统计 + Statistics + + + + 查询 + Search + + + + 收藏 + Favorite + + + + 导出表头 + Export Header + + + + 导入表头 + Import Header + + + + 导出表格 + Export Table + + + + 开始时间 + Start Time + + + + + 年 + Year + + + + + 月 + Month + + + + + 日 + Day + + + + + 时 + Hour + + + + + 分 + Minute + + + + 结束时间 + End Time + + + + 时间间隔 + Time Interval + + + + 1年 + 1年 + + + + 1个月 + 1 Month + + + + 1天 + 1天 + + + + 1小时 + 1 Hour + + + + 30分钟 + 30 Minutes + + + + 15分钟 + 15 Minutes + + + + 全部 + All + + + + CSeqPermDialog + + + + 验证 + Verification + + + + 操作验证 + Operation validation + + + + + 用户组 + User group + + + + + 姓名 + User name + + + + + 密码 + Password + + + + + 账号 + User alias + + + + 监护验证 + Guardian validation + + + + 取消 + Cancel + + + + 监护验证: + Guardian validation: + + + + 操作验证: + Operation validation: + + + + + %1输入名称不存在! + The input name %1 does not exist! + + + + %1无遥控监护权限! + %1 have no perm guard! + + + + %1无顺控执行权限! + %1 have no perm to execute sequence! + + + + %1不允许在该节点登录! + %1 Logon on this node is not allowed! + + + + %1用户口令错误! + %1 Password error! + + + + %1用户已失效! + %1 User deactivated! + + + + %1用户已锁定! + %1 User locked! + + + + %1用户不属于所选用户组! + The user %1 does not belong to the selected user group! + + + + %1用户权限检查出错! + %1 check failed! + + + + 提示 + Prompt + + + + 监护验证: 输入账号有误! + Guardian validation: incorrect input name! + + + + 监护人和操作人不能为同一人! + Guardian and operator can not be the same person! + + + + CSequenceManageWidget + + + 顺控配置 + Configuration + + + + 顺控执行 + Execute + + + + 顺控报告 + Report + + + + 所有顺控 + All sequence + + + + 正在执行 + Executing + + + + + 过滤 + Filter + + + + 历史列表 + History List + + + + 执行详情 + Execute details + + + + 导出 + Export + + + + 打印 + Print + + + + 提示 + Prompt + + + + 无顺控操作权限! + No sequence control operation permission! + + + + CSequenceManageWidget + CSequenceManageWidget + + + + Save File + Save File + + + + (*.pdf *) + (*.pdf *) + + + + CSequenceWidget + + + 顺控 + Sequence + + + + 顺控名称: + Sequence Name: + + + + 执行方式: + Executive Mode: + + + + 自动 + Automatic + + + + 单步 + Step + + + + 执行 + Execute + + + + + + + + + + + + + 暂停 + Pause + + + + + 终止 + Terminate + + + 正在检查控制点状态,请稍等 + Check the status of control point, please wait a moment + + + + 正在查询... + Being queried... + + + + 服务应答 [%1]:%2 + Service response [%1]:%2 + + + + 服务应答-错误 [%1] + Service response-error [%1] + + + + 顺控名称: + Sequence name: + + + + 错误代码: + Error code: + + + + 错误描述: + Error description: + + + + 状态变化 [顺控-%1]:%2 + Change of state [Sequence-%1]:%2 + + + + 状态变化 [顺控-%1] [功能-%2]:%3 + Change of state [Sequence-%1] [Function-%2]:%3 + + + + 状态变化 [顺控-%1] [功能-%2] [动作-%3]:%4 + Change of state [Sequence-%1] [Function-%2] [Action-%3]:%4 + + + + 顺控名称 + Sequence name + + + + 功能名称 + Function name + + + + 动作名称 + Action name + + + + 请求人工干预! + Manual intervention request! + + + + 人工干预请求 + Manual intervention request + + + + 重试 + Retry + + + + 跳过 + Skip + + + + 等待执行... + Wait for execution... + + + + 等待暂停... + Wait for pause... + + + + 等待继续... + Wait for continue... + + + + 等待终止... + Wait for termination... + + + + 顺控开始 + Sequence start + + + + 顺控终止 + Sequence termination + + + + 顺控暂停 + Sequence pause + + + + 顺控继续 + Sequence continue + + + + 单步开始 + One step to start + + + + 单步继续 + One step to continue + + + + 未执行 + non-execution + + + + 正在执行 + executing + + + + 已触发 + triggered + + + + 执行失败 + execution failure + + + + 执行成功 + execution success + + + + 执行终止 + execution termination + + + + 执行暂停 + execution pause + + + + 执行跳过 + execution skip + + + + 继续 + Continue + + + + - - + + + + + %1[%2] +%3%4 +%5%6 + + + + + + CSeriaDevTableModel + + + 序号 + Serial Number + + + + 位置 + Location + + + + 通道描述 + Channel Description + + + + RTU描述 + RTU Description + + + + 设备描述 + Device + + + + 端口名 + Port Name + + + + 设备ID + DeviceId + + + + 通讯状态 + Communication status + + + + 通讯中断 + Communication Interrupted + + + + 通讯正常 + Communication Normal + + + + CSerialDevStatusWidget + + + RTU/端口 + RTU/Port + + + + CShape + + 画笔 + Pen + + + 画刷 + Brush + + + %1 + + %1 + + + + CShapeConfigDialog + + 数据绑定 + Data Binding + + + 函数绑定 + Function Binding + + + 策略配置 + Strategy Configuration + + + 属性配置 + Properties Configuration + + + 标签名称 + Label Name + + + 文本内容 + Text content + + + 确认 + Confirm + + + 取消 + Cancel + + + 清空 + Clear + + + 语法检查 + Syntax checking + + + 新建策略 + New strategy + + + 删除策略 + Delete strategy + + + 取消选中 + Uncheck + + + 添加行 + Add row + + + 删除行 + Delete row + + + Error + Error + + + Information + Information + + + 语法正确, 脚本有效。 + Syntax correct, script valid. + + + 策略名称: + Strategy name: + + + 函数代码 + Function Name + + + 函数名称 + Description + + + 新建 + New + + + 删除 + Delete + + + 复制 + Copy + + + 修改 + Modify + + + 函数编辑 + Function Editor + + + 策略描述: + Description + + + 提示 + Prompt + + + 策略名称不能为空! + The strategy name cannot be empty! + + + 策略描述不能为空! + The description cannot be empty! + + + 非法的命名 + Illegal name + + + 策略名称已经存在, 不能重复创建! + The strategy name already exists and cannot be repeated! + + + 策略名称不能以数字开头! + Strategy names cannot begin with Numbers! + + + 警告 + Warning + + + 当前未选中行! + Currently unchecked row! + + + + CShieldTableDelegate + + + 删除 + Delete + + + + 启用 + Enable + + + + 取消 + Disable + + + + + + 提示 + Prompt + + + + 请先取消屏蔽! + Please disable first! + + + + 删除失败! + Delete failure! + + + + 当前用户无标签设置功能权限! + The current user have no perm to operate! + + + + CShieldTableModel + + + 名称 + Name + + + + 屏蔽类型 + Type + + + + 屏蔽属性 + Property + + + + 屏蔽模式 + Mode + + + + 是否启用 + Status + + + + 时段类型 + Time Type + + + + 屏蔽时段 + Time + + + + 操作用户 + User + + + + 操作主机 + Hostname + + + + 屏蔽描述 + Description + + + + 操作 + Operate + + + + 全站屏蔽 + Location + + + + 电压屏蔽 + Voltage + + + + 责任区屏蔽 + Region + + + + 设备组屏蔽 + DeviceGroup + + + + 设备屏蔽 + Device + + + + 测点屏蔽 + Point + + + + + 未知 + Unknown + + + + 已过期 + Expired + + + + 已启用 + Enable + + + + 未启用 + Disable + + + + 一次性屏蔽 + Once + + + + 每周 + Week + + + + 每月 + Month + + + + 每周( + Week( + + + + 每月( + Month( + + + + %1 + + + + + CShiftWidget + + + 查询 + Search + + + + 保存 + Save + + + + 序号 + Number + + + + 交接班管理 + Shift Management + + + + 当前值班组 + Current duty group + + + + 填写记录 + Input record + + + + 交接班 + Duty shift + + + + 查询时间 + Search time + + + + 按值班员过滤 + Filter by duty person + + + + 导出记录 + Export + + + + 班组 + Work groups + + + + 值班员 + Duty person + + + + 接班时间 + Take over time + + + + 交班时间 + Shift time + + + + 本班处理问题 + Handling problem on duty + + + + 本班遗留问题 + Leftover problem on duty + + + + 关键信息备注 + Key information notes + + + + CSimOptWidget + + + 序号 + Number + + + + CSimOptWidget + CSimOptWidget + + + + 开始模拟操作 + Begin + + + + 图形列表 + Graph List + + + + + + 提示 + Prompt + + + + 当前登录用户无运维管理功能权限! + Current user have no perm to operate! + + + + 请选择一张图形! + Please select one graph! + + + + 确定打开图形:"%1",开始模拟操作? + Confirm open graph:"%1",begin simulate? + + + + CSliderRangeWidget + + + + 最小值: + Minimum: + + + + + 最大值: + Maximum: + + + + + 确定 + Confirm + + + + + 取消 + Cancel + + + + CSpinBoxGroup + + 错误 + Error + + + 的最小值不能超过最大值! + s minimum cannot exceed the maximum! + + + 的最大值不能小于最小值! + s maximum cannot less than the minimum! + + + + CStationNavWidget + + Form + Form + + + + CStatisWidget + + + Form + Form + + + + 统计方式: + Statistical Style: + + + + 设备类型: + Device Type: + + + + 开始时间: + Start Time: + + + + 结束时间: + End Time: + + + + 查询 + Search + + + + 打印 + Print + + + + 日统计 + Day + + + + 月统计 + Month + + + + 年统计 + Year + + + + 导出成功! +导出路径: + Exported successfully! +Exported path: + + + + 结束时间不能小于开始时间! + The end time cannot be less than start time! + + + + 位置: + Location: + + + + + yyyy-MM-dd + yyyy-MM-dd + + + + 告警等级: + Alarm level: + + + + Excel + Excel + + + + Pdf + Pdf + + + + 报表 + Report + + + + 图表 + Chart + + + + 保存为 + Save as + + + + (*.jpg) + (*.jpg) + + + + + + + + + + 提示 + Prompt + + + + 保存失败 + Failed to save + + + + 日统计最多查询31天! + Maximum query time was 31 days on day! + + + + 月统计最多查询12月! + Maximum query time was 12 months on month! + + + + 年统计最多查询2年! + Maximum query time was 2 years on year! + + + + 至少勾选一个告警等级! + Check one alarm level at least! + + + + CStrategyConfigDelegate + + 颜色选择 + Color + + + + CStrategyConfigModel + + 合成值 + Synthetic value + + + 线色 + Line color + + + 填充色 + Fill color + + + 闪烁线色前景色 + The foreground color of the flicker line + + + 闪烁线色背景色 + The background color of the flicker line + + + 闪烁填充前景色 + The foreground color of the flicker fill + + + 闪烁填充背景色 + The background color of the flicker fill + + + 图元平面 + Primitive plane + + + 是否闪烁 + Whether Flicker + + + 闪烁频率 + Flicker frequency + + + 是否显示 + Whether Display + + + 警告 + Warning + + + 当前合成值已经存在! + The current composite value already exists! + + + + CSysParamWidget + + + CSysParamWidget + CSysParamWidget + + + + IP设置 + IP Settings + + + + + 查询 + Search + + + + + 设置 + Config + + + + 网卡 + Network Card + + + + 子网掩码 + Subnet Mask + + + + IP地址 + IP Address + + + + 网关 + Gateway + + + + 日期 + Date + + + + yyyy-MM-dd + yyyy-MM-dd + + + + 时间 + Time + + + + hh:mm:ss + hh:mm:ss + + + + 时间设置 + Time Settings + + + + NTP设置 + NTP Settings + + + + 是否开启NTP + Enable NTP + + + + 是 + Yes + + + + 否 + No + + + + NTP服务器 + NTP Server + + + + NTP设置失败:%1,主机名:%2 + NTP setting failed: %1, hostname: %2 + + + + NTP设置成功 + NTP setting succeeded + + + + 时间设置失败:%1,主机名:%2 + Time setting failed: %1, hostname: %2 + + + + 时间设置成功 + Time setting succeeded + + + + IP设置失败:%1,主机名:%2 + IP setting failed: %1, hostname: %2 + + + + IP设置成功 + IP setting succeeded + + + + CTableDataModel + + + + 提示 + Prompt + + + + + 只显示前%1条记录! + Onle the %1 records is displayed! + + + + + + + 时间 + Time + + + + CTableDelegata + + + 是 + Yes + + + + 否 + No + + + + CTableModel + + + 统计日期 + Statistical Date + + + + 区域名称 + Location + + + + 设备类型 + Device Type + + + + %1总数 + Number of %1 + + + + 图元名称 + Element Name + + + + 触发动作 + Trigger Action + + + + 控制面板 + Control Panel + + + + 默认着色策略 + Default Coloring Strategy + + + + 模拟操作 + Simulation Operation + + + + CTableViewExport + + + + 保存 + Save + + + + + 导出成功! +导出路径: + Exported successfully! +Exported path: + + + + + + + 提示 + Prompt + + + + + 保存失败 + Failure to save + + + + CTagSourceCfgDialog + + 数据源配置 + Data source configuration + + + 取消 + Cancel + + + 确定 + Confirm + + + + CTextPrinter + + 另存PDF文件为 + Save as PDF file + + + PDF文件(*.pdf) + PDF file(*.pdf) + + + + CTextReplacer + + Dialog + Search Dialog + + + 查找: + Find: + + + 替换为: + Replace With: + + + 替换 + Replace + + + 大小写匹配 + Case Sensitive + + + 文本替换 + Text Replace + + + + CToolTip + + + + 全部 + All + + + + + 告警列表 + Alarm List + + + + + 时间 + Time + + + + + 告警内容 + Alarm Content + + + + CTreeItemDelegate + + + 切换导航 + Switch navigation + + + + 加载网页 + Load Web Page + + + + CTrendDelegate + + + + 颜色选择 + Color Selection + + + + CTrendEditDialog + + + + 趋势编辑 + Trend Editor + + + + + 取消 + Cancel + + + + + 确定 + Confirm + + + + + 添加 + Add + + + + + 删除 + Delete + + + + + 清空 + Clear + + + + + + + 警告 + Warning + + + + + 测点数量不允许为空! + The number of measuring points is not allowed to be empty! + + + + + 测点名称不允许存在空值! + The name of measuring points are not allowed to be null! + + + + + 提示 + Prompt + + + + + 当前未选中行! + Not row selected currently! + + + + CTrendEditModel + + + + 测点名称 + The name of measuring points + + + + + 颜色 + color + + + + + 点标签非法 + Illegal point label + + + + + 只能添加模拟量和累积量! + Only analog and cumulative quantities can be added! + + + 只能添加模拟量! + Only analog can be added! + + + + + 该测点已存在! + The measuring point already exists! + + + 测点标签 + Measurement Point Label + + + + CTrendEditView + + + + + + 提示 + Prompt + + + + + 请选中一行! + Select a row please! + + + + + 警告 + Warning + + + + + 该测点已存在! + The measuring point already exists! + + + + CTrendFavTreeWidget + + + + 收藏夹 + Favorite + + + + + + + 错误 + Error + + + + + + + 当前趋势名称已存在! + The name of trend is already exist! + + + + + 添加趋势 + Add trend + + + + + 导入 + Import + + + + + 显示 + Show + + + + 编辑 + Edit + + + + 自定义趋势_ + Custom Trend_ + + + 趋势名称不允许为空,自动重命名! + The trend name cannot be empty, it will be automatically renamed! + + + 当前趋势名称已存在,自动重命名! + The current trend name already exists, it will be automatically renamed! + + + + + 重命名 + Rename + + + + + 删除 + Delete + + + + + 导出 + Export + + + + + 提示 + Prompt + + + + + 确定删除所选项吗? + Are you sure you want to delete the selected item(s)? + + + + + 选择趋势收藏文件 + Select file + + + + + 保存趋势收藏文件 + Save file + + + + CTrendTreeView + + + + + 全选 + Check All + + + + + + 清空 + Clear + + + + 刷新 + Refresh + + + + CTrendWindow + + + + 设备/点 + Device/Point + + + + + 收藏夹 + Favorite + + + + + + + 错误 + Error + + + + + 趋势名称不允许为空! + Trend names are not allowed to be empty! + + + + + 最小值不能大于最大值! + The minimum cannot be greater than the maximum! + + + 设备/测点 + Device/Measurement Point + + + + CWaittingDlg + + + 报表管理 + Report Management + + + + 查询中,请等待或终止查询 . . . +(退出窗口默认终止查询) + Query in progress, please wait or terminate the query... +(Exiting the window will terminate the query by default.) + + + + 终止查询 + Terminate Query + + + + CWaveAnalyzeWidget + + CWaveAnalyzeWidget + CWaveAnalyzeWidget + + + 开始日期 + Start Date + + + 结束日期 + End Date + + + 查询 + Search + + + 打开 + Open + + + 删除 + Delete + + + 导出 + Export + + + 打印 + Print + + + 文件列表 + File List + + + Error + Error + + + 提示 + Note + + + 开始时间应小于结束时间 + The start time should be earlier than the end time. + + + + CWaveGraph + + Trigger Line + Trigger Line + + + Line B + Line B + + + Line C + Line C + + + + CWaveListDialog + + + Dialog + Dialog + + + + CWaveShow + + Save Wave Graph + Save Wave Graph + + + Save File + Save File + + + Save Successfully! + Save Successfully! + + + + CWebEngineView + + + Render process normal exit + Render process normal exit + + + + Render process abnormal exit + Render process abnormal exit + + + + Render process crashed + Render process crashed + + + + Render process killed + Render process killed + + + + 刷新 + Refresh + + + 后退 + Back + + + 前进 + Forward + + + + CWebPublish + + 提示 + Prompt + + + 只能在服务器上进行Web发布! + Web publishing only on the server! + + + 发布成功! + Publish Success! + + + 发布失败! + Publish Failure! + + + + CWorkTicketManage + + + 票库管理 + Ticket Library + + + + 开票 + Ticket + + + + 删除 + Delete + + + + 开票记录 + Ticket Record + + + + 名称 + Name + + + + 类型 + Type + + + + 文件路径 + File Path + + + + + 请选中一条记录! + Please select a record! + + + + 确认删除 + Confirm + + + + 是否删除 %1 ? + Delete %1 ? + + + + + + + + 提示 + Prompt + + + + 删除失败 + Failed to delete + + + + Form + Form + + + + 当前登录用户无运维管理功能权限! + Current user have no perm to operate! + + + + CWorker + + + 设备名称 + Device Name + + + + 备注 + Remark + + + + 操作人 + Operator + + + + + 设备id + DeviceId + + + + 型号 + Type + + + + 参数 + Parameter + + + + 安装日期 + Installation Date + + + + 状态 + State + + + + 厂家联系方式 + Manufacturer Contact + + + + 维护周期(月) + Maintenance Period(month) + + + + 所属设备组描述 + Device Group + + + + 所属设备组标签 + Device Group Tag + + + + 导出资产信息成功 + Successful export asset info + + + + 记录id + RecordId + + + + 设备描述 + Device + + + + 记录名称 + Record Name + + + + 开始时间 + Start Time + + + + 结束时间 + End Time + + + + 维护内容 + Maintenance Content + + + + 导出维护记录成功 + Successful export maintenance records + + + + 导入资产信息失败,文件打开失败! + Failure to import asset info,failed to open file! + + + + 部分设备组标签不存在 + Part of device group tag does not exist + + + + 导入维护记录失败,文件打开失败! + Failure to import maintenance records,failed to open file! + + + + 部分资产不存在 + Part of asset not exist + + + + ChanParaWidget + + + Form + Form + + + + 网口参数 + Network Port Parameters + + + + 串口参数 + Serial Port Parameters + + + + 确认修改 + Confirm Changes + + + + 重启通道 + Restart Channel + + + + + 通道使能 + Channel Enabled + + + + + 通道名称 + Channel Name + + + + + 通道描述 + Channel Description + + + + 通道号 + Channel Number + + + + 波特率 + Baud Rate + + + + 校验位 + Parity + + + + 通道IP1 + NET_DESC1 + + + + 端口号1 + PORT_NO1 + + + + 通道IP2 + NET_DESC2 + + + + 端口号2 + PORT_NO2 + + + + 通道IP3 + NET_DESC3 + + + + 端口号3 + PORT_NO3 + + + + 通道IP4 + NET_DESC4 + + + + 端口号4 + PORT_NO4 + + + + 本地端口号 + RES_PARA_INT4 + + + + + 警告 + Warning + + + + 无修改权限! + No permission to modify! + + + + 初始化权限失败! + Failed to initialize permissions! + + + + + + + 提示 + Note + + + + 重启成功 + Restart successful + + + + 确定 + OK + + + + 取消 + Cancel + + + + 修改完成 + Modification completed + + + + 没有修改数据记录! + No data records were modified! + + + + ChanStatusWidget + + + 位置 + Location + + + + 否 + No + + + + 是 + Yes + + + + 未知 + Unknown + + + + 采集通道 + Data Acquisition Channel + + + + 转发通道 + Forwarding Channel + + + + ChanTableModel + + + 序号 + Serial Number + + + + 位置 + Position + + + + 通道号 + Channel Number + + + + 通道描述 + Channel Description + + + + 通道使能 + Channel Enabled + + + + 通讯性质 + Communication Nature + + + + 通讯规约 + Communication Protocol + + + + 通道地址 + Channel Address + + + + 通道状态 + Channel Status + + + + 保留未用 + Reserved Unused + + + + 通道检测 + Channel Detection + + + + 通道运行 + Channel Running + + + + 通道停止 + Channel Stopped + + + + 接收帧错误率高 + High Frame Error Rate + + + + ConfigWidget + + + 分组管理 + Group + + + + + 新增 + Add + + + + + 删除 + Delete + + + + + 上移 + Up + + + + + 下移 + Down + + + + 保存 + Save + + + + 轮询组 + Polling Group + + + + 画面文件名称 + Graph Name + + + + 是否启用 + Enable + + + + 画面轮询间隔(s) + Interval + + + + + + 警告 + Warning + + + + + + 请选择任意一条记录 + Please select any record. + + + + 确认删除? + Confirm deletion? + + + + 画面文件名称不能为空! + Graph name cannot be empty! + + + + 保存成功 + Save success + + + + 保存失败 + Fail to save + + + + 是 + Yes + + + + 否 + No + + + + + 提示 + Prompt + + + + ContrastWidget + + + Form + Form + + + + 统计方式: + Statistical Style: + + + + 查询 + Search + + + + 打印 + Print + + + + 清空 + Clear + + + + 全选 + Check All + + + + 导出成功! +导出路径: + Exported successfully! +Exported path: + + + + 对比方式: + Compare Style: + + + + 对比时间: + Compare Time: + + + + yyyy/MM/dd + + + + + Excel + + + + + Pdf + + + + + 报表 + Report + + + + 图表 + Chart + + + + 最严重告警设备 + The most serious alarm device + + + + + 设备 + Device + + + + 按位置统计 + Statistics by location + + + + 按设备类型统计 + Statistics by device type + + + + 日 + Day + + + + 月 + Month + + + + 年 + Year + + + + + + 提示 + Prompt + + + + 请至少选择一项! + Please select one item! + + + + : + + + + + 总共: + Total: + + + + 保存为 + Save as + + + + (*.jpg) + + + + + 保存失败 + Failed to save + + + + FaultRecordModel + + + 时间 + Time + + + + 位置 + Location + + + + 设备名 + Dev Name + + + + 文件名 + File Name + + + + FaultRecordWidget + + 故障录波记录 + Fault Record + + + 位置 + Location + + + 设备 + Dev + + + + 开始时间 + Start Time + + + + 结束时间 + End Time + + + + 刷新 + Refresh + + + + 删除 + Delete + + + + 打开 + Open + + + + 全部删除 + All Delete + + + All + All + + + + + + + + + 提示 + Tip + + + + + 当前未选中任何项 + No rows are currently selected + + + + 开始时间不能大于结束时间! + Start time cannot be greater than end time ! + + + + 确定 + OK + + + + 不存在%1位置! + Does not exist %1 location ! + + + + FaultRecordWidget + + + + + + 当前用户不具有删除权限 + Current user have not perm to delete + + + + FilepathWidget + + 打开文件 + Open File + + + + FindReplaceDlg + + 连库替换 + Connection Replace + + + 连设备组 + DevGroup + + + 连位置 + Location + + + 连设备 + Deviece + + + 替换前: + Before: + + + 替换 + Replace + + + 替换后: + After: + + + 关闭 + close + + + 区分大小写 + Case Sensitive + + + 整站连接 + Site Connect + + + + FindWidget + + Form + FindDialog + + + + HandoverWidget + + + 交接班 + Duty shift + + + + 操作记录 + Operate Events + + + + 值班信息 + Duty info + + + + 关键告警 + Key Alarms + + + + 工作票 + Work Tickets + + + + 交班班组: + Shift group: + + + + 接班班组: + Take over group: + + + + 接班员 + Take over person + + + + 密码 + Password + + + + 接班签到 + Sign in + + + + 确认交接 + Confirm to shift + + + + + + 未签到 + Signed In + + + + + + + + 已签到 + Not Sign In + + + + HistoryWidget + + + 开始时间 + Start Time + + + + 结束时间 + End Time + + + + 查询 + Search + + + + 重开 + reTicket + + + + + 消息 + Infomation + + + + 链接数据库错误 + Linked database error + + + + 历史数据过多!表格仅展示查询结果的10000条 +更多数据查看,请缩小起始时间和结束时间之差 + Too much historical data! The table shows only 10,000 results of the query +For more data, narrow the gap between the start and end times + + + + 请选中一条记录! + Please select a record! + + + + + 提示 + Prompt + + + + InverseTimeLimit + + 该功能只支持在windows系统运行 + Only running on windows + + + 曲线配置 + Curve configuration + + + 选择文件 + Select file + + + 生成曲线 + Generate curve + + + 保存模板 + Save as template + + + 设备1 + Device 1 + + + 曲线名称 + Curve name + + + CO曲线 + CO curve + + + Vb(基准) + Vb(base) + + + Vt(换算) + Vt(conversion) + + + 设备2 + Device 2 + + + 设备3 + Device 3 + + + 设备4 + Device 4 + + + 设备5 + Device 5 + + + 设备6 + Device 6 + + + + IpcPlusWidget + + + 提醒 + Remind + + + + IpcPlusWidget + IpcPlusWidget + + + + ptz + ptz + + + + 调焦 + Focus + + + + 聚焦 + Focus + + + + 光圈 + Aperture + + + + 缩 + In + + + + 伸 + Out + + + + 近 + In + + + + 远 + Out + + + + 大 + In + + + + 小 + Out + + + + 预置点: + Preset: + + + + 调用 + Call + + + + 内存库读取失败 + Failure to query realtime database + + + + Label + + 打开 + Open + + + + LoadStatWidget + + LoadStatWidget + LoadStatWidget + + + 配置 + Config + + + 实时 + Real + + + 历史 + History + + + 风险点 + Risk Point + + + + MainWindow + + web发布 + Web Publish + + + 基础配置 + Basic Configuration + + + 首页配置 + HomePage Configuration + + + 背景图片配置 + BackgroundImage Configuration + + + 下一步 + Next + + + 权限验证 + Browser Permission Verification + + + 发布内容 + Publish Content + + + 画面/图元 + pic/icon + + + 图片 + back_pixmap + + + 风格 + style + + + 发布 + Publish + + + 上一步 + Previous + + + + Mainwindow + + + Form + Form + + + + 票库管理 + Ticket Library + + + + 开票记录 + Ticket Record + + + + NavigationConfigDialog + + + + 导航栏配置 + Configuration of Navigation Bar + + + + + + + 导入 + Import + + + + + 添加节点 + Add Node + + + + + 删除节点 + Delete Node + + + + + 清空 + Clear + + + + + 添加子节点 + Add ChildNode + + + + + 插入节点 + Insert Node + + + + + 导航栏 + Navigation Bar + + + + + + + 导出 + Export + + + + + + + + + 背景颜色: + Background Color: + + + + + + + 文字颜色: + Text Color: + + + + + 鼠标选中: + Mouse checked: + + + + + 鼠标悬停: + Mouse hovered: + + + + + 图标: + Icon: + + + + + 数据: + Data: + + + + + 项属性: + Item Property: + + + + + 节点层级属性: + Node hierarchy properties: + + + + + 节点状态属性: + Node state properties: + + + + + 窗口配置: + Window Configuration: + + + + + 一级节点 + First Node + + + + + + + + + 级别背景颜色: + Background Color: + + + + + + + + + 级别文字颜色: + Text Color: + + + + + + + + + 级别缩进距离: + Indent distance: + + + + + 二级节点 + Second Node + + + + + 三级节点 + Third Node + + + + + 取消 + Cancel + + + + + 确定 + Confirm + + + + + + + + + + + + - + + + + + + × + × + + + + + ∟ + + + + + + | + | + + + + + 启用: + Enable: + + + + + web发布: + web publish: + + + + + + + ... + ... + + + + + 操作: + Operation: + + + + + + + + + px + px + + + + PreviewForm + + Form + Form + + + + QCPItemTracer + + 时间 + Time + + + 事件信息 + Event Infomation + + + + QColorDialog + + Hu&e: + Hu&e: + + + &Sat: + &Sat: + + + &Val: + &Val: + + + &Red: + &Red: + + + &Green: + &Green: + + + Bl&ue: + Bl&ue: + + + A&lpha channel: + A&lpha channel: + + + &HTML: + &HTML: + + + Cursor at %1, %2 +Press ESC to cancel + Cursor at %1, %2 +Press ESC to cancel + + + Select Color + Select Color + + + &Basic colors + &Basic colors + + + &Custom colors + &Custom colors + + + &Add to Custom Colors + &Add to Custom Colors + + + &Pick Screen Color + &Pick Screen Color + + + + QFileDialog + + All Files (*) + All Files (*) + + + Look in: + Look in: + + + Back + Back + + + Go back + Go back + + + Alt+Left + Alt+Left + + + Forward + Forward + + + Go forward + Go forward + + + Alt+Right + Alt+Right + + + Parent Directory + Parent Directory + + + Go to the parent directory + Go to the parent directory + + + Alt+Up + Alt+Up + + + Create New Folder + Create New Folder + + + Create a New Folder + Create a New Folder + + + List View + List View + + + Change to list view mode + Change to list view mode + + + Detail View + Detail View + + + Change to detail view mode + Change to detail view mode + + + Sidebar + Sidebar + + + List of places and bookmarks + List of places and bookmarks + + + Files + Files + + + Files of type: + Files of type: + + + Find Directory + Find Directory + + + Open + Open + + + Save As + Save As + + + Directory: + Directory: + + + File &name: + File &name: + + + &Open + &Open + + + &Choose + &Choose + + + &Save + &Save + + + Show + Show + + + &Rename + &Rename + + + &Delete + &Delete + + + Show &hidden files + Show &hidden files + + + &New Folder + &New Folder + + + All files (*) + All files (*) + + + Directories + Directories + + + %1 +Directory not found. +Please verify the correct directory name was given. + %1 +Directory not found. +Please verify the correct directory name was given. + + + %1 already exists. +Do you want to replace it? + %1 already exists. +Do you want to replace it? + + + %1 +File not found. +Please verify the correct file name was given. + %1 +File not found. +Please verify the correct file name was given. + + + New Folder + New Folder + + + Delete + Delete + + + '%1' is write protected. +Do you want to delete it anyway? + '%1' is write protected. +Do you want to delete it anyway? + + + Are you sure you want to delete '%1'? + Are you sure you want to delete '%1'? + + + Could not delete directory. + Could not delete directory. + + + Recent Places + Recent Places + + + Remove + Remove + + + My Computer + My Computer + + + Drive + Drive + + + %1 File + %1 is a file name suffix, for example txt + %1 File + + + File + File + + + File Folder + Match Windows Explorer + File Folder + + + Folder + All other platforms + Folder + + + Alias + OS X Finder + Alias + + + Shortcut + All other platforms + Shortcut + + + Unknown + Unknown + + + + QFontDialog + + Select Font + Select Font + + + &Font + &Font + + + Font st&yle + Font st&yle + + + &Size + &Size + + + Effects + Effects + + + Stri&keout + Stri&keout + + + &Underline + &Underline + + + Sample + Sample + + + Wr&iting System + Wr&iting System + + + + QObject + + QPushButton::配置工具 + QPushButton::Configuration Tool + + + 起始角度 + Start Angle + + + 弧线角度 + Arc Angle + + + 半径 + Radius + + + x轴半径 + Xaxis Radius + + + y轴半径 + Yaxis Radius + + + 值 + Value + + + 属性 + Attribute + + + 组合图元不可镜像! + Composite primitive cannot be mirrored! + + + 精灵图元不可镜像! + Sprite elements cannot be mirrored! + + + 控件图元不可镜像! + Wiget primitive cannot be mirrored! + + + 图表图元不可镜像! + Chart primitive cannot be mirrored! + + + 该操作不支持组合图元 + This operation does not support composite primitive + + + 提示 + Prompt + + + 图层0 + Layer0 + + + 状态%1 + State%1 + + + 组态页面 + Configuration Page + + + 静态页面 + Static Page + + + QPushButton::图层工具 + QPushButton::Layer Tool + + + 警告 + Warning + + + HMI正在运行 + HMI still in running + + + 文字编辑 + Text Editor + + + 确定 + Confirm + + + 取消 + Cancel + + + 关系库 + Relation library + + + 时序库 + Timing library + + + 实时库 + RealTime library + + + 测点 + Measuring point + + + 数据源 + Data Source + + + 查询语句 + Query + + + 贝塞尔曲线 + Bezier curve + + + 显示类型 + Display type + + + 宽高 + Size + + + 横向缩放比例 + Horizontal Scaling + + + 纵向缩放比例 + Vertical Scaling + + + 是否显示 + isVisible + + + 数据长度 + data-length + + + 小数点位数 + Decimal places + + + 正负号显示 + Sign display + + + 边框样式 + Border style + + + 边框颜色 + Border color + + + 水平方向 + Horizontal + + + 竖直方向 + Vertical + + + 水平居左 + Horizontal left + + + 水平居中 + Horizontal center + + + 水平居右 + Horizontal right + + + 垂直居上 + Vertical up + + + 垂直居中 + Vertical center + + + 垂直居下 + Vertical down + + + 无边框 + No border + + + 凸出边框 + Raised border + + + 凹陷边框 + Sunken border + + + 浮点型 + Float + + + 整型 + Int + + + 字符串 + String + + + 日期 + Date + + + 数字量文本显示 + Dict text display + + + 菜单 + Menu + + + 光字牌 + Card + + + 平行边框 + Plain border + + + 数字量文本 + Dict text + + + 正常显示 + Normal display + + + 显示负号 + Show minus + + + 显示左右箭头 + Show left and right arrows + + + 显示上下箭头 + Show up and down arrows + + + 对象名称 + Object name + + + 文本内容 + Text content + + + 位置 + Location + + + 字体 + Font + + + 字体颜色 + Font color + + + 背景颜色 + Background color + + + 水平对齐方式 + Horizontal alignment + + + 垂直对齐方式 + Vertical alignment + + + 边框深度 + Border depth + + + 轴Z坐标 + Zaxis coordinates + + + 透明度 + Transparency + + + 网格线颜色 + Gridline color + + + 网格填充颜色 + Grid color + + + 交替填充颜色 + Alternate color + + + 交替填充 + Alternate fill + + + 行数量 + RowCount + + + 列数量 + ColumnCount + + + 旋转角度 + Rotation Angle + + + 中心点旋转 + Center rotation + + + 着色策略 + Coloring strategy + + + 起点箭头 + Starting point of the arrow + + + 终点箭头 + Ending point of the arrow + + + 起点 + Starting point + + + 终点 + Ending point + + + 起点箭头外观 + Appearance of starting arrow + + + 起点箭头大小 + Size of starting arrow + + + 终点箭头外观 + Appearance of ending arrow + + + 终点箭头大小 + Size of ending arrow + + + 位图 + Bitmap + + + 显示方式 + Display mode + + + 居中 + In the middle + + + 放缩 + Scaling + + + 调用图形 + Call the graphics + + + 热键类型 + Poke type + + + 图层显示 + Layer Display + + + 切换画面 + Switch picture + + + 弹出画面 + Popup picture + + + 程序调用 + Program Invocation + + + 文字方向 + Text direction + + + 箭头外观 + Arrow appearance + + + 水平填充百分比 + Horizontal fill percentage + + + 垂直填充百分比 + Vertical fill percentage + + + 矩形圆角 + Rounded corner + + + 画笔 + Pen + + + 画刷 + Brush + + + 所属应用 + Subordinate of the application + + + 层显示范围 + Layer display range + + + 脚本 + Script + + + 时间格式 + Time format + + + 内容 + Content + + + 插件名 + Plugin name + + + Tip提示信息 + Tip + + + 图标 + Icon + + + 图标宽高 + Icon Size + + + view_mode + view_mode + + + 调用资源 + Resource + + + 动作类型 + Action type + + + 组号 + Group no + + + 选中 + Selected + + + 类型 + Type + + + 切换图层 + Switch layer + + + 切换导航 + Switch navigation + + + 上一页 + Preview + + + 下一页 + Next + + + 显示文本 + Show Text + + + 显示密码 + Show Password + + + 文本输入 + TextEdit + + + 按钮 + Button + + + 组合框 + ComboBox + + + 复选框 + CheckBox + + + 单选按钮 + RadioBox + + + 标签 + Label + + + 列表框 + List + + + 数字输入 + SpinBox + + + 时间 + Time + + + 树形 + Tree + + + 表格 + Table + + + 插件 + Plugin + + + 文本框 + LineEdit + + + 图表标题 + Chart title + + + 标题颜色 + Title color + + + 标题字体 + Title font + + + 显示图例 + Show legend + + + 图例文字颜色 + Legend text color + + + 图例文字字体 + Legend text font + + + 显示背景 + Show background + + + 轮廓颜色 + Outline color + + + 图例位置 + Legend location + + + 图表模式 + Chart pattern + + + 是否统计图表 + Statistical chart + + + 时间滚动 + Time to roll + + + 项提示文本颜色 + Item prompt text color + + + 项提示文本字体 + Item prompt text font + + + 项数量 + Number of Item + + + 组数量 + Number of group + + + 棒描述 + Stick description + + + 棒颜色 + Stick color + + + 饼描述 + Pie description + + + 饼颜色 + Pie color + + + 曲线数量 + Curve number + + + 曲线线宽 + Curve width + + + Y轴线颜色 + Yaxis color + + + Y轴标题 + Yaxis title + + + Y轴标题颜色 + Yaxis title color + + + Y轴标题字体 + Yaxis title font + + + Y轴最小值 + Yaxis minimum + + + Y轴最大值 + Yaxis maximum + + + Y轴刻度数 + Yaxis dial number + + + Y轴文字颜色 + Yaxis text color + + + Y轴文字字体 + Yaxis text font + + + 显示Y轴网格线 + Show Yaxis grid + + + Y轴网格线 + Yaxis grid + + + X轴格式 + Xaxis format + + + X轴跨度 + Xaxis span + + + X轴刻度数 + Xaxis dial number + + + X轴线颜色 + Xaxis line color + + + X轴文字颜色 + Xaxis text color + + + X轴文字字体 + Xaxis text font + + + X轴网格线 + Xaxis grid + + + 显示X轴网格线 + Show Xaxis grid + + + 刷新间隔 + Refresh interval + + + 曲线描述 + Curve description + + + 曲线颜色 + Curve color + + + 参考线数量 + Guides Number + + + 参考线1 + Guides1 + + + 参考线2 + Guides2 + + + 参考线3 + Guides3 + + + 自定义 + Custom + + + 日 + Day + + + 月 + Month + + + 年 + Year + + + 左侧 + Left side + + + 顶部 + Top + + + 右侧 + Right side + + + 底部 + Bottom + + + 潮流外观 + Load flow appearance + + + 矩形 + Rect + + + 箭头 + Arrow + + + 圆形 + Circular + + + 圆流 + Circular flow + + + 显示端号 + Display the number + + + 方向性 + Directional + + + 圆弧 + Arc + + + 母线 + Bus + + + 多态文本 + Polymorphic text + + + 线端 + Incoming Line + + + 椭圆 + Ellipse + + + 圆 + Circle + + + 潮流线 + flow line + + + 网格 + Grid + + + 组合 + Combination + + + 直线 + Line + + + 连接线 + Connecting line + + + 折线 + Path + + + 端子 + Terminal + + + 热键 + Poke + + + 多边形 + Polygon + + + 文本 + Text + + + 设备组 + Device Group + + + 自适应模式 + Adaptive pattern + + + 屏幕宽高比 + Screen aspect radio + + + 图元宽高比 + Primitive aspect radio + + + 告警提示 + Alarm Prompt + + + 带电区域 + Power Polygon + + + 存在重复设备:%1 + Repeat device:%1 + + + + + + + 未确认 + Unconfirmed + + + + + + + 已确认 + Confirmed + + + + 预览 + Preview + + + + 打印 + Print + + + + + 模拟量 + Analog + + + + + 数字量 + Digital + + + + + 累积量 + Accuml + + + + + 混合量 + Mix + + + + + + + + 其他 + Other + + + + + 未复归 + unResumed + + + + + 已复归 + Resumed + + + + + - + - + + + + 位置列表 + Location List + + + + 告警/智能告警 + Alarms/Intelligent Alarms + + + 告警数/智能告警数 + Alarm/Intelligent Alarm + + + 自由连接线 + Free Connection Line + + + + 自定义项目 + Custom Item + + + phase A + phase A + + + phase B + phase B + + + phase C + phase C + + + Mark + Mark + + + The Order Of Harmonic Sholud Be Greater Than 0 + The Order Of Harmonic Sholud Be Greater Than 0 + + + Smapling Data Reading Error + Smapling Data Reading Error + + + The Order Of Harmonic Sholud Be Less Than nn + The Order Of Harmonic Sholud Be Less Than nn + + + Out of Memory + Out of Memory + + + Error + Error + + + input error + input error + + + + QSMessageBox + + 是 + Yes + + + 否 + No + + + + QssEditor + + 样式编辑器 + QssEditor + + + Ctrl+S + Ctrl+S + + + Ctrl+F + Ctrl+F + + + + QtBoolEdit + + True + True + + + False + False + + + + QtBoolPropertyManager + + True + True + + + False + False + + + + QtCharEdit + + Clear Char + Clear Char + + + + QtColorEditWidget + + ... + ... + + + + QtColorPropertyManager + + Red + Red + + + Green + Green + + + Blue + Blue + + + Alpha + Alpha + + + + QtCursorDatabase + + Arrow + Arrow + + + Up Arrow + Up Arrow + + + Cross + Cross + + + Wait + Wait + + + IBeam + IBeam + + + Size Vertical + Size Vertical + + + Size Horizontal + Size Horizontal + + + Size Backslash + Size Backslash + + + Size Slash + Size Slash + + + Size All + Size All + + + Blank + Blank + + + Split Vertical + Split Vertical + + + Split Horizontal + Split Horizontal + + + Pointing Hand + Pointing Hand + + + Forbidden + Forbidden + + + Open Hand + Open Hand + + + Closed Hand + Closed Hand + + + What's This + What's This + + + Busy + Busy + + + + QtFontEditWidget + + ... + ... + + + 选择字体 + Select Font + + + + QtFontPropertyManager + + Family + Family + + + Point Size + Point Size + + + Bold + Bold + + + Italic + Italic + + + Underline + Underline + + + Strikeout + Strikeout + + + Kerning + Kerning + + + + QtGradientDialog + + 编辑渐变 + Gradient Editor + + + 确认 + Confirm + + + 取消 + Cancel + + + + QtGradientEditor + + Form + Form + + + Gradient Editor + Gradient Editor + + + 1 + 1 + + + 2 + 2 + + + 3 + 3 + + + 4 + 4 + + + 5 + 5 + + + Gradient Stops Editor + Gradient Stops Editor + + + Zoom + Zoom + + + Reset Zoom + Reset Zoom + + + Position + Position + + + Hue + Hue + + + H + H + + + Saturation + Saturation + + + S + S + + + Sat + Sat + + + Value + Value + + + V + V + + + Val + Val + + + Alpha + Alpha + + + A + A + + + Type + Type + + + Spread + Spread + + + Color + Color + + + Current stop's color + Current stop's color + + + Show HSV specification + Show HSV specification + + + HSV + HSV + + + Show RGB specification + Show RGB specification + + + RGB + RGB + + + Current stop's position + Current stop's position + + + % + % + + + Zoom In + Zoom In + + + Zoom Out + Zoom Out + + + Toggle details extension + Toggle details extension + + + > + > + + + Linear Type + Linear Type + + + ... + ... + + + Radial Type + Radial Type + + + Conical Type + Conical Type + + + Pad Spread + Pad Spread + + + Repeat Spread + Repeat Spread + + + Reflect Spread + Reflect Spread + + + Start X + Start X + + + Start Y + Start Y + + + Final X + Final X + + + Final Y + Final Y + + + Central X + Central X + + + Central Y + Central Y + + + Focal X + Focal X + + + Focal Y + Focal Y + + + Radius + Radius + + + Angle + Angle + + + Linear + Linear + + + Radial + Radial + + + Conical + Conical + + + Pad + Pad + + + Repeat + Repeat + + + Reflect + Reflect + + + + QtGradientViewDialogN + + 确认 + Confirm + + + 取消 + Cancel + + + + Renderer + + 打开 + Open + + + + SWitchButton + + 打开告警联动失败! + Failure to open alarm linkage! + + + 关闭告警联动失败! + Failure to close alarm linkage! + + + 数据库连接失败! + Failure to connect to database! + + + + SearchDialog + + 查找和替换 + Find && Replace + + + 查找目标 + Find What + + + 下一个 + Next Word + + + 替换为 + Replace With + + + 全部替换 + All Replace + + + + SetValueInputDialog + + + Dialog + Dialog + + + + 确定 + Confirm + + + + 取消 + Cancel + + + + + 设置值 + Setting Value + + + + 人工置数 + Manual Setting + + + + StationLineWidget + + 站点标签设置 + Station Label Settings + + + 站点标签: + Station Label: + + + 标签字体: + Label Font: + + + 字体大小: + Font Size: + + + 标签宽度: + Label Width: + + + 标签高度: + Label Height: + + + 是否加粗 + Bold: + + + 告警提示设置 + Alert Prompt Settings + + + 按钮半径: + Button Radius: + + + 闪烁间隔: + Flash Interval: + + + 渐变步长: + Gradient Step: + + + 保存布局 + Save Layout + + + 提示 + Prompt + + + 布局保存成功 + Layout saved successfully + + + + UserManageWidget + + + UserManageWidget + User Management Widget + + + + + 提示 + Prompt + + + + 用户管理插件用户权限认证库调用失败! + Failure to initialize perm library! + + + + 当前用户ID获取失败! + Failure to get current user id! + + + + VoiceSlider + + + Form + Form + + + 53 + 53 + + + + 0 + 0 + + + + WorkTicketWidget + + + 保存 + Save + + + 出票&预览 + Ticket&Preview + + + + 保存失败:%1 + Failed to save:%1 + + + + 保存成功 + Save successed + + + + 获取当前登录用户失败! + Failure to get current user! + + + + 事务执行失败!启动回滚 + Transaction execution failed! Start the rollback + + + 出票失败 + Failed to ticket + + + + + 出票失败:%1 + Failed to ticket:%1 + + + + 消息 + Infomation + + + + 电子签章 + Electronic signature + + + + 出票 + Ticket + + + + + (签章) + (signature) + + + + 创建目录失败: %1 + Failure to create directory:%1 + + + + + + + 请先关闭文件: %1 + Please close file:%1 + + + + 历史票不存在! + Not historical ticket found! + + + + + 当前登录用户无运维管理功能权限! + Current user have no perm to operate! + + + + 出票失败,请检查网络或者主数据库服务器连接是否异常! + Failure to ticket,please check the network and database server! + + + + qtgradientviewn + + Form + Gradient Editor + + + 新建 + New + + + 编辑 + Edit + + + 重命名 + Rename + + + 移除 + Remove + + + 渐变 + Gradient + + + 确认移除选中渐变? + Remove selected gradient? + + + diff --git a/product/src/include/application/fault_recall_srv/JsonMsgClass.cpp b/product/src/include/application/fault_recall_srv/JsonMsgClass.cpp index 5677de07..23d428fa 100644 --- a/product/src/include/application/fault_recall_srv/JsonMsgClass.cpp +++ b/product/src/include/application/fault_recall_srv/JsonMsgClass.cpp @@ -16,7 +16,7 @@ #include "JsonMsgClass.h" -namespace iot_application +namespace iot_app { CFrMsgNewSess::CFrMsgNewSess() @@ -417,5 +417,5 @@ bool CFrMsgSetTime::operator==(const CFrMsgSetTime &other) const } -} //< namespace iot_application +} //< namespace iot_app diff --git a/product/src/include/application/fault_recall_srv/JsonMsgClass.h b/product/src/include/application/fault_recall_srv/JsonMsgClass.h index a033f639..228e802c 100644 --- a/product/src/include/application/fault_recall_srv/JsonMsgClass.h +++ b/product/src/include/application/fault_recall_srv/JsonMsgClass.h @@ -17,7 +17,7 @@ //< Sess : Session 会话 //< Srv : Service 服务 -namespace iot_application +namespace iot_app { //< 会话超时时间,单位s,若此时间内未收到任何该会话的消息,则超时 @@ -164,5 +164,5 @@ public: std::string m_strSess; //< 会话名称,唯一标识 }; -} //< namespace iot_application +} //< namespace iot_app diff --git a/product/src/include/application/linkage_server_api/CLinkageForHmiApi.h b/product/src/include/application/linkage_server_api/CLinkageForHmiApi.h index 45458362..5496f3f2 100644 --- a/product/src/include/application/linkage_server_api/CLinkageForHmiApi.h +++ b/product/src/include/application/linkage_server_api/CLinkageForHmiApi.h @@ -10,7 +10,7 @@ #include "CLinkageApiExport.h" #include "LinkageMessage.pb.h" -namespace iot_application { +namespace iot_app { class CLinkageForHmiApiImpl; using namespace iot_idl::linkage; class LINKAGE_SERVER_API CLinkageForHmiApi diff --git a/product/src/include/application/linkage_server_api/CLinkageForServerApi.h b/product/src/include/application/linkage_server_api/CLinkageForServerApi.h index 6be45273..159c8d51 100644 --- a/product/src/include/application/linkage_server_api/CLinkageForServerApi.h +++ b/product/src/include/application/linkage_server_api/CLinkageForServerApi.h @@ -11,7 +11,7 @@ #include "CLinkageApiExport.h" #include "LinkageMessage.pb.h" -namespace iot_application +namespace iot_app { // struct SToHostMsg // { diff --git a/product/src/include/application/sequence_server_api/CSeqForHmiApi.h b/product/src/include/application/sequence_server_api/CSeqForHmiApi.h index 709cd9b6..69ba15da 100644 --- a/product/src/include/application/sequence_server_api/CSeqForHmiApi.h +++ b/product/src/include/application/sequence_server_api/CSeqForHmiApi.h @@ -9,7 +9,7 @@ #include "SequenceMessage.pb.h" #include "Common.h" -namespace iot_application { +namespace iot_app { using namespace iot_idl::sequence; class CSeqForHmiApiImpl; class SEQUENCE_SERVER_API CSeqForHmiApi diff --git a/product/src/include/application/sequence_server_api/CSeqForServerApi.h b/product/src/include/application/sequence_server_api/CSeqForServerApi.h index 88fbc075..63f6cdf1 100644 --- a/product/src/include/application/sequence_server_api/CSeqForServerApi.h +++ b/product/src/include/application/sequence_server_api/CSeqForServerApi.h @@ -11,7 +11,7 @@ #include "CSeqApiExport.h" #include "SequenceMessage.pb.h" -namespace iot_application { +namespace iot_app { using namespace iot_idl::sequence; class CSeqForServerApiImpl; diff --git a/product/src/include/application/trigger_api/CTriggerApi.h b/product/src/include/application/trigger_api/CTriggerApi.h index f4986e71..f4dfde3a 100644 --- a/product/src/include/application/trigger_api/CTriggerApi.h +++ b/product/src/include/application/trigger_api/CTriggerApi.h @@ -15,7 +15,7 @@ #include "application/trigger_api/CTriggerApiExport.h" #include "application/trigger_api/CTriggerPara.h" -namespace iot_application { +namespace iot_app { struct STriggerInitParam; class CTriggerApiImpl; diff --git a/product/src/include/application/trigger_api/CTriggerPara.h b/product/src/include/application/trigger_api/CTriggerPara.h index bfcc8e4f..452e4f18 100644 --- a/product/src/include/application/trigger_api/CTriggerPara.h +++ b/product/src/include/application/trigger_api/CTriggerPara.h @@ -8,7 +8,7 @@ #include #include "application/trigger_api/CTriggerApiExport.h" -namespace iot_application { +namespace iot_app { using namespace std; class TRIGGER_API CTriggerPara diff --git a/product/src/include/tools/calc_lua_api/CCalcLua.h b/product/src/include/tools/calc_lua_api/CCalcLua.h index 88c51c2f..eef6c114 100644 --- a/product/src/include/tools/calc_lua_api/CCalcLua.h +++ b/product/src/include/tools/calc_lua_api/CCalcLua.h @@ -22,6 +22,10 @@ public: static lua_State* lua_state; static QString m_error; + +private: + void registFunctionToLua(); + private: QString m_name; diff --git a/product/src/include/tools/emsPlanCurve/CPlanCurvesConfigure.h b/product/src/include/tools/emsPlanCurve/CPlanCurvesConfigure.h index 081f8312..410b6a51 100644 --- a/product/src/include/tools/emsPlanCurve/CPlanCurvesConfigure.h +++ b/product/src/include/tools/emsPlanCurve/CPlanCurvesConfigure.h @@ -48,6 +48,7 @@ private: void initialize(); void initTable(); + void initMainTabBar(); void initPlanTypeComb(QComboBox *combox); void initDaysTmplComb(QComboBox *combox); void setBtnEnable(bool enable); diff --git a/product/src/include/tools/emsPlanCurve/CTableDefine.h b/product/src/include/tools/emsPlanCurve/CTableDefine.h index be927848..3f60cfaf 100644 --- a/product/src/include/tools/emsPlanCurve/CTableDefine.h +++ b/product/src/include/tools/emsPlanCurve/CTableDefine.h @@ -49,6 +49,7 @@ struct SApcCurveDayValue int start_sec; int end_sec; double value; + QString unit; curveType type; }; diff --git a/product/src/src.pro b/product/src/src.pro index f6b81e09..692d6ec5 100644 --- a/product/src/src.pro +++ b/product/src/src.pro @@ -8,14 +8,15 @@ CONFIG += ordered SUBDIRS += public \ idl_files \ - application/OnvifLibs \ + fes/fes_idl_files \ + #application/OnvifLibs \ sys \ net \ dbms \ service \ application \ gui \ - tools/kbd61850dbinterface \ +# tools/kbd61850dbinterface \ tools/calc_lua_api \ fes \ tools